marks notifications as read after mute
authorMaksim Pechnikov <parallel588@gmail.com>
Fri, 28 Aug 2020 15:17:44 +0000 (18:17 +0300)
committerMaksim Pechnikov <parallel588@gmail.com>
Fri, 28 Aug 2020 15:17:44 +0000 (18:17 +0300)
lib/pleroma/notification.ex
lib/pleroma/web/common_api/common_api.ex
test/web/common_api/common_api_test.exs

index c1825f81044d7a5ca6afb84ccd4d6b49eac50298..b952e81fac9bdd70c637b38dd38faf2ac3a20519 100644 (file)
@@ -648,4 +648,16 @@ defmodule Pleroma.Notification do
     )
     |> Repo.one()
   end
+
+  @spec mark_as_read(User.t(), Activity.t()) :: {integer(), nil | [term()]}
+  def mark_as_read(%User{id: id}, %Activity{data: %{"context" => context}}) do
+    from(
+      n in Notification,
+      join: a in assoc(n, :activity),
+      where: n.user_id == ^id,
+      where: n.seen == false,
+      where: fragment("?->>'context'", a.data) == ^context
+    )
+    |> Repo.update_all(set: [seen: true])
+  end
 end
index 5ad2b91c265c836b20e8f4840729db768a38a73b..43e9e39a813555f7b774ad137aa8a87d8838da86 100644 (file)
@@ -452,7 +452,8 @@ defmodule Pleroma.Web.CommonAPI do
   end
 
   def add_mute(user, activity) do
-    with {:ok, _} <- ThreadMute.add_mute(user.id, activity.data["context"]) do
+    with {:ok, _} <- ThreadMute.add_mute(user.id, activity.data["context"]),
+         _ <- Pleroma.Notification.mark_as_read(user, activity) do
       {:ok, activity}
     else
       {:error, _} -> {:error, dgettext("errors", "conversation is already muted")}
index 4ba6232dc7dafe2b3f59fb13e49ec7c95f5b9149..800db9a207207921b31b6da87e4433abe6519ee8 100644 (file)
@@ -9,6 +9,7 @@ defmodule Pleroma.Web.CommonAPITest do
   alias Pleroma.Conversation.Participation
   alias Pleroma.Notification
   alias Pleroma.Object
+  alias Pleroma.Repo
   alias Pleroma.User
   alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.ActivityPub.Transmogrifier
@@ -18,6 +19,7 @@ defmodule Pleroma.Web.CommonAPITest do
 
   import Pleroma.Factory
   import Mock
+  import Ecto.Query, only: [from: 2]
 
   require Pleroma.Constants
 
@@ -808,6 +810,69 @@ defmodule Pleroma.Web.CommonAPITest do
       [user: user, activity: activity]
     end
 
+    test "marks notifications as read after mute" do
+      author = insert(:user)
+      activity = insert(:note_activity, user: author)
+
+      friend1 = insert(:user)
+      friend2 = insert(:user)
+
+      {:ok, reply_activity} =
+        CommonAPI.post(
+          friend2,
+          %{
+            status: "@#{author.nickname} @#{friend1.nickname} test reply",
+            in_reply_to_status_id: activity.id
+          }
+        )
+
+      {:ok, favorite_activity} = CommonAPI.favorite(friend2, activity.id)
+      {:ok, repeat_activity} = CommonAPI.repeat(activity.id, friend1)
+
+      assert Repo.aggregate(
+               from(n in Notification, where: n.seen == false and n.user_id == ^friend1.id),
+               :count
+             ) == 1
+
+      unread_notifications =
+        Repo.all(from(n in Notification, where: n.seen == false, where: n.user_id == ^author.id))
+
+      assert Enum.any?(unread_notifications, fn n ->
+               n.type == "favourite" && n.activity_id == favorite_activity.id
+             end)
+
+      assert Enum.any?(unread_notifications, fn n ->
+               n.type == "reblog" && n.activity_id == repeat_activity.id
+             end)
+
+      assert Enum.any?(unread_notifications, fn n ->
+               n.type == "mention" && n.activity_id == reply_activity.id
+             end)
+
+      {:ok, _} = CommonAPI.add_mute(author, activity)
+      assert CommonAPI.thread_muted?(author, activity)
+
+      assert Repo.aggregate(
+               from(n in Notification, where: n.seen == false and n.user_id == ^friend1.id),
+               :count
+             ) == 1
+
+      read_notifications =
+        Repo.all(from(n in Notification, where: n.seen == true, where: n.user_id == ^author.id))
+
+      assert Enum.any?(read_notifications, fn n ->
+               n.type == "favourite" && n.activity_id == favorite_activity.id
+             end)
+
+      assert Enum.any?(read_notifications, fn n ->
+               n.type == "reblog" && n.activity_id == repeat_activity.id
+             end)
+
+      assert Enum.any?(read_notifications, fn n ->
+               n.type == "mention" && n.activity_id == reply_activity.id
+             end)
+    end
+
     test "add mute", %{user: user, activity: activity} do
       {:ok, _} = CommonAPI.add_mute(user, activity)
       assert CommonAPI.thread_muted?(user, activity)