Merge branch 'restricted-relations-embedding' into 'develop'

Restricted support for embedded relationships

See merge request pleroma/pleroma!2456
This commit is contained in:
lain 2020-05-17 07:26:51 +00:00
commit 4b28d812cf
31 changed files with 193 additions and 323 deletions

View file

@ -387,56 +387,47 @@ defmodule Pleroma.LoadTesting.Fetcher do
favourites = ActivityPub.fetch_favourites(user) favourites = ActivityPub.fetch_favourites(user)
output_relationships =
!!Pleroma.Config.get([:extensions, :output_relationships_in_statuses_by_default])
Benchee.run( Benchee.run(
%{ %{
"Rendering home timeline" => fn -> "Rendering home timeline" => fn ->
StatusView.render("index.json", %{ StatusView.render("index.json", %{
activities: home_activities, activities: home_activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: !output_relationships
}) })
end, end,
"Rendering direct timeline" => fn -> "Rendering direct timeline" => fn ->
StatusView.render("index.json", %{ StatusView.render("index.json", %{
activities: direct_activities, activities: direct_activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: !output_relationships
}) })
end, end,
"Rendering public timeline" => fn -> "Rendering public timeline" => fn ->
StatusView.render("index.json", %{ StatusView.render("index.json", %{
activities: public_activities, activities: public_activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: !output_relationships
}) })
end, end,
"Rendering tag timeline" => fn -> "Rendering tag timeline" => fn ->
StatusView.render("index.json", %{ StatusView.render("index.json", %{
activities: tag_activities, activities: tag_activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: !output_relationships
}) })
end, end,
"Rendering notifications" => fn -> "Rendering notifications" => fn ->
Pleroma.Web.MastodonAPI.NotificationView.render("index.json", %{ Pleroma.Web.MastodonAPI.NotificationView.render("index.json", %{
notifications: notifications, notifications: notifications,
for: user, for: user
skip_relationships: !output_relationships
}) })
end, end,
"Rendering favourites timeline" => fn -> "Rendering favourites timeline" => fn ->
StatusView.render("index.json", %{ StatusView.render("index.json", %{
activities: favourites, activities: favourites,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: !output_relationships
}) })
end end
}, },

View file

@ -251,8 +251,6 @@ config :pleroma, :instance,
] ]
] ]
config :pleroma, :extensions, output_relationships_in_statuses_by_default: true
config :pleroma, :feed, config :pleroma, :feed,
post_title: %{ post_title: %{
max_length: 100, max_length: 100,

View file

@ -67,8 +67,7 @@ defmodule Mix.Tasks.Pleroma.Benchmark do
Pleroma.Web.MastodonAPI.StatusView.render("index.json", %{ Pleroma.Web.MastodonAPI.StatusView.render("index.json", %{
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: true
}) })
end end
}, },

View file

@ -87,6 +87,22 @@ defmodule Pleroma.UserRelationship do
source_to_target_rel_types \\ nil, source_to_target_rel_types \\ nil,
target_to_source_rel_types \\ nil target_to_source_rel_types \\ nil
) )
def dictionary(
_source_users,
_target_users,
[] = _source_to_target_rel_types,
[] = _target_to_source_rel_types
) do
[]
end
def dictionary(
source_users,
target_users,
source_to_target_rel_types,
target_to_source_rel_types
)
when is_list(source_users) and is_list(target_users) do when is_list(source_users) and is_list(target_users) do
source_user_ids = User.binary_id(source_users) source_user_ids = User.binary_id(source_users)
target_user_ids = User.binary_id(target_users) target_user_ids = User.binary_id(target_users)
@ -138,11 +154,16 @@ defmodule Pleroma.UserRelationship do
def view_relationships_option(%User{} = reading_user, actors, opts) do def view_relationships_option(%User{} = reading_user, actors, opts) do
{source_to_target_rel_types, target_to_source_rel_types} = {source_to_target_rel_types, target_to_source_rel_types} =
if opts[:source_mutes_only] do case opts[:subset] do
# This option is used for rendering statuses (FE needs `muted` flag for each one anyways) :source_mutes ->
{[:mute], []} # Used for statuses rendering (FE needs `muted` flag for each status when statuses load)
else {[:mute], []}
{[:block, :mute, :notification_mute, :reblog_mute], [:block, :inverse_subscription]}
nil ->
{[:block, :mute, :notification_mute, :reblog_mute], [:block, :inverse_subscription]}
unknown ->
raise "Unsupported :subset option value: #{inspect(unknown)}"
end end
user_relationships = user_relationships =
@ -153,7 +174,17 @@ defmodule Pleroma.UserRelationship do
target_to_source_rel_types target_to_source_rel_types
) )
following_relationships = FollowingRelationship.all_between_user_sets([reading_user], actors) following_relationships =
case opts[:subset] do
:source_mutes ->
[]
nil ->
FollowingRelationship.all_between_user_sets([reading_user], actors)
unknown ->
raise "Unsupported :subset option value: #{inspect(unknown)}"
end
%{user_relationships: user_relationships, following_relationships: following_relationships} %{user_relationships: user_relationships, following_relationships: following_relationships}
end end

