From e2bf6b1f7ee6115a7eafa78272bdbafe7f4789c5 Mon Sep 17 00:00:00 2001
From: Alexander Strizhakov <alex.strizhakov@gmail.com>
Date: Mon, 16 Nov 2020 19:22:32 +0300
Subject: [PATCH 1/7] fix for forwarded reports

---
 lib/pleroma/emails/admin_email.ex             |  3 +
 lib/pleroma/web/activity_pub/activity_pub.ex  | 35 +++++----
 .../activity_pub_controller_test.exs          | 76 +++++++++++++++++++
 .../web/activity_pub/activity_pub_test.exs    | 25 ++++++
 test/support/factory.ex                       | 32 ++++++--
 5 files changed, 150 insertions(+), 21 deletions(-)

diff --git a/lib/pleroma/emails/admin_email.ex b/lib/pleroma/emails/admin_email.ex
index 02274554f..d5757c12a 100644
--- a/lib/pleroma/emails/admin_email.ex
+++ b/lib/pleroma/emails/admin_email.ex
@@ -48,6 +48,9 @@ def report(to, reporter, account, statuses, comment) do
               status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, id)
               "<li><a href=\"#{status_url}\">#{status_url}</li>"
 
+            %{"id" => id} when is_binary(id) ->
+              "<li><a href=\"#{id}\">#{id}</li>"
+
             id when is_binary(id) ->
               "<li><a href=\"#{id}\">#{id}</li>"
           end)
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 35f71b7ae..8f3ce1343 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -332,15 +332,21 @@ defp do_unfollow(follower, followed, activity_id, local) do
   end
 
   @spec flag(map()) :: {:ok, Activity.t()} | {:error, any()}
-  def flag(
-        %{
-          actor: actor,
-          context: _context,
-          account: account,
-          statuses: statuses,
-          content: content
-        } = params
-      ) do
+  def flag(params) do
+    with {:ok, result} <- Repo.transaction(fn -> do_flag(params) end) do
+      result
+    end
+  end
+
+  defp do_flag(
+         %{
+           actor: actor,
+           context: _context,
+           account: account,
+           statuses: statuses,
+           content: content
+         } = params
+       ) do
     # only accept false as false value
     local = !(params[:local] == false)
     forward = !(params[:forward] == false)
