Delete pending follow requests on user deletion
[akkoma] / test / user_test.exs
index 3582b193da7913015fbb1538cce6aa45782863c5..d68b4a58c3bd431cc45cc1753ab0aac2fe11a7a4 100644 (file)
@@ -1,5 +1,5 @@
 # Pleroma: A lightweight social networking server
 # Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.UserTest do
 # SPDX-License-Identifier: AGPL-3.0-only
 
 defmodule Pleroma.UserTest do
@@ -7,21 +7,128 @@ defmodule Pleroma.UserTest do
   alias Pleroma.Builders.UserBuilder
   alias Pleroma.Object
   alias Pleroma.Repo
   alias Pleroma.Builders.UserBuilder
   alias Pleroma.Object
   alias Pleroma.Repo
+  alias Pleroma.Tests.ObanHelpers
   alias Pleroma.User
   alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.CommonAPI
 
   use Pleroma.DataCase
   alias Pleroma.User
   alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.CommonAPI
 
   use Pleroma.DataCase
+  use Oban.Testing, repo: Pleroma.Repo
 
   import Pleroma.Factory
 
   import Pleroma.Factory
-  import Mock
+  import ExUnit.CaptureLog
 
   setup_all do
     Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
     :ok
   end
 
 
   setup_all do
     Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
     :ok
   end
 
-  clear_config([:instance, :account_activation_required])
+  setup do: clear_config([:instance, :account_activation_required])
+
+  describe "service actors" do
+    test "returns updated invisible actor" do
+      uri = "#{Pleroma.Web.Endpoint.url()}/relay"
+      followers_uri = "#{uri}/followers"
+
+      insert(
+        :user,
+        %{
+          nickname: "relay",
+          invisible: false,
+          local: true,
+          ap_id: uri,
+          follower_address: followers_uri
+        }
+      )
+
+      actor = User.get_or_create_service_actor_by_ap_id(uri, "relay")
+      assert actor.invisible
+    end
+
+    test "returns relay user" do
+      uri = "#{Pleroma.Web.Endpoint.url()}/relay"
+      followers_uri = "#{uri}/followers"
+
+      assert %User{
+               nickname: "relay",
+               invisible: true,
+               local: true,
+               ap_id: ^uri,
+               follower_address: ^followers_uri
+             } = User.get_or_create_service_actor_by_ap_id(uri, "relay")
+
+      assert capture_log(fn ->
+               refute User.get_or_create_service_actor_by_ap_id("/relay", "relay")
+             end) =~ "Cannot create service actor:"
+    end
+
+    test "returns invisible actor" do
+      uri = "#{Pleroma.Web.Endpoint.url()}/internal/fetch-test"
+      followers_uri = "#{uri}/followers"
+      user = User.get_or_create_service_actor_by_ap_id(uri, "internal.fetch-test")
+
+      assert %User{
+               nickname: "internal.fetch-test",
+               invisible: true,
+               local: true,
+               ap_id: ^uri,
+               follower_address: ^followers_uri
+             } = user
+
+      user2 = User.get_or_create_service_actor_by_ap_id(uri, "internal.fetch-test")
+      assert user.id == user2.id
+    end
+  end
+
+  describe "AP ID user relationships" do
+    setup do
+      {:ok, user: insert(:user)}
+    end
+
+    test "outgoing_relationships_ap_ids/1", %{user: user} do
+      rel_types = [:block, :mute, :notification_mute, :reblog_mute, :inverse_subscription]
+
+      ap_ids_by_rel =
+        Enum.into(
+          rel_types,
+          %{},
+          fn rel_type ->
+            rel_records =
+              insert_list(2, :user_relationship, %{source: user, relationship_type: rel_type})
+
+            ap_ids = Enum.map(rel_records, fn rr -> Repo.preload(rr, :target).target.ap_id end)
+            {rel_type, Enum.sort(ap_ids)}
+          end
+        )
+
+      assert ap_ids_by_rel[:block] == Enum.sort(User.blocked_users_ap_ids(user))
+      assert ap_ids_by_rel[:block] == Enum.sort(Enum.map(User.blocked_users(user), & &1.ap_id))
+
+      assert ap_ids_by_rel[:mute] == Enum.sort(User.muted_users_ap_ids(user))
+      assert ap_ids_by_rel[:mute] == Enum.sort(Enum.map(User.muted_users(user), & &1.ap_id))
+
+      assert ap_ids_by_rel[:notification_mute] ==
+               Enum.sort(User.notification_muted_users_ap_ids(user))
+
+      assert ap_ids_by_rel[:notification_mute] ==
+               Enum.sort(Enum.map(User.notification_muted_users(user), & &1.ap_id))
+
+      assert ap_ids_by_rel[:reblog_mute] == Enum.sort(User.reblog_muted_users_ap_ids(user))
+
+      assert ap_ids_by_rel[:reblog_mute] ==
+               Enum.sort(Enum.map(User.reblog_muted_users(user), & &1.ap_id))
+
+      assert ap_ids_by_rel[:inverse_subscription] == Enum.sort(User.subscriber_users_ap_ids(user))
+
+      assert ap_ids_by_rel[:inverse_subscription] ==
+               Enum.sort(Enum.map(User.subscriber_users(user), & &1.ap_id))
+
+      outgoing_relationships_ap_ids = User.outgoing_relationships_ap_ids(user, rel_types)
+
+      assert ap_ids_by_rel ==
+               Enum.into(outgoing_relationships_ap_ids, %{}, fn {k, v} -> {k, Enum.sort(v)} end)
+    end
+  end
 
   describe "when tags are nil" do
     test "tagging a user" do
 
   describe "when tags are nil" do
     test "tagging a user" do
@@ -66,41 +173,41 @@ defmodule Pleroma.UserTest do
 
   test "returns all pending follow requests" do
     unlocked = insert(:user)
 
   test "returns all pending follow requests" do
     unlocked = insert(:user)
-    locked = insert(:user, %{info: %{locked: true}})
+    locked = insert(:user, locked: true)
     follower = insert(:user)
 
     CommonAPI.follow(follower, unlocked)
     CommonAPI.follow(follower, locked)
 
     follower = insert(:user)
 
     CommonAPI.follow(follower, unlocked)
     CommonAPI.follow(follower, locked)
 
-    assert {:ok, []} = User.get_follow_requests(unlocked)
-    assert {:ok, [activity]} = User.get_follow_requests(locked)
+    assert [] = User.get_follow_requests(unlocked)
+    assert [activity] = User.get_follow_requests(locked)
 
     assert activity
   end
 
   test "doesn't return already accepted or duplicate follow requests" do
 
     assert activity
   end
 
   test "doesn't return already accepted or duplicate follow requests" do
-    locked = insert(:user, %{info: %{locked: true}})
+    locked = insert(:user, locked: true)
     pending_follower = insert(:user)
     accepted_follower = insert(:user)
 
     CommonAPI.follow(pending_follower, locked)
     CommonAPI.follow(pending_follower, locked)
     CommonAPI.follow(accepted_follower, locked)
     pending_follower = insert(:user)
     accepted_follower = insert(:user)
 
     CommonAPI.follow(pending_follower, locked)
     CommonAPI.follow(pending_follower, locked)
     CommonAPI.follow(accepted_follower, locked)
-    User.follow(accepted_follower, locked)
 
 
-    assert {:ok, [activity]} = User.get_follow_requests(locked)
-    assert activity
+    Pleroma.FollowingRelationship.update(accepted_follower, locked, :follow_accept)
+
+    assert [^pending_follower] = User.get_follow_requests(locked)
   end
 
   test "clears follow requests when requester is blocked" do
   end
 
   test "clears follow requests when requester is blocked" do
-    followed = insert(:user, %{info: %{locked: true}})
+    followed = insert(:user, locked: true)
     follower = insert(:user)
 
     CommonAPI.follow(follower, followed)
     follower = insert(:user)
 
     CommonAPI.follow(follower, followed)
-    assert {:ok, [_activity]} = User.get_follow_requests(followed)
+    assert [_activity] = User.get_follow_requests(followed)
 
 
-    {:ok, _follower} = User.block(followed, follower)
-    assert {:ok, []} = User.get_follow_requests(followed)
+    {:ok, _user_relationship} = User.block(followed, follower)
+    assert [] = User.get_follow_requests(followed)
   end
 
   test "follow_all follows mutliple users" do
   end
 
   test "follow_all follows mutliple users" do
@@ -112,8 +219,8 @@ defmodule Pleroma.UserTest do
     not_followed = insert(:user)
     reverse_blocked = insert(:user)
 
     not_followed = insert(:user)
     reverse_blocked = insert(:user)
 
-    {:ok, user} = User.block(user, blocked)
-    {:ok, reverse_blocked} = User.block(reverse_blocked, user)
+    {:ok, _user_relationship} = User.block(user, blocked)
+    {:ok, _user_relationship} = User.block(reverse_blocked, user)
 
     {:ok, user} = User.follow(user, followed_zero)
 
 
     {:ok, user} = User.follow(user, followed_zero)
 
@@ -134,10 +241,10 @@ defmodule Pleroma.UserTest do
     followed_two = insert(:user)
 
     {:ok, user} = User.follow_all(user, [followed_zero, followed_one])
     followed_two = insert(:user)
 
     {:ok, user} = User.follow_all(user, [followed_zero, followed_one])
