Fix regex usage in MRF (#254)
[akkoma] / test / pleroma / user_test.exs
index 6449e4b4d6697ff6d5e591f5392604518c5326b9..195df2a03047231e9a95325af57ebe9306825565 100644 (file)
@@ -5,6 +5,7 @@
 defmodule Pleroma.UserTest do
   alias Pleroma.Activity
   alias Pleroma.Builders.UserBuilder
 defmodule Pleroma.UserTest do
   alias Pleroma.Activity
   alias Pleroma.Builders.UserBuilder
+  alias Pleroma.Notification
   alias Pleroma.Object
   alias Pleroma.Repo
   alias Pleroma.Tests.ObanHelpers
   alias Pleroma.Object
   alias Pleroma.Repo
   alias Pleroma.Tests.ObanHelpers
@@ -151,7 +152,7 @@ defmodule Pleroma.UserTest do
   test "ap_id returns the activity pub id for the user" do
     user = UserBuilder.build()
 
   test "ap_id returns the activity pub id for the user" do
     user = UserBuilder.build()
 
-    expected_ap_id = "#{Pleroma.Web.base_url()}/users/#{user.nickname}"
+    expected_ap_id = "#{Pleroma.Web.Endpoint.url()}/users/#{user.nickname}"
 
     assert expected_ap_id == User.ap_id(user)
   end
 
     assert expected_ap_id == User.ap_id(user)
   end
@@ -310,8 +311,8 @@ defmodule Pleroma.UserTest do
   describe "unfollow/2" do
     setup do: clear_config([:instance, :external_user_synchronization])
 
   describe "unfollow/2" do
     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 synchronizes external user" do
+      clear_config([:instance, :external_user_synchronization], true)
 
       followed =
         insert(:user,
 
       followed =
         insert(:user,
@@ -396,7 +397,7 @@ defmodule Pleroma.UserTest do
       user = insert(:user)
       remote_user = insert(:user, %{local: false})
 
       user = insert(:user)
       remote_user = insert(:user, %{local: false})
 
-      Pleroma.Config.put([:instance, :autofollowed_nicknames], [
+      clear_config([:instance, :autofollowed_nicknames], [
         user.nickname,
         remote_user.nickname
       ])
         user.nickname,
         remote_user.nickname
       ])
@@ -413,7 +414,7 @@ defmodule Pleroma.UserTest do
       user1 = insert(:user)
       user2 = insert(:user)
 
       user1 = insert(:user)
       user2 = insert(:user)
 
-      Pleroma.Config.put([:instance, :autofollowing_nicknames], [
+      clear_config([:instance, :autofollowing_nicknames], [
         user1.nickname,
         user2.nickname
       ])
         user1.nickname,
         user2.nickname
       ])
@@ -428,9 +429,9 @@ defmodule Pleroma.UserTest do
 
     test "it sends a welcome message if it is set" do
       welcome_user = insert(:user)
 
     test "it sends a welcome message if it is set" do
       welcome_user = insert(:user)
-      Pleroma.Config.put([:welcome, :direct_message, :enabled], true)
-      Pleroma.Config.put([:welcome, :direct_message, :sender_nickname], welcome_user.nickname)
-      Pleroma.Config.put([:welcome, :direct_message, :message], "Hello, this is a direct message")
+      clear_config([:welcome, :direct_message, :enabled], true)
+      clear_config([:welcome, :direct_message, :sender_nickname], welcome_user.nickname)
+      clear_config([:welcome, :direct_message, :message], "Hello, this is a direct message")
 
       cng = User.register_changeset(%User{}, @full_user_data)
       {:ok, registered_user} = User.register(cng)
 
       cng = User.register_changeset(%User{}, @full_user_data)
       {:ok, registered_user} = User.register(cng)
@@ -442,34 +443,21 @@ defmodule Pleroma.UserTest do
       assert activity.actor == welcome_user.ap_id
     end
 
       assert activity.actor == welcome_user.ap_id
     end
 
-    test "it sends a welcome chat message if it is set" do
-      welcome_user = insert(:user)
-      Pleroma.Config.put([:welcome, :chat_message, :enabled], true)
-      Pleroma.Config.put([:welcome, :chat_message, :sender_nickname], welcome_user.nickname)
-      Pleroma.Config.put([:welcome, :chat_message, :message], "Hello, this is a chat message")
-
-      cng = User.register_changeset(%User{}, @full_user_data)
-      {:ok, registered_user} = User.register(cng)
-      ObanHelpers.perform_all()
-
-      activity = Repo.one(Pleroma.Activity)
-      assert registered_user.ap_id in activity.recipients
-      assert Object.normalize(activity, fetch: false).data["content"] =~ "chat message"
-      assert activity.actor == welcome_user.ap_id
-    end
-
     setup do:
     setup do:
-            clear_config(:mrf_simple,
-              media_removal: [],
-              media_nsfw: [],
-              federated_timeline_removal: [],
-              report_removal: [],
-              reject: [],
-              followers_only: [],
-              accept: [],
-              avatar_removal: [],
-              banner_removal: [],
-              reject_deletes: []
+            clear_config(
+              [:mrf_simple],
+              %{
+                media_removal: [],
+                media_nsfw: [],
+                federated_timeline_removal: [],
+                report_removal: [],
+                reject: [],
+                followers_only: [],
+                accept: [],
+                avatar_removal: [],
+                banner_removal: [],
+                reject_deletes: []
+              }
             )
 
     setup do:
             )
 
     setup do:
@@ -479,30 +467,12 @@ defmodule Pleroma.UserTest do
               ]
             )
 
               ]
             )
 
