AdminAPI: Grouped reports old/new fix
authorMaxim Filippov <colixer@gmail.com>
Fri, 22 Nov 2019 04:35:21 +0000 (13:35 +0900)
committerMaxim Filippov <colixer@gmail.com>
Mon, 25 Nov 2019 15:20:46 +0000 (00:20 +0900)
If some status received reports both in the "new" format and "old" format it was considered reports on two different statuses (in the context of grouped reports)

CHANGELOG.md
lib/pleroma/web/activity_pub/utils.ex
test/web/activity_pub/utils_test.exs

index 443e5f3c3b6e3aeab59efde60dc5c0a630dab72e..60512c6b11f5a4066c18c303d68a783bff923596 100644 (file)
@@ -80,6 +80,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
 - Mastodon API: Fix private and direct statuses not being filtered out from the public timeline for an authenticated user (`GET /api/v1/timelines/public`)
 - Mastodon API: Inability to get some local users by nickname in `/api/v1/accounts/:id_or_nickname`
+- AdminAPI: If some status received reports both in the "new" format and "old" format it was considered reports on two different statuses (in the context of grouped reports)
 </details>
 
 ## [1.1.6] - 2019-11-19
index 9e460b6049da4978d8f9dcc26711ae10299bc909..718e3328dfe22fb8ce315c36a93be4308b121ed4 100644 (file)
@@ -788,36 +788,6 @@ defmodule Pleroma.Web.ActivityPub.Utils do
     ActivityPub.fetch_activities([], params, :offset)
   end
 
-  @spec get_reports_grouped_by_status(%{required(:activity) => String.t()}) :: %{
-          required(:groups) => [
-            %{
-              required(:date) => String.t(),
-              required(:account) => %{},
-              required(:status) => %{},
-              required(:actors) => [%User{}],
-              required(:reports) => [%Activity{}]
-            }
-          ],
-          required(:total) => integer
-        }
-  def get_reports_grouped_by_status(groups) do
-    parsed_groups =
-      groups
-      |> Enum.map(fn entry ->
-        activity =
-          case Jason.decode(entry.activity) do
-            {:ok, activity} -> activity
-            _ -> build_flag_object(entry.activity)
-          end
-
-        parse_report_group(activity)
-      end)
-
-    %{
-      groups: parsed_groups
-    }
-  end
-
   def parse_report_group(activity) do
     reports = get_reports_by_status_id(activity["id"])
     max_date = Enum.max_by(reports, &NaiveDateTime.from_iso8601!(&1.data["published"]))
@@ -859,6 +829,32 @@ defmodule Pleroma.Web.ActivityPub.Utils do
     |> Repo.all()
   end
 
+  @spec get_reports_grouped_by_status(%{required(:activity) => String.t()}) :: %{
+          required(:groups) => [
+            %{
+              required(:date) => String.t(),
+              required(:account) => %{},
+              required(:status) => %{},
+              required(:actors) => [%User{}],
+              required(:reports) => [%Activity{}]
+            }
+          ],
+          required(:total) => integer
+        }
+  def get_reports_grouped_by_status(activity_ids) do
+    parsed_groups =
+      activity_ids
+      |> Enum.map(fn id ->
+        id
+        |> build_flag_object()
+        |> parse_report_group()
+      end)
+
+    %{
+      groups: parsed_groups
+    }
+  end
+
   @spec get_reported_activities() :: [
           %{
             required(:activity) => String.t(),
@@ -866,17 +862,23 @@ defmodule Pleroma.Web.ActivityPub.Utils do
           }
         ]
   def get_reported_activities do
-    from(a in Activity,
-      where: fragment("(?)->>'type' = 'Flag'", a.data),
+    reported_activities_query =
+      from(a in Activity,
+        where: fragment("(?)->>'type' = 'Flag'", a.data),
+        select: %{
+          activity: fragment("jsonb_array_elements((? #- '{object,0}')->'object')", a.data)
+        },
+        group_by: fragment("activity")
+      )
+
+    from(a in subquery(reported_activities_query),
+      distinct: true,
       select: %{
-        date: fragment("max(?->>'published') date", a.data),
-        activity:
-          fragment("jsonb_array_elements_text((? #- '{object,0}')->'object') activity", a.data)
-      },
-      group_by: fragment("activity"),
-      order_by: fragment("date DESC")
+        id: fragment("COALESCE(?->>'id'::text, ? #>> '{}')", a.activity, a.activity)
+      }
     )
     |> Repo.all()
+    |> Enum.map(& &1.id)
   end
 
   def update_report_state(%Activity{} = activity, state)
index 1feb076ba953d9693aa03f38ee5ae0cf13d667f1..586eb1d2f902bf11b83e9be7d2d2af942f68aa5d 100644 (file)
@@ -636,47 +636,4 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
       assert updated_object.data["announcement_count"] == 1
     end
   end
-
-  describe "get_reports_grouped_by_status/1" do
-    setup do
-      [reporter, target_user] = insert_pair(:user)
-      first_status = insert(:note_activity, user: target_user)
-      second_status = insert(:note_activity, user: target_user)
-
-      CommonAPI.report(reporter, %{
-        "account_id" => target_user.id,
-        "comment" => "I feel offended",
-        "status_ids" => [first_status.id]
-      })
-
-      CommonAPI.report(reporter, %{
-        "account_id" => target_user.id,
-        "comment" => "I feel offended2",
-        "status_ids" => [second_status.id]
-      })
-
-      data = [%{activity: first_status.data["id"]}, %{activity: second_status.data["id"]}]
-
-      {:ok,
-       %{
-         first_status: first_status,
-         second_status: second_status,
-         data: data
-       }}
-    end
-
-    test "works for deprecated reports format", %{
-      first_status: first_status,
-      second_status: second_status,
-      data: data
-    } do
-      groups = Utils.get_reports_grouped_by_status(data).groups
-
-      first_group = Enum.find(groups, &(&1.status.id == first_status.data["id"]))
-      second_group = Enum.find(groups, &(&1.status.id == second_status.data["id"]))
-
-      assert first_group.status.id == first_status.data["id"]
-      assert second_group.status.id == second_status.data["id"]
-    end
-  end
 end