-    assert length(user.following) == 3
+    assert length(User.following(user)) == 3
 
     {:ok, user} = User.follow_all(user, [followed_one, followed_two])
 
     {:ok, user} = User.follow_all(user, [followed_one, followed_two])
-    assert length(user.following) == 4
+    assert length(User.following(user)) == 4
   end
 
   test "follow takes a user and another user" do
   end
 
   test "follow takes a user and another user" do
@@ -147,16 +254,17 @@ defmodule Pleroma.UserTest do
     {:ok, user} = User.follow(user, followed)
 
     user = User.get_cached_by_id(user.id)
     {:ok, user} = User.follow(user, followed)
 
     user = User.get_cached_by_id(user.id)
-
     followed = User.get_cached_by_ap_id(followed.ap_id)
     followed = User.get_cached_by_ap_id(followed.ap_id)
-    assert followed.info.follower_count == 1
 
 
-    assert User.ap_followers(followed) in user.following
+    assert followed.follower_count == 1
+    assert user.following_count == 1
+
+    assert User.ap_followers(followed) in User.following(user)
   end
 
   test "can't follow a deactivated users" do
     user = insert(:user)
   end
 
   test "can't follow a deactivated users" do
     user = insert(:user)
-    followed = insert(:user, info: %{deactivated: true})
+    followed = insert(:user, %{deactivated: true})
 
     {:error, _} = User.follow(user, followed)
   end
 
     {:error, _} = User.follow(user, followed)
   end
@@ -165,7 +273,7 @@ defmodule Pleroma.UserTest do
     blocker = insert(:user)
     blockee = insert(:user)
 
     blocker = insert(:user)
     blockee = insert(:user)
 
-    {:ok, blocker} = User.block(blocker, blockee)
+    {:ok, _user_relationship} = User.block(blocker, blockee)
 
     {:error, _} = User.follow(blockee, blocker)
   end
 
     {:error, _} = User.follow(blockee, blocker)
   end
@@ -174,47 +282,22 @@ defmodule Pleroma.UserTest do
     blocker = insert(:user)
     blocked = insert(:user)
 
     blocker = insert(:user)
     blocked = insert(:user)
 
-    {:ok, blocker} = User.block(blocker, blocked)
+    {:ok, _user_relationship} = User.block(blocker, blocked)
 
     {:error, _} = User.subscribe(blocked, blocker)
   end
 
   test "local users do not automatically follow local locked accounts" do
 
     {:error, _} = User.subscribe(blocked, blocker)
   end
 
   test "local users do not automatically follow local locked accounts" do
-    follower = insert(:user, info: %{locked: true})
-    followed = insert(:user, info: %{locked: true})
+    follower = insert(:user, locked: true)
+    followed = insert(:user, locked: true)
 
     {:ok, follower} = User.maybe_direct_follow(follower, followed)
 
     refute User.following?(follower, followed)
   end
 
 
     {:ok, follower} = User.maybe_direct_follow(follower, followed)
 
     refute User.following?(follower, followed)
   end
 
-  # This is a somewhat useless test.
-  # test "following a remote user will ensure a websub subscription is present" do
-  #   user = insert(:user)
-  #   {:ok, followed} = OStatus.make_user("shp@social.heldscal.la")
-
-  #   assert followed.local == false
-
-  #   {:ok, user} = User.follow(user, followed)
-  #   assert User.ap_followers(followed) in user.following
-
-  #   query = from w in WebsubClientSubscription,
-  #   where: w.topic == ^followed.info["topic"]
-  #   websub = Repo.one(query)
-
-  #   assert websub
-  # end
-
   describe "unfollow/2" do
   describe "unfollow/2" do
-    setup do
-      setting = Pleroma.Config.get([:instance, :external_user_synchronization])
-
-      on_exit(fn ->
-        Pleroma.Config.put([:instance, :external_user_synchronization], setting)
-      end)
-
-      :ok
-    end
+    setup do: clear_config([:instance, :external_user_synchronization])
 
     test "unfollow with syncronizes external user" do
       Pleroma.Config.put([:instance, :external_user_synchronization], true)
 
     test "unfollow with syncronizes external user" do
       Pleroma.Config.put([:instance, :external_user_synchronization], true)
@@ -233,26 +316,29 @@ defmodule Pleroma.UserTest do
           nickname: "fuser2",
           ap_id: "http://localhost:4001/users/fuser2",
           follower_address: "http://localhost:4001/users/fuser2/followers",
           nickname: "fuser2",
           ap_id: "http://localhost:4001/users/fuser2",
           follower_address: "http://localhost:4001/users/fuser2/followers",
-          following_address: "http://localhost:4001/users/fuser2/following",
-          following: [User.ap_followers(followed)]
+          following_address: "http://localhost:4001/users/fuser2/following"
         })
 
         })
 
+      {:ok, user} = User.follow(user, followed, :follow_accept)
+
       {:ok, user, _activity} = User.unfollow(user, followed)
 
       user = User.get_cached_by_id(user.id)
 
       {:ok, user, _activity} = User.unfollow(user, followed)
 
       user = User.get_cached_by_id(user.id)
 
-      assert user.following == []
+      assert User.following(user) == []
     end
 
     test "unfollow takes a user and another user" do
       followed = insert(:user)
     end
 
     test "unfollow takes a user and another user" do
       followed = insert(:user)
-      user = insert(:user, %{following: [User.ap_followers(followed)]})
+      user = insert(:user)
 
 
-      {:ok, user, _activity} = User.unfollow(user, followed)
+      {:ok, user} = User.follow(user, followed, :follow_accept)
 
 
-      user = User.get_cached_by_id(user.id)
+      assert User.following(user) == [user.follower_address, followed.follower_address]
+
+      {:ok, user, _activity} = User.unfollow(user, followed)
 
 
-      assert user.following == []
+      assert User.following(user) == [user.follower_address]
     end
 
     test "unfollow doesn't unfollow yourself" do
     end
 
     test "unfollow doesn't unfollow yourself" do
@@ -260,14 +346,14 @@ defmodule Pleroma.UserTest do
 
       {:error, _} = User.unfollow(user, user)
 
 
       {:error, _} = User.unfollow(user, user)
 
-      user = User.get_cached_by_id(user.id)
-      assert user.following == [user.ap_id]
+      assert User.following(user) == [user.follower_address]
     end
   end
 
   test "test if a user is following another user" do
     followed = insert(:user)
     end
   end
 
   test "test if a user is following another user" do
     followed = insert(:user)
-    user = insert(:user, %{following: [User.ap_followers(followed)]})
+    user = insert(:user)
+    User.follow(user, followed, :follow_accept)
 
     assert User.following?(user, followed)
     refute User.following?(followed, user)
 
     assert User.following?(user, followed)
     refute User.following?(followed, user)
@@ -289,9 +375,9 @@ defmodule Pleroma.UserTest do
       password_confirmation: "test",
       email: "email@example.com"
     }
       password_confirmation: "test",
       email: "email@example.com"
     }
-    clear_config([:instance, :autofollowed_nicknames])
-    clear_config([:instance, :welcome_message])
-    clear_config([:instance, :welcome_user_nickname])
+    setup do: clear_config([:instance, :autofollowed_nicknames])
+    setup do: clear_config([:instance, :welcome_message])
+    setup do: clear_config([:instance, :welcome_user_nickname])
 
     test "it autofollows accounts that are set for it" do
       user = insert(:user)
 
     test "it autofollows accounts that are set for it" do
       user = insert(:user)
@@ -325,7 +411,11 @@ defmodule Pleroma.UserTest do
       assert activity.actor == welcome_user.ap_id
     end
 
       assert activity.actor == welcome_user.ap_id
     end
 
-    test "it requires an email, name, nickname and password, bio is optional" do
+    setup do: clear_config([:instance, :account_activation_required])
+
+    test "it requires an email, name, nickname and password, bio is optional when account_activation_required is enabled" do
+      Pleroma.Config.put([:instance, :account_activation_required], true)
+
       @full_user_data
       |> Map.keys()
       |> Enum.each(fn key ->
       @full_user_data
       |> Map.keys()
       |> Enum.each(fn key ->
@@ -336,6 +426,19 @@ defmodule Pleroma.UserTest do
       end)
     end
 
       end)
     end
 
+    test "it requires an name, nickname and password, bio and email are optional when account_activation_required is disabled" do
+      Pleroma.Config.put([:instance, :account_activation_required], false)
+
+      @full_user_data
+      |> Map.keys()
+      |> Enum.each(fn key ->
+        params = Map.delete(@full_user_data, key)
+        changeset = User.register_changeset(%User{}, params)
+
+        assert if key in [:bio, :email], do: changeset.valid?, else: not changeset.valid?
+      end)
+    end
+
     test "it restricts certain nicknames" do
       [restricted_name | _] = Pleroma.Config.get([User, :restricted_nicknames])
 
     test "it restricts certain nicknames" do
       [restricted_name | _] = Pleroma.Config.get([User, :restricted_nicknames])
 
@@ -350,7 +453,7 @@ defmodule Pleroma.UserTest do
       refute changeset.valid?
     end
 
       refute changeset.valid?
     end
 
-    test "it sets the password_hash, ap_id and following fields" do
+    test "it sets the password_hash and ap_id" do
       changeset = User.register_changeset(%User{}, @full_user_data)
 
       assert changeset.valid?
       changeset = User.register_changeset(%User{}, @full_user_data)
 
       assert changeset.valid?
