Migrations: Move Notification migration code to helper
authorlain <lain@soykaf.club>
Sat, 6 Jun 2020 13:33:02 +0000 (15:33 +0200)
committerlain <lain@soykaf.club>
Sat, 6 Jun 2020 13:33:02 +0000 (15:33 +0200)
lib/pleroma/migration_helper.ex [new file with mode: 0644]
lib/pleroma/notification.ex
priv/repo/migrations/20200602125218_backfill_notification_types.exs
test/migration_helper_test.exs [new file with mode: 0644]
test/notification_test.exs

diff --git a/lib/pleroma/migration_helper.ex b/lib/pleroma/migration_helper.ex
new file mode 100644 (file)
index 0000000..e6346af
--- /dev/null
@@ -0,0 +1,85 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.MigrationHelper do
+  alias Pleroma.User
+  alias Pleroma.Object
+  alias Pleroma.Notification
+  alias Pleroma.Repo
+
+  import Ecto.Query
+
+  def fill_in_notification_types do
+    query =
+      from(n in Pleroma.Notification,
+        where: is_nil(n.type),
+        preload: :activity
+      )
+
+    query
+    |> Repo.all()
+    |> Enum.each(fn notification ->
+      type =
+        notification.activity
+        |> type_from_activity()
+
+      notification
+      |> Notification.changeset(%{type: type})
+      |> Repo.update()
+    end)
+  end
+
+  # This is copied over from Notifications to keep this stable.
+  defp type_from_activity(%{data: %{"type" => type}} = activity) do
+    case type do
+      "Follow" ->
+        accepted_function = fn activity ->
+          with %User{} = follower <- User.get_by_ap_id(activity.data["actor"]),
+               %User{} = followed <- User.get_by_ap_id(activity.data["object"]) do
+            Pleroma.FollowingRelationship.following?(follower, followed)
+          end
+        end
+
+        if accepted_function.(activity) do
+          "follow"
+        else
+          "follow_request"
+        end
+
+      "Announce" ->
+        "reblog"
+
+      "Like" ->
+        "favourite"
+
+      "Move" ->
+        "move"
+
+      "EmojiReact" ->
+        "pleroma:emoji_reaction"
+
+      # Compatibility with old reactions
+      "EmojiReaction" ->
+        "pleroma:emoji_reaction"
+
+      "Create" ->
+        activity
+        |> type_from_activity_object()
+
+      t ->
+        raise "No notification type for activity type #{t}"
+    end
+  end
+
+  defp type_from_activity_object(%{data: %{"type" => "Create", "object" => %{}}}), do: "mention"
+
+  defp type_from_activity_object(%{data: %{"type" => "Create"}} = activity) do
+    object = Object.get_by_ap_id(activity.data["object"])
+
+    case object && object.data["type"] do
+      "ChatMessage" -> "pleroma:chat_mention"
+      _ -> "mention"
+    end
+  end
+end
index 5c8994e358e3f4ef9069982aaef8d51f7a4ff619..682a26912a5a7fe04d5af08ee256de2ec089d0d4 100644 (file)
@@ -40,26 +40,6 @@ defmodule Pleroma.Notification do
     timestamps()
   end
 
-  def fill_in_notification_types do
-    query =
-      from(n in __MODULE__,
-        where: is_nil(n.type),
-        preload: :activity
-      )
-
-    query
-    |> Repo.all()
-    |> Enum.each(fn notification ->
-      type =
-        notification.activity
-        |> type_from_activity(no_cachex: true)
-
-      notification
-      |> changeset(%{type: type})
-      |> Repo.update()
-    end)
-  end
-
   def update_notification_type(user, activity) do
     with %__MODULE__{} = notification <-
            Repo.get_by(__MODULE__, user_id: user.id, activity_id: activity.id) do
@@ -371,23 +351,10 @@ defmodule Pleroma.Notification do
     {:ok, notifications}
   end
 
-  defp type_from_activity(%{data: %{"type" => type}} = activity, opts \\ []) do
+  defp type_from_activity(%{data: %{"type" => type}} = activity) do
     case type do
       "Follow" ->
-        accepted_function =
-          if Keyword.get(opts, :no_cachex, false) do
-            # A special function to make this usable in a migration.
-            fn activity ->
-              with %User{} = follower <- User.get_by_ap_id(activity.data["actor"]),
-                   %User{} = followed <- User.get_by_ap_id(activity.data["object"]) do
-                Pleroma.FollowingRelationship.following?(follower, followed)
-              end
-            end
-          else
-            &Activity.follow_accepted?/1
-          end
-
-        if accepted_function.(activity) do
+        if Activity.follow_accepted?(activity) do
           "follow"
         else
           "follow_request"
index 493c0280c9237a61122f461d0fe220163fb799dd..58943fad039d69e9632131ba35779a00f1925008 100644 (file)
@@ -2,7 +2,7 @@ defmodule Pleroma.Repo.Migrations.BackfillNotificationTypes do
   use Ecto.Migration
 
   def up do
