Merge branch 'fix/normalize-file-extension' into 'develop'
[akkoma] / test / web / activity_pub / transmogrifier_test.exs
1 defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
2 use Pleroma.DataCase
3 alias Pleroma.Web.ActivityPub.Transmogrifier
4 alias Pleroma.Web.ActivityPub.Utils
5 alias Pleroma.Web.ActivityPub.ActivityPub
6 alias Pleroma.Web.OStatus
7 alias Pleroma.Activity
8 alias Pleroma.User
9 alias Pleroma.Repo
10 alias Pleroma.Web.Websub.WebsubClientSubscription
11
12 import Pleroma.Factory
13 alias Pleroma.Web.CommonAPI
14
15 describe "handle_incoming" do
16 test "it ignores an incoming notice if we already have it" do
17 activity = insert(:note_activity)
18
19 data =
20 File.read!("test/fixtures/mastodon-post-activity.json")
21 |> Poison.decode!()
22 |> Map.put("object", activity.data["object"])
23
24 {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
25
26 assert activity == returned_activity
27 end
28
29 test "it fetches replied-to activities if we don't have them" do
30 data =
31 File.read!("test/fixtures/mastodon-post-activity.json")
32 |> Poison.decode!()
33
34 object =
35 data["object"]
36 |> Map.put("inReplyTo", "https://shitposter.club/notice/2827873")
37
38 data =
39 data
40 |> Map.put("object", object)
41
42 {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
43
44 assert activity =
45 Activity.get_create_activity_by_object_ap_id(
46 "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
47 )
48
49 assert returned_activity.data["object"]["inReplyToAtomUri"] ==
50 "https://shitposter.club/notice/2827873"
51
52 assert returned_activity.data["object"]["inReplyToStatusId"] == activity.id
53 end
54
55 test "it works for incoming notices" do
56 data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
57
58 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
59
60 assert data["id"] ==
61 "http://mastodon.example.org/users/admin/statuses/99512778738411822/activity"
62
63 assert data["context"] ==
64 "tag:mastodon.example.org,2018-02-12:objectId=20:objectType=Conversation"
65
66 assert data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
67
68 assert data["cc"] == [
69 "http://mastodon.example.org/users/admin/followers",
70 "http://localtesting.pleroma.lol/users/lain"
71 ]
72
73 assert data["actor"] == "http://mastodon.example.org/users/admin"
74
75 object = data["object"]
76 assert object["id"] == "http://mastodon.example.org/users/admin/statuses/99512778738411822"
77
78 assert object["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
79
80 assert object["cc"] == [
81 "http://mastodon.example.org/users/admin/followers",
82 "http://localtesting.pleroma.lol/users/lain"
83 ]
84
85 assert object["actor"] == "http://mastodon.example.org/users/admin"
86 assert object["attributedTo"] == "http://mastodon.example.org/users/admin"
87
88 assert object["context"] ==
89 "tag:mastodon.example.org,2018-02-12:objectId=20:objectType=Conversation"
90
91 assert object["sensitive"] == true
92
93 user = User.get_by_ap_id(object["actor"])
94
95 assert user.info["note_count"] == 1
96 end
97
98 test "it works for incoming notices with hashtags" do
99 data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Poison.decode!()
100
101 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
102 assert Enum.at(data["object"]["tag"], 2) == "moo"
103 end
104
105 test "it works for incoming notices with contentMap" do
106 data =
107 File.read!("test/fixtures/mastodon-post-activity-contentmap.json") |> Poison.decode!()
108
109 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
110
111 assert data["object"]["content"] ==
112 "<p><span class=\"h-card\"><a href=\"http://localtesting.pleroma.lol/users/lain\" class=\"u-url mention\">@<span>lain</span></a></span></p>"
113 end
114
115 test "it works for incoming follow requests" do
116 user = insert(:user)
117
118 data =
119 File.read!("test/fixtures/mastodon-follow-activity.json")
120 |> Poison.decode!()
121 |> Map.put("object", user.ap_id)
122
123 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
124
125 assert data["actor"] == "http://mastodon.example.org/users/admin"
126 assert data["type"] == "Follow"
127 assert data["id"] == "http://mastodon.example.org/users/admin#follows/2"
128 assert User.following?(User.get_by_ap_id(data["actor"]), user)
129 end
130
131 test "it works for incoming follow requests from hubzilla" do
132 user = insert(:user)
133
134 data =
135 File.read!("test/fixtures/hubzilla-follow-activity.json")
136 |> Poison.decode!()
137 |> Map.put("object", user.ap_id)
138 |> Utils.normalize_params()
139
140 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
141
142 assert data["actor"] == "https://hubzilla.example.org/channel/kaniini"
143 assert data["type"] == "Follow"
144 assert data["id"] == "https://hubzilla.example.org/channel/kaniini#follows/2"
145 assert User.following?(User.get_by_ap_id(data["actor"]), user)
146 end
147
148 test "it works for incoming likes" do
149 user = insert(:user)
150 {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"})
151
152 data =
153 File.read!("test/fixtures/mastodon-like.json")
154 |> Poison.decode!()
155 |> Map.put("object", activity.data["object"]["id"])
156
157 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
158
159 assert data["actor"] == "http://mastodon.example.org/users/admin"
160 assert data["type"] == "Like"
161 assert data["id"] == "http://mastodon.example.org/users/admin#likes/2"
162 assert data["object"] == activity.data["object"]["id"]
163 end
164
165 test "it returns an error for incoming unlikes wihout a like activity" do
166 user = insert(:user)
167 {:ok, activity} = CommonAPI.post(user, %{"status" => "leave a like pls"})
168
169 data =
170 File.read!("test/fixtures/mastodon-undo-like.json")
171 |> Poison.decode!()
172 |> Map.put("object", activity.data["object"]["id"])
173
174 assert Transmogrifier.handle_incoming(data) == :error
175 end
176
177 test "it works for incoming unlikes with an existing like activity" do
178 user = insert(:user)
179 {:ok, activity} = CommonAPI.post(user, %{"status" => "leave a like pls"})
180
181 like_data =
182 File.read!("test/fixtures/mastodon-like.json")
183 |> Poison.decode!()
184 |> Map.put("object", activity.data["object"]["id"])
185
186 {:ok, %Activity{data: like_data, local: false}} = Transmogrifier.handle_incoming(like_data)
187
188 data =
189 File.read!("test/fixtures/mastodon-undo-like.json")
190 |> Poison.decode!()
191 |> Map.put("object", like_data)
192 |> Map.put("actor", like_data["actor"])
193
194 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
195
196 assert data["actor"] == "http://mastodon.example.org/users/admin"
197 assert data["type"] == "Undo"
198 assert data["id"] == "http://mastodon.example.org/users/admin#likes/2/undo"
199 assert data["object"]["id"] == "http://mastodon.example.org/users/admin#likes/2"
200 end
201
202 test "it works for incoming announces" do
203 data = File.read!("test/fixtures/mastodon-announce.json") |> Poison.decode!()
204
205 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
206
207 assert data["actor"] == "http://mastodon.example.org/users/admin"
208 assert data["type"] == "Announce"
209
210 assert data["id"] ==
211 "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
212
213 assert data["object"] ==
214 "http://mastodon.example.org/users/admin/statuses/99541947525187367"
215
216 assert Activity.get_create_activity_by_object_ap_id(data["object"])
217 end
218
219 test "it works for incoming announces with an existing activity" do
220 user = insert(:user)
221 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"})
222
223 data =
224 File.read!("test/fixtures/mastodon-announce.json")
225 |> Poison.decode!()
226 |> Map.put("object", activity.data["object"]["id"])
227
228 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
229
230 assert data["actor"] == "http://mastodon.example.org/users/admin"
231 assert data["type"] == "Announce"
232
233 assert data["id"] ==
234 "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
235
236 assert data["object"] == activity.data["object"]["id"]
237
238 assert Activity.get_create_activity_by_object_ap_id(data["object"]).id == activity.id
239 end
240
241 test "it works for incoming update activities" do
242 data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
243
244 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
245 update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!()
246
247 object =
248 update_data["object"]
249 |> Map.put("actor", data["actor"])
250 |> Map.put("id", data["actor"])
251
252 update_data =
253 update_data
254 |> Map.put("actor", data["actor"])
255 |> Map.put("object", object)
256
257 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(update_data)
258
259 user = User.get_cached_by_ap_id(data["actor"])
260 assert user.name == "gargle"
261
262 assert user.avatar["url"] == [
263 %{
264 "href" =>
265 "https://cd.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
266 }
267 ]
268
269 assert user.info["banner"]["url"] == [
270 %{
271 "href" =>
272 "https://cd.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
273 }
274 ]
275
276 assert user.bio == "<p>Some bio</p>"
277 end
278
279 test "it works for incoming update activities which lock the account" do
280 data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
281
282 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
283 update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!()
284
285 object =
286 update_data["object"]
287 |> Map.put("actor", data["actor"])
288 |> Map.put("id", data["actor"])
289 |> Map.put("manuallyApprovesFollowers", true)
290
291 update_data =
292 update_data
293 |> Map.put("actor", data["actor"])
294 |> Map.put("object", object)
295
296 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(update_data)
297
298 user = User.get_cached_by_ap_id(data["actor"])
299 assert user.info["locked"] == true
300 end
301
302 test "it works for incoming deletes" do
303 activity = insert(:note_activity)
304
305 data =
306 File.read!("test/fixtures/mastodon-delete.json")
307 |> Poison.decode!()
308
309 object =
310 data["object"]
311 |> Map.put("id", activity.data["object"]["id"])
312
313 data =
314 data
315 |> Map.put("object", object)
316 |> Map.put("actor", activity.data["actor"])
317
318 {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
319
320 refute Repo.get(Activity, activity.id)
321 end
322
323 test "it works for incoming unannounces with an existing notice" do
324 user = insert(:user)
325 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"})
326
327 announce_data =
328 File.read!("test/fixtures/mastodon-announce.json")
329 |> Poison.decode!()
330 |> Map.put("object", activity.data["object"]["id"])
331
332 {:ok, %Activity{data: announce_data, local: false}} =
333 Transmogrifier.handle_incoming(announce_data)
334
335 data =
336 File.read!("test/fixtures/mastodon-undo-announce.json")
337 |> Poison.decode!()
338 |> Map.put("object", announce_data)
339 |> Map.put("actor", announce_data["actor"])
340
341 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
342
343 assert data["type"] == "Undo"
344 assert data["object"]["type"] == "Announce"
345 assert data["object"]["object"] == activity.data["object"]["id"]
346
347 assert data["object"]["id"] ==
348 "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
349 end
350
351 test "it works for incomming unfollows with an existing follow" do
352 user = insert(:user)
353
354 follow_data =
355 File.read!("test/fixtures/mastodon-follow-activity.json")
356 |> Poison.decode!()
357 |> Map.put("object", user.ap_id)
358
359 {:ok, %Activity{data: _, local: false}} = Transmogrifier.handle_incoming(follow_data)
360
361 data =
362 File.read!("test/fixtures/mastodon-unfollow-activity.json")
363 |> Poison.decode!()
364 |> Map.put("object", follow_data)
365
366 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
367
368 assert data["type"] == "Undo"
369 assert data["object"]["type"] == "Follow"
370 assert data["object"]["object"] == user.ap_id
371 assert data["actor"] == "http://mastodon.example.org/users/admin"
372
373 refute User.following?(User.get_by_ap_id(data["actor"]), user)
374 end
375
376 test "it works for incoming blocks" do
377 user = insert(:user)
378
379 data =
380 File.read!("test/fixtures/mastodon-block-activity.json")
381 |> Poison.decode!()
382 |> Map.put("object", user.ap_id)
383
384 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
385
386 assert data["type"] == "Block"
387 assert data["object"] == user.ap_id
388 assert data["actor"] == "http://mastodon.example.org/users/admin"
389
390 blocker = User.get_by_ap_id(data["actor"])
391
392 assert User.blocks?(blocker, user)
393 end
394
395 test "incoming blocks successfully tear down any follow relationship" do
396 blocker = insert(:user)
397 blocked = insert(:user)
398
399 data =
400 File.read!("test/fixtures/mastodon-block-activity.json")
401 |> Poison.decode!()
402 |> Map.put("object", blocked.ap_id)
403 |> Map.put("actor", blocker.ap_id)
404
405 {:ok, blocker} = User.follow(blocker, blocked)
406 {:ok, blocked} = User.follow(blocked, blocker)
407
408 assert User.following?(blocker, blocked)
409 assert User.following?(blocked, blocker)
410
411 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
412
413 assert data["type"] == "Block"
414 assert data["object"] == blocked.ap_id
415 assert data["actor"] == blocker.ap_id
416
417 blocker = User.get_by_ap_id(data["actor"])
418 blocked = User.get_by_ap_id(data["object"])
419
420 assert User.blocks?(blocker, blocked)
421
422 refute User.following?(blocker, blocked)
423 refute User.following?(blocked, blocker)
424 end
425
426 test "it works for incoming unblocks with an existing block" do
427 user = insert(:user)
428
429 block_data =
430 File.read!("test/fixtures/mastodon-block-activity.json")
431 |> Poison.decode!()
432 |> Map.put("object", user.ap_id)
433
434 {:ok, %Activity{data: _, local: false}} = Transmogrifier.handle_incoming(block_data)
435
436 data =
437 File.read!("test/fixtures/mastodon-unblock-activity.json")
438 |> Poison.decode!()
439 |> Map.put("object", block_data)
440
441 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
442 assert data["type"] == "Undo"
443 assert data["object"]["type"] == "Block"
444 assert data["object"]["object"] == user.ap_id
445 assert data["actor"] == "http://mastodon.example.org/users/admin"
446
447 blocker = User.get_by_ap_id(data["actor"])
448
449 refute User.blocks?(blocker, user)
450 end
451
452 test "it works for incoming accepts which were pre-accepted" do
453 follower = insert(:user)
454 followed = insert(:user)
455
456 {:ok, follower} = User.follow(follower, followed)
457 assert User.following?(follower, followed) == true
458
459 {:ok, follow_activity} = ActivityPub.follow(follower, followed)
460
461 accept_data =
462 File.read!("test/fixtures/mastodon-accept-activity.json")
463 |> Poison.decode!()
464 |> Map.put("actor", followed.ap_id)
465
466 object =
467 accept_data["object"]
468 |> Map.put("actor", follower.ap_id)
469 |> Map.put("id", follow_activity.data["id"])
470
471 accept_data = Map.put(accept_data, "object", object)
472
473 {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
474 refute activity.local
475
476 assert activity.data["object"] == follow_activity.data["id"]
477
478 follower = Repo.get(User, follower.id)
479
480 assert User.following?(follower, followed) == true
481 end
482
483 test "it works for incoming accepts which were orphaned" do
484 follower = insert(:user)
485 followed = insert(:user, %{info: %{"locked" => true}})
486
487 {:ok, follow_activity} = ActivityPub.follow(follower, followed)
488
489 accept_data =
490 File.read!("test/fixtures/mastodon-accept-activity.json")
491 |> Poison.decode!()
492 |> Map.put("actor", followed.ap_id)
493
494 accept_data =
495 Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.ap_id))
496
497 {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
498 assert activity.data["object"] == follow_activity.data["id"]
499
500 follower = Repo.get(User, follower.id)
501
502 assert User.following?(follower, followed) == true
503 end
504
505 test "it works for incoming accepts which are referenced by IRI only" do
506 follower = insert(:user)
507 followed = insert(:user, %{info: %{"locked" => true}})
508
509 {:ok, follow_activity} = ActivityPub.follow(follower, followed)
510
511 accept_data =
512 File.read!("test/fixtures/mastodon-accept-activity.json")
513 |> Poison.decode!()
514 |> Map.put("actor", followed.ap_id)
515 |> Map.put("object", follow_activity.data["id"])
516
517 {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
518 assert activity.data["object"] == follow_activity.data["id"]
519
520 follower = Repo.get(User, follower.id)
521
522 assert User.following?(follower, followed) == true
523 end
524
525 test "it fails for incoming accepts which cannot be correlated" do
526 follower = insert(:user)
527 followed = insert(:user, %{info: %{"locked" => true}})
528
529 accept_data =
530 File.read!("test/fixtures/mastodon-accept-activity.json")
531 |> Poison.decode!()
532 |> Map.put("actor", followed.ap_id)
533
534 accept_data =
535 Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.ap_id))
536
537 :error = Transmogrifier.handle_incoming(accept_data)
538
539 follower = Repo.get(User, follower.id)
540
541 refute User.following?(follower, followed) == true
542 end
543
544 test "it fails for incoming rejects which cannot be correlated" do
545 follower = insert(:user)
546 followed = insert(:user, %{info: %{"locked" => true}})
547
548 accept_data =
549 File.read!("test/fixtures/mastodon-reject-activity.json")
550 |> Poison.decode!()
551 |> Map.put("actor", followed.ap_id)
552
553 accept_data =
554 Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.ap_id))
555
556 :error = Transmogrifier.handle_incoming(accept_data)
557
558 follower = Repo.get(User, follower.id)
559
560 refute User.following?(follower, followed) == true
561 end
562
563 test "it works for incoming rejects which are orphaned" do
564 follower = insert(:user)
565 followed = insert(:user, %{info: %{"locked" => true}})
566
567 {:ok, follower} = User.follow(follower, followed)
568 {:ok, _follow_activity} = ActivityPub.follow(follower, followed)
569
570 assert User.following?(follower, followed) == true
571
572 reject_data =
573 File.read!("test/fixtures/mastodon-reject-activity.json")
574 |> Poison.decode!()
575 |> Map.put("actor", followed.ap_id)
576
577 reject_data =
578 Map.put(reject_data, "object", Map.put(reject_data["object"], "actor", follower.ap_id))
579
580 {:ok, activity} = Transmogrifier.handle_incoming(reject_data)
581 refute activity.local
582
583 follower = Repo.get(User, follower.id)
584
585 assert User.following?(follower, followed) == false
586 end
587
588 test "it works for incoming rejects which are referenced by IRI only" do
589 follower = insert(:user)
590 followed = insert(:user, %{info: %{"locked" => true}})
591
592 {:ok, follower} = User.follow(follower, followed)
593 {:ok, follow_activity} = ActivityPub.follow(follower, followed)
594
595 assert User.following?(follower, followed) == true
596
597 reject_data =
598 File.read!("test/fixtures/mastodon-reject-activity.json")
599 |> Poison.decode!()
600 |> Map.put("actor", followed.ap_id)
601 |> Map.put("object", follow_activity.data["id"])
602
603 {:ok, %Activity{data: _}} = Transmogrifier.handle_incoming(reject_data)
604
605 follower = Repo.get(User, follower.id)
606
607 assert User.following?(follower, followed) == false
608 end
609 end
610
611 describe "prepare outgoing" do
612 test "it turns mentions into tags" do
613 user = insert(:user)
614 other_user = insert(:user)
615
616 {:ok, activity} =
617 CommonAPI.post(user, %{"status" => "hey, @#{other_user.nickname}, how are ya? #2hu"})
618
619 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
620 object = modified["object"]
621
622 expected_mention = %{
623 "href" => other_user.ap_id,
624 "name" => "@#{other_user.nickname}",
625 "type" => "Mention"
626 }
627
628 expected_tag = %{
629 "href" => Pleroma.Web.Endpoint.url() <> "/tags/2hu",
630 "type" => "Hashtag",
631 "name" => "#2hu"
632 }
633
634 assert Enum.member?(object["tag"], expected_tag)
635 assert Enum.member?(object["tag"], expected_mention)
636 end
637
638 test "it adds the sensitive property" do
639 user = insert(:user)
640
641 {:ok, activity} = CommonAPI.post(user, %{"status" => "#nsfw hey"})
642 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
643
644 assert modified["object"]["sensitive"]
645 end
646
647 test "it adds the json-ld context and the conversation property" do
648 user = insert(:user)
649
650 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"})
651 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
652
653 assert modified["@context"] == "https://www.w3.org/ns/activitystreams"
654 assert modified["object"]["conversation"] == modified["context"]
655 end
656
657 test "it sets the 'attributedTo' property to the actor of the object if it doesn't have one" do
658 user = insert(:user)
659
660 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"})
661 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
662
663 assert modified["object"]["actor"] == modified["object"]["attributedTo"]
664 end
665
666 test "it translates ostatus IDs to external URLs" do
667 incoming = File.read!("test/fixtures/incoming_note_activity.xml")
668 {:ok, [referent_activity]} = OStatus.handle_incoming(incoming)
669
670 user = insert(:user)
671
672 {:ok, activity, _} = CommonAPI.favorite(referent_activity.id, user)
673 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
674
675 assert modified["object"] == "http://gs.example.org:4040/index.php/notice/29"
676 end
677
678 test "it translates ostatus reply_to IDs to external URLs" do
679 incoming = File.read!("test/fixtures/incoming_note_activity.xml")
680 {:ok, [referred_activity]} = OStatus.handle_incoming(incoming)
681
682 user = insert(:user)
683
684 {:ok, activity} =
685 CommonAPI.post(user, %{"status" => "HI!", "in_reply_to_status_id" => referred_activity.id})
686
687 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
688
689 assert modified["object"]["inReplyTo"] == "http://gs.example.org:4040/index.php/notice/29"
690 end
691 end
692
693 describe "user upgrade" do
694 test "it upgrades a user to activitypub" do
695 user =
696 insert(:user, %{
697 nickname: "rye@niu.moe",
698 local: false,
699 ap_id: "https://niu.moe/users/rye",
700 follower_address: User.ap_followers(%User{nickname: "rye@niu.moe"})
701 })
702
703 user_two = insert(:user, %{following: [user.follower_address]})
704
705 {:ok, activity} = CommonAPI.post(user, %{"status" => "test"})
706 {:ok, unrelated_activity} = CommonAPI.post(user_two, %{"status" => "test"})
707 assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients
708
709 user = Repo.get(User, user.id)
710 assert user.info["note_count"] == 1
711
712 {:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
713 assert user.info["ap_enabled"]
714 assert user.info["note_count"] == 1
715 assert user.follower_address == "https://niu.moe/users/rye/followers"
716
717 # Wait for the background task
718 :timer.sleep(1000)
719
720 user = Repo.get(User, user.id)
721 assert user.info["note_count"] == 1
722
723 activity = Repo.get(Activity, activity.id)
724 assert user.follower_address in activity.recipients
725
726 assert %{
727 "url" => [
728 %{
729 "href" =>
730 "https://cdn.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
731 }
732 ]
733 } = user.avatar
734
735 assert %{
736 "url" => [
737 %{
738 "href" =>
739 "https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
740 }
741 ]
742 } = user.info["banner"]
743
744 refute "..." in activity.recipients
745
746 unrelated_activity = Repo.get(Activity, unrelated_activity.id)
747 refute user.follower_address in unrelated_activity.recipients
748
749 user_two = Repo.get(User, user_two.id)
750 assert user.follower_address in user_two.following
751 refute "..." in user_two.following
752 end
753 end
754
755 describe "maybe_retire_websub" do
756 test "it deletes all websub client subscripitions with the user as topic" do
757 subscription = %WebsubClientSubscription{topic: "https://niu.moe/users/rye.atom"}
758 {:ok, ws} = Repo.insert(subscription)
759
760 subscription = %WebsubClientSubscription{topic: "https://niu.moe/users/pasty.atom"}
761 {:ok, ws2} = Repo.insert(subscription)
762
763 Transmogrifier.maybe_retire_websub("https://niu.moe/users/rye")
764
765 refute Repo.get(WebsubClientSubscription, ws.id)
766 assert Repo.get(WebsubClientSubscription, ws2.id)
767 end
768 end
769
770 describe "actor rewriting" do
771 test "it fixes the actor URL property to be a proper URI" do
772 data = %{
773 "url" => %{"href" => "http://example.com"}
774 }
775
776 rewritten = Transmogrifier.maybe_fix_user_object(data)
777 assert rewritten["url"] == "http://example.com"
778 end
779 end
780 end