Merge branch 'develop' into activation-meta
[akkoma] / test / web / activity_pub / utils_test.exs
index eb429b2c48530d9eb33a7be002e6646844e4ac0a..2f9ecb5a3220873fa0c8a4c9cdf43c4822cd195a 100644 (file)
@@ -1,5 +1,5 @@
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.Web.ActivityPub.UtilsTest do
@@ -10,6 +10,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
   alias Pleroma.User
   alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.ActivityPub.Utils
+  alias Pleroma.Web.AdminAPI.AccountView
   alias Pleroma.Web.CommonAPI
 
   import Pleroma.Factory
@@ -26,16 +27,6 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
     end
   end
 
-  describe "fetch the latest Block" do
-    test "fetches the latest Block activity" do
-      blocker = insert(:user)
-      blocked = insert(:user)
-      {:ok, activity} = ActivityPub.block(blocker, blocked)
-
-      assert activity == Utils.fetch_latest_block(blocker, blocked)
-    end
-  end
-
   describe "determine_explicit_mentions()" do
     test "works with an object that has mentions" do
       object = %{
@@ -87,31 +78,17 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
 
       assert Utils.determine_explicit_mentions(object) == []
     end
-  end
 
-  describe "make_unlike_data/3" do
-    test "returns data for unlike activity" do
-      user = insert(:user)
-      like_activity = insert(:like_activity, data_attrs: %{"context" => "test context"})
-
-      assert Utils.make_unlike_data(user, like_activity, nil) == %{
-               "type" => "Undo",
-               "actor" => user.ap_id,
-               "object" => like_activity.data,
-               "to" => [user.follower_address, like_activity.data["actor"]],
-               "cc" => [Pleroma.Constants.as_public()],
-               "context" => like_activity.data["context"]
-             }
-
-      assert Utils.make_unlike_data(user, like_activity, "9mJEZK0tky1w2xD2vY") == %{
-               "type" => "Undo",
-               "actor" => user.ap_id,
-               "object" => like_activity.data,
-               "to" => [user.follower_address, like_activity.data["actor"]],
-               "cc" => [Pleroma.Constants.as_public()],
-               "context" => like_activity.data["context"],
-               "id" => "9mJEZK0tky1w2xD2vY"
-             }
+    test "works with an object has tags as map" do
+      object = %{
+        "tag" => %{
+          "type" => "Mention",
+          "href" => "https://example.com/~alyssa",
+          "name" => "Alyssa P. Hacker"
+        }
+      }
+
+      assert Utils.determine_explicit_mentions(object) == ["https://example.com/~alyssa"]
     end
   end
 
@@ -133,7 +110,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
 
       {:ok, activity} =
         CommonAPI.post(user, %{
-          "status" =>
+          status:
             "hey @#{other_user.nickname}, @#{third_user.nickname} how about beering together this weekend?"
         })
 
@@ -152,8 +129,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
 
       {:ok, activity} =
         CommonAPI.post(user, %{
-          "status" => "@#{other_user.nickname} @#{third_user.nickname} bought a new swimsuit!",
-          "visibility" => "private"
+          status: "@#{other_user.nickname} @#{third_user.nickname} bought a new swimsuit!",
+          visibility: "private"
         })
 
       %{"to" => to, "cc" => cc} = Utils.make_like_data(other_user, activity, nil)
@@ -162,71 +139,6 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
     end
   end
 
-  describe "fetch_ordered_collection" do
-    import Tesla.Mock
-
-    test "fetches the first OrderedCollectionPage when an OrderedCollection is encountered" do
-      mock(fn
-        %{method: :get, url: "http://mastodon.com/outbox"} ->
-          json(%{"type" => "OrderedCollection", "first" => "http://mastodon.com/outbox?page=true"})
-
-        %{method: :get, url: "http://mastodon.com/outbox?page=true"} ->
-          json(%{"type" => "OrderedCollectionPage", "orderedItems" => ["ok"]})
-      end)
-
-      assert Utils.fetch_ordered_collection("http://mastodon.com/outbox", 1) == ["ok"]
-    end
-
-    test "fetches several pages in the right order one after another, but only the specified amount" do
-      mock(fn
-        %{method: :get, url: "http://example.com/outbox"} ->
-          json(%{
-            "type" => "OrderedCollectionPage",
-            "orderedItems" => [0],
-            "next" => "http://example.com/outbox?page=1"
-          })
-
-        %{method: :get, url: "http://example.com/outbox?page=1"} ->
-          json(%{
-            "type" => "OrderedCollectionPage",
-            "orderedItems" => [1],
-            "next" => "http://example.com/outbox?page=2"
-          })
-
-        %{method: :get, url: "http://example.com/outbox?page=2"} ->
-          json(%{"type" => "OrderedCollectionPage", "orderedItems" => [2]})
-      end)
-
-      assert Utils.fetch_ordered_collection("http://example.com/outbox", 0) == [0]
-      assert Utils.fetch_ordered_collection("http://example.com/outbox", 1) == [0, 1]
-    end
-
-    test "returns an error if the url doesn't have an OrderedCollection/Page" do
-      mock(fn
-        %{method: :get, url: "http://example.com/not-an-outbox"} ->
-          json(%{"type" => "NotAnOutbox"})
-      end)
-
-      assert {:error, _} = Utils.fetch_ordered_collection("http://example.com/not-an-outbox", 1)
-    end
-
-    test "returns the what was collected if there are less pages than specified" do
-      mock(fn
-        %{method: :get, url: "http://example.com/outbox"} ->
-          json(%{
-            "type" => "OrderedCollectionPage",
-            "orderedItems" => [0],
-            "next" => "http://example.com/outbox?page=1"
-          })
-
-        %{method: :get, url: "http://example.com/outbox?page=1"} ->
-          json(%{"type" => "OrderedCollectionPage", "orderedItems" => [1]})
-      end)
-
-      assert Utils.fetch_ordered_collection("http://example.com/outbox", 5) == [0, 1]
-    end
-  end
-
   test "make_json_ld_header/0" do
     assert Utils.make_json_ld_header() == %{
              "@context" => [
@@ -246,11 +158,11 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
 
       {:ok, activity} =
         CommonAPI.post(user, %{
-          "status" => "How do I pronounce LaTeX?",
-          "poll" => %{
-            "options" => ["laytekh", "lahtekh", "latex"],
-            "expires_in" => 20,
-            "multiple" => true
+          status: "How do I pronounce LaTeX?",
+          poll: %{
+            options: ["laytekh", "lahtekh", "latex"],
+            expires_in: 20,
+            multiple: true
           }
         })
 
@@ -265,17 +177,16 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
 
       {:ok, activity} =
         CommonAPI.post(user, %{
-          "status" => "Are we living in a society?",
-          "poll" => %{
-            "options" => ["yes", "no"],
-            "expires_in" => 20
+          status: "Are we living in a society?",
+          poll: %{
+            options: ["yes", "no"],
+            expires_in: 20
           }
         })
 
       object = Object.normalize(activity)
       {:ok, [vote], object} = CommonAPI.vote(other_user, object, [0])
-      vote_object = Object.normalize(vote)
-      {:ok, _activity, _object} = ActivityPub.like(user, vote_object)
+      {:ok, _activity} = CommonAPI.favorite(user, activity.id)
       [fetched_vote] = Utils.get_existing_votes(other_user.ap_id, object)
       assert fetched_vote.id == vote.id
     end
@@ -283,7 +194,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
 
   describe "update_follow_state_for_all/2" do
     test "updates the state of all Follow activities with the same actor and object" do
-      user = insert(:user, info: %{locked: true})
+      user = insert(:user, locked: true)
       follower = insert(:user)
 
       {:ok, follow_activity} = ActivityPub.follow(follower, user)
@@ -300,14 +211,14 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
       {:ok, follow_activity_two} =
         Utils.update_follow_state_for_all(follow_activity_two, "accept")
 
-      assert Repo.get(Activity, follow_activity.id).data["state"] == "accept"
-      assert Repo.get(Activity, follow_activity_two.id).data["state"] == "accept"
+      assert refresh_record(follow_activity).data["state"] == "accept"
+      assert refresh_record(follow_activity_two).data["state"] == "accept"
     end
   end
 
   describe "update_follow_state/2" do
     test "updates the state of the given follow activity" do
-      user = insert(:user, info: %{locked: true})
+      user = insert(:user, locked: true)
       follower = insert(:user)
 
       {:ok, follow_activity} = ActivityPub.follow(follower, user)
@@ -323,8 +234,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
 
       {:ok, follow_activity_two} = Utils.update_follow_state(follow_activity_two, "reject")
 
-      assert Repo.get(Activity, follow_activity.id).data["state"] == "pending"
-      assert Repo.get(Activity, follow_activity_two.id).data["state"] == "reject"
+      assert refresh_record(follow_activity).data["state"] == "pending"
+      assert refresh_record(follow_activity_two).data["state"] == "reject"
     end
   end
 
@@ -396,9 +307,242 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
 
       user = insert(:user)
       refute Utils.get_existing_like(user.ap_id, object)
-      {:ok, like_activity, _object} = ActivityPub.like(user, object)
+      {:ok, like_activity} = CommonAPI.favorite(user, note_activity.id)
 
       assert ^like_activity = Utils.get_existing_like(user.ap_id, object)
     end
   end
+
+  describe "get_get_existing_announce/2" do
+    test "returns nil if announce not found" do
+      actor = insert(:user)
+      refute Utils.get_existing_announce(actor.ap_id, %{data: %{"id" => "test"}})
+    end
+
+    test "fetches existing announce" do
+      note_activity = insert(:note_activity)
+      assert object = Object.normalize(note_activity)
+      actor = insert(:user)
+
+      {:ok, announce} = CommonAPI.repeat(note_activity.id, actor)
+      assert Utils.get_existing_announce(actor.ap_id, object) == announce
+    end
+  end
+
+  describe "fetch_latest_block/2" do
+    test "fetches last block activities" do
+      user1 = insert(:user)
+      user2 = insert(:user)
+
+      assert {:ok, %Activity{} = _} = CommonAPI.block(user1, user2)
+      assert {:ok, %Activity{} = _} = CommonAPI.block(user1, user2)
+      assert {:ok, %Activity{} = activity} = CommonAPI.block(user1, user2)
+
+      assert Utils.fetch_latest_block(user1, user2) == activity
+    end
+  end
+
+  describe "recipient_in_message/3" do
+    test "returns true when recipient in `to`" do
+      recipient = insert(:user)
+      actor = insert(:user)
+      assert Utils.recipient_in_message(recipient, actor, %{"to" => recipient.ap_id})
+
+      assert Utils.recipient_in_message(
+               recipient,
+               actor,
+               %{"to" => [recipient.ap_id], "cc" => ""}
+             )
+    end
+
+    test "returns true when recipient in `cc`" do
+      recipient = insert(:user)
+      actor = insert(:user)
+      assert Utils.recipient_in_message(recipient, actor, %{"cc" => recipient.ap_id})
+
+      assert Utils.recipient_in_message(
+               recipient,
+               actor,
+               %{"cc" => [recipient.ap_id], "to" => ""}
+             )
+    end
+
+    test "returns true when recipient in `bto`" do
+      recipient = insert(:user)
+      actor = insert(:user)
+      assert Utils.recipient_in_message(recipient, actor, %{"bto" => recipient.ap_id})
+
+      assert Utils.recipient_in_message(
+               recipient,
+               actor,
+               %{"bcc" => "", "bto" => [recipient.ap_id]}
+             )
+    end
+
+    test "returns true when recipient in `bcc`" do
+      recipient = insert(:user)
+      actor = insert(:user)
+      assert Utils.recipient_in_message(recipient, actor, %{"bcc" => recipient.ap_id})
+
+      assert Utils.recipient_in_message(
+               recipient,
+               actor,
+               %{"bto" => "", "bcc" => [recipient.ap_id]}
+             )
+    end
+
+    test "returns true when message without addresses fields" do
+      recipient = insert(:user)
+      actor = insert(:user)
+      assert Utils.recipient_in_message(recipient, actor, %{"bccc" => recipient.ap_id})
+
+      assert Utils.recipient_in_message(
+               recipient,
+               actor,
+               %{"btod" => "", "bccc" => [recipient.ap_id]}
+             )
+    end
+
+    test "returns false" do
+      recipient = insert(:user)
+      actor = insert(:user)
+      refute Utils.recipient_in_message(recipient, actor, %{"to" => "ap_id"})
+    end
+  end
+
+  describe "lazy_put_activity_defaults/2" do
+    test "returns map with id and published data" do
+      note_activity = insert(:note_activity)
+      object = Object.normalize(note_activity)
+      res = Utils.lazy_put_activity_defaults(%{"context" => object.data["id"]})
+      assert res["context"] == object.data["id"]
+      assert res["context_id"] == object.id
+      assert res["id"]
+      assert res["published"]
+    end
+
+    test "returns map with fake id and published data" do
+      assert %{
+               "context" => "pleroma:fakecontext",
+               "context_id" => -1,
+               "id" => "pleroma:fakeid",
+               "published" => _
+             } = Utils.lazy_put_activity_defaults(%{}, true)
+    end
+
+    test "returns activity data with object" do
+      note_activity = insert(:note_activity)
+      object = Object.normalize(note_activity)
+
+      res =
+        Utils.lazy_put_activity_defaults(%{
+          "context" => object.data["id"],
+          "object" => %{}
+        })
+
+      assert res["context"] == object.data["id"]
+      assert res["context_id"] == object.id
+      assert res["id"]
+      assert res["published"]
+      assert res["object"]["id"]
+      assert res["object"]["published"]
+      assert res["object"]["context"] == object.data["id"]
+      assert res["object"]["context_id"] == object.id
+    end
+  end
+
+  describe "make_flag_data" do
+    test "returns empty map when params is invalid" do
+      assert Utils.make_flag_data(%{}, %{}) == %{}
+    end
+
+    test "returns map with Flag object" do
+      reporter = insert(:user)
+      target_account = insert(:user)
+      {:ok, activity} = CommonAPI.post(target_account, %{status: "foobar"})
+      context = Utils.generate_context_id()
+      content = "foobar"
+
+      target_ap_id = target_account.ap_id
+      activity_ap_id = activity.data["id"]
+
+      res =
+        Utils.make_flag_data(
+          %{
+            actor: reporter,
+            context: context,
+            account: target_account,
+            statuses: [%{"id" => activity.data["id"]}],
+            content: content
+          },
+          %{}
+        )
+
+      note_obj = %{
+        "type" => "Note",
+        "id" => activity_ap_id,
+        "content" => content,
+        "published" => activity.object.data["published"],
+        "actor" => AccountView.render("show.json", %{user: target_account})
+      }
+
+      assert %{
+               "type" => "Flag",
+               "content" => ^content,
+               "context" => ^context,
+               "object" => [^target_ap_id, ^note_obj],
+               "state" => "open"
+             } = res
+    end
+  end
+
+  describe "add_announce_to_object/2" do
+    test "adds actor to announcement" do
+      user = insert(:user)
+      object = insert(:note)
+
+      activity =
+        insert(:note_activity,
+          data: %{
+            "actor" => user.ap_id,
+            "cc" => [Pleroma.Constants.as_public()]
+          }
+        )
+
+      assert {:ok, updated_object} = Utils.add_announce_to_object(activity, object)
+      assert updated_object.data["announcements"] == [user.ap_id]
+      assert updated_object.data["announcement_count"] == 1
+    end
+  end
+
+  describe "remove_announce_from_object/2" do
+    test "removes actor from announcements" do
+      user = insert(:user)
+      user2 = insert(:user)
+
+      object =
+        insert(:note,
+          data: %{"announcements" => [user.ap_id, user2.ap_id], "announcement_count" => 2}
+        )
+
+      activity = insert(:note_activity, data: %{"actor" => user.ap_id})
+
+      assert {:ok, updated_object} = Utils.remove_announce_from_object(activity, object)
+      assert updated_object.data["announcements"] == [user2.ap_id]
+      assert updated_object.data["announcement_count"] == 1
+    end
+  end
+
+  describe "get_cached_emoji_reactions/1" do
+    test "returns the data or an emtpy list" do
+      object = insert(:note)
+      assert Utils.get_cached_emoji_reactions(object) == []
+
+      object = insert(:note, data: %{"reactions" => [["x", ["lain"]]]})
+      assert Utils.get_cached_emoji_reactions(object) == [["x", ["lain"]]]
+
+      object = insert(:note, data: %{"reactions" => %{}})
+      assert Utils.get_cached_emoji_reactions(object) == []
+    end
+  end
 end