-    Pleroma.Notification.fill_in_notification_types()
+    Pleroma.MigrationHelper.fill_in_notification_types()
   end
 
   def down do
diff --git a/test/migration_helper_test.exs b/test/migration_helper_test.exs
new file mode 100644 (file)
index 0000000..1c81739
--- /dev/null
@@ -0,0 +1,56 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.MigrationHelperTest do
+  use Pleroma.DataCase
+
+  alias Pleroma.Activity
+  alias Pleroma.MigrationHelper
+  alias Pleroma.Notification
+  alias Pleroma.Repo
+  alias Pleroma.Web.CommonAPI
+
+  import Pleroma.Factory
+
+  describe "fill_in_notification_types" do
+    test "it fills in missing notification types" do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, post} = CommonAPI.post(user, %{status: "yeah, @#{other_user.nickname}"})
+      {:ok, chat} = CommonAPI.post_chat_message(user, other_user, "yo")
+      {:ok, react} = CommonAPI.react_with_emoji(post.id, other_user, "☕")
+      {:ok, like} = CommonAPI.favorite(other_user, post.id)
+      {:ok, react_2} = CommonAPI.react_with_emoji(post.id, other_user, "☕")
+
+      data =
+        react_2.data
+        |> Map.put("type", "EmojiReaction")
+
+      {:ok, react_2} =
+        react_2
+        |> Activity.change(%{data: data})
+        |> Repo.update()
+
+      assert {5, nil} = Repo.update_all(Notification, set: [type: nil])
+
+      MigrationHelper.fill_in_notification_types()
+
+      assert %{type: "mention"} =
+               Repo.get_by(Notification, user_id: other_user.id, activity_id: post.id)
+
+      assert %{type: "favourite"} =
+               Repo.get_by(Notification, user_id: user.id, activity_id: like.id)
+
+      assert %{type: "pleroma:emoji_reaction"} =
+               Repo.get_by(Notification, user_id: user.id, activity_id: react.id)
+
+      assert %{type: "pleroma:emoji_reaction"} =
+               Repo.get_by(Notification, user_id: user.id, activity_id: react_2.id)
+
+      assert %{type: "pleroma:chat_mention"} =
+               Repo.get_by(Notification, user_id: other_user.id, activity_id: chat.id)
+    end
+  end
+end
index f2115a29efd266d2548a056ddc604b76af774c22..b9bbdceca84ca814122d48e0b93ed4da4dc1c6ed 100644 (file)
@@ -8,7 +8,6 @@ defmodule Pleroma.NotificationTest do
   import Pleroma.Factory
   import Mock
 
-  alias Pleroma.Activity
   alias Pleroma.FollowingRelationship
   alias Pleroma.Notification
   alias Pleroma.Repo
@@ -22,47 +21,6 @@ defmodule Pleroma.NotificationTest do
   alias Pleroma.Web.Push
   alias Pleroma.Web.Streamer
 
-  describe "fill_in_notification_types" do
-    test "it fills in missing notification types" do
-      user = insert(:user)
-      other_user = insert(:user)
-
-      {:ok, post} = CommonAPI.post(user, %{status: "yeah, @#{other_user.nickname}"})
-      {:ok, chat} = CommonAPI.post_chat_message(user, other_user, "yo")
-      {:ok, react} = CommonAPI.react_with_emoji(post.id, other_user, "☕")
-      {:ok, like} = CommonAPI.favorite(other_user, post.id)
-      {:ok, react_2} = CommonAPI.react_with_emoji(post.id, other_user, "☕")
-
-      data =
-        react_2.data
-        |> Map.put("type", "EmojiReaction")
-
-      {:ok, react_2} =
-        react_2
-        |> Activity.change(%{data: data})
-        |> Repo.update()
-
-      assert {5, nil} = Repo.update_all(Notification, set: [type: nil])
-
-      Notification.fill_in_notification_types()
-
-      assert %{type: "mention"} =
-               Repo.get_by(Notification, user_id: other_user.id, activity_id: post.id)
-
-      assert %{type: "favourite"} =
-               Repo.get_by(Notification, user_id: user.id, activity_id: like.id)
-
-      assert %{type: "pleroma:emoji_reaction"} =
-               Repo.get_by(Notification, user_id: user.id, activity_id: react.id)
-
-      assert %{type: "pleroma:emoji_reaction"} =
-               Repo.get_by(Notification, user_id: user.id, activity_id: react_2.id)
-
-      assert %{type: "pleroma:chat_mention"} =
-               Repo.get_by(Notification, user_id: other_user.id, activity_id: chat.id)
-    end
-  end
-
   describe "create_notifications" do
     test "creates a notification for an emoji reaction" do
       user = insert(:user)