@@ -358,24 +461,8 @@ defmodule Pleroma.UserTest do
       assert is_binary(changeset.changes[:password_hash])
       assert changeset.changes[:ap_id] == User.ap_id(%User{nickname: @full_user_data.nickname})
 
       assert is_binary(changeset.changes[:password_hash])
       assert changeset.changes[:ap_id] == User.ap_id(%User{nickname: @full_user_data.nickname})
 
-      assert changeset.changes[:following] == [
-               User.ap_followers(%User{nickname: @full_user_data.nickname})
-             ]
-
       assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
     end
       assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
     end
-
-    test "it ensures info is not nil" do
-      changeset = User.register_changeset(%User{}, @full_user_data)
-
-      assert changeset.valid?
-
-      {:ok, user} =
-        changeset
-        |> Repo.insert()
-
-      refute is_nil(user.info)
-    end
   end
 
   describe "user registration, with :account_activation_required" do
   end
 
   describe "user registration, with :account_activation_required" do
@@ -387,10 +474,7 @@ defmodule Pleroma.UserTest do
       password_confirmation: "test",
       email: "email@example.com"
     }
       password_confirmation: "test",
       email: "email@example.com"
     }
-
-    clear_config([:instance, :account_activation_required]) do
-      Pleroma.Config.put([:instance, :account_activation_required], true)
-    end
+    setup do: clear_config([:instance, :account_activation_required], true)
 
     test "it creates unconfirmed user" do
       changeset = User.register_changeset(%User{}, @full_user_data)
 
     test "it creates unconfirmed user" do
       changeset = User.register_changeset(%User{}, @full_user_data)
@@ -398,8 +482,8 @@ defmodule Pleroma.UserTest do
 
       {:ok, user} = Repo.insert(changeset)
 
 
       {:ok, user} = Repo.insert(changeset)
 
-      assert user.info.confirmation_pending
-      assert user.info.confirmation_token
+      assert user.confirmation_pending
+      assert user.confirmation_token
     end
 
     test "it creates confirmed user if :confirmed option is given" do
     end
 
     test "it creates confirmed user if :confirmed option is given" do
@@ -408,8 +492,8 @@ defmodule Pleroma.UserTest do
 
       {:ok, user} = Repo.insert(changeset)
 
 
       {:ok, user} = Repo.insert(changeset)
 
-      refute user.info.confirmation_pending
-      refute user.info.confirmation_token
+      refute user.confirmation_pending
+      refute user.confirmation_token
     end
   end
 
     end
   end
 
@@ -429,8 +513,7 @@ defmodule Pleroma.UserTest do
           :user,
           local: false,
           nickname: "admin@mastodon.example.org",
           :user,
           local: false,
           nickname: "admin@mastodon.example.org",
-          ap_id: ap_id,
-          info: %{}
+          ap_id: ap_id
         )
 
       {:ok, fetched_user} = User.get_or_fetch(ap_id)
         )
 
       {:ok, fetched_user} = User.get_or_fetch(ap_id)
@@ -472,11 +555,7 @@ defmodule Pleroma.UserTest do
       assert user == fetched_user
     end
 
       assert user == fetched_user
     end
 
-    test "fetches an external user via ostatus if no user exists" do
-      {:ok, fetched_user} = User.get_or_fetch_by_nickname("shp@social.heldscal.la")
-      assert fetched_user.nickname == "shp@social.heldscal.la"
-    end
-
+    @tag capture_log: true
     test "returns nil if no user could be fetched" do
       {:error, fetched_user} = User.get_or_fetch_by_nickname("nonexistant@social.heldscal.la")
       assert fetched_user == "not found nonexistant@social.heldscal.la"
     test "returns nil if no user could be fetched" do
       {:error, fetched_user} = User.get_or_fetch_by_nickname("nonexistant@social.heldscal.la")
       assert fetched_user == "not found nonexistant@social.heldscal.la"
@@ -496,24 +575,44 @@ defmodule Pleroma.UserTest do
           local: false,
           nickname: "admin@mastodon.example.org",
           ap_id: "http://mastodon.example.org/users/admin",
           local: false,
           nickname: "admin@mastodon.example.org",
           ap_id: "http://mastodon.example.org/users/admin",
