X-Git-Url: https://git.squeep.com/?a=blobdiff_plain;f=test%2Fpleroma%2Fuser_test.exs;h=44763daf70bcf544c273dea4866693b3444b6495;hb=8d6cc6cb65d8216d9f8d75e274e23fc78b75639c;hp=181990e4befe07bf7ccd8cd7ef2389125880a036;hpb=43800d83f4fc3b251cdd93c28dab2df7297021b3;p=akkoma diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index 181990e4b..44763daf7 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -5,6 +5,7 @@ defmodule Pleroma.UserTest do alias Pleroma.Activity alias Pleroma.Builders.UserBuilder + alias Pleroma.Notification 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() - 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 @@ -310,7 +311,7 @@ defmodule Pleroma.UserTest do describe "unfollow/2" do setup do: clear_config([:instance, :external_user_synchronization]) - test "unfollow with syncronizes external user" do + test "unfollow with synchronizes external user" do clear_config([:instance, :external_user_synchronization], true) followed = @@ -442,34 +443,21 @@ defmodule Pleroma.UserTest do assert activity.actor == welcome_user.ap_id end - test "it sends a welcome chat message if it is set" do - welcome_user = insert(:user) - clear_config([:welcome, :chat_message, :enabled], true) - clear_config([:welcome, :chat_message, :sender_nickname], welcome_user.nickname) - clear_config([: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: - 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: @@ -479,24 +467,6 @@ defmodule Pleroma.UserTest do ] ) - test "it sends a welcome chat message when Simple policy applied to local instance" do - clear_config([:mrf_simple, :media_nsfw], ["localhost"]) - - welcome_user = insert(:user) - clear_config([:welcome, :chat_message, :enabled], true) - clear_config([:welcome, :chat_message, :sender_nickname], welcome_user.nickname) - clear_config([: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) clear_config([:welcome, :email, :enabled], true) @@ -572,6 +542,24 @@ defmodule Pleroma.UserTest do ) 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 clear_config([:instance, :account_activation_required], true) @@ -635,26 +623,18 @@ defmodule Pleroma.UserTest do 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]) + assert is_binary(changeset.changes[:keys]) 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 - 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? @@ -760,6 +740,123 @@ defmodule Pleroma.UserTest do 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 @@ -871,6 +968,25 @@ defmodule Pleroma.UserTest do assert user.last_refreshed_at == orig_user.last_refreshed_at end + + test "it doesn't fail on invalid alsoKnownAs entries" do + Tesla.Mock.mock(fn + %{url: "https://mbp.example.com/"} -> + %Tesla.Env{ + status: 200, + body: + "test/fixtures/microblogpub/user_with_invalid_also_known_as.json" + |> File.read!(), + headers: [{"content-type", "application/activity+json"}] + } + + _ -> + %Tesla.Env{status: 404} + end) + + assert {:ok, %User{also_known_as: []}} = + User.get_or_fetch_by_ap_id("https://mbp.example.com/") + end end test "returns an ap_id for a user" do @@ -1230,7 +1346,7 @@ defmodule Pleroma.UserTest do 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 @@ -1248,7 +1364,7 @@ defmodule Pleroma.UserTest do 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) @@ -1651,8 +1767,8 @@ defmodule Pleroma.UserTest do 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, @@ -1702,6 +1818,38 @@ defmodule Pleroma.UserTest do 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 @@ -1870,9 +2018,7 @@ defmodule Pleroma.UserTest do bio = "A.k.a. @nick@domain.com" expected_text = - ~s(A.k.a. @nick@domain.com) + ~s(A.k.a. @nick@domain.com) assert expected_text == User.parse_bio(bio, user) end @@ -2013,21 +2159,6 @@ defmodule Pleroma.UserTest do 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) @@ -2105,6 +2236,26 @@ 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 + + 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 @@ -2131,7 +2282,7 @@ defmodule Pleroma.UserTest do assert other_user.follower_count == 1 end - test "syncronizes the counters with the remote instance for the followed when enabled" do + test "synchronizes the counters with the remote instance for the followed when enabled" do clear_config([:instance, :external_user_synchronization], false) user = insert(:user) @@ -2153,7 +2304,7 @@ defmodule Pleroma.UserTest do assert other_user.follower_count == 437 end - test "syncronizes the counters with the remote instance for the follower when enabled" do + test "synchronizes the counters with the remote instance for the follower when enabled" do clear_config([:instance, :external_user_synchronization], false) user = insert(:user) @@ -2181,11 +2332,40 @@ defmodule Pleroma.UserTest do [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 + 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) @@ -2201,6 +2381,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 "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 @@ -2348,12 +2547,136 @@ defmodule Pleroma.UserTest do test "active_user_count/1" do insert(:user) insert(:user, %{local: false}) - insert(:user, %{last_active_at: Timex.shift(NaiveDateTime.utc_now(), weeks: -5)}) - insert(:user, %{last_active_at: Timex.shift(NaiveDateTime.utc_now(), weeks: -3)}) 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(6) == 3 - assert User.active_user_count(1) == 1 + 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