Merge branch 'remake-remodel' into develop
[akkoma] / test / web / activity_pub / activity_pub_test.exs
index 2677b9e36bbd48b1a700a2dc9f5811f997dc237a..d5dd44cc31cd067816ff4d4cbf8814300cdd7b86 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.ActivityPubTest do
@@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
 
   alias Pleroma.Activity
   alias Pleroma.Builders.ActivityBuilder
+  alias Pleroma.Config
   alias Pleroma.Notification
   alias Pleroma.Object
   alias Pleroma.User
@@ -15,6 +16,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
   alias Pleroma.Web.ActivityPub.Utils
   alias Pleroma.Web.AdminAPI.AccountView
   alias Pleroma.Web.CommonAPI
+  alias Pleroma.Web.Federator
 
   import Pleroma.Factory
   import Tesla.Mock
@@ -224,7 +226,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
 
   describe "insertion" do
     test "drops activities beyond a certain limit" do
-      limit = Pleroma.Config.get([:instance, :remote_limit])
+      limit = Config.get([:instance, :remote_limit])
 
       random_text =
         :crypto.strong_rand_bytes(limit + 1)
@@ -385,6 +387,27 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
   end
 
   describe "create activities" do
+    test "it reverts create" do
+      user = insert(:user)
+
+      with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
+        assert {:error, :reverted} =
+                 ActivityPub.create(%{
+                   to: ["user1", "user2"],
+                   actor: user,
+                   context: "",
+                   object: %{
+                     "to" => ["user1", "user2"],
+                     "type" => "Note",
+                     "content" => "testing"
+                   }
+                 })
+      end
+
+      assert Repo.aggregate(Activity, :count, :id) == 0
+      assert Repo.aggregate(Object, :count, :id) == 0
+    end
+
     test "removes doubled 'to' recipients" do
       user = insert(:user)
 
@@ -487,7 +510,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       activity_five = insert(:note_activity)
       user = insert(:user)
 
-      {:ok, user} = User.block(user, %{ap_id: activity_five.data["actor"]})
+      {:ok, _user_relationship} = User.block(user, %{ap_id: activity_five.data["actor"]})
 
       activities = ActivityPub.fetch_activities_for_context("2hu", %{"blocking_user" => user})
       assert activities == [activity_two, activity]
@@ -500,7 +523,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
     activity_three = insert(:note_activity)
     user = insert(:user)
     booster = insert(:user)
-    {:ok, user} = User.block(user, %{ap_id: activity_one.data["actor"]})
+    {:ok, _user_relationship} = User.block(user, %{ap_id: activity_one.data["actor"]})
 
     activities =
       ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true})
@@ -509,7 +532,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
     assert Enum.member?(activities, activity_three)
     refute Enum.member?(activities, activity_one)
 
-    {:ok, user} = User.unblock(user, %{ap_id: activity_one.data["actor"]})
+    {:ok, _user_block} = User.unblock(user, %{ap_id: activity_one.data["actor"]})
 
     activities =
       ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true})
@@ -518,7 +541,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
     assert Enum.member?(activities, activity_three)
     assert Enum.member?(activities, activity_one)
 
-    {:ok, user} = User.block(user, %{ap_id: activity_three.data["actor"]})
+    {:ok, _user_relationship} = User.block(user, %{ap_id: activity_three.data["actor"]})
     {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(activity_three.id, booster)
     %Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id)
     activity_three = Activity.get_by_id(activity_three.id)
@@ -545,7 +568,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
     blockee = insert(:user)
     friend = insert(:user)
 
-    {:ok, blocker} = User.block(blocker, blockee)
+    {:ok, _user_relationship} = User.block(blocker, blockee)
 
     {:ok, activity_one} = CommonAPI.post(friend, %{"status" => "hey!"})
 
@@ -568,7 +591,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
     blockee = insert(:user)
     friend = insert(:user)
 
-    {:ok, blocker} = User.block(blocker, blockee)
+    {:ok, _user_relationship} = User.block(blocker, blockee)
 
     {:ok, activity_one} = CommonAPI.post(friend, %{"status" => "hey!"})
 
@@ -608,13 +631,48 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
     refute repeat_activity in activities
   end
 
