Merge branch 'fix_486' into 'develop'
[akkoma] / test / user_test.exs
index 5c61b093042328b401dd5948cf0eb8ffa78a7fac..869e9196db18196796c1bee5b02b8fcc77c9fa2e 100644 (file)
@@ -1,13 +1,36 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
 defmodule Pleroma.UserTest do
   alias Pleroma.Builders.UserBuilder
   alias Pleroma.{User, Repo, Activity}
-  alias Pleroma.Web.OStatus
-  alias Pleroma.Web.Websub.WebsubClientSubscription
   alias Pleroma.Web.CommonAPI
   use Pleroma.DataCase
 
   import Pleroma.Factory
-  import Ecto.Query
+
+  setup_all do
+    Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
+    :ok
+  end
+
+  describe "when tags are nil" do
+    test "tagging a user" do
+      user = insert(:user, %{tags: nil})
+      user = User.tag(user, ["cool", "dude"])
+
+      assert "cool" in user.tags
+      assert "dude" in user.tags
+    end
+
+    test "untagging a user" do
+      user = insert(:user, %{tags: nil})
+      user = User.untag(user, ["cool", "dude"])
+
+      assert user.tags == []
+    end
+  end
 
   test "ap_id returns the activity pub id for the user" do
     user = UserBuilder.build()
@@ -34,14 +57,14 @@ defmodule Pleroma.UserTest do
     user = Repo.get(User, user.id)
 
     followed = User.get_by_ap_id(followed.ap_id)
-    assert followed.info["follower_count"] == 1
+    assert followed.info.follower_count == 1
 
     assert User.ap_followers(followed) in user.following
   end
 
   test "can't follow a deactivated users" do
     user = insert(:user)
-    followed = insert(:user, info: %{"deactivated" => true})
+    followed = insert(:user, info: %{deactivated: true})
 
     {:error, _} = User.follow(user, followed)
   end
@@ -55,6 +78,15 @@ defmodule Pleroma.UserTest do
     {:error, _} = User.follow(blockee, 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})
+
+    {: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)
@@ -121,6 +153,20 @@ defmodule Pleroma.UserTest do
       end)
     end
 
+    test "it restricts certain nicknames" do
+      [restricted_name | _] = Pleroma.Config.get([Pleroma.User, :restricted_nicknames])
+
+      assert is_bitstring(restricted_name)
+
+      params =
+        @full_user_data
+        |> Map.put(:nickname, restricted_name)
+
+      changeset = User.register_changeset(%User{}, params)
+
+      refute changeset.valid?
+    end
+
     test "it sets the password_hash, ap_id and following fields" do
       changeset = User.register_changeset(%User{}, @full_user_data)
 
@@ -135,6 +181,86 @@ defmodule Pleroma.UserTest do
 
       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
+    @full_user_data %{
+      bio: "A guy",
+      name: "my name",
+      nickname: "nick",
+      password: "test",
+      password_confirmation: "test",
+      email: "email@example.com"
+    }
+
+    setup do
+      setting = Pleroma.Config.get([:instance, :account_activation_required])
+
+      unless setting do
+        Pleroma.Config.put([:instance, :account_activation_required], true)
+        on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
+      end
+
+      :ok
+    end
+
+    test "it creates unconfirmed user" do
+      changeset = User.register_changeset(%User{}, @full_user_data)
+      assert changeset.valid?
+
+      {:ok, user} = Repo.insert(changeset)
+
+      assert user.info.confirmation_pending
+      assert user.info.confirmation_token
+    end
+
+    test "it creates confirmed user if :confirmed option is given" do
+      changeset = User.register_changeset(%User{}, @full_user_data, confirmed: true)
+      assert changeset.valid?
+
+      {:ok, user} = Repo.insert(changeset)
+
+      refute user.info.confirmation_pending
+      refute user.info.confirmation_token
+    end
+  end
+
+  describe "get_or_fetch/1" do
+    test "gets an existing user by nickname" do
+      user = insert(:user)
+      fetched_user = User.get_or_fetch(user.nickname)
+
+      assert user == fetched_user
+    end
+
+    test "gets an existing user by ap_id" do
+      ap_id = "http://mastodon.example.org/users/admin"
+
+      user =
+        insert(
+          :user,
+          local: false,
+          nickname: "admin@mastodon.example.org",
+          ap_id: ap_id,
+          info: %{}
+        )
+
+      fetched_user = User.get_or_fetch(ap_id)
+      freshed_user = refresh_record(user)
+      assert freshed_user == fetched_user
+    end
   end
 
   describe "fetching a user from nickname or trying to build one" do
