diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/integration/mastodon_websocket_test.exs | 100 | ||||
| -rw-r--r-- | test/support/websocket_client.ex | 58 | ||||
| -rw-r--r-- | test/tasks/relay_test.exs | 65 | ||||
| -rw-r--r-- | test/tasks/uploads_test.exs | 47 | ||||
| -rw-r--r-- | test/tasks/user_test.exs | 247 | ||||
| -rw-r--r-- | test/user_test.exs | 17 | ||||
| -rw-r--r-- | test/web/mastodon_api/mastodon_api_controller_test.exs | 14 | ||||
| -rw-r--r-- | test/web/mastodon_api/mastodon_socket_test.exs | 31 | ||||
| -rw-r--r-- | test/web/web_finger/web_finger_controller_test.exs | 42 | 
9 files changed, 590 insertions, 31 deletions
| diff --git a/test/integration/mastodon_websocket_test.exs b/test/integration/mastodon_websocket_test.exs new file mode 100644 index 000000000..b5f3d3a47 --- /dev/null +++ b/test/integration/mastodon_websocket_test.exs @@ -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 diff --git a/test/support/websocket_client.ex b/test/support/websocket_client.ex new file mode 100644 index 000000000..57e9bb17f --- /dev/null +++ b/test/support/websocket_client.ex @@ -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 diff --git a/test/tasks/relay_test.exs b/test/tasks/relay_test.exs new file mode 100644 index 000000000..737293865 --- /dev/null +++ b/test/tasks/relay_test.exs @@ -0,0 +1,65 @@ +defmodule Mix.Tasks.Pleroma.RelayTest do +  alias Pleroma.Activity +  alias Pleroma.Web.ActivityPub.{ActivityPub, Relay, Utils} +  alias Pleroma.User +  use Pleroma.DataCase + +  setup_all do +    Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) + +    Mix.shell(Mix.Shell.Process) + +    on_exit(fn -> +      Mix.shell(Mix.Shell.IO) +    end) + +    :ok +  end + +  describe "running follow" do +    test "relay is followed" do +      target_instance = "http://mastodon.example.org/users/admin" + +      Mix.Tasks.Pleroma.Relay.run(["follow", target_instance]) + +      local_user = Relay.get_actor() +      assert local_user.ap_id =~ "/relay" + +      target_user = User.get_by_ap_id(target_instance) +      refute target_user.local + +      activity = Utils.fetch_latest_follow(local_user, target_user) +      assert activity.data["type"] == "Follow" +      assert activity.data["actor"] == local_user.ap_id +      assert activity.data["object"] == target_user.ap_id +    end +  end + +  describe "running unfollow" do +    test "relay is unfollowed" do +      target_instance = "http://mastodon.example.org/users/admin" + +      Mix.Tasks.Pleroma.Relay.run(["follow", target_instance]) + +      %User{ap_id: follower_id} = local_user = Relay.get_actor() +      target_user = User.get_by_ap_id(target_instance) +      follow_activity = Utils.fetch_latest_follow(local_user, target_user) + +      Mix.Tasks.Pleroma.Relay.run(["unfollow", target_instance]) + +      cancelled_activity = Activity.get_by_ap_id(follow_activity.data["id"]) +      assert cancelled_activity.data["state"] == "cancelled" + +      [undo_activity] = +        ActivityPub.fetch_activities([], %{ +          "type" => "Undo", +          "actor_id" => follower_id, +          "limit" => 1 +        }) + +      assert undo_activity.data["type"] == "Undo" +      assert undo_activity.data["actor"] == local_user.ap_id +      assert undo_activity.data["object"] == cancelled_activity.data +    end +  end +end diff --git a/test/tasks/uploads_test.exs b/test/tasks/uploads_test.exs new file mode 100644 index 000000000..a76e96df5 --- /dev/null +++ b/test/tasks/uploads_test.exs @@ -0,0 +1,47 @@ +defmodule Mix.Tasks.Pleroma.UploadsTest do +  alias Pleroma.Upload +  use Pleroma.DataCase + +  import Mock + +  setup_all do +    Mix.shell(Mix.Shell.Process) + +    on_exit(fn -> +      Mix.shell(Mix.Shell.IO) +    end) + +    :ok +  end + +  describe "running migrate_local" do +    test "uploads migrated" do +      with_mock Upload, +        store: fn %Upload{name: _file, path: _path}, _opts -> {:ok, %{}} end do +        Mix.Tasks.Pleroma.Uploads.run(["migrate_local", "S3"]) + +        assert_received {:mix_shell, :info, [message]} +        assert message =~ "Migrating files from local" + +        assert_received {:mix_shell, :info, [message]} + +        assert %{"total_count" => total_count} = +                 Regex.named_captures(~r"^Found (?<total_count>\d+) uploads$", message) + +        assert_received {:mix_shell, :info, [message]} + +        assert %{"count" => ^total_count, "total_count" => ^total_count} = +                 Regex.named_captures( +                   ~r"^Uploaded (?<count>\d+)/(?<total_count>\d+) files$", +                   message +                 ) +      end +    end + +    test "nonexistent uploader" do +      assert_raise RuntimeError, ~r/The uploader .* is not an existing/, fn -> +        Mix.Tasks.Pleroma.Uploads.run(["migrate_local", "nonexistent"]) +      end +    end +  end +end diff --git a/test/tasks/user_test.exs b/test/tasks/user_test.exs new file mode 100644 index 000000000..7479bf749 --- /dev/null +++ b/test/tasks/user_test.exs @@ -0,0 +1,247 @@ +defmodule Mix.Tasks.Pleroma.UserTest do +  alias Pleroma.User +  use Pleroma.DataCase + +  import Pleroma.Factory +  import ExUnit.CaptureIO + +  setup_all do +    Mix.shell(Mix.Shell.Process) + +    on_exit(fn -> +      Mix.shell(Mix.Shell.IO) +    end) + +    :ok +  end + +  describe "running new" do +    test "user is created" do +      # just get random data +      unsaved = build(:user) + +      # prepare to answer yes +      send(self(), {:mix_shell_input, :yes?, true}) + +      Mix.Tasks.Pleroma.User.run([ +        "new", +        unsaved.nickname, +        unsaved.email, +        "--name", +        unsaved.name, +        "--bio", +        unsaved.bio, +        "--password", +        "test", +        "--moderator", +        "--admin" +      ]) + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ "user will be created" + +      assert_received {:mix_shell, :yes?, [message]} +      assert message =~ "Continue" + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ "created" + +      user = User.get_by_nickname(unsaved.nickname) +      assert user.name == unsaved.name +      assert user.email == unsaved.email +      assert user.bio == unsaved.bio +      assert user.info.is_moderator +      assert user.info.is_admin +    end + +    test "user is not created" do +      unsaved = build(:user) + +      # prepare to answer no +      send(self(), {:mix_shell_input, :yes?, false}) + +      Mix.Tasks.Pleroma.User.run(["new", unsaved.nickname, unsaved.email]) + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ "user will be created" + +      assert_received {:mix_shell, :yes?, [message]} +      assert message =~ "Continue" + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ "will not be created" + +      refute User.get_by_nickname(unsaved.nickname) +    end +  end + +  describe "running rm" do +    test "user is deleted" do +      user = insert(:user) + +      Mix.Tasks.Pleroma.User.run(["rm", user.nickname]) + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ " deleted" + +      user = User.get_by_nickname(user.nickname) +      assert user.info.deactivated +    end + +    test "no user to delete" do +      Mix.Tasks.Pleroma.User.run(["rm", "nonexistent"]) + +      assert_received {:mix_shell, :error, [message]} +      assert message =~ "No local user" +    end +  end + +  describe "running toggle_activated" do +    test "user is deactivated" do +      user = insert(:user) + +      Mix.Tasks.Pleroma.User.run(["toggle_activated", user.nickname]) + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ " deactivated" + +      user = User.get_by_nickname(user.nickname) +      assert user.info.deactivated +    end + +    test "user is activated" do +      user = insert(:user, info: %{deactivated: true}) + +      Mix.Tasks.Pleroma.User.run(["toggle_activated", user.nickname]) + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ " activated" + +      user = User.get_by_nickname(user.nickname) +      refute user.info.deactivated +    end + +    test "no user to toggle" do +      Mix.Tasks.Pleroma.User.run(["toggle_activated", "nonexistent"]) + +      assert_received {:mix_shell, :error, [message]} +      assert message =~ "No user" +    end +  end + +  describe "running unsubscribe" do +    test "user is unsubscribed" do +      followed = insert(:user) +      user = insert(:user, %{following: [User.ap_followers(followed)]}) + +      Mix.Tasks.Pleroma.User.run(["unsubscribe", user.nickname]) + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ "Deactivating" + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ "Unsubscribing" + +      # Note that the task has delay :timer.sleep(500) +      assert_received {:mix_shell, :info, [message]} +      assert message =~ "Successfully unsubscribed" + +      user = User.get_by_nickname(user.nickname) +      assert length(user.following) == 0 +      assert user.info.deactivated +    end + +    test "no user to unsubscribe" do +      Mix.Tasks.Pleroma.User.run(["unsubscribe", "nonexistent"]) + +      assert_received {:mix_shell, :error, [message]} +      assert message =~ "No user" +    end +  end + +  describe "running set" do +    test "All statuses set" do +      user = insert(:user) + +      Mix.Tasks.Pleroma.User.run(["set", user.nickname, "--moderator", "--admin", "--locked"]) + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ ~r/Moderator status .* true/ + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ ~r/Locked status .* true/ + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ ~r/Admin status .* true/ + +      user = User.get_by_nickname(user.nickname) +      assert user.info.is_moderator +      assert user.info.locked +      assert user.info.is_admin +    end + +    test "All statuses unset" do +      user = insert(:user, info: %{is_moderator: true, locked: true, is_admin: true}) + +      Mix.Tasks.Pleroma.User.run([ +        "set", +        user.nickname, +        "--no-moderator", +        "--no-admin", +        "--no-locked" +      ]) + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ ~r/Moderator status .* false/ + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ ~r/Locked status .* false/ + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ ~r/Admin status .* false/ + +      user = User.get_by_nickname(user.nickname) +      refute user.info.is_moderator +      refute user.info.locked +      refute user.info.is_admin +    end + +    test "no user to set status" do +      Mix.Tasks.Pleroma.User.run(["set", "nonexistent", "--moderator"]) + +      assert_received {:mix_shell, :error, [message]} +      assert message =~ "No local user" +    end +  end + +  describe "running reset_password" do +    test "password reset token is generated" do +      user = insert(:user) + +      assert capture_io(fn -> +               Mix.Tasks.Pleroma.User.run(["reset_password", user.nickname]) +             end) =~ "URL:" + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ "Generated" +    end + +    test "no user to reset password" do +      Mix.Tasks.Pleroma.User.run(["reset_password", "nonexistent"]) + +      assert_received {:mix_shell, :error, [message]} +      assert message =~ "No local user" +    end +  end + +  describe "running invite" do +    test "invite token is generated" do +      assert capture_io(fn -> +               Mix.Tasks.Pleroma.User.run(["invite"]) +             end) =~ "http" + +      assert_received {:mix_shell, :info, [message]} +      assert message =~ "Generated" +    end +  end +end diff --git a/test/user_test.exs b/test/user_test.exs index 9baa5ef24..1e73770df 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -11,6 +11,23 @@ defmodule Pleroma.UserTest do      :ok    end +  describe "when tags are nil" do +    test "tagging a user" do +      user = insert(:user, %{tags: nil}) +      user = User.tag(user, ["cool", "dude"]) + +      assert "cool" in user.tags +      assert "dude" in user.tags +    end + +    test "untagging a user" do +      user = insert(:user, %{tags: nil}) +      user = User.untag(user, ["cool", "dude"]) + +      assert user.tags == [] +    end +  end +    test "ap_id returns the activity pub id for the user" do      user = UserBuilder.build() diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index e8275d4ab..aec0f851c 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -1415,4 +1415,18 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do      assert result["stats"]["user_count"] == 2      assert result["stats"]["status_count"] == 1    end + +  test "put settings", %{conn: conn} do +    user = insert(:user) + +    conn = +      conn +      |> assign(:user, user) +      |> put("/api/web/settings", %{"data" => %{"programming" => "socks"}}) + +    assert result = json_response(conn, 200) + +    user = User.get_cached_by_ap_id(user.ap_id) +    assert user.info.settings == %{"programming" => "socks"} +  end  end diff --git a/test/web/mastodon_api/mastodon_socket_test.exs b/test/web/mastodon_api/mastodon_socket_test.exs deleted file mode 100644 index 5d9b96861..000000000 --- a/test/web/mastodon_api/mastodon_socket_test.exs +++ /dev/null @@ -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 diff --git a/test/web/web_finger/web_finger_controller_test.exs b/test/web/web_finger/web_finger_controller_test.exs new file mode 100644 index 000000000..844ff51d2 --- /dev/null +++ b/test/web/web_finger/web_finger_controller_test.exs @@ -0,0 +1,42 @@ +defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do +  use Pleroma.Web.ConnCase + +  import Pleroma.Factory +  import Tesla.Mock + +  setup do +    mock(fn env -> apply(HttpRequestMock, :request, [env]) end) +    :ok +  end + +  test "Webfinger JRD" do +    user = insert(:user) + +    response = +      build_conn() +      |> put_req_header("accept", "application/jrd+json") +      |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost") + +    assert json_response(response, 200)["subject"] == "acct:#{user.nickname}@localhost" +  end + +  test "Webfinger XML" do +    user = insert(:user) + +    response = +      build_conn() +      |> put_req_header("accept", "application/xrd+xml") +      |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost") + +    assert response(response, 200) +  end + +  test "Sends a 400 when resource param is missing" do +    response = +      build_conn() +      |> put_req_header("accept", "application/xrd+xml,application/jrd+json") +      |> get("/.well-known/webfinger") + +    assert response(response, 400) +  end +end | 
