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 =
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:
]
)
- 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)
ObanHelpers.perform_all()
Pleroma.Emails.UserEmail.account_confirmation_email(registered_user)
- # temporary hackney fix until hackney max_connections bug is fixed
- # https://git.pleroma.social/pleroma/pleroma/-/issues/2101
- |> Swoosh.Email.put_private(:hackney_options, ssl_options: [versions: [:"tlsv1.2"]])
|> assert_email_sent()
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])
+ 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?
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
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
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
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)
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)
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)
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)
%{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
+
+ describe "follow_hashtag/2" do
+ test "should follow a hashtag" do
+ user = insert(:user)
+ hashtag = insert(:hashtag)
+
+ assert {:ok, _} = user |> User.follow_hashtag(hashtag)
+
+ user = User.get_cached_by_ap_id(user.ap_id)
+
+ assert user.followed_hashtags |> Enum.count() == 1
+ assert hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end)
+ end
+
+ test "should not follow a hashtag twice" do
+ user = insert(:user)
+ hashtag = insert(:hashtag)
+
+ assert {:ok, _} = user |> User.follow_hashtag(hashtag)
+
+ assert {:ok, _} = user |> User.follow_hashtag(hashtag)
+
+ user = User.get_cached_by_ap_id(user.ap_id)
+
+ assert user.followed_hashtags |> Enum.count() == 1
+ assert hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end)
+ end
+
+ test "can follow multiple hashtags" do
+ user = insert(:user)
+ hashtag = insert(:hashtag)
+ other_hashtag = insert(:hashtag)
+
+ assert {:ok, _} = user |> User.follow_hashtag(hashtag)
+ assert {:ok, _} = user |> User.follow_hashtag(other_hashtag)
+
+ user = User.get_cached_by_ap_id(user.ap_id)
+
+ assert user.followed_hashtags |> Enum.count() == 2
+ assert hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end)
+ assert other_hashtag.name in Enum.map(user.followed_hashtags, fn %{name: name} -> name end)
+ end
+ end
+
+ describe "unfollow_hashtag/2" do
+ test "should unfollow a hashtag" do
+ user = insert(:user)
+ hashtag = insert(:hashtag)
+
+ assert {:ok, _} = user |> User.follow_hashtag(hashtag)
+ assert {:ok, _} = user |> User.unfollow_hashtag(hashtag)
+
+ user = User.get_cached_by_ap_id(user.ap_id)
+
+ assert user.followed_hashtags |> Enum.count() == 0
+ end
+
+ test "should not error when trying to unfollow a hashtag twice" do
+ user = insert(:user)
+ hashtag = insert(:hashtag)
+
+ assert {:ok, _} = user |> User.follow_hashtag(hashtag)
+ assert {:ok, _} = user |> User.unfollow_hashtag(hashtag)
+ assert {:ok, _} = user |> User.unfollow_hashtag(hashtag)
+
+ user = User.get_cached_by_ap_id(user.ap_id)
+
+ assert user.followed_hashtags |> Enum.count() == 0
+ end
+ end
end