Migrations: Move Notification migration code to helper
This commit is contained in:
parent
9fa3f0b156
commit
9189b489ee
5 changed files with 144 additions and 78 deletions
85
lib/pleroma/migration_helper.ex
Normal file
85
lib/pleroma/migration_helper.ex
Normal file
|
@ -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
|
|
@ -40,26 +40,6 @@ defmodule Pleroma.Notification do
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
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
|
def update_notification_type(user, activity) do
|
||||||
with %__MODULE__{} = notification <-
|
with %__MODULE__{} = notification <-
|
||||||
Repo.get_by(__MODULE__, user_id: user.id, activity_id: activity.id) do
|
Repo.get_by(__MODULE__, user_id: user.id, activity_id: activity.id) do
|
||||||
|
@ -371,23 +351,10 @@ defp do_create_notifications(%Activity{} = activity, options) do
|
||||||
{:ok, notifications}
|
{:ok, notifications}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp type_from_activity(%{data: %{"type" => type}} = activity, opts \\ []) do
|
defp type_from_activity(%{data: %{"type" => type}} = activity) do
|
||||||
case type do
|
case type do
|
||||||
"Follow" ->
|
"Follow" ->
|
||||||
accepted_function =
|
if Activity.follow_accepted?(activity) do
|
||||||
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
|
|
||||||
"follow"
|
"follow"
|
||||||
else
|
else
|
||||||
"follow_request"
|
"follow_request"
|
||||||
|
|
|
@ -2,7 +2,7 @@ defmodule Pleroma.Repo.Migrations.BackfillNotificationTypes do
|
||||||
use Ecto.Migration
|
use Ecto.Migration
|
||||||
|
|
||||||
def up do
|
def up do
|
||||||
Pleroma.Notification.fill_in_notification_types()
|
Pleroma.MigrationHelper.fill_in_notification_types()
|
||||||
end
|
end
|
||||||
|
|
||||||
def down do
|
def down do
|
||||||
|
|
56
test/migration_helper_test.exs
Normal file
56
test/migration_helper_test.exs
Normal file
|
@ -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
|
|
@ -8,7 +8,6 @@ defmodule Pleroma.NotificationTest do
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
import Mock
|
import Mock
|
||||||
|
|
||||||
alias Pleroma.Activity
|
|
||||||
alias Pleroma.FollowingRelationship
|
alias Pleroma.FollowingRelationship
|
||||||
alias Pleroma.Notification
|
alias Pleroma.Notification
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
|
@ -22,47 +21,6 @@ defmodule Pleroma.NotificationTest do
|
||||||
alias Pleroma.Web.Push
|
alias Pleroma.Web.Push
|
||||||
alias Pleroma.Web.Streamer
|
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
|
describe "create_notifications" do
|
||||||
test "creates a notification for an emoji reaction" do
|
test "creates a notification for an emoji reaction" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
Loading…
Reference in a new issue