-    test "it sends a welcome chat message when Simple policy applied to local instance" do
-      Pleroma.Config.put([:mrf_simple, :media_nsfw], ["localhost"])
-
-      welcome_user = insert(:user)
-      Pleroma.Config.put([:welcome, :chat_message, :enabled], true)
-      Pleroma.Config.put([:welcome, :chat_message, :sender_nickname], welcome_user.nickname)
-      Pleroma.Config.put([:welcome, :chat_message, :message], "Hello, this is a chat message")
-
-      cng = User.register_changeset(%User{}, @full_user_data)
-      {:ok, registered_user} = User.register(cng)
-      ObanHelpers.perform_all()
-
-      activity = Repo.one(Pleroma.Activity)
-      assert registered_user.ap_id in activity.recipients
-      assert Object.normalize(activity, fetch: false).data["content"] =~ "chat message"
-      assert activity.actor == welcome_user.ap_id
-    end
-
     test "it sends a welcome email message if it is set" do
       welcome_user = insert(:user)
     test "it sends a welcome email message if it is set" do
       welcome_user = insert(:user)
-      Pleroma.Config.put([:welcome, :email, :enabled], true)
-      Pleroma.Config.put([:welcome, :email, :sender], welcome_user.email)
+      clear_config([:welcome, :email, :enabled], true)
+      clear_config([:welcome, :email, :sender], welcome_user.email)
 
 
-      Pleroma.Config.put(
+      clear_config(
         [:welcome, :email, :subject],
         "Hello, welcome to cool site: <%= instance_name %>"
       )
         [:welcome, :email, :subject],
         "Hello, welcome to cool site: <%= instance_name %>"
       )
@@ -522,7 +492,7 @@ defmodule Pleroma.UserTest do
     end
 
     test "it sends a confirm email" do
     end
 
     test "it sends a confirm email" do
-      Pleroma.Config.put([:instance, :account_activation_required], true)
+      clear_config([:instance, :account_activation_required], true)
 
       cng = User.register_changeset(%User{}, @full_user_data)
       {:ok, registered_user} = User.register(cng)
 
       cng = User.register_changeset(%User{}, @full_user_data)
       {:ok, registered_user} = User.register(cng)
@@ -551,8 +521,47 @@ defmodule Pleroma.UserTest do
       )
     end
 
       )
     end
 
+    test "it sends a registration confirmed email if no others will be sent" do
+      clear_config([:welcome, :email, :enabled], false)
+      clear_config([:instance, :account_activation_required], false)
+      clear_config([:instance, :account_approval_required], false)
+
+      {:ok, user} =
+        User.register_changeset(%User{}, @full_user_data)
+        |> User.register()
+
+      ObanHelpers.perform_all()
+
+      instance_name = Pleroma.Config.get([:instance, :name])
+      sender = Pleroma.Config.get([:instance, :notify_email])
+
+      assert_email_sent(
+        from: {instance_name, sender},
+        to: {user.name, user.email},
+        subject: "Account registered on #{instance_name}"
+      )
+    end
+
+    test "it fails gracefully with invalid email config" do
+      cng = User.register_changeset(%User{}, @full_user_data)
+
+      # Disable the mailer but enable all the things that want to send emails
+      clear_config([Pleroma.Emails.Mailer, :enabled], false)
+      clear_config([:instance, :account_activation_required], true)
+      clear_config([:instance, :account_approval_required], true)
+      clear_config([:welcome, :email, :enabled], true)
+      clear_config([:welcome, :email, :sender], "lain@lain.com")
+
+      # The user is still created
+      assert {:ok, %User{nickname: "nick"}} = User.register(cng)
+
+      # No emails are sent
+      ObanHelpers.perform_all()
+      refute_email_sent()
+    end
+
     test "it requires an email, name, nickname and password, bio is optional when account_activation_required is enabled" do
     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)
+      clear_config([:instance, :account_activation_required], true)
 
       @full_user_data
       |> Map.keys()
 
       @full_user_data
       |> Map.keys()
@@ -565,7 +574,7 @@ defmodule Pleroma.UserTest do
     end
 
     test "it requires an name, nickname and password, bio and email are optional when account_activation_required is disabled" do
     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)
+      clear_config([:instance, :account_activation_required], false)
 
       @full_user_data
       |> Map.keys()
 
       @full_user_data
       |> Map.keys()
@@ -614,26 +623,18 @@ defmodule Pleroma.UserTest do
       assert changeset.valid?
     end
 
       assert changeset.valid?
     end
 
-    test "it sets the password_hash and ap_id" do
+    test "it sets the password_hash, ap_id, private key and followers collection address" do
       changeset = User.register_changeset(%User{}, @full_user_data)
 
       assert changeset.valid?
 
       assert is_binary(changeset.changes[:password_hash])
       changeset = User.register_changeset(%User{}, @full_user_data)
 
       assert changeset.valid?
 
       assert is_binary(changeset.changes[:password_hash])
+      assert is_binary(changeset.changes[:keys])
       assert changeset.changes[:ap_id] == User.ap_id(%User{nickname: @full_user_data.nickname})
       assert changeset.changes[:ap_id] == User.ap_id(%User{nickname: @full_user_data.nickname})
-
+      assert is_binary(changeset.changes[:keys])
       assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
     end
 
       assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
     end
 