View file

@ -22,6 +22,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
alias Pleroma.Web.ActivityPub.Pipeline alias Pleroma.Web.ActivityPub.Pipeline
alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.AdminAPI
alias Pleroma.Web.AdminAPI.AccountView alias Pleroma.Web.AdminAPI.AccountView
alias Pleroma.Web.AdminAPI.ConfigView alias Pleroma.Web.AdminAPI.ConfigView
alias Pleroma.Web.AdminAPI.ModerationLogView alias Pleroma.Web.AdminAPI.ModerationLogView
@ -30,8 +31,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
alias Pleroma.Web.AdminAPI.Search alias Pleroma.Web.AdminAPI.Search
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Endpoint alias Pleroma.Web.Endpoint
alias Pleroma.Web.MastodonAPI
alias Pleroma.Web.MastodonAPI.AppView alias Pleroma.Web.MastodonAPI.AppView
alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.App
alias Pleroma.Web.Router alias Pleroma.Web.Router
@ -280,8 +281,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
}) })
conn conn
|> put_view(Pleroma.Web.AdminAPI.StatusView) |> put_view(AdminAPI.StatusView)
|> render("index.json", %{activities: activities, as: :activity, skip_relationships: false}) |> render("index.json", %{activities: activities, as: :activity})
end end
def list_user_statuses(conn, %{"nickname" => nickname} = params) do def list_user_statuses(conn, %{"nickname" => nickname} = params) do
@ -299,8 +300,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
}) })
conn conn
|> put_view(StatusView) |> put_view(MastodonAPI.StatusView)
|> render("index.json", %{activities: activities, as: :activity, skip_relationships: false}) |> render("index.json", %{activities: activities, as: :activity})
else else
_ -> {:error, :not_found} _ -> {:error, :not_found}
end end
@ -829,14 +830,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
}) })
conn conn
|> put_view(Pleroma.Web.AdminAPI.StatusView) |> put_view(AdminAPI.StatusView)
|> render("index.json", %{activities: activities, as: :activity, skip_relationships: false}) |> render("index.json", %{activities: activities, as: :activity})
end end
def status_show(conn, %{"id" => id}) do def status_show(conn, %{"id" => id}) do
with %Activity{} = activity <- Activity.get_by_id(id) do with %Activity{} = activity <- Activity.get_by_id(id) do
conn conn
|> put_view(StatusView) |> put_view(MastodonAPI.StatusView)
|> render("show.json", %{activity: activity}) |> render("show.json", %{activity: activity})
else else
_ -> errors(conn, {:error, :not_found}) _ -> errors(conn, {:error, :not_found})
@ -861,7 +862,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
}) })
conn conn
|> put_view(StatusView) |> put_view(MastodonAPI.StatusView)
|> render("show.json", %{activity: activity}) |> render("show.json", %{activity: activity})
end end
end end

View file

@ -6,7 +6,9 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
use Pleroma.Web, :view use Pleroma.Web, :view
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.AdminAPI
alias Pleroma.Web.AdminAPI.AccountView alias Pleroma.Web.AdminAPI.AccountView
alias Pleroma.Web.MastodonAPI
alias Pleroma.Web.MediaProxy alias Pleroma.Web.MediaProxy
def render("index.json", %{users: users, count: count, page_size: page_size}) do def render("index.json", %{users: users, count: count, page_size: page_size}) do
@ -119,6 +121,13 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
} }
end end
def merge_account_views(%User{} = user) do
MastodonAPI.AccountView.render("show.json", %{user: user})
|> Map.merge(AdminAPI.AccountView.render("show.json", %{user: user}))
end
def merge_account_views(_), do: %{}
defp parse_error([]), do: "" defp parse_error([]), do: ""
defp parse_error(errors) do defp parse_error(errors) do

View file

@ -7,10 +7,13 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
alias Pleroma.HTML alias Pleroma.HTML
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.AdminAPI
alias Pleroma.Web.AdminAPI.Report alias Pleroma.Web.AdminAPI.Report
alias Pleroma.Web.CommonAPI.Utils alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MastodonAPI.StatusView
defdelegate merge_account_views(user), to: AdminAPI.AccountView
def render("index.json", %{reports: reports}) do def render("index.json", %{reports: reports}) do
%{ %{
reports: reports:
@ -41,8 +44,7 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
statuses: statuses:
StatusView.render("index.json", %{ StatusView.render("index.json", %{
activities: statuses, activities: statuses,
as: :activity, as: :activity
skip_relationships: false
}), }),
state: report.data["state"], state: report.data["state"],
notes: render(__MODULE__, "index_notes.json", %{notes: report.report_notes}) notes: render(__MODULE__, "index_notes.json", %{notes: report.report_notes})
@ -70,11 +72,4 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
created_at: Utils.to_masto_date(inserted_at) created_at: Utils.to_masto_date(inserted_at)
} }
end end
defp merge_account_views(%User{} = user) do
Pleroma.Web.MastodonAPI.AccountView.render("show.json", %{user: user})
|> Map.merge(Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user}))
end
defp merge_account_views(_), do: %{}
end end

