From f171095960d172d54015b28e8da302b5745dca86 Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Wed, 6 Nov 2019 21:25:46 +1000 Subject: [PATCH] Grouped reports with status data baked in --- lib/pleroma/web/activity_pub/utils.ex | 58 ++++----- .../web/admin_api/views/report_view.ex | 4 +- .../admin_api/admin_api_controller_test.exs | 121 ++++++++++++++---- 3 files changed, 123 insertions(+), 60 deletions(-) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 57349e304..5a51b7884 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -6,7 +6,6 @@ defmodule Pleroma.Web.ActivityPub.Utils do alias Ecto.Changeset alias Ecto.UUID alias Pleroma.Activity - alias Pleroma.Activity.Queries alias Pleroma.Notification alias Pleroma.Object alias Pleroma.Repo @@ -697,8 +696,8 @@ def get_reports(params, page, page_size) do required(:groups) => [ %{ required(:date) => String.t(), - required(:account) => %User{}, - required(:status) => %Activity{}, + required(:account) => %{}, + required(:status) => %{}, required(:actors) => [%User{}], required(:reports) => [%Activity{}] } @@ -706,32 +705,23 @@ def get_reports(params, page, page_size) do required(:total) => integer } def get_reports_grouped_by_status do - paginated_activities = get_reported_status_ids() - groups = - paginated_activities + get_reported_status_ids() |> Enum.map(fn entry -> - status = - Activity - |> Queries.by_ap_id(entry[:activity_id]) - |> Activity.with_preloaded_object(:left) - |> Activity.with_preloaded_user_actor() - |> Repo.one() - - reports = get_reports_by_status_id(status.data["id"]) - - max_date = - Enum.max_by(reports, &Pleroma.Web.CommonAPI.Utils.to_masto_date(&1.data["published"])).data[ - "published" - ] - + activity = Jason.decode!(entry.activity) + reports = get_reports_by_status_id(activity["id"]) + max_date = Enum.max_by(reports, &NaiveDateTime.from_iso8601!(&1.data["published"])) actors = Enum.map(reports, & &1.user_actor) %{ - date: max_date, - account: status.user_actor, - status: status, - actors: actors, + date: max_date.data["published"], + account: activity["actor"], + status: %{ + id: activity["id"], + content: activity["content"], + published: activity["published"] + }, + actors: Enum.uniq(actors), reports: reports } end) @@ -741,28 +731,30 @@ def get_reports_grouped_by_status do } end - def get_reports_by_status_id(status_id) do + def get_reports_by_status_id(ap_id) do from(a in Activity, where: fragment("(?)->>'type' = 'Flag'", a.data), - where: fragment("(?)->'object' \\? (?)", a.data, ^status_id) + where: fragment("(?)->'object' @> ?", a.data, ^[%{id: ap_id}]) ) |> Activity.with_preloaded_user_actor() |> Repo.all() end - @spec get_reported_status_ids() :: %{ - required(:items) => [%Activity{}], - required(:total) => integer - } + @spec get_reported_status_ids() :: [ + %{ + required(:activity) => String.t(), + required(:date) => String.t() + } + ] def get_reported_status_ids do from(a in Activity, where: fragment("(?)->>'type' = 'Flag'", a.data), select: %{ date: fragment("max(?->>'published') date", a.data), - activity_id: - fragment("jsonb_array_elements_text((? #- '{object,0}')->'object') activity_id", a.data) + activity: + fragment("jsonb_array_elements_text((? #- '{object,0}')->'object') activity", a.data) }, - group_by: fragment("activity_id"), + group_by: fragment("activity"), order_by: fragment("date DESC") ) |> Repo.all() diff --git a/lib/pleroma/web/admin_api/views/report_view.ex b/lib/pleroma/web/admin_api/views/report_view.ex index ac25925da..ca88595c7 100644 --- a/lib/pleroma/web/admin_api/views/report_view.ex +++ b/lib/pleroma/web/admin_api/views/report_view.ex @@ -47,8 +47,8 @@ def render("index_grouped.json", %{groups: groups}) do Enum.map(groups, fn group -> %{ date: group[:date], - account: merge_account_views(group[:account]), - status: StatusView.render("show.json", %{activity: group[:status]}), + account: group[:account], + status: group[:status], actors: Enum.map(group[:actors], &merge_account_views/1), reports: group[:reports] diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index 35367bed3..4e28c7774 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -1551,7 +1551,7 @@ test "returns 403 when requested by anonymous" do describe "GET /api/pleroma/admin/grouped_reports" do setup %{conn: conn} do - admin = insert(:user, info: %{is_admin: true}) + admin = insert(:user, is_admin: true) [reporter, target_user] = insert_pair(:user) date1 = (DateTime.to_unix(DateTime.utc_now()) + 1000) |> DateTime.from_unix!() @@ -1567,53 +1567,124 @@ test "returns 403 when requested by anonymous" do third_status = insert(:note_activity, user: target_user, data_attrs: %{"published" => date3}) - %{ - conn: assign(conn, :user, admin), - reporter: reporter, - target_user: target_user, - first_status: first_status, - second_status: second_status, - third_status: third_status - } - end - - test "returns reports grouped by status", %{ - conn: conn, - reporter: reporter, - target_user: target_user, - first_status: first_status, - second_status: second_status, - third_status: third_status - } do - {:ok, %{id: _}} = + {:ok, first_report} = CommonAPI.report(reporter, %{ "account_id" => target_user.id, "status_ids" => [first_status.id, second_status.id, third_status.id] }) - {:ok, %{id: _}} = + {:ok, second_report} = CommonAPI.report(reporter, %{ "account_id" => target_user.id, "status_ids" => [first_status.id, second_status.id] }) - {:ok, %{id: _}} = + {:ok, third_report} = CommonAPI.report(reporter, %{ "account_id" => target_user.id, "status_ids" => [first_status.id] }) + %{ + conn: assign(conn, :user, admin), + first_status: Activity.get_by_ap_id_with_object(first_status.data["id"]), + second_status: Activity.get_by_ap_id_with_object(second_status.data["id"]), + third_status: Activity.get_by_ap_id_with_object(third_status.data["id"]), + first_status_reports: [first_report, second_report, third_report], + second_status_reports: [first_report, second_report], + third_status_reports: [first_report], + target_user: target_user, + reporter: reporter + } + end + + test "returns reports grouped by status", %{ + conn: conn, + first_status: first_status, + second_status: second_status, + third_status: third_status, + first_status_reports: first_status_reports, + second_status_reports: second_status_reports, + third_status_reports: third_status_reports, + target_user: target_user, + reporter: reporter + } do response = conn |> get("/api/pleroma/admin/grouped_reports") |> json_response(:ok) assert length(response["reports"]) == 3 - [third_group, second_group, first_group] = response["reports"] - assert length(third_group["reports"]) == 3 + first_group = + Enum.find(response["reports"], &(&1["status"]["id"] == first_status.data["id"])) + + second_group = + Enum.find(response["reports"], &(&1["status"]["id"] == second_status.data["id"])) + + third_group = + Enum.find(response["reports"], &(&1["status"]["id"] == third_status.data["id"])) + + assert length(first_group["reports"]) == 3 assert length(second_group["reports"]) == 2 - assert length(first_group["reports"]) == 1 + assert length(third_group["reports"]) == 1 + + assert first_group["date"] == + Enum.max_by(first_status_reports, fn act -> + NaiveDateTime.from_iso8601!(act.data["published"]) + end).data["published"] + + assert first_group["status"] == %{ + "id" => first_status.data["id"], + "content" => first_status.object.data["content"], + "published" => first_status.object.data["published"] + } + + assert first_group["account"]["id"] == target_user.id + + assert length(first_group["actors"]) == 1 + assert hd(first_group["actors"])["id"] == reporter.id + + assert Enum.map(first_group["reports"], & &1["id"]) -- + Enum.map(first_status_reports, & &1.id) == [] + + assert second_group["date"] == + Enum.max_by(second_status_reports, fn act -> + NaiveDateTime.from_iso8601!(act.data["published"]) + end).data["published"] + + assert second_group["status"] == %{ + "id" => second_status.data["id"], + "content" => second_status.object.data["content"], + "published" => second_status.object.data["published"] + } + + assert second_group["account"]["id"] == target_user.id + + assert length(second_group["actors"]) == 1 + assert hd(second_group["actors"])["id"] == reporter.id + + assert Enum.map(second_group["reports"], & &1["id"]) -- + Enum.map(second_status_reports, & &1.id) == [] + + assert third_group["date"] == + Enum.max_by(third_status_reports, fn act -> + NaiveDateTime.from_iso8601!(act.data["published"]) + end).data["published"] + + assert third_group["status"] == %{ + "id" => third_status.data["id"], + "content" => third_status.object.data["content"], + "published" => third_status.object.data["published"] + } + + assert third_group["account"]["id"] == target_user.id + + assert length(third_group["actors"]) == 1 + assert hd(third_group["actors"])["id"] == reporter.id + + assert Enum.map(third_group["reports"], & &1["id"]) -- + Enum.map(third_status_reports, & &1.id) == [] end end