-    test "it sets the 'accepts_chat_messages' set to true" do
-      changeset = User.register_changeset(%User{}, @full_user_data)
-      assert changeset.valid?
-
-      {:ok, user} = Repo.insert(changeset)
-
-      assert user.accepts_chat_messages
-    end
-
     test "it creates a confirmed user" do
       changeset = User.register_changeset(%User{}, @full_user_data)
       assert changeset.valid?
     test "it creates a confirmed user" do
       changeset = User.register_changeset(%User{}, @full_user_data)
       assert changeset.valid?
@@ -739,6 +740,123 @@ defmodule Pleroma.UserTest do
       freshed_user = refresh_record(user)
       assert freshed_user == fetched_user
     end
       freshed_user = refresh_record(user)
       assert freshed_user == fetched_user
     end
+
+    test "gets an existing user by nickname starting with http" do
+      user = insert(:user, nickname: "httpssome")
+      {:ok, fetched_user} = User.get_or_fetch("httpssome")
+
+      assert user == fetched_user
+    end
+  end
+
+  describe "get_or_fetch/1 remote users with tld, while BE is runned on subdomain" do
+    setup do: clear_config([Pleroma.Web.WebFinger, :update_nickname_on_user_fetch], true)
+
+    test "for mastodon" do
+      Tesla.Mock.mock(fn
+        %{url: "https://example.com/.well-known/host-meta"} ->
+          %Tesla.Env{
+            status: 302,
+            headers: [{"location", "https://sub.example.com/.well-known/host-meta"}]
+          }
+
+        %{url: "https://sub.example.com/.well-known/host-meta"} ->
+          %Tesla.Env{
+            status: 200,
+            body:
+              "test/fixtures/webfinger/masto-host-meta.xml"
+              |> File.read!()
+              |> String.replace("{{domain}}", "sub.example.com")
+          }
+
+        %{url: "https://sub.example.com/.well-known/webfinger?resource=acct:a@example.com"} ->
+          %Tesla.Env{
+            status: 200,
+            body:
+              "test/fixtures/webfinger/masto-webfinger.json"
+              |> File.read!()
+              |> String.replace("{{nickname}}", "a")
+              |> String.replace("{{domain}}", "example.com")
+              |> String.replace("{{subdomain}}", "sub.example.com"),
+            headers: [{"content-type", "application/jrd+json"}]
+          }
+
+        %{url: "https://sub.example.com/users/a"} ->
+          %Tesla.Env{
+            status: 200,
+            body:
+              "test/fixtures/webfinger/masto-user.json"
+              |> File.read!()
+              |> String.replace("{{nickname}}", "a")
+              |> String.replace("{{domain}}", "sub.example.com"),
+            headers: [{"content-type", "application/activity+json"}]
+          }
+
+        %{url: "https://sub.example.com/users/a/collections/featured"} ->
+          %Tesla.Env{
+            status: 200,
+            body:
+              File.read!("test/fixtures/users_mock/masto_featured.json")
+              |> String.replace("{{domain}}", "sub.example.com")
+              |> String.replace("{{nickname}}", "a"),
+            headers: [{"content-type", "application/activity+json"}]
+          }
+      end)
+
+      ap_id = "a@example.com"
+      {:ok, fetched_user} = User.get_or_fetch(ap_id)
+
+      assert fetched_user.ap_id == "https://sub.example.com/users/a"
+      assert fetched_user.nickname == "a@example.com"
+    end
+
+    test "for pleroma" do
+      Tesla.Mock.mock(fn
+        %{url: "https://example.com/.well-known/host-meta"} ->
+          %Tesla.Env{
+            status: 302,
+            headers: [{"location", "https://sub.example.com/.well-known/host-meta"}]
+          }
+
+        %{url: "https://sub.example.com/.well-known/host-meta"} ->
+          %Tesla.Env{
+            status: 200,
+            body:
+              "test/fixtures/webfinger/pleroma-host-meta.xml"
+              |> File.read!()
+              |> String.replace("{{domain}}", "sub.example.com")
+          }
+
+        %{url: "https://sub.example.com/.well-known/webfinger?resource=acct:a@example.com"} ->
+          %Tesla.Env{
+            status: 200,
+            body:
+              "test/fixtures/webfinger/pleroma-webfinger.json"
+              |> File.read!()
+              |> String.replace("{{nickname}}", "a")
+              |> String.replace("{{domain}}", "example.com")
+              |> String.replace("{{subdomain}}", "sub.example.com"),
+            headers: [{"content-type", "application/jrd+json"}]
+          }
+
+        %{url: "https://sub.example.com/users/a"} ->
+          %Tesla.Env{
+            status: 200,
+            body:
+              "test/fixtures/webfinger/pleroma-user.json"
+              |> File.read!()
+              |> String.replace("{{nickname}}", "a")
+              |> String.replace("{{domain}}", "sub.example.com"),
+            headers: [{"content-type", "application/activity+json"}]
+          }
+      end)
+
+      ap_id = "a@example.com"
+      {:ok, fetched_user} = User.get_or_fetch(ap_id)
+
+      assert fetched_user.ap_id == "https://sub.example.com/users/a"
+      assert fetched_user.nickname == "a@example.com"
+    end
   end
 
   describe "fetching a user from nickname or trying to build one" do
   end
 
   describe "fetching a user from nickname or trying to build one" do
