Merge branch 'develop' into feature/bulk-confirmation
[akkoma] / test / web / push / impl_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 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
7
8 alias Pleroma.Notification
9 alias Pleroma.Object
10 alias Pleroma.User
11 alias Pleroma.Web.ActivityPub.ActivityPub
12 alias Pleroma.Web.CommonAPI
13 alias Pleroma.Web.Push.Impl
14 alias Pleroma.Web.Push.Subscription
15 alias Pleroma.Web.WebPushHttpClientMock
16
17 import Mock
18 import Pleroma.Factory
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 test_with_mock "uses WebPushHttpClientMock as an HTTP client", WebPushHttpClientMock,
84 post: fn _, _, _ -> {:ok, %{status_code: 200}} end do
85 Impl.push_message(@message, @sub, @api_key, %Subscription{})
86 assert_called(WebPushHttpClientMock.post("https://example.com/example/1234", :_, :_))
87 end
88
89 test_with_mock "uses Pleroma.HTTP as an HTTP client", Pleroma.HTTP,
90 post: fn _, _, _ -> {:ok, %{status_code: 200}} end do
91 client = Application.get_env(:web_push_encryption, :http_client)
92 on_exit(fn -> Application.put_env(:web_push_encryption, :http_client, client) end)
93 Application.put_env(:web_push_encryption, :http_client, Pleroma.HTTP)
94
95 Impl.push_message(@message, @sub, @api_key, %Subscription{})
96 assert_called(Pleroma.HTTP.post("https://example.com/example/1234", :_, :_))
97 end
98
99 @tag capture_log: true
100 test "fail message sending" do
101 assert Impl.push_message(
102 @message,
103 Map.merge(@sub, %{endpoint: "https://example.com/example/bad"}),
104 @api_key,
105 %Subscription{}
106 ) == :error
107 end
108
109 test "delete subscription if result send message between 400..500" do
110 subscription = insert(:push_subscription)
111
112 assert Impl.push_message(
113 @message,
114 Map.merge(@sub, %{endpoint: "https://example.com/example/not_found"}),
115 @api_key,
116 subscription
117 ) == :ok
118
119 refute Pleroma.Repo.get(Subscription, subscription.id)
120 end
121
122 test "deletes subscription when token has been deleted" do
123 subscription = insert(:push_subscription)
124
125 Pleroma.Repo.delete(subscription.token)
126
127 refute Pleroma.Repo.get(Subscription, subscription.id)
128 end
129
130 test "renders title and body for create activity" do
131 user = insert(:user, nickname: "Bob")
132
133 {:ok, activity} =
134 CommonAPI.post(user, %{
135 status:
136 "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
137 })
138
139 object = Object.normalize(activity)
140
141 assert Impl.format_body(
142 %{
143 activity: activity
144 },
145 user,
146 object
147 ) ==
148 "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..."
149
150 assert Impl.format_title(%{activity: activity, type: "mention"}) ==
151 "New Mention"
152 end
153
154 test "renders title and body for follow activity" do
155 user = insert(:user, nickname: "Bob")
156 other_user = insert(:user)
157 {:ok, _, _, activity} = CommonAPI.follow(user, other_user)
158 object = Object.normalize(activity, false)
159
160 assert Impl.format_body(%{activity: activity, type: "follow"}, user, object) ==
161 "@Bob has followed you"
162
163 assert Impl.format_title(%{activity: activity, type: "follow"}) ==
164 "New Follower"
165 end
166
167 test "renders title and body for announce activity" do
168 user = insert(:user)
169
170 {:ok, activity} =
171 CommonAPI.post(user, %{
172 status:
173 "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
174 })
175
176 {:ok, announce_activity} = CommonAPI.repeat(activity.id, user)
177 object = Object.normalize(activity)
178
179 assert Impl.format_body(%{activity: announce_activity}, user, object) ==
180 "@#{user.nickname} repeated: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..."
181
182 assert Impl.format_title(%{activity: announce_activity, type: "reblog"}) ==
183 "New Repeat"
184 end
185
186 test "renders title and body for like activity" do
187 user = insert(:user, nickname: "Bob")
188
189 {:ok, activity} =
190 CommonAPI.post(user, %{
191 status:
192 "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
193 })
194
195 {:ok, activity} = CommonAPI.favorite(user, activity.id)
196 object = Object.normalize(activity)
197
198 assert Impl.format_body(%{activity: activity, type: "favourite"}, user, object) ==
199 "@Bob has favorited your post"
200
201 assert Impl.format_title(%{activity: activity, type: "favourite"}) ==
202 "New Favorite"
203 end
204
205 test "renders title for create activity with direct visibility" do
206 user = insert(:user, nickname: "Bob")
207
208 {:ok, activity} =
209 CommonAPI.post(user, %{
210 visibility: "direct",
211 status: "This is just between you and me, pal"
212 })
213
214 assert Impl.format_title(%{activity: activity}) ==
215 "New Direct Message"
216 end
217
218 describe "build_content/3" do
219 test "builds content for chat messages" do
220 user = insert(:user)
221 recipient = insert(:user)
222
223 {:ok, chat} = CommonAPI.post_chat_message(user, recipient, "hey")
224 object = Object.normalize(chat, false)
225 [notification] = Notification.for_user(recipient)
226
227 res = Impl.build_content(notification, user, object)
228
229 assert res == %{
230 body: "@#{user.nickname}: hey",
231 title: "New Chat Message"
232 }
233 end
234
235 test "builds content for chat messages with no content" do
236 user = insert(:user)
237 recipient = insert(:user)
238
239 file = %Plug.Upload{
240 content_type: "image/jpg",
241 path: Path.absname("test/fixtures/image.jpg"),
242 filename: "an_image.jpg"
243 }
244
245 {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
246
247 {:ok, chat} = CommonAPI.post_chat_message(user, recipient, nil, media_id: upload.id)
248 object = Object.normalize(chat, false)
249 [notification] = Notification.for_user(recipient)
250
251 res = Impl.build_content(notification, user, object)
252
253 assert res == %{
254 body: "@#{user.nickname}: (Attachment)",
255 title: "New Chat Message"
256 }
257 end
258
259 test "hides contents of notifications when option enabled" do
260 user = insert(:user, nickname: "Bob")
261
262 user2 =
263 insert(:user, nickname: "Rob", notification_settings: %{hide_notification_contents: true})
264
265 {:ok, activity} =
266 CommonAPI.post(user, %{
267 visibility: "direct",
268 status: "<Lorem ipsum dolor sit amet."
269 })
270
271 notif = insert(:notification, user: user2, activity: activity)
272
273 actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
274 object = Object.normalize(activity)
275
276 assert Impl.build_content(notif, actor, object) == %{
277 body: "New Direct Message"
278 }
279
280 {:ok, activity} =
281 CommonAPI.post(user, %{
282 visibility: "public",
283 status: "<Lorem ipsum dolor sit amet."
284 })
285
286 notif = insert(:notification, user: user2, activity: activity, type: "mention")
287
288 actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
289 object = Object.normalize(activity)
290
291 assert Impl.build_content(notif, actor, object) == %{
292 body: "New Mention"
293 }
294
295 {:ok, activity} = CommonAPI.favorite(user, activity.id)
296
297 notif = insert(:notification, user: user2, activity: activity, type: "favourite")
298
299 actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
300 object = Object.normalize(activity)
301
302 assert Impl.build_content(notif, actor, object) == %{
303 body: "New Favorite"
304 }
305 end
306
307 test "returns regular content when hiding contents option disabled" do
308 user = insert(:user, nickname: "Bob")
309
310 user2 =
311 insert(:user, nickname: "Rob", notification_settings: %{hide_notification_contents: false})
312
313 {:ok, activity} =
314 CommonAPI.post(user, %{
315 visibility: "direct",
316 status:
317 "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
318 })
319
320 notif = insert(:notification, user: user2, activity: activity)
321
322 actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
323 object = Object.normalize(activity)
324
325 assert Impl.build_content(notif, actor, object) == %{
326 body:
327 "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini...",
328 title: "New Direct Message"
329 }
330
331 {:ok, activity} =
332 CommonAPI.post(user, %{
333 visibility: "public",
334 status:
335 "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
336 })
337
338 notif = insert(:notification, user: user2, activity: activity, type: "mention")
339
340 actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
341 object = Object.normalize(activity)
342
343 assert Impl.build_content(notif, actor, object) == %{
344 body:
345 "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini...",
346 title: "New Mention"
347 }
348
349 {:ok, activity} = CommonAPI.favorite(user, activity.id)
350
351 notif = insert(:notification, user: user2, activity: activity, type: "favourite")
352
353 actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
354 object = Object.normalize(activity)
355
356 assert Impl.build_content(notif, actor, object) == %{
357 body: "@Bob has favorited your post",
358 title: "New Favorite"
359 }
360 end
361 end
362 end