total rebase
[anni] / test / pleroma / web / push / impl_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.Push.ImplTest do
6   use Pleroma.DataCase, async: true
7
8   import Mox
9   import Pleroma.Factory
10
11   alias Pleroma.Notification
12   alias Pleroma.Object
13   alias Pleroma.UnstubbedConfigMock, as: ConfigMock
14   alias Pleroma.User
15   alias Pleroma.Web.ActivityPub.ActivityPub
16   alias Pleroma.Web.CommonAPI
17   alias Pleroma.Web.Push.Impl
18   alias Pleroma.Web.Push.Subscription
19
20   setup do
21     Tesla.Mock.mock(fn
22       %{method: :post, url: "https://example.com/example/1234"} ->
23         %Tesla.Env{status: 200}
24
25       %{method: :post, url: "https://example.com/example/not_found"} ->
26         %Tesla.Env{status: 400}
27
28       %{method: :post, url: "https://example.com/example/bad"} ->
29         %Tesla.Env{status: 100}
30     end)
31
32     :ok
33   end
34
35   @sub %{
36     endpoint: "https://example.com/example/1234",
37     keys: %{
38       auth: "8eDyX_uCN0XRhSbY5hs7Hg==",
39       p256dh:
40         "BCIWgsnyXDv1VkhqL2P7YRBvdeuDnlwAPT2guNhdIoW3IP7GmHh1SMKPLxRf7x8vJy6ZFK3ol2ohgn_-0yP7QQA="
41     }
42   }
43   @api_key "BASgACIHpN1GYgzSRp"
44   @message "@Bob: Lorem ipsum dolor sit amet, consectetur  adipiscing elit. Fusce sagittis fini..."
45
46   test "performs sending notifications" do
47     user = insert(:user)
48     user2 = insert(:user)
49     insert(:push_subscription, user: user, data: %{alerts: %{"mention" => true}})
50     insert(:push_subscription, user: user2, data: %{alerts: %{"mention" => true}})
51
52     insert(:push_subscription,
53       user: user,
54       data: %{alerts: %{"follow" => true, "mention" => true}}
55     )
56
57     insert(:push_subscription,
58       user: user,
59       data: %{alerts: %{"follow" => true, "mention" => false}}
60     )
61
62     {:ok, activity} = CommonAPI.post(user, %{status: "<Lorem ipsum dolor sit amet."})
63
64     notif =
65       insert(:notification,
66         user: user,
67         activity: activity,
68         type: "mention"
69       )
70
71     assert Impl.perform(notif) == {:ok, [:ok, :ok]}
72   end
73
74   @tag capture_log: true
75   test "returns error if notif does not match " do
76     assert Impl.perform(%{}) == {:error, :unknown_type}
77   end
78
79   test "successful message sending" do
80     assert Impl.push_message(@message, @sub, @api_key, %Subscription{}) == :ok
81   end
82
83   @tag capture_log: true
84   test "fail message sending" do
85     assert Impl.push_message(
86              @message,
87              Map.merge(@sub, %{endpoint: "https://example.com/example/bad"}),
88              @api_key,
89              %Subscription{}
90            ) == :error
91   end
92
93   test "delete subscription if result send message between 400..500" do
94     subscription = insert(:push_subscription)
95
96     assert Impl.push_message(
97              @message,
98              Map.merge(@sub, %{endpoint: "https://example.com/example/not_found"}),
99              @api_key,
100              subscription
101            ) == :ok
102
103     refute Pleroma.Repo.get(Subscription, subscription.id)
104   end
105
106   test "deletes subscription when token has been deleted" do
107     subscription = insert(:push_subscription)
108
109     Pleroma.Repo.delete(subscription.token)
110
111     refute Pleroma.Repo.get(Subscription, subscription.id)
112   end
113
114   test "renders title and body for create activity" do
115     user = insert(:user, nickname: "Bob")
116
117     {:ok, activity} =
118       CommonAPI.post(user, %{
119         status:
120           "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
121       })
122
123     object = Object.normalize(activity, fetch: false)
124
125     assert Impl.format_body(
126              %{
127                activity: activity
128              },
129              user,
130              object
131            ) ==
132              "@Bob: Lorem ipsum dolor sit amet, consectetur  adipiscing elit. Fusce sagittis fini..."
133
134     assert Impl.format_title(%{activity: activity, type: "mention"}) ==
135              "New Mention"
136   end
137
138   test "renders title and body for follow activity" do
139     user = insert(:user, nickname: "Bob")
140     other_user = insert(:user)
141     {:ok, _, _, activity} = CommonAPI.follow(user, other_user)
142     object = Object.normalize(activity, fetch: false)
143
144     assert Impl.format_body(%{activity: activity, type: "follow"}, user, object) ==
145              "@Bob has followed you"
146
147     assert Impl.format_title(%{activity: activity, type: "follow"}) ==
148              "New Follower"
149   end
150
151   test "renders title and body for announce activity" do
152     user = insert(:user)
153
154     {:ok, activity} =
155       CommonAPI.post(user, %{
156         status:
157           "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
158       })
159
160     {:ok, announce_activity} = CommonAPI.repeat(activity.id, user)
161     object = Object.normalize(activity, fetch: false)
162
163     assert Impl.format_body(%{activity: announce_activity}, user, object) ==
164              "@#{user.nickname} repeated: Lorem ipsum dolor sit amet, consectetur  adipiscing elit. Fusce sagittis fini..."
165
166     assert Impl.format_title(%{activity: announce_activity, type: "reblog"}) ==
167              "New Repeat"
168   end
169
170   test "renders title and body for like activity" do
171     user = insert(:user, nickname: "Bob")
172
173     {:ok, activity} =
174       CommonAPI.post(user, %{
175         status:
176           "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
177       })
178
179     {:ok, activity} = CommonAPI.favorite(user, activity.id)
180     object = Object.normalize(activity, fetch: false)
181
182     assert Impl.format_body(%{activity: activity, type: "favourite"}, user, object) ==
183              "@Bob has favorited your post"
184
185     assert Impl.format_title(%{activity: activity, type: "favourite"}) ==
186              "New Favorite"
187   end
188
189   test "renders title and body for pleroma:emoji_reaction activity" do
190     user = insert(:user, nickname: "Bob")
191
192     {:ok, activity} =
193       CommonAPI.post(user, %{
194         status: "This post is a really good post!"
195       })
196
197     {:ok, activity} = CommonAPI.react_with_emoji(activity.id, user, "👍")
198     object = Object.normalize(activity, fetch: false)
199
200     assert Impl.format_body(%{activity: activity, type: "pleroma:emoji_reaction"}, user, object) ==
201              "@Bob reacted with 👍"
202
203     assert Impl.format_title(%{activity: activity, type: "pleroma:emoji_reaction"}) ==
204              "New Reaction"
205   end
206
207   test "renders title and body for update activity" do
208     user = insert(:user)
209
210     {:ok, activity} = CommonAPI.post(user, %{status: "lorem ipsum"})
211
212     {:ok, activity} = CommonAPI.update(user, activity, %{status: "edited status"})
213     object = Object.normalize(activity, fetch: false)
214
215     assert Impl.format_body(%{activity: activity, type: "update"}, user, object) ==
216              "@#{user.nickname} edited a status"
217
218     assert Impl.format_title(%{activity: activity, type: "update"}) ==
219              "New Update"
220   end
221
222   test "renders title for create activity with direct visibility" do
223     user = insert(:user, nickname: "Bob")
224
225     {:ok, activity} =
226       CommonAPI.post(user, %{
227         visibility: "direct",
228         status: "This is just between you and me, pal"
229       })
230
231     assert Impl.format_title(%{activity: activity}) ==
232              "New Direct Message"
233   end
234
235   describe "build_content/3" do
236     test "builds content for chat messages" do
237       user = insert(:user)
238       recipient = insert(:user)
239
240       {:ok, chat} = CommonAPI.post_chat_message(user, recipient, "hey")
241       object = Object.normalize(chat, fetch: false)
242       [notification] = Notification.for_user(recipient)
243
244       res = Impl.build_content(notification, user, object)
245
246       assert res == %{
247                body: "@#{user.nickname}: hey",
248                title: "New Chat Message"
249              }
250     end
251
252     test "builds content for chat messages with no content" do
253       user = insert(:user)
254       recipient = insert(:user)
255
256       file = %Plug.Upload{
257         content_type: "image/jpeg",
258         path: Path.absname("test/fixtures/image.jpg"),
259         filename: "an_image.jpg"
260       }
261
262       ConfigMock
263       |> stub_with(Pleroma.Test.StaticConfig)
264
265       {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
266
267       {:ok, chat} = CommonAPI.post_chat_message(user, recipient, nil, media_id: upload.id)
268       object = Object.normalize(chat, fetch: false)
269       [notification] = Notification.for_user(recipient)
270
271       res = Impl.build_content(notification, user, object)
272
273       assert res == %{
274                body: "@#{user.nickname}: (Attachment)",
275                title: "New Chat Message"
276              }
277     end
278
279     test "hides contents of notifications when option enabled" do
280       user = insert(:user, nickname: "Bob")
281
282       user2 =
283         insert(:user, nickname: "Rob", notification_settings: %{hide_notification_contents: true})
284
285       {:ok, activity} =
286         CommonAPI.post(user, %{
287           visibility: "direct",
288           status: "<Lorem ipsum dolor sit amet."
289         })
290
291       notif = insert(:notification, user: user2, activity: activity)
292
293       actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
294       object = Object.normalize(activity, fetch: false)
295
296       assert Impl.build_content(notif, actor, object) == %{
297                body: "New Direct Message"
298              }
299
300       {:ok, activity} =
301         CommonAPI.post(user, %{
302           visibility: "public",
303           status: "<Lorem ipsum dolor sit amet."
304         })
305
306       notif = insert(:notification, user: user2, activity: activity, type: "mention")
307
308       actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
309       object = Object.normalize(activity, fetch: false)
310
311       assert Impl.build_content(notif, actor, object) == %{
312                body: "New Mention"
313              }
314
315       {:ok, activity} = CommonAPI.favorite(user, activity.id)
316
317       notif = insert(:notification, user: user2, activity: activity, type: "favourite")
318
319       actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
320       object = Object.normalize(activity, fetch: false)
321
322       assert Impl.build_content(notif, actor, object) == %{
323                body: "New Favorite"
324              }
325     end
326
327     test "returns regular content when hiding contents option disabled" do
328       user = insert(:user, nickname: "Bob")
329
330       user2 =
331         insert(:user, nickname: "Rob", notification_settings: %{hide_notification_contents: false})
332
333       {:ok, activity} =
334         CommonAPI.post(user, %{
335           visibility: "direct",
336           status:
337             "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
338         })
339
340       notif = insert(:notification, user: user2, activity: activity)
341
342       actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
343       object = Object.normalize(activity, fetch: false)
344
345       assert Impl.build_content(notif, actor, object) == %{
346                body:
347                  "@Bob: Lorem ipsum dolor sit amet, consectetur  adipiscing elit. Fusce sagittis fini...",
348                title: "New Direct Message"
349              }
350
351       {:ok, activity} =
352         CommonAPI.post(user, %{
353           visibility: "public",
354           status:
355             "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
356         })
357
358       notif = insert(:notification, user: user2, activity: activity, type: "mention")
359
360       actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
361       object = Object.normalize(activity, fetch: false)
362
363       assert Impl.build_content(notif, actor, object) == %{
364                body:
365                  "@Bob: Lorem ipsum dolor sit amet, consectetur  adipiscing elit. Fusce sagittis fini...",
366                title: "New Mention"
367              }
368
369       {:ok, activity} = CommonAPI.favorite(user, activity.id)
370
371       notif = insert(:notification, user: user2, activity: activity, type: "favourite")
372
373       actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
374       object = Object.normalize(activity, fetch: false)
375
376       assert Impl.build_content(notif, actor, object) == %{
377                body: "@Bob has favorited your post",
378                title: "New Favorite"
379              }
380     end
381   end
382 end