@@ -1209,7 +1327,7 @@ defmodule Pleroma.UserTest do
       collateral_user =
         insert(:user, %{ap_id: "https://another-awful-and-rude-instance.com/user/bully"})
 
       collateral_user =
         insert(:user, %{ap_id: "https://another-awful-and-rude-instance.com/user/bully"})
 
-      {:ok, user} = User.block_domain(user, "*.awful-and-rude-instance.com")
+      {:ok, user} = User.block_domain(user, "awful-and-rude-instance.com")
 
       refute User.blocks?(user, collateral_user)
     end
 
       refute User.blocks?(user, collateral_user)
     end
@@ -1227,7 +1345,7 @@ defmodule Pleroma.UserTest do
 
       user_domain = insert(:user, %{ap_id: "https://awful-and-rude-instance.com/user/bully"})
 
 
       user_domain = insert(:user, %{ap_id: "https://awful-and-rude-instance.com/user/bully"})
 
-      {:ok, user} = User.block_domain(user, "*.awful-and-rude-instance.com")
+      {:ok, user} = User.block_domain(user, "awful-and-rude-instance.com")
 
       assert User.blocks?(user, user_from_subdomain)
       assert User.blocks?(user, user_with_two_subdomains)
 
       assert User.blocks?(user, user_from_subdomain)
       assert User.blocks?(user, user_with_two_subdomains)
@@ -1563,31 +1681,15 @@ defmodule Pleroma.UserTest do
     end
   end
 
     end
   end
 
-  describe "delete/1 when confirmation is pending" do
-    setup do
-      user = insert(:user, is_confirmed: false)
-      {:ok, user: user}
-    end
+  test "delete/1 when confirmation is pending deletes the user" do
+    clear_config([:instance, :account_activation_required], true)
+    user = insert(:user, is_confirmed: false)
 
 
-    test "deletes user from database when activation required", %{user: user} do
-      clear_config([:instance, :account_activation_required], true)
-
-      {:ok, job} = User.delete(user)
-      {:ok, _} = ObanHelpers.perform(job)
-
-      refute User.get_cached_by_id(user.id)
-      refute User.get_by_id(user.id)
-    end
-
-    test "deactivates user when activation is not required", %{user: user} do
-      clear_config([:instance, :account_activation_required], false)
-
-      {:ok, job} = User.delete(user)
-      {:ok, _} = ObanHelpers.perform(job)
+    {:ok, job} = User.delete(user)
+    {:ok, _} = ObanHelpers.perform(job)
 
 
-      assert %{is_active: false} = User.get_cached_by_id(user.id)
-      assert %{is_active: false} = User.get_by_id(user.id)
-    end
+    refute User.get_cached_by_id(user.id)
+    refute User.get_by_id(user.id)
   end
 
   test "delete/1 when approval is pending deletes the user" do
   end
 
   test "delete/1 when approval is pending deletes the user" do
@@ -1616,9 +1718,9 @@ defmodule Pleroma.UserTest do
         follower_count: 9,
         following_count: 9001,
         is_locked: true,
         follower_count: 9,
         following_count: 9001,
         is_locked: true,
-        is_confirmed: false,
+        is_confirmed: true,
         password_reset_pending: true,
         password_reset_pending: true,
-        is_approved: false,
+        is_approved: true,
         registration_reason: "ahhhhh",
         confirmation_token: "qqqq",
         domain_blocks: ["lain.com"],
         registration_reason: "ahhhhh",
         confirmation_token: "qqqq",
         domain_blocks: ["lain.com"],
@@ -1646,8 +1748,8 @@ defmodule Pleroma.UserTest do
              email: nil,
              name: nil,
              password_hash: nil,
              email: nil,
              name: nil,
              password_hash: nil,
-             keys: nil,
-             public_key: nil,
+             keys: "RSA begin buplic key",
+             public_key: "--PRIVATE KEYE--",
              avatar: %{},
              tags: [],
              last_refreshed_at: nil,
              avatar: %{},
              tags: [],
              last_refreshed_at: nil,
@@ -1679,6 +1781,56 @@ defmodule Pleroma.UserTest do
            } = user
   end
 
            } = user
   end
 
+  test "delete/1 purges a remote user" do
+    user =
+      insert(:user, %{
+        name: "qqqqqqq",
+        avatar: %{"a" => "b"},
+        banner: %{"a" => "b"},
+        local: false
+      })
+
+    {:ok, job} = User.delete(user)
+    {:ok, _} = ObanHelpers.perform(job)
+    user = User.get_by_id(user.id)
+
+    assert user.name == nil
+    assert user.avatar == %{}
+    assert user.banner == %{}
+  end
+
+  describe "set_suggestion" do
+    test "suggests a user" do
+      user = insert(:user, is_suggested: false)
+      refute user.is_suggested
+      {:ok, user} = User.set_suggestion(user, true)
+      assert user.is_suggested
+    end
+
+    test "suggests a list of users" do
+      unsuggested_users = [
+        insert(:user, is_suggested: false),
+        insert(:user, is_suggested: false),
+        insert(:user, is_suggested: false)
+      ]
+
+      {:ok, users} = User.set_suggestion(unsuggested_users, true)
+
+      assert Enum.count(users) == 3
+
+      Enum.each(users, fn user ->
+        assert user.is_suggested
+      end)
+    end
+
+    test "unsuggests a user" do
+      user = insert(:user, is_suggested: true)
+      assert user.is_suggested
+      {:ok, user} = User.set_suggestion(user, false)
+      refute user.is_suggested
+    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
   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
