diff options
Diffstat (limited to 'test')
40 files changed, 1595 insertions, 379 deletions
diff --git a/test/activity_test.exs b/test/activity_test.exs index 7e91d534b..15c95502a 100644 --- a/test/activity_test.exs +++ b/test/activity_test.exs @@ -6,6 +6,7 @@ defmodule Pleroma.ActivityTest do    use Pleroma.DataCase    alias Pleroma.Activity    alias Pleroma.Bookmark +  alias Pleroma.ThreadMute    import Pleroma.Factory    test "returns an activity by it's AP id" do @@ -47,6 +48,31 @@ defmodule Pleroma.ActivityTest do      assert queried_activity.bookmark == bookmark3    end +  test "setting thread_muted?" do +    activity = insert(:note_activity) +    user = insert(:user) +    annoyed_user = insert(:user) +    {:ok, _} = ThreadMute.add_mute(annoyed_user.id, activity.data["context"]) + +    activity_with_unset_thread_muted_field = +      Ecto.Query.from(Activity) +      |> Repo.one() + +    activity_for_user = +      Ecto.Query.from(Activity) +      |> Activity.with_set_thread_muted_field(user) +      |> Repo.one() + +    activity_for_annoyed_user = +      Ecto.Query.from(Activity) +      |> Activity.with_set_thread_muted_field(annoyed_user) +      |> Repo.one() + +    assert activity_with_unset_thread_muted_field.thread_muted? == nil +    assert activity_for_user.thread_muted? == false +    assert activity_for_annoyed_user.thread_muted? == true +  end +    describe "getting a bookmark" do      test "when association is loaded" do        user = insert(:user) diff --git a/test/conversation_test.exs b/test/conversation_test.exs index 864b2eb03..5903d10ff 100644 --- a/test/conversation_test.exs +++ b/test/conversation_test.exs @@ -11,6 +11,26 @@ defmodule Pleroma.ConversationTest do    import Pleroma.Factory +  test "it goes through old direct conversations" do +    user = insert(:user) +    other_user = insert(:user) + +    {:ok, _activity} = +      CommonAPI.post(user, %{"visibility" => "direct", "status" => "hey @#{other_user.nickname}"}) + +    Repo.delete_all(Conversation) +    Repo.delete_all(Conversation.Participation) + +    refute Repo.one(Conversation) + +    Conversation.bump_for_all_activities() + +    assert Repo.one(Conversation) +    [participation, _p2] = Repo.all(Conversation.Participation) + +    assert participation.read +  end +    test "it creates a conversation for given ap_id" do      assert {:ok, %Conversation{} = conversation} =               Conversation.create_for_ap_id("https://some_ap_id") diff --git a/test/fixtures/rich_media/ogp-missing-data.html b/test/fixtures/rich_media/ogp-missing-data.html new file mode 100644 index 000000000..5746dc2f4 --- /dev/null +++ b/test/fixtures/rich_media/ogp-missing-data.html @@ -0,0 +1,8 @@ +<html prefix="og: http://ogp.me/ns#"> +  <head> +    <title>Pleroma</title> +    <meta property="og:title" content="Pleroma" /> +    <meta property="og:type" content="website" /> +    <meta property="og:url" content="https://pleroma.social/" /> +  </head> +</html> diff --git a/test/fixtures/rich_media/ogp.html b/test/fixtures/rich_media/ogp.html index c886b5871..4b5a33595 100644 --- a/test/fixtures/rich_media/ogp.html +++ b/test/fixtures/rich_media/ogp.html @@ -5,5 +5,6 @@      <meta property="og:type" content="video.movie" />      <meta property="og:url" content="http://www.imdb.com/title/tt0117500/" />      <meta property="og:image" content="http://ia.media-imdb.com/images/rock.jpg" /> +    <meta property="og:description" content="Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.">    </head>  </html> diff --git a/test/fixtures/sound.mp3 b/test/fixtures/sound.mp3 Binary files differnew file mode 100644 index 000000000..9f0f661a3 --- /dev/null +++ b/test/fixtures/sound.mp3 diff --git a/test/formatter_test.exs b/test/formatter_test.exs index 06f4f6e50..bfa673049 100644 --- a/test/formatter_test.exs +++ b/test/formatter_test.exs @@ -125,7 +125,7 @@ defmodule Pleroma.FormatterTest do        archaeme =          insert(:user, %{            nickname: "archa_eme_", -          info: %Pleroma.User.Info{source_data: %{"url" => "https://archeme/@archa_eme_"}} +          info: %User.Info{source_data: %{"url" => "https://archeme/@archa_eme_"}}          })        archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"}) @@ -184,17 +184,19 @@ defmodule Pleroma.FormatterTest do      test "given the 'safe_mention' option, it will only mention people in the beginning" do        user = insert(:user) -      _other_user = insert(:user) +      other_user = insert(:user)        third_user = insert(:user) -      text = " @#{user.nickname} hey dude i hate @#{third_user.nickname}" +      text = " @#{user.nickname} @#{other_user.nickname} hey dudes i hate @#{third_user.nickname}"        {expected_text, mentions, [] = _tags} = Formatter.linkify(text, safe_mention: true) -      assert mentions == [{"@#{user.nickname}", user}] +      assert mentions == [{"@#{user.nickname}", user}, {"@#{other_user.nickname}", other_user}]        assert expected_text ==                 "<span class='h-card'><a data-user='#{user.id}' class='u-url mention' href='#{                   user.ap_id -               }'>@<span>#{user.nickname}</span></a></span> hey dude i hate <span class='h-card'><a data-user='#{ +               }'>@<span>#{user.nickname}</span></a></span> <span class='h-card'><a data-user='#{ +                 other_user.id +               }' class='u-url mention' href='#{other_user.ap_id}'>@<span>#{other_user.nickname}</span></a></span> hey dudes i hate <span class='h-card'><a data-user='#{                   third_user.id                 }' class='u-url mention' href='#{third_user.ap_id}'>@<span>#{third_user.nickname}</span></a></span>"      end @@ -206,6 +208,15 @@ defmodule Pleroma.FormatterTest do        assert mentions == []        assert expected_text == text      end + +    test "given the 'safe_mention' option, it will keep text after newlines" do +      user = insert(:user) +      text = " @#{user.nickname}\n hey dude\n\nhow are you doing?" + +      {expected_text, _, _} = Formatter.linkify(text, safe_mention: true) + +      assert expected_text =~ "how are you doing?" +    end    end    describe ".parse_tags" do diff --git a/test/keys_test.exs b/test/keys_test.exs new file mode 100644 index 000000000..776fdea6f --- /dev/null +++ b/test/keys_test.exs @@ -0,0 +1,20 @@ +defmodule Pleroma.KeysTest do +  use Pleroma.DataCase + +  alias Pleroma.Keys + +  test "generates an RSA private key pem" do +    {:ok, key} = Keys.generate_rsa_pem() + +    assert is_binary(key) +    assert Regex.match?(~r/RSA/, key) +  end + +  test "returns a public and private key from a pem" do +    pem = File.read!("test/fixtures/private_key.pem") +    {:ok, private, public} = Keys.keys_from_pem(pem) + +    assert elem(private, 0) == :RSAPrivateKey +    assert elem(public, 0) == :RSAPublicKey +  end +end diff --git a/test/object/fetcher_test.exs b/test/object/fetcher_test.exs index 72f616782..d604fd5f5 100644 --- a/test/object/fetcher_test.exs +++ b/test/object/fetcher_test.exs @@ -87,4 +87,23 @@ defmodule Pleroma.Object.FetcherTest do          )      end    end + +  describe "pruning" do +    test "it can refetch pruned objects" do +      object_id = "http://mastodon.example.org/@admin/99541947525187367" + +      {:ok, object} = Fetcher.fetch_object_from_id(object_id) + +      assert object + +      {:ok, _object} = Object.prune(object) + +      refute Object.get_by_ap_id(object_id) + +      {:ok, %Object{} = object_two} = Fetcher.fetch_object_from_id(object_id) + +      assert object.data["id"] == object_two.data["id"] +      assert object.id != object_two.id +    end +  end  end diff --git a/test/plugs/cache_control_test.exs b/test/plugs/cache_control_test.exs new file mode 100644 index 000000000..45151b289 --- /dev/null +++ b/test/plugs/cache_control_test.exs @@ -0,0 +1,20 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.CacheControlTest do +  use Pleroma.Web.ConnCase +  alias Plug.Conn + +  test "Verify Cache-Control header on static assets", %{conn: conn} do +    conn = get(conn, "/index.html") + +    assert Conn.get_resp_header(conn, "cache-control") == ["public, no-cache"] +  end + +  test "Verify Cache-Control header on the API", %{conn: conn} do +    conn = get(conn, "/api/v1/instance") + +    assert Conn.get_resp_header(conn, "cache-control") == ["max-age=0, private, must-revalidate"] +  end +end diff --git a/test/plugs/http_security_plug_test.exs b/test/plugs/http_security_plug_test.exs index 0cbb7e4b1..7dfd50c1f 100644 --- a/test/plugs/http_security_plug_test.exs +++ b/test/plugs/http_security_plug_test.exs @@ -7,77 +7,96 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do    alias Pleroma.Config    alias Plug.Conn -  test "it sends CSP headers when enabled", %{conn: conn} do -    Config.put([:http_security, :enabled], true) - -    conn = -      conn -      |> get("/api/v1/instance") - -    refute Conn.get_resp_header(conn, "x-xss-protection") == [] -    refute Conn.get_resp_header(conn, "x-permitted-cross-domain-policies") == [] -    refute Conn.get_resp_header(conn, "x-frame-options") == [] -    refute Conn.get_resp_header(conn, "x-content-type-options") == [] -    refute Conn.get_resp_header(conn, "x-download-options") == [] -    refute Conn.get_resp_header(conn, "referrer-policy") == [] -    refute Conn.get_resp_header(conn, "content-security-policy") == [] -  end +  describe "http security enabled" do +    setup do +      enabled = Config.get([:http_securiy, :enabled]) -  test "it does not send CSP headers when disabled", %{conn: conn} do -    Config.put([:http_security, :enabled], false) +      Config.put([:http_security, :enabled], true) -    conn = -      conn -      |> get("/api/v1/instance") +      on_exit(fn -> +        Config.put([:http_security, :enabled], enabled) +      end) -    assert Conn.get_resp_header(conn, "x-xss-protection") == [] -    assert Conn.get_resp_header(conn, "x-permitted-cross-domain-policies") == [] -    assert Conn.get_resp_header(conn, "x-frame-options") == [] -    assert Conn.get_resp_header(conn, "x-content-type-options") == [] -    assert Conn.get_resp_header(conn, "x-download-options") == [] -    assert Conn.get_resp_header(conn, "referrer-policy") == [] -    assert Conn.get_resp_header(conn, "content-security-policy") == [] -  end +      :ok +    end -  test "it sends STS headers when enabled", %{conn: conn} do -    Config.put([:http_security, :enabled], true) -    Config.put([:http_security, :sts], true) +    test "it sends CSP headers when enabled", %{conn: conn} do +      conn = get(conn, "/api/v1/instance") -    conn = -      conn -      |> get("/api/v1/instance") +      refute Conn.get_resp_header(conn, "x-xss-protection") == [] +      refute Conn.get_resp_header(conn, "x-permitted-cross-domain-policies") == [] +      refute Conn.get_resp_header(conn, "x-frame-options") == [] +      refute Conn.get_resp_header(conn, "x-content-type-options") == [] +      refute Conn.get_resp_header(conn, "x-download-options") == [] +      refute Conn.get_resp_header(conn, "referrer-policy") == [] +      refute Conn.get_resp_header(conn, "content-security-policy") == [] +    end -    refute Conn.get_resp_header(conn, "strict-transport-security") == [] -    refute Conn.get_resp_header(conn, "expect-ct") == [] -  end +    test "it sends STS headers when enabled", %{conn: conn} do +      Config.put([:http_security, :sts], true) -  test "it does not send STS headers when disabled", %{conn: conn} do -    Config.put([:http_security, :enabled], true) -    Config.put([:http_security, :sts], false) +      conn = get(conn, "/api/v1/instance") -    conn = -      conn -      |> get("/api/v1/instance") +      refute Conn.get_resp_header(conn, "strict-transport-security") == [] +      refute Conn.get_resp_header(conn, "expect-ct") == [] +    end -    assert Conn.get_resp_header(conn, "strict-transport-security") == [] -    assert Conn.get_resp_header(conn, "expect-ct") == [] -  end +    test "it does not send STS headers when disabled", %{conn: conn} do +      Config.put([:http_security, :sts], false) + +      conn = get(conn, "/api/v1/instance") + +      assert Conn.get_resp_header(conn, "strict-transport-security") == [] +      assert Conn.get_resp_header(conn, "expect-ct") == [] +    end + +    test "referrer-policy header reflects configured value", %{conn: conn} do +      conn = get(conn, "/api/v1/instance") + +      assert Conn.get_resp_header(conn, "referrer-policy") == ["same-origin"] -  test "referrer-policy header reflects configured value", %{conn: conn} do -    Config.put([:http_security, :enabled], true) +      Config.put([:http_security, :referrer_policy], "no-referrer") -    conn = -      conn -      |> get("/api/v1/instance") +      conn = +        build_conn() +        |> get("/api/v1/instance") -    assert Conn.get_resp_header(conn, "referrer-policy") == ["same-origin"] +      assert Conn.get_resp_header(conn, "referrer-policy") == ["no-referrer"] +    end -    Config.put([:http_security, :referrer_policy], "no-referrer") +    test "it sends `report-to` & `report-uri` CSP response headers" do +      conn = +        build_conn() +        |> get("/api/v1/instance") -    conn = -      build_conn() -      |> get("/api/v1/instance") +      [csp] = Conn.get_resp_header(conn, "content-security-policy") -    assert Conn.get_resp_header(conn, "referrer-policy") == ["no-referrer"] +      assert csp =~ ~r|report-uri https://endpoint.com; report-to csp-endpoint;| + +      [reply_to] = Conn.get_resp_header(conn, "reply-to") + +      assert reply_to == +               "{\"endpoints\":[{\"url\":\"https://endpoint.com\"}],\"group\":\"csp-endpoint\",\"max-age\":10886400}" +    end +  end + +  test "it does not send CSP headers when disabled", %{conn: conn} do +    enabled = Config.get([:http_securiy, :enabled]) + +    Config.put([:http_security, :enabled], false) + +    on_exit(fn -> +      Config.put([:http_security, :enabled], enabled) +    end) + +    conn = get(conn, "/api/v1/instance") + +    assert Conn.get_resp_header(conn, "x-xss-protection") == [] +    assert Conn.get_resp_header(conn, "x-permitted-cross-domain-policies") == [] +    assert Conn.get_resp_header(conn, "x-frame-options") == [] +    assert Conn.get_resp_header(conn, "x-content-type-options") == [] +    assert Conn.get_resp_header(conn, "x-download-options") == [] +    assert Conn.get_resp_header(conn, "referrer-policy") == [] +    assert Conn.get_resp_header(conn, "content-security-policy") == []    end  end diff --git a/test/plugs/legacy_authentication_plug_test.exs b/test/plugs/legacy_authentication_plug_test.exs index 8b0b06772..02f530058 100644 --- a/test/plugs/legacy_authentication_plug_test.exs +++ b/test/plugs/legacy_authentication_plug_test.exs @@ -3,7 +3,7 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Pleroma.Plugs.LegacyAuthenticationPlugTest do -  use Pleroma.Web.ConnCase, async: true +  use Pleroma.Web.ConnCase    alias Pleroma.Plugs.LegacyAuthenticationPlug    alias Pleroma.User diff --git a/test/repo_test.exs b/test/repo_test.exs index 5382289c7..85085a1fa 100644 --- a/test/repo_test.exs +++ b/test/repo_test.exs @@ -1,23 +1,24 @@  defmodule Pleroma.RepoTest do    use Pleroma.DataCase    import Pleroma.Factory +  alias Pleroma.User    describe "find_resource/1" do      test "returns user" do        user = insert(:user) -      query = from(t in Pleroma.User, where: t.id == ^user.id) +      query = from(t in User, where: t.id == ^user.id)        assert Repo.find_resource(query) == {:ok, user}      end      test "returns not_found" do -      query = from(t in Pleroma.User, where: t.id == ^"9gBuXNpD2NyDmmxxdw") +      query = from(t in User, where: t.id == ^"9gBuXNpD2NyDmmxxdw")        assert Repo.find_resource(query) == {:error, :not_found}      end    end    describe "get_assoc/2" do      test "get assoc from preloaded data" do -      user = %Pleroma.User{name: "Agent Smith"} +      user = %User{name: "Agent Smith"}        token = %Pleroma.Web.OAuth.Token{insert(:oauth_token) | user: user}        assert Repo.get_assoc(token, :user) == {:ok, user}      end diff --git a/test/support/factory.ex b/test/support/factory.ex index 2a2954ad6..be6247ca4 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -4,6 +4,7 @@  defmodule Pleroma.Factory do    use ExMachina.Ecto, repo: Pleroma.Repo +  alias Pleroma.User    def participation_factory do      conversation = insert(:conversation) @@ -23,7 +24,7 @@ defmodule Pleroma.Factory do    end    def user_factory do -    user = %Pleroma.User{ +    user = %User{        name: sequence(:name, &"Test テスト User #{&1}"),        email: sequence(:email, &"user#{&1}@example.com"),        nickname: sequence(:nickname, &"nick#{&1}"), @@ -34,16 +35,16 @@ defmodule Pleroma.Factory do      %{        user -      | ap_id: Pleroma.User.ap_id(user), -        follower_address: Pleroma.User.ap_followers(user), -        following: [Pleroma.User.ap_id(user)] +      | ap_id: User.ap_id(user), +        follower_address: User.ap_followers(user), +        following: [User.ap_id(user)]      }    end    def note_factory(attrs \\ %{}) do      text = sequence(:text, &"This is :moominmamma: note #{&1}") -    user = insert(:user) +    user = attrs[:user] || insert(:user)      data = %{        "type" => "Note", @@ -113,7 +114,8 @@ defmodule Pleroma.Factory do    end    def note_activity_factory(attrs \\ %{}) do -    note = attrs[:note] || insert(:note) +    user = attrs[:user] || insert(:user) +    note = attrs[:note] || insert(:note, user: user)      data = %{        "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(), diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex index 5b355bfe6..66d7d5ba9 100644 --- a/test/support/http_request_mock.ex +++ b/test/support/http_request_mock.ex @@ -728,6 +728,14 @@ defmodule HttpRequestMock do      {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}}    end +  def get("http://example.com/ogp-missing-data", _, _, _) do +    {:ok, +     %Tesla.Env{ +       status: 200, +       body: File.read!("test/fixtures/rich_media/ogp-missing-data.html") +     }} +  end +    def get("http://example.com/malformed", _, _, _) do      {:ok,       %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/malformed-data.html")}} diff --git a/test/support/ostatus_mock.ex b/test/support/ostatus_mock.ex deleted file mode 100644 index 9c0f2f323..000000000 --- a/test/support/ostatus_mock.ex +++ /dev/null @@ -1,11 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.OStatusMock do -  import Pleroma.Factory - -  def handle_incoming(_doc) do -    insert(:note_activity) -  end -end diff --git a/test/support/websub_mock.ex b/test/support/websub_mock.ex deleted file mode 100644 index e3d5a5b16..000000000 --- a/test/support/websub_mock.ex +++ /dev/null @@ -1,9 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.WebsubMock do -  def verify(sub) do -    {:ok, sub} -  end -end diff --git a/test/tasks/database_test.exs b/test/tasks/database_test.exs new file mode 100644 index 000000000..579130b05 --- /dev/null +++ b/test/tasks/database_test.exs @@ -0,0 +1,49 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Mix.Tasks.Pleroma.DatabaseTest do +  alias Pleroma.Repo +  alias Pleroma.User +  use Pleroma.DataCase + +  import Pleroma.Factory + +  setup_all do +    Mix.shell(Mix.Shell.Process) + +    on_exit(fn -> +      Mix.shell(Mix.Shell.IO) +    end) + +    :ok +  end + +  describe "running update_users_following_followers_counts" do +    test "following and followers count are updated" do +      [user, user2] = insert_pair(:user) +      {:ok, %User{following: following, info: info} = user} = User.follow(user, user2) + +      assert length(following) == 2 +      assert info.follower_count == 0 + +      info_cng = Ecto.Changeset.change(info, %{follower_count: 3}) + +      {:ok, user} = +        user +        |> Ecto.Changeset.change(%{following: following ++ following}) +        |> Ecto.Changeset.put_embed(:info, info_cng) +        |> Repo.update() + +      assert length(user.following) == 4 +      assert user.info.follower_count == 3 + +      assert :ok == Mix.Tasks.Pleroma.Database.run(["update_users_following_followers_counts"]) + +      user = User.get_by_id(user.id) + +      assert length(user.following) == 2 +      assert user.info.follower_count == 0 +    end +  end +end diff --git a/test/tasks/user_test.exs b/test/tasks/user_test.exs index eaf4ecf84..260ce0d95 100644 --- a/test/tasks/user_test.exs +++ b/test/tasks/user_test.exs @@ -3,6 +3,7 @@  # SPDX-License-Identifier: AGPL-3.0-only  defmodule Mix.Tasks.Pleroma.UserTest do +  alias Pleroma.Repo    alias Pleroma.User    use Pleroma.DataCase @@ -338,4 +339,31 @@ defmodule Mix.Tasks.Pleroma.UserTest do        assert message == "User #{nickname} statuses deleted."      end    end + +  describe "running toggle_confirmed" do +    test "user is confirmed" do +      %{id: id, nickname: nickname} = insert(:user, info: %{confirmation_pending: false}) + +      assert :ok = Mix.Tasks.Pleroma.User.run(["toggle_confirmed", nickname]) +      assert_received {:mix_shell, :info, [message]} +      assert message == "#{nickname} needs confirmation." + +      user = Repo.get(User, id) +      assert user.info.confirmation_pending +      assert user.info.confirmation_token +    end + +    test "user is not confirmed" do +      %{id: id, nickname: nickname} = +        insert(:user, info: %{confirmation_pending: true, confirmation_token: "some token"}) + +      assert :ok = Mix.Tasks.Pleroma.User.run(["toggle_confirmed", nickname]) +      assert_received {:mix_shell, :info, [message]} +      assert message == "#{nickname} doesn't need confirmation." + +      user = Repo.get(User, id) +      refute user.info.confirmation_pending +      refute user.info.confirmation_token +    end +  end  end diff --git a/test/user_test.exs b/test/user_test.exs index 0b65e89e9..019f2b56d 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -277,7 +277,7 @@ defmodule Pleroma.UserTest do      end      test "it restricts certain nicknames" do -      [restricted_name | _] = Pleroma.Config.get([Pleroma.User, :restricted_nicknames]) +      [restricted_name | _] = Pleroma.Config.get([User, :restricted_nicknames])        assert is_bitstring(restricted_name) @@ -626,6 +626,37 @@ defmodule Pleroma.UserTest do      end    end +  describe "remove duplicates from following list" do +    test "it removes duplicates" do +      user = insert(:user) +      follower = insert(:user) + +      {:ok, %User{following: following} = follower} = User.follow(follower, user) +      assert length(following) == 2 + +      {:ok, follower} = +        follower +        |> User.update_changeset(%{following: following ++ following}) +        |> Repo.update() + +      assert length(follower.following) == 4 + +      {:ok, follower} = User.remove_duplicated_following(follower) +      assert length(follower.following) == 2 +    end + +    test "it does nothing when following is uniq" do +      user = insert(:user) +      follower = insert(:user) + +      {:ok, follower} = User.follow(follower, user) +      assert length(follower.following) == 2 + +      {:ok, follower} = User.remove_duplicated_following(follower) +      assert length(follower.following) == 2 +    end +  end +    describe "follow_import" do      test "it imports user followings from list" do        [user1, user2, user3] = insert_list(3, :user) @@ -871,9 +902,8 @@ defmodule Pleroma.UserTest do        assert [activity] == ActivityPub.fetch_public_activities(%{}) |> Repo.preload(:bookmark) -      assert [activity] == +      assert [%{activity | thread_muted?: CommonAPI.thread_muted?(user2, activity)}] ==                 ActivityPub.fetch_activities([user2.ap_id | user2.following], %{"user" => user2}) -               |> ActivityPub.contain_timeline(user2)        {:ok, _user} = User.deactivate(user) @@ -882,7 +912,6 @@ defmodule Pleroma.UserTest do        assert [] ==                 ActivityPub.fetch_activities([user2.ap_id | user2.following], %{"user" => user2}) -               |> ActivityPub.contain_timeline(user2)      end    end @@ -1194,14 +1223,47 @@ defmodule Pleroma.UserTest do      follower2 = insert(:user)      follower3 = insert(:user) -    {:ok, follower} = Pleroma.User.follow(follower, user) -    {:ok, _follower2} = Pleroma.User.follow(follower2, user) -    {:ok, _follower3} = Pleroma.User.follow(follower3, user) +    {:ok, follower} = User.follow(follower, user) +    {:ok, _follower2} = User.follow(follower2, user) +    {:ok, _follower3} = User.follow(follower3, user) -    {:ok, _} = Pleroma.User.block(user, follower) +    {:ok, _} = User.block(user, follower)      user_show = Pleroma.Web.TwitterAPI.UserView.render("show.json", %{user: user})      assert Map.get(user_show, "followers_count") == 2    end + +  describe "toggle_confirmation/1" do +    test "if user is confirmed" do +      user = insert(:user, info: %{confirmation_pending: false}) +      {:ok, user} = User.toggle_confirmation(user) + +      assert user.info.confirmation_pending +      assert user.info.confirmation_token +    end + +    test "if user is unconfirmed" do +      user = insert(:user, info: %{confirmation_pending: true, confirmation_token: "some token"}) +      {:ok, user} = User.toggle_confirmation(user) + +      refute user.info.confirmation_pending +      refute user.info.confirmation_token +    end +  end + +  describe "ensure_keys_present" do +    test "it creates keys for a user and stores them in info" do +      user = insert(:user) +      refute is_binary(user.info.keys) +      {:ok, user} = User.ensure_keys_present(user) +      assert is_binary(user.info.keys) +    end + +    test "it doesn't create keys if there already are some" do +      user = insert(:user, %{info: %{keys: "xxx"}}) +      {:ok, user} = User.ensure_keys_present(user) +      assert user.info.keys == "xxx" +    end +  end  end diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index 0f90aa1ac..76586ee4a 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -462,6 +462,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do      refute Enum.member?(activities, activity_three.id)    end +  test "doesn't return activities from blocked domains" do +    domain = "dogwhistle.zone" +    domain_user = insert(:user, %{ap_id: "https://#{domain}/@pundit"}) +    note = insert(:note, %{data: %{"actor" => domain_user.ap_id}}) +    activity = insert(:note_activity, %{note: note}) +    user = insert(:user) +    {:ok, user} = User.block_domain(user, domain) + +    activities = +      ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true}) + +    refute activity in activities + +    followed_user = insert(:user) +    ActivityPub.follow(user, followed_user) +    {:ok, repeat_activity, _} = CommonAPI.repeat(activity.id, followed_user) + +    activities = +      ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true}) + +    refute repeat_activity in activities +  end +    test "doesn't return muted activities" do      activity_one = insert(:note_activity)      activity_two = insert(:note_activity) @@ -960,17 +983,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do            "in_reply_to_status_id" => private_activity_2.id          }) -      activities = ActivityPub.fetch_activities([user1.ap_id | user1.following]) +      activities = +        ActivityPub.fetch_activities([user1.ap_id | user1.following]) +        |> Enum.map(fn a -> a.id end)        private_activity_1 = Activity.get_by_ap_id_with_object(private_activity_1.data["id"]) -      assert [public_activity, private_activity_1, private_activity_3] == activities +      assert [public_activity.id, private_activity_1.id, private_activity_3.id] == activities        assert length(activities) == 3 -      activities = ActivityPub.contain_timeline(activities, user1) +      activities = +        ActivityPub.fetch_activities([user1.ap_id | user1.following], %{"user" => user1}) +        |> Enum.map(fn a -> a.id end) -      assert [public_activity, private_activity_1] == activities +      assert [public_activity.id, private_activity_1.id] == activities        assert length(activities) == 2      end    end @@ -978,7 +1005,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do    describe "update" do      test "it creates an update activity with the new user data" do        user = insert(:user) -      {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) +      {:ok, user} = User.ensure_keys_present(user)        user_data = Pleroma.Web.ActivityPub.UserView.render("user.json", %{user: user})        {:ok, update} = @@ -1159,4 +1186,33 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do    def data_uri do      File.read!("test/fixtures/avatar_data_uri")    end + +  describe "fetch_activities_bounded" do +    test "fetches private posts for followed users" do +      user = insert(:user) + +      {:ok, activity} = +        CommonAPI.post(user, %{ +          "status" => "thought I looked cute might delete later :3", +          "visibility" => "private" +        }) + +      [result] = ActivityPub.fetch_activities_bounded([user.follower_address], []) +      assert result.id == activity.id +    end + +    test "fetches only public posts for other users" do +      user = insert(:user) +      {:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe", "visibility" => "public"}) + +      {:ok, _private_activity} = +        CommonAPI.post(user, %{ +          "status" => "why is tenshi eating a corndog so cute?", +          "visibility" => "private" +        }) + +      [result] = ActivityPub.fetch_activities_bounded([], [user.follower_address]) +      assert result.id == activity.id +    end +  end  end diff --git a/test/web/activity_pub/mrf/simple_policy_test.exs b/test/web/activity_pub/mrf/simple_policy_test.exs new file mode 100644 index 000000000..0fd68e103 --- /dev/null +++ b/test/web/activity_pub/mrf/simple_policy_test.exs @@ -0,0 +1,309 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do +  use Pleroma.DataCase +  import Pleroma.Factory +  alias Pleroma.Config +  alias Pleroma.Web.ActivityPub.MRF.SimplePolicy + +  setup do +    orig = Config.get!(:mrf_simple) + +    Config.put(:mrf_simple, +      media_removal: [], +      media_nsfw: [], +      federated_timeline_removal: [], +      report_removal: [], +      reject: [], +      accept: [], +      avatar_removal: [], +      banner_removal: [] +    ) + +    on_exit(fn -> +      Config.put(:mrf_simple, orig) +    end) +  end + +  describe "when :media_removal" do +    test "is empty" do +      Config.put([:mrf_simple, :media_removal], []) +      media_message = build_media_message() +      local_message = build_local_message() + +      assert SimplePolicy.filter(media_message) == {:ok, media_message} +      assert SimplePolicy.filter(local_message) == {:ok, local_message} +    end + +    test "has a matching host" do +      Config.put([:mrf_simple, :media_removal], ["remote.instance"]) +      media_message = build_media_message() +      local_message = build_local_message() + +      assert SimplePolicy.filter(media_message) == +               {:ok, +                media_message +                |> Map.put("object", Map.delete(media_message["object"], "attachment"))} + +      assert SimplePolicy.filter(local_message) == {:ok, local_message} +    end +  end + +  describe "when :media_nsfw" do +    test "is empty" do +      Config.put([:mrf_simple, :media_nsfw], []) +      media_message = build_media_message() +      local_message = build_local_message() + +      assert SimplePolicy.filter(media_message) == {:ok, media_message} +      assert SimplePolicy.filter(local_message) == {:ok, local_message} +    end + +    test "has a matching host" do +      Config.put([:mrf_simple, :media_nsfw], ["remote.instance"]) +      media_message = build_media_message() +      local_message = build_local_message() + +      assert SimplePolicy.filter(media_message) == +               {:ok, +                media_message +                |> put_in(["object", "tag"], ["foo", "nsfw"]) +                |> put_in(["object", "sensitive"], true)} + +      assert SimplePolicy.filter(local_message) == {:ok, local_message} +    end +  end + +  defp build_media_message do +    %{ +      "actor" => "https://remote.instance/users/bob", +      "type" => "Create", +      "object" => %{ +        "attachment" => [%{}], +        "tag" => ["foo"], +        "sensitive" => false +      } +    } +  end + +  describe "when :report_removal" do +    test "is empty" do +      Config.put([:mrf_simple, :report_removal], []) +      report_message = build_report_message() +      local_message = build_local_message() + +      assert SimplePolicy.filter(report_message) == {:ok, report_message} +      assert SimplePolicy.filter(local_message) == {:ok, local_message} +    end + +    test "has a matching host" do +      Config.put([:mrf_simple, :report_removal], ["remote.instance"]) +      report_message = build_report_message() +      local_message = build_local_message() + +      assert SimplePolicy.filter(report_message) == {:reject, nil} +      assert SimplePolicy.filter(local_message) == {:ok, local_message} +    end +  end + +  defp build_report_message do +    %{ +      "actor" => "https://remote.instance/users/bob", +      "type" => "Flag" +    } +  end + +  describe "when :federated_timeline_removal" do +    test "is empty" do +      Config.put([:mrf_simple, :federated_timeline_removal], []) +      {_, ftl_message} = build_ftl_actor_and_message() +      local_message = build_local_message() + +      assert SimplePolicy.filter(ftl_message) == {:ok, ftl_message} +      assert SimplePolicy.filter(local_message) == {:ok, local_message} +    end + +    test "has a matching host" do +      {actor, ftl_message} = build_ftl_actor_and_message() + +      ftl_message_actor_host = +        ftl_message +        |> Map.fetch!("actor") +        |> URI.parse() +        |> Map.fetch!(:host) + +      Config.put([:mrf_simple, :federated_timeline_removal], [ftl_message_actor_host]) +      local_message = build_local_message() + +      assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message) +      assert actor.follower_address in ftl_message["to"] +      refute actor.follower_address in ftl_message["cc"] +      refute "https://www.w3.org/ns/activitystreams#Public" in ftl_message["to"] +      assert "https://www.w3.org/ns/activitystreams#Public" in ftl_message["cc"] + +      assert SimplePolicy.filter(local_message) == {:ok, local_message} +    end + +    test "has a matching host but only as:Public in to" do +      {_actor, ftl_message} = build_ftl_actor_and_message() + +      ftl_message_actor_host = +        ftl_message +        |> Map.fetch!("actor") +        |> URI.parse() +        |> Map.fetch!(:host) + +      ftl_message = Map.put(ftl_message, "cc", []) + +      Config.put([:mrf_simple, :federated_timeline_removal], [ftl_message_actor_host]) + +      assert {:ok, ftl_message} = SimplePolicy.filter(ftl_message) +      refute "https://www.w3.org/ns/activitystreams#Public" in ftl_message["to"] +      assert "https://www.w3.org/ns/activitystreams#Public" in ftl_message["cc"] +    end +  end + +  defp build_ftl_actor_and_message do +    actor = insert(:user) + +    {actor, +     %{ +       "actor" => actor.ap_id, +       "to" => ["https://www.w3.org/ns/activitystreams#Public", "http://foo.bar/baz"], +       "cc" => [actor.follower_address, "http://foo.bar/qux"] +     }} +  end + +  describe "when :reject" do +    test "is empty" do +      Config.put([:mrf_simple, :reject], []) + +      remote_message = build_remote_message() + +      assert SimplePolicy.filter(remote_message) == {:ok, remote_message} +    end + +    test "has a matching host" do +      Config.put([:mrf_simple, :reject], ["remote.instance"]) + +      remote_message = build_remote_message() + +      assert SimplePolicy.filter(remote_message) == {:reject, nil} +    end +  end + +  describe "when :accept" do +    test "is empty" do +      Config.put([:mrf_simple, :accept], []) + +      local_message = build_local_message() +      remote_message = build_remote_message() + +      assert SimplePolicy.filter(local_message) == {:ok, local_message} +      assert SimplePolicy.filter(remote_message) == {:ok, remote_message} +    end + +    test "is not empty but it doesn't have a matching host" do +      Config.put([:mrf_simple, :accept], ["non.matching.remote"]) + +      local_message = build_local_message() +      remote_message = build_remote_message() + +      assert SimplePolicy.filter(local_message) == {:ok, local_message} +      assert SimplePolicy.filter(remote_message) == {:reject, nil} +    end + +    test "has a matching host" do +      Config.put([:mrf_simple, :accept], ["remote.instance"]) + +      local_message = build_local_message() +      remote_message = build_remote_message() + +      assert SimplePolicy.filter(local_message) == {:ok, local_message} +      assert SimplePolicy.filter(remote_message) == {:ok, remote_message} +    end +  end + +  describe "when :avatar_removal" do +    test "is empty" do +      Config.put([:mrf_simple, :avatar_removal], []) + +      remote_user = build_remote_user() + +      assert SimplePolicy.filter(remote_user) == {:ok, remote_user} +    end + +    test "is not empty but it doesn't have a matching host" do +      Config.put([:mrf_simple, :avatar_removal], ["non.matching.remote"]) + +      remote_user = build_remote_user() + +      assert SimplePolicy.filter(remote_user) == {:ok, remote_user} +    end + +    test "has a matching host" do +      Config.put([:mrf_simple, :avatar_removal], ["remote.instance"]) + +      remote_user = build_remote_user() +      {:ok, filtered} = SimplePolicy.filter(remote_user) + +      refute filtered["icon"] +    end +  end + +  describe "when :banner_removal" do +    test "is empty" do +      Config.put([:mrf_simple, :banner_removal], []) + +      remote_user = build_remote_user() + +      assert SimplePolicy.filter(remote_user) == {:ok, remote_user} +    end + +    test "is not empty but it doesn't have a matching host" do +      Config.put([:mrf_simple, :banner_removal], ["non.matching.remote"]) + +      remote_user = build_remote_user() + +      assert SimplePolicy.filter(remote_user) == {:ok, remote_user} +    end + +    test "has a matching host" do +      Config.put([:mrf_simple, :banner_removal], ["remote.instance"]) + +      remote_user = build_remote_user() +      {:ok, filtered} = SimplePolicy.filter(remote_user) + +      refute filtered["image"] +    end +  end + +  defp build_local_message do +    %{ +      "actor" => "#{Pleroma.Web.base_url()}/users/alice", +      "to" => [], +      "cc" => [] +    } +  end + +  defp build_remote_message do +    %{"actor" => "https://remote.instance/users/bob"} +  end + +  defp build_remote_user do +    %{ +      "id" => "https://remote.instance/users/bob", +      "icon" => %{ +        "url" => "http://example.com/image.jpg", +        "type" => "Image" +      }, +      "image" => %{ +        "url" => "http://example.com/image.jpg", +        "type" => "Image" +      }, +      "type" => "Person" +    } +  end +end diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index c24b50f8c..ee71de8d0 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -1209,4 +1209,44 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        {:ok, _} = Transmogrifier.prepare_outgoing(activity.data)      end    end + +  describe "fix_explicit_addressing" do +    test "moves non-explicitly mentioned actors to cc" do +      user = insert(:user) + +      explicitly_mentioned_actors = [ +        "https://pleroma.gold/users/user1", +        "https://pleroma.gold/user2" +      ] + +      object = %{ +        "actor" => user.ap_id, +        "to" => explicitly_mentioned_actors ++ ["https://social.beepboop.ga/users/dirb"], +        "cc" => [], +        "tag" => +          Enum.map(explicitly_mentioned_actors, fn href -> +            %{"type" => "Mention", "href" => href} +          end) +      } + +      fixed_object = Transmogrifier.fix_explicit_addressing(object) +      assert Enum.all?(explicitly_mentioned_actors, &(&1 in fixed_object["to"])) +      refute "https://social.beepboop.ga/users/dirb" in fixed_object["to"] +      assert "https://social.beepboop.ga/users/dirb" in fixed_object["cc"] +    end + +    test "does not move actor's follower collection to cc" do +      user = insert(:user) + +      object = %{ +        "actor" => user.ap_id, +        "to" => [user.follower_address], +        "cc" => [] +      } + +      fixed_object = Transmogrifier.fix_explicit_addressing(object) +      assert user.follower_address in fixed_object["to"] +      refute user.follower_address in fixed_object["cc"] +    end +  end  end diff --git a/test/web/activity_pub/views/user_view_test.exs b/test/web/activity_pub/views/user_view_test.exs index 9fb9455d2..e6483db8b 100644 --- a/test/web/activity_pub/views/user_view_test.exs +++ b/test/web/activity_pub/views/user_view_test.exs @@ -2,11 +2,12 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do    use Pleroma.DataCase    import Pleroma.Factory +  alias Pleroma.User    alias Pleroma.Web.ActivityPub.UserView    test "Renders a user, including the public key" do      user = insert(:user) -    {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) +    {:ok, user} = User.ensure_keys_present(user)      result = UserView.render("user.json", %{user: user}) @@ -18,7 +19,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do    test "Does not add an avatar image if the user hasn't set one" do      user = insert(:user) -    {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) +    {:ok, user} = User.ensure_keys_present(user)      result = UserView.render("user.json", %{user: user})      refute result["icon"] @@ -32,7 +33,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do          }        ) -    {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) +    {:ok, user} = User.ensure_keys_present(user)      result = UserView.render("user.json", %{user: user})      assert result["icon"]["url"] == "https://someurl" @@ -42,7 +43,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do    describe "endpoints" do      test "local users have a usable endpoints structure" do        user = insert(:user) -      {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) +      {:ok, user} = User.ensure_keys_present(user)        result = UserView.render("user.json", %{user: user}) @@ -58,7 +59,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do      test "remote users have an empty endpoints structure" do        user = insert(:user, local: false) -      {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) +      {:ok, user} = User.ensure_keys_present(user)        result = UserView.render("user.json", %{user: user}) @@ -68,7 +69,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do      test "instance users do not expose oAuth endpoints" do        user = insert(:user, nickname: nil, local: true) -      {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) +      {:ok, user} = User.ensure_keys_present(user)        result = UserView.render("user.json", %{user: user}) diff --git a/test/web/activity_pub/visibilty_test.exs b/test/web/activity_pub/visibilty_test.exs index 9c03c8be2..e2584f635 100644 --- a/test/web/activity_pub/visibilty_test.exs +++ b/test/web/activity_pub/visibilty_test.exs @@ -96,6 +96,16 @@ defmodule Pleroma.Web.ActivityPub.VisibilityTest do      refute Visibility.visible_for_user?(direct, unrelated)    end +  test "doesn't die when the user doesn't exist", +       %{ +         direct: direct, +         user: user +       } do +    Repo.delete(user) +    Cachex.clear(:user_cache) +    refute Visibility.is_private?(direct) +  end +    test "get_visibility", %{      public: public,      private: private, diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index 019905137..9721a4034 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -5,8 +5,10 @@  defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do    use Pleroma.Web.ConnCase +  alias Pleroma.Activity    alias Pleroma.User    alias Pleroma.UserInviteToken +  alias Pleroma.Web.CommonAPI    import Pleroma.Factory    describe "/api/pleroma/admin/users" do @@ -530,14 +532,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do      end    end -  test "/api/pleroma/admin/invite_token" do +  test "/api/pleroma/admin/users/invite_token" do      admin = insert(:user, info: %{is_admin: true})      conn =        build_conn()        |> assign(:user, admin)        |> put_req_header("accept", "application/json") -      |> get("/api/pleroma/admin/invite_token") +      |> get("/api/pleroma/admin/users/invite_token")      assert conn.status == 200    end @@ -570,27 +572,31 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do        user = insert(:user, local: false, tags: ["foo", "bar"])        conn = get(conn, "/api/pleroma/admin/users?page=1") +      users = +        [ +          %{ +            "deactivated" => admin.info.deactivated, +            "id" => admin.id, +            "nickname" => admin.nickname, +            "roles" => %{"admin" => true, "moderator" => false}, +            "local" => true, +            "tags" => [] +          }, +          %{ +            "deactivated" => user.info.deactivated, +            "id" => user.id, +            "nickname" => user.nickname, +            "roles" => %{"admin" => false, "moderator" => false}, +            "local" => false, +            "tags" => ["foo", "bar"] +          } +        ] +        |> Enum.sort_by(& &1["nickname"]) +        assert json_response(conn, 200) == %{                 "count" => 2,                 "page_size" => 50, -               "users" => [ -                 %{ -                   "deactivated" => admin.info.deactivated, -                   "id" => admin.id, -                   "nickname" => admin.nickname, -                   "roles" => %{"admin" => true, "moderator" => false}, -                   "local" => true, -                   "tags" => [] -                 }, -                 %{ -                   "deactivated" => user.info.deactivated, -                   "id" => user.id, -                   "nickname" => user.nickname, -                   "roles" => %{"admin" => false, "moderator" => false}, -                   "local" => false, -                   "tags" => ["foo", "bar"] -                 } -               ] +               "users" => users               }      end @@ -792,35 +798,39 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do          |> assign(:user, admin)          |> get("/api/pleroma/admin/users?filters=local") +      users = +        [ +          %{ +            "deactivated" => user.info.deactivated, +            "id" => user.id, +            "nickname" => user.nickname, +            "roles" => %{"admin" => false, "moderator" => false}, +            "local" => true, +            "tags" => [] +          }, +          %{ +            "deactivated" => admin.info.deactivated, +            "id" => admin.id, +            "nickname" => admin.nickname, +            "roles" => %{"admin" => true, "moderator" => false}, +            "local" => true, +            "tags" => [] +          }, +          %{ +            "deactivated" => false, +            "id" => old_admin.id, +            "local" => true, +            "nickname" => old_admin.nickname, +            "roles" => %{"admin" => true, "moderator" => false}, +            "tags" => [] +          } +        ] +        |> Enum.sort_by(& &1["nickname"]) +        assert json_response(conn, 200) == %{                 "count" => 3,                 "page_size" => 50, -               "users" => [ -                 %{ -                   "deactivated" => user.info.deactivated, -                   "id" => user.id, -                   "nickname" => user.nickname, -                   "roles" => %{"admin" => false, "moderator" => false}, -                   "local" => true, -                   "tags" => [] -                 }, -                 %{ -                   "deactivated" => admin.info.deactivated, -                   "id" => admin.id, -                   "nickname" => admin.nickname, -                   "roles" => %{"admin" => true, "moderator" => false}, -                   "local" => true, -                   "tags" => [] -                 }, -                 %{ -                   "deactivated" => false, -                   "id" => old_admin.id, -                   "local" => true, -                   "nickname" => old_admin.nickname, -                   "roles" => %{"admin" => true, "moderator" => false}, -                   "tags" => [] -                 } -               ] +               "users" => users               }      end @@ -831,27 +841,31 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do        conn = get(conn, "/api/pleroma/admin/users?filters=is_admin") +      users = +        [ +          %{ +            "deactivated" => false, +            "id" => admin.id, +            "nickname" => admin.nickname, +            "roles" => %{"admin" => true, "moderator" => false}, +            "local" => admin.local, +            "tags" => [] +          }, +          %{ +            "deactivated" => false, +            "id" => second_admin.id, +            "nickname" => second_admin.nickname, +            "roles" => %{"admin" => true, "moderator" => false}, +            "local" => second_admin.local, +            "tags" => [] +          } +        ] +        |> Enum.sort_by(& &1["nickname"]) +        assert json_response(conn, 200) == %{                 "count" => 2,                 "page_size" => 50, -               "users" => [ -                 %{ -                   "deactivated" => false, -                   "id" => admin.id, -                   "nickname" => admin.nickname, -                   "roles" => %{"admin" => true, "moderator" => false}, -                   "local" => admin.local, -                   "tags" => [] -                 }, -                 %{ -                   "deactivated" => false, -                   "id" => second_admin.id, -                   "nickname" => second_admin.nickname, -                   "roles" => %{"admin" => true, "moderator" => false}, -                   "local" => second_admin.local, -                   "tags" => [] -                 } -               ] +               "users" => users               }      end @@ -886,27 +900,31 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do        conn = get(conn, "/api/pleroma/admin/users?tags[]=first&tags[]=second") +      users = +        [ +          %{ +            "deactivated" => false, +            "id" => user1.id, +            "nickname" => user1.nickname, +            "roles" => %{"admin" => false, "moderator" => false}, +            "local" => user1.local, +            "tags" => ["first"] +          }, +          %{ +            "deactivated" => false, +            "id" => user2.id, +            "nickname" => user2.nickname, +            "roles" => %{"admin" => false, "moderator" => false}, +            "local" => user2.local, +            "tags" => ["second"] +          } +        ] +        |> Enum.sort_by(& &1["nickname"]) +        assert json_response(conn, 200) == %{                 "count" => 2,                 "page_size" => 50, -               "users" => [ -                 %{ -                   "deactivated" => false, -                   "id" => user1.id, -                   "nickname" => user1.nickname, -                   "roles" => %{"admin" => false, "moderator" => false}, -                   "local" => user1.local, -                   "tags" => ["first"] -                 }, -                 %{ -                   "deactivated" => false, -                   "id" => user2.id, -                   "nickname" => user2.nickname, -                   "roles" => %{"admin" => false, "moderator" => false}, -                   "local" => user2.local, -                   "tags" => ["second"] -                 } -               ] +               "users" => users               }      end @@ -1084,4 +1102,329 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do               }      end    end + +  describe "GET /api/pleroma/admin/reports/:id" do +    setup %{conn: conn} do +      admin = insert(:user, info: %{is_admin: true}) + +      %{conn: assign(conn, :user, admin)} +    end + +    test "returns report by its id", %{conn: conn} do +      [reporter, target_user] = insert_pair(:user) +      activity = insert(:note_activity, user: target_user) + +      {:ok, %{id: report_id}} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "comment" => "I feel offended", +          "status_ids" => [activity.id] +        }) + +      response = +        conn +        |> get("/api/pleroma/admin/reports/#{report_id}") +        |> json_response(:ok) + +      assert response["id"] == report_id +    end + +    test "returns 404 when report id is invalid", %{conn: conn} do +      conn = get(conn, "/api/pleroma/admin/reports/test") + +      assert json_response(conn, :not_found) == "Not found" +    end +  end + +  describe "PUT /api/pleroma/admin/reports/:id" do +    setup %{conn: conn} do +      admin = insert(:user, info: %{is_admin: true}) +      [reporter, target_user] = insert_pair(:user) +      activity = insert(:note_activity, user: target_user) + +      {:ok, %{id: report_id}} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "comment" => "I feel offended", +          "status_ids" => [activity.id] +        }) + +      %{conn: assign(conn, :user, admin), id: report_id} +    end + +    test "mark report as resolved", %{conn: conn, id: id} do +      response = +        conn +        |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "resolved"}) +        |> json_response(:ok) + +      assert response["state"] == "resolved" +    end + +    test "closes report", %{conn: conn, id: id} do +      response = +        conn +        |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "closed"}) +        |> json_response(:ok) + +      assert response["state"] == "closed" +    end + +    test "returns 400 when state is unknown", %{conn: conn, id: id} do +      conn = +        conn +        |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "test"}) + +      assert json_response(conn, :bad_request) == "Unsupported state" +    end + +    test "returns 404 when report is not exist", %{conn: conn} do +      conn = +        conn +        |> put("/api/pleroma/admin/reports/test", %{"state" => "closed"}) + +      assert json_response(conn, :not_found) == "Not found" +    end +  end + +  describe "GET /api/pleroma/admin/reports" do +    setup %{conn: conn} do +      admin = insert(:user, info: %{is_admin: true}) + +      %{conn: assign(conn, :user, admin)} +    end + +    test "returns empty response when no reports created", %{conn: conn} do +      response = +        conn +        |> get("/api/pleroma/admin/reports") +        |> json_response(:ok) + +      assert Enum.empty?(response["reports"]) +    end + +    test "returns reports", %{conn: conn} do +      [reporter, target_user] = insert_pair(:user) +      activity = insert(:note_activity, user: target_user) + +      {:ok, %{id: report_id}} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "comment" => "I feel offended", +          "status_ids" => [activity.id] +        }) + +      response = +        conn +        |> get("/api/pleroma/admin/reports") +        |> json_response(:ok) + +      [report] = response["reports"] + +      assert length(response["reports"]) == 1 +      assert report["id"] == report_id +    end + +    test "returns reports with specified state", %{conn: conn} do +      [reporter, target_user] = insert_pair(:user) +      activity = insert(:note_activity, user: target_user) + +      {:ok, %{id: first_report_id}} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "comment" => "I feel offended", +          "status_ids" => [activity.id] +        }) + +      {:ok, %{id: second_report_id}} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "comment" => "I don't like this user" +        }) + +      CommonAPI.update_report_state(second_report_id, "closed") + +      response = +        conn +        |> get("/api/pleroma/admin/reports", %{ +          "state" => "open" +        }) +        |> json_response(:ok) + +      [open_report] = response["reports"] + +      assert length(response["reports"]) == 1 +      assert open_report["id"] == first_report_id + +      response = +        conn +        |> get("/api/pleroma/admin/reports", %{ +          "state" => "closed" +        }) +        |> json_response(:ok) + +      [closed_report] = response["reports"] + +      assert length(response["reports"]) == 1 +      assert closed_report["id"] == second_report_id + +      response = +        conn +        |> get("/api/pleroma/admin/reports", %{ +          "state" => "resolved" +        }) +        |> json_response(:ok) + +      assert Enum.empty?(response["reports"]) +    end + +    test "returns 403 when requested by a non-admin" do +      user = insert(:user) + +      conn = +        build_conn() +        |> assign(:user, user) +        |> get("/api/pleroma/admin/reports") + +      assert json_response(conn, :forbidden) == %{"error" => "User is not admin."} +    end + +    test "returns 403 when requested by anonymous" do +      conn = +        build_conn() +        |> get("/api/pleroma/admin/reports") + +      assert json_response(conn, :forbidden) == %{"error" => "Invalid credentials."} +    end +  end + +  describe "POST /api/pleroma/admin/reports/:id/respond" do +    setup %{conn: conn} do +      admin = insert(:user, info: %{is_admin: true}) + +      %{conn: assign(conn, :user, admin)} +    end + +    test "returns created dm", %{conn: conn} do +      [reporter, target_user] = insert_pair(:user) +      activity = insert(:note_activity, user: target_user) + +      {:ok, %{id: report_id}} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "comment" => "I feel offended", +          "status_ids" => [activity.id] +        }) + +      response = +        conn +        |> post("/api/pleroma/admin/reports/#{report_id}/respond", %{ +          "status" => "I will check it out" +        }) +        |> json_response(:ok) + +      recipients = Enum.map(response["mentions"], & &1["username"]) + +      assert conn.assigns[:user].nickname in recipients +      assert reporter.nickname in recipients +      assert response["content"] == "I will check it out" +      assert response["visibility"] == "direct" +    end + +    test "returns 400 when status is missing", %{conn: conn} do +      conn = post(conn, "/api/pleroma/admin/reports/test/respond") + +      assert json_response(conn, :bad_request) == "Invalid parameters" +    end + +    test "returns 404 when report id is invalid", %{conn: conn} do +      conn = +        post(conn, "/api/pleroma/admin/reports/test/respond", %{ +          "status" => "foo" +        }) + +      assert json_response(conn, :not_found) == "Not found" +    end +  end + +  describe "PUT /api/pleroma/admin/statuses/:id" do +    setup %{conn: conn} do +      admin = insert(:user, info: %{is_admin: true}) +      activity = insert(:note_activity) + +      %{conn: assign(conn, :user, admin), id: activity.id} +    end + +    test "toggle sensitive flag", %{conn: conn, id: id} do +      response = +        conn +        |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "true"}) +        |> json_response(:ok) + +      assert response["sensitive"] + +      response = +        conn +        |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "false"}) +        |> json_response(:ok) + +      refute response["sensitive"] +    end + +    test "change visibility flag", %{conn: conn, id: id} do +      response = +        conn +        |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "public"}) +        |> json_response(:ok) + +      assert response["visibility"] == "public" + +      response = +        conn +        |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "private"}) +        |> json_response(:ok) + +      assert response["visibility"] == "private" + +      response = +        conn +        |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "unlisted"}) +        |> json_response(:ok) + +      assert response["visibility"] == "unlisted" +    end + +    test "returns 400 when visibility is unknown", %{conn: conn, id: id} do +      conn = +        conn +        |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "test"}) + +      assert json_response(conn, :bad_request) == "Unsupported visibility" +    end +  end + +  describe "DELETE /api/pleroma/admin/statuses/:id" do +    setup %{conn: conn} do +      admin = insert(:user, info: %{is_admin: true}) +      activity = insert(:note_activity) + +      %{conn: assign(conn, :user, admin), id: activity.id} +    end + +    test "deletes status", %{conn: conn, id: id} do +      conn +      |> delete("/api/pleroma/admin/statuses/#{id}") +      |> json_response(:ok) + +      refute Activity.get_by_id(id) +    end + +    test "returns error when status is not exist", %{conn: conn} do +      conn = +        conn +        |> delete("/api/pleroma/admin/statuses/test") + +      assert json_response(conn, :bad_request) == "Could not delete" +    end +  end  end diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs index 8d4f401ee..696060fb1 100644 --- a/test/web/common_api/common_api_test.exs +++ b/test/web/common_api/common_api_test.exs @@ -261,10 +261,41 @@ defmodule Pleroma.Web.CommonAPITest do                 data: %{                   "type" => "Flag",                   "content" => ^comment, -                 "object" => [^target_ap_id, ^activity_ap_id] +                 "object" => [^target_ap_id, ^activity_ap_id], +                 "state" => "open"                 }               } = flag_activity      end + +    test "updates report state" do +      [reporter, target_user] = insert_pair(:user) +      activity = insert(:note_activity, user: target_user) + +      {:ok, %Activity{id: report_id}} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "comment" => "I feel offended", +          "status_ids" => [activity.id] +        }) + +      {:ok, report} = CommonAPI.update_report_state(report_id, "resolved") + +      assert report.data["state"] == "resolved" +    end + +    test "does not update report state when state is unsupported" do +      [reporter, target_user] = insert_pair(:user) +      activity = insert(:note_activity, user: target_user) + +      {:ok, %Activity{id: report_id}} = +        CommonAPI.report(reporter, %{ +          "account_id" => target_user.id, +          "comment" => "I feel offended", +          "status_ids" => [activity.id] +        }) + +      assert CommonAPI.update_report_state(report_id, "test") == {:error, "Unsupported state"} +    end    end    describe "reblog muting" do @@ -279,14 +310,14 @@ defmodule Pleroma.Web.CommonAPITest do      test "add a reblog mute", %{muter: muter, muted: muted} do        {:ok, muter} = CommonAPI.hide_reblogs(muter, muted) -      assert Pleroma.User.showing_reblogs?(muter, muted) == false +      assert User.showing_reblogs?(muter, muted) == false      end      test "remove a reblog mute", %{muter: muter, muted: muted} do        {:ok, muter} = CommonAPI.hide_reblogs(muter, muted)        {:ok, muter} = CommonAPI.show_reblogs(muter, muted) -      assert Pleroma.User.showing_reblogs?(muter, muted) == true +      assert User.showing_reblogs?(muter, muted) == true      end    end  end diff --git a/test/web/fallback_test.exs b/test/web/fallback_test.exs new file mode 100644 index 000000000..cc78b3ae1 --- /dev/null +++ b/test/web/fallback_test.exs @@ -0,0 +1,52 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.FallbackTest do +  use Pleroma.Web.ConnCase +  import Pleroma.Factory + +  test "GET /registration/:token", %{conn: conn} do +    assert conn +           |> get("/registration/foo") +           |> html_response(200) =~ "<!--server-generated-meta-->" +  end + +  test "GET /:maybe_nickname_or_id", %{conn: conn} do +    user = insert(:user) + +    assert conn +           |> get("/foo") +           |> html_response(200) =~ "<!--server-generated-meta-->" + +    refute conn +           |> get("/" <> user.nickname) +           |> html_response(200) =~ "<!--server-generated-meta-->" +  end + +  test "GET /api*path", %{conn: conn} do +    assert conn +           |> get("/api/foo") +           |> json_response(404) == %{"error" => "Not implemented"} +  end + +  test "GET /*path", %{conn: conn} do +    assert conn +           |> get("/foo") +           |> html_response(200) =~ "<!--server-generated-meta-->" + +    assert conn +           |> get("/foo/bar") +           |> html_response(200) =~ "<!--server-generated-meta-->" +  end + +  test "OPTIONS /*path", %{conn: conn} do +    assert conn +           |> options("/foo") +           |> response(204) == "" + +    assert conn +           |> options("/foo/bar") +           |> response(204) == "" +  end +end diff --git a/test/web/mastodon_api/account_view_test.exs b/test/web/mastodon_api/account_view_test.exs index a24f2a050..aaf2261bb 100644 --- a/test/web/mastodon_api/account_view_test.exs +++ b/test/web/mastodon_api/account_view_test.exs @@ -55,7 +55,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do        fields: [],        bot: false,        source: %{ -        note: "", +        note: "valid html",          sensitive: false,          pleroma: %{}        }, @@ -120,7 +120,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do        fields: [],        bot: true,        source: %{ -        note: "", +        note: user.bio,          sensitive: false,          pleroma: %{}        }, @@ -209,7 +209,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do        fields: [],        bot: true,        source: %{ -        note: "", +        note: user.bio,          sensitive: false,          pleroma: %{}        }, diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index 40e7739e7..93ef630f2 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -446,7 +446,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do    end    test "verify_credentials default scope unlisted", %{conn: conn} do -    user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "unlisted"}}) +    user = insert(:user, %{info: %User.Info{default_scope: "unlisted"}})      conn =        conn @@ -1322,7 +1322,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do    describe "locked accounts" do      test "/api/v1/follow_requests works" do -      user = insert(:user, %{info: %Pleroma.User.Info{locked: true}}) +      user = insert(:user, %{info: %User.Info{locked: true}})        other_user = insert(:user)        {:ok, _activity} = ActivityPub.follow(other_user, user) @@ -1367,7 +1367,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do      end      test "verify_credentials", %{conn: conn} do -      user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "private"}}) +      user = insert(:user, %{info: %User.Info{default_scope: "private"}})        conn =          conn @@ -1379,7 +1379,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do      end      test "/api/v1/follow_requests/:id/reject works" do -      user = insert(:user, %{info: %Pleroma.User.Info{locked: true}}) +      user = insert(:user, %{info: %User.Info{locked: true}})        other_user = insert(:user)        {:ok, _activity} = ActivityPub.follow(other_user, user) @@ -1455,6 +1455,72 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do      assert object.data["actor"] == User.ap_id(user)    end +  test "mascot upload", %{conn: conn} do +    user = insert(:user) + +    non_image_file = %Plug.Upload{ +      content_type: "audio/mpeg", +      path: Path.absname("test/fixtures/sound.mp3"), +      filename: "sound.mp3" +    } + +    conn = +      conn +      |> assign(:user, user) +      |> put("/api/v1/pleroma/mascot", %{"file" => non_image_file}) + +    assert json_response(conn, 415) + +    file = %Plug.Upload{ +      content_type: "image/jpg", +      path: Path.absname("test/fixtures/image.jpg"), +      filename: "an_image.jpg" +    } + +    conn = +      build_conn() +      |> assign(:user, user) +      |> put("/api/v1/pleroma/mascot", %{"file" => file}) + +    assert %{"id" => _, "type" => image} = json_response(conn, 200) +  end + +  test "mascot retrieving", %{conn: conn} do +    user = insert(:user) +    # When user hasn't set a mascot, we should just get pleroma tan back +    conn = +      conn +      |> assign(:user, user) +      |> get("/api/v1/pleroma/mascot") + +    assert %{"url" => url} = json_response(conn, 200) +    assert url =~ "pleroma-fox-tan-smol" + +    # When a user sets their mascot, we should get that back +    file = %Plug.Upload{ +      content_type: "image/jpg", +      path: Path.absname("test/fixtures/image.jpg"), +      filename: "an_image.jpg" +    } + +    conn = +      build_conn() +      |> assign(:user, user) +      |> put("/api/v1/pleroma/mascot", %{"file" => file}) + +    assert json_response(conn, 200) + +    user = User.get_cached_by_id(user.id) + +    conn = +      build_conn() +      |> assign(:user, user) +      |> get("/api/v1/pleroma/mascot") + +    assert %{"url" => url, "type" => "image"} = json_response(conn, 200) +    assert url =~ "an_image" +  end +    test "hashtag timeline", %{conn: conn} do      following = insert(:user) @@ -2129,7 +2195,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do          |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")          |> json_response(:ok) -      assert length(anonymous_response) == 0 +      assert Enum.empty?(anonymous_response)      end      test "does not return others' favorited DM when user is not one of recipients", %{ @@ -2153,7 +2219,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do          |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")          |> json_response(:ok) -      assert length(response) == 0 +      assert Enum.empty?(response)      end      test "paginates favorites using since_id and max_id", %{ @@ -2618,33 +2684,50 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do                 |> post("/api/v1/statuses/#{activity_two.id}/pin")                 |> json_response(400)      end +  end -    test "Status rich-media Card", %{conn: conn, user: user} do +  describe "cards" do +    setup do        Pleroma.Config.put([:rich_media, :enabled], true) + +      on_exit(fn -> +        Pleroma.Config.put([:rich_media, :enabled], false) +      end) + +      user = insert(:user) +      %{user: user} +    end + +    test "returns rich-media card", %{conn: conn, user: user} do        {:ok, activity} = CommonAPI.post(user, %{"status" => "http://example.com/ogp"}) +      card_data = %{ +        "image" => "http://ia.media-imdb.com/images/rock.jpg", +        "provider_name" => "www.imdb.com", +        "provider_url" => "http://www.imdb.com", +        "title" => "The Rock", +        "type" => "link", +        "url" => "http://www.imdb.com/title/tt0117500/", +        "description" => +          "Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.", +        "pleroma" => %{ +          "opengraph" => %{ +            "image" => "http://ia.media-imdb.com/images/rock.jpg", +            "title" => "The Rock", +            "type" => "video.movie", +            "url" => "http://www.imdb.com/title/tt0117500/", +            "description" => +              "Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer." +          } +        } +      } +        response =          conn          |> get("/api/v1/statuses/#{activity.id}/card")          |> json_response(200) -      assert response == %{ -               "image" => "http://ia.media-imdb.com/images/rock.jpg", -               "provider_name" => "www.imdb.com", -               "provider_url" => "http://www.imdb.com", -               "title" => "The Rock", -               "type" => "link", -               "url" => "http://www.imdb.com/title/tt0117500/", -               "description" => nil, -               "pleroma" => %{ -                 "opengraph" => %{ -                   "image" => "http://ia.media-imdb.com/images/rock.jpg", -                   "title" => "The Rock", -                   "type" => "video.movie", -                   "url" => "http://www.imdb.com/title/tt0117500/" -                 } -               } -             } +      assert response == card_data        # works with private posts        {:ok, activity} = @@ -2656,9 +2739,33 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do          |> get("/api/v1/statuses/#{activity.id}/card")          |> json_response(200) -      assert response_two == response +      assert response_two == card_data +    end + +    test "replaces missing description with an empty string", %{conn: conn, user: user} do +      {:ok, activity} = CommonAPI.post(user, %{"status" => "http://example.com/ogp-missing-data"}) + +      response = +        conn +        |> get("/api/v1/statuses/#{activity.id}/card") +        |> json_response(:ok) -      Pleroma.Config.put([:rich_media, :enabled], false) +      assert response == %{ +               "type" => "link", +               "title" => "Pleroma", +               "description" => "", +               "image" => nil, +               "provider_name" => "pleroma.social", +               "provider_url" => "https://pleroma.social", +               "url" => "https://pleroma.social/", +               "pleroma" => %{ +                 "opengraph" => %{ +                   "title" => "Pleroma", +                   "type" => "website", +                   "url" => "https://pleroma.social/" +                 } +               } +             }      end    end diff --git a/test/web/mongooseim/mongoose_im_controller_test.exs b/test/web/mongooseim/mongoose_im_controller_test.exs new file mode 100644 index 000000000..eb83999bb --- /dev/null +++ b/test/web/mongooseim/mongoose_im_controller_test.exs @@ -0,0 +1,59 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MongooseIMController do +  use Pleroma.Web.ConnCase +  import Pleroma.Factory + +  test "/user_exists", %{conn: conn} do +    _user = insert(:user, nickname: "lain") +    _remote_user = insert(:user, nickname: "alice", local: false) + +    res = +      conn +      |> get(mongoose_im_path(conn, :user_exists), user: "lain") +      |> json_response(200) + +    assert res == true + +    res = +      conn +      |> get(mongoose_im_path(conn, :user_exists), user: "alice") +      |> json_response(404) + +    assert res == false + +    res = +      conn +      |> get(mongoose_im_path(conn, :user_exists), user: "bob") +      |> json_response(404) + +    assert res == false +  end + +  test "/check_password", %{conn: conn} do +    user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt("cool")) + +    res = +      conn +      |> get(mongoose_im_path(conn, :check_password), user: user.nickname, pass: "cool") +      |> json_response(200) + +    assert res == true + +    res = +      conn +      |> get(mongoose_im_path(conn, :check_password), user: user.nickname, pass: "uncool") +      |> json_response(403) + +    assert res == false + +    res = +      conn +      |> get(mongoose_im_path(conn, :check_password), user: "nobody", pass: "cool") +      |> json_response(404) + +    assert res == false +  end +end diff --git a/test/web/node_info_test.exs b/test/web/node_info_test.exs index 2fc42b7cc..be1173513 100644 --- a/test/web/node_info_test.exs +++ b/test/web/node_info_test.exs @@ -7,6 +7,22 @@ defmodule Pleroma.Web.NodeInfoTest do    import Pleroma.Factory +  test "GET /.well-known/nodeinfo", %{conn: conn} do +    links = +      conn +      |> get("/.well-known/nodeinfo") +      |> json_response(200) +      |> Map.fetch!("links") + +    Enum.each(links, fn link -> +      href = Map.fetch!(link, "href") + +      conn +      |> get(href) +      |> json_response(200) +    end) +  end +    test "nodeinfo shows staff accounts", %{conn: conn} do      moderator = insert(:user, %{local: true, info: %{is_moderator: true}})      admin = insert(:user, %{local: true, info: %{is_admin: true}}) @@ -32,70 +48,6 @@ defmodule Pleroma.Web.NodeInfoTest do               result["metadata"]["restrictedNicknames"]    end -  test "returns 404 when federation is disabled", %{conn: conn} do -    instance = -      Application.get_env(:pleroma, :instance) -      |> Keyword.put(:federating, false) - -    Application.put_env(:pleroma, :instance, instance) - -    conn -    |> get("/.well-known/nodeinfo") -    |> json_response(404) - -    conn -    |> get("/nodeinfo/2.1.json") -    |> json_response(404) - -    instance = -      Application.get_env(:pleroma, :instance) -      |> Keyword.put(:federating, true) - -    Application.put_env(:pleroma, :instance, instance) -  end - -  test "returns 200 when federation is enabled", %{conn: conn} do -    conn -    |> get("/.well-known/nodeinfo") -    |> json_response(200) - -    conn -    |> get("/nodeinfo/2.1.json") -    |> json_response(200) -  end - -  test "returns 404 when federation is disabled (nodeinfo 2.0)", %{conn: conn} do -    instance = -      Application.get_env(:pleroma, :instance) -      |> Keyword.put(:federating, false) - -    Application.put_env(:pleroma, :instance, instance) - -    conn -    |> get("/.well-known/nodeinfo") -    |> json_response(404) - -    conn -    |> get("/nodeinfo/2.0.json") -    |> json_response(404) - -    instance = -      Application.get_env(:pleroma, :instance) -      |> Keyword.put(:federating, true) - -    Application.put_env(:pleroma, :instance, instance) -  end - -  test "returns 200 when federation is enabled (nodeinfo 2.0)", %{conn: conn} do -    conn -    |> get("/.well-known/nodeinfo") -    |> json_response(200) - -    conn -    |> get("/nodeinfo/2.0.json") -    |> json_response(200) -  end -    test "returns software.repository field in nodeinfo 2.1", %{conn: conn} do      conn      |> get("/.well-known/nodeinfo") diff --git a/test/web/oauth/token_test.exs b/test/web/oauth/token_test.exs index ad2a49f09..3c07309b7 100644 --- a/test/web/oauth/token_test.exs +++ b/test/web/oauth/token_test.exs @@ -69,4 +69,17 @@ defmodule Pleroma.Web.OAuth.TokenTest do      assert tokens == 2    end + +  test "deletes expired tokens" do +    insert(:oauth_token, valid_until: Timex.shift(Timex.now(), days: -3)) +    insert(:oauth_token, valid_until: Timex.shift(Timex.now(), days: -3)) +    t3 = insert(:oauth_token) +    t4 = insert(:oauth_token, valid_until: Timex.shift(Timex.now(), minutes: 10)) +    {tokens, _} = Token.delete_expired_tokens() +    assert tokens == 2 +    available_tokens = Pleroma.Repo.all(Token) + +    token_ids = available_tokens |> Enum.map(& &1.id) +    assert token_ids == [t3.id, t4.id] +  end  end diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs index 2916caf8d..f6be16862 100644 --- a/test/web/ostatus/ostatus_test.exs +++ b/test/web/ostatus/ostatus_test.exs @@ -355,7 +355,7 @@ defmodule Pleroma.Web.OStatusTest do        {:ok, user} = OStatus.find_or_make_user(uri) -      user = Pleroma.User.get_cached_by_id(user.id) +      user = User.get_cached_by_id(user.id)        assert user.name == "Constance Variable"        assert user.nickname == "lambadalambda@social.heldscal.la"        assert user.local == false @@ -374,7 +374,7 @@ defmodule Pleroma.Web.OStatusTest do        {:ok, user} = OStatus.find_or_make_user(uri)        assert user.info == -               %Pleroma.User.Info{ +               %User.Info{                   id: user.info.id,                   ap_enabled: false,                   background: %{}, @@ -407,7 +407,7 @@ defmodule Pleroma.Web.OStatusTest do        {:ok, user} = OStatus.find_or_make_user(uri)        old_name = user.name        old_bio = user.bio -      change = Ecto.Changeset.change(user, %{avatar: nil, bio: nil, old_name: nil}) +      change = Ecto.Changeset.change(user, %{avatar: nil, bio: nil, name: nil})        {:ok, user} = Repo.update(change)        refute user.avatar diff --git a/test/web/plugs/federating_plug_test.exs b/test/web/plugs/federating_plug_test.exs index 612db7e32..530562325 100644 --- a/test/web/plugs/federating_plug_test.exs +++ b/test/web/plugs/federating_plug_test.exs @@ -6,11 +6,7 @@ defmodule Pleroma.Web.FederatingPlugTest do    use Pleroma.Web.ConnCase    test "returns and halt the conn when federating is disabled" do -    instance = -      Application.get_env(:pleroma, :instance) -      |> Keyword.put(:federating, false) - -    Application.put_env(:pleroma, :instance, instance) +    Pleroma.Config.put([:instance, :federating], false)      conn =        build_conn() @@ -19,11 +15,7 @@ defmodule Pleroma.Web.FederatingPlugTest do      assert conn.status == 404      assert conn.halted -    instance = -      Application.get_env(:pleroma, :instance) -      |> Keyword.put(:federating, true) - -    Application.put_env(:pleroma, :instance, instance) +    Pleroma.Config.put([:instance, :federating], true)    end    test "does nothing when federating is enabled" do diff --git a/test/web/rich_media/helpers_test.exs b/test/web/rich_media/helpers_test.exs index 60d93768f..53b0596f5 100644 --- a/test/web/rich_media/helpers_test.exs +++ b/test/web/rich_media/helpers_test.exs @@ -1,6 +1,7 @@  defmodule Pleroma.Web.RichMedia.HelpersTest do    use Pleroma.DataCase +  alias Pleroma.Object    alias Pleroma.Web.CommonAPI    import Pleroma.Factory @@ -59,4 +60,43 @@ defmodule Pleroma.Web.RichMedia.HelpersTest do      Pleroma.Config.put([:rich_media, :enabled], false)    end + +  test "refuses to crawl URLs from posts marked sensitive" do +    user = insert(:user) + +    {:ok, activity} = +      CommonAPI.post(user, %{ +        "status" => "http://example.com/ogp", +        "sensitive" => true +      }) + +    %Object{} = object = Object.normalize(activity) + +    assert object.data["sensitive"] + +    Pleroma.Config.put([:rich_media, :enabled], true) + +    assert %{} = Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) + +    Pleroma.Config.put([:rich_media, :enabled], false) +  end + +  test "refuses to crawl URLs from posts tagged NSFW" do +    user = insert(:user) + +    {:ok, activity} = +      CommonAPI.post(user, %{ +        "status" => "http://example.com/ogp #nsfw" +      }) + +    %Object{} = object = Object.normalize(activity) + +    assert object.data["sensitive"] + +    Pleroma.Config.put([:rich_media, :enabled], true) + +    assert %{} = Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity) + +    Pleroma.Config.put([:rich_media, :enabled], false) +  end  end diff --git a/test/web/rich_media/parser_test.exs b/test/web/rich_media/parser_test.exs index 47b127cf9..3a9cc1854 100644 --- a/test/web/rich_media/parser_test.exs +++ b/test/web/rich_media/parser_test.exs @@ -44,6 +44,8 @@ defmodule Pleroma.Web.RichMedia.ParserTest do                %{                  image: "http://ia.media-imdb.com/images/rock.jpg",                  title: "The Rock", +                description: +                  "Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.",                  type: "video.movie",                  url: "http://www.imdb.com/title/tt0117500/"                }} diff --git a/test/web/salmon/salmon_test.exs b/test/web/salmon/salmon_test.exs index 232082779..e86e76fe9 100644 --- a/test/web/salmon/salmon_test.exs +++ b/test/web/salmon/salmon_test.exs @@ -5,6 +5,7 @@  defmodule Pleroma.Web.Salmon.SalmonTest do    use Pleroma.DataCase    alias Pleroma.Activity +  alias Pleroma.Keys    alias Pleroma.Repo    alias Pleroma.User    alias Pleroma.Web.Federator.Publisher @@ -34,12 +35,6 @@ defmodule Pleroma.Web.Salmon.SalmonTest do      assert Salmon.decode_and_validate(@wrong_magickey, salmon) == :error    end -  test "generates an RSA private key pem" do -    {:ok, key} = Salmon.generate_rsa_pem() -    assert is_binary(key) -    assert Regex.match?(~r/RSA/, key) -  end -    test "it encodes a magic key from a public key" do      key = Salmon.decode_key(@magickey)      magic_key = Salmon.encode_key(key) @@ -51,18 +46,10 @@ defmodule Pleroma.Web.Salmon.SalmonTest do      _key = Salmon.decode_key(@magickey_friendica)    end -  test "returns a public and private key from a pem" do -    pem = File.read!("test/fixtures/private_key.pem") -    {:ok, private, public} = Salmon.keys_from_pem(pem) - -    assert elem(private, 0) == :RSAPrivateKey -    assert elem(public, 0) == :RSAPublicKey -  end -    test "encodes an xml payload with a private key" do      doc = File.read!("test/fixtures/incoming_note_activity.xml")      pem = File.read!("test/fixtures/private_key.pem") -    {:ok, private, public} = Salmon.keys_from_pem(pem) +    {:ok, private, public} = Keys.keys_from_pem(pem)      # Let's try a roundtrip.      {:ok, salmon} = Salmon.encode(private, doc) @@ -105,7 +92,7 @@ defmodule Pleroma.Web.Salmon.SalmonTest do      {:ok, activity} = Repo.insert(%Activity{data: activity_data, recipients: activity_data["to"]})      user = User.get_cached_by_ap_id(activity.data["actor"]) -    {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) +    {:ok, user} = User.ensure_keys_present(user)      Salmon.publish(user, activity) diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs index e194f14fb..bcd0f522d 100644 --- a/test/web/twitter_api/twitter_api_controller_test.exs +++ b/test/web/twitter_api/twitter_api_controller_test.exs @@ -144,41 +144,25 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do      end      test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do -      instance = -        Application.get_env(:pleroma, :instance) -        |> Keyword.put(:public, false) - -      Application.put_env(:pleroma, :instance, instance) +      Pleroma.Config.put([:instance, :public], false)        conn        |> get("/api/statuses/public_timeline.json")        |> json_response(403) -      instance = -        Application.get_env(:pleroma, :instance) -        |> Keyword.put(:public, true) - -      Application.put_env(:pleroma, :instance, instance) +      Pleroma.Config.put([:instance, :public], true)      end      test "returns 200 to authenticated request when the instance is not public",           %{conn: conn, user: user} do -      instance = -        Application.get_env(:pleroma, :instance) -        |> Keyword.put(:public, false) - -      Application.put_env(:pleroma, :instance, instance) +      Pleroma.Config.put([:instance, :public], false)        conn        |> with_credentials(user.nickname, "test")        |> get("/api/statuses/public_timeline.json")        |> json_response(200) -      instance = -        Application.get_env(:pleroma, :instance) -        |> Keyword.put(:public, true) - -      Application.put_env(:pleroma, :instance, instance) +      Pleroma.Config.put([:instance, :public], true)      end      test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do @@ -214,41 +198,25 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do      setup [:valid_user]      test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do -      instance = -        Application.get_env(:pleroma, :instance) -        |> Keyword.put(:public, false) - -      Application.put_env(:pleroma, :instance, instance) +      Pleroma.Config.put([:instance, :public], false)        conn        |> get("/api/statuses/public_and_external_timeline.json")        |> json_response(403) -      instance = -        Application.get_env(:pleroma, :instance) -        |> Keyword.put(:public, true) - -      Application.put_env(:pleroma, :instance, instance) +      Pleroma.Config.put([:instance, :public], true)      end      test "returns 200 to authenticated request when the instance is not public",           %{conn: conn, user: user} do -      instance = -        Application.get_env(:pleroma, :instance) -        |> Keyword.put(:public, false) - -      Application.put_env(:pleroma, :instance, instance) +      Pleroma.Config.put([:instance, :public], false)        conn        |> with_credentials(user.nickname, "test")        |> get("/api/statuses/public_and_external_timeline.json")        |> json_response(200) -      instance = -        Application.get_env(:pleroma, :instance) -        |> Keyword.put(:public, true) - -      Application.put_env(:pleroma, :instance, instance) +      Pleroma.Config.put([:instance, :public], true)      end      test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do diff --git a/test/web/web_finger/web_finger_test.exs b/test/web/web_finger/web_finger_test.exs index 6b20d8d56..335c95b18 100644 --- a/test/web/web_finger/web_finger_test.exs +++ b/test/web/web_finger/web_finger_test.exs @@ -105,19 +105,4 @@ defmodule Pleroma.Web.WebFingerTest do        assert template == "http://status.alpicola.com/main/xrd?uri={uri}"      end    end - -  describe "ensure_keys_present" do -    test "it creates keys for a user and stores them in info" do -      user = insert(:user) -      refute is_binary(user.info.keys) -      {:ok, user} = WebFinger.ensure_keys_present(user) -      assert is_binary(user.info.keys) -    end - -    test "it doesn't create keys if there already are some" do -      user = insert(:user, %{info: %{keys: "xxx"}}) -      {:ok, user} = WebFinger.ensure_keys_present(user) -      assert user.info.keys == "xxx" -    end -  end  end diff --git a/test/web/websub/websub_controller_test.exs b/test/web/websub/websub_controller_test.exs index 1e69ed01a..f79745d58 100644 --- a/test/web/websub/websub_controller_test.exs +++ b/test/web/websub/websub_controller_test.exs @@ -5,7 +5,6 @@  defmodule Pleroma.Web.Websub.WebsubControllerTest do    use Pleroma.Web.ConnCase    import Pleroma.Factory -  alias Pleroma.Activity    alias Pleroma.Repo    alias Pleroma.Web.Websub    alias Pleroma.Web.Websub.WebsubClientSubscription @@ -52,7 +51,7 @@ defmodule Pleroma.Web.Websub.WebsubControllerTest do    end    describe "websub_incoming" do -    test "handles incoming feed updates", %{conn: conn} do +    test "accepts incoming feed updates", %{conn: conn} do        websub = insert(:websub_client_subscription)        doc = "some stuff"        signature = Websub.sign(websub.secret, doc) @@ -64,8 +63,6 @@ defmodule Pleroma.Web.Websub.WebsubControllerTest do          |> post("/push/subscriptions/#{websub.id}", doc)        assert response(conn, 200) == "OK" - -      assert length(Repo.all(Activity)) == 1      end      test "rejects incoming feed updates with the wrong signature", %{conn: conn} do @@ -80,8 +77,6 @@ defmodule Pleroma.Web.Websub.WebsubControllerTest do          |> post("/push/subscriptions/#{websub.id}", doc)        assert response(conn, 500) == "Error" - -      assert Enum.empty?(Repo.all(Activity))      end    end  end  | 
