logo

pleroma

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

report_controller_test.exs (16424B)


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