View file

@ -7,24 +7,19 @@ defmodule Pleroma.Web.AdminAPI.StatusView do
require Pleroma.Constants require Pleroma.Constants
alias Pleroma.User alias Pleroma.Web.AdminAPI
alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MastodonAPI
defdelegate merge_account_views(user), to: AdminAPI.AccountView
def render("index.json", opts) do def render("index.json", opts) do
safe_render_many(opts.activities, __MODULE__, "show.json", opts) safe_render_many(opts.activities, __MODULE__, "show.json", opts)
end end
def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do
user = StatusView.get_user(activity.data["actor"]) user = MastodonAPI.StatusView.get_user(activity.data["actor"])
StatusView.render("show.json", opts) MastodonAPI.StatusView.render("show.json", opts)
|> Map.merge(%{account: merge_account_views(user)}) |> Map.merge(%{account: merge_account_views(user)})
end end
defp merge_account_views(%User{} = user) do
Pleroma.Web.MastodonAPI.AccountView.render("show.json", %{user: user})
|> Map.merge(Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user}))
end
defp merge_account_views(_), do: %{}
end end

View file

@ -5,6 +5,7 @@
defmodule Pleroma.Web.ApiSpec.Helpers do defmodule Pleroma.Web.ApiSpec.Helpers do
alias OpenApiSpex.Operation alias OpenApiSpex.Operation
alias OpenApiSpex.Schema alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
def request_body(description, schema_ref, opts \\ []) do def request_body(description, schema_ref, opts \\ []) do
media_types = ["application/json", "multipart/form-data", "application/x-www-form-urlencoded"] media_types = ["application/json", "multipart/form-data", "application/x-www-form-urlencoded"]
@ -47,6 +48,15 @@ defmodule Pleroma.Web.ApiSpec.Helpers do
] ]
end end
def with_relationships_param do
Operation.parameter(
:with_relationships,
:query,
BooleanLike,
"Embed relationships into accounts."
)
end
def empty_object_response do def empty_object_response do
Operation.response("Empty object", "application/json", %Schema{type: :object, example: %{}}) Operation.response("Empty object", "application/json", %Schema{type: :object, example: %{}})
end end

View file

@ -155,8 +155,10 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
security: [%{"oAuth" => ["read:accounts"]}], security: [%{"oAuth" => ["read:accounts"]}],
description: description:
"Accounts which follow the given account, if network is not hidden by the account owner.", "Accounts which follow the given account, if network is not hidden by the account owner.",
parameters: parameters: [
[%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}] ++ pagination_params(), %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
with_relationships_param() | pagination_params()
],
responses: %{ responses: %{
200 => Operation.response("Accounts", "application/json", array_of_accounts()) 200 => Operation.response("Accounts", "application/json", array_of_accounts())
} }
@ -171,8 +173,10 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
security: [%{"oAuth" => ["read:accounts"]}], security: [%{"oAuth" => ["read:accounts"]}],
description: description:
"Accounts which the given account is following, if network is not hidden by the account owner.", "Accounts which the given account is following, if network is not hidden by the account owner.",
parameters: parameters: [
[%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}] ++ pagination_params(), %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
with_relationships_param() | pagination_params()
],
responses: %{200 => Operation.response("Accounts", "application/json", array_of_accounts())} responses: %{200 => Operation.response("Accounts", "application/json", array_of_accounts())}
} }
end end

View file