-          last_refreshed_at: a_week_ago,
-          info: %{}
+          last_refreshed_at: a_week_ago
         )
 
       assert orig_user.last_refreshed_at == a_week_ago
 
       {:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
         )
 
       assert orig_user.last_refreshed_at == a_week_ago
 
       {:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
-      assert user.info.source_data["endpoints"]
+
+      assert user.inbox
 
       refute user.last_refreshed_at == orig_user.last_refreshed_at
     end
 
       refute user.last_refreshed_at == orig_user.last_refreshed_at
     end
+
+    @tag capture_log: true
+    test "it returns the old user if stale, but unfetchable" do
+      a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)
+
+      orig_user =
+        insert(
+          :user,
+          local: false,
+          nickname: "admin@mastodon.example.org",
+          ap_id: "http://mastodon.example.org/users/raymoo",
+          last_refreshed_at: a_week_ago
+        )
+
+      assert orig_user.last_refreshed_at == a_week_ago
+
+      {:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/raymoo")
+
+      assert user.last_refreshed_at == orig_user.last_refreshed_at
+    end
   end
 
   test "returns an ap_id for a user" do
     user = insert(:user)
 
     assert User.ap_id(user) ==
   end
 
   test "returns an ap_id for a user" do
     user = insert(:user)
 
     assert User.ap_id(user) ==
-             Pleroma.Web.Router.Helpers.o_status_url(
+             Pleroma.Web.Router.Helpers.user_feed_url(
                Pleroma.Web.Endpoint,
                :feed_redirect,
                user.nickname
                Pleroma.Web.Endpoint,
                :feed_redirect,
                user.nickname
@@ -524,49 +623,47 @@ defmodule Pleroma.UserTest do
     user = insert(:user)
 
     assert User.ap_followers(user) ==
     user = insert(:user)
 
     assert User.ap_followers(user) ==
-             Pleroma.Web.Router.Helpers.o_status_url(
+             Pleroma.Web.Router.Helpers.user_feed_url(
                Pleroma.Web.Endpoint,
                :feed_redirect,
                user.nickname
              ) <> "/followers"
   end
 
                Pleroma.Web.Endpoint,
                :feed_redirect,
                user.nickname
              ) <> "/followers"
   end
 
-  describe "remote user creation changeset" do
+  describe "remote user changeset" do
     @valid_remote %{
       bio: "hello",
       name: "Someone",
       nickname: "a@b.de",
       ap_id: "http...",
     @valid_remote %{
       bio: "hello",
       name: "Someone",
       nickname: "a@b.de",
       ap_id: "http...",
-      info: %{some: "info"},
       avatar: %{some: "avatar"}
     }
       avatar: %{some: "avatar"}
     }
-
-    clear_config([:instance, :user_bio_length])
-    clear_config([:instance, :user_name_length])
+    setup do: clear_config([:instance, :user_bio_length])
+    setup do: clear_config([:instance, :user_name_length])
 
     test "it confirms validity" do
 
     test "it confirms validity" do
-      cs = User.remote_user_creation(@valid_remote)
+      cs = User.remote_user_changeset(@valid_remote)
       assert cs.valid?
     end
 
     test "it sets the follower_adress" do
       assert cs.valid?
     end
 
     test "it sets the follower_adress" do
-      cs = User.remote_user_creation(@valid_remote)
+      cs = User.remote_user_changeset(@valid_remote)
       # remote users get a fake local follower address
       assert cs.changes.follower_address ==
                User.ap_followers(%User{nickname: @valid_remote[:nickname]})
     end
 
     test "it enforces the fqn format for nicknames" do
       # remote users get a fake local follower address
       assert cs.changes.follower_address ==
                User.ap_followers(%User{nickname: @valid_remote[:nickname]})
     end
 
     test "it enforces the fqn format for nicknames" do
-      cs = User.remote_user_creation(%{@valid_remote | nickname: "bla"})
-      assert cs.changes.local == false
+      cs = User.remote_user_changeset(%{@valid_remote | nickname: "bla"})
+      assert Ecto.Changeset.get_field(cs, :local) == false
       assert cs.changes.avatar
       refute cs.valid?
     end
 
     test "it has required fields" do
       assert cs.changes.avatar
       refute cs.valid?
     end
 
     test "it has required fields" do
-      [:name, :ap_id]
+      [:ap_id]
       |> Enum.each(fn field ->
       |> Enum.each(fn field ->
-        cs = User.remote_user_creation(Map.delete(@valid_remote, field))
+        cs = User.remote_user_changeset(Map.delete(@valid_remote, field))
         refute cs.valid?
       end)
     end
         refute cs.valid?
       end)
     end
@@ -582,7 +679,7 @@ defmodule Pleroma.UserTest do
       {:ok, follower_one} = User.follow(follower_one, user)
       {:ok, follower_two} = User.follow(follower_two, user)
 
       {:ok, follower_one} = User.follow(follower_one, user)
       {:ok, follower_two} = User.follow(follower_two, user)
 
-      {:ok, res} = User.get_followers(user)
+      res = User.get_followers(user)
 
       assert Enum.member?(res, follower_one)
       assert Enum.member?(res, follower_two)
 
       assert Enum.member?(res, follower_one)
       assert Enum.member?(res, follower_two)
@@ -598,7 +695,7 @@ defmodule Pleroma.UserTest do
       {:ok, user} = User.follow(user, followed_one)
       {:ok, user} = User.follow(user, followed_two)
 
       {:ok, user} = User.follow(user, followed_one)
       {:ok, user} = User.follow(user, followed_two)
 
-      {:ok, res} = User.get_friends(user)
+      res = User.get_friends(user)
 
       followed_one = User.get_cached_by_ap_id(followed_one.ap_id)
       followed_two = User.get_cached_by_ap_id(followed_two.ap_id)
 
       followed_one = User.get_cached_by_ap_id(followed_one.ap_id)
       followed_two = User.get_cached_by_ap_id(followed_two.ap_id)
@@ -609,94 +706,63 @@ defmodule Pleroma.UserTest do
   end
 
   describe "updating note and follower count" do
   end
 
   describe "updating note and follower count" do
-    test "it sets the info->note_count property" do
+    test "it sets the note_count property" do
       note = insert(:note)
 
       user = User.get_cached_by_ap_id(note.data["actor"])
 
       note = insert(:note)
 
       user = User.get_cached_by_ap_id(note.data["actor"])
 
-      assert user.info.note_count == 0
+      assert user.note_count == 0
 
       {:ok, user} = User.update_note_count(user)
 
 
       {:ok, user} = User.update_note_count(user)
 
-      assert user.info.note_count == 1
+      assert user.note_count == 1
     end
 
     end
 
-    test "it increases the info->note_count property" do
+    test "it increases the note_count property" do
       note = insert(:note)
       user = User.get_cached_by_ap_id(note.data["actor"])
 
       note = insert(:note)
       user = User.get_cached_by_ap_id(note.data["actor"])
 
-      assert user.info.note_count == 0
+      assert user.note_count == 0
 
       {:ok, user} = User.increase_note_count(user)
 
 
       {:ok, user} = User.increase_note_count(user)
 
-      assert user.info.note_count == 1
+      assert user.note_count == 1
 
       {:ok, user} = User.increase_note_count(user)
 
 
       {:ok, user} = User.increase_note_count(user)
 
-      assert user.info.note_count == 2
+      assert user.note_count == 2
     end
 
     end
 
-    test "it decreases the info->note_count property" do
+    test "it decreases the note_count property" do
       note = insert(:note)
       user = User.get_cached_by_ap_id(note.data["actor"])
 
       note = insert(:note)
       user = User.get_cached_by_ap_id(note.data["actor"])
 
-      assert user.info.note_count == 0
+      assert user.note_count == 0
 
       {:ok, user} = User.increase_note_count(user)
 
 
       {:ok, user} = User.increase_note_count(user)
 
-      assert user.info.note_count == 1
+      assert user.note_count == 1
 
       {:ok, user} = User.decrease_note_count(user)
 
 
       {:ok, user} = User.decrease_note_count(user)
 
-      assert user.info.note_count == 0
+      assert user.note_count == 0
 
       {:ok, user} = User.decrease_note_count(user)
 
 
       {:ok, user} = User.decrease_note_count(user)
 
-      assert user.info.note_count == 0
+      assert user.note_count == 0
     end
 
     end
 
-    test "it sets the info->follower_count property" do
+    test "it sets the follower_count property" do
       user = insert(:user)
       follower = insert(:user)
 
       User.follow(follower, user)
 
       user = insert(:user)
       follower = insert(:user)
 
       User.follow(follower, user)
 
-      assert user.info.follower_count == 0
+      assert user.follower_count == 0
 
       {:ok, user} = User.update_follower_count(user)
 
 
       {:ok, user} = User.update_follower_count(user)
 
-      assert user.info.follower_count == 1
-    end
-  end
-
-  describe "remove duplicates from following list" do
-    test "it removes duplicates" do
-      user = insert(:user)
-      follower = insert(:user)
-
-      {:ok, %User{following: following} = follower} = User.follow(follower, user)
-      assert length(following) == 2
-
-      {:ok, follower} =
-        follower
-        |> User.update_changeset(%{following: following ++ following})
-        |> Repo.update()
-
-      assert length(follower.following) == 4
-
-      {:ok, follower} = User.remove_duplicated_following(follower)
-      assert length(follower.following) == 2
-    end
-
-    test "it does nothing when following is uniq" do
-      user = insert(:user)
-      follower = insert(:user)
-
-      {:ok, follower} = User.follow(follower, user)
-      assert length(follower.following) == 2
-
-      {:ok, follower} = User.remove_duplicated_following(follower)
-      assert length(follower.following) == 2
+      assert user.follower_count == 1
     end
   end
 
     end
   end
 
@@ -709,7 +775,9 @@ defmodule Pleroma.UserTest do
         user3.nickname
       ]
 
         user3.nickname
       ]
 
-      result = User.follow_import(user1, identifiers)
+      {:ok, job} = User.follow_import(user1, identifiers)
+
+      assert {:ok, result} = ObanHelpers.perform(job)
       assert is_list(result)
       assert result == [user2, user3]
     end
       assert is_list(result)
       assert result == [user2, user3]
     end
@@ -723,7 +791,7 @@ defmodule Pleroma.UserTest do
       refute User.mutes?(user, muted_user)
       refute User.muted_notifications?(user, muted_user)
 
       refute User.mutes?(user, muted_user)
       refute User.muted_notifications?(user, muted_user)
 
-      {:ok, user} = User.mute(user, muted_user)
+      {:ok, _user_relationships} = User.mute(user, muted_user)
 
       assert User.mutes?(user, muted_user)
       assert User.muted_notifications?(user, muted_user)
 
       assert User.mutes?(user, muted_user)
       assert User.muted_notifications?(user, muted_user)
@@ -733,8 +801,8 @@ defmodule Pleroma.UserTest do
       user = insert(:user)
       muted_user = insert(:user)
 
       user = insert(:user)
       muted_user = insert(:user)
 
-      {:ok, user} = User.mute(user, muted_user)
-      {:ok, user} = User.unmute(user, muted_user)
+      {:ok, _user_relationships} = User.mute(user, muted_user)
+      {:ok, _user_mute} = User.unmute(user, muted_user)
 
       refute User.mutes?(user, muted_user)
       refute User.muted_notifications?(user, muted_user)
 
       refute User.mutes?(user, muted_user)
       refute User.muted_notifications?(user, muted_user)
@@ -747,7 +815,7 @@ defmodule Pleroma.UserTest do
       refute User.mutes?(user, muted_user)
       refute User.muted_notifications?(user, muted_user)
 
       refute User.mutes?(user, muted_user)
       refute User.muted_notifications?(user, muted_user)
 
-      {:ok, user} = User.mute(user, muted_user, false)
+      {:ok, _user_relationships} = User.mute(user, muted_user, false)
 
       assert User.mutes?(user, muted_user)
       refute User.muted_notifications?(user, muted_user)
 
       assert User.mutes?(user, muted_user)
       refute User.muted_notifications?(user, muted_user)
@@ -761,7 +829,7 @@ defmodule Pleroma.UserTest do
 
       refute User.blocks?(user, blocked_user)
 
 
       refute User.blocks?(user, blocked_user)
 
-      {:ok, user} = User.block(user, blocked_user)
+      {:ok, _user_relationship} = User.block(user, blocked_user)
 
       assert User.blocks?(user, blocked_user)
     end
 
       assert User.blocks?(user, blocked_user)
     end
@@ -770,8 +838,8 @@ defmodule Pleroma.UserTest do
       user = insert(:user)
       blocked_user = insert(:user)
 
       user = insert(:user)
       blocked_user = insert(:user)
 
-      {:ok, user} = User.block(user, blocked_user)
-      {:ok, user} = User.unblock(user, blocked_user)
+      {:ok, _user_relationship} = User.block(user, blocked_user)
+      {:ok, _user_block} = User.unblock(user, blocked_user)
 
       refute User.blocks?(user, blocked_user)
     end
 
       refute User.blocks?(user, blocked_user)
     end
@@ -786,7 +854,7 @@ defmodule Pleroma.UserTest do
       assert User.following?(blocker, blocked)
       assert User.following?(blocked, blocker)
 
       assert User.following?(blocker, blocked)
       assert User.following?(blocked, blocker)
 
-      {:ok, blocker} = User.block(blocker, blocked)
+      {:ok, _user_relationship} = User.block(blocker, blocked)
       blocked = User.get_cached_by_id(blocked.id)
 
       assert User.blocks?(blocker, blocked)
       blocked = User.get_cached_by_id(blocked.id)
 
       assert User.blocks?(blocker, blocked)
@@ -804,7 +872,7 @@ defmodule Pleroma.UserTest do
       assert User.following?(blocker, blocked)
       refute User.following?(blocked, blocker)
 
       assert User.following?(blocker, blocked)
       refute User.following?(blocked, blocker)
 
-      {:ok, blocker} = User.block(blocker, blocked)
+      {:ok, _user_relationship} = User.block(blocker, blocked)
       blocked = User.get_cached_by_id(blocked.id)
 
       assert User.blocks?(blocker, blocked)
       blocked = User.get_cached_by_id(blocked.id)
 
       assert User.blocks?(blocker, blocked)
@@ -822,7 +890,7 @@ defmodule Pleroma.UserTest do
       refute User.following?(blocker, blocked)
       assert User.following?(blocked, blocker)
 
       refute User.following?(blocker, blocked)
       assert User.following?(blocked, blocker)
 
-      {:ok, blocker} = User.block(blocker, blocked)
+      {:ok, _user_relationship} = User.block(blocker, blocked)
       blocked = User.get_cached_by_id(blocked.id)
 
       assert User.blocks?(blocker, blocked)
       blocked = User.get_cached_by_id(blocked.id)
 
       assert User.blocks?(blocker, blocked)
@@ -835,12 +903,12 @@ defmodule Pleroma.UserTest do
       blocker = insert(:user)
       blocked = insert(:user)
 
       blocker = insert(:user)
       blocked = insert(:user)
 
-      {:ok, blocker} = User.subscribe(blocked, blocker)
+      {:ok, _subscription} = User.subscribe(blocked, blocker)
 
       assert User.subscribed_to?(blocked, blocker)
       refute User.subscribed_to?(blocker, blocked)
 
 
       assert User.subscribed_to?(blocked, blocker)
       refute User.subscribed_to?(blocker, blocked)
 
-      {:ok, blocker} = User.block(blocker, blocked)
+      {:ok, _user_relationship} = User.block(blocker, blocked)
 
       assert User.blocks?(blocker, blocked)
       refute User.subscribed_to?(blocker, blocked)
 
       assert User.blocks?(blocker, blocked)
       refute User.subscribed_to?(blocker, blocked)
@@ -909,6 +977,16 @@ defmodule Pleroma.UserTest do
 
       refute User.blocks?(user, collateral_user)
     end
 
       refute User.blocks?(user, collateral_user)
     end
+
+    test "follows take precedence over domain blocks" do
+      user = insert(:user)
+      good_eggo = insert(:user, %{ap_id: "https://meanies.social/user/cuteposter"})
+
+      {:ok, user} = User.block_domain(user, "meanies.social")
+      {:ok, user} = User.follow(user, good_eggo)
+
+      refute User.blocks?(user, good_eggo)
+    end
   end
 
   describe "blocks_import" do
   end
 
   describe "blocks_import" do
@@ -920,56 +998,93 @@ defmodule Pleroma.UserTest do
         user3.nickname
       ]
 
         user3.nickname
       ]
 
