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
14 alias Pleroma.Tests.ObanHelpers
16 alias Pleroma.Web.ActivityPub.ActivityPub
17 alias Pleroma.Web.ActivityPub.Builder
18 alias Pleroma.Web.ActivityPub.Transmogrifier
19 alias Pleroma.Web.CommonAPI
20 alias Pleroma.Web.MastodonAPI.NotificationView
21 alias Pleroma.Web.Push
22 alias Pleroma.Web.Streamer
24 describe "create_notifications" do
25 test "creates a notification for an emoji reaction" do
27 other_user = insert(:user)
29 {:ok, activity} = CommonAPI.post(user, %{status: "yeah"})
30 {:ok, activity} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
32 {:ok, [notification]} = Notification.create_notifications(activity)
34 assert notification.user_id == user.id
35 assert notification.type == "pleroma:emoji_reaction"
38 test "notifies someone when they are directly addressed" do
40 other_user = insert(:user)
41 third_user = insert(:user)
44 CommonAPI.post(user, %{
45 status: "hey @#{other_user.nickname} and @#{third_user.nickname}"
48 {:ok, [notification, other_notification]} = Notification.create_notifications(activity)
50 notified_ids = Enum.sort([notification.user_id, other_notification.user_id])
51 assert notified_ids == [other_user.id, third_user.id]
52 assert notification.activity_id == activity.id
53 assert notification.type == "mention"
54 assert other_notification.activity_id == activity.id
56 assert [%Pleroma.Marker{unread_count: 2}] =
57 Pleroma.Marker.get_markers(other_user, ["notifications"])
60 test "it creates a notification for subscribed users" do
62 subscriber = insert(:user)
64 User.subscribe(subscriber, user)
66 {:ok, status} = CommonAPI.post(user, %{status: "Akariiiin"})
67 {:ok, [notification]} = Notification.create_notifications(status)
69 assert notification.user_id == subscriber.id
72 test "does not create a notification for subscribed users if status is a reply" do
74 other_user = insert(:user)
75 subscriber = insert(:user)
77 User.subscribe(subscriber, other_user)
79 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
81 {:ok, _reply_activity} =
82 CommonAPI.post(other_user, %{
84 in_reply_to_status_id: activity.id
87 user_notifications = Notification.for_user(user)
88 assert length(user_notifications) == 1
90 subscriber_notifications = Notification.for_user(subscriber)
91 assert Enum.empty?(subscriber_notifications)
95 describe "CommonApi.post/2 notification-related functionality" do
96 test_with_mock "creates but does NOT send notification to blocker user",
101 blocker = insert(:user)
102 {:ok, _user_relationship} = User.block(blocker, user)
104 {:ok, _activity} = CommonAPI.post(user, %{status: "hey @#{blocker.nickname}!"})
106 blocker_id = blocker.id
107 assert [%Notification{user_id: ^blocker_id}] = Repo.all(Notification)
108 refute called(Push.send(:_))
111 test_with_mock "creates but does NOT send notification to notification-muter user",
116 muter = insert(:user)
117 {:ok, _user_relationships} = User.mute(muter, user)
119 {:ok, _activity} = CommonAPI.post(user, %{status: "hey @#{muter.nickname}!"})
122 assert [%Notification{user_id: ^muter_id}] = Repo.all(Notification)
123 refute called(Push.send(:_))
126 test_with_mock "creates but does NOT send notification to thread-muter user",
131 thread_muter = insert(:user)
133 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{thread_muter.nickname}!"})
135 {:ok, _} = CommonAPI.add_mute(thread_muter, activity)
137 {:ok, _same_context_activity} =
138 CommonAPI.post(user, %{
139 status: "hey-hey-hey @#{thread_muter.nickname}!",
140 in_reply_to_status_id: activity.id
143 [pre_mute_notification, post_mute_notification] =
144 Repo.all(from(n in Notification, where: n.user_id == ^thread_muter.id, order_by: n.id))
146 pre_mute_notification_id = pre_mute_notification.id
147 post_mute_notification_id = post_mute_notification.id
152 %Notification{id: ^pre_mute_notification_id} -> true
161 %Notification{id: ^post_mute_notification_id} -> true
169 describe "create_notification" do
170 @tag needs_streamer: true
171 test "it creates a notification for user and send to the 'user' and the 'user:notification' stream" do
176 Streamer.get_topic_and_add_socket("user", user)
177 assert_receive {:render_with_user, _, _, _}, 4_000
180 task_user_notification =
182 Streamer.get_topic_and_add_socket("user:notification", user)
183 assert_receive {:render_with_user, _, _, _}, 4_000
186 activity = insert(:note_activity)
188 notify = Notification.create_notification(activity, user)
189 assert notify.user_id == user.id
191 Task.await(task_user_notification)
194 test "it creates a notification for user if the user blocks the activity author" do
195 activity = insert(:note_activity)
196 author = User.get_cached_by_ap_id(activity.data["actor"])
198 {:ok, _user_relationship} = User.block(user, author)
200 assert Notification.create_notification(activity, user)
203 test "it creates a notification for the user if the user mutes the activity author" do
204 muter = insert(:user)
205 muted = insert(:user)
206 {:ok, _} = User.mute(muter, muted)
207 muter = Repo.get(User, muter.id)
208 {:ok, activity} = CommonAPI.post(muted, %{status: "Hi @#{muter.nickname}"})
210 assert Notification.create_notification(activity, muter)
213 test "notification created if user is muted without notifications" do
214 muter = insert(:user)
215 muted = insert(:user)
217 {:ok, _user_relationships} = User.mute(muter, muted, false)
219 {:ok, activity} = CommonAPI.post(muted, %{status: "Hi @#{muter.nickname}"})
221 assert Notification.create_notification(activity, muter)
224 test "it creates a notification for an activity from a muted thread" do
225 muter = insert(:user)
226 other_user = insert(:user)
227 {:ok, activity} = CommonAPI.post(muter, %{status: "hey"})
228 CommonAPI.add_mute(muter, activity)
231 CommonAPI.post(other_user, %{
232 status: "Hi @#{muter.nickname}",
233 in_reply_to_status_id: activity.id
236 assert Notification.create_notification(activity, muter)
239 test "it disables notifications from followers" do
240 follower = insert(:user)
243 insert(:user, notification_settings: %Pleroma.User.NotificationSetting{followers: false})
245 User.follow(follower, followed)
246 {:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
247 refute Notification.create_notification(activity, followed)
250 test "it disables notifications from non-followers" do
251 follower = insert(:user)
255 notification_settings: %Pleroma.User.NotificationSetting{non_followers: false}
258 {:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
259 refute Notification.create_notification(activity, followed)
262 test "it disables notifications from people the user follows" do
264 insert(:user, notification_settings: %Pleroma.User.NotificationSetting{follows: false})
266 followed = insert(:user)
267 User.follow(follower, followed)
268 follower = Repo.get(User, follower.id)
269 {:ok, activity} = CommonAPI.post(followed, %{status: "hey @#{follower.nickname}"})
270 refute Notification.create_notification(activity, follower)
273 test "it disables notifications from people the user does not follow" do
275 insert(:user, notification_settings: %Pleroma.User.NotificationSetting{non_follows: false})
277 followed = insert(:user)
278 {:ok, activity} = CommonAPI.post(followed, %{status: "hey @#{follower.nickname}"})
279 refute Notification.create_notification(activity, follower)
282 test "it doesn't create a notification for user if he is the activity author" do
283 activity = insert(:note_activity)
284 author = User.get_cached_by_ap_id(activity.data["actor"])
286 refute Notification.create_notification(activity, author)
289 test "it doesn't create duplicate notifications for follow+subscribed users" do
291 subscriber = insert(:user)
293 {:ok, _, _, _} = CommonAPI.follow(subscriber, user)
294 User.subscribe(subscriber, user)
295 {:ok, status} = CommonAPI.post(user, %{status: "Akariiiin"})
296 {:ok, [_notif]} = Notification.create_notifications(status)
299 test "it doesn't create subscription notifications if the recipient cannot see the status" do
301 subscriber = insert(:user)
303 User.subscribe(subscriber, user)
305 {:ok, status} = CommonAPI.post(user, %{status: "inwisible", visibility: "direct"})
307 assert {:ok, []} == Notification.create_notifications(status)
310 test "it disables notifications from people who are invisible" do
311 author = insert(:user, invisible: true)
314 {:ok, status} = CommonAPI.post(author, %{status: "hey @#{user.nickname}"})
315 refute Notification.create_notification(status, user)
319 describe "follow / follow_request notifications" do
320 test "it creates `follow` notification for approved Follow activity" do
322 followed_user = insert(:user, locked: false)
324 {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
325 assert FollowingRelationship.following?(user, followed_user)
326 assert [notification] = Notification.for_user(followed_user)
328 assert %{type: "follow"} =
329 NotificationView.render("show.json", %{
330 notification: notification,
335 test "it creates `follow_request` notification for pending Follow activity" do
337 followed_user = insert(:user, locked: true)
339 {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
340 refute FollowingRelationship.following?(user, followed_user)
341 assert [notification] = Notification.for_user(followed_user)
343 render_opts = %{notification: notification, for: followed_user}
344 assert %{type: "follow_request"} = NotificationView.render("show.json", render_opts)
346 # After request is accepted, the same notification is rendered with type "follow":
347 assert {:ok, _} = CommonAPI.accept_follow_request(user, followed_user)
350 Repo.get(Notification, notification.id)
351 |> Repo.preload(:activity)
353 assert %{type: "follow"} =
354 NotificationView.render("show.json", notification: notification, for: followed_user)
357 test "it doesn't create a notification for follow-unfollow-follow chains" do
359 followed_user = insert(:user, locked: false)
361 {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
362 assert FollowingRelationship.following?(user, followed_user)
363 assert [notification] = Notification.for_user(followed_user)
365 CommonAPI.unfollow(user, followed_user)
366 {:ok, _, _, _activity_dupe} = CommonAPI.follow(user, followed_user)
368 notification_id = notification.id
369 assert [%{id: ^notification_id}] = Notification.for_user(followed_user)
372 test "dismisses the notification on follow request rejection" do
373 user = insert(:user, locked: true)
374 follower = insert(:user)
375 {:ok, _, _, _follow_activity} = CommonAPI.follow(follower, user)
376 assert [notification] = Notification.for_user(user)
377 {:ok, _follower} = CommonAPI.reject_follow_request(follower, user)
378 assert [] = Notification.for_user(user)
382 describe "get notification" do
383 test "it gets a notification that belongs to the user" do
385 other_user = insert(:user)
387 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
389 {:ok, [notification]} = Notification.create_notifications(activity)
390 {:ok, notification} = Notification.get(other_user, notification.id)
392 assert notification.user_id == other_user.id
395 test "it returns error if the notification doesn't belong to the user" do
397 other_user = insert(:user)
399 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
401 {:ok, [notification]} = Notification.create_notifications(activity)
402 {:error, _notification} = Notification.get(user, notification.id)
406 describe "dismiss notification" do
407 test "it dismisses a notification that belongs to the user" do
409 other_user = insert(:user)
411 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
413 {:ok, [notification]} = Notification.create_notifications(activity)
414 {:ok, notification} = Notification.dismiss(other_user, notification.id)
416 assert notification.user_id == other_user.id
419 test "it returns error if the notification doesn't belong to the user" do
421 other_user = insert(:user)
423 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
425 {:ok, [notification]} = Notification.create_notifications(activity)
426 {:error, _notification} = Notification.dismiss(user, notification.id)
430 describe "clear notification" do
431 test "it clears all notifications belonging to the user" do
433 other_user = insert(:user)
434 third_user = insert(:user)
437 CommonAPI.post(user, %{
438 status: "hey @#{other_user.nickname} and @#{third_user.nickname} !"
441 {:ok, _notifs} = Notification.create_notifications(activity)
444 CommonAPI.post(user, %{
445 status: "hey again @#{other_user.nickname} and @#{third_user.nickname} !"
448 {:ok, _notifs} = Notification.create_notifications(activity)
449 Notification.clear(other_user)
451 assert Notification.for_user(other_user) == []
452 assert Notification.for_user(third_user) != []
456 describe "set_read_up_to()" do
457 test "it sets all notifications as read up to a specified notification ID" do
459 other_user = insert(:user)
462 CommonAPI.post(user, %{
463 status: "hey @#{other_user.nickname}!"
467 CommonAPI.post(user, %{
468 status: "hey again @#{other_user.nickname}!"
471 [n2, n1] = Notification.for_user(other_user)
476 CommonAPI.post(user, %{
477 status: "hey yet again @#{other_user.nickname}!"
480 [_, read_notification] = Notification.set_read_up_to(other_user, n2.id)
482 assert read_notification.activity.object
484 [n3, n2, n1] = Notification.for_user(other_user)
486 assert n1.seen == true
487 assert n2.seen == true
488 assert n3.seen == false
490 assert %Pleroma.Marker{} =
494 user_id: other_user.id,
495 timeline: "notifications"
498 assert m.last_read_id == to_string(n2.id)
502 describe "for_user_since/2" do
503 defp days_ago(days) do
505 NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second),
506 -days * 60 * 60 * 24,
511 test "Returns recent notifications" do
512 user1 = insert(:user)
513 user2 = insert(:user)
515 Enum.each(0..10, fn i ->
517 CommonAPI.post(user1, %{
518 status: "hey ##{i} @#{user2.nickname}!"
522 {old, new} = Enum.split(Notification.for_user(user2), 5)
524 Enum.each(old, fn notification ->
526 |> cast(%{updated_at: days_ago(10)}, [:updated_at])
527 |> Pleroma.Repo.update!()
530 recent_notifications_ids =
532 |> Notification.for_user_since(
533 NaiveDateTime.add(NaiveDateTime.utc_now(), -5 * 86_400, :second)
537 Enum.each(old, fn %{id: id} ->
538 refute id in recent_notifications_ids
541 Enum.each(new, fn %{id: id} ->
542 assert id in recent_notifications_ids
547 describe "notification target determination / get_notified_from_activity/2" do
548 test "it sends notifications to addressed users in new messages" do
550 other_user = insert(:user)
553 CommonAPI.post(user, %{
554 status: "hey @#{other_user.nickname}!"
557 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
559 assert other_user in enabled_receivers
562 test "it sends notifications to mentioned users in new messages" do
564 other_user = insert(:user)
567 "@context" => "https://www.w3.org/ns/activitystreams",
569 "to" => ["https://www.w3.org/ns/activitystreams#Public"],
570 "actor" => user.ap_id,
573 "content" => "message with a Mention tag, but no explicit tagging",
577 "href" => other_user.ap_id,
578 "name" => other_user.nickname
581 "attributedTo" => user.ap_id
585 {:ok, activity} = Transmogrifier.handle_incoming(create_activity)
587 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
589 assert other_user in enabled_receivers
592 test "it does not send notifications to users who are only cc in new messages" do
594 other_user = insert(:user)
597 "@context" => "https://www.w3.org/ns/activitystreams",
599 "to" => ["https://www.w3.org/ns/activitystreams#Public"],
600 "cc" => [other_user.ap_id],
601 "actor" => user.ap_id,
604 "content" => "hi everyone",
605 "attributedTo" => user.ap_id
609 {:ok, activity} = Transmogrifier.handle_incoming(create_activity)
611 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
613 assert other_user not in enabled_receivers
616 test "it does not send notification to mentioned users in likes" do
618 other_user = insert(:user)
619 third_user = insert(:user)
621 {:ok, activity_one} =
622 CommonAPI.post(user, %{
623 status: "hey @#{other_user.nickname}!"
626 {:ok, activity_two} = CommonAPI.favorite(third_user, activity_one.id)
628 {enabled_receivers, _disabled_receivers} =
629 Notification.get_notified_from_activity(activity_two)
631 assert other_user not in enabled_receivers
634 test "it only notifies the post's author in likes" do
636 other_user = insert(:user)
637 third_user = insert(:user)
639 {:ok, activity_one} =
640 CommonAPI.post(user, %{
641 status: "hey @#{other_user.nickname}!"
644 {:ok, like_data, _} = Builder.like(third_user, activity_one.object)
648 |> Map.put("to", [other_user.ap_id | like_data["to"]])
649 |> ActivityPub.persist(local: true)
651 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(like)
653 assert other_user not in enabled_receivers
656 test "it does not send notification to mentioned users in announces" do
658 other_user = insert(:user)
659 third_user = insert(:user)
661 {:ok, activity_one} =
662 CommonAPI.post(user, %{
663 status: "hey @#{other_user.nickname}!"
666 {:ok, activity_two} = CommonAPI.repeat(activity_one.id, third_user)
668 {enabled_receivers, _disabled_receivers} =
669 Notification.get_notified_from_activity(activity_two)
671 assert other_user not in enabled_receivers
674 test "it returns blocking recipient in disabled recipients list" do
676 other_user = insert(:user)
677 {:ok, _user_relationship} = User.block(other_user, user)
679 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
681 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
683 assert [] == enabled_receivers
684 assert [other_user] == disabled_receivers
687 test "it returns notification-muting recipient in disabled recipients list" do
689 other_user = insert(:user)
690 {:ok, _user_relationships} = User.mute(other_user, user)
692 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
694 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
696 assert [] == enabled_receivers
697 assert [other_user] == disabled_receivers
700 test "it returns thread-muting recipient in disabled recipients list" do
702 other_user = insert(:user)
704 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
706 {:ok, _} = CommonAPI.add_mute(other_user, activity)
708 {:ok, same_context_activity} =
709 CommonAPI.post(user, %{
710 status: "hey-hey-hey @#{other_user.nickname}!",
711 in_reply_to_status_id: activity.id
714 {enabled_receivers, disabled_receivers} =
715 Notification.get_notified_from_activity(same_context_activity)
717 assert [other_user] == disabled_receivers
718 refute other_user in enabled_receivers
721 test "it returns non-following domain-blocking recipient in disabled recipients list" do
722 blocked_domain = "blocked.domain"
723 user = insert(:user, %{ap_id: "https://#{blocked_domain}/@actor"})
724 other_user = insert(:user)
726 {:ok, other_user} = User.block_domain(other_user, blocked_domain)
728 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
730 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
732 assert [] == enabled_receivers
733 assert [other_user] == disabled_receivers
736 test "it returns following domain-blocking recipient in enabled recipients list" do
737 blocked_domain = "blocked.domain"
738 user = insert(:user, %{ap_id: "https://#{blocked_domain}/@actor"})
739 other_user = insert(:user)
741 {:ok, other_user} = User.block_domain(other_user, blocked_domain)
742 {:ok, other_user} = User.follow(other_user, user)
744 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
746 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
748 assert [other_user] == enabled_receivers
749 assert [] == disabled_receivers
753 describe "notification lifecycle" do
754 test "liking an activity results in 1 notification, then 0 if the activity is deleted" do
756 other_user = insert(:user)
758 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
760 assert Enum.empty?(Notification.for_user(user))
762 {:ok, _} = CommonAPI.favorite(other_user, activity.id)
764 assert length(Notification.for_user(user)) == 1
766 {:ok, _} = CommonAPI.delete(activity.id, user)
768 assert Enum.empty?(Notification.for_user(user))
771 test "liking an activity results in 1 notification, then 0 if the activity is unliked" do
773 other_user = insert(:user)
775 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
777 assert Enum.empty?(Notification.for_user(user))
779 {:ok, _} = CommonAPI.favorite(other_user, activity.id)
781 assert length(Notification.for_user(user)) == 1
783 {:ok, _} = CommonAPI.unfavorite(activity.id, other_user)
785 assert Enum.empty?(Notification.for_user(user))
788 test "repeating an activity results in 1 notification, then 0 if the activity is deleted" do
790 other_user = insert(:user)
792 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
794 assert Enum.empty?(Notification.for_user(user))
796 {:ok, _} = CommonAPI.repeat(activity.id, other_user)
798 assert length(Notification.for_user(user)) == 1
800 {:ok, _} = CommonAPI.delete(activity.id, user)
802 assert Enum.empty?(Notification.for_user(user))
805 test "repeating an activity results in 1 notification, then 0 if the activity is unrepeated" do
807 other_user = insert(:user)
809 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
811 assert Enum.empty?(Notification.for_user(user))
813 {:ok, _} = CommonAPI.repeat(activity.id, other_user)
815 assert length(Notification.for_user(user)) == 1
817 {:ok, _} = CommonAPI.unrepeat(activity.id, other_user)
819 assert Enum.empty?(Notification.for_user(user))
822 test "liking an activity which is already deleted does not generate a notification" do
824 other_user = insert(:user)
826 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
828 assert Enum.empty?(Notification.for_user(user))
830 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
832 assert Enum.empty?(Notification.for_user(user))
834 {:error, :not_found} = CommonAPI.favorite(other_user, activity.id)
836 assert Enum.empty?(Notification.for_user(user))
839 test "repeating an activity which is already deleted does not generate a notification" do
841 other_user = insert(:user)
843 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
845 assert Enum.empty?(Notification.for_user(user))
847 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
849 assert Enum.empty?(Notification.for_user(user))
851 {:error, _} = CommonAPI.repeat(activity.id, other_user)
853 assert Enum.empty?(Notification.for_user(user))
856 test "replying to a deleted post without tagging does not generate a notification" do
858 other_user = insert(:user)
860 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
861 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
863 {:ok, _reply_activity} =
864 CommonAPI.post(other_user, %{
865 status: "test reply",
866 in_reply_to_status_id: activity.id
869 assert Enum.empty?(Notification.for_user(user))
872 test "notifications are deleted if a local user is deleted" do
874 other_user = insert(:user)
877 CommonAPI.post(user, %{status: "hi @#{other_user.nickname}", visibility: "direct"})
879 refute Enum.empty?(Notification.for_user(other_user))
881 {:ok, job} = User.delete(user)
882 ObanHelpers.perform(job)
884 assert Enum.empty?(Notification.for_user(other_user))
887 test "notifications are deleted if a remote user is deleted" do
888 remote_user = insert(:user)
889 local_user = insert(:user)
892 "@context" => "https://www.w3.org/ns/activitystreams",
894 "actor" => remote_user.ap_id,
895 "id" => remote_user.ap_id <> "/activities/test",
896 "to" => [local_user.ap_id],
900 "content" => "Hello!",
904 "href" => local_user.ap_id,
905 "name" => "@#{local_user.nickname}"
908 "to" => [local_user.ap_id],
910 "attributedTo" => remote_user.ap_id
914 {:ok, _dm_activity} = Transmogrifier.handle_incoming(dm_message)
916 refute Enum.empty?(Notification.for_user(local_user))
918 delete_user_message = %{
919 "@context" => "https://www.w3.org/ns/activitystreams",
920 "id" => remote_user.ap_id <> "/activities/delete",
921 "actor" => remote_user.ap_id,
923 "object" => remote_user.ap_id
926 remote_user_url = remote_user.ap_id
929 %{method: :get, url: ^remote_user_url} ->
930 %Tesla.Env{status: 404, body: ""}
933 {:ok, _delete_activity} = Transmogrifier.handle_incoming(delete_user_message)
934 ObanHelpers.perform_all()
936 assert Enum.empty?(Notification.for_user(local_user))
939 @tag capture_log: true
940 test "move activity generates a notification" do
941 %{ap_id: old_ap_id} = old_user = insert(:user)
942 %{ap_id: new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id])
943 follower = insert(:user)
944 other_follower = insert(:user, %{allow_following_move: false})
946 User.follow(follower, old_user)
947 User.follow(other_follower, old_user)
949 old_user_url = old_user.ap_id
952 File.read!("test/fixtures/users_mock/localhost.json")
953 |> String.replace("{{nickname}}", old_user.nickname)
957 %{method: :get, url: ^old_user_url} ->
958 %Tesla.Env{status: 200, body: body}
961 Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
962 ObanHelpers.perform_all()
967 data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
970 ] = Notification.for_user(follower)
975 data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
978 ] = Notification.for_user(other_follower)
982 describe "for_user" do
983 test "it returns notifications for muted user without notifications" do
985 muted = insert(:user)
986 {:ok, _user_relationships} = User.mute(user, muted, false)
988 {:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
990 [notification] = Notification.for_user(user)
992 assert notification.activity.object
995 test "it doesn't return notifications for muted user with notifications" do
997 muted = insert(:user)
998 {:ok, _user_relationships} = User.mute(user, muted)
1000 {:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
1002 assert Notification.for_user(user) == []
1005 test "it doesn't return notifications for blocked user" do
1006 user = insert(:user)
1007 blocked = insert(:user)
1008 {:ok, _user_relationship} = User.block(user, blocked)
1010 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
1012 assert Notification.for_user(user) == []
1015 test "it doesn't return notifications for domain-blocked non-followed user" do
1016 user = insert(:user)
1017 blocked = insert(:user, ap_id: "http://some-domain.com")
1018 {:ok, user} = User.block_domain(user, "some-domain.com")
1020 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
1022 assert Notification.for_user(user) == []
1025 test "it returns notifications for domain-blocked but followed user" do
1026 user = insert(:user)
1027 blocked = insert(:user, ap_id: "http://some-domain.com")
1029 {:ok, user} = User.block_domain(user, "some-domain.com")
1030 {:ok, _} = User.follow(user, blocked)
1032 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
1034 assert length(Notification.for_user(user)) == 1
1037 test "it doesn't return notifications for muted thread" 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 Notification.for_user(user) == []
1047 test "it returns notifications from a muted user when with_muted is set" do
1048 user = insert(:user)
1049 muted = insert(:user)
1050 {:ok, _user_relationships} = User.mute(user, muted)
1052 {:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
1054 assert length(Notification.for_user(user, %{with_muted: true})) == 1
1057 test "it doesn't return notifications from a blocked user when with_muted is set" do
1058 user = insert(:user)
1059 blocked = insert(:user)
1060 {:ok, _user_relationship} = User.block(user, blocked)
1062 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
1064 assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
1067 test "when with_muted is set, " <>
1068 "it doesn't return notifications from a domain-blocked non-followed user" do
1069 user = insert(:user)
1070 blocked = insert(:user, ap_id: "http://some-domain.com")
1071 {:ok, user} = User.block_domain(user, "some-domain.com")
1073 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
1075 assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
1078 test "it returns notifications from muted threads when with_muted is set" do
1079 user = insert(:user)
1080 another_user = insert(:user)
1082 {:ok, activity} = CommonAPI.post(another_user, %{status: "hey @#{user.nickname}"})
1084 {:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
1085 assert length(Notification.for_user(user, %{with_muted: true})) == 1