@ -19,6 +19,7 @@ defmodule Pleroma.Web.ApiSpec.SearchOperation do
apply(__MODULE__, operation, []) apply(__MODULE__, operation, [])
end end
# Note: `with_relationships` param is not supported (PleromaFE uses this op for autocomplete)
def account_search_operation do def account_search_operation do
%Operation{ %Operation{
tags: ["Search"], tags: ["Search"],
@ -96,8 +97,8 @@ defmodule Pleroma.Web.ApiSpec.SearchOperation do
:query, :query,
%Schema{type: :integer}, %Schema{type: :integer},
"Offset" "Offset"
) ),
| pagination_params() with_relationships_param() | pagination_params()
], ],
responses: %{ responses: %{
200 => Operation.response("Results", "application/json", results()) 200 => Operation.response("Results", "application/json", results())
@ -138,8 +139,8 @@ defmodule Pleroma.Web.ApiSpec.SearchOperation do
:query, :query,
%Schema{allOf: [BooleanLike], default: false}, %Schema{allOf: [BooleanLike], default: false},
"Only include accounts that the user is following" "Only include accounts that the user is following"
) ),
| pagination_params() with_relationships_param() | pagination_params()
], ],
responses: %{ responses: %{
200 => Operation.response("Results", "application/json", results2()) 200 => Operation.response("Results", "application/json", results2())

View file

@ -7,7 +7,6 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
alias OpenApiSpex.Schema alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.AccountOperation alias Pleroma.Web.ApiSpec.AccountOperation
alias Pleroma.Web.ApiSpec.Schemas.ApiError alias Pleroma.Web.ApiSpec.Schemas.ApiError
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
alias Pleroma.Web.ApiSpec.Schemas.FlakeID alias Pleroma.Web.ApiSpec.Schemas.FlakeID
alias Pleroma.Web.ApiSpec.Schemas.ScheduledStatus alias Pleroma.Web.ApiSpec.Schemas.ScheduledStatus
alias Pleroma.Web.ApiSpec.Schemas.Status alias Pleroma.Web.ApiSpec.Schemas.Status
@ -349,10 +348,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
summary: "Bookmarked statuses", summary: "Bookmarked statuses",
description: "Statuses the user has bookmarked", description: "Statuses the user has bookmarked",
operationId: "StatusController.bookmarks", operationId: "StatusController.bookmarks",
parameters: [ parameters: pagination_params(),
Operation.parameter(:with_relationships, :query, BooleanLike, "Include relationships")
| pagination_params()
],
security: [%{"oAuth" => ["read:bookmarks"]}], security: [%{"oAuth" => ["read:bookmarks"]}],
responses: %{ responses: %{
200 => Operation.response("Array of Statuses", "application/json", array_of_statuses()) 200 => Operation.response("Array of Statuses", "application/json", array_of_statuses())

View file

@ -27,8 +27,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
local_param(), local_param(),
with_muted_param(), with_muted_param(),
exclude_visibilities_param(), exclude_visibilities_param(),
reply_visibility_param(), reply_visibility_param() | pagination_params()
with_relationships_param() | pagination_params()
], ],
operationId: "TimelineController.home", operationId: "TimelineController.home",
responses: %{ responses: %{
@ -63,8 +62,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
only_media_param(), only_media_param(),
with_muted_param(), with_muted_param(),
exclude_visibilities_param(), exclude_visibilities_param(),
reply_visibility_param(), reply_visibility_param() | pagination_params()
with_relationships_param() | pagination_params()
], ],
operationId: "TimelineController.public", operationId: "TimelineController.public",
responses: %{ responses: %{
@ -109,8 +107,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
local_param(), local_param(),
only_media_param(), only_media_param(),
with_muted_param(), with_muted_param(),
exclude_visibilities_param(), exclude_visibilities_param() | pagination_params()
with_relationships_param() | pagination_params()
], ],
operationId: "TimelineController.hashtag", operationId: "TimelineController.hashtag",
responses: %{ responses: %{
@ -134,8 +131,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
required: true required: true
), ),
with_muted_param(), with_muted_param(),
exclude_visibilities_param(), exclude_visibilities_param() | pagination_params()
with_relationships_param() | pagination_params()
], ],
operationId: "TimelineController.list", operationId: "TimelineController.list",
responses: %{ responses: %{
@ -153,10 +149,6 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
} }
end end
defp with_relationships_param do
Operation.parameter(:with_relationships, :query, BooleanLike, "Include relationships")
end
defp local_param do defp local_param do
Operation.parameter( Operation.parameter(
:local, :local,

View file

@ -23,6 +23,7 @@ defmodule Pleroma.Web.ChatChannel do
if String.length(text) in 1..Pleroma.Config.get([:instance, :chat_limit]) do if String.length(text) in 1..Pleroma.Config.get([:instance, :chat_limit]) do
author = User.get_cached_by_nickname(user_name) author = User.get_cached_by_nickname(user_name)
author = Pleroma.Web.MastodonAPI.AccountView.render("show.json", user: author) author = Pleroma.Web.MastodonAPI.AccountView.render("show.json", user: author)
message = ChatChannelState.add_message(%{text: text, author: author}) message = ChatChannelState.add_message(%{text: text, author: author})
broadcast!(socket, "new_msg", message) broadcast!(socket, "new_msg", message)

View file

@ -5,8 +5,6 @@
defmodule Pleroma.Web.ControllerHelper do defmodule Pleroma.Web.ControllerHelper do
use Pleroma.Web, :controller use Pleroma.Web, :controller
alias Pleroma.Config
# As in Mastodon API, per https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html # As in Mastodon API, per https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html
@falsy_param_values [false, 0, "0", "f", "F", "false", "False", "FALSE", "off", "OFF"] @falsy_param_values [false, 0, "0", "f", "F", "false", "False", "FALSE", "off", "OFF"]
@ -106,13 +104,16 @@ defmodule Pleroma.Web.ControllerHelper do
def put_if_exist(map, key, value), do: Map.put(map, key, value) def put_if_exist(map, key, value), do: Map.put(map, key, value)
@doc "Whether to skip rendering `[:account][:pleroma][:relationship]`for statuses/notifications" @doc """
def skip_relationships?(params) do Returns true if request specifies to include embedded relationships in account objects.
if Config.get([:extensions, :output_relationships_in_statuses_by_default]) do May only be used in selected account-related endpoints; has no effect for status- or
false notification-related endpoints.
else """
# BREAKING: older PleromaFE versions do not send this param but _do_ expect relationships. # Intended for PleromaFE: https://git.pleroma.social/pleroma/pleroma-fe/-/issues/838
not truthy_param?(params["with_relationships"]) def embed_relationships?(params) do
end # To do once OpenAPI transition mess is over: just `truthy_param?(params[:with_relationships])`
params
|> Map.get(:with_relationships, params["with_relationships"])
|> truthy_param?()
end end
end end

View file

@ -10,8 +10,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
add_link_headers: 2, add_link_headers: 2,
truthy_param?: 1, truthy_param?: 1,
assign_account_by_id: 2, assign_account_by_id: 2,
json_response: 3, embed_relationships?: 1,
skip_relationships?: 1 json_response: 3
] ]
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
@ -247,8 +247,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: reading_user, for: reading_user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
else else
_e -> render_error(conn, :not_found, "Can't find user") _e -> render_error(conn, :not_found, "Can't find user")
@ -271,7 +270,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
conn conn
|> add_link_headers(followers) |> add_link_headers(followers)
|> render("index.json", for: for_user, users: followers, as: :user) # https://git.pleroma.social/pleroma/pleroma-fe/-/issues/838#note_59223
|> render("index.json",
for: for_user,
users: followers,
as: :user,
embed_relationships: embed_relationships?(params)
)
end end
@doc "GET /api/v1/accounts/:id/following" @doc "GET /api/v1/accounts/:id/following"
@ -290,7 +295,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
conn conn
|> add_link_headers(followers) |> add_link_headers(followers)
|> render("index.json", for: for_user, users: followers, as: :user) # https://git.pleroma.social/pleroma/pleroma-fe/-/issues/838#note_59223
|> render("index.json",
for: for_user,
users: followers,
as: :user,
embed_relationships: embed_relationships?(params)
)
end end
@doc "GET /api/v1/accounts/:id/lists" @doc "GET /api/v1/accounts/:id/lists"

