Merge branch 'develop' into command-available-check
[akkoma] / test / web / admin_api / controllers / report_controller_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
6 use Pleroma.Web.ConnCase
7
8 import Pleroma.Factory
9
10 alias Pleroma.Activity
11 alias Pleroma.Config
12 alias Pleroma.ModerationLog
13 alias Pleroma.Repo
14 alias Pleroma.ReportNote
15 alias Pleroma.Web.CommonAPI
16
17 setup do
18 admin = insert(:user, is_admin: true)
19 token = insert(:oauth_admin_token, user: admin)
20
21 conn =
22 build_conn()
23 |> assign(:user, admin)
24 |> assign(:token, token)
25
26 {:ok, %{admin: admin, token: token, conn: conn}}
27 end
28
29 describe "GET /api/pleroma/admin/reports/:id" do
30 test "returns report by its id", %{conn: conn} do
31 [reporter, target_user] = insert_pair(:user)
32 activity = insert(:note_activity, user: target_user)
33
34 {:ok, %{id: report_id}} =
35 CommonAPI.report(reporter, %{
36 account_id: target_user.id,
37 comment: "I feel offended",
38 status_ids: [activity.id]
39 })
40
41 response =
42 conn
43 |> get("/api/pleroma/admin/reports/#{report_id}")
44 |> json_response_and_validate_schema(:ok)
45
46 assert response["id"] == report_id
47 end
48
49 test "returns 404 when report id is invalid", %{conn: conn} do
50 conn = get(conn, "/api/pleroma/admin/reports/test")
51
52 assert json_response_and_validate_schema(conn, :not_found) == %{"error" => "Not found"}
53 end
54 end
55
56 describe "PATCH /api/pleroma/admin/reports" do
57 setup do
58 [reporter, target_user] = insert_pair(:user)
59 activity = insert(:note_activity, user: target_user)
60
61 {:ok, %{id: report_id}} =
62 CommonAPI.report(reporter, %{
63 account_id: target_user.id,
64 comment: "I feel offended",
65 status_ids: [activity.id]
66 })
67
68 {:ok, %{id: second_report_id}} =
69 CommonAPI.report(reporter, %{
70 account_id: target_user.id,
71 comment: "I feel very offended",
72 status_ids: [activity.id]
73 })
74
75 %{
76 id: report_id,
77 second_report_id: second_report_id
78 }
79 end
80
81 test "requires admin:write:reports scope", %{conn: conn, id: id, admin: admin} do
82 read_token = insert(:oauth_token, user: admin, scopes: ["admin:read"])
83 write_token = insert(:oauth_token, user: admin, scopes: ["admin:write:reports"])
84
85 response =
86 conn
87 |> assign(:token, read_token)
88 |> put_req_header("content-type", "application/json")
89 |> patch("/api/pleroma/admin/reports", %{
90 "reports" => [%{"state" => "resolved", "id" => id}]
91 })
92 |> json_response_and_validate_schema(403)
93
94 assert response == %{
95 "error" => "Insufficient permissions: admin:write:reports."
96 }
97
98 conn
99 |> assign(:token, write_token)
100 |> put_req_header("content-type", "application/json")
101 |> patch("/api/pleroma/admin/reports", %{
102 "reports" => [%{"state" => "resolved", "id" => id}]
103 })
104 |> json_response_and_validate_schema(:no_content)
105 end
106
107 test "mark report as resolved", %{conn: conn, id: id, admin: admin} do
108 conn
109 |> put_req_header("content-type", "application/json")
110 |> patch("/api/pleroma/admin/reports", %{
111 "reports" => [
112 %{"state" => "resolved", "id" => id}
113 ]
114 })
115 |> json_response_and_validate_schema(:no_content)
116
117 activity = Activity.get_by_id(id)
118 assert activity.data["state"] == "resolved"
119
120 log_entry = Repo.one(ModerationLog)
121
122 assert ModerationLog.get_log_entry_message(log_entry) ==
123 "@#{admin.nickname} updated report ##{id} with 'resolved' state"
124 end
125
126 test "closes report", %{conn: conn, id: id, admin: admin} do
127 conn
128 |> put_req_header("content-type", "application/json")
129 |> patch("/api/pleroma/admin/reports", %{
130 "reports" => [
131 %{"state" => "closed", "id" => id}
132 ]
133 })
134 |> json_response_and_validate_schema(:no_content)
135
136 activity = Activity.get_by_id(id)
137 assert activity.data["state"] == "closed"
138
139 log_entry = Repo.one(ModerationLog)
140
141 assert ModerationLog.get_log_entry_message(log_entry) ==
142 "@#{admin.nickname} updated report ##{id} with 'closed' state"
143 end
144
145 test "returns 400 when state is unknown", %{conn: conn, id: id} do
146 conn =
147 conn
148 |> put_req_header("content-type", "application/json")
149 |> patch("/api/pleroma/admin/reports", %{
150 "reports" => [
151 %{"state" => "test", "id" => id}
152 ]
153 })
154
155 assert "Unsupported state" =
156 hd(json_response_and_validate_schema(conn, :bad_request))["error"]
157 end
158
159 test "returns 404 when report is not exist", %{conn: conn} do
160 conn =
161 conn
162 |> put_req_header("content-type", "application/json")
163 |> patch("/api/pleroma/admin/reports", %{
164 "reports" => [
165 %{"state" => "closed", "id" => "test"}
166 ]
167 })
168
169 assert hd(json_response_and_validate_schema(conn, :bad_request))["error"] == "not_found"
170 end
171
172 test "updates state of multiple reports", %{
173 conn: conn,
174 id: id,
175 admin: admin,
176 second_report_id: second_report_id
177 } do
178 conn
179 |> put_req_header("content-type", "application/json")
180 |> patch("/api/pleroma/admin/reports", %{
181 "reports" => [
182 %{"state" => "resolved", "id" => id},
183 %{"state" => "closed", "id" => second_report_id}
184 ]
185 })
186 |> json_response_and_validate_schema(:no_content)
187
188 activity = Activity.get_by_id(id)
189 second_activity = Activity.get_by_id(second_report_id)
190 assert activity.data["state"] == "resolved"
191 assert second_activity.data["state"] == "closed"
192
193 [first_log_entry, second_log_entry] = Repo.all(ModerationLog)
194
195 assert ModerationLog.get_log_entry_message(first_log_entry) ==
196 "@#{admin.nickname} updated report ##{id} with 'resolved' state"
197
198 assert ModerationLog.get_log_entry_message(second_log_entry) ==
199 "@#{admin.nickname} updated report ##{second_report_id} with 'closed' state"
200 end
201 end
202
203 describe "GET /api/pleroma/admin/reports" do
204 test "returns empty response when no reports created", %{conn: conn} do
205 response =
206 conn
207 |> get(report_path(conn, :index))
208 |> json_response_and_validate_schema(:ok)
209
210 assert Enum.empty?(response["reports"])
211 assert response["total"] == 0
212 end
213
214 test "returns reports", %{conn: conn} do
215 [reporter, target_user] = insert_pair(:user)
216 activity = insert(:note_activity, user: target_user)
217
218 {:ok, %{id: report_id}} =
219 CommonAPI.report(reporter, %{
220 account_id: target_user.id,
221 comment: "I feel offended",
222 status_ids: [activity.id]
223 })
224
225 response =
226 conn
227 |> get(report_path(conn, :index))
228 |> json_response_and_validate_schema(:ok)
229
230 [report] = response["reports"]
231
232 assert length(response["reports"]) == 1
233 assert report["id"] == report_id
234
235 assert response["total"] == 1
236 end
237
238 test "returns reports with specified state", %{conn: conn} do
239 [reporter, target_user] = insert_pair(:user)
240 activity = insert(:note_activity, user: target_user)
241
242 {:ok, %{id: first_report_id}} =
243 CommonAPI.report(reporter, %{
244 account_id: target_user.id,
245 comment: "I feel offended",
246 status_ids: [activity.id]
247 })
248
249 {:ok, %{id: second_report_id}} =
250 CommonAPI.report(reporter, %{
251 account_id: target_user.id,
252 comment: "I don't like this user"
253 })
254
255 CommonAPI.update_report_state(second_report_id, "closed")
256
257 response =
258 conn
259 |> get(report_path(conn, :index, %{state: "open"}))
260 |> json_response_and_validate_schema(:ok)
261
262 assert [open_report] = response["reports"]
263
264 assert length(response["reports"]) == 1
265 assert open_report["id"] == first_report_id
266
267 assert response["total"] == 1
268
269 response =
270 conn
271 |> get(report_path(conn, :index, %{state: "closed"}))
272 |> json_response_and_validate_schema(:ok)
273
274 assert [closed_report] = response["reports"]
275
276 assert length(response["reports"]) == 1
277 assert closed_report["id"] == second_report_id
278
279 assert response["total"] == 1
280
281 assert %{"total" => 0, "reports" => []} ==
282 conn
283 |> get(report_path(conn, :index, %{state: "resolved"}))
284 |> json_response_and_validate_schema(:ok)
285 end
286
287 test "returns 403 when requested by a non-admin" do
288 user = insert(:user)
289 token = insert(:oauth_token, user: user)
290
291 conn =
292 build_conn()
293 |> assign(:user, user)
294 |> assign(:token, token)
295 |> get("/api/pleroma/admin/reports")
296
297 assert json_response(conn, :forbidden) ==
298 %{"error" => "User is not an admin."}
299 end
300
301 test "returns 403 when requested by anonymous" do
302 conn = get(build_conn(), "/api/pleroma/admin/reports")
303
304 assert json_response(conn, :forbidden) == %{
305 "error" => "Invalid credentials."
306 }
307 end
308 end
309
310 describe "POST /api/pleroma/admin/reports/:id/notes" do
311 setup %{conn: conn, admin: admin} do
312 [reporter, target_user] = insert_pair(:user)
313 activity = insert(:note_activity, user: target_user)
314
315 {:ok, %{id: report_id}} =
316 CommonAPI.report(reporter, %{
317 account_id: target_user.id,
318 comment: "I feel offended",
319 status_ids: [activity.id]
320 })
321
322 conn
323 |> put_req_header("content-type", "application/json")
324 |> post("/api/pleroma/admin/reports/#{report_id}/notes", %{
325 content: "this is disgusting!"
326 })
327
328 conn
329 |> put_req_header("content-type", "application/json")
330 |> post("/api/pleroma/admin/reports/#{report_id}/notes", %{
331 content: "this is disgusting2!"
332 })
333
334 %{
335 admin_id: admin.id,
336 report_id: report_id
337 }
338 end
339
340 test "it creates report note", %{admin_id: admin_id, report_id: report_id} do
341 assert [note, _] = Repo.all(ReportNote)
342
343 assert %{
344 activity_id: ^report_id,
345 content: "this is disgusting!",
346 user_id: ^admin_id
347 } = note
348 end
349
350 test "it returns reports with notes", %{conn: conn, admin: admin} do
351 conn = get(conn, "/api/pleroma/admin/reports")
352
353 response = json_response_and_validate_schema(conn, 200)
354 notes = hd(response["reports"])["notes"]
355 [note, _] = notes
356
357 assert note["user"]["nickname"] == admin.nickname
358 assert note["content"] == "this is disgusting!"
359 assert note["created_at"]
360 assert response["total"] == 1
361 end
362
363 test "it deletes the note", %{conn: conn, report_id: report_id} do
364 assert ReportNote |> Repo.all() |> length() == 2
365 assert [note, _] = Repo.all(ReportNote)
366
367 delete(conn, "/api/pleroma/admin/reports/#{report_id}/notes/#{note.id}")
368
369 assert ReportNote |> Repo.all() |> length() == 1
370 end
371 end
372 end