diff options
Diffstat (limited to 'test/web/activity_pub')
| -rw-r--r-- | test/web/activity_pub/activity_pub_controller_test.exs | 233 | ||||
| -rw-r--r-- | test/web/activity_pub/activity_pub_test.exs | 63 | ||||
| -rw-r--r-- | test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs | 6 | ||||
| -rw-r--r-- | test/web/activity_pub/publisher_test.exs | 94 | ||||
| -rw-r--r-- | test/web/activity_pub/relay_test.exs | 52 | ||||
| -rw-r--r-- | test/web/activity_pub/transmogrifier/follow_handling_test.exs | 21 | ||||
| -rw-r--r-- | test/web/activity_pub/transmogrifier_test.exs | 283 | ||||
| -rw-r--r-- | test/web/activity_pub/utils_test.exs | 334 | ||||
| -rw-r--r-- | test/web/activity_pub/views/user_view_test.exs | 71 | 
9 files changed, 1123 insertions, 34 deletions
diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index 77f5e39fa..ab52044ae 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -1,18 +1,24 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do    use Pleroma.Web.ConnCase +  use Oban.Testing, repo: Pleroma.Repo +    import Pleroma.Factory    alias Pleroma.Activity +  alias Pleroma.Delivery    alias Pleroma.Instances    alias Pleroma.Object +  alias Pleroma.Tests.ObanHelpers    alias Pleroma.User    alias Pleroma.Web.ActivityPub.ObjectView +  alias Pleroma.Web.ActivityPub.Relay    alias Pleroma.Web.ActivityPub.UserView    alias Pleroma.Web.ActivityPub.Utils    alias Pleroma.Web.CommonAPI +  alias Pleroma.Workers.ReceiverWorker    setup_all do      Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) @@ -174,6 +180,49 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do        assert json_response(conn, 404)      end + +    test "it caches a response", %{conn: conn} do +      note = insert(:note) +      uuid = String.split(note.data["id"], "/") |> List.last() + +      conn1 = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get("/objects/#{uuid}") + +      assert json_response(conn1, :ok) +      assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"})) + +      conn2 = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get("/objects/#{uuid}") + +      assert json_response(conn1, :ok) == json_response(conn2, :ok) +      assert Enum.any?(conn2.resp_headers, &(&1 == {"x-cache", "HIT from Pleroma"})) +    end + +    test "cached purged after object deletion", %{conn: conn} do +      note = insert(:note) +      uuid = String.split(note.data["id"], "/") |> List.last() + +      conn1 = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get("/objects/#{uuid}") + +      assert json_response(conn1, :ok) +      assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"})) + +      Object.delete(note) + +      conn2 = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get("/objects/#{uuid}") + +      assert "Not found" == json_response(conn2, :not_found) +    end    end    describe "/object/:uuid/likes" do @@ -263,6 +312,51 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do        assert json_response(conn, 404)      end + +    test "it caches a response", %{conn: conn} do +      activity = insert(:note_activity) +      uuid = String.split(activity.data["id"], "/") |> List.last() + +      conn1 = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get("/activities/#{uuid}") + +      assert json_response(conn1, :ok) +      assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"})) + +      conn2 = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get("/activities/#{uuid}") + +      assert json_response(conn1, :ok) == json_response(conn2, :ok) +      assert Enum.any?(conn2.resp_headers, &(&1 == {"x-cache", "HIT from Pleroma"})) +    end + +    test "cached purged after activity deletion", %{conn: conn} do +      user = insert(:user) +      {:ok, activity} = CommonAPI.post(user, %{"status" => "cofe"}) + +      uuid = String.split(activity.data["id"], "/") |> List.last() + +      conn1 = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get("/activities/#{uuid}") + +      assert json_response(conn1, :ok) +      assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"})) + +      Activity.delete_by_ap_id(activity.object.data["id"]) + +      conn2 = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get("/activities/#{uuid}") + +      assert "Not found" == json_response(conn2, :not_found) +    end    end    describe "/inbox" do @@ -276,7 +370,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do          |> post("/inbox", data)        assert "ok" == json_response(conn, 200) -      :timer.sleep(500) + +      ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))        assert Activity.get_by_ap_id(data["id"])      end @@ -318,7 +413,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do          |> post("/users/#{user.nickname}/inbox", data)        assert "ok" == json_response(conn, 200) -      :timer.sleep(500) +      ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))        assert Activity.get_by_ap_id(data["id"])      end @@ -347,7 +442,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do          |> post("/users/#{recipient.nickname}/inbox", data)        assert "ok" == json_response(conn, 200) -      :timer.sleep(500) +      ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))        assert Activity.get_by_ap_id(data["id"])      end @@ -364,6 +459,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do        assert json_response(conn, 403)      end +    test "it doesn't crash without an authenticated user", %{conn: conn} do +      user = insert(:user) + +      conn = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get("/users/#{user.nickname}/inbox") + +      assert json_response(conn, 403) +    end +      test "it returns a note activity in a collection", %{conn: conn} do        note_activity = insert(:direct_note_activity)        note_object = Object.normalize(note_activity) @@ -373,7 +479,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do          conn          |> assign(:user, user)          |> put_req_header("accept", "application/activity+json") -        |> get("/users/#{user.nickname}/inbox") +        |> get("/users/#{user.nickname}/inbox?page=true")        assert response(conn, 200) =~ note_object.data["content"]      end @@ -426,6 +532,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do        |> post("/users/#{recipient.nickname}/inbox", data)        |> json_response(200) +      ObanHelpers.perform(all_enqueued(worker: ReceiverWorker)) +        activity = Activity.get_by_ap_id(data["id"])        assert activity.id @@ -459,7 +567,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do        conn =          conn          |> put_req_header("accept", "application/activity+json") -        |> get("/users/#{user.nickname}/outbox") +        |> get("/users/#{user.nickname}/outbox?page=true")        assert response(conn, 200) =~ note_object.data["content"]      end @@ -471,7 +579,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do        conn =          conn          |> put_req_header("accept", "application/activity+json") -        |> get("/users/#{user.nickname}/outbox") +        |> get("/users/#{user.nickname}/outbox?page=true")        assert response(conn, 200) =~ announce_activity.data["object"]      end @@ -501,6 +609,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do          |> post("/users/#{user.nickname}/outbox", data)        result = json_response(conn, 201) +        assert Activity.get_by_ap_id(result["id"])      end @@ -593,6 +702,34 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do      end    end +  describe "/relay/followers" do +    test "it returns relay followers", %{conn: conn} do +      relay_actor = Relay.get_actor() +      user = insert(:user) +      User.follow(user, relay_actor) + +      result = +        conn +        |> assign(:relay, true) +        |> get("/relay/followers") +        |> json_response(200) + +      assert result["first"]["orderedItems"] == [user.ap_id] +    end +  end + +  describe "/relay/following" do +    test "it returns relay following", %{conn: conn} do +      result = +        conn +        |> assign(:relay, true) +        |> get("/relay/following") +        |> json_response(200) + +      assert result["first"]["orderedItems"] == [] +    end +  end +    describe "/users/:nickname/followers" do      test "it returns the followers in a collection", %{conn: conn} do        user = insert(:user) @@ -757,4 +894,86 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do        assert result["totalItems"] == 15      end    end + +  describe "delivery tracking" do +    test "it tracks a signed object fetch", %{conn: conn} do +      user = insert(:user, local: false) +      activity = insert(:note_activity) +      object = Object.normalize(activity) + +      object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url()) + +      conn +      |> put_req_header("accept", "application/activity+json") +      |> assign(:user, user) +      |> get(object_path) +      |> json_response(200) + +      assert Delivery.get(object.id, user.id) +    end + +    test "it tracks a signed activity fetch", %{conn: conn} do +      user = insert(:user, local: false) +      activity = insert(:note_activity) +      object = Object.normalize(activity) + +      activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url()) + +      conn +      |> put_req_header("accept", "application/activity+json") +      |> assign(:user, user) +      |> get(activity_path) +      |> json_response(200) + +      assert Delivery.get(object.id, user.id) +    end + +    test "it tracks a signed object fetch when the json is cached", %{conn: conn} do +      user = insert(:user, local: false) +      other_user = insert(:user, local: false) +      activity = insert(:note_activity) +      object = Object.normalize(activity) + +      object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url()) + +      conn +      |> put_req_header("accept", "application/activity+json") +      |> assign(:user, user) +      |> get(object_path) +      |> json_response(200) + +      build_conn() +      |> put_req_header("accept", "application/activity+json") +      |> assign(:user, other_user) +      |> get(object_path) +      |> json_response(200) + +      assert Delivery.get(object.id, user.id) +      assert Delivery.get(object.id, other_user.id) +    end + +    test "it tracks a signed activity fetch when the json is cached", %{conn: conn} do +      user = insert(:user, local: false) +      other_user = insert(:user, local: false) +      activity = insert(:note_activity) +      object = Object.normalize(activity) + +      activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url()) + +      conn +      |> put_req_header("accept", "application/activity+json") +      |> assign(:user, user) +      |> get(activity_path) +      |> json_response(200) + +      build_conn() +      |> put_req_header("accept", "application/activity+json") +      |> assign(:user, other_user) +      |> get(activity_path) +      |> json_response(200) + +      assert Delivery.get(object.id, user.id) +      assert Delivery.get(object.id, other_user.id) +    end +  end  end diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index 1515f4eb6..f28fd6871 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -21,6 +21,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do      :ok    end +  clear_config([:instance, :federating]) +    describe "streaming out participations" do      test "it streams them out" do        user = insert(:user) @@ -36,9 +38,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do          stream: fn _, _ -> nil end do          ActivityPub.stream_out_participations(conversation.participations) -        Enum.each(participations, fn participation -> -          assert called(Pleroma.Web.Streamer.stream("participation", participation)) -        end) +        assert called(Pleroma.Web.Streamer.stream("participation", participations))        end      end    end @@ -647,6 +647,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do        assert last == last_expected      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) + +      activities = +        ActivityPub.fetch_public_activities(%{"page" => "2", "page_size" => "20"}, :offset) + +      first = List.first(activities) + +      assert length(activities) == 20 +      assert first == first_expected +    end +      test "doesn't return reblogs for users for whom reblogs have been muted" do        activity = insert(:note_activity)        user = insert(:user) @@ -676,6 +691,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do    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) +      note_activity = insert(:note_activity) +      assert object_activity = Object.normalize(note_activity) + +      user = insert(:user) + +      {:ok, like_activity, _object} = ActivityPub.like(user, object_activity) +      assert called(Pleroma.Web.Federator.publish(like_activity)) +    end + +    test "returns exist activity if object already liked" do +      note_activity = insert(:note_activity) +      assert object_activity = Object.normalize(note_activity) + +      user = insert(:user) + +      {:ok, like_activity, _object} = ActivityPub.like(user, object_activity) + +      {:ok, like_activity_exist, _object} = ActivityPub.like(user, object_activity) +      assert like_activity == like_activity_exist +    end +      test "adds a like activity to the db" do        note_activity = insert(:note_activity)        assert object = Object.normalize(note_activity) @@ -706,6 +744,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do    end    describe "unliking" do +    test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do +      Pleroma.Config.put([:instance, :federating], true) + +      note_activity = insert(:note_activity) +      object = Object.normalize(note_activity) +      user = insert(:user) + +      {:ok, object} = ActivityPub.unlike(user, object) +      refute called(Pleroma.Web.Federator.publish()) + +      {:ok, _like_activity, object} = ActivityPub.like(user, object) +      assert object.data["like_count"] == 1 + +      {:ok, unlike_activity, _, object} = ActivityPub.unlike(user, object) +      assert object.data["like_count"] == 0 + +      assert called(Pleroma.Web.Federator.publish(unlike_activity)) +    end +      test "unliking a previously liked object" do        note_activity = insert(:note_activity)        object = Object.normalize(note_activity) diff --git a/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs b/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs index 372e789be..95a809d25 100644 --- a/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs +++ b/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs @@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do    use Pleroma.DataCase    alias Pleroma.HTTP +  alias Pleroma.Tests.ObanHelpers    alias Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy    import Mock @@ -24,6 +25,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do    test "it prefetches media proxy URIs" do      with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do        MediaProxyWarmingPolicy.filter(@message) + +      ObanHelpers.perform_all() +      # Performing jobs which has been just enqueued +      ObanHelpers.perform_all() +        assert called(HTTP.get(:_, :_, :_))      end    end diff --git a/test/web/activity_pub/publisher_test.exs b/test/web/activity_pub/publisher_test.exs index 36a39c84c..df03b4008 100644 --- a/test/web/activity_pub/publisher_test.exs +++ b/test/web/activity_pub/publisher_test.exs @@ -3,15 +3,18 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.ActivityPub.PublisherTest do -  use Pleroma.DataCase +  use Pleroma.Web.ConnCase +  import ExUnit.CaptureLog    import Pleroma.Factory    import Tesla.Mock    import Mock    alias Pleroma.Activity    alias Pleroma.Instances +  alias Pleroma.Object    alias Pleroma.Web.ActivityPub.Publisher +  alias Pleroma.Web.CommonAPI    @as_public "https://www.w3.org/ns/activitystreams#Public" @@ -188,7 +191,10 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do        actor = insert(:user)        inbox = "http://connrefused.site/users/nick1/inbox" -      assert {:error, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1}) +      assert capture_log(fn -> +               assert {:error, _} = +                        Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1}) +             end) =~ "connrefused"        assert called(Instances.set_unreachable(inbox))      end @@ -212,14 +218,16 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do        actor = insert(:user)        inbox = "http://connrefused.site/users/nick1/inbox" -      assert {:error, _} = -               Publisher.publish_one(%{ -                 inbox: inbox, -                 json: "{}", -                 actor: actor, -                 id: 1, -                 unreachable_since: NaiveDateTime.utc_now() -               }) +      assert capture_log(fn -> +               assert {:error, _} = +                        Publisher.publish_one(%{ +                          inbox: inbox, +                          json: "{}", +                          actor: actor, +                          id: 1, +                          unreachable_since: NaiveDateTime.utc_now() +                        }) +             end) =~ "connrefused"        refute called(Instances.set_unreachable(inbox))      end @@ -257,10 +265,74 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do        assert called(                 Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{                   inbox: "https://domain.com/users/nick1/inbox", -                 actor: actor, +                 actor_id: actor.id,                   id: note_activity.data["id"]                 })               )      end + +    test_with_mock "publishes a delete activity to peers who signed fetch requests to the create acitvity/object.", +                   Pleroma.Web.Federator.Publisher, +                   [:passthrough], +                   [] do +      fetcher = +        insert(:user, +          local: false, +          info: %{ +            ap_enabled: true, +            source_data: %{"inbox" => "https://domain.com/users/nick1/inbox"} +          } +        ) + +      another_fetcher = +        insert(:user, +          local: false, +          info: %{ +            ap_enabled: true, +            source_data: %{"inbox" => "https://domain2.com/users/nick1/inbox"} +          } +        ) + +      actor = insert(:user) + +      note_activity = insert(:note_activity, user: actor) +      object = Object.normalize(note_activity) + +      activity_path = String.trim_leading(note_activity.data["id"], Pleroma.Web.Endpoint.url()) +      object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url()) + +      build_conn() +      |> put_req_header("accept", "application/activity+json") +      |> assign(:user, fetcher) +      |> get(object_path) +      |> json_response(200) + +      build_conn() +      |> put_req_header("accept", "application/activity+json") +      |> assign(:user, another_fetcher) +      |> get(activity_path) +      |> json_response(200) + +      {:ok, delete} = CommonAPI.delete(note_activity.id, actor) + +      res = Publisher.publish(actor, delete) +      assert res == :ok + +      assert called( +               Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{ +                 inbox: "https://domain.com/users/nick1/inbox", +                 actor_id: actor.id, +                 id: delete.data["id"] +               }) +             ) + +      assert called( +               Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{ +                 inbox: "https://domain2.com/users/nick1/inbox", +                 actor_id: actor.id, +                 id: delete.data["id"] +               }) +             ) +    end    end  end diff --git a/test/web/activity_pub/relay_test.exs b/test/web/activity_pub/relay_test.exs index e10b808f7..0f7556538 100644 --- a/test/web/activity_pub/relay_test.exs +++ b/test/web/activity_pub/relay_test.exs @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.ActivityPub.RelayTest do @@ -10,7 +10,9 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.Web.ActivityPub.Relay +  import ExUnit.CaptureLog    import Pleroma.Factory +  import Mock    test "gets an actor for the relay" do      user = Relay.get_actor() @@ -19,7 +21,9 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do    describe "follow/1" do      test "returns errors when user not found" do -      assert Relay.follow("test-ap-id") == {:error, "Could not fetch by AP id"} +      assert capture_log(fn -> +               assert Relay.follow("test-ap-id") == {:error, "Could not fetch by AP id"} +             end) =~ "Could not fetch by AP id"      end      test "returns activity" do @@ -36,23 +40,30 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do    describe "unfollow/1" do      test "returns errors when user not found" do -      assert Relay.unfollow("test-ap-id") == {:error, "Could not fetch by AP id"} +      assert capture_log(fn -> +               assert Relay.unfollow("test-ap-id") == {:error, "Could not fetch by AP id"} +             end) =~ "Could not fetch by AP id"      end      test "returns activity" do        user = insert(:user)        service_actor = Relay.get_actor()        ActivityPub.follow(service_actor, user) +      Pleroma.User.follow(service_actor, user) +      assert "#{user.ap_id}/followers" in refresh_record(service_actor).following        assert {:ok, %Activity{} = activity} = Relay.unfollow(user.ap_id)        assert activity.actor == "#{Pleroma.Web.Endpoint.url()}/relay"        assert user.ap_id in activity.recipients        assert activity.data["type"] == "Undo"        assert activity.data["actor"] == service_actor.ap_id        assert activity.data["to"] == [user.ap_id] +      refute "#{user.ap_id}/followers" in refresh_record(service_actor).following      end    end    describe "publish/1" do +    clear_config([:instance, :federating]) +      test "returns error when activity not `Create` type" do        activity = insert(:like_activity)        assert Relay.publish(activity) == {:error, "Not implemented"} @@ -63,13 +74,46 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do        assert Relay.publish(activity) == {:error, false}      end -    test "returns announce activity" do +    test "returns error when object is unknown" do +      activity = +        insert(:note_activity, +          data: %{ +            "type" => "Create", +            "object" => "http://mastodon.example.org/eee/99541947525187367" +          } +        ) + +      assert capture_log(fn -> +               assert Relay.publish(activity) == {:error, nil} +             end) =~ "[error] error: nil" +    end + +    test_with_mock "returns announce activity and publish to federate", +                   Pleroma.Web.Federator, +                   [:passthrough], +                   [] do +      Pleroma.Config.put([:instance, :federating], true) +      service_actor = Relay.get_actor() +      note = insert(:note_activity) +      assert {:ok, %Activity{} = activity, %Object{} = obj} = Relay.publish(note) +      assert activity.data["type"] == "Announce" +      assert activity.data["actor"] == service_actor.ap_id +      assert activity.data["object"] == obj.data["id"] +      assert called(Pleroma.Web.Federator.publish(activity)) +    end + +    test_with_mock "returns announce activity and not publish to federate", +                   Pleroma.Web.Federator, +                   [:passthrough], +                   [] do +      Pleroma.Config.put([:instance, :federating], false)        service_actor = Relay.get_actor()        note = insert(:note_activity)        assert {:ok, %Activity{} = activity, %Object{} = obj} = Relay.publish(note)        assert activity.data["type"] == "Announce"        assert activity.data["actor"] == service_actor.ap_id        assert activity.data["object"] == obj.data["id"] +      refute called(Pleroma.Web.Federator.publish(activity))      end    end  end diff --git a/test/web/activity_pub/transmogrifier/follow_handling_test.exs b/test/web/activity_pub/transmogrifier/follow_handling_test.exs index 857d65564..99ab573c5 100644 --- a/test/web/activity_pub/transmogrifier/follow_handling_test.exs +++ b/test/web/activity_pub/transmogrifier/follow_handling_test.exs @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do @@ -19,6 +19,25 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do    end    describe "handle_incoming" do +    test "it works for osada follow request" do +      user = insert(:user) + +      data = +        File.read!("test/fixtures/osada-follow-activity.json") +        |> Poison.decode!() +        |> Map.put("object", user.ap_id) + +      {:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data) + +      assert data["actor"] == "https://apfed.club/channel/indio" +      assert data["type"] == "Follow" +      assert data["id"] == "https://apfed.club/follow/9" + +      activity = Repo.get(Activity, activity.id) +      assert activity.data["state"] == "accept" +      assert User.following?(User.get_cached_by_ap_id(data["actor"]), user) +    end +      test "it works for incoming follow requests" do        user = insert(:user) diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index 629c76c97..a35db71dc 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -1,5 +1,5 @@  # Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do @@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do    alias Pleroma.Object    alias Pleroma.Object.Fetcher    alias Pleroma.Repo +  alias Pleroma.Tests.ObanHelpers    alias Pleroma.User    alias Pleroma.Web.ActivityPub.ActivityPub    alias Pleroma.Web.ActivityPub.Transmogrifier @@ -102,7 +103,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        assert capture_log(fn ->                 {:ok, _returned_activity} = Transmogrifier.handle_incoming(data) -             end) =~ "[error] Couldn't fetch \"\"https://404.site/whatever\"\", error: nil" +             end) =~ "[error] Couldn't fetch \"https://404.site/whatever\", error: nil"      end      test "it works for incoming notices" do @@ -563,6 +564,14 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do                 %{"name" => "foo", "value" => "updated"},                 %{"name" => "foo1", "value" => "updated"}               ] + +      update_data = put_in(update_data, ["object", "attachment"], []) + +      {:ok, _} = Transmogrifier.handle_incoming(update_data) + +      user = User.get_cached_by_ap_id(user.ap_id) + +      assert User.Info.fields(user.info) == []      end      test "it works for incoming update activities which lock the account" do @@ -640,6 +649,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do          |> Poison.decode!()        {:ok, _} = Transmogrifier.handle_incoming(data) +      ObanHelpers.perform_all()        refute User.get_cached_by_ap_id(ap_id)      end @@ -1202,6 +1212,8 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        assert user.info.note_count == 1        {:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye") +      ObanHelpers.perform_all() +        assert user.info.ap_enabled        assert user.info.note_count == 1        assert user.follower_address == "https://niu.moe/users/rye/followers" @@ -1443,4 +1455,271 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        refute recipient.follower_address in fixed_object["to"]      end    end + +  describe "fix_summary/1" do +    test "returns fixed object" do +      assert Transmogrifier.fix_summary(%{"summary" => nil}) == %{"summary" => ""} +      assert Transmogrifier.fix_summary(%{"summary" => "ok"}) == %{"summary" => "ok"} +      assert Transmogrifier.fix_summary(%{}) == %{"summary" => ""} +    end +  end + +  describe "fix_in_reply_to/2" do +    clear_config([:instance, :federation_incoming_replies_max_depth]) + +    setup do +      data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json")) +      [data: data] +    end + +    test "returns not modified object when hasn't containts inReplyTo field", %{data: data} do +      assert Transmogrifier.fix_in_reply_to(data) == data +    end + +    test "returns object with inReplyToAtomUri when denied incoming reply", %{data: data} do +      Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 0) + +      object_with_reply = +        Map.put(data["object"], "inReplyTo", "https://shitposter.club/notice/2827873") + +      modified_object = Transmogrifier.fix_in_reply_to(object_with_reply) +      assert modified_object["inReplyTo"] == "https://shitposter.club/notice/2827873" +      assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873" + +      object_with_reply = +        Map.put(data["object"], "inReplyTo", %{"id" => "https://shitposter.club/notice/2827873"}) + +      modified_object = Transmogrifier.fix_in_reply_to(object_with_reply) +      assert modified_object["inReplyTo"] == %{"id" => "https://shitposter.club/notice/2827873"} +      assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873" + +      object_with_reply = +        Map.put(data["object"], "inReplyTo", ["https://shitposter.club/notice/2827873"]) + +      modified_object = Transmogrifier.fix_in_reply_to(object_with_reply) +      assert modified_object["inReplyTo"] == ["https://shitposter.club/notice/2827873"] +      assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873" + +      object_with_reply = Map.put(data["object"], "inReplyTo", []) +      modified_object = Transmogrifier.fix_in_reply_to(object_with_reply) +      assert modified_object["inReplyTo"] == [] +      assert modified_object["inReplyToAtomUri"] == "" +    end + +    test "returns modified object when allowed incoming reply", %{data: data} do +      object_with_reply = +        Map.put( +          data["object"], +          "inReplyTo", +          "https://shitposter.club/notice/2827873" +        ) + +      Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 5) +      modified_object = Transmogrifier.fix_in_reply_to(object_with_reply) + +      assert modified_object["inReplyTo"] == +               "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment" + +      assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873" + +      assert modified_object["conversation"] == +               "tag:shitposter.club,2017-05-05:objectType=thread:nonce=3c16e9c2681f6d26" + +      assert modified_object["context"] == +               "tag:shitposter.club,2017-05-05:objectType=thread:nonce=3c16e9c2681f6d26" +    end +  end + +  describe "fix_url/1" do +    test "fixes data for object when url is map" do +      object = %{ +        "url" => %{ +          "type" => "Link", +          "mimeType" => "video/mp4", +          "href" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4" +        } +      } + +      assert Transmogrifier.fix_url(object) == %{ +               "url" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4" +             } +    end + +    test "fixes data for video object" do +      object = %{ +        "type" => "Video", +        "url" => [ +          %{ +            "type" => "Link", +            "mimeType" => "video/mp4", +            "href" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4" +          }, +          %{ +            "type" => "Link", +            "mimeType" => "video/mp4", +            "href" => "https://peertube46fb-ad81-2d4c2d1630e3-240.mp4" +          }, +          %{ +            "type" => "Link", +            "mimeType" => "text/html", +            "href" => "https://peertube.-2d4c2d1630e3" +          }, +          %{ +            "type" => "Link", +            "mimeType" => "text/html", +            "href" => "https://peertube.-2d4c2d16377-42" +          } +        ] +      } + +      assert Transmogrifier.fix_url(object) == %{ +               "attachment" => [ +                 %{ +                   "href" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4", +                   "mimeType" => "video/mp4", +                   "type" => "Link" +                 } +               ], +               "type" => "Video", +               "url" => "https://peertube.-2d4c2d1630e3" +             } +    end + +    test "fixes url for not Video object" do +      object = %{ +        "type" => "Text", +        "url" => [ +          %{ +            "type" => "Link", +            "mimeType" => "text/html", +            "href" => "https://peertube.-2d4c2d1630e3" +          }, +          %{ +            "type" => "Link", +            "mimeType" => "text/html", +            "href" => "https://peertube.-2d4c2d16377-42" +          } +        ] +      } + +      assert Transmogrifier.fix_url(object) == %{ +               "type" => "Text", +               "url" => "https://peertube.-2d4c2d1630e3" +             } + +      assert Transmogrifier.fix_url(%{"type" => "Text", "url" => []}) == %{ +               "type" => "Text", +               "url" => "" +             } +    end + +    test "retunrs not modified object" do +      assert Transmogrifier.fix_url(%{"type" => "Text"}) == %{"type" => "Text"} +    end +  end + +  describe "get_obj_helper/2" do +    test "returns nil when cannot normalize object" do +      refute Transmogrifier.get_obj_helper("test-obj-id") +    end + +    test "returns {:ok, %Object{}} for success case" do +      assert {:ok, %Object{}} = +               Transmogrifier.get_obj_helper("https://shitposter.club/notice/2827873") +    end +  end + +  describe "fix_attachments/1" do +    test "returns not modified object" do +      data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json")) +      assert Transmogrifier.fix_attachments(data) == data +    end + +    test "returns modified object when attachment is map" do +      assert Transmogrifier.fix_attachments(%{ +               "attachment" => %{ +                 "mediaType" => "video/mp4", +                 "url" => "https://peertube.moe/stat-480.mp4" +               } +             }) == %{ +               "attachment" => [ +                 %{ +                   "mediaType" => "video/mp4", +                   "url" => [ +                     %{ +                       "href" => "https://peertube.moe/stat-480.mp4", +                       "mediaType" => "video/mp4", +                       "type" => "Link" +                     } +                   ] +                 } +               ] +             } +    end + +    test "returns modified object when attachment is list" do +      assert Transmogrifier.fix_attachments(%{ +               "attachment" => [ +                 %{"mediaType" => "video/mp4", "url" => "https://pe.er/stat-480.mp4"}, +                 %{"mimeType" => "video/mp4", "href" => "https://pe.er/stat-480.mp4"} +               ] +             }) == %{ +               "attachment" => [ +                 %{ +                   "mediaType" => "video/mp4", +                   "url" => [ +                     %{ +                       "href" => "https://pe.er/stat-480.mp4", +                       "mediaType" => "video/mp4", +                       "type" => "Link" +                     } +                   ] +                 }, +                 %{ +                   "href" => "https://pe.er/stat-480.mp4", +                   "mediaType" => "video/mp4", +                   "mimeType" => "video/mp4", +                   "url" => [ +                     %{ +                       "href" => "https://pe.er/stat-480.mp4", +                       "mediaType" => "video/mp4", +                       "type" => "Link" +                     } +                   ] +                 } +               ] +             } +    end +  end + +  describe "fix_emoji/1" do +    test "returns not modified object when object not contains tags" do +      data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json")) +      assert Transmogrifier.fix_emoji(data) == data +    end + +    test "returns object with emoji when object contains list tags" do +      assert Transmogrifier.fix_emoji(%{ +               "tag" => [ +                 %{"type" => "Emoji", "name" => ":bib:", "icon" => %{"url" => "/test"}}, +                 %{"type" => "Hashtag"} +               ] +             }) == %{ +               "emoji" => %{"bib" => "/test"}, +               "tag" => [ +                 %{"icon" => %{"url" => "/test"}, "name" => ":bib:", "type" => "Emoji"}, +                 %{"type" => "Hashtag"} +               ] +             } +    end + +    test "returns object with emoji when object contains map tag" do +      assert Transmogrifier.fix_emoji(%{ +               "tag" => %{"type" => "Emoji", "name" => ":bib:", "icon" => %{"url" => "/test"}} +             }) == %{ +               "emoji" => %{"bib" => "/test"}, +               "tag" => %{"icon" => %{"url" => "/test"}, "name" => ":bib:", "type" => "Emoji"} +             } +    end +  end  end diff --git a/test/web/activity_pub/utils_test.exs b/test/web/activity_pub/utils_test.exs index ca5f057a7..b1c1d6f71 100644 --- a/test/web/activity_pub/utils_test.exs +++ b/test/web/activity_pub/utils_test.exs @@ -14,6 +14,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do    import Pleroma.Factory +  require Pleroma.Constants +    describe "fetch the latest Follow" do      test "fetches the latest Follow activity" do        %Activity{data: %{"type" => "Follow"}} = activity = insert(:follow_activity) @@ -85,6 +87,44 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do        assert Utils.determine_explicit_mentions(object) == []      end + +    test "works with an object has tags as map" do +      object = %{ +        "tag" => %{ +          "type" => "Mention", +          "href" => "https://example.com/~alyssa", +          "name" => "Alyssa P. Hacker" +        } +      } + +      assert Utils.determine_explicit_mentions(object) == ["https://example.com/~alyssa"] +    end +  end + +  describe "make_unlike_data/3" do +    test "returns data for unlike activity" do +      user = insert(:user) +      like_activity = insert(:like_activity, data_attrs: %{"context" => "test context"}) + +      assert Utils.make_unlike_data(user, like_activity, nil) == %{ +               "type" => "Undo", +               "actor" => user.ap_id, +               "object" => like_activity.data, +               "to" => [user.follower_address, like_activity.data["actor"]], +               "cc" => [Pleroma.Constants.as_public()], +               "context" => like_activity.data["context"] +             } + +      assert Utils.make_unlike_data(user, like_activity, "9mJEZK0tky1w2xD2vY") == %{ +               "type" => "Undo", +               "actor" => user.ap_id, +               "object" => like_activity.data, +               "to" => [user.follower_address, like_activity.data["actor"]], +               "cc" => [Pleroma.Constants.as_public()], +               "context" => like_activity.data["context"], +               "id" => "9mJEZK0tky1w2xD2vY" +             } +    end    end    describe "make_like_data" do @@ -272,8 +312,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do        {:ok, follow_activity_two} =          Utils.update_follow_state_for_all(follow_activity_two, "accept") -      assert Repo.get(Activity, follow_activity.id).data["state"] == "accept" -      assert Repo.get(Activity, follow_activity_two.id).data["state"] == "accept" +      assert refresh_record(follow_activity).data["state"] == "accept" +      assert refresh_record(follow_activity_two).data["state"] == "accept"      end    end @@ -295,8 +335,294 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do        {:ok, follow_activity_two} = Utils.update_follow_state(follow_activity_two, "reject") -      assert Repo.get(Activity, follow_activity.id).data["state"] == "pending" -      assert Repo.get(Activity, follow_activity_two.id).data["state"] == "reject" +      assert refresh_record(follow_activity).data["state"] == "pending" +      assert refresh_record(follow_activity_two).data["state"] == "reject" +    end +  end + +  describe "update_element_in_object/3" do +    test "updates likes" do +      user = insert(:user) +      activity = insert(:note_activity) +      object = Object.normalize(activity) + +      assert {:ok, updated_object} = +               Utils.update_element_in_object( +                 "like", +                 [user.ap_id], +                 object +               ) + +      assert updated_object.data["likes"] == [user.ap_id] +      assert updated_object.data["like_count"] == 1 +    end +  end + +  describe "add_like_to_object/2" do +    test "add actor to likes" do +      user = insert(:user) +      user2 = insert(:user) +      object = insert(:note) + +      assert {:ok, updated_object} = +               Utils.add_like_to_object( +                 %Activity{data: %{"actor" => user.ap_id}}, +                 object +               ) + +      assert updated_object.data["likes"] == [user.ap_id] +      assert updated_object.data["like_count"] == 1 + +      assert {:ok, updated_object2} = +               Utils.add_like_to_object( +                 %Activity{data: %{"actor" => user2.ap_id}}, +                 updated_object +               ) + +      assert updated_object2.data["likes"] == [user2.ap_id, user.ap_id] +      assert updated_object2.data["like_count"] == 2 +    end +  end + +  describe "remove_like_from_object/2" do +    test "removes ap_id from likes" do +      user = insert(:user) +      user2 = insert(:user) +      object = insert(:note, data: %{"likes" => [user.ap_id, user2.ap_id], "like_count" => 2}) + +      assert {:ok, updated_object} = +               Utils.remove_like_from_object( +                 %Activity{data: %{"actor" => user.ap_id}}, +                 object +               ) + +      assert updated_object.data["likes"] == [user2.ap_id] +      assert updated_object.data["like_count"] == 1 +    end +  end + +  describe "get_existing_like/2" do +    test "fetches existing like" do +      note_activity = insert(:note_activity) +      assert object = Object.normalize(note_activity) + +      user = insert(:user) +      refute Utils.get_existing_like(user.ap_id, object) +      {:ok, like_activity, _object} = ActivityPub.like(user, object) + +      assert ^like_activity = Utils.get_existing_like(user.ap_id, object) +    end +  end + +  describe "get_get_existing_announce/2" do +    test "returns nil if announce not found" do +      actor = insert(:user) +      refute Utils.get_existing_announce(actor.ap_id, %{data: %{"id" => "test"}}) +    end + +    test "fetches existing announce" do +      note_activity = insert(:note_activity) +      assert object = Object.normalize(note_activity) +      actor = insert(:user) + +      {:ok, announce, _object} = ActivityPub.announce(actor, object) +      assert Utils.get_existing_announce(actor.ap_id, object) == announce +    end +  end + +  describe "fetch_latest_block/2" do +    test "fetches last block activities" do +      user1 = insert(:user) +      user2 = insert(:user) + +      assert {:ok, %Activity{} = _} = ActivityPub.block(user1, user2) +      assert {:ok, %Activity{} = _} = ActivityPub.block(user1, user2) +      assert {:ok, %Activity{} = activity} = ActivityPub.block(user1, user2) + +      assert Utils.fetch_latest_block(user1, user2) == activity +    end +  end + +  describe "recipient_in_message/3" do +    test "returns true when recipient in `to`" do +      recipient = insert(:user) +      actor = insert(:user) +      assert Utils.recipient_in_message(recipient, actor, %{"to" => recipient.ap_id}) + +      assert Utils.recipient_in_message( +               recipient, +               actor, +               %{"to" => [recipient.ap_id], "cc" => ""} +             ) +    end + +    test "returns true when recipient in `cc`" do +      recipient = insert(:user) +      actor = insert(:user) +      assert Utils.recipient_in_message(recipient, actor, %{"cc" => recipient.ap_id}) + +      assert Utils.recipient_in_message( +               recipient, +               actor, +               %{"cc" => [recipient.ap_id], "to" => ""} +             ) +    end + +    test "returns true when recipient in `bto`" do +      recipient = insert(:user) +      actor = insert(:user) +      assert Utils.recipient_in_message(recipient, actor, %{"bto" => recipient.ap_id}) + +      assert Utils.recipient_in_message( +               recipient, +               actor, +               %{"bcc" => "", "bto" => [recipient.ap_id]} +             ) +    end + +    test "returns true when recipient in `bcc`" do +      recipient = insert(:user) +      actor = insert(:user) +      assert Utils.recipient_in_message(recipient, actor, %{"bcc" => recipient.ap_id}) + +      assert Utils.recipient_in_message( +               recipient, +               actor, +               %{"bto" => "", "bcc" => [recipient.ap_id]} +             ) +    end + +    test "returns true when message without addresses fields" do +      recipient = insert(:user) +      actor = insert(:user) +      assert Utils.recipient_in_message(recipient, actor, %{"bccc" => recipient.ap_id}) + +      assert Utils.recipient_in_message( +               recipient, +               actor, +               %{"btod" => "", "bccc" => [recipient.ap_id]} +             ) +    end + +    test "returns false" do +      recipient = insert(:user) +      actor = insert(:user) +      refute Utils.recipient_in_message(recipient, actor, %{"to" => "ap_id"}) +    end +  end + +  describe "lazy_put_activity_defaults/2" do +    test "returns map with id and published data" do +      note_activity = insert(:note_activity) +      object = Object.normalize(note_activity) +      res = Utils.lazy_put_activity_defaults(%{"context" => object.data["id"]}) +      assert res["context"] == object.data["id"] +      assert res["context_id"] == object.id +      assert res["id"] +      assert res["published"] +    end + +    test "returns map with fake id and published data" do +      assert %{ +               "context" => "pleroma:fakecontext", +               "context_id" => -1, +               "id" => "pleroma:fakeid", +               "published" => _ +             } = Utils.lazy_put_activity_defaults(%{}, true) +    end + +    test "returns activity data with object" do +      note_activity = insert(:note_activity) +      object = Object.normalize(note_activity) + +      res = +        Utils.lazy_put_activity_defaults(%{ +          "context" => object.data["id"], +          "object" => %{} +        }) + +      assert res["context"] == object.data["id"] +      assert res["context_id"] == object.id +      assert res["id"] +      assert res["published"] +      assert res["object"]["id"] +      assert res["object"]["published"] +      assert res["object"]["context"] == object.data["id"] +      assert res["object"]["context_id"] == object.id +    end +  end + +  describe "make_flag_data" do +    test "returns empty map when params is invalid" do +      assert Utils.make_flag_data(%{}, %{}) == %{} +    end + +    test "returns map with Flag object" do +      reporter = insert(:user) +      target_account = insert(:user) +      {:ok, activity} = CommonAPI.post(target_account, %{"status" => "foobar"}) +      context = Utils.generate_context_id() +      content = "foobar" + +      target_ap_id = target_account.ap_id +      activity_ap_id = activity.data["id"] + +      res = +        Utils.make_flag_data( +          %{ +            actor: reporter, +            context: context, +            account: target_account, +            statuses: [%{"id" => activity.data["id"]}], +            content: content +          }, +          %{} +        ) + +      assert %{ +               "type" => "Flag", +               "content" => ^content, +               "context" => ^context, +               "object" => [^target_ap_id, ^activity_ap_id], +               "state" => "open" +             } = res +    end +  end + +  describe "add_announce_to_object/2" do +    test "adds actor to announcement" do +      user = insert(:user) +      object = insert(:note) + +      activity = +        insert(:note_activity, +          data: %{ +            "actor" => user.ap_id, +            "cc" => [Pleroma.Constants.as_public()] +          } +        ) + +      assert {:ok, updated_object} = Utils.add_announce_to_object(activity, object) +      assert updated_object.data["announcements"] == [user.ap_id] +      assert updated_object.data["announcement_count"] == 1 +    end +  end + +  describe "remove_announce_from_object/2" do +    test "removes actor from announcements" do +      user = insert(:user) +      user2 = insert(:user) + +      object = +        insert(:note, +          data: %{"announcements" => [user.ap_id, user2.ap_id], "announcement_count" => 2} +        ) + +      activity = insert(:note_activity, data: %{"actor" => user.ap_id}) + +      assert {:ok, updated_object} = Utils.remove_announce_from_object(activity, object) +      assert updated_object.data["announcements"] == [user2.ap_id] +      assert updated_object.data["announcement_count"] == 1      end    end  end diff --git a/test/web/activity_pub/views/user_view_test.exs b/test/web/activity_pub/views/user_view_test.exs index fb7fd9e79..3155749aa 100644 --- a/test/web/activity_pub/views/user_view_test.exs +++ b/test/web/activity_pub/views/user_view_test.exs @@ -37,6 +37,22 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do             } = UserView.render("user.json", %{user: user})    end +  test "Renders with emoji tags" do +    user = insert(:user, %{info: %{emoji: [%{"bib" => "/test"}]}}) + +    assert %{ +             "tag" => [ +               %{ +                 "icon" => %{"type" => "Image", "url" => "/test"}, +                 "id" => "/test", +                 "name" => ":bib:", +                 "type" => "Emoji", +                 "updated" => "1970-01-01T00:00:00Z" +               } +             ] +           } = UserView.render("user.json", %{user: user}) +  end +    test "Does not add an avatar image if the user hasn't set one" do      user = insert(:user)      {:ok, user} = User.ensure_keys_present(user) @@ -105,10 +121,20 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do        other_user = insert(:user)        {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)        assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user}) -      info = Map.put(user.info, :hide_followers, true) +      info = Map.merge(user.info, %{hide_followers_count: true, hide_followers: true})        user = Map.put(user, :info, info)        assert %{"totalItems" => 0} = UserView.render("followers.json", %{user: user})      end + +    test "sets correct totalItems when followers are hidden but the follower counter is not" do +      user = insert(:user) +      other_user = insert(:user) +      {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) +      assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user}) +      info = Map.merge(user.info, %{hide_followers_count: false, hide_followers: true}) +      user = Map.put(user, :info, info) +      assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user}) +    end    end    describe "following" do @@ -117,9 +143,50 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do        other_user = insert(:user)        {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)        assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user}) -      info = Map.put(user.info, :hide_follows, true) +      info = Map.merge(user.info, %{hide_follows_count: true, hide_follows: true})        user = Map.put(user, :info, info)        assert %{"totalItems" => 0} = UserView.render("following.json", %{user: user})      end + +    test "sets correct totalItems when follows are hidden but the follow counter is not" do +      user = insert(:user) +      other_user = insert(:user) +      {:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user) +      assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user}) +      info = Map.merge(user.info, %{hide_follows_count: false, hide_follows: true}) +      user = Map.put(user, :info, info) +      assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user}) +    end +  end + +  test "activity collection page aginates correctly" do +    user = insert(:user) + +    posts = +      for i <- 0..25 do +        {:ok, activity} = CommonAPI.post(user, %{"status" => "post #{i}"}) +        activity +      end + +    # outbox sorts chronologically, newest first, with ten per page +    posts = Enum.reverse(posts) + +    %{"next" => next_url} = +      UserView.render("activity_collection_page.json", %{ +        iri: "#{user.ap_id}/outbox", +        activities: Enum.take(posts, 10) +      }) + +    next_id = Enum.at(posts, 9).id +    assert next_url =~ next_id + +    %{"next" => next_url} = +      UserView.render("activity_collection_page.json", %{ +        iri: "#{user.ap_id}/outbox", +        activities: Enum.take(Enum.drop(posts, 10), 10) +      }) + +    next_id = Enum.at(posts, 19).id +    assert next_url =~ next_id    end  end  | 