+  test "does return activities from followed users on blocked domains" do
+    domain = "meanies.social"
+    domain_user = insert(:user, %{ap_id: "https://#{domain}/@pundit"})
+    blocker = insert(:user)
+
+    {:ok, blocker} = User.follow(blocker, domain_user)
+    {:ok, blocker} = User.block_domain(blocker, domain)
+
+    assert User.following?(blocker, domain_user)
+    assert User.blocks_domain?(blocker, domain_user)
+    refute User.blocks?(blocker, domain_user)
+
+    note = insert(:note, %{data: %{"actor" => domain_user.ap_id}})
+    activity = insert(:note_activity, %{note: note})
+
+    activities =
+      ActivityPub.fetch_activities([], %{"blocking_user" => blocker, "skip_preload" => true})
+
+    assert activity in activities
+
+    # And check that if the guy we DO follow boosts someone else from their domain,
+    # that should be hidden
+    another_user = insert(:user, %{ap_id: "https://#{domain}/@meanie2"})
+    bad_note = insert(:note, %{data: %{"actor" => another_user.ap_id}})
+    bad_activity = insert(:note_activity, %{note: bad_note})
+    {:ok, repeat_activity, _} = CommonAPI.repeat(bad_activity.id, domain_user)
+
+    activities =
+      ActivityPub.fetch_activities([], %{"blocking_user" => blocker, "skip_preload" => true})
+
+    refute repeat_activity in activities
+  end
+
   test "doesn't return muted activities" do
     activity_one = insert(:note_activity)
     activity_two = insert(:note_activity)
     activity_three = insert(:note_activity)
     user = insert(:user)
     booster = insert(:user)
-    {:ok, user} = User.mute(user, %User{ap_id: activity_one.data["actor"]})
+
+    activity_one_actor = User.get_by_ap_id(activity_one.data["actor"])
+    {:ok, _user_relationships} = User.mute(user, activity_one_actor)
 
     activities =
       ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true})
@@ -635,7 +693,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
     assert Enum.member?(activities, activity_three)
     assert Enum.member?(activities, activity_one)
 
-    {:ok, user} = User.unmute(user, %User{ap_id: activity_one.data["actor"]})
+    {:ok, _user_mute} = User.unmute(user, activity_one_actor)
 
     activities =
       ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true})
@@ -644,7 +702,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
     assert Enum.member?(activities, activity_three)
     assert Enum.member?(activities, activity_one)
 
-    {:ok, user} = User.mute(user, %User{ap_id: activity_three.data["actor"]})
+    activity_three_actor = User.get_by_ap_id(activity_three.data["actor"])
+    {:ok, _user_relationships} = User.mute(user, activity_three_actor)
     {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(activity_three.id, booster)
     %Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id)
     activity_three = Activity.get_by_id(activity_three.id)
@@ -791,7 +850,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       activity = insert(:note_activity)
       user = insert(:user)
       booster = insert(:user)
-      {:ok, user} = CommonAPI.hide_reblogs(user, booster)
+      {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, booster)
 
       {:ok, activity, _} = CommonAPI.repeat(activity.id, booster)
 
@@ -804,8 +863,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       activity = insert(:note_activity)
       user = insert(:user)
       booster = insert(:user)
-      {:ok, user} = CommonAPI.hide_reblogs(user, booster)
-      {:ok, user} = CommonAPI.show_reblogs(user, booster)
+      {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, booster)
+      {:ok, _reblog_mute} = CommonAPI.show_reblogs(user, booster)
 
       {:ok, activity, _} = CommonAPI.repeat(activity.id, booster)
 
@@ -816,8 +875,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
   end
 
   describe "react to an object" do
