Integration tests for mastodon websocket
This commit is contained in:
parent
77b5154c82
commit
b12a904911
6 changed files with 163 additions and 33 deletions
|
@ -4,7 +4,8 @@
|
|||
# you can enable the server option below.
|
||||
config :pleroma, Pleroma.Web.Endpoint,
|
||||
http: [port: 4001],
|
||||
server: false
|
||||
url: [port: 4001],
|
||||
server: true
|
||||
|
||||
# Print only warnings and errors during test
|
||||
config :logger, level: :warn
|
||||
|
|
3
mix.exs
3
mix.exs
|
@ -73,7 +73,8 @@ defp deps do
|
|||
{:ex_doc, "> 0.18.3 and < 0.20.0", only: :dev, runtime: false},
|
||||
{:web_push_encryption, "~> 0.2.1"},
|
||||
{:swoosh, "~> 0.20"},
|
||||
{:gen_smtp, "~> 0.13"}
|
||||
{:gen_smtp, "~> 0.13"},
|
||||
{:websocket_client, git: "https://github.com/jeremyong/websocket_client.git", only: :test}
|
||||
]
|
||||
end
|
||||
|
||||
|
|
1
mix.lock
1
mix.lock
|
@ -59,4 +59,5 @@
|
|||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"},
|
||||
"unsafe": {:hex, :unsafe, "1.0.0", "7c21742cd05380c7875546b023481d3a26f52df8e5dfedcb9f958f322baae305", [:mix], [], "hexpm"},
|
||||
"web_push_encryption": {:hex, :web_push_encryption, "0.2.1", "d42cecf73420d9dc0053ba3299cc8c8d6ff2be2487d67ca2a57265868e4d9a98", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:poison, "~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"websocket_client": {:git, "https://github.com/jeremyong/websocket_client.git", "9a6f65d05ebf2725d62fb19262b21f1805a59fbf", []},
|
||||
}
|
||||
|
|
100
test/integration/mastodon_websocket_test.exs
Normal file
100
test/integration/mastodon_websocket_test.exs
Normal file
|
@ -0,0 +1,100 @@
|
|||
defmodule Pleroma.Integration.MastodonWebsocketTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.OAuth
|
||||
alias Pleroma.Integration.WebsocketClient
|
||||
alias Pleroma.Web.Streamer
|
||||
|
||||
@path Pleroma.Web.Endpoint.url()
|
||||
|> URI.parse()
|
||||
|> Map.put(:scheme, "ws")
|
||||
|> Map.put(:path, "/api/v1/streaming")
|
||||
|> URI.to_string()
|
||||
|
||||
setup do
|
||||
GenServer.start(Streamer, %{}, name: Streamer)
|
||||
|
||||
on_exit(fn ->
|
||||
if pid = Process.whereis(Streamer) do
|
||||
Process.exit(pid, :kill)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
def start_socket(qs \\ nil, headers \\ []) do
|
||||
path =
|
||||
case qs do
|
||||
nil -> @path
|
||||
qs -> @path <> qs
|
||||
end
|
||||
|
||||
WebsocketClient.start_link(self(), path, headers)
|
||||
end
|
||||
|
||||
test "refuses invalid requests" do
|
||||
assert {:error, {400, _}} = start_socket()
|
||||
assert {:error, {404, _}} = start_socket("?stream=ncjdk")
|
||||
end
|
||||
|
||||
test "requires authentication and a valid token for protected streams" do
|
||||
assert {:error, {403, _}} = start_socket("?stream=user&access_token=aaaaaaaaaaaa")
|
||||
assert {:error, {403, _}} = start_socket("?stream=user")
|
||||
end
|
||||
|
||||
test "allows public streams without authentication" do
|
||||
assert {:ok, _} = start_socket("?stream=public")
|
||||
assert {:ok, _} = start_socket("?stream=public:local")
|
||||
assert {:ok, _} = start_socket("?stream=hashtag&tag=lain")
|
||||
end
|
||||
|
||||
test "receives well formatted events" do
|
||||
user = insert(:user)
|
||||
{:ok, _} = start_socket("?stream=public")
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "nice echo chamber"})
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
assert {:ok, json} = Jason.decode(raw_json)
|
||||
|
||||
assert "update" == json["event"]
|
||||
assert json["payload"]
|
||||
assert {:ok, json} = Jason.decode(json["payload"])
|
||||
|
||||
# Note: we remove the "statuses_count" from this result as it changes in the meantime
|
||||
|
||||
view_json =
|
||||
Pleroma.Web.MastodonAPI.StatusView.render("status.json", activity: activity, for: nil)
|
||||
|> Jason.encode!()
|
||||
|> Jason.decode!()
|
||||
|> put_in(["account", "statuses_count"], 0)
|
||||
|
||||
assert json == view_json
|
||||
end
|
||||
|
||||
describe "with a valid user token" do
|
||||
setup do
|
||||
{:ok, app} =
|
||||
Pleroma.Repo.insert(
|
||||
OAuth.App.register_changeset(%OAuth.App{}, %{
|
||||
client_name: "client",
|
||||
scopes: "scope",
|
||||
redirect_uris: "url"
|
||||
})
|
||||
)
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, auth} = OAuth.Authorization.create_authorization(app, user)
|
||||
|
||||
{:ok, token} = OAuth.Token.exchange_token(app, auth)
|
||||
|
||||
%{user: user, token: token}
|
||||
end
|
||||
|
||||
test "accepts valid tokens", state do
|
||||
assert {:ok, _} = start_socket("?stream=user&access_token=#{state.token.token}")
|
||||
end
|
||||
end
|
||||
end
|
58
test/support/websocket_client.ex
Normal file
58
test/support/websocket_client.ex
Normal file
|
@ -0,0 +1,58 @@
|
|||
defmodule Pleroma.Integration.WebsocketClient do
|
||||
# https://github.com/phoenixframework/phoenix/blob/master/test/support/websocket_client.exs
|
||||
|
||||
@doc """
|
||||
Starts the WebSocket server for given ws URL. Received Socket.Message's
|
||||
are forwarded to the sender pid
|
||||
"""
|
||||
def start_link(sender, url, headers \\ []) do
|
||||
:crypto.start()
|
||||
:ssl.start()
|
||||
|
||||
:websocket_client.start_link(
|
||||
String.to_charlist(url),
|
||||
__MODULE__,
|
||||
[sender],
|
||||
extra_headers: headers
|
||||
)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Closes the socket
|
||||
"""
|
||||
def close(socket) do
|
||||
send(socket, :close)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Sends a low-level text message to the client.
|
||||
"""
|
||||
def send_text(server_pid, msg) do
|
||||
send(server_pid, {:text, msg})
|
||||
end
|
||||
|
||||
@doc false
|
||||
def init([sender], _conn_state) do
|
||||
{:ok, %{sender: sender}}
|
||||
end
|
||||
|
||||
@doc false
|
||||
def websocket_handle(frame, _conn_state, state) do
|
||||
send(state.sender, frame)
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
@doc false
|
||||
def websocket_info({:text, msg}, _conn_state, state) do
|
||||
{:reply, {:text, msg}, state}
|
||||
end
|
||||
|
||||
def websocket_info(:close, _conn_state, _state) do
|
||||
{:close, <<>>, "done"}
|
||||
end
|
||||
|
||||
@doc false
|
||||
def websocket_terminate(_reason, _conn_state, _state) do
|
||||
:ok
|
||||
end
|
||||
end
|
|
@ -1,31 +0,0 @@
|
|||
defmodule Pleroma.Web.MastodonApi.MastodonSocketTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Web.{Streamer, CommonAPI}
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
test "public is working when non-authenticated" do
|
||||
user = insert(:user)
|
||||
|
||||
task =
|
||||
Task.async(fn ->
|
||||
assert_receive {:text, _}, 4_000
|
||||
end)
|
||||
|
||||
fake_socket = %{
|
||||
transport_pid: task.pid,
|
||||
assigns: %{}
|
||||
}
|
||||
|
||||
topics = %{
|
||||
"public" => [fake_socket]
|
||||
}
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "Test"})
|
||||
|
||||
Streamer.push_to_socket(topics, "public", activity)
|
||||
|
||||
Task.await(task)
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue