Feature/1072 muting notifications Closes #1072 See merge request pleroma/pleroma!1398tags/v1.1.4
@@ -27,13 +27,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). | |||
- Mastodon API: Support for the [`tagged` filter](https://github.com/tootsuite/mastodon/pull/9755) in [`GET /api/v1/accounts/:id/statuses`](https://docs.joinmastodon.org/api/rest/accounts/#get-api-v1-accounts-id-statuses) | |||
- Mastodon API, streaming: Add support for passing the token in the `Sec-WebSocket-Protocol` header | |||
- Mastodon API, extension: Ability to reset avatar, profile banner, and background | |||
- Mastodon API: Add support for categories for custom emojis by reusing the group feature. <https://github.com/tootsuite/mastodon/pull/11196> | |||
- Mastodon API: Add support for muting/unmuting notifications | |||
- Admin API: Return users' tags when querying reports | |||
- Admin API: Return avatar and display name when querying users | |||
- Admin API: Allow querying user by ID | |||
- Admin API: Added support for `tuples`. | |||
- Added synchronization of following/followers counters for external users | |||
- Configuration: `enabled` option for `Pleroma.Emails.Mailer`, defaulting to `false`. | |||
- Mastodon API: Add support for categories for custom emojis by reusing the group feature. <https://github.com/tootsuite/mastodon/pull/11196> | |||
- Configuration: Pleroma.Plugs.RateLimiter `bucket_name`, `params` options. | |||
### Changed | |||
@@ -11,7 +11,6 @@ defmodule Pleroma.Notification do | |||
alias Pleroma.Pagination | |||
alias Pleroma.Repo | |||
alias Pleroma.User | |||
alias Pleroma.Web.CommonAPI | |||
alias Pleroma.Web.CommonAPI.Utils | |||
alias Pleroma.Web.Push | |||
alias Pleroma.Web.Streamer | |||
@@ -32,31 +31,47 @@ defmodule Pleroma.Notification do | |||
|> cast(attrs, [:seen]) | |||
end | |||
def for_user_query(user) do | |||
Notification | |||
|> where(user_id: ^user.id) | |||
|> where( | |||
[n, a], | |||
fragment( | |||
"? not in (SELECT ap_id FROM users WHERE info->'deactivated' @> 'true')", | |||
a.actor | |||
) | |||
) | |||
|> join(:inner, [n], activity in assoc(n, :activity)) | |||
|> join(:left, [n, a], object in Object, | |||
on: | |||
def for_user_query(user, opts) do | |||
query = | |||
Notification | |||
|> where(user_id: ^user.id) | |||
|> where( | |||
[n, a], | |||
fragment( | |||
"(?->>'id') = COALESCE((? -> 'object'::text) ->> 'id'::text)", | |||
object.data, | |||
a.data | |||
"? not in (SELECT ap_id FROM users WHERE info->'deactivated' @> 'true')", | |||
a.actor | |||
) | |||
) | |||
|> preload([n, a, o], activity: {a, object: o}) | |||
) | |||
|> join(:inner, [n], activity in assoc(n, :activity)) | |||
|> join(:left, [n, a], object in Object, | |||
on: | |||
fragment( | |||
"(?->>'id') = COALESCE((? -> 'object'::text) ->> 'id'::text)", | |||
object.data, | |||
a.data | |||
) | |||
) | |||
|> preload([n, a, o], activity: {a, object: o}) | |||
if opts[:with_muted] do | |||
query | |||
else | |||
where(query, [n, a], a.actor not in ^user.info.muted_notifications) | |||
|> where([n, a], a.actor not in ^user.info.blocks) | |||
|> where( | |||
[n, a], | |||
fragment("substring(? from '.*://([^/]*)')", a.actor) not in ^user.info.domain_blocks | |||
) | |||
|> join(:left, [n, a], tm in Pleroma.ThreadMute, | |||
on: tm.user_id == ^user.id and tm.context == fragment("?->>'context'", a.data) | |||
) | |||
|> where([n, a, o, tm], is_nil(tm.id)) | |||
end | |||
end | |||
def for_user(user, opts \\ %{}) do | |||
user | |||
|> for_user_query() | |||
|> for_user_query(opts) | |||
|> Pagination.fetch_paginated(opts) | |||
end | |||
@@ -179,11 +194,10 @@ defmodule Pleroma.Notification do | |||
def get_notified_from_activity(_, _local_only), do: [] | |||
@spec skip?(Activity.t(), User.t()) :: boolean() | |||
def skip?(activity, user) do | |||
[ | |||
:self, | |||
:blocked, | |||
:muted, | |||
:followers, | |||
:follows, | |||
:non_followers, | |||
@@ -193,21 +207,11 @@ defmodule Pleroma.Notification do | |||
|> Enum.any?(&skip?(&1, activity, user)) | |||
end | |||
@spec skip?(atom(), Activity.t(), User.t()) :: boolean() | |||
def skip?(:self, activity, user) do | |||
activity.data["actor"] == user.ap_id | |||
end | |||
def skip?(:blocked, activity, user) do | |||
actor = activity.data["actor"] | |||
User.blocks?(user, %{ap_id: actor}) | |||
end | |||
def skip?(:muted, activity, user) do | |||
actor = activity.data["actor"] | |||
User.mutes?(user, %{ap_id: actor}) or CommonAPI.thread_muted?(user, activity) | |||
end | |||
def skip?( | |||
:followers, | |||
activity, | |||
@@ -749,10 +749,13 @@ defmodule Pleroma.User do | |||
|> Repo.all() | |||
end | |||
def mute(muter, %User{ap_id: ap_id}) do | |||
@spec mute(User.t(), User.t(), boolean()) :: {:ok, User.t()} | {:error, String.t()} | |||
def mute(muter, %User{ap_id: ap_id}, notifications? \\ true) do | |||
info = muter.info | |||
info_cng = | |||
muter.info | |||
|> User.Info.add_to_mutes(ap_id) | |||
User.Info.add_to_mutes(info, ap_id) | |||
|> User.Info.add_to_muted_notifications(info, ap_id, notifications?) | |||
cng = | |||
change(muter) | |||
@@ -762,9 +765,11 @@ defmodule Pleroma.User do | |||
end | |||
def unmute(muter, %{ap_id: ap_id}) do | |||
info = muter.info | |||
info_cng = | |||
muter.info | |||
|> User.Info.remove_from_mutes(ap_id) | |||
User.Info.remove_from_mutes(info, ap_id) | |||
|> User.Info.remove_from_muted_notifications(info, ap_id) | |||
cng = | |||
change(muter) | |||
@@ -860,6 +865,12 @@ defmodule Pleroma.User do | |||
def mutes?(nil, _), do: false | |||
def mutes?(user, %{ap_id: ap_id}), do: Enum.member?(user.info.mutes, ap_id) | |||
@spec muted_notifications?(User.t() | nil, User.t() | map()) :: boolean() | |||
def muted_notifications?(nil, _), do: false | |||
def muted_notifications?(user, %{ap_id: ap_id}), | |||
do: Enum.member?(user.info.muted_notifications, ap_id) | |||
def blocks?(%User{info: info} = _user, %{ap_id: ap_id}) do | |||
blocks = info.blocks | |||
domain_blocks = info.domain_blocks | |||
@@ -24,6 +24,7 @@ defmodule Pleroma.User.Info do | |||
field(:domain_blocks, {:array, :string}, default: []) | |||
field(:mutes, {:array, :string}, default: []) | |||
field(:muted_reblogs, {:array, :string}, default: []) | |||
field(:muted_notifications, {:array, :string}, default: []) | |||
field(:subscribers, {:array, :string}, default: []) | |||
field(:deactivated, :boolean, default: false) | |||
field(:no_rich_text, :boolean, default: false) | |||
@@ -120,6 +121,16 @@ defmodule Pleroma.User.Info do | |||
|> validate_required([:mutes]) | |||
end | |||
@spec set_notification_mutes(Changeset.t(), [String.t()], boolean()) :: Changeset.t() | |||
def set_notification_mutes(changeset, muted_notifications, notifications?) do | |||
if notifications? do | |||
put_change(changeset, :muted_notifications, muted_notifications) | |||
|> validate_required([:muted_notifications]) | |||
else | |||
changeset | |||
end | |||
end | |||
def set_blocks(info, blocks) do | |||
params = %{blocks: blocks} | |||
@@ -136,14 +147,31 @@ defmodule Pleroma.User.Info do | |||
|> validate_required([:subscribers]) | |||
end | |||
@spec add_to_mutes(Info.t(), String.t()) :: Changeset.t() | |||
def add_to_mutes(info, muted) do | |||
set_mutes(info, Enum.uniq([muted | info.mutes])) | |||
end | |||
@spec add_to_muted_notifications(Changeset.t(), Info.t(), String.t(), boolean()) :: | |||
Changeset.t() | |||
def add_to_muted_notifications(changeset, info, muted, notifications?) do | |||
set_notification_mutes( | |||
changeset, | |||
Enum.uniq([muted | info.muted_notifications]), | |||
notifications? | |||
) | |||
end | |||
@spec remove_from_mutes(Info.t(), String.t()) :: Changeset.t() | |||
def remove_from_mutes(info, muted) do | |||
set_mutes(info, List.delete(info.mutes, muted)) | |||
end | |||
@spec remove_from_muted_notifications(Changeset.t(), Info.t(), String.t()) :: Changeset.t() | |||
def remove_from_muted_notifications(changeset, info, muted) do | |||
set_notification_mutes(changeset, List.delete(info.muted_notifications, muted), true) | |||
end | |||
def add_to_block(info, blocked) do | |||
set_blocks(info, Enum.uniq([blocked | info.blocks])) | |||
end | |||
@@ -53,7 +53,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do | |||
options = cast_params(params) | |||
user | |||
|> Notification.for_user_query() | |||
|> Notification.for_user_query(options) | |||
|> restrict(:exclude_types, options) | |||
|> Pagination.fetch_paginated(params) | |||
end | |||
@@ -67,7 +67,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do | |||
defp cast_params(params) do | |||
param_types = %{ | |||
exclude_types: {:array, :string}, | |||
reblogs: :boolean | |||
reblogs: :boolean, | |||
with_muted: :boolean | |||
} | |||
changeset = cast({%{}, param_types}, params, Map.keys(param_types)) | |||
@@ -1068,9 +1068,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
end | |||
end | |||
def mute(%{assigns: %{user: muter}} = conn, %{"id" => id}) do | |||
def mute(%{assigns: %{user: muter}} = conn, %{"id" => id} = params) do | |||
notifications = | |||
if Map.has_key?(params, "notifications"), | |||
do: params["notifications"] in [true, "True", "true", "1"], | |||
else: true | |||
with %User{} = muted <- User.get_cached_by_id(id), | |||
{:ok, muter} <- User.mute(muter, muted) do | |||
{:ok, muter} <- User.mute(muter, muted, notifications) do | |||
conn | |||
|> put_view(AccountView) | |||
|> render("relationship.json", %{user: muter, target: muted}) | |||
@@ -52,7 +52,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do | |||
followed_by: User.following?(target, user), | |||
blocking: User.blocks?(user, target), | |||
muting: User.mutes?(user, target), | |||
muting_notifications: false, | |||
muting_notifications: User.muted_notifications?(user, target), | |||
subscribing: User.subscribed_to?(user, target), | |||
requested: requested, | |||
domain_blocking: false, | |||
@@ -192,6 +192,13 @@ defmodule Pleroma.Web.TwitterAPI.Controller do | |||
end | |||
def notifications(%{assigns: %{user: user}} = conn, params) do | |||
params = | |||
if Map.has_key?(params, "with_muted") do | |||
Map.put(params, :with_muted, params["with_muted"] in [true, "True", "true", "1"]) | |||
else | |||
params | |||
end | |||
notifications = Notification.for_user(user, params) | |||
conn | |||
@@ -0,0 +1,24 @@ | |||
defmodule Pleroma.Repo.Migrations.CopyMutedToMutedNotifications do | |||
use Ecto.Migration | |||
alias Pleroma.User | |||
def change do | |||
query = | |||
User.Query.build(%{ | |||
local: true, | |||
active: true, | |||
order_by: :id | |||
}) | |||
Pleroma.Repo.stream(query) | |||
|> Enum.each(fn | |||
%{info: %{mutes: mutes} = info} = user -> | |||
info_cng = | |||
Ecto.Changeset.cast(info, %{muted_notifications: mutes}, [:muted_notifications]) | |||
Ecto.Changeset.change(user) | |||
|> Ecto.Changeset.put_embed(:info, info_cng) | |||
|> Pleroma.Repo.update() | |||
end) | |||
end | |||
end |
@@ -74,26 +74,37 @@ defmodule Pleroma.NotificationTest do | |||
Task.await(task_user_notification) | |||
end | |||
test "it doesn't create a notification for user if the user blocks the activity author" do | |||
test "it creates a notification for user if the user blocks the activity author" do | |||
activity = insert(:note_activity) | |||
author = User.get_cached_by_ap_id(activity.data["actor"]) | |||
user = insert(:user) | |||
{:ok, user} = User.block(user, author) | |||
refute Notification.create_notification(activity, user) | |||
assert Notification.create_notification(activity, user) | |||
end | |||
test "it doesn't create a notificatin for the user if the user mutes the activity author" do | |||
test "it creates a notificatin for the user if the user mutes the activity author" do | |||
muter = insert(:user) | |||
muted = insert(:user) | |||
{:ok, _} = User.mute(muter, muted) | |||
muter = Repo.get(User, muter.id) | |||
{:ok, activity} = CommonAPI.post(muted, %{"status" => "Hi @#{muter.nickname}"}) | |||
refute Notification.create_notification(activity, muter) | |||
assert Notification.create_notification(activity, muter) | |||
end | |||
test "it doesn't create a notification for an activity from a muted thread" do | |||
test "notification created if user is muted without notifications" do | |||
muter = insert(:user) | |||
muted = insert(:user) | |||
{:ok, muter} = User.mute(muter, muted, false) | |||
{:ok, activity} = CommonAPI.post(muted, %{"status" => "Hi @#{muter.nickname}"}) | |||
assert Notification.create_notification(activity, muter) | |||
end | |||
test "it creates a notification for an activity from a muted thread" do | |||
muter = insert(:user) | |||
other_user = insert(:user) | |||
{:ok, activity} = CommonAPI.post(muter, %{"status" => "hey"}) | |||
@@ -105,7 +116,7 @@ defmodule Pleroma.NotificationTest do | |||
"in_reply_to_status_id" => activity.id | |||
}) | |||
refute Notification.create_notification(activity, muter) | |||
assert Notification.create_notification(activity, muter) | |||
end | |||
test "it disables notifications from followers" do | |||
@@ -532,4 +543,98 @@ defmodule Pleroma.NotificationTest do | |||
assert Enum.empty?(Notification.for_user(user)) | |||
end | |||
end | |||
describe "for_user" do | |||
test "it returns notifications for muted user without notifications" do | |||
user = insert(:user) | |||
muted = insert(:user) | |||
{:ok, user} = User.mute(user, muted, false) | |||
{:ok, _activity} = TwitterAPI.create_status(muted, %{"status" => "hey @#{user.nickname}"}) | |||
assert length(Notification.for_user(user)) == 1 | |||
end | |||
test "it doesn't return notifications for muted user with notifications" do | |||
user = insert(:user) | |||
muted = insert(:user) | |||
{:ok, user} = User.mute(user, muted) | |||
{:ok, _activity} = TwitterAPI.create_status(muted, %{"status" => "hey @#{user.nickname}"}) | |||
assert Notification.for_user(user) == [] | |||
end | |||
test "it doesn't return notifications for blocked user" do | |||
user = insert(:user) | |||
blocked = insert(:user) | |||
{:ok, user} = User.block(user, blocked) | |||
{:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"}) | |||
assert Notification.for_user(user) == [] | |||
end | |||
test "it doesn't return notificatitons for blocked domain" do | |||
user = insert(:user) | |||
blocked = insert(:user, ap_id: "http://some-domain.com") | |||
{:ok, user} = User.block_domain(user, "some-domain.com") | |||
{:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"}) | |||
assert Notification.for_user(user) == [] | |||
end | |||
test "it doesn't return notifications for muted thread" do | |||
user = insert(:user) | |||
another_user = insert(:user) | |||
{:ok, activity} = | |||
TwitterAPI.create_status(another_user, %{"status" => "hey @#{user.nickname}"}) | |||
{:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"]) | |||
assert Notification.for_user(user) == [] | |||
end | |||
test "it returns notifications for muted user with notifications and with_muted parameter" do | |||
user = insert(:user) | |||
muted = insert(:user) | |||
{:ok, user} = User.mute(user, muted) | |||
{:ok, _activity} = TwitterAPI.create_status(muted, %{"status" => "hey @#{user.nickname}"}) | |||
assert length(Notification.for_user(user, %{with_muted: true})) == 1 | |||
end | |||
test "it returns notifications for blocked user and with_muted parameter" do | |||
user = insert(:user) | |||
blocked = insert(:user) | |||
{:ok, user} = User.block(user, blocked) | |||
{:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"}) | |||
assert length(Notification.for_user(user, %{with_muted: true})) == 1 | |||
end | |||
test "it returns notificatitons for blocked domain and with_muted parameter" do | |||
user = insert(:user) | |||
blocked = insert(:user, ap_id: "http://some-domain.com") | |||
{:ok, user} = User.block_domain(user, "some-domain.com") | |||
{:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"}) | |||
assert length(Notification.for_user(user, %{with_muted: true})) == 1 | |||
end | |||
test "it returns notifications for muted thread with_muted parameter" do | |||
user = insert(:user) | |||
another_user = insert(:user) | |||
{:ok, activity} = | |||
TwitterAPI.create_status(another_user, %{"status" => "hey @#{user.nickname}"}) | |||
{:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"]) | |||
assert length(Notification.for_user(user, %{with_muted: true})) == 1 | |||
end | |||
end | |||
end |
@@ -687,10 +687,12 @@ defmodule Pleroma.UserTest do | |||
muted_user = insert(:user) | |||
refute User.mutes?(user, muted_user) | |||
refute User.muted_notifications?(user, muted_user) | |||
{:ok, user} = User.mute(user, muted_user) | |||
assert User.mutes?(user, muted_user) | |||
assert User.muted_notifications?(user, muted_user) | |||
end | |||
test "it unmutes users" do | |||
@@ -701,6 +703,20 @@ defmodule Pleroma.UserTest do | |||
{:ok, user} = User.unmute(user, muted_user) | |||
refute User.mutes?(user, muted_user) | |||
refute User.muted_notifications?(user, muted_user) | |||
end | |||
test "it mutes user without notifications" do | |||
user = insert(:user) | |||
muted_user = insert(:user) | |||
refute User.mutes?(user, muted_user) | |||
refute User.muted_notifications?(user, muted_user) | |||
{:ok, user} = User.mute(user, muted_user, false) | |||
assert User.mutes?(user, muted_user) | |||
refute User.muted_notifications?(user, muted_user) | |||
end | |||
end | |||
@@ -1274,6 +1274,71 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
result = json_response(conn_res, 200) | |||
assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result | |||
end | |||
test "doesn't see notifications after muting user with notifications", %{conn: conn} do | |||
user = insert(:user) | |||
user2 = insert(:user) | |||
{:ok, _, _, _} = CommonAPI.follow(user, user2) | |||
{:ok, _} = CommonAPI.post(user2, %{"status" => "hey @#{user.nickname}"}) | |||
conn = assign(conn, :user, user) | |||
conn = get(conn, "/api/v1/notifications") | |||
assert length(json_response(conn, 200)) == 1 | |||
{:ok, user} = User.mute(user, user2) | |||
conn = assign(build_conn(), :user, user) | |||
conn = get(conn, "/api/v1/notifications") | |||
assert json_response(conn, 200) == [] | |||
end | |||
test "see notifications after muting user without notifications", %{conn: conn} do | |||
user = insert(:user) | |||
user2 = insert(:user) | |||
{:ok, _, _, _} = CommonAPI.follow(user, user2) | |||
{:ok, _} = CommonAPI.post(user2, %{"status" => "hey @#{user.nickname}"}) | |||
conn = assign(conn, :user, user) | |||
conn = get(conn, "/api/v1/notifications") | |||
assert length(json_response(conn, 200)) == 1 | |||
{:ok, user} = User.mute(user, user2, false) | |||
conn = assign(build_conn(), :user, user) | |||
conn = get(conn, "/api/v1/notifications") | |||
assert length(json_response(conn, 200)) == 1 | |||
end | |||
test "see notifications after muting user with notifications and with_muted parameter", %{ | |||
conn: conn | |||
} do | |||
user = insert(:user) | |||
user2 = insert(:user) | |||
{:ok, _, _, _} = CommonAPI.follow(user, user2) | |||
{:ok, _} = CommonAPI.post(user2, %{"status" => "hey @#{user.nickname}"}) | |||
conn = assign(conn, :user, user) | |||
conn = get(conn, "/api/v1/notifications") | |||
assert length(json_response(conn, 200)) == 1 | |||
{:ok, user} = User.mute(user, user2) | |||
conn = assign(build_conn(), :user, user) | |||
conn = get(conn, "/api/v1/notifications", %{"with_muted" => "true"}) | |||
assert length(json_response(conn, 200)) == 1 | |||
end | |||
end | |||
describe "reblogging" do | |||
@@ -2105,25 +2170,52 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
assert %{"error" => "Record not found"} = json_response(conn_res, 404) | |||
end | |||
test "muting / unmuting a user", %{conn: conn} do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
describe "mute/unmute" do | |||
test "with notifications", %{conn: conn} do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/accounts/#{other_user.id}/mute") | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/accounts/#{other_user.id}/mute") | |||
assert %{"id" => _id, "muting" => true} = json_response(conn, 200) | |||
response = json_response(conn, 200) | |||
user = User.get_cached_by_id(user.id) | |||
assert %{"id" => _id, "muting" => true, "muting_notifications" => true} = response | |||
user = User.get_cached_by_id(user.id) | |||
conn = | |||
build_conn() | |||
|> assign(:user, user) | |||
|> post("/api/v1/accounts/#{other_user.id}/unmute") | |||
conn = | |||
build_conn() | |||
|> assign(:user, user) | |||
|> post("/api/v1/accounts/#{other_user.id}/unmute") | |||
assert %{"id" => _id, "muting" => false} = json_response(conn, 200) | |||
response = json_response(conn, 200) | |||
assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response | |||
end | |||
test "without notifications", %{conn: conn} do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/accounts/#{other_user.id}/mute", %{"notifications" => "false"}) | |||
response = json_response(conn, 200) | |||
assert %{"id" => _id, "muting" => true, "muting_notifications" => false} = response | |||
user = User.get_cached_by_id(user.id) | |||
conn = | |||
build_conn() | |||
|> assign(:user, user) | |||
|> post("/api/v1/accounts/#{other_user.id}/unmute") | |||
response = json_response(conn, 200) | |||
assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response | |||
end | |||
end | |||
test "subscribing / unsubscribing to a user", %{conn: conn} do | |||
@@ -521,6 +521,38 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do | |||
for: current_user | |||
}) | |||
end | |||
test "muted user", %{conn: conn, user: current_user} do | |||
other_user = insert(:user) | |||
{:ok, current_user} = User.mute(current_user, other_user) | |||
{:ok, _activity} = | |||
ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user}) | |||
conn = | |||
conn | |||
|> with_credentials(current_user.nickname, "test") | |||
|> get("/api/qvitter/statuses/notifications.json") | |||
assert json_response(conn, 200) == [] | |||
end | |||
test "muted user with with_muted parameter", %{conn: conn, user: current_user} do | |||
other_user = insert(:user) | |||
{:ok, current_user} = User.mute(current_user, other_user) | |||
{:ok, _activity} = | |||
ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user}) | |||
conn = | |||
conn | |||
|> with_credentials(current_user.nickname, "test") | |||
|> get("/api/qvitter/statuses/notifications.json", %{"with_muted" => "true"}) | |||
assert length(json_response(conn, 200)) == 1 | |||
end | |||
end | |||
describe "POST /api/qvitter/statuses/notifications/read" do | |||