-    test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do
-      Pleroma.Config.put([:instance, :federating], true)
+    test_with_mock "sends an activity to federation", Federator, [:passthrough], [] do
+      Config.put([:instance, :federating], true)
       user = insert(:user)
       reactor = insert(:user)
       {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"})
@@ -825,12 +884,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
 
       {:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥")
 
-      assert called(Pleroma.Web.Federator.publish(reaction_activity))
+      assert called(Federator.publish(reaction_activity))
     end
 
     test "adds an emoji reaction activity to the db" do
       user = insert(:user)
       reactor = insert(:user)
+      third_user = insert(:user)
+      fourth_user = insert(:user)
       {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"})
       assert object = Object.normalize(activity)
 
@@ -839,19 +900,48 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       assert reaction_activity
 
       assert reaction_activity.data["actor"] == reactor.ap_id
-      assert reaction_activity.data["type"] == "EmojiReaction"
+      assert reaction_activity.data["type"] == "EmojiReact"
       assert reaction_activity.data["content"] == "🔥"
       assert reaction_activity.data["object"] == object.data["id"]
       assert reaction_activity.data["to"] == [User.ap_followers(reactor), activity.data["actor"]]
       assert reaction_activity.data["context"] == object.data["context"]
       assert object.data["reaction_count"] == 1
-      assert object.data["reactions"]["🔥"] == [reactor.ap_id]
+      assert object.data["reactions"] == [["🔥", [reactor.ap_id]]]
+
+      {:ok, _reaction_activity, object} = ActivityPub.react_with_emoji(third_user, object, "☕")
+
+      assert object.data["reaction_count"] == 2
+      assert object.data["reactions"] == [["🔥", [reactor.ap_id]], ["☕", [third_user.ap_id]]]
+
+      {:ok, _reaction_activity, object} = ActivityPub.react_with_emoji(fourth_user, object, "🔥")
+
+      assert object.data["reaction_count"] == 3
+
+      assert object.data["reactions"] == [
+               ["🔥", [fourth_user.ap_id, reactor.ap_id]],
+               ["☕", [third_user.ap_id]]
+             ]
+    end
+
+    test "reverts emoji reaction on error" do
+      [user, reactor] = insert_list(2, :user)
+
+      {:ok, activity} = CommonAPI.post(user, %{"status" => "Status"})
+      object = Object.normalize(activity)
+
+      with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
+        assert {:error, :reverted} = ActivityPub.react_with_emoji(reactor, object, "😀")
+      end
+
+      object = Object.get_by_ap_id(object.data["id"])
+      refute object.data["reaction_count"]
+      refute object.data["reactions"]
     end
   end
 
   describe "unreacting to an object" do
-    test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do
-      Pleroma.Config.put([:instance, :federating], true)
+    test_with_mock "sends an activity to federation", Federator, [:passthrough], [] do
+      Config.put([:instance, :federating], true)
       user = insert(:user)
       reactor = insert(:user)
       {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"})
@@ -859,12 +949,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
 
       {:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥")
 
-      assert called(Pleroma.Web.Federator.publish(reaction_activity))
+      assert called(Federator.publish(reaction_activity))
 
       {:ok, unreaction_activity, _object} =
         ActivityPub.unreact_with_emoji(reactor, reaction_activity.data["id"])
 
-      assert called(Pleroma.Web.Federator.publish(unreaction_activity))
+      assert called(Federator.publish(unreaction_activity))
     end
 
     test "adds an undo activity to the db" do
@@ -883,20 +973,38 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
 
       object = Object.get_by_ap_id(object.data["id"])
       assert object.data["reaction_count"] == 0
-      assert object.data["reactions"] == %{}
+      assert object.data["reactions"] == []
+    end
+
+    test "reverts emoji unreact on error" do
+      [user, reactor] = insert_list(2, :user)
+      {:ok, activity} = CommonAPI.post(user, %{"status" => "Status"})
+      object = Object.normalize(activity)
+
+      {:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "😀")
+
+      with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
+        assert {:error, :reverted} =
+                 ActivityPub.unreact_with_emoji(reactor, reaction_activity.data["id"])
+      end
+
+      object = Object.get_by_ap_id(object.data["id"])
+
+      assert object.data["reaction_count"] == 1
+      assert object.data["reactions"] == [["😀", [reactor.ap_id]]]
     end
   end
 
   describe "like an object" do
-    test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do
-      Pleroma.Config.put([:instance, :federating], true)
+    test_with_mock "sends an activity to federation", Federator, [:passthrough], [] do
+      Config.put([:instance, :federating], true)
       note_activity = insert(:note_activity)
       assert object_activity = Object.normalize(note_activity)
 
       user = insert(:user)
 
       {:ok, like_activity, _object} = ActivityPub.like(user, object_activity)
-      assert called(Pleroma.Web.Federator.publish(like_activity))
+      assert called(Federator.publish(like_activity))
     end
 
     test "returns exist activity if object already liked" do
@@ -911,6 +1019,19 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       assert like_activity == like_activity_exist
     end
 
+    test "reverts like activity on error" do
+      note_activity = insert(:note_activity)
+      object = Object.normalize(note_activity)
+      user = insert(:user)
+
+      with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
+        assert {:error, :reverted} = ActivityPub.like(user, object)
+      end
+
+      assert Repo.aggregate(Activity, :count, :id) == 1
+      assert Repo.get(Object, object.id) == object
+    end
+
     test "adds a like activity to the db" do
       note_activity = insert(:note_activity)
       assert object = Object.normalize(note_activity)
@@ -941,15 +1062,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
   end
 
   describe "unliking" do
-    test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do
-      Pleroma.Config.put([:instance, :federating], true)
+    test_with_mock "sends an activity to federation", Federator, [:passthrough], [] do
+      Config.put([:instance, :federating], true)
 
       note_activity = insert(:note_activity)
       object = Object.normalize(note_activity)
       user = insert(:user)
 
       {:ok, object} = ActivityPub.unlike(user, object)
-      refute called(Pleroma.Web.Federator.publish())
+      refute called(Federator.publish())
 
       {:ok, _like_activity, object} = ActivityPub.like(user, object)
       assert object.data["like_count"] == 1
@@ -957,7 +1078,24 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       {:ok, unlike_activity, _, object} = ActivityPub.unlike(user, object)
       assert object.data["like_count"] == 0
 
-      assert called(Pleroma.Web.Federator.publish(unlike_activity))
+      assert called(Federator.publish(unlike_activity))
+    end
+
+    test "reverts unliking on error" do
+      note_activity = insert(:note_activity)
+      object = Object.normalize(note_activity)
+      user = insert(:user)
+
+      {:ok, like_activity, object} = ActivityPub.like(user, object)
+      assert object.data["like_count"] == 1
+
+      with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
+        assert {:error, :reverted} = ActivityPub.unlike(user, object)
+      end
+
+      assert Object.get_by_ap_id(object.data["id"]) == object
+      assert object.data["like_count"] == 1
+      assert Activity.get_by_id(like_activity.id)
     end
 
     test "unliking a previously liked object" do
@@ -999,6 +1137,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       assert announce_activity.data["actor"] == user.ap_id
       assert announce_activity.data["context"] == object.data["context"]
     end
+
+    test "reverts annouce from object on error" do
+      note_activity = insert(:note_activity)
+      object = Object.normalize(note_activity)
+      user = insert(:user)
+
+      with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
+        assert {:error, :reverted} = ActivityPub.announce(user, object)
+      end
+
+      reloaded_object = Object.get_by_ap_id(object.data["id"])
+      assert reloaded_object == object
+      refute reloaded_object.data["announcement_count"]
+      refute reloaded_object.data["announcements"]
+    end
   end
 
   describe "announcing a private object" do
@@ -1041,8 +1194,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       user = insert(:user)
 
       # Unannouncing an object that is not announced does nothing
-      {:ok, object} = ActivityPub.unannounce(user, object)
-      # assert object.data["announcement_count"] == 0
+      {:ok, object} = ActivityPub.unannounce(user, object)
+      refute object.data["announcement_count"]
 
       {:ok, announce_activity, object} = ActivityPub.announce(user, object)
       assert object.data["announcement_count"] == 1
@@ -1062,6 +1215,22 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
 
       assert Activity.get_by_id(announce_activity.id) == nil
     end
+
+    test "reverts unannouncing on error" do
+      note_activity = insert(:note_activity)
+      object = Object.normalize(note_activity)
+      user = insert(:user)
+
+      {:ok, _announce_activity, object} = ActivityPub.announce(user, object)
+      assert object.data["announcement_count"] == 1
+
+      with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
+        assert {:error, :reverted} = ActivityPub.unannounce(user, object)
+      end
+
+      object = Object.get_by_ap_id(object.data["id"])
+      assert object.data["announcement_count"] == 1
+    end
   end
 
   describe "uploading files" do
@@ -1096,6 +1265,35 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
   end
 
   describe "following / unfollowing" do
+    test "it reverts follow activity" do
+      follower = insert(:user)
+      followed = insert(:user)
+
+      with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
+        assert {:error, :reverted} = ActivityPub.follow(follower, followed)
+      end
+
+      assert Repo.aggregate(Activity, :count, :id) == 0
+      assert Repo.aggregate(Object, :count, :id) == 0
+    end
+
+    test "it reverts unfollow activity" do
+      follower = insert(:user)
+      followed = insert(:user)
+
+      {:ok, follow_activity} = ActivityPub.follow(follower, followed)
+
+      with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
+        assert {:error, :reverted} = ActivityPub.unfollow(follower, followed)
+      end
+
+      activity = Activity.get_by_id(follow_activity.id)
+      assert activity.data["type"] == "Follow"
+      assert activity.data["actor"] == follower.ap_id
+
+      assert activity.data["object"] == followed.ap_id
+    end
+
     test "creates a follow activity" do
       follower = insert(:user)
       followed = insert(:user)
@@ -1122,9 +1320,37 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       assert embedded_object["object"] == followed.ap_id
       assert embedded_object["id"] == follow_activity.data["id"]
     end
+
+    test "creates an undo activity for a pending follow request" do
+      follower = insert(:user)
+      followed = insert(:user, %{locked: true})
+
+      {:ok, follow_activity} = ActivityPub.follow(follower, followed)
+      {:ok, activity} = ActivityPub.unfollow(follower, followed)
+
+      assert activity.data["type"] == "Undo"
+      assert activity.data["actor"] == follower.ap_id
+
+      embedded_object = activity.data["object"]
+      assert is_map(embedded_object)
+      assert embedded_object["type"] == "Follow"
+      assert embedded_object["object"] == followed.ap_id
+      assert embedded_object["id"] == follow_activity.data["id"]
+    end
   end
 
   describe "blocking / unblocking" do
+    test "reverts block activity on error" do
+      [blocker, blocked] = insert_list(2, :user)
+
+      with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
+        assert {:error, :reverted} = ActivityPub.block(blocker, blocked)
+      end
+
+      assert Repo.aggregate(Activity, :count, :id) == 0
+      assert Repo.aggregate(Object, :count, :id) == 0
+    end
+
     test "creates a block activity" do
       blocker = insert(:user)
       blocked = insert(:user)
@@ -1136,6 +1362,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       assert activity.data["object"] == blocked.ap_id
     end
 
+    test "reverts unblock activity on error" do
+      [blocker, blocked] = insert_list(2, :user)
+      {:ok, block_activity} = ActivityPub.block(blocker, blocked)
+
+      with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
+        assert {:error, :reverted} = ActivityPub.unblock(blocker, blocked)
+      end
+
+      assert block_activity.data["type"] == "Block"
+      assert block_activity.data["actor"] == blocker.ap_id
+
+      assert Repo.aggregate(Activity, :count, :id) == 1
+      assert Repo.aggregate(Object, :count, :id) == 1
+    end
+
     test "creates an undo activity for the last block" do
       blocker = insert(:user)
       blocked = insert(:user)
@@ -1155,6 +1396,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
   end
 
   describe "deletion" do
+    clear_config([:instance, :rewrite_policy])
+
+    test "it reverts deletion on error" do
+      note = insert(:note_activity)
+      object = Object.normalize(note)
+
+      with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
+        assert {:error, :reverted} = ActivityPub.delete(object)
+      end
+
+      assert Repo.aggregate(Activity, :count, :id) == 1
+      assert Repo.get(Object, object.id) == object
+      assert Activity.get_by_id(note.id) == note
+    end
+
     test "it creates a delete activity and deletes the original object" do
       note = insert(:note_activity)
       object = Object.normalize(note)
@@ -1256,6 +1512,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
       assert object.data["repliesCount"] == 0
     end
+
+    test "it passes delete activity through MRF before deleting the object" do
+      Pleroma.Config.put([:instance, :rewrite_policy], Pleroma.Web.ActivityPub.MRF.DropPolicy)
+
+      note = insert(:note_activity)
+      object = Object.normalize(note)
+
+      {:error, {:reject, _}} = ActivityPub.delete(object)
+
+      assert Activity.get_by_id(note.id)
+      assert Repo.get(Object, object.id).data["type"] == object.data["type"]
+    end
   end
 
   describe "timeline post-processing" do
@@ -1312,6 +1580,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
   end
 
   describe "update" do
+    clear_config([:instance, :max_pinned_statuses])
+
     test "it creates an update activity with the new user data" do
       user = insert(:user)
       {:ok, user} = User.ensure_keys_present(user)
@@ -1334,7 +1604,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
   end
 
   test "returned pinned statuses" do
-    Pleroma.Config.put([:instance, :max_pinned_statuses], 3)
+    Config.put([:instance, :max_pinned_statuses], 3)
     user = insert(:user)
 
     {:ok, activity_one} = CommonAPI.post(user, %{"status" => "HI!!!"})
@@ -1572,6 +1842,73 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       assert follow_info.following_count == 32
       assert follow_info.hide_follows == true
     end
+
+    test "doesn't crash when follower and following counters are hidden" do
+      mock(fn env ->
+        case env.url do
+          "http://localhost:4001/users/masto_hidden_counters/following" ->
+            json(%{
+              "@context" => "https://www.w3.org/ns/activitystreams",
+              "id" => "http://localhost:4001/users/masto_hidden_counters/followers"
+            })
+
+          "http://localhost:4001/users/masto_hidden_counters/following?page=1" ->
+            %Tesla.Env{status: 403, body: ""}
+
+          "http://localhost:4001/users/masto_hidden_counters/followers" ->
+            json(%{
+              "@context" => "https://www.w3.org/ns/activitystreams",
+              "id" => "http://localhost:4001/users/masto_hidden_counters/following"
+            })
+
+          "http://localhost:4001/users/masto_hidden_counters/followers?page=1" ->
+            %Tesla.Env{status: 403, body: ""}
+        end
+      end)
+
+      user =
+        insert(:user,
+          local: false,
+          follower_address: "http://localhost:4001/users/masto_hidden_counters/followers",
+          following_address: "http://localhost:4001/users/masto_hidden_counters/following"
+        )
+
+      {:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user)
+
+      assert follow_info.hide_followers == true
+      assert follow_info.follower_count == 0
+      assert follow_info.hide_follows == true
+      assert follow_info.following_count == 0
+    end
+  end
+
+  describe "fetch_favourites/3" do
+    test "returns a favourite activities sorted by adds to favorite" do
+      user = insert(:user)
+      other_user = insert(:user)
+      user1 = insert(:user)
+      user2 = insert(:user)
+      {:ok, a1} = CommonAPI.post(user1, %{"status" => "bla"})
+      {:ok, _a2} = CommonAPI.post(user2, %{"status" => "traps are happy"})
+      {:ok, a3} = CommonAPI.post(user2, %{"status" => "Trees Are "})
+      {:ok, a4} = CommonAPI.post(user2, %{"status" => "Agent Smith "})
+      {:ok, a5} = CommonAPI.post(user1, %{"status" => "Red or Blue "})
+
+      {:ok, _} = CommonAPI.favorite(user, a4.id)
+      {:ok, _} = CommonAPI.favorite(other_user, a3.id)
+      {:ok, _} = CommonAPI.favorite(user, a3.id)
+      {:ok, _} = CommonAPI.favorite(other_user, a5.id)
+      {:ok, _} = CommonAPI.favorite(user, a5.id)
+      {:ok, _} = CommonAPI.favorite(other_user, a4.id)
+      {:ok, _} = CommonAPI.favorite(user, a1.id)
+      {:ok, _} = CommonAPI.favorite(other_user, a1.id)
+      result = ActivityPub.fetch_favourites(user)
+
+      assert Enum.map(result, & &1.id) == [a1.id, a5.id, a3.id, a4.id]
+
+      result = ActivityPub.fetch_favourites(user, %{"limit" => 2})
+      assert Enum.map(result, & &1.id) == [a1.id, a5.id]
+    end
   end
 
   describe "Move activity" do
@@ -1619,10 +1956,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
       activity = %Activity{activity | object: nil}
 
       assert [%Notification{activity: ^activity}] =
-               Notification.for_user_since(follower, ~N[2019-04-13 11:22:33])
+               Notification.for_user(follower, %{with_move: true})
 
       assert [%Notification{activity: ^activity}] =
-               Notification.for_user_since(follower_move_opted_out, ~N[2019-04-13 11:22:33])
+               Notification.for_user(follower_move_opted_out, %{with_move: true})
     end
 
     test "old user must be in the new user's `also_known_as` list" do