diff options
| author | Hakaba Hitoyo <hakabahitoyo@example.com> | 2018-11-15 14:04:09 +0900 | 
|---|---|---|
| committer | Hakaba Hitoyo <hakabahitoyo@example.com> | 2018-11-15 14:04:09 +0900 | 
| commit | 5c8b8f6cb7212bd202924b535cd2a263416e78d4 (patch) | |
| tree | 07ad2b2dd44189ae14a1ff44ff5a98013143866b /test | |
| parent | 3484f687958f57ea5ce749135f78517ff12849d7 (diff) | |
| parent | cc45797f4e1765f5123c058166f6032c6a6556a0 (diff) | |
| download | pleroma-5c8b8f6cb7212bd202924b535cd2a263416e78d4.tar.gz pleroma-5c8b8f6cb7212bd202924b535cd2a263416e78d4.zip | |
Merge remote-tracking branch 'official/develop' into develop
Diffstat (limited to 'test')
22 files changed, 899 insertions, 17 deletions
| diff --git a/test/config_test.exs b/test/config_test.exs new file mode 100644 index 000000000..0124544c8 --- /dev/null +++ b/test/config_test.exs @@ -0,0 +1,56 @@ +defmodule Pleroma.ConfigTest do +  use ExUnit.Case + +  test "get/1 with an atom" do +    assert Pleroma.Config.get(:instance) == Application.get_env(:pleroma, :instance) +    assert Pleroma.Config.get(:azertyuiop) == nil +    assert Pleroma.Config.get(:azertyuiop, true) == true +  end + +  test "get/1 with a list of keys" do +    assert Pleroma.Config.get([:instance, :public]) == +             Keyword.get(Application.get_env(:pleroma, :instance), :public) + +    assert Pleroma.Config.get([Pleroma.Web.Endpoint, :render_errors, :view]) == +             get_in( +               Application.get_env( +                 :pleroma, +                 Pleroma.Web.Endpoint +               ), +               [:render_errors, :view] +             ) + +    assert Pleroma.Config.get([:azerty, :uiop]) == nil +    assert Pleroma.Config.get([:azerty, :uiop], true) == true +  end + +  test "get!/1" do +    assert Pleroma.Config.get!(:instance) == Application.get_env(:pleroma, :instance) + +    assert Pleroma.Config.get!([:instance, :public]) == +             Keyword.get(Application.get_env(:pleroma, :instance), :public) + +    assert_raise(Pleroma.Config.Error, fn -> +      Pleroma.Config.get!(:azertyuiop) +    end) + +    assert_raise(Pleroma.Config.Error, fn -> +      Pleroma.Config.get!([:azerty, :uiop]) +    end) +  end + +  test "put/2 with a key" do +    Pleroma.Config.put(:config_test, true) + +    assert Pleroma.Config.get(:config_test) == true +  end + +  test "put/2 with a list of keys" do +    Pleroma.Config.put([:instance, :config_test], true) +    Pleroma.Config.put([:instance, :config_nested_test], []) +    Pleroma.Config.put([:instance, :config_nested_test, :x], true) + +    assert Pleroma.Config.get([:instance, :config_test]) == true +    assert Pleroma.Config.get([:instance, :config_nested_test, :x]) == true +  end +end diff --git a/test/filter_test.exs b/test/filter_test.exs index d81c92f08..509c15317 100644 --- a/test/filter_test.exs +++ b/test/filter_test.exs @@ -5,19 +5,88 @@ defmodule Pleroma.FilterTest do    import Pleroma.Factory    import Ecto.Query -  test "creating a filter" do -    user = insert(:user) +  describe "creating filters" do +    test "creating one filter" do +      user = insert(:user) -    query = %Pleroma.Filter{ -      user_id: user.id, -      filter_id: 42, -      phrase: "knights", -      context: ["home"] -    } +      query = %Pleroma.Filter{ +        user_id: user.id, +        filter_id: 42, +        phrase: "knights", +        context: ["home"] +      } + +      {:ok, %Pleroma.Filter{} = filter} = Pleroma.Filter.create(query) +      result = Pleroma.Filter.get(filter.filter_id, user) +      assert query.phrase == result.phrase +    end + +    test "creating one filter without a pre-defined filter_id" do +      user = insert(:user) + +      query = %Pleroma.Filter{ +        user_id: user.id, +        phrase: "knights", +        context: ["home"] +      } + +      {:ok, %Pleroma.Filter{} = filter} = Pleroma.Filter.create(query) +      # Should start at 1 +      assert filter.filter_id == 1 +    end + +    test "creating additional filters uses previous highest filter_id + 1" do +      user = insert(:user) + +      query_one = %Pleroma.Filter{ +        user_id: user.id, +        filter_id: 42, +        phrase: "knights", +        context: ["home"] +      } + +      {:ok, %Pleroma.Filter{} = filter_one} = Pleroma.Filter.create(query_one) + +      query_two = %Pleroma.Filter{ +        user_id: user.id, +        # No filter_id +        phrase: "who", +        context: ["home"] +      } + +      {:ok, %Pleroma.Filter{} = filter_two} = Pleroma.Filter.create(query_two) +      assert filter_two.filter_id == filter_one.filter_id + 1 +    end + +    test "filter_id is unique per user" do +      user_one = insert(:user) +      user_two = insert(:user) + +      query_one = %Pleroma.Filter{ +        user_id: user_one.id, +        phrase: "knights", +        context: ["home"] +      } + +      {:ok, %Pleroma.Filter{} = filter_one} = Pleroma.Filter.create(query_one) + +      query_two = %Pleroma.Filter{ +        user_id: user_two.id, +        phrase: "who", +        context: ["home"] +      } + +      {:ok, %Pleroma.Filter{} = filter_two} = Pleroma.Filter.create(query_two) + +      assert filter_one.filter_id == 1 +      assert filter_two.filter_id == 1 + +      result_one = Pleroma.Filter.get(filter_one.filter_id, user_one) +      assert result_one.phrase == filter_one.phrase -    {:ok, %Pleroma.Filter{} = filter} = Pleroma.Filter.create(query) -    result = Pleroma.Filter.get(filter.filter_id, user) -    assert query.phrase == result.phrase +      result_two = Pleroma.Filter.get(filter_two.filter_id, user_two) +      assert result_two.phrase == filter_two.phrase +    end    end    test "deleting a filter" do diff --git a/test/fixtures/httpoison_mock/https___prismo.news__mxb.json b/test/fixtures/httpoison_mock/https___prismo.news__mxb.json new file mode 100644 index 000000000..a2fe53117 --- /dev/null +++ b/test/fixtures/httpoison_mock/https___prismo.news__mxb.json @@ -0,0 +1 @@ +{"id":"https://prismo.news/@mxb","type":"Person","name":"mxb","preferredUsername":"mxb","summary":"Creator of △ Prismo\r\n\r\nFollow me at @mb@mstdn.io","inbox":"https://prismo.news/ap/accounts/mxb/inbox","outbox":"https://prismo.news/ap/accounts/mxb/outbox","url":"https://prismo.news/@mxb","publicKey":{"id":"https://prismo.news/@mxb#main-key","owner":"https://prismo.news/@mxb","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA41gqLkBYuPLurC2TarF8\nbdyvqP54XzKyScJ6iPNkk4D4plYdWUVj0aOIHQ8LVfBeziH83jDMpRegm1sRLpNG\n1Ti+SzlWyTwugJ8wfQvwJL7iEzqhuPFddjPLpv0djMptvm5vtG6u6O3g4RpX12bv\n4pYRoMStPSv9KRKD/8Naw5Nv85PIWRc9rOly/EoVZBnbesroo69caiGthgChE2pa\niisQ5CEgj/615WUlUATkz3VdExKQkQOdeVABheIvcS5OsMurXnpWyLQ4n9WalNvF\nlJc08aOTIo4plsLAvdcGRDsBzio4qPok3jgzPpFkDqe+02WG/QMPT9VrzKO49N5R\nqQIDAQAB\n-----END PUBLIC KEY-----\n"},"icon":{"type":"Image","url":"https://prismo.s3.wasabisys.com/account/1/avatar/size_400-b6e570850878684362ba3b4bd9ceb007.jpg","media_type":null},"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"Hashtag":"as:Hashtag"},{"votes":{"@id":"as:votes","@type":"@id"}}]}
\ No newline at end of file diff --git a/test/fixtures/prismo-url-map.json b/test/fixtures/prismo-url-map.json new file mode 100644 index 000000000..4e2e2fd4a --- /dev/null +++ b/test/fixtures/prismo-url-map.json @@ -0,0 +1,65 @@ +{ +    "id": "https://prismo.news/posts/83#Create", +    "type": "Create", +    "actor": [ +        { +            "type": "Person", +            "id": "https://prismo.news/@mxb" +        } +    ], +    "to": [ +        "https://www.w3.org/ns/activitystreams#Public" +    ], +    "object": { +        "id": "https://prismo.news/posts/83", +        "type": "Article", +        "name": "Introducing: Federated follows!", +        "published": "2018-11-01T07:10:05Z", +        "content": "We are more than thrilled to announce that Prismo now supports federated follows! It means you ca...", +        "url": { +            "type": "Link", +            "mimeType": "text/html", +            "href": "https://prismo.news/posts/83" +        }, +        "votes": 12, +        "attributedTo": [ +            { +                "type": "Person", +                "id": "https://prismo.news/@mxb" +            } +        ], +        "to": [ +            "https://www.w3.org/ns/activitystreams#Public" +        ], +        "tags": [ +            { +                "type": "Hashtag", +                "href": "https://prismo.news/tags/prismo", +                "name": "#prismo" +            }, +            { +                "type": "Hashtag", +                "href": "https://prismo.news/tags/prismodev", +                "name": "#prismodev" +            }, +            { +                "type": "Hashtag", +                "href": "https://prismo.news/tags/meta", +                "name": "#meta" +            } +        ], +        "@context": [ +            "https://www.w3.org/ns/activitystreams", +            "https://w3id.org/security/v1", +            { +                "Hashtag": "as:Hashtag" +            }, +            { +                "votes": { +                    "@id": "as:votes", +                    "@type": "@id" +                } +            } +        ] +    } +} diff --git a/test/notification_test.exs b/test/notification_test.exs index d86b5c1ab..a36ed5bb8 100644 --- a/test/notification_test.exs +++ b/test/notification_test.exs @@ -3,6 +3,7 @@ defmodule Pleroma.NotificationTest do    alias Pleroma.Web.TwitterAPI.TwitterAPI    alias Pleroma.Web.CommonAPI    alias Pleroma.{User, Notification} +  alias Pleroma.Web.ActivityPub.Transmogrifier    import Pleroma.Factory    describe "create_notifications" do @@ -121,6 +122,135 @@ defmodule Pleroma.NotificationTest do      end    end +  describe "set_read_up_to()" do +    test "it sets all notifications as read up to a specified notification ID" do +      user = insert(:user) +      other_user = insert(:user) + +      {:ok, activity} = +        TwitterAPI.create_status(user, %{ +          "status" => "hey @#{other_user.nickname}!" +        }) + +      {:ok, activity} = +        TwitterAPI.create_status(user, %{ +          "status" => "hey again @#{other_user.nickname}!" +        }) + +      [n2, n1] = notifs = Notification.for_user(other_user) +      assert length(notifs) == 2 + +      assert n2.id > n1.id + +      {:ok, activity} = +        TwitterAPI.create_status(user, %{ +          "status" => "hey yet again @#{other_user.nickname}!" +        }) + +      Notification.set_read_up_to(other_user, n2.id) + +      [n3, n2, n1] = notifs = Notification.for_user(other_user) + +      assert n1.seen == true +      assert n2.seen == true +      assert n3.seen == false +    end +  end + +  describe "notification target determination" do +    test "it sends notifications to addressed users in new messages" do +      user = insert(:user) +      other_user = insert(:user) + +      {:ok, activity} = +        CommonAPI.post(user, %{ +          "status" => "hey @#{other_user.nickname}!" +        }) + +      assert other_user in Notification.get_notified_from_activity(activity) +    end + +    test "it sends notifications to mentioned users in new messages" do +      user = insert(:user) +      other_user = insert(:user) + +      create_activity = %{ +        "@context" => "https://www.w3.org/ns/activitystreams", +        "type" => "Create", +        "to" => ["https://www.w3.org/ns/activitystreams#Public"], +        "actor" => user.ap_id, +        "object" => %{ +          "type" => "Note", +          "content" => "message with a Mention tag, but no explicit tagging", +          "tag" => [ +            %{ +              "type" => "Mention", +              "href" => other_user.ap_id, +              "name" => other_user.nickname +            } +          ], +          "attributedTo" => user.ap_id +        } +      } + +      {:ok, activity} = Transmogrifier.handle_incoming(create_activity) + +      assert other_user in Notification.get_notified_from_activity(activity) +    end + +    test "it does not send notifications to users who are only cc in new messages" do +      user = insert(:user) +      other_user = insert(:user) + +      create_activity = %{ +        "@context" => "https://www.w3.org/ns/activitystreams", +        "type" => "Create", +        "to" => ["https://www.w3.org/ns/activitystreams#Public"], +        "cc" => [other_user.ap_id], +        "actor" => user.ap_id, +        "object" => %{ +          "type" => "Note", +          "content" => "hi everyone", +          "attributedTo" => user.ap_id +        } +      } + +      {:ok, activity} = Transmogrifier.handle_incoming(create_activity) + +      assert other_user not in Notification.get_notified_from_activity(activity) +    end + +    test "it does not send notification to mentioned users in likes" do +      user = insert(:user) +      other_user = insert(:user) +      third_user = insert(:user) + +      {:ok, activity_one} = +        CommonAPI.post(user, %{ +          "status" => "hey @#{other_user.nickname}!" +        }) + +      {:ok, activity_two, _} = CommonAPI.favorite(activity_one.id, third_user) + +      assert other_user not in Notification.get_notified_from_activity(activity_two) +    end + +    test "it does not send notification to mentioned users in announces" do +      user = insert(:user) +      other_user = insert(:user) +      third_user = insert(:user) + +      {:ok, activity_one} = +        CommonAPI.post(user, %{ +          "status" => "hey @#{other_user.nickname}!" +        }) + +      {:ok, activity_two, _} = CommonAPI.repeat(activity_one.id, third_user) + +      assert other_user not in Notification.get_notified_from_activity(activity_two) +    end +  end +    describe "notification lifecycle" do      test "liking an activity results in 1 notification, then 0 if the activity is deleted" do        user = insert(:user) diff --git a/test/object_test.exs b/test/object_test.exs index 5eb9b7530..909605560 100644 --- a/test/object_test.exs +++ b/test/object_test.exs @@ -19,4 +19,34 @@ defmodule Pleroma.ObjectTest do        {:error, _result} = Repo.insert(cs)      end    end + +  describe "deletion function" do +    test "deletes an object" do +      object = insert(:note) +      found_object = Object.get_by_ap_id(object.data["id"]) + +      assert object == found_object + +      Object.delete(found_object) + +      found_object = Object.get_by_ap_id(object.data["id"]) + +      refute object == found_object +    end + +    test "ensures cache is cleared for the object" do +      object = insert(:note) +      cached_object = Object.get_cached_by_ap_id(object.data["id"]) + +      assert object == cached_object + +      Object.delete(cached_object) + +      {:ok, nil} = Cachex.get(:object_cache, "object:#{object.data["id"]}") + +      cached_object = Object.get_cached_by_ap_id(object.data["id"]) + +      refute object == cached_object +    end +  end  end diff --git a/test/plugs/http_security_plug_test.exs b/test/plugs/http_security_plug_test.exs new file mode 100644 index 000000000..55040a108 --- /dev/null +++ b/test/plugs/http_security_plug_test.exs @@ -0,0 +1,77 @@ +defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do +  use Pleroma.Web.ConnCase +  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 + +  test "it does not send CSP headers when disabled", %{conn: conn} do +    Config.put([:http_security, :enabled], false) + +    conn = +      conn +      |> get("/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 + +  test "it sends STS headers when enabled", %{conn: conn} do +    Config.put([:http_security, :enabled], true) +    Config.put([:http_security, :sts], true) + +    conn = +      conn +      |> get("/api/v1/instance") + +    refute Conn.get_resp_header(conn, "strict-transport-security") == [] +    refute Conn.get_resp_header(conn, "expect-ct") == [] +  end + +  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 = +      conn +      |> get("/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 = +      conn +      |> get("/api/v1/instance") + +    assert Conn.get_resp_header(conn, "referrer-policy") == ["same-origin"] + +    Config.put([:http_security, :referrer_policy], "no-referrer") + +    conn = +      build_conn() +      |> get("/api/v1/instance") + +    assert Conn.get_resp_header(conn, "referrer-policy") == ["no-referrer"] +  end +end diff --git a/test/support/httpoison_mock.ex b/test/support/httpoison_mock.ex index 75c78d70e..ab964334d 100644 --- a/test/support/httpoison_mock.ex +++ b/test/support/httpoison_mock.ex @@ -3,6 +3,14 @@ defmodule HTTPoisonMock do    def get(url, body \\ [], headers \\ []) +  def get("https://prismo.news/@mxb", _, _) do +    {:ok, +     %Response{ +       status_code: 200, +       body: File.read!("test/fixtures/httpoison_mock/https___prismo.news__mxb.json") +     }} +  end +    def get("https://osada.macgirvin.com/channel/mike", _, _) do      {:ok,       %Response{ diff --git a/test/user_test.exs b/test/user_test.exs index 248c26a3d..7dec3462f 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -487,11 +487,13 @@ defmodule Pleroma.UserTest do      assert addressed in recipients    end -  test ".deactivate deactivates a user" do +  test ".deactivate can de-activate then re-activate a user" do      user = insert(:user)      assert false == !!user.info["deactivated"]      {:ok, user} = User.deactivate(user)      assert true == user.info["deactivated"] +    {:ok, user} = User.deactivate(user, false) +    assert false == !!user.info["deactivated"]    end    test ".delete deactivates a user, all follow relationships and all create activities" do @@ -509,7 +511,7 @@ defmodule Pleroma.UserTest do      {:ok, _, _} = CommonAPI.favorite(activity.id, follower)      {:ok, _, _} = CommonAPI.repeat(activity.id, follower) -    :ok = User.delete(user) +    {:ok, _} = User.delete(user)      followed = Repo.get(User, followed.id)      follower = Repo.get(User, follower.id) @@ -549,4 +551,31 @@ defmodule Pleroma.UserTest do        assert Pleroma.HTML.Scrubber.TwitterText == User.html_filter_policy(user)      end    end + +  describe "caching" do +    test "invalidate_cache works" do +      user = insert(:user) +      user_info = User.get_cached_user_info(user) + +      User.invalidate_cache(user) + +      {:ok, nil} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}") +      {:ok, nil} = Cachex.get(:user_cache, "nickname:#{user.nickname}") +      {:ok, nil} = Cachex.get(:user_cache, "user_info:#{user.id}") +    end + +    test "User.delete() plugs any possible zombie objects" do +      user = insert(:user) + +      {:ok, _} = User.delete(user) + +      {:ok, cached_user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}") + +      assert cached_user != user + +      {:ok, cached_user} = Cachex.get(:user_cache, "nickname:#{user.ap_id}") + +      assert cached_user != user +    end +  end  end diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index e63cd6583..1c24b348c 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -5,6 +5,28 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do    alias Pleroma.{Repo, User}    alias Pleroma.Activity +  describe "/relay" do +    test "with the relay active, it returns the relay user", %{conn: conn} do +      res = +        conn +        |> get(activity_pub_path(conn, :relay)) +        |> json_response(200) + +      assert res["id"] =~ "/relay" +    end + +    test "with the relay disabled, it returns 404", %{conn: conn} do +      Pleroma.Config.put([:instance, :allow_relay], false) + +      res = +        conn +        |> get(activity_pub_path(conn, :relay)) +        |> json_response(404) + +      Pleroma.Config.put([:instance, :allow_relay], true) +    end +  end +    describe "/users/:nickname" do      test "it returns a json representation of the user", %{conn: conn} do        user = insert(:user) diff --git a/test/web/activity_pub/relay_test.exs b/test/web/activity_pub/relay_test.exs new file mode 100644 index 000000000..41d13e055 --- /dev/null +++ b/test/web/activity_pub/relay_test.exs @@ -0,0 +1,11 @@ +defmodule Pleroma.Web.ActivityPub.RelayTest do +  use Pleroma.DataCase + +  alias Pleroma.Web.ActivityPub.Relay + +  test "gets an actor for the relay" do +    user = Relay.get_actor() + +    assert user.ap_id =~ "/relay" +  end +end diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index 6a6f2a44c..0278ef5d1 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -145,6 +145,14 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        assert "test" in data["object"]["tag"]      end +    test "it works for incoming notices with url not being a string (prismo)" do +      data = File.read!("test/fixtures/prismo-url-map.json") |> Poison.decode!() + +      {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) + +      assert data["object"]["url"] == "https://prismo.news/posts/83" +    end +      test "it works for incoming follow requests" do        user = insert(:user) @@ -695,7 +703,9 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"})        {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) -      assert modified["@context"] == "https://www.w3.org/ns/activitystreams" +      assert modified["@context"] == +               Pleroma.Web.ActivityPub.Utils.make_json_ld_header()["@context"] +        assert modified["object"]["conversation"] == modified["context"]      end @@ -733,6 +743,39 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do        assert modified["object"]["inReplyTo"] == "http://gs.example.org:4040/index.php/notice/29"      end + +    test "it strips internal hashtag data" do +      user = insert(:user) + +      {:ok, activity} = CommonAPI.post(user, %{"status" => "#2hu"}) + +      expected_tag = %{ +        "href" => Pleroma.Web.Endpoint.url() <> "/tags/2hu", +        "type" => "Hashtag", +        "name" => "#2hu" +      } + +      {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) + +      assert modified["object"]["tag"] == [expected_tag] +    end + +    test "it strips internal fields" do +      user = insert(:user) + +      {:ok, activity} = CommonAPI.post(user, %{"status" => "#2hu :moominmamma:"}) + +      {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data) + +      assert length(modified["object"]["tag"]) == 2 + +      assert is_nil(modified["object"]["emoji"]) +      assert is_nil(modified["object"]["likes"]) +      assert is_nil(modified["object"]["like_count"]) +      assert is_nil(modified["object"]["announcements"]) +      assert is_nil(modified["object"]["announcement_count"]) +      assert is_nil(modified["object"]["context_id"]) +    end    end    describe "user upgrade" do diff --git a/test/web/activity_pub/views/object_view_test.exs b/test/web/activity_pub/views/object_view_test.exs index 6a1311be7..7e08dff5d 100644 --- a/test/web/activity_pub/views/object_view_test.exs +++ b/test/web/activity_pub/views/object_view_test.exs @@ -13,5 +13,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectViewTest do      assert result["to"] == note.data["to"]      assert result["content"] == note.data["content"]      assert result["type"] == "Note" +    assert result["@context"]    end  end diff --git a/test/web/federator_test.exs b/test/web/federator_test.exs index 09533362a..c709d1181 100644 --- a/test/web/federator_test.exs +++ b/test/web/federator_test.exs @@ -1,6 +1,9 @@  defmodule Pleroma.Web.FederatorTest do    alias Pleroma.Web.Federator +  alias Pleroma.Web.CommonAPI    use Pleroma.DataCase +  import Pleroma.Factory +  import Mock    test "enqueues an element according to priority" do      queue = [%{item: 1, priority: 2}] @@ -17,4 +20,45 @@ defmodule Pleroma.Web.FederatorTest do      assert {2, [%{item: 1, priority: 2}]} = Federator.queue_pop(queue)    end + +  describe "Publish an activity" do +    setup do +      user = insert(:user) +      {:ok, activity} = CommonAPI.post(user, %{"status" => "HI"}) + +      relay_mock = { +        Pleroma.Web.ActivityPub.Relay, +        [], +        [publish: fn _activity -> send(self(), :relay_publish) end] +      } + +      %{activity: activity, relay_mock: relay_mock} +    end + +    test "with relays active, it publishes to the relay", %{ +      activity: activity, +      relay_mock: relay_mock +    } do +      with_mocks([relay_mock]) do +        Federator.handle(:publish, activity) +      end + +      assert_received :relay_publish +    end + +    test "with relays deactivated, it does not publish to the relay", %{ +      activity: activity, +      relay_mock: relay_mock +    } do +      Pleroma.Config.put([:instance, :allow_relay], false) + +      with_mocks([relay_mock]) do +        Federator.handle(:publish, activity) +      end + +      refute_received :relay_publish + +      Pleroma.Config.put([:instance, :allow_relay], true) +    end +  end  end diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index e9deae64d..ad67cae6b 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -178,6 +178,32 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do        |> get("api/v1/timelines/home")      [_s1, _s2] = json_response(res_conn, 200) + +    # Test pagination +    Enum.each(1..20, fn _ -> +      {:ok, _} = +        CommonAPI.post(user_one, %{ +          "status" => "Hi @#{user_two.nickname}!", +          "visibility" => "direct" +        }) +    end) + +    res_conn = +      conn +      |> assign(:user, user_two) +      |> get("api/v1/timelines/direct") + +    statuses = json_response(res_conn, 200) +    assert length(statuses) == 20 + +    res_conn = +      conn +      |> assign(:user, user_two) +      |> get("api/v1/timelines/direct", %{max_id: List.last(statuses)["id"]}) + +    [status] = json_response(res_conn, 200) + +    assert status["url"] != direct.data["id"]    end    test "replying to a status", %{conn: conn} do @@ -198,6 +224,21 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do      assert activity.data["object"]["inReplyToStatusId"] == replied_to.id    end +  test "posting a status with an invalid in_reply_to_id", %{conn: conn} do +    user = insert(:user) + +    conn = +      conn +      |> assign(:user, user) +      |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => ""}) + +    assert %{"content" => "xD", "id" => id} = json_response(conn, 200) + +    activity = Repo.get(Activity, id) + +    assert activity +  end +    test "verify_credentials", %{conn: conn} do      user = insert(:user) @@ -280,6 +321,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do        assert response = json_response(conn, 200)        assert response["phrase"] == filter.phrase        assert response["context"] == filter.context +      assert response["id"] != nil +      assert response["id"] != ""      end      test "fetching a list of filters", %{conn: conn} do @@ -927,11 +970,20 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do        {:ok, [_activity]} =          OStatus.fetch_activity_from_url("https://shitposter.club/notice/2827873") -      conn = +      nconn =          conn          |> get("/api/v1/timelines/tag/2hu") -      assert [%{"id" => id}] = json_response(conn, 200) +      assert [%{"id" => id}] = json_response(nconn, 200) + +      assert id == to_string(activity.id) + +      # works for different capitalization too +      nconn = +        conn +        |> get("/api/v1/timelines/tag/2HU") + +      assert [%{"id" => id}] = json_response(nconn, 200)        assert id == to_string(activity.id)      end) diff --git a/test/web/mastodon_api/status_view_test.exs b/test/web/mastodon_api/status_view_test.exs index b9c019206..31554a07d 100644 --- a/test/web/mastodon_api/status_view_test.exs +++ b/test/web/mastodon_api/status_view_test.exs @@ -7,6 +7,24 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do    alias Pleroma.Web.CommonAPI    import Pleroma.Factory +  test "a note with null content" do +    note = insert(:note_activity) + +    data = +      note.data +      |> put_in(["object", "content"], nil) + +    note = +      note +      |> Map.put(:data, data) + +    user = User.get_cached_by_ap_id(note.data["actor"]) + +    status = StatusView.render("status.json", %{activity: note}) + +    assert status.content == "" +  end +    test "a note activity" do      note = insert(:note_activity)      user = User.get_cached_by_ap_id(note.data["actor"]) diff --git a/test/web/node_info_test.exs b/test/web/node_info_test.exs index d48f40e47..a6376453c 100644 --- a/test/web/node_info_test.exs +++ b/test/web/node_info_test.exs @@ -14,4 +14,36 @@ defmodule Pleroma.Web.NodeInfoTest do      assert user.ap_id in result["metadata"]["staffAccounts"]    end + +  test "returns 404 when federation is disabled" 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" do +    conn +    |> get("/.well-known/nodeinfo") +    |> json_response(200) + +    conn +    |> get("/nodeinfo/2.0.json") +    |> json_response(200) +  end  end diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs index f095e41dd..f95da8b0a 100644 --- a/test/web/ostatus/ostatus_test.exs +++ b/test/web/ostatus/ostatus_test.exs @@ -456,4 +456,28 @@ defmodule Pleroma.Web.OStatusTest do               "https://www.w3.org/ns/activitystreams#Public"             ]    end + +  describe "is_representable?" do +    test "Note objects are representable" do +      note_activity = insert(:note_activity) + +      assert OStatus.is_representable?(note_activity) +    end + +    test "Article objects are not representable" do +      note_activity = insert(:note_activity) + +      note_object = Object.normalize(note_activity.data["object"]) + +      note_data = +        note_object.data +        |> Map.put("type", "Article") + +      cs = Object.change(note_object, %{data: note_data}) +      {:ok, article_object} = Repo.update(cs) + +      # the underlying object is now an Article instead of a note, so this should fail +      refute OStatus.is_representable?(note_activity) +    end +  end  end diff --git a/test/web/plugs/federating_plug_test.exs b/test/web/plugs/federating_plug_test.exs new file mode 100644 index 000000000..1455a1c46 --- /dev/null +++ b/test/web/plugs/federating_plug_test.exs @@ -0,0 +1,33 @@ +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) + +    conn = +      build_conn() +      |> Pleroma.Web.FederatingPlug.call(%{}) + +    assert conn.status == 404 +    assert conn.halted + +    instance = +      Application.get_env(:pleroma, :instance) +      |> Keyword.put(:federating, true) + +    Application.put_env(:pleroma, :instance, instance) +  end + +  test "does nothing when federating is enabled" do +    conn = +      build_conn() +      |> Pleroma.Web.FederatingPlug.call(%{}) + +    refute conn.status +    refute conn.halted +  end +end diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs index 87bcdaf71..788e3a6eb 100644 --- a/test/web/twitter_api/twitter_api_controller_test.exs +++ b/test/web/twitter_api/twitter_api_controller_test.exs @@ -100,6 +100,56 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do        assert length(response) == 10      end + +    test "returns 403 to unauthenticated request when the instance is not public" do +      instance = +        Application.get_env(:pleroma, :instance) +        |> Keyword.put(:public, false) + +      Application.put_env(:pleroma, :instance, instance) + +      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) +    end + +    test "returns 200 to unauthenticated request when the instance is public" do +      conn +      |> get("/api/statuses/public_timeline.json") +      |> json_response(200) +    end +  end + +  describe "GET /statuses/public_and_external_timeline.json" do +    test "returns 403 to unauthenticated request when the instance is not public" do +      instance = +        Application.get_env(:pleroma, :instance) +        |> Keyword.put(:public, false) + +      Application.put_env(:pleroma, :instance, instance) + +      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) +    end + +    test "returns 200 to unauthenticated request when the instance is public" do +      conn +      |> get("/api/statuses/public_and_external_timeline.json") +      |> json_response(200) +    end    end    describe "GET /statuses/show/:id.json" do @@ -221,6 +271,36 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do      end    end +  describe "GET /statuses/dm_timeline.json" do +    test "it show direct messages", %{conn: conn} do +      user_one = insert(:user) +      user_two = insert(:user) + +      {:ok, user_two} = User.follow(user_two, user_one) + +      {:ok, direct} = +        CommonAPI.post(user_one, %{ +          "status" => "Hi @#{user_two.nickname}!", +          "visibility" => "direct" +        }) + +      {:ok, _follower_only} = +        CommonAPI.post(user_one, %{ +          "status" => "Hi @#{user_two.nickname}!", +          "visibility" => "private" +        }) + +      # Only direct should be visible here +      res_conn = +        conn +        |> assign(:user, user_two) +        |> get("/api/statuses/dm_timeline.json") + +      [status] = json_response(res_conn, 200) +      assert status["id"] == direct.id +    end +  end +    describe "GET /statuses/mentions.json" do      setup [:valid_user] @@ -281,6 +361,56 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do      end    end +  describe "POST /api/qvitter/statuses/notifications/read" do +    setup [:valid_user] + +    test "without valid credentials", %{conn: conn} do +      conn = post(conn, "/api/qvitter/statuses/notifications/read", %{"latest_id" => 1_234_567}) +      assert json_response(conn, 403) == %{"error" => "Invalid credentials."} +    end + +    test "with credentials, without any params", %{conn: conn, user: current_user} do +      conn = +        conn +        |> with_credentials(current_user.nickname, "test") +        |> post("/api/qvitter/statuses/notifications/read") + +      assert json_response(conn, 400) == %{ +               "error" => "You need to specify latest_id", +               "request" => "/api/qvitter/statuses/notifications/read" +             } +    end + +    test "with credentials, with params", %{conn: conn, user: current_user} do +      other_user = insert(:user) + +      {:ok, _activity} = +        ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user}) + +      response_conn = +        conn +        |> with_credentials(current_user.nickname, "test") +        |> get("/api/qvitter/statuses/notifications.json") + +      [notification] = response = json_response(response_conn, 200) + +      assert length(response) == 1 + +      assert notification["is_seen"] == 0 + +      response_conn = +        conn +        |> with_credentials(current_user.nickname, "test") +        |> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]}) + +      [notification] = response = json_response(response_conn, 200) + +      assert length(response) == 1 + +      assert notification["is_seen"] == 1 +    end +  end +    describe "GET /statuses/user_timeline.json" do      setup [:valid_user] diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs index 6486540f8..8b9920bd9 100644 --- a/test/web/twitter_api/twitter_api_test.exs +++ b/test/web/twitter_api/twitter_api_test.exs @@ -48,7 +48,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do               "https://www.w3.org/ns/activitystreams#Public"             ) -    assert Enum.member?(get_in(activity.data, ["cc"]), "shp") +    assert Enum.member?(get_in(activity.data, ["to"]), "shp")      assert activity.local == true      assert %{"moominmamma" => "http://localhost:4001/finmoji/128px/moominmamma-128.png"} = diff --git a/test/web/twitter_api/views/user_view_test.exs b/test/web/twitter_api/views/user_view_test.exs index 2deb22fb1..2c583c0d3 100644 --- a/test/web/twitter_api/views/user_view_test.exs +++ b/test/web/twitter_api/views/user_view_test.exs @@ -13,6 +13,13 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do      [user: user]    end +  test "A user with only a nickname", %{user: user} do +    user = %{user | name: nil, nickname: "scarlett@catgirl.science"} +    represented = UserView.render("show.json", %{user: user}) +    assert represented["name"] == user.nickname +    assert represented["name_html"] == user.nickname +  end +    test "A user with an avatar object", %{user: user} do      image = "image"      user = %{user | avatar: %{"url" => [%{"href" => image}]}} | 
