1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.NotificationTest do
11 alias Pleroma.FollowingRelationship
12 alias Pleroma.Notification
13 alias Pleroma.Tests.ObanHelpers
15 alias Pleroma.Web.ActivityPub.ActivityPub
16 alias Pleroma.Web.ActivityPub.Builder
17 alias Pleroma.Web.ActivityPub.Transmogrifier
18 alias Pleroma.Web.CommonAPI
19 alias Pleroma.Web.MastodonAPI.NotificationView
20 alias Pleroma.Web.Push
21 alias Pleroma.Web.Streamer
23 describe "create_notifications" do
24 test "creates a notification for an emoji reaction" do
26 other_user = insert(:user)
28 {:ok, activity} = CommonAPI.post(user, %{status: "yeah"})
29 {:ok, activity} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
31 {:ok, [notification]} = Notification.create_notifications(activity)
33 assert notification.user_id == user.id
36 test "notifies someone when they are directly addressed" do
38 other_user = insert(:user)
39 third_user = insert(:user)
42 CommonAPI.post(user, %{
43 status: "hey @#{other_user.nickname} and @#{third_user.nickname}"
46 {:ok, [notification, other_notification]} = Notification.create_notifications(activity)
48 notified_ids = Enum.sort([notification.user_id, other_notification.user_id])
49 assert notified_ids == [other_user.id, third_user.id]
50 assert notification.activity_id == activity.id
51 assert other_notification.activity_id == activity.id
53 assert [%Pleroma.Marker{unread_count: 2}] =
54 Pleroma.Marker.get_markers(other_user, ["notifications"])
57 test "it creates a notification for subscribed users" do
59 subscriber = insert(:user)
61 User.subscribe(subscriber, user)
63 {:ok, status} = CommonAPI.post(user, %{status: "Akariiiin"})
64 {:ok, [notification]} = Notification.create_notifications(status)
66 assert notification.user_id == subscriber.id
69 test "does not create a notification for subscribed users if status is a reply" do
71 other_user = insert(:user)
72 subscriber = insert(:user)
74 User.subscribe(subscriber, other_user)
76 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
78 {:ok, _reply_activity} =
79 CommonAPI.post(other_user, %{
81 in_reply_to_status_id: activity.id
84 user_notifications = Notification.for_user(user)
85 assert length(user_notifications) == 1
87 subscriber_notifications = Notification.for_user(subscriber)
88 assert Enum.empty?(subscriber_notifications)
92 describe "CommonApi.post/2 notification-related functionality" do
93 test_with_mock "creates but does NOT send notification to blocker user",
98 blocker = insert(:user)
99 {:ok, _user_relationship} = User.block(blocker, user)
101 {:ok, _activity} = CommonAPI.post(user, %{status: "hey @#{blocker.nickname}!"})
103 blocker_id = blocker.id
104 assert [%Notification{user_id: ^blocker_id}] = Repo.all(Notification)
105 refute called(Push.send(:_))
108 test_with_mock "creates but does NOT send notification to notification-muter user",
113 muter = insert(:user)
114 {:ok, _user_relationships} = User.mute(muter, user)
116 {:ok, _activity} = CommonAPI.post(user, %{status: "hey @#{muter.nickname}!"})
119 assert [%Notification{user_id: ^muter_id}] = Repo.all(Notification)
120 refute called(Push.send(:_))
123 test_with_mock "creates but does NOT send notification to thread-muter user",
128 thread_muter = insert(:user)
130 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{thread_muter.nickname}!"})
132 {:ok, _} = CommonAPI.add_mute(thread_muter, activity)
134 {:ok, _same_context_activity} =
135 CommonAPI.post(user, %{
136 status: "hey-hey-hey @#{thread_muter.nickname}!",
137 in_reply_to_status_id: activity.id
140 [pre_mute_notification, post_mute_notification] =
141 Repo.all(from(n in Notification, where: n.user_id == ^thread_muter.id, order_by: n.id))
143 pre_mute_notification_id = pre_mute_notification.id
144 post_mute_notification_id = post_mute_notification.id
149 %Notification{id: ^pre_mute_notification_id} -> true
158 %Notification{id: ^post_mute_notification_id} -> true
166 describe "create_notification" do
167 @tag needs_streamer: true
168 test "it creates a notification for user and send to the 'user' and the 'user:notification' stream" do
173 Streamer.get_topic_and_add_socket("user", user)
174 assert_receive {:render_with_user, _, _, _}, 4_000
177 task_user_notification =
179 Streamer.get_topic_and_add_socket("user:notification", user)
180 assert_receive {:render_with_user, _, _, _}, 4_000
183 activity = insert(:note_activity)
185 notify = Notification.create_notification(activity, user)
186 assert notify.user_id == user.id
188 Task.await(task_user_notification)
191 test "it creates a notification for user if the user blocks the activity author" do
192 activity = insert(:note_activity)
193 author = User.get_cached_by_ap_id(activity.data["actor"])
195 {:ok, _user_relationship} = User.block(user, author)
197 assert Notification.create_notification(activity, user)
200 test "it creates a notification for the user if the user mutes the activity author" do
201 muter = insert(:user)
202 muted = insert(:user)
203 {:ok, _} = User.mute(muter, muted)
204 muter = Repo.get(User, muter.id)
205 {:ok, activity} = CommonAPI.post(muted, %{status: "Hi @#{muter.nickname}"})
207 assert Notification.create_notification(activity, muter)
210 test "notification created if user is muted without notifications" do
211 muter = insert(:user)
212 muted = insert(:user)
214 {:ok, _user_relationships} = User.mute(muter, muted, false)
216 {:ok, activity} = CommonAPI.post(muted, %{status: "Hi @#{muter.nickname}"})
218 assert Notification.create_notification(activity, muter)
221 test "it creates a notification for an activity from a muted thread" do
222 muter = insert(:user)
223 other_user = insert(:user)
224 {:ok, activity} = CommonAPI.post(muter, %{status: "hey"})
225 CommonAPI.add_mute(muter, activity)
228 CommonAPI.post(other_user, %{
229 status: "Hi @#{muter.nickname}",
230 in_reply_to_status_id: activity.id
233 assert Notification.create_notification(activity, muter)
236 test "it disables notifications from followers" do
237 follower = insert(:user)
240 insert(:user, notification_settings: %Pleroma.User.NotificationSetting{from_followers: false})
242 User.follow(follower, followed)
243 {:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
244 refute Notification.create_notification(activity, followed)
247 test "it disables notifications from strangers" do
248 follower = insert(:user)
252 notification_settings: %Pleroma.User.NotificationSetting{from_strangers: false}
255 {:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
256 refute Notification.create_notification(activity, followed)
259 test "it disables notifications from people the user follows" do
261 insert(:user, notification_settings: %Pleroma.User.NotificationSetting{from_following: false})
263 followed = insert(:user)
264 User.follow(follower, followed)
265 follower = Repo.get(User, follower.id)
266 {:ok, activity} = CommonAPI.post(followed, %{status: "hey @#{follower.nickname}"})
267 refute Notification.create_notification(activity, follower)
270 test "it doesn't create a notification for user if he is the activity author" do
271 activity = insert(:note_activity)
272 author = User.get_cached_by_ap_id(activity.data["actor"])
274 refute Notification.create_notification(activity, author)
277 test "it doesn't create duplicate notifications for follow+subscribed users" do
279 subscriber = insert(:user)
281 {:ok, _, _, _} = CommonAPI.follow(subscriber, user)
282 User.subscribe(subscriber, user)
283 {:ok, status} = CommonAPI.post(user, %{status: "Akariiiin"})
284 {:ok, [_notif]} = Notification.create_notifications(status)
287 test "it doesn't create subscription notifications if the recipient cannot see the status" do
289 subscriber = insert(:user)
291 User.subscribe(subscriber, user)
293 {:ok, status} = CommonAPI.post(user, %{status: "inwisible", visibility: "direct"})
295 assert {:ok, []} == Notification.create_notifications(status)
299 describe "follow / follow_request notifications" do
300 test "it creates `follow` notification for approved Follow activity" do
302 followed_user = insert(:user, locked: false)
304 {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
305 assert FollowingRelationship.following?(user, followed_user)
306 assert [notification] = Notification.for_user(followed_user)
308 assert %{type: "follow"} =
309 NotificationView.render("show.json", %{
310 notification: notification,
315 test "it creates `follow_request` notification for pending Follow activity" do
317 followed_user = insert(:user, locked: true)
319 {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
320 refute FollowingRelationship.following?(user, followed_user)
321 assert [notification] = Notification.for_user(followed_user)
323 render_opts = %{notification: notification, for: followed_user}
324 assert %{type: "follow_request"} = NotificationView.render("show.json", render_opts)
326 # After request is accepted, the same notification is rendered with type "follow":
327 assert {:ok, _} = CommonAPI.accept_follow_request(user, followed_user)
329 notification_id = notification.id
330 assert [%{id: ^notification_id}] = Notification.for_user(followed_user)
331 assert %{type: "follow"} = NotificationView.render("show.json", render_opts)
334 test "it doesn't create a notification for follow-unfollow-follow chains" do
336 followed_user = insert(:user, locked: false)
338 {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
339 assert FollowingRelationship.following?(user, followed_user)
340 assert [notification] = Notification.for_user(followed_user)
342 CommonAPI.unfollow(user, followed_user)
343 {:ok, _, _, _activity_dupe} = CommonAPI.follow(user, followed_user)
345 notification_id = notification.id
346 assert [%{id: ^notification_id}] = Notification.for_user(followed_user)
349 test "dismisses the notification on follow request rejection" do
350 user = insert(:user, locked: true)
351 follower = insert(:user)
352 {:ok, _, _, _follow_activity} = CommonAPI.follow(follower, user)
353 assert [notification] = Notification.for_user(user)
354 {:ok, _follower} = CommonAPI.reject_follow_request(follower, user)
355 assert [] = Notification.for_user(user)
359 describe "get notification" do
360 test "it gets a notification that belongs to the user" do
362 other_user = insert(:user)
364 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
366 {:ok, [notification]} = Notification.create_notifications(activity)
367 {:ok, notification} = Notification.get(other_user, notification.id)
369 assert notification.user_id == other_user.id
372 test "it returns error if the notification doesn't belong to the user" do
374 other_user = insert(:user)
376 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
378 {:ok, [notification]} = Notification.create_notifications(activity)
379 {:error, _notification} = Notification.get(user, notification.id)
383 describe "dismiss notification" do
384 test "it dismisses a notification that belongs to the user" do
386 other_user = insert(:user)
388 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
390 {:ok, [notification]} = Notification.create_notifications(activity)
391 {:ok, notification} = Notification.dismiss(other_user, notification.id)
393 assert notification.user_id == other_user.id
396 test "it returns error if the notification doesn't belong to the user" do
398 other_user = insert(:user)
400 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
402 {:ok, [notification]} = Notification.create_notifications(activity)
403 {:error, _notification} = Notification.dismiss(user, notification.id)
407 describe "clear notification" do
408 test "it clears all notifications belonging to the user" do
410 other_user = insert(:user)
411 third_user = insert(:user)
414 CommonAPI.post(user, %{
415 status: "hey @#{other_user.nickname} and @#{third_user.nickname} !"
418 {:ok, _notifs} = Notification.create_notifications(activity)
421 CommonAPI.post(user, %{
422 status: "hey again @#{other_user.nickname} and @#{third_user.nickname} !"
425 {:ok, _notifs} = Notification.create_notifications(activity)
426 Notification.clear(other_user)
428 assert Notification.for_user(other_user) == []
429 assert Notification.for_user(third_user) != []
433 describe "set_read_up_to()" do
434 test "it sets all notifications as read up to a specified notification ID" do
436 other_user = insert(:user)
439 CommonAPI.post(user, %{
440 status: "hey @#{other_user.nickname}!"
444 CommonAPI.post(user, %{
445 status: "hey again @#{other_user.nickname}!"
448 [n2, n1] = Notification.for_user(other_user)
453 CommonAPI.post(user, %{
454 status: "hey yet again @#{other_user.nickname}!"
457 [_, read_notification] = Notification.set_read_up_to(other_user, n2.id)
459 assert read_notification.activity.object
461 [n3, n2, n1] = Notification.for_user(other_user)
463 assert n1.seen == true
464 assert n2.seen == true
465 assert n3.seen == false
467 assert %Pleroma.Marker{} =
471 user_id: other_user.id,
472 timeline: "notifications"
475 assert m.last_read_id == to_string(n2.id)
479 describe "for_user_since/2" do
480 defp days_ago(days) do
482 NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second),
483 -days * 60 * 60 * 24,
488 test "Returns recent notifications" do
489 user1 = insert(:user)
490 user2 = insert(:user)
492 Enum.each(0..10, fn i ->
494 CommonAPI.post(user1, %{
495 status: "hey ##{i} @#{user2.nickname}!"
499 {old, new} = Enum.split(Notification.for_user(user2), 5)
501 Enum.each(old, fn notification ->
503 |> cast(%{updated_at: days_ago(10)}, [:updated_at])
504 |> Pleroma.Repo.update!()
507 recent_notifications_ids =
509 |> Notification.for_user_since(
510 NaiveDateTime.add(NaiveDateTime.utc_now(), -5 * 86_400, :second)
514 Enum.each(old, fn %{id: id} ->
515 refute id in recent_notifications_ids
518 Enum.each(new, fn %{id: id} ->
519 assert id in recent_notifications_ids
524 describe "notification target determination / get_notified_from_activity/2" do
525 test "it sends notifications to addressed users in new messages" do
527 other_user = insert(:user)
530 CommonAPI.post(user, %{
531 status: "hey @#{other_user.nickname}!"
534 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
536 assert other_user in enabled_receivers
539 test "it sends notifications to mentioned users in new messages" do
541 other_user = insert(:user)
544 "@context" => "https://www.w3.org/ns/activitystreams",
546 "to" => ["https://www.w3.org/ns/activitystreams#Public"],
547 "actor" => user.ap_id,
550 "content" => "message with a Mention tag, but no explicit tagging",
554 "href" => other_user.ap_id,
555 "name" => other_user.nickname
558 "attributedTo" => user.ap_id
562 {:ok, activity} = Transmogrifier.handle_incoming(create_activity)
564 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
566 assert other_user in enabled_receivers
569 test "it does not send notifications to users who are only cc in new messages" do
571 other_user = insert(:user)
574 "@context" => "https://www.w3.org/ns/activitystreams",
576 "to" => ["https://www.w3.org/ns/activitystreams#Public"],
577 "cc" => [other_user.ap_id],
578 "actor" => user.ap_id,
581 "content" => "hi everyone",
582 "attributedTo" => user.ap_id
586 {:ok, activity} = Transmogrifier.handle_incoming(create_activity)
588 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
590 assert other_user not in enabled_receivers
593 test "it does not send notification to mentioned users in likes" do
595 other_user = insert(:user)
596 third_user = insert(:user)
598 {:ok, activity_one} =
599 CommonAPI.post(user, %{
600 status: "hey @#{other_user.nickname}!"
603 {:ok, activity_two} = CommonAPI.favorite(third_user, activity_one.id)
605 {enabled_receivers, _disabled_receivers} =
606 Notification.get_notified_from_activity(activity_two)
608 assert other_user not in enabled_receivers
611 test "it only notifies the post's author in likes" do
613 other_user = insert(:user)
614 third_user = insert(:user)
616 {:ok, activity_one} =
617 CommonAPI.post(user, %{
618 status: "hey @#{other_user.nickname}!"
621 {:ok, like_data, _} = Builder.like(third_user, activity_one.object)
625 |> Map.put("to", [other_user.ap_id | like_data["to"]])
626 |> ActivityPub.persist(local: true)
628 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(like)
630 assert other_user not in enabled_receivers
633 test "it does not send notification to mentioned users in announces" do
635 other_user = insert(:user)
636 third_user = insert(:user)
638 {:ok, activity_one} =
639 CommonAPI.post(user, %{
640 status: "hey @#{other_user.nickname}!"
643 {:ok, activity_two} = CommonAPI.repeat(activity_one.id, third_user)
645 {enabled_receivers, _disabled_receivers} =
646 Notification.get_notified_from_activity(activity_two)
648 assert other_user not in enabled_receivers
651 test "it returns blocking recipient in disabled recipients list" do
653 other_user = insert(:user)
654 {:ok, _user_relationship} = User.block(other_user, user)
656 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
658 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
660 assert [] == enabled_receivers
661 assert [other_user] == disabled_receivers
664 test "it returns notification-muting recipient in disabled recipients list" do
666 other_user = insert(:user)
667 {:ok, _user_relationships} = User.mute(other_user, user)
669 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
671 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
673 assert [] == enabled_receivers
674 assert [other_user] == disabled_receivers
677 test "it returns thread-muting recipient in disabled recipients list" do
679 other_user = insert(:user)
681 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
683 {:ok, _} = CommonAPI.add_mute(other_user, activity)
685 {:ok, same_context_activity} =
686 CommonAPI.post(user, %{
687 status: "hey-hey-hey @#{other_user.nickname}!",
688 in_reply_to_status_id: activity.id
691 {enabled_receivers, disabled_receivers} =
692 Notification.get_notified_from_activity(same_context_activity)
694 assert [other_user] == disabled_receivers
695 refute other_user in enabled_receivers
698 test "it returns non-following domain-blocking recipient in disabled recipients list" do
699 blocked_domain = "blocked.domain"
700 user = insert(:user, %{ap_id: "https://#{blocked_domain}/@actor"})
701 other_user = insert(:user)
703 {:ok, other_user} = User.block_domain(other_user, blocked_domain)
705 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
707 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
709 assert [] == enabled_receivers
710 assert [other_user] == disabled_receivers
713 test "it returns following domain-blocking recipient in enabled recipients list" do
714 blocked_domain = "blocked.domain"
715 user = insert(:user, %{ap_id: "https://#{blocked_domain}/@actor"})
716 other_user = insert(:user)
718 {:ok, other_user} = User.block_domain(other_user, blocked_domain)
719 {:ok, other_user} = User.follow(other_user, user)
721 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
723 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
725 assert [other_user] == enabled_receivers
726 assert [] == disabled_receivers
730 describe "notification lifecycle" do
731 test "liking an activity results in 1 notification, then 0 if the activity is deleted" do
733 other_user = insert(:user)
735 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
737 assert Enum.empty?(Notification.for_user(user))
739 {:ok, _} = CommonAPI.favorite(other_user, activity.id)
741 assert length(Notification.for_user(user)) == 1
743 {:ok, _} = CommonAPI.delete(activity.id, user)
745 assert Enum.empty?(Notification.for_user(user))
748 test "liking an activity results in 1 notification, then 0 if the activity is unliked" do
750 other_user = insert(:user)
752 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
754 assert Enum.empty?(Notification.for_user(user))
756 {:ok, _} = CommonAPI.favorite(other_user, activity.id)
758 assert length(Notification.for_user(user)) == 1
760 {:ok, _} = CommonAPI.unfavorite(activity.id, other_user)
762 assert Enum.empty?(Notification.for_user(user))
765 test "repeating an activity results in 1 notification, then 0 if the activity is deleted" do
767 other_user = insert(:user)
769 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
771 assert Enum.empty?(Notification.for_user(user))
773 {:ok, _} = CommonAPI.repeat(activity.id, other_user)
775 assert length(Notification.for_user(user)) == 1
777 {:ok, _} = CommonAPI.delete(activity.id, user)
779 assert Enum.empty?(Notification.for_user(user))
782 test "repeating an activity results in 1 notification, then 0 if the activity is unrepeated" do
784 other_user = insert(:user)
786 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
788 assert Enum.empty?(Notification.for_user(user))
790 {:ok, _} = CommonAPI.repeat(activity.id, other_user)
792 assert length(Notification.for_user(user)) == 1
794 {:ok, _} = CommonAPI.unrepeat(activity.id, other_user)
796 assert Enum.empty?(Notification.for_user(user))
799 test "liking an activity which is already deleted does not generate a notification" do
801 other_user = insert(:user)
803 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
805 assert Enum.empty?(Notification.for_user(user))
807 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
809 assert Enum.empty?(Notification.for_user(user))
811 {:error, :not_found} = CommonAPI.favorite(other_user, activity.id)
813 assert Enum.empty?(Notification.for_user(user))
816 test "repeating an activity which is already deleted does not generate a notification" do
818 other_user = insert(:user)
820 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
822 assert Enum.empty?(Notification.for_user(user))
824 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
826 assert Enum.empty?(Notification.for_user(user))
828 {:error, _} = CommonAPI.repeat(activity.id, other_user)
830 assert Enum.empty?(Notification.for_user(user))
833 test "replying to a deleted post without tagging does not generate a notification" do
835 other_user = insert(:user)
837 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
838 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
840 {:ok, _reply_activity} =
841 CommonAPI.post(other_user, %{
842 status: "test reply",
843 in_reply_to_status_id: activity.id
846 assert Enum.empty?(Notification.for_user(user))
849 test "notifications are deleted if a local user is deleted" do
851 other_user = insert(:user)
854 CommonAPI.post(user, %{status: "hi @#{other_user.nickname}", visibility: "direct"})
856 refute Enum.empty?(Notification.for_user(other_user))
858 {:ok, job} = User.delete(user)
859 ObanHelpers.perform(job)
861 assert Enum.empty?(Notification.for_user(other_user))
864 test "notifications are deleted if a remote user is deleted" do
865 remote_user = insert(:user)
866 local_user = insert(:user)
869 "@context" => "https://www.w3.org/ns/activitystreams",
871 "actor" => remote_user.ap_id,
872 "id" => remote_user.ap_id <> "/activities/test",
873 "to" => [local_user.ap_id],
877 "content" => "Hello!",
881 "href" => local_user.ap_id,
882 "name" => "@#{local_user.nickname}"
885 "to" => [local_user.ap_id],
887 "attributedTo" => remote_user.ap_id
891 {:ok, _dm_activity} = Transmogrifier.handle_incoming(dm_message)
893 refute Enum.empty?(Notification.for_user(local_user))
895 delete_user_message = %{
896 "@context" => "https://www.w3.org/ns/activitystreams",
897 "id" => remote_user.ap_id <> "/activities/delete",
898 "actor" => remote_user.ap_id,
900 "object" => remote_user.ap_id
903 remote_user_url = remote_user.ap_id
906 %{method: :get, url: ^remote_user_url} ->
907 %Tesla.Env{status: 404, body: ""}
910 {:ok, _delete_activity} = Transmogrifier.handle_incoming(delete_user_message)
911 ObanHelpers.perform_all()
913 assert Enum.empty?(Notification.for_user(local_user))
916 @tag capture_log: true
917 test "move activity generates a notification" do
918 %{ap_id: old_ap_id} = old_user = insert(:user)
919 %{ap_id: new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id])
920 follower = insert(:user)
921 other_follower = insert(:user, %{allow_following_move: false})
923 User.follow(follower, old_user)
924 User.follow(other_follower, old_user)
926 old_user_url = old_user.ap_id
929 File.read!("test/fixtures/users_mock/localhost.json")
930 |> String.replace("{{nickname}}", old_user.nickname)
934 %{method: :get, url: ^old_user_url} ->
935 %Tesla.Env{status: 200, body: body}
938 Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
939 ObanHelpers.perform_all()
944 data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
947 ] = Notification.for_user(follower)
952 data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
955 ] = Notification.for_user(other_follower)
959 describe "for_user" do
960 test "it returns notifications for muted user without notifications" do
962 muted = insert(:user)
963 {:ok, _user_relationships} = User.mute(user, muted, false)
965 {:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
967 [notification] = Notification.for_user(user)
969 assert notification.activity.object
972 test "it doesn't return notifications for muted user with notifications" do
974 muted = insert(:user)
975 {:ok, _user_relationships} = User.mute(user, muted)
977 {:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
979 assert Notification.for_user(user) == []
982 test "it doesn't return notifications for blocked user" do
984 blocked = insert(:user)
985 {:ok, _user_relationship} = User.block(user, blocked)
987 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
989 assert Notification.for_user(user) == []
992 test "it doesn't return notifications for domain-blocked non-followed user" do
994 blocked = insert(:user, ap_id: "http://some-domain.com")
995 {:ok, user} = User.block_domain(user, "some-domain.com")
997 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
999 assert Notification.for_user(user) == []
1002 test "it returns notifications for domain-blocked but followed user" do
1003 user = insert(:user)
1004 blocked = insert(:user, ap_id: "http://some-domain.com")
1006 {:ok, user} = User.block_domain(user, "some-domain.com")
1007 {:ok, _} = User.follow(user, blocked)
1009 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
1011 assert length(Notification.for_user(user)) == 1
1014 test "it doesn't return notifications for muted thread" do
1015 user = insert(:user)
1016 another_user = insert(:user)
1018 {:ok, activity} = CommonAPI.post(another_user, %{status: "hey @#{user.nickname}"})
1020 {:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
1021 assert Notification.for_user(user) == []
1024 test "it returns notifications from a muted user when with_muted is set" do
1025 user = insert(:user)
1026 muted = insert(:user)
1027 {:ok, _user_relationships} = User.mute(user, muted)
1029 {:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
1031 assert length(Notification.for_user(user, %{with_muted: true})) == 1
1034 test "it doesn't return notifications from a blocked user when with_muted is set" do
1035 user = insert(:user)
1036 blocked = insert(:user)
1037 {:ok, _user_relationship} = User.block(user, blocked)
1039 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
1041 assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
1044 test "when with_muted is set, " <>
1045 "it doesn't return notifications from a domain-blocked non-followed user" do
1046 user = insert(:user)
1047 blocked = insert(:user, ap_id: "http://some-domain.com")
1048 {:ok, user} = User.block_domain(user, "some-domain.com")
1050 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
1052 assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
1055 test "it returns notifications from muted threads when with_muted is set" do
1056 user = insert(:user)
1057 another_user = insert(:user)
1059 {:ok, activity} = CommonAPI.post(another_user, %{status: "hey @#{user.nickname}"})
1061 {:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
1062 assert length(Notification.for_user(user, %{with_muted: true})) == 1