@@ -1728,13 +1880,13 @@ defmodule Pleroma.UserTest do
     setup do: clear_config([:instance, :account_activation_required])
 
     test "return confirmation_pending for unconfirm user" do
     setup do: clear_config([:instance, :account_activation_required])
 
     test "return confirmation_pending for unconfirm user" do
-      Pleroma.Config.put([:instance, :account_activation_required], true)
+      clear_config([:instance, :account_activation_required], true)
       user = insert(:user, is_confirmed: false)
       assert User.account_status(user) == :confirmation_pending
     end
 
     test "return active for confirmed user" do
       user = insert(:user, is_confirmed: false)
       assert User.account_status(user) == :confirmation_pending
     end
 
     test "return active for confirmed user" do
-      Pleroma.Config.put([:instance, :account_activation_required], true)
+      clear_config([:instance, :account_activation_required], true)
       user = insert(:user, is_confirmed: true)
       assert User.account_status(user) == :active
     end
       user = insert(:user, is_confirmed: true)
       assert User.account_status(user) == :active
     end
@@ -1813,7 +1965,7 @@ defmodule Pleroma.UserTest do
     end
 
     test "returns false when the account is unconfirmed and confirmation is required" do
     end
 
     test "returns false when the account is unconfirmed and confirmation is required" do
-      Pleroma.Config.put([:instance, :account_activation_required], true)
+      clear_config([:instance, :account_activation_required], true)
 
       user = insert(:user, local: true, is_confirmed: false)
       other_user = insert(:user, local: true)
 
       user = insert(:user, local: true, is_confirmed: false)
       other_user = insert(:user, local: true)
@@ -1822,7 +1974,7 @@ defmodule Pleroma.UserTest do
     end
 
     test "returns true when the account is unconfirmed and confirmation is required but the account is remote" do
     end
 
     test "returns true when the account is unconfirmed and confirmation is required but the account is remote" do
-      Pleroma.Config.put([:instance, :account_activation_required], true)
+      clear_config([:instance, :account_activation_required], true)
 
       user = insert(:user, local: false, is_confirmed: false)
       other_user = insert(:user, local: true)
 
       user = insert(:user, local: false, is_confirmed: false)
       other_user = insert(:user, local: true)
@@ -1830,15 +1982,8 @@ defmodule Pleroma.UserTest do
       assert User.visible_for(user, other_user) == :visible
     end
 
       assert User.visible_for(user, other_user) == :visible
     end
 
-    test "returns true when the account is unconfirmed and confirmation is not required" do
-      user = insert(:user, local: true, is_confirmed: false)
-      other_user = insert(:user, local: true)
-
-      assert User.visible_for(user, other_user) == :visible
-    end
-
     test "returns true when the account is unconfirmed and being viewed by a privileged account (confirmation required)" do
     test "returns true when the account is unconfirmed and being viewed by a privileged account (confirmation required)" do
-      Pleroma.Config.put([:instance, :account_activation_required], true)
+      clear_config([:instance, :account_activation_required], true)
 
       user = insert(:user, local: true, is_confirmed: false)
       other_user = insert(:user, local: true, is_admin: true)
 
       user = insert(:user, local: true, is_confirmed: false)
       other_user = insert(:user, local: true, is_admin: true)
@@ -1854,9 +1999,7 @@ defmodule Pleroma.UserTest do
       bio = "A.k.a. @nick@domain.com"
 
       expected_text =
       bio = "A.k.a. @nick@domain.com"
 
       expected_text =
-        ~s(A.k.a. <span class="h-card"><a class="u-url mention" data-user="#{remote_user.id}" href="#{
-          remote_user.ap_id
-        }" rel="ugc">@<span>nick@domain.com</span></a></span>)
+        ~s(A.k.a. <span class="h-card"><a class="u-url mention" data-user="#{remote_user.id}" href="#{remote_user.ap_id}" 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
@@ -1997,21 +2140,6 @@ defmodule Pleroma.UserTest do
     end
   end
 
     end
   end
 
-  describe "ensure_keys_present" do
-    test "it creates keys for a user and stores them in info" do
-      user = insert(:user)
-      refute is_binary(user.keys)
-      {:ok, user} = User.ensure_keys_present(user)
-      assert is_binary(user.keys)
-    end
-
-    test "it doesn't create keys if there already are some" do
-      user = insert(:user, keys: "xxx")
-      {:ok, user} = User.ensure_keys_present(user)
-      assert user.keys == "xxx"
-    end
-  end
-
   describe "get_ap_ids_by_nicknames" do
     test "it returns a list of AP ids for a given set of nicknames" do
       user = insert(:user)
   describe "get_ap_ids_by_nicknames" do
     test "it returns a list of AP ids for a given set of nicknames" do
       user = insert(:user)
@@ -2089,13 +2217,33 @@ defmodule Pleroma.UserTest do
       assert {:ok, user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
       assert %User{bio: "test-bio"} = User.get_cached_by_ap_id(user.ap_id)
     end
       assert {:ok, user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
       assert %User{bio: "test-bio"} = User.get_cached_by_ap_id(user.ap_id)
     end
+
+    test "removes report notifs when user isn't superuser any more" do
+      report_activity = insert(:report_activity)
+      user = insert(:user, is_moderator: true, is_admin: true)
+      {:ok, _} = Notification.create_notifications(report_activity)
+
+      assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user)
+
+      {:ok, user} = user |> User.admin_api_update(%{is_moderator: false})
+      # is still superuser because still admin
+      assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user)
+
+      {:ok, user} = user |> User.admin_api_update(%{is_moderator: true, is_admin: false})
+      # is still superuser because still moderator
+      assert [%Pleroma.Notification{type: "pleroma:report"}] = Notification.for_user(user)
+
+      {:ok, user} = user |> User.admin_api_update(%{is_moderator: false})
+      # is not a superuser any more
+      assert [] = Notification.for_user(user)
+    end
   end
 
   describe "following/followers synchronization" do
     setup do: clear_config([:instance, :external_user_synchronization])
 
     test "updates the counters normally on following/getting a follow when disabled" do
   end
 
   describe "following/followers synchronization" do
     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)
