transmogrifier: use User.delete() instead of handrolled user deletion code for remote...
[akkoma] / test / notification_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.NotificationTest do
6 use Pleroma.DataCase
7 alias Pleroma.Notification
8 alias Pleroma.User
9 alias Pleroma.Web.ActivityPub.Transmogrifier
10 alias Pleroma.Web.CommonAPI
11 alias Pleroma.Web.Streamer
12 alias Pleroma.Web.TwitterAPI.TwitterAPI
13 import Pleroma.Factory
14
15 describe "create_notifications" do
16 test "notifies someone when they are directly addressed" do
17 user = insert(:user)
18 other_user = insert(:user)
19 third_user = insert(:user)
20
21 {:ok, activity} =
22 TwitterAPI.create_status(user, %{
23 "status" => "hey @#{other_user.nickname} and @#{third_user.nickname}"
24 })
25
26 {:ok, [notification, other_notification]} = Notification.create_notifications(activity)
27
28 notified_ids = Enum.sort([notification.user_id, other_notification.user_id])
29 assert notified_ids == [other_user.id, third_user.id]
30 assert notification.activity_id == activity.id
31 assert other_notification.activity_id == activity.id
32 end
33
34 test "it creates a notification for subscribed users" do
35 user = insert(:user)
36 subscriber = insert(:user)
37
38 User.subscribe(subscriber, user)
39
40 {:ok, status} = TwitterAPI.create_status(user, %{"status" => "Akariiiin"})
41 {:ok, [notification]} = Notification.create_notifications(status)
42
43 assert notification.user_id == subscriber.id
44 end
45
46 test "does not create a notification for subscribed users if status is a reply" do
47 user = insert(:user)
48 other_user = insert(:user)
49 subscriber = insert(:user)
50
51 User.subscribe(subscriber, other_user)
52
53 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
54
55 {:ok, _reply_activity} =
56 CommonAPI.post(other_user, %{
57 "status" => "test reply",
58 "in_reply_to_status_id" => activity.id
59 })
60
61 user_notifications = Notification.for_user(user)
62 assert length(user_notifications) == 1
63
64 subscriber_notifications = Notification.for_user(subscriber)
65 assert Enum.empty?(subscriber_notifications)
66 end
67 end
68
69 describe "create_notification" do
70 setup do
71 GenServer.start(Streamer, %{}, name: Streamer)
72
73 on_exit(fn ->
74 if pid = Process.whereis(Streamer) do
75 Process.exit(pid, :kill)
76 end
77 end)
78 end
79
80 test "it creates a notification for user and send to the 'user' and the 'user:notification' stream" do
81 user = insert(:user)
82 task = Task.async(fn -> assert_receive {:text, _}, 4_000 end)
83 task_user_notification = Task.async(fn -> assert_receive {:text, _}, 4_000 end)
84 Streamer.add_socket("user", %{transport_pid: task.pid, assigns: %{user: user}})
85
86 Streamer.add_socket(
87 "user:notification",
88 %{transport_pid: task_user_notification.pid, assigns: %{user: user}}
89 )
90
91 activity = insert(:note_activity)
92
93 notify = Notification.create_notification(activity, user)
94 assert notify.user_id == user.id
95 Task.await(task)
96 Task.await(task_user_notification)
97 end
98
99 test "it creates a notification for user if the user blocks the activity author" do
100 activity = insert(:note_activity)
101 author = User.get_cached_by_ap_id(activity.data["actor"])
102 user = insert(:user)
103 {:ok, user} = User.block(user, author)
104
105 assert Notification.create_notification(activity, user)
106 end
107
108 test "it creates a notificatin for the user if the user mutes the activity author" do
109 muter = insert(:user)
110 muted = insert(:user)
111 {:ok, _} = User.mute(muter, muted)
112 muter = Repo.get(User, muter.id)
113 {:ok, activity} = CommonAPI.post(muted, %{"status" => "Hi @#{muter.nickname}"})
114
115 assert Notification.create_notification(activity, muter)
116 end
117
118 test "notification created if user is muted without notifications" do
119 muter = insert(:user)
120 muted = insert(:user)
121
122 {:ok, muter} = User.mute(muter, muted, false)
123
124 {:ok, activity} = CommonAPI.post(muted, %{"status" => "Hi @#{muter.nickname}"})
125
126 assert Notification.create_notification(activity, muter)
127 end
128
129 test "it creates a notification for an activity from a muted thread" do
130 muter = insert(:user)
131 other_user = insert(:user)
132 {:ok, activity} = CommonAPI.post(muter, %{"status" => "hey"})
133 CommonAPI.add_mute(muter, activity)
134
135 {:ok, activity} =
136 CommonAPI.post(other_user, %{
137 "status" => "Hi @#{muter.nickname}",
138 "in_reply_to_status_id" => activity.id
139 })
140
141 assert Notification.create_notification(activity, muter)
142 end
143
144 test "it disables notifications from followers" do
145 follower = insert(:user)
146 followed = insert(:user, info: %{notification_settings: %{"followers" => false}})
147 User.follow(follower, followed)
148 {:ok, activity} = CommonAPI.post(follower, %{"status" => "hey @#{followed.nickname}"})
149 refute Notification.create_notification(activity, followed)
150 end
151
152 test "it disables notifications from non-followers" do
153 follower = insert(:user)
154 followed = insert(:user, info: %{notification_settings: %{"non_followers" => false}})
155 {:ok, activity} = CommonAPI.post(follower, %{"status" => "hey @#{followed.nickname}"})
156 refute Notification.create_notification(activity, followed)
157 end
158
159 test "it disables notifications from people the user follows" do
160 follower = insert(:user, info: %{notification_settings: %{"follows" => false}})
161 followed = insert(:user)
162 User.follow(follower, followed)
163 follower = Repo.get(User, follower.id)
164 {:ok, activity} = CommonAPI.post(followed, %{"status" => "hey @#{follower.nickname}"})
165 refute Notification.create_notification(activity, follower)
166 end
167
168 test "it disables notifications from people the user does not follow" do
169 follower = insert(:user, info: %{notification_settings: %{"non_follows" => false}})
170 followed = insert(:user)
171 {:ok, activity} = CommonAPI.post(followed, %{"status" => "hey @#{follower.nickname}"})
172 refute Notification.create_notification(activity, follower)
173 end
174
175 test "it doesn't create a notification for user if he is the activity author" do
176 activity = insert(:note_activity)
177 author = User.get_cached_by_ap_id(activity.data["actor"])
178
179 refute Notification.create_notification(activity, author)
180 end
181
182 test "it doesn't create a notification for follow-unfollow-follow chains" do
183 user = insert(:user)
184 followed_user = insert(:user)
185 {:ok, _, _, activity} = TwitterAPI.follow(user, %{"user_id" => followed_user.id})
186 Notification.create_notification(activity, followed_user)
187 TwitterAPI.unfollow(user, %{"user_id" => followed_user.id})
188 {:ok, _, _, activity_dupe} = TwitterAPI.follow(user, %{"user_id" => followed_user.id})
189 refute Notification.create_notification(activity_dupe, followed_user)
190 end
191
192 test "it doesn't create a notification for like-unlike-like chains" do
193 user = insert(:user)
194 liked_user = insert(:user)
195 {:ok, status} = TwitterAPI.create_status(liked_user, %{"status" => "Yui is best yuru"})
196 {:ok, fav_status} = TwitterAPI.fav(user, status.id)
197 Notification.create_notification(fav_status, liked_user)
198 TwitterAPI.unfav(user, status.id)
199 {:ok, dupe} = TwitterAPI.fav(user, status.id)
200 refute Notification.create_notification(dupe, liked_user)
201 end
202
203 test "it doesn't create a notification for repeat-unrepeat-repeat chains" do
204 user = insert(:user)
205 retweeted_user = insert(:user)
206
207 {:ok, status} =
208 TwitterAPI.create_status(retweeted_user, %{
209 "status" => "Send dupe notifications to the shadow realm"
210 })
211
212 {:ok, retweeted_activity} = TwitterAPI.repeat(user, status.id)
213 Notification.create_notification(retweeted_activity, retweeted_user)
214 TwitterAPI.unrepeat(user, status.id)
215 {:ok, dupe} = TwitterAPI.repeat(user, status.id)
216 refute Notification.create_notification(dupe, retweeted_user)
217 end
218
219 test "it doesn't create duplicate notifications for follow+subscribed users" do
220 user = insert(:user)
221 subscriber = insert(:user)
222
223 {:ok, _, _, _} = TwitterAPI.follow(subscriber, %{"user_id" => user.id})
224 User.subscribe(subscriber, user)
225 {:ok, status} = TwitterAPI.create_status(user, %{"status" => "Akariiiin"})
226 {:ok, [_notif]} = Notification.create_notifications(status)
227 end
228
229 test "it doesn't create subscription notifications if the recipient cannot see the status" do
230 user = insert(:user)
231 subscriber = insert(:user)
232
233 User.subscribe(subscriber, user)
234
235 {:ok, status} =
236 TwitterAPI.create_status(user, %{"status" => "inwisible", "visibility" => "direct"})
237
238 assert {:ok, []} == Notification.create_notifications(status)
239 end
240 end
241
242 describe "get notification" do
243 test "it gets a notification that belongs to the user" do
244 user = insert(:user)
245 other_user = insert(:user)
246
247 {:ok, activity} =
248 TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
249
250 {:ok, [notification]} = Notification.create_notifications(activity)
251 {:ok, notification} = Notification.get(other_user, notification.id)
252
253 assert notification.user_id == other_user.id
254 end
255
256 test "it returns error if the notification doesn't belong to the user" do
257 user = insert(:user)
258 other_user = insert(:user)
259
260 {:ok, activity} =
261 TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
262
263 {:ok, [notification]} = Notification.create_notifications(activity)
264 {:error, _notification} = Notification.get(user, notification.id)
265 end
266 end
267
268 describe "dismiss notification" do
269 test "it dismisses a notification that belongs to the user" do
270 user = insert(:user)
271 other_user = insert(:user)
272
273 {:ok, activity} =
274 TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
275
276 {:ok, [notification]} = Notification.create_notifications(activity)
277 {:ok, notification} = Notification.dismiss(other_user, notification.id)
278
279 assert notification.user_id == other_user.id
280 end
281
282 test "it returns error if the notification doesn't belong to the user" do
283 user = insert(:user)
284 other_user = insert(:user)
285
286 {:ok, activity} =
287 TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
288
289 {:ok, [notification]} = Notification.create_notifications(activity)
290 {:error, _notification} = Notification.dismiss(user, notification.id)
291 end
292 end
293
294 describe "clear notification" do
295 test "it clears all notifications belonging to the user" do
296 user = insert(:user)
297 other_user = insert(:user)
298 third_user = insert(:user)
299
300 {:ok, activity} =
301 TwitterAPI.create_status(user, %{
302 "status" => "hey @#{other_user.nickname} and @#{third_user.nickname} !"
303 })
304
305 {:ok, _notifs} = Notification.create_notifications(activity)
306
307 {:ok, activity} =
308 TwitterAPI.create_status(user, %{
309 "status" => "hey again @#{other_user.nickname} and @#{third_user.nickname} !"
310 })
311
312 {:ok, _notifs} = Notification.create_notifications(activity)
313 Notification.clear(other_user)
314
315 assert Notification.for_user(other_user) == []
316 assert Notification.for_user(third_user) != []
317 end
318 end
319
320 describe "set_read_up_to()" do
321 test "it sets all notifications as read up to a specified notification ID" do
322 user = insert(:user)
323 other_user = insert(:user)
324
325 {:ok, _activity} =
326 TwitterAPI.create_status(user, %{
327 "status" => "hey @#{other_user.nickname}!"
328 })
329
330 {:ok, _activity} =
331 TwitterAPI.create_status(user, %{
332 "status" => "hey again @#{other_user.nickname}!"
333 })
334
335 [n2, n1] = notifs = Notification.for_user(other_user)
336 assert length(notifs) == 2
337
338 assert n2.id > n1.id
339
340 {:ok, _activity} =
341 TwitterAPI.create_status(user, %{
342 "status" => "hey yet again @#{other_user.nickname}!"
343 })
344
345 Notification.set_read_up_to(other_user, n2.id)
346
347 [n3, n2, n1] = Notification.for_user(other_user)
348
349 assert n1.seen == true
350 assert n2.seen == true
351 assert n3.seen == false
352 end
353 end
354
355 describe "notification target determination" do
356 test "it sends notifications to addressed users in new messages" do
357 user = insert(:user)
358 other_user = insert(:user)
359
360 {:ok, activity} =
361 CommonAPI.post(user, %{
362 "status" => "hey @#{other_user.nickname}!"
363 })
364
365 assert other_user in Notification.get_notified_from_activity(activity)
366 end
367
368 test "it sends notifications to mentioned users in new messages" do
369 user = insert(:user)
370 other_user = insert(:user)
371
372 create_activity = %{
373 "@context" => "https://www.w3.org/ns/activitystreams",
374 "type" => "Create",
375 "to" => ["https://www.w3.org/ns/activitystreams#Public"],
376 "actor" => user.ap_id,
377 "object" => %{
378 "type" => "Note",
379 "content" => "message with a Mention tag, but no explicit tagging",
380 "tag" => [
381 %{
382 "type" => "Mention",
383 "href" => other_user.ap_id,
384 "name" => other_user.nickname
385 }
386 ],
387 "attributedTo" => user.ap_id
388 }
389 }
390
391 {:ok, activity} = Transmogrifier.handle_incoming(create_activity)
392
393 assert other_user in Notification.get_notified_from_activity(activity)
394 end
395
396 test "it does not send notifications to users who are only cc in new messages" do
397 user = insert(:user)
398 other_user = insert(:user)
399
400 create_activity = %{
401 "@context" => "https://www.w3.org/ns/activitystreams",
402 "type" => "Create",
403 "to" => ["https://www.w3.org/ns/activitystreams#Public"],
404 "cc" => [other_user.ap_id],
405 "actor" => user.ap_id,
406 "object" => %{
407 "type" => "Note",
408 "content" => "hi everyone",
409 "attributedTo" => user.ap_id
410 }
411 }
412
413 {:ok, activity} = Transmogrifier.handle_incoming(create_activity)
414
415 assert other_user not in Notification.get_notified_from_activity(activity)
416 end
417
418 test "it does not send notification to mentioned users in likes" do
419 user = insert(:user)
420 other_user = insert(:user)
421 third_user = insert(:user)
422
423 {:ok, activity_one} =
424 CommonAPI.post(user, %{
425 "status" => "hey @#{other_user.nickname}!"
426 })
427
428 {:ok, activity_two, _} = CommonAPI.favorite(activity_one.id, third_user)
429
430 assert other_user not in Notification.get_notified_from_activity(activity_two)
431 end
432
433 test "it does not send notification to mentioned users in announces" do
434 user = insert(:user)
435 other_user = insert(:user)
436 third_user = insert(:user)
437
438 {:ok, activity_one} =
439 CommonAPI.post(user, %{
440 "status" => "hey @#{other_user.nickname}!"
441 })
442
443 {:ok, activity_two, _} = CommonAPI.repeat(activity_one.id, third_user)
444
445 assert other_user not in Notification.get_notified_from_activity(activity_two)
446 end
447 end
448
449 describe "notification lifecycle" do
450 test "liking an activity results in 1 notification, then 0 if the activity is deleted" do
451 user = insert(:user)
452 other_user = insert(:user)
453
454 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
455
456 assert Enum.empty?(Notification.for_user(user))
457
458 {:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
459
460 assert length(Notification.for_user(user)) == 1
461
462 {:ok, _} = CommonAPI.delete(activity.id, user)
463
464 assert Enum.empty?(Notification.for_user(user))
465 end
466
467 test "liking an activity results in 1 notification, then 0 if the activity is unliked" do
468 user = insert(:user)
469 other_user = insert(:user)
470
471 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
472
473 assert Enum.empty?(Notification.for_user(user))
474
475 {:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
476
477 assert length(Notification.for_user(user)) == 1
478
479 {:ok, _, _, _} = CommonAPI.unfavorite(activity.id, other_user)
480
481 assert Enum.empty?(Notification.for_user(user))
482 end
483
484 test "repeating an activity results in 1 notification, then 0 if the activity is deleted" do
485 user = insert(:user)
486 other_user = insert(:user)
487
488 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
489
490 assert Enum.empty?(Notification.for_user(user))
491
492 {:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
493
494 assert length(Notification.for_user(user)) == 1
495
496 {:ok, _} = CommonAPI.delete(activity.id, user)
497
498 assert Enum.empty?(Notification.for_user(user))
499 end
500
501 test "repeating an activity results in 1 notification, then 0 if the activity is unrepeated" do
502 user = insert(:user)
503 other_user = insert(:user)
504
505 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
506
507 assert Enum.empty?(Notification.for_user(user))
508
509 {:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
510
511 assert length(Notification.for_user(user)) == 1
512
513 {:ok, _, _} = CommonAPI.unrepeat(activity.id, other_user)
514
515 assert Enum.empty?(Notification.for_user(user))
516 end
517
518 test "liking an activity which is already deleted does not generate a notification" do
519 user = insert(:user)
520 other_user = insert(:user)
521
522 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
523
524 assert Enum.empty?(Notification.for_user(user))
525
526 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
527
528 assert Enum.empty?(Notification.for_user(user))
529
530 {:error, _} = CommonAPI.favorite(activity.id, other_user)
531
532 assert Enum.empty?(Notification.for_user(user))
533 end
534
535 test "repeating an activity which is already deleted does not generate a notification" do
536 user = insert(:user)
537 other_user = insert(:user)
538
539 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
540
541 assert Enum.empty?(Notification.for_user(user))
542
543 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
544
545 assert Enum.empty?(Notification.for_user(user))
546
547 {:error, _} = CommonAPI.repeat(activity.id, other_user)
548
549 assert Enum.empty?(Notification.for_user(user))
550 end
551
552 test "replying to a deleted post without tagging does not generate a notification" do
553 user = insert(:user)
554 other_user = insert(:user)
555
556 {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
557 {:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
558
559 {:ok, _reply_activity} =
560 CommonAPI.post(other_user, %{
561 "status" => "test reply",
562 "in_reply_to_status_id" => activity.id
563 })
564
565 assert Enum.empty?(Notification.for_user(user))
566 end
567
568 test "notifications are deleted if a local user is deleted" do
569 user = insert(:user)
570 other_user = insert(:user)
571
572 {:ok, _activity} =
573 CommonAPI.post(user, %{"status" => "hi @#{other_user.nickname}", "visibility" => "direct"})
574
575 refute Enum.empty?(Notification.for_user(other_user))
576
577 User.delete(user)
578
579 assert Enum.empty?(Notification.for_user(other_user))
580 end
581
582 test "notifications are deleted if a remote user is deleted" do
583 remote_user = insert(:user)
584 local_user = insert(:user)
585
586 dm_message = %{
587 "@context" => "https://www.w3.org/ns/activitystreams",
588 "type" => "Create",
589 "actor" => remote_user.ap_id,
590 "id" => remote_user.ap_id <> "/activities/test",
591 "to" => [local_user.ap_id],
592 "cc" => [],
593 "object" => %{
594 "type" => "Note",
595 "content" => "Hello!",
596 "tag" => [
597 %{
598 "type" => "Mention",
599 "href" => local_user.ap_id,
600 "name" => "@#{local_user.nickname}"
601 }
602 ],
603 "to" => [local_user.ap_id],
604 "cc" => [],
605 "attributedTo" => remote_user.ap_id
606 }
607 }
608
609 {:ok, _dm_activity} = Transmogrifier.handle_incoming(dm_message)
610
611 refute Enum.empty?(Notification.for_user(local_user))
612
613 delete_user_message = %{
614 "@context" => "https://www.w3.org/ns/activitystreams",
615 "id" => remote_user.ap_id <> "/activities/delete",
616 "actor" => remote_user.ap_id,
617 "type" => "Delete",
618 "object" => remote_user.ap_id
619 }
620
621 {:ok, _delete_activity} = Transmogrifier.handle_incoming(delete_user_message)
622
623 assert Enum.empty?(Notification.for_user(local_user))
624 end
625 end
626
627 describe "for_user" do
628 test "it returns notifications for muted user without notifications" do
629 user = insert(:user)
630 muted = insert(:user)
631 {:ok, user} = User.mute(user, muted, false)
632
633 {:ok, _activity} = TwitterAPI.create_status(muted, %{"status" => "hey @#{user.nickname}"})
634
635 assert length(Notification.for_user(user)) == 1
636 end
637
638 test "it doesn't return notifications for muted user with notifications" do
639 user = insert(:user)
640 muted = insert(:user)
641 {:ok, user} = User.mute(user, muted)
642
643 {:ok, _activity} = TwitterAPI.create_status(muted, %{"status" => "hey @#{user.nickname}"})
644
645 assert Notification.for_user(user) == []
646 end
647
648 test "it doesn't return notifications for blocked user" do
649 user = insert(:user)
650 blocked = insert(:user)
651 {:ok, user} = User.block(user, blocked)
652
653 {:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"})
654
655 assert Notification.for_user(user) == []
656 end
657
658 test "it doesn't return notificatitons for blocked domain" do
659 user = insert(:user)
660 blocked = insert(:user, ap_id: "http://some-domain.com")
661 {:ok, user} = User.block_domain(user, "some-domain.com")
662
663 {:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"})
664
665 assert Notification.for_user(user) == []
666 end
667
668 test "it doesn't return notifications for muted thread" do
669 user = insert(:user)
670 another_user = insert(:user)
671
672 {:ok, activity} =
673 TwitterAPI.create_status(another_user, %{"status" => "hey @#{user.nickname}"})
674
675 {:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
676 assert Notification.for_user(user) == []
677 end
678
679 test "it returns notifications for muted user with notifications and with_muted parameter" do
680 user = insert(:user)
681 muted = insert(:user)
682 {:ok, user} = User.mute(user, muted)
683
684 {:ok, _activity} = TwitterAPI.create_status(muted, %{"status" => "hey @#{user.nickname}"})
685
686 assert length(Notification.for_user(user, %{with_muted: true})) == 1
687 end
688
689 test "it returns notifications for blocked user and with_muted parameter" do
690 user = insert(:user)
691 blocked = insert(:user)
692 {:ok, user} = User.block(user, blocked)
693
694 {:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"})
695
696 assert length(Notification.for_user(user, %{with_muted: true})) == 1
697 end
698
699 test "it returns notificatitons for blocked domain and with_muted parameter" do
700 user = insert(:user)
701 blocked = insert(:user, ap_id: "http://some-domain.com")
702 {:ok, user} = User.block_domain(user, "some-domain.com")
703
704 {:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"})
705
706 assert length(Notification.for_user(user, %{with_muted: true})) == 1
707 end
708
709 test "it returns notifications for muted thread with_muted parameter" do
710 user = insert(:user)
711 another_user = insert(:user)
712
713 {:ok, activity} =
714 TwitterAPI.create_status(another_user, %{"status" => "hey @#{user.nickname}"})
715
716 {:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
717 assert length(Notification.for_user(user, %{with_muted: true})) == 1
718 end
719 end
720 end