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 strangers" do
240 follower = insert(:user)
244 notification_settings: %Pleroma.User.NotificationSetting{block_from_strangers: true}
247 {:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
248 refute Notification.create_notification(activity, followed)
251 test "it doesn't create a notification for user if he is the activity author" do
252 activity = insert(:note_activity)
253 author = User.get_cached_by_ap_id(activity.data["actor"])
255 refute Notification.create_notification(activity, author)
258 test "it doesn't create duplicate notifications for follow+subscribed users" do
260 subscriber = insert(:user)
262 {:ok, _, _, _} = CommonAPI.follow(subscriber, user)
263 User.subscribe(subscriber, user)
264 {:ok, status} = CommonAPI.post(user, %{status: "Akariiiin"})
265 {:ok, [_notif]} = Notification.create_notifications(status)
268 test "it doesn't create subscription notifications if the recipient cannot see the status" do
270 subscriber = insert(:user)
272 User.subscribe(subscriber, user)
274 {:ok, status} = CommonAPI.post(user, %{status: "inwisible", visibility: "direct"})
276 assert {:ok, []} == Notification.create_notifications(status)
279 test "it disables notifications from people who are invisible" do
280 author = insert(:user, invisible: true)
283 {:ok, status} = CommonAPI.post(author, %{status: "hey @#{user.nickname}"})
284 refute Notification.create_notification(status, user)
288 describe "follow / follow_request notifications" do
289 test "it creates `follow` notification for approved Follow activity" do
291 followed_user = insert(:user, locked: false)
293 {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
294 assert FollowingRelationship.following?(user, followed_user)
295 assert [notification] = Notification.for_user(followed_user)
297 assert %{type: "follow"} =
298 NotificationView.render("show.json", %{
299 notification: notification,
304 test "it creates `follow_request` notification for pending Follow activity" do
306 followed_user = insert(:user, locked: true)
308 {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
309 refute FollowingRelationship.following?(user, followed_user)
310 assert [notification] = Notification.for_user(followed_user)
312 render_opts = %{notification: notification, for: followed_user}
313 assert %{type: "follow_request"} = NotificationView.render("show.json", render_opts)
315 # After request is accepted, the same notification is rendered with type "follow":
316 assert {:ok, _} = CommonAPI.accept_follow_request(user, followed_user)
319 Repo.get(Notification, notification.id)
320 |> Repo.preload(:activity)
322 assert %{type: "follow"} =
323 NotificationView.render("show.json", notification: notification, for: followed_user)
326 test "it doesn't create a notification for follow-unfollow-follow chains" do
328 followed_user = insert(:user, locked: false)
330 {:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
331 assert FollowingRelationship.following?(user, followed_user)
332 assert [notification] = Notification.for_user(followed_user)
334 CommonAPI.unfollow(user, followed_user)
335 {:ok, _, _, _activity_dupe} = CommonAPI.follow(user, followed_user)
337 notification_id = notification.id
338 assert [%{id: ^notification_id}] = Notification.for_user(followed_user)
341 test "dismisses the notification on follow request rejection" do
342 user = insert(:user, locked: true)
343 follower = insert(:user)
344 {:ok, _, _, _follow_activity} = CommonAPI.follow(follower, user)
345 assert [notification] = Notification.for_user(user)
346 {:ok, _follower} = CommonAPI.reject_follow_request(follower, user)
347 assert [] = Notification.for_user(user)
351 describe "get notification" do
352 test "it gets a notification that belongs to the user" do
354 other_user = insert(:user)
356 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
358 {:ok, [notification]} = Notification.create_notifications(activity)
359 {:ok, notification} = Notification.get(other_user, notification.id)
361 assert notification.user_id == other_user.id
364 test "it returns error if the notification doesn't belong to the user" do
366 other_user = insert(:user)
368 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
370 {:ok, [notification]} = Notification.create_notifications(activity)
371 {:error, _notification} = Notification.get(user, notification.id)
375 describe "dismiss notification" do
376 test "it dismisses a notification that belongs to the user" do
378 other_user = insert(:user)
380 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
382 {:ok, [notification]} = Notification.create_notifications(activity)
383 {:ok, notification} = Notification.dismiss(other_user, notification.id)
385 assert notification.user_id == other_user.id
388 test "it returns error if the notification doesn't belong to the user" do
390 other_user = insert(:user)
392 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
394 {:ok, [notification]} = Notification.create_notifications(activity)
395 {:error, _notification} = Notification.dismiss(user, notification.id)
399 describe "clear notification" do
400 test "it clears all notifications belonging to the user" do
402 other_user = insert(:user)
403 third_user = insert(:user)
406 CommonAPI.post(user, %{
407 status: "hey @#{other_user.nickname} and @#{third_user.nickname} !"
410 {:ok, _notifs} = Notification.create_notifications(activity)
413 CommonAPI.post(user, %{
414 status: "hey again @#{other_user.nickname} and @#{third_user.nickname} !"
417 {:ok, _notifs} = Notification.create_notifications(activity)
418 Notification.clear(other_user)
420 assert Notification.for_user(other_user) == []
421 assert Notification.for_user(third_user) != []
425 describe "set_read_up_to()" do
426 test "it sets all notifications as read up to a specified notification ID" do
428 other_user = insert(:user)
431 CommonAPI.post(user, %{
432 status: "hey @#{other_user.nickname}!"
436 CommonAPI.post(user, %{
437 status: "hey again @#{other_user.nickname}!"
440 [n2, n1] = Notification.for_user(other_user)
445 CommonAPI.post(user, %{
446 status: "hey yet again @#{other_user.nickname}!"
449 [_, read_notification] = Notification.set_read_up_to(other_user, n2.id)
451 assert read_notification.activity.object
453 [n3, n2, n1] = Notification.for_user(other_user)
455 assert n1.seen == true
456 assert n2.seen == true
457 assert n3.seen == false
459 assert %Pleroma.Marker{} =
463 user_id: other_user.id,
464 timeline: "notifications"
467 assert m.last_read_id == to_string(n2.id)
471 describe "for_user_since/2" do
472 defp days_ago(days) do
474 NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second),
475 -days * 60 * 60 * 24,
480 test "Returns recent notifications" do
481 user1 = insert(:user)
482 user2 = insert(:user)
484 Enum.each(0..10, fn i ->
486 CommonAPI.post(user1, %{
487 status: "hey ##{i} @#{user2.nickname}!"
491 {old, new} = Enum.split(Notification.for_user(user2), 5)
493 Enum.each(old, fn notification ->
495 |> cast(%{updated_at: days_ago(10)}, [:updated_at])
496 |> Pleroma.Repo.update!()
499 recent_notifications_ids =
501 |> Notification.for_user_since(
502 NaiveDateTime.add(NaiveDateTime.utc_now(), -5 * 86_400, :second)
506 Enum.each(old, fn %{id: id} ->
507 refute id in recent_notifications_ids
510 Enum.each(new, fn %{id: id} ->
511 assert id in recent_notifications_ids
516 describe "notification target determination / get_notified_from_activity/2" do
517 test "it sends notifications to addressed users in new messages" do
519 other_user = insert(:user)
522 CommonAPI.post(user, %{
523 status: "hey @#{other_user.nickname}!"
526 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
528 assert other_user in enabled_receivers
531 test "it sends notifications to mentioned users in new messages" do
533 other_user = insert(:user)
536 "@context" => "https://www.w3.org/ns/activitystreams",
538 "to" => ["https://www.w3.org/ns/activitystreams#Public"],
539 "actor" => user.ap_id,
542 "content" => "message with a Mention tag, but no explicit tagging",
546 "href" => other_user.ap_id,
547 "name" => other_user.nickname
550 "attributedTo" => user.ap_id
554 {:ok, activity} = Transmogrifier.handle_incoming(create_activity)
556 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
558 assert other_user in enabled_receivers
561 test "it does not send notifications to users who are only cc in new messages" do
563 other_user = insert(:user)
566 "@context" => "https://www.w3.org/ns/activitystreams",
568 "to" => ["https://www.w3.org/ns/activitystreams#Public"],
569 "cc" => [other_user.ap_id],
570 "actor" => user.ap_id,
573 "content" => "hi everyone",
574 "attributedTo" => user.ap_id
578 {:ok, activity} = Transmogrifier.handle_incoming(create_activity)
580 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
582 assert other_user not in enabled_receivers
585 test "it does not send notification to mentioned users in likes" do
587 other_user = insert(:user)
588 third_user = insert(:user)
590 {:ok, activity_one} =
591 CommonAPI.post(user, %{
592 status: "hey @#{other_user.nickname}!"
595 {:ok, activity_two} = CommonAPI.favorite(third_user, activity_one.id)
597 {enabled_receivers, _disabled_receivers} =
598 Notification.get_notified_from_activity(activity_two)
600 assert other_user not in enabled_receivers
603 test "it only notifies the post's author in likes" do
605 other_user = insert(:user)
606 third_user = insert(:user)
608 {:ok, activity_one} =
609 CommonAPI.post(user, %{
610 status: "hey @#{other_user.nickname}!"
613 {:ok, like_data, _} = Builder.like(third_user, activity_one.object)
617 |> Map.put("to", [other_user.ap_id | like_data["to"]])
618 |> ActivityPub.persist(local: true)
620 {enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(like)
622 assert other_user not in enabled_receivers
625 test "it does not send notification to mentioned users in announces" do
627 other_user = insert(:user)
628 third_user = insert(:user)
630 {:ok, activity_one} =
631 CommonAPI.post(user, %{
632 status: "hey @#{other_user.nickname}!"
635 {:ok, activity_two} = CommonAPI.repeat(activity_one.id, third_user)
637 {enabled_receivers, _disabled_receivers} =
638 Notification.get_notified_from_activity(activity_two)
640 assert other_user not in enabled_receivers
643 test "it returns blocking recipient in disabled recipients list" do
645 other_user = insert(:user)
646 {:ok, _user_relationship} = User.block(other_user, user)
648 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
650 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
652 assert [] == enabled_receivers
653 assert [other_user] == disabled_receivers
656 test "it returns notification-muting recipient in disabled recipients list" do
658 other_user = insert(:user)
659 {:ok, _user_relationships} = User.mute(other_user, user)
661 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
663 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
665 assert [] == enabled_receivers
666 assert [other_user] == disabled_receivers
669 test "it returns thread-muting recipient in disabled recipients list" do
671 other_user = insert(:user)
673 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
675 {:ok, _} = CommonAPI.add_mute(other_user, activity)
677 {:ok, same_context_activity} =
678 CommonAPI.post(user, %{
679 status: "hey-hey-hey @#{other_user.nickname}!",
680 in_reply_to_status_id: activity.id
683 {enabled_receivers, disabled_receivers} =
684 Notification.get_notified_from_activity(same_context_activity)
686 assert [other_user] == disabled_receivers
687 refute other_user in enabled_receivers
690 test "it returns non-following domain-blocking recipient in disabled recipients list" do
691 blocked_domain = "blocked.domain"
692 user = insert(:user, %{ap_id: "https://#{blocked_domain}/@actor"})
693 other_user = insert(:user)
695 {:ok, other_user} = User.block_domain(other_user, blocked_domain)
697 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
699 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
701 assert [] == enabled_receivers
702 assert [other_user] == disabled_receivers
705 test "it returns following domain-blocking recipient in enabled recipients list" do
706 blocked_domain = "blocked.domain"
707 user = insert(:user, %{ap_id: "https://#{blocked_domain}/@actor"})
708 other_user = insert(:user)
710 {:ok, other_user} = User.block_domain(other_user, blocked_domain)
711 {:ok, other_user} = User.follow(other_user, user)
713 {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
715 {enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
717 assert [other_user] == enabled_receivers
718 assert [] == disabled_receivers
722 describe "notification lifecycle" do
723 test "liking an activity results in 1 notification, then 0 if the activity is deleted" do
725 other_user = insert(:user)
727 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
729 assert Enum.empty?(Notification.for_user(user))
731 {:ok, _} = CommonAPI.favorite(other_user, activity.id)
733 assert length(Notification.for_user(user)) == 1
735 {:ok, _} = CommonAPI.delete(activity.id, user)
737 assert Enum.empty?(Notification.for_user(user))
740 test "liking an activity results in 1 notification, then 0 if the activity is unliked" do
742 other_user = insert(:user)
744 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
746 assert Enum.empty?(Notification.for_user(user))
748 {:ok, _} = CommonAPI.favorite(other_user, activity.id)
750 assert length(Notification.for_user(user)) == 1
752 {:ok, _} = CommonAPI.unfavorite(activity.id, other_user)
754 assert Enum.empty?(Notification.for_user(user))
757 test "repeating an activity results in 1 notification, then 0 if the activity is deleted" do
759 other_user = insert(:user)
761 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
763 assert Enum.empty?(Notification.for_user(user))
765 {:ok, _} = CommonAPI.repeat(activity.id, other_user)
767 assert length(Notification.for_user(user)) == 1
769 {:ok, _} = CommonAPI.delete(activity.id, user)
771 assert Enum.empty?(Notification.for_user(user))
774 test "repeating an activity results in 1 notification, then 0 if the activity is unrepeated" do
776 other_user = insert(:user)
778 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
780 assert Enum.empty?(Notification.for_user(user))
782 {:ok, _} = CommonAPI.repeat(activity.id, other_user)
784 assert length(Notification.for_user(user)) == 1
786 {:ok, _} = CommonAPI.unrepeat(activity.id, other_user)
788 assert Enum.empty?(Notification.for_user(user))
791 test "liking an activity which is already deleted does not generate a notification" do
793 other_user = insert(:user)
795 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
797 assert Enum.empty?(Notification.for_user(user))
799 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
801 assert Enum.empty?(Notification.for_user(user))
803 {:error, :not_found} = CommonAPI.favorite(other_user, activity.id)
805 assert Enum.empty?(Notification.for_user(user))
808 test "repeating an activity which is already deleted does not generate a notification" do
810 other_user = insert(:user)
812 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
814 assert Enum.empty?(Notification.for_user(user))
816 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
818 assert Enum.empty?(Notification.for_user(user))
820 {:error, _} = CommonAPI.repeat(activity.id, other_user)
822 assert Enum.empty?(Notification.for_user(user))
825 test "replying to a deleted post without tagging does not generate a notification" do
827 other_user = insert(:user)
829 {:ok, activity} = CommonAPI.post(user, %{status: "test post"})
830 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
832 {:ok, _reply_activity} =
833 CommonAPI.post(other_user, %{
834 status: "test reply",
835 in_reply_to_status_id: activity.id
838 assert Enum.empty?(Notification.for_user(user))
841 test "notifications are deleted if a local user is deleted" do
843 other_user = insert(:user)
846 CommonAPI.post(user, %{status: "hi @#{other_user.nickname}", visibility: "direct"})
848 refute Enum.empty?(Notification.for_user(other_user))
850 {:ok, job} = User.delete(user)
851 ObanHelpers.perform(job)
853 assert Enum.empty?(Notification.for_user(other_user))
856 test "notifications are deleted if a remote user is deleted" do
857 remote_user = insert(:user)
858 local_user = insert(:user)
861 "@context" => "https://www.w3.org/ns/activitystreams",
863 "actor" => remote_user.ap_id,
864 "id" => remote_user.ap_id <> "/activities/test",
865 "to" => [local_user.ap_id],
869 "content" => "Hello!",
873 "href" => local_user.ap_id,
874 "name" => "@#{local_user.nickname}"
877 "to" => [local_user.ap_id],
879 "attributedTo" => remote_user.ap_id
883 {:ok, _dm_activity} = Transmogrifier.handle_incoming(dm_message)
885 refute Enum.empty?(Notification.for_user(local_user))
887 delete_user_message = %{
888 "@context" => "https://www.w3.org/ns/activitystreams",
889 "id" => remote_user.ap_id <> "/activities/delete",
890 "actor" => remote_user.ap_id,
892 "object" => remote_user.ap_id
895 remote_user_url = remote_user.ap_id
898 %{method: :get, url: ^remote_user_url} ->
899 %Tesla.Env{status: 404, body: ""}
902 {:ok, _delete_activity} = Transmogrifier.handle_incoming(delete_user_message)
903 ObanHelpers.perform_all()
905 assert Enum.empty?(Notification.for_user(local_user))
908 @tag capture_log: true
909 test "move activity generates a notification" do
910 %{ap_id: old_ap_id} = old_user = insert(:user)
911 %{ap_id: new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id])
912 follower = insert(:user)
913 other_follower = insert(:user, %{allow_following_move: false})
915 User.follow(follower, old_user)
916 User.follow(other_follower, old_user)
918 old_user_url = old_user.ap_id
921 File.read!("test/fixtures/users_mock/localhost.json")
922 |> String.replace("{{nickname}}", old_user.nickname)
926 %{method: :get, url: ^old_user_url} ->
927 %Tesla.Env{status: 200, body: body}
930 Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
931 ObanHelpers.perform_all()
936 data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
939 ] = Notification.for_user(follower)
944 data: %{"type" => "Move", "actor" => ^old_ap_id, "target" => ^new_ap_id}
947 ] = Notification.for_user(other_follower)
951 describe "for_user" do
952 test "it returns notifications for muted user without notifications" do
954 muted = insert(:user)
955 {:ok, _user_relationships} = User.mute(user, muted, false)
957 {:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
959 [notification] = Notification.for_user(user)
961 assert notification.activity.object
964 test "it doesn't return notifications for muted user with notifications" do
966 muted = insert(:user)
967 {:ok, _user_relationships} = User.mute(user, muted)
969 {:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
971 assert Notification.for_user(user) == []
974 test "it doesn't return notifications for blocked user" do
976 blocked = insert(:user)
977 {:ok, _user_relationship} = User.block(user, blocked)
979 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
981 assert Notification.for_user(user) == []
984 test "it doesn't return notifications for domain-blocked non-followed user" do
986 blocked = insert(:user, ap_id: "http://some-domain.com")
987 {:ok, user} = User.block_domain(user, "some-domain.com")
989 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
991 assert Notification.for_user(user) == []
994 test "it returns notifications for domain-blocked but followed user" do
996 blocked = insert(:user, ap_id: "http://some-domain.com")
998 {:ok, user} = User.block_domain(user, "some-domain.com")
999 {:ok, _} = User.follow(user, blocked)
1001 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
1003 assert length(Notification.for_user(user)) == 1
1006 test "it doesn't return notifications for muted thread" do
1007 user = insert(:user)
1008 another_user = insert(:user)
1010 {:ok, activity} = CommonAPI.post(another_user, %{status: "hey @#{user.nickname}"})
1012 {:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
1013 assert Notification.for_user(user) == []
1016 test "it returns notifications from a muted user when with_muted is set" do
1017 user = insert(:user)
1018 muted = insert(:user)
1019 {:ok, _user_relationships} = User.mute(user, muted)
1021 {:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
1023 assert length(Notification.for_user(user, %{with_muted: true})) == 1
1026 test "it doesn't return notifications from a blocked user when with_muted is set" do
1027 user = insert(:user)
1028 blocked = insert(:user)
1029 {:ok, _user_relationship} = User.block(user, blocked)
1031 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
1033 assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
1036 test "when with_muted is set, " <>
1037 "it doesn't return notifications from a domain-blocked non-followed user" do
1038 user = insert(:user)
1039 blocked = insert(:user, ap_id: "http://some-domain.com")
1040 {:ok, user} = User.block_domain(user, "some-domain.com")
1042 {:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
1044 assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
1047 test "it returns notifications from muted threads when with_muted is set" do
1048 user = insert(:user)
1049 another_user = insert(:user)
1051 {:ok, activity} = CommonAPI.post(another_user, %{status: "hey @#{user.nickname}"})
1053 {:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
1054 assert length(Notification.for_user(user, %{with_muted: true})) == 1