View file

@ -5,7 +5,7 @@
defmodule Pleroma.Web.MastodonAPI.NotificationController do defmodule Pleroma.Web.MastodonAPI.NotificationController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2, skip_relationships?: 1] import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
alias Pleroma.Notification alias Pleroma.Notification
alias Pleroma.Plugs.OAuthScopesPlug alias Pleroma.Plugs.OAuthScopesPlug
@ -50,8 +50,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationController do
|> add_link_headers(notifications) |> add_link_headers(notifications)
|> render("index.json", |> render("index.json",
notifications: notifications, notifications: notifications,
for: user, for: user
skip_relationships: skip_relationships?(params)
) )
end end

View file

@ -5,14 +5,13 @@
defmodule Pleroma.Web.MastodonAPI.SearchController do defmodule Pleroma.Web.MastodonAPI.SearchController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [skip_relationships?: 1]
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Plugs.OAuthScopesPlug alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.Plugs.RateLimiter alias Pleroma.Plugs.RateLimiter
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web alias Pleroma.Web
alias Pleroma.Web.ControllerHelper
alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MastodonAPI.StatusView
@ -34,7 +33,11 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
conn conn
|> put_view(AccountView) |> put_view(AccountView)
|> render("index.json", users: accounts, for: user, as: :user) |> render("index.json",
users: accounts,
for: user,
as: :user
)
end end
def search2(conn, params), do: do_search(:v2, conn, params) def search2(conn, params), do: do_search(:v2, conn, params)
@ -71,13 +74,13 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
defp search_options(params, user) do defp search_options(params, user) do
[ [
skip_relationships: skip_relationships?(params),
resolve: params[:resolve], resolve: params[:resolve],
following: params[:following], following: params[:following],
limit: params[:limit], limit: params[:limit],
offset: params[:offset], offset: params[:offset],
type: params[:type], type: params[:type],
author: get_author(params), author: get_author(params),
embed_relationships: ControllerHelper.embed_relationships?(params),
for_user: user for_user: user
] ]
|> Enum.filter(&elem(&1, 1)) |> Enum.filter(&elem(&1, 1))
@ -90,7 +93,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
users: accounts, users: accounts,
for: options[:for_user], for: options[:for_user],
as: :user, as: :user,
skip_relationships: false embed_relationships: options[:embed_relationships]
) )
end end
@ -100,8 +103,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
StatusView.render("index.json", StatusView.render("index.json",
activities: statuses, activities: statuses,
for: options[:for_user], for: options[:for_user],
as: :activity, as: :activity
skip_relationships: options[:skip_relationships]
) )
end end

View file

