1524df98fa9832e42b09ba4641e2189ea65d40fd
[anni] / test / pleroma / web / mastodon_api / controllers / notification_controller_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
6   use Pleroma.Web.ConnCase, async: false
7
8   alias Pleroma.Notification
9   alias Pleroma.Repo
10   alias Pleroma.User
11   alias Pleroma.Web.CommonAPI
12
13   import Pleroma.Factory
14
15   test "does NOT render account/pleroma/relationship by default" do
16     %{user: user, conn: conn} = oauth_access(["read:notifications"])
17     other_user = insert(:user)
18
19     {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
20     {:ok, [_notification]} = Notification.create_notifications(activity)
21
22     response =
23       conn
24       |> assign(:user, user)
25       |> get("/api/v1/notifications")
26       |> json_response_and_validate_schema(200)
27
28     assert Enum.all?(response, fn n ->
29              get_in(n, ["account", "pleroma", "relationship"]) == %{}
30            end)
31   end
32
33   test "list of notifications" do
34     %{user: user, conn: conn} = oauth_access(["read:notifications"])
35     other_user = insert(:user)
36
37     {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
38
39     {:ok, [_notification]} = Notification.create_notifications(activity)
40
41     conn =
42       conn
43       |> assign(:user, user)
44       |> get("/api/v1/notifications")
45
46     expected_response =
47       "hi <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{user.id}\" href=\"#{user.ap_id}\" rel=\"ugc\">@<span>#{user.nickname}</span></a></span>"
48
49     assert [%{"status" => %{"content" => response}} | _rest] =
50              json_response_and_validate_schema(conn, 200)
51
52     assert response == expected_response
53   end
54
55   test "by default, does not contain pleroma:chat_mention" do
56     %{user: user, conn: conn} = oauth_access(["read:notifications"])
57     other_user = insert(:user)
58
59     {:ok, _activity} = CommonAPI.post_chat_message(other_user, user, "hey")
60
61     result =
62       conn
63       |> get("/api/v1/notifications")
64       |> json_response_and_validate_schema(200)
65
66     assert [] == result
67
68     result =
69       conn
70       |> get("/api/v1/notifications?include_types[]=pleroma:chat_mention")
71       |> json_response_and_validate_schema(200)
72
73     assert [_] = result
74   end
75
76   test "by default, does not contain pleroma:report" do
77     clear_config([:instance, :moderator_privileges], [:reports_manage_reports])
78
79     user = insert(:user)
80     other_user = insert(:user)
81     third_user = insert(:user)
82
83     {:ok, user} = user |> User.admin_api_update(%{is_moderator: true})
84
85     %{conn: conn} = oauth_access(["read:notifications"], user: user)
86
87     {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
88
89     {:ok, _report} =
90       CommonAPI.report(third_user, %{account_id: other_user.id, status_ids: [activity.id]})
91
92     result =
93       conn
94       |> get("/api/v1/notifications")
95       |> json_response_and_validate_schema(200)
96
97     assert [] == result
98
99     result =
100       conn
101       |> get("/api/v1/notifications?include_types[]=pleroma:report")
102       |> json_response_and_validate_schema(200)
103
104     assert [_] = result
105   end
106
107   test "Pleroma:report is hidden for non-privileged users" do
108     clear_config([:instance, :moderator_privileges], [:reports_manage_reports])
109
110     user = insert(:user)
111     other_user = insert(:user)
112     third_user = insert(:user)
113
114     {:ok, user} = user |> User.admin_api_update(%{is_moderator: true})
115
116     %{conn: conn} = oauth_access(["read:notifications"], user: user)
117
118     {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
119
120     {:ok, _report} =
121       CommonAPI.report(third_user, %{account_id: other_user.id, status_ids: [activity.id]})
122
123     result =
124       conn
125       |> get("/api/v1/notifications?include_types[]=pleroma:report")
126       |> json_response_and_validate_schema(200)
127
128     assert [_] = result
129
130     clear_config([:instance, :moderator_privileges], [])
131
132     result =
133       conn
134       |> get("/api/v1/notifications?include_types[]=pleroma:report")
135       |> json_response_and_validate_schema(200)
136
137     assert [] == result
138   end
139
140   test "excludes mentions from blockers when blockers_visible is false" do
141     clear_config([:activitypub, :blockers_visible], false)
142
143     %{user: user, conn: conn} = oauth_access(["read:notifications"])
144     blocker = insert(:user)
145
146     {:ok, _} = CommonAPI.block(blocker, user)
147     {:ok, activity} = CommonAPI.post(blocker, %{status: "hi @#{user.nickname}"})
148
149     {:ok, [_notification]} = Notification.create_notifications(activity)
150
151     conn =
152       conn
153       |> assign(:user, user)
154       |> get("/api/v1/notifications")
155
156     assert [] == json_response_and_validate_schema(conn, 200)
157   end
158
159   test "getting a single notification" do
160     %{user: user, conn: conn} = oauth_access(["read:notifications"])
161     other_user = insert(:user)
162
163     {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
164
165     {:ok, [notification]} = Notification.create_notifications(activity)
166
167     conn = get(conn, "/api/v1/notifications/#{notification.id}")
168
169     expected_response =
170       "hi <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{user.id}\" href=\"#{user.ap_id}\" rel=\"ugc\">@<span>#{user.nickname}</span></a></span>"
171
172     assert %{"status" => %{"content" => response}} = json_response_and_validate_schema(conn, 200)
173     assert response == expected_response
174   end
175
176   test "dismissing a single notification (deprecated endpoint)" do
177     %{user: user, conn: conn} = oauth_access(["write:notifications"])
178     other_user = insert(:user)
179
180     {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
181
182     {:ok, [notification]} = Notification.create_notifications(activity)
183
184     conn =
185       conn
186       |> assign(:user, user)
187       |> put_req_header("content-type", "application/json")
188       |> post("/api/v1/notifications/dismiss", %{"id" => to_string(notification.id)})
189
190     assert %{} = json_response_and_validate_schema(conn, 200)
191   end
192
193   test "dismissing a single notification" do
194     %{user: user, conn: conn} = oauth_access(["write:notifications"])
195     other_user = insert(:user)
196
197     {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
198
199     {:ok, [notification]} = Notification.create_notifications(activity)
200
201     conn =
202       conn
203       |> assign(:user, user)
204       |> post("/api/v1/notifications/#{notification.id}/dismiss")
205
206     assert %{} = json_response_and_validate_schema(conn, 200)
207   end
208
209   test "clearing all notifications" do
210     %{user: user, conn: conn} = oauth_access(["write:notifications", "read:notifications"])
211     other_user = insert(:user)
212
213     {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
214
215     {:ok, [_notification]} = Notification.create_notifications(activity)
216
217     ret_conn = post(conn, "/api/v1/notifications/clear")
218
219     assert %{} = json_response_and_validate_schema(ret_conn, 200)
220
221     ret_conn = get(conn, "/api/v1/notifications")
222
223     assert all = json_response_and_validate_schema(ret_conn, 200)
224     assert all == []
225   end
226
227   test "paginates notifications using min_id, since_id, max_id, and limit" do
228     %{user: user, conn: conn} = oauth_access(["read:notifications"])
229     other_user = insert(:user)
230
231     {:ok, activity1} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
232     {:ok, activity2} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
233     {:ok, activity3} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
234     {:ok, activity4} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
235
236     notification1_id = get_notification_id_by_activity(activity1)
237     notification2_id = get_notification_id_by_activity(activity2)
238     notification3_id = get_notification_id_by_activity(activity3)
239     notification4_id = get_notification_id_by_activity(activity4)
240
241     conn = assign(conn, :user, user)
242
243     # min_id
244     result =
245       conn
246       |> get("/api/v1/notifications?limit=2&min_id=#{notification1_id}")
247       |> json_response_and_validate_schema(:ok)
248
249     assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result
250
251     # since_id
252     result =
253       conn
254       |> get("/api/v1/notifications?limit=2&since_id=#{notification1_id}")
255       |> json_response_and_validate_schema(:ok)
256
257     assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result
258
259     # max_id
260     result =
261       conn
262       |> get("/api/v1/notifications?limit=2&max_id=#{notification4_id}")
263       |> json_response_and_validate_schema(:ok)
264
265     assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result
266   end
267
268   describe "exclude_visibilities" do
269     test "filters notifications for mentions" do
270       %{user: user, conn: conn} = oauth_access(["read:notifications"])
271       other_user = insert(:user)
272
273       {:ok, public_activity} =
274         CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "public"})
275
276       {:ok, direct_activity} =
277         CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "direct"})
278
279       {:ok, unlisted_activity} =
280         CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "unlisted"})
281
282       {:ok, private_activity} =
283         CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "private"})
284
285       query = params_to_query(%{exclude_visibilities: ["public", "unlisted", "private"]})
286       conn_res = get(conn, "/api/v1/notifications?" <> query)
287
288       assert [%{"status" => %{"id" => id}}] = json_response_and_validate_schema(conn_res, 200)
289       assert id == direct_activity.id
290
291       query = params_to_query(%{exclude_visibilities: ["public", "unlisted", "direct"]})
292       conn_res = get(conn, "/api/v1/notifications?" <> query)
293
294       assert [%{"status" => %{"id" => id}}] = json_response_and_validate_schema(conn_res, 200)
295       assert id == private_activity.id
296
297       query = params_to_query(%{exclude_visibilities: ["public", "private", "direct"]})
298       conn_res = get(conn, "/api/v1/notifications?" <> query)
299
300       assert [%{"status" => %{"id" => id}}] = json_response_and_validate_schema(conn_res, 200)
301       assert id == unlisted_activity.id
302
303       query = params_to_query(%{exclude_visibilities: ["unlisted", "private", "direct"]})
304       conn_res = get(conn, "/api/v1/notifications?" <> query)
305
306       assert [%{"status" => %{"id" => id}}] = json_response_and_validate_schema(conn_res, 200)
307       assert id == public_activity.id
308     end
309
310     test "filters notifications for Like activities" do
311       user = insert(:user)
312       %{user: other_user, conn: conn} = oauth_access(["read:notifications"])
313
314       {:ok, public_activity} = CommonAPI.post(other_user, %{status: ".", visibility: "public"})
315
316       {:ok, direct_activity} =
317         CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "direct"})
318
319       {:ok, unlisted_activity} =
320         CommonAPI.post(other_user, %{status: ".", visibility: "unlisted"})
321
322       {:ok, private_activity} = CommonAPI.post(other_user, %{status: ".", visibility: "private"})
323
324       {:ok, _} = CommonAPI.favorite(user, public_activity.id)
325       {:ok, _} = CommonAPI.favorite(user, direct_activity.id)
326       {:ok, _} = CommonAPI.favorite(user, unlisted_activity.id)
327       {:ok, _} = CommonAPI.favorite(user, private_activity.id)
328
329       activity_ids =
330         conn
331         |> get("/api/v1/notifications?exclude_visibilities[]=direct")
332         |> json_response_and_validate_schema(200)
333         |> Enum.map(& &1["status"]["id"])
334
335       assert public_activity.id in activity_ids
336       assert unlisted_activity.id in activity_ids
337       assert private_activity.id in activity_ids
338       refute direct_activity.id in activity_ids
339
340       activity_ids =
341         conn
342         |> get("/api/v1/notifications?exclude_visibilities[]=unlisted")
343         |> json_response_and_validate_schema(200)
344         |> Enum.map(& &1["status"]["id"])
345
346       assert public_activity.id in activity_ids
347       refute unlisted_activity.id in activity_ids
348       assert private_activity.id in activity_ids
349       assert direct_activity.id in activity_ids
350
351       activity_ids =
352         conn
353         |> get("/api/v1/notifications?exclude_visibilities[]=private")
354         |> json_response_and_validate_schema(200)
355         |> Enum.map(& &1["status"]["id"])
356
357       assert public_activity.id in activity_ids
358       assert unlisted_activity.id in activity_ids
359       refute private_activity.id in activity_ids
360       assert direct_activity.id in activity_ids
361
362       activity_ids =
363         conn
364         |> get("/api/v1/notifications?exclude_visibilities[]=public")
365         |> json_response_and_validate_schema(200)
366         |> Enum.map(& &1["status"]["id"])
367
368       refute public_activity.id in activity_ids
369       assert unlisted_activity.id in activity_ids
370       assert private_activity.id in activity_ids
371       assert direct_activity.id in activity_ids
372     end
373
374     test "filters notifications for Announce activities" do
375       user = insert(:user)
376       %{user: other_user, conn: conn} = oauth_access(["read:notifications"])
377
378       {:ok, public_activity} = CommonAPI.post(other_user, %{status: ".", visibility: "public"})
379
380       {:ok, unlisted_activity} =
381         CommonAPI.post(other_user, %{status: ".", visibility: "unlisted"})
382
383       {:ok, _} = CommonAPI.repeat(public_activity.id, user)
384       {:ok, _} = CommonAPI.repeat(unlisted_activity.id, user)
385
386       activity_ids =
387         conn
388         |> get("/api/v1/notifications?exclude_visibilities[]=unlisted")
389         |> json_response_and_validate_schema(200)
390         |> Enum.map(& &1["status"]["id"])
391
392       assert public_activity.id in activity_ids
393       refute unlisted_activity.id in activity_ids
394     end
395
396     test "doesn't return less than the requested amount of records when the user's reply is liked" do
397       user = insert(:user)
398       %{user: other_user, conn: conn} = oauth_access(["read:notifications"])
399
400       {:ok, mention} =
401         CommonAPI.post(user, %{status: "@#{other_user.nickname}", visibility: "public"})
402
403       {:ok, activity} = CommonAPI.post(user, %{status: ".", visibility: "public"})
404
405       {:ok, reply} =
406         CommonAPI.post(other_user, %{
407           status: ".",
408           visibility: "public",
409           in_reply_to_status_id: activity.id
410         })
411
412       {:ok, _favorite} = CommonAPI.favorite(user, reply.id)
413
414       activity_ids =
415         conn
416         |> get("/api/v1/notifications?exclude_visibilities[]=direct&limit=2")
417         |> json_response_and_validate_schema(200)
418         |> Enum.map(& &1["status"]["id"])
419
420       assert [reply.id, mention.id] == activity_ids
421     end
422   end
423
424   test "filters notifications using exclude_types" do
425     %{user: user, conn: conn} = oauth_access(["read:notifications"])
426     other_user = insert(:user)
427
428     {:ok, mention_activity} = CommonAPI.post(other_user, %{status: "hey @#{user.nickname}"})
429     {:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
430     {:ok, favorite_activity} = CommonAPI.favorite(other_user, create_activity.id)
431     {:ok, reblog_activity} = CommonAPI.repeat(create_activity.id, other_user)
432     {:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
433
434     mention_notification_id = get_notification_id_by_activity(mention_activity)
435     favorite_notification_id = get_notification_id_by_activity(favorite_activity)
436     reblog_notification_id = get_notification_id_by_activity(reblog_activity)
437     follow_notification_id = get_notification_id_by_activity(follow_activity)
438
439     query = params_to_query(%{exclude_types: ["mention", "favourite", "reblog"]})
440     conn_res = get(conn, "/api/v1/notifications?" <> query)
441
442     assert [%{"id" => ^follow_notification_id}] = json_response_and_validate_schema(conn_res, 200)
443
444     query = params_to_query(%{exclude_types: ["favourite", "reblog", "follow"]})
445     conn_res = get(conn, "/api/v1/notifications?" <> query)
446
447     assert [%{"id" => ^mention_notification_id}] =
448              json_response_and_validate_schema(conn_res, 200)
449
450     query = params_to_query(%{exclude_types: ["reblog", "follow", "mention"]})
451     conn_res = get(conn, "/api/v1/notifications?" <> query)
452
453     assert [%{"id" => ^favorite_notification_id}] =
454              json_response_and_validate_schema(conn_res, 200)
455
456     query = params_to_query(%{exclude_types: ["follow", "mention", "favourite"]})
457     conn_res = get(conn, "/api/v1/notifications?" <> query)
458
459     assert [%{"id" => ^reblog_notification_id}] = json_response_and_validate_schema(conn_res, 200)
460   end
461
462   test "filters notifications using types" do
463     %{user: user, conn: conn} = oauth_access(["read:notifications"])
464     other_user = insert(:user)
465
466     {:ok, mention_activity} = CommonAPI.post(other_user, %{status: "hey @#{user.nickname}"})
467     {:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
468     {:ok, favorite_activity} = CommonAPI.favorite(other_user, create_activity.id)
469     {:ok, reblog_activity} = CommonAPI.repeat(create_activity.id, other_user)
470     {:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
471
472     mention_notification_id = get_notification_id_by_activity(mention_activity)
473     favorite_notification_id = get_notification_id_by_activity(favorite_activity)
474     reblog_notification_id = get_notification_id_by_activity(reblog_activity)
475     follow_notification_id = get_notification_id_by_activity(follow_activity)
476
477     conn_res = get(conn, "/api/v1/notifications?types[]=follow")
478
479     assert [%{"id" => ^follow_notification_id}] = json_response_and_validate_schema(conn_res, 200)
480
481     conn_res = get(conn, "/api/v1/notifications?types[]=mention")
482
483     assert [%{"id" => ^mention_notification_id}] =
484              json_response_and_validate_schema(conn_res, 200)
485
486     conn_res = get(conn, "/api/v1/notifications?types[]=favourite")
487
488     assert [%{"id" => ^favorite_notification_id}] =
489              json_response_and_validate_schema(conn_res, 200)
490
491     conn_res = get(conn, "/api/v1/notifications?types[]=reblog")
492
493     assert [%{"id" => ^reblog_notification_id}] = json_response_and_validate_schema(conn_res, 200)
494
495     result = conn |> get("/api/v1/notifications") |> json_response_and_validate_schema(200)
496
497     assert length(result) == 4
498
499     query = params_to_query(%{types: ["follow", "mention", "favourite", "reblog"]})
500
501     result =
502       conn
503       |> get("/api/v1/notifications?" <> query)
504       |> json_response_and_validate_schema(200)
505
506     assert length(result) == 4
507   end
508
509   test "filtering falls back to include_types" do
510     %{user: user, conn: conn} = oauth_access(["read:notifications"])
511     other_user = insert(:user)
512
513     {:ok, _activity} = CommonAPI.post(other_user, %{status: "hey @#{user.nickname}"})
514     {:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
515     {:ok, _activity} = CommonAPI.favorite(other_user, create_activity.id)
516     {:ok, _activity} = CommonAPI.repeat(create_activity.id, other_user)
517     {:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
518
519     follow_notification_id = get_notification_id_by_activity(follow_activity)
520
521     conn_res = get(conn, "/api/v1/notifications?include_types[]=follow")
522
523     assert [%{"id" => ^follow_notification_id}] = json_response_and_validate_schema(conn_res, 200)
524   end
525
526   test "destroy multiple" do
527     %{user: user, conn: conn} = oauth_access(["read:notifications", "write:notifications"])
528     other_user = insert(:user)
529
530     {:ok, activity1} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
531     {:ok, activity2} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
532     {:ok, activity3} = CommonAPI.post(user, %{status: "hi @#{other_user.nickname}"})
533     {:ok, activity4} = CommonAPI.post(user, %{status: "hi @#{other_user.nickname}"})
534
535     notification1_id = get_notification_id_by_activity(activity1)
536     notification2_id = get_notification_id_by_activity(activity2)
537     notification3_id = get_notification_id_by_activity(activity3)
538     notification4_id = get_notification_id_by_activity(activity4)
539
540     result =
541       conn
542       |> get("/api/v1/notifications")
543       |> json_response_and_validate_schema(:ok)
544
545     assert [%{"id" => ^notification2_id}, %{"id" => ^notification1_id}] = result
546
547     conn2 =
548       conn
549       |> assign(:user, other_user)
550       |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:notifications"]))
551
552     result =
553       conn2
554       |> get("/api/v1/notifications")
555       |> json_response_and_validate_schema(:ok)
556
557     assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result
558
559     query = params_to_query(%{ids: [notification1_id, notification2_id]})
560     conn_destroy = delete(conn, "/api/v1/notifications/destroy_multiple?" <> query)
561
562     assert json_response_and_validate_schema(conn_destroy, 200) == %{}
563
564     result =
565       conn2
566       |> get("/api/v1/notifications")
567       |> json_response_and_validate_schema(:ok)
568
569     assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result
570   end
571
572   test "doesn't see notifications after muting user with notifications" do
573     %{user: user, conn: conn} = oauth_access(["read:notifications"])
574     user2 = insert(:user)
575
576     {:ok, _, _, _} = CommonAPI.follow(user, user2)
577     {:ok, _} = CommonAPI.post(user2, %{status: "hey @#{user.nickname}"})
578
579     ret_conn = get(conn, "/api/v1/notifications")
580
581     assert length(json_response_and_validate_schema(ret_conn, 200)) == 1
582
583     {:ok, _user_relationships} = User.mute(user, user2)
584
585     conn = get(conn, "/api/v1/notifications")
586
587     assert json_response_and_validate_schema(conn, 200) == []
588   end
589
590   test "see notifications after muting user without notifications" do
591     %{user: user, conn: conn} = oauth_access(["read:notifications"])
592     user2 = insert(:user)
593
594     {:ok, _, _, _} = CommonAPI.follow(user, user2)
595     {:ok, _} = CommonAPI.post(user2, %{status: "hey @#{user.nickname}"})
596
597     ret_conn = get(conn, "/api/v1/notifications")
598
599     assert length(json_response_and_validate_schema(ret_conn, 200)) == 1
600
601     {:ok, _user_relationships} = User.mute(user, user2, %{notifications: false})
602
603     conn = get(conn, "/api/v1/notifications")
604
605     assert length(json_response_and_validate_schema(conn, 200)) == 1
606   end
607
608   test "see notifications after muting user with notifications and with_muted parameter" do
609     %{user: user, conn: conn} = oauth_access(["read:notifications"])
610     user2 = insert(:user)
611
612     {:ok, _, _, _} = CommonAPI.follow(user, user2)
613     {:ok, _} = CommonAPI.post(user2, %{status: "hey @#{user.nickname}"})
614
615     ret_conn = get(conn, "/api/v1/notifications")
616
617     assert length(json_response_and_validate_schema(ret_conn, 200)) == 1
618
619     {:ok, _user_relationships} = User.mute(user, user2)
620
621     conn = get(conn, "/api/v1/notifications?with_muted=true")
622
623     assert length(json_response_and_validate_schema(conn, 200)) == 1
624   end
625
626   test "see move notifications" do
627     old_user = insert(:user)
628     new_user = insert(:user, also_known_as: [old_user.ap_id])
629     %{user: follower, conn: conn} = oauth_access(["read:notifications"])
630
631     User.follow(follower, old_user)
632     Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
633     Pleroma.Tests.ObanHelpers.perform_all()
634
635     conn = get(conn, "/api/v1/notifications")
636
637     assert length(json_response_and_validate_schema(conn, 200)) == 1
638   end
639
640   describe "link headers" do
641     test "preserves parameters in link headers" do
642       %{user: user, conn: conn} = oauth_access(["read:notifications"])
643       other_user = insert(:user)
644
645       {:ok, activity1} =
646         CommonAPI.post(other_user, %{
647           status: "hi @#{user.nickname}",
648           visibility: "public"
649         })
650
651       {:ok, activity2} =
652         CommonAPI.post(other_user, %{
653           status: "hi @#{user.nickname}",
654           visibility: "public"
655         })
656
657       notification1 = Repo.get_by(Notification, activity_id: activity1.id)
658       notification2 = Repo.get_by(Notification, activity_id: activity2.id)
659
660       conn =
661         conn
662         |> assign(:user, user)
663         |> get("/api/v1/notifications?limit=5")
664
665       assert [link_header] = get_resp_header(conn, "link")
666       assert link_header =~ ~r/limit=5/
667       assert link_header =~ ~r/min_id=#{notification2.id}/
668       assert link_header =~ ~r/max_id=#{notification1.id}/
669     end
670   end
671
672   describe "from specified user" do
673     test "account_id" do
674       %{user: user, conn: conn} = oauth_access(["read:notifications"])
675
676       %{id: account_id} = other_user1 = insert(:user)
677       other_user2 = insert(:user)
678
679       {:ok, _activity} = CommonAPI.post(other_user1, %{status: "hi @#{user.nickname}"})
680       {:ok, _activity} = CommonAPI.post(other_user2, %{status: "bye @#{user.nickname}"})
681
682       assert [%{"account" => %{"id" => ^account_id}}] =
683                conn
684                |> assign(:user, user)
685                |> get("/api/v1/notifications?account_id=#{account_id}")
686                |> json_response_and_validate_schema(200)
687
688       assert %{"error" => "Account is not found"} =
689                conn
690                |> assign(:user, user)
691                |> get("/api/v1/notifications?account_id=cofe")
692                |> json_response_and_validate_schema(404)
693     end
694   end
695
696   defp get_notification_id_by_activity(%{id: id}) do
697     Notification
698     |> Repo.get_by(activity_id: id)
699     |> Map.get(:id)
700     |> to_string()
701   end
702
703   defp params_to_query(%{} = params) do
704     Enum.map_join(params, "&", fn
705       {k, v} when is_list(v) -> Enum.map_join(v, "&", &"#{k}[]=#{&1}")
706       {k, v} -> k <> "=" <> v
707     end)
708   end
709 end