From fa870c7188ec8126f5066a46a6ea9cf1431991dc Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Sun, 5 Jun 2022 15:02:25 -0400 Subject: [PATCH] Create Update notifications --- lib/pleroma/notification.ex | 22 +++++++- ...85734_add_update_to_notifications_enum.exs | 51 +++++++++++++++++++ test/pleroma/notification_test.exs | 46 +++++++++++++++++ 3 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 priv/repo/migrations/20220605185734_add_update_to_notifications_enum.exs diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index d8878338e..e62ae0ec9 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -384,7 +384,7 @@ def create_notifications(%Activity{data: %{"to" => _, "type" => "Create"}} = act end def create_notifications(%Activity{data: %{"type" => type}} = activity, options) - when type in ["Follow", "Like", "Announce", "Move", "EmojiReact", "Flag"] do + when type in ["Follow", "Like", "Announce", "Move", "EmojiReact", "Flag", "Update"] do do_create_notifications(activity, options) end @@ -438,6 +438,9 @@ defp type_from_activity(%{data: %{"type" => type}} = activity) do activity |> type_from_activity_object() + "Update" -> + "update" + t -> raise "No notification type for activity type #{t}" end @@ -503,7 +506,7 @@ def create_poll_notifications(%Activity{} = activity) do def get_notified_from_activity(activity, local_only \\ true) def get_notified_from_activity(%Activity{data: %{"type" => type}} = activity, local_only) - when type in ["Create", "Like", "Announce", "Follow", "Move", "EmojiReact", "Flag"] do + when type in ["Create", "Like", "Announce", "Follow", "Move", "EmojiReact", "Flag", "Update"] do potential_receiver_ap_ids = get_potential_receiver_ap_ids(activity) potential_receivers = @@ -543,6 +546,21 @@ def get_potential_receiver_ap_ids(%{data: %{"type" => "Flag", "actor" => actor}} (User.all_superusers() |> Enum.map(fn user -> user.ap_id end)) -- [actor] end + # Update activity: notify all who repeated this + def get_potential_receiver_ap_ids(%{data: %{"type" => "Update", "actor" => actor}} = activity) do + with %Object{data: %{"id" => object_id}} <- Object.normalize(activity, fetch: false) do + repeaters = + Activity.Queries.by_type("Announce") + |> Activity.Queries.by_object_id(object_id) + |> Activity.with_joined_user_actor() + |> where([a, u], u.local) + |> select([a, u], u.ap_id) + |> Repo.all() + + repeaters -- [actor] + end + end + def get_potential_receiver_ap_ids(activity) do [] |> Utils.maybe_notify_to_recipients(activity) diff --git a/priv/repo/migrations/20220605185734_add_update_to_notifications_enum.exs b/priv/repo/migrations/20220605185734_add_update_to_notifications_enum.exs new file mode 100644 index 000000000..0656c885f --- /dev/null +++ b/priv/repo/migrations/20220605185734_add_update_to_notifications_enum.exs @@ -0,0 +1,51 @@ +defmodule Pleroma.Repo.Migrations.AddUpdateToNotificationsEnum do + use Ecto.Migration + + @disable_ddl_transaction true + + def up do + """ + alter type notification_type add value 'update' + """ + |> execute() + end + + # 20210717000000_add_poll_to_notifications_enum.exs + def down do + alter table(:notifications) do + modify(:type, :string) + end + + """ + delete from notifications where type = 'update' + """ + |> execute() + + """ + drop type if exists notification_type + """ + |> execute() + + """ + create type notification_type as enum ( + 'follow', + 'follow_request', + 'mention', + 'move', + 'pleroma:emoji_reaction', + 'pleroma:chat_mention', + 'reblog', + 'favourite', + 'pleroma:report', + 'poll' + ) + """ + |> execute() + + """ + alter table notifications + alter column type type notification_type using (type::notification_type) + """ + |> execute() + end +end diff --git a/test/pleroma/notification_test.exs b/test/pleroma/notification_test.exs index 8db208878..68330465b 100644 --- a/test/pleroma/notification_test.exs +++ b/test/pleroma/notification_test.exs @@ -127,6 +127,28 @@ test "does not create a notification for subscribed users if status is a reply" subscriber_notifications = Notification.for_user(subscriber) assert Enum.empty?(subscriber_notifications) end + + test "it sends edited notifications to those who repeated a status" do + user = insert(:user) + repeated_user = insert(:user) + other_user = insert(:user) + + {:ok, activity_one} = + CommonAPI.post(user, %{ + status: "hey @#{other_user.nickname}!" + }) + + {:ok, _activity_two} = CommonAPI.repeat(activity_one.id, repeated_user) + + {:ok, _edit_activity} = + CommonAPI.update(user, activity_one, %{ + status: "hey @#{other_user.nickname}! mew mew" + }) + + assert [%{type: "reblog"}] = Notification.for_user(user) + assert [%{type: "update"}] = Notification.for_user(repeated_user) + assert [%{type: "mention"}] = Notification.for_user(other_user) + end end test "create_poll_notifications/1" do @@ -838,6 +860,30 @@ test "it returns following domain-blocking recipient in enabled recipients list" assert [other_user] == enabled_receivers assert [] == disabled_receivers end + + test "it sends edited notifications to those who repeated a status" do + user = insert(:user) + repeated_user = insert(:user) + other_user = insert(:user) + + {:ok, activity_one} = + CommonAPI.post(user, %{ + status: "hey @#{other_user.nickname}!" + }) + + {:ok, _activity_two} = CommonAPI.repeat(activity_one.id, repeated_user) + + {:ok, edit_activity} = + CommonAPI.update(user, activity_one, %{ + status: "hey @#{other_user.nickname}! mew mew" + }) + + {enabled_receivers, _disabled_receivers} = + Notification.get_notified_from_activity(edit_activity) + + assert repeated_user in enabled_receivers + assert other_user not in enabled_receivers + end end describe "notification lifecycle" do