-      result = User.blocks_import(user1, identifiers)
+      {:ok, job} = User.blocks_import(user1, identifiers)
+
+      assert {:ok, result} = ObanHelpers.perform(job)
       assert is_list(result)
       assert result == [user2, user3]
     end
   end
 
       assert is_list(result)
       assert result == [user2, user3]
     end
   end
 
-  test "get recipients from activity" do
-    actor = insert(:user)
-    user = insert(:user, local: true)
-    user_two = insert(:user, local: false)
-    addressed = insert(:user, local: true)
-    addressed_remote = insert(:user, local: false)
-
-    {:ok, activity} =
-      CommonAPI.post(actor, %{
-        "status" => "hey @#{addressed.nickname} @#{addressed_remote.nickname}"
-      })
-
-    assert Enum.map([actor, addressed], & &1.ap_id) --
-             Enum.map(User.get_recipients_from_activity(activity), & &1.ap_id) == []
-
-    {:ok, user} = User.follow(user, actor)
-    {:ok, _user_two} = User.follow(user_two, actor)
-    recipients = User.get_recipients_from_activity(activity)
-    assert length(recipients) == 3
-    assert user in recipients
-    assert addressed in recipients
+  describe "get_recipients_from_activity" do
+    test "works for announces" do
+      actor = insert(:user)
+      user = insert(:user, local: true)
+
+      {:ok, activity} = CommonAPI.post(actor, %{status: "hello"})
+      {:ok, announce} = CommonAPI.repeat(activity.id, user)
+
+      recipients = User.get_recipients_from_activity(announce)
+
+      assert user in recipients
+    end
+
+    test "get recipients" do
+      actor = insert(:user)
+      user = insert(:user, local: true)
+      user_two = insert(:user, local: false)
+      addressed = insert(:user, local: true)
+      addressed_remote = insert(:user, local: false)
+
+      {:ok, activity} =
+        CommonAPI.post(actor, %{
+          status: "hey @#{addressed.nickname} @#{addressed_remote.nickname}"
+        })
+
+      assert Enum.map([actor, addressed], & &1.ap_id) --
+               Enum.map(User.get_recipients_from_activity(activity), & &1.ap_id) == []
+
+      {:ok, user} = User.follow(user, actor)
+      {:ok, _user_two} = User.follow(user_two, actor)
+      recipients = User.get_recipients_from_activity(activity)
+      assert length(recipients) == 3
+      assert user in recipients
+      assert addressed in recipients
+    end
+
+    test "has following" do
+      actor = insert(:user)
+      user = insert(:user)
+      user_two = insert(:user)
+      addressed = insert(:user, local: true)
+
+      {:ok, activity} =
+        CommonAPI.post(actor, %{
+          status: "hey @#{addressed.nickname}"
+        })
+
+      assert Enum.map([actor, addressed], & &1.ap_id) --
+               Enum.map(User.get_recipients_from_activity(activity), & &1.ap_id) == []
+
+      {:ok, _actor} = User.follow(actor, user)
+      {:ok, _actor} = User.follow(actor, user_two)
+      recipients = User.get_recipients_from_activity(activity)
+      assert length(recipients) == 2
+      assert addressed in recipients
+    end
   end
 
   describe ".deactivate" do
     test "can de-activate then re-activate a user" do
       user = insert(:user)
   end
 
   describe ".deactivate" do
     test "can de-activate then re-activate a user" do
       user = insert(:user)
-      assert false == user.info.deactivated
+      assert false == user.deactivated
       {:ok, user} = User.deactivate(user)
       {:ok, user} = User.deactivate(user)
-      assert true == user.info.deactivated
+      assert true == user.deactivated
       {:ok, user} = User.deactivate(user, false)
       {:ok, user} = User.deactivate(user, false)
-      assert false == user.info.deactivated
+      assert false == user.deactivated
     end
 
     end
 
-    test "hide a user from followers " do
+    test "hide a user from followers" do
       user = insert(:user)
       user2 = insert(:user)
 
       {:ok, user} = User.follow(user, user2)
       {:ok, _user} = User.deactivate(user)
 
       user = insert(:user)
       user2 = insert(:user)
 
       {:ok, user} = User.follow(user, user2)
       {:ok, _user} = User.deactivate(user)
 
-      info = User.get_cached_user_info(user2)
+      user2 = User.get_cached_by_id(user2.id)
 
 
-      assert info.follower_count == 0
-      assert {:ok, []} = User.get_followers(user2)
+      assert user2.follower_count == 0
+      assert [] = User.get_followers(user2)
     end
 
     test "hide a user from friends" do
     end
 
     test "hide a user from friends" do
@@ -977,15 +1092,17 @@ defmodule Pleroma.UserTest do
       user2 = insert(:user)
 
       {:ok, user2} = User.follow(user2, user)
       user2 = insert(:user)
 
       {:ok, user2} = User.follow(user2, user)
+      assert user2.following_count == 1
       assert User.following_count(user2) == 1
 
       {:ok, _user} = User.deactivate(user)
 
       assert User.following_count(user2) == 1
 
       {:ok, _user} = User.deactivate(user)
 
-      info = User.get_cached_user_info(user2)
+      user2 = User.get_cached_by_id(user2.id)
 
 
-      assert info.following_count == 0
+      assert refresh_record(user2).following_count == 0
+      assert user2.following_count == 0
       assert User.following_count(user2) == 0
       assert User.following_count(user2) == 0
-      assert {:ok, []} = User.get_friends(user2)
+      assert [] = User.get_friends(user2)
     end
 
     test "hide a user's statuses from timelines and notifications" do
     end
 
     test "hide a user's statuses from timelines and notifications" do
@@ -994,7 +1111,7 @@ defmodule Pleroma.UserTest do
 
       {:ok, user2} = User.follow(user2, user)
 
 
       {:ok, user2} = User.follow(user2, user)
 
