Registration: user state is separate from instance state
[akkoma] / test / object / fetcher_test.exs
index 58abcfe5522ac26414137988b4df9d547ca22c64..14d2c645fe4fbbbc83f62bc70b157eef0e9ff345 100644 (file)
@@ -1,9 +1,16 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
 defmodule Pleroma.Object.FetcherTest do
   use Pleroma.DataCase
 
   alias Pleroma.Activity
+  alias Pleroma.Config
   alias Pleroma.Object
   alias Pleroma.Object.Fetcher
+
+  import Mock
   import Tesla.Mock
 
   setup do
@@ -11,6 +18,9 @@ defmodule Pleroma.Object.FetcherTest do
       %{method: :get, url: "https://mastodon.example.org/users/userisgone"} ->
         %Tesla.Env{status: 410}
 
+      %{method: :get, url: "https://mastodon.example.org/users/userisgone404"} ->
+        %Tesla.Env{status: 404}
+
       env ->
         apply(HttpRequestMock, :request, [env])
     end)
@@ -18,6 +28,70 @@ defmodule Pleroma.Object.FetcherTest do
     :ok
   end
 
+  describe "error cases" do
+    setup do
+      mock(fn
+        %{method: :get, url: "https://social.sakamoto.gq/notice/9wTkLEnuq47B25EehM"} ->
+          %Tesla.Env{
+            status: 200,
+            body: File.read!("test/fixtures/fetch_mocks/9wTkLEnuq47B25EehM.json")
+          }
+
+        %{method: :get, url: "https://social.sakamoto.gq/users/eal"} ->
+          %Tesla.Env{
+            status: 200,
+            body: File.read!("test/fixtures/fetch_mocks/eal.json")
+          }
+
+        %{method: :get, url: "https://busshi.moe/users/tuxcrafting/statuses/104410921027210069"} ->
+          %Tesla.Env{
+            status: 200,
+            body: File.read!("test/fixtures/fetch_mocks/104410921027210069.json")
+          }
+
+        %{method: :get, url: "https://busshi.moe/users/tuxcrafting"} ->
+          %Tesla.Env{
+            status: 500
+          }
+      end)
+
+      :ok
+    end
+
+    @tag capture_log: true
+    test "it works when fetching the OP actor errors out" do
+      # Here we simulate a case where the author of the OP can't be read
+      assert {:ok, _} =
+               Fetcher.fetch_object_from_id(
+                 "https://social.sakamoto.gq/notice/9wTkLEnuq47B25EehM"
+               )
+    end
+  end
+
+  describe "max thread distance restriction" do
+    @ap_id "http://mastodon.example.org/@admin/99541947525187367"
+    setup do: clear_config([:instance, :federation_incoming_replies_max_depth])
+
+    test "it returns thread depth exceeded error if thread depth is exceeded" do
+      Config.put([:instance, :federation_incoming_replies_max_depth], 0)
+
+      assert {:error, "Max thread distance exceeded."} =
+               Fetcher.fetch_object_from_id(@ap_id, depth: 1)
+    end
+
+    test "it fetches object if max thread depth is restricted to 0 and depth is not specified" do
+      Config.put([:instance, :federation_incoming_replies_max_depth], 0)
+
+      assert {:ok, _} = Fetcher.fetch_object_from_id(@ap_id)
+    end
+
+    test "it fetches object if requested depth does not exceed max thread depth" do
+      Config.put([:instance, :federation_incoming_replies_max_depth], 10)
+
+      assert {:ok, _} = Fetcher.fetch_object_from_id(@ap_id, depth: 10)
+    end
+  end
+
   describe "actor origin containment" do
     test "it rejects objects with a bogus origin" do
       {:error, _} = Fetcher.fetch_object_from_id("https://info.pleroma.site/activity.json")
@@ -49,22 +123,14 @@ defmodule Pleroma.Object.FetcherTest do
       assert object == object_again
     end
 
-    test "it works with objects only available via Ostatus" do
-      {:ok, object} = Fetcher.fetch_object_from_id("https://shitposter.club/notice/2827873")
-      assert activity = Activity.get_create_by_object_ap_id(object.data["id"])
-      assert activity.data["id"]
+    test "Return MRF reason when fetched status is rejected by one" do
+      clear_config([:mrf_keyword, :reject], ["yeah"])
+      clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
 
-      {:ok, object_again} = Fetcher.fetch_object_from_id("https://shitposter.club/notice/2827873")
-
-      assert object == object_again
-    end
-
-    test "it correctly stitches up conversations between ostatus and ap" do
-      last = "https://mstdn.io/users/mayuutann/statuses/99568293732299394"
-      {:ok, object} = Fetcher.fetch_object_from_id(last)
-
-      object = Object.get_by_ap_id(object.data["inReplyTo"])
-      assert object
+      assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} ==
+               Fetcher.fetch_object_from_id(
+                 "http://mastodon.example.org/@admin/99541947525187367"
+               )
     end
   end
 
@@ -87,6 +153,22 @@ defmodule Pleroma.Object.FetcherTest do
       assert object
     end
 
+    test "it can fetch Mobilizon events" do
+      {:ok, object} =
+        Fetcher.fetch_object_from_id(
+          "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39"
+        )
+
+      assert object
+    end
+
+    test "it can fetch wedistribute articles" do
+      {:ok, object} =
+        Fetcher.fetch_object_from_id("https://wedistribute.org/wp-json/pterotype/v1/object/85810")
+
+      assert object
+    end
+
     test "all objects with fake directions are rejected by the object fetcher" do
       assert {:error, _} =
                Fetcher.fetch_and_contain_remote_object_from_id(
@@ -100,6 +182,20 @@ defmodule Pleroma.Object.FetcherTest do
                  "https://mastodon.example.org/users/userisgone"
                )
     end
+
+    test "handle HTTP 404 response" do
+      assert {:error, "Object has been deleted"} ==
+               Fetcher.fetch_and_contain_remote_object_from_id(
+                 "https://mastodon.example.org/users/userisgone404"
+               )
+    end
+
+    test "it can fetch pleroma polls with attachments" do
+      {:ok, object} =
+        Fetcher.fetch_object_from_id("https://patch.cx/objects/tesla_mock/poll_attachment")
+
+      assert object
+    end
   end
 
   describe "pruning" do
@@ -120,4 +216,30 @@ defmodule Pleroma.Object.FetcherTest do
       assert object.id != object_two.id
     end
   end
+
+  describe "signed fetches" do
+    setup do: clear_config([:activitypub, :sign_object_fetches])
+
+    test_with_mock "it signs fetches when configured to do so",
+                   Pleroma.Signature,
+                   [:passthrough],
+                   [] do
+      Config.put([:activitypub, :sign_object_fetches], true)
+
+      Fetcher.fetch_object_from_id("http://mastodon.example.org/@admin/99541947525187367")
+
+      assert called(Pleroma.Signature.sign(:_, :_))
+    end
+
+    test_with_mock "it doesn't sign fetches when not configured to do so",
+                   Pleroma.Signature,
+                   [:passthrough],
+                   [] do
+      Config.put([:activitypub, :sign_object_fetches], false)
+
+      Fetcher.fetch_object_from_id("http://mastodon.example.org/@admin/99541947525187367")
+
+      refute called(Pleroma.Signature.sign(:_, :_))
+    end
+  end
 end