+      clear_config([:instance, :external_user_synchronization], false)
       user = insert(:user)
 
       other_user =
       user = insert(:user)
 
       other_user =
@@ -2115,8 +2263,8 @@ defmodule Pleroma.UserTest do
       assert other_user.follower_count == 1
     end
 
       assert other_user.follower_count == 1
     end
 
-    test "syncronizes the counters with the remote instance for the followed when enabled" do
-      Pleroma.Config.put([:instance, :external_user_synchronization], false)
+    test "synchronizes the counters with the remote instance for the followed when enabled" do
+      clear_config([:instance, :external_user_synchronization], false)
 
       user = insert(:user)
 
 
       user = insert(:user)
 
@@ -2131,14 +2279,14 @@ defmodule Pleroma.UserTest do
       assert other_user.following_count == 0
       assert 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)
+      clear_config([:instance, :external_user_synchronization], true)
       {:ok, _user, other_user} = User.follow(user, other_user)
 
       assert other_user.follower_count == 437
     end
 
       {:ok, _user, other_user} = User.follow(user, other_user)
 
       assert other_user.follower_count == 437
     end
 
-    test "syncronizes the counters with the remote instance for the follower when enabled" do
-      Pleroma.Config.put([:instance, :external_user_synchronization], false)
+    test "synchronizes the counters with the remote instance for the follower when enabled" do
+      clear_config([:instance, :external_user_synchronization], false)
 
       user = insert(:user)
 
 
       user = insert(:user)
 
@@ -2153,7 +2301,7 @@ defmodule Pleroma.UserTest do
       assert other_user.following_count == 0
       assert 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)
+      clear_config([:instance, :external_user_synchronization], true)
       {:ok, other_user, _user} = User.follow(other_user, user)
 
       assert other_user.following_count == 152
       {:ok, other_user, _user} = User.follow(other_user, user)
 
       assert other_user.following_count == 152
@@ -2165,11 +2313,40 @@ defmodule Pleroma.UserTest do
       [user: insert(:user)]
     end
 
       [user: insert(:user)]
     end
 
-    test "blank email returns error", %{user: user} do
+    test "blank email returns error if we require an email on registration", %{user: user} do
+      orig_account_activation_required =
+        Pleroma.Config.get([:instance, :account_activation_required])
+
+      Pleroma.Config.put([:instance, :account_activation_required], true)
+
+      on_exit(fn ->
+        Pleroma.Config.put(
+          [:instance, :account_activation_required],
+          orig_account_activation_required
+        )
+      end)
+
       assert {:error, %{errors: [email: {"can't be blank", _}]}} = User.change_email(user, "")
       assert {:error, %{errors: [email: {"can't be blank", _}]}} = User.change_email(user, nil)
     end
 
       assert {:error, %{errors: [email: {"can't be blank", _}]}} = User.change_email(user, "")
       assert {:error, %{errors: [email: {"can't be blank", _}]}} = User.change_email(user, nil)
     end
 
+    test "blank email should be fine if we do not require an email on registration", %{user: user} do
+      orig_account_activation_required =
+        Pleroma.Config.get([:instance, :account_activation_required])
+
+      Pleroma.Config.put([:instance, :account_activation_required], false)
+
+      on_exit(fn ->
+        Pleroma.Config.put(
+          [:instance, :account_activation_required],
+          orig_account_activation_required
+        )
+      end)
+
+      assert {:ok, %User{email: nil}} = User.change_email(user, "")
+      assert {:ok, %User{email: nil}} = User.change_email(user, nil)
+    end
+
     test "non unique email returns error", %{user: user} do
       %{email: email} = insert(:user)
 
     test "non unique email returns error", %{user: user} do
       %{email: email} = insert(:user)
 
@@ -2185,6 +2362,25 @@ defmodule Pleroma.UserTest do
     test "changes email", %{user: user} do
       assert {:ok, %User{email: "cofe@cofe.party"}} = User.change_email(user, "cofe@cofe.party")
     end
     test "changes email", %{user: user} do
       assert {:ok, %User{email: "cofe@cofe.party"}} = User.change_email(user, "cofe@cofe.party")
     end
+
+    test "adds email", %{user: user} do
+      orig_account_activation_required =
+        Pleroma.Config.get([:instance, :account_activation_required])
+
+      Pleroma.Config.put([:instance, :account_activation_required], false)
+
+      on_exit(fn ->
+        Pleroma.Config.put(
+          [:instance, :account_activation_required],
+          orig_account_activation_required
+        )
+      end)
+
+      assert {:ok, _} = User.change_email(user, "")
+      Pleroma.Config.put([:instance, :account_activation_required], true)
+
+      assert {:ok, %User{email: "cofe2@cofe.party"}} = User.change_email(user, "cofe2@cofe.party")
+    end
   end
 
   describe "get_cached_by_nickname_or_id" do
   end
 
   describe "get_cached_by_nickname_or_id" do