-      {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{user2.nickname}"})
+      {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{user2.nickname}"})
 
       activity = Repo.preload(activity, :bookmark)
 
 
       activity = Repo.preload(activity, :bookmark)
 
@@ -1004,7 +1121,9 @@ defmodule Pleroma.UserTest do
       assert [activity] == ActivityPub.fetch_public_activities(%{}) |> Repo.preload(:bookmark)
 
       assert [%{activity | thread_muted?: CommonAPI.thread_muted?(user2, activity)}] ==
       assert [activity] == ActivityPub.fetch_public_activities(%{}) |> Repo.preload(:bookmark)
 
       assert [%{activity | thread_muted?: CommonAPI.thread_muted?(user2, activity)}] ==
-               ActivityPub.fetch_activities([user2.ap_id | user2.following], %{"user" => user2})
+               ActivityPub.fetch_activities([user2.ap_id | User.following(user2)], %{
+                 "user" => user2
+               })
 
       {:ok, _user} = User.deactivate(user)
 
 
       {:ok, _user} = User.deactivate(user)
 
@@ -1012,7 +1131,9 @@ defmodule Pleroma.UserTest do
       assert [] == Pleroma.Notification.for_user(user2)
 
       assert [] ==
       assert [] == Pleroma.Notification.for_user(user2)
 
       assert [] ==
-               ActivityPub.fetch_activities([user2.ap_id | user2.following], %{"user" => user2})
+               ActivityPub.fetch_activities([user2.ap_id | User.following(user2)], %{
+                 "user" => user2
+               })
     end
   end
 
     end
   end
 
@@ -1023,45 +1144,43 @@ defmodule Pleroma.UserTest do
       [user: user]
     end
 
       [user: user]
     end
 
-    clear_config([:instance, :federating])
+    setup do: clear_config([:instance, :federating])
 
     test ".delete_user_activities deletes all create activities", %{user: user} do
 
     test ".delete_user_activities deletes all create activities", %{user: user} do
-      {:ok, activity} = CommonAPI.post(user, %{"status" => "2hu"})
+      {:ok, activity} = CommonAPI.post(user, %{status: "2hu"})
 
 
-      {:ok, _} = User.delete_user_activities(user)
+      User.delete_user_activities(user)
 
 
-      # TODO: Remove favorites, repeats, delete activities.
+      # TODO: Test removal favorites, repeats, delete activities.
       refute Activity.get_by_id(activity.id)
     end
 
       refute Activity.get_by_id(activity.id)
     end
 
-    test "it deletes deactivated user" do
-      {:ok, user} = insert(:user, info: %{deactivated: true}) |> User.set_cache()
-
-      assert {:ok, _} = User.delete(user)
-      refute User.get_by_id(user.id)
-    end
-
-    test "it deletes a user, all follow relationships and all activities", %{user: user} do
+    test "it deactivates a user, all follow relationships and all activities", %{user: user} do
       follower = insert(:user)
       {:ok, follower} = User.follow(follower, user)
 
       follower = insert(:user)
       {:ok, follower} = User.follow(follower, user)
 
+      locked_user = insert(:user, name: "locked", locked: true)
+      {:ok, _} = User.follow(user, locked_user, :follow_pending)
+
       object = insert(:note, user: user)
       activity = insert(:note_activity, user: user, note: object)
 
       object_two = insert(:note, user: follower)
       activity_two = insert(:note_activity, user: follower, note: object_two)
 
       object = insert(:note, user: user)
       activity = insert(:note_activity, user: user, note: object)
 
       object_two = insert(:note, user: follower)
       activity_two = insert(:note_activity, user: follower, note: object_two)
 
-      {:ok, like, _} = CommonAPI.favorite(activity_two.id, user)
-      {:ok, like_two, _} = CommonAPI.favorite(activity.id, follower)
-      {:ok, repeat, _} = CommonAPI.repeat(activity_two.id, user)
+      {:ok, like} = CommonAPI.favorite(user, activity_two.id)
+      {:ok, like_two} = CommonAPI.favorite(follower, activity.id)
+      {:ok, repeat} = CommonAPI.repeat(activity_two.id, user)
 
 
-      {:ok, _} = User.delete(user)
+      {:ok, job} = User.delete(user)
+      {:ok, _user} = ObanHelpers.perform(job)
 
       follower = User.get_cached_by_id(follower.id)
 
       refute User.following?(follower, user)
 
       follower = User.get_cached_by_id(follower.id)
 
       refute User.following?(follower, user)
-      refute User.get_by_id(user.id)
-      assert {:ok, nil} == Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
+      assert %{deactivated: true} = User.get_by_id(user.id)
+
+      assert [] == User.get_follow_requests(locked_user)
 
       user_activities =
         user.ap_id
 
       user_activities =
         user.ap_id
@@ -1076,85 +1195,37 @@ defmodule Pleroma.UserTest do
       refute Activity.get_by_id(like_two.id)
       refute Activity.get_by_id(repeat.id)
     end
       refute Activity.get_by_id(like_two.id)
       refute Activity.get_by_id(repeat.id)
     end
-
-    test_with_mock "it sends out User Delete activity",
-                   %{user: user},
-                   Pleroma.Web.ActivityPub.Publisher,
-                   [:passthrough],
-                   [] do
-      Pleroma.Config.put([:instance, :federating], true)
-
-      {:ok, follower} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
-      {:ok, _} = User.follow(follower, user)
-
-      {:ok, _user} = User.delete(user)
-
-      assert called(
-               Pleroma.Web.ActivityPub.Publisher.publish_one(%{
-                 inbox: "http://mastodon.example.org/inbox"
-               })
-             )
-    end
-  end
-
-  test "get_public_key_for_ap_id fetches a user that's not in the db" do
-    assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
   end
 
   end
 
-  describe "insert or update a user from given data" do
-    test "with normal data" do
-      user = insert(:user, %{nickname: "nick@name.de"})
-      data = %{ap_id: user.ap_id <> "xxx", name: user.name, nickname: user.nickname}
-
-      assert {:ok, %User{}} = User.insert_or_update_user(data)
+  describe "delete/1 when confirmation is pending" do
+    setup do
+      user = insert(:user, confirmation_pending: true)
+      {:ok, user: user}
     end
 
     end
 
-    test "with overly long fields" do
-      current_max_length = Pleroma.Config.get([:instance, :account_field_value_length], 255)
-      user = insert(:user, nickname: "nickname@supergood.domain")
+    test "deletes user from database when activation required", %{user: user} do
+      clear_config([:instance, :account_activation_required], true)
 
 
-      data = %{
-        ap_id: user.ap_id,
-        name: user.name,
-        nickname: user.nickname,
-        info: %{
-          fields: [
-            %{"name" => "myfield", "value" => String.duplicate("h", current_max_length + 1)}
-          ]
-        }
-      }
+      {:ok, job} = User.delete(user)
+      {:ok, _} = ObanHelpers.perform(job)
 
 
-      assert {:ok, %User{}} = User.insert_or_update_user(data)
+      refute User.get_cached_by_id(user.id)
+      refute User.get_by_id(user.id)
     end
 
     end
 
-    test "with an overly long bio" do
-      current_max_length = Pleroma.Config.get([:instance, :user_bio_length], 5000)
-      user = insert(:user, nickname: "nickname@supergood.domain")
+    test "deactivates user when activation is not required", %{user: user} do
+      clear_config([:instance, :account_activation_required], false)
 
 
-      data = %{
-        ap_id: user.ap_id,
-        name: user.name,
-        nickname: user.nickname,
-        bio: String.duplicate("h", current_max_length + 1),
-        info: %{}
-      }
+      {:ok, job} = User.delete(user)
+      {:ok, _} = ObanHelpers.perform(job)
 
 
-      assert {:ok, %User{}} = User.insert_or_update_user(data)
+      assert %{deactivated: true} = User.get_cached_by_id(user.id)
+      assert %{deactivated: true} = User.get_by_id(user.id)
     end
     end
+  end
 
 
-    test "with an overly long display name" do
-      current_max_length = Pleroma.Config.get([:instance, :user_name_length], 100)
-      user = insert(:user, nickname: "nickname@supergood.domain")
-
-      data = %{
-        ap_id: user.ap_id,
-        name: String.duplicate("h", current_max_length + 1),
-        nickname: user.nickname,
-        info: %{}
-      }
-
-      assert {:ok, %User{}} = User.insert_or_update_user(data)
-    end
+  test "get_public_key_for_ap_id fetches a user that's not in the db" do
+    assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
   end
 
   describe "per-user rich-text filtering" do
   end
 
   describe "per-user rich-text filtering" do
@@ -1165,7 +1236,7 @@ defmodule Pleroma.UserTest do
     end
 
     test "html_filter_policy returns TwitterText scrubber when rich-text is disabled" do
     end
 
     test "html_filter_policy returns TwitterText scrubber when rich-text is disabled" do
-      user = insert(:user, %{info: %{no_rich_text: true}})
+      user = insert(:user, no_rich_text: true)
 
       assert Pleroma.HTML.Scrubber.TwitterText == User.html_filter_policy(user)
     end
 
       assert Pleroma.HTML.Scrubber.TwitterText == User.html_filter_policy(user)
     end
@@ -1174,19 +1245,19 @@ defmodule Pleroma.UserTest do
   describe "caching" do
     test "invalidate_cache works" do
       user = insert(:user)
   describe "caching" do
     test "invalidate_cache works" do
       user = insert(:user)
-      _user_info = User.get_cached_user_info(user)
 
 
+      User.set_cache(user)
       User.invalidate_cache(user)
 
       {:ok, nil} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
       {:ok, nil} = Cachex.get(:user_cache, "nickname:#{user.nickname}")
       User.invalidate_cache(user)
 
       {:ok, nil} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
       {:ok, nil} = Cachex.get(:user_cache, "nickname:#{user.nickname}")
-      {:ok, nil} = Cachex.get(:user_cache, "user_info:#{user.id}")
     end
 
     test "User.delete() plugs any possible zombie objects" do
       user = insert(:user)
 
     end
 
     test "User.delete() plugs any possible zombie objects" do
       user = insert(:user)
 
-      {:ok, _} = User.delete(user)
+      {:ok, job} = User.delete(user)
+      {:ok, _} = ObanHelpers.perform(job)
 
       {:ok, cached_user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
 
 
       {:ok, cached_user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
 
@@ -1198,16 +1269,35 @@ defmodule Pleroma.UserTest do
     end
   end
 
     end
   end
 
-  test "auth_active?/1 works correctly" do
-    Pleroma.Config.put([:instance, :account_activation_required], true)
+  describe "account_status/1" do
+    setup do: clear_config([:instance, :account_activation_required])
 
 
-    local_user = insert(:user, local: true, info: %{confirmation_pending: true})
-    confirmed_user = insert(:user, local: true, info: %{confirmation_pending: false})
-    remote_user = insert(:user, local: false)
+    test "return confirmation_pending for unconfirm user" do
+      Pleroma.Config.put([:instance, :account_activation_required], true)
+      user = insert(:user, confirmation_pending: true)
+      assert User.account_status(user) == :confirmation_pending
+    end
 
 
-    refute User.auth_active?(local_user)
-    assert User.auth_active?(confirmed_user)
-    assert User.auth_active?(remote_user)
+    test "return active for confirmed user" do
+      Pleroma.Config.put([:instance, :account_activation_required], true)
+      user = insert(:user, confirmation_pending: false)
+      assert User.account_status(user) == :active
+    end
+
+    test "return active for remote user" do
+      user = insert(:user, local: false)
+      assert User.account_status(user) == :active
+    end
+
+    test "returns :password_reset_pending for user with reset password" do
+      user = insert(:user, password_reset_pending: true)
+      assert User.account_status(user) == :password_reset_pending
+    end
+
+    test "returns :deactivated for deactivated user" do
+      user = insert(:user, local: true, confirmation_pending: false, deactivated: true)
+      assert User.account_status(user) == :deactivated
+    end
   end
 
   describe "superuser?/1" do
   end
 
   describe "superuser?/1" do
@@ -1219,25 +1309,39 @@ defmodule Pleroma.UserTest do
 
     test "returns false for remote users" do
       user = insert(:user, local: false)
 
     test "returns false for remote users" do
       user = insert(:user, local: false)
-      remote_admin_user = insert(:user, local: false, info: %{is_admin: true})
+      remote_admin_user = insert(:user, local: false, is_admin: true)
 
       refute User.superuser?(user)
       refute User.superuser?(remote_admin_user)
     end
 
     test "returns true for local moderators" do
 
       refute User.superuser?(user)
       refute User.superuser?(remote_admin_user)
     end
 
     test "returns true for local moderators" do
-      user = insert(:user, local: true, info: %{is_moderator: true})
+      user = insert(:user, local: true, is_moderator: true)
 
       assert User.superuser?(user)
     end
 
     test "returns true for local admins" do
 
       assert User.superuser?(user)
     end
 
     test "returns true for local admins" do
-      user = insert(:user, local: true, info: %{is_admin: true})
+      user = insert(:user, local: true, is_admin: true)
 
       assert User.superuser?(user)
     end
   end
 
 
       assert User.superuser?(user)
     end
   end
 
+  describe "invisible?/1" do
+    test "returns true for an invisible user" do
+      user = insert(:user, local: true, invisible: true)
+
+      assert User.invisible?(user)
+    end
+
+    test "returns false for a non-invisible user" do
+      user = insert(:user, local: true)
+
+      refute User.invisible?(user)
+    end
+  end
+
   describe "visible_for?/2" do
     test "returns true when the account is itself" do
       user = insert(:user, local: true)
   describe "visible_for?/2" do
     test "returns true when the account is itself" do
       user = insert(:user, local: true)
@@ -1248,14 +1352,14 @@ defmodule Pleroma.UserTest do
     test "returns false when the account is unauthenticated and auth is required" do
       Pleroma.Config.put([:instance, :account_activation_required], true)
 
     test "returns false when the account is unauthenticated and auth is required" do
       Pleroma.Config.put([:instance, :account_activation_required], true)
 
-      user = insert(:user, local: true, info: %{confirmation_pending: true})
+      user = insert(:user, local: true, confirmation_pending: true)
       other_user = insert(:user, local: true)
 
       refute User.visible_for?(user, other_user)
     end
 
     test "returns true when the account is unauthenticated and auth is not required" do
       other_user = insert(:user, local: true)
 
       refute User.visible_for?(user, other_user)
     end
 
     test "returns true when the account is unauthenticated and auth is not required" do
-      user = insert(:user, local: true, info: %{confirmation_pending: true})
+      user = insert(:user, local: true, confirmation_pending: true)
       other_user = insert(:user, local: true)
 
       assert User.visible_for?(user, other_user)
       other_user = insert(:user, local: true)
 
       assert User.visible_for?(user, other_user)
@@ -1264,8 +1368,8 @@ defmodule Pleroma.UserTest do
     test "returns true when the account is unauthenticated and being viewed by a privileged account (auth required)" do
       Pleroma.Config.put([:instance, :account_activation_required], true)
 
     test "returns true when the account is unauthenticated and being viewed by a privileged account (auth required)" do
       Pleroma.Config.put([:instance, :account_activation_required], true)
 
-      user = insert(:user, local: true, info: %{confirmation_pending: true})
-      other_user = insert(:user, local: true, info: %{is_admin: true})
+      user = insert(:user, local: true, confirmation_pending: true)
+      other_user = insert(:user, local: true, is_admin: true)
 
       assert User.visible_for?(user, other_user)
     end
 
       assert User.visible_for?(user, other_user)
     end
@@ -1278,9 +1382,9 @@ defmodule Pleroma.UserTest do
       bio = "A.k.a. @nick@domain.com"
 
       expected_text =
       bio = "A.k.a. @nick@domain.com"
 
       expected_text =
-        "A.k.a. <span class='h-card'><a data-user='#{remote_user.id}' class='u-url mention' href='#{
+        ~s(A.k.a. <span class="h-card"><a class="u-url mention" data-user="#{remote_user.id}" href="#{
           remote_user.ap_id
           remote_user.ap_id
-        }'>@<span>nick@domain.com</span></a></span>"
+        }" rel="ugc">@<span>nick@domain.com</span></a></span>)
 
       assert expected_text == User.parse_bio(bio, user)
     end
 
       assert expected_text == User.parse_bio(bio, user)
     end
@@ -1312,9 +1416,10 @@ defmodule Pleroma.UserTest do
     {:ok, _follower2} = User.follow(follower2, user)
     {:ok, _follower3} = User.follow(follower3, user)
 
     {:ok, _follower2} = User.follow(follower2, user)
     {:ok, _follower3} = User.follow(follower3, user)
 
-    {:ok, user} = User.block(user, follower)
+    {:ok, _user_relationship} = User.block(user, follower)
+    user = refresh_record(user)
 
 
-    assert User.user_info(user).follower_count == 2
+    assert user.follower_count == 2
   end
 
   describe "list_inactive_users_query/1" do
   end
 
   describe "list_inactive_users_query/1" do
@@ -1331,7 +1436,7 @@ defmodule Pleroma.UserTest do
 
       users =
         Enum.map(1..total, fn _ ->
 
       users =
         Enum.map(1..total, fn _ ->
-          insert(:user, last_digest_emailed_at: days_ago(20), info: %{deactivated: false})
+          insert(:user, last_digest_emailed_at: days_ago(20), deactivated: false)
         end)
 
       inactive_users_ids =
         end)
 
       inactive_users_ids =
@@ -1349,7 +1454,7 @@ defmodule Pleroma.UserTest do
 
       users =
         Enum.map(1..total, fn _ ->
 
       users =
         Enum.map(1..total, fn _ ->
-          insert(:user, last_digest_emailed_at: days_ago(20), info: %{deactivated: false})
+          insert(:user, last_digest_emailed_at: days_ago(20), deactivated: false)
         end)
 
       {inactive, active} = Enum.split(users, trunc(total / 2))
         end)
 
       {inactive, active} = Enum.split(users, trunc(total / 2))
@@ -1359,7 +1464,7 @@ defmodule Pleroma.UserTest do
 
         {:ok, _} =
           CommonAPI.post(user, %{
 
         {:ok, _} =
           CommonAPI.post(user, %{
-            "status" => "hey @#{to.nickname}"
+            status: "hey @#{to.nickname}"
           })
       end)
 
           })
       end)
 
@@ -1382,7 +1487,7 @@ defmodule Pleroma.UserTest do
 
       users =
         Enum.map(1..total, fn _ ->
 
       users =
         Enum.map(1..total, fn _ ->
-          insert(:user, last_digest_emailed_at: days_ago(20), info: %{deactivated: false})
+          insert(:user, last_digest_emailed_at: days_ago(20), deactivated: false)
         end)
 
       [sender | recipients] = users
         end)
 
       [sender | recipients] = users
@@ -1391,12 +1496,12 @@ defmodule Pleroma.UserTest do
       Enum.each(recipients, fn to ->
         {:ok, _} =
           CommonAPI.post(sender, %{
       Enum.each(recipients, fn to ->
         {:ok, _} =
           CommonAPI.post(sender, %{
-            "status" => "hey @#{to.nickname}"
+            status: "hey @#{to.nickname}"
           })
 
         {:ok, _} =
           CommonAPI.post(sender, %{
           })
 
         {:ok, _} =
           CommonAPI.post(sender, %{
-            "status" => "hey again @#{to.nickname}"
+            status: "hey again @#{to.nickname}"
           })
       end)
 
           })
       end)
 
@@ -1422,19 +1527,19 @@ defmodule Pleroma.UserTest do
 
   describe "toggle_confirmation/1" do
     test "if user is confirmed" do
 
   describe "toggle_confirmation/1" do
     test "if user is confirmed" do
-      user = insert(:user, info: %{confirmation_pending: false})
+      user = insert(:user, confirmation_pending: false)
       {:ok, user} = User.toggle_confirmation(user)
 
       {:ok, user} = User.toggle_confirmation(user)
 
-      assert user.info.confirmation_pending
-      assert user.info.confirmation_token
+      assert user.confirmation_pending
+      assert user.confirmation_token
     end
 
     test "if user is unconfirmed" do
     end
 
     test "if user is unconfirmed" do
-      user = insert(:user, info: %{confirmation_pending: true, confirmation_token: "some token"})
+      user = insert(:user, confirmation_pending: true, confirmation_token: "some token")
       {:ok, user} = User.toggle_confirmation(user)
 
       {:ok, user} = User.toggle_confirmation(user)
 
-      refute user.info.confirmation_pending
-      refute user.info.confirmation_token
+      refute user.confirmation_pending
+      refute user.confirmation_token
     end
   end
 
     end
   end
 
@@ -1470,7 +1575,7 @@ defmodule Pleroma.UserTest do
       user1 = insert(:user, local: false, ap_id: "http://localhost:4001/users/masto_closed")
       user2 = insert(:user, local: false, ap_id: "http://localhost:4001/users/fuser2")
       insert(:user, local: true)
       user1 = insert(:user, local: false, ap_id: "http://localhost:4001/users/masto_closed")
       user2 = insert(:user, local: false, ap_id: "http://localhost:4001/users/fuser2")
       insert(:user, local: true)
-      insert(:user, local: false, info: %{deactivated: true})
+      insert(:user, local: false, deactivated: true)
       {:ok, user1: user1, user2: user2}
     end
 
       {:ok, user1: user1, user2: user2}
     end
 
@@ -1491,51 +1596,6 @@ defmodule Pleroma.UserTest do
     end
   end
 
     end
   end
 
-  describe "set_info_cache/2" do
-    setup do
-      user = insert(:user)
-      {:ok, user: user}
-    end
-
-    test "update from args", %{user: user} do
-      User.set_info_cache(user, %{following_count: 15, follower_count: 18})
-
-      %{follower_count: followers, following_count: following} = User.get_cached_user_info(user)
-      assert followers == 18
-      assert following == 15
-    end
-
-    test "without args", %{user: user} do
-      User.set_info_cache(user, %{})
-
-      %{follower_count: followers, following_count: following} = User.get_cached_user_info(user)
-      assert followers == 0
-      assert following == 0
-    end
-  end
-
-  describe "user_info/2" do
-    setup do
-      user = insert(:user)
-      {:ok, user: user}
-    end
-
-    test "update from args", %{user: user} do
-      %{follower_count: followers, following_count: following} =
-        User.user_info(user, %{following_count: 15, follower_count: 18})
-
-      assert followers == 18
-      assert following == 15
-    end
-
-    test "without args", %{user: user} do
-      %{follower_count: followers, following_count: following} = User.user_info(user)
-
-      assert followers == 0
-      assert following == 0
-    end
-  end
-
   describe "is_internal_user?/1" do
     test "non-internal user returns false" do
       user = insert(:user)
   describe "is_internal_user?/1" do
     test "non-internal user returns false" do
       user = insert(:user)
@@ -1578,7 +1638,7 @@ defmodule Pleroma.UserTest do
   end
 
   describe "following/followers synchronization" do
   end
 
   describe "following/followers synchronization" do
-    clear_config([:instance, :external_user_synchronization])
+    setup do: clear_config([:instance, :external_user_synchronization])
 
     test "updates the counters normally on following/getting a follow when disabled" do
       Pleroma.Config.put([:instance, :external_user_synchronization], false)
 
     test "updates the counters normally on following/getting a follow when disabled" do
       Pleroma.Config.put([:instance, :external_user_synchronization], false)
@@ -1589,17 +1649,17 @@ defmodule Pleroma.UserTest do
           local: false,
           follower_address: "http://localhost:4001/users/masto_closed/followers",
           following_address: "http://localhost:4001/users/masto_closed/following",
           local: false,
           follower_address: "http://localhost:4001/users/masto_closed/followers",
           following_address: "http://localhost:4001/users/masto_closed/following",
-          info: %{ap_enabled: true}
+          ap_enabled: true
         )
 
         )
 
