diff options
Diffstat (limited to 'test/web/ostatus')
| -rw-r--r-- | test/web/ostatus/ostatus_controller_test.exs | 602 | ||||
| -rw-r--r-- | test/web/ostatus/ostatus_test.exs | 56 | 
2 files changed, 543 insertions, 115 deletions
| diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs index bb7648bdd..9f756effb 100644 --- a/test/web/ostatus/ostatus_controller_test.exs +++ b/test/web/ostatus/ostatus_controller_test.exs @@ -101,160 +101,538 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do      assert response(conn, 404)    end -  test "gets an object", %{conn: conn} do -    note_activity = insert(:note_activity) -    object = Object.normalize(note_activity) -    user = User.get_cached_by_ap_id(note_activity.data["actor"]) -    [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"])) -    url = "/objects/#{uuid}" +  describe "GET object/2" do +    test "gets an object", %{conn: conn} do +      note_activity = insert(:note_activity) +      object = Object.normalize(note_activity) +      user = User.get_cached_by_ap_id(note_activity.data["actor"]) +      [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"])) +      url = "/objects/#{uuid}" + +      conn = +        conn +        |> put_req_header("accept", "application/xml") +        |> get(url) + +      expected = +        ActivityRepresenter.to_simple_form(note_activity, user, true) +        |> ActivityRepresenter.wrap_with_entry() +        |> :xmerl.export_simple(:xmerl_xml) +        |> to_string + +      assert response(conn, 200) == expected +    end + +    test "redirects to /notice/id for html format", %{conn: conn} do +      note_activity = insert(:note_activity) +      object = Object.normalize(note_activity) +      [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"])) +      url = "/objects/#{uuid}" + +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get(url) + +      assert redirected_to(conn) == "/notice/#{note_activity.id}" +    end + +    test "500s when user not found", %{conn: conn} do +      note_activity = insert(:note_activity) +      object = Object.normalize(note_activity) +      user = User.get_cached_by_ap_id(note_activity.data["actor"]) +      User.invalidate_cache(user) +      Pleroma.Repo.delete(user) +      [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"])) +      url = "/objects/#{uuid}" + +      conn = +        conn +        |> put_req_header("accept", "application/xml") +        |> get(url) + +      assert response(conn, 500) == ~S({"error":"Something went wrong"}) +    end + +    test "404s on private objects", %{conn: conn} do +      note_activity = insert(:direct_note_activity) +      object = Object.normalize(note_activity) +      [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"])) + +      conn +      |> get("/objects/#{uuid}") +      |> response(404) +    end + +    test "404s on nonexisting objects", %{conn: conn} do +      conn +      |> get("/objects/123") +      |> response(404) +    end +  end + +  describe "GET activity/2" do +    test "gets an activity in xml format", %{conn: conn} do +      note_activity = insert(:note_activity) +      [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) -    conn =        conn        |> put_req_header("accept", "application/xml") -      |> get(url) +      |> get("/activities/#{uuid}") +      |> response(200) +    end -    expected = -      ActivityRepresenter.to_simple_form(note_activity, user, true) -      |> ActivityRepresenter.wrap_with_entry() -      |> :xmerl.export_simple(:xmerl_xml) -      |> to_string +    test "redirects to /notice/id for html format", %{conn: conn} do +      note_activity = insert(:note_activity) +      [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) -    assert response(conn, 200) == expected -  end +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/activities/#{uuid}") -  test "404s on private objects", %{conn: conn} do -    note_activity = insert(:direct_note_activity) -    object = Object.normalize(note_activity) -    [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"])) +      assert redirected_to(conn) == "/notice/#{note_activity.id}" +    end -    conn -    |> get("/objects/#{uuid}") -    |> response(404) -  end +    test "505s when user not found", %{conn: conn} do +      note_activity = insert(:note_activity) +      [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) +      user = User.get_cached_by_ap_id(note_activity.data["actor"]) +      User.invalidate_cache(user) +      Pleroma.Repo.delete(user) -  test "404s on nonexisting objects", %{conn: conn} do -    conn -    |> get("/objects/123") -    |> response(404) -  end +      conn = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/activities/#{uuid}") -  test "gets an activity in xml format", %{conn: conn} do -    note_activity = insert(:note_activity) -    [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) +      assert response(conn, 500) == ~S({"error":"Something went wrong"}) +    end -    conn -    |> put_req_header("accept", "application/xml") -    |> get("/activities/#{uuid}") -    |> response(200) -  end +    test "404s on deleted objects", %{conn: conn} do +      note_activity = insert(:note_activity) +      object = Object.normalize(note_activity) +      [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"])) -  test "404s on deleted objects", %{conn: conn} do -    note_activity = insert(:note_activity) -    object = Object.normalize(note_activity) -    [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"])) +      conn +      |> put_req_header("accept", "application/xml") +      |> get("/objects/#{uuid}") +      |> response(200) -    conn -    |> put_req_header("accept", "application/xml") -    |> get("/objects/#{uuid}") -    |> response(200) +      Object.delete(object) -    Object.delete(object) +      conn +      |> put_req_header("accept", "application/xml") +      |> get("/objects/#{uuid}") +      |> response(404) +    end -    conn -    |> put_req_header("accept", "application/xml") -    |> get("/objects/#{uuid}") -    |> response(404) -  end +    test "404s on private activities", %{conn: conn} do +      note_activity = insert(:direct_note_activity) +      [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) -  test "404s on private activities", %{conn: conn} do -    note_activity = insert(:direct_note_activity) -    [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) +      conn +      |> get("/activities/#{uuid}") +      |> response(404) +    end -    conn -    |> get("/activities/#{uuid}") -    |> response(404) -  end +    test "404s on nonexistent activities", %{conn: conn} do +      conn +      |> get("/activities/123") +      |> response(404) +    end -  test "404s on nonexistent activities", %{conn: conn} do -    conn -    |> get("/activities/123") -    |> response(404) -  end +    test "gets an activity in AS2 format", %{conn: conn} do +      note_activity = insert(:note_activity) +      [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) +      url = "/activities/#{uuid}" -  test "gets a notice in xml format", %{conn: conn} do -    note_activity = insert(:note_activity) +      conn = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get(url) -    conn -    |> get("/notice/#{note_activity.id}") -    |> response(200) +      assert json_response(conn, 200) +    end    end -  test "gets a notice in AS2 format", %{conn: conn} do -    note_activity = insert(:note_activity) +  describe "GET notice/2" do +    test "gets a notice in xml format", %{conn: conn} do +      note_activity = insert(:note_activity) -    conn -    |> put_req_header("accept", "application/activity+json") -    |> get("/notice/#{note_activity.id}") -    |> json_response(200) -  end +      conn +      |> get("/notice/#{note_activity.id}") +      |> response(200) +    end -  test "only gets a notice in AS2 format for Create messages", %{conn: conn} do -    note_activity = insert(:note_activity) -    url = "/notice/#{note_activity.id}" +    test "gets a notice in AS2 format", %{conn: conn} do +      note_activity = insert(:note_activity) -    conn =        conn        |> put_req_header("accept", "application/activity+json") -      |> get(url) +      |> get("/notice/#{note_activity.id}") +      |> json_response(200) +    end -    assert json_response(conn, 200) +    test "500s when actor not found", %{conn: conn} do +      note_activity = insert(:note_activity) +      user = User.get_cached_by_ap_id(note_activity.data["actor"]) +      User.invalidate_cache(user) +      Pleroma.Repo.delete(user) -    user = insert(:user) +      conn = +        conn +        |> get("/notice/#{note_activity.id}") -    {:ok, like_activity, _} = CommonAPI.favorite(note_activity.id, user) -    url = "/notice/#{like_activity.id}" +      assert response(conn, 500) == ~S({"error":"Something went wrong"}) +    end -    assert like_activity.data["type"] == "Like" +    test "only gets a notice in AS2 format for Create messages", %{conn: conn} do +      note_activity = insert(:note_activity) +      url = "/notice/#{note_activity.id}" -    conn = -      build_conn() -      |> put_req_header("accept", "application/activity+json") -      |> get(url) +      conn = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get(url) -    assert response(conn, 404) -  end +      assert json_response(conn, 200) -  test "gets an activity in AS2 format", %{conn: conn} do -    note_activity = insert(:note_activity) -    [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) -    url = "/activities/#{uuid}" +      user = insert(:user) -    conn = -      conn -      |> put_req_header("accept", "application/activity+json") -      |> get(url) +      {:ok, like_activity, _} = CommonAPI.favorite(note_activity.id, user) +      url = "/notice/#{like_activity.id}" + +      assert like_activity.data["type"] == "Like" + +      conn = +        build_conn() +        |> put_req_header("accept", "application/activity+json") +        |> get(url) + +      assert response(conn, 404) +    end + +    test "render html for redirect for html format", %{conn: conn} do +      note_activity = insert(:note_activity) + +      resp = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/notice/#{note_activity.id}") +        |> response(200) + +      assert resp =~ +               "<meta content=\"#{Pleroma.Web.base_url()}/notice/#{note_activity.id}\" property=\"og:url\">" + +      user = insert(:user) + +      {:ok, like_activity, _} = CommonAPI.favorite(note_activity.id, user) + +      assert like_activity.data["type"] == "Like" + +      resp = +        conn +        |> put_req_header("accept", "text/html") +        |> get("/notice/#{like_activity.id}") +        |> response(200) + +      assert resp =~ "<!--server-generated-meta-->" +    end + +    test "404s a private notice", %{conn: conn} do +      note_activity = insert(:direct_note_activity) +      url = "/notice/#{note_activity.id}" + +      conn = +        conn +        |> get(url) + +      assert response(conn, 404) +    end + +    test "404s a nonexisting notice", %{conn: conn} do +      url = "/notice/123" -    assert json_response(conn, 200) +      conn = +        conn +        |> get(url) + +      assert response(conn, 404) +    end    end -  test "404s a private notice", %{conn: conn} do -    note_activity = insert(:direct_note_activity) -    url = "/notice/#{note_activity.id}" +  describe "feed_redirect" do +    test "undefined format. it redirects to feed", %{conn: conn} do +      note_activity = insert(:note_activity) +      user = User.get_cached_by_ap_id(note_activity.data["actor"]) + +      response = +        conn +        |> put_req_header("accept", "application/xml") +        |> get("/users/#{user.nickname}") +        |> response(302) + +      assert response == +               "<html><body>You are being <a href=\"#{Pleroma.Web.base_url()}/users/#{ +                 user.nickname +               }/feed.atom\">redirected</a>.</body></html>" +    end -    conn = -      conn -      |> get(url) +    test "undefined format. it returns error when user not found", %{conn: conn} do +      response = +        conn +        |> put_req_header("accept", "application/xml") +        |> get("/users/jimm") +        |> response(404) -    assert response(conn, 404) +      assert response == ~S({"error":"Not found"}) +    end + +    test "activity+json format. it redirects on actual feed of user", %{conn: conn} do +      note_activity = insert(:note_activity) +      user = User.get_cached_by_ap_id(note_activity.data["actor"]) + +      response = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get("/users/#{user.nickname}") +        |> json_response(200) + +      assert response["endpoints"] == %{ +               "oauthAuthorizationEndpoint" => "#{Pleroma.Web.base_url()}/oauth/authorize", +               "oauthRegistrationEndpoint" => "#{Pleroma.Web.base_url()}/api/v1/apps", +               "oauthTokenEndpoint" => "#{Pleroma.Web.base_url()}/oauth/token", +               "sharedInbox" => "#{Pleroma.Web.base_url()}/inbox" +             } + +      assert response["@context"] == [ +               "https://www.w3.org/ns/activitystreams", +               "http://localhost:4001/schemas/litepub-0.1.jsonld", +               %{"@language" => "und"} +             ] + +      assert Map.take(response, [ +               "followers", +               "following", +               "id", +               "inbox", +               "manuallyApprovesFollowers", +               "name", +               "outbox", +               "preferredUsername", +               "summary", +               "tag", +               "type", +               "url" +             ]) == %{ +               "followers" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/followers", +               "following" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/following", +               "id" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}", +               "inbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/inbox", +               "manuallyApprovesFollowers" => false, +               "name" => user.name, +               "outbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/outbox", +               "preferredUsername" => user.nickname, +               "summary" => user.bio, +               "tag" => [], +               "type" => "Person", +               "url" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}" +             } +    end + +    test "activity+json format. it returns error whe use not found", %{conn: conn} do +      response = +        conn +        |> put_req_header("accept", "application/activity+json") +        |> get("/users/jimm") +        |> json_response(404) + +      assert response == "Not found" +    end + +    test "json format. it redirects on actual feed of user", %{conn: conn} do +      note_activity = insert(:note_activity) +      user = User.get_cached_by_ap_id(note_activity.data["actor"]) + +      response = +        conn +        |> put_req_header("accept", "application/json") +        |> get("/users/#{user.nickname}") +        |> json_response(200) + +      assert response["endpoints"] == %{ +               "oauthAuthorizationEndpoint" => "#{Pleroma.Web.base_url()}/oauth/authorize", +               "oauthRegistrationEndpoint" => "#{Pleroma.Web.base_url()}/api/v1/apps", +               "oauthTokenEndpoint" => "#{Pleroma.Web.base_url()}/oauth/token", +               "sharedInbox" => "#{Pleroma.Web.base_url()}/inbox" +             } + +      assert response["@context"] == [ +               "https://www.w3.org/ns/activitystreams", +               "http://localhost:4001/schemas/litepub-0.1.jsonld", +               %{"@language" => "und"} +             ] + +      assert Map.take(response, [ +               "followers", +               "following", +               "id", +               "inbox", +               "manuallyApprovesFollowers", +               "name", +               "outbox", +               "preferredUsername", +               "summary", +               "tag", +               "type", +               "url" +             ]) == %{ +               "followers" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/followers", +               "following" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/following", +               "id" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}", +               "inbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/inbox", +               "manuallyApprovesFollowers" => false, +               "name" => user.name, +               "outbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/outbox", +               "preferredUsername" => user.nickname, +               "summary" => user.bio, +               "tag" => [], +               "type" => "Person", +               "url" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}" +             } +    end + +    test "json format. it returns error whe use not found", %{conn: conn} do +      response = +        conn +        |> put_req_header("accept", "application/json") +        |> get("/users/jimm") +        |> json_response(404) + +      assert response == "Not found" +    end + +    test "html format. it redirects on actual feed of user", %{conn: conn} do +      note_activity = insert(:note_activity) +      user = User.get_cached_by_ap_id(note_activity.data["actor"]) + +      response = +        conn +        |> get("/users/#{user.nickname}") +        |> response(200) + +      assert response == +               Fallback.RedirectController.redirector_with_meta( +                 conn, +                 %{user: user} +               ).resp_body +    end + +    test "html format. it returns error when user not found", %{conn: conn} do +      response = +        conn +        |> get("/users/jimm") +        |> json_response(404) + +      assert response == %{"error" => "Not found"} +    end    end -  test "404s a nonexisting notice", %{conn: conn} do -    url = "/notice/123" +  describe "GET /notice/:id/embed_player" do +    test "render embed player", %{conn: conn} do +      note_activity = insert(:note_activity) +      object = Pleroma.Object.normalize(note_activity) + +      object_data = +        Map.put(object.data, "attachment", [ +          %{ +            "url" => [ +              %{ +                "href" => +                  "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4", +                "mediaType" => "video/mp4", +                "type" => "Link" +              } +            ] +          } +        ]) + +      object +      |> Ecto.Changeset.change(data: object_data) +      |> Pleroma.Repo.update() + +      conn = +        conn +        |> get("/notice/#{note_activity.id}/embed_player") + +      assert Plug.Conn.get_resp_header(conn, "x-frame-options") == ["ALLOW"] + +      assert Plug.Conn.get_resp_header( +               conn, +               "content-security-policy" +             ) == [ +               "default-src 'none';style-src 'self' 'unsafe-inline';img-src 'self' data: https:; media-src 'self' https:;" +             ] + +      assert response(conn, 200) =~ +               "<video controls loop><source src=\"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4\" type=\"video/mp4\">Your browser does not support video/mp4 playback.</video>" +    end -    conn = -      conn -      |> get(url) +    test "404s when activity isn't create", %{conn: conn} do +      note_activity = insert(:note_activity, data_attrs: %{"type" => "Like"}) -    assert response(conn, 404) +      assert conn +             |> get("/notice/#{note_activity.id}/embed_player") +             |> response(404) +    end + +    test "404s when activity is direct message", %{conn: conn} do +      note_activity = insert(:note_activity, data_attrs: %{"directMessage" => true}) + +      assert conn +             |> get("/notice/#{note_activity.id}/embed_player") +             |> response(404) +    end + +    test "404s when attachment is empty", %{conn: conn} do +      note_activity = insert(:note_activity) +      object = Pleroma.Object.normalize(note_activity) +      object_data = Map.put(object.data, "attachment", []) + +      object +      |> Ecto.Changeset.change(data: object_data) +      |> Pleroma.Repo.update() + +      assert conn +             |> get("/notice/#{note_activity.id}/embed_player") +             |> response(404) +    end + +    test "404s when attachment isn't audio or video", %{conn: conn} do +      note_activity = insert(:note_activity) +      object = Pleroma.Object.normalize(note_activity) + +      object_data = +        Map.put(object.data, "attachment", [ +          %{ +            "url" => [ +              %{ +                "href" => "https://peertube.moe/static/webseed/480.jpg", +                "mediaType" => "image/jpg", +                "type" => "Link" +              } +            ] +          } +        ]) + +      object +      |> Ecto.Changeset.change(data: object_data) +      |> Pleroma.Repo.update() + +      assert conn +             |> get("/notice/#{note_activity.id}/embed_player") +             |> response(404) +    end    end  end diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs index 4e8f3a0fc..f8d389020 100644 --- a/test/web/ostatus/ostatus_test.exs +++ b/test/web/ostatus/ostatus_test.exs @@ -326,6 +326,14 @@ defmodule Pleroma.Web.OStatusTest do      assert User.following?(follower, followed)    end +  test "refuse following over OStatus if the followed's account is locked" do +    incoming = File.read!("test/fixtures/follow.xml") +    _user = insert(:user, info: %{locked: true}, ap_id: "https://pawoo.net/users/pekorino") + +    {:ok, [{:error, "It's not possible to follow locked accounts over OStatus"}]} = +      OStatus.handle_incoming(incoming) +  end +    test "handle incoming unfollows with existing follow" do      incoming_follow = File.read!("test/fixtures/follow.xml")      {:ok, [_activity]} = OStatus.handle_incoming(incoming_follow) @@ -426,7 +434,7 @@ defmodule Pleroma.Web.OStatusTest do                 }      end -    test "find_make_or_update_user takes an author element and returns an updated user" do +    test "find_make_or_update_actor takes an author element and returns an updated user" do        uri = "https://social.heldscal.la/user/23211"        {:ok, user} = OStatus.find_or_make_user(uri) @@ -439,14 +447,56 @@ defmodule Pleroma.Web.OStatusTest do        doc = XML.parse_document(File.read!("test/fixtures/23211.atom"))        [author] = :xmerl_xpath.string('//author[1]', doc) -      {:ok, user} = OStatus.find_make_or_update_user(author) +      {:ok, user} = OStatus.find_make_or_update_actor(author)        assert user.avatar["type"] == "Image"        assert user.name == old_name        assert user.bio == old_bio -      {:ok, user_again} = OStatus.find_make_or_update_user(author) +      {:ok, user_again} = OStatus.find_make_or_update_actor(author)        assert user_again == user      end + +    test "find_or_make_user disallows protocol downgrade" do +      user = insert(:user, %{local: true}) +      {:ok, user} = OStatus.find_or_make_user(user.ap_id) + +      assert User.ap_enabled?(user) + +      user = +        insert(:user, %{ +          ap_id: "https://social.heldscal.la/user/23211", +          info: %{ap_enabled: true}, +          local: false +        }) + +      assert User.ap_enabled?(user) + +      {:ok, user} = OStatus.find_or_make_user(user.ap_id) +      assert User.ap_enabled?(user) +    end + +    test "find_make_or_update_actor disallows protocol downgrade" do +      user = insert(:user, %{local: true}) +      {:ok, user} = OStatus.find_or_make_user(user.ap_id) + +      assert User.ap_enabled?(user) + +      user = +        insert(:user, %{ +          ap_id: "https://social.heldscal.la/user/23211", +          info: %{ap_enabled: true}, +          local: false +        }) + +      assert User.ap_enabled?(user) + +      {:ok, user} = OStatus.find_or_make_user(user.ap_id) +      assert User.ap_enabled?(user) + +      doc = XML.parse_document(File.read!("test/fixtures/23211.atom")) +      [author] = :xmerl_xpath.string('//author[1]', doc) +      {:error, :invalid_protocol} = OStatus.find_make_or_update_actor(author) +    end    end    describe "gathering user info from a user id" do | 
