SideEffects.DeleteTest: asyncify.
authorlain <lain@soykaf.club>
Mon, 4 Jan 2021 17:40:59 +0000 (18:40 +0100)
committerlain <lain@soykaf.club>
Mon, 4 Jan 2021 17:40:59 +0000 (18:40 +0100)
Replace Mock with Mox, mock out Logger.

config/test.exs
lib/pleroma/logging.ex [new file with mode: 0644]
lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/activity_pub/activity_pub/streaming.ex [new file with mode: 0644]
lib/pleroma/web/activity_pub/side_effects.ex
test/pleroma/web/activity_pub/side_effects/delete_test.exs [new file with mode: 0644]
test/pleroma/web/activity_pub/side_effects_test.exs
test/support/conn_case.ex
test/support/data_case.ex
test/support/mocks.ex

index a858815921f65c81dcc60b5de679cb3182803dc5..7fc4574633fc704a48ec54dd49bdb05c1357d8e8 100644 (file)
@@ -134,6 +134,10 @@ config :pleroma, :pipeline,
 
 config :pleroma, :cachex, provider: Pleroma.CachexMock
 
+config :pleroma, :side_effects,
+  ap_streamer: Pleroma.Web.ActivityPub.ActivityPubMock,
+  logger: Pleroma.LoggerMock
+
 if File.exists?("./config/test.secret.exs") do
   import_config "test.secret.exs"
 else
diff --git a/lib/pleroma/logging.ex b/lib/pleroma/logging.ex
new file mode 100644 (file)
index 0000000..37b201c
--- /dev/null
@@ -0,0 +1,7 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Logging do
+  @callback error(String.t()) :: any()
+end
index 15f298bb824e2df77cc2718b3c27888fde2f5679..3e346d49a7a0c5a7bd3d5aebb4298093d4074e1d 100644 (file)
@@ -33,6 +33,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
   require Pleroma.Constants
 
   @behaviour Pleroma.Web.ActivityPub.ActivityPub.Persisting
+  @behaviour Pleroma.Web.ActivityPub.ActivityPub.Streaming
 
   defp get_recipients(%{"type" => "Create"} = data) do
     to = Map.get(data, "to", [])
@@ -224,6 +225,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     Streamer.stream("participation", participations)
   end
 
+  @impl true
   def stream_out_participations(%Object{data: %{"context" => context}}, user) do
     with %Conversation{} = conversation <- Conversation.get_for_ap_id(context) do
       conversation = Repo.preload(conversation, :participations)
@@ -240,8 +242,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     end
   end
 
+  @impl true
   def stream_out_participations(_, _), do: :noop
 
+  @impl true
   def stream_out(%Activity{data: %{"type" => data_type}} = activity)
       when data_type in ["Create", "Announce", "Delete"] do
     activity
@@ -249,6 +253,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     |> Streamer.stream(activity)
   end
 
+  @impl true
   def stream_out(_activity) do
     :noop
   end
diff --git a/lib/pleroma/web/activity_pub/activity_pub/streaming.ex b/lib/pleroma/web/activity_pub/activity_pub/streaming.ex
new file mode 100644 (file)
index 0000000..30009f2
--- /dev/null
@@ -0,0 +1,12 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.ActivityPub.Streaming do
+  alias Pleroma.Activity
+  alias Pleroma.Object
+  alias Pleroma.User
+
+  @callback stream_out(Activity.t()) :: any()
+  @callback stream_out_participations(Object.t(), User.t()) :: any()
+end
index 55c99ad0cabf3da38ae35494fb192ba8b035f9a6..e37caf6a062b6a6d8334222d5ae3caf9539e0c4d 100644 (file)
@@ -28,6 +28,8 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
   require Logger
 
   @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
+  @ap_streamer Pleroma.Config.get([:side_effects, :ap_streamer], ActivityPub)
+  @logger Pleroma.Config.get([:side_effects, :logger], Logger)
 
   @behaviour Pleroma.Web.ActivityPub.SideEffects.Handling
 
@@ -287,12 +289,12 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
 
             MessageReference.delete_for_object(deleted_object)
 
-            ActivityPub.stream_out(object)
-            ActivityPub.stream_out_participations(deleted_object, user)
+            @ap_streamer.stream_out(object)
+            @ap_streamer.stream_out_participations(deleted_object, user)
             :ok
           else
             {:actor, _} ->
-              Logger.error("The object doesn't have an actor: #{inspect(deleted_object)}")
+              @logger.error("The object doesn't have an actor: #{inspect(deleted_object)}")
               :no_object_actor
           end
 
