From 042852ecf344b4ede15a22ea0279fff8a67b75f0 Mon Sep 17 00:00:00 2001 From: Sadposter Date: Sat, 5 Jan 2019 22:54:25 +0000 Subject: [PATCH] Add check to prevent multiple follow notifications from the same user --- lib/pleroma/notification.ex | 7 ++++++- test/notification_test.exs | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 51d59870c..c7d01f63b 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -109,7 +109,12 @@ def create_notifications(_), do: {:ok, []} # TODO move to sql, too. def create_notification(%Activity{} = activity, %User{} = user) do unless User.blocks?(user, %{ap_id: activity.data["actor"]}) or - user.ap_id == activity.data["actor"] do + user.ap_id == activity.data["actor"] or + (activity.data["type"] == "Follow" and + Enum.any?(Notification.for_user(user), fn notif -> + notif.activity.data["type"] == "Follow" and + notif.activity.data["actor"] == activity.data["actor"] + end)) do notification = %Notification{user_id: user.id, activity: activity} {:ok, notification} = Repo.insert(notification) Pleroma.Web.Streamer.stream("user", notification) diff --git a/test/notification_test.exs b/test/notification_test.exs index 31c0d2c64..94fb0ab15 100644 --- a/test/notification_test.exs +++ b/test/notification_test.exs @@ -46,6 +46,43 @@ test "it doesn't create a notification for user if he is the activity author" do assert nil == Notification.create_notification(activity, author) end + + test "it doesn't create a notification for follow-unfollow-follow chains" do + user = insert(:user) + followed_user = insert(:user) + {:ok, _, _, activity} = TwitterAPI.follow(user, %{"user_id" => followed_user.id}) + Notification.create_notification(activity, followed_user) + TwitterAPI.unfollow(user, %{"user_id" => followed_user.id}) + {:ok, _, _, activity_dupe} = TwitterAPI.follow(user, %{"user_id" => followed_user.id}) + assert nil == Notification.create_notification(activity_dupe, followed_user) + end + + test "it doesn't create a notification for like-unlike-like chains" do + user = insert(:user) + liked_user = insert(:user) + {:ok, status} = TwitterAPI.create_status(liked_user, %{"status" => "Yui is best yuru"}) + {:ok, fav_status} = TwitterAPI.fav(user, status.id) + Notification.create_notification(fav_status, liked_user) + TwitterAPI.unfav(user, status.id) + {:ok, dupe} = TwitterAPI.fav(user, status.id) + assert nil == Notification.create_notification(dupe, liked_user) + end + + test "it doesn't create a notification for repeat-unrepeat-repeat chains" do + user = insert(:user) + retweeted_user = insert(:user) + + {:ok, status} = + TwitterAPI.create_status(retweeted_user, %{ + "status" => "Send dupe notifications to the shadow realm" + }) + + {:ok, retweeted_activity} = TwitterAPI.repeat(user, status.id) + Notification.create_notification(retweeted_activity, retweeted_user) + TwitterAPI.unrepeat(user, status.id) + {:ok, dupe} = TwitterAPI.repeat(user, status.id) + assert nil == Notification.create_notification(dupe, retweeted_user) + end end describe "get notification" do