-      assert User.user_info(other_user).following_count == 0
-      assert User.user_info(other_user).follower_count == 0
+      assert other_user.following_count == 0
+      assert other_user.follower_count == 0
 
       {:ok, user} = Pleroma.User.follow(user, other_user)
       other_user = Pleroma.User.get_by_id(other_user.id)
 
 
       {:ok, user} = Pleroma.User.follow(user, other_user)
       other_user = Pleroma.User.get_by_id(other_user.id)
 
-      assert User.user_info(user).following_count == 1
-      assert User.user_info(other_user).follower_count == 1
+      assert user.following_count == 1
+      assert other_user.follower_count == 1
     end
 
     test "syncronizes the counters with the remote instance for the followed when enabled" do
     end
 
     test "syncronizes the counters with the remote instance for the followed when enabled" do
@@ -1612,17 +1672,17 @@ defmodule Pleroma.UserTest do
           local: false,
           follower_address: "http://localhost:4001/users/masto_closed/followers",
           following_address: "http://localhost:4001/users/masto_closed/following",
           local: false,
           follower_address: "http://localhost:4001/users/masto_closed/followers",
           following_address: "http://localhost:4001/users/masto_closed/following",
-          info: %{ap_enabled: true}
+          ap_enabled: true
         )
 
         )
 
