forked from YokaiRick/akkoma
API compatibility with fedibird, frontend config (#163)
Reviewed-on: AkkomaGang/akkoma#163
This commit is contained in:
parent
89ffc01c23
commit
11ec9daa5b
19 changed files with 256 additions and 60 deletions
|
@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- support for fedibird-fe, and non-breaking API parity for it to function
|
||||
|
||||
### Fixed
|
||||
- Compatibility with latest meilisearch
|
||||
- Resolution of nested mix tasks (i.e search.meilisearch) in OTP releases
|
||||
|
|
|
@ -734,6 +734,14 @@
|
|||
"build_dir" => "distribution",
|
||||
"ref" => "akkoma"
|
||||
},
|
||||
"fedibird-fe" => %{
|
||||
"name" => "fedibird-fe",
|
||||
"git" => "https://akkoma.dev/AkkomaGang/fedibird-fe",
|
||||
"build_url" =>
|
||||
"https://akkoma-updates.s3-website.fr-par.scw.cloud/frontend/${ref}/fedibird-fe.zip",
|
||||
"build_dir" => "distribution",
|
||||
"ref" => "akkoma"
|
||||
},
|
||||
"admin-fe" => %{
|
||||
"name" => "admin-fe",
|
||||
"git" => "https://akkoma.dev/AkkomaGang/admin-fe",
|
||||
|
|
|
@ -19,6 +19,10 @@ config :pleroma, :frontends,
|
|||
admin: %{
|
||||
"name" => "admin-fe",
|
||||
"ref" => "stable"
|
||||
},
|
||||
mastodon: %{
|
||||
"name" => "mastodon-fe",
|
||||
"ref" => "akkoma"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -26,12 +30,18 @@ This would serve the frontend from the the folder at `$instance_static/frontends
|
|||
|
||||
Refer to [the frontend CLI task](../../administration/CLI_tasks/frontend) for how to install the frontend's files
|
||||
|
||||
If you wish masto-fe to also be enabled, you will also need to run the install task for `mastodon-fe`. Not doing this will lead to the frontend not working.
|
||||
|
||||
If you choose not to install a frontend for whatever reason, it is recommended that you enable [`:static_fe`](#static_fe) to allow remote users to click "view remote source". Don't bother with this if you've got no unauthenticated access though.
|
||||
|
||||
You can also replace the default "no frontend" page by placing an `index.html` file under your `instance/static/` directory.
|
||||
|
||||
## Mastodon-FE
|
||||
|
||||
Akkoma supports both [glitchsoc](https://github.com/glitch-soc/mastodon)'s more "vanilla" mastodon frontend,
|
||||
as well as [fedibird](https://github.com/fedibird/mastodon)'s extended frontend which has near-feature-parity with akkoma (with quoting and reactions).
|
||||
|
||||
To enable either one, you must run the `frontend.install` task for either `mastodon-fe` or `fedibird-fe` (both `--ref akkoma`), then make sure
|
||||
`:pleroma, :frontends, :mastodon` references the one you want.
|
||||
|
||||
## Swagger (openAPI) documentation viewer
|
||||
|
||||
If you're a developer and you'd like a human-readable rendering of the
|
||||
|
|
|
@ -27,9 +27,21 @@ defmodule Pleroma.Web.MastoFEController do
|
|||
def index(conn, _params) do
|
||||
with %{assigns: %{user: %User{} = user, token: %Token{app_id: token_app_id} = token}} <- conn,
|
||||
{:ok, %{id: ^token_app_id}} <- AuthController.local_mastofe_app() do
|
||||
flavour =
|
||||
[:frontends, :mastodon]
|
||||
|> Pleroma.Config.get()
|
||||
|> Map.get("name", "mastodon-fe")
|
||||
|
||||
index =
|
||||
if flavour == "fedibird-fe" do
|
||||
"fedibird.index.html"
|
||||
else
|
||||
"glitchsoc.index.html"
|
||||
end
|
||||
|
||||
conn
|
||||
|> put_layout(false)
|
||||
|> render("index.html",
|
||||
|> render(index,
|
||||
token: token.token,
|
||||
user: user,
|
||||
custom_emojis: Pleroma.Emoji.get_all()
|
||||
|
|
|
@ -375,6 +375,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
|
|||
emojis: build_emojis(object.data["emoji"]),
|
||||
quote_id: if(quote, do: quote.id, else: nil),
|
||||
quote: maybe_render_quote(quote, opts),
|
||||
emoji_reactions: emoji_reactions,
|
||||
pleroma: %{
|
||||
local: activity.local,
|
||||
conversation_id: get_context_id(activity),
|
||||
|
@ -589,7 +590,8 @@ defp build_emoji_map(emoji, users, url, current_user) do
|
|||
name: emoji,
|
||||
count: length(users),
|
||||
url: MediaProxy.url(url),
|
||||
me: !!(current_user && current_user.ap_id in users)
|
||||
me: !!(current_user && current_user.ap_id in users),
|
||||
account_ids: Enum.map(users, fn user -> User.get_cached_by_ap_id(user).id end)
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -32,8 +32,15 @@ def init(%{qs: qs} = req, state) do
|
|||
req
|
||||
end
|
||||
|
||||
{:cowboy_websocket, req, %{user: user, topic: topic, count: 0, timer: nil},
|
||||
%{idle_timeout: @timeout}}
|
||||
{:cowboy_websocket, req,
|
||||
%{
|
||||
user: user,
|
||||
topic: topic,
|
||||
count: 0,
|
||||
timer: nil,
|
||||
subscriptions: [],
|
||||
oauth_token: oauth_token
|
||||
}, %{idle_timeout: @timeout}}
|
||||
else
|
||||
{:error, :bad_topic} ->
|
||||
Logger.debug("#{__MODULE__} bad topic #{inspect(req)}")
|
||||
|
@ -65,21 +72,50 @@ def websocket_handle(:pong, state) do
|
|||
# We only receive pings for now
|
||||
def websocket_handle(:ping, state), do: {:ok, state}
|
||||
|
||||
def websocket_handle({:text, "ping"}, state) do
|
||||
def websocket_handle({:text, ping}, state) when ping in ~w[ping PING] do
|
||||
if state.timer, do: Process.cancel_timer(state.timer)
|
||||
{:reply, {:text, "pong"}, %{state | timer: timer()}}
|
||||
end
|
||||
|
||||
def websocket_handle({:text, text}, state) do
|
||||
with {:ok, json} <- Jason.decode(text) do
|
||||
websocket_handle({:json, json}, state)
|
||||
else
|
||||
_ ->
|
||||
Logger.error("#{__MODULE__} received text frame: #{text}")
|
||||
{:ok, state}
|
||||
end
|
||||
end
|
||||
|
||||
def websocket_handle(
|
||||
{:json, %{"type" => "subscribe", "stream" => stream_name}},
|
||||
%{user: user, oauth_token: token} = state
|
||||
) do
|
||||
with {:ok, topic} <- Streamer.get_topic(stream_name, user, token, %{}) do
|
||||
new_subscriptions =
|
||||
[topic | Map.get(state, :subscriptions, [])]
|
||||
|> Enum.uniq()
|
||||
|
||||
{:ok, _topic} = Streamer.add_socket(topic, user)
|
||||
|
||||
{:ok, Map.put(state, :subscriptions, new_subscriptions)}
|
||||
else
|
||||
_ ->
|
||||
Logger.error("#{__MODULE__} received invalid topic: #{stream_name}")
|
||||
{:ok, state}
|
||||
end
|
||||
end
|
||||
|
||||
def websocket_handle(frame, state) do
|
||||
Logger.error("#{__MODULE__} received frame: #{inspect(frame)}")
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
def websocket_info({:render_with_user, view, template, item}, state) do
|
||||
def websocket_info({:render_with_user, view, template, item, topic}, state) do
|
||||
user = %User{} = User.get_cached_by_ap_id(state.user.ap_id)
|
||||
|
||||
unless Streamer.filtered_by_user?(user, item) do
|
||||
websocket_info({:text, view.render(template, item, user)}, %{state | user: user})
|
||||
websocket_info({:text, view.render(template, item, user, topic)}, %{state | user: user})
|
||||
else
|
||||
{:ok, state}
|
||||
end
|
||||
|
|
|
@ -74,6 +74,8 @@ defp filter(reactions, %{emoji: emoji}) when is_binary(emoji) do
|
|||
defp filter(reactions, _), do: reactions
|
||||
|
||||
def create(%{assigns: %{user: user}} = conn, %{id: activity_id, emoji: emoji}) do
|
||||
emoji = Pleroma.Emoji.maybe_quote(emoji)
|
||||
|
||||
with {:ok, _activity} <- CommonAPI.react_with_emoji(activity_id, user, emoji) do
|
||||
activity = Activity.get_by_id(activity_id)
|
||||
|
||||
|
|
|
@ -457,6 +457,11 @@ defmodule Pleroma.Web.Router do
|
|||
get("/federation_status", InstancesController, :show)
|
||||
end
|
||||
|
||||
scope "/api/v1", Pleroma.Web.PleromaAPI do
|
||||
pipe_through(:authenticated_api)
|
||||
put("/statuses/:id/emoji_reactions/:emoji", EmojiReactionController, :create)
|
||||
end
|
||||
|
||||
scope "/api/v1", Pleroma.Web.MastodonAPI do
|
||||
pipe_through(:authenticated_api)
|
||||
|
||||
|
|
|
@ -114,6 +114,11 @@ def get_topic("list", _user, _oauth_token, _params) do
|
|||
{:error, :unauthorized}
|
||||
end
|
||||
|
||||
# mastodon multi-topic WS
|
||||
def get_topic(nil, _user, _oauth_token, _params) do
|
||||
{:ok, :multi}
|
||||
end
|
||||
|
||||
def get_topic(_stream, _user, _oauth_token, _params) do
|
||||
{:error, :bad_topic}
|
||||
end
|
||||
|
@ -186,8 +191,8 @@ defp do_stream("direct", item) do
|
|||
end
|
||||
|
||||
defp do_stream("follow_relationship", item) do
|
||||
text = StreamerView.render("follow_relationships_update.json", item)
|
||||
user_topic = "user:#{item.follower.id}"
|
||||
text = StreamerView.render("follow_relationships_update.json", item, user_topic)
|
||||
|
||||
Logger.debug("Trying to push follow relationship update to #{user_topic}\n\n")
|
||||
|
||||
|
@ -235,7 +240,7 @@ defp do_stream(topic, %Notification{} = item)
|
|||
when topic in ["user", "user:notification"] do
|
||||
Registry.dispatch(@registry, "#{topic}:#{item.user_id}", fn list ->
|
||||
Enum.each(list, fn {pid, _auth} ->
|
||||
send(pid, {:render_with_user, StreamerView, "notification.json", item})
|
||||
send(pid, {:render_with_user, StreamerView, "notification.json", item, topic})
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
@ -259,7 +264,7 @@ defp do_stream(topic, item) do
|
|||
end
|
||||
|
||||
defp push_to_socket(topic, %Participation{} = participation) do
|
||||
rendered = StreamerView.render("conversation.json", participation)
|
||||
rendered = StreamerView.render("conversation.json", participation, topic)
|
||||
|
||||
Registry.dispatch(@registry, topic, fn list ->
|
||||
Enum.each(list, fn {pid, _} ->
|
||||
|
@ -283,12 +288,12 @@ defp push_to_socket(topic, %Activity{
|
|||
defp push_to_socket(_topic, %Activity{data: %{"type" => "Delete"}}), do: :noop
|
||||
|
||||
defp push_to_socket(topic, item) do
|
||||
anon_render = StreamerView.render("update.json", item)
|
||||
anon_render = StreamerView.render("update.json", item, topic)
|
||||
|
||||
Registry.dispatch(@registry, topic, fn list ->
|
||||
Enum.each(list, fn {pid, auth?} ->
|
||||
if auth? do
|
||||
send(pid, {:render_with_user, StreamerView, "update.json", item})
|
||||
send(pid, {:render_with_user, StreamerView, "update.json", item, topic})
|
||||
else
|
||||
send(pid, {:text, anon_render})
|
||||
end
|
||||
|
|
34
lib/pleroma/web/templates/masto_fe/fedibird.index.html.eex
Normal file
34
lib/pleroma/web/templates/masto_fe/fedibird.index.html.eex
Normal file
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<meta content='width=device-width, initial-scale=1' name='viewport'>
|
||||
<title>
|
||||
<%= Config.get([:instance, :name]) %>
|
||||
</title>
|
||||
<link rel="icon" type="image/png" href="/favicon.png"/>
|
||||
<link rel="manifest" type="applicaton/manifest+json" href="<%= Routes.masto_fe_path(Pleroma.Web.Endpoint, :manifest) %>" />
|
||||
|
||||
<meta name="theme-color" content="<%= Config.get([:manifest, :theme_color]) %>" />
|
||||
|
||||
<script id='initial-state' type='application/json'><%= initial_state(@token, @user, @custom_emojis) %></script>
|
||||
|
||||
<script crossorigin='anonymous' src="/packs/js/common.js"></script>
|
||||
<script crossorigin='anonymous' src="/packs/js/locale_en.js"></script>
|
||||
|
||||
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/js/features/getting_started.js'>
|
||||
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/js/features/compose.js'>
|
||||
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/js/features/home_timeline.js'>
|
||||
<link rel='preload' as='script' crossorigin='anonymous' href='/packs/js/features/notifications.js'>
|
||||
<script crossorigin='anonymous' src="/packs/js/application.js"></script>
|
||||
|
||||
|
||||
<link rel="stylesheet" media="all" href="/packs/css/common.css" />
|
||||
<link rel="stylesheet" media="all" href="/packs/css/default.css" />
|
||||
|
||||
</head>
|
||||
<body class='app-body no-reduce-motion system-font'>
|
||||
<div class='app-holder' data-props='{"locale":"en"}' id='mastodon'>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -14,6 +14,7 @@ def initial_state(token, user, custom_emojis) do
|
|||
|
||||
%{
|
||||
meta: %{
|
||||
title: Config.get([:instance, :name]),
|
||||
streaming_api_base_url: Pleroma.Web.Endpoint.websocket_url(),
|
||||
access_token: token,
|
||||
locale: "en",
|
||||
|
@ -27,7 +28,11 @@ def initial_state(token, user, custom_emojis) do
|
|||
display_sensitive_media: false,
|
||||
reduce_motion: false,
|
||||
max_toot_chars: limit,
|
||||
mascot: User.get_mascot(user)["url"]
|
||||
mascot: User.get_mascot(user)["url"],
|
||||
show_quote_button: true,
|
||||
enable_reaction: true,
|
||||
compact_reaction: false,
|
||||
advanced_layout: true
|
||||
},
|
||||
poll_limits: Config.get([:instance, :poll_limits]),
|
||||
rights: %{
|
||||
|
@ -56,6 +61,7 @@ def initial_state(token, user, custom_emojis) do
|
|||
"video\/mp4"
|
||||
]
|
||||
},
|
||||
lists: [],
|
||||
settings: user.mastofe_settings || %{},
|
||||
push_subscription: nil,
|
||||
accounts: %{user.id => render(AccountView, "show.json", user: user, for: user)},
|
||||
|
|
|
@ -11,8 +11,9 @@ defmodule Pleroma.Web.StreamerView do
|
|||
alias Pleroma.User
|
||||
alias Pleroma.Web.MastodonAPI.NotificationView
|
||||
|
||||
def render("update.json", %Activity{} = activity, %User{} = user) do
|
||||
def render("update.json", %Activity{} = activity, %User{} = user, topic) do
|
||||
%{
|
||||
stream: [topic],
|
||||
event: "update",
|
||||
payload:
|
||||
Pleroma.Web.MastodonAPI.StatusView.render(
|
||||
|
@ -25,8 +26,9 @@ def render("update.json", %Activity{} = activity, %User{} = user) do
|
|||
|> Jason.encode!()
|
||||
end
|
||||
|
||||
def render("notification.json", %Notification{} = notify, %User{} = user) do
|
||||
def render("notification.json", %Notification{} = notify, %User{} = user, topic) do
|
||||
%{
|
||||
stream: [topic],
|
||||
event: "notification",
|
||||
payload:
|
||||
NotificationView.render(
|
||||
|
@ -38,8 +40,9 @@ def render("notification.json", %Notification{} = notify, %User{} = user) do
|
|||
|> Jason.encode!()
|
||||
end
|
||||
|
||||
def render("update.json", %Activity{} = activity) do
|
||||
def render("update.json", %Activity{} = activity, topic) do
|
||||
%{
|
||||
stream: [topic],
|
||||
event: "update",
|
||||
payload:
|
||||
Pleroma.Web.MastodonAPI.StatusView.render(
|
||||
|
@ -51,8 +54,9 @@ def render("update.json", %Activity{} = activity) do
|
|||
|> Jason.encode!()
|
||||
end
|
||||
|
||||
def render("follow_relationships_update.json", item) do
|
||||
def render("follow_relationships_update.json", item, topic) do
|
||||
%{
|
||||
stream: [topic],
|
||||
event: "pleroma:follow_relationships_update",
|
||||
payload:
|
||||
%{
|
||||
|
@ -73,8 +77,9 @@ def render("follow_relationships_update.json", item) do
|
|||
|> Jason.encode!()
|
||||
end
|
||||
|
||||
def render("conversation.json", %Participation{} = participation) do
|
||||
def render("conversation.json", %Participation{} = participation, topic) do
|
||||
%{
|
||||
stream: [topic],
|
||||
event: "conversation",
|
||||
payload:
|
||||
Pleroma.Web.MastodonAPI.ConversationView.render("participation.json", %{
|
||||
|
|
|
@ -31,9 +31,9 @@ def start_socket(qs \\ nil, headers \\ []) do
|
|||
WebsocketClient.start_link(self(), path, headers)
|
||||
end
|
||||
|
||||
test "refuses invalid requests" do
|
||||
test "allows multi-streams" do
|
||||
capture_log(fn ->
|
||||
assert {:error, {404, _}} = start_socket()
|
||||
assert {:ok, _} = start_socket()
|
||||
assert {:error, {404, _}} = start_socket("?stream=ncjdk")
|
||||
Process.sleep(30)
|
||||
end)
|
||||
|
|
|
@ -224,7 +224,7 @@ test "it creates a notification for user and send to the 'user' and the 'user:no
|
|||
task =
|
||||
Task.async(fn ->
|
||||
{:ok, _topic} = Streamer.get_topic_and_add_socket("user", user, oauth_token)
|
||||
assert_receive {:render_with_user, _, _, _}, 4_000
|
||||
assert_receive {:render_with_user, _, _, _, "user"}, 4_000
|
||||
end)
|
||||
|
||||
task_user_notification =
|
||||
|
@ -232,7 +232,7 @@ test "it creates a notification for user and send to the 'user' and the 'user:no
|
|||
{:ok, _topic} =
|
||||
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
|
||||
|
||||
assert_receive {:render_with_user, _, _, _}, 4_000
|
||||
assert_receive {:render_with_user, _, _, _, "user:notification"}, 4_000
|
||||
end)
|
||||
|
||||
activity = insert(:note_activity)
|
||||
|
|
38
test/pleroma/web/masto_fe_controller_test.exs
Normal file
38
test/pleroma/web/masto_fe_controller_test.exs
Normal file
|
@ -0,0 +1,38 @@
|
|||
defmodule Pleroma.Web.MastoFEControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
alias Pleroma.Web.MastodonAPI.AuthController
|
||||
|
||||
describe "index/2 (main page)" do
|
||||
test "GET /web/ (glitch-soc)" do
|
||||
clear_config([:frontends, :mastodon], %{"name" => "mastodon-fe"})
|
||||
|
||||
{:ok, masto_app} = AuthController.local_mastofe_app()
|
||||
user = Pleroma.Factory.insert(:user)
|
||||
token = Pleroma.Factory.insert(:oauth_token, app: masto_app, user: user)
|
||||
%{conn: conn} = oauth_access(["read", "write"], oauth_token: token, user: user)
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> get("/web/getting-started")
|
||||
|> html_response(200)
|
||||
|
||||
assert resp =~ "glitch"
|
||||
end
|
||||
|
||||
test "GET /web/ (fedibird)" do
|
||||
clear_config([:frontends, :mastodon], %{"name" => "fedibird-fe"})
|
||||
|
||||
{:ok, masto_app} = AuthController.local_mastofe_app()
|
||||
user = Pleroma.Factory.insert(:user)
|
||||
token = Pleroma.Factory.insert(:oauth_token, app: masto_app, user: user)
|
||||
%{conn: conn} = oauth_access(["read", "write"], oauth_token: token, user: user)
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> get("/web/getting-started")
|
||||
|> html_response(200)
|
||||
|
||||
refute resp =~ "glitch"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -44,14 +44,15 @@ test "has an emoji reaction list" do
|
|||
assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 2, me: false, url: nil},
|
||||
%{name: "☕", count: 2, me: false, url: nil, account_ids: [other_user.id, user.id]},
|
||||
%{
|
||||
count: 2,
|
||||
me: false,
|
||||
name: "dinosaur",
|
||||
url: "http://localhost:4001/emoji/dino walking.gif"
|
||||
url: "http://localhost:4001/emoji/dino walking.gif",
|
||||
account_ids: [other_user.id, user.id]
|
||||
},
|
||||
%{name: "🍵", count: 1, me: false, url: nil}
|
||||
%{name: "🍵", count: 1, me: false, url: nil, account_ids: [third_user.id]}
|
||||
]
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, for: user)
|
||||
|
@ -59,14 +60,15 @@ test "has an emoji reaction list" do
|
|||
assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 2, me: true, url: nil},
|
||||
%{name: "☕", count: 2, me: true, url: nil, account_ids: [other_user.id, user.id]},
|
||||
%{
|
||||
count: 2,
|
||||
me: true,
|
||||
name: "dinosaur",
|
||||
url: "http://localhost:4001/emoji/dino walking.gif"
|
||||
url: "http://localhost:4001/emoji/dino walking.gif",
|
||||
account_ids: [other_user.id, user.id]
|
||||
},
|
||||
%{name: "🍵", count: 1, me: false, url: nil}
|
||||
%{name: "🍵", count: 1, me: false, url: nil, account_ids: [third_user.id]}
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -82,7 +84,7 @@ test "works correctly with badly formatted emojis" do
|
|||
status = StatusView.render("show.json", activity: activity, for: user)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 1, me: true, url: nil}
|
||||
%{name: "☕", count: 1, me: true, url: nil, account_ids: [user.id]}
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -102,7 +104,7 @@ test "doesn't show reactions from muted and blocked users" do
|
|||
status = StatusView.render("show.json", activity: activity)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 1, me: false, url: nil}
|
||||
%{name: "☕", count: 1, me: false, url: nil, account_ids: [other_user.id]}
|
||||
]
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, for: user)
|
||||
|
@ -114,19 +116,25 @@ test "doesn't show reactions from muted and blocked users" do
|
|||
status = StatusView.render("show.json", activity: activity)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 2, me: false, url: nil}
|
||||
%{
|
||||
name: "☕",
|
||||
count: 2,
|
||||
me: false,
|
||||
url: nil,
|
||||
account_ids: [third_user.id, other_user.id]
|
||||
}
|
||||
]
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, for: user)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 1, me: false, url: nil}
|
||||
%{name: "☕", count: 1, me: false, url: nil, account_ids: [third_user.id]}
|
||||
]
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, for: other_user)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 1, me: true, url: nil}
|
||||
%{name: "☕", count: 1, me: true, url: nil, account_ids: [other_user.id]}
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -272,6 +280,7 @@ test "a note activity" do
|
|||
spoiler_text: HTML.filter_tags(object_data["summary"]),
|
||||
visibility: "public",
|
||||
media_attachments: [],
|
||||
emoji_reactions: [],
|
||||
mentions: [],
|
||||
tags: [
|
||||
%{
|
||||
|
|
|
@ -31,7 +31,13 @@ test "PUT /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
|
|||
assert to_string(activity.id) == id
|
||||
|
||||
assert result["pleroma"]["emoji_reactions"] == [
|
||||
%{"name" => "☕", "count" => 1, "me" => true, "url" => nil}
|
||||
%{
|
||||
"name" => "☕",
|
||||
"count" => 1,
|
||||
"me" => true,
|
||||
"url" => nil,
|
||||
"account_ids" => [other_user.id]
|
||||
}
|
||||
]
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
|
||||
|
@ -54,7 +60,8 @@ test "PUT /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
|
|||
"name" => "dinosaur",
|
||||
"count" => 1,
|
||||
"me" => true,
|
||||
"url" => "http://localhost:4001/emoji/dino walking.gif"
|
||||
"url" => "http://localhost:4001/emoji/dino walking.gif",
|
||||
"account_ids" => [other_user.id]
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -157,7 +157,8 @@ test "it streams the user's post in the 'user' stream", %{user: user, token: oau
|
|||
Streamer.get_topic_and_add_socket("user", user, oauth_token)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})
|
||||
|
||||
assert_receive {:render_with_user, _, _, ^activity}
|
||||
stream_name = "user:#{user.id}"
|
||||
assert_receive {:render_with_user, _, _, ^activity, ^stream_name}
|
||||
refute Streamer.filtered_by_user?(user, activity)
|
||||
end
|
||||
|
||||
|
@ -168,7 +169,11 @@ test "it streams boosts of the user in the 'user' stream", %{user: user, token:
|
|||
{:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
|
||||
{:ok, announce} = CommonAPI.repeat(activity.id, user)
|
||||
|
||||
assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
|
||||
stream_name = "user:#{user.id}"
|
||||
|
||||
assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce,
|
||||
^stream_name}
|
||||
|
||||
refute Streamer.filtered_by_user?(user, announce)
|
||||
end
|
||||
|
||||
|
@ -221,7 +226,11 @@ test "it streams boosts of mastodon user in the 'user' stream", %{
|
|||
{:ok, %Pleroma.Activity{data: _data, local: false} = announce} =
|
||||
Pleroma.Web.ActivityPub.Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
|
||||
stream_name = "user:#{user.id}"
|
||||
|
||||
assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce,
|
||||
^stream_name}
|
||||
|
||||
refute Streamer.filtered_by_user?(user, announce)
|
||||
end
|
||||
|
||||
|
@ -233,7 +242,7 @@ test "it sends notify to in the 'user' stream", %{
|
|||
Streamer.get_topic_and_add_socket("user", user, oauth_token)
|
||||
Streamer.stream("user", notify)
|
||||
|
||||
assert_receive {:render_with_user, _, _, ^notify}
|
||||
assert_receive {:render_with_user, _, _, ^notify, "user"}
|
||||
refute Streamer.filtered_by_user?(user, notify)
|
||||
end
|
||||
|
||||
|
@ -245,7 +254,7 @@ test "it sends notify to in the 'user:notification' stream", %{
|
|||
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
|
||||
Streamer.stream("user:notification", notify)
|
||||
|
||||
assert_receive {:render_with_user, _, _, ^notify}
|
||||
assert_receive {:render_with_user, _, _, ^notify, "user:notification"}
|
||||
refute Streamer.filtered_by_user?(user, notify)
|
||||
end
|
||||
|
||||
|
@ -291,7 +300,7 @@ test "it sends favorite to 'user:notification' stream'", %{
|
|||
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
|
||||
{:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
|
||||
|
||||
assert_receive {:render_with_user, _, "notification.json", notif}
|
||||
assert_receive {:render_with_user, _, "notification.json", notif, "user:notification"}
|
||||
assert notif.activity.id == favorite_activity.id
|
||||
refute Streamer.filtered_by_user?(user, notif)
|
||||
end
|
||||
|
@ -320,7 +329,7 @@ test "it sends follow activities to the 'user:notification' stream", %{
|
|||
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
|
||||
{:ok, _follower, _followed, follow_activity} = CommonAPI.follow(user2, user)
|
||||
|
||||
assert_receive {:render_with_user, _, "notification.json", notif}
|
||||
assert_receive {:render_with_user, _, "notification.json", notif, "user:notification"}
|
||||
assert notif.activity.id == follow_activity.id
|
||||
refute Streamer.filtered_by_user?(user, notif)
|
||||
end
|
||||
|
@ -384,7 +393,7 @@ test "it sends to public (authenticated)" do
|
|||
Streamer.get_topic_and_add_socket("public", user, oauth_token)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(other_user, %{status: "Test"})
|
||||
assert_receive {:render_with_user, _, _, ^activity}
|
||||
assert_receive {:render_with_user, _, _, ^activity, "public"}
|
||||
refute Streamer.filtered_by_user?(other_user, activity)
|
||||
end
|
||||
|
||||
|
@ -436,7 +445,7 @@ test "it filters to user if recipients invalid and thread containment is enabled
|
|||
|
||||
Streamer.get_topic_and_add_socket("public", user, oauth_token)
|
||||
Streamer.stream("public", activity)
|
||||
assert_receive {:render_with_user, _, _, ^activity}
|
||||
assert_receive {:render_with_user, _, _, ^activity, "public"}
|
||||
assert Streamer.filtered_by_user?(user, activity)
|
||||
end
|
||||
|
||||
|
@ -458,7 +467,7 @@ test "it sends message if recipients invalid and thread containment is disabled"
|
|||
Streamer.get_topic_and_add_socket("public", user, oauth_token)
|
||||
Streamer.stream("public", activity)
|
||||
|
||||
assert_receive {:render_with_user, _, _, ^activity}
|
||||
assert_receive {:render_with_user, _, _, ^activity, "public"}
|
||||
refute Streamer.filtered_by_user?(user, activity)
|
||||
end
|
||||
|
||||
|
@ -481,7 +490,7 @@ test "it sends message if recipients invalid and thread containment is enabled b
|
|||
Streamer.get_topic_and_add_socket("public", user, oauth_token)
|
||||
Streamer.stream("public", activity)
|
||||
|
||||
assert_receive {:render_with_user, _, _, ^activity}
|
||||
assert_receive {:render_with_user, _, _, ^activity, "public"}
|
||||
refute Streamer.filtered_by_user?(user, activity)
|
||||
end
|
||||
end
|
||||
|
@ -495,7 +504,7 @@ test "it filters messages involving blocked users", %{user: user, token: oauth_t
|
|||
|
||||
Streamer.get_topic_and_add_socket("public", user, oauth_token)
|
||||
{:ok, activity} = CommonAPI.post(blocked_user, %{status: "Test"})
|
||||
assert_receive {:render_with_user, _, _, ^activity}
|
||||
assert_receive {:render_with_user, _, _, ^activity, "public"}
|
||||
assert Streamer.filtered_by_user?(user, activity)
|
||||
end
|
||||
|
||||
|
@ -512,17 +521,17 @@ test "it filters messages transitively involving blocked users", %{
|
|||
|
||||
{:ok, activity_one} = CommonAPI.post(friend, %{status: "hey! @#{blockee.nickname}"})
|
||||
|
||||
assert_receive {:render_with_user, _, _, ^activity_one}
|
||||
assert_receive {:render_with_user, _, _, ^activity_one, "public"}
|
||||
assert Streamer.filtered_by_user?(blocker, activity_one)
|
||||
|
||||
{:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
|
||||
|
||||
assert_receive {:render_with_user, _, _, ^activity_two}
|
||||
assert_receive {:render_with_user, _, _, ^activity_two, "public"}
|
||||
assert Streamer.filtered_by_user?(blocker, activity_two)
|
||||
|
||||
{:ok, activity_three} = CommonAPI.post(blockee, %{status: "hey! @#{blocker.nickname}"})
|
||||
|
||||
assert_receive {:render_with_user, _, _, ^activity_three}
|
||||
assert_receive {:render_with_user, _, _, ^activity_three, "public"}
|
||||
assert Streamer.filtered_by_user?(blocker, activity_three)
|
||||
end
|
||||
end
|
||||
|
@ -583,7 +592,8 @@ test "it sends wanted private posts to list", %{user: user_a, token: user_a_toke
|
|||
visibility: "private"
|
||||
})
|
||||
|
||||
assert_receive {:render_with_user, _, _, ^activity}
|
||||
stream_name = "list:#{list.id}"
|
||||
assert_receive {:render_with_user, _, _, ^activity, ^stream_name}
|
||||
refute Streamer.filtered_by_user?(user_a, activity)
|
||||
end
|
||||
end
|
||||
|
@ -601,7 +611,8 @@ test "it filters muted reblogs", %{user: user1, token: user1_token} do
|
|||
|
||||
Streamer.get_topic_and_add_socket("user", user1, user1_token)
|
||||
{:ok, announce_activity} = CommonAPI.repeat(create_activity.id, user2)
|
||||
assert_receive {:render_with_user, _, _, ^announce_activity}
|
||||
stream_name = "user:#{user1.id}"
|
||||
assert_receive {:render_with_user, _, _, ^announce_activity, ^stream_name}
|
||||
assert Streamer.filtered_by_user?(user1, announce_activity)
|
||||
end
|
||||
|
||||
|
@ -617,7 +628,7 @@ test "it filters reblog notification for reblog-muted actors", %{
|
|||
Streamer.get_topic_and_add_socket("user", user1, user1_token)
|
||||
{:ok, _announce_activity} = CommonAPI.repeat(create_activity.id, user2)
|
||||
|
||||
assert_receive {:render_with_user, _, "notification.json", notif}
|
||||
assert_receive {:render_with_user, _, "notification.json", notif, "user"}
|
||||
assert Streamer.filtered_by_user?(user1, notif)
|
||||
end
|
||||
|
||||
|
@ -633,7 +644,7 @@ test "it send non-reblog notification for reblog-muted actors", %{
|
|||
Streamer.get_topic_and_add_socket("user", user1, user1_token)
|
||||
{:ok, _favorite_activity} = CommonAPI.favorite(user2, create_activity.id)
|
||||
|
||||
assert_receive {:render_with_user, _, "notification.json", notif}
|
||||
assert_receive {:render_with_user, _, "notification.json", notif, "user"}
|
||||
refute Streamer.filtered_by_user?(user1, notif)
|
||||
end
|
||||
end
|
||||
|
@ -648,7 +659,8 @@ test "it filters posts from muted threads" do
|
|||
{:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
|
||||
{:ok, _} = CommonAPI.add_mute(user2, activity)
|
||||
|
||||
assert_receive {:render_with_user, _, _, ^activity}
|
||||
stream_name = "user:#{user2.id}"
|
||||
assert_receive {:render_with_user, _, _, ^activity, ^stream_name}
|
||||
assert Streamer.filtered_by_user?(user2, activity)
|
||||
end
|
||||
end
|
||||
|
@ -690,7 +702,8 @@ test "it doesn't send conversation update to the 'direct' stream when the last m
|
|||
})
|
||||
|
||||
create_activity_id = create_activity.id
|
||||
assert_receive {:render_with_user, _, _, ^create_activity}
|
||||
stream_name = "direct:#{user.id}"
|
||||
assert_receive {:render_with_user, _, _, ^create_activity, ^stream_name}
|
||||
assert_receive {:text, received_conversation1}
|
||||
assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1)
|
||||
|
||||
|
@ -725,8 +738,9 @@ test "it sends conversation update to the 'direct' stream when a message is dele
|
|||
visibility: "direct"
|
||||
})
|
||||
|
||||
assert_receive {:render_with_user, _, _, ^create_activity}
|
||||
assert_receive {:render_with_user, _, _, ^create_activity2}
|
||||
stream_name = "direct:#{user.id}"
|
||||
assert_receive {:render_with_user, _, _, ^create_activity, ^stream_name}
|
||||
assert_receive {:render_with_user, _, _, ^create_activity2, ^stream_name}
|
||||
assert_receive {:text, received_conversation1}
|
||||
assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1)
|
||||
assert_receive {:text, received_conversation1}
|
||||
|
|
Loading…
Reference in a new issue