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