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.Transmogrifier
16 alias Pleroma.Web.CommonAPI
17 alias Pleroma.Web.MastodonAPI.NotificationView
18 alias Pleroma.Web.Push
19 alias Pleroma.Web.Streamer
21 describe "create_notifications" do
22 test "creates a notification for an emoji reaction" do
24 other_user = insert(:user)
26 {:ok, activity} = CommonAPI.post(user, %{"status" => "yeah"})
27 {:ok, activity} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
29 {:ok, [notification]} = Notification.create_notifications(activity)
31 assert notification.user_id == user.id
34 test "notifies someone when they are directly addressed" do
36 other_user = insert(:user)
37 third_user = insert(:user)
40 CommonAPI.post(user, %{
41 "status" => "hey @#{other_user.nickname} and @#{third_user.nickname}"
44 {:ok, [notification, other_notification]} = Notification.create_notifications(activity)
46 notified_ids = Enum.sort([notification.user_id, other_notification.user_id])
47 assert notified_ids == [other_user.id, third_user.id]
48 assert notification.activity_id == activity.id
49 assert other_notification.activity_id == activity.id
51 assert [%Pleroma.Marker{unread_count: 2}] =
52 Pleroma.Marker.get_markers(other_user, ["notifications"])
55 test "it creates a notification for subscribed users" do
57 subscriber = insert(:user)
59 User.subscribe(subscriber, user)
61 {:ok, status} = CommonAPI.post(user, %{"status" => "Akariiiin"})
62 {:ok, [notification]} = Notification.create_notifications(status)
64 assert notification.user_id == subscriber.id
67 test "does not create a notification for subscribed users if status is a reply" do
69 other_user = insert(:user)
70 subscriber = insert(:user)
72 User.subscribe(subscriber, other_user)
74 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
76 {:ok, _reply_activity} =
77 CommonAPI.post(other_user, %{
78 "status" => "test reply",
79 "in_reply_to_status_id" => activity.id
82 user_notifications = Notification.for_user(user)
83 assert length(user_notifications) == 1
85 subscriber_notifications = Notification.for_user(subscriber)
86 assert Enum.empty?(subscriber_notifications)
90 describe "CommonApi.post/2 notification-related functionality" do
91 test_with_mock "creates but does NOT send notification to blocker user",
96 blocker = insert(:user)
97 {:ok, _user_relationship} = User.block(blocker, user)
99 {:ok, _activity} = CommonAPI.post(user, %{"status" => "hey @#{blocker.nickname}!"})
101 blocker_id = blocker.id
102 assert [%Notification{user_id: ^blocker_id}] = Repo.all(Notification)
103 refute called(Push.send(:_))
106 test_with_mock "creates but does NOT send notification to notification-muter user",
111 muter = insert(:user)
112 {:ok, _user_relationships} = User.mute(muter, user)
114 {:ok, _activity} = CommonAPI.post(user, %{"status" => "hey @#{muter.nickname}!"})
117 assert [%Notification{user_id: ^muter_id}] = Repo.all(Notification)
118 refute called(Push.send(:_))
121 test_with_mock "creates but does NOT send notification to thread-muter user",
126 thread_muter = insert(:user)
128 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{thread_muter.nickname}!"})
130 {:ok, _} = CommonAPI.add_mute(thread_muter, activity)
132 {:ok, _same_context_activity} =
133 CommonAPI.post(user, %{
134 "status" => "hey-hey-hey @#{thread_muter.nickname}!",
135 "in_reply_to_status_id" => activity.id
138 [pre_mute_notification, post_mute_notification] =
139 Repo.all(from(n in Notification, where: n.user_id == ^thread_muter.id, order_by: n.id))
141 pre_mute_notification_id = pre_mute_notification.id
142 post_mute_notification_id = post_mute_notification.id
147 %Notification{id: ^pre_mute_notification_id} -> true
156 %Notification{id: ^post_mute_notification_id} -> true
164 describe "create_notification" do
165 @tag needs_streamer: true
166 test "it creates a notification for user and send to the 'user' and the 'user:notification' stream" do
171 Streamer.add_socket("user", user)
172 assert_receive {:render_with_user, _, _, _}, 4_000
175 task_user_notification =
177 Streamer.add_socket("user:notification", user)
178 assert_receive {:render_with_user, _, _, _}, 4_000
181 activity = insert(:note_activity)
183 notify = Notification.create_notification(activity, user)
184 assert notify.user_id == user.id
186 Task.await(task_user_notification)
189 test "it creates a notification for user if the user blocks the activity author" do
190 activity = insert(:note_activity)
191 author = User.get_cached_by_ap_id(activity.data["actor"])
193 {:ok, _user_relationship} = User.block(user, author)
195 assert Notification.create_notification(activity, user)
198 test "it creates a notification for the user if the user mutes the activity author" do
199 muter = insert(:user)
200 muted = insert(:user)
201 {:ok, _} = User.mute(muter, muted)
202 muter = Repo.get(User, muter.id)
203 {:ok, activity} = CommonAPI.post(muted, %{"status" => "Hi @#{muter.nickname}"})
205 assert Notification.create_notification(activity, muter)
208 test "notification created if user is muted without notifications" do
209 muter = insert(:user)
210 muted = insert(:user)
212 {:ok, _user_relationships} = User.mute(muter, muted, false)
214 {:ok, activity} = CommonAPI.post(muted, %{"status" => "Hi @#{muter.nickname}"})
216 assert Notification.create_notification(activity, muter)
219 test "it creates a notification for an activity from a muted thread" do
220 muter = insert(:user)
221 other_user = insert(:user)
222 {:ok, activity} = CommonAPI.post(muter, %{"status" => "hey"})
223 CommonAPI.add_mute(muter, activity)
226 CommonAPI.post(other_user, %{
227 "status" => "Hi @#{muter.nickname}",
228 "in_reply_to_status_id" => activity.id
231 assert Notification.create_notification(activity, muter)
234 test "it disables notifications from followers" do
235 follower = insert(:user)
238 insert(:user, notification_settings: %Pleroma.User.NotificationSetting{followers: false})
240 User.follow(follower, followed)
241 {:ok, activity} = CommonAPI.post(follower, %{"status" => "hey @#{followed.nickname}"})
242 refute Notification.create_notification(activity, followed)
245 test "it disables notifications from non-followers" do
246 follower = insert(:user)
250 notification_settings: %Pleroma.User.NotificationSetting{non_followers: false}
253 {:ok, activity} = CommonAPI.post(follower, %{"status" => "hey @#{followed.nickname}"})
254 refute Notification.create_notification(activity, followed)
257 test "it disables notifications from people the user follows" do
259 insert(:user, notification_settings: %Pleroma.User.NotificationSetting{follows: false})
261 followed = insert(:user)
262 User.follow(follower, followed)
263 follower = Repo.get(User, follower.id)
264 {:ok, activity} = CommonAPI.post(followed, %{"status" => "hey @#{follower.nickname}"})
265 refute Notification.create_notification(activity, follower)
268 test "it disables notifications from people the user does not follow" do
270 insert(:user, notification_settings: %Pleroma.User.NotificationSetting{non_follows: false})
272 followed = insert(:user)
273 {:ok, activity} = CommonAPI.post(followed, %{"status" => "hey @#{follower.nickname}"})
274 refute Notification.create_notification(activity, follower)
277 test "it doesn't create a notification for user if he is the activity author" do
278 activity = insert(:note_activity)
279 author = User.get_cached_by_ap_id(activity.data["actor"])
281 refute Notification.create_notification(activity, author)
284 test "it doesn't create duplicate notifications for follow+subscribed users" do
286 subscriber = insert(:user)
288 {:ok, _, _, _} = CommonAPI.follow(subscriber, user)
289 User.subscribe(subscriber, user)
290 {:ok, status} = CommonAPI.post(user, %{"status" => "Akariiiin"})
291 {:ok, [_notif]} = Notification.create_notifications(status)
294 test "it doesn't create subscription notifications if the recipient cannot see the status" do
296 subscriber = insert(:user)
298 User.subscribe(subscriber, user)
300 {:ok, status} = CommonAPI.post(user, %{"status" => "inwisible", "visibility" => "direct"})
302 assert {:ok, []} == Notification.create_notifications(status)
306 describe "follow / follow_request notifications" do
307 test "it creates `follow` notification for approved Follow activity" do
309 followed_user = insert(:user, locked: false)
311 {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
312 assert FollowingRelationship.following?(user, followed_user)
313 assert [notification] = Notification.for_user(followed_user)
315 assert %{type: "follow"} =
316 NotificationView.render("show.json", %{
317 notification: notification,
322 test "it creates `follow_request` notification for pending Follow activity" do
324 followed_user = insert(:user, locked: true)
326 {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
327 refute FollowingRelationship.following?(user, followed_user)
328 assert [notification] = Notification.for_user(followed_user)
330 render_opts = %{notification: notification, for: followed_user}
331 assert %{type: "follow_request"} = NotificationView.render("show.json", render_opts)
333 # After request is accepted, the same notification is rendered with type "follow":
334 assert {:ok, _} = CommonAPI.accept_follow_request(user, followed_user)
336 notification_id = notification.id
337 assert [%{id: ^notification_id}] = Notification.for_user(followed_user)
338 assert %{type: "follow"} = NotificationView.render("show.json", render_opts)
341 test "it doesn't create a notification for follow-unfollow-follow chains" do
343 followed_user = insert(:user, locked: false)
345 {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
346 assert FollowingRelationship.following?(user, followed_user)
347 assert [notification] = Notification.for_user(followed_user)
349 CommonAPI.unfollow(user, followed_user)
350 {:ok, _, _, _activity_dupe} = CommonAPI.follow(user, followed_user)
352 notification_id = notification.id
353 assert [%{id: ^notification_id}] = Notification.for_user(followed_user)
356 test "dismisses the notification on follow request rejection" do
357 user = insert(:user, locked: true)
358 follower = insert(:user)
359 {:ok, _, _, _follow_activity} = CommonAPI.follow(follower, user)
360 assert [notification] = Notification.for_user(user)
361 {:ok, _follower} = CommonAPI.reject_follow_request(follower, user)
362 assert [] = Notification.for_user(user)
366 describe "get notification" do
367 test "it gets a notification that belongs to the user" do
369 other_user = insert(:user)
371 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
373 {:ok, [notification]} = Notification.create_notifications(activity)
374 {:ok, notification} = Notification.get(other_user, notification.id)
376 assert notification.user_id == other_user.id
379 test "it returns error if the notification doesn't belong to the user" do
381 other_user = insert(:user)
383 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
385 {:ok, [notification]} = Notification.create_notifications(activity)
386 {:error, _notification} = Notification.get(user, notification.id)
390 describe "dismiss notification" do
391 test "it dismisses a notification that belongs to the user" do
393 other_user = insert(:user)
395 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
397 {:ok, [notification]} = Notification.create_notifications(activity)
398 {:ok, notification} = Notification.dismiss(other_user, notification.id)
400 assert notification.user_id == other_user.id
403 test "it returns error if the notification doesn't belong to the user" do
405 other_user = insert(:user)
407 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
409 {:ok, [notification]} = Notification.create_notifications(activity)
410 {:error, _notification} = Notification.dismiss(user, notification.id)
414 describe "clear notification" do
415 test "it clears all notifications belonging to the user" do
417 other_user = insert(:user)
418 third_user = insert(:user)
421 CommonAPI.post(user, %{
422 "status" => "hey @#{other_user.nickname} and @#{third_user.nickname} !"
425 {:ok, _notifs} = Notification.create_notifications(activity)
428 CommonAPI.post(user, %{
429 "status" => "hey again @#{other_user.nickname} and @#{third_user.nickname} !"
432 {:ok, _notifs} = Notification.create_notifications(activity)
433 Notification.clear(other_user)
435 assert Notification.for_user(other_user) == []
436 assert Notification.for_user(third_user) != []
440 describe "set_read_up_to()" do
441 test "it sets all notifications as read up to a specified notification ID" do
443 other_user = insert(:user)
446 CommonAPI.post(user, %{
447 "status" => "hey @#{other_user.nickname}!"
451 CommonAPI.post(user, %{
452 "status" => "hey again @#{other_user.nickname}!"
455 [n2, n1] = notifs = Notification.for_user(other_user)
456 assert length(notifs) == 2
461 CommonAPI.post(user, %{
462 "status" => "hey yet again @#{other_user.nickname}!"
465 Notification.set_read_up_to(other_user, n2.id)
467 [n3, n2, n1] = Notification.for_user(other_user)
469 assert n1.seen == true
470 assert n2.seen == true
471 assert n3.seen == false
473 assert %Pleroma.Marker{} =
477 user_id: other_user.id,
478 timeline: "notifications"
481 assert m.last_read_id == to_string(n2.id)
485 describe "for_user_since/2" do
486 defp days_ago(days) do
488 NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second),
489 -days * 60 * 60 * 24,
494 test "Returns recent notifications" do
495 user1 = insert(:user)
496 user2 = insert(:user)
498 Enum.each(0..10, fn i ->
500 CommonAPI.post(user1, %{
501 "status" => "hey ##{i} @#{user2.nickname}!"
505 {old, new} = Enum.split(Notification.for_user(user2), 5)
507 Enum.each(old, fn notification ->
509 |> cast(%{updated_at: days_ago(10)}, [:updated_at])
510 |> Pleroma.Repo.update!()
513 recent_notifications_ids =
515 |> Notification.for_user_since(
516 NaiveDateTime.add(NaiveDateTime.utc_now(), -5 * 86_400, :second)
520 Enum.each(old, fn %{id: id} ->
521 refute id in recent_notifications_ids
524 Enum.each(new, fn %{id: id} ->
525 assert id in recent_notifications_ids
530 describe "notification target determination / get_notified_from_activity/2" do
531 test "it sends notifications to addressed users in new messages" do
533 other_user = insert(:user)
536 CommonAPI.post(user, %{
537 "status" => "hey @#{other_user.nickname}!"
540 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
542 assert other_user in enabled_receivers
545 test "it sends notifications to mentioned users in new messages" do
547 other_user = insert(:user)
550 "@context" => "https://www.w3.org/ns/activitystreams",
552 "to" => ["https://www.w3.org/ns/activitystreams#Public"],
553 "actor" => user.ap_id,
556 "content" => "message with a Mention tag, but no explicit tagging",
560 "href" => other_user.ap_id,
561 "name" => other_user.nickname
564 "attributedTo" => user.ap_id
568 {:ok, activity} = Transmogrifier.handle_incoming(create_activity)
570 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
572 assert other_user in enabled_receivers
575 test "it does not send notifications to users who are only cc in new messages" do
577 other_user = insert(:user)
580 "@context" => "https://www.w3.org/ns/activitystreams",
582 "to" => ["https://www.w3.org/ns/activitystreams#Public"],
583 "cc" => [other_user.ap_id],
584 "actor" => user.ap_id,
587 "content" => "hi everyone",
588 "attributedTo" => user.ap_id
592 {:ok, activity} = Transmogrifier.handle_incoming(create_activity)
594 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
596 assert other_user not in enabled_receivers
599 test "it does not send notification to mentioned users in likes" do
601 other_user = insert(:user)
602 third_user = insert(:user)
604 {:ok, activity_one} =
605 CommonAPI.post(user, %{
606 "status" => "hey @#{other_user.nickname}!"
609 {:ok, activity_two} = CommonAPI.favorite(third_user, activity_one.id)
611 {enabled_receivers, _disabled_receivers} =
612 Notification.get_notified_from_activity(activity_two)
614 assert other_user not in enabled_receivers
617 test "it does not send notification to mentioned users in announces" do
619 other_user = insert(:user)
620 third_user = insert(:user)
622 {:ok, activity_one} =
623 CommonAPI.post(user, %{
624 "status" => "hey @#{other_user.nickname}!"
627 {:ok, activity_two, _} = CommonAPI.repeat(activity_one.id, third_user)
629 {enabled_receivers, _disabled_receivers} =
630 Notification.get_notified_from_activity(activity_two)
632 assert other_user not in enabled_receivers
635 test "it returns blocking recipient in disabled recipients list" do
637 other_user = insert(:user)
638 {:ok, _user_relationship} = User.block(other_user, user)
640 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}!"})
642 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
644 assert [] == enabled_receivers
645 assert [other_user] == disabled_receivers
648 test "it returns notification-muting recipient in disabled recipients list" do
650 other_user = insert(:user)
651 {:ok, _user_relationships} = User.mute(other_user, user)
653 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}!"})
655 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
657 assert [] == enabled_receivers
658 assert [other_user] == disabled_receivers
661 test "it returns thread-muting recipient in disabled recipients list" do
663 other_user = insert(:user)
665 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}!"})
667 {:ok, _} = CommonAPI.add_mute(other_user, activity)
669 {:ok, same_context_activity} =
670 CommonAPI.post(user, %{
671 "status" => "hey-hey-hey @#{other_user.nickname}!",
672 "in_reply_to_status_id" => activity.id
675 {enabled_receivers, disabled_receivers} =
676 Notification.get_notified_from_activity(same_context_activity)
678 assert [other_user] == disabled_receivers
679 refute other_user in enabled_receivers
682 test "it returns non-following domain-blocking recipient in disabled recipients list" do
683 blocked_domain = "blocked.domain"
684 user = insert(:user, %{ap_id: "https://#{blocked_domain}/@actor"})
685 other_user = insert(:user)
687 {:ok, other_user} = User.block_domain(other_user, blocked_domain)
689 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}!"})
691 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
693 assert [] == enabled_receivers
694 assert [other_user] == disabled_receivers
697 test "it returns following domain-blocking recipient in enabled recipients list" do
698 blocked_domain = "blocked.domain"
699 user = insert(:user, %{ap_id: "https://#{blocked_domain}/@actor"})
700 other_user = insert(:user)
702 {:ok, other_user} = User.block_domain(other_user, blocked_domain)
703 {:ok, other_user} = User.follow(other_user, user)
705 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}!"})
707 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
709 assert [other_user] == enabled_receivers
710 assert [] == disabled_receivers
714 describe "notification lifecycle" do
715 test "liking an activity results in 1 notification, then 0 if the activity is deleted" do
717 other_user = insert(:user)
719 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
721 assert Enum.empty?(Notification.for_user(user))
723 {:ok, _} = CommonAPI.favorite(other_user, activity.id)
725 assert length(Notification.for_user(user)) == 1
727 {:ok, _} = CommonAPI.delete(activity.id, user)
729 assert Enum.empty?(Notification.for_user(user))
732 test "liking an activity results in 1 notification, then 0 if the activity is unliked" do
734 other_user = insert(:user)
736 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
738 assert Enum.empty?(Notification.for_user(user))
740 {:ok, _} = CommonAPI.favorite(other_user, activity.id)
742 assert length(Notification.for_user(user)) == 1
744 {:ok, _} = CommonAPI.unfavorite(activity.id, other_user)
746 assert Enum.empty?(Notification.for_user(user))
749 test "repeating an activity results in 1 notification, then 0 if the activity is deleted" do
751 other_user = insert(:user)
753 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
755 assert Enum.empty?(Notification.for_user(user))
757 {:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
759 assert length(Notification.for_user(user)) == 1
761 {:ok, _} = CommonAPI.delete(activity.id, user)
763 assert Enum.empty?(Notification.for_user(user))
766 test "repeating an activity results in 1 notification, then 0 if the activity is unrepeated" do
768 other_user = insert(:user)
770 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
772 assert Enum.empty?(Notification.for_user(user))
774 {:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
776 assert length(Notification.for_user(user)) == 1
778 {:ok, _} = CommonAPI.unrepeat(activity.id, other_user)
780 assert Enum.empty?(Notification.for_user(user))
783 test "liking an activity which is already deleted does not generate a notification" do
785 other_user = insert(:user)
787 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
789 assert Enum.empty?(Notification.for_user(user))
791 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
793 assert Enum.empty?(Notification.for_user(user))
795 {:error, :not_found} = CommonAPI.favorite(other_user, activity.id)
797 assert Enum.empty?(Notification.for_user(user))
800 test "repeating an activity which is already deleted does not generate a notification" do
802 other_user = insert(:user)
804 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
806 assert Enum.empty?(Notification.for_user(user))
808 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
810 assert Enum.empty?(Notification.for_user(user))
812 {:error, _} = CommonAPI.repeat(activity.id, other_user)
814 assert Enum.empty?(Notification.for_user(user))
817 test "replying to a deleted post without tagging does not generate a notification" do
819 other_user = insert(:user)
821 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
822 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
824 {:ok, _reply_activity} =
825 CommonAPI.post(other_user, %{
826 "status" => "test reply",
827 "in_reply_to_status_id" => activity.id
830 assert Enum.empty?(Notification.for_user(user))
833 test "notifications are deleted if a local user is deleted" do
835 other_user = insert(:user)
838 CommonAPI.post(user, %{"status" => "hi @#{other_user.nickname}", "visibility" => "direct"})
840 refute Enum.empty?(Notification.for_user(other_user))
842 {:ok, job} = User.delete(user)
843 ObanHelpers.perform(job)
845 assert Enum.empty?(Notification.for_user(other_user))
848 test "notifications are deleted if a remote user is deleted" do
849 remote_user = insert(:user)
850 local_user = insert(:user)
853 "@context" => "https://www.w3.org/ns/activitystreams",
855 "actor" => remote_user.ap_id,
856 "id" => remote_user.ap_id <> "/activities/test",
857 "to" => [local_user.ap_id],
861 "content" => "Hello!",
865 "href" => local_user.ap_id,
866 "name" => "@#{local_user.nickname}"
869 "to" => [local_user.ap_id],
871 "attributedTo" => remote_user.ap_id
875 {:ok, _dm_activity} = Transmogrifier.handle_incoming(dm_message)
877 refute Enum.empty?(Notification.for_user(local_user))
879 delete_user_message = %{
880 "@context" => "https://www.w3.org/ns/activitystreams",
881 "id" => remote_user.ap_id <> "/activities/delete",
882 "actor" => remote_user.ap_id,
884 "object" => remote_user.ap_id
887 remote_user_url = remote_user.ap_id
890 %{method: :get, url: ^remote_user_url} ->
891 %Tesla.Env{status: 404, body: ""}
894 {:ok, _delete_activity} = Transmogrifier.handle_incoming(delete_user_message)
895 ObanHelpers.perform_all()
897 assert Enum.empty?(Notification.for_user(local_user))
900 @tag capture_log: true
901 test "move activity generates a notification" do
902 %{ap_id: old_ap_id} = old_user = insert(:user)
903 %{ap_id: new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id])
904 follower = insert(:user)
905 other_follower = insert(:user, %{allow_following_move: false})
907 User.follow(follower, old_user)
908 User.follow(other_follower, old_user)
910 old_user_url = old_user.ap_id
913 File.read!("test/fixtures/users_mock/localhost.json")
914 |> String.replace("{{nickname}}", old_user.nickname)
918 %{method: :get, url: ^old_user_url} ->
919 %Tesla.Env{status: 200, body: body}
922 Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
923 ObanHelpers.perform_all()
928 data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
931 ] = Notification.for_user(follower)
936 data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
939 ] = Notification.for_user(other_follower)
943 describe "for_user" do
944 test "it returns notifications for muted user without notifications" do
946 muted = insert(:user)
947 {:ok, _user_relationships} = User.mute(user, muted, false)
949 {:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
951 assert length(Notification.for_user(user)) == 1
954 test "it doesn't return notifications for muted user with notifications" do
956 muted = insert(:user)
957 {:ok, _user_relationships} = User.mute(user, muted)
959 {:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
961 assert Notification.for_user(user) == []
964 test "it doesn't return notifications for blocked user" do
966 blocked = insert(:user)
967 {:ok, _user_relationship} = User.block(user, blocked)
969 {:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
971 assert Notification.for_user(user) == []
974 test "it doesn't return notifications for domain-blocked non-followed user" do
976 blocked = insert(:user, ap_id: "http://some-domain.com")
977 {:ok, user} = User.block_domain(user, "some-domain.com")
979 {:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
981 assert Notification.for_user(user) == []
984 test "it returns notifications for domain-blocked but followed user" do
986 blocked = insert(:user, ap_id: "http://some-domain.com")
988 {:ok, user} = User.block_domain(user, "some-domain.com")
989 {:ok, _} = User.follow(user, blocked)
991 {:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
993 assert length(Notification.for_user(user)) == 1
996 test "it doesn't return notifications for muted thread" do
998 another_user = insert(:user)
1000 {:ok, activity} = CommonAPI.post(another_user, %{"status" => "hey @#{user.nickname}"})
1002 {:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
1003 assert Notification.for_user(user) == []
1006 test "it returns notifications from a muted user when with_muted is set" do
1007 user = insert(:user)
1008 muted = insert(:user)
1009 {:ok, _user_relationships} = User.mute(user, muted)
1011 {:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
1013 assert length(Notification.for_user(user, %{with_muted: true})) == 1
1016 test "it doesn't return notifications from a blocked user when with_muted is set" do
1017 user = insert(:user)
1018 blocked = insert(:user)
1019 {:ok, _user_relationship} = User.block(user, blocked)
1021 {:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
1023 assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
1026 test "when with_muted is set, " <>
1027 "it doesn't return notifications from a domain-blocked non-followed user" do
1028 user = insert(:user)
1029 blocked = insert(:user, ap_id: "http://some-domain.com")
1030 {:ok, user} = User.block_domain(user, "some-domain.com")
1032 {:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
1034 assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
1037 test "it returns notifications from muted threads when with_muted is set" do
1038 user = insert(:user)
1039 another_user = insert(:user)
1041 {:ok, activity} = CommonAPI.post(another_user, %{"status" => "hey @#{user.nickname}"})
1043 {:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
1044 assert length(Notification.for_user(user, %{with_muted: true})) == 1