First
[anni] / test / pleroma / web / activity_pub / transmogrifier / announce_handling_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.ActivityPub.Transmogrifier.AnnounceHandlingTest do
6   use Pleroma.DataCase
7
8   alias Pleroma.Activity
9   alias Pleroma.Object
10   alias Pleroma.Web.ActivityPub.Transmogrifier
11   alias Pleroma.Web.CommonAPI
12
13   import Pleroma.Factory
14
15   test "it works for incoming honk announces" do
16     user = insert(:user, ap_id: "https://honktest/u/test", local: false)
17     other_user = insert(:user)
18     {:ok, post} = CommonAPI.post(other_user, %{status: "bonkeronk"})
19
20     announce = %{
21       "@context" => "https://www.w3.org/ns/activitystreams",
22       "actor" => "https://honktest/u/test",
23       "id" => "https://honktest/u/test/bonk/1793M7B9MQ48847vdx",
24       "object" => post.data["object"],
25       "published" => "2019-06-25T19:33:58Z",
26       "to" => "https://www.w3.org/ns/activitystreams#Public",
27       "type" => "Announce"
28     }
29
30     {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(announce)
31
32     object = Object.get_by_ap_id(post.data["object"])
33
34     assert length(object.data["announcements"]) == 1
35     assert user.ap_id in object.data["announcements"]
36   end
37
38   test "it works for incoming announces with actor being inlined (kroeg)" do
39     data = File.read!("test/fixtures/kroeg-announce-with-inline-actor.json") |> Jason.decode!()
40
41     _user = insert(:user, local: false, ap_id: data["actor"]["id"])
42     other_user = insert(:user)
43
44     {:ok, post} = CommonAPI.post(other_user, %{status: "kroegeroeg"})
45
46     data =
47       data
48       |> put_in(["object", "id"], post.data["object"])
49
50     {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
51
52     assert data["actor"] == "https://puckipedia.com/"
53   end
54
55   test "it works for incoming announces, fetching the announced object" do
56     data =
57       File.read!("test/fixtures/mastodon-announce.json")
58       |> Jason.decode!()
59       |> Map.put("object", "http://mastodon.example.org/users/admin/statuses/99541947525187367")
60
61     Tesla.Mock.mock(fn
62       %{method: :get} ->
63         %Tesla.Env{
64           status: 200,
65           body: File.read!("test/fixtures/mastodon-note-object.json"),
66           headers: HttpRequestMock.activitypub_object_headers()
67         }
68     end)
69
70     _user = insert(:user, local: false, ap_id: data["actor"])
71
72     {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
73
74     assert data["actor"] == "http://mastodon.example.org/users/admin"
75     assert data["type"] == "Announce"
76
77     assert data["id"] ==
78              "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
79
80     assert data["object"] ==
81              "http://mastodon.example.org/users/admin/statuses/99541947525187367"
82
83     assert(Activity.get_create_by_object_ap_id(data["object"]))
84   end
85
86   @tag capture_log: true
87   test "it works for incoming announces with an existing activity" do
88     user = insert(:user)
89     {:ok, activity} = CommonAPI.post(user, %{status: "hey"})
90
91     data =
92       File.read!("test/fixtures/mastodon-announce.json")
93       |> Jason.decode!()
94       |> Map.put("object", activity.data["object"])
95
96     _user = insert(:user, local: false, ap_id: data["actor"])
97
98     {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
99
100     assert data["actor"] == "http://mastodon.example.org/users/admin"
101     assert data["type"] == "Announce"
102
103     assert data["id"] ==
104              "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
105
106     assert data["object"] == activity.data["object"]
107
108     assert Activity.get_create_by_object_ap_id(data["object"]).id == activity.id
109   end
110
111   # Ignore inlined activities for now
112   @tag skip: true
113   test "it works for incoming announces with an inlined activity" do
114     data =
115       File.read!("test/fixtures/mastodon-announce-private.json")
116       |> Jason.decode!()
117
118     _user =
119       insert(:user,
120         local: false,
121         ap_id: data["actor"],
122         follower_address: data["actor"] <> "/followers"
123       )
124
125     {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
126
127     assert data["actor"] == "http://mastodon.example.org/users/admin"
128     assert data["type"] == "Announce"
129
130     assert data["id"] ==
131              "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
132
133     object = Object.normalize(data["object"], fetch: false)
134
135     assert object.data["id"] == "http://mastodon.example.org/@admin/99541947525187368"
136     assert object.data["content"] == "this is a private toot"
137   end
138
139   @tag capture_log: true
140   test "it rejects incoming announces with an inlined activity from another origin" do
141     Tesla.Mock.mock(fn
142       %{method: :get} -> %Tesla.Env{status: 404, body: ""}
143     end)
144
145     data =
146       File.read!("test/fixtures/bogus-mastodon-announce.json")
147       |> Jason.decode!()
148
149     _user = insert(:user, local: false, ap_id: data["actor"])
150
151     assert {:error, _e} = Transmogrifier.handle_incoming(data)
152   end
153 end