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