@@ -152,6 +278,24 @@ defmodule Pleroma.UserTest do
       assert user == fetched_user
     end
 
+    test "gets an existing user by fully qualified nickname" do
+      user = insert(:user)
+
+      fetched_user =
+        User.get_or_fetch_by_nickname(user.nickname <> "@" <> Pleroma.Web.Endpoint.host())
+
+      assert user == fetched_user
+    end
+
+    test "gets an existing user by fully qualified nickname, case insensitive" do
+      user = insert(:user, nickname: "nick")
+      casing_altered_fqn = String.upcase(user.nickname <> "@" <> Pleroma.Web.Endpoint.host())
+
+      fetched_user = User.get_or_fetch_by_nickname(casing_altered_fqn)
+
+      assert user == fetched_user
+    end
+
     test "fetches an external user via ostatus if no user exists" do
       fetched_user = User.get_or_fetch_by_nickname("shp@social.heldscal.la")
       assert fetched_user.nickname == "shp@social.heldscal.la"
@@ -166,6 +310,27 @@ defmodule Pleroma.UserTest do
       fetched_user = User.get_or_fetch_by_nickname("nonexistant")
       assert fetched_user == nil
     end
+
+    test "updates an existing user, if stale" 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/admin",
+          last_refreshed_at: a_week_ago,
+          info: %{}
+        )
+
+      assert orig_user.last_refreshed_at == a_week_ago
+
+      user = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
+      assert user.info.source_data["endpoints"]
+
+      refute user.last_refreshed_at == orig_user.last_refreshed_at
+    end
   end
 
   test "returns an ap_id for a user" do
@@ -283,45 +448,45 @@ defmodule Pleroma.UserTest do
 
       user = User.get_by_ap_id(note.data["actor"])
 
-      assert user.info["note_count"] == nil
+      assert user.info.note_count == 0
 
       {:ok, user} = User.update_note_count(user)
 
-      assert user.info["note_count"] == 1
+      assert user.info.note_count == 1
     end
 
     test "it increases the info->note_count property" do
       note = insert(:note)
       user = User.get_by_ap_id(note.data["actor"])
 
-      assert user.info["note_count"] == nil
+      assert user.info.note_count == 0
 
       {:ok, user} = User.increase_note_count(user)
 
-      assert user.info["note_count"] == 1
+      assert user.info.note_count == 1
 
       {:ok, user} = User.increase_note_count(user)
 
-      assert user.info["note_count"] == 2
+      assert user.info.note_count == 2
     end
 
     test "it decreases the info->note_count property" do
       note = insert(:note)
       user = User.get_by_ap_id(note.data["actor"])
 
-      assert user.info["note_count"] == nil
+      assert user.info.note_count == 0
 
       {:ok, user} = User.increase_note_count(user)
 
-      assert user.info["note_count"] == 1
+      assert user.info.note_count == 1
 
       {:ok, user} = User.decrease_note_count(user)
 
-      assert user.info["note_count"] == 0
+      assert user.info.note_count == 0
 
       {:ok, user} = User.decrease_note_count(user)
 
-      assert user.info["note_count"] == 0
+      assert user.info.note_count == 0
     end
 
     test "it sets the info->follower_count property" do
@@ -330,11 +495,26 @@ defmodule Pleroma.UserTest do
 
       User.follow(follower, user)
 
-      assert user.info["follower_count"] == nil
+      assert user.info.follower_count == 0
 
       {:ok, user} = User.update_follower_count(user)
 