@@ -2200,43 +2396,43 @@ defmodule Pleroma.UserTest do
     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
-      Pleroma.Config.put([:instance, :limit_to_local_content], false)
+      clear_config([:instance, :limit_to_local_content], false)
       assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
 
       assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
 
-      Pleroma.Config.put([:instance, :limit_to_local_content], true)
+      clear_config([:instance, :limit_to_local_content], true)
       assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
 
       assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
 
-      Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
+      clear_config([:instance, :limit_to_local_content], :unauthenticated)
       assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
     end
 
     test "disallows getting remote users by nickname without authentication when :limit_to_local_content is set to :unauthenticated",
          %{remote_user: remote_user} do
       assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
     end
 
     test "disallows getting remote users by nickname without authentication when :limit_to_local_content is set to :unauthenticated",
          %{remote_user: remote_user} do
-      Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
+      clear_config([:instance, :limit_to_local_content], :unauthenticated)
       assert nil == User.get_cached_by_nickname_or_id(remote_user.nickname)
     end
 
     test "allows getting remote users by nickname with authentication when :limit_to_local_content is set to :unauthenticated",
          %{remote_user: remote_user, local_user: local_user} do
       assert nil == User.get_cached_by_nickname_or_id(remote_user.nickname)
     end
 
     test "allows getting remote users by nickname with authentication when :limit_to_local_content is set to :unauthenticated",
          %{remote_user: remote_user, local_user: local_user} do
-      Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
+      clear_config([:instance, :limit_to_local_content], :unauthenticated)
       assert %User{} = User.get_cached_by_nickname_or_id(remote_user.nickname, for: local_user)
     end
 
     test "disallows getting remote users by nickname when :limit_to_local_content is set to true",
          %{remote_user: remote_user} do
       assert %User{} = User.get_cached_by_nickname_or_id(remote_user.nickname, for: local_user)
     end
 
     test "disallows getting remote users by nickname when :limit_to_local_content is set to true",
          %{remote_user: remote_user} do
-      Pleroma.Config.put([:instance, :limit_to_local_content], true)
+      clear_config([:instance, :limit_to_local_content], true)
       assert nil == User.get_cached_by_nickname_or_id(remote_user.nickname)
     end
 
     test "allows getting local users by nickname no matter what :limit_to_local_content is set to",
          %{local_user: local_user} do
       assert nil == User.get_cached_by_nickname_or_id(remote_user.nickname)
     end
 
     test "allows getting local users by nickname no matter what :limit_to_local_content is set to",
          %{local_user: local_user} do
-      Pleroma.Config.put([:instance, :limit_to_local_content], false)
+      clear_config([:instance, :limit_to_local_content], false)
       assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
 
       assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
 
-      Pleroma.Config.put([:instance, :limit_to_local_content], true)
+      clear_config([:instance, :limit_to_local_content], true)
       assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
 
       assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
 
-      Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
+      clear_config([:instance, :limit_to_local_content], :unauthenticated)
       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
@@ -2255,6 +2451,36 @@ defmodule Pleroma.UserTest do
     end
   end
 
     end
   end
 
+  describe "local_nickname/1" do
+    test "returns nickname without host" do
+      assert User.local_nickname("@mentioned") == "mentioned"
+      assert User.local_nickname("a_local_nickname") == "a_local_nickname"
+      assert User.local_nickname("nickname@host.com") == "nickname"
+    end
+  end
+
+  describe "full_nickname/1" do
+    test "returns fully qualified nickname for local and remote users" do
+      local_user =
+        insert(:user, nickname: "local_user", ap_id: "https://somehost.com/users/local_user")
+
+      remote_user = insert(:user, nickname: "remote@host.com", local: false)
+
+      assert User.full_nickname(local_user) == "local_user@somehost.com"
+      assert User.full_nickname(remote_user) == "remote@host.com"
+    end
+
+    test "strips leading @ from mentions" do
+      assert User.full_nickname("@mentioned") == "mentioned"
+      assert User.full_nickname("@nickname@host.com") == "nickname@host.com"
+    end
+
+    test "does not modify nicknames" do
+      assert User.full_nickname("nickname") == "nickname"
+      assert User.full_nickname("nickname@host.com") == "nickname@host.com"
+    end
+  end
+
   test "avatar fallback" do
     user = insert(:user)
     assert User.avatar_url(user) =~ "/images/avi.png"
   test "avatar fallback" do
     user = insert(:user)
     assert User.avatar_url(user) =~ "/images/avi.png"
@@ -2271,4 +2497,167 @@ defmodule Pleroma.UserTest do
     user = insert(:user, ap_id: "https://lain.com/users/lain", nickname: "lain")
     assert User.get_host(user) == "lain.com"
   end
     user = insert(:user, ap_id: "https://lain.com/users/lain", nickname: "lain")
     assert User.get_host(user) == "lain.com"
   end