@@ -358,7 +364,8 @@ def flag(
          {:ok, activity} <- insert(flag_data, local),
          {:ok, stripped_activity} <- strip_report_status_data(activity),
          _ <- notify_and_stream(activity),
-         :ok <- maybe_federate(stripped_activity) do
+         :ok <-
+           maybe_federate(stripped_activity) do
       User.all_superusers()
       |> Enum.filter(fn user -> not is_nil(user.email) end)
       |> Enum.each(fn superuser ->
@@ -368,6 +375,8 @@ def flag(
       end)
 
       {:ok, activity}
+    else
+      {:error, error} -> Repo.rollback(error)
     end
   end
 
@@ -791,10 +800,10 @@ defp restrict_replies(query, %{
       where:
         fragment(
           """
-          ?->>'type' != 'Create'     -- This isn't a Create      
+          ?->>'type' != 'Create'     -- This isn't a Create
           OR ?->>'inReplyTo' is null -- this isn't a reply
-          OR ? && array_remove(?, ?) -- The recipient is us or one of our friends, 
-                                     -- unless they are the author (because authors 
+          OR ? && array_remove(?, ?) -- The recipient is us or one of our friends,
+                                     -- unless they are the author (because authors
                                      -- are also part of the recipients). This leads
                                      -- to a bug that self-replies by friends won't
                                      -- show up.
diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
index 31e48f87f..49eeaeaff 100644
--- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
@@ -799,6 +799,82 @@ test "it requires authentication", %{conn: conn} do
 
       assert json_response(ret_conn, 200)
     end
+
+    test "forwarded report", %{conn: conn} do
+      admin = insert(:user, is_admin: true)
+      actor = insert(:user, local: false)
+      remote_domain = URI.parse(actor.ap_id).host
+      reported_user = insert(:user)
+
+      note = insert(:note_activity, user: reported_user)
+
+      data = %{
+        "@context" => [
+          "https://www.w3.org/ns/activitystreams",
+          "https://#{remote_domain}/schemas/litepub-0.1.jsonld",
+          %{
+            "@language" => "und"
+          }
+        ],
+        "actor" => actor.ap_id,
+        "cc" => [
+          reported_user.ap_id
+        ],
+        "content" => "test",
+        "context" => "context",
+        "id" => "http://#{remote_domain}/activities/02be56cf-35e3-46b4-b2c6-47ae08dfee9e",
+        "nickname" => reported_user.nickname,
+        "object" => [
+          reported_user.ap_id,
+          %{
+            "actor" => %{
+              "actor_type" => "Person",
+              "approval_pending" => false,
+              "avatar" => "",
+              "confirmation_pending" => false,
+              "deactivated" => false,
+              "display_name" => "test user",
+              "id" => reported_user.id,
+              "local" => false,
+              "nickname" => reported_user.nickname,
+              "registration_reason" => nil,
+              "roles" => %{
+                "admin" => false,
+                "moderator" => false
+              },
+              "tags" => [],
+              "url" => reported_user.ap_id
+            },
+            "content" => "",
+            "id" => note.data["id"],
+            "published" => note.data["published"],
+            "type" => "Note"
+          }
+        ],
+        "published" => note.data["published"],
+        "state" => "open",
+        "to" => [],
+        "type" => "Flag"
+      }
+
+      conn
+      |> assign(:valid_signature, true)
+      |> put_req_header("content-type", "application/activity+json")
+      |> post("/users/#{reported_user.nickname}/inbox", data)
+      |> json_response(200)
+
+      ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
+
+      assert Pleroma.Repo.aggregate(Activity, :count, :id) == 2
+
+      ObanHelpers.perform_all()
+
+      Swoosh.TestAssertions.assert_email_sent(
+        to: {admin.name, admin.email},
+        html_body: ~r/Reported Account:/i
+      )
+
+    end
   end
 
   describe "GET /users/:nickname/outbox" do
diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs
index 3eeb0f735..6cc25dd9e 100644
--- a/test/pleroma/web/activity_pub/activity_pub_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_test.exs
@@ -1298,6 +1298,31 @@ test "it can create a Flag activity",
 
       assert_called(Utils.maybe_federate(%{activity | data: new_data}))
     end
+
+    test_with_mock "reverts on error",
+                   %{
+                     reporter: reporter,
+                     context: context,
+                     target_account: target_account,
+                     reported_activity: reported_activity,
+                     content: content
+                   },
+                   Utils,
+                   [:passthrough],
+                   maybe_federate: fn _ -> {:error, :reverted} end do
+      assert {:error, :reverted} =
+               ActivityPub.flag(%{
+                 actor: reporter,
+                 context: context,
+                 account: target_account,
+                 statuses: [reported_activity],
+                 content: content
+               })
+
+      assert Repo.aggregate(Activity, :count, :id) == 1
+      assert Repo.aggregate(Object, :count, :id) == 2
+      assert Repo.aggregate(Notification, :count, :id) == 0
+    end
   end
 
   test "fetch_activities/2 returns activities addressed to a list " do
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 80b882ee4..8eb07dc3c 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -24,7 +24,7 @@ def conversation_factory do
     }
   end
 
-  def user_factory do
+  def user_factory(attrs \\ %{}) do
     user = %User{
       name: sequence(:name, &"Test ใƒ†ใ‚นใƒˆ User #{&1}"),
       email: sequence(:email, &"user#{&1}@example.com"),
@@ -39,13 +39,29 @@ def user_factory do
       ap_enabled: true
     }
 
-    %{
-      user
-      | ap_id: User.ap_id(user),
-        follower_address: User.ap_followers(user),
-        following_address: User.ap_following(user),
-        raw_bio: user.bio
-    }
+    urls =
+      if attrs[:local] == false do
+        base_domain = Enum.random(["domain1.com", "domain2.com", "domain3.com"])
+
+        ap_id = "https://#{base_domain}/users/#{user.nickname}"
+
+        %{
+          ap_id: ap_id,
+          follower_address: ap_id <> "/followers",
+          following_address: ap_id <> "/following"
+        }
+      else
+        %{
+          ap_id: User.ap_id(user),
+          follower_address: User.ap_followers(user),
+          following_address: User.ap_following(user)
+        }
+      end
+
+    user
+    |> Map.put(:raw_bio, user.bio)
+    |> Map.merge(urls)
+    |> merge_attributes(attrs)
   end
 
   def user_relationship_factory(attrs \\ %{}) do

From a840aefda85c5c32b6904a828f06c84bf4d2a685 Mon Sep 17 00:00:00 2001
From: Alexander Strizhakov <alex.strizhakov@gmail.com>
Date: Mon, 16 Nov 2020 19:41:03 +0300
Subject: [PATCH 2/7] formatting

---
 test/pleroma/web/activity_pub/activity_pub_controller_test.exs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
index 49eeaeaff..f05f7a487 100644
--- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
@@ -873,7 +873,6 @@ test "forwarded report", %{conn: conn} do
         to: {admin.name, admin.email},
         html_body: ~r/Reported Account:/i
       )
-
     end
   end
 

From be0b874e1da0178115e27778a55f52d7d28a727a Mon Sep 17 00:00:00 2001
From: Alexander Strizhakov <alex.strizhakov@gmail.com>
Date: Tue, 17 Nov 2020 19:57:57 +0300
Subject: [PATCH 3/7] fix for mastodon forwarded reports

---
 lib/pleroma/activity.ex                       | 10 +++
 lib/pleroma/web/activity_pub/utils.ex         | 38 ++++++-----
 test/fixtures/mastodon/application_actor.json | 67 +++++++++++++++++++
 .../activity_pub_controller_test.exs          | 59 ++++++++++++++++
 4 files changed, 159 insertions(+), 15 deletions(-)
 create mode 100644 test/fixtures/mastodon/application_actor.json

diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex
index 553834da0..bda5aa616 100644
--- a/lib/pleroma/activity.ex
+++ b/lib/pleroma/activity.ex
@@ -356,4 +356,14 @@ def pinned_by_actor?(%Activity{} = activity) do
     actor = user_actor(activity)
     activity.id in actor.pinned_activities
   end
+
+  @spec get_by_object_ap_id_with_object(String.t()) :: t() | nil
+  def get_by_object_ap_id_with_object(ap_id) when is_binary(ap_id) do
+    ap_id
+    |> Queries.by_object_id()
+    |> with_preloaded_object()
+    |> Repo.one()
+  end
+
+  def get_by_object_ap_id_with_object(_), do: nil
 end
diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index 46002bec2..f93909a50 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -710,6 +710,22 @@ defp build_flag_object(%{statuses: statuses}) do
     Enum.map(statuses || [], &build_flag_object/1)
   end
 
+  defp build_flag_object(%Activity{} = activity) do
+    activity_actor = User.get_by_ap_id(activity.object.data["actor"])
+
+    %{
+      "type" => "Note",
+      "id" => activity.data["id"],
+      "content" => activity.object.data["content"],
+      "published" => activity.object.data["published"],
+      "actor" =>
+        AccountView.render(
+          "show.json",
+          %{user: activity_actor, skip_visibility_check: true}
+        )
+    }
+  end
+
   defp build_flag_object(act) when is_map(act) or is_binary(act) do
     id =
       case act do
@@ -720,22 +736,14 @@ defp build_flag_object(act) when is_map(act) or is_binary(act) do
 
     case Activity.get_by_ap_id_with_object(id) do
       %Activity{} = activity ->
-        activity_actor = User.get_by_ap_id(activity.object.data["actor"])
+        build_flag_object(activity)
 
-        %{
-          "type" => "Note",
-          "id" => activity.data["id"],
-          "content" => activity.object.data["content"],
-          "published" => activity.object.data["published"],
-          "actor" =>
-            AccountView.render(
-              "show.json",
-              %{user: activity_actor, skip_visibility_check: true}
-            )
-        }
-
-      _ ->
-        %{"id" => id, "deleted" => true}
+      nil ->
+        if activity = Activity.get_by_object_ap_id_with_object(id) do
+          build_flag_object(activity)
+        else
+          %{"id" => id, "deleted" => true}
+        end
     end
   end
 
diff --git a/test/fixtures/mastodon/application_actor.json b/test/fixtures/mastodon/application_actor.json
new file mode 100644
index 000000000..2089ea049
--- /dev/null
+++ b/test/fixtures/mastodon/application_actor.json
@@ -0,0 +1,67 @@
+{
+  "@context": [
+    "https://www.w3.org/ns/activitystreams",
+    "https://w3id.org/security/v1",
+    {
+      "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
+      "toot": "http://joinmastodon.org/ns#",
+      "featured": {
+        "@id": "toot:featured",
+        "@type": "@id"
+      },
+      "alsoKnownAs": {
+        "@id": "as:alsoKnownAs",
+        "@type": "@id"
+      },
+      "movedTo": {
+        "@id": "as:movedTo",
+        "@type": "@id"
+      },
+      "schema": "http://schema.org#",
+      "PropertyValue": "schema:PropertyValue",
+      "value": "schema:value",
+      "IdentityProof": "toot:IdentityProof",
+      "discoverable": "toot:discoverable",
+      "Device": "toot:Device",
+      "Ed25519Signature": "toot:Ed25519Signature",
+      "Ed25519Key": "toot:Ed25519Key",
+      "Curve25519Key": "toot:Curve25519Key",
+      "EncryptedMessage": "toot:EncryptedMessage",
+      "publicKeyBase64": "toot:publicKeyBase64",
+      "deviceId": "toot:deviceId",
+      "claim": {
+        "@type": "@id",
+        "@id": "toot:claim"
+      },
+      "fingerprintKey": {
+        "@type": "@id",
+        "@id": "toot:fingerprintKey"
+      },
+      "identityKey": {
+        "@type": "@id",
+        "@id": "toot:identityKey"
+      },
+      "devices": {
+        "@type": "@id",
+        "@id": "toot:devices"
+      },
+      "messageFranking": "toot:messageFranking",
+      "messageType": "toot:messageType",
+      "cipherText": "toot:cipherText"
+    }
+  ],
+  "id": "https://{{DOMAIN}}/actor",
+  "type": "Application",
+  "inbox": "https://{{DOMAIN}}/actor/inbox",
+  "preferredUsername": "{{DOMAIN}}",
+  "url": "https://{{DOMAIN}}/about/more?instance_actor=true",
+  "manuallyApprovesFollowers": true,
+  "publicKey": {
+    "id": "https://{{DOMAIN}}/actor#main-key",
+    "owner": "https://{{DOMAIN}}/actor",
+    "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAA0CA08AMIIBCgKCAQEAyi2T2FFZJgRPY+96YQrn\n6J6eF2P60J+nz+/pRc/acv/Nx+NLxxPyXby0F2s60MV7uALRQbBBnf7oNKCd/T4S\nvbr7UXMCWTdaJBpYubMKWT9uBlaUUkUfqL+WTV+IQnlcKtssQ4+AwrAKAZXza8ws\nZypevOsLHzayyEzztmm1KQC9GCUOITCLf7Q6qEhy8z/HuqLBEC0Own0pD7QsbfcS\no1peuZY7g1E/jJ9HR9GqJccMaR0H28KmJ7tT1Yzlyf5uZMRIdPxsoMR9sGLjR2B8\noegSwaf9SogR3ScP395Tt/9Ud1VVzuhpoS8Uy7jKSs+3CuLJsEGoMrib8VyOwadS\n9wIDAQAB\n-----END PUBLIC KEY-----\n"
+  },
+  "endpoints": {
+    "sharedInbox": "https://{{DOMAIN}}/inbox"
+  }
+}
diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
index f05f7a487..c3d4fcca7 100644
--- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
@@ -874,6 +874,65 @@ test "forwarded report", %{conn: conn} do
         html_body: ~r/Reported Account:/i
       )
     end
+
+    test "forwarded report from mastodon", %{conn: conn} do
+      admin = insert(:user, is_admin: true)
+      actor = insert(:user, local: false)
+      remote_domain = URI.parse(actor.ap_id).host
+      remote_actor = "https://#{remote_domain}/actor"
+      reported_user = insert(:user)
+
+      note = insert(:note_activity, user: reported_user)
+
+      mock_json_body =
+        "test/fixtures/mastodon/application_actor.json"
+        |> File.read!()
+        |> String.replace("{{DOMAIN}}", remote_domain)
+
+      Tesla.Mock.mock(fn %{url: ^remote_actor} ->
+        %Tesla.Env{
+          status: 200,
+          body: mock_json_body,
+          headers: [{"content-type", "application/activity+json"}]
+        }
+      end)
+
+      data = %{
+        "@context" => "https://www.w3.org/ns/activitystreams",
+        "actor" => remote_actor,
+        "content" => "test report",
+        "id" => "https://#{remote_domain}/e3b12fd1-948c-446e-b93b-a5e67edbe1d8",
+        "nickname" => reported_user.nickname,
+        "object" => [
+          reported_user.ap_id,
+          note.data["object"]
+        ],
+        "type" => "Flag"
+      }
+
+      conn
+      |> assign(:valid_signature, true)
+      |> put_req_header("content-type", "application/activity+json")
+      |> post("/users/#{reported_user.nickname}/inbox", data)
+      |> json_response(200)
+
+      ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
+
+      assert Pleroma.Repo.aggregate(Activity, :count, :id) == 2
+
+      flag_activity = "Flag" |> Pleroma.Activity.Queries.by_type() |> Pleroma.Repo.one()
+      reported_user_ap_id = reported_user.ap_id
+
+      [^reported_user_ap_id, flag_data] = flag_activity.data["object"]
+
+      Enum.each(~w(actor content id published type), &Map.has_key?(flag_data, &1))
+      ObanHelpers.perform_all()
+
+      Swoosh.TestAssertions.assert_email_sent(
+        to: {admin.name, admin.email},
+        html_body: ~r/#{note.data["object"]}/i
+      )
+    end
   end
 
   describe "GET /users/:nickname/outbox" do

From 44f3795b8ede118bfce4989ce96df6dd83636ec4 Mon Sep 17 00:00:00 2001
From: Alexander Strizhakov <alex.strizhakov@gmail.com>
Date: Tue, 17 Nov 2020 20:03:28 +0300
Subject: [PATCH 4/7] changelog entries for fixes

---
 CHANGELOG.md | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index cd90562c2..5e09df22c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -45,13 +45,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
 ### Changed
 
-- Fix ability to update Pleroma Chat push notifications with PUT /api/v1/push/subscription and alert type pleroma:chat_mention
-
 ### Fixed
 
 - Config generation: rename `Pleroma.Upload.Filter.ExifTool` to `Pleroma.Upload.Filter.Exiftool`.
 - S3 Uploads with Elixir 1.11.
 - Mix task pleroma.user delete_activities for source installations.
+- Fix ability to update Pleroma Chat push notifications with PUT /api/v1/push/subscription and alert type pleroma:chat_mention
+- Forwarded reports duplication from Pleroma instances.
+
+<details>
+  <summary>API</summary>
+- Statuses were not displayed for Mastodon forwarded reports.
+
+</details>
 
 ## [2.2.0] - 2020-11-12
 

From 8a8c154b4eb5a271c9904a9bb21f4c5f2d985fe4 Mon Sep 17 00:00:00 2001
From: Alexander Strizhakov <alex.strizhakov@gmail.com>
Date: Wed, 18 Nov 2020 10:03:48 +0300
Subject: [PATCH 5/7] test fixes

---
 lib/pleroma/web/activity_pub/utils.ex | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index f93909a50..ea1c3a04a 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -702,22 +702,22 @@ def make_flag_data(%{actor: actor, context: context, content: content} = params,
 
   def make_flag_data(_, _), do: %{}
 
-  defp build_flag_object(%{account: account, statuses: statuses} = _) do
-    [account.ap_id] ++ build_flag_object(%{statuses: statuses})
+  defp build_flag_object(%{account: account, statuses: statuses}) do
+    [account.ap_id | build_flag_object(%{statuses: statuses})]
   end
 
   defp build_flag_object(%{statuses: statuses}) do
     Enum.map(statuses || [], &build_flag_object/1)
   end
 
-  defp build_flag_object(%Activity{} = activity) do
-    activity_actor = User.get_by_ap_id(activity.object.data["actor"])
+  defp build_flag_object(%Activity{data: %{"id" => id}, object: %{data: data}}) do
+    activity_actor = User.get_by_ap_id(data["actor"])
 
     %{
       "type" => "Note",
-      "id" => activity.data["id"],
-      "content" => activity.object.data["content"],
-      "published" => activity.object.data["published"],
+      "id" => id,
+      "content" => data["content"],
+      "published" => data["published"],
       "actor" =>
         AccountView.render(
           "show.json",

From 4aaffe3a10e9aaba4a649ac108221a82e7038387 Mon Sep 17 00:00:00 2001
From: Alexander Strizhakov <alex.strizhakov@gmail.com>
Date: Wed, 18 Nov 2020 16:36:24 +0300
Subject: [PATCH 6/7] log capture

---
 test/pleroma/web/activity_pub/activity_pub_controller_test.exs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
index c3d4fcca7..6a1044991 100644
--- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
@@ -800,6 +800,7 @@ test "it requires authentication", %{conn: conn} do
       assert json_response(ret_conn, 200)
     end
 
+    @tag capture_log: true
     test "forwarded report", %{conn: conn} do
       admin = insert(:user, is_admin: true)
       actor = insert(:user, local: false)
@@ -875,6 +876,7 @@ test "forwarded report", %{conn: conn} do
       )
     end
 
+    @tag capture_log: true
     test "forwarded report from mastodon", %{conn: conn} do
       admin = insert(:user, is_admin: true)
       actor = insert(:user, local: false)

From 46dab37351994567ddb3a8a6fe654355175fe654 Mon Sep 17 00:00:00 2001
From: Alexander Strizhakov <alex.strizhakov@gmail.com>
Date: Thu, 19 Nov 2020 15:29:26 +0300
Subject: [PATCH 7/7] little fix

---
 lib/pleroma/activity.ex                          |  1 +
 test/pleroma/activity_test.exs                   | 16 ++++++++++++++++
 .../activity_pub_controller_test.exs             |  6 +++---
 3 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex
index bda5aa616..8559ae6a9 100644
--- a/lib/pleroma/activity.ex
+++ b/lib/pleroma/activity.ex
@@ -362,6 +362,7 @@ def get_by_object_ap_id_with_object(ap_id) when is_binary(ap_id) do
     ap_id
     |> Queries.by_object_id()
     |> with_preloaded_object()
+    |> first()
     |> Repo.one()
   end
 
diff --git a/test/pleroma/activity_test.exs b/test/pleroma/activity_test.exs
index ee6a99cc3..3e9fe209e 100644
--- a/test/pleroma/activity_test.exs
+++ b/test/pleroma/activity_test.exs
@@ -231,4 +231,20 @@ test "all_by_actor_and_id/2" do
 
     assert [%Activity{id: ^id1}, %Activity{id: ^id2}] = activities
   end
+
+  test "get_by_object_ap_id_with_object/1" do
+    user = insert(:user)
+    another = insert(:user)
+
+    {:ok, %{id: id, object: %{data: %{"id" => obj_id}}}} =
+      Pleroma.Web.CommonAPI.post(user, %{status: "cofe"})
+
+    Pleroma.Web.CommonAPI.favorite(another, id)
+
+    assert obj_id
+           |> Pleroma.Activity.Queries.by_object_id()
+           |> Repo.aggregate(:count, :id) == 2
+
+    assert %{id: ^id} = Activity.get_by_object_ap_id_with_object(obj_id)
+  end
 end
diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
index 6a1044991..b577e25dd 100644
--- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
@@ -882,10 +882,12 @@ test "forwarded report from mastodon", %{conn: conn} do
       actor = insert(:user, local: false)
       remote_domain = URI.parse(actor.ap_id).host
       remote_actor = "https://#{remote_domain}/actor"
-      reported_user = insert(:user)
+      [reported_user, another] = insert_list(2, :user)
 
       note = insert(:note_activity, user: reported_user)
 
+      Pleroma.Web.CommonAPI.favorite(another, note.id)
+
       mock_json_body =
         "test/fixtures/mastodon/application_actor.json"
         |> File.read!()
@@ -920,8 +922,6 @@ test "forwarded report from mastodon", %{conn: conn} do
 
       ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
 
-      assert Pleroma.Repo.aggregate(Activity, :count, :id) == 2
-
       flag_activity = "Flag" |> Pleroma.Activity.Queries.by_type() |> Pleroma.Repo.one()
       reported_user_ap_id = reported_user.ap_id