diff --git a/test/pleroma/web/activity_pub/side_effects/delete_test.exs b/test/pleroma/web/activity_pub/side_effects/delete_test.exs
new file mode 100644 (file)
index 0000000..e4ad606
--- /dev/null
@@ -0,0 +1,147 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.SideEffects.DeleteTest do
+  use Oban.Testing, repo: Pleroma.Repo
+  use Pleroma.DataCase, async: true
+
+  alias Pleroma.Activity
+  alias Pleroma.Object
+  alias Pleroma.Repo
+  alias Pleroma.Tests.ObanHelpers
+  alias Pleroma.User
+  alias Pleroma.Web.ActivityPub.ActivityPub
+  alias Pleroma.Web.ActivityPub.Builder
+  alias Pleroma.Web.ActivityPub.SideEffects
+  alias Pleroma.Web.CommonAPI
+
+  alias Pleroma.LoggerMock
+  alias Pleroma.Web.ActivityPub.ActivityPubMock
+
+  import Mox
+  import Pleroma.Factory
+
+  describe "user deletion" do
+    setup do
+      user = insert(:user)
+
+      {:ok, delete_user_data, _meta} = Builder.delete(user, user.ap_id)
+      {:ok, delete_user, _meta} = ActivityPub.persist(delete_user_data, local: true)
+
+      %{
+        user: user,
+        delete_user: delete_user
+      }
+    end
+
+    test "it handles user deletions", %{delete_user: delete, user: user} do
+      {:ok, _delete, _} = SideEffects.handle(delete)
+      ObanHelpers.perform_all()
+
+      assert User.get_cached_by_ap_id(user.ap_id).deactivated
+    end
+  end
+
+  describe "object deletion" do
+    setup do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, op} = CommonAPI.post(other_user, %{status: "big oof"})
+      {:ok, post} = CommonAPI.post(user, %{status: "hey", in_reply_to_id: op})
+      {:ok, favorite} = CommonAPI.favorite(user, post.id)
+      object = Object.normalize(post)
+      {:ok, delete_data, _meta} = Builder.delete(user, object.data["id"])
+      {:ok, delete, _meta} = ActivityPub.persist(delete_data, local: true)
+
+      %{
+        user: user,
+        delete: delete,
+        post: post,
+        object: object,
+        op: op,
+        favorite: favorite
+      }
+    end
+
+    test "it handles object deletions", %{
+      delete: delete,
+      post: post,
+      object: object,
+      user: user,
+      op: op,
+      favorite: favorite
+    } do
+      object_id = object.id
+      user_id = user.id
+
+      ActivityPubMock
+      |> expect(:stream_out, fn ^delete -> nil end)
+      |> expect(:stream_out_participations, fn %Object{id: ^object_id}, %User{id: ^user_id} ->
+        nil
+      end)
+
+      {:ok, _delete, _} = SideEffects.handle(delete)
+      user = User.get_cached_by_ap_id(object.data["actor"])
+
+      object = Object.get_by_id(object.id)
+      assert object.data["type"] == "Tombstone"
+      refute Activity.get_by_id(post.id)
+      refute Activity.get_by_id(favorite.id)
+
+      user = User.get_by_id(user.id)
+      assert user.note_count == 0
+
+      object = Object.normalize(op.data["object"], false)
+
+      assert object.data["repliesCount"] == 0
+    end
+
+    test "it handles object deletions when the object itself has been pruned", %{
+      delete: delete,
+      post: post,
+      object: object,
+      user: user,
+      op: op
+    } do
+      object_id = object.id
+      user_id = user.id
+
+      ActivityPubMock
+      |> expect(:stream_out, fn ^delete -> nil end)
+      |> expect(:stream_out_participations, fn %Object{id: ^object_id}, %User{id: ^user_id} ->
+        nil
+      end)
+
+      {:ok, _delete, _} = SideEffects.handle(delete)
+      user = User.get_cached_by_ap_id(object.data["actor"])
+
+      object = Object.get_by_id(object.id)
+      assert object.data["type"] == "Tombstone"
+      refute Activity.get_by_id(post.id)
+
+      user = User.get_by_id(user.id)
+      assert user.note_count == 0
+
+      object = Object.normalize(op.data["object"], false)
+
+      assert object.data["repliesCount"] == 0
+    end
+
+    test "it logs issues with objects deletion", %{
+      delete: delete,
+      object: object
+    } do
+      {:ok, _object} =
+        object
+        |> Object.change(%{data: Map.delete(object.data, "actor")})
+        |> Repo.update()
+
+      LoggerMock
+      |> expect(:error, fn str -> assert str =~ "The object doesn't have an actor" end)
+
+      {:error, :no_object_actor} = SideEffects.handle(delete)
+    end
+  end
+end
index 297fc0b84d1b2a8bea04b36618bd280856fac93c..50af7a5076523f586e1a40b01b389cd1cd68950b 100644 (file)
@@ -19,7 +19,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
   alias Pleroma.Web.ActivityPub.SideEffects
   alias Pleroma.Web.CommonAPI
 
-  import ExUnit.CaptureLog
   import Mock
   import Pleroma.Factory
 
@@ -131,115 +130,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
     end
   end
 
