diff --git a/lib/pleroma/tag.ex b/lib/pleroma/tag.ex index 5185a907b..3b01f1119 100644 --- a/lib/pleroma/tag.ex +++ b/lib/pleroma/tag.ex @@ -22,11 +22,23 @@ defmodule Pleroma.Tag do @spec upsert(String.t()) :: {:ok, t()} | {:error, Ecto.Changeset.t()} def upsert(name) do %__MODULE__{} - |> Ecto.Changeset.change(name: name) + |> Ecto.Changeset.change(name: normalize_tag(name)) |> Ecto.Changeset.unique_constraint(:name) |> Repo.insert(on_conflict: :nothing, conflict_target: :name) end + @spec upsert_tags(list(String.t())) :: {integer(), nil | [term()]} + def upsert_tags(names) do + date = NaiveDateTime.utc_now() + + tags = + names + |> normalize_tags() + |> Enum.map(&%{name: &1, inserted_at: date, updated_at: date}) + + Repo.insert_all("tags", tags, on_conflict: :nothing, conflict_target: :name) + end + @spec list_tags() :: list(String.t()) def list_tags do from(u in __MODULE__, select: u.name) @@ -35,4 +47,25 @@ defmodule Pleroma.Tag do |> Enum.uniq() |> Enum.sort() end + + def get_tag_ids(tag_names) do + names = normalize_tags(tag_names) + + from( + u in __MODULE__, + select: u.id, + where: u.name in ^names + ) + |> Repo.all() + end + + def normalize_tags(tag_names) do + tag_names + |> List.wrap() + |> Enum.map(&normalize_tag/1) + end + + defp normalize_tag(tag_name) do + String.trim(String.downcase(tag_name)) + end end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index e4cb8e5c1..9396815e9 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -1674,43 +1674,51 @@ defmodule Pleroma.User do def purge_user_changeset(user) do # "Right to be forgotten" # https://gdpr.eu/right-to-be-forgotten/ - change(user, %{ - bio: "", - raw_bio: nil, - email: nil, - name: nil, - password_hash: nil, - keys: nil, - public_key: nil, - avatar: %{}, - tags: [], - last_refreshed_at: nil, - last_digest_emailed_at: nil, - banner: %{}, - background: %{}, - note_count: 0, - follower_count: 0, - following_count: 0, - is_locked: false, - is_confirmed: true, - password_reset_pending: false, - is_approved: true, - registration_reason: nil, - confirmation_token: nil, - domain_blocks: [], - is_active: false, - ap_enabled: false, - is_moderator: false, - is_admin: false, - mastofe_settings: nil, - mascot: nil, - emoji: %{}, - pleroma_settings_store: %{}, - fields: [], - raw_fields: [], - is_discoverable: false, - also_known_as: [] - }) + + default_user_attrs = + Map.take( + %__MODULE__{}, + [ + :registration_reason, + :is_discoverable, + :mastofe_settings, + :email, + :background, + :is_approved, + :avatar, + :password_hash, + :public_key, + :mascot, + :is_confirmed, + :is_locked, + :ap_enabled, + :note_count, + :pleroma_settings_store, + :follower_count, + :bio, + :name, + :is_admin, + :is_moderator, + :also_known_as, + :keys, + :confirmation_token, + :banner, + :raw_fields, + :fields, + :password_reset_pending, + :domain_blocks, + :last_digest_emailed_at, + :raw_bio, + :last_refreshed_at, + :emoji, + :following_count + ] + ) + + user + |> Repo.preload([:tags]) + |> change(Map.merge(default_user_attrs, %{is_active: false})) + |> put_assoc(:tags, []) end def delete(users) when is_list(users) do @@ -2007,8 +2015,11 @@ defmodule Pleroma.User do def tag(nickname, tags) when is_binary(nickname), do: tag(get_by_nickname(nickname), tags) - def tag(%User{} = user, tags), - do: update_tags(user, Enum.uniq((user.tags || []) ++ normalize_tags(tags))) + def tag(%User{} = user, tags) do + tag_names = Pleroma.Tag.normalize_tags(tags) + Pleroma.Tag.upsert_tags(tag_names) + update_tags(user, tag_names) + end def untag(user_identifiers, tags) when is_list(user_identifiers) do Repo.transaction(fn -> @@ -2019,22 +2030,40 @@ defmodule Pleroma.User do def untag(nickname, tags) when is_binary(nickname), do: untag(get_by_nickname(nickname), tags) - def untag(%User{} = user, tags), - do: update_tags(user, (user.tags || []) -- normalize_tags(tags)) + def untag(%User{} = user, remove_tags) do + tag_ids = Pleroma.Tag.get_tag_ids(remove_tags) + {:ok, user_id} = FlakeId.Ecto.Type.dump(user.id) - defp update_tags(%User{} = user, new_tags) do - {:ok, updated_user} = - user - |> change(%{tags: new_tags}) - |> update_and_set_cache() + from( + ut in "users_tags", + where: ut.user_id == ^user_id, + where: ut.tag_id in ^tag_ids + ) + |> Repo.delete_all() - updated_user + preload_tags_and_set_cache(user) end - defp normalize_tags(tags) do - [tags] - |> List.flatten() - |> Enum.map(&String.downcase/1) + defp update_tags(%User{} = user, new_tags) do + {:ok, user_id} = FlakeId.Ecto.Type.dump(user.id) + + tags = + new_tags + |> Pleroma.Tag.normalize_tags() + |> Pleroma.Tag.get_tag_ids() + |> Enum.map(&%{user_id: user_id, tag_id: &1}) + + Repo.insert_all("users_tags", tags, on_conflict: :nothing) + preload_tags_and_set_cache(user) + end + + defp preload_tags_and_set_cache(user) do + {:ok, updated_user} = + user + |> Repo.preload([:tags], force: true) + |> set_cache() + + updated_user end defp local_nickname_regex do diff --git a/lib/pleroma/user/query.ex b/lib/pleroma/user/query.ex index fa46545da..36e03466a 100644 --- a/lib/pleroma/user/query.ex +++ b/lib/pleroma/user/query.ex @@ -109,7 +109,9 @@ defmodule Pleroma.User.Query do end defp compose_query({:tags, tags}, query) when is_list(tags) and length(tags) > 0 do - where(query, [u], fragment("? && ?", u.tags, ^tags)) + query + |> join(:inner, [u], t in assoc(u, :tags), as: :tags) + |> where([tags: t], t.name in ^tags) end defp compose_query({:is_admin, bool}, query) do diff --git a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex index 316ea0368..dc445add2 100644 --- a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex @@ -32,7 +32,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do ] end - defp get_tags(%User{tags: tags}) when is_list(tags), do: tags + defp get_tags(%User{} = user) do + {:ok, tags} = Pleroma.Repo.get_assoc(user, :tags) + Enum.map(tags, & &1.name) + end + defp get_tags(_), do: [] defp process_tag( diff --git a/lib/pleroma/web/admin_api/views/account_view.ex b/lib/pleroma/web/admin_api/views/account_view.ex index e053a9b67..ac8c952d9 100644 --- a/lib/pleroma/web/admin_api/views/account_view.ex +++ b/lib/pleroma/web/admin_api/views/account_view.ex @@ -66,6 +66,7 @@ defmodule Pleroma.Web.AdminAPI.AccountView do avatar = User.avatar_url(user) |> MediaProxy.url() display_name = Pleroma.HTML.strip_tags(user.name || user.nickname) user = User.sanitize_html(user, FastSanitize.Sanitizer.StripTags) + {:ok, user_tags} = Pleroma.Repo.get_assoc(user, :tags) %{ "id" => user.id, @@ -76,7 +77,7 @@ defmodule Pleroma.Web.AdminAPI.AccountView do "is_active" => user.is_active, "local" => user.local, "roles" => roles(user), - "tags" => user.tags || [], + "tags" => Enum.map(user_tags, & &1.name), "is_confirmed" => user.is_confirmed, "is_approved" => user.is_approved, "url" => user.uri || user.ap_id, diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index ac25aefdd..7e5a5d732 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -233,6 +233,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do nil end + {:ok, user_tags} = Pleroma.Repo.get_assoc(user, :tags) + %{ id: to_string(user.id), username: username_from_nickname(user.nickname), @@ -269,7 +271,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do ap_id: user.ap_id, also_known_as: user.also_known_as, is_confirmed: user.is_confirmed, - tags: user.tags, + tags: Enum.map(user_tags, & &1.name), hide_followers_count: user.hide_followers_count, hide_follows_count: user.hide_follows_count, hide_followers: user.hide_followers, diff --git a/priv/repo/migrations/20201014064744_create_user_tag.exs b/priv/repo/migrations/20201014064744_create_user_tag.exs index d68b3a1cd..af8fa0952 100644 --- a/priv/repo/migrations/20201014064744_create_user_tag.exs +++ b/priv/repo/migrations/20201014064744_create_user_tag.exs @@ -1,7 +1,7 @@ defmodule Pleroma.Repo.Migrations.CreateUserTag do use Ecto.Migration - def up do + def change do create_if_not_exists table(:users_tags, primary_key: false) do add(:tag_id, references(:tags, on_delete: :delete_all)) add(:user_id, references(:users, type: :uuid, on_delete: :delete_all)) @@ -10,65 +10,5 @@ defmodule Pleroma.Repo.Migrations.CreateUserTag do create_if_not_exists(index(:users_tags, [:tag_id])) create_if_not_exists(index(:users_tags, [:user_id])) create_if_not_exists(unique_index(:users_tags, [:user_id, :tag_id])) - - flush() - - execute(import_user_tags()) - - alter table(:users) do - remove_if_exists(:tags, {:array, :string}) - end - - drop_if_exists(index(:users, [:tags])) - end - - def down do - alter table(:users) do - add_if_not_exists(:tags, {:array, :string}, default: [], null: false) - end - - create_if_not_exists(index(:users, [:tags], using: :gin)) - - flush() - - execute(restore_tags_column()) - - drop_if_exists(table(:users_tags)) - drop_if_exists(index(:users_tags, [:tag_id])) - drop_if_exists(index(:users_tags, [:user_id])) - - drop_if_exists( - unique_index(:users_tags, [:user_id, :tag_id], name: :user_id_tag_id_unique_index) - ) - end - - defp import_user_tags do - """ - INSERT INTO users_tags(user_id, tag_id) - SELECT user_tags.user_id, tags.id - FROM ( - SELECT DISTINCT TRIM(unnest(tags)) as "tag", id as "user_id" - FROM users ) as "user_tags" - INNER JOIN tags as tags on tags.name = user_tags."tag" - ON CONFLICT DO NOTHING - """ - end - - defp restore_tags_column do - """ - UPDATE - users - SET - tags = tags_query.tags_array, - updated_at = now() - FROM ( - SELECT user_id, array_agg(tags.name) as tags_array - FROM users_tags - INNER JOIN users ON users.id = user_id - INNER JOIN tags ON tags.id = tag_id - GROUP BY user_id - ) as tags_query - WHERE tags_query.user_id = users.id - """ end end diff --git a/priv/repo/migrations/20201021180413_import_legacy_tags_to_users_tags.exs b/priv/repo/migrations/20201021180413_import_legacy_tags_to_users_tags.exs new file mode 100644 index 000000000..0cdcc5c19 --- /dev/null +++ b/priv/repo/migrations/20201021180413_import_legacy_tags_to_users_tags.exs @@ -0,0 +1,55 @@ +defmodule Pleroma.Repo.Migrations.ImportLegacyTagsToUsersTags do + use Ecto.Migration + + def up do + execute(import_user_tags()) + + alter table(:users) do + remove_if_exists(:tags, {:array, :string}) + end + + drop_if_exists(index(:users, [:tags])) + end + + def down do + alter table(:users) do + add_if_not_exists(:tags, {:array, :string}, default: [], null: false) + end + + create_if_not_exists(index(:users, [:tags], using: :gin)) + + flush() + + execute(restore_tags_column()) + end + + defp import_user_tags do + """ + INSERT INTO users_tags(user_id, tag_id) + SELECT user_tags.user_id, tags.id + FROM ( + SELECT DISTINCT TRIM(unnest(tags)) as "tag", id as "user_id" + FROM users ) as "user_tags" + INNER JOIN tags as tags on tags.name = user_tags."tag" + ON CONFLICT DO NOTHING + """ + end + + defp restore_tags_column do + """ + UPDATE + users + SET + tags = tags_query.tags_array, + updated_at = now() + FROM ( + SELECT user_id, array_agg(tags.name) as tags_array + FROM users_tags + INNER JOIN users ON users.id = user_id + INNER JOIN tags ON tags.id = tag_id + GROUP BY user_id + ) as tags_query + WHERE tags_query.user_id = users.id + """ + end +end diff --git a/test/mix/tasks/pleroma/user_test.exs b/test/mix/tasks/pleroma/user_test.exs index a2178bbd1..baf4ac29d 100644 --- a/test/mix/tasks/pleroma/user_test.exs +++ b/test/mix/tasks/pleroma/user_test.exs @@ -548,7 +548,7 @@ defmodule Mix.Tasks.Pleroma.UserTest do :ok = Mix.Tasks.Pleroma.User.run(["tag", user.nickname, "pleroma"]) user = User.get_cached_by_nickname(user.nickname) - assert "pleroma" in user.tags + assert "pleroma" in Enum.map(user.tags, & &1.name) end test "it prints an error message when user is not exist" do @@ -561,8 +561,8 @@ defmodule Mix.Tasks.Pleroma.UserTest do describe "untagging" do test "it deletes tags from a user" do - user = insert(:user, tags: ["pleroma"]) - assert "pleroma" in user.tags + user = insert(:user, tags: [build(:tag, name: "pleroma")]) + assert "pleroma" in Enum.map(user.tags, & &1.name) :ok = Mix.Tasks.Pleroma.User.run(["untag", user.nickname, "pleroma"]) diff --git a/test/pleroma/repo/migrations/fix_legacy_tags_test.exs b/test/pleroma/repo/migrations/fix_legacy_tags_test.exs deleted file mode 100644 index 0a1d1d0bb..000000000 --- a/test/pleroma/repo/migrations/fix_legacy_tags_test.exs +++ /dev/null @@ -1,28 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2021 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Repo.Migrations.FixLegacyTagsTest do - alias Pleroma.User - use Pleroma.DataCase, async: true - import Pleroma.Factory - import Pleroma.Tests.Helpers - - setup_all do: require_migration("20200802170532_fix_legacy_tags") - - test "change/0 converts legacy user tags into correct values", %{migration: migration} do - user = insert(:user, tags: ["force_nsfw", "force_unlisted", "verified"]) - user2 = insert(:user) - - assert :ok == migration.change() - - fixed_user = User.get_by_id(user.id) - fixed_user2 = User.get_by_id(user2.id) - - assert fixed_user.tags == ["mrf_tag:media-force-nsfw", "mrf_tag:force-unlisted", "verified"] - assert fixed_user2.tags == [] - - # user2 should not have been updated - assert fixed_user2.updated_at == fixed_user2.inserted_at - end -end diff --git a/test/pleroma/tag_test.exs b/test/pleroma/tag_test.exs new file mode 100644 index 000000000..97b64db86 --- /dev/null +++ b/test/pleroma/tag_test.exs @@ -0,0 +1,94 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.TagTest do + use Pleroma.DataCase + + import Pleroma.Factory + + alias Pleroma.Tag + + describe "upsert/1" do + test "create new normalize tag" do + Tag.upsert(" verify \n") + + assert [tag] = Pleroma.Repo.all(Tag) + assert tag.name == "verify" + end + + test "create new tag" do + Tag.upsert("verify") + + assert [tag] = Pleroma.Repo.all(Tag) + assert tag.name == "verify" + end + + test "do nothing when tag exists" do + insert(:tag, name: "verify") + Tag.upsert("verify") + + assert [tag] = Pleroma.Repo.all(Tag) + assert tag.name == "verify" + end + end + + describe "upsert_tags/1" do + test "create new normalize tags" do + Tag.upsert_tags([" verify \n", "bot", "unconfirmed "]) + + assert tags = Pleroma.Repo.all(Tag) + assert Enum.sort(Enum.map(tags, & &1.name)) == ["bot", "unconfirmed", "verify"] + end + + test "do nothing when tag exists" do + insert(:tag, name: "verify") + + Tag.upsert_tags([" verify \n", "bot", "unconfirmed "]) + + assert tags = Pleroma.Repo.all(Tag) + assert Enum.sort(Enum.map(tags, & &1.name)) == ["bot", "unconfirmed", "verify"] + end + end + + describe "get_tag_ids/1" do + test "returns tags by name" do + verify_tag = insert(:tag, name: "verify") + bot_tag = insert(:tag, name: "bot") + unconfirmed_tag = insert(:tag, name: "unconfirmed") + + tag_ids = Tag.get_tag_ids(["bot", "verify"]) + assert verify_tag.id in tag_ids + assert bot_tag.id in tag_ids + refute unconfirmed_tag.id in tag_ids + end + end + + describe "list_tags/0" do + test "returns all users tags + mrf tags" do + insert(:tag, name: "verify") + insert(:tag, name: "bot") + insert(:tag, name: "unconfirmed") + insert(:tag, name: "mrf_tag:media-strip") + + assert Enum.sort(Tag.list_tags()) == [ + "bot", + "mrf_tag:disable-any-subscription", + "mrf_tag:disable-remote-subscription", + "mrf_tag:force-unlisted", + "mrf_tag:media-force-nsfw", + "mrf_tag:media-strip", + "mrf_tag:sandbox", + "unconfirmed", + "verify" + ] + end + end + + describe "normalize_tags/1" do + test "returns normalize tags" do + assert ["verify", "bot"] == Tag.normalize_tags([" verify \n", "\n bot "]) + assert ["verify"] == Tag.normalize_tags(" verify \n") + end + end +end diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index 6f5bcab57..e0f66a74b 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -133,15 +133,19 @@ defmodule Pleroma.UserTest do describe "when tags are nil" do test "tagging a user" do - user = insert(:user, %{tags: nil}) - user = User.tag(user, ["cool", "dude"]) + insert(:tag, name: "cool") + insert(:tag, name: "dude") + user = insert(:user, %{tags: []}) - assert "cool" in user.tags - assert "dude" in user.tags + user = User.tag(user, ["cool", "dude"]) + user_tags = Enum.map(user.tags, & &1.name) + + assert "cool" in user_tags + assert "dude" in user_tags end test "untagging a user" do - user = insert(:user, %{tags: nil}) + user = insert(:user, %{tags: []}) user = User.untag(user, ["cool", "dude"]) assert user.tags == [] @@ -1606,6 +1610,8 @@ defmodule Pleroma.UserTest do end test "delete/1 purges a user when they wouldn't be fully deleted" do + _tag = insert(:tag, name: "verify") + user = insert(:user, %{ bio: "eyy lmao", @@ -1614,7 +1620,7 @@ defmodule Pleroma.UserTest do keys: "RSA begin buplic key", public_key: "--PRIVATE KEYE--", avatar: %{"a" => "b"}, - tags: ["qqqqq"], + # tags: ["qqqqq"], banner: %{"a" => "b"}, background: %{"a" => "b"}, note_count: 9, @@ -1641,9 +1647,17 @@ defmodule Pleroma.UserTest do also_known_as: ["https://lol.olo/users/loll"] }) + user = User.tag(user, "verify") + assert Enum.map(user.tags, & &1.name) == ["verify"] + assert Repo.aggregate(from(ut in "users_tags"), :count, :user_id) == 1 {:ok, job} = User.delete(user) {:ok, _} = ObanHelpers.perform(job) - user = User.get_by_id(user.id) + + user = + User.get_by_id(user.id) + |> Repo.preload([:tags]) + + assert Repo.aggregate(from(ut in "users_tags"), :count, :user_id) == 0 assert %User{ bio: "", diff --git a/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs b/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs index faaadff79..7b1486365 100644 --- a/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs @@ -11,7 +11,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicyTest do describe "mrf_tag:disable-any-subscription" do test "rejects message" do - actor = insert(:user, tags: ["mrf_tag:disable-any-subscription"]) + actor = insert(:user, tags: [build(:tag, name: "mrf_tag:disable-any-subscription")]) message = %{"object" => actor.ap_id, "type" => "Follow", "actor" => actor.ap_id} assert {:reject, _} = TagPolicy.filter(message) end @@ -19,15 +19,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicyTest do describe "mrf_tag:disable-remote-subscription" do test "rejects non-local follow requests" do - actor = insert(:user, tags: ["mrf_tag:disable-remote-subscription"]) - follower = insert(:user, tags: ["mrf_tag:disable-remote-subscription"], local: false) + tag = insert(:tag, name: "mrf_tag:disable-remote-subscription") + actor = insert(:user, tags: [tag]) + follower = insert(:user, tags: [tag], local: false) message = %{"object" => actor.ap_id, "type" => "Follow", "actor" => follower.ap_id} assert {:reject, _} = TagPolicy.filter(message) end test "allows non-local follow requests" do - actor = insert(:user, tags: ["mrf_tag:disable-remote-subscription"]) - follower = insert(:user, tags: ["mrf_tag:disable-remote-subscription"], local: true) + tag = insert(:tag, name: "mrf_tag:disable-remote-subscription") + actor = insert(:user, tags: [tag]) + follower = insert(:user, tags: [tag], local: true) message = %{"object" => actor.ap_id, "type" => "Follow", "actor" => follower.ap_id} assert {:ok, _message} = TagPolicy.filter(message) end @@ -35,7 +37,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicyTest do describe "mrf_tag:sandbox" do test "removes from public timelines" do - actor = insert(:user, tags: ["mrf_tag:sandbox"]) + actor = insert(:user, tags: [build(:tag, name: "mrf_tag:sandbox")]) message = %{ "actor" => actor.ap_id, @@ -59,7 +61,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicyTest do describe "mrf_tag:force-unlisted" do test "removes from the federated timeline" do - actor = insert(:user, tags: ["mrf_tag:force-unlisted"]) + actor = insert(:user, tags: [build(:tag, name: "mrf_tag:force-unlisted")]) message = %{ "actor" => actor.ap_id, @@ -83,7 +85,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicyTest do describe "mrf_tag:media-strip" do test "removes attachments" do - actor = insert(:user, tags: ["mrf_tag:media-strip"]) + actor = insert(:user, tags: [build(:tag, name: "mrf_tag:media-strip")]) message = %{ "actor" => actor.ap_id, @@ -103,7 +105,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicyTest do describe "mrf_tag:media-force-nsfw" do test "Mark as sensitive on presence of attachments" do - actor = insert(:user, tags: ["mrf_tag:media-force-nsfw"]) + actor = insert(:user, tags: [build(:tag, name: "mrf_tag:media-force-nsfw")]) message = %{ "actor" => actor.ap_id, diff --git a/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs b/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs index 8cd9f939b..bf67218f8 100644 --- a/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/admin_api_controller_test.exs @@ -90,98 +90,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end end - describe "PUT /api/pleroma/admin/users/tag" do - setup %{conn: conn} do - user1 = insert(:user, %{tags: ["x"]}) - user2 = insert(:user, %{tags: ["y"]}) - user3 = insert(:user, %{tags: ["unchanged"]}) - - conn = - conn - |> put_req_header("accept", "application/json") - |> put( - "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <> - "#{user2.nickname}&tags[]=foo&tags[]=bar" - ) - - %{conn: conn, user1: user1, user2: user2, user3: user3} - end - - test "it appends specified tags to users with specified nicknames", %{ - conn: conn, - admin: admin, - user1: user1, - user2: user2 - } do - assert empty_json_response(conn) - assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"] - assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"] - - log_entry = Repo.one(ModerationLog) - - users = - [user1.nickname, user2.nickname] - |> Enum.map(&"@#{&1}") - |> Enum.join(", ") - - tags = ["foo", "bar"] |> Enum.join(", ") - - assert ModerationLog.get_log_entry_message(log_entry) == - "@#{admin.nickname} added tags: #{tags} to users: #{users}" - end - - test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do - assert empty_json_response(conn) - assert User.get_cached_by_id(user3.id).tags == ["unchanged"] - end - end - - describe "DELETE /api/pleroma/admin/users/tag" do - setup %{conn: conn} do - user1 = insert(:user, %{tags: ["x"]}) - user2 = insert(:user, %{tags: ["y", "z"]}) - user3 = insert(:user, %{tags: ["unchanged"]}) - - conn = - conn - |> put_req_header("accept", "application/json") - |> delete( - "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <> - "#{user2.nickname}&tags[]=x&tags[]=z" - ) - - %{conn: conn, user1: user1, user2: user2, user3: user3} - end - - test "it removes specified tags from users with specified nicknames", %{ - conn: conn, - admin: admin, - user1: user1, - user2: user2 - } do - assert empty_json_response(conn) - assert User.get_cached_by_id(user1.id).tags == [] - assert User.get_cached_by_id(user2.id).tags == ["y"] - - log_entry = Repo.one(ModerationLog) - - users = - [user1.nickname, user2.nickname] - |> Enum.map(&"@#{&1}") - |> Enum.join(", ") - - tags = ["x", "z"] |> Enum.join(", ") - - assert ModerationLog.get_log_entry_message(log_entry) == - "@#{admin.nickname} removed tags: #{tags} from users: #{users}" - end - - test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do - assert empty_json_response(conn) - assert User.get_cached_by_id(user3.id).tags == ["unchanged"] - end - end - describe "/api/pleroma/admin/users/:nickname/permission_group" do test "GET is giving user_info", %{admin: admin, conn: conn} do conn = diff --git a/test/web/admin_api/controllers/tag_controller_test.exs b/test/pleroma/web/admin_api/controllers/tag_controller_test.exs similarity index 75% rename from test/web/admin_api/controllers/tag_controller_test.exs rename to test/pleroma/web/admin_api/controllers/tag_controller_test.exs index 88eeafac0..1ead1ca76 100644 --- a/test/web/admin_api/controllers/tag_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/tag_controller_test.exs @@ -58,9 +58,9 @@ defmodule Pleroma.Web.AdminAPI.TagControllerTest do describe "PUT /api/pleroma/admin/users/tag" do setup %{conn: conn} do - user1 = insert(:user, %{tags: ["x"]}) - user2 = insert(:user, %{tags: ["y"]}) - user3 = insert(:user, %{tags: ["unchanged"]}) + user1 = insert(:user, %{tags: [build(:tag, name: "x")]}) + user2 = insert(:user, %{tags: [build(:tag, name: "y")]}) + user3 = insert(:user, %{tags: [build(:tag, name: "unchanged")]}) conn = conn @@ -80,8 +80,10 @@ defmodule Pleroma.Web.AdminAPI.TagControllerTest do user2: user2 } do assert empty_json_response(conn) - assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"] - assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"] + {:ok, tags} = Repo.get_assoc(User.get_cached_by_id(user1.id), :tags) + assert Enum.map(tags, & &1.name) == ["x", "foo", "bar"] + {:ok, tags} = Repo.get_assoc(User.get_cached_by_id(user2.id), :tags) + assert Enum.map(tags, & &1.name) == ["y", "foo", "bar"] log_entry = Repo.one(ModerationLog) @@ -98,15 +100,16 @@ defmodule Pleroma.Web.AdminAPI.TagControllerTest do test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do assert empty_json_response(conn) - assert User.get_cached_by_id(user3.id).tags == ["unchanged"] + {:ok, tags} = Repo.get_assoc(User.get_cached_by_id(user3.id), :tags) + assert Enum.map(tags, & &1.name) == ["unchanged"] end end describe "DELETE /api/pleroma/admin/users/tag" do setup %{conn: conn} do - user1 = insert(:user, %{tags: ["x"]}) - user2 = insert(:user, %{tags: ["y", "z"]}) - user3 = insert(:user, %{tags: ["unchanged"]}) + user1 = insert(:user, %{tags: [build(:tag, name: "x")]}) + user2 = insert(:user, %{tags: [build(:tag, name: "y"), build(:tag, name: "z")]}) + user3 = insert(:user, %{tags: [build(:tag, name: "unchanged")]}) conn = conn @@ -126,8 +129,10 @@ defmodule Pleroma.Web.AdminAPI.TagControllerTest do user2: user2 } do assert empty_json_response(conn) - assert User.get_cached_by_id(user1.id).tags == [] - assert User.get_cached_by_id(user2.id).tags == ["y"] + {:ok, tags} = Repo.get_assoc(User.get_cached_by_id(user1.id), :tags) + assert tags == [] + {:ok, tags} = Repo.get_assoc(User.get_cached_by_id(user2.id), :tags) + assert Enum.map(tags, & &1.name) == ["y"] log_entry = Repo.one(ModerationLog) @@ -144,7 +149,8 @@ defmodule Pleroma.Web.AdminAPI.TagControllerTest do test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do assert empty_json_response(conn) - assert User.get_cached_by_id(user3.id).tags == ["unchanged"] + {:ok, tags} = Repo.get_assoc(User.get_cached_by_id(user3.id), :tags) + assert Enum.map(tags, & &1.name) == ["unchanged"] end end end diff --git a/test/pleroma/web/admin_api/search_test.exs b/test/pleroma/web/admin_api/search_test.exs index b8eeec65b..40e0007e8 100644 --- a/test/pleroma/web/admin_api/search_test.exs +++ b/test/pleroma/web/admin_api/search_test.exs @@ -130,17 +130,18 @@ defmodule Pleroma.Web.AdminAPI.SearchTest do end test "it returns users with tags" do - user1 = insert(:user, tags: ["first"]) - user2 = insert(:user, tags: ["second"]) + user1 = insert(:user, tags: [build(:tag, name: "first")]) + user2 = insert(:user, tags: [build(:tag, name: "second")]) insert(:user) insert(:user) {:ok, _results, total} = Search.user() {:ok, users, count} = Search.user(%{tags: ["first", "second"]}) + assert total == 4 assert count == 2 - assert user1 in users - assert user2 in users + assert user1.id in collect_ids(users) + assert user2.id in collect_ids(users) end test "it returns users by actor_types" do