-      assert User.user_info(other_user).following_count == 0
-      assert User.user_info(other_user).follower_count == 0
+      assert other_user.following_count == 0
+      assert other_user.follower_count == 0
 
       Pleroma.Config.put([:instance, :external_user_synchronization], true)
       {:ok, _user} = User.follow(user, other_user)
       other_user = User.get_by_id(other_user.id)
 
 
       Pleroma.Config.put([:instance, :external_user_synchronization], true)
       {:ok, _user} = User.follow(user, other_user)
       other_user = User.get_by_id(other_user.id)
 
-      assert User.user_info(other_user).follower_count == 437
+      assert other_user.follower_count == 437
     end
 
     test "syncronizes the counters with the remote instance for the follower when enabled" do
     end
 
     test "syncronizes the counters with the remote instance for the follower when enabled" do
@@ -1635,16 +1695,16 @@ defmodule Pleroma.UserTest do
           local: false,
           follower_address: "http://localhost:4001/users/masto_closed/followers",
           following_address: "http://localhost:4001/users/masto_closed/following",
           local: false,
           follower_address: "http://localhost:4001/users/masto_closed/followers",
           following_address: "http://localhost:4001/users/masto_closed/following",
-          info: %{ap_enabled: true}
+          ap_enabled: true
         )
 
         )
 
-      assert User.user_info(other_user).following_count == 0
-      assert User.user_info(other_user).follower_count == 0
+      assert other_user.following_count == 0
+      assert other_user.follower_count == 0
 
       Pleroma.Config.put([:instance, :external_user_synchronization], true)
       {:ok, other_user} = User.follow(other_user, user)
 
 
       Pleroma.Config.put([:instance, :external_user_synchronization], true)
       {:ok, other_user} = User.follow(other_user, user)
 
-      assert User.user_info(other_user).following_count == 152
+      assert other_user.following_count == 152
     end
   end
 
     end
   end
 
@@ -1677,17 +1737,14 @@ defmodule Pleroma.UserTest do
 
   describe "get_cached_by_nickname_or_id" do
     setup do
 
   describe "get_cached_by_nickname_or_id" do
     setup do
-      limit_to_local_content = Pleroma.Config.get([:instance, :limit_to_local_content])
       local_user = insert(:user)
       remote_user = insert(:user, nickname: "nickname@example.com", local: false)
 
       local_user = insert(:user)
       remote_user = insert(:user, nickname: "nickname@example.com", local: false)
 
-      on_exit(fn ->
-        Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local_content)
-      end)
-
       [local_user: local_user, remote_user: remote_user]
     end
 
       [local_user: local_user, remote_user: remote_user]
     end
 
+    setup do: clear_config([:instance, :limit_to_local_content])
+
     test "allows getting remote users by id no matter what :limit_to_local_content is set to", %{
       remote_user: remote_user
     } do
     test "allows getting remote users by id no matter what :limit_to_local_content is set to", %{
       remote_user: remote_user
     } do
@@ -1731,4 +1788,30 @@ defmodule Pleroma.UserTest do
       assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
     end
   end
       assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
     end
   end
+
+  describe "update_email_notifications/2" do
+    setup do
+      user = insert(:user, email_notifications: %{"digest" => true})
+
+      {:ok, user: user}
+    end
+
+    test "Notifications are updated", %{user: user} do
+      true = user.email_notifications["digest"]
+      assert {:ok, result} = User.update_email_notifications(user, %{"digest" => false})
+      assert result.email_notifications["digest"] == false
+    end
+  end
+
+  test "avatar fallback" do
+    user = insert(:user)
+    assert User.avatar_url(user) =~ "/images/avi.png"
+
+    clear_config([:assets, :default_user_avatar], "avatar.png")
+
+    user = User.get_cached_by_nickname_or_id(user.nickname)
+    assert User.avatar_url(user) =~ "avatar.png"
+
+    assert User.avatar_url(user, no_default: true) == nil
+  end
 end
 end