diff options
| author | lain <lain@soykaf.club> | 2019-12-04 16:35:59 +0100 | 
|---|---|---|
| committer | lain <lain@soykaf.club> | 2019-12-04 16:35:59 +0100 | 
| commit | e9993acdbbd1649bbcbf3fb36581b91145fe6055 (patch) | |
| tree | b78d91c904e307a504ed91a06ab718d8c694ca5c /test/web | |
| parent | 1bd1f62af55e01613e6362661b36a19091c87424 (diff) | |
| parent | 228bf4d214abe3bb62c52128d3bc145e396b174d (diff) | |
| download | pleroma-e9993acdbbd1649bbcbf3fb36581b91145fe6055.tar.gz pleroma-e9993acdbbd1649bbcbf3fb36581b91145fe6055.zip  | |
Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into remake-remodel
Diffstat (limited to 'test/web')
21 files changed, 1413 insertions, 135 deletions
diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index a5414c521..1aa73d75c 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -110,6 +110,19 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do        assert json_response(conn, 200) == UserView.render("user.json", %{user: user})      end + +    test "it returns 404 for remote users", %{ +      conn: conn +    } do +      user = insert(:user, local: false, nickname: "remoteuser@example.com") + +      conn = +        conn +        |> put_req_header("accept", "application/json") +        |> get("/users/#{user.nickname}.json") + +      assert json_response(conn, 404) +    end    end    describe "/object/:uuid" do diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index f29b8cc74..2677b9e36 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -4,8 +4,11 @@  defmodule Pleroma.Web.ActivityPub.ActivityPubTest do    use Pleroma.DataCase +  use Oban.Testing, repo: Pleroma.Repo +    alias Pleroma.Activity    alias Pleroma.Builders.ActivityBuilder +  alias Pleroma.Notification    alias Pleroma.Object    alias Pleroma.User    alias Pleroma.Web.ActivityPub.ActivityPub @@ -734,56 +737,54 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do      end      test "retrieves a maximum of 20 activities" do -      activities = ActivityBuilder.insert_list(30) -      last_expected = List.last(activities) +      ActivityBuilder.insert_list(10) +      expected_activities = ActivityBuilder.insert_list(20)        activities = ActivityPub.fetch_public_activities() -      last = List.last(activities) +      assert collect_ids(activities) == collect_ids(expected_activities)        assert length(activities) == 20 -      assert last == last_expected      end      test "retrieves ids starting from a since_id" do        activities = ActivityBuilder.insert_list(30) -      later_activities = ActivityBuilder.insert_list(10) +      expected_activities = ActivityBuilder.insert_list(10)        since_id = List.last(activities).id -      last_expected = List.last(later_activities)        activities = ActivityPub.fetch_public_activities(%{"since_id" => since_id}) -      last = List.last(activities) +      assert collect_ids(activities) == collect_ids(expected_activities)        assert length(activities) == 10 -      assert last == last_expected      end      test "retrieves ids up to max_id" do -      _first_activities = ActivityBuilder.insert_list(10) -      activities = ActivityBuilder.insert_list(20) -      later_activities = ActivityBuilder.insert_list(10) -      max_id = List.first(later_activities).id -      last_expected = List.last(activities) +      ActivityBuilder.insert_list(10) +      expected_activities = ActivityBuilder.insert_list(20) + +      %{id: max_id} = +        10 +        |> ActivityBuilder.insert_list() +        |> List.first()        activities = ActivityPub.fetch_public_activities(%{"max_id" => max_id}) -      last = List.last(activities)        assert length(activities) == 20 -      assert last == last_expected +      assert collect_ids(activities) == collect_ids(expected_activities)      end      test "paginates via offset/limit" do -      _first_activities = ActivityBuilder.insert_list(10) -      activities = ActivityBuilder.insert_list(10) -      _later_activities = ActivityBuilder.insert_list(10) -      first_expected = List.first(activities) +      _first_part_activities = ActivityBuilder.insert_list(10) +      second_part_activities = ActivityBuilder.insert_list(10) + +      later_activities = ActivityBuilder.insert_list(10)        activities =          ActivityPub.fetch_public_activities(%{"page" => "2", "page_size" => "20"}, :offset) -      first = List.first(activities) -        assert length(activities) == 20 -      assert first == first_expected + +      assert collect_ids(activities) == +               collect_ids(second_part_activities) ++ collect_ids(later_activities)      end      test "doesn't return reblogs for users for whom reblogs have been muted" do @@ -814,6 +815,78 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do      end    end +  describe "react to an object" do +    test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do +      Pleroma.Config.put([:instance, :federating], true) +      user = insert(:user) +      reactor = insert(:user) +      {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"}) +      assert object = Object.normalize(activity) + +      {:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥") + +      assert called(Pleroma.Web.Federator.publish(reaction_activity)) +    end + +    test "adds an emoji reaction activity to the db" do +      user = insert(:user) +      reactor = insert(:user) +      {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"}) +      assert object = Object.normalize(activity) + +      {:ok, reaction_activity, object} = ActivityPub.react_with_emoji(reactor, object, "🔥") + +      assert reaction_activity + +      assert reaction_activity.data["actor"] == reactor.ap_id +      assert reaction_activity.data["type"] == "EmojiReaction" +      assert reaction_activity.data["content"] == "🔥" +      assert reaction_activity.data["object"] == object.data["id"] +      assert reaction_activity.data["to"] == [User.ap_followers(reactor), activity.data["actor"]] +      assert reaction_activity.data["context"] == object.data["context"] +      assert object.data["reaction_count"] == 1 +      assert object.data["reactions"]["🔥"] == [reactor.ap_id] +    end +  end + +  describe "unreacting to an object" do +    test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do +      Pleroma.Config.put([:instance, :federating], true) +      user = insert(:user) +      reactor = insert(:user) +      {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"}) +      assert object = Object.normalize(activity) + +      {:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥") + +      assert called(Pleroma.Web.Federator.publish(reaction_activity)) + +      {:ok, unreaction_activity, _object} = +        ActivityPub.unreact_with_emoji(reactor, reaction_activity.data["id"]) + +      assert called(Pleroma.Web.Federator.publish(unreaction_activity)) +    end + +    test "adds an undo activity to the db" do +      user = insert(:user) +      reactor = insert(:user) +      {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"}) +      assert object = Object.normalize(activity) + +      {:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥") + +      {:ok, unreaction_activity, _object} = +        ActivityPub.unreact_with_emoji(reactor, reaction_activity.data["id"]) + +      assert unreaction_activity.actor == reactor.ap_id +      assert unreaction_activity.data["object"] == reaction_activity.data["id"] + +      object = Object.get_by_ap_id(object.data["id"]) +      assert object.data["reaction_count"] == 0 +      assert object.data["reactions"] == %{} +    end +  end +    describe "like an object" do      test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do        Pleroma.Config.put([:instance, :federating], true) @@ -1484,5 +1557,80 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do        assert follow_info.hide_followers == false        assert follow_info.hide_follows == true      end + +    test "detects hidden follows/followers for friendica" do +      user = +        insert(:user, +          local: false, +          follower_address: "http://localhost:8080/followers/fuser3", +          following_address: "http://localhost:8080/following/fuser3" +        ) + +      {:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user) +      assert follow_info.hide_followers == true +      assert follow_info.follower_count == 296 +      assert follow_info.following_count == 32 +      assert follow_info.hide_follows == true +    end +  end + +  describe "Move activity" do +    test "create" do +      %{ap_id: old_ap_id} = old_user = insert(:user) +      %{ap_id: new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id]) +      follower = insert(:user) +      follower_move_opted_out = insert(:user, allow_following_move: false) + +      User.follow(follower, old_user) +      User.follow(follower_move_opted_out, old_user) + +      assert User.following?(follower, old_user) +      assert User.following?(follower_move_opted_out, old_user) + +      assert {:ok, activity} = ActivityPub.move(old_user, new_user) + +      assert %Activity{ +               actor: ^old_ap_id, +               data: %{ +                 "actor" => ^old_ap_id, +                 "object" => ^old_ap_id, +                 "target" => ^new_ap_id, +                 "type" => "Move" +               }, +               local: true +             } = activity + +      params = %{ +        "op" => "move_following", +        "origin_id" => old_user.id, +        "target_id" => new_user.id +      } + +      assert_enqueued(worker: Pleroma.Workers.BackgroundWorker, args: params) + +      Pleroma.Workers.BackgroundWorker.perform(params, nil) + +      refute User.following?(follower, old_user) +      assert User.following?(follower, new_user) + +      assert User.following?(follower_move_opted_out, old_user) +      refute User.following?(follower_move_opted_out, new_user) + +      activity = %Activity{activity | object: nil} + +      assert [%Notification{activity: ^activity}] = +               Notification.for_user_since(follower, ~N[2019-04-13 11:22:33]) + +      assert [%Notification{activity: ^activity}] = +               Notification.for_user_since(follower_move_opted_out, ~N[2019-04-13 11:22:33]) +    end + +    test "old user must be in the new user's `also_known_as` list" do +      old_user = insert(:user) +      new_user = insert(:user) + +      assert {:error, "Target account must have the origin in `alsoKnownAs`"} = +               ActivityPub.move(old_user, new_user) +    end    end  end diff --git a/test/web/activity_pub/mrf/object_age_policy_test.exs b/test/web/activity_pub/mrf/object_age_policy_test.exs new file mode 100644 index 000000000..643609da4 --- /dev/null +++ b/test/web/activity_pub/mrf/object_age_policy_test.exs @@ -0,0 +1,105 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do +  use Pleroma.DataCase +  alias Pleroma.Config +  alias Pleroma.User +  alias Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy +  alias Pleroma.Web.ActivityPub.Visibility + +  clear_config([:mrf_object_age]) do +    Config.put(:mrf_object_age, +      threshold: 172_800, +      actions: [:delist, :strip_followers] +    ) +  end + +  setup_all do +    Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) +    :ok +  end + +  describe "with reject action" do +    test "it rejects an old post" do +      Config.put([:mrf_object_age, :actions], [:reject]) + +      data = +        File.read!("test/fixtures/mastodon-post-activity.json") +        |> Poison.decode!() + +      {:reject, _} = ObjectAgePolicy.filter(data) +    end + +    test "it allows a new post" do +      Config.put([:mrf_object_age, :actions], [:reject]) + +      data = +        File.read!("test/fixtures/mastodon-post-activity.json") +        |> Poison.decode!() +        |> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601()) + +      {:ok, _} = ObjectAgePolicy.filter(data) +    end +  end + +  describe "with delist action" do +    test "it delists an old post" do +      Config.put([:mrf_object_age, :actions], [:delist]) + +      data = +        File.read!("test/fixtures/mastodon-post-activity.json") +        |> Poison.decode!() + +      {:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"]) + +      {:ok, data} = ObjectAgePolicy.filter(data) + +      assert Visibility.get_visibility(%{data: data}) == "unlisted" +    end + +    test "it allows a new post" do +      Config.put([:mrf_object_age, :actions], [:delist]) + +      data = +        File.read!("test/fixtures/mastodon-post-activity.json") +        |> Poison.decode!() +        |> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601()) + +      {:ok, _user} = User.get_or_fetch_by_ap_id(data["actor"]) + +      {:ok, ^data} = ObjectAgePolicy.filter(data) +    end +  end + +  describe "with strip_followers action" do +    test "it strips followers collections from an old post" do +      Config.put([:mrf_object_age, :actions], [:strip_followers]) + +      data = +        File.read!("test/fixtures/mastodon-post-activity.json") +        |> Poison.decode!() + +      {:ok, user} = User.get_or_fetch_by_ap_id(data["actor"]) + +      {:ok, data} = ObjectAgePolicy.filter(data) + +      refute user.follower_address in data["to"] +      refute user.follower_address in data["cc"] +    end + +    test "it allows a new post" do +      Config.put([:mrf_object_age, :actions], [:strip_followers]) + +      data = +        File.read!("test/fixtures/mastodon-post-activity.json") +        |> Poison.decode!() +        |> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601()) + +      {:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"]) + +      {:ok, ^data} = ObjectAgePolicy.filter(data) +    end +  end +end diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index 5e72f33b2..1910de6e0 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -39,6 +39,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        assert activity == returned_activity      end +    @tag capture_log: true      test "it fetches replied-to activities if we don't have them" do        data =          File.read!("test/fixtures/mastodon-post-activity.json") @@ -341,6 +342,80 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        assert data["object"] == activity.data["object"]      end +    test "it works for incoming misskey likes, turning them into EmojiReactions" do +      user = insert(:user) +      {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"}) + +      data = +        File.read!("test/fixtures/misskey-like.json") +        |> Poison.decode!() +        |> Map.put("object", activity.data["object"]) + +      {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) + +      assert data["actor"] == data["actor"] +      assert data["type"] == "EmojiReaction" +      assert data["id"] == data["id"] +      assert data["object"] == activity.data["object"] +      assert data["content"] == "🍮" +    end + +    test "it works for incoming misskey likes that contain unicode emojis, turning them into EmojiReactions" do +      user = insert(:user) +      {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"}) + +      data = +        File.read!("test/fixtures/misskey-like.json") +        |> Poison.decode!() +        |> Map.put("object", activity.data["object"]) +        |> Map.put("_misskey_reaction", "⭐") + +      {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) + +      assert data["actor"] == data["actor"] +      assert data["type"] == "EmojiReaction" +      assert data["id"] == data["id"] +      assert data["object"] == activity.data["object"] +      assert data["content"] == "⭐" +    end + +    test "it works for incoming emoji reactions" do +      user = insert(:user) +      {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"}) + +      data = +        File.read!("test/fixtures/emoji-reaction.json") +        |> Poison.decode!() +        |> Map.put("object", activity.data["object"]) + +      {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) + +      assert data["actor"] == "http://mastodon.example.org/users/admin" +      assert data["type"] == "EmojiReaction" +      assert data["id"] == "http://mastodon.example.org/users/admin#reactions/2" +      assert data["object"] == activity.data["object"] +      assert data["content"] == "👌" +    end + +    test "it works for incoming emoji reaction undos" do +      user = insert(:user) + +      {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"}) +      {:ok, reaction_activity, _object} = CommonAPI.react_with_emoji(activity.id, user, "👌") + +      data = +        File.read!("test/fixtures/mastodon-undo-like.json") +        |> Poison.decode!() +        |> Map.put("object", reaction_activity.data["id"]) +        |> Map.put("actor", user.ap_id) + +      {:ok, activity} = Transmogrifier.handle_incoming(data) + +      assert activity.actor == user.ap_id +      assert activity.data["id"] == data["id"] +      assert activity.data["type"] == "Undo" +    end +      test "it returns an error for incoming unlikes wihout a like activity" do        user = insert(:user)        {:ok, activity} = CommonAPI.post(user, %{"status" => "leave a like pls"}) @@ -461,6 +536,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        assert object.data["content"] == "this is a private toot"      end +    @tag capture_log: true      test "it rejects incoming announces with an inlined activity from another origin" do        data =          File.read!("test/fixtures/bogus-mastodon-announce.json") @@ -555,6 +631,20 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        refute Map.has_key?(object.data, "likes")      end +    test "it strips internal reactions" do +      user = insert(:user) +      {:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"}) +      {:ok, _, _} = CommonAPI.react_with_emoji(activity.id, user, "📢") + +      %{object: object} = Activity.get_by_id_with_object(activity.id) +      assert Map.has_key?(object.data, "reactions") +      assert Map.has_key?(object.data, "reaction_count") + +      object_data = Transmogrifier.strip_internal_fields(object.data) +      refute Map.has_key?(object_data, "reactions") +      refute Map.has_key?(object_data, "reaction_count") +    end +      test "it works for incoming update activities" do        data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() @@ -595,6 +685,37 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        assert user.bio == "<p>Some bio</p>"      end +    test "it works with alsoKnownAs" do +      {:ok, %Activity{data: %{"actor" => actor}}} = +        "test/fixtures/mastodon-post-activity.json" +        |> File.read!() +        |> Poison.decode!() +        |> Transmogrifier.handle_incoming() + +      assert User.get_cached_by_ap_id(actor).also_known_as == ["http://example.org/users/foo"] + +      {:ok, _activity} = +        "test/fixtures/mastodon-update.json" +        |> File.read!() +        |> Poison.decode!() +        |> Map.put("actor", actor) +        |> Map.update!("object", fn object -> +          object +          |> Map.put("actor", actor) +          |> Map.put("id", actor) +          |> Map.put("alsoKnownAs", [ +            "http://mastodon.example.org/users/foo", +            "http://example.org/users/bar" +          ]) +        end) +        |> Transmogrifier.handle_incoming() + +      assert User.get_cached_by_ap_id(actor).also_known_as == [ +               "http://mastodon.example.org/users/foo", +               "http://example.org/users/bar" +             ] +    end +      test "it works with custom profile fields" do        {:ok, activity} =          "test/fixtures/mastodon-post-activity.json" @@ -728,6 +849,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        assert Activity.get_by_id(activity.id)      end +    @tag capture_log: true      test "it works for incoming user deletes" do        %{ap_id: ap_id} = insert(:user, ap_id: "http://mastodon.example.org/users/admin") @@ -1183,6 +1305,30 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        assert ["https://www.w3.org/ns/activitystreams#Public"] == activity.data["cc"]        assert [user.follower_address] == activity.data["to"]      end + +    test "it accepts Move activities" do +      old_user = insert(:user) +      new_user = insert(:user) + +      message = %{ +        "@context" => "https://www.w3.org/ns/activitystreams", +        "type" => "Move", +        "actor" => old_user.ap_id, +        "object" => old_user.ap_id, +        "target" => new_user.ap_id +      } + +      assert :error = Transmogrifier.handle_incoming(message) + +      {:ok, _new_user} = User.update_and_set_cache(new_user, %{also_known_as: [old_user.ap_id]}) + +      assert {:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(message) +      assert activity.actor == old_user.ap_id +      assert activity.data["actor"] == old_user.ap_id +      assert activity.data["object"] == old_user.ap_id +      assert activity.data["target"] == new_user.ap_id +      assert activity.data["type"] == "Move" +    end    end    describe "prepare outgoing" do @@ -1663,6 +1809,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        assert modified_object["inReplyToAtomUri"] == ""      end +    @tag capture_log: true      test "returns modified object when allowed incoming reply", %{data: data} do        object_with_reply =          Map.put( @@ -1782,6 +1929,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do               end) =~ "Unsupported URI scheme"      end +    @tag capture_log: true      test "returns {:ok, %Object{}} for success case" do        assert {:ok, %Object{}} =                 Transmogrifier.get_obj_helper("https://shitposter.club/notice/2827873") diff --git a/test/web/activity_pub/utils_test.exs b/test/web/activity_pub/utils_test.exs index 586eb1d2f..1feb076ba 100644 --- a/test/web/activity_pub/utils_test.exs +++ b/test/web/activity_pub/utils_test.exs @@ -636,4 +636,47 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do        assert updated_object.data["announcement_count"] == 1      end    end + +  describe "get_reports_grouped_by_status/1" do +    setup do +      [reporter, target_user] = insert_pair(:user) +      first_status = insert(:note_activity, user: target_user) +      second_status = insert(:note_activity, user: target_user) + +      CommonAPI.report(reporter, %{ +        "account_id" => target_user.id, +        "comment" => "I feel offended", +        "status_ids" => [first_status.id] +      }) + +      CommonAPI.report(reporter, %{ +        "account_id" => target_user.id, +        "comment" => "I feel offended2", +        "status_ids" => [second_status.id] +      }) + +      data = [%{activity: first_status.data["id"]}, %{activity: second_status.data["id"]}] + +      {:ok, +       %{ +         first_status: first_status, +         second_status: second_status, +         data: data +       }} +    end + +    test "works for deprecated reports format", %{ +      first_status: first_status, +      second_status: second_status, +      data: data +    } do +      groups = Utils.get_reports_grouped_by_status(data).groups + +      first_group = Enum.find(groups, &(&1.status.id == first_status.data["id"])) +      second_group = Enum.find(groups, &(&1.status.id == second_status.data["id"])) + +      assert first_group.status.id == first_status.data["id"] +      assert second_group.status.id == second_status.data["id"] +    end +  end  end diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index 045c87e95..32577afee 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -225,7 +225,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do          "roles" => %{"admin" => false, "moderator" => false},          "tags" => [],          "avatar" => User.avatar_url(user) |> MediaProxy.url(), -        "display_name" => HTML.strip_tags(user.name || user.nickname) +        "display_name" => HTML.strip_tags(user.name || user.nickname), +        "confirmation_pending" => false        }        assert expected == json_response(conn, 200) @@ -634,7 +635,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do              "local" => true,              "tags" => [],              "avatar" => User.avatar_url(admin) |> MediaProxy.url(), -            "display_name" => HTML.strip_tags(admin.name || admin.nickname) +            "display_name" => HTML.strip_tags(admin.name || admin.nickname), +            "confirmation_pending" => false            },            %{              "deactivated" => user.deactivated, @@ -644,7 +646,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do              "local" => false,              "tags" => ["foo", "bar"],              "avatar" => User.avatar_url(user) |> MediaProxy.url(), -            "display_name" => HTML.strip_tags(user.name || user.nickname) +            "display_name" => HTML.strip_tags(user.name || user.nickname), +            "confirmation_pending" => false            }          ]          |> Enum.sort_by(& &1["nickname"]) @@ -685,7 +688,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do                     "local" => true,                     "tags" => [],                     "avatar" => User.avatar_url(user) |> MediaProxy.url(), -                   "display_name" => HTML.strip_tags(user.name || user.nickname) +                   "display_name" => HTML.strip_tags(user.name || user.nickname), +                   "confirmation_pending" => false                   }                 ]               } @@ -709,7 +713,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do                     "local" => true,                     "tags" => [],                     "avatar" => User.avatar_url(user) |> MediaProxy.url(), -                   "display_name" => HTML.strip_tags(user.name || user.nickname) +                   "display_name" => HTML.strip_tags(user.name || user.nickname), +                   "confirmation_pending" => false                   }                 ]               } @@ -733,7 +738,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do                     "local" => true,                     "tags" => [],                     "avatar" => User.avatar_url(user) |> MediaProxy.url(), -                   "display_name" => HTML.strip_tags(user.name || user.nickname) +                   "display_name" => HTML.strip_tags(user.name || user.nickname), +                   "confirmation_pending" => false                   }                 ]               } @@ -757,7 +763,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do                     "local" => true,                     "tags" => [],                     "avatar" => User.avatar_url(user) |> MediaProxy.url(), -                   "display_name" => HTML.strip_tags(user.name || user.nickname) +                   "display_name" => HTML.strip_tags(user.name || user.nickname), +                   "confirmation_pending" => false                   }                 ]               } @@ -781,7 +788,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do                     "local" => true,                     "tags" => [],                     "avatar" => User.avatar_url(user) |> MediaProxy.url(), -                   "display_name" => HTML.strip_tags(user.name || user.nickname) +                   "display_name" => HTML.strip_tags(user.name || user.nickname), +                   "confirmation_pending" => false                   }                 ]               } @@ -805,7 +813,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do                     "local" => true,                     "tags" => [],                     "avatar" => User.avatar_url(user) |> MediaProxy.url(), -                   "display_name" => HTML.strip_tags(user.name || user.nickname) +                   "display_name" => HTML.strip_tags(user.name || user.nickname), +                   "confirmation_pending" => false                   }                 ]               } @@ -824,7 +833,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do                     "local" => true,                     "tags" => [],                     "avatar" => User.avatar_url(user2) |> MediaProxy.url(), -                   "display_name" => HTML.strip_tags(user2.name || user2.nickname) +                   "display_name" => HTML.strip_tags(user2.name || user2.nickname), +                   "confirmation_pending" => false                   }                 ]               } @@ -853,7 +863,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do                     "local" => true,                     "tags" => [],                     "avatar" => User.avatar_url(user) |> MediaProxy.url(), -                   "display_name" => HTML.strip_tags(user.name || user.nickname) +                   "display_name" => HTML.strip_tags(user.name || user.nickname), +                   "confirmation_pending" => false                   }                 ]               } @@ -880,7 +891,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do              "local" => true,              "tags" => [],              "avatar" => User.avatar_url(user) |> MediaProxy.url(), -            "display_name" => HTML.strip_tags(user.name || user.nickname) +            "display_name" => HTML.strip_tags(user.name || user.nickname), +            "confirmation_pending" => false            },            %{              "deactivated" => admin.deactivated, @@ -890,7 +902,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do              "local" => true,              "tags" => [],              "avatar" => User.avatar_url(admin) |> MediaProxy.url(), -            "display_name" => HTML.strip_tags(admin.name || admin.nickname) +            "display_name" => HTML.strip_tags(admin.name || admin.nickname), +            "confirmation_pending" => false            },            %{              "deactivated" => false, @@ -900,7 +913,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do              "roles" => %{"admin" => true, "moderator" => false},              "tags" => [],              "avatar" => User.avatar_url(old_admin) |> MediaProxy.url(), -            "display_name" => HTML.strip_tags(old_admin.name || old_admin.nickname) +            "display_name" => HTML.strip_tags(old_admin.name || old_admin.nickname), +            "confirmation_pending" => false            }          ]          |> Enum.sort_by(& &1["nickname"]) @@ -929,7 +943,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do              "local" => admin.local,              "tags" => [],              "avatar" => User.avatar_url(admin) |> MediaProxy.url(), -            "display_name" => HTML.strip_tags(admin.name || admin.nickname) +            "display_name" => HTML.strip_tags(admin.name || admin.nickname), +            "confirmation_pending" => false            },            %{              "deactivated" => false, @@ -939,7 +954,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do              "local" => second_admin.local,              "tags" => [],              "avatar" => User.avatar_url(second_admin) |> MediaProxy.url(), -            "display_name" => HTML.strip_tags(second_admin.name || second_admin.nickname) +            "display_name" => HTML.strip_tags(second_admin.name || second_admin.nickname), +            "confirmation_pending" => false            }          ]          |> Enum.sort_by(& &1["nickname"]) @@ -970,7 +986,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do                     "local" => moderator.local,                     "tags" => [],                     "avatar" => User.avatar_url(moderator) |> MediaProxy.url(), -                   "display_name" => HTML.strip_tags(moderator.name || moderator.nickname) +                   "display_name" => HTML.strip_tags(moderator.name || moderator.nickname), +                   "confirmation_pending" => false                   }                 ]               } @@ -994,7 +1011,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do              "local" => user1.local,              "tags" => ["first"],              "avatar" => User.avatar_url(user1) |> MediaProxy.url(), -            "display_name" => HTML.strip_tags(user1.name || user1.nickname) +            "display_name" => HTML.strip_tags(user1.name || user1.nickname), +            "confirmation_pending" => false            },            %{              "deactivated" => false, @@ -1004,7 +1022,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do              "local" => user2.local,              "tags" => ["second"],              "avatar" => User.avatar_url(user2) |> MediaProxy.url(), -            "display_name" => HTML.strip_tags(user2.name || user2.nickname) +            "display_name" => HTML.strip_tags(user2.name || user2.nickname), +            "confirmation_pending" => false            }          ]          |> Enum.sort_by(& &1["nickname"]) @@ -1040,7 +1059,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do                     "local" => user.local,                     "tags" => [],                     "avatar" => User.avatar_url(user) |> MediaProxy.url(), -                   "display_name" => HTML.strip_tags(user.name || user.nickname) +                   "display_name" => HTML.strip_tags(user.name || user.nickname), +                   "confirmation_pending" => false                   }                 ]               } @@ -1066,7 +1086,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do                     "local" => true,                     "tags" => [],                     "avatar" => User.avatar_url(admin) |> MediaProxy.url(), -                   "display_name" => HTML.strip_tags(admin.name || admin.nickname) +                   "display_name" => HTML.strip_tags(admin.name || admin.nickname), +                   "confirmation_pending" => false                   }                 ]               } @@ -1135,7 +1156,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do                 "local" => true,                 "tags" => [],                 "avatar" => User.avatar_url(user) |> MediaProxy.url(), -               "display_name" => HTML.strip_tags(user.name || user.nickname) +               "display_name" => HTML.strip_tags(user.name || user.nickname), +               "confirmation_pending" => false               }      log_entry = Repo.one(ModerationLog) @@ -1312,7 +1334,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do      end    end -  describe "PUT /api/pleroma/admin/reports/:id" do +  describe "PATCH /api/pleroma/admin/reports" do      setup %{conn: conn} do        admin = insert(:user, is_admin: true)        [reporter, target_user] = insert_pair(:user) @@ -1325,16 +1347,32 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do            "status_ids" => [activity.id]          }) -      %{conn: assign(conn, :user, admin), id: report_id, admin: admin} +      {:ok, %{id: second_report_id}} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "comment" => "I feel very offended", +          "status_ids" => [activity.id] +        }) + +      %{ +        conn: assign(conn, :user, admin), +        id: report_id, +        admin: admin, +        second_report_id: second_report_id +      }      end      test "mark report as resolved", %{conn: conn, id: id, admin: admin} do -      response = -        conn -        |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "resolved"}) -        |> json_response(:ok) +      conn +      |> patch("/api/pleroma/admin/reports", %{ +        "reports" => [ +          %{"state" => "resolved", "id" => id} +        ] +      }) +      |> json_response(:no_content) -      assert response["state"] == "resolved" +      activity = Activity.get_by_id(id) +      assert activity.data["state"] == "resolved"        log_entry = Repo.one(ModerationLog) @@ -1343,12 +1381,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do      end      test "closes report", %{conn: conn, id: id, admin: admin} do -      response = -        conn -        |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "closed"}) -        |> json_response(:ok) +      conn +      |> patch("/api/pleroma/admin/reports", %{ +        "reports" => [ +          %{"state" => "closed", "id" => id} +        ] +      }) +      |> json_response(:no_content) -      assert response["state"] == "closed" +      activity = Activity.get_by_id(id) +      assert activity.data["state"] == "closed"        log_entry = Repo.one(ModerationLog) @@ -1359,17 +1401,54 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do      test "returns 400 when state is unknown", %{conn: conn, id: id} do        conn =          conn -        |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "test"}) +        |> patch("/api/pleroma/admin/reports", %{ +          "reports" => [ +            %{"state" => "test", "id" => id} +          ] +        }) -      assert json_response(conn, :bad_request) == "Unsupported state" +      assert hd(json_response(conn, :bad_request))["error"] == "Unsupported state"      end      test "returns 404 when report is not exist", %{conn: conn} do        conn =          conn -        |> put("/api/pleroma/admin/reports/test", %{"state" => "closed"}) +        |> patch("/api/pleroma/admin/reports", %{ +          "reports" => [ +            %{"state" => "closed", "id" => "test"} +          ] +        }) -      assert json_response(conn, :not_found) == "Not found" +      assert hd(json_response(conn, :bad_request))["error"] == "not_found" +    end + +    test "updates state of multiple reports", %{ +      conn: conn, +      id: id, +      admin: admin, +      second_report_id: second_report_id +    } do +      conn +      |> patch("/api/pleroma/admin/reports", %{ +        "reports" => [ +          %{"state" => "resolved", "id" => id}, +          %{"state" => "closed", "id" => second_report_id} +        ] +      }) +      |> json_response(:no_content) + +      activity = Activity.get_by_id(id) +      second_activity = Activity.get_by_id(second_report_id) +      assert activity.data["state"] == "resolved" +      assert second_activity.data["state"] == "closed" + +      [first_log_entry, second_log_entry] = Repo.all(ModerationLog) + +      assert ModerationLog.get_log_entry_message(first_log_entry) == +               "@#{admin.nickname} updated report ##{id} with 'resolved' state" + +      assert ModerationLog.get_log_entry_message(second_log_entry) == +               "@#{admin.nickname} updated report ##{second_report_id} with 'closed' state"      end    end @@ -1492,7 +1571,145 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do      end    end -  # +  describe "GET /api/pleroma/admin/grouped_reports" do +    setup %{conn: conn} do +      admin = insert(:user, is_admin: true) +      [reporter, target_user] = insert_pair(:user) + +      date1 = (DateTime.to_unix(DateTime.utc_now()) + 1000) |> DateTime.from_unix!() +      date2 = (DateTime.to_unix(DateTime.utc_now()) + 2000) |> DateTime.from_unix!() +      date3 = (DateTime.to_unix(DateTime.utc_now()) + 3000) |> DateTime.from_unix!() + +      first_status = +        insert(:note_activity, user: target_user, data_attrs: %{"published" => date1}) + +      second_status = +        insert(:note_activity, user: target_user, data_attrs: %{"published" => date2}) + +      third_status = +        insert(:note_activity, user: target_user, data_attrs: %{"published" => date3}) + +      {:ok, first_report} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "status_ids" => [first_status.id, second_status.id, third_status.id] +        }) + +      {:ok, second_report} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "status_ids" => [first_status.id, second_status.id] +        }) + +      {:ok, third_report} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "status_ids" => [first_status.id] +        }) + +      %{ +        conn: assign(conn, :user, admin), +        first_status: Activity.get_by_ap_id_with_object(first_status.data["id"]), +        second_status: Activity.get_by_ap_id_with_object(second_status.data["id"]), +        third_status: Activity.get_by_ap_id_with_object(third_status.data["id"]), +        first_status_reports: [first_report, second_report, third_report], +        second_status_reports: [first_report, second_report], +        third_status_reports: [first_report], +        target_user: target_user, +        reporter: reporter +      } +    end + +    test "returns reports grouped by status", %{ +      conn: conn, +      first_status: first_status, +      second_status: second_status, +      third_status: third_status, +      first_status_reports: first_status_reports, +      second_status_reports: second_status_reports, +      third_status_reports: third_status_reports, +      target_user: target_user, +      reporter: reporter +    } do +      response = +        conn +        |> get("/api/pleroma/admin/grouped_reports") +        |> json_response(:ok) + +      assert length(response["reports"]) == 3 + +      first_group = +        Enum.find(response["reports"], &(&1["status"]["id"] == first_status.data["id"])) + +      second_group = +        Enum.find(response["reports"], &(&1["status"]["id"] == second_status.data["id"])) + +      third_group = +        Enum.find(response["reports"], &(&1["status"]["id"] == third_status.data["id"])) + +      assert length(first_group["reports"]) == 3 +      assert length(second_group["reports"]) == 2 +      assert length(third_group["reports"]) == 1 + +      assert first_group["date"] == +               Enum.max_by(first_status_reports, fn act -> +                 NaiveDateTime.from_iso8601!(act.data["published"]) +               end).data["published"] + +      assert first_group["status"] == %{ +               "id" => first_status.data["id"], +               "content" => first_status.object.data["content"], +               "published" => first_status.object.data["published"] +             } + +      assert first_group["account"]["id"] == target_user.id + +      assert length(first_group["actors"]) == 1 +      assert hd(first_group["actors"])["id"] == reporter.id + +      assert Enum.map(first_group["reports"], & &1["id"]) -- +               Enum.map(first_status_reports, & &1.id) == [] + +      assert second_group["date"] == +               Enum.max_by(second_status_reports, fn act -> +                 NaiveDateTime.from_iso8601!(act.data["published"]) +               end).data["published"] + +      assert second_group["status"] == %{ +               "id" => second_status.data["id"], +               "content" => second_status.object.data["content"], +               "published" => second_status.object.data["published"] +             } + +      assert second_group["account"]["id"] == target_user.id + +      assert length(second_group["actors"]) == 1 +      assert hd(second_group["actors"])["id"] == reporter.id + +      assert Enum.map(second_group["reports"], & &1["id"]) -- +               Enum.map(second_status_reports, & &1.id) == [] + +      assert third_group["date"] == +               Enum.max_by(third_status_reports, fn act -> +                 NaiveDateTime.from_iso8601!(act.data["published"]) +               end).data["published"] + +      assert third_group["status"] == %{ +               "id" => third_status.data["id"], +               "content" => third_status.object.data["content"], +               "published" => third_status.object.data["published"] +             } + +      assert third_group["account"]["id"] == target_user.id + +      assert length(third_group["actors"]) == 1 +      assert hd(third_group["actors"])["id"] == reporter.id + +      assert Enum.map(third_group["reports"], & &1["id"]) -- +               Enum.map(third_status_reports, & &1.id) == [] +    end +  end +    describe "POST /api/pleroma/admin/reports/:id/respond" do      setup %{conn: conn} do        admin = insert(:user, is_admin: true) @@ -1706,6 +1923,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do        Pleroma.Config.put([:instance, :dynamic_configuration], true)      end +    @tag capture_log: true      test "create new config setting in db", %{conn: conn} do        conn =          post(conn, "/api/pleroma/admin/config", %{ @@ -2269,6 +2487,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do        Pleroma.Config.put([:instance, :dynamic_configuration], true)      end +    clear_config([:feed, :post_title]) do +      Pleroma.Config.put([:feed, :post_title], %{max_length: 100, omission: "…"}) +    end +      test "transfer settings to DB and to file", %{conn: conn, admin: admin} do        assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == []        conn = get(conn, "/api/pleroma/admin/config/migrate_to_db") @@ -2565,7 +2787,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do        conn =          build_conn()          |> assign(:user, admin) -        |> patch("/api/pleroma/admin/users/#{user.nickname}/force_password_reset") +        |> patch("/api/pleroma/admin/users/force_password_reset", %{nicknames: [user.nickname]})        assert json_response(conn, 204) == "" @@ -2640,6 +2862,105 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do                 "@#{admin.nickname} unfollowed relay: http://mastodon.example.org/users/admin"      end    end + +  describe "instances" do +    test "GET /instances/:instance/statuses" do +      admin = insert(:user, is_admin: true) +      user = insert(:user, local: false, nickname: "archaeme@archae.me") +      user2 = insert(:user, local: false, nickname: "test@test.com") +      insert_pair(:note_activity, user: user) +      insert(:note_activity, user: user2) + +      conn = +        build_conn() +        |> assign(:user, admin) +        |> get("/api/pleroma/admin/instances/archae.me/statuses") + +      response = json_response(conn, 200) + +      assert length(response) == 2 + +      conn = +        build_conn() +        |> assign(:user, admin) +        |> get("/api/pleroma/admin/instances/test.com/statuses") + +      response = json_response(conn, 200) + +      assert length(response) == 1 + +      conn = +        build_conn() +        |> assign(:user, admin) +        |> get("/api/pleroma/admin/instances/nonexistent.com/statuses") + +      response = json_response(conn, 200) + +      assert length(response) == 0 +    end +  end + +  describe "PATCH /confirm_email" do +    setup %{conn: conn} do +      admin = insert(:user, is_admin: true) + +      %{conn: assign(conn, :user, admin), admin: admin} +    end + +    test "it confirms emails of two users", %{admin: admin} do +      [first_user, second_user] = insert_pair(:user, confirmation_pending: true) + +      assert first_user.confirmation_pending == true +      assert second_user.confirmation_pending == true + +      build_conn() +      |> assign(:user, admin) +      |> patch("/api/pleroma/admin/users/confirm_email", %{ +        nicknames: [ +          first_user.nickname, +          second_user.nickname +        ] +      }) + +      assert first_user.confirmation_pending == true +      assert second_user.confirmation_pending == true + +      log_entry = Repo.one(ModerationLog) + +      assert ModerationLog.get_log_entry_message(log_entry) == +               "@#{admin.nickname} confirmed email for users: @#{first_user.nickname}, @#{ +                 second_user.nickname +               }" +    end +  end + +  describe "PATCH /resend_confirmation_email" do +    setup %{conn: conn} do +      admin = insert(:user, is_admin: true) + +      %{conn: assign(conn, :user, admin), admin: admin} +    end + +    test "it resend emails for two users", %{admin: admin} do +      [first_user, second_user] = insert_pair(:user, confirmation_pending: true) + +      build_conn() +      |> assign(:user, admin) +      |> patch("/api/pleroma/admin/users/resend_confirmation_email", %{ +        nicknames: [ +          first_user.nickname, +          second_user.nickname +        ] +      }) + +      log_entry = Repo.one(ModerationLog) + +      assert ModerationLog.get_log_entry_message(log_entry) == +               "@#{admin.nickname} re-sent confirmation email for users: @#{first_user.nickname}, @#{ +                 second_user.nickname +               }" +    end +  end  end  # Needed for testing diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs index 5e5d46847..d641f7478 100644 --- a/test/web/common_api/common_api_test.exs +++ b/test/web/common_api/common_api_test.exs @@ -228,6 +228,33 @@ defmodule Pleroma.Web.CommonAPITest do    end    describe "reactions" do +    test "reacting to a status with an emoji" do +      user = insert(:user) +      other_user = insert(:user) + +      {:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"}) + +      {:ok, reaction, _} = CommonAPI.react_with_emoji(activity.id, user, "👍") + +      assert reaction.data["actor"] == user.ap_id +      assert reaction.data["content"] == "👍" + +      # TODO: test error case. +    end + +    test "unreacting to a status with an emoji" do +      user = insert(:user) +      other_user = insert(:user) + +      {:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"}) +      {:ok, reaction, _} = CommonAPI.react_with_emoji(activity.id, user, "👍") + +      {:ok, unreaction, _} = CommonAPI.unreact_with_emoji(activity.id, user, "👍") + +      assert unreaction.data["type"] == "Undo" +      assert unreaction.data["object"] == reaction.data["id"] +    end +      test "repeating a status" do        user = insert(:user)        other_user = insert(:user) @@ -448,6 +475,35 @@ defmodule Pleroma.Web.CommonAPITest do        assert CommonAPI.update_report_state(report_id, "test") == {:error, "Unsupported state"}      end + +    test "updates state of multiple reports" do +      [reporter, target_user] = insert_pair(:user) +      activity = insert(:note_activity, user: target_user) + +      {:ok, %Activity{id: first_report_id}} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "comment" => "I feel offended", +          "status_ids" => [activity.id] +        }) + +      {:ok, %Activity{id: second_report_id}} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "comment" => "I feel very offended!", +          "status_ids" => [activity.id] +        }) + +      {:ok, report_ids} = +        CommonAPI.update_report_state([first_report_id, second_report_id], "resolved") + +      first_report = Activity.get_by_id(first_report_id) +      second_report = Activity.get_by_id(second_report_id) + +      assert report_ids -- [first_report_id, second_report_id] == [] +      assert first_report.data["state"] == "resolved" +      assert second_report.data["state"] == "resolved" +    end    end    describe "reblog muting" do diff --git a/test/web/feed/feed_controller_test.exs b/test/web/feed/feed_controller_test.exs index 1f44eae20..6f61acf43 100644 --- a/test/web/feed/feed_controller_test.exs +++ b/test/web/feed/feed_controller_test.exs @@ -6,16 +6,25 @@ defmodule Pleroma.Web.Feed.FeedControllerTest do    use Pleroma.Web.ConnCase    import Pleroma.Factory +  import SweetXml    alias Pleroma.Object    alias Pleroma.User +  clear_config([:feed]) +    test "gets a feed", %{conn: conn} do +    Pleroma.Config.put( +      [:feed, :post_title], +      %{max_length: 10, omission: "..."} +    ) +      activity = insert(:note_activity)      note =        insert(:note,          data: %{ +          "content" => "This is :moominmamma: note ",            "attachment" => [              %{                "url" => [%{"mediaType" => "image/png", "href" => "https://pleroma.gov/image.png"}] @@ -26,15 +35,30 @@ defmodule Pleroma.Web.Feed.FeedControllerTest do        )      note_activity = insert(:note_activity, note: note) -    object = Object.normalize(note_activity)      user = User.get_cached_by_ap_id(note_activity.data["actor"]) -    conn = +    note2 = +      insert(:note, +        user: user, +        data: %{"content" => "42 This is :moominmamma: note ", "inReplyTo" => activity.data["id"]} +      ) + +    _note_activity2 = insert(:note_activity, note: note2) +    object = Object.normalize(note_activity) + +    resp =        conn        |> put_req_header("content-type", "application/atom+xml")        |> get("/users/#{user.nickname}/feed.atom") +      |> response(200) + +    activity_titles = +      resp +      |> SweetXml.parse() +      |> SweetXml.xpath(~x"//entry/title/text()"l) -    assert response(conn, 200) =~ object.data["content"] +    assert activity_titles == ['42 This...', 'This is...'] +    assert resp =~ object.data["content"]    end    test "returns 404 for a missing feed", %{conn: conn} do diff --git a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs index 519b56d6c..77cfce4fa 100644 --- a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs +++ b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs @@ -103,6 +103,21 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do        assert user["locked"] == true      end +    test "updates the user's allow_following_move", %{conn: conn} do +      user = insert(:user) + +      assert user.allow_following_move == true + +      conn = +        conn +        |> assign(:user, user) +        |> patch("/api/v1/accounts/update_credentials", %{allow_following_move: "false"}) + +      assert refresh_record(user).allow_following_move == false +      assert user = json_response(conn, 200) +      assert user["pleroma"]["allow_following_move"] == false +    end +      test "updates the user's default scope", %{conn: conn} do        user = insert(:user) diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs index 8fc2d9300..585cb8a9e 100644 --- a/test/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/web/mastodon_api/controllers/account_controller_test.exs @@ -8,6 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do    alias Pleroma.Repo    alias Pleroma.User    alias Pleroma.Web.ActivityPub.ActivityPub +  alias Pleroma.Web.ActivityPub.InternalFetchActor    alias Pleroma.Web.CommonAPI    alias Pleroma.Web.OAuth.Token @@ -118,6 +119,28 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do        refute acc_one == acc_two        assert acc_two == acc_three      end + +    test "returns 404 when user is invisible", %{conn: conn} do +      user = insert(:user, %{invisible: true}) + +      resp = +        conn +        |> get("/api/v1/accounts/#{user.nickname}") +        |> json_response(404) + +      assert %{"error" => "Can't find user"} = resp +    end + +    test "returns 404 for internal.fetch actor", %{conn: conn} do +      %User{nickname: "internal.fetch"} = InternalFetchActor.get_actor() + +      resp = +        conn +        |> get("/api/v1/accounts/internal.fetch") +        |> json_response(404) + +      assert %{"error" => "Can't find user"} = resp +    end    end    describe "user timelines" do diff --git a/test/web/mastodon_api/controllers/conversation_controller_test.exs b/test/web/mastodon_api/controllers/conversation_controller_test.exs index 542af4944..2a1223b18 100644 --- a/test/web/mastodon_api/controllers/conversation_controller_test.exs +++ b/test/web/mastodon_api/controllers/conversation_controller_test.exs @@ -59,6 +59,59 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do      assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0    end +  test "filters conversations by recipients", %{conn: conn} do +    user_one = insert(:user) +    user_two = insert(:user) +    user_three = insert(:user) + +    {:ok, direct1} = +      CommonAPI.post(user_one, %{ +        "status" => "Hi @#{user_two.nickname}!", +        "visibility" => "direct" +      }) + +    {:ok, _direct2} = +      CommonAPI.post(user_one, %{ +        "status" => "Hi @#{user_three.nickname}!", +        "visibility" => "direct" +      }) + +    {:ok, direct3} = +      CommonAPI.post(user_one, %{ +        "status" => "Hi @#{user_two.nickname}, @#{user_three.nickname}!", +        "visibility" => "direct" +      }) + +    {:ok, _direct4} = +      CommonAPI.post(user_two, %{ +        "status" => "Hi @#{user_three.nickname}!", +        "visibility" => "direct" +      }) + +    {:ok, direct5} = +      CommonAPI.post(user_two, %{ +        "status" => "Hi @#{user_one.nickname}!", +        "visibility" => "direct" +      }) + +    [conversation1, conversation2] = +      conn +      |> assign(:user, user_one) +      |> get("/api/v1/conversations", %{"recipients" => [user_two.id]}) +      |> json_response(200) + +    assert conversation1["last_status"]["id"] == direct5.id +    assert conversation2["last_status"]["id"] == direct1.id + +    [conversation1] = +      conn +      |> assign(:user, user_one) +      |> get("/api/v1/conversations", %{"recipients" => [user_two.id, user_three.id]}) +      |> json_response(200) + +    assert conversation1["last_status"]["id"] == direct3.id +  end +    test "updates the last_status on reply", %{conn: conn} do      user_one = insert(:user)      user_two = insert(:user) diff --git a/test/web/mastodon_api/controllers/filter_controller_test.exs b/test/web/mastodon_api/controllers/filter_controller_test.exs index 5d5b56c8e..550689788 100644 --- a/test/web/mastodon_api/controllers/filter_controller_test.exs +++ b/test/web/mastodon_api/controllers/filter_controller_test.exs @@ -3,7 +3,7 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do -  use Pleroma.Web.ConnCase, async: true +  use Pleroma.Web.ConnCase    alias Pleroma.Web.MastodonAPI.FilterView diff --git a/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs b/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs index 9ad6a4fa7..ae5fee2bc 100644 --- a/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs +++ b/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs @@ -3,7 +3,7 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do -  use Pleroma.Web.ConnCase, async: true +  use Pleroma.Web.ConnCase    alias Pleroma.Repo    alias Pleroma.ScheduledActivity diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/web/mastodon_api/views/account_view_test.exs index af88841ed..35aefb7dc 100644 --- a/test/web/mastodon_api/views/account_view_test.exs +++ b/test/web/mastodon_api/views/account_view_test.exs @@ -102,7 +102,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do      privacy = user.default_scope      assert %{ -             pleroma: %{notification_settings: ^notification_settings}, +             pleroma: %{notification_settings: ^notification_settings, allow_following_move: true},               source: %{privacy: ^privacy}             } = AccountView.render("show.json", %{user: user, for: user})    end @@ -350,7 +350,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do        }      } -    assert expected == AccountView.render("show.json", %{user: user, for: other_user}) +    assert expected == +             AccountView.render("show.json", %{user: refresh_record(user), for: other_user})    end    test "returns the settings store if the requesting user is the represented user and it's requested specifically" do @@ -374,6 +375,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do      refute result.display_name == "<marquee> username </marquee>"    end +  test "never display nil user follow counts" do +    user = insert(:user, following_count: 0, follower_count: 0) +    result = AccountView.render("show.json", %{user: user}) + +    assert result.following_count == 0 +    assert result.followers_count == 0 +  end +    describe "hiding follows/following" do      test "shows when follows/followers stats are hidden and sets follow/follower count to 0" do        user = diff --git a/test/web/mastodon_api/views/notification_view_test.exs b/test/web/mastodon_api/views/notification_view_test.exs index d06809268..a741cc014 100644 --- a/test/web/mastodon_api/views/notification_view_test.exs +++ b/test/web/mastodon_api/views/notification_view_test.exs @@ -107,4 +107,31 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do      assert [] ==               NotificationView.render("index.json", %{notifications: [notification], for: followed})    end + +  test "Move notification" do +    %{ap_id: old_ap_id} = old_user = insert(:user) +    %{ap_id: _new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id]) +    follower = insert(:user) + +    User.follow(follower, old_user) +    Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user) +    Pleroma.Tests.ObanHelpers.perform_all() + +    old_user = refresh_record(old_user) +    new_user = refresh_record(new_user) + +    [notification] = Notification.for_user(follower) + +    expected = %{ +      id: to_string(notification.id), +      pleroma: %{is_seen: false}, +      type: "move", +      account: AccountView.render("show.json", %{user: old_user, for: follower}), +      target: AccountView.render("show.json", %{user: new_user, for: follower}), +      created_at: Utils.to_masto_date(notification.inserted_at) +    } + +    assert [expected] == +             NotificationView.render("index.json", %{notifications: [notification], for: follower}) +  end  end diff --git a/test/web/node_info_test.exs b/test/web/node_info_test.exs index a3281b25b..9a574a38d 100644 --- a/test/web/node_info_test.exs +++ b/test/web/node_info_test.exs @@ -61,6 +61,33 @@ defmodule Pleroma.Web.NodeInfoTest do      assert Pleroma.Application.repository() == result["software"]["repository"]    end +  test "returns fieldsLimits field", %{conn: conn} do +    max_account_fields = Pleroma.Config.get([:instance, :max_account_fields]) +    max_remote_account_fields = Pleroma.Config.get([:instance, :max_remote_account_fields]) +    account_field_name_length = Pleroma.Config.get([:instance, :account_field_name_length]) +    account_field_value_length = Pleroma.Config.get([:instance, :account_field_value_length]) + +    Pleroma.Config.put([:instance, :max_account_fields], 10) +    Pleroma.Config.put([:instance, :max_remote_account_fields], 15) +    Pleroma.Config.put([:instance, :account_field_name_length], 255) +    Pleroma.Config.put([:instance, :account_field_value_length], 2048) + +    response = +      conn +      |> get("/nodeinfo/2.1.json") +      |> json_response(:ok) + +    assert response["metadata"]["fieldsLimits"]["maxFields"] == 10 +    assert response["metadata"]["fieldsLimits"]["maxRemoteFields"] == 15 +    assert response["metadata"]["fieldsLimits"]["nameLength"] == 255 +    assert response["metadata"]["fieldsLimits"]["valueLength"] == 2048 + +    Pleroma.Config.put([:instance, :max_account_fields], max_account_fields) +    Pleroma.Config.put([:instance, :max_remote_account_fields], max_remote_account_fields) +    Pleroma.Config.put([:instance, :account_field_name_length], account_field_name_length) +    Pleroma.Config.put([:instance, :account_field_value_length], account_field_value_length) +  end +    test "it returns the safe_dm_mentions feature if enabled", %{conn: conn} do      option = Pleroma.Config.get([:instance, :safe_dm_mentions])      Pleroma.Config.put([:instance, :safe_dm_mentions], true) @@ -84,6 +111,30 @@ defmodule Pleroma.Web.NodeInfoTest do      Pleroma.Config.put([:instance, :safe_dm_mentions], option)    end +  test "it shows if federation is enabled/disabled", %{conn: conn} do +    original = Pleroma.Config.get([:instance, :federating]) + +    Pleroma.Config.put([:instance, :federating], true) + +    response = +      conn +      |> get("/nodeinfo/2.1.json") +      |> json_response(:ok) + +    assert response["metadata"]["federation"]["enabled"] == true + +    Pleroma.Config.put([:instance, :federating], false) + +    response = +      conn +      |> get("/nodeinfo/2.1.json") +      |> json_response(:ok) + +    assert response["metadata"]["federation"]["enabled"] == false + +    Pleroma.Config.put([:instance, :federating], original) +  end +    test "it shows MRF transparency data if enabled", %{conn: conn} do      config = Pleroma.Config.get([:instance, :rewrite_policy])      Pleroma.Config.put([:instance, :rewrite_policy], [Pleroma.Web.ActivityPub.MRF.SimplePolicy]) diff --git a/test/web/oauth/oauth_controller_test.exs b/test/web/oauth/oauth_controller_test.exs index ad8d79083..beb995cd8 100644 --- a/test/web/oauth/oauth_controller_test.exs +++ b/test/web/oauth/oauth_controller_test.exs @@ -469,6 +469,29 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do        assert html_response(conn, 200) =~ ~s(type="submit")      end +    test "renders authentication page if user is already authenticated but user request with another client", +         %{ +           app: app, +           conn: conn +         } do +      token = insert(:oauth_token, app_id: app.id) + +      conn = +        conn +        |> put_session(:oauth_token, token.token) +        |> get( +          "/oauth/authorize", +          %{ +            "response_type" => "code", +            "client_id" => "another_client_id", +            "redirect_uri" => OAuthController.default_redirect_uri(app), +            "scope" => "read" +          } +        ) + +      assert html_response(conn, 200) =~ ~s(type="submit") +    end +      test "with existing authentication and non-OOB `redirect_uri`, redirects to app with `token` and `state` params",           %{             app: app, diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs index 60090c1eb..567aabbf1 100644 --- a/test/web/ostatus/ostatus_controller_test.exs +++ b/test/web/ostatus/ostatus_controller_test.exs @@ -35,23 +35,6 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do        assert redirected_to(conn) == "/notice/#{note_activity.id}"      end -    test "500s when user not found", %{conn: conn} do -      note_activity = insert(:note_activity) -      object = Object.normalize(note_activity) -      user = User.get_cached_by_ap_id(note_activity.data["actor"]) -      User.invalidate_cache(user) -      Pleroma.Repo.delete(user) -      [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"])) -      url = "/objects/#{uuid}" - -      conn = -        conn -        |> put_req_header("accept", "application/xml") -        |> get(url) - -      assert response(conn, 500) == ~S({"error":"Something went wrong"}) -    end -      test "404s on private objects", %{conn: conn} do        note_activity = insert(:direct_note_activity)        object = Object.normalize(note_activity) @@ -82,21 +65,6 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do        assert redirected_to(conn) == "/notice/#{note_activity.id}"      end -    test "505s when user not found", %{conn: conn} do -      note_activity = insert(:note_activity) -      [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) -      user = User.get_cached_by_ap_id(note_activity.data["actor"]) -      User.invalidate_cache(user) -      Pleroma.Repo.delete(user) - -      conn = -        conn -        |> put_req_header("accept", "text/html") -        |> get("/activities/#{uuid}") - -      assert response(conn, 500) == ~S({"error":"Something went wrong"}) -    end -      test "404s on private activities", %{conn: conn} do        note_activity = insert(:direct_note_activity)        [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) @@ -127,21 +95,28 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do    end    describe "GET notice/2" do -    test "gets a notice in xml format", %{conn: conn} do +    test "redirects to a proper object URL when json requested and the object is local", %{ +      conn: conn +    } do        note_activity = insert(:note_activity) +      expected_redirect_url = Object.normalize(note_activity).data["id"] -      conn -      |> get("/notice/#{note_activity.id}") -      |> response(200) +      redirect_url = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get("/notice/#{note_activity.id}") +        |> redirected_to() + +      assert redirect_url == expected_redirect_url      end -    test "gets a notice in AS2 format", %{conn: conn} do -      note_activity = insert(:note_activity) +    test "returns a 404 on remote notice when json requested", %{conn: conn} do +      note_activity = insert(:note_activity, local: false)        conn        |> put_req_header("accept", "application/activity+json")        |> get("/notice/#{note_activity.id}") -      |> json_response(200) +      |> response(404)      end      test "500s when actor not found", %{conn: conn} do @@ -157,32 +132,6 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do        assert response(conn, 500) == ~S({"error":"Something went wrong"})      end -    test "only gets a notice in AS2 format for Create messages", %{conn: conn} do -      note_activity = insert(:note_activity) -      url = "/notice/#{note_activity.id}" - -      conn = -        conn -        |> put_req_header("accept", "application/activity+json") -        |> get(url) - -      assert json_response(conn, 200) - -      user = insert(:user) - -      {:ok, like_activity} = CommonAPI.favorite(user, note_activity.id) -      url = "/notice/#{like_activity.id}" - -      assert like_activity.data["type"] == "Like" - -      conn = -        build_conn() -        |> put_req_header("accept", "application/activity+json") -        |> get(url) - -      assert response(conn, 404) -    end -      test "render html for redirect for html format", %{conn: conn} do        note_activity = insert(:note_activity) diff --git a/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs b/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs index 0c83edb56..b1b59beed 100644 --- a/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs +++ b/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs @@ -7,12 +7,72 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do    alias Pleroma.Conversation.Participation    alias Pleroma.Notification +  alias Pleroma.Object    alias Pleroma.Repo    alias Pleroma.User    alias Pleroma.Web.CommonAPI    import Pleroma.Factory +  test "POST /api/v1/pleroma/statuses/:id/react_with_emoji", %{conn: conn} do +    user = insert(:user) +    other_user = insert(:user) + +    {:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"}) + +    result = +      conn +      |> assign(:user, other_user) +      |> post("/api/v1/pleroma/statuses/#{activity.id}/react_with_emoji", %{"emoji" => "☕"}) + +    assert %{"id" => id} = json_response(result, 200) +    assert to_string(activity.id) == id +  end + +  test "POST /api/v1/pleroma/statuses/:id/unreact_with_emoji", %{conn: conn} do +    user = insert(:user) +    other_user = insert(:user) + +    {:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"}) +    {:ok, activity, _object} = CommonAPI.react_with_emoji(activity.id, other_user, "☕") + +    result = +      conn +      |> assign(:user, other_user) +      |> post("/api/v1/pleroma/statuses/#{activity.id}/unreact_with_emoji", %{"emoji" => "☕"}) + +    assert %{"id" => id} = json_response(result, 200) +    assert to_string(activity.id) == id + +    object = Object.normalize(activity) + +    assert object.data["reaction_count"] == 0 +  end + +  test "GET /api/v1/pleroma/statuses/:id/emoji_reactions_by", %{conn: conn} do +    user = insert(:user) +    other_user = insert(:user) + +    {:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"}) + +    result = +      conn +      |> get("/api/v1/pleroma/statuses/#{activity.id}/emoji_reactions_by") +      |> json_response(200) + +    assert result == %{} + +    {:ok, _, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅") + +    result = +      conn +      |> get("/api/v1/pleroma/statuses/#{activity.id}/emoji_reactions_by") +      |> json_response(200) + +    [represented_user] = result["🎅"] +    assert represented_user["id"] == other_user.id +  end +    test "/api/v1/pleroma/conversations/:id", %{conn: conn} do      user = insert(:user)      other_user = insert(:user) diff --git a/test/web/static_fe/static_fe_controller_test.exs b/test/web/static_fe/static_fe_controller_test.exs new file mode 100644 index 000000000..2ce8f9fa3 --- /dev/null +++ b/test/web/static_fe/static_fe_controller_test.exs @@ -0,0 +1,210 @@ +defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do +  use Pleroma.Web.ConnCase +  alias Pleroma.Activity +  alias Pleroma.Web.ActivityPub.Transmogrifier +  alias Pleroma.Web.CommonAPI + +  import Pleroma.Factory + +  clear_config_all([:static_fe, :enabled]) do +    Pleroma.Config.put([:static_fe, :enabled], true) +  end + +  describe "user profile page" do +    test "just the profile as HTML", %{conn: conn} do +      user = insert(:user) + +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/users/#{user.nickname}") + +      assert html_response(conn, 200) =~ user.nickname +    end + +    test "renders json unless there's an html accept header", %{conn: conn} do +      user = insert(:user) + +      conn = +        conn +        |> put_req_header("accept", "application/json") +        |> get("/users/#{user.nickname}") + +      assert json_response(conn, 200) +    end + +    test "404 when user not found", %{conn: conn} do +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/users/limpopo") + +      assert html_response(conn, 404) =~ "not found" +    end + +    test "profile does not include private messages", %{conn: conn} do +      user = insert(:user) +      CommonAPI.post(user, %{"status" => "public"}) +      CommonAPI.post(user, %{"status" => "private", "visibility" => "private"}) + +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/users/#{user.nickname}") + +      html = html_response(conn, 200) + +      assert html =~ ">public<" +      refute html =~ ">private<" +    end + +    test "pagination", %{conn: conn} do +      user = insert(:user) +      Enum.map(1..30, fn i -> CommonAPI.post(user, %{"status" => "test#{i}"}) end) + +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/users/#{user.nickname}") + +      html = html_response(conn, 200) + +      assert html =~ ">test30<" +      assert html =~ ">test11<" +      refute html =~ ">test10<" +      refute html =~ ">test1<" +    end + +    test "pagination, page 2", %{conn: conn} do +      user = insert(:user) +      activities = Enum.map(1..30, fn i -> CommonAPI.post(user, %{"status" => "test#{i}"}) end) +      {:ok, a11} = Enum.at(activities, 11) + +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/users/#{user.nickname}?max_id=#{a11.id}") + +      html = html_response(conn, 200) + +      assert html =~ ">test1<" +      assert html =~ ">test10<" +      refute html =~ ">test20<" +      refute html =~ ">test29<" +    end +  end + +  describe "notice rendering" do +    test "single notice page", %{conn: conn} do +      user = insert(:user) +      {:ok, activity} = CommonAPI.post(user, %{"status" => "testing a thing!"}) + +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/notice/#{activity.id}") + +      html = html_response(conn, 200) +      assert html =~ "<header>" +      assert html =~ user.nickname +      assert html =~ "testing a thing!" +    end + +    test "shows the whole thread", %{conn: conn} do +      user = insert(:user) +      {:ok, activity} = CommonAPI.post(user, %{"status" => "space: the final frontier"}) + +      CommonAPI.post(user, %{ +        "status" => "these are the voyages or something", +        "in_reply_to_status_id" => activity.id +      }) + +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/notice/#{activity.id}") + +      html = html_response(conn, 200) +      assert html =~ "the final frontier" +      assert html =~ "voyages" +    end + +    test "redirect by AP object ID", %{conn: conn} do +      user = insert(:user) + +      {:ok, %Activity{data: %{"object" => object_url}}} = +        CommonAPI.post(user, %{"status" => "beam me up"}) + +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get(URI.parse(object_url).path) + +      assert html_response(conn, 302) =~ "redirected" +    end + +    test "redirect by activity ID", %{conn: conn} do +      user = insert(:user) + +      {:ok, %Activity{data: %{"id" => id}}} = +        CommonAPI.post(user, %{"status" => "I'm a doctor, not a devops!"}) + +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get(URI.parse(id).path) + +      assert html_response(conn, 302) =~ "redirected" +    end + +    test "404 when notice not found", %{conn: conn} do +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/notice/88c9c317") + +      assert html_response(conn, 404) =~ "not found" +    end + +    test "404 for private status", %{conn: conn} do +      user = insert(:user) + +      {:ok, activity} = +        CommonAPI.post(user, %{"status" => "don't show me!", "visibility" => "private"}) + +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/notice/#{activity.id}") + +      assert html_response(conn, 404) =~ "not found" +    end + +    test "302 for remote cached status", %{conn: conn} do +      user = insert(:user) + +      message = %{ +        "@context" => "https://www.w3.org/ns/activitystreams", +        "to" => user.follower_address, +        "cc" => "https://www.w3.org/ns/activitystreams#Public", +        "type" => "Create", +        "object" => %{ +          "content" => "blah blah blah", +          "type" => "Note", +          "attributedTo" => user.ap_id, +          "inReplyTo" => nil +        }, +        "actor" => user.ap_id +      } + +      assert {:ok, activity} = Transmogrifier.handle_incoming(message) + +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/notice/#{activity.id}") + +      assert html_response(conn, 302) =~ "redirected" +    end +  end +end diff --git a/test/web/streamer/streamer_test.exs b/test/web/streamer/streamer_test.exs index 3a14d12f0..5a5b35147 100644 --- a/test/web/streamer/streamer_test.exs +++ b/test/web/streamer/streamer_test.exs @@ -15,7 +15,7 @@ defmodule Pleroma.Web.StreamerTest do    alias Pleroma.Web.Streamer.StreamerSocket    alias Pleroma.Web.Streamer.Worker -  @moduletag needs_streamer: true +  @moduletag needs_streamer: true, capture_log: true    clear_config_all([:instance, :skip_thread_containment])    describe "user streams" do  | 
