Merge branch 'develop' into feature/database-compaction
[akkoma] / test / web / activity_pub / transmogrifier_test.exs
index c1d542245b5e493a12e3cbdb200f5a332cfa5bac..5559cdf879ffe963179fa246e9c74b6f596f404c 100644 (file)
@@ -4,13 +4,14 @@
 
 defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
   use Pleroma.DataCase
+  alias Pleroma.Activity
+  alias Pleroma.Object
+  alias Pleroma.Repo
+  alias Pleroma.User
+  alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.ActivityPub.Transmogrifier
   alias Pleroma.Web.ActivityPub.Utils
-  alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.OStatus
-  alias Pleroma.Activity
-  alias Pleroma.User
-  alias Pleroma.Repo
   alias Pleroma.Web.Websub.WebsubClientSubscription
 
   import Pleroma.Factory
@@ -49,16 +50,14 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
         |> Map.put("object", object)
 
       {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
+      returned_object = Object.normalize(returned_activity.data["object"])
 
       assert activity =
-               Activity.get_create_activity_by_object_ap_id(
+               Activity.get_create_by_object_ap_id(
                  "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
                )
 
-      assert returned_activity.data["object"]["inReplyToAtomUri"] ==
-               "https://shitposter.club/notice/2827873"
-
-      assert returned_activity.data["object"]["inReplyToStatusId"] == activity.id
+      assert returned_object.data["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873"
     end
 
     test "it works for incoming notices" do
@@ -81,7 +80,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       assert data["actor"] == "http://mastodon.example.org/users/admin"
 
-      object = data["object"]
+      object = Object.normalize(data["object"]).data
       assert object["id"] == "http://mastodon.example.org/users/admin/statuses/99512778738411822"
 
       assert object["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
@@ -108,7 +107,9 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Poison.decode!()
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
-      assert Enum.at(data["object"]["tag"], 2) == "moo"
+      object = Object.normalize(data["object"])
+
+      assert Enum.at(object.data["tag"], 2) == "moo"
     end
 
     test "it works for incoming notices with contentMap" do
@@ -116,8 +117,9 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
         File.read!("test/fixtures/mastodon-post-activity-contentmap.json") |> Poison.decode!()
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
+      object = Object.normalize(data["object"])
 
-      assert data["object"]["content"] ==
+      assert object.data["content"] ==
                "<p><span class=\"h-card\"><a href=\"http://localtesting.pleroma.lol/users/lain\" class=\"u-url mention\">@<span>lain</span></a></span></p>"
     end
 
@@ -125,8 +127,9 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       data = File.read!("test/fixtures/kroeg-post-activity.json") |> Poison.decode!()
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
+      object = Object.normalize(data["object"])
 
-      assert data["object"]["content"] ==
+      assert object.data["content"] ==
                "<p>henlo from my Psion netBook</p><p>message sent from my Psion netBook</p>"
     end
 
@@ -142,24 +145,27 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       data = File.read!("test/fixtures/kroeg-array-less-emoji.json") |> Poison.decode!()
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
+      object = Object.normalize(data["object"])
 
-      assert data["object"]["emoji"] == %{
+      assert object.data["emoji"] == %{
                "icon_e_smile" => "https://puckipedia.com/forum/images/smilies/icon_e_smile.png"
              }
 
       data = File.read!("test/fixtures/kroeg-array-less-hashtag.json") |> Poison.decode!()
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
+      object = Object.normalize(data["object"])
 
-      assert "test" in data["object"]["tag"]
+      assert "test" in object.data["tag"]
     end
 
     test "it works for incoming notices with url not being a string (prismo)" do
       data = File.read!("test/fixtures/prismo-url-map.json") |> Poison.decode!()
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
+      object = Object.normalize(data["object"])
 
-      assert data["object"]["url"] == "https://prismo.news/posts/83"
+      assert object.data["url"] == "https://prismo.news/posts/83"
     end
 
     test "it cleans up incoming notices which are not really DMs" do
@@ -232,14 +238,14 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       data =
         File.read!("test/fixtures/mastodon-like.json")
         |> Poison.decode!()
-        |> Map.put("object", activity.data["object"]["id"])
+        |> Map.put("object", activity.data["object"])
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
 
       assert data["actor"] == "http://mastodon.example.org/users/admin"
       assert data["type"] == "Like"
       assert data["id"] == "http://mastodon.example.org/users/admin#likes/2"
-      assert data["object"] == activity.data["object"]["id"]
+      assert data["object"] == activity.data["object"]
     end
 
     test "it returns an error for incoming unlikes wihout a like activity" do
@@ -249,7 +255,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       data =
         File.read!("test/fixtures/mastodon-undo-like.json")
         |> Poison.decode!()
-        |> Map.put("object", activity.data["object"]["id"])
+        |> Map.put("object", activity.data["object"])
 
       assert Transmogrifier.handle_incoming(data) == :error
     end
@@ -261,7 +267,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       like_data =
         File.read!("test/fixtures/mastodon-like.json")
         |> Poison.decode!()
-        |> Map.put("object", activity.data["object"]["id"])
+        |> Map.put("object", activity.data["object"])
 
       {:ok, %Activity{data: like_data, local: false}} = Transmogrifier.handle_incoming(like_data)
 
@@ -293,7 +299,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       assert data["object"] ==
                "http://mastodon.example.org/users/admin/statuses/99541947525187367"
 
-      assert Activity.get_create_activity_by_object_ap_id(data["object"])
+      assert Activity.get_create_by_object_ap_id(data["object"])
     end
 
     test "it works for incoming announces with an existing activity" do
@@ -303,7 +309,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       data =
         File.read!("test/fixtures/mastodon-announce.json")
         |> Poison.decode!()
-        |> Map.put("object", activity.data["object"]["id"])
+        |> Map.put("object", activity.data["object"])
 
       {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
 
@@ -313,9 +319,9 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       assert data["id"] ==
                "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
 
-      assert data["object"] == activity.data["object"]["id"]
+      assert data["object"] == activity.data["object"]
 
-      assert Activity.get_create_activity_by_object_ap_id(data["object"]).id == activity.id
+      assert Activity.get_create_by_object_ap_id(data["object"]).id == activity.id
     end
 
     test "it does not clobber the addressing on announce activities" do
@@ -334,6 +340,53 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       assert data["to"] == ["http://mastodon.example.org/users/admin/followers"]
     end
 
+    test "it ensures that as:Public activities make it to their followers collection" do
+      user = insert(:user)
+
+      data =
+        File.read!("test/fixtures/mastodon-post-activity.json")
+        |> Poison.decode!()
+        |> Map.put("actor", user.ap_id)
+        |> Map.put("to", ["https://www.w3.org/ns/activitystreams#Public"])
+        |> Map.put("cc", [])
+
+      object =
+        data["object"]
+        |> Map.put("attributedTo", user.ap_id)
+        |> Map.put("to", ["https://www.w3.org/ns/activitystreams#Public"])
+        |> Map.put("cc", [])
+
+      data = Map.put(data, "object", object)
+
+      {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
+
+      assert data["cc"] == [User.ap_followers(user)]
+    end
+
+    test "it ensures that address fields become lists" do
+      user = insert(:user)
+
+      data =
+        File.read!("test/fixtures/mastodon-post-activity.json")
+        |> Poison.decode!()
+        |> Map.put("actor", user.ap_id)
+        |> Map.put("to", nil)
+        |> Map.put("cc", nil)
+
+      object =
+        data["object"]
+        |> Map.put("attributedTo", user.ap_id)
+        |> Map.put("to", nil)
+        |> Map.put("cc", nil)
+
+      data = Map.put(data, "object", object)
+
+      {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
+
+      assert !is_nil(data["to"])
+      assert !is_nil(data["cc"])
+    end
+
     test "it works for incoming update activities" do
       data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
 
@@ -404,7 +457,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       object =
         data["object"]
-        |> Map.put("id", activity.data["object"]["id"])
+        |> Map.put("id", activity.data["object"])
 
       data =
         data
@@ -413,7 +466,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
 
-      refute Repo.get(Activity, activity.id)
+      refute Activity.get_by_id(activity.id)
     end
 
     test "it fails for incoming deletes with spoofed origin" do
@@ -425,7 +478,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       object =
         data["object"]
-        |> Map.put("id", activity.data["object"]["id"])
+        |> Map.put("id", activity.data["object"])
 
       data =
         data
@@ -433,7 +486,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       :error = Transmogrifier.handle_incoming(data)
 
-      assert Repo.get(Activity, activity.id)
+      assert Activity.get_by_id(activity.id)
     end
 
     test "it works for incoming unannounces with an existing notice" do
@@ -443,7 +496,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       announce_data =
         File.read!("test/fixtures/mastodon-announce.json")
         |> Poison.decode!()
-        |> Map.put("object", activity.data["object"]["id"])
+        |> Map.put("object", activity.data["object"])
 
       {:ok, %Activity{data: announce_data, local: false}} =
         Transmogrifier.handle_incoming(announce_data)
@@ -458,7 +511,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       assert data["type"] == "Undo"
       assert data["object"]["type"] == "Announce"
-      assert data["object"]["object"] == activity.data["object"]["id"]
+      assert data["object"]["object"] == activity.data["object"]
 
       assert data["object"]["id"] ==
                "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
@@ -591,7 +644,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       assert activity.data["object"] == follow_activity.data["id"]
 
-      follower = Repo.get(User, follower.id)
+      follower = User.get_by_id(follower.id)
 
       assert User.following?(follower, followed) == true
     end
@@ -613,7 +666,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
       assert activity.data["object"] == follow_activity.data["id"]
 
-      follower = Repo.get(User, follower.id)
+      follower = User.get_by_id(follower.id)
 
       assert User.following?(follower, followed) == true
     end
@@ -633,7 +686,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
       assert activity.data["object"] == follow_activity.data["id"]
 
-      follower = Repo.get(User, follower.id)
+      follower = User.get_by_id(follower.id)
 
       assert User.following?(follower, followed) == true
     end
@@ -652,7 +705,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       :error = Transmogrifier.handle_incoming(accept_data)
 
-      follower = Repo.get(User, follower.id)
+      follower = User.get_by_id(follower.id)
 
       refute User.following?(follower, followed) == true
     end
@@ -671,7 +724,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       :error = Transmogrifier.handle_incoming(accept_data)
 
-      follower = Repo.get(User, follower.id)
+      follower = User.get_by_id(follower.id)
 
       refute User.following?(follower, followed) == true
     end
@@ -696,7 +749,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       {:ok, activity} = Transmogrifier.handle_incoming(reject_data)
       refute activity.local
 
-      follower = Repo.get(User, follower.id)
+      follower = User.get_by_id(follower.id)
 
       assert User.following?(follower, followed) == false
     end
@@ -718,7 +771,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       {:ok, %Activity{data: _}} = Transmogrifier.handle_incoming(reject_data)
 
-      follower = Repo.get(User, follower.id)
+      follower = User.get_by_id(follower.id)
 
       assert User.following?(follower, followed) == false
     end
@@ -764,6 +817,30 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       assert object.data["attachment"] == [attachment]
     end
+
+    test "it accepts Flag activities" do
+      user = insert(:user)
+      other_user = insert(:user)
+
+      {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
+      object = Object.normalize(activity.data["object"])
+
+      message = %{
+        "@context" => "https://www.w3.org/ns/activitystreams",
+        "cc" => [user.ap_id],
+        "object" => [user.ap_id, object.data["id"]],
+        "type" => "Flag",
+        "content" => "blocked AND reported!!!",
+        "actor" => other_user.ap_id
+      }
+
+      assert {:ok, activity} = Transmogrifier.handle_incoming(message)
+
+      assert activity.data["object"] == [user.ap_id, object.data["id"]]
+      assert activity.data["content"] == "blocked AND reported!!!"
+      assert activity.data["actor"] == other_user.ap_id
+      assert activity.data["cc"] == [user.ap_id]
+    end
   end
 
   describe "prepare outgoing" do
@@ -914,7 +991,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       assert modified["directMessage"] == false
 
       {:ok, activity} =
-        CommonAPI.post(user, %{"status" => "@{other_user.nickname} :moominmamma:"})
+        CommonAPI.post(user, %{"status" => "@#{other_user.nickname} :moominmamma:"})
 
       {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
 
@@ -922,7 +999,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       {:ok, activity} =
         CommonAPI.post(user, %{
-          "status" => "@{other_user.nickname} :moominmamma:",
+          "status" => "@#{other_user.nickname} :moominmamma:",
           "visibility" => "direct"
         })
 
@@ -948,7 +1025,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       {:ok, unrelated_activity} = CommonAPI.post(user_two, %{"status" => "test"})
       assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients
 
-      user = Repo.get(User, user.id)
+      user = User.get_by_id(user.id)
       assert user.info.note_count == 1
 
       {:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
@@ -956,13 +1033,10 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       assert user.info.note_count == 1
       assert user.follower_address == "https://niu.moe/users/rye/followers"
 
-      # Wait for the background task
-      :timer.sleep(1000)
-
-      user = Repo.get(User, user.id)
+      user = User.get_by_id(user.id)
       assert user.info.note_count == 1
 
-      activity = Repo.get(Activity, activity.id)
+      activity = Activity.get_by_id(activity.id)
       assert user.follower_address in activity.recipients
 
       assert %{
@@ -985,10 +1059,10 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
 
       refute "..." in activity.recipients
 
-      unrelated_activity = Repo.get(Activity, unrelated_activity.id)
+      unrelated_activity = Activity.get_by_id(unrelated_activity.id)
       refute user.follower_address in unrelated_activity.recipients
 
-      user_two = Repo.get(User, user_two.id)
+      user_two = User.get_by_id(user_two.id)
       assert user.follower_address in user_two.following
       refute "..." in user_two.following
     end
@@ -1021,10 +1095,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
   end
 
   describe "actor origin containment" do
-    test "it rejects objects with a bogus origin" do
-      {:error, _} = ActivityPub.fetch_object_from_id("https://info.pleroma.site/activity.json")
-    end
-
     test "it rejects activities which reference objects with bogus origins" do
       data = %{
         "@context" => "https://www.w3.org/ns/activitystreams",
@@ -1038,10 +1108,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       :error = Transmogrifier.handle_incoming(data)
     end
 
-    test "it rejects objects when attributedTo is wrong (variant 1)" do
-      {:error, _} = ActivityPub.fetch_object_from_id("https://info.pleroma.site/activity2.json")
-    end
-
     test "it rejects activities which reference objects that have an incorrect attribution (variant 1)" do
       data = %{
         "@context" => "https://www.w3.org/ns/activitystreams",
@@ -1055,10 +1121,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       :error = Transmogrifier.handle_incoming(data)
     end
 
-    test "it rejects objects when attributedTo is wrong (variant 2)" do
-      {:error, _} = ActivityPub.fetch_object_from_id("https://info.pleroma.site/activity3.json")
-    end
-
     test "it rejects activities which reference objects that have an incorrect attribution (variant 2)" do
       data = %{
         "@context" => "https://www.w3.org/ns/activitystreams",
@@ -1128,4 +1190,58 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
         )
     end
   end
+
+  describe "reserialization" do
+    test "successfully reserializes a message with inReplyTo == nil" do
+      user = insert(:user)
+
+      message = %{
+        "@context" => "https://www.w3.org/ns/activitystreams",
+        "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+        "cc" => [],
+        "type" => "Create",
+        "object" => %{
+          "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+          "cc" => [],
+          "type" => "Note",
+          "content" => "Hi",
+          "inReplyTo" => nil,
+          "attributedTo" => user.ap_id
+        },
+        "actor" => user.ap_id
+      }
+
+      {:ok, activity} = Transmogrifier.handle_incoming(message)
+
+      {:ok, _} = Transmogrifier.prepare_outgoing(activity.data)
+    end
+
+    test "successfully reserializes a message with AS2 objects in IR" do
+      user = insert(:user)
+
+      message = %{
+        "@context" => "https://www.w3.org/ns/activitystreams",
+        "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+        "cc" => [],
+        "type" => "Create",
+        "object" => %{
+          "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+          "cc" => [],
+          "type" => "Note",
+          "content" => "Hi",
+          "inReplyTo" => nil,
+          "attributedTo" => user.ap_id,
+          "tag" => [
+            %{"name" => "#2hu", "href" => "http://example.com/2hu", "type" => "Hashtag"},
+            %{"name" => "Bob", "href" => "http://example.com/bob", "type" => "Mention"}
+          ]
+        },
+        "actor" => user.ap_id
+      }
+
+      {:ok, activity} = Transmogrifier.handle_incoming(message)
+
+      {:ok, _} = Transmogrifier.prepare_outgoing(activity.data)
+    end
+  end
 end