[#1335] Reorganized `users.mutes` as relation to UserMute entity.

This commit is contained in:
Ivan Tashkinov 2019-11-15 21:38:54 +03:00
parent 5cf2c7422b
commit c31ddce51e
16 changed files with 258 additions and 64 deletions

View File

@ -23,6 +23,7 @@ defmodule Pleroma.User do
alias Pleroma.RepoStreamer alias Pleroma.RepoStreamer
alias Pleroma.User alias Pleroma.User
alias Pleroma.UserBlock alias Pleroma.UserBlock
alias Pleroma.UserMute
alias Pleroma.Web alias Pleroma.Web
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
@ -119,11 +120,17 @@ defmodule Pleroma.User do
has_many(:notifications, Notification) has_many(:notifications, Notification)
has_many(:registrations, Registration) has_many(:registrations, Registration)
has_many(:deliveries, Delivery) has_many(:deliveries, Delivery)
has_many(:blocker_blocks, UserBlock, foreign_key: :blocker_id) has_many(:blocker_blocks, UserBlock, foreign_key: :blocker_id)
has_many(:blockee_blocks, UserBlock, foreign_key: :blockee_id) has_many(:blockee_blocks, UserBlock, foreign_key: :blockee_id)
has_many(:blocked_users, through: [:blocker_blocks, :blockee]) has_many(:blocked_users, through: [:blocker_blocks, :blockee])
has_many(:blocker_users, through: [:blockee_blocks, :blocker]) has_many(:blocker_users, through: [:blockee_blocks, :blocker])
has_many(:muter_mutes, UserMute, foreign_key: :muter_id)
has_many(:mutee_mutes, UserMute, foreign_key: :mutee_id)
has_many(:muted_users, through: [:muter_mutes, :mutee])
has_many(:muter_users, through: [:mutee_mutes, :muter])
field(:info, :map, default: %{}) field(:info, :map, default: %{})
# `:blocks` is deprecated (replaced with `blocked_users` relation) # `:blocks` is deprecated (replaced with `blocked_users` relation)
@ -968,12 +975,12 @@ def get_recipients_from_activity(%Activity{recipients: to}) do
end end
@spec mute(User.t(), User.t(), boolean()) :: {:ok, User.t()} | {:error, String.t()} @spec mute(User.t(), User.t(), boolean()) :: {:ok, User.t()} | {:error, String.t()}
def mute(muter, %User{ap_id: ap_id}, notifications? \\ true) do def mute(muter, %User{} = mutee, notifications? \\ true) do
add_to_mutes(muter, ap_id, notifications?) add_to_mutes(muter, mutee, notifications?)
end end
def unmute(muter, %{ap_id: ap_id}) do def unmute(muter, %User{} = mutee) do
remove_from_mutes(muter, ap_id) remove_from_mutes(muter, mutee)
end end
def subscribe(subscriber, %{ap_id: ap_id}) do def subscribe(subscriber, %{ap_id: ap_id}) do
@ -1041,7 +1048,11 @@ def unblock(blocker, %{ap_id: ap_id}) do
end end
def mutes?(nil, _), do: false def mutes?(nil, _), do: false
def mutes?(user, %{ap_id: ap_id}), do: Enum.member?(user.mutes, ap_id) def mutes?(%User{} = user, %User{} = target), do: mutes_user?(user, target)
def mutes_user?(%User{} = user, %User{} = target) do
UserMute.exists?(user, target)
end
@spec muted_notifications?(User.t() | nil, User.t() | map()) :: boolean() @spec muted_notifications?(User.t() | nil, User.t() | map()) :: boolean()
def muted_notifications?(nil, _), do: false def muted_notifications?(nil, _), do: false
@ -1049,17 +1060,17 @@ def muted_notifications?(nil, _), do: false
def muted_notifications?(user, %{ap_id: ap_id}), def muted_notifications?(user, %{ap_id: ap_id}),
do: Enum.member?(user.muted_notifications, ap_id) do: Enum.member?(user.muted_notifications, ap_id)
def blocks?(%User{} = user, %User{} = target) do
blocks_ap_id?(user, target) || blocks_domain?(user, target)
end
def blocks?(nil, _), do: false def blocks?(nil, _), do: false
def blocks_ap_id?(%User{} = user, %User{} = target) do def blocks?(%User{} = user, %User{} = target) do
blocks_user?(user, target) || blocks_domain?(user, target)
end
def blocks_user?(%User{} = user, %User{} = target) do
UserBlock.exists?(user, target) UserBlock.exists?(user, target)
end end
def blocks_ap_id?(_, _), do: false def blocks_user?(_, _), do: false
def blocks_domain?(%User{} = user, %User{} = target) do def blocks_domain?(%User{} = user, %User{} = target) do
domain_blocks = Pleroma.Web.ActivityPub.MRF.subdomains_regex(user.domain_blocks) domain_blocks = Pleroma.Web.ActivityPub.MRF.subdomains_regex(user.domain_blocks)
@ -1077,7 +1088,16 @@ def subscribed_to?(user, %{ap_id: ap_id}) do
@spec muted_users(User.t()) :: [User.t()] @spec muted_users(User.t()) :: [User.t()]
def muted_users(user) do def muted_users(user) do
User.Query.build(%{ap_id: user.mutes, deactivated: false}) user
|> assoc(:muted_users)
|> restrict_deactivated()
|> Repo.all()
end
def muted_ap_ids(user) do
user
|> assoc(:muted_users)
|> select([u], u.ap_id)
|> Repo.all() |> Repo.all()
end end
@ -1096,6 +1116,35 @@ def blocked_ap_ids(user) do
|> Repo.all() |> Repo.all()
end end
defp related_ap_ids_sql(join_table, source_column, target_column) do
"(SELECT array_agg(u.ap_id) FROM users as u " <>
"INNER JOIN #{join_table} AS join_table " <>
"ON join_table.#{source_column} = $1 " <>
"WHERE u.id = join_table.#{target_column})"
end
@related_ap_ids_sql_params %{
blocked_users: ["user_blocks", "blocker_id", "blockee_id"],
muted_users: ["user_mutes", "muter_id", "mutee_id"]
}
def related_ap_ids(user, relations) when is_list(relations) do
query =
relations
|> Enum.map(fn r -> @related_ap_ids_sql_params[r] end)
|> Enum.filter(& &1)
|> Enum.map(fn [join_table, source_column, target_column] ->
related_ap_ids_sql(join_table, source_column, target_column)
end)
|> Enum.join(", ")
with {:ok, %{rows: [ap_ids_arrays]}} <-
Repo.query("SELECT #{query}", [FlakeId.from_string(user.id)]) do
ap_ids_arrays = Enum.map(ap_ids_arrays, &(&1 || []))
{:ok, ap_ids_arrays}
end
end
@spec subscribers(User.t()) :: [User.t()] @spec subscribers(User.t()) :: [User.t()]
def subscribers(user) do def subscribers(user) do
User.Query.build(%{ap_id: user.subscribers, deactivated: false}) User.Query.build(%{ap_id: user.subscribers, deactivated: false})
@ -1877,32 +1926,27 @@ defp remove_from_block(%User{} = user, %User{} = blocked) do
UserBlock.delete(user, blocked) UserBlock.delete(user, blocked)
end end
defp set_mutes(user, mutes) do defp add_to_mutes(%User{} = user, %User{ap_id: ap_id} = muted_user, notifications?) do
params = %{mutes: mutes} with {:ok, user_mute} <- UserMute.create(user, muted_user),
{:ok, _user} <-
user
|> cast(params, [:mutes])
|> validate_required([:mutes])
|> update_and_set_cache()
end
def add_to_mutes(user, muted, notifications?) do
with {:ok, user} <- set_mutes(user, Enum.uniq([muted | user.mutes])) do
set_notification_mutes( set_notification_mutes(
user, user,
Enum.uniq([muted | user.muted_notifications]), Enum.uniq([ap_id | user.muted_notifications]),
notifications? notifications?
) ) do
{:ok, user_mute}
end end
end end
def remove_from_mutes(user, muted) do defp remove_from_mutes(user, %User{ap_id: ap_id} = muted_user) do
with {:ok, user} <- set_mutes(user, List.delete(user.mutes, muted)) do with {:ok, user_mute} <- UserMute.delete(user, muted_user),
{:ok, _user} <-
set_notification_mutes( set_notification_mutes(
user, user,
List.delete(user.muted_notifications, muted), List.delete(user.muted_notifications, ap_id),
true true
) ) do
{:ok, user_mute}
end end
end end

71
lib/pleroma/user_mute.ex Normal file
View File

@ -0,0 +1,71 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.UserMute do
use Ecto.Schema
import Ecto.Changeset
import Ecto.Query
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.UserMute
schema "user_mutes" do
belongs_to(:muter, User, type: FlakeId.Ecto.CompatType)
belongs_to(:mutee, User, type: FlakeId.Ecto.CompatType)
timestamps(updated_at: false)
end
def changeset(%UserMute{} = user_mute, params \\ %{}) do
user_mute
|> cast(params, [:muter_id, :mutee_id])
|> validate_required([:muter_id, :mutee_id])
|> unique_constraint(:mutee_id, name: :user_mutes_muter_id_mutee_id_index)
|> validate_not_self_mute()
end
def exists?(%User{} = muter, %User{} = mutee) do
UserMute
|> where(muter_id: ^muter.id, mutee_id: ^mutee.id)
|> Repo.exists?()
end
def create(%User{} = muter, %User{} = mutee) do
%UserMute{}
|> changeset(%{muter_id: muter.id, mutee_id: mutee.id})
|> Repo.insert(
on_conflict: :replace_all_except_primary_key,
conflict_target: [:muter_id, :mutee_id]
)
end
def delete(%User{} = muter, %User{} = mutee) do
attrs = %{muter_id: muter.id, mutee_id: mutee.id}
case Repo.get_by(UserMute, attrs) do
%UserMute{} = existing_record -> Repo.delete(existing_record)
nil -> {:ok, nil}
end
end
defp validate_not_self_mute(%Ecto.Changeset{} = changeset) do
changeset
|> validate_change(:mutee_id, fn _, mutee_id ->
if mutee_id == get_field(changeset, :muter_id) do
[mutee_id: "can't be equal to muter_id"]
else
[]
end
end)
|> validate_change(:muter_id, fn _, muter_id ->
if muter_id == get_field(changeset, :mutee_id) do
[muter_id: "can't be equal to mutee_id"]
else
[]
end
end)
end
end

View File

@ -858,7 +858,7 @@ defp restrict_reblogs(query, _), do: query
defp restrict_muted(query, %{"with_muted" => val}) when val in [true, "true", "1"], do: query defp restrict_muted(query, %{"with_muted" => val}) when val in [true, "true", "1"], do: query
defp restrict_muted(query, %{"muting_user" => %User{} = user} = opts) do defp restrict_muted(query, %{"muting_user" => %User{} = user} = opts) do
mutes = user.mutes mutes = opts["muted_ap_ids"] || User.muted_ap_ids(user)
query = query =
from([activity] in query, from([activity] in query,
@ -875,8 +875,8 @@ defp restrict_muted(query, %{"muting_user" => %User{} = user} = opts) do
defp restrict_muted(query, _), do: query defp restrict_muted(query, _), do: query
defp restrict_blocked(query, %{"blocking_user" => %User{} = user}) do defp restrict_blocked(query, %{"blocking_user" => %User{} = user} = opts) do
blocked_ap_ids = User.blocked_ap_ids(user) blocked_ap_ids = opts["blocked_ap_ids"] || User.blocked_ap_ids(user)
domain_blocks = user.domain_blocks || [] domain_blocks = user.domain_blocks || []
query = query =

View File

@ -323,7 +323,9 @@ def unfollow(%{assigns: %{user: follower, account: followed}} = conn, _params) d
def mute(%{assigns: %{user: muter, account: muted}} = conn, params) do def mute(%{assigns: %{user: muter, account: muted}} = conn, params) do
notifications? = params |> Map.get("notifications", true) |> truthy_param?() notifications? = params |> Map.get("notifications", true) |> truthy_param?()
with {:ok, muter} <- User.mute(muter, muted, notifications?) do with {:ok, _user_mute} <- User.mute(muter, muted, notifications?) do
# TODO: remove `muter` refresh once `muted_notifications` field is deprecated
muter = User.get_cached_by_id(muter.id)
render(conn, "relationship.json", user: muter, target: muted) render(conn, "relationship.json", user: muter, target: muted)
else else
{:error, message} -> json_response(conn, :forbidden, %{error: message}) {:error, message} -> json_response(conn, :forbidden, %{error: message})
@ -332,7 +334,9 @@ def mute(%{assigns: %{user: muter, account: muted}} = conn, params) do
@doc "POST /api/v1/accounts/:id/unmute" @doc "POST /api/v1/accounts/:id/unmute"
def unmute(%{assigns: %{user: muter, account: muted}} = conn, _params) do def unmute(%{assigns: %{user: muter, account: muted}} = conn, _params) do
with {:ok, muter} <- User.unmute(muter, muted) do with {:ok, _user_mute} <- User.unmute(muter, muted) do
# TODO: remove `muter` refresh once `muted_notifications` field is deprecated
muter = User.get_cached_by_id(muter.id)
render(conn, "relationship.json", user: muter, target: muted) render(conn, "relationship.json", user: muter, target: muted)
else else
{:error, message} -> json_response(conn, :forbidden, %{error: message}) {:error, message} -> json_response(conn, :forbidden, %{error: message})

View File

@ -50,8 +50,8 @@ def render("relationship.json", %{user: %User{} = user, target: %User{} = target
id: to_string(target.id), id: to_string(target.id),
following: User.following?(user, target), following: User.following?(user, target),
followed_by: User.following?(target, user), followed_by: User.following?(target, user),
blocking: User.blocks_ap_id?(user, target), blocking: User.blocks_user?(user, target),
blocked_by: User.blocks_ap_id?(target, user), blocked_by: User.blocks_user?(target, user),
muting: User.mutes?(user, target), muting: User.mutes?(user, target),
muting_notifications: User.muted_notifications?(user, target), muting_notifications: User.muted_notifications?(user, target),
subscribing: User.subscribed_to?(user, target), subscribing: User.subscribed_to?(user, target),

View File

@ -129,8 +129,7 @@ defp do_stream(%{topic: topic, item: item}) do
end end
defp should_send?(%User{} = user, %Activity{} = item) do defp should_send?(%User{} = user, %Activity{} = item) do
blocks = User.blocked_ap_ids(user) {:ok, [blocks, mutes]} = User.related_ap_ids(user, [:blocked_users, :muted_users])
mutes = user.mutes || []
reblog_mutes = user.muted_reblogs || [] reblog_mutes = user.muted_reblogs || []
recipient_blocks = MapSet.new(blocks ++ mutes) recipient_blocks = MapSet.new(blocks ++ mutes)
recipients = MapSet.new(item.recipients) recipients = MapSet.new(item.recipients)

View File

@ -30,9 +30,8 @@ def up do
for blockee_ap_id <- blockee_ap_ids do for blockee_ap_id <- blockee_ap_ids do
blockee_id = blockee_id_by_ap_id[blockee_ap_id] blockee_id = blockee_id_by_ap_id[blockee_ap_id]
blockee_uuid = blockee_id && Ecto.UUID.cast!(blockee_id)
with {:ok, blockee_uuid} <- Ecto.UUID.cast(blockee_id) do with {:ok, blockee_uuid} <- blockee_id && Ecto.UUID.cast(blockee_id) do
execute( execute(
"INSERT INTO user_blocks(blocker_id, blockee_id, inserted_at) " <> "INSERT INTO user_blocks(blocker_id, blockee_id, inserted_at) " <>
"VALUES('#{blocker_uuid}'::uuid, '#{blockee_uuid}'::uuid, now()) " <> "VALUES('#{blocker_uuid}'::uuid, '#{blockee_uuid}'::uuid, now()) " <>

View File

@ -0,0 +1,14 @@
defmodule Pleroma.Repo.Migrations.CreateUserMutes do
use Ecto.Migration
def change do
create_if_not_exists table(:user_mutes) do
add(:muter_id, references(:users, type: :uuid, on_delete: :delete_all))
add(:mutee_id, references(:users, type: :uuid, on_delete: :delete_all))
timestamps(updated_at: false)
end
create_if_not_exists(unique_index(:user_mutes, [:muter_id, :mutee_id]))
end
end

View File

@ -0,0 +1,48 @@
defmodule Pleroma.Repo.Migrations.DataMigrationPopulateUserMutes do
use Ecto.Migration
alias Ecto.Adapters.SQL
alias Pleroma.Repo
require Logger
def up do
{:ok, %{rows: mute_rows}} = SQL.query(Repo, "SELECT id, mutes FROM users WHERE mutes != '{}'")
mutee_ap_ids =
Enum.flat_map(
mute_rows,
fn [_, ap_ids] -> ap_ids end
)
|> Enum.uniq()
# Selecting ids of all mutees at once in order to reduce the number of SELECT queries
{:ok, %{rows: mutee_ap_id_id}} =
SQL.query(Repo, "SELECT ap_id, id FROM users WHERE ap_id = ANY($1)", [mutee_ap_ids])
mutee_id_by_ap_id = Enum.into(mutee_ap_id_id, %{}, fn [k, v] -> {k, v} end)
Enum.each(
mute_rows,
fn [muter_id, mutee_ap_ids] ->
muter_uuid = Ecto.UUID.cast!(muter_id)
for mutee_ap_id <- mutee_ap_ids do
mutee_id = mutee_id_by_ap_id[mutee_ap_id]
with {:ok, mutee_uuid} <- mutee_id && Ecto.UUID.cast(mutee_id) do
execute(
"INSERT INTO user_mutes(muter_id, mutee_id, inserted_at) " <>
"VALUES('#{muter_uuid}'::uuid, '#{mutee_uuid}'::uuid, now()) " <>
"ON CONFLICT (muter_id, mutee_id) DO NOTHING"
)
else
_ -> Logger.warn("Missing reference: (#{muter_uuid}, #{mutee_id})")
end
end
end
)
end
def down, do: :noop
end

View File

@ -112,7 +112,7 @@ test "notification created if user is muted without notifications" do
muter = insert(:user) muter = insert(:user)
muted = insert(:user) muted = insert(:user)
{:ok, muter} = User.mute(muter, muted, false) {:ok, _user_mute} = User.mute(muter, muted, false)
{:ok, activity} = CommonAPI.post(muted, %{"status" => "Hi @#{muter.nickname}"}) {:ok, activity} = CommonAPI.post(muted, %{"status" => "Hi @#{muter.nickname}"})
@ -636,7 +636,7 @@ test "notifications are deleted if a remote user is deleted" do
test "it returns notifications for muted user without notifications" do test "it returns notifications for muted user without notifications" do
user = insert(:user) user = insert(:user)
muted = insert(:user) muted = insert(:user)
{:ok, user} = User.mute(user, muted, false) {:ok, _user_mute} = User.mute(user, muted, false)
{:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"}) {:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
@ -646,7 +646,10 @@ test "it returns notifications for muted user without notifications" do
test "it doesn't return notifications for muted user with notifications" do test "it doesn't return notifications for muted user with notifications" do
user = insert(:user) user = insert(:user)
muted = insert(:user) muted = insert(:user)
{:ok, user} = User.mute(user, muted) {:ok, _user_mute} = User.mute(user, muted)
# Refreshing to reflect embedded ap id relation fields (remove once removed)
user = refresh_record(user)
{:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"}) {:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
@ -686,7 +689,7 @@ test "it doesn't return notifications for muted thread" do
test "it returns notifications from a muted user when with_muted is set" do test "it returns notifications from a muted user when with_muted is set" do
user = insert(:user) user = insert(:user)
muted = insert(:user) muted = insert(:user)
{:ok, user} = User.mute(user, muted) {:ok, _user_mute} = User.mute(user, muted)
{:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"}) {:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})

View File

@ -673,7 +673,10 @@ test "it mutes people" do
refute User.mutes?(user, muted_user) refute User.mutes?(user, muted_user)
refute User.muted_notifications?(user, muted_user) refute User.muted_notifications?(user, muted_user)
{:ok, user} = User.mute(user, muted_user) {:ok, _user_mute} = User.mute(user, muted_user)
# Refreshing to reflect embedded ap id relation fields (remove once removed)
user = refresh_record(user)
assert User.mutes?(user, muted_user) assert User.mutes?(user, muted_user)
assert User.muted_notifications?(user, muted_user) assert User.muted_notifications?(user, muted_user)
@ -683,8 +686,8 @@ test "it unmutes users" do
user = insert(:user) user = insert(:user)
muted_user = insert(:user) muted_user = insert(:user)
{:ok, user} = User.mute(user, muted_user) {:ok, _user_mute} = User.mute(user, muted_user)
{:ok, user} = User.unmute(user, muted_user) {:ok, _user_mute} = User.unmute(user, muted_user)
refute User.mutes?(user, muted_user) refute User.mutes?(user, muted_user)
refute User.muted_notifications?(user, muted_user) refute User.muted_notifications?(user, muted_user)
@ -697,7 +700,7 @@ test "it mutes user without notifications" do
refute User.mutes?(user, muted_user) refute User.mutes?(user, muted_user)
refute User.muted_notifications?(user, muted_user) refute User.muted_notifications?(user, muted_user)
{:ok, user} = User.mute(user, muted_user, false) {:ok, _user_mute} = User.mute(user, muted_user, false)
assert User.mutes?(user, muted_user) assert User.mutes?(user, muted_user)
refute User.muted_notifications?(user, muted_user) refute User.muted_notifications?(user, muted_user)

View File

@ -611,7 +611,9 @@ test "doesn't return muted activities" do
activity_three = insert(:note_activity) activity_three = insert(:note_activity)
user = insert(:user) user = insert(:user)
booster = insert(:user) booster = insert(:user)
{:ok, user} = User.mute(user, %User{ap_id: activity_one.data["actor"]})
activity_one_actor = User.get_by_ap_id(activity_one.data["actor"])
{:ok, _user_mute} = User.mute(user, activity_one_actor)
activities = activities =
ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true}) ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true})
@ -632,7 +634,7 @@ test "doesn't return muted activities" do
assert Enum.member?(activities, activity_three) assert Enum.member?(activities, activity_three)
assert Enum.member?(activities, activity_one) assert Enum.member?(activities, activity_one)
{:ok, user} = User.unmute(user, %User{ap_id: activity_one.data["actor"]}) {:ok, _user_mute} = User.unmute(user, activity_one_actor)
activities = activities =
ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true}) ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true})
@ -641,7 +643,8 @@ test "doesn't return muted activities" do
assert Enum.member?(activities, activity_three) assert Enum.member?(activities, activity_three)
assert Enum.member?(activities, activity_one) assert Enum.member?(activities, activity_one)
{:ok, user} = User.mute(user, %User{ap_id: activity_three.data["actor"]}) activity_three_actor = User.get_by_ap_id(activity_three.data["actor"])
{:ok, _user_mute} = User.mute(user, activity_three_actor)
{:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(activity_three.id, booster) {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(activity_three.id, booster)
%Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id) %Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id)
activity_three = Activity.get_by_id(activity_three.id) activity_three = Activity.get_by_id(activity_three.id)

View File

@ -868,7 +868,7 @@ test "getting a list of mutes", %{conn: conn} do
user = insert(:user) user = insert(:user)
other_user = insert(:user) other_user = insert(:user)
{:ok, user} = User.mute(user, other_user) {:ok, _user_mute} = User.mute(user, other_user)
conn = conn =
conn conn

View File

@ -289,7 +289,10 @@ test "doesn't see notifications after muting user with notifications", %{conn: c
assert length(json_response(conn, 200)) == 1 assert length(json_response(conn, 200)) == 1
{:ok, user} = User.mute(user, user2) {:ok, _user_mute} = User.mute(user, user2)
# Refreshing to reflect embedded ap id relation fields (remove once removed)
user = refresh_record(user)
conn = assign(build_conn(), :user, user) conn = assign(build_conn(), :user, user)
conn = get(conn, "/api/v1/notifications") conn = get(conn, "/api/v1/notifications")
@ -310,7 +313,7 @@ test "see notifications after muting user without notifications", %{conn: conn}
assert length(json_response(conn, 200)) == 1 assert length(json_response(conn, 200)) == 1
{:ok, user} = User.mute(user, user2, false) {:ok, _user_mute} = User.mute(user, user2, false)
conn = assign(build_conn(), :user, user) conn = assign(build_conn(), :user, user)
conn = get(conn, "/api/v1/notifications") conn = get(conn, "/api/v1/notifications")
@ -333,7 +336,7 @@ test "see notifications after muting user with notifications and with_muted para
assert length(json_response(conn, 200)) == 1 assert length(json_response(conn, 200)) == 1
{:ok, user} = User.mute(user, user2) {:ok, _user_mute} = User.mute(user, user2)
conn = assign(build_conn(), :user, user) conn = assign(build_conn(), :user, user)
conn = get(conn, "/api/v1/notifications", %{"with_muted" => "true"}) conn = get(conn, "/api/v1/notifications", %{"with_muted" => "true"})

View File

@ -191,9 +191,12 @@ test "represent a relationship for the following and followed user" do
{:ok, user} = User.follow(user, other_user) {:ok, user} = User.follow(user, other_user)
{:ok, other_user} = User.follow(other_user, user) {:ok, other_user} = User.follow(other_user, user)
{:ok, other_user} = User.subscribe(user, other_user) {:ok, other_user} = User.subscribe(user, other_user)
{:ok, user} = User.mute(user, other_user, true) {:ok, _user_mute} = User.mute(user, other_user, true)
{:ok, user} = CommonAPI.hide_reblogs(user, other_user) {:ok, user} = CommonAPI.hide_reblogs(user, other_user)
# Refreshing to reflect embedded ap id relation fields (remove once removed)
user = refresh_record(user)
expected = %{ expected = %{
id: to_string(other_user.id), id: to_string(other_user.id),
following: true, following: true,

View File

@ -183,7 +183,7 @@ test "tells if the message is muted for some reason" do
user = insert(:user) user = insert(:user)
other_user = insert(:user) other_user = insert(:user)
{:ok, user} = User.mute(user, other_user) {:ok, _user_mute} = User.mute(user, other_user)
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"}) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"})
status = StatusView.render("show.json", %{activity: activity}) status = StatusView.render("show.json", %{activity: activity})
@ -199,7 +199,7 @@ test "tells if the message is thread muted" do
user = insert(:user) user = insert(:user)
other_user = insert(:user) other_user = insert(:user)
{:ok, user} = User.mute(user, other_user) {:ok, _user_mute} = User.mute(user, other_user)
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"}) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"})
status = StatusView.render("show.json", %{activity: activity, for: user}) status = StatusView.render("show.json", %{activity: activity, for: user})