Merge branch 'hide-muted-reactions' into 'develop'
Hide reactions from muted and blocked users Closes #1875 See merge request pleroma/pleroma!3147
This commit is contained in:
commit
6f9b03384f
17 changed files with 462 additions and 31 deletions
|
@ -51,6 +51,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
- Config generation: rename `Pleroma.Upload.Filter.ExifTool` to `Pleroma.Upload.Filter.Exiftool`.
|
||||
- S3 Uploads with Elixir 1.11.
|
||||
- Fixed Emoji Reaction activity filtering from blocked and muted accounts
|
||||
- Mix task pleroma.user delete_activities for source installations.
|
||||
|
||||
## [2.2.0] - 2020-11-12
|
||||
|
|
|
@ -245,6 +245,18 @@ def unquote(:"#{outgoing_relation_target}_ap_ids")(user, restrict_deactivated? \
|
|||
end
|
||||
end
|
||||
|
||||
def cached_blocked_users_ap_ids(user) do
|
||||
Cachex.fetch!(:user_cache, "blocked_users_ap_ids:#{user.ap_id}", fn _ ->
|
||||
blocked_users_ap_ids(user)
|
||||
end)
|
||||
end
|
||||
|
||||
def cached_muted_users_ap_ids(user) do
|
||||
Cachex.fetch!(:user_cache, "muted_users_ap_ids:#{user.ap_id}", fn _ ->
|
||||
muted_users_ap_ids(user)
|
||||
end)
|
||||
end
|
||||
|
||||
defdelegate following_count(user), to: FollowingRelationship
|
||||
defdelegate following(user), to: FollowingRelationship
|
||||
defdelegate following?(follower, followed), to: FollowingRelationship
|
||||
|
@ -1036,6 +1048,8 @@ def invalidate_cache(user) do
|
|||
Cachex.del(:user_cache, "ap_id:#{user.ap_id}")
|
||||
Cachex.del(:user_cache, "nickname:#{user.nickname}")
|
||||
Cachex.del(:user_cache, "friends_ap_ids:#{user.ap_id}")
|
||||
Cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
|
||||
Cachex.del(:user_cache, "muted_users_ap_ids:#{user.ap_id}")
|
||||
end
|
||||
|
||||
@spec get_cached_by_ap_id(String.t()) :: User.t() | nil
|
||||
|
@ -1342,6 +1356,8 @@ def mute(%User{} = muter, %User{} = mutee, params \\ %{}) do
|
|||
)
|
||||
end
|
||||
|
||||
Cachex.del(:user_cache, "muted_users_ap_ids:#{muter.ap_id}")
|
||||
|
||||
{:ok, Enum.filter([user_mute, user_notification_mute], & &1)}
|
||||
end
|
||||
end
|
||||
|
@ -1350,6 +1366,7 @@ def unmute(%User{} = muter, %User{} = mutee) do
|
|||
with {:ok, user_mute} <- UserRelationship.delete_mute(muter, mutee),
|
||||
{:ok, user_notification_mute} <-
|
||||
UserRelationship.delete_notification_mute(muter, mutee) do
|
||||
Cachex.del(:user_cache, "muted_users_ap_ids:#{muter.ap_id}")
|
||||
{:ok, [user_mute, user_notification_mute]}
|
||||
end
|
||||
end
|
||||
|
@ -2345,13 +2362,19 @@ def unblock_domain(user, domain_blocked) do
|
|||
@spec add_to_block(User.t(), User.t()) ::
|
||||
{:ok, UserRelationship.t()} | {:error, Ecto.Changeset.t()}
|
||||
defp add_to_block(%User{} = user, %User{} = blocked) do
|
||||
UserRelationship.create_block(user, blocked)
|
||||
with {:ok, relationship} <- UserRelationship.create_block(user, blocked) do
|
||||
Cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
|
||||
{:ok, relationship}
|
||||
end
|
||||
end
|
||||
|
||||
@spec add_to_block(User.t(), User.t()) ::
|
||||
{:ok, UserRelationship.t()} | {:ok, nil} | {:error, Ecto.Changeset.t()}
|
||||
defp remove_from_block(%User{} = user, %User{} = blocked) do
|
||||
UserRelationship.delete_block(user, blocked)
|
||||
with {:ok, relationship} <- UserRelationship.delete_block(user, blocked) do
|
||||
Cachex.del(:user_cache, "blocked_users_ap_ids:#{user.ap_id}")
|
||||
{:ok, relationship}
|
||||
end
|
||||
end
|
||||
|
||||
def set_invisible(user, invisible) do
|
||||
|
|
|
@ -139,6 +139,12 @@ def statuses_operation do
|
|||
:query,
|
||||
%Schema{type: :array, items: VisibilityScope},
|
||||
"Exclude visibilities"
|
||||
),
|
||||
Operation.parameter(
|
||||
:with_muted,
|
||||
:query,
|
||||
BooleanLike,
|
||||
"Include reactions from muted acccounts."
|
||||
)
|
||||
] ++ pagination_params(),
|
||||
responses: %{
|
||||
|
|
|
@ -24,6 +24,12 @@ def index_operation do
|
|||
Operation.parameter(:id, :path, FlakeID, "Status ID", required: true),
|
||||
Operation.parameter(:emoji, :path, :string, "Filter by a single unicode emoji",
|
||||
required: nil
|
||||
),
|
||||
Operation.parameter(
|
||||
:with_muted,
|
||||
:query,
|
||||
:boolean,
|
||||
"Include reactions from muted acccounts."
|
||||
)
|
||||
],
|
||||
security: [%{"oAuth" => ["read:statuses"]}],
|
||||
|
|
|
@ -31,6 +31,12 @@ def index_operation do
|
|||
:query,
|
||||
%Schema{type: :array, items: FlakeID},
|
||||
"Array of status IDs"
|
||||
),
|
||||
Operation.parameter(
|
||||
:with_muted,
|
||||
:query,
|
||||
BooleanLike,
|
||||
"Include reactions from muted acccounts."
|
||||
)
|
||||
],
|
||||
operationId: "StatusController.index",
|
||||
|
@ -67,7 +73,15 @@ def show_operation do
|
|||
description: "View information about a status",
|
||||
operationId: "StatusController.show",
|
||||
security: [%{"oAuth" => ["read:statuses"]}],
|
||||
parameters: [id_param()],
|
||||
parameters: [
|
||||
id_param(),
|
||||
Operation.parameter(
|
||||
:with_muted,
|
||||
:query,
|
||||
BooleanLike,
|
||||
"Include reactions from muted acccounts."
|
||||
)
|
||||
],
|
||||
responses: %{
|
||||
200 => status_response(),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
|
|
|
@ -292,7 +292,8 @@ def statuses(%{assigns: %{user: reading_user}} = conn, params) do
|
|||
|> render("index.json",
|
||||
activities: activities,
|
||||
for: reading_user,
|
||||
as: :activity
|
||||
as: :activity,
|
||||
with_muted: Map.get(params, :with_muted, false)
|
||||
)
|
||||
else
|
||||
error -> user_visibility_error(conn, error)
|
||||
|
|
|
@ -109,7 +109,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|
|||
|
||||
`ids` query param is required
|
||||
"""
|
||||
def index(%{assigns: %{user: user}} = conn, %{ids: ids} = _params) do
|
||||
def index(%{assigns: %{user: user}} = conn, %{ids: ids} = params) do
|
||||
limit = 100
|
||||
|
||||
activities =
|
||||
|
@ -121,7 +121,8 @@ def index(%{assigns: %{user: user}} = conn, %{ids: ids} = _params) do
|
|||
render(conn, "index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity
|
||||
as: :activity,
|
||||
with_muted: Map.get(params, :with_muted, false)
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -189,13 +190,14 @@ def create(%{assigns: %{user: _user}, body_params: %{media_ids: _} = params} = c
|
|||
end
|
||||
|
||||
@doc "GET /api/v1/statuses/:id"
|
||||
def show(%{assigns: %{user: user}} = conn, %{id: id}) do
|
||||
def show(%{assigns: %{user: user}} = conn, %{id: id} = params) do
|
||||
with %Activity{} = activity <- Activity.get_by_id_with_object(id),
|
||||
true <- Visibility.visible_for_user?(activity, user) do
|
||||
try_render(conn, "show.json",
|
||||
activity: activity,
|
||||
for: user,
|
||||
with_direct_conversation_id: true
|
||||
with_direct_conversation_id: true,
|
||||
with_muted: Map.get(params, :with_muted, false)
|
||||
)
|
||||
else
|
||||
_ -> {:error, :not_found}
|
||||
|
|
|
@ -62,7 +62,8 @@ def home(%{assigns: %{user: user}} = conn, params) do
|
|||
|> render("index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity
|
||||
as: :activity,
|
||||
with_muted: Map.get(params, :with_muted, false)
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -119,7 +120,8 @@ def public(%{assigns: %{user: user}} = conn, params) do
|
|||
|> render("index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity
|
||||
as: :activity,
|
||||
with_muted: Map.get(params, :with_muted, false)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -173,7 +175,8 @@ def hashtag(%{assigns: %{user: user}} = conn, params) do
|
|||
|> render("index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity
|
||||
as: :activity,
|
||||
with_muted: Map.get(params, :with_muted, false)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -202,7 +205,8 @@ def list(%{assigns: %{user: user}} = conn, %{list_id: id} = params) do
|
|||
render(conn, "index.json",
|
||||
activities: activities,
|
||||
for: user,
|
||||
as: :activity
|
||||
as: :activity,
|
||||
with_muted: Map.get(params, :with_muted, false)
|
||||
)
|
||||
else
|
||||
_e -> render_error(conn, :forbidden, "Error.")
|
||||
|
|
|
@ -19,6 +19,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
alias Pleroma.Web.MastodonAPI.PollView
|
||||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
alias Pleroma.Web.MediaProxy
|
||||
alias Pleroma.Web.PleromaAPI.EmojiReactionController
|
||||
|
||||
import Pleroma.Web.ActivityPub.Visibility, only: [get_visibility: 1, visible_for_user?: 2]
|
||||
|
||||
|
@ -294,21 +295,16 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
|
|||
end
|
||||
|
||||
emoji_reactions =
|
||||
with %{data: %{"reactions" => emoji_reactions}} <- object do
|
||||
Enum.map(emoji_reactions, fn
|
||||
[emoji, users] when is_list(users) ->
|
||||
build_emoji_map(emoji, users, opts[:for])
|
||||
|
||||
{emoji, users} when is_list(users) ->
|
||||
build_emoji_map(emoji, users, opts[:for])
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end)
|
||||
|> Enum.reject(&is_nil/1)
|
||||
else
|
||||
_ -> []
|
||||
end
|
||||
object.data
|
||||
|> Map.get("reactions", [])
|
||||
|> EmojiReactionController.filter_allowed_users(
|
||||
opts[:for],
|
||||
Map.get(opts, :with_muted, false)
|
||||
)
|
||||
|> Stream.map(fn {emoji, users} ->
|
||||
build_emoji_map(emoji, users, opts[:for])
|
||||
end)
|
||||
|> Enum.to_list()
|
||||
|
||||
# Status muted state (would do 1 request per status unless user mutes are preloaded)
|
||||
muted =
|
||||
|
|
|
@ -140,8 +140,8 @@ def messages(%{assigns: %{user: user}} = conn, %{id: id} = params) do
|
|||
|
||||
def index(%{assigns: %{user: %{id: user_id} = user}} = conn, params) do
|
||||
exclude_users =
|
||||
User.blocked_users_ap_ids(user) ++
|
||||
if params[:with_muted], do: [], else: User.muted_users_ap_ids(user)
|
||||
User.cached_blocked_users_ap_ids(user) ++
|
||||
if params[:with_muted], do: [], else: User.cached_muted_users_ap_ids(user)
|
||||
|
||||
chats =
|
||||
user_id
|
||||
|
|
|
@ -7,6 +7,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionController do
|
|||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
alias Pleroma.Web.Plugs.OAuthScopesPlug
|
||||
|
@ -29,13 +30,42 @@ def index(%{assigns: %{user: user}} = conn, %{id: activity_id} = params) do
|
|||
%Activity{} = activity <- Activity.get_by_id_with_object(activity_id),
|
||||
%Object{data: %{"reactions" => reactions}} when is_list(reactions) <-
|
||||
Object.normalize(activity) do
|
||||
reactions = filter(reactions, params)
|
||||
reactions =
|
||||
reactions
|
||||
|> filter(params)
|
||||
|> filter_allowed_users(user, Map.get(params, :with_muted, false))
|
||||
|
||||
render(conn, "index.json", emoji_reactions: reactions, user: user)
|
||||
else
|
||||
_e -> json(conn, [])
|
||||
end
|
||||
end
|
||||
|
||||
def filter_allowed_users(reactions, user, with_muted) do
|
||||
exclude_ap_ids =
|
||||
if is_nil(user) do
|
||||
[]
|
||||
else
|
||||
User.cached_blocked_users_ap_ids(user) ++
|
||||
if not with_muted, do: User.cached_muted_users_ap_ids(user), else: []
|
||||
end
|
||||
|
||||
filter_emoji = fn emoji, users ->
|
||||
case Enum.reject(users, &(&1 in exclude_ap_ids)) do
|
||||
[] -> nil
|
||||
users -> {emoji, users}
|
||||
end
|
||||
end
|
||||
|
||||
reactions
|
||||
|> Stream.map(fn
|
||||
[emoji, users] when is_list(users) -> filter_emoji.(emoji, users)
|
||||
{emoji, users} when is_list(users) -> filter_emoji.(emoji, users)
|
||||
_ -> nil
|
||||
end)
|
||||
|> Stream.reject(&is_nil/1)
|
||||
end
|
||||
|
||||
defp filter(reactions, %{emoji: emoji}) when is_binary(emoji) do
|
||||
Enum.filter(reactions, fn [e, _] -> e == emoji end)
|
||||
end
|
||||
|
|
|
@ -11,7 +11,7 @@ def render("index.json", %{emoji_reactions: emoji_reactions} = opts) do
|
|||
render_many(emoji_reactions, __MODULE__, "show.json", opts)
|
||||
end
|
||||
|
||||
def render("show.json", %{emoji_reaction: [emoji, user_ap_ids], user: user}) do
|
||||
def render("show.json", %{emoji_reaction: {emoji, user_ap_ids}, user: user}) do
|
||||
users = fetch_users(user_ap_ids)
|
||||
|
||||
%{
|
||||
|
|
|
@ -436,6 +436,39 @@ test "the user views their own timelines and excludes direct messages", %{
|
|||
conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?exclude_visibilities[]=direct")
|
||||
assert [%{"id" => ^public_activity_id}] = json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
|
||||
test "muted reactions", %{user: user, conn: conn} do
|
||||
user2 = insert(:user)
|
||||
User.mute(user, user2)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "."})
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, user2, "🎅")
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/accounts/#{user.id}/statuses")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => []
|
||||
}
|
||||
}
|
||||
] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/accounts/#{user.id}/statuses?with_muted=true")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
|
||||
}
|
||||
}
|
||||
] = result
|
||||
end
|
||||
end
|
||||
|
||||
defp local_and_remote_activities(%{local: local, remote: remote}) do
|
||||
|
|
|
@ -1759,4 +1759,75 @@ test "posting a local only status" do
|
|||
|
||||
assert %Activity{id: ^id, data: %{"to" => [^local]}} = Activity.get_by_id(id)
|
||||
end
|
||||
|
||||
describe "muted reactions" do
|
||||
test "index" do
|
||||
%{conn: conn, user: user} = oauth_access(["read:statuses"])
|
||||
|
||||
other_user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "test"})
|
||||
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
|
||||
User.mute(user, other_user)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/statuses/?ids[]=#{activity.id}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => []
|
||||
}
|
||||
}
|
||||
] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/statuses/?ids[]=#{activity.id}&with_muted=true")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
|
||||
}
|
||||
}
|
||||
] = result
|
||||
end
|
||||
|
||||
test "show" do
|
||||
# %{conn: conn, user: user, token: token} = oauth_access(["read:statuses"])
|
||||
%{conn: conn, user: user, token: _token} = oauth_access(["read:statuses"])
|
||||
|
||||
other_user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "test"})
|
||||
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
|
||||
User.mute(user, other_user)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/statuses/#{activity.id}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert %{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => []
|
||||
}
|
||||
} = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/statuses/#{activity.id}?with_muted=true")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert %{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
|
||||
}
|
||||
} = result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -54,6 +54,42 @@ test "the home timeline when the direct messages are excluded", %{user: user, co
|
|||
assert private_activity.id in status_ids
|
||||
refute direct_activity.id in status_ids
|
||||
end
|
||||
|
||||
test "muted emotions", %{user: user, conn: conn} do
|
||||
other_user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "."})
|
||||
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
|
||||
User.mute(user, other_user)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/api/v1/timelines/home")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => []
|
||||
}
|
||||
}
|
||||
] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/api/v1/timelines/home?with_muted=true")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
|
||||
}
|
||||
}
|
||||
] = result
|
||||
end
|
||||
end
|
||||
|
||||
describe "public" do
|
||||
|
@ -159,6 +195,48 @@ test "can be filtered by instance", %{conn: conn} do
|
|||
|
||||
assert length(json_response_and_validate_schema(conn, :ok)) == 1
|
||||
end
|
||||
|
||||
test "muted emotions", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
token = insert(:oauth_token, user: user, scopes: ["read:statuses"])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, token)
|
||||
|
||||
other_user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "."})
|
||||
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
|
||||
User.mute(user, other_user)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/timelines/public")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => []
|
||||
}
|
||||
}
|
||||
] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/timelines/public?with_muted=true")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
|
||||
}
|
||||
}
|
||||
] = result
|
||||
end
|
||||
end
|
||||
|
||||
defp local_and_remote_activities do
|
||||
|
@ -428,6 +506,44 @@ test "list timeline does not leak non-public statuses for unfollowed users", %{
|
|||
|
||||
assert id == to_string(activity_one.id)
|
||||
end
|
||||
|
||||
test "muted emotions", %{user: user, conn: conn} do
|
||||
user2 = insert(:user)
|
||||
user3 = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user2, %{status: "."})
|
||||
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, user3, "🎅")
|
||||
User.mute(user, user3)
|
||||
|
||||
{:ok, list} = Pleroma.List.create("name", user)
|
||||
{:ok, list} = Pleroma.List.follow(list, user2)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/timelines/list/#{list.id}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => []
|
||||
}
|
||||
}
|
||||
] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/timelines/list/#{list.id}?with_muted=true")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
|
||||
}
|
||||
}
|
||||
] = result
|
||||
end
|
||||
end
|
||||
|
||||
describe "hashtag" do
|
||||
|
@ -476,6 +592,48 @@ test "multi-hashtag timeline", %{conn: conn} do
|
|||
|
||||
assert [status_none] == json_response_and_validate_schema(all_test, :ok)
|
||||
end
|
||||
|
||||
test "muted emotions", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
token = insert(:oauth_token, user: user, scopes: ["read:statuses"])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, token)
|
||||
|
||||
other_user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "test #2hu"})
|
||||
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
|
||||
User.mute(user, other_user)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/timelines/tag/2hu")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => []
|
||||
}
|
||||
}
|
||||
] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/timelines/tag/2hu?with_muted=true")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"pleroma" => %{
|
||||
"emoji_reactions" => [%{"count" => 1, "me" => false, "name" => "🎅"}]
|
||||
}
|
||||
}
|
||||
] = result
|
||||
end
|
||||
end
|
||||
|
||||
describe "hashtag timeline handling of :restrict_unauthenticated setting" do
|
||||
|
|
|
@ -73,6 +73,50 @@ test "works correctly with badly formatted emojis" do
|
|||
]
|
||||
end
|
||||
|
||||
test "doesn't show reactions from muted and blocked users" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
third_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "dae cofe??"})
|
||||
|
||||
{:ok, _} = User.mute(user, other_user)
|
||||
{:ok, _} = User.block(other_user, third_user)
|
||||
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
|
||||
|
||||
activity = Repo.get(Activity, activity.id)
|
||||
status = StatusView.render("show.json", activity: activity)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 1, me: false}
|
||||
]
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, for: user)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == []
|
||||
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, third_user, "☕")
|
||||
|
||||
status = StatusView.render("show.json", activity: activity)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 2, me: false}
|
||||
]
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, for: user)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 1, me: false}
|
||||
]
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, for: other_user)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 1, me: true}
|
||||
]
|
||||
end
|
||||
|
||||
test "loads and returns the direct conversation id when given the `with_direct_conversation_id` option" do
|
||||
user = insert(:user)
|
||||
|
||||
|
|
|
@ -106,6 +106,48 @@ test "GET /api/v1/pleroma/statuses/:id/reactions", %{conn: conn} do
|
|||
result
|
||||
end
|
||||
|
||||
test "GET /api/v1/pleroma/statuses/:id/reactions?with_muted=true", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
user2 = insert(:user)
|
||||
user3 = insert(:user)
|
||||
|
||||
token = insert(:oauth_token, user: user, scopes: ["read:statuses"])
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
|
||||
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, user2, "🎅")
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, user3, "🎅")
|
||||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, token)
|
||||
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"name" => "🎅", "count" => 2}] = result
|
||||
|
||||
User.mute(user, user3)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, token)
|
||||
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"name" => "🎅", "count" => 1}] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, token)
|
||||
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions?with_muted=true")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"name" => "🎅", "count" => 2}] = result
|
||||
end
|
||||
|
||||
test "GET /api/v1/pleroma/statuses/:id/reactions with :show_reactions disabled", %{conn: conn} do
|
||||
clear_config([:instance, :show_reactions], false)
|
||||
|
||||
|
|
Loading…
Reference in a new issue