Merge branch 'feature/expire-mutes' into 'develop'
Expiring mutes for users and activities Closes #1817 See merge request pleroma/pleroma!2971
This commit is contained in:
commit
294628d981
15 changed files with 191 additions and 35 deletions
|
@ -43,6 +43,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Admin API: (`GET /api/pleroma/admin/users`) added filters user by `actor_type`
|
- Admin API: (`GET /api/pleroma/admin/users`) added filters user by `actor_type`
|
||||||
- Pleroma API: Add `idempotency_key` to the chat message entity that can be used for optimistic message sending.
|
- Pleroma API: Add `idempotency_key` to the chat message entity that can be used for optimistic message sending.
|
||||||
- Pleroma API: (`GET /api/v1/pleroma/federation_status`) Add a way to get a list of unreachable instances.
|
- Pleroma API: (`GET /api/v1/pleroma/federation_status`) Add a way to get a list of unreachable instances.
|
||||||
|
- Mastodon API: User and conversation mutes can now auto-expire if `expires_in` parameter was given while adding the mute.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
|
@ -562,7 +562,8 @@ config :pleroma, Oban,
|
||||||
background: 5,
|
background: 5,
|
||||||
remote_fetcher: 2,
|
remote_fetcher: 2,
|
||||||
attachments_cleanup: 5,
|
attachments_cleanup: 5,
|
||||||
new_users_digest: 1
|
new_users_digest: 1,
|
||||||
|
mute_expire: 5
|
||||||
],
|
],
|
||||||
plugins: [Oban.Plugins.Pruner],
|
plugins: [Oban.Plugins.Pruner],
|
||||||
crontab: [
|
crontab: [
|
||||||
|
|
|
@ -255,6 +255,10 @@ There is an additional `user:pleroma_chat` stream. Incoming chat messages will m
|
||||||
|
|
||||||
For viewing remote server timelines, there are `public:remote` and `public:remote:media` streams. Each of these accept a parameter like `?instance=lain.com`.
|
For viewing remote server timelines, there are `public:remote` and `public:remote:media` streams. Each of these accept a parameter like `?instance=lain.com`.
|
||||||
|
|
||||||
|
## User muting and thread muting
|
||||||
|
|
||||||
|
Both user muting and thread muting can be done for only a certain time by adding an `expires_in` parameter to the API calls and giving the expiration time in seconds.
|
||||||
|
|
||||||
## Not implemented
|
## Not implemented
|
||||||
|
|
||||||
Pleroma is generally compatible with the Mastodon 2.7.2 API, but some newer features and non-essential features are omitted. These features usually return an HTTP 200 status code, but with an empty response. While they may be added in the future, they are considered low priority.
|
Pleroma is generally compatible with the Mastodon 2.7.2 API, but some newer features and non-essential features are omitted. These features usually return an HTTP 200 status code, but with an empty response. While they may be added in the future, they are considered low priority.
|
||||||
|
|
|
@ -1324,14 +1324,48 @@ defmodule Pleroma.User do
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec mute(User.t(), User.t(), boolean()) ::
|
@spec mute(User.t(), User.t(), map()) ::
|
||||||
{:ok, list(UserRelationship.t())} | {:error, String.t()}
|
{:ok, list(UserRelationship.t())} | {:error, String.t()}
|
||||||
def mute(%User{} = muter, %User{} = mutee, notifications? \\ true) do
|
def mute(%User{} = muter, %User{} = mutee, params \\ %{}) do
|
||||||
add_to_mutes(muter, mutee, notifications?)
|
notifications? = Map.get(params, :notifications, true)
|
||||||
|
expires_in = Map.get(params, :expires_in, 0)
|
||||||
|
|
||||||
|
with {:ok, user_mute} <- UserRelationship.create_mute(muter, mutee),
|
||||||
|
{:ok, user_notification_mute} <-
|
||||||
|
(notifications? && UserRelationship.create_notification_mute(muter, mutee)) ||
|
||||||
|
{:ok, nil} do
|
||||||
|
if expires_in > 0 do
|
||||||
|
Pleroma.Workers.MuteExpireWorker.enqueue(
|
||||||
|
"unmute_user",
|
||||||
|
%{"muter_id" => muter.id, "mutee_id" => mutee.id},
|
||||||
|
schedule_in: expires_in
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
{:ok, Enum.filter([user_mute, user_notification_mute], & &1)}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def unmute(%User{} = muter, %User{} = mutee) do
|
def unmute(%User{} = muter, %User{} = mutee) do
|
||||||
remove_from_mutes(muter, mutee)
|
with {:ok, user_mute} <- UserRelationship.delete_mute(muter, mutee),
|
||||||
|
{:ok, user_notification_mute} <-
|
||||||
|
UserRelationship.delete_notification_mute(muter, mutee) do
|
||||||
|
{:ok, [user_mute, user_notification_mute]}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def unmute(muter_id, mutee_id) do
|
||||||
|
with {:muter, %User{} = muter} <- {:muter, User.get_by_id(muter_id)},
|
||||||
|
{:mutee, %User{} = mutee} <- {:mutee, User.get_by_id(mutee_id)} do
|
||||||
|
unmute(muter, mutee)
|
||||||
|
else
|
||||||
|
{who, result} = error ->
|
||||||
|
Logger.warn(
|
||||||
|
"User.unmute/2 failed. #{who}: #{result}, muter_id: #{muter_id}, mutee_id: #{mutee_id}"
|
||||||
|
)
|
||||||
|
|
||||||
|
{:error, error}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def subscribe(%User{} = subscriber, %User{} = target) do
|
def subscribe(%User{} = subscriber, %User{} = target) do
|
||||||
|
@ -2320,23 +2354,6 @@ defmodule Pleroma.User do
|
||||||
UserRelationship.delete_block(user, blocked)
|
UserRelationship.delete_block(user, blocked)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp add_to_mutes(%User{} = user, %User{} = muted_user, notifications?) do
|
|
||||||
with {:ok, user_mute} <- UserRelationship.create_mute(user, muted_user),
|
|
||||||
{:ok, user_notification_mute} <-
|
|
||||||
(notifications? && UserRelationship.create_notification_mute(user, muted_user)) ||
|
|
||||||
{:ok, nil} do
|
|
||||||
{:ok, Enum.filter([user_mute, user_notification_mute], & &1)}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp remove_from_mutes(user, %User{} = muted_user) do
|
|
||||||
with {:ok, user_mute} <- UserRelationship.delete_mute(user, muted_user),
|
|
||||||
{:ok, user_notification_mute} <-
|
|
||||||
UserRelationship.delete_notification_mute(user, muted_user) do
|
|
||||||
{:ok, [user_mute, user_notification_mute]}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_invisible(user, invisible) do
|
def set_invisible(user, invisible) do
|
||||||
params = %{invisible: invisible}
|
params = %{invisible: invisible}
|
||||||
|
|
||||||
|
|
|
@ -262,6 +262,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
|
||||||
:query,
|
:query,
|
||||||
%Schema{allOf: [BooleanLike], default: true},
|
%Schema{allOf: [BooleanLike], default: true},
|
||||||
"Mute notifications in addition to statuses? Defaults to `true`."
|
"Mute notifications in addition to statuses? Defaults to `true`."
|
||||||
|
),
|
||||||
|
Operation.parameter(
|
||||||
|
:expires_in,
|
||||||
|
:query,
|
||||||
|
%Schema{type: :integer, default: 0},
|
||||||
|
"Expire the mute in `expires_in` seconds. Default 0 for infinity"
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
responses: %{
|
responses: %{
|
||||||
|
@ -723,10 +729,17 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
|
||||||
nullable: true,
|
nullable: true,
|
||||||
description: "Mute notifications in addition to statuses? Defaults to true.",
|
description: "Mute notifications in addition to statuses? Defaults to true.",
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
expires_in: %Schema{
|
||||||
|
type: :integer,
|
||||||
|
nullable: true,
|
||||||
|
description: "Expire the mute in `expires_in` seconds. Default 0 for infinity",
|
||||||
|
default: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
example: %{
|
example: %{
|
||||||
"notifications" => true
|
"notifications" => true,
|
||||||
|
"expires_in" => 86_400
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -223,7 +223,27 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
|
||||||
security: [%{"oAuth" => ["write:mutes"]}],
|
security: [%{"oAuth" => ["write:mutes"]}],
|
||||||
description: "Do not receive notifications for the thread that this status is part of.",
|
description: "Do not receive notifications for the thread that this status is part of.",
|
||||||
operationId: "StatusController.mute_conversation",
|
operationId: "StatusController.mute_conversation",
|
||||||
parameters: [id_param()],
|
requestBody:
|
||||||
|
request_body("Parameters", %Schema{
|
||||||
|
type: :object,
|
||||||
|
properties: %{
|
||||||
|
expires_in: %Schema{
|
||||||
|
type: :integer,
|
||||||
|
nullable: true,
|
||||||
|
description: "Expire the mute in `expires_in` seconds. Default 0 for infinity",
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
parameters: [
|
||||||
|
id_param(),
|
||||||
|
Operation.parameter(
|
||||||
|
:expires_in,
|
||||||
|
:query,
|
||||||
|
%Schema{type: :integer, default: 0},
|
||||||
|
"Expire the mute in `expires_in` seconds. Default 0 for infinity"
|
||||||
|
)
|
||||||
|
],
|
||||||
responses: %{
|
responses: %{
|
||||||
200 => status_response(),
|
200 => status_response(),
|
||||||
400 => Operation.response("Error", "application/json", ApiError)
|
400 => Operation.response("Error", "application/json", ApiError)
|
||||||
|
|
|
@ -454,20 +454,46 @@ defmodule Pleroma.Web.CommonAPI do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_mute(user, activity) do
|
def add_mute(user, activity, params \\ %{}) do
|
||||||
|
expires_in = Map.get(params, :expires_in, 0)
|
||||||
|
|
||||||
with {:ok, _} <- ThreadMute.add_mute(user.id, activity.data["context"]),
|
with {:ok, _} <- ThreadMute.add_mute(user.id, activity.data["context"]),
|
||||||
_ <- Pleroma.Notification.mark_context_as_read(user, activity.data["context"]) do
|
_ <- Pleroma.Notification.mark_context_as_read(user, activity.data["context"]) do
|
||||||
|
if expires_in > 0 do
|
||||||
|
Pleroma.Workers.MuteExpireWorker.enqueue(
|
||||||
|
"unmute_conversation",
|
||||||
|
%{"user_id" => user.id, "activity_id" => activity.id},
|
||||||
|
schedule_in: expires_in
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
else
|
else
|
||||||
{:error, _} -> {:error, dgettext("errors", "conversation is already muted")}
|
{:error, _} -> {:error, dgettext("errors", "conversation is already muted")}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_mute(user, activity) do
|
def remove_mute(%User{} = user, %Activity{} = activity) do
|
||||||
ThreadMute.remove_mute(user.id, activity.data["context"])
|
ThreadMute.remove_mute(user.id, activity.data["context"])
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def remove_mute(user_id, activity_id) do
|
||||||
|
with {:user, %User{} = user} <- {:user, User.get_by_id(user_id)},
|
||||||
|
{:activity, %Activity{} = activity} <- {:activity, Activity.get_by_id(activity_id)} do
|
||||||
|
remove_mute(user, activity)
|
||||||
|
else
|
||||||
|
{what, result} = error ->
|
||||||
|
Logger.warn(
|
||||||
|
"CommonAPI.remove_mute/2 failed. #{what}: #{result}, user_id: #{user_id}, activity_id: #{
|
||||||
|
activity_id
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
|
||||||
|
{:error, error}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def thread_muted?(%User{id: user_id}, %{data: %{"context" => context}})
|
def thread_muted?(%User{id: user_id}, %{data: %{"context" => context}})
|
||||||
when is_binary(context) do
|
when is_binary(context) do
|
||||||
ThreadMute.exists?(user_id, context)
|
ThreadMute.exists?(user_id, context)
|
||||||
|
|
|
@ -394,7 +394,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|
||||||
|
|
||||||
@doc "POST /api/v1/accounts/:id/mute"
|
@doc "POST /api/v1/accounts/:id/mute"
|
||||||
def mute(%{assigns: %{user: muter, account: muted}, body_params: params} = conn, _params) do
|
def mute(%{assigns: %{user: muter, account: muted}, body_params: params} = conn, _params) do
|
||||||
with {:ok, _user_relationships} <- User.mute(muter, muted, params.notifications) do
|
with {:ok, _user_relationships} <- User.mute(muter, muted, params) do
|
||||||
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})
|
||||||
|
|
|
@ -284,9 +284,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "POST /api/v1/statuses/:id/mute"
|
@doc "POST /api/v1/statuses/:id/mute"
|
||||||
def mute_conversation(%{assigns: %{user: user}} = conn, %{id: id}) do
|
def mute_conversation(%{assigns: %{user: user}, body_params: params} = conn, %{id: id}) do
|
||||||
with %Activity{} = activity <- Activity.get_by_id(id),
|
with %Activity{} = activity <- Activity.get_by_id(id),
|
||||||
{:ok, activity} <- CommonAPI.add_mute(user, activity) do
|
{:ok, activity} <- CommonAPI.add_mute(user, activity, params) do
|
||||||
try_render(conn, "show.json", activity: activity, for: user, as: :activity)
|
try_render(conn, "show.json", activity: activity, for: user, as: :activity)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
20
lib/pleroma/workers/mute_expire_worker.ex
Normal file
20
lib/pleroma/workers/mute_expire_worker.ex
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Workers.MuteExpireWorker do
|
||||||
|
use Pleroma.Workers.WorkerHelper, queue: "mute_expire"
|
||||||
|
|
||||||
|
@impl Oban.Worker
|
||||||
|
def perform(%Job{args: %{"op" => "unmute_user", "muter_id" => muter_id, "mutee_id" => mutee_id}}) do
|
||||||
|
Pleroma.User.unmute(muter_id, mutee_id)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform(%Job{
|
||||||
|
args: %{"op" => "unmute_conversation", "user_id" => user_id, "activity_id" => activity_id}
|
||||||
|
}) do
|
||||||
|
Pleroma.Web.CommonAPI.remove_mute(user_id, activity_id)
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
end
|
|
@ -229,7 +229,7 @@ defmodule Pleroma.NotificationTest do
|
||||||
muter = insert(:user)
|
muter = insert(:user)
|
||||||
muted = insert(:user)
|
muted = insert(:user)
|
||||||
|
|
||||||
{:ok, _user_relationships} = User.mute(muter, muted, false)
|
{:ok, _user_relationships} = User.mute(muter, muted, %{notifications: false})
|
||||||
|
|
||||||
{:ok, activity} = CommonAPI.post(muted, %{status: "Hi @#{muter.nickname}"})
|
{:ok, activity} = CommonAPI.post(muted, %{status: "Hi @#{muter.nickname}"})
|
||||||
|
|
||||||
|
@ -1015,7 +1015,7 @@ defmodule Pleroma.NotificationTest do
|
||||||
|
|
||||||
test "it returns notifications for muted user without notifications", %{user: user} do
|
test "it returns notifications for muted user without notifications", %{user: user} do
|
||||||
muted = insert(:user)
|
muted = insert(:user)
|
||||||
{:ok, _user_relationships} = User.mute(user, muted, false)
|
{:ok, _user_relationships} = User.mute(user, muted, %{notifications: false})
|
||||||
|
|
||||||
{:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
|
{:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
|
||||||
|
|
||||||
|
|
|
@ -1008,6 +1008,27 @@ defmodule Pleroma.UserTest do
|
||||||
assert User.muted_notifications?(user, muted_user)
|
assert User.muted_notifications?(user, muted_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "expiring" do
|
||||||
|
user = insert(:user)
|
||||||
|
muted_user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, _user_relationships} = User.mute(user, muted_user, %{expires_in: 60})
|
||||||
|
assert User.mutes?(user, muted_user)
|
||||||
|
|
||||||
|
worker = Pleroma.Workers.MuteExpireWorker
|
||||||
|
args = %{"op" => "unmute_user", "muter_id" => user.id, "mutee_id" => muted_user.id}
|
||||||
|
|
||||||
|
assert_enqueued(
|
||||||
|
worker: worker,
|
||||||
|
args: args
|
||||||
|
)
|
||||||
|
|
||||||
|
assert :ok = perform_job(worker, args)
|
||||||
|
|
||||||
|
refute User.mutes?(user, muted_user)
|
||||||
|
refute User.muted_notifications?(user, muted_user)
|
||||||
|
end
|
||||||
|
|
||||||
test "it unmutes users" do
|
test "it unmutes users" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
muted_user = insert(:user)
|
muted_user = insert(:user)
|
||||||
|
@ -1019,6 +1040,17 @@ defmodule Pleroma.UserTest do
|
||||||
refute User.muted_notifications?(user, muted_user)
|
refute User.muted_notifications?(user, muted_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "it unmutes users by id" do
|
||||||
|
user = insert(:user)
|
||||||
|
muted_user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, _user_relationships} = User.mute(user, muted_user)
|
||||||
|
{:ok, _user_mute} = User.unmute(user.id, muted_user.id)
|
||||||
|
|
||||||
|
refute User.mutes?(user, muted_user)
|
||||||
|
refute User.muted_notifications?(user, muted_user)
|
||||||
|
end
|
||||||
|
|
||||||
test "it mutes user without notifications" do
|
test "it mutes user without notifications" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
muted_user = insert(:user)
|
muted_user = insert(:user)
|
||||||
|
@ -1026,7 +1058,7 @@ defmodule Pleroma.UserTest 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_relationships} = User.mute(user, muted_user, false)
|
{:ok, _user_relationships} = User.mute(user, muted_user, %{notifications: 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)
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.CommonAPITest do
|
defmodule Pleroma.Web.CommonAPITest do
|
||||||
use Pleroma.DataCase
|
|
||||||
use Oban.Testing, repo: Pleroma.Repo
|
use Oban.Testing, repo: Pleroma.Repo
|
||||||
|
use Pleroma.DataCase
|
||||||
|
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Chat
|
alias Pleroma.Chat
|
||||||
|
@ -922,12 +922,34 @@ defmodule Pleroma.Web.CommonAPITest do
|
||||||
assert CommonAPI.thread_muted?(user, activity)
|
assert CommonAPI.thread_muted?(user, activity)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "add expiring mute", %{user: user, activity: activity} do
|
||||||
|
{:ok, _} = CommonAPI.add_mute(user, activity, %{expires_in: 60})
|
||||||
|
assert CommonAPI.thread_muted?(user, activity)
|
||||||
|
|
||||||
|
worker = Pleroma.Workers.MuteExpireWorker
|
||||||
|
args = %{"op" => "unmute_conversation", "user_id" => user.id, "activity_id" => activity.id}
|
||||||
|
|
||||||
|
assert_enqueued(
|
||||||
|
worker: worker,
|
||||||
|
args: args
|
||||||
|
)
|
||||||
|
|
||||||
|
assert :ok = perform_job(worker, args)
|
||||||
|
refute CommonAPI.thread_muted?(user, activity)
|
||||||
|
end
|
||||||
|
|
||||||
test "remove mute", %{user: user, activity: activity} do
|
test "remove mute", %{user: user, activity: activity} do
|
||||||
CommonAPI.add_mute(user, activity)
|
CommonAPI.add_mute(user, activity)
|
||||||
{:ok, _} = CommonAPI.remove_mute(user, activity)
|
{:ok, _} = CommonAPI.remove_mute(user, activity)
|
||||||
refute CommonAPI.thread_muted?(user, activity)
|
refute CommonAPI.thread_muted?(user, activity)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "remove mute by ids", %{user: user, activity: activity} do
|
||||||
|
CommonAPI.add_mute(user, activity)
|
||||||
|
{:ok, _} = CommonAPI.remove_mute(user.id, activity.id)
|
||||||
|
refute CommonAPI.thread_muted?(user, activity)
|
||||||
|
end
|
||||||
|
|
||||||
test "check that mutes can't be duplicate", %{user: user, activity: activity} do
|
test "check that mutes can't be duplicate", %{user: user, activity: activity} do
|
||||||
CommonAPI.add_mute(user, activity)
|
CommonAPI.add_mute(user, activity)
|
||||||
{:error, _} = CommonAPI.add_mute(user, activity)
|
{:error, _} = CommonAPI.add_mute(user, activity)
|
||||||
|
|
|
@ -502,7 +502,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
||||||
|
|
||||||
assert length(json_response_and_validate_schema(ret_conn, 200)) == 1
|
assert length(json_response_and_validate_schema(ret_conn, 200)) == 1
|
||||||
|
|
||||||
{:ok, _user_relationships} = User.mute(user, user2, false)
|
{:ok, _user_relationships} = User.mute(user, user2, %{notifications: false})
|
||||||
|
|
||||||
conn = get(conn, "/api/v1/notifications")
|
conn = get(conn, "/api/v1/notifications")
|
||||||
|
|
||||||
|
|
|
@ -277,7 +277,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest 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, _subscription} = User.subscribe(user, other_user)
|
{:ok, _subscription} = User.subscribe(user, other_user)
|
||||||
{:ok, _user_relationships} = User.mute(user, other_user, true)
|
{:ok, _user_relationships} = User.mute(user, other_user, %{notifications: true})
|
||||||
{:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, other_user)
|
{:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, other_user)
|
||||||
|
|
||||||
expected =
|
expected =
|
||||||
|
|
Loading…
Reference in a new issue