Merge branch 'fix/html-cache-content-collision' into 'develop'
[akkoma] / test / web / activity_pub / activity_pub_controller_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
6 use Pleroma.Web.ConnCase
7 import Pleroma.Factory
8 alias Pleroma.Web.ActivityPub.{UserView, ObjectView}
9 alias Pleroma.{Object, Repo, User}
10 alias Pleroma.Activity
11
12 setup_all do
13 Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
14 :ok
15 end
16
17 describe "/relay" do
18 test "with the relay active, it returns the relay user", %{conn: conn} do
19 res =
20 conn
21 |> get(activity_pub_path(conn, :relay))
22 |> json_response(200)
23
24 assert res["id"] =~ "/relay"
25 end
26
27 test "with the relay disabled, it returns 404", %{conn: conn} do
28 Pleroma.Config.put([:instance, :allow_relay], false)
29
30 conn
31 |> get(activity_pub_path(conn, :relay))
32 |> json_response(404)
33 |> assert
34
35 Pleroma.Config.put([:instance, :allow_relay], true)
36 end
37 end
38
39 describe "/users/:nickname" do
40 test "it returns a json representation of the user", %{conn: conn} do
41 user = insert(:user)
42
43 conn =
44 conn
45 |> put_req_header("accept", "application/activity+json")
46 |> get("/users/#{user.nickname}")
47
48 user = Repo.get(User, user.id)
49
50 assert json_response(conn, 200) == UserView.render("user.json", %{user: user})
51 end
52 end
53
54 describe "/object/:uuid" do
55 test "it returns a json representation of the object", %{conn: conn} do
56 note = insert(:note)
57 uuid = String.split(note.data["id"], "/") |> List.last()
58
59 conn =
60 conn
61 |> put_req_header("accept", "application/activity+json")
62 |> get("/objects/#{uuid}")
63
64 assert json_response(conn, 200) == ObjectView.render("object.json", %{object: note})
65 end
66
67 test "it returns 404 for non-public messages", %{conn: conn} do
68 note = insert(:direct_note)
69 uuid = String.split(note.data["id"], "/") |> List.last()
70
71 conn =
72 conn
73 |> put_req_header("accept", "application/activity+json")
74 |> get("/objects/#{uuid}")
75
76 assert json_response(conn, 404)
77 end
78 end
79
80 describe "/inbox" do
81 test "it inserts an incoming activity into the database", %{conn: conn} do
82 data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
83
84 conn =
85 conn
86 |> assign(:valid_signature, true)
87 |> put_req_header("content-type", "application/activity+json")
88 |> post("/inbox", data)
89
90 assert "ok" == json_response(conn, 200)
91 :timer.sleep(500)
92 assert Activity.get_by_ap_id(data["id"])
93 end
94 end
95
96 describe "/users/:nickname/inbox" do
97 test "it inserts an incoming activity into the database", %{conn: conn} do
98 user = insert(:user)
99
100 data =
101 File.read!("test/fixtures/mastodon-post-activity.json")
102 |> Poison.decode!()
103 |> Map.put("bcc", [user.ap_id])
104
105 conn =
106 conn
107 |> assign(:valid_signature, true)
108 |> put_req_header("content-type", "application/activity+json")
109 |> post("/users/#{user.nickname}/inbox", data)
110
111 assert "ok" == json_response(conn, 200)
112 :timer.sleep(500)
113 assert Activity.get_by_ap_id(data["id"])
114 end
115
116 test "it rejects reads from other users", %{conn: conn} do
117 user = insert(:user)
118 otheruser = insert(:user)
119
120 conn =
121 conn
122 |> assign(:user, otheruser)
123 |> put_req_header("accept", "application/activity+json")
124 |> get("/users/#{user.nickname}/inbox")
125
126 assert json_response(conn, 403)
127 end
128
129 test "it returns a note activity in a collection", %{conn: conn} do
130 note_activity = insert(:direct_note_activity)
131 user = User.get_cached_by_ap_id(hd(note_activity.data["to"]))
132
133 conn =
134 conn
135 |> assign(:user, user)
136 |> put_req_header("accept", "application/activity+json")
137 |> get("/users/#{user.nickname}/inbox")
138
139 assert response(conn, 200) =~ note_activity.data["object"]["content"]
140 end
141 end
142
143 describe "/users/:nickname/outbox" do
144 test "it returns a note activity in a collection", %{conn: conn} do
145 note_activity = insert(:note_activity)
146 user = User.get_cached_by_ap_id(note_activity.data["actor"])
147
148 conn =
149 conn
150 |> put_req_header("accept", "application/activity+json")
151 |> get("/users/#{user.nickname}/outbox")
152
153 assert response(conn, 200) =~ note_activity.data["object"]["content"]
154 end
155
156 test "it returns an announce activity in a collection", %{conn: conn} do
157 announce_activity = insert(:announce_activity)
158 user = User.get_cached_by_ap_id(announce_activity.data["actor"])
159
160 conn =
161 conn
162 |> put_req_header("accept", "application/activity+json")
163 |> get("/users/#{user.nickname}/outbox")
164
165 assert response(conn, 200) =~ announce_activity.data["object"]
166 end
167
168 test "it rejects posts from other users", %{conn: conn} do
169 data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
170 user = insert(:user)
171 otheruser = insert(:user)
172
173 conn =
174 conn
175 |> assign(:user, otheruser)
176 |> put_req_header("content-type", "application/activity+json")
177 |> post("/users/#{user.nickname}/outbox", data)
178
179 assert json_response(conn, 403)
180 end
181
182 test "it inserts an incoming create activity into the database", %{conn: conn} do
183 data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
184 user = insert(:user)
185
186 conn =
187 conn
188 |> assign(:user, user)
189 |> put_req_header("content-type", "application/activity+json")
190 |> post("/users/#{user.nickname}/outbox", data)
191
192 result = json_response(conn, 201)
193 assert Activity.get_by_ap_id(result["id"])
194 end
195
196 test "it rejects an incoming activity with bogus type", %{conn: conn} do
197 data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
198 user = insert(:user)
199
200 data =
201 data
202 |> Map.put("type", "BadType")
203
204 conn =
205 conn
206 |> assign(:user, user)
207 |> put_req_header("content-type", "application/activity+json")
208 |> post("/users/#{user.nickname}/outbox", data)
209
210 assert json_response(conn, 400)
211 end
212
213 test "it erects a tombstone when receiving a delete activity", %{conn: conn} do
214 note_activity = insert(:note_activity)
215 user = User.get_cached_by_ap_id(note_activity.data["actor"])
216
217 data = %{
218 type: "Delete",
219 object: %{
220 id: note_activity.data["object"]["id"]
221 }
222 }
223
224 conn =
225 conn
226 |> assign(:user, user)
227 |> put_req_header("content-type", "application/activity+json")
228 |> post("/users/#{user.nickname}/outbox", data)
229
230 result = json_response(conn, 201)
231 assert Activity.get_by_ap_id(result["id"])
232
233 object = Object.get_by_ap_id(note_activity.data["object"]["id"])
234 assert object
235 assert object.data["type"] == "Tombstone"
236 end
237
238 test "it rejects delete activity of object from other actor", %{conn: conn} do
239 note_activity = insert(:note_activity)
240 user = insert(:user)
241
242 data = %{
243 type: "Delete",
244 object: %{
245 id: note_activity.data["object"]["id"]
246 }
247 }
248
249 conn =
250 conn
251 |> assign(:user, user)
252 |> put_req_header("content-type", "application/activity+json")
253 |> post("/users/#{user.nickname}/outbox", data)
254
255 assert json_response(conn, 400)
256 end
257 end
258
259 describe "/users/:nickname/followers" do
260 test "it returns the followers in a collection", %{conn: conn} do
261 user = insert(:user)
262 user_two = insert(:user)
263 User.follow(user, user_two)
264
265 result =
266 conn
267 |> get("/users/#{user_two.nickname}/followers")
268 |> json_response(200)
269
270 assert result["first"]["orderedItems"] == [user.ap_id]
271 end
272
273 test "it returns returns empty if the user has 'hide_network' set", %{conn: conn} do
274 user = insert(:user)
275 user_two = insert(:user, %{info: %{hide_network: true}})
276 User.follow(user, user_two)
277
278 result =
279 conn
280 |> get("/users/#{user_two.nickname}/followers")
281 |> json_response(200)
282
283 assert result["first"]["orderedItems"] == []
284 assert result["totalItems"] == 1
285 end
286
287 test "it works for more than 10 users", %{conn: conn} do
288 user = insert(:user)
289
290 Enum.each(1..15, fn _ ->
291 other_user = insert(:user)
292 User.follow(other_user, user)
293 end)
294
295 result =
296 conn
297 |> get("/users/#{user.nickname}/followers")
298 |> json_response(200)
299
300 assert length(result["first"]["orderedItems"]) == 10
301 assert result["first"]["totalItems"] == 15
302 assert result["totalItems"] == 15
303
304 result =
305 conn
306 |> get("/users/#{user.nickname}/followers?page=2")
307 |> json_response(200)
308
309 assert length(result["orderedItems"]) == 5
310 assert result["totalItems"] == 15
311 end
312 end
313
314 describe "/users/:nickname/following" do
315 test "it returns the following in a collection", %{conn: conn} do
316 user = insert(:user)
317 user_two = insert(:user)
318 User.follow(user, user_two)
319
320 result =
321 conn
322 |> get("/users/#{user.nickname}/following")
323 |> json_response(200)
324
325 assert result["first"]["orderedItems"] == [user_two.ap_id]
326 end
327
328 test "it returns returns empty if the user has 'hide_network' set", %{conn: conn} do
329 user = insert(:user, %{info: %{hide_network: true}})
330 user_two = insert(:user)
331 User.follow(user, user_two)
332
333 result =
334 conn
335 |> get("/users/#{user.nickname}/following")
336 |> json_response(200)
337
338 assert result["first"]["orderedItems"] == []
339 assert result["totalItems"] == 1
340 end
341
342 test "it works for more than 10 users", %{conn: conn} do
343 user = insert(:user)
344
345 Enum.each(1..15, fn _ ->
346 user = Repo.get(User, user.id)
347 other_user = insert(:user)
348 User.follow(user, other_user)
349 end)
350
351 result =
352 conn
353 |> get("/users/#{user.nickname}/following")
354 |> json_response(200)
355
356 assert length(result["first"]["orderedItems"]) == 10
357 assert result["first"]["totalItems"] == 15
358 assert result["totalItems"] == 15
359
360 result =
361 conn
362 |> get("/users/#{user.nickname}/following?page=2")
363 |> json_response(200)
364
365 assert length(result["orderedItems"]) == 5
366 assert result["totalItems"] == 15
367 end
368 end
369 end