-      assert user.info["follower_count"] == 1
+      assert user.info.follower_count == 1
+    end
+  end
+
+  describe "follow_import" do
+    test "it imports user followings from list" do
+      [user1, user2, user3] = insert_list(3, :user)
+
+      identifiers = [
+        user2.ap_id,
+        user3.nickname
+      ]
+
+      result = User.follow_import(user1, identifiers)
+      assert is_list(result)
+      assert result == [user2, user3]
     end
   end
 
@@ -437,6 +617,21 @@ defmodule Pleroma.UserTest do
     end
   end
 
+  describe "blocks_import" do
+    test "it imports user blocks from list" do
+      [user1, user2, user3] = insert_list(3, :user)
+
+      identifiers = [
+        user2.ap_id,
+        user3.nickname
+      ]
+
+      result = User.blocks_import(user1, identifiers)
+      assert is_list(result)
+      assert result == [user2, user3]
+    end
+  end
+
   test "get recipients from activity" do
     actor = insert(:user)
     user = insert(:user, local: true)
@@ -459,11 +654,13 @@ defmodule Pleroma.UserTest do
     assert addressed in recipients
   end
 
-  test ".deactivate deactivates a user" do
+  test ".deactivate can de-activate then re-activate a user" do
     user = insert(:user)
-    assert false == !!user.info["deactivated"]
+    assert false == user.info.deactivated
     {:ok, user} = User.deactivate(user)
-    assert true == user.info["deactivated"]
+    assert true == user.info.deactivated
+    {:ok, user} = User.deactivate(user, false)
+    assert false == user.info.deactivated
   end
 
   test ".delete deactivates a user, all follow relationships and all create activities" do
@@ -481,13 +678,13 @@ defmodule Pleroma.UserTest do
     {:ok, _, _} = CommonAPI.favorite(activity.id, follower)
     {:ok, _, _} = CommonAPI.repeat(activity.id, follower)
 
-    :ok = User.delete(user)
+    {:ok, _} = User.delete(user)
 
     followed = Repo.get(User, followed.id)
     follower = Repo.get(User, follower.id)
     user = Repo.get(User, user.id)
 
-    assert user.info["deactivated"]
+    assert user.info.deactivated
 
     refute User.following?(user, followed)
     refute User.following?(followed, follower)
@@ -507,4 +704,57 @@ defmodule Pleroma.UserTest do
 
     assert {:ok, %User{}} = User.insert_or_update_user(data)
   end
+
+  describe "per-user rich-text filtering" do
+    test "html_filter_policy returns default policies, when rich-text is enabled" do
+      user = insert(:user)
+
+      assert Pleroma.Config.get([:markup, :scrub_policy]) == User.html_filter_policy(user)
+    end
+
+    test "html_filter_policy returns TwitterText scrubber when rich-text is disabled" do
+      user = insert(:user, %{info: %{no_rich_text: true}})
+
+      assert Pleroma.HTML.Scrubber.TwitterText == User.html_filter_policy(user)
+    end
+  end
+
+  describe "caching" do
+    test "invalidate_cache works" do
+      user = insert(:user)
+      _user_info = User.get_cached_user_info(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}")
+      {:ok, nil} = Cachex.get(:user_cache, "user_info:#{user.id}")
+    end
+
+    test "User.delete() plugs any possible zombie objects" do
+      user = insert(:user)
+
+      {:ok, _} = User.delete(user)
+
+      {:ok, cached_user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
+
+      assert cached_user != user
+
+      {:ok, cached_user} = Cachex.get(:user_cache, "nickname:#{user.ap_id}")
+
+      assert cached_user != user
+    end
+  end
+
+  describe "User.search" do
+    test "finds a user, ranking by similarity" do
+      _user = insert(:user, %{name: "lain"})
+      _user_two = insert(:user, %{name: "ean"})
+      _user_three = insert(:user, %{name: "ebn", nickname: "lain@mastodon.social"})
+      user_four = insert(:user, %{nickname: "lain@pleroma.soykaf.com"})
+
+      assert user_four ==
+               User.search("lain@ple") |> List.first() |> Map.put(:search_distance, nil)
+    end
+  end
 end