1 defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
3 alias Pleroma.Web.ActivityPub.Transmogrifier
4 alias Pleroma.Web.ActivityPub.Utils
5 alias Pleroma.Web.ActivityPub.ActivityPub
6 alias Pleroma.Web.OStatus
10 alias Pleroma.Web.Websub.WebsubClientSubscription
12 import Pleroma.Factory
13 alias Pleroma.Web.CommonAPI
15 describe "handle_incoming" do
16 test "it ignores an incoming notice if we already have it" do
17 activity = insert(:note_activity)
20 File.read!("test/fixtures/mastodon-post-activity.json")
22 |> Map.put("object", activity.data["object"])
24 {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
26 assert activity == returned_activity
29 test "it fetches replied-to activities if we don't have them" do
31 File.read!("test/fixtures/mastodon-post-activity.json")
36 |> Map.put("inReplyTo", "https://shitposter.club/notice/2827873")
40 |> Map.put("object", object)
42 {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
45 Activity.get_create_activity_by_object_ap_id(
46 "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
49 assert returned_activity.data["object"]["inReplyToAtomUri"] ==
50 "https://shitposter.club/notice/2827873"
52 assert returned_activity.data["object"]["inReplyToStatusId"] == activity.id
55 test "it works for incoming notices" do
56 data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
58 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
61 "http://mastodon.example.org/users/admin/statuses/99512778738411822/activity"
63 assert data["context"] ==
64 "tag:mastodon.example.org,2018-02-12:objectId=20:objectType=Conversation"
66 assert data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
68 assert data["cc"] == [
69 "http://mastodon.example.org/users/admin/followers",
70 "http://localtesting.pleroma.lol/users/lain"
73 assert data["actor"] == "http://mastodon.example.org/users/admin"
75 object = data["object"]
76 assert object["id"] == "http://mastodon.example.org/users/admin/statuses/99512778738411822"
78 assert object["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
80 assert object["cc"] == [
81 "http://mastodon.example.org/users/admin/followers",
82 "http://localtesting.pleroma.lol/users/lain"
85 assert object["actor"] == "http://mastodon.example.org/users/admin"
86 assert object["attributedTo"] == "http://mastodon.example.org/users/admin"
88 assert object["context"] ==
89 "tag:mastodon.example.org,2018-02-12:objectId=20:objectType=Conversation"
91 assert object["sensitive"] == true
93 user = User.get_by_ap_id(object["actor"])
95 assert user.info["note_count"] == 1
98 test "it works for incoming notices with hashtags" do
99 data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Poison.decode!()
101 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
102 assert Enum.at(data["object"]["tag"], 2) == "moo"
105 test "it works for incoming notices with contentMap" do
107 File.read!("test/fixtures/mastodon-post-activity-contentmap.json") |> Poison.decode!()
109 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
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>"
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!()
118 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
120 assert data["object"]["content"] ==
121 "<p>henlo from my Psion netBook</p><p>message sent from my Psion netBook</p>"
124 test "it works for incoming announces with actor being inlined (kroeg)" do
125 data = File.read!("test/fixtures/kroeg-announce-with-inline-actor.json") |> Poison.decode!()
127 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
129 assert data["actor"] == "https://puckipedia.com/"
132 test "it works for incoming notices with tag not being an array (kroeg)" do
133 data = File.read!("test/fixtures/kroeg-array-less-emoji.json") |> Poison.decode!()
135 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
137 assert data["object"]["emoji"] == %{
138 "icon_e_smile" => "https://puckipedia.com/forum/images/smilies/icon_e_smile.png"
141 data = File.read!("test/fixtures/kroeg-array-less-hashtag.json") |> Poison.decode!()
143 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
145 assert "test" in data["object"]["tag"]
148 test "it works for incoming notices with url not being a string (prismo)" do
149 data = File.read!("test/fixtures/prismo-url-map.json") |> Poison.decode!()
151 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
153 assert data["object"]["url"] == "https://prismo.news/posts/83"
156 test "it works for incoming follow requests" do
160 File.read!("test/fixtures/mastodon-follow-activity.json")
162 |> Map.put("object", user.ap_id)
164 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
166 assert data["actor"] == "http://mastodon.example.org/users/admin"
167 assert data["type"] == "Follow"
168 assert data["id"] == "http://mastodon.example.org/users/admin#follows/2"
169 assert User.following?(User.get_by_ap_id(data["actor"]), user)
172 test "it works for incoming follow requests from hubzilla" do
176 File.read!("test/fixtures/hubzilla-follow-activity.json")
178 |> Map.put("object", user.ap_id)
179 |> Utils.normalize_params()
181 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
183 assert data["actor"] == "https://hubzilla.example.org/channel/kaniini"
184 assert data["type"] == "Follow"
185 assert data["id"] == "https://hubzilla.example.org/channel/kaniini#follows/2"
186 assert User.following?(User.get_by_ap_id(data["actor"]), user)
189 test "it works for incoming likes" do
191 {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"})
194 File.read!("test/fixtures/mastodon-like.json")
196 |> Map.put("object", activity.data["object"]["id"])
198 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
200 assert data["actor"] == "http://mastodon.example.org/users/admin"
201 assert data["type"] == "Like"
202 assert data["id"] == "http://mastodon.example.org/users/admin#likes/2"
203 assert data["object"] == activity.data["object"]["id"]
206 test "it returns an error for incoming unlikes wihout a like activity" do
208 {:ok, activity} = CommonAPI.post(user, %{"status" => "leave a like pls"})
211 File.read!("test/fixtures/mastodon-undo-like.json")
213 |> Map.put("object", activity.data["object"]["id"])
215 assert Transmogrifier.handle_incoming(data) == :error
218 test "it works for incoming unlikes with an existing like activity" do
220 {:ok, activity} = CommonAPI.post(user, %{"status" => "leave a like pls"})
223 File.read!("test/fixtures/mastodon-like.json")
225 |> Map.put("object", activity.data["object"]["id"])
227 {:ok, %Activity{data: like_data, local: false}} = Transmogrifier.handle_incoming(like_data)
230 File.read!("test/fixtures/mastodon-undo-like.json")
232 |> Map.put("object", like_data)
233 |> Map.put("actor", like_data["actor"])
235 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
237 assert data["actor"] == "http://mastodon.example.org/users/admin"
238 assert data["type"] == "Undo"
239 assert data["id"] == "http://mastodon.example.org/users/admin#likes/2/undo"
240 assert data["object"]["id"] == "http://mastodon.example.org/users/admin#likes/2"
243 test "it works for incoming announces" do
244 data = File.read!("test/fixtures/mastodon-announce.json") |> Poison.decode!()
246 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
248 assert data["actor"] == "http://mastodon.example.org/users/admin"
249 assert data["type"] == "Announce"
252 "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
254 assert data["object"] ==
255 "http://mastodon.example.org/users/admin/statuses/99541947525187367"
257 assert Activity.get_create_activity_by_object_ap_id(data["object"])
260 test "it works for incoming announces with an existing activity" do
262 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"})
265 File.read!("test/fixtures/mastodon-announce.json")
267 |> Map.put("object", activity.data["object"]["id"])
269 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
271 assert data["actor"] == "http://mastodon.example.org/users/admin"
272 assert data["type"] == "Announce"
275 "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
277 assert data["object"] == activity.data["object"]["id"]
279 assert Activity.get_create_activity_by_object_ap_id(data["object"]).id == activity.id
282 test "it works for incoming update activities" do
283 data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
285 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
286 update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!()
289 update_data["object"]
290 |> Map.put("actor", data["actor"])
291 |> Map.put("id", data["actor"])
295 |> Map.put("actor", data["actor"])
296 |> Map.put("object", object)
298 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(update_data)
300 user = User.get_cached_by_ap_id(data["actor"])
301 assert user.name == "gargle"
303 assert user.avatar["url"] == [
306 "https://cd.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
310 assert user.info["banner"]["url"] == [
313 "https://cd.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
317 assert user.bio == "<p>Some bio</p>"
320 test "it works for incoming update activities which lock the account" do
321 data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
323 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
324 update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!()
327 update_data["object"]
328 |> Map.put("actor", data["actor"])
329 |> Map.put("id", data["actor"])
330 |> Map.put("manuallyApprovesFollowers", true)
334 |> Map.put("actor", data["actor"])
335 |> Map.put("object", object)
337 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(update_data)
339 user = User.get_cached_by_ap_id(data["actor"])
340 assert user.info["locked"] == true
343 test "it works for incoming deletes" do
344 activity = insert(:note_activity)
347 File.read!("test/fixtures/mastodon-delete.json")
352 |> Map.put("id", activity.data["object"]["id"])
356 |> Map.put("object", object)
357 |> Map.put("actor", activity.data["actor"])
359 {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
361 refute Repo.get(Activity, activity.id)
364 test "it works for incoming unannounces with an existing notice" do
366 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"})
369 File.read!("test/fixtures/mastodon-announce.json")
371 |> Map.put("object", activity.data["object"]["id"])
373 {:ok, %Activity{data: announce_data, local: false}} =
374 Transmogrifier.handle_incoming(announce_data)
377 File.read!("test/fixtures/mastodon-undo-announce.json")
379 |> Map.put("object", announce_data)
380 |> Map.put("actor", announce_data["actor"])
382 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
384 assert data["type"] == "Undo"
385 assert data["object"]["type"] == "Announce"
386 assert data["object"]["object"] == activity.data["object"]["id"]
388 assert data["object"]["id"] ==
389 "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
392 test "it works for incomming unfollows with an existing follow" do
396 File.read!("test/fixtures/mastodon-follow-activity.json")
398 |> Map.put("object", user.ap_id)
400 {:ok, %Activity{data: _, local: false}} = Transmogrifier.handle_incoming(follow_data)
403 File.read!("test/fixtures/mastodon-unfollow-activity.json")
405 |> Map.put("object", follow_data)
407 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
409 assert data["type"] == "Undo"
410 assert data["object"]["type"] == "Follow"
411 assert data["object"]["object"] == user.ap_id
412 assert data["actor"] == "http://mastodon.example.org/users/admin"
414 refute User.following?(User.get_by_ap_id(data["actor"]), user)
417 test "it works for incoming blocks" do
421 File.read!("test/fixtures/mastodon-block-activity.json")
423 |> Map.put("object", user.ap_id)
425 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
427 assert data["type"] == "Block"
428 assert data["object"] == user.ap_id
429 assert data["actor"] == "http://mastodon.example.org/users/admin"
431 blocker = User.get_by_ap_id(data["actor"])
433 assert User.blocks?(blocker, user)
436 test "incoming blocks successfully tear down any follow relationship" do
437 blocker = insert(:user)
438 blocked = insert(:user)
441 File.read!("test/fixtures/mastodon-block-activity.json")
443 |> Map.put("object", blocked.ap_id)
444 |> Map.put("actor", blocker.ap_id)
446 {:ok, blocker} = User.follow(blocker, blocked)
447 {:ok, blocked} = User.follow(blocked, blocker)
449 assert User.following?(blocker, blocked)
450 assert User.following?(blocked, blocker)
452 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
454 assert data["type"] == "Block"
455 assert data["object"] == blocked.ap_id
456 assert data["actor"] == blocker.ap_id
458 blocker = User.get_by_ap_id(data["actor"])
459 blocked = User.get_by_ap_id(data["object"])
461 assert User.blocks?(blocker, blocked)
463 refute User.following?(blocker, blocked)
464 refute User.following?(blocked, blocker)
467 test "it works for incoming unblocks with an existing block" do
471 File.read!("test/fixtures/mastodon-block-activity.json")
473 |> Map.put("object", user.ap_id)
475 {:ok, %Activity{data: _, local: false}} = Transmogrifier.handle_incoming(block_data)
478 File.read!("test/fixtures/mastodon-unblock-activity.json")
480 |> Map.put("object", block_data)
482 {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
483 assert data["type"] == "Undo"
484 assert data["object"]["type"] == "Block"
485 assert data["object"]["object"] == user.ap_id
486 assert data["actor"] == "http://mastodon.example.org/users/admin"
488 blocker = User.get_by_ap_id(data["actor"])
490 refute User.blocks?(blocker, user)
493 test "it works for incoming accepts which were pre-accepted" do
494 follower = insert(:user)
495 followed = insert(:user)
497 {:ok, follower} = User.follow(follower, followed)
498 assert User.following?(follower, followed) == true
500 {:ok, follow_activity} = ActivityPub.follow(follower, followed)
503 File.read!("test/fixtures/mastodon-accept-activity.json")
505 |> Map.put("actor", followed.ap_id)
508 accept_data["object"]
509 |> Map.put("actor", follower.ap_id)
510 |> Map.put("id", follow_activity.data["id"])
512 accept_data = Map.put(accept_data, "object", object)
514 {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
515 refute activity.local
517 assert activity.data["object"] == follow_activity.data["id"]
519 follower = Repo.get(User, follower.id)
521 assert User.following?(follower, followed) == true
524 test "it works for incoming accepts which were orphaned" do
525 follower = insert(:user)
526 followed = insert(:user, %{info: %{"locked" => true}})
528 {:ok, follow_activity} = ActivityPub.follow(follower, followed)
531 File.read!("test/fixtures/mastodon-accept-activity.json")
533 |> Map.put("actor", followed.ap_id)
536 Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.ap_id))
538 {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
539 assert activity.data["object"] == follow_activity.data["id"]
541 follower = Repo.get(User, follower.id)
543 assert User.following?(follower, followed) == true
546 test "it works for incoming accepts which are referenced by IRI only" do
547 follower = insert(:user)
548 followed = insert(:user, %{info: %{"locked" => true}})
550 {:ok, follow_activity} = ActivityPub.follow(follower, followed)
553 File.read!("test/fixtures/mastodon-accept-activity.json")
555 |> Map.put("actor", followed.ap_id)
556 |> Map.put("object", follow_activity.data["id"])
558 {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
559 assert activity.data["object"] == follow_activity.data["id"]
561 follower = Repo.get(User, follower.id)
563 assert User.following?(follower, followed) == true
566 test "it fails for incoming accepts which cannot be correlated" do
567 follower = insert(:user)
568 followed = insert(:user, %{info: %{"locked" => true}})
571 File.read!("test/fixtures/mastodon-accept-activity.json")
573 |> Map.put("actor", followed.ap_id)
576 Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.ap_id))
578 :error = Transmogrifier.handle_incoming(accept_data)
580 follower = Repo.get(User, follower.id)
582 refute User.following?(follower, followed) == true
585 test "it fails for incoming rejects which cannot be correlated" do
586 follower = insert(:user)
587 followed = insert(:user, %{info: %{"locked" => true}})
590 File.read!("test/fixtures/mastodon-reject-activity.json")
592 |> Map.put("actor", followed.ap_id)
595 Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.ap_id))
597 :error = Transmogrifier.handle_incoming(accept_data)
599 follower = Repo.get(User, follower.id)
601 refute User.following?(follower, followed) == true
604 test "it works for incoming rejects which are orphaned" do
605 follower = insert(:user)
606 followed = insert(:user, %{info: %{"locked" => true}})
608 {:ok, follower} = User.follow(follower, followed)
609 {:ok, _follow_activity} = ActivityPub.follow(follower, followed)
611 assert User.following?(follower, followed) == true
614 File.read!("test/fixtures/mastodon-reject-activity.json")
616 |> Map.put("actor", followed.ap_id)
619 Map.put(reject_data, "object", Map.put(reject_data["object"], "actor", follower.ap_id))
621 {:ok, activity} = Transmogrifier.handle_incoming(reject_data)
622 refute activity.local
624 follower = Repo.get(User, follower.id)
626 assert User.following?(follower, followed) == false
629 test "it works for incoming rejects which are referenced by IRI only" do
630 follower = insert(:user)
631 followed = insert(:user, %{info: %{"locked" => true}})
633 {:ok, follower} = User.follow(follower, followed)
634 {:ok, follow_activity} = ActivityPub.follow(follower, followed)
636 assert User.following?(follower, followed) == true
639 File.read!("test/fixtures/mastodon-reject-activity.json")
641 |> Map.put("actor", followed.ap_id)
642 |> Map.put("object", follow_activity.data["id"])
644 {:ok, %Activity{data: _}} = Transmogrifier.handle_incoming(reject_data)
646 follower = Repo.get(User, follower.id)
648 assert User.following?(follower, followed) == false
651 test "it rejects activities without a valid ID" do
655 File.read!("test/fixtures/mastodon-follow-activity.json")
657 |> Map.put("object", user.ap_id)
660 :error = Transmogrifier.handle_incoming(data)
664 describe "prepare outgoing" do
665 test "it turns mentions into tags" do
667 other_user = insert(:user)
670 CommonAPI.post(user, %{"status" => "hey, @#{other_user.nickname}, how are ya? #2hu"})
672 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
673 object = modified["object"]
675 expected_mention = %{
676 "href" => other_user.ap_id,
677 "name" => "@#{other_user.nickname}",
682 "href" => Pleroma.Web.Endpoint.url() <> "/tags/2hu",
687 assert Enum.member?(object["tag"], expected_tag)
688 assert Enum.member?(object["tag"], expected_mention)
691 test "it adds the sensitive property" do
694 {:ok, activity} = CommonAPI.post(user, %{"status" => "#nsfw hey"})
695 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
697 assert modified["object"]["sensitive"]
700 test "it adds the json-ld context and the conversation property" do
703 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"})
704 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
706 assert modified["@context"] ==
707 Pleroma.Web.ActivityPub.Utils.make_json_ld_header()["@context"]
709 assert modified["object"]["conversation"] == modified["context"]
712 test "it sets the 'attributedTo' property to the actor of the object if it doesn't have one" do
715 {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"})
716 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
718 assert modified["object"]["actor"] == modified["object"]["attributedTo"]
721 test "it translates ostatus IDs to external URLs" do
722 incoming = File.read!("test/fixtures/incoming_note_activity.xml")
723 {:ok, [referent_activity]} = OStatus.handle_incoming(incoming)
727 {:ok, activity, _} = CommonAPI.favorite(referent_activity.id, user)
728 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
730 assert modified["object"] == "http://gs.example.org:4040/index.php/notice/29"
733 test "it translates ostatus reply_to IDs to external URLs" do
734 incoming = File.read!("test/fixtures/incoming_note_activity.xml")
735 {:ok, [referred_activity]} = OStatus.handle_incoming(incoming)
740 CommonAPI.post(user, %{"status" => "HI!", "in_reply_to_status_id" => referred_activity.id})
742 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
744 assert modified["object"]["inReplyTo"] == "http://gs.example.org:4040/index.php/notice/29"
747 test "it strips internal hashtag data" do
750 {:ok, activity} = CommonAPI.post(user, %{"status" => "#2hu"})
753 "href" => Pleroma.Web.Endpoint.url() <> "/tags/2hu",
758 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
760 assert modified["object"]["tag"] == [expected_tag]
763 test "it strips internal fields" do
766 {:ok, activity} = CommonAPI.post(user, %{"status" => "#2hu :moominmamma:"})
768 {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
770 assert length(modified["object"]["tag"]) == 2
772 assert is_nil(modified["object"]["emoji"])
773 assert is_nil(modified["object"]["likes"])
774 assert is_nil(modified["object"]["like_count"])
775 assert is_nil(modified["object"]["announcements"])
776 assert is_nil(modified["object"]["announcement_count"])
777 assert is_nil(modified["object"]["context_id"])
781 describe "user upgrade" do
782 test "it upgrades a user to activitypub" do
785 nickname: "rye@niu.moe",
787 ap_id: "https://niu.moe/users/rye",
788 follower_address: User.ap_followers(%User{nickname: "rye@niu.moe"})
791 user_two = insert(:user, %{following: [user.follower_address]})
793 {:ok, activity} = CommonAPI.post(user, %{"status" => "test"})
794 {:ok, unrelated_activity} = CommonAPI.post(user_two, %{"status" => "test"})
795 assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients
797 user = Repo.get(User, user.id)
798 assert user.info["note_count"] == 1
800 {:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
801 assert user.info["ap_enabled"]
802 assert user.info["note_count"] == 1
803 assert user.follower_address == "https://niu.moe/users/rye/followers"
805 # Wait for the background task
808 user = Repo.get(User, user.id)
809 assert user.info["note_count"] == 1
811 activity = Repo.get(Activity, activity.id)
812 assert user.follower_address in activity.recipients
818 "https://cdn.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
827 "https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
830 } = user.info["banner"]
832 refute "..." in activity.recipients
834 unrelated_activity = Repo.get(Activity, unrelated_activity.id)
835 refute user.follower_address in unrelated_activity.recipients
837 user_two = Repo.get(User, user_two.id)
838 assert user.follower_address in user_two.following
839 refute "..." in user_two.following
843 describe "maybe_retire_websub" do
844 test "it deletes all websub client subscripitions with the user as topic" do
845 subscription = %WebsubClientSubscription{topic: "https://niu.moe/users/rye.atom"}
846 {:ok, ws} = Repo.insert(subscription)
848 subscription = %WebsubClientSubscription{topic: "https://niu.moe/users/pasty.atom"}
849 {:ok, ws2} = Repo.insert(subscription)
851 Transmogrifier.maybe_retire_websub("https://niu.moe/users/rye")
853 refute Repo.get(WebsubClientSubscription, ws.id)
854 assert Repo.get(WebsubClientSubscription, ws2.id)
858 describe "actor rewriting" do
859 test "it fixes the actor URL property to be a proper URI" do
861 "url" => %{"href" => "http://example.com"}
864 rewritten = Transmogrifier.maybe_fix_user_object(data)
865 assert rewritten["url"] == "http://example.com"
869 describe "actor origin containment" do
870 test "it rejects objects with a bogus origin" do
871 {:error, _} = ActivityPub.fetch_object_from_id("https://info.pleroma.site/activity.json")
874 test "it rejects activities which reference objects with bogus origins" do
875 user = insert(:user, %{local: false})
878 "@context" => "https://www.w3.org/ns/activitystreams",
879 "id" => user.ap_id <> "/activities/1234",
880 "actor" => user.ap_id,
881 "to" => ["https://www.w3.org/ns/activitystreams#Public"],
882 "object" => "https://info.pleroma.site/activity.json",
886 :error = Transmogrifier.handle_incoming(data)