logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://anongit.hacktivis.me/git/pleroma.git/

report_controller_test.exs (17186B)


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