-  describe "delete objects" do
-    setup do
-      user = insert(:user)
-      other_user = insert(:user)
-
-      {:ok, op} = CommonAPI.post(other_user, %{status: "big oof"})
-      {:ok, post} = CommonAPI.post(user, %{status: "hey", in_reply_to_id: op})
-      {:ok, favorite} = CommonAPI.favorite(user, post.id)
-      object = Object.normalize(post)
-      {:ok, delete_data, _meta} = Builder.delete(user, object.data["id"])
-      {:ok, delete_user_data, _meta} = Builder.delete(user, user.ap_id)
-      {:ok, delete, _meta} = ActivityPub.persist(delete_data, local: true)
-      {:ok, delete_user, _meta} = ActivityPub.persist(delete_user_data, local: true)
-
-      %{
-        user: user,
-        delete: delete,
-        post: post,
-        object: object,
-        delete_user: delete_user,
-        op: op,
-        favorite: favorite
-      }
-    end
-
-    test "it handles object deletions", %{
-      delete: delete,
-      post: post,
-      object: object,
-      user: user,
-      op: op,
-      favorite: favorite
-    } do
-      with_mock Pleroma.Web.ActivityPub.ActivityPub, [:passthrough],
-        stream_out: fn _ -> nil end,
-        stream_out_participations: fn _, _ -> nil end do
-        {:ok, delete, _} = SideEffects.handle(delete)
-        user = User.get_cached_by_ap_id(object.data["actor"])
-
-        assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out(delete))
-        assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out_participations(object, user))
-      end
-
-      object = Object.get_by_id(object.id)
-      assert object.data["type"] == "Tombstone"
-      refute Activity.get_by_id(post.id)
-      refute Activity.get_by_id(favorite.id)
-
-      user = User.get_by_id(user.id)
-      assert user.note_count == 0
-
-      object = Object.normalize(op.data["object"], false)
-
-      assert object.data["repliesCount"] == 0
-    end
-
-    test "it handles object deletions when the object itself has been pruned", %{
-      delete: delete,
-      post: post,
-      object: object,
-      user: user,
-      op: op
-    } do
-      with_mock Pleroma.Web.ActivityPub.ActivityPub, [:passthrough],
-        stream_out: fn _ -> nil end,
-        stream_out_participations: fn _, _ -> nil end do
-        {:ok, delete, _} = SideEffects.handle(delete)
-        user = User.get_cached_by_ap_id(object.data["actor"])
-
-        assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out(delete))
-        assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out_participations(object, user))
-      end
-
-      object = Object.get_by_id(object.id)
-      assert object.data["type"] == "Tombstone"
-      refute Activity.get_by_id(post.id)
-
-      user = User.get_by_id(user.id)
-      assert user.note_count == 0
-
-      object = Object.normalize(op.data["object"], false)
-
-      assert object.data["repliesCount"] == 0
-    end
-
-    test "it handles user deletions", %{delete_user: delete, user: user} do
-      {:ok, _delete, _} = SideEffects.handle(delete)
-      ObanHelpers.perform_all()
-
-      assert User.get_cached_by_ap_id(user.ap_id).deactivated
-    end
-
-    test "it logs issues with objects deletion", %{
-      delete: delete,
-      object: object
-    } do
-      {:ok, object} =
-        object
-        |> Object.change(%{data: Map.delete(object.data, "actor")})
-        |> Repo.update()
-
-      Object.invalid_object_cache(object)
-
-      assert capture_log(fn ->
-               {:error, :no_object_actor} = SideEffects.handle(delete)
-             end) =~ "object doesn't have an actor"
-    end
-  end
-
   describe "EmojiReact objects" do
     setup do
       poster = insert(:user)
index 02f49c5906a2847c4c2d6aff7d8c0b1b95512765..f20e3d955e33dafcdd1728da1bc24d4372b3e4df 100644 (file)
@@ -138,6 +138,8 @@ defmodule Pleroma.Web.ConnCase do
 
     Pleroma.DataCase.stub_pipeline()
 
+    Mox.verify_on_exit!()
+
     {:ok, conn: Phoenix.ConnTest.build_conn()}
   end
 end
index 5c657c1d92cd9a656249ba80c8da8ba08d31018c..0b41f0f635a7cd0ccffc38e239d3f1d237f89046 100644 (file)
@@ -85,6 +85,8 @@ defmodule Pleroma.DataCase do
 
     stub_pipeline()
 
+    Mox.verify_on_exit!()
+
     :ok
   end
 
index a600a64581d5700d8442a3e073910f290f1ea29c..442ff5b7199e1f1bedacf4a7ee86f1e4855fe816 100644 (file)
@@ -13,7 +13,10 @@ Mox.defmock(Pleroma.Web.ActivityPub.MRFMock,
 )
 
 Mox.defmock(Pleroma.Web.ActivityPub.ActivityPubMock,
-  for: Pleroma.Web.ActivityPub.ActivityPub.Persisting
+  for: [
+    Pleroma.Web.ActivityPub.ActivityPub.Persisting,
+    Pleroma.Web.ActivityPub.ActivityPub.Streaming
+  ]
 )
 
 Mox.defmock(Pleroma.Web.ActivityPub.SideEffectsMock,
@@ -23,3 +26,5 @@ Mox.defmock(Pleroma.Web.ActivityPub.SideEffectsMock,
 Mox.defmock(Pleroma.Web.FederatorMock, for: Pleroma.Web.Federator.Publishing)
 
 Mox.defmock(Pleroma.ConfigMock, for: Pleroma.Config.Getting)
+
+Mox.defmock(Pleroma.LoggerMock, for: Pleroma.Logging)