X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=test%2Fuser_test.exs;h=9baa5ef242586c3cc1f80276ad01a1b054b78f2f;hb=cc6689cc203d44e19e9aa14c2ef3a3dad823ef88;hp=058b67c6deecd817603a637c44a240fc50ed08db;hpb=0aa56a853b79dc6c2003a32f1e0d8c85258880b9;p=akkoma diff --git a/test/user_test.exs b/test/user_test.exs index 058b67c6d..9baa5ef24 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -1,24 +1,26 @@ 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 test "ap_id returns the activity pub id for the user" do - user = UserBuilder.build + user = UserBuilder.build() - expected_ap_id = "#{Pleroma.Web.base_url}/users/#{user.nickname}" + expected_ap_id = "#{Pleroma.Web.base_url()}/users/#{user.nickname}" assert expected_ap_id == User.ap_id(user) end test "ap_followers returns the followers collection for the user" do - user = UserBuilder.build + user = UserBuilder.build() expected_followers_collection = "#{User.ap_id(user)}/followers" @@ -34,39 +36,58 @@ 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 - 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") + test "can't follow a user who blocked us" do + blocker = insert(:user) + blockee = insert(:user) - assert followed.local == false + {:ok, blocker} = User.block(blocker, blockee) - {:ok, user} = User.follow(user, followed) - assert User.ap_followers(followed) in user.following + {: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}) - query = from w in WebsubClientSubscription, - where: w.topic == ^followed.info["topic"] - websub = Repo.one(query) + {:ok, follower} = User.maybe_direct_follow(follower, followed) - assert websub + 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 + test "unfollow takes a user and another user" do followed = insert(:user) user = insert(:user, %{following: [User.ap_followers(followed)]}) - {:ok, user, _activity } = User.unfollow(user, followed) + {:ok, user, _activity} = User.unfollow(user, followed) user = Repo.get(User, user.id) @@ -82,7 +103,6 @@ defmodule Pleroma.UserTest do assert user.following == [user.ap_id] end - test "test if a user is following another user" do followed = insert(:user) user = insert(:user, %{following: [User.ap_followers(followed)]}) @@ -101,13 +121,14 @@ defmodule Pleroma.UserTest do email: "email@example.com" } - test "it requires a bio, email, name, nickname and password" do + test "it requires an email, name, nickname and password, bio is optional" do @full_user_data - |> Map.keys - |> Enum.each(fn (key) -> + |> Map.keys() + |> Enum.each(fn key -> params = Map.delete(@full_user_data, key) changeset = User.register_changeset(%User{}, params) - assert changeset.valid? == false + + assert if key == :bio, do: changeset.valid?, else: not changeset.valid? end) end @@ -118,9 +139,51 @@ 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 changeset.changes[:following] == [User.ap_followers(%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 + + 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 "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,16 +215,49 @@ 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 user = insert(:user) - assert User.ap_id(user) == Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :feed_redirect, user.nickname) + + assert User.ap_id(user) == + Pleroma.Web.Router.Helpers.o_status_url( + Pleroma.Web.Endpoint, + :feed_redirect, + user.nickname + ) end test "returns an ap_followers link for a user" do user = insert(:user) - assert User.ap_followers(user) == Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :feed_redirect, user.nickname) <> "/followers" + + assert User.ap_followers(user) == + Pleroma.Web.Router.Helpers.o_status_url( + Pleroma.Web.Endpoint, + :feed_redirect, + user.nickname + ) <> "/followers" end describe "remote user creation changeset" do @@ -182,7 +278,8 @@ defmodule Pleroma.UserTest do test "it sets the follower_adress" do cs = User.remote_user_creation(@valid_remote) # remote users get a fake local follower address - assert cs.changes.follower_address == User.ap_followers(%User{ nickname: @valid_remote[:nickname] }) + assert cs.changes.follower_address == + User.ap_followers(%User{nickname: @valid_remote[:nickname]}) end test "it enforces the fqn format for nicknames" do @@ -193,8 +290,8 @@ defmodule Pleroma.UserTest do end test "it has required fields" do - [:name, :nickname, :ap_id] - |> Enum.each(fn (field) -> + [:name, :ap_id] + |> Enum.each(fn field -> cs = User.remote_user_creation(Map.delete(@valid_remote, field)) refute cs.valid? end) @@ -202,7 +299,7 @@ defmodule Pleroma.UserTest do test "it restricts some sizes" do [bio: 5000, name: 100] - |> Enum.each(fn ({field, size}) -> + |> Enum.each(fn {field, size} -> string = String.pad_leading(".", size) cs = User.remote_user_creation(Map.put(@valid_remote, field, string)) assert cs.valid? @@ -256,26 +353,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 == 0 + + {:ok, user} = User.increase_note_count(user) + + assert user.info.note_count == 1 + + {:ok, user} = User.decrease_note_count(user) + + assert user.info.note_count == 0 + + {:ok, user} = User.decrease_note_count(user) + + assert user.info.note_count == 0 end test "it sets the info->follower_count property" do @@ -284,11 +400,11 @@ 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 @@ -313,6 +429,82 @@ defmodule Pleroma.UserTest do refute User.blocks?(user, blocked_user) end + + test "blocks tear down cyclical follow relationships" do + blocker = insert(:user) + blocked = insert(:user) + + {:ok, blocker} = User.follow(blocker, blocked) + {:ok, blocked} = User.follow(blocked, blocker) + + assert User.following?(blocker, blocked) + assert User.following?(blocked, blocker) + + {:ok, blocker} = User.block(blocker, blocked) + blocked = Repo.get(User, blocked.id) + + assert User.blocks?(blocker, blocked) + + refute User.following?(blocker, blocked) + refute User.following?(blocked, blocker) + end + + test "blocks tear down blocker->blocked follow relationships" do + blocker = insert(:user) + blocked = insert(:user) + + {:ok, blocker} = User.follow(blocker, blocked) + + assert User.following?(blocker, blocked) + refute User.following?(blocked, blocker) + + {:ok, blocker} = User.block(blocker, blocked) + blocked = Repo.get(User, blocked.id) + + assert User.blocks?(blocker, blocked) + + refute User.following?(blocker, blocked) + refute User.following?(blocked, blocker) + end + + test "blocks tear down blocked->blocker follow relationships" do + blocker = insert(:user) + blocked = insert(:user) + + {:ok, blocked} = User.follow(blocked, blocker) + + refute User.following?(blocker, blocked) + assert User.following?(blocked, blocker) + + {:ok, blocker} = User.block(blocker, blocked) + blocked = Repo.get(User, blocked.id) + + assert User.blocks?(blocker, blocked) + + refute User.following?(blocker, blocked) + refute User.following?(blocked, blocker) + end + end + + describe "domain blocking" do + test "blocks domains" do + user = insert(:user) + collateral_user = insert(:user, %{ap_id: "https://awful-and-rude-instance.com/user/bully"}) + + {:ok, user} = User.block_domain(user, "awful-and-rude-instance.com") + + assert User.blocks?(user, collateral_user) + end + + test "unblocks domains" do + user = insert(:user) + collateral_user = 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.unblock_domain(user, "awful-and-rude-instance.com") + + refute User.blocks?(user, collateral_user) + end end test "get recipients from activity" do @@ -321,7 +513,11 @@ defmodule Pleroma.UserTest do 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}"}) + + {:ok, activity} = + CommonAPI.post(actor, %{ + "status" => "hey @#{addressed.nickname} @#{addressed_remote.nickname}" + }) assert [addressed] == User.get_recipients_from_activity(activity) @@ -333,11 +529,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 @@ -355,13 +553,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) @@ -377,8 +575,61 @@ defmodule Pleroma.UserTest do test "insert or update a user from given data" do user = insert(:user, %{nickname: "nick@name.de"}) - data = %{ ap_id: user.ap_id <> "xxx", name: user.name, nickname: user.nickname } + data = %{ap_id: user.ap_id <> "xxx", name: user.name, nickname: user.nickname} assert {:ok, %User{}} = User.insert_or_update_user(data) end + + describe "per-user rich-text filtering" do + test "html_filter_policy returns nil when rich-text is enabled" do + user = insert(:user) + + assert nil == 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