diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/captcha_test.exs | 40 | ||||
| -rw-r--r-- | test/integration/mastodon_websocket_test.exs | 100 | ||||
| -rw-r--r-- | test/support/captcha_mock.ex | 13 | ||||
| -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_socket_test.exs | 31 | ||||
| -rw-r--r-- | test/web/twitter_api/views/activity_view_test.exs | 16 | ||||
| -rw-r--r-- | test/web/web_finger/web_finger_controller_test.exs | 4 | 
11 files changed, 603 insertions, 35 deletions
| diff --git a/test/captcha_test.exs b/test/captcha_test.exs new file mode 100644 index 000000000..54ffbd92f --- /dev/null +++ b/test/captcha_test.exs @@ -0,0 +1,40 @@ +defmodule Pleroma.CaptchaTest do +  use ExUnit.Case + +  import Tesla.Mock + +  alias Pleroma.Captcha.Kocaptcha + +  @ets_options [:ordered_set, :private, :named_table, {:read_concurrency, true}] + +  describe "Kocaptcha" do +    setup do +      ets_name = Kocaptcha.Ets +      ^ets_name = :ets.new(ets_name, @ets_options) + +      mock(fn +        %{method: :get, url: "https://captcha.kotobank.ch/new"} -> +          json(%{ +            md5: "63615261b77f5354fb8c4e4986477555", +            token: "afa1815e14e29355e6c8f6b143a39fa2", +            url: "/captchas/afa1815e14e29355e6c8f6b143a39fa2.png" +          }) +      end) + +      :ok +    end + +    test "new and validate" do +      assert Kocaptcha.new() == %{ +               type: :kocaptcha, +               token: "afa1815e14e29355e6c8f6b143a39fa2", +               url: "https://captcha.kotobank.ch/captchas/afa1815e14e29355e6c8f6b143a39fa2.png" +             } + +      assert Kocaptcha.validate( +               "afa1815e14e29355e6c8f6b143a39fa2", +               "7oEy8c" +             ) +    end +  end +end 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/captcha_mock.ex b/test/support/captcha_mock.ex new file mode 100644 index 000000000..898aa17b8 --- /dev/null +++ b/test/support/captcha_mock.ex @@ -0,0 +1,13 @@ +defmodule Pleroma.Captcha.Mock do +  alias Pleroma.Captcha.Service +  @behaviour Service + +  @impl Service +  def new(), do: %{type: :mock} + +  @impl Service +  def validate(_token, _captcha), do: true + +  @impl Service +  def cleanup(), do: :ok +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_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/twitter_api/views/activity_view_test.exs b/test/web/twitter_api/views/activity_view_test.exs index 77b8d99e7..8aa9e3130 100644 --- a/test/web/twitter_api/views/activity_view_test.exs +++ b/test/web/twitter_api/views/activity_view_test.exs @@ -14,6 +14,22 @@ defmodule Pleroma.Web.TwitterAPI.ActivityViewTest do    import Pleroma.Factory    import Mock +  test "a create activity with a html status" do +    text = """ +    #Bike log - Commute Tuesday\nhttps://pla.bike/posts/20181211/\n#cycling #CHScycling #commute\nMVIMG_20181211_054020.jpg +    """ + +    {:ok, activity} = CommonAPI.post(insert(:user), %{"status" => text}) + +    result = ActivityView.render("activity.json", activity: activity) + +    assert result["statusnet_html"] == +             "<a data-tag=\"bike\" href=\"http://localhost:4001/tag/bike\">#Bike</a> log - Commute Tuesday<br /><a href=\"https://pla.bike/posts/20181211/\">https://pla.bike/posts/20181211/</a><br /><a data-tag=\"cycling\" href=\"http://localhost:4001/tag/cycling\">#cycling</a> <a data-tag=\"chscycling\" href=\"http://localhost:4001/tag/chscycling\">#CHScycling</a> <a data-tag=\"commute\" href=\"http://localhost:4001/tag/commute\">#commute</a><br />MVIMG_20181211_054020.jpg" + +    assert result["text"] == +             "#Bike log - Commute Tuesday\nhttps://pla.bike/posts/20181211/\n#cycling #CHScycling #commute\nMVIMG_20181211_054020.jpg" +  end +    test "a create activity with a note" do      user = insert(:user)      other_user = insert(:user, %{nickname: "shp"}) diff --git a/test/web/web_finger/web_finger_controller_test.exs b/test/web/web_finger/web_finger_controller_test.exs index 3bc878532..844ff51d2 100644 --- a/test/web/web_finger/web_finger_controller_test.exs +++ b/test/web/web_finger/web_finger_controller_test.exs @@ -1,11 +1,7 @@  defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do    use Pleroma.Web.ConnCase -  alias Pleroma.User -  alias Pleroma.Web.WebFinger.WebFingerController -    import Pleroma.Factory -  import ExUnit.CaptureLog    import Tesla.Mock    setup do | 