+
+  test "update_last_active_at/1" do
+    user = insert(:user)
+    assert is_nil(user.last_active_at)
+
+    test_started_at = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
+
+    assert {:ok, user} = User.update_last_active_at(user)
+
+    assert user.last_active_at >= test_started_at
+    assert user.last_active_at <= NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second)
+
+    last_active_at =
+      NaiveDateTime.utc_now()
+      |> NaiveDateTime.add(-:timer.hours(24), :millisecond)
+      |> NaiveDateTime.truncate(:second)
+
+    assert {:ok, user} =
+             user
+             |> cast(%{last_active_at: last_active_at}, [:last_active_at])
+             |> User.update_and_set_cache()
+
+    assert user.last_active_at == last_active_at
+    assert {:ok, user} = User.update_last_active_at(user)
+    assert user.last_active_at >= test_started_at
+    assert user.last_active_at <= NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second)
+  end
+
+  test "active_user_count/1" do
+    insert(:user)
+    insert(:user, %{local: false})
+    insert(:user, %{last_active_at: NaiveDateTime.utc_now()})
+    insert(:user, %{last_active_at: Timex.shift(NaiveDateTime.utc_now(), days: -15)})
+    insert(:user, %{last_active_at: Timex.shift(NaiveDateTime.utc_now(), weeks: -6)})
+    insert(:user, %{last_active_at: Timex.shift(NaiveDateTime.utc_now(), months: -7)})
+    insert(:user, %{last_active_at: Timex.shift(NaiveDateTime.utc_now(), years: -2)})
+
+    assert User.active_user_count() == 2
+    assert User.active_user_count(180) == 3
+    assert User.active_user_count(365) == 4
+    assert User.active_user_count(1000) == 5
+  end
+
+  describe "pins" do
+    setup do
+      user = insert(:user)
+
+      [user: user, object_id: object_id_from_created_activity(user)]
+    end
+
+    test "unique pins", %{user: user, object_id: object_id} do
+      assert {:ok, %{pinned_objects: %{^object_id => pinned_at1} = pins} = updated_user} =
+               User.add_pinned_object_id(user, object_id)
+
+      assert Enum.count(pins) == 1
+
+      assert {:ok, %{pinned_objects: %{^object_id => pinned_at2} = pins}} =
+               User.add_pinned_object_id(updated_user, object_id)
+
+      assert pinned_at1 == pinned_at2
+
+      assert Enum.count(pins) == 1
+    end
+
+    test "respects max_pinned_statuses limit", %{user: user, object_id: object_id} do
+      clear_config([:instance, :max_pinned_statuses], 1)
+      {:ok, updated} = User.add_pinned_object_id(user, object_id)
+
+      object_id2 = object_id_from_created_activity(user)
+
+      {:error, %{errors: errors}} = User.add_pinned_object_id(updated, object_id2)
+      assert Keyword.has_key?(errors, :pinned_objects)
+    end
+
+    test "remove_pinned_object_id/2", %{user: user, object_id: object_id} do
+      assert {:ok, updated} = User.add_pinned_object_id(user, object_id)
+
+      {:ok, after_remove} = User.remove_pinned_object_id(updated, object_id)
+      assert after_remove.pinned_objects == %{}
+    end
+  end
+
+  defp object_id_from_created_activity(user) do
+    %{id: id} = insert(:note_activity, user: user)
+    %{object: %{data: %{"id" => object_id}}} = Activity.get_by_id_with_object(id)
+    object_id
+  end
+
+  describe "add_alias/2" do
+    test "should add alias for another user" do
+      user = insert(:user)
+      user2 = insert(:user)
+
+      assert {:ok, user_updated} = user |> User.add_alias(user2)
+
+      assert user_updated.also_known_as |> length() == 1
+      assert user2.ap_id in user_updated.also_known_as
+    end
+
+    test "should add multiple aliases" do
+      user = insert(:user)
+      user2 = insert(:user)
+      user3 = insert(:user)
+
+      assert {:ok, user} = user |> User.add_alias(user2)
+      assert {:ok, user_updated} = user |> User.add_alias(user3)
+
+      assert user_updated.also_known_as |> length() == 2
+      assert user2.ap_id in user_updated.also_known_as
+      assert user3.ap_id in user_updated.also_known_as
+    end
+
+    test "should not add duplicate aliases" do
+      user = insert(:user)
+      user2 = insert(:user)
+
+      assert {:ok, user} = user |> User.add_alias(user2)
+
+      assert {:ok, user_updated} = user |> User.add_alias(user2)
+
+      assert user_updated.also_known_as |> length() == 1
+      assert user2.ap_id in user_updated.also_known_as
+    end
+  end
+
+  describe "alias_users/1" do
+    test "should get aliases for a user" do
+      user = insert(:user)
+      user2 = insert(:user, also_known_as: [user.ap_id])
+
+      aliases = user2 |> User.alias_users()
+
+      assert aliases |> length() == 1
+
+      alias_user = aliases |> Enum.at(0)
+
+      assert alias_user.ap_id == user.ap_id
+    end
+  end
+
+  describe "delete_alias/2" do
+    test "should delete existing alias" do
+      user = insert(:user)
+      user2 = insert(:user, also_known_as: [user.ap_id])
+
+      assert {:ok, user_updated} = user2 |> User.delete_alias(user)
+
+      assert user_updated.also_known_as == []
+    end
+
+    test "should report error on non-existing alias" do
+      user = insert(:user)
+      user2 = insert(:user)
+      user3 = insert(:user, also_known_as: [user.ap_id])
+
+      assert {:error, :no_such_alias} = user3 |> User.delete_alias(user2)
+
+      user3_updated = User.get_cached_by_ap_id(user3.ap_id)
+
+      assert user3_updated.also_known_as |> length() == 1
+      assert user.ap_id in user3_updated.also_known_as
+    end
+  end
 end
 end