@ -6,7 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, import Pleroma.Web.ControllerHelper,
only: [try_render: 3, add_link_headers: 2, skip_relationships?: 1] only: [try_render: 3, add_link_headers: 2]
require Ecto.Query require Ecto.Query
@ -105,7 +105,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
`ids` query param is required `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 limit = 100
activities = activities =
@ -117,8 +117,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
render(conn, "index.json", render(conn, "index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
@ -383,8 +382,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
@ -406,8 +404,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
end end

View file

@ -6,7 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, import Pleroma.Web.ControllerHelper,
only: [add_link_headers: 2, add_link_headers: 3, skip_relationships?: 1] only: [add_link_headers: 2, add_link_headers: 3]
alias Pleroma.Pagination alias Pleroma.Pagination
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
@ -63,8 +63,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
@ -88,8 +87,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
@ -125,8 +123,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
end end
@ -173,8 +170,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end
@ -203,8 +199,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
render(conn, "index.json", render(conn, "index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
else else
_e -> render_error(conn, :forbidden, "Error.") _e -> render_error(conn, :forbidden, "Error.")

View file

@ -15,13 +15,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
def render("index.json", %{users: users} = opts) do def render("index.json", %{users: users} = opts) do
reading_user = opts[:for] reading_user = opts[:for]
# Note: :skip_relationships option is currently intentionally not supported for accounts
relationships_opt = relationships_opt =
cond do cond do
Map.has_key?(opts, :relationships) -> Map.has_key?(opts, :relationships) ->
opts[:relationships] opts[:relationships]
is_nil(reading_user) -> is_nil(reading_user) || !opts[:embed_relationships] ->
UserRelationship.view_relationships_option(nil, []) UserRelationship.view_relationships_option(nil, [])
true -> true ->
@ -193,14 +192,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
end) end)
relationship = relationship =
if opts[:skip_relationships] do if opts[:embed_relationships] do
%{}
else
render("relationship.json", %{ render("relationship.json", %{
user: opts[:for], user: opts[:for],
target: user, target: user,
relationships: opts[:relationships] relationships: opts[:relationships]
}) })
else
%{}
end end
%{ %{

View file

@ -51,9 +51,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
|> Enum.filter(& &1) |> Enum.filter(& &1)
|> Kernel.++(move_activities_targets) |> Kernel.++(move_activities_targets)
UserRelationship.view_relationships_option(reading_user, actors, UserRelationship.view_relationships_option(reading_user, actors, subset: :source_mutes)
source_mutes_only: opts[:skip_relationships]
)
end end
opts = opts =
@ -83,15 +81,13 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
mastodon_type = Activity.mastodon_notification_type(activity) mastodon_type = Activity.mastodon_notification_type(activity)
render_opts = %{ # Note: :relationships contain user mutes (needed for :muted flag in :status)
relationships: opts[:relationships], status_render_opts = %{relationships: opts[:relationships]}
skip_relationships: opts[:skip_relationships]
}
with %{id: _} = account <- with %{id: _} = account <-
AccountView.render( AccountView.render(
"show.json", "show.json",
Map.merge(render_opts, %{user: actor, for: reading_user}) %{user: actor, for: reading_user}
) do ) do
response = %{ response = %{
id: to_string(notification.id), id: to_string(notification.id),
@ -105,21 +101,20 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
case mastodon_type do case mastodon_type do
"mention" -> "mention" ->
put_status(response, activity, reading_user, render_opts) put_status(response, activity, reading_user, status_render_opts)
"favourite" -> "favourite" ->
put_status(response, parent_activity_fn.(), reading_user, render_opts) put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
"reblog" -> "reblog" ->
put_status(response, parent_activity_fn.(), reading_user, render_opts) put_status(response, parent_activity_fn.(), reading_user, status_render_opts)
"move" -> "move" ->
# Note: :skip_relationships option being applied to _account_ rendering (here) put_target(response, activity, reading_user, %{})
put_target(response, activity, reading_user, render_opts)
"pleroma:emoji_reaction" -> "pleroma:emoji_reaction" ->
response response
|> put_status(parent_activity_fn.(), reading_user, render_opts) |> put_status(parent_activity_fn.(), reading_user, status_render_opts)
|> put_emoji(activity) |> put_emoji(activity)
type when type in ["follow", "follow_request"] -> type when type in ["follow", "follow_request"] ->

View file

@ -107,9 +107,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|> Enum.map(&get_user(&1.data["actor"], false)) |> Enum.map(&get_user(&1.data["actor"], false))
|> Enum.filter(& &1) |> Enum.filter(& &1)
UserRelationship.view_relationships_option(reading_user, actors, UserRelationship.view_relationships_option(reading_user, actors, subset: :source_mutes)
source_mutes_only: opts[:skip_relationships]
)
end end
opts = opts =
@ -162,9 +160,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
account: account:
AccountView.render("show.json", %{ AccountView.render("show.json", %{
user: user, user: user,
for: opts[:for], for: opts[:for]
relationships: opts[:relationships],
skip_relationships: opts[:skip_relationships]
}), }),
in_reply_to_id: nil, in_reply_to_id: nil,
in_reply_to_account_id: nil, in_reply_to_account_id: nil,
@ -330,9 +326,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
account: account:
AccountView.render("show.json", %{ AccountView.render("show.json", %{
user: user, user: user,
for: opts[:for], for: opts[:for]
relationships: opts[:relationships],
skip_relationships: opts[:skip_relationships]
}), }),
in_reply_to_id: reply_to && to_string(reply_to.id), in_reply_to_id: reply_to && to_string(reply_to.id),
in_reply_to_account_id: reply_to_user && to_string(reply_to_user.id), in_reply_to_account_id: reply_to_user && to_string(reply_to_user.id),

View file

@ -6,7 +6,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, import Pleroma.Web.ControllerHelper,
only: [json_response: 3, add_link_headers: 2, assign_account_by_id: 2, skip_relationships?: 1] only: [json_response: 3, add_link_headers: 2, assign_account_by_id: 2]
alias Ecto.Changeset alias Ecto.Changeset
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
@ -149,8 +149,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: for_user, for: for_user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
end end

View file

@ -5,7 +5,7 @@
defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2, skip_relationships?: 1] import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Conversation.Participation alias Pleroma.Conversation.Participation
@ -69,7 +69,12 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
%{ %{
name: emoji, name: emoji,
count: length(users), count: length(users),
accounts: AccountView.render("index.json", %{users: users, for: user, as: :user}), accounts:
AccountView.render("index.json", %{
users: users,
for: user,
as: :user
}),
me: !!(user && user.ap_id in user_ap_ids) me: !!(user && user.ap_id in user_ap_ids)
} }
end end
@ -145,8 +150,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
|> render("index.json", |> render("index.json",
activities: activities, activities: activities,
for: user, for: user,
as: :activity, as: :activity
skip_relationships: skip_relationships?(params)
) )
else else
_error -> _error ->
@ -201,7 +205,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
end end
end end
def mark_notifications_as_read(%{assigns: %{user: user}} = conn, %{"max_id" => max_id} = params) do def mark_notifications_as_read(%{assigns: %{user: user}} = conn, %{"max_id" => max_id}) do
with notifications <- Notification.set_read_up_to(user, max_id) do with notifications <- Notification.set_read_up_to(user, max_id) do
notifications = Enum.take(notifications, 80) notifications = Enum.take(notifications, 80)
@ -209,8 +213,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
|> put_view(NotificationView) |> put_view(NotificationView)
|> render("index.json", |> render("index.json",
notifications: notifications, notifications: notifications,
for: user, for: user
skip_relationships: skip_relationships?(params)
) )
end end
end end

View file

@ -12,9 +12,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
import Pleroma.Factory import Pleroma.Factory
test "does NOT render account/pleroma/relationship if this is disabled by default" do test "does NOT render account/pleroma/relationship by default" do
clear_config([:extensions, :output_relationships_in_statuses_by_default], false)
%{user: user, conn: conn} = oauth_access(["read:notifications"]) %{user: user, conn: conn} = oauth_access(["read:notifications"])
other_user = insert(:user) other_user = insert(:user)

View file

@ -1176,7 +1176,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
end end
test "bookmarks" do test "bookmarks" do
bookmarks_uri = "/api/v1/bookmarks?with_relationships=true" bookmarks_uri = "/api/v1/bookmarks"
%{conn: conn} = oauth_access(["write:bookmarks", "read:bookmarks"]) %{conn: conn} = oauth_access(["write:bookmarks", "read:bookmarks"])
author = insert(:user) author = insert(:user)

View file

@ -20,12 +20,10 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
describe "home" do describe "home" do
setup do: oauth_access(["read:statuses"]) setup do: oauth_access(["read:statuses"])
test "does NOT render account/pleroma/relationship if this is disabled by default", %{ test "does NOT embed account/pleroma/relationship in statuses", %{
user: user, user: user,
conn: conn conn: conn
} do } do
clear_config([:extensions, :output_relationships_in_statuses_by_default], false)
other_user = insert(:user) other_user = insert(:user)
{:ok, _} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) {:ok, _} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
@ -41,72 +39,6 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
end) end)
end end
test "the home timeline", %{user: user, conn: conn} do
uri = "/api/v1/timelines/home?with_relationships=1"
following = insert(:user, nickname: "followed")
third_user = insert(:user, nickname: "repeated")
{:ok, _activity} = CommonAPI.post(following, %{status: "post"})
{:ok, activity} = CommonAPI.post(third_user, %{status: "repeated post"})
{:ok, _, _} = CommonAPI.repeat(activity.id, following)
ret_conn = get(conn, uri)
assert Enum.empty?(json_response_and_validate_schema(ret_conn, :ok))
{:ok, _user} = User.follow(user, following)
ret_conn = get(conn, uri)
assert [
%{
"reblog" => %{
"content" => "repeated post",
"account" => %{
"pleroma" => %{
"relationship" => %{"following" => false, "followed_by" => false}
}
}
},
"account" => %{"pleroma" => %{"relationship" => %{"following" => true}}}
},
%{
"content" => "post",
"account" => %{
"acct" => "followed",
"pleroma" => %{"relationship" => %{"following" => true}}
}
}
] = json_response_and_validate_schema(ret_conn, :ok)
{:ok, _user} = User.follow(third_user, user)
ret_conn = get(conn, uri)
assert [
%{
"reblog" => %{
"content" => "repeated post",
"account" => %{
"acct" => "repeated",
"pleroma" => %{
"relationship" => %{"following" => false, "followed_by" => true}
}
}
},
"account" => %{"pleroma" => %{"relationship" => %{"following" => true}}}
},
%{
"content" => "post",
"account" => %{
"acct" => "followed",
"pleroma" => %{"relationship" => %{"following" => true}}
}
}
] = json_response_and_validate_schema(ret_conn, :ok)
end
test "the home timeline when the direct messages are excluded", %{user: user, conn: conn} do test "the home timeline when the direct messages are excluded", %{user: user, conn: conn} do
{:ok, public_activity} = CommonAPI.post(user, %{status: ".", visibility: "public"}) {:ok, public_activity} = CommonAPI.post(user, %{status: ".", visibility: "public"})
{:ok, direct_activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"}) {:ok, direct_activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"})

View file

@ -302,82 +302,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
end end
end end
test "represent an embedded relationship" do
user =
insert(:user, %{
follower_count: 0,
note_count: 5,
actor_type: "Service",
nickname: "shp@shitposter.club",
inserted_at: ~N[2017-08-15 15:47:06.597036]
})
other_user = insert(:user)
{:ok, other_user} = User.follow(other_user, user)
{:ok, _user_relationship} = User.block(other_user, user)
{:ok, _} = User.follow(insert(:user), user)
expected = %{
id: to_string(user.id),
username: "shp",
acct: user.nickname,
display_name: user.name,
locked: false,
created_at: "2017-08-15T15:47:06.000Z",
followers_count: 1,
following_count: 0,
statuses_count: 5,
note: user.bio,
url: user.ap_id,
avatar: "http://localhost:4001/images/avi.png",
avatar_static: "http://localhost:4001/images/avi.png",
header: "http://localhost:4001/images/banner.png",
header_static: "http://localhost:4001/images/banner.png",
emojis: [],
fields: [],
bot: true,
source: %{
note: user.bio,
sensitive: false,
pleroma: %{
actor_type: "Service",
discoverable: false
},
fields: []
},
pleroma: %{
background_image: nil,
confirmation_pending: false,
tags: [],
is_admin: false,
is_moderator: false,
hide_favorites: true,
hide_followers: false,
hide_follows: false,
hide_followers_count: false,
hide_follows_count: false,
relationship: %{
id: to_string(user.id),
following: false,
followed_by: false,
blocking: true,
blocked_by: false,
subscribing: false,
muting: false,
muting_notifications: false,
requested: false,
domain_blocking: false,
showing_reblogs: true,
endorsed: false
},
skip_thread_containment: false
}
}
assert expected ==
AccountView.render("show.json", %{user: refresh_record(user), for: other_user})
end
test "returns the settings store if the requesting user is the represented user and it's requested specifically" do test "returns the settings store if the requesting user is the represented user and it's requested specifically" do
user = insert(:user, pleroma_settings_store: %{fe: "test"}) user = insert(:user, pleroma_settings_store: %{fe: "test"})

View file

@ -42,7 +42,11 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
id: to_string(notification.id), id: to_string(notification.id),
pleroma: %{is_seen: false}, pleroma: %{is_seen: false},
type: "mention", type: "mention",
account: AccountView.render("show.json", %{user: user, for: mentioned_user}), account:
AccountView.render("show.json", %{
user: user,
for: mentioned_user
}),
status: StatusView.render("show.json", %{activity: activity, for: mentioned_user}), status: StatusView.render("show.json", %{activity: activity, for: mentioned_user}),
created_at: Utils.to_masto_date(notification.inserted_at) created_at: Utils.to_masto_date(notification.inserted_at)
} }

View file

@ -576,7 +576,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
end end
end end
test "embeds a relationship in the account" do test "does not embed a relationship in the account" do
user = insert(:user) user = insert(:user)
other_user = insert(:user) other_user = insert(:user)
@ -587,13 +587,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
result = StatusView.render("show.json", %{activity: activity, for: other_user}) result = StatusView.render("show.json", %{activity: activity, for: other_user})
assert result[:account][:pleroma][:relationship] == assert result[:account][:pleroma][:relationship] == %{}
AccountView.render("relationship.json", %{user: other_user, target: user})
assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec()) assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
end end
test "embeds a relationship in the account in reposts" do test "does not embed a relationship in the account in reposts" do
user = insert(:user) user = insert(:user)
other_user = insert(:user) other_user = insert(:user)
@ -606,12 +604,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
result = StatusView.render("show.json", %{activity: activity, for: user}) result = StatusView.render("show.json", %{activity: activity, for: user})
assert result[:account][:pleroma][:relationship] == assert result[:account][:pleroma][:relationship] == %{}
AccountView.render("relationship.json", %{user: user, target: other_user}) assert result[:reblog][:account][:pleroma][:relationship] == %{}
assert result[:reblog][:account][:pleroma][:relationship] ==
AccountView.render("relationship.json", %{user: user, target: user})
assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec()) assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
end end