diff options
Diffstat (limited to 'test/web/mastodon_api')
33 files changed, 2440 insertions, 1167 deletions
diff --git a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs index 82d9e7d2f..fdb6d4c5d 100644 --- a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs +++ b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do @@ -9,10 +9,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do use Pleroma.Web.ConnCase import Pleroma.Factory - clear_config([:instance, :max_account_fields]) + + setup do: clear_config([:instance, :max_account_fields]) describe "updating credentials" do setup do: oauth_access(["write:accounts"]) + setup :request_content_type test "sets user settings in a generic way", %{conn: conn} do res_conn = @@ -24,7 +26,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do } }) - assert user_data = json_response(res_conn, 200) + assert user_data = json_response_and_validate_schema(res_conn, 200) assert user_data["pleroma"]["settings_store"] == %{"pleroma_fe" => %{"theme" => "bla"}} user = Repo.get(User, user_data["id"]) @@ -40,7 +42,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do } }) - assert user_data = json_response(res_conn, 200) + assert user_data = json_response_and_validate_schema(res_conn, 200) assert user_data["pleroma"]["settings_store"] == %{ @@ -61,7 +63,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do } }) - assert user_data = json_response(res_conn, 200) + assert user_data = json_response_and_validate_schema(res_conn, 200) assert user_data["pleroma"]["settings_store"] == %{ @@ -75,21 +77,21 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do conn = patch(conn, "/api/v1/accounts/update_credentials", %{ - "note" => "I drink #cofe with @#{user2.nickname}" + "note" => "I drink #cofe with @#{user2.nickname}\n\nsuya.." }) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["note"] == - ~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe">#cofe</a> with <span class="h-card"><a data-user="#{ + ~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe">#cofe</a> with <span class="h-card"><a class="u-url mention" data-user="#{ user2.id - }" class="u-url mention" href="#{user2.ap_id}" rel="ugc">@<span>#{user2.nickname}</span></a></span>) + }" href="#{user2.ap_id}" rel="ugc">@<span>#{user2.nickname}</span></a></span><br/><br/>suya..) end test "updates the user's locking status", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{locked: "true"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["locked"] == true end @@ -99,24 +101,36 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do conn = patch(conn, "/api/v1/accounts/update_credentials", %{allow_following_move: "false"}) assert refresh_record(user).allow_following_move == false - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["pleroma"]["allow_following_move"] == false end test "updates the user's default scope", %{conn: conn} do - conn = patch(conn, "/api/v1/accounts/update_credentials", %{default_scope: "cofe"}) + conn = patch(conn, "/api/v1/accounts/update_credentials", %{default_scope: "unlisted"}) - assert user_data = json_response(conn, 200) - assert user_data["source"]["privacy"] == "cofe" + assert user_data = json_response_and_validate_schema(conn, 200) + assert user_data["source"]["privacy"] == "unlisted" end test "updates the user's hide_followers status", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_followers: "true"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["pleroma"]["hide_followers"] == true end + test "updates the user's discoverable status", %{conn: conn} do + assert %{"source" => %{"pleroma" => %{"discoverable" => true}}} = + conn + |> patch("/api/v1/accounts/update_credentials", %{discoverable: "true"}) + |> json_response_and_validate_schema(:ok) + + assert %{"source" => %{"pleroma" => %{"discoverable" => false}}} = + conn + |> patch("/api/v1/accounts/update_credentials", %{discoverable: "false"}) + |> json_response_and_validate_schema(:ok) + end + test "updates the user's hide_followers_count and hide_follows_count", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{ @@ -124,7 +138,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do hide_follows_count: "true" }) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["pleroma"]["hide_followers_count"] == true assert user_data["pleroma"]["hide_follows_count"] == true end @@ -133,7 +147,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do response = conn |> patch("/api/v1/accounts/update_credentials", %{skip_thread_containment: "true"}) - |> json_response(200) + |> json_response_and_validate_schema(200) assert response["pleroma"]["skip_thread_containment"] == true assert refresh_record(user).skip_thread_containment @@ -142,28 +156,28 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do test "updates the user's hide_follows status", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_follows: "true"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["pleroma"]["hide_follows"] == true end test "updates the user's hide_favorites status", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_favorites: "true"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["pleroma"]["hide_favorites"] == true end test "updates the user's show_role status", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{show_role: "false"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["source"]["pleroma"]["show_role"] == false end test "updates the user's no_rich_text status", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{no_rich_text: "true"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["source"]["pleroma"]["no_rich_text"] == true end @@ -171,7 +185,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do conn = patch(conn, "/api/v1/accounts/update_credentials", %{"display_name" => "markorepairs"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["display_name"] == "markorepairs" end @@ -184,7 +198,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do conn = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar}) - assert user_response = json_response(conn, 200) + assert user_response = json_response_and_validate_schema(conn, 200) assert user_response["avatar"] != User.avatar_url(user) end @@ -197,7 +211,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do conn = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header}) - assert user_response = json_response(conn, 200) + assert user_response = json_response_and_validate_schema(conn, 200) assert user_response["header"] != User.banner_url(user) end @@ -213,7 +227,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do "pleroma_background_image" => new_header }) - assert user_response = json_response(conn, 200) + assert user_response = json_response_and_validate_schema(conn, 200) assert user_response["pleroma"]["background_image"] end @@ -224,14 +238,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do for token <- [token1, token2] do conn = build_conn() + |> put_req_header("content-type", "multipart/form-data") |> put_req_header("authorization", "Bearer #{token.token}") |> patch("/api/v1/accounts/update_credentials", %{}) if token == token1 do assert %{"error" => "Insufficient permissions: write:accounts."} == - json_response(conn, 403) + json_response_and_validate_schema(conn, 403) else - assert json_response(conn, 200) + assert json_response_and_validate_schema(conn, 200) end end end @@ -246,11 +261,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do "display_name" => name }) - assert json_response(ret_conn, 200) + assert json_response_and_validate_schema(ret_conn, 200) conn = get(conn, "/api/v1/accounts/#{user.id}") - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["note"] == note assert user_data["display_name"] == name @@ -260,17 +275,20 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do test "update fields", %{conn: conn} do fields = [ %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "<script>bar</script>"}, - %{"name" => "link", "value" => "cofe.io"} + %{"name" => "link.io", "value" => "cofe.io"} ] account_data = conn |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) - |> json_response(200) + |> json_response_and_validate_schema(200) assert account_data["fields"] == [ %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "bar"}, - %{"name" => "link", "value" => ~S(<a href="http://cofe.io" rel="ugc">cofe.io</a>)} + %{ + "name" => "link.io", + "value" => ~S(<a href="http://cofe.io" rel="ugc">cofe.io</a>) + } ] assert account_data["source"]["fields"] == [ @@ -278,14 +296,16 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do "name" => "<a href=\"http://google.com\">foo</a>", "value" => "<script>bar</script>" }, - %{"name" => "link", "value" => "cofe.io"} + %{"name" => "link.io", "value" => "cofe.io"} ] + end + test "update fields via x-www-form-urlencoded", %{conn: conn} do fields = [ "fields_attributes[1][name]=link", - "fields_attributes[1][value]=cofe.io", - "fields_attributes[0][name]=<a href=\"http://google.com\">foo</a>", + "fields_attributes[1][value]=http://cofe.io", + "fields_attributes[0][name]=foo", "fields_attributes[0][value]=bar" ] |> Enum.join("&") @@ -294,67 +314,70 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do conn |> put_req_header("content-type", "application/x-www-form-urlencoded") |> patch("/api/v1/accounts/update_credentials", fields) - |> json_response(200) + |> json_response_and_validate_schema(200) assert account["fields"] == [ - %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "bar"}, - %{"name" => "link", "value" => ~S(<a href="http://cofe.io" rel="ugc">cofe.io</a>)} + %{"name" => "foo", "value" => "bar"}, + %{ + "name" => "link", + "value" => ~S(<a href="http://cofe.io" rel="ugc">http://cofe.io</a>) + } ] assert account["source"]["fields"] == [ - %{ - "name" => "<a href=\"http://google.com\">foo</a>", - "value" => "bar" - }, - %{"name" => "link", "value" => "cofe.io"} + %{"name" => "foo", "value" => "bar"}, + %{"name" => "link", "value" => "http://cofe.io"} ] + end + + test "update fields with empty name", %{conn: conn} do + fields = [ + %{"name" => "foo", "value" => ""}, + %{"name" => "", "value" => "bar"} + ] + account = + conn + |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) + |> json_response_and_validate_schema(200) + + assert account["fields"] == [ + %{"name" => "foo", "value" => ""} + ] + end + + test "update fields when invalid request", %{conn: conn} do name_limit = Pleroma.Config.get([:instance, :account_field_name_length]) value_limit = Pleroma.Config.get([:instance, :account_field_value_length]) + long_name = Enum.map(0..name_limit, fn _ -> "x" end) |> Enum.join() long_value = Enum.map(0..value_limit, fn _ -> "x" end) |> Enum.join() - fields = [%{"name" => "<b>foo<b>", "value" => long_value}] + fields = [%{"name" => "foo", "value" => long_value}] assert %{"error" => "Invalid request"} == conn |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) - |> json_response(403) - - long_name = Enum.map(0..name_limit, fn _ -> "x" end) |> Enum.join() + |> json_response_and_validate_schema(403) fields = [%{"name" => long_name, "value" => "bar"}] assert %{"error" => "Invalid request"} == conn |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) - |> json_response(403) + |> json_response_and_validate_schema(403) Pleroma.Config.put([:instance, :max_account_fields], 1) fields = [ - %{"name" => "<b>foo<b>", "value" => "<i>bar</i>"}, + %{"name" => "foo", "value" => "bar"}, %{"name" => "link", "value" => "cofe.io"} ] assert %{"error" => "Invalid request"} == conn |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) - |> json_response(403) - - fields = [ - %{"name" => "foo", "value" => ""}, - %{"name" => "", "value" => "bar"} - ] - - account = - conn - |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) - |> json_response(200) - - assert account["fields"] == [ - %{"name" => "foo", "value" => ""} - ] + |> json_response_and_validate_schema(403) end end end diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs index 8625bb9cf..280bd6aca 100644 --- a/test/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/web/mastodon_api/controllers/account_controller_test.exs @@ -1,10 +1,11 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do use Pleroma.Web.ConnCase + alias Pleroma.Config alias Pleroma.Repo alias Pleroma.User alias Pleroma.Web.ActivityPub.ActivityPub @@ -15,62 +16,54 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do import Pleroma.Factory describe "account fetching" do - clear_config([:instance, :limit_to_local_content]) + setup do: clear_config([:instance, :limit_to_local_content]) test "works by id" do - user = insert(:user) + %User{id: user_id} = insert(:user) - conn = - build_conn() - |> get("/api/v1/accounts/#{user.id}") - - assert %{"id" => id} = json_response(conn, 200) - assert id == to_string(user.id) + assert %{"id" => ^user_id} = + build_conn() + |> get("/api/v1/accounts/#{user_id}") + |> json_response_and_validate_schema(200) - conn = - build_conn() - |> get("/api/v1/accounts/-1") - - assert %{"error" => "Can't find user"} = json_response(conn, 404) + assert %{"error" => "Can't find user"} = + build_conn() + |> get("/api/v1/accounts/-1") + |> json_response_and_validate_schema(404) end test "works by nickname" do user = insert(:user) - conn = - build_conn() - |> get("/api/v1/accounts/#{user.nickname}") - - assert %{"id" => id} = json_response(conn, 200) - assert id == user.id + assert %{"id" => user_id} = + build_conn() + |> get("/api/v1/accounts/#{user.nickname}") + |> json_response_and_validate_schema(200) end test "works by nickname for remote users" do - Pleroma.Config.put([:instance, :limit_to_local_content], false) - user = insert(:user, nickname: "user@example.com", local: false) + Config.put([:instance, :limit_to_local_content], false) - conn = - build_conn() - |> get("/api/v1/accounts/#{user.nickname}") + user = insert(:user, nickname: "user@example.com", local: false) - assert %{"id" => id} = json_response(conn, 200) - assert id == user.id + assert %{"id" => user_id} = + build_conn() + |> get("/api/v1/accounts/#{user.nickname}") + |> json_response_and_validate_schema(200) end test "respects limit_to_local_content == :all for remote user nicknames" do - Pleroma.Config.put([:instance, :limit_to_local_content], :all) + Config.put([:instance, :limit_to_local_content], :all) user = insert(:user, nickname: "user@example.com", local: false) - conn = - build_conn() - |> get("/api/v1/accounts/#{user.nickname}") - - assert json_response(conn, 404) + assert build_conn() + |> get("/api/v1/accounts/#{user.nickname}") + |> json_response_and_validate_schema(404) end test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do - Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated) + Config.put([:instance, :limit_to_local_content], :unauthenticated) user = insert(:user, nickname: "user@example.com", local: false) reading_user = insert(:user) @@ -79,7 +72,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do build_conn() |> get("/api/v1/accounts/#{user.nickname}") - assert json_response(conn, 404) + assert json_response_and_validate_schema(conn, 404) conn = build_conn() @@ -87,7 +80,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> assign(:token, insert(:oauth_token, user: reading_user, scopes: ["read:accounts"])) |> get("/api/v1/accounts/#{user.nickname}") - assert %{"id" => id} = json_response(conn, 200) + assert %{"id" => id} = json_response_and_validate_schema(conn, 200) assert id == user.id end @@ -98,21 +91,21 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do user_one = insert(:user, %{id: 1212}) user_two = insert(:user, %{nickname: "#{user_one.id}garbage"}) - resp_one = + acc_one = conn |> get("/api/v1/accounts/#{user_one.id}") + |> json_response_and_validate_schema(:ok) - resp_two = + acc_two = conn |> get("/api/v1/accounts/#{user_two.nickname}") + |> json_response_and_validate_schema(:ok) - resp_three = + acc_three = conn |> get("/api/v1/accounts/#{user_two.id}") + |> json_response_and_validate_schema(:ok) - acc_one = json_response(resp_one, 200) - acc_two = json_response(resp_two, 200) - acc_three = json_response(resp_three, 200) refute acc_one == acc_two assert acc_two == acc_three end @@ -120,59 +113,182 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do test "returns 404 when user is invisible", %{conn: conn} do user = insert(:user, %{invisible: true}) - resp = - conn - |> get("/api/v1/accounts/#{user.nickname}") - |> json_response(404) - - assert %{"error" => "Can't find user"} = resp + assert %{"error" => "Can't find user"} = + conn + |> get("/api/v1/accounts/#{user.nickname}") + |> json_response_and_validate_schema(404) end test "returns 404 for internal.fetch actor", %{conn: conn} do %User{nickname: "internal.fetch"} = InternalFetchActor.get_actor() - resp = - conn - |> get("/api/v1/accounts/internal.fetch") - |> json_response(404) + assert %{"error" => "Can't find user"} = + conn + |> get("/api/v1/accounts/internal.fetch") + |> json_response_and_validate_schema(404) + end + end + + defp local_and_remote_users do + local = insert(:user) + remote = insert(:user, local: false) + {:ok, local: local, remote: remote} + end + + describe "user fetching with restrict unauthenticated profiles for local and remote" do + setup do: local_and_remote_users() - assert %{"error" => "Can't find user"} = resp + setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true) + + setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true) + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + assert %{"error" => "Can't find user"} == + conn + |> get("/api/v1/accounts/#{local.id}") + |> json_response_and_validate_schema(:not_found) + + assert %{"error" => "Can't find user"} == + conn + |> get("/api/v1/accounts/#{remote.id}") + |> json_response_and_validate_schema(:not_found) + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/accounts/#{local.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + end + end + + describe "user fetching with restrict unauthenticated profiles for local" do + setup do: local_and_remote_users() + + setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true) + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/accounts/#{local.id}") + + assert json_response_and_validate_schema(res_conn, :not_found) == %{ + "error" => "Can't find user" + } + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/accounts/#{local.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + end + end + + describe "user fetching with restrict unauthenticated profiles for remote" do + setup do: local_and_remote_users() + + setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true) + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/accounts/#{local.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}") + + assert json_response_and_validate_schema(res_conn, :not_found) == %{ + "error" => "Can't find user" + } + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/accounts/#{local.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) end end describe "user timelines" do setup do: oauth_access(["read:statuses"]) + test "works with announces that are just addressed to public", %{conn: conn} do + user = insert(:user, ap_id: "https://honktest/u/test", local: false) + other_user = insert(:user) + + {:ok, post} = CommonAPI.post(other_user, %{status: "bonkeronk"}) + + {:ok, announce, _} = + %{ + "@context" => "https://www.w3.org/ns/activitystreams", + "actor" => "https://honktest/u/test", + "id" => "https://honktest/u/test/bonk/1793M7B9MQ48847vdx", + "object" => post.data["object"], + "published" => "2019-06-25T19:33:58Z", + "to" => ["https://www.w3.org/ns/activitystreams#Public"], + "type" => "Announce" + } + |> ActivityPub.persist(local: false) + + assert resp = + conn + |> get("/api/v1/accounts/#{user.id}/statuses") + |> json_response_and_validate_schema(200) + + assert [%{"id" => id}] = resp + assert id == announce.id + end + test "respects blocks", %{user: user_one, conn: conn} do user_two = insert(:user) user_three = insert(:user) User.block(user_one, user_two) - {:ok, activity} = CommonAPI.post(user_two, %{"status" => "User one sux0rz"}) + {:ok, activity} = CommonAPI.post(user_two, %{status: "User one sux0rz"}) {:ok, repeat, _} = CommonAPI.repeat(activity.id, user_three) - resp = get(conn, "/api/v1/accounts/#{user_two.id}/statuses") + assert resp = + conn + |> get("/api/v1/accounts/#{user_two.id}/statuses") + |> json_response_and_validate_schema(200) - assert [%{"id" => id}] = json_response(resp, 200) + assert [%{"id" => id}] = resp assert id == activity.id # Even a blocked user will deliver the full user timeline, there would be # no point in looking at a blocked users timeline otherwise - resp = get(conn, "/api/v1/accounts/#{user_two.id}/statuses") + assert resp = + conn + |> get("/api/v1/accounts/#{user_two.id}/statuses") + |> json_response_and_validate_schema(200) - assert [%{"id" => id}] = json_response(resp, 200) + assert [%{"id" => id}] = resp assert id == activity.id # Third user's timeline includes the repeat when viewed by unauthenticated user - resp = get(build_conn(), "/api/v1/accounts/#{user_three.id}/statuses") - assert [%{"id" => id}] = json_response(resp, 200) + resp = + build_conn() + |> get("/api/v1/accounts/#{user_three.id}/statuses") + |> json_response_and_validate_schema(200) + + assert [%{"id" => id}] = resp assert id == repeat.id # When viewing a third user's timeline, the blocked users' statuses will NOT be shown resp = get(conn, "/api/v1/accounts/#{user_three.id}/statuses") - assert [] = json_response(resp, 200) + assert [] == json_response_and_validate_schema(resp, 200) end test "gets users statuses", %{conn: conn} do @@ -182,20 +298,24 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do {:ok, _user_three} = User.follow(user_three, user_one) - {:ok, activity} = CommonAPI.post(user_one, %{"status" => "HI!!!"}) + {:ok, activity} = CommonAPI.post(user_one, %{status: "HI!!!"}) {:ok, direct_activity} = CommonAPI.post(user_one, %{ - "status" => "Hi, @#{user_two.nickname}.", - "visibility" => "direct" + status: "Hi, @#{user_two.nickname}.", + visibility: "direct" }) {:ok, private_activity} = - CommonAPI.post(user_one, %{"status" => "private", "visibility" => "private"}) + CommonAPI.post(user_one, %{status: "private", visibility: "private"}) - resp = get(conn, "/api/v1/accounts/#{user_one.id}/statuses") + # TODO!!! + resp = + conn + |> get("/api/v1/accounts/#{user_one.id}/statuses") + |> json_response_and_validate_schema(200) - assert [%{"id" => id}] = json_response(resp, 200) + assert [%{"id" => id}] = resp assert id == to_string(activity.id) resp = @@ -203,8 +323,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> assign(:user, user_two) |> assign(:token, insert(:oauth_token, user: user_two, scopes: ["read:statuses"])) |> get("/api/v1/accounts/#{user_one.id}/statuses") + |> json_response_and_validate_schema(200) - assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200) + assert [%{"id" => id_one}, %{"id" => id_two}] = resp assert id_one == to_string(direct_activity.id) assert id_two == to_string(activity.id) @@ -213,8 +334,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> assign(:user, user_three) |> assign(:token, insert(:oauth_token, user: user_three, scopes: ["read:statuses"])) |> get("/api/v1/accounts/#{user_one.id}/statuses") + |> json_response_and_validate_schema(200) - assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200) + assert [%{"id" => id_one}, %{"id" => id_two}] = resp assert id_one == to_string(private_activity.id) assert id_two == to_string(activity.id) end @@ -225,7 +347,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?pinned=true") - assert json_response(conn, 200) == [] + assert json_response_and_validate_schema(conn, 200) == [] end test "gets an users media", %{conn: conn} do @@ -240,56 +362,139 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do {:ok, %{id: media_id}} = ActivityPub.upload(file, actor: user.ap_id) - {:ok, image_post} = CommonAPI.post(user, %{"status" => "cofe", "media_ids" => [media_id]}) + {:ok, %{id: image_post_id}} = CommonAPI.post(user, %{status: "cofe", media_ids: [media_id]}) - conn = get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "true"}) + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?only_media=true") - assert [%{"id" => id}] = json_response(conn, 200) - assert id == to_string(image_post.id) + assert [%{"id" => ^image_post_id}] = json_response_and_validate_schema(conn, 200) - conn = get(build_conn(), "/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "1"}) + conn = get(build_conn(), "/api/v1/accounts/#{user.id}/statuses?only_media=1") - assert [%{"id" => id}] = json_response(conn, 200) - assert id == to_string(image_post.id) + assert [%{"id" => ^image_post_id}] = json_response_and_validate_schema(conn, 200) end test "gets a user's statuses without reblogs", %{user: user, conn: conn} do - {:ok, post} = CommonAPI.post(user, %{"status" => "HI!!!"}) - {:ok, _, _} = CommonAPI.repeat(post.id, user) - - conn = get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "true"}) + {:ok, %{id: post_id}} = CommonAPI.post(user, %{status: "HI!!!"}) + {:ok, _, _} = CommonAPI.repeat(post_id, user) - assert [%{"id" => id}] = json_response(conn, 200) - assert id == to_string(post.id) + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?exclude_reblogs=true") + assert [%{"id" => ^post_id}] = json_response_and_validate_schema(conn, 200) - conn = get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "1"}) - - assert [%{"id" => id}] = json_response(conn, 200) - assert id == to_string(post.id) + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?exclude_reblogs=1") + assert [%{"id" => ^post_id}] = json_response_and_validate_schema(conn, 200) end test "filters user's statuses by a hashtag", %{user: user, conn: conn} do - {:ok, post} = CommonAPI.post(user, %{"status" => "#hashtag"}) - {:ok, _post} = CommonAPI.post(user, %{"status" => "hashtag"}) - - conn = get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"tagged" => "hashtag"}) + {:ok, %{id: post_id}} = CommonAPI.post(user, %{status: "#hashtag"}) + {:ok, _post} = CommonAPI.post(user, %{status: "hashtag"}) - assert [%{"id" => id}] = json_response(conn, 200) - assert id == to_string(post.id) + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?tagged=hashtag") + assert [%{"id" => ^post_id}] = json_response_and_validate_schema(conn, 200) end test "the user views their own timelines and excludes direct messages", %{ user: user, conn: conn } do - {:ok, public_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "public"}) - {:ok, _direct_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "direct"}) + {:ok, %{id: public_activity_id}} = + CommonAPI.post(user, %{status: ".", visibility: "public"}) - conn = - get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"exclude_visibilities" => ["direct"]}) + {:ok, _direct_activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"}) + + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?exclude_visibilities[]=direct") + assert [%{"id" => ^public_activity_id}] = json_response_and_validate_schema(conn, 200) + end + end + + defp local_and_remote_activities(%{local: local, remote: remote}) do + insert(:note_activity, user: local) + insert(:note_activity, user: remote, local: false) + + :ok + end + + describe "statuses with restrict unauthenticated profiles for local and remote" do + setup do: local_and_remote_users() + setup :local_and_remote_activities + + setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true) + + setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true) + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + assert %{"error" => "Can't find user"} == + conn + |> get("/api/v1/accounts/#{local.id}/statuses") + |> json_response_and_validate_schema(:not_found) + + assert %{"error" => "Can't find user"} == + conn + |> get("/api/v1/accounts/#{remote.id}/statuses") + |> json_response_and_validate_schema(:not_found) + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 - assert [%{"id" => id}] = json_response(conn, 200) - assert id == to_string(public_activity.id) + res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 + end + end + + describe "statuses with restrict unauthenticated profiles for local" do + setup do: local_and_remote_users() + setup :local_and_remote_activities + + setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true) + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + assert %{"error" => "Can't find user"} == + conn + |> get("/api/v1/accounts/#{local.id}/statuses") + |> json_response_and_validate_schema(:not_found) + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 + end + end + + describe "statuses with restrict unauthenticated profiles for remote" do + setup do: local_and_remote_users() + setup :local_and_remote_activities + + setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true) + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 + + assert %{"error" => "Can't find user"} == + conn + |> get("/api/v1/accounts/#{remote.id}/statuses") + |> json_response_and_validate_schema(:not_found) + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 end end @@ -298,12 +503,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do test "getting followers", %{user: user, conn: conn} do other_user = insert(:user) - {:ok, user} = User.follow(user, other_user) + {:ok, %{id: user_id}} = User.follow(user, other_user) conn = get(conn, "/api/v1/accounts/#{other_user.id}/followers") - assert [%{"id" => id}] = json_response(conn, 200) - assert id == to_string(user.id) + assert [%{"id" => ^user_id}] = json_response_and_validate_schema(conn, 200) end test "getting followers, hide_followers", %{user: user, conn: conn} do @@ -312,7 +516,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = get(conn, "/api/v1/accounts/#{other_user.id}/followers") - assert [] == json_response(conn, 200) + assert [] == json_response_and_validate_schema(conn, 200) end test "getting followers, hide_followers, same user requesting" do @@ -326,37 +530,31 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"])) |> get("/api/v1/accounts/#{other_user.id}/followers") - refute [] == json_response(conn, 200) + refute [] == json_response_and_validate_schema(conn, 200) end test "getting followers, pagination", %{user: user, conn: conn} do - follower1 = insert(:user) - follower2 = insert(:user) - follower3 = insert(:user) - {:ok, _} = User.follow(follower1, user) - {:ok, _} = User.follow(follower2, user) - {:ok, _} = User.follow(follower3, user) - - res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?since_id=#{follower1.id}") + {:ok, %User{id: follower1_id}} = :user |> insert() |> User.follow(user) + {:ok, %User{id: follower2_id}} = :user |> insert() |> User.follow(user) + {:ok, %User{id: follower3_id}} = :user |> insert() |> User.follow(user) - assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200) - assert id3 == follower3.id - assert id2 == follower2.id + assert [%{"id" => ^follower3_id}, %{"id" => ^follower2_id}] = + conn + |> get("/api/v1/accounts/#{user.id}/followers?since_id=#{follower1_id}") + |> json_response_and_validate_schema(200) - res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?max_id=#{follower3.id}") + assert [%{"id" => ^follower2_id}, %{"id" => ^follower1_id}] = + conn + |> get("/api/v1/accounts/#{user.id}/followers?max_id=#{follower3_id}") + |> json_response_and_validate_schema(200) - assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200) - assert id2 == follower2.id - assert id1 == follower1.id + res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?limit=1&max_id=#{follower3_id}") - res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?limit=1&max_id=#{follower3.id}") - - assert [%{"id" => id2}] = json_response(res_conn, 200) - assert id2 == follower2.id + assert [%{"id" => ^follower2_id}] = json_response_and_validate_schema(res_conn, 200) assert [link_header] = get_resp_header(res_conn, "link") - assert link_header =~ ~r/min_id=#{follower2.id}/ - assert link_header =~ ~r/max_id=#{follower2.id}/ + assert link_header =~ ~r/min_id=#{follower2_id}/ + assert link_header =~ ~r/max_id=#{follower2_id}/ end end @@ -369,7 +567,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = get(conn, "/api/v1/accounts/#{user.id}/following") - assert [%{"id" => id}] = json_response(conn, 200) + assert [%{"id" => id}] = json_response_and_validate_schema(conn, 200) assert id == to_string(other_user.id) end @@ -384,7 +582,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"])) |> get("/api/v1/accounts/#{user.id}/following") - assert [] == json_response(conn, 200) + assert [] == json_response_and_validate_schema(conn, 200) end test "getting following, hide_follows, same user requesting" do @@ -398,7 +596,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> assign(:token, insert(:oauth_token, user: user, scopes: ["read:accounts"])) |> get("/api/v1/accounts/#{user.id}/following") - refute [] == json_response(conn, 200) + refute [] == json_response_and_validate_schema(conn, 200) end test "getting following, pagination", %{user: user, conn: conn} do @@ -411,20 +609,20 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do res_conn = get(conn, "/api/v1/accounts/#{user.id}/following?since_id=#{following1.id}") - assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200) + assert [%{"id" => id3}, %{"id" => id2}] = json_response_and_validate_schema(res_conn, 200) assert id3 == following3.id assert id2 == following2.id res_conn = get(conn, "/api/v1/accounts/#{user.id}/following?max_id=#{following3.id}") - assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200) + assert [%{"id" => id2}, %{"id" => id1}] = json_response_and_validate_schema(res_conn, 200) assert id2 == following2.id assert id1 == following1.id res_conn = get(conn, "/api/v1/accounts/#{user.id}/following?limit=1&max_id=#{following3.id}") - assert [%{"id" => id2}] = json_response(res_conn, 200) + assert [%{"id" => id2}] = json_response_and_validate_schema(res_conn, 200) assert id2 == following2.id assert [link_header] = get_resp_header(res_conn, "link") @@ -437,30 +635,37 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do setup do: oauth_access(["follow"]) test "following / unfollowing a user", %{conn: conn} do - other_user = insert(:user) - - ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/follow") - - assert %{"id" => _id, "following" => true} = json_response(ret_conn, 200) - - ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/unfollow") - - assert %{"id" => _id, "following" => false} = json_response(ret_conn, 200) - - conn = post(conn, "/api/v1/follows", %{"uri" => other_user.nickname}) - - assert %{"id" => id} = json_response(conn, 200) - assert id == to_string(other_user.id) + %{id: other_user_id, nickname: other_user_nickname} = insert(:user) + + assert %{"id" => _id, "following" => true} = + conn + |> post("/api/v1/accounts/#{other_user_id}/follow") + |> json_response_and_validate_schema(200) + + assert %{"id" => _id, "following" => false} = + conn + |> post("/api/v1/accounts/#{other_user_id}/unfollow") + |> json_response_and_validate_schema(200) + + assert %{"id" => ^other_user_id} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/follows", %{"uri" => other_user_nickname}) + |> json_response_and_validate_schema(200) end test "cancelling follow request", %{conn: conn} do %{id: other_user_id} = insert(:user, %{locked: true}) assert %{"id" => ^other_user_id, "following" => false, "requested" => true} = - conn |> post("/api/v1/accounts/#{other_user_id}/follow") |> json_response(:ok) + conn + |> post("/api/v1/accounts/#{other_user_id}/follow") + |> json_response_and_validate_schema(:ok) assert %{"id" => ^other_user_id, "following" => false, "requested" => false} = - conn |> post("/api/v1/accounts/#{other_user_id}/unfollow") |> json_response(:ok) + conn + |> post("/api/v1/accounts/#{other_user_id}/unfollow") + |> json_response_and_validate_schema(:ok) end test "following without reblogs" do @@ -470,51 +675,65 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do ret_conn = post(conn, "/api/v1/accounts/#{followed.id}/follow?reblogs=false") - assert %{"showing_reblogs" => false} = json_response(ret_conn, 200) - - {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hey"}) - {:ok, reblog, _} = CommonAPI.repeat(activity.id, followed) + assert %{"showing_reblogs" => false} = json_response_and_validate_schema(ret_conn, 200) - ret_conn = get(conn, "/api/v1/timelines/home") + {:ok, activity} = CommonAPI.post(other_user, %{status: "hey"}) + {:ok, %{id: reblog_id}, _} = CommonAPI.repeat(activity.id, followed) - assert [] == json_response(ret_conn, 200) + assert [] == + conn + |> get("/api/v1/timelines/home") + |> json_response(200) - ret_conn = post(conn, "/api/v1/accounts/#{followed.id}/follow?reblogs=true") + assert %{"showing_reblogs" => true} = + conn + |> post("/api/v1/accounts/#{followed.id}/follow?reblogs=true") + |> json_response_and_validate_schema(200) - assert %{"showing_reblogs" => true} = json_response(ret_conn, 200) - - conn = get(conn, "/api/v1/timelines/home") - - expected_activity_id = reblog.id - assert [%{"id" => ^expected_activity_id}] = json_response(conn, 200) + assert [%{"id" => ^reblog_id}] = + conn + |> get("/api/v1/timelines/home") + |> json_response(200) end test "following / unfollowing errors", %{user: user, conn: conn} do # self follow conn_res = post(conn, "/api/v1/accounts/#{user.id}/follow") - assert %{"error" => "Record not found"} = json_response(conn_res, 404) + + assert %{"error" => "Can not follow yourself"} = + json_response_and_validate_schema(conn_res, 400) # self unfollow user = User.get_cached_by_id(user.id) conn_res = post(conn, "/api/v1/accounts/#{user.id}/unfollow") - assert %{"error" => "Record not found"} = json_response(conn_res, 404) + + assert %{"error" => "Can not unfollow yourself"} = + json_response_and_validate_schema(conn_res, 400) # self follow via uri user = User.get_cached_by_id(user.id) - conn_res = post(conn, "/api/v1/follows", %{"uri" => user.nickname}) - assert %{"error" => "Record not found"} = json_response(conn_res, 404) + + assert %{"error" => "Can not follow yourself"} = + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/v1/follows", %{"uri" => user.nickname}) + |> json_response_and_validate_schema(400) # follow non existing user conn_res = post(conn, "/api/v1/accounts/doesntexist/follow") - assert %{"error" => "Record not found"} = json_response(conn_res, 404) + assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn_res, 404) # follow non existing user via uri - conn_res = post(conn, "/api/v1/follows", %{"uri" => "doesntexist"}) - assert %{"error" => "Record not found"} = json_response(conn_res, 404) + conn_res = + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/v1/follows", %{"uri" => "doesntexist"}) + + assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn_res, 404) # unfollow non existing user conn_res = post(conn, "/api/v1/accounts/doesntexist/unfollow") - assert %{"error" => "Record not found"} = json_response(conn_res, 404) + assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn_res, 404) end end @@ -524,55 +743,52 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do test "with notifications", %{conn: conn} do other_user = insert(:user) - ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/mute") - - response = json_response(ret_conn, 200) - - assert %{"id" => _id, "muting" => true, "muting_notifications" => true} = response + assert %{"id" => _id, "muting" => true, "muting_notifications" => true} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts/#{other_user.id}/mute") + |> json_response_and_validate_schema(200) conn = post(conn, "/api/v1/accounts/#{other_user.id}/unmute") - response = json_response(conn, 200) - assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response + assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = + json_response_and_validate_schema(conn, 200) end test "without notifications", %{conn: conn} do other_user = insert(:user) ret_conn = - post(conn, "/api/v1/accounts/#{other_user.id}/mute", %{"notifications" => "false"}) - - response = json_response(ret_conn, 200) + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/v1/accounts/#{other_user.id}/mute", %{"notifications" => "false"}) - assert %{"id" => _id, "muting" => true, "muting_notifications" => false} = response + assert %{"id" => _id, "muting" => true, "muting_notifications" => false} = + json_response_and_validate_schema(ret_conn, 200) conn = post(conn, "/api/v1/accounts/#{other_user.id}/unmute") - response = json_response(conn, 200) - assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response + assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = + json_response_and_validate_schema(conn, 200) end end describe "pinned statuses" do setup do user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!"}) + {:ok, activity} = CommonAPI.post(user, %{status: "HI!!!"}) %{conn: conn} = oauth_access(["read:statuses"], user: user) [conn: conn, user: user, activity: activity] end - test "returns pinned statuses", %{conn: conn, user: user, activity: activity} do - {:ok, _} = CommonAPI.pin(activity.id, user) - - result = - conn - |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true") - |> json_response(200) + test "returns pinned statuses", %{conn: conn, user: user, activity: %{id: activity_id}} do + {:ok, _} = CommonAPI.pin(activity_id, user) - id_str = to_string(activity.id) - - assert [%{"id" => ^id_str, "pinned" => true}] = result + assert [%{"id" => ^activity_id, "pinned" => true}] = + conn + |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true") + |> json_response_and_validate_schema(200) end end @@ -582,11 +798,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/block") - assert %{"id" => _id, "blocking" => true} = json_response(ret_conn, 200) + assert %{"id" => _id, "blocking" => true} = json_response_and_validate_schema(ret_conn, 200) conn = post(conn, "/api/v1/accounts/#{other_user.id}/unblock") - assert %{"id" => _id, "blocking" => false} = json_response(conn, 200) + assert %{"id" => _id, "blocking" => false} = json_response_and_validate_schema(conn, 200) end describe "create account by app" do @@ -601,23 +817,27 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do [valid_params: valid_params] end + setup do: clear_config([:instance, :account_activation_required]) + test "Account registration via Application", %{conn: conn} do conn = - post(conn, "/api/v1/apps", %{ + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/apps", %{ client_name: "client_name", redirect_uris: "urn:ietf:wg:oauth:2.0:oob", scopes: "read, write, follow" }) - %{ - "client_id" => client_id, - "client_secret" => client_secret, - "id" => _, - "name" => "client_name", - "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob", - "vapid_key" => _, - "website" => nil - } = json_response(conn, 200) + assert %{ + "client_id" => client_id, + "client_secret" => client_secret, + "id" => _, + "name" => "client_name", + "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob", + "vapid_key" => _, + "website" => nil + } = json_response_and_validate_schema(conn, 200) conn = post(conn, "/oauth/token", %{ @@ -637,6 +857,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = build_conn() + |> put_req_header("content-type", "multipart/form-data") |> put_req_header("authorization", "Bearer " <> token) |> post("/api/v1/accounts", %{ username: "lain", @@ -651,7 +872,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do "created_at" => _created_at, "scope" => _scope, "token_type" => "Bearer" - } = json_response(conn, 200) + } = json_response_and_validate_schema(conn, 200) token_from_db = Repo.get_by(Token, token: token) assert token_from_db @@ -665,28 +886,205 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do _user = insert(:user, email: "lain@example.org") app_token = insert(:oauth_token, user: nil) + res = + conn + |> put_req_header("authorization", "Bearer " <> app_token.token) + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts", valid_params) + + assert json_response_and_validate_schema(res, 400) == %{ + "error" => "{\"email\":[\"has already been taken\"]}" + } + end + + test "returns bad_request if missing required params", %{ + conn: conn, + valid_params: valid_params + } do + app_token = insert(:oauth_token, user: nil) + conn = conn |> put_req_header("authorization", "Bearer " <> app_token.token) + |> put_req_header("content-type", "application/json") res = post(conn, "/api/v1/accounts", valid_params) - assert json_response(res, 400) == %{"error" => "{\"email\":[\"has already been taken\"]}"} + assert json_response_and_validate_schema(res, 200) + + [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}] + |> Stream.zip(Map.delete(valid_params, :email)) + |> Enum.each(fn {ip, {attr, _}} -> + res = + conn + |> Map.put(:remote_ip, ip) + |> post("/api/v1/accounts", Map.delete(valid_params, attr)) + |> json_response_and_validate_schema(400) + + assert res == %{ + "error" => "Missing field: #{attr}.", + "errors" => [ + %{ + "message" => "Missing field: #{attr}", + "source" => %{"pointer" => "/#{attr}"}, + "title" => "Invalid value" + } + ] + } + end) + end + + setup do: clear_config([:instance, :account_activation_required]) + + test "returns bad_request if missing email params when :account_activation_required is enabled", + %{conn: conn, valid_params: valid_params} do + Pleroma.Config.put([:instance, :account_activation_required], true) + + app_token = insert(:oauth_token, user: nil) + + conn = + conn + |> put_req_header("authorization", "Bearer " <> app_token.token) + |> put_req_header("content-type", "application/json") + + res = + conn + |> Map.put(:remote_ip, {127, 0, 0, 5}) + |> post("/api/v1/accounts", Map.delete(valid_params, :email)) + + assert json_response_and_validate_schema(res, 400) == + %{"error" => "Missing parameter: email"} + + res = + conn + |> Map.put(:remote_ip, {127, 0, 0, 6}) + |> post("/api/v1/accounts", Map.put(valid_params, :email, "")) + + assert json_response_and_validate_schema(res, 400) == %{ + "error" => "{\"email\":[\"can't be blank\"]}" + } + end + + test "allow registration without an email", %{conn: conn, valid_params: valid_params} do + app_token = insert(:oauth_token, user: nil) + conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token) + + res = + conn + |> put_req_header("content-type", "application/json") + |> Map.put(:remote_ip, {127, 0, 0, 7}) + |> post("/api/v1/accounts", Map.delete(valid_params, :email)) + + assert json_response_and_validate_schema(res, 200) + end + + test "allow registration with an empty email", %{conn: conn, valid_params: valid_params} do + app_token = insert(:oauth_token, user: nil) + conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token) + + res = + conn + |> put_req_header("content-type", "application/json") + |> Map.put(:remote_ip, {127, 0, 0, 8}) + |> post("/api/v1/accounts", Map.put(valid_params, :email, "")) + + assert json_response_and_validate_schema(res, 200) + end + + test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do + res = + conn + |> put_req_header("authorization", "Bearer " <> "invalid-token") + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/v1/accounts", valid_params) + + assert json_response_and_validate_schema(res, 403) == %{"error" => "Invalid credentials"} end - clear_config([Pleroma.Plugs.RemoteIp, :enabled]) + test "registration from trusted app" do + clear_config([Pleroma.Captcha, :enabled], true) + app = insert(:oauth_app, trusted: true, scopes: ["read", "write", "follow", "push"]) + + conn = + build_conn() + |> post("/oauth/token", %{ + "grant_type" => "client_credentials", + "client_id" => app.client_id, + "client_secret" => app.client_secret + }) - test "rate limit", %{conn: conn} do - Pleroma.Config.put([Pleroma.Plugs.RemoteIp, :enabled], true) + assert %{"access_token" => token, "token_type" => "Bearer"} = json_response(conn, 200) + + response = + build_conn() + |> Plug.Conn.put_req_header("authorization", "Bearer " <> token) + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/v1/accounts", %{ + nickname: "nickanme", + agreement: true, + email: "email@example.com", + fullname: "Lain", + username: "Lain", + password: "some_password", + confirm: "some_password" + }) + |> json_response_and_validate_schema(200) + + assert %{ + "access_token" => access_token, + "created_at" => _, + "scope" => ["read", "write", "follow", "push"], + "token_type" => "Bearer" + } = response + + response = + build_conn() + |> Plug.Conn.put_req_header("authorization", "Bearer " <> access_token) + |> get("/api/v1/accounts/verify_credentials") + |> json_response_and_validate_schema(200) + + assert %{ + "acct" => "Lain", + "bot" => false, + "display_name" => "Lain", + "follow_requests_count" => 0, + "followers_count" => 0, + "following_count" => 0, + "locked" => false, + "note" => "", + "source" => %{ + "fields" => [], + "note" => "", + "pleroma" => %{ + "actor_type" => "Person", + "discoverable" => false, + "no_rich_text" => false, + "show_role" => true + }, + "privacy" => "public", + "sensitive" => false + }, + "statuses_count" => 0, + "username" => "Lain" + } = response + end + end + + describe "create account by app / rate limit" do + setup do: clear_config([:rate_limit, :app_account_creation], {10_000, 2}) + + test "respects rate limit setting", %{conn: conn} do app_token = insert(:oauth_token, user: nil) conn = conn |> put_req_header("authorization", "Bearer " <> app_token.token) |> Map.put(:remote_ip, {15, 15, 15, 15}) + |> put_req_header("content-type", "multipart/form-data") - for i <- 1..5 do + for i <- 1..2 do conn = - post(conn, "/api/v1/accounts", %{ + conn + |> post("/api/v1/accounts", %{ username: "#{i}lain", email: "#{i}lain@example.org", password: "PlzDontHackLain", @@ -698,7 +1096,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do "created_at" => _created_at, "scope" => _scope, "token_type" => "Bearer" - } = json_response(conn, 200) + } = json_response_and_validate_schema(conn, 200) token_from_db = Repo.get_by(Token, token: token) assert token_from_db @@ -716,38 +1114,94 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do agreement: true }) - assert json_response(conn, :too_many_requests) == %{"error" => "Throttled"} + assert json_response_and_validate_schema(conn, :too_many_requests) == %{ + "error" => "Throttled" + } end + end - test "returns bad_request if missing required params", %{ - conn: conn, - valid_params: valid_params - } do + describe "create account with enabled captcha" do + setup %{conn: conn} do app_token = insert(:oauth_token, user: nil) - conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token) + conn = + conn + |> put_req_header("authorization", "Bearer " <> app_token.token) + |> put_req_header("content-type", "multipart/form-data") - res = post(conn, "/api/v1/accounts", valid_params) - assert json_response(res, 200) + [conn: conn] + end - [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}] - |> Stream.zip(valid_params) - |> Enum.each(fn {ip, {attr, _}} -> - res = - conn - |> Map.put(:remote_ip, ip) - |> post("/api/v1/accounts", Map.delete(valid_params, attr)) - |> json_response(400) + setup do: clear_config([Pleroma.Captcha, :enabled], true) - assert res == %{"error" => "Missing parameters"} - end) + test "creates an account and returns 200 if captcha is valid", %{conn: conn} do + %{token: token, answer_data: answer_data} = Pleroma.Captcha.new() + + params = %{ + username: "lain", + email: "lain@example.org", + password: "PlzDontHackLain", + agreement: true, + captcha_solution: Pleroma.Captcha.Mock.solution(), + captcha_token: token, + captcha_answer_data: answer_data + } + + assert %{ + "access_token" => access_token, + "created_at" => _, + "scope" => ["read"], + "token_type" => "Bearer" + } = + conn + |> post("/api/v1/accounts", params) + |> json_response_and_validate_schema(:ok) + + assert Token |> Repo.get_by(token: access_token) |> Repo.preload(:user) |> Map.get(:user) + + Cachex.del(:used_captcha_cache, token) end - test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do - conn = put_req_header(conn, "authorization", "Bearer " <> "invalid-token") + test "returns 400 if any captcha field is not provided", %{conn: conn} do + captcha_fields = [:captcha_solution, :captcha_token, :captcha_answer_data] - res = post(conn, "/api/v1/accounts", valid_params) - assert json_response(res, 403) == %{"error" => "Invalid credentials"} + valid_params = %{ + username: "lain", + email: "lain@example.org", + password: "PlzDontHackLain", + agreement: true, + captcha_solution: "xx", + captcha_token: "xx", + captcha_answer_data: "xx" + } + + for field <- captcha_fields do + expected = %{ + "error" => "{\"captcha\":[\"Invalid CAPTCHA (Missing parameter: #{field})\"]}" + } + + assert expected == + conn + |> post("/api/v1/accounts", Map.delete(valid_params, field)) + |> json_response_and_validate_schema(:bad_request) + end + end + + test "returns an error if captcha is invalid", %{conn: conn} do + params = %{ + username: "lain", + email: "lain@example.org", + password: "PlzDontHackLain", + agreement: true, + captcha_solution: "cofe", + captcha_token: "cofe", + captcha_answer_data: "cofe" + } + + assert %{"error" => "{\"captcha\":[\"Invalid answer data\"]}"} == + conn + |> post("/api/v1/accounts", params) + |> json_response_and_validate_schema(:bad_request) end end @@ -755,27 +1209,28 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do test "returns lists to which the account belongs" do %{user: user, conn: conn} = oauth_access(["read:lists"]) other_user = insert(:user) - assert {:ok, %Pleroma.List{} = list} = Pleroma.List.create("Test List", user) + assert {:ok, %Pleroma.List{id: list_id} = list} = Pleroma.List.create("Test List", user) {:ok, %{following: _following}} = Pleroma.List.follow(list, other_user) - res = - conn - |> get("/api/v1/accounts/#{other_user.id}/lists") - |> json_response(200) - - assert res == [%{"id" => to_string(list.id), "title" => "Test List"}] + assert [%{"id" => list_id, "title" => "Test List"}] = + conn + |> get("/api/v1/accounts/#{other_user.id}/lists") + |> json_response_and_validate_schema(200) end end describe "verify_credentials" do test "verify_credentials" do %{user: user, conn: conn} = oauth_access(["read:accounts"]) + [notification | _] = insert_list(7, :notification, user: user) + Pleroma.Notification.set_read_up_to(user, notification.id) conn = get(conn, "/api/v1/accounts/verify_credentials") - response = json_response(conn, 200) + response = json_response_and_validate_schema(conn, 200) assert %{"id" => id, "source" => %{"privacy" => "public"}} = response assert response["pleroma"]["chat_token"] + assert response["pleroma"]["unread_notifications_count"] == 6 assert id == to_string(user.id) end @@ -785,7 +1240,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = get(conn, "/api/v1/accounts/verify_credentials") - assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = json_response(conn, 200) + assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = + json_response_and_validate_schema(conn, 200) + assert id == to_string(user.id) end @@ -795,7 +1252,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = get(conn, "/api/v1/accounts/verify_credentials") - assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200) + assert %{"id" => id, "source" => %{"privacy" => "private"}} = + json_response_and_validate_schema(conn, 200) + assert id == to_string(user.id) end end @@ -804,20 +1263,24 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do setup do: oauth_access(["read:follows"]) test "returns the relationships for the current user", %{user: user, conn: conn} do - other_user = insert(:user) + %{id: other_user_id} = other_user = insert(:user) {:ok, _user} = User.follow(user, other_user) - conn = get(conn, "/api/v1/accounts/relationships", %{"id" => [other_user.id]}) - - assert [relationship] = json_response(conn, 200) + assert [%{"id" => ^other_user_id}] = + conn + |> get("/api/v1/accounts/relationships?id=#{other_user.id}") + |> json_response_and_validate_schema(200) - assert to_string(other_user.id) == relationship["id"] + assert [%{"id" => ^other_user_id}] = + conn + |> get("/api/v1/accounts/relationships?id[]=#{other_user.id}") + |> json_response_and_validate_schema(200) end test "returns an empty list on a bad request", %{conn: conn} do conn = get(conn, "/api/v1/accounts/relationships", %{}) - assert [] = json_response(conn, 200) + assert [] = json_response_and_validate_schema(conn, 200) end end @@ -830,7 +1293,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = get(conn, "/api/v1/mutes") other_user_id = to_string(other_user.id) - assert [%{"id" => ^other_user_id}] = json_response(conn, 200) + assert [%{"id" => ^other_user_id}] = json_response_and_validate_schema(conn, 200) end test "getting a list of blocks" do @@ -845,6 +1308,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> get("/api/v1/blocks") other_user_id = to_string(other_user.id) - assert [%{"id" => ^other_user_id}] = json_response(conn, 200) + assert [%{"id" => ^other_user_id}] = json_response_and_validate_schema(conn, 200) end end diff --git a/test/web/mastodon_api/controllers/app_controller_test.exs b/test/web/mastodon_api/controllers/app_controller_test.exs index 51788155b..a0b8b126c 100644 --- a/test/web/mastodon_api/controllers/app_controller_test.exs +++ b/test/web/mastodon_api/controllers/app_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.AppControllerTest do @@ -16,8 +16,7 @@ defmodule Pleroma.Web.MastodonAPI.AppControllerTest do conn = conn - |> assign(:user, token.user) - |> assign(:token, token) + |> put_req_header("authorization", "Bearer #{token.token}") |> get("/api/v1/apps/verify_credentials") app = Repo.preload(token, :app).app @@ -28,7 +27,7 @@ defmodule Pleroma.Web.MastodonAPI.AppControllerTest do "vapid_key" => Push.vapid_config() |> Keyword.get(:public_key) } - assert expected == json_response(conn, 200) + assert expected == json_response_and_validate_schema(conn, 200) end test "creates an oauth app", %{conn: conn} do @@ -37,6 +36,7 @@ defmodule Pleroma.Web.MastodonAPI.AppControllerTest do conn = conn + |> put_req_header("content-type", "application/json") |> assign(:user, user) |> post("/api/v1/apps", %{ client_name: app_attrs.client_name, @@ -55,6 +55,6 @@ defmodule Pleroma.Web.MastodonAPI.AppControllerTest do "vapid_key" => Push.vapid_config() |> Keyword.get(:public_key) } - assert expected == json_response(conn, 200) + assert expected == json_response_and_validate_schema(conn, 200) end end diff --git a/test/web/mastodon_api/controllers/auth_controller_test.exs b/test/web/mastodon_api/controllers/auth_controller_test.exs index 98b2a82e7..a485f8e41 100644 --- a/test/web/mastodon_api/controllers/auth_controller_test.exs +++ b/test/web/mastodon_api/controllers/auth_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.AuthControllerTest do @@ -85,6 +85,37 @@ defmodule Pleroma.Web.MastodonAPI.AuthControllerTest do end end + describe "POST /auth/password, with nickname" do + test "it returns 204", %{conn: conn} do + user = insert(:user) + + assert conn + |> post("/auth/password?nickname=#{user.nickname}") + |> json_response(:no_content) + + ObanHelpers.perform_all() + token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id) + + email = Pleroma.Emails.UserEmail.password_reset_email(user, token_record.token) + notify_email = Config.get([:instance, :notify_email]) + instance_name = Config.get([:instance, :name]) + + assert_email_sent( + from: {instance_name, notify_email}, + to: {user.name, user.email}, + html_body: email.html_body + ) + end + + test "it doesn't fail when a user has no email", %{conn: conn} do + user = insert(:user, %{email: nil}) + + assert conn + |> post("/auth/password?nickname=#{user.nickname}") + |> json_response(:no_content) + end + end + describe "POST /auth/password, with invalid parameters" do setup do user = insert(:user) diff --git a/test/web/mastodon_api/controllers/conversation_controller_test.exs b/test/web/mastodon_api/controllers/conversation_controller_test.exs index 4bb9781a6..693ba51e5 100644 --- a/test/web/mastodon_api/controllers/conversation_controller_test.exs +++ b/test/web/mastodon_api/controllers/conversation_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do @@ -22,21 +22,21 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do {:ok, direct} = CommonAPI.post(user_one, %{ - "status" => "Hi @#{user_two.nickname}, @#{user_three.nickname}!", - "visibility" => "direct" + status: "Hi @#{user_two.nickname}, @#{user_three.nickname}!", + visibility: "direct" }) assert User.get_cached_by_id(user_two.id).unread_conversation_count == 1 {:ok, _follower_only} = CommonAPI.post(user_one, %{ - "status" => "Hi @#{user_two.nickname}!", - "visibility" => "private" + status: "Hi @#{user_two.nickname}!", + visibility: "private" }) res_conn = get(conn, "/api/v1/conversations") - assert response = json_response(res_conn, 200) + assert response = json_response_and_validate_schema(res_conn, 200) assert [ %{ @@ -63,46 +63,46 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do {:ok, direct1} = CommonAPI.post(user_one, %{ - "status" => "Hi @#{user_two.nickname}!", - "visibility" => "direct" + status: "Hi @#{user_two.nickname}!", + visibility: "direct" }) {:ok, _direct2} = CommonAPI.post(user_one, %{ - "status" => "Hi @#{user_three.nickname}!", - "visibility" => "direct" + status: "Hi @#{user_three.nickname}!", + visibility: "direct" }) {:ok, direct3} = CommonAPI.post(user_one, %{ - "status" => "Hi @#{user_two.nickname}, @#{user_three.nickname}!", - "visibility" => "direct" + status: "Hi @#{user_two.nickname}, @#{user_three.nickname}!", + visibility: "direct" }) {:ok, _direct4} = CommonAPI.post(user_two, %{ - "status" => "Hi @#{user_three.nickname}!", - "visibility" => "direct" + status: "Hi @#{user_three.nickname}!", + visibility: "direct" }) {:ok, direct5} = CommonAPI.post(user_two, %{ - "status" => "Hi @#{user_one.nickname}!", - "visibility" => "direct" + status: "Hi @#{user_one.nickname}!", + visibility: "direct" }) - [conversation1, conversation2] = - conn - |> get("/api/v1/conversations", %{"recipients" => [user_two.id]}) - |> json_response(200) + assert [conversation1, conversation2] = + conn + |> get("/api/v1/conversations?recipients[]=#{user_two.id}") + |> json_response_and_validate_schema(200) assert conversation1["last_status"]["id"] == direct5.id assert conversation2["last_status"]["id"] == direct1.id [conversation1] = conn - |> get("/api/v1/conversations", %{"recipients" => [user_two.id, user_three.id]}) - |> json_response(200) + |> get("/api/v1/conversations?recipients[]=#{user_two.id}&recipients[]=#{user_three.id}") + |> json_response_and_validate_schema(200) assert conversation1["last_status"]["id"] == direct3.id end @@ -112,21 +112,21 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do {:ok, direct} = CommonAPI.post(user_one, %{ - "status" => "Hi @#{user_two.nickname}", - "visibility" => "direct" + status: "Hi @#{user_two.nickname}", + visibility: "direct" }) {:ok, direct_reply} = CommonAPI.post(user_two, %{ - "status" => "reply", - "visibility" => "direct", - "in_reply_to_status_id" => direct.id + status: "reply", + visibility: "direct", + in_reply_to_status_id: direct.id }) [%{"last_status" => res_last_status}] = conn |> get("/api/v1/conversations") - |> json_response(200) + |> json_response_and_validate_schema(200) assert res_last_status["id"] == direct_reply.id end @@ -136,8 +136,8 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do {:ok, direct} = CommonAPI.post(user_one, %{ - "status" => "Hi @#{user_two.nickname}", - "visibility" => "direct" + status: "Hi @#{user_two.nickname}", + visibility: "direct" }) assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0 @@ -154,12 +154,12 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do [%{"id" => direct_conversation_id, "unread" => true}] = user_two_conn |> get("/api/v1/conversations") - |> json_response(200) + |> json_response_and_validate_schema(200) %{"unread" => false} = user_two_conn |> post("/api/v1/conversations/#{direct_conversation_id}/read") - |> json_response(200) + |> json_response_and_validate_schema(200) assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0 assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0 @@ -167,15 +167,15 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do # The conversation is marked as unread on reply {:ok, _} = CommonAPI.post(user_two, %{ - "status" => "reply", - "visibility" => "direct", - "in_reply_to_status_id" => direct.id + status: "reply", + visibility: "direct", + in_reply_to_status_id: direct.id }) [%{"unread" => true}] = conn |> get("/api/v1/conversations") - |> json_response(200) + |> json_response_and_validate_schema(200) assert User.get_cached_by_id(user_one.id).unread_conversation_count == 1 assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0 @@ -183,9 +183,9 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do # A reply doesn't increment the user's unread_conversation_count if the conversation is unread {:ok, _} = CommonAPI.post(user_two, %{ - "status" => "reply", - "visibility" => "direct", - "in_reply_to_status_id" => direct.id + status: "reply", + visibility: "direct", + in_reply_to_status_id: direct.id }) assert User.get_cached_by_id(user_one.id).unread_conversation_count == 1 @@ -197,8 +197,8 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do {:ok, direct} = CommonAPI.post(user_one, %{ - "status" => "Hi @#{user_two.nickname}!", - "visibility" => "direct" + status: "Hi @#{user_two.nickname}!", + visibility: "direct" }) res_conn = get(conn, "/api/v1/statuses/#{direct.id}/context") diff --git a/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs b/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs index 2d988b0b8..ab0027f90 100644 --- a/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs +++ b/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs @@ -1,16 +1,17 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.CustomEmojiControllerTest do use Pleroma.Web.ConnCase, async: true test "with tags", %{conn: conn} do - [emoji | _body] = - conn - |> get("/api/v1/custom_emojis") - |> json_response(200) + assert resp = + conn + |> get("/api/v1/custom_emojis") + |> json_response_and_validate_schema(200) + assert [emoji | _body] = resp assert Map.has_key?(emoji, "shortcode") assert Map.has_key?(emoji, "static_url") assert Map.has_key?(emoji, "tags") diff --git a/test/web/mastodon_api/controllers/domain_block_controller_test.exs b/test/web/mastodon_api/controllers/domain_block_controller_test.exs index 55de625ba..01a24afcf 100644 --- a/test/web/mastodon_api/controllers/domain_block_controller_test.exs +++ b/test/web/mastodon_api/controllers/domain_block_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.DomainBlockControllerTest do @@ -13,15 +13,21 @@ defmodule Pleroma.Web.MastodonAPI.DomainBlockControllerTest do %{user: user, conn: conn} = oauth_access(["write:blocks"]) other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"}) - ret_conn = post(conn, "/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"}) + ret_conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"}) - assert %{} = json_response(ret_conn, 200) + assert %{} == json_response_and_validate_schema(ret_conn, 200) user = User.get_cached_by_ap_id(user.ap_id) assert User.blocks?(user, other_user) - ret_conn = delete(conn, "/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"}) + ret_conn = + conn + |> put_req_header("content-type", "application/json") + |> delete("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"}) - assert %{} = json_response(ret_conn, 200) + assert %{} == json_response_and_validate_schema(ret_conn, 200) user = User.get_cached_by_ap_id(user.ap_id) refute User.blocks?(user, other_user) end @@ -32,14 +38,10 @@ defmodule Pleroma.Web.MastodonAPI.DomainBlockControllerTest do {:ok, user} = User.block_domain(user, "bad.site") {:ok, user} = User.block_domain(user, "even.worse.site") - conn = - conn - |> assign(:user, user) - |> get("/api/v1/domain_blocks") - - domain_blocks = json_response(conn, 200) - - assert "bad.site" in domain_blocks - assert "even.worse.site" in domain_blocks + assert ["even.worse.site", "bad.site"] == + conn + |> assign(:user, user) + |> get("/api/v1/domain_blocks") + |> json_response_and_validate_schema(200) end end diff --git a/test/web/mastodon_api/controllers/filter_controller_test.exs b/test/web/mastodon_api/controllers/filter_controller_test.exs index 3aea17ec7..f29547d13 100644 --- a/test/web/mastodon_api/controllers/filter_controller_test.exs +++ b/test/web/mastodon_api/controllers/filter_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do @@ -15,9 +15,12 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do context: ["home"] } - conn = post(conn, "/api/v1/filters", %{"phrase" => filter.phrase, context: filter.context}) + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/filters", %{"phrase" => filter.phrase, context: filter.context}) - assert response = json_response(conn, 200) + assert response = json_response_and_validate_schema(conn, 200) assert response["phrase"] == filter.phrase assert response["context"] == filter.context assert response["irreversible"] == false @@ -48,12 +51,12 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do response = conn |> get("/api/v1/filters") - |> json_response(200) + |> json_response_and_validate_schema(200) assert response == render_json( FilterView, - "filters.json", + "index.json", filters: [filter_two, filter_one] ) end @@ -72,7 +75,7 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do conn = get(conn, "/api/v1/filters/#{filter.filter_id}") - assert _response = json_response(conn, 200) + assert response = json_response_and_validate_schema(conn, 200) end test "update a filter" do @@ -82,7 +85,8 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do user_id: user.id, filter_id: 2, phrase: "knight", - context: ["home"] + context: ["home"], + hide: true } {:ok, _filter} = Pleroma.Filter.create(query) @@ -93,14 +97,17 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do } conn = - put(conn, "/api/v1/filters/#{query.filter_id}", %{ + conn + |> put_req_header("content-type", "application/json") + |> put("/api/v1/filters/#{query.filter_id}", %{ phrase: new.phrase, context: new.context }) - assert response = json_response(conn, 200) + assert response = json_response_and_validate_schema(conn, 200) assert response["phrase"] == new.phrase assert response["context"] == new.context + assert response["irreversible"] == true end test "delete a filter" do @@ -117,7 +124,6 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do conn = delete(conn, "/api/v1/filters/#{filter.filter_id}") - assert response = json_response(conn, 200) - assert response == %{} + assert json_response_and_validate_schema(conn, 200) == %{} end end diff --git a/test/web/mastodon_api/controllers/follow_request_controller_test.exs b/test/web/mastodon_api/controllers/follow_request_controller_test.exs index 6e4a76501..44e12d15a 100644 --- a/test/web/mastodon_api/controllers/follow_request_controller_test.exs +++ b/test/web/mastodon_api/controllers/follow_request_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do @@ -21,13 +21,13 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do other_user = insert(:user) {:ok, _activity} = ActivityPub.follow(other_user, user) - {:ok, other_user} = User.follow(other_user, user, "pending") + {:ok, other_user} = User.follow(other_user, user, :follow_pending) assert User.following?(other_user, user) == false conn = get(conn, "/api/v1/follow_requests") - assert [relationship] = json_response(conn, 200) + assert [relationship] = json_response_and_validate_schema(conn, 200) assert to_string(other_user.id) == relationship["id"] end @@ -35,7 +35,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do other_user = insert(:user) {:ok, _activity} = ActivityPub.follow(other_user, user) - {:ok, other_user} = User.follow(other_user, user, "pending") + {:ok, other_user} = User.follow(other_user, user, :follow_pending) user = User.get_cached_by_id(user.id) other_user = User.get_cached_by_id(other_user.id) @@ -44,7 +44,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do conn = post(conn, "/api/v1/follow_requests/#{other_user.id}/authorize") - assert relationship = json_response(conn, 200) + assert relationship = json_response_and_validate_schema(conn, 200) assert to_string(other_user.id) == relationship["id"] user = User.get_cached_by_id(user.id) @@ -62,7 +62,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do conn = post(conn, "/api/v1/follow_requests/#{other_user.id}/reject") - assert relationship = json_response(conn, 200) + assert relationship = json_response_and_validate_schema(conn, 200) assert to_string(other_user.id) == relationship["id"] user = User.get_cached_by_id(user.id) diff --git a/test/web/mastodon_api/controllers/instance_controller_test.exs b/test/web/mastodon_api/controllers/instance_controller_test.exs index e00de6b18..2c61dc5ba 100644 --- a/test/web/mastodon_api/controllers/instance_controller_test.exs +++ b/test/web/mastodon_api/controllers/instance_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do @@ -10,7 +10,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do test "get instance information", %{conn: conn} do conn = get(conn, "/api/v1/instance") - assert result = json_response(conn, 200) + assert result = json_response_and_validate_schema(conn, 200) email = Pleroma.Config.get([:instance, :email]) # Note: not checking for "max_toot_chars" since it's optional @@ -34,6 +34,10 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do "banner_upload_limit" => _ } = result + assert result["pleroma"]["metadata"]["features"] + assert result["pleroma"]["metadata"]["federation"] + assert result["pleroma"]["vapid_public_key"] + assert email == from_config_email end @@ -46,13 +50,13 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do insert(:user, %{local: false, nickname: "u@peer1.com"}) insert(:user, %{local: false, nickname: "u@peer2.com"}) - {:ok, _} = Pleroma.Web.CommonAPI.post(user, %{"status" => "cofe"}) + {:ok, _} = Pleroma.Web.CommonAPI.post(user, %{status: "cofe"}) Pleroma.Stats.force_update() conn = get(conn, "/api/v1/instance") - assert result = json_response(conn, 200) + assert result = json_response_and_validate_schema(conn, 200) stats = result["stats"] @@ -70,7 +74,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do conn = get(conn, "/api/v1/instance/peers") - assert result = json_response(conn, 200) + assert result = json_response_and_validate_schema(conn, 200) assert ["peer1.com", "peer2.com"] == Enum.sort(result) end diff --git a/test/web/mastodon_api/controllers/list_controller_test.exs b/test/web/mastodon_api/controllers/list_controller_test.exs index a6effbb69..57a9ef4a4 100644 --- a/test/web/mastodon_api/controllers/list_controller_test.exs +++ b/test/web/mastodon_api/controllers/list_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.ListControllerTest do @@ -12,37 +12,44 @@ defmodule Pleroma.Web.MastodonAPI.ListControllerTest do test "creating a list" do %{conn: conn} = oauth_access(["write:lists"]) - conn = post(conn, "/api/v1/lists", %{"title" => "cuties"}) - - assert %{"title" => title} = json_response(conn, 200) - assert title == "cuties" + assert %{"title" => "cuties"} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/lists", %{"title" => "cuties"}) + |> json_response_and_validate_schema(:ok) end test "renders error for invalid params" do %{conn: conn} = oauth_access(["write:lists"]) - conn = post(conn, "/api/v1/lists", %{"title" => nil}) + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/lists", %{"title" => nil}) - assert %{"error" => "can't be blank"} == json_response(conn, :unprocessable_entity) + assert %{"error" => "title - null value where string expected."} = + json_response_and_validate_schema(conn, 400) end test "listing a user's lists" do %{conn: conn} = oauth_access(["read:lists", "write:lists"]) conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/lists", %{"title" => "cuties"}) - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/lists", %{"title" => "cofe"}) - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) conn = get(conn, "/api/v1/lists") assert [ %{"id" => _, "title" => "cofe"}, %{"id" => _, "title" => "cuties"} - ] = json_response(conn, :ok) + ] = json_response_and_validate_schema(conn, :ok) end test "adding users to a list" do @@ -50,9 +57,12 @@ defmodule Pleroma.Web.MastodonAPI.ListControllerTest do other_user = insert(:user) {:ok, list} = Pleroma.List.create("name", user) - conn = post(conn, "/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) + assert %{} == + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) + |> json_response_and_validate_schema(:ok) - assert %{} == json_response(conn, 200) %Pleroma.List{following: following} = Pleroma.List.get(list.id, user) assert following == [other_user.follower_address] end @@ -65,9 +75,12 @@ defmodule Pleroma.Web.MastodonAPI.ListControllerTest do {:ok, list} = Pleroma.List.follow(list, other_user) {:ok, list} = Pleroma.List.follow(list, third_user) - conn = delete(conn, "/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) + assert %{} == + conn + |> put_req_header("content-type", "application/json") + |> delete("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) + |> json_response_and_validate_schema(:ok) - assert %{} == json_response(conn, 200) %Pleroma.List{following: following} = Pleroma.List.get(list.id, user) assert following == [third_user.follower_address] end @@ -83,7 +96,7 @@ defmodule Pleroma.Web.MastodonAPI.ListControllerTest do |> assign(:user, user) |> get("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) - assert [%{"id" => id}] = json_response(conn, 200) + assert [%{"id" => id}] = json_response_and_validate_schema(conn, 200) assert id == to_string(other_user.id) end @@ -96,7 +109,7 @@ defmodule Pleroma.Web.MastodonAPI.ListControllerTest do |> assign(:user, user) |> get("/api/v1/lists/#{list.id}") - assert %{"id" => id} = json_response(conn, 200) + assert %{"id" => id} = json_response_and_validate_schema(conn, 200) assert id == to_string(list.id) end @@ -105,17 +118,18 @@ defmodule Pleroma.Web.MastodonAPI.ListControllerTest do conn = get(conn, "/api/v1/lists/666") - assert %{"error" => "List not found"} = json_response(conn, :not_found) + assert %{"error" => "List not found"} = json_response_and_validate_schema(conn, :not_found) end test "renaming a list" do %{user: user, conn: conn} = oauth_access(["write:lists"]) {:ok, list} = Pleroma.List.create("name", user) - conn = put(conn, "/api/v1/lists/#{list.id}", %{"title" => "newname"}) - - assert %{"title" => name} = json_response(conn, 200) - assert name == "newname" + assert %{"title" => "newname"} = + conn + |> put_req_header("content-type", "application/json") + |> put("/api/v1/lists/#{list.id}", %{"title" => "newname"}) + |> json_response_and_validate_schema(:ok) end test "validates title when renaming a list" do @@ -125,9 +139,11 @@ defmodule Pleroma.Web.MastodonAPI.ListControllerTest do conn = conn |> assign(:user, user) + |> put_req_header("content-type", "application/json") |> put("/api/v1/lists/#{list.id}", %{"title" => " "}) - assert %{"error" => "can't be blank"} == json_response(conn, :unprocessable_entity) + assert %{"error" => "can't be blank"} == + json_response_and_validate_schema(conn, :unprocessable_entity) end test "deleting a list" do @@ -136,7 +152,7 @@ defmodule Pleroma.Web.MastodonAPI.ListControllerTest do conn = delete(conn, "/api/v1/lists/#{list.id}") - assert %{} = json_response(conn, 200) + assert %{} = json_response_and_validate_schema(conn, 200) assert is_nil(Repo.get(Pleroma.List, list.id)) end end diff --git a/test/web/mastodon_api/controllers/marker_controller_test.exs b/test/web/mastodon_api/controllers/marker_controller_test.exs index 1fcad873d..6dd40fb4a 100644 --- a/test/web/mastodon_api/controllers/marker_controller_test.exs +++ b/test/web/mastodon_api/controllers/marker_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.MarkerControllerTest do @@ -11,6 +11,7 @@ defmodule Pleroma.Web.MastodonAPI.MarkerControllerTest do test "gets markers with correct scopes", %{conn: conn} do user = insert(:user) token = insert(:oauth_token, user: user, scopes: ["read:statuses"]) + insert_list(7, :notification, user: user) {:ok, %{"notifications" => marker}} = Pleroma.Marker.upsert( @@ -22,14 +23,15 @@ defmodule Pleroma.Web.MastodonAPI.MarkerControllerTest do conn |> assign(:user, user) |> assign(:token, token) - |> get("/api/v1/markers", %{timeline: ["notifications"]}) - |> json_response(200) + |> get("/api/v1/markers?timeline[]=notifications") + |> json_response_and_validate_schema(200) assert response == %{ "notifications" => %{ "last_read_id" => "69420", "updated_at" => NaiveDateTime.to_iso8601(marker.updated_at), - "version" => 0 + "version" => 0, + "pleroma" => %{"unread_count" => 7} } } end @@ -45,7 +47,7 @@ defmodule Pleroma.Web.MastodonAPI.MarkerControllerTest do |> assign(:user, user) |> assign(:token, token) |> get("/api/v1/markers", %{timeline: ["notifications"]}) - |> json_response(403) + |> json_response_and_validate_schema(403) assert response == %{"error" => "Insufficient permissions: read:statuses."} end @@ -60,17 +62,19 @@ defmodule Pleroma.Web.MastodonAPI.MarkerControllerTest do conn |> assign(:user, user) |> assign(:token, token) + |> put_req_header("content-type", "application/json") |> post("/api/v1/markers", %{ home: %{last_read_id: "777"}, notifications: %{"last_read_id" => "69420"} }) - |> json_response(200) + |> json_response_and_validate_schema(200) assert %{ "notifications" => %{ "last_read_id" => "69420", "updated_at" => _, - "version" => 0 + "version" => 0, + "pleroma" => %{"unread_count" => 0} } } = response end @@ -89,17 +93,19 @@ defmodule Pleroma.Web.MastodonAPI.MarkerControllerTest do conn |> assign(:user, user) |> assign(:token, token) + |> put_req_header("content-type", "application/json") |> post("/api/v1/markers", %{ home: %{last_read_id: "777"}, notifications: %{"last_read_id" => "69888"} }) - |> json_response(200) + |> json_response_and_validate_schema(200) assert response == %{ "notifications" => %{ "last_read_id" => "69888", "updated_at" => NaiveDateTime.to_iso8601(marker.updated_at), - "version" => 0 + "version" => 0, + "pleroma" => %{"unread_count" => 0} } } end @@ -112,11 +118,12 @@ defmodule Pleroma.Web.MastodonAPI.MarkerControllerTest do conn |> assign(:user, user) |> assign(:token, token) + |> put_req_header("content-type", "application/json") |> post("/api/v1/markers", %{ home: %{last_read_id: "777"}, notifications: %{"last_read_id" => "69420"} }) - |> json_response(403) + |> json_response_and_validate_schema(403) assert response == %{"error" => "Insufficient permissions: write:statuses."} end diff --git a/test/web/mastodon_api/controllers/media_controller_test.exs b/test/web/mastodon_api/controllers/media_controller_test.exs index 042511ca4..6ac4cf63b 100644 --- a/test/web/mastodon_api/controllers/media_controller_test.exs +++ b/test/web/mastodon_api/controllers/media_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do @@ -22,8 +22,8 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do [image: image] end - clear_config([:media_proxy]) - clear_config([Pleroma.Upload]) + setup do: clear_config([:media_proxy]) + setup do: clear_config([Pleroma.Upload]) test "returns uploaded image", %{conn: conn, image: image} do desc = "Description of the image" diff --git a/test/web/mastodon_api/controllers/notification_controller_test.exs b/test/web/mastodon_api/controllers/notification_controller_test.exs index 6f0606250..d9356a844 100644 --- a/test/web/mastodon_api/controllers/notification_controller_test.exs +++ b/test/web/mastodon_api/controllers/notification_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do @@ -12,11 +12,31 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do import Pleroma.Factory + test "does NOT render account/pleroma/relationship if this is disabled by default" do + clear_config([:extensions, :output_relationships_in_statuses_by_default], false) + + %{user: user, conn: conn} = oauth_access(["read:notifications"]) + other_user = insert(:user) + + {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) + {:ok, [_notification]} = Notification.create_notifications(activity) + + response = + conn + |> assign(:user, user) + |> get("/api/v1/notifications") + |> json_response_and_validate_schema(200) + + assert Enum.all?(response, fn n -> + get_in(n, ["account", "pleroma", "relationship"]) == %{} + end) + end + test "list of notifications" do %{user: user, conn: conn} = oauth_access(["read:notifications"]) other_user = insert(:user) - {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) + {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) {:ok, [_notification]} = Notification.create_notifications(activity) @@ -26,11 +46,13 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do |> get("/api/v1/notifications") expected_response = - "hi <span class=\"h-card\"><a data-user=\"#{user.id}\" class=\"u-url mention\" href=\"#{ + "hi <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{user.id}\" href=\"#{ user.ap_id }\" rel=\"ugc\">@<span>#{user.nickname}</span></a></span>" - assert [%{"status" => %{"content" => response}} | _rest] = json_response(conn, 200) + assert [%{"status" => %{"content" => response}} | _rest] = + json_response_and_validate_schema(conn, 200) + assert response == expected_response end @@ -38,52 +60,69 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do %{user: user, conn: conn} = oauth_access(["read:notifications"]) other_user = insert(:user) - {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) + {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) {:ok, [notification]} = Notification.create_notifications(activity) conn = get(conn, "/api/v1/notifications/#{notification.id}") expected_response = - "hi <span class=\"h-card\"><a data-user=\"#{user.id}\" class=\"u-url mention\" href=\"#{ + "hi <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{user.id}\" href=\"#{ user.ap_id }\" rel=\"ugc\">@<span>#{user.nickname}</span></a></span>" - assert %{"status" => %{"content" => response}} = json_response(conn, 200) + assert %{"status" => %{"content" => response}} = json_response_and_validate_schema(conn, 200) assert response == expected_response end + test "dismissing a single notification (deprecated endpoint)" do + %{user: user, conn: conn} = oauth_access(["write:notifications"]) + other_user = insert(:user) + + {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) + + {:ok, [notification]} = Notification.create_notifications(activity) + + conn = + conn + |> assign(:user, user) + |> put_req_header("content-type", "application/json") + |> post("/api/v1/notifications/dismiss", %{"id" => to_string(notification.id)}) + + assert %{} = json_response_and_validate_schema(conn, 200) + end + test "dismissing a single notification" do %{user: user, conn: conn} = oauth_access(["write:notifications"]) other_user = insert(:user) - {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) + {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) {:ok, [notification]} = Notification.create_notifications(activity) conn = conn |> assign(:user, user) - |> post("/api/v1/notifications/dismiss", %{"id" => notification.id}) + |> post("/api/v1/notifications/#{notification.id}/dismiss") - assert %{} = json_response(conn, 200) + assert %{} = json_response_and_validate_schema(conn, 200) end test "clearing all notifications" do %{user: user, conn: conn} = oauth_access(["write:notifications", "read:notifications"]) other_user = insert(:user) - {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) + {:ok, activity} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) {:ok, [_notification]} = Notification.create_notifications(activity) ret_conn = post(conn, "/api/v1/notifications/clear") - assert %{} = json_response(ret_conn, 200) + assert %{} = json_response_and_validate_schema(ret_conn, 200) ret_conn = get(conn, "/api/v1/notifications") - assert all = json_response(ret_conn, 200) + assert all = json_response_and_validate_schema(ret_conn, 200) assert all == [] end @@ -91,10 +130,10 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do %{user: user, conn: conn} = oauth_access(["read:notifications"]) other_user = insert(:user) - {:ok, activity1} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) - {:ok, activity2} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) - {:ok, activity3} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) - {:ok, activity4} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) + {:ok, activity1} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) + {:ok, activity2} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) + {:ok, activity3} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) + {:ok, activity4} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) notification1_id = get_notification_id_by_activity(activity1) notification2_id = get_notification_id_by_activity(activity2) @@ -107,7 +146,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do result = conn |> get("/api/v1/notifications?limit=2&min_id=#{notification1_id}") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result @@ -115,7 +154,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do result = conn |> get("/api/v1/notifications?limit=2&since_id=#{notification1_id}") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result @@ -123,7 +162,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do result = conn |> get("/api/v1/notifications?limit=2&max_id=#{notification4_id}") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result end @@ -134,47 +173,39 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do other_user = insert(:user) {:ok, public_activity} = - CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "public"}) + CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "public"}) {:ok, direct_activity} = - CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "direct"}) + CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "direct"}) {:ok, unlisted_activity} = - CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "unlisted"}) + CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "unlisted"}) {:ok, private_activity} = - CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "private"}) + CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "private"}) - conn_res = - get(conn, "/api/v1/notifications", %{ - exclude_visibilities: ["public", "unlisted", "private"] - }) + query = params_to_query(%{exclude_visibilities: ["public", "unlisted", "private"]}) + conn_res = get(conn, "/api/v1/notifications?" <> query) - assert [%{"status" => %{"id" => id}}] = json_response(conn_res, 200) + assert [%{"status" => %{"id" => id}}] = json_response_and_validate_schema(conn_res, 200) assert id == direct_activity.id - conn_res = - get(conn, "/api/v1/notifications", %{ - exclude_visibilities: ["public", "unlisted", "direct"] - }) + query = params_to_query(%{exclude_visibilities: ["public", "unlisted", "direct"]}) + conn_res = get(conn, "/api/v1/notifications?" <> query) - assert [%{"status" => %{"id" => id}}] = json_response(conn_res, 200) + assert [%{"status" => %{"id" => id}}] = json_response_and_validate_schema(conn_res, 200) assert id == private_activity.id - conn_res = - get(conn, "/api/v1/notifications", %{ - exclude_visibilities: ["public", "private", "direct"] - }) + query = params_to_query(%{exclude_visibilities: ["public", "private", "direct"]}) + conn_res = get(conn, "/api/v1/notifications?" <> query) - assert [%{"status" => %{"id" => id}}] = json_response(conn_res, 200) + assert [%{"status" => %{"id" => id}}] = json_response_and_validate_schema(conn_res, 200) assert id == unlisted_activity.id - conn_res = - get(conn, "/api/v1/notifications", %{ - exclude_visibilities: ["unlisted", "private", "direct"] - }) + query = params_to_query(%{exclude_visibilities: ["unlisted", "private", "direct"]}) + conn_res = get(conn, "/api/v1/notifications?" <> query) - assert [%{"status" => %{"id" => id}}] = json_response(conn_res, 200) + assert [%{"status" => %{"id" => id}}] = json_response_and_validate_schema(conn_res, 200) assert id == public_activity.id end @@ -182,27 +213,25 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do user = insert(:user) %{user: other_user, conn: conn} = oauth_access(["read:notifications"]) - {:ok, public_activity} = - CommonAPI.post(other_user, %{"status" => ".", "visibility" => "public"}) + {:ok, public_activity} = CommonAPI.post(other_user, %{status: ".", visibility: "public"}) {:ok, direct_activity} = - CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "direct"}) + CommonAPI.post(other_user, %{status: "@#{user.nickname}", visibility: "direct"}) {:ok, unlisted_activity} = - CommonAPI.post(other_user, %{"status" => ".", "visibility" => "unlisted"}) + CommonAPI.post(other_user, %{status: ".", visibility: "unlisted"}) - {:ok, private_activity} = - CommonAPI.post(other_user, %{"status" => ".", "visibility" => "private"}) + {:ok, private_activity} = CommonAPI.post(other_user, %{status: ".", visibility: "private"}) - {:ok, _, _} = CommonAPI.favorite(public_activity.id, user) - {:ok, _, _} = CommonAPI.favorite(direct_activity.id, user) - {:ok, _, _} = CommonAPI.favorite(unlisted_activity.id, user) - {:ok, _, _} = CommonAPI.favorite(private_activity.id, user) + {:ok, _} = CommonAPI.favorite(user, public_activity.id) + {:ok, _} = CommonAPI.favorite(user, direct_activity.id) + {:ok, _} = CommonAPI.favorite(user, unlisted_activity.id) + {:ok, _} = CommonAPI.favorite(user, private_activity.id) activity_ids = conn - |> get("/api/v1/notifications", %{exclude_visibilities: ["direct"]}) - |> json_response(200) + |> get("/api/v1/notifications?exclude_visibilities[]=direct") + |> json_response_and_validate_schema(200) |> Enum.map(& &1["status"]["id"]) assert public_activity.id in activity_ids @@ -212,8 +241,8 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do activity_ids = conn - |> get("/api/v1/notifications", %{exclude_visibilities: ["unlisted"]}) - |> json_response(200) + |> get("/api/v1/notifications?exclude_visibilities[]=unlisted") + |> json_response_and_validate_schema(200) |> Enum.map(& &1["status"]["id"]) assert public_activity.id in activity_ids @@ -223,8 +252,8 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do activity_ids = conn - |> get("/api/v1/notifications", %{exclude_visibilities: ["private"]}) - |> json_response(200) + |> get("/api/v1/notifications?exclude_visibilities[]=private") + |> json_response_and_validate_schema(200) |> Enum.map(& &1["status"]["id"]) assert public_activity.id in activity_ids @@ -234,8 +263,8 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do activity_ids = conn - |> get("/api/v1/notifications", %{exclude_visibilities: ["public"]}) - |> json_response(200) + |> get("/api/v1/notifications?exclude_visibilities[]=public") + |> json_response_and_validate_schema(200) |> Enum.map(& &1["status"]["id"]) refute public_activity.id in activity_ids @@ -248,19 +277,18 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do user = insert(:user) %{user: other_user, conn: conn} = oauth_access(["read:notifications"]) - {:ok, public_activity} = - CommonAPI.post(other_user, %{"status" => ".", "visibility" => "public"}) + {:ok, public_activity} = CommonAPI.post(other_user, %{status: ".", visibility: "public"}) {:ok, unlisted_activity} = - CommonAPI.post(other_user, %{"status" => ".", "visibility" => "unlisted"}) + CommonAPI.post(other_user, %{status: ".", visibility: "unlisted"}) {:ok, _, _} = CommonAPI.repeat(public_activity.id, user) {:ok, _, _} = CommonAPI.repeat(unlisted_activity.id, user) activity_ids = conn - |> get("/api/v1/notifications", %{exclude_visibilities: ["unlisted"]}) - |> json_response(200) + |> get("/api/v1/notifications?exclude_visibilities[]=unlisted") + |> json_response_and_validate_schema(200) |> Enum.map(& &1["status"]["id"]) assert public_activity.id in activity_ids @@ -272,9 +300,9 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do %{user: user, conn: conn} = oauth_access(["read:notifications"]) other_user = insert(:user) - {:ok, mention_activity} = CommonAPI.post(other_user, %{"status" => "hey @#{user.nickname}"}) - {:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"}) - {:ok, favorite_activity, _} = CommonAPI.favorite(create_activity.id, other_user) + {:ok, mention_activity} = CommonAPI.post(other_user, %{status: "hey @#{user.nickname}"}) + {:ok, create_activity} = CommonAPI.post(user, %{status: "hey"}) + {:ok, favorite_activity} = CommonAPI.favorite(other_user, create_activity.id) {:ok, reblog_activity, _} = CommonAPI.repeat(create_activity.id, other_user) {:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user) @@ -283,35 +311,84 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do reblog_notification_id = get_notification_id_by_activity(reblog_activity) follow_notification_id = get_notification_id_by_activity(follow_activity) - conn_res = - get(conn, "/api/v1/notifications", %{exclude_types: ["mention", "favourite", "reblog"]}) + query = params_to_query(%{exclude_types: ["mention", "favourite", "reblog"]}) + conn_res = get(conn, "/api/v1/notifications?" <> query) - assert [%{"id" => ^follow_notification_id}] = json_response(conn_res, 200) + assert [%{"id" => ^follow_notification_id}] = json_response_and_validate_schema(conn_res, 200) - conn_res = - get(conn, "/api/v1/notifications", %{exclude_types: ["favourite", "reblog", "follow"]}) + query = params_to_query(%{exclude_types: ["favourite", "reblog", "follow"]}) + conn_res = get(conn, "/api/v1/notifications?" <> query) - assert [%{"id" => ^mention_notification_id}] = json_response(conn_res, 200) + assert [%{"id" => ^mention_notification_id}] = + json_response_and_validate_schema(conn_res, 200) - conn_res = - get(conn, "/api/v1/notifications", %{exclude_types: ["reblog", "follow", "mention"]}) + query = params_to_query(%{exclude_types: ["reblog", "follow", "mention"]}) + conn_res = get(conn, "/api/v1/notifications?" <> query) - assert [%{"id" => ^favorite_notification_id}] = json_response(conn_res, 200) + assert [%{"id" => ^favorite_notification_id}] = + json_response_and_validate_schema(conn_res, 200) - conn_res = - get(conn, "/api/v1/notifications", %{exclude_types: ["follow", "mention", "favourite"]}) + query = params_to_query(%{exclude_types: ["follow", "mention", "favourite"]}) + conn_res = get(conn, "/api/v1/notifications?" <> query) - assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200) + assert [%{"id" => ^reblog_notification_id}] = json_response_and_validate_schema(conn_res, 200) + end + + test "filters notifications using include_types" do + %{user: user, conn: conn} = oauth_access(["read:notifications"]) + other_user = insert(:user) + + {:ok, mention_activity} = CommonAPI.post(other_user, %{status: "hey @#{user.nickname}"}) + {:ok, create_activity} = CommonAPI.post(user, %{status: "hey"}) + {:ok, favorite_activity} = CommonAPI.favorite(other_user, create_activity.id) + {:ok, reblog_activity, _} = CommonAPI.repeat(create_activity.id, other_user) + {:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user) + + mention_notification_id = get_notification_id_by_activity(mention_activity) + favorite_notification_id = get_notification_id_by_activity(favorite_activity) + reblog_notification_id = get_notification_id_by_activity(reblog_activity) + follow_notification_id = get_notification_id_by_activity(follow_activity) + + conn_res = get(conn, "/api/v1/notifications?include_types[]=follow") + + assert [%{"id" => ^follow_notification_id}] = json_response_and_validate_schema(conn_res, 200) + + conn_res = get(conn, "/api/v1/notifications?include_types[]=mention") + + assert [%{"id" => ^mention_notification_id}] = + json_response_and_validate_schema(conn_res, 200) + + conn_res = get(conn, "/api/v1/notifications?include_types[]=favourite") + + assert [%{"id" => ^favorite_notification_id}] = + json_response_and_validate_schema(conn_res, 200) + + conn_res = get(conn, "/api/v1/notifications?include_types[]=reblog") + + assert [%{"id" => ^reblog_notification_id}] = json_response_and_validate_schema(conn_res, 200) + + result = conn |> get("/api/v1/notifications") |> json_response_and_validate_schema(200) + + assert length(result) == 4 + + query = params_to_query(%{include_types: ["follow", "mention", "favourite", "reblog"]}) + + result = + conn + |> get("/api/v1/notifications?" <> query) + |> json_response_and_validate_schema(200) + + assert length(result) == 4 end test "destroy multiple" do %{user: user, conn: conn} = oauth_access(["read:notifications", "write:notifications"]) other_user = insert(:user) - {:ok, activity1} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) - {:ok, activity2} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) - {:ok, activity3} = CommonAPI.post(user, %{"status" => "hi @#{other_user.nickname}"}) - {:ok, activity4} = CommonAPI.post(user, %{"status" => "hi @#{other_user.nickname}"}) + {:ok, activity1} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) + {:ok, activity2} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) + {:ok, activity3} = CommonAPI.post(user, %{status: "hi @#{other_user.nickname}"}) + {:ok, activity4} = CommonAPI.post(user, %{status: "hi @#{other_user.nickname}"}) notification1_id = get_notification_id_by_activity(activity1) notification2_id = get_notification_id_by_activity(activity2) @@ -321,7 +398,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do result = conn |> get("/api/v1/notifications") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert [%{"id" => ^notification2_id}, %{"id" => ^notification1_id}] = result @@ -333,22 +410,19 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do result = conn2 |> get("/api/v1/notifications") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result - conn_destroy = - conn - |> delete("/api/v1/notifications/destroy_multiple", %{ - "ids" => [notification1_id, notification2_id] - }) + query = params_to_query(%{ids: [notification1_id, notification2_id]}) + conn_destroy = delete(conn, "/api/v1/notifications/destroy_multiple?" <> query) - assert json_response(conn_destroy, 200) == %{} + assert json_response_and_validate_schema(conn_destroy, 200) == %{} result = conn2 |> get("/api/v1/notifications") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result end @@ -358,17 +432,17 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do user2 = insert(:user) {:ok, _, _, _} = CommonAPI.follow(user, user2) - {:ok, _} = CommonAPI.post(user2, %{"status" => "hey @#{user.nickname}"}) + {:ok, _} = CommonAPI.post(user2, %{status: "hey @#{user.nickname}"}) ret_conn = get(conn, "/api/v1/notifications") - assert length(json_response(ret_conn, 200)) == 1 + assert length(json_response_and_validate_schema(ret_conn, 200)) == 1 {:ok, _user_relationships} = User.mute(user, user2) conn = get(conn, "/api/v1/notifications") - assert json_response(conn, 200) == [] + assert json_response_and_validate_schema(conn, 200) == [] end test "see notifications after muting user without notifications" do @@ -376,17 +450,17 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do user2 = insert(:user) {:ok, _, _, _} = CommonAPI.follow(user, user2) - {:ok, _} = CommonAPI.post(user2, %{"status" => "hey @#{user.nickname}"}) + {:ok, _} = CommonAPI.post(user2, %{status: "hey @#{user.nickname}"}) ret_conn = get(conn, "/api/v1/notifications") - assert length(json_response(ret_conn, 200)) == 1 + assert length(json_response_and_validate_schema(ret_conn, 200)) == 1 {:ok, _user_relationships} = User.mute(user, user2, false) conn = get(conn, "/api/v1/notifications") - assert length(json_response(conn, 200)) == 1 + assert length(json_response_and_validate_schema(conn, 200)) == 1 end test "see notifications after muting user with notifications and with_muted parameter" do @@ -394,35 +468,44 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do user2 = insert(:user) {:ok, _, _, _} = CommonAPI.follow(user, user2) - {:ok, _} = CommonAPI.post(user2, %{"status" => "hey @#{user.nickname}"}) + {:ok, _} = CommonAPI.post(user2, %{status: "hey @#{user.nickname}"}) ret_conn = get(conn, "/api/v1/notifications") - assert length(json_response(ret_conn, 200)) == 1 + assert length(json_response_and_validate_schema(ret_conn, 200)) == 1 {:ok, _user_relationships} = User.mute(user, user2) - conn = get(conn, "/api/v1/notifications", %{"with_muted" => "true"}) + conn = get(conn, "/api/v1/notifications?with_muted=true") - assert length(json_response(conn, 200)) == 1 + assert length(json_response_and_validate_schema(conn, 200)) == 1 end - test "see move notifications with `with_move` parameter" do + @tag capture_log: true + test "see move notifications" do old_user = insert(:user) new_user = insert(:user, also_known_as: [old_user.ap_id]) %{user: follower, conn: conn} = oauth_access(["read:notifications"]) + old_user_url = old_user.ap_id + + body = + File.read!("test/fixtures/users_mock/localhost.json") + |> String.replace("{{nickname}}", old_user.nickname) + |> Jason.encode!() + + Tesla.Mock.mock(fn + %{method: :get, url: ^old_user_url} -> + %Tesla.Env{status: 200, body: body} + end) + User.follow(follower, old_user) Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user) Pleroma.Tests.ObanHelpers.perform_all() - ret_conn = get(conn, "/api/v1/notifications") - - assert json_response(ret_conn, 200) == [] - - conn = get(conn, "/api/v1/notifications", %{"with_move" => "true"}) + conn = get(conn, "/api/v1/notifications") - assert length(json_response(conn, 200)) == 1 + assert length(json_response_and_validate_schema(conn, 200)) == 1 end describe "link headers" do @@ -432,14 +515,14 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do {:ok, activity1} = CommonAPI.post(other_user, %{ - "status" => "hi @#{user.nickname}", - "visibility" => "public" + status: "hi @#{user.nickname}", + visibility: "public" }) {:ok, activity2} = CommonAPI.post(other_user, %{ - "status" => "hi @#{user.nickname}", - "visibility" => "public" + status: "hi @#{user.nickname}", + visibility: "public" }) notification1 = Repo.get_by(Notification, activity_id: activity1.id) @@ -448,10 +531,10 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do conn = conn |> assign(:user, user) - |> get("/api/v1/notifications", %{media_only: true}) + |> get("/api/v1/notifications?limit=5") assert [link_header] = get_resp_header(conn, "link") - assert link_header =~ ~r/media_only=true/ + assert link_header =~ ~r/limit=5/ assert link_header =~ ~r/min_id=#{notification2.id}/ assert link_header =~ ~r/max_id=#{notification1.id}/ end @@ -464,20 +547,20 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do %{id: account_id} = other_user1 = insert(:user) other_user2 = insert(:user) - {:ok, _activity} = CommonAPI.post(other_user1, %{"status" => "hi @#{user.nickname}"}) - {:ok, _activity} = CommonAPI.post(other_user2, %{"status" => "bye @#{user.nickname}"}) + {:ok, _activity} = CommonAPI.post(other_user1, %{status: "hi @#{user.nickname}"}) + {:ok, _activity} = CommonAPI.post(other_user2, %{status: "bye @#{user.nickname}"}) assert [%{"account" => %{"id" => ^account_id}}] = conn |> assign(:user, user) - |> get("/api/v1/notifications", %{account_id: account_id}) - |> json_response(200) + |> get("/api/v1/notifications?account_id=#{account_id}") + |> json_response_and_validate_schema(200) assert %{"error" => "Account is not found"} = conn |> assign(:user, user) - |> get("/api/v1/notifications", %{account_id: "cofe"}) - |> json_response(404) + |> get("/api/v1/notifications?account_id=cofe") + |> json_response_and_validate_schema(404) end end @@ -487,4 +570,11 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do |> Map.get(:id) |> to_string() end + + defp params_to_query(%{} = params) do + Enum.map_join(params, "&", fn + {k, v} when is_list(v) -> Enum.map_join(v, "&", &"#{k}[]=#{&1}") + {k, v} -> k <> "=" <> v + end) + end end diff --git a/test/web/mastodon_api/controllers/poll_controller_test.exs b/test/web/mastodon_api/controllers/poll_controller_test.exs index 5a1cea11b..f41de6448 100644 --- a/test/web/mastodon_api/controllers/poll_controller_test.exs +++ b/test/web/mastodon_api/controllers/poll_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.PollControllerTest do @@ -16,15 +16,15 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do test "returns poll entity for object id", %{user: user, conn: conn} do {:ok, activity} = CommonAPI.post(user, %{ - "status" => "Pleroma does", - "poll" => %{"options" => ["what Mastodon't", "n't what Mastodoes"], "expires_in" => 20} + status: "Pleroma does", + poll: %{options: ["what Mastodon't", "n't what Mastodoes"], expires_in: 20} }) object = Object.normalize(activity) conn = get(conn, "/api/v1/polls/#{object.id}") - response = json_response(conn, 200) + response = json_response_and_validate_schema(conn, 200) id = to_string(object.id) assert %{"id" => ^id, "expired" => false, "multiple" => false} = response end @@ -34,16 +34,16 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do {:ok, activity} = CommonAPI.post(other_user, %{ - "status" => "Pleroma does", - "poll" => %{"options" => ["what Mastodon't", "n't what Mastodoes"], "expires_in" => 20}, - "visibility" => "private" + status: "Pleroma does", + poll: %{options: ["what Mastodon't", "n't what Mastodoes"], expires_in: 20}, + visibility: "private" }) object = Object.normalize(activity) conn = get(conn, "/api/v1/polls/#{object.id}") - assert json_response(conn, 404) + assert json_response_and_validate_schema(conn, 404) end end @@ -55,19 +55,22 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do {:ok, activity} = CommonAPI.post(other_user, %{ - "status" => "A very delicious sandwich", - "poll" => %{ - "options" => ["Lettuce", "Grilled Bacon", "Tomato"], - "expires_in" => 20, - "multiple" => true + status: "A very delicious sandwich", + poll: %{ + options: ["Lettuce", "Grilled Bacon", "Tomato"], + expires_in: 20, + multiple: true } }) object = Object.normalize(activity) - conn = post(conn, "/api/v1/polls/#{object.id}/votes", %{"choices" => [0, 1, 2]}) + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [0, 1, 2]}) - assert json_response(conn, 200) + assert json_response_and_validate_schema(conn, 200) object = Object.get_by_id(object.id) assert Enum.all?(object.data["anyOf"], fn %{"replies" => %{"totalItems" => total_items}} -> @@ -78,15 +81,16 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do test "author can't vote", %{user: user, conn: conn} do {:ok, activity} = CommonAPI.post(user, %{ - "status" => "Am I cute?", - "poll" => %{"options" => ["Yes", "No"], "expires_in" => 20} + status: "Am I cute?", + poll: %{options: ["Yes", "No"], expires_in: 20} }) object = Object.normalize(activity) assert conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [1]}) - |> json_response(422) == %{"error" => "Poll's author can't vote"} + |> json_response_and_validate_schema(422) == %{"error" => "Poll's author can't vote"} object = Object.get_by_id(object.id) @@ -98,15 +102,16 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do {:ok, activity} = CommonAPI.post(other_user, %{ - "status" => "The glass is", - "poll" => %{"options" => ["half empty", "half full"], "expires_in" => 20} + status: "The glass is", + poll: %{options: ["half empty", "half full"], expires_in: 20} }) object = Object.normalize(activity) assert conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [0, 1]}) - |> json_response(422) == %{"error" => "Too many choices"} + |> json_response_and_validate_schema(422) == %{"error" => "Too many choices"} object = Object.get_by_id(object.id) @@ -120,21 +125,27 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do {:ok, activity} = CommonAPI.post(other_user, %{ - "status" => "Am I cute?", - "poll" => %{"options" => ["Yes", "No"], "expires_in" => 20} + status: "Am I cute?", + poll: %{options: ["Yes", "No"], expires_in: 20} }) object = Object.normalize(activity) - conn = post(conn, "/api/v1/polls/#{object.id}/votes", %{"choices" => [2]}) + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [2]}) - assert json_response(conn, 422) == %{"error" => "Invalid indices"} + assert json_response_and_validate_schema(conn, 422) == %{"error" => "Invalid indices"} end test "returns 404 error when object is not exist", %{conn: conn} do - conn = post(conn, "/api/v1/polls/1/votes", %{"choices" => [0]}) + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/polls/1/votes", %{"choices" => [0]}) - assert json_response(conn, 404) == %{"error" => "Record not found"} + assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"} end test "returns 404 when poll is private and not available for user", %{conn: conn} do @@ -142,16 +153,19 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do {:ok, activity} = CommonAPI.post(other_user, %{ - "status" => "Am I cute?", - "poll" => %{"options" => ["Yes", "No"], "expires_in" => 20}, - "visibility" => "private" + status: "Am I cute?", + poll: %{options: ["Yes", "No"], expires_in: 20}, + visibility: "private" }) object = Object.normalize(activity) - conn = post(conn, "/api/v1/polls/#{object.id}/votes", %{"choices" => [0]}) + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [0]}) - assert json_response(conn, 404) == %{"error" => "Record not found"} + assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"} end end end diff --git a/test/web/mastodon_api/controllers/report_controller_test.exs b/test/web/mastodon_api/controllers/report_controller_test.exs index 53c132ff4..6636cff96 100644 --- a/test/web/mastodon_api/controllers/report_controller_test.exs +++ b/test/web/mastodon_api/controllers/report_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do @@ -14,7 +14,7 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do setup do target_user = insert(:user) - {:ok, activity} = CommonAPI.post(target_user, %{"status" => "foobar"}) + {:ok, activity} = CommonAPI.post(target_user, %{status: "foobar"}) [target_user: target_user, activity: activity] end @@ -22,8 +22,9 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do test "submit a basic report", %{conn: conn, target_user: target_user} do assert %{"action_taken" => false, "id" => _} = conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/reports", %{"account_id" => target_user.id}) - |> json_response(200) + |> json_response_and_validate_schema(200) end test "submit a report with statuses and comment", %{ @@ -33,23 +34,25 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do } do assert %{"action_taken" => false, "id" => _} = conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/reports", %{ "account_id" => target_user.id, "status_ids" => [activity.id], "comment" => "bad status!", "forward" => "false" }) - |> json_response(200) + |> json_response_and_validate_schema(200) end test "account_id is required", %{ conn: conn, activity: activity } do - assert %{"error" => "Valid `account_id` required"} = + assert %{"error" => "Missing field: account_id."} = conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/reports", %{"status_ids" => [activity.id]}) - |> json_response(400) + |> json_response_and_validate_schema(400) end test "comment must be up to the size specified in the config", %{ @@ -63,16 +66,30 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do assert ^error = conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/reports", %{"account_id" => target_user.id, "comment" => comment}) - |> json_response(400) + |> json_response_and_validate_schema(400) end test "returns error when account is not exist", %{ conn: conn, activity: activity } do - conn = post(conn, "/api/v1/reports", %{"status_ids" => [activity.id], "account_id" => "foo"}) + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/reports", %{"status_ids" => [activity.id], "account_id" => "foo"}) - assert json_response(conn, 400) == %{"error" => "Account not found"} + assert json_response_and_validate_schema(conn, 400) == %{"error" => "Account not found"} + end + + test "doesn't fail if an admin has no email", %{conn: conn, target_user: target_user} do + insert(:user, %{is_admin: true, email: nil}) + + assert %{"action_taken" => false, "id" => _} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/reports", %{"account_id" => target_user.id}) + |> json_response_and_validate_schema(200) end end diff --git a/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs b/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs index 6317d1b47..1ff871c89 100644 --- a/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs +++ b/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do @@ -11,7 +11,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do import Pleroma.Factory import Ecto.Query - clear_config([ScheduledActivity, :enabled]) + setup do: clear_config([ScheduledActivity, :enabled]) test "shows scheduled activities" do %{user: user, conn: conn} = oauth_access(["read:statuses"]) @@ -24,19 +24,19 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do # min_id conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&min_id=#{scheduled_activity_id1}") - result = json_response(conn_res, 200) + result = json_response_and_validate_schema(conn_res, 200) assert [%{"id" => ^scheduled_activity_id3}, %{"id" => ^scheduled_activity_id2}] = result # since_id conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&since_id=#{scheduled_activity_id1}") - result = json_response(conn_res, 200) + result = json_response_and_validate_schema(conn_res, 200) assert [%{"id" => ^scheduled_activity_id4}, %{"id" => ^scheduled_activity_id3}] = result # max_id conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&max_id=#{scheduled_activity_id4}") - result = json_response(conn_res, 200) + result = json_response_and_validate_schema(conn_res, 200) assert [%{"id" => ^scheduled_activity_id3}, %{"id" => ^scheduled_activity_id2}] = result end @@ -46,12 +46,12 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do res_conn = get(conn, "/api/v1/scheduled_statuses/#{scheduled_activity.id}") - assert %{"id" => scheduled_activity_id} = json_response(res_conn, 200) + assert %{"id" => scheduled_activity_id} = json_response_and_validate_schema(res_conn, 200) assert scheduled_activity_id == scheduled_activity.id |> to_string() res_conn = get(conn, "/api/v1/scheduled_statuses/404") - assert %{"error" => "Record not found"} = json_response(res_conn, 404) + assert %{"error" => "Record not found"} = json_response_and_validate_schema(res_conn, 404) end test "updates a scheduled activity" do @@ -74,22 +74,32 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do assert job.args == %{"activity_id" => scheduled_activity.id} assert DateTime.truncate(job.scheduled_at, :second) == to_datetime(scheduled_at) - new_scheduled_at = Timex.shift(NaiveDateTime.utc_now(), minutes: 120) + new_scheduled_at = + NaiveDateTime.utc_now() + |> Timex.shift(minutes: 120) + |> Timex.format!("%Y-%m-%dT%H:%M:%S.%fZ", :strftime) res_conn = - put(conn, "/api/v1/scheduled_statuses/#{scheduled_activity.id}", %{ + conn + |> put_req_header("content-type", "application/json") + |> put("/api/v1/scheduled_statuses/#{scheduled_activity.id}", %{ scheduled_at: new_scheduled_at }) - assert %{"scheduled_at" => expected_scheduled_at} = json_response(res_conn, 200) + assert %{"scheduled_at" => expected_scheduled_at} = + json_response_and_validate_schema(res_conn, 200) + assert expected_scheduled_at == Pleroma.Web.CommonAPI.Utils.to_masto_date(new_scheduled_at) job = refresh_record(job) assert DateTime.truncate(job.scheduled_at, :second) == to_datetime(new_scheduled_at) - res_conn = put(conn, "/api/v1/scheduled_statuses/404", %{scheduled_at: new_scheduled_at}) + res_conn = + conn + |> put_req_header("content-type", "application/json") + |> put("/api/v1/scheduled_statuses/404", %{scheduled_at: new_scheduled_at}) - assert %{"error" => "Record not found"} = json_response(res_conn, 404) + assert %{"error" => "Record not found"} = json_response_and_validate_schema(res_conn, 404) end test "deletes a scheduled activity" do @@ -115,7 +125,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do |> assign(:user, user) |> delete("/api/v1/scheduled_statuses/#{scheduled_activity.id}") - assert %{} = json_response(res_conn, 200) + assert %{} = json_response_and_validate_schema(res_conn, 200) refute Repo.get(ScheduledActivity, scheduled_activity.id) refute Repo.get(Oban.Job, job.id) @@ -124,6 +134,6 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do |> assign(:user, user) |> delete("/api/v1/scheduled_statuses/#{scheduled_activity.id}") - assert %{"error" => "Record not found"} = json_response(res_conn, 404) + assert %{"error" => "Record not found"} = json_response_and_validate_schema(res_conn, 404) end end diff --git a/test/web/mastodon_api/controllers/search_controller_test.exs b/test/web/mastodon_api/controllers/search_controller_test.exs index effae130c..7d0cafccc 100644 --- a/test/web/mastodon_api/controllers/search_controller_test.exs +++ b/test/web/mastodon_api/controllers/search_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do @@ -13,7 +13,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do import Tesla.Mock import Mock - setup do + setup_all do mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) :ok end @@ -27,8 +27,8 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do capture_log(fn -> results = conn - |> get("/api/v2/search", %{"q" => "2hu"}) - |> json_response(200) + |> get("/api/v2/search?q=2hu") + |> json_response_and_validate_schema(200) assert results["accounts"] == [] assert results["statuses"] == [] @@ -42,20 +42,20 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do user_two = insert(:user, %{nickname: "shp@shitposter.club"}) user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) - {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu private 天子"}) + {:ok, activity} = CommonAPI.post(user, %{status: "This is about 2hu private 天子"}) {:ok, _activity} = CommonAPI.post(user, %{ - "status" => "This is about 2hu, but private", - "visibility" => "private" + status: "This is about 2hu, but private", + visibility: "private" }) - {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"}) + {:ok, _} = CommonAPI.post(user_two, %{status: "This isn't"}) results = conn - |> get("/api/v2/search", %{"q" => "2hu #private"}) - |> json_response(200) + |> get("/api/v2/search?#{URI.encode_query(%{q: "2hu #private"})}") + |> json_response_and_validate_schema(200) [account | _] = results["accounts"] assert account["id"] == to_string(user_three.id) @@ -68,8 +68,8 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do assert status["id"] == to_string(activity.id) results = - get(conn, "/api/v2/search", %{"q" => "天子"}) - |> json_response(200) + get(conn, "/api/v2/search?q=天子") + |> json_response_and_validate_schema(200) [status] = results["statuses"] assert status["id"] == to_string(activity.id) @@ -80,17 +80,17 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do user_smith = insert(:user, %{nickname: "Agent", name: "I love 2hu"}) user_neo = insert(:user, %{nickname: "Agent Neo", name: "Agent"}) - {:ok, act1} = CommonAPI.post(user, %{"status" => "This is about 2hu private 天子"}) - {:ok, act2} = CommonAPI.post(user_smith, %{"status" => "Agent Smith"}) - {:ok, act3} = CommonAPI.post(user_neo, %{"status" => "Agent Smith"}) + {:ok, act1} = CommonAPI.post(user, %{status: "This is about 2hu private 天子"}) + {:ok, act2} = CommonAPI.post(user_smith, %{status: "Agent Smith"}) + {:ok, act3} = CommonAPI.post(user_neo, %{status: "Agent Smith"}) Pleroma.User.block(user, user_smith) results = conn |> assign(:user, user) |> assign(:token, insert(:oauth_token, user: user, scopes: ["read"])) - |> get("/api/v2/search", %{"q" => "Agent"}) - |> json_response(200) + |> get("/api/v2/search?q=Agent") + |> json_response_and_validate_schema(200) status_ids = Enum.map(results["statuses"], fn g -> g["id"] end) @@ -107,8 +107,8 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do results = conn - |> get("/api/v1/accounts/search", %{"q" => "shp"}) - |> json_response(200) + |> get("/api/v1/accounts/search?q=shp") + |> json_response_and_validate_schema(200) result_ids = for result <- results, do: result["acct"] @@ -117,8 +117,8 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do results = conn - |> get("/api/v1/accounts/search", %{"q" => "2hu"}) - |> json_response(200) + |> get("/api/v1/accounts/search?q=2hu") + |> json_response_and_validate_schema(200) result_ids = for result <- results, do: result["acct"] @@ -130,8 +130,8 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do results = conn - |> get("/api/v1/accounts/search", %{"q" => "shp@shitposter.club xxx "}) - |> json_response(200) + |> get("/api/v1/accounts/search?q=shp@shitposter.club xxx") + |> json_response_and_validate_schema(200) assert length(results) == 1 end @@ -146,8 +146,8 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do capture_log(fn -> results = conn - |> get("/api/v1/search", %{"q" => "2hu"}) - |> json_response(200) + |> get("/api/v1/search?q=2hu") + |> json_response_and_validate_schema(200) assert results["accounts"] == [] assert results["statuses"] == [] @@ -161,20 +161,20 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do user_two = insert(:user, %{nickname: "shp@shitposter.club"}) user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) - {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"}) + {:ok, activity} = CommonAPI.post(user, %{status: "This is about 2hu"}) {:ok, _activity} = CommonAPI.post(user, %{ - "status" => "This is about 2hu, but private", - "visibility" => "private" + status: "This is about 2hu, but private", + visibility: "private" }) - {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"}) + {:ok, _} = CommonAPI.post(user_two, %{status: "This isn't"}) results = conn - |> get("/api/v1/search", %{"q" => "2hu"}) - |> json_response(200) + |> get("/api/v1/search?q=2hu") + |> json_response_and_validate_schema(200) [account | _] = results["accounts"] assert account["id"] == to_string(user_three.id) @@ -189,13 +189,13 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do capture_log(fn -> {:ok, %{id: activity_id}} = CommonAPI.post(insert(:user), %{ - "status" => "check out https://shitposter.club/notice/2827873" + status: "check out https://shitposter.club/notice/2827873" }) results = conn - |> get("/api/v1/search", %{"q" => "https://shitposter.club/notice/2827873"}) - |> json_response(200) + |> get("/api/v1/search?q=https://shitposter.club/notice/2827873") + |> json_response_and_validate_schema(200) [status, %{"id" => ^activity_id}] = results["statuses"] @@ -207,15 +207,17 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do test "search doesn't show statuses that it shouldn't", %{conn: conn} do {:ok, activity} = CommonAPI.post(insert(:user), %{ - "status" => "This is about 2hu, but private", - "visibility" => "private" + status: "This is about 2hu, but private", + visibility: "private" }) capture_log(fn -> + q = Object.normalize(activity).data["id"] + results = conn - |> get("/api/v1/search", %{"q" => Object.normalize(activity).data["id"]}) - |> json_response(200) + |> get("/api/v1/search?q=#{q}") + |> json_response_and_validate_schema(200) [] = results["statuses"] end) @@ -228,8 +230,8 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do conn |> assign(:user, user) |> assign(:token, insert(:oauth_token, user: user, scopes: ["read"])) - |> get("/api/v1/search", %{"q" => "mike@osada.macgirvin.com", "resolve" => "true"}) - |> json_response(200) + |> get("/api/v1/search?q=mike@osada.macgirvin.com&resolve=true") + |> json_response_and_validate_schema(200) [account] = results["accounts"] assert account["acct"] == "mike@osada.macgirvin.com" @@ -238,8 +240,8 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do test "search doesn't fetch remote accounts if resolve is false", %{conn: conn} do results = conn - |> get("/api/v1/search", %{"q" => "mike@osada.macgirvin.com", "resolve" => "false"}) - |> json_response(200) + |> get("/api/v1/search?q=mike@osada.macgirvin.com&resolve=false") + |> json_response_and_validate_schema(200) assert [] == results["accounts"] end @@ -249,21 +251,21 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do _user_two = insert(:user, %{nickname: "shp@shitposter.club"}) _user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) - {:ok, _activity1} = CommonAPI.post(user, %{"status" => "This is about 2hu"}) - {:ok, _activity2} = CommonAPI.post(user, %{"status" => "This is also about 2hu"}) + {:ok, _activity1} = CommonAPI.post(user, %{status: "This is about 2hu"}) + {:ok, _activity2} = CommonAPI.post(user, %{status: "This is also about 2hu"}) result = conn - |> get("/api/v1/search", %{"q" => "2hu", "limit" => 1}) + |> get("/api/v1/search?q=2hu&limit=1") - assert results = json_response(result, 200) + assert results = json_response_and_validate_schema(result, 200) assert [%{"id" => activity_id1}] = results["statuses"] assert [_] = results["accounts"] results = conn - |> get("/api/v1/search", %{"q" => "2hu", "limit" => 1, "offset" => 1}) - |> json_response(200) + |> get("/api/v1/search?q=2hu&limit=1&offset=1") + |> json_response_and_validate_schema(200) assert [%{"id" => activity_id2}] = results["statuses"] assert [] = results["accounts"] @@ -275,30 +277,30 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do user = insert(:user) _user_two = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) - {:ok, _activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"}) + {:ok, _activity} = CommonAPI.post(user, %{status: "This is about 2hu"}) assert %{"statuses" => [_activity], "accounts" => [], "hashtags" => []} = conn - |> get("/api/v1/search", %{"q" => "2hu", "type" => "statuses"}) - |> json_response(200) + |> get("/api/v1/search?q=2hu&type=statuses") + |> json_response_and_validate_schema(200) assert %{"statuses" => [], "accounts" => [_user_two], "hashtags" => []} = conn - |> get("/api/v1/search", %{"q" => "2hu", "type" => "accounts"}) - |> json_response(200) + |> get("/api/v1/search?q=2hu&type=accounts") + |> json_response_and_validate_schema(200) end test "search uses account_id to filter statuses by the author", %{conn: conn} do user = insert(:user, %{nickname: "shp@shitposter.club"}) user_two = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) - {:ok, activity1} = CommonAPI.post(user, %{"status" => "This is about 2hu"}) - {:ok, activity2} = CommonAPI.post(user_two, %{"status" => "This is also about 2hu"}) + {:ok, activity1} = CommonAPI.post(user, %{status: "This is about 2hu"}) + {:ok, activity2} = CommonAPI.post(user_two, %{status: "This is also about 2hu"}) results = conn - |> get("/api/v1/search", %{"q" => "2hu", "account_id" => user.id}) - |> json_response(200) + |> get("/api/v1/search?q=2hu&account_id=#{user.id}") + |> json_response_and_validate_schema(200) assert [%{"id" => activity_id1}] = results["statuses"] assert activity_id1 == activity1.id @@ -306,8 +308,8 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do results = conn - |> get("/api/v1/search", %{"q" => "2hu", "account_id" => user_two.id}) - |> json_response(200) + |> get("/api/v1/search?q=2hu&account_id=#{user_two.id}") + |> json_response_and_validate_schema(200) assert [%{"id" => activity_id2}] = results["statuses"] assert activity_id2 == activity2.id diff --git a/test/web/mastodon_api/controllers/status_controller_test.exs b/test/web/mastodon_api/controllers/status_controller_test.exs index 781c3f7dc..a4403132c 100644 --- a/test/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/web/mastodon_api/controllers/status_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do @@ -19,9 +19,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do import Pleroma.Factory - clear_config([:instance, :federating]) - clear_config([:instance, :allow_relay]) - clear_config([:rich_media, :enabled]) + setup do: clear_config([:instance, :federating]) + setup do: clear_config([:instance, :allow_relay]) + setup do: clear_config([:rich_media, :enabled]) describe "posting statuses" do setup do: oauth_access(["write:statuses"]) @@ -32,13 +32,14 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do response = conn + |> put_req_header("content-type", "application/json") |> post("api/v1/statuses", %{ "content_type" => "text/plain", "source" => "Pleroma FE", "status" => "Hello world", "visibility" => "public" }) - |> json_response(200) + |> json_response_and_validate_schema(200) assert response["reblogs_count"] == 0 ObanHelpers.perform_all() @@ -46,7 +47,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do response = conn |> get("api/v1/statuses/#{response["id"]}", %{}) - |> json_response(200) + |> json_response_and_validate_schema(200) assert response["reblogs_count"] == 0 end @@ -56,6 +57,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do conn_one = conn + |> put_req_header("content-type", "application/json") |> put_req_header("idempotency-key", idempotency_key) |> post("/api/v1/statuses", %{ "status" => "cofe", @@ -68,12 +70,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert ttl > :timer.seconds(6 * 60 * 60 - 1) assert %{"content" => "cofe", "id" => id, "spoiler_text" => "2hu", "sensitive" => false} = - json_response(conn_one, 200) + json_response_and_validate_schema(conn_one, 200) assert Activity.get_by_id(id) conn_two = conn + |> put_req_header("content-type", "application/json") |> put_req_header("idempotency-key", idempotency_key) |> post("/api/v1/statuses", %{ "status" => "cofe", @@ -86,13 +89,14 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do conn_three = conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/statuses", %{ "status" => "cofe", "spoiler_text" => "2hu", "sensitive" => "false" }) - assert %{"id" => third_id} = json_response(conn_three, 200) + assert %{"id" => third_id} = json_response_and_validate_schema(conn_three, 200) refute id == third_id # An activity that will expire: @@ -101,12 +105,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do conn_four = conn + |> put_req_header("content-type", "application/json") |> post("api/v1/statuses", %{ "status" => "oolong", "expires_in" => expires_in }) - assert fourth_response = %{"id" => fourth_id} = json_response(conn_four, 200) + assert fourth_response = + %{"id" => fourth_id} = json_response_and_validate_schema(conn_four, 200) + assert activity = Activity.get_by_id(fourth_id) assert expiration = ActivityExpiration.get_by_activity_id(fourth_id) @@ -130,22 +137,24 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert %{"error" => "Expiry date is too soon"} = conn + |> put_req_header("content-type", "application/json") |> post("api/v1/statuses", %{ "status" => "oolong", "expires_in" => expires_in }) - |> json_response(422) + |> json_response_and_validate_schema(422) # 30 minutes expires_in = 30 * 60 assert %{"error" => "Expiry date is too soon"} = conn + |> put_req_header("content-type", "application/json") |> post("api/v1/statuses", %{ "status" => "oolong", "expires_in" => expires_in }) - |> json_response(422) + |> json_response_and_validate_schema(422) end test "posting an undefined status with an attachment", %{user: user, conn: conn} do @@ -158,21 +167,24 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id) conn = - post(conn, "/api/v1/statuses", %{ + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ "media_ids" => [to_string(upload.id)] }) - assert json_response(conn, 200) + assert json_response_and_validate_schema(conn, 200) end test "replying to a status", %{user: user, conn: conn} do - {:ok, replied_to} = CommonAPI.post(user, %{"status" => "cofe"}) + {:ok, replied_to} = CommonAPI.post(user, %{status: "cofe"}) conn = conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => replied_to.id}) - assert %{"content" => "xD", "id" => id} = json_response(conn, 200) + assert %{"content" => "xD", "id" => id} = json_response_and_validate_schema(conn, 200) activity = Activity.get_by_id(id) @@ -184,43 +196,56 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do user: user, conn: conn } do - {:ok, replied_to} = CommonAPI.post(user, %{"status" => "suya..", "visibility" => "direct"}) + {:ok, replied_to} = CommonAPI.post(user, %{status: "suya..", visibility: "direct"}) Enum.each(["public", "private", "unlisted"], fn visibility -> conn = conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/statuses", %{ "status" => "@#{user.nickname} hey", "in_reply_to_id" => replied_to.id, "visibility" => visibility }) - assert json_response(conn, 422) == %{"error" => "The message visibility must be direct"} + assert json_response_and_validate_schema(conn, 422) == %{ + "error" => "The message visibility must be direct" + } end) end test "posting a status with an invalid in_reply_to_id", %{conn: conn} do - conn = post(conn, "/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => ""}) + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => ""}) - assert %{"content" => "xD", "id" => id} = json_response(conn, 200) + assert %{"content" => "xD", "id" => id} = json_response_and_validate_schema(conn, 200) assert Activity.get_by_id(id) end test "posting a sensitive status", %{conn: conn} do - conn = post(conn, "/api/v1/statuses", %{"status" => "cofe", "sensitive" => true}) + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{"status" => "cofe", "sensitive" => true}) + + assert %{"content" => "cofe", "id" => id, "sensitive" => true} = + json_response_and_validate_schema(conn, 200) - assert %{"content" => "cofe", "id" => id, "sensitive" => true} = json_response(conn, 200) assert Activity.get_by_id(id) end test "posting a fake status", %{conn: conn} do real_conn = - post(conn, "/api/v1/statuses", %{ + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ "status" => "\"Tenshi Eating a Corndog\" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it" }) - real_status = json_response(real_conn, 200) + real_status = json_response_and_validate_schema(real_conn, 200) assert real_status assert Object.get_by_ap_id(real_status["uri"]) @@ -234,13 +259,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do |> Kernel.put_in(["pleroma", "conversation_id"], nil) fake_conn = - post(conn, "/api/v1/statuses", %{ + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ "status" => "\"Tenshi Eating a Corndog\" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it", "preview" => true }) - fake_status = json_response(fake_conn, 200) + fake_status = json_response_and_validate_schema(fake_conn, 200) assert fake_status refute Object.get_by_ap_id(fake_status["uri"]) @@ -261,11 +288,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do Config.put([:rich_media, :enabled], true) conn = - post(conn, "/api/v1/statuses", %{ + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ "status" => "https://example.com/ogp" }) - assert %{"id" => id, "card" => %{"title" => "The Rock"}} = json_response(conn, 200) + assert %{"id" => id, "card" => %{"title" => "The Rock"}} = + json_response_and_validate_schema(conn, 200) + assert Activity.get_by_id(id) end @@ -273,9 +304,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do user2 = insert(:user) content = "direct cofe @#{user2.nickname}" - conn = post(conn, "api/v1/statuses", %{"status" => content, "visibility" => "direct"}) + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"}) - assert %{"id" => id} = response = json_response(conn, 200) + assert %{"id" => id} = response = json_response_and_validate_schema(conn, 200) assert response["visibility"] == "direct" assert response["pleroma"]["direct_conversation_id"] assert activity = Activity.get_by_id(id) @@ -289,21 +323,45 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do setup do: oauth_access(["write:statuses"]) test "creates a scheduled activity", %{conn: conn} do - scheduled_at = NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(120), :millisecond) + scheduled_at = + NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(120), :millisecond) + |> NaiveDateTime.to_iso8601() + |> Kernel.<>("Z") conn = - post(conn, "/api/v1/statuses", %{ + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ "status" => "scheduled", "scheduled_at" => scheduled_at }) - assert %{"scheduled_at" => expected_scheduled_at} = json_response(conn, 200) + assert %{"scheduled_at" => expected_scheduled_at} = + json_response_and_validate_schema(conn, 200) + assert expected_scheduled_at == CommonAPI.Utils.to_masto_date(scheduled_at) assert [] == Repo.all(Activity) end + test "ignores nil values", %{conn: conn} do + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ + "status" => "not scheduled", + "scheduled_at" => nil + }) + + assert result = json_response_and_validate_schema(conn, 200) + assert Activity.get_by_id(result["id"]) + end + test "creates a scheduled activity with a media attachment", %{user: user, conn: conn} do - scheduled_at = NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(120), :millisecond) + scheduled_at = + NaiveDateTime.utc_now() + |> NaiveDateTime.add(:timer.minutes(120), :millisecond) + |> NaiveDateTime.to_iso8601() + |> Kernel.<>("Z") file = %Plug.Upload{ content_type: "image/jpg", @@ -314,13 +372,17 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id) conn = - post(conn, "/api/v1/statuses", %{ + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ "media_ids" => [to_string(upload.id)], "status" => "scheduled", "scheduled_at" => scheduled_at }) - assert %{"media_attachments" => [media_attachment]} = json_response(conn, 200) + assert %{"media_attachments" => [media_attachment]} = + json_response_and_validate_schema(conn, 200) + assert %{"type" => "image"} = media_attachment end @@ -328,14 +390,18 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do %{conn: conn} do scheduled_at = NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(5) - 1, :millisecond) + |> NaiveDateTime.to_iso8601() + |> Kernel.<>("Z") conn = - post(conn, "/api/v1/statuses", %{ + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ "status" => "not scheduled", "scheduled_at" => scheduled_at }) - assert %{"content" => "not scheduled"} = json_response(conn, 200) + assert %{"content" => "not scheduled"} = json_response_and_validate_schema(conn, 200) assert [] == Repo.all(ScheduledActivity) end @@ -344,14 +410,19 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do NaiveDateTime.utc_now() |> NaiveDateTime.add(:timer.minutes(6), :millisecond) |> NaiveDateTime.to_iso8601() + # TODO + |> Kernel.<>("Z") attrs = %{params: %{}, scheduled_at: today} {:ok, _} = ScheduledActivity.create(user, attrs) {:ok, _} = ScheduledActivity.create(user, attrs) - conn = post(conn, "/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => today}) + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => today}) - assert %{"error" => "daily limit exceeded"} == json_response(conn, 422) + assert %{"error" => "daily limit exceeded"} == json_response_and_validate_schema(conn, 422) end test "returns error when total user limit is exceeded", %{user: user, conn: conn} do @@ -359,11 +430,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do NaiveDateTime.utc_now() |> NaiveDateTime.add(:timer.minutes(6), :millisecond) |> NaiveDateTime.to_iso8601() + |> Kernel.<>("Z") tomorrow = NaiveDateTime.utc_now() |> NaiveDateTime.add(:timer.hours(36), :millisecond) |> NaiveDateTime.to_iso8601() + |> Kernel.<>("Z") attrs = %{params: %{}, scheduled_at: today} {:ok, _} = ScheduledActivity.create(user, attrs) @@ -371,9 +444,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, _} = ScheduledActivity.create(user, %{params: %{}, scheduled_at: tomorrow}) conn = - post(conn, "/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => tomorrow}) + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => tomorrow}) - assert %{"error" => "total limit exceeded"} == json_response(conn, 422) + assert %{"error" => "total limit exceeded"} == json_response_and_validate_schema(conn, 422) end end @@ -384,12 +459,17 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do time = NaiveDateTime.utc_now() conn = - post(conn, "/api/v1/statuses", %{ + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ "status" => "Who is the #bestgrill?", - "poll" => %{"options" => ["Rei", "Asuka", "Misato"], "expires_in" => 420} + "poll" => %{ + "options" => ["Rei", "Asuka", "Misato"], + "expires_in" => 420 + } }) - response = json_response(conn, 200) + response = json_response_and_validate_schema(conn, 200) assert Enum.all?(response["poll"]["options"], fn %{"title" => title} -> title in ["Rei", "Asuka", "Misato"] @@ -408,12 +488,14 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do limit = Config.get([:instance, :poll_limits, :max_options]) conn = - post(conn, "/api/v1/statuses", %{ + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ "status" => "desu~", "poll" => %{"options" => Enum.map(0..limit, fn _ -> "desu" end), "expires_in" => 1} }) - %{"error" => error} = json_response(conn, 422) + %{"error" => error} = json_response_and_validate_schema(conn, 422) assert error == "Poll can't contain more than #{limit} options" end @@ -421,7 +503,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do limit = Config.get([:instance, :poll_limits, :max_option_chars]) conn = - post(conn, "/api/v1/statuses", %{ + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ "status" => "...", "poll" => %{ "options" => [Enum.reduce(0..limit, "", fn _, acc -> acc <> "." end)], @@ -429,7 +513,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do } }) - %{"error" => error} = json_response(conn, 422) + %{"error" => error} = json_response_and_validate_schema(conn, 422) assert error == "Poll options cannot be longer than #{limit} characters each" end @@ -437,7 +521,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do limit = Config.get([:instance, :poll_limits, :min_expiration]) conn = - post(conn, "/api/v1/statuses", %{ + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ "status" => "imagine arbitrary limits", "poll" => %{ "options" => ["this post was made by pleroma gang"], @@ -445,7 +531,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do } }) - %{"error" => error} = json_response(conn, 422) + %{"error" => error} = json_response_and_validate_schema(conn, 422) assert error == "Expiration date is too soon" end @@ -453,7 +539,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do limit = Config.get([:instance, :poll_limits, :max_expiration]) conn = - post(conn, "/api/v1/statuses", %{ + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses", %{ "status" => "imagine arbitrary limits", "poll" => %{ "options" => ["this post was made by pleroma gang"], @@ -461,7 +549,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do } }) - %{"error" => error} = json_response(conn, 422) + %{"error" => error} = json_response_and_validate_schema(conn, 422) assert error == "Expiration date is too far in the future" end end @@ -472,16 +560,114 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do conn = get(conn, "/api/v1/statuses/#{activity.id}") - assert %{"id" => id} = json_response(conn, 200) + assert %{"id" => id} = json_response_and_validate_schema(conn, 200) assert id == to_string(activity.id) end + defp local_and_remote_activities do + local = insert(:note_activity) + remote = insert(:note_activity, local: false) + {:ok, local: local, remote: remote} + end + + describe "status with restrict unauthenticated activities for local and remote" do + setup do: local_and_remote_activities() + + setup do: clear_config([:restrict_unauthenticated, :activities, :local], true) + + setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true) + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/statuses/#{local.id}") + + assert json_response_and_validate_schema(res_conn, :not_found) == %{ + "error" => "Record not found" + } + + res_conn = get(conn, "/api/v1/statuses/#{remote.id}") + + assert json_response_and_validate_schema(res_conn, :not_found) == %{ + "error" => "Record not found" + } + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + res_conn = get(conn, "/api/v1/statuses/#{local.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + + res_conn = get(conn, "/api/v1/statuses/#{remote.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + end + end + + describe "status with restrict unauthenticated activities for local" do + setup do: local_and_remote_activities() + + setup do: clear_config([:restrict_unauthenticated, :activities, :local], true) + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/statuses/#{local.id}") + + assert json_response_and_validate_schema(res_conn, :not_found) == %{ + "error" => "Record not found" + } + + res_conn = get(conn, "/api/v1/statuses/#{remote.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + res_conn = get(conn, "/api/v1/statuses/#{local.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + + res_conn = get(conn, "/api/v1/statuses/#{remote.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + end + end + + describe "status with restrict unauthenticated activities for remote" do + setup do: local_and_remote_activities() + + setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true) + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/statuses/#{local.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + + res_conn = get(conn, "/api/v1/statuses/#{remote.id}") + + assert json_response_and_validate_schema(res_conn, :not_found) == %{ + "error" => "Record not found" + } + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + res_conn = get(conn, "/api/v1/statuses/#{local.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + + res_conn = get(conn, "/api/v1/statuses/#{remote.id}") + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) + end + end + + test "getting a status that doesn't exist returns 404" do + %{conn: conn} = oauth_access(["read:statuses"]) + activity = insert(:note_activity) + + conn = get(conn, "/api/v1/statuses/#{String.downcase(activity.id)}") + + assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"} + end + test "get a direct status" do %{user: user, conn: conn} = oauth_access(["read:statuses"]) other_user = insert(:user) {:ok, activity} = - CommonAPI.post(user, %{"status" => "@#{other_user.nickname}", "visibility" => "direct"}) + CommonAPI.post(user, %{status: "@#{other_user.nickname}", visibility: "direct"}) conn = conn @@ -490,7 +676,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do [participation] = Participation.for_user(user) - res = json_response(conn, 200) + res = json_response_and_validate_schema(conn, 200) assert res["pleroma"]["direct_conversation_id"] == participation.id end @@ -502,7 +688,72 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do query_string = "ids[]=#{id1}&ids[]=#{id2}" conn = get(conn, "/api/v1/statuses/?#{query_string}") - assert [%{"id" => ^id1}, %{"id" => ^id2}] = Enum.sort_by(json_response(conn, :ok), & &1["id"]) + assert [%{"id" => ^id1}, %{"id" => ^id2}] = + Enum.sort_by(json_response_and_validate_schema(conn, :ok), & &1["id"]) + end + + describe "getting statuses by ids with restricted unauthenticated for local and remote" do + setup do: local_and_remote_activities() + + setup do: clear_config([:restrict_unauthenticated, :activities, :local], true) + + setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true) + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}") + + assert json_response_and_validate_schema(res_conn, 200) == [] + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}") + + assert length(json_response_and_validate_schema(res_conn, 200)) == 2 + end + end + + describe "getting statuses by ids with restricted unauthenticated for local" do + setup do: local_and_remote_activities() + + setup do: clear_config([:restrict_unauthenticated, :activities, :local], true) + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}") + + remote_id = remote.id + assert [%{"id" => ^remote_id}] = json_response_and_validate_schema(res_conn, 200) + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}") + + assert length(json_response_and_validate_schema(res_conn, 200)) == 2 + end + end + + describe "getting statuses by ids with restricted unauthenticated for remote" do + setup do: local_and_remote_activities() + + setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true) + + test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do + res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}") + + local_id = local.id + assert [%{"id" => ^local_id}] = json_response_and_validate_schema(res_conn, 200) + end + + test "if user is authenticated", %{local: local, remote: remote} do + %{conn: conn} = oauth_access(["read"]) + + res_conn = get(conn, "/api/v1/statuses?ids[]=#{local.id}&ids[]=#{remote.id}") + + assert length(json_response_and_validate_schema(res_conn, 200)) == 2 + end end describe "deleting a status" do @@ -515,18 +766,30 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do |> assign(:user, author) |> delete("/api/v1/statuses/#{activity.id}") - assert %{} = json_response(conn, 200) + assert %{} = json_response_and_validate_schema(conn, 200) refute Activity.get_by_id(activity.id) end + test "when it doesn't exist" do + %{user: author, conn: conn} = oauth_access(["write:statuses"]) + activity = insert(:note_activity, user: author) + + conn = + conn + |> assign(:user, author) + |> delete("/api/v1/statuses/#{String.downcase(activity.id)}") + + assert %{"error" => "Record not found"} == json_response_and_validate_schema(conn, 404) + end + test "when you didn't create it" do %{conn: conn} = oauth_access(["write:statuses"]) activity = insert(:note_activity) conn = delete(conn, "/api/v1/statuses/#{activity.id}") - assert %{"error" => _} = json_response(conn, 403) + assert %{"error" => _} = json_response_and_validate_schema(conn, 403) assert Activity.get_by_id(activity.id) == activity end @@ -543,7 +806,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do |> assign(:token, insert(:oauth_token, user: admin, scopes: ["write:statuses"])) |> delete("/api/v1/statuses/#{activity1.id}") - assert %{} = json_response(res_conn, 200) + assert %{} = json_response_and_validate_schema(res_conn, 200) res_conn = conn @@ -551,7 +814,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do |> assign(:token, insert(:oauth_token, user: moderator, scopes: ["write:statuses"])) |> delete("/api/v1/statuses/#{activity2.id}") - assert %{} = json_response(res_conn, 200) + assert %{} = json_response_and_validate_schema(res_conn, 200) refute Activity.get_by_id(activity1.id) refute Activity.get_by_id(activity2.id) @@ -564,26 +827,46 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do test "reblogs and returns the reblogged status", %{conn: conn} do activity = insert(:note_activity) - conn = post(conn, "/api/v1/statuses/#{activity.id}/reblog") + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/#{activity.id}/reblog") assert %{ "reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1}, "reblogged" => true - } = json_response(conn, 200) + } = json_response_and_validate_schema(conn, 200) assert to_string(activity.id) == id end + test "returns 404 if the reblogged status doesn't exist", %{conn: conn} do + activity = insert(:note_activity) + + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/#{String.downcase(activity.id)}/reblog") + + assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn, 404) + end + test "reblogs privately and returns the reblogged status", %{conn: conn} do activity = insert(:note_activity) - conn = post(conn, "/api/v1/statuses/#{activity.id}/reblog", %{"visibility" => "private"}) + conn = + conn + |> put_req_header("content-type", "application/json") + |> post( + "/api/v1/statuses/#{activity.id}/reblog", + %{"visibility" => "private"} + ) assert %{ "reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1}, "reblogged" => true, "visibility" => "private" - } = json_response(conn, 200) + } = json_response_and_validate_schema(conn, 200) assert to_string(activity.id) == id end @@ -593,7 +876,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do user1 = insert(:user) user2 = insert(:user) user3 = insert(:user) - CommonAPI.favorite(activity.id, user2) + {:ok, _} = CommonAPI.favorite(user2, activity.id) {:ok, _bookmark} = Pleroma.Bookmark.create(user2.id, activity.id) {:ok, reblog_activity1, _object} = CommonAPI.repeat(activity.id, user1) {:ok, _, _object} = CommonAPI.repeat(activity.id, user2) @@ -609,7 +892,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do "reblogged" => false, "favourited" => false, "bookmarked" => false - } = json_response(conn_res, 200) + } = json_response_and_validate_schema(conn_res, 200) conn_res = build_conn() @@ -622,16 +905,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do "reblogged" => true, "favourited" => true, "bookmarked" => true - } = json_response(conn_res, 200) + } = json_response_and_validate_schema(conn_res, 200) assert to_string(activity.id) == id end - - test "returns 400 error when activity is not exist", %{conn: conn} do - conn = post(conn, "/api/v1/statuses/foo/reblog") - - assert json_response(conn, 400) == %{"error" => "Could not repeat"} - end end describe "unreblogging" do @@ -642,17 +919,24 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, _, _} = CommonAPI.repeat(activity.id, user) - conn = post(conn, "/api/v1/statuses/#{activity.id}/unreblog") + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/#{activity.id}/unreblog") - assert %{"id" => id, "reblogged" => false, "reblogs_count" => 0} = json_response(conn, 200) + assert %{"id" => id, "reblogged" => false, "reblogs_count" => 0} = + json_response_and_validate_schema(conn, 200) assert to_string(activity.id) == id end - test "returns 400 error when activity is not exist", %{conn: conn} do - conn = post(conn, "/api/v1/statuses/foo/unreblog") + test "returns 404 error when activity does not exist", %{conn: conn} do + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/foo/unreblog") - assert json_response(conn, 400) == %{"error" => "Could not unrepeat"} + assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"} end end @@ -662,10 +946,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do test "favs a status and returns it", %{conn: conn} do activity = insert(:note_activity) - conn = post(conn, "/api/v1/statuses/#{activity.id}/favourite") + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/#{activity.id}/favourite") assert %{"id" => id, "favourites_count" => 1, "favourited" => true} = - json_response(conn, 200) + json_response_and_validate_schema(conn, 200) assert to_string(activity.id) == id end @@ -673,14 +960,23 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do test "favoriting twice will just return 200", %{conn: conn} do activity = insert(:note_activity) - post(conn, "/api/v1/statuses/#{activity.id}/favourite") - assert post(conn, "/api/v1/statuses/#{activity.id}/favourite") |> json_response(200) + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/#{activity.id}/favourite") + + assert conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/#{activity.id}/favourite") + |> json_response_and_validate_schema(200) end - test "returns 400 error for a wrong id", %{conn: conn} do - conn = post(conn, "/api/v1/statuses/1/favourite") + test "returns 404 error for a wrong id", %{conn: conn} do + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/1/favourite") - assert json_response(conn, 400) == %{"error" => "Could not favorite"} + assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"} end end @@ -690,20 +986,26 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do test "unfavorites a status and returns it", %{user: user, conn: conn} do activity = insert(:note_activity) - {:ok, _, _} = CommonAPI.favorite(activity.id, user) + {:ok, _} = CommonAPI.favorite(user, activity.id) - conn = post(conn, "/api/v1/statuses/#{activity.id}/unfavourite") + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/#{activity.id}/unfavourite") assert %{"id" => id, "favourites_count" => 0, "favourited" => false} = - json_response(conn, 200) + json_response_and_validate_schema(conn, 200) assert to_string(activity.id) == id end - test "returns 400 error for a wrong id", %{conn: conn} do - conn = post(conn, "/api/v1/statuses/1/unfavourite") + test "returns 404 error for a wrong id", %{conn: conn} do + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/1/unfavourite") - assert json_response(conn, 400) == %{"error" => "Could not unfavorite"} + assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"} end end @@ -711,35 +1013,37 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do setup do: oauth_access(["write:accounts"]) setup %{user: user} do - {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!"}) + {:ok, activity} = CommonAPI.post(user, %{status: "HI!!!"}) %{activity: activity} end - clear_config([:instance, :max_pinned_statuses]) do - Config.put([:instance, :max_pinned_statuses], 1) - end + setup do: clear_config([:instance, :max_pinned_statuses], 1) test "pin status", %{conn: conn, user: user, activity: activity} do id_str = to_string(activity.id) assert %{"id" => ^id_str, "pinned" => true} = conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/statuses/#{activity.id}/pin") - |> json_response(200) + |> json_response_and_validate_schema(200) assert [%{"id" => ^id_str, "pinned" => true}] = conn |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true") - |> json_response(200) + |> json_response_and_validate_schema(200) end test "/pin: returns 400 error when activity is not public", %{conn: conn, user: user} do - {:ok, dm} = CommonAPI.post(user, %{"status" => "test", "visibility" => "direct"}) + {:ok, dm} = CommonAPI.post(user, %{status: "test", visibility: "direct"}) - conn = post(conn, "/api/v1/statuses/#{dm.id}/pin") + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/#{dm.id}/pin") - assert json_response(conn, 400) == %{"error" => "Could not pin"} + assert json_response_and_validate_schema(conn, 400) == %{"error" => "Could not pin"} end test "unpin status", %{conn: conn, user: user, activity: activity} do @@ -752,29 +1056,33 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do conn |> assign(:user, user) |> post("/api/v1/statuses/#{activity.id}/unpin") - |> json_response(200) + |> json_response_and_validate_schema(200) assert [] = conn |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true") - |> json_response(200) + |> json_response_and_validate_schema(200) end test "/unpin: returns 400 error when activity is not exist", %{conn: conn} do - conn = post(conn, "/api/v1/statuses/1/unpin") + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/1/unpin") - assert json_response(conn, 400) == %{"error" => "Could not unpin"} + assert json_response_and_validate_schema(conn, 400) == %{"error" => "Could not unpin"} end test "max pinned statuses", %{conn: conn, user: user, activity: activity_one} do - {:ok, activity_two} = CommonAPI.post(user, %{"status" => "HI!!!"}) + {:ok, activity_two} = CommonAPI.post(user, %{status: "HI!!!"}) id_str_one = to_string(activity_one.id) assert %{"id" => ^id_str_one, "pinned" => true} = conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/statuses/#{id_str_one}/pin") - |> json_response(200) + |> json_response_and_validate_schema(200) user = refresh_record(user) @@ -782,7 +1090,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do conn |> assign(:user, user) |> post("/api/v1/statuses/#{activity_two.id}/pin") - |> json_response(400) + |> json_response_and_validate_schema(400) end end @@ -796,7 +1104,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do test "returns rich-media card", %{conn: conn, user: user} do Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end) - {:ok, activity} = CommonAPI.post(user, %{"status" => "https://example.com/ogp"}) + {:ok, activity} = CommonAPI.post(user, %{status: "https://example.com/ogp"}) card_data = %{ "image" => "http://ia.media-imdb.com/images/rock.jpg", @@ -822,18 +1130,18 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do response = conn |> get("/api/v1/statuses/#{activity.id}/card") - |> json_response(200) + |> json_response_and_validate_schema(200) assert response == card_data # works with private posts {:ok, activity} = - CommonAPI.post(user, %{"status" => "https://example.com/ogp", "visibility" => "direct"}) + CommonAPI.post(user, %{status: "https://example.com/ogp", visibility: "direct"}) response_two = conn |> get("/api/v1/statuses/#{activity.id}/card") - |> json_response(200) + |> json_response_and_validate_schema(200) assert response_two == card_data end @@ -841,13 +1149,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do test "replaces missing description with an empty string", %{conn: conn, user: user} do Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end) - {:ok, activity} = - CommonAPI.post(user, %{"status" => "https://example.com/ogp-missing-data"}) + {:ok, activity} = CommonAPI.post(user, %{status: "https://example.com/ogp-missing-data"}) response = conn |> get("/api/v1/statuses/#{activity.id}/card") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert response == %{ "type" => "link", @@ -869,39 +1176,47 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end test "bookmarks" do + bookmarks_uri = "/api/v1/bookmarks?with_relationships=true" + %{conn: conn} = oauth_access(["write:bookmarks", "read:bookmarks"]) author = insert(:user) - {:ok, activity1} = - CommonAPI.post(author, %{ - "status" => "heweoo?" - }) - - {:ok, activity2} = - CommonAPI.post(author, %{ - "status" => "heweoo!" - }) + {:ok, activity1} = CommonAPI.post(author, %{status: "heweoo?"}) + {:ok, activity2} = CommonAPI.post(author, %{status: "heweoo!"}) - response1 = post(conn, "/api/v1/statuses/#{activity1.id}/bookmark") + response1 = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/#{activity1.id}/bookmark") - assert json_response(response1, 200)["bookmarked"] == true + assert json_response_and_validate_schema(response1, 200)["bookmarked"] == true - response2 = post(conn, "/api/v1/statuses/#{activity2.id}/bookmark") + response2 = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/#{activity2.id}/bookmark") - assert json_response(response2, 200)["bookmarked"] == true + assert json_response_and_validate_schema(response2, 200)["bookmarked"] == true - bookmarks = get(conn, "/api/v1/bookmarks") + bookmarks = get(conn, bookmarks_uri) - assert [json_response(response2, 200), json_response(response1, 200)] == - json_response(bookmarks, 200) + assert [ + json_response_and_validate_schema(response2, 200), + json_response_and_validate_schema(response1, 200) + ] == + json_response_and_validate_schema(bookmarks, 200) - response1 = post(conn, "/api/v1/statuses/#{activity1.id}/unbookmark") + response1 = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/#{activity1.id}/unbookmark") - assert json_response(response1, 200)["bookmarked"] == false + assert json_response_and_validate_schema(response1, 200)["bookmarked"] == false - bookmarks = get(conn, "/api/v1/bookmarks") + bookmarks = get(conn, bookmarks_uri) - assert [json_response(response2, 200)] == json_response(bookmarks, 200) + assert [json_response_and_validate_schema(response2, 200)] == + json_response_and_validate_schema(bookmarks, 200) end describe "conversation muting" do @@ -909,7 +1224,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do setup do post_user = insert(:user) - {:ok, activity} = CommonAPI.post(post_user, %{"status" => "HIE"}) + {:ok, activity} = CommonAPI.post(post_user, %{status: "HIE"}) %{activity: activity} end @@ -918,16 +1233,22 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert %{"id" => ^id_str, "muted" => true} = conn + |> put_req_header("content-type", "application/json") |> post("/api/v1/statuses/#{activity.id}/mute") - |> json_response(200) + |> json_response_and_validate_schema(200) end test "cannot mute already muted conversation", %{conn: conn, user: user, activity: activity} do {:ok, _} = CommonAPI.add_mute(user, activity) - conn = post(conn, "/api/v1/statuses/#{activity.id}/mute") + conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/statuses/#{activity.id}/mute") - assert json_response(conn, 400) == %{"error" => "conversation is already muted"} + assert json_response_and_validate_schema(conn, 400) == %{ + "error" => "conversation is already muted" + } end test "unmute conversation", %{conn: conn, user: user, activity: activity} do @@ -939,7 +1260,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do conn # |> assign(:user, user) |> post("/api/v1/statuses/#{activity.id}/unmute") - |> json_response(200) + |> json_response_and_validate_schema(200) end end @@ -948,16 +1269,17 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do user2 = insert(:user) user3 = insert(:user) - {:ok, replied_to} = CommonAPI.post(user1, %{"status" => "cofe"}) + {:ok, replied_to} = CommonAPI.post(user1, %{status: "cofe"}) # Reply to status from another user conn1 = conn |> assign(:user, user2) |> assign(:token, insert(:oauth_token, user: user2, scopes: ["write:statuses"])) + |> put_req_header("content-type", "application/json") |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => replied_to.id}) - assert %{"content" => "xD", "id" => id} = json_response(conn1, 200) + assert %{"content" => "xD", "id" => id} = json_response_and_validate_schema(conn1, 200) activity = Activity.get_by_id_with_object(id) @@ -969,10 +1291,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do conn |> assign(:user, user3) |> assign(:token, insert(:oauth_token, user: user3, scopes: ["write:statuses"])) + |> put_req_header("content-type", "application/json") |> post("/api/v1/statuses/#{activity.id}/reblog") assert %{"reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1}} = - json_response(conn2, 200) + json_response_and_validate_schema(conn2, 200) assert to_string(activity.id) == id @@ -995,19 +1318,19 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do setup do: oauth_access(["read:accounts"]) setup %{user: user} do - {:ok, activity} = CommonAPI.post(user, %{"status" => "test"}) + {:ok, activity} = CommonAPI.post(user, %{status: "test"}) %{activity: activity} end test "returns users who have favorited the status", %{conn: conn, activity: activity} do other_user = insert(:user) - {:ok, _, _} = CommonAPI.favorite(activity.id, other_user) + {:ok, _} = CommonAPI.favorite(other_user, activity.id) response = conn |> get("/api/v1/statuses/#{activity.id}/favourited_by") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) [%{"id" => id}] = response @@ -1021,7 +1344,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do response = conn |> get("/api/v1/statuses/#{activity.id}/favourited_by") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert Enum.empty?(response) end @@ -1033,24 +1356,24 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do other_user = insert(:user) {:ok, _user_relationship} = User.block(user, other_user) - {:ok, _, _} = CommonAPI.favorite(activity.id, other_user) + {:ok, _} = CommonAPI.favorite(other_user, activity.id) response = conn |> get("/api/v1/statuses/#{activity.id}/favourited_by") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert Enum.empty?(response) end test "does not fail on an unauthenticated request", %{activity: activity} do other_user = insert(:user) - {:ok, _, _} = CommonAPI.favorite(activity.id, other_user) + {:ok, _} = CommonAPI.favorite(other_user, activity.id) response = build_conn() |> get("/api/v1/statuses/#{activity.id}/favourited_by") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) [%{"id" => id}] = response assert id == other_user.id @@ -1061,17 +1384,17 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, activity} = CommonAPI.post(user, %{ - "status" => "@#{other_user.nickname} wanna get some #cofe together?", - "visibility" => "direct" + status: "@#{other_user.nickname} wanna get some #cofe together?", + visibility: "direct" }) - {:ok, _, _} = CommonAPI.favorite(activity.id, other_user) + {:ok, _} = CommonAPI.favorite(other_user, activity.id) favourited_by_url = "/api/v1/statuses/#{activity.id}/favourited_by" build_conn() |> get(favourited_by_url) - |> json_response(404) + |> json_response_and_validate_schema(404) conn = build_conn() @@ -1081,12 +1404,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do conn |> assign(:token, nil) |> get(favourited_by_url) - |> json_response(404) + |> json_response_and_validate_schema(404) response = conn |> get(favourited_by_url) - |> json_response(200) + |> json_response_and_validate_schema(200) [%{"id" => id}] = response assert id == other_user.id @@ -1097,7 +1420,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do setup do: oauth_access(["read:accounts"]) setup %{user: user} do - {:ok, activity} = CommonAPI.post(user, %{"status" => "test"}) + {:ok, activity} = CommonAPI.post(user, %{status: "test"}) %{activity: activity} end @@ -1109,7 +1432,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do response = conn |> get("/api/v1/statuses/#{activity.id}/reblogged_by") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) [%{"id" => id}] = response @@ -1123,7 +1446,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do response = conn |> get("/api/v1/statuses/#{activity.id}/reblogged_by") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert Enum.empty?(response) end @@ -1140,7 +1463,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do response = conn |> get("/api/v1/statuses/#{activity.id}/reblogged_by") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert Enum.empty?(response) end @@ -1151,12 +1474,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do } do other_user = insert(:user) - {:ok, _, _} = CommonAPI.repeat(activity.id, other_user, %{"visibility" => "private"}) + {:ok, _, _} = CommonAPI.repeat(activity.id, other_user, %{visibility: "private"}) response = conn |> get("/api/v1/statuses/#{activity.id}/reblogged_by") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert Enum.empty?(response) end @@ -1168,7 +1491,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do response = build_conn() |> get("/api/v1/statuses/#{activity.id}/reblogged_by") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) [%{"id" => id}] = response assert id == other_user.id @@ -1179,20 +1502,20 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, activity} = CommonAPI.post(user, %{ - "status" => "@#{other_user.nickname} wanna get some #cofe together?", - "visibility" => "direct" + status: "@#{other_user.nickname} wanna get some #cofe together?", + visibility: "direct" }) build_conn() |> get("/api/v1/statuses/#{activity.id}/reblogged_by") - |> json_response(404) + |> json_response_and_validate_schema(404) response = build_conn() |> assign(:user, other_user) |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"])) |> get("/api/v1/statuses/#{activity.id}/reblogged_by") - |> json_response(200) + |> json_response_and_validate_schema(200) assert [] == response end @@ -1201,16 +1524,16 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do test "context" do user = insert(:user) - {:ok, %{id: id1}} = CommonAPI.post(user, %{"status" => "1"}) - {:ok, %{id: id2}} = CommonAPI.post(user, %{"status" => "2", "in_reply_to_status_id" => id1}) - {:ok, %{id: id3}} = CommonAPI.post(user, %{"status" => "3", "in_reply_to_status_id" => id2}) - {:ok, %{id: id4}} = CommonAPI.post(user, %{"status" => "4", "in_reply_to_status_id" => id3}) - {:ok, %{id: id5}} = CommonAPI.post(user, %{"status" => "5", "in_reply_to_status_id" => id4}) + {:ok, %{id: id1}} = CommonAPI.post(user, %{status: "1"}) + {:ok, %{id: id2}} = CommonAPI.post(user, %{status: "2", in_reply_to_status_id: id1}) + {:ok, %{id: id3}} = CommonAPI.post(user, %{status: "3", in_reply_to_status_id: id2}) + {:ok, %{id: id4}} = CommonAPI.post(user, %{status: "4", in_reply_to_status_id: id3}) + {:ok, %{id: id5}} = CommonAPI.post(user, %{status: "5", in_reply_to_status_id: id4}) response = build_conn() |> get("/api/v1/statuses/#{id3}/context") - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert %{ "ancestors" => [%{"id" => ^id1}, %{"id" => ^id2}], @@ -1222,14 +1545,14 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do %{user: user, conn: conn} = oauth_access(["read:favourites"]) other_user = insert(:user) - {:ok, _} = CommonAPI.post(other_user, %{"status" => "bla"}) - {:ok, activity} = CommonAPI.post(other_user, %{"status" => "traps are happy"}) + {:ok, _} = CommonAPI.post(other_user, %{status: "bla"}) + {:ok, activity} = CommonAPI.post(other_user, %{status: "traps are happy"}) - {:ok, _, _} = CommonAPI.favorite(activity.id, user) + {:ok, _} = CommonAPI.favorite(user, activity.id) first_conn = get(conn, "/api/v1/favourites") - assert [status] = json_response(first_conn, 200) + assert [status] = json_response_and_validate_schema(first_conn, 200) assert status["id"] == to_string(activity.id) assert [{"link", _link_header}] = @@ -1238,27 +1561,26 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do # Honours query params {:ok, second_activity} = CommonAPI.post(other_user, %{ - "status" => - "Trees Are Never Sad Look At Them Every Once In Awhile They're Quite Beautiful." + status: "Trees Are Never Sad Look At Them Every Once In Awhile They're Quite Beautiful." }) - {:ok, _, _} = CommonAPI.favorite(second_activity.id, user) + {:ok, _} = CommonAPI.favorite(user, second_activity.id) last_like = status["id"] second_conn = get(conn, "/api/v1/favourites?since_id=#{last_like}") - assert [second_status] = json_response(second_conn, 200) + assert [second_status] = json_response_and_validate_schema(second_conn, 200) assert second_status["id"] == to_string(second_activity.id) third_conn = get(conn, "/api/v1/favourites?limit=0") - assert [] = json_response(third_conn, 200) + assert [] = json_response_and_validate_schema(third_conn, 200) end test "expires_at is nil for another user" do %{conn: conn, user: user} = oauth_access(["read:statuses"]) - {:ok, activity} = CommonAPI.post(user, %{"status" => "foobar", "expires_in" => 1_000_000}) + {:ok, activity} = CommonAPI.post(user, %{status: "foobar", expires_in: 1_000_000}) expires_at = activity.id @@ -1267,11 +1589,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do |> NaiveDateTime.to_iso8601() assert %{"pleroma" => %{"expires_at" => ^expires_at}} = - conn |> get("/api/v1/statuses/#{activity.id}") |> json_response(:ok) + conn + |> get("/api/v1/statuses/#{activity.id}") + |> json_response_and_validate_schema(:ok) %{conn: conn} = oauth_access(["read:statuses"]) assert %{"pleroma" => %{"expires_at" => nil}} = - conn |> get("/api/v1/statuses/#{activity.id}") |> json_response(:ok) + conn + |> get("/api/v1/statuses/#{activity.id}") + |> json_response_and_validate_schema(:ok) end end diff --git a/test/web/mastodon_api/controllers/subscription_controller_test.exs b/test/web/mastodon_api/controllers/subscription_controller_test.exs index 7dfb02f63..4aa260663 100644 --- a/test/web/mastodon_api/controllers/subscription_controller_test.exs +++ b/test/web/mastodon_api/controllers/subscription_controller_test.exs @@ -1,11 +1,12 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do use Pleroma.Web.ConnCase import Pleroma.Factory + alias Pleroma.Web.Push alias Pleroma.Web.Push.Subscription @@ -27,6 +28,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do build_conn() |> assign(:user, user) |> assign(:token, token) + |> put_req_header("content-type", "application/json") %{conn: conn, user: user, token: token} end @@ -35,7 +37,10 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do quote do vapid_details = Application.get_env(:web_push_encryption, :vapid_details, []) Application.put_env(:web_push_encryption, :vapid_details, []) - assert "Something went wrong" == unquote(yield) + + assert %{"error" => "Web push subscription is disabled on this Pleroma instance"} == + unquote(yield) + Application.put_env(:web_push_encryption, :vapid_details, vapid_details) end end @@ -44,8 +49,8 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do test "returns error when push disabled ", %{conn: conn} do assert_error_when_disable_push do conn - |> post("/api/v1/push/subscription", %{}) - |> json_response(500) + |> post("/api/v1/push/subscription", %{subscription: @sub}) + |> json_response_and_validate_schema(403) end end @@ -56,7 +61,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do "data" => %{"alerts" => %{"mention" => true, "test" => true}}, "subscription" => @sub }) - |> json_response(200) + |> json_response_and_validate_schema(200) [subscription] = Pleroma.Repo.all(Subscription) @@ -74,7 +79,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do assert_error_when_disable_push do conn |> get("/api/v1/push/subscription", %{}) - |> json_response(500) + |> json_response_and_validate_schema(403) end end @@ -82,9 +87,9 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do res = conn |> get("/api/v1/push/subscription", %{}) - |> json_response(404) + |> json_response_and_validate_schema(404) - assert "Not found" == res + assert %{"error" => "Record not found"} == res end test "returns a user subsciption", %{conn: conn, user: user, token: token} do @@ -98,7 +103,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do res = conn |> get("/api/v1/push/subscription", %{}) - |> json_response(200) + |> json_response_and_validate_schema(200) expect = %{ "alerts" => %{"mention" => true}, @@ -127,7 +132,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do assert_error_when_disable_push do conn |> put("/api/v1/push/subscription", %{data: %{"alerts" => %{"mention" => false}}}) - |> json_response(500) + |> json_response_and_validate_schema(403) end end @@ -137,7 +142,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do |> put("/api/v1/push/subscription", %{ data: %{"alerts" => %{"mention" => false, "follow" => true}} }) - |> json_response(200) + |> json_response_and_validate_schema(200) expect = %{ "alerts" => %{"follow" => true, "mention" => false}, @@ -155,7 +160,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do assert_error_when_disable_push do conn |> delete("/api/v1/push/subscription", %{}) - |> json_response(500) + |> json_response_and_validate_schema(403) end end @@ -163,9 +168,9 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do res = conn |> delete("/api/v1/push/subscription", %{}) - |> json_response(404) + |> json_response_and_validate_schema(404) - assert "Not found" == res + assert %{"error" => "Record not found"} == res end test "returns empty result and delete user subsciption", %{ @@ -183,7 +188,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do res = conn |> delete("/api/v1/push/subscription", %{}) - |> json_response(200) + |> json_response_and_validate_schema(200) assert %{} == res refute Pleroma.Repo.get(Subscription, subscription.id) diff --git a/test/web/mastodon_api/controllers/suggestion_controller_test.exs b/test/web/mastodon_api/controllers/suggestion_controller_test.exs index 0319d3475..7f08e187c 100644 --- a/test/web/mastodon_api/controllers/suggestion_controller_test.exs +++ b/test/web/mastodon_api/controllers/suggestion_controller_test.exs @@ -1,45 +1,17 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.SuggestionControllerTest do use Pleroma.Web.ConnCase - alias Pleroma.Config - - import Pleroma.Factory - import Tesla.Mock - setup do: oauth_access(["read"]) - setup %{user: user} do - other_user = insert(:user) - host = Config.get([Pleroma.Web.Endpoint, :url, :host]) - url500 = "http://test500?#{host}&#{user.nickname}" - url200 = "http://test200?#{host}&#{user.nickname}" - - mock(fn - %{method: :get, url: ^url500} -> - %Tesla.Env{status: 500, body: "bad request"} - - %{method: :get, url: ^url200} -> - %Tesla.Env{ - status: 200, - body: - ~s([{"acct":"yj455","avatar":"https://social.heldscal.la/avatar/201.jpeg","avatar_static":"https://social.heldscal.la/avatar/s/201.jpeg"}, {"acct":"#{ - other_user.ap_id - }","avatar":"https://social.heldscal.la/avatar/202.jpeg","avatar_static":"https://social.heldscal.la/avatar/s/202.jpeg"}]) - } - end) - - [other_user: other_user] - end - test "returns empty result", %{conn: conn} do res = conn |> get("/api/v1/suggestions") - |> json_response(200) + |> json_response_and_validate_schema(200) assert res == [] end diff --git a/test/web/mastodon_api/controllers/timeline_controller_test.exs b/test/web/mastodon_api/controllers/timeline_controller_test.exs index bb94d8e5a..f8b9289f3 100644 --- a/test/web/mastodon_api/controllers/timeline_controller_test.exs +++ b/test/web/mastodon_api/controllers/timeline_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do @@ -12,8 +12,6 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do alias Pleroma.User alias Pleroma.Web.CommonAPI - clear_config([:instance, :public]) - setup do mock(fn env -> apply(HttpRequestMock, :request, [env]) end) :ok @@ -22,35 +20,104 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do describe "home" do setup do: oauth_access(["read:statuses"]) + test "does NOT render account/pleroma/relationship if this is disabled by default", %{ + user: user, + conn: conn + } do + clear_config([:extensions, :output_relationships_in_statuses_by_default], false) + + other_user = insert(:user) + + {:ok, _} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"}) + + response = + conn + |> assign(:user, user) + |> get("/api/v1/timelines/home") + |> json_response_and_validate_schema(200) + + assert Enum.all?(response, fn n -> + get_in(n, ["account", "pleroma", "relationship"]) == %{} + end) + end + test "the home timeline", %{user: user, conn: conn} do - following = insert(:user) + uri = "/api/v1/timelines/home?with_relationships=1" - {:ok, _activity} = CommonAPI.post(following, %{"status" => "test"}) + following = insert(:user, nickname: "followed") + third_user = insert(:user, nickname: "repeated") - ret_conn = get(conn, "/api/v1/timelines/home") + {:ok, _activity} = CommonAPI.post(following, %{status: "post"}) + {:ok, activity} = CommonAPI.post(third_user, %{status: "repeated post"}) + {:ok, _, _} = CommonAPI.repeat(activity.id, following) - assert Enum.empty?(json_response(ret_conn, :ok)) + ret_conn = get(conn, uri) - {:ok, _user} = User.follow(user, following) + assert Enum.empty?(json_response_and_validate_schema(ret_conn, :ok)) - conn = get(conn, "/api/v1/timelines/home") + {:ok, _user} = User.follow(user, following) - assert [%{"content" => "test"}] = json_response(conn, :ok) + ret_conn = get(conn, uri) + + assert [ + %{ + "reblog" => %{ + "content" => "repeated post", + "account" => %{ + "pleroma" => %{ + "relationship" => %{"following" => false, "followed_by" => false} + } + } + }, + "account" => %{"pleroma" => %{"relationship" => %{"following" => true}}} + }, + %{ + "content" => "post", + "account" => %{ + "acct" => "followed", + "pleroma" => %{"relationship" => %{"following" => true}} + } + } + ] = json_response_and_validate_schema(ret_conn, :ok) + + {:ok, _user} = User.follow(third_user, user) + + ret_conn = get(conn, uri) + + assert [ + %{ + "reblog" => %{ + "content" => "repeated post", + "account" => %{ + "acct" => "repeated", + "pleroma" => %{ + "relationship" => %{"following" => false, "followed_by" => true} + } + } + }, + "account" => %{"pleroma" => %{"relationship" => %{"following" => true}}} + }, + %{ + "content" => "post", + "account" => %{ + "acct" => "followed", + "pleroma" => %{"relationship" => %{"following" => true}} + } + } + ] = json_response_and_validate_schema(ret_conn, :ok) end test "the home timeline when the direct messages are excluded", %{user: user, conn: conn} do - {:ok, public_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "public"}) - {:ok, direct_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "direct"}) + {:ok, public_activity} = CommonAPI.post(user, %{status: ".", visibility: "public"}) + {:ok, direct_activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"}) - {:ok, unlisted_activity} = - CommonAPI.post(user, %{"status" => ".", "visibility" => "unlisted"}) + {:ok, unlisted_activity} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"}) - {:ok, private_activity} = - CommonAPI.post(user, %{"status" => ".", "visibility" => "private"}) + {:ok, private_activity} = CommonAPI.post(user, %{status: ".", visibility: "private"}) - conn = get(conn, "/api/v1/timelines/home", %{"exclude_visibilities" => ["direct"]}) + conn = get(conn, "/api/v1/timelines/home?exclude_visibilities[]=direct") - assert status_ids = json_response(conn, :ok) |> Enum.map(& &1["id"]) + assert status_ids = json_response_and_validate_schema(conn, :ok) |> Enum.map(& &1["id"]) assert public_activity.id in status_ids assert unlisted_activity.id in status_ids assert private_activity.id in status_ids @@ -63,42 +130,125 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do test "the public timeline", %{conn: conn} do following = insert(:user) - {:ok, _activity} = CommonAPI.post(following, %{"status" => "test"}) + {:ok, _activity} = CommonAPI.post(following, %{status: "test"}) _activity = insert(:note_activity, local: false) - conn = get(conn, "/api/v1/timelines/public", %{"local" => "False"}) + conn = get(conn, "/api/v1/timelines/public?local=False") - assert length(json_response(conn, :ok)) == 2 + assert length(json_response_and_validate_schema(conn, :ok)) == 2 - conn = get(build_conn(), "/api/v1/timelines/public", %{"local" => "True"}) + conn = get(build_conn(), "/api/v1/timelines/public?local=True") - assert [%{"content" => "test"}] = json_response(conn, :ok) + assert [%{"content" => "test"}] = json_response_and_validate_schema(conn, :ok) - conn = get(build_conn(), "/api/v1/timelines/public", %{"local" => "1"}) + conn = get(build_conn(), "/api/v1/timelines/public?local=1") - assert [%{"content" => "test"}] = json_response(conn, :ok) - end - - test "the public timeline when public is set to false", %{conn: conn} do - Config.put([:instance, :public], false) - - assert %{"error" => "This resource requires authentication."} == - conn - |> get("/api/v1/timelines/public", %{"local" => "False"}) - |> json_response(:forbidden) + assert [%{"content" => "test"}] = json_response_and_validate_schema(conn, :ok) end test "the public timeline includes only public statuses for an authenticated user" do %{user: user, conn: conn} = oauth_access(["read:statuses"]) - {:ok, _activity} = CommonAPI.post(user, %{"status" => "test"}) - {:ok, _activity} = CommonAPI.post(user, %{"status" => "test", "visibility" => "private"}) - {:ok, _activity} = CommonAPI.post(user, %{"status" => "test", "visibility" => "unlisted"}) - {:ok, _activity} = CommonAPI.post(user, %{"status" => "test", "visibility" => "direct"}) + {:ok, _activity} = CommonAPI.post(user, %{status: "test"}) + {:ok, _activity} = CommonAPI.post(user, %{status: "test", visibility: "private"}) + {:ok, _activity} = CommonAPI.post(user, %{status: "test", visibility: "unlisted"}) + {:ok, _activity} = CommonAPI.post(user, %{status: "test", visibility: "direct"}) res_conn = get(conn, "/api/v1/timelines/public") - assert length(json_response(res_conn, 200)) == 1 + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 + end + end + + defp local_and_remote_activities do + insert(:note_activity) + insert(:note_activity, local: false) + :ok + end + + describe "public with restrict unauthenticated timeline for local and federated timelines" do + setup do: local_and_remote_activities() + + setup do: clear_config([:restrict_unauthenticated, :timelines, :local], true) + + setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], true) + + test "if user is unauthenticated", %{conn: conn} do + res_conn = get(conn, "/api/v1/timelines/public?local=true") + + assert json_response_and_validate_schema(res_conn, :unauthorized) == %{ + "error" => "authorization required for timeline view" + } + + res_conn = get(conn, "/api/v1/timelines/public?local=false") + + assert json_response_and_validate_schema(res_conn, :unauthorized) == %{ + "error" => "authorization required for timeline view" + } + end + + test "if user is authenticated" do + %{conn: conn} = oauth_access(["read:statuses"]) + + res_conn = get(conn, "/api/v1/timelines/public?local=true") + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/timelines/public?local=false") + assert length(json_response_and_validate_schema(res_conn, 200)) == 2 + end + end + + describe "public with restrict unauthenticated timeline for local" do + setup do: local_and_remote_activities() + + setup do: clear_config([:restrict_unauthenticated, :timelines, :local], true) + + test "if user is unauthenticated", %{conn: conn} do + res_conn = get(conn, "/api/v1/timelines/public?local=true") + + assert json_response_and_validate_schema(res_conn, :unauthorized) == %{ + "error" => "authorization required for timeline view" + } + + res_conn = get(conn, "/api/v1/timelines/public?local=false") + assert length(json_response_and_validate_schema(res_conn, 200)) == 2 + end + + test "if user is authenticated", %{conn: _conn} do + %{conn: conn} = oauth_access(["read:statuses"]) + + res_conn = get(conn, "/api/v1/timelines/public?local=true") + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/timelines/public?local=false") + assert length(json_response_and_validate_schema(res_conn, 200)) == 2 + end + end + + describe "public with restrict unauthenticated timeline for remote" do + setup do: local_and_remote_activities() + + setup do: clear_config([:restrict_unauthenticated, :timelines, :federated], true) + + test "if user is unauthenticated", %{conn: conn} do + res_conn = get(conn, "/api/v1/timelines/public?local=true") + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/timelines/public?local=false") + + assert json_response_and_validate_schema(res_conn, :unauthorized) == %{ + "error" => "authorization required for timeline view" + } + end + + test "if user is authenticated", %{conn: _conn} do + %{conn: conn} = oauth_access(["read:statuses"]) + + res_conn = get(conn, "/api/v1/timelines/public?local=true") + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 + + res_conn = get(conn, "/api/v1/timelines/public?local=false") + assert length(json_response_and_validate_schema(res_conn, 200)) == 2 end end @@ -111,14 +261,14 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do {:ok, direct} = CommonAPI.post(user_one, %{ - "status" => "Hi @#{user_two.nickname}!", - "visibility" => "direct" + status: "Hi @#{user_two.nickname}!", + visibility: "direct" }) {:ok, _follower_only} = CommonAPI.post(user_one, %{ - "status" => "Hi @#{user_two.nickname}!", - "visibility" => "private" + status: "Hi @#{user_two.nickname}!", + visibility: "private" }) conn_user_two = @@ -129,7 +279,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do # Only direct should be visible here res_conn = get(conn_user_two, "api/v1/timelines/direct") - [status] = json_response(res_conn, :ok) + assert [status] = json_response_and_validate_schema(res_conn, :ok) assert %{"visibility" => "direct"} = status assert status["url"] != direct.data["id"] @@ -141,33 +291,34 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do |> assign(:token, insert(:oauth_token, user: user_one, scopes: ["read:statuses"])) |> get("api/v1/timelines/direct") - [status] = json_response(res_conn, :ok) + [status] = json_response_and_validate_schema(res_conn, :ok) assert %{"visibility" => "direct"} = status # Both should be visible here res_conn = get(conn_user_two, "api/v1/timelines/home") - [_s1, _s2] = json_response(res_conn, :ok) + [_s1, _s2] = json_response_and_validate_schema(res_conn, :ok) # Test pagination Enum.each(1..20, fn _ -> {:ok, _} = CommonAPI.post(user_one, %{ - "status" => "Hi @#{user_two.nickname}!", - "visibility" => "direct" + status: "Hi @#{user_two.nickname}!", + visibility: "direct" }) end) res_conn = get(conn_user_two, "api/v1/timelines/direct") - statuses = json_response(res_conn, :ok) + statuses = json_response_and_validate_schema(res_conn, :ok) assert length(statuses) == 20 - res_conn = - get(conn_user_two, "api/v1/timelines/direct", %{max_id: List.last(statuses)["id"]}) + max_id = List.last(statuses)["id"] + + res_conn = get(conn_user_two, "api/v1/timelines/direct?max_id=#{max_id}") - [status] = json_response(res_conn, :ok) + assert [status] = json_response_and_validate_schema(res_conn, :ok) assert status["url"] != direct.data["id"] end @@ -180,19 +331,19 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do {:ok, _blocked_direct} = CommonAPI.post(blocked, %{ - "status" => "Hi @#{blocker.nickname}!", - "visibility" => "direct" + status: "Hi @#{blocker.nickname}!", + visibility: "direct" }) {:ok, direct} = CommonAPI.post(other_user, %{ - "status" => "Hi @#{blocker.nickname}!", - "visibility" => "direct" + status: "Hi @#{blocker.nickname}!", + visibility: "direct" }) res_conn = get(conn, "api/v1/timelines/direct") - [status] = json_response(res_conn, :ok) + [status] = json_response_and_validate_schema(res_conn, :ok) assert status["id"] == direct.id end end @@ -202,14 +353,14 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do test "list timeline", %{user: user, conn: conn} do other_user = insert(:user) - {:ok, _activity_one} = CommonAPI.post(user, %{"status" => "Marisa is cute."}) - {:ok, activity_two} = CommonAPI.post(other_user, %{"status" => "Marisa is cute."}) + {:ok, _activity_one} = CommonAPI.post(user, %{status: "Marisa is cute."}) + {:ok, activity_two} = CommonAPI.post(other_user, %{status: "Marisa is cute."}) {:ok, list} = Pleroma.List.create("name", user) {:ok, list} = Pleroma.List.follow(list, other_user) conn = get(conn, "/api/v1/timelines/list/#{list.id}") - assert [%{"id" => id}] = json_response(conn, :ok) + assert [%{"id" => id}] = json_response_and_validate_schema(conn, :ok) assert id == to_string(activity_two.id) end @@ -219,12 +370,12 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do conn: conn } do other_user = insert(:user) - {:ok, activity_one} = CommonAPI.post(other_user, %{"status" => "Marisa is cute."}) + {:ok, activity_one} = CommonAPI.post(other_user, %{status: "Marisa is cute."}) {:ok, _activity_two} = CommonAPI.post(other_user, %{ - "status" => "Marisa is cute.", - "visibility" => "private" + status: "Marisa is cute.", + visibility: "private" }) {:ok, list} = Pleroma.List.create("name", user) @@ -232,7 +383,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do conn = get(conn, "/api/v1/timelines/list/#{list.id}") - assert [%{"id" => id}] = json_response(conn, :ok) + assert [%{"id" => id}] = json_response_and_validate_schema(conn, :ok) assert id == to_string(activity_one.id) end @@ -245,18 +396,18 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do test "hashtag timeline", %{conn: conn} do following = insert(:user) - {:ok, activity} = CommonAPI.post(following, %{"status" => "test #2hu"}) + {:ok, activity} = CommonAPI.post(following, %{status: "test #2hu"}) nconn = get(conn, "/api/v1/timelines/tag/2hu") - assert [%{"id" => id}] = json_response(nconn, :ok) + assert [%{"id" => id}] = json_response_and_validate_schema(nconn, :ok) assert id == to_string(activity.id) # works for different capitalization too nconn = get(conn, "/api/v1/timelines/tag/2HU") - assert [%{"id" => id}] = json_response(nconn, :ok) + assert [%{"id" => id}] = json_response_and_validate_schema(nconn, :ok) assert id == to_string(activity.id) end @@ -264,26 +415,25 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do test "multi-hashtag timeline", %{conn: conn} do user = insert(:user) - {:ok, activity_test} = CommonAPI.post(user, %{"status" => "#test"}) - {:ok, activity_test1} = CommonAPI.post(user, %{"status" => "#test #test1"}) - {:ok, activity_none} = CommonAPI.post(user, %{"status" => "#test #none"}) + {:ok, activity_test} = CommonAPI.post(user, %{status: "#test"}) + {:ok, activity_test1} = CommonAPI.post(user, %{status: "#test #test1"}) + {:ok, activity_none} = CommonAPI.post(user, %{status: "#test #none"}) - any_test = get(conn, "/api/v1/timelines/tag/test", %{"any" => ["test1"]}) + any_test = get(conn, "/api/v1/timelines/tag/test?any[]=test1") - [status_none, status_test1, status_test] = json_response(any_test, :ok) + [status_none, status_test1, status_test] = json_response_and_validate_schema(any_test, :ok) assert to_string(activity_test.id) == status_test["id"] assert to_string(activity_test1.id) == status_test1["id"] assert to_string(activity_none.id) == status_none["id"] - restricted_test = - get(conn, "/api/v1/timelines/tag/test", %{"all" => ["test1"], "none" => ["none"]}) + restricted_test = get(conn, "/api/v1/timelines/tag/test?all[]=test1&none[]=none") - assert [status_test1] == json_response(restricted_test, :ok) + assert [status_test1] == json_response_and_validate_schema(restricted_test, :ok) - all_test = get(conn, "/api/v1/timelines/tag/test", %{"all" => ["none"]}) + all_test = get(conn, "/api/v1/timelines/tag/test?all[]=none") - assert [status_none] == json_response(all_test, :ok) + assert [status_none] == json_response_and_validate_schema(all_test, :ok) 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 c1f70f9fe..bb4bc4396 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do @@ -7,35 +7,28 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do describe "empty_array/2 (stubs)" do test "GET /api/v1/accounts/:id/identity_proofs" do - %{user: user, conn: conn} = oauth_access(["n/a"]) + %{user: user, conn: conn} = oauth_access(["read:accounts"]) - res = - conn - |> assign(:user, user) - |> get("/api/v1/accounts/#{user.id}/identity_proofs") - |> json_response(200) - - assert res == [] + assert [] == + conn + |> get("/api/v1/accounts/#{user.id}/identity_proofs") + |> json_response(200) end test "GET /api/v1/endorsements" do %{conn: conn} = oauth_access(["read:accounts"]) - res = - conn - |> get("/api/v1/endorsements") - |> json_response(200) - - assert res == [] + assert [] == + conn + |> get("/api/v1/endorsements") + |> json_response(200) end test "GET /api/v1/trends", %{conn: conn} do - res = - conn - |> get("/api/v1/trends") - |> json_response(200) - - assert res == [] + assert [] == + conn + |> get("/api/v1/trends") + |> json_response(200) end end end diff --git a/test/web/mastodon_api/mastodon_api_test.exs b/test/web/mastodon_api/mastodon_api_test.exs index 561ef05aa..a7f9c5205 100644 --- a/test/web/mastodon_api/mastodon_api_test.exs +++ b/test/web/mastodon_api/mastodon_api_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.MastodonAPITest do @@ -75,9 +75,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPITest do User.subscribe(subscriber, user) - {:ok, status} = CommonAPI.post(user, %{"status" => "Akariiiin"}) + {:ok, status} = CommonAPI.post(user, %{status: "Akariiiin"}) - {:ok, status1} = CommonAPI.post(user, %{"status" => "Magi"}) + {:ok, status1} = CommonAPI.post(user, %{status: "Magi"}) {:ok, [notification]} = Notification.create_notifications(status) {:ok, [notification1]} = Notification.create_notifications(status1) res = MastodonAPI.get_notifications(subscriber) diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/web/mastodon_api/views/account_view_test.exs index 00c294845..69ddbb5d4 100644 --- a/test/web/mastodon_api/views/account_view_test.exs +++ b/test/web/mastodon_api/views/account_view_test.exs @@ -1,25 +1,24 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.AccountViewTest do use Pleroma.DataCase - import Pleroma.Factory + alias Pleroma.User + alias Pleroma.UserRelationship alias Pleroma.Web.CommonAPI alias Pleroma.Web.MastodonAPI.AccountView - test "Represent a user account" do - source_data = %{ - "tag" => [ - %{ - "type" => "Emoji", - "icon" => %{"url" => "/file.png"}, - "name" => ":karjalanpiirakka:" - } - ] - } + import Pleroma.Factory + import Tesla.Mock + + setup do + mock(fn env -> apply(HttpRequestMock, :request, [env]) end) + :ok + end + test "Represent a user account" do background_image = %{ "url" => [%{"href" => "https://example.com/images/asuka_hospital.png"}] } @@ -28,12 +27,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do insert(:user, %{ follower_count: 3, note_count: 5, - source_data: source_data, background: background_image, nickname: "shp@shitposter.club", name: ":karjalanpiirakka: shp", - bio: "<script src=\"invalid-html\"></script><span>valid html</span>", - inserted_at: ~N[2017-08-15 15:47:06.597036] + bio: + "<script src=\"invalid-html\"></script><span>valid html</span>. a<br>b<br/>c<br >d<br />f '&<>\"", + inserted_at: ~N[2017-08-15 15:47:06.597036], + emoji: %{"karjalanpiirakka" => "/file.png"} }) expected = %{ @@ -46,7 +46,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do followers_count: 3, following_count: 0, statuses_count: 5, - note: "<span>valid html</span>", + note: "<span>valid html</span>. a<br/>b<br/>c<br/>d<br/>f '&<>"", url: user.ap_id, avatar: "http://localhost:4001/images/avi.png", avatar_static: "http://localhost:4001/images/avi.png", @@ -63,7 +63,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do fields: [], bot: false, source: %{ - note: "valid html", + note: "valid html. a\nb\nc\nd\nf '&<>\"", sensitive: false, pleroma: %{ actor_type: "Person", @@ -93,7 +93,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do test "Represent the user account for the account owner" do user = insert(:user) - notification_settings = %Pleroma.User.NotificationSetting{} + notification_settings = %{ + followers: true, + follows: true, + non_followers: true, + non_follows: true, + privacy_option: false + } + privacy = user.default_scope assert %{ @@ -107,7 +114,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do insert(:user, %{ follower_count: 3, note_count: 5, - source_data: %{}, actor_type: "Service", nickname: "shp@shitposter.club", inserted_at: ~N[2017-08-15 15:47:06.597036] @@ -160,6 +166,17 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do assert expected == AccountView.render("show.json", %{user: user}) end + test "Represent a Funkwhale channel" do + {:ok, user} = + User.get_or_fetch_by_ap_id( + "https://channels.tests.funkwhale.audio/federation/actors/compositions" + ) + + assert represented = AccountView.render("show.json", %{user: user}) + assert represented.acct == "compositions@channels.tests.funkwhale.audio" + assert represented.url == "https://channels.tests.funkwhale.audio/channels/compositions" + end + test "Represent a deactivated user for an admin" do admin = insert(:user, is_admin: true) deactivated_user = insert(:user, deactivated: true) @@ -181,6 +198,32 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do end describe "relationship" do + defp test_relationship_rendering(user, other_user, expected_result) do + opts = %{user: user, target: other_user, relationships: nil} + assert expected_result == AccountView.render("relationship.json", opts) + + relationships_opt = UserRelationship.view_relationships_option(user, [other_user]) + opts = Map.put(opts, :relationships, relationships_opt) + assert expected_result == AccountView.render("relationship.json", opts) + + assert [expected_result] == + AccountView.render("relationships.json", %{user: user, targets: [other_user]}) + end + + @blank_response %{ + following: false, + followed_by: false, + blocking: false, + blocked_by: false, + muting: false, + muting_notifications: false, + subscribing: false, + requested: false, + domain_blocking: false, + showing_reblogs: true, + endorsed: false + } + test "represent a relationship for the following and followed user" do user = insert(:user) other_user = insert(:user) @@ -191,23 +234,21 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do {:ok, _user_relationships} = User.mute(user, other_user, true) {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, other_user) - expected = %{ - id: to_string(other_user.id), - following: true, - followed_by: true, - blocking: false, - blocked_by: false, - muting: true, - muting_notifications: true, - subscribing: true, - requested: false, - domain_blocking: false, - showing_reblogs: false, - endorsed: false - } - - assert expected == - AccountView.render("relationship.json", %{user: user, target: other_user}) + expected = + Map.merge( + @blank_response, + %{ + following: true, + followed_by: true, + muting: true, + muting_notifications: true, + subscribing: true, + showing_reblogs: false, + id: to_string(other_user.id) + } + ) + + test_relationship_rendering(user, other_user, expected) end test "represent a relationship for the blocking and blocked user" do @@ -219,23 +260,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do {:ok, _user_relationship} = User.block(user, other_user) {:ok, _user_relationship} = User.block(other_user, user) - expected = %{ - id: to_string(other_user.id), - following: false, - followed_by: false, - blocking: true, - blocked_by: true, - muting: false, - muting_notifications: false, - subscribing: false, - requested: false, - domain_blocking: false, - showing_reblogs: true, - endorsed: false - } + expected = + Map.merge( + @blank_response, + %{following: false, blocking: true, blocked_by: true, id: to_string(other_user.id)} + ) - assert expected == - AccountView.render("relationship.json", %{user: user, target: other_user}) + test_relationship_rendering(user, other_user, expected) end test "represent a relationship for the user blocking a domain" do @@ -244,8 +275,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do {:ok, user} = User.block_domain(user, "bad.site") - assert %{domain_blocking: true, blocking: false} = - AccountView.render("relationship.json", %{user: user, target: other_user}) + expected = + Map.merge( + @blank_response, + %{domain_blocking: true, blocking: false, id: to_string(other_user.id)} + ) + + test_relationship_rendering(user, other_user, expected) end test "represent a relationship for the user with a pending follow request" do @@ -256,23 +292,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do user = User.get_cached_by_id(user.id) other_user = User.get_cached_by_id(other_user.id) - expected = %{ - id: to_string(other_user.id), - following: false, - followed_by: false, - blocking: false, - blocked_by: false, - muting: false, - muting_notifications: false, - subscribing: false, - requested: true, - domain_blocking: false, - showing_reblogs: true, - endorsed: false - } + expected = + Map.merge( + @blank_response, + %{requested: true, following: false, id: to_string(other_user.id)} + ) - assert expected == - AccountView.render("relationship.json", %{user: user, target: other_user}) + test_relationship_rendering(user, other_user, expected) end end @@ -281,7 +307,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do insert(:user, %{ follower_count: 0, note_count: 5, - source_data: %{}, actor_type: "Service", nickname: "shp@shitposter.club", inserted_at: ~N[2017-08-15 15:47:06.597036] @@ -434,8 +459,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do {:ok, _activity} = CommonAPI.post(other_user, %{ - "status" => "Hey @#{user.nickname}.", - "visibility" => "direct" + status: "Hey @#{user.nickname}.", + visibility: "direct" }) user = User.get_cached_by_ap_id(user.ap_id) @@ -448,6 +473,24 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do :unread_conversation_count ] == 1 end + + test "shows unread_count only to the account owner" do + user = insert(:user) + insert_list(7, :notification, user: user) + other_user = insert(:user) + + user = User.get_cached_by_ap_id(user.ap_id) + + assert AccountView.render( + "show.json", + %{user: user, for: other_user} + )[:pleroma][:unread_notifications_count] == nil + + assert AccountView.render( + "show.json", + %{user: user, for: user} + )[:pleroma][:unread_notifications_count] == 7 + end end describe "follow requests counter" do diff --git a/test/web/mastodon_api/views/conversation_view_test.exs b/test/web/mastodon_api/views/conversation_view_test.exs index 6ed22597d..6f84366f8 100644 --- a/test/web/mastodon_api/views/conversation_view_test.exs +++ b/test/web/mastodon_api/views/conversation_view_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.ConversationViewTest do @@ -16,7 +16,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationViewTest do other_user = insert(:user) {:ok, activity} = - CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}", "visibility" => "direct"}) + CommonAPI.post(user, %{status: "hey @#{other_user.nickname}", visibility: "direct"}) [participation] = Participation.for_user_with_last_activity_id(user) diff --git a/test/web/mastodon_api/views/list_view_test.exs b/test/web/mastodon_api/views/list_view_test.exs index 59e896a7c..ca99242cb 100644 --- a/test/web/mastodon_api/views/list_view_test.exs +++ b/test/web/mastodon_api/views/list_view_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.ListViewTest do diff --git a/test/web/mastodon_api/views/marker_view_test.exs b/test/web/mastodon_api/views/marker_view_test.exs index 8a5c89d56..48a0a6d33 100644 --- a/test/web/mastodon_api/views/marker_view_test.exs +++ b/test/web/mastodon_api/views/marker_view_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.MarkerViewTest do @@ -8,19 +8,21 @@ defmodule Pleroma.Web.MastodonAPI.MarkerViewTest do import Pleroma.Factory test "returns markers" do - marker1 = insert(:marker, timeline: "notifications", last_read_id: "17") + marker1 = insert(:marker, timeline: "notifications", last_read_id: "17", unread_count: 5) marker2 = insert(:marker, timeline: "home", last_read_id: "42") assert MarkerView.render("markers.json", %{markers: [marker1, marker2]}) == %{ "home" => %{ last_read_id: "42", updated_at: NaiveDateTime.to_iso8601(marker2.updated_at), - version: 0 + version: 0, + pleroma: %{unread_count: 0} }, "notifications" => %{ last_read_id: "17", updated_at: NaiveDateTime.to_iso8601(marker1.updated_at), - version: 0 + version: 0, + pleroma: %{unread_count: 5} } } end diff --git a/test/web/mastodon_api/views/notification_view_test.exs b/test/web/mastodon_api/views/notification_view_test.exs index 2ac75c2ff..04a774d17 100644 --- a/test/web/mastodon_api/views/notification_view_test.exs +++ b/test/web/mastodon_api/views/notification_view_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do @@ -16,10 +16,25 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do alias Pleroma.Web.MastodonAPI.StatusView import Pleroma.Factory + defp test_notifications_rendering(notifications, user, expected_result) do + result = NotificationView.render("index.json", %{notifications: notifications, for: user}) + + assert expected_result == result + + result = + NotificationView.render("index.json", %{ + notifications: notifications, + for: user, + relationships: nil + }) + + assert expected_result == result + end + test "Mention notification" do user = insert(:user) mentioned_user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{mentioned_user.nickname}"}) + {:ok, activity} = CommonAPI.post(user, %{status: "hey @#{mentioned_user.nickname}"}) {:ok, [notification]} = Notification.create_notifications(activity) user = User.get_cached_by_id(user.id) @@ -32,17 +47,14 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do created_at: Utils.to_masto_date(notification.inserted_at) } - result = - NotificationView.render("index.json", %{notifications: [notification], for: mentioned_user}) - - assert [expected] == result + test_notifications_rendering([notification], mentioned_user, [expected]) end test "Favourite notification" do user = insert(:user) another_user = insert(:user) - {:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"}) - {:ok, favorite_activity, _object} = CommonAPI.favorite(create_activity.id, another_user) + {:ok, create_activity} = CommonAPI.post(user, %{status: "hey"}) + {:ok, favorite_activity} = CommonAPI.favorite(another_user, create_activity.id) {:ok, [notification]} = Notification.create_notifications(favorite_activity) create_activity = Activity.get_by_id(create_activity.id) @@ -55,15 +67,13 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do created_at: Utils.to_masto_date(notification.inserted_at) } - result = NotificationView.render("index.json", %{notifications: [notification], for: user}) - - assert [expected] == result + test_notifications_rendering([notification], user, [expected]) end test "Reblog notification" do user = insert(:user) another_user = insert(:user) - {:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"}) + {:ok, create_activity} = CommonAPI.post(user, %{status: "hey"}) {:ok, reblog_activity, _object} = CommonAPI.repeat(create_activity.id, another_user) {:ok, [notification]} = Notification.create_notifications(reblog_activity) reblog_activity = Activity.get_by_id(create_activity.id) @@ -77,9 +87,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do created_at: Utils.to_masto_date(notification.inserted_at) } - result = NotificationView.render("index.json", %{notifications: [notification], for: user}) - - assert [expected] == result + test_notifications_rendering([notification], user, [expected]) end test "Follow notification" do @@ -96,23 +104,32 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do created_at: Utils.to_masto_date(notification.inserted_at) } - result = - NotificationView.render("index.json", %{notifications: [notification], for: followed}) - - assert [expected] == result + test_notifications_rendering([notification], followed, [expected]) User.perform(:delete, follower) notification = Notification |> Repo.one() |> Repo.preload(:activity) - assert [] == - NotificationView.render("index.json", %{notifications: [notification], for: followed}) + test_notifications_rendering([notification], followed, []) end + @tag capture_log: true test "Move notification" do old_user = insert(:user) new_user = insert(:user, also_known_as: [old_user.ap_id]) follower = insert(:user) + old_user_url = old_user.ap_id + + body = + File.read!("test/fixtures/users_mock/localhost.json") + |> String.replace("{{nickname}}", old_user.nickname) + |> Jason.encode!() + + Tesla.Mock.mock(fn + %{method: :get, url: ^old_user_url} -> + %Tesla.Env{status: 200, body: body} + end) + User.follow(follower, old_user) Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user) Pleroma.Tests.ObanHelpers.perform_all() @@ -120,7 +137,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do old_user = refresh_record(old_user) new_user = refresh_record(new_user) - [notification] = Notification.for_user(follower, %{with_move: true}) + [notification] = Notification.for_user(follower) expected = %{ id: to_string(notification.id), @@ -131,16 +148,15 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do created_at: Utils.to_masto_date(notification.inserted_at) } - assert [expected] == - NotificationView.render("index.json", %{notifications: [notification], for: follower}) + test_notifications_rendering([notification], follower, [expected]) end test "EmojiReact notification" do user = insert(:user) other_user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"}) - {:ok, _activity, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕") + {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"}) + {:ok, _activity} = CommonAPI.react_with_emoji(activity.id, other_user, "☕") activity = Repo.get(Activity, activity.id) @@ -158,7 +174,6 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do created_at: Utils.to_masto_date(notification.inserted_at) } - assert expected == - NotificationView.render("show.json", %{notification: notification, for: user}) + test_notifications_rendering([notification], user, [expected]) end end diff --git a/test/web/mastodon_api/views/poll_view_test.exs b/test/web/mastodon_api/views/poll_view_test.exs index 8cd7636a5..76672f36c 100644 --- a/test/web/mastodon_api/views/poll_view_test.exs +++ b/test/web/mastodon_api/views/poll_view_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.PollViewTest do @@ -22,10 +22,10 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do {:ok, activity} = CommonAPI.post(user, %{ - "status" => "Is Tenshi eating a corndog cute?", - "poll" => %{ - "options" => ["absolutely!", "sure", "yes", "why are you even asking?"], - "expires_in" => 20 + status: "Is Tenshi eating a corndog cute?", + poll: %{ + options: ["absolutely!", "sure", "yes", "why are you even asking?"], + expires_in: 20 } }) @@ -43,7 +43,8 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do %{title: "why are you even asking?", votes_count: 0} ], voted: false, - votes_count: 0 + votes_count: 0, + voters_count: nil } result = PollView.render("show.json", %{object: object}) @@ -61,17 +62,28 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do {:ok, activity} = CommonAPI.post(user, %{ - "status" => "Which Mastodon developer is your favourite?", - "poll" => %{ - "options" => ["Gargron", "Eugen"], - "expires_in" => 20, - "multiple" => true + status: "Which Mastodon developer is your favourite?", + poll: %{ + options: ["Gargron", "Eugen"], + expires_in: 20, + multiple: true } }) + voter = insert(:user) + object = Object.normalize(activity) - assert %{multiple: true} = PollView.render("show.json", %{object: object}) + {:ok, _votes, object} = CommonAPI.vote(voter, object, [0, 1]) + + assert match?( + %{ + multiple: true, + voters_count: 1, + votes_count: 2 + }, + PollView.render("show.json", %{object: object}) + ) end test "detects emoji" do @@ -79,10 +91,10 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do {:ok, activity} = CommonAPI.post(user, %{ - "status" => "What's with the smug face?", - "poll" => %{ - "options" => [":blank: sip", ":blank::blank: sip", ":blank::blank::blank: sip"], - "expires_in" => 20 + status: "What's with the smug face?", + poll: %{ + options: [":blank: sip", ":blank::blank: sip", ":blank::blank::blank: sip"], + expires_in: 20 } }) @@ -97,11 +109,11 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do {:ok, activity} = CommonAPI.post(user, %{ - "status" => "Which input devices do you use?", - "poll" => %{ - "options" => ["mouse", "trackball", "trackpoint"], - "multiple" => true, - "expires_in" => 20 + status: "Which input devices do you use?", + poll: %{ + options: ["mouse", "trackball", "trackpoint"], + multiple: true, + expires_in: 20 } }) diff --git a/test/web/mastodon_api/views/scheduled_activity_view_test.exs b/test/web/mastodon_api/views/scheduled_activity_view_test.exs index 6387e4555..fbfd873ef 100644 --- a/test/web/mastodon_api/views/scheduled_activity_view_test.exs +++ b/test/web/mastodon_api/views/scheduled_activity_view_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do @@ -14,7 +14,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do test "A scheduled activity with a media attachment" do user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "hi"}) + {:ok, activity} = CommonAPI.post(user, %{status: "hi"}) scheduled_at = NaiveDateTime.utc_now() @@ -47,7 +47,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do expected = %{ id: to_string(scheduled_activity.id), media_attachments: - %{"media_ids" => [upload.id]} + %{media_ids: [upload.id]} |> Utils.attachments_from_ids() |> Enum.map(&StatusView.render("attachment.json", %{attachment: &1})), params: %{ diff --git a/test/web/mastodon_api/views/status_view_test.exs b/test/web/mastodon_api/views/status_view_test.exs index 560f8179f..ffad65b01 100644 --- a/test/web/mastodon_api/views/status_view_test.exs +++ b/test/web/mastodon_api/views/status_view_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.MastodonAPI.StatusViewTest do @@ -12,12 +12,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do alias Pleroma.Object alias Pleroma.Repo alias Pleroma.User + alias Pleroma.UserRelationship alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI.Utils alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.StatusView + import Pleroma.Factory import Tesla.Mock + import OpenApiSpex.TestAssertions setup do mock(fn env -> apply(HttpRequestMock, :request, [env]) end) @@ -28,14 +31,16 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do user = insert(:user) other_user = insert(:user) third_user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "dae cofe??"}) + {:ok, activity} = CommonAPI.post(user, %{status: "dae cofe??"}) - {:ok, _, _} = CommonAPI.react_with_emoji(activity.id, user, "☕") - {:ok, _, _} = CommonAPI.react_with_emoji(activity.id, third_user, "🍵") - {:ok, _, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕") + {:ok, _} = CommonAPI.react_with_emoji(activity.id, user, "☕") + {:ok, _} = CommonAPI.react_with_emoji(activity.id, third_user, "🍵") + {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕") activity = Repo.get(Activity, activity.id) status = StatusView.render("show.json", activity: activity) + assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) + assert status[:pleroma][:emoji_reactions] == [ %{name: "☕", count: 2, me: false}, %{name: "🍵", count: 1, me: false} @@ -43,6 +48,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do status = StatusView.render("show.json", activity: activity, for: user) + assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) + assert status[:pleroma][:emoji_reactions] == [ %{name: "☕", count: 2, me: true}, %{name: "🍵", count: 1, me: false} @@ -52,7 +59,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do test "loads and returns the direct conversation id when given the `with_direct_conversation_id` option" do user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) + {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"}) [participation] = Participation.for_user(user) status = @@ -66,12 +73,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do status = StatusView.render("show.json", activity: activity, for: user) assert status[:pleroma][:direct_conversation_id] == nil + assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) end test "returns the direct conversation id when given the `direct_conversation_id` option" do user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) + {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"}) [participation] = Participation.for_user(user) status = @@ -82,16 +90,34 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do ) assert status[:pleroma][:direct_conversation_id] == participation.id + assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) end test "returns a temporary ap_id based user for activities missing db users" do user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) + {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"}) Repo.delete(user) Cachex.clear(:user_cache) + finger_url = + "https://localhost/.well-known/webfinger?resource=acct:#{user.nickname}@localhost" + + Tesla.Mock.mock_global(fn + %{method: :get, url: "http://localhost/.well-known/host-meta"} -> + %Tesla.Env{status: 404, body: ""} + + %{method: :get, url: "https://localhost/.well-known/host-meta"} -> + %Tesla.Env{status: 404, body: ""} + + %{ + method: :get, + url: ^finger_url + } -> + %Tesla.Env{status: 404, body: ""} + end) + %{account: ms_user} = StatusView.render("show.json", activity: activity) assert ms_user.acct == "erroruser@example.com" @@ -100,7 +126,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do test "tries to get a user by nickname if fetching by ap_id doesn't work" do user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) + {:ok, activity} = CommonAPI.post(user, %{status: "Hey @shp!", visibility: "direct"}) {:ok, user} = user @@ -112,6 +138,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do result = StatusView.render("show.json", activity: activity) assert result[:account][:id] == to_string(user.id) + assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec()) end test "a note with null content" do @@ -130,6 +157,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do status = StatusView.render("show.json", %{activity: note}) assert status.content == "" + assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) end test "a note activity" do @@ -203,6 +231,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do } assert status == expected + assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) end test "tells if the message is muted for some reason" do @@ -211,14 +240,25 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do {:ok, _user_relationships} = User.mute(user, other_user) - {:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"}) - status = StatusView.render("show.json", %{activity: activity}) + {:ok, activity} = CommonAPI.post(other_user, %{status: "test"}) + + relationships_opt = UserRelationship.view_relationships_option(user, [other_user]) + opts = %{activity: activity} + status = StatusView.render("show.json", opts) assert status.muted == false + assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) - status = StatusView.render("show.json", %{activity: activity, for: user}) + status = StatusView.render("show.json", Map.put(opts, :relationships, relationships_opt)) + assert status.muted == false + + for_opts = %{activity: activity, for: user} + status = StatusView.render("show.json", for_opts) + assert status.muted == true + status = StatusView.render("show.json", Map.put(for_opts, :relationships, relationships_opt)) assert status.muted == true + assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) end test "tells if the message is thread muted" do @@ -227,7 +267,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do {:ok, _user_relationships} = User.mute(user, other_user) - {:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"}) + {:ok, activity} = CommonAPI.post(other_user, %{status: "test"}) status = StatusView.render("show.json", %{activity: activity, for: user}) assert status.pleroma.thread_muted == false @@ -242,7 +282,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do test "tells if the status is bookmarked" do user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "Cute girls doing cute things"}) + {:ok, activity} = CommonAPI.post(user, %{status: "Cute girls doing cute things"}) status = StatusView.render("show.json", %{activity: activity}) assert status.bookmarked == false @@ -264,8 +304,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do note = insert(:note_activity) user = insert(:user) - {:ok, activity} = - CommonAPI.post(user, %{"status" => "he", "in_reply_to_status_id" => note.id}) + {:ok, activity} = CommonAPI.post(user, %{status: "he", in_reply_to_status_id: note.id}) status = StatusView.render("show.json", %{activity: activity}) @@ -280,12 +319,14 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do user = insert(:user) mentioned = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "hi @#{mentioned.nickname}"}) + {:ok, activity} = CommonAPI.post(user, %{status: "hi @#{mentioned.nickname}"}) status = StatusView.render("show.json", %{activity: activity}) assert status.mentions == Enum.map([mentioned], fn u -> AccountView.render("mention.json", %{user: u}) end) + + assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) end test "create mentions from the 'to' field" do @@ -374,11 +415,17 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do pleroma: %{mime_type: "image/png"} } + api_spec = Pleroma.Web.ApiSpec.spec() + assert expected == StatusView.render("attachment.json", %{attachment: object}) + assert_schema(expected, "Attachment", api_spec) # If theres a "id", use that instead of the generated one object = Map.put(object, "id", 2) - assert %{id: "2"} = StatusView.render("attachment.json", %{attachment: object}) + result = StatusView.render("attachment.json", %{attachment: object}) + + assert %{id: "2"} = result + assert_schema(result, "Attachment", api_spec) end test "put the url advertised in the Activity in to the url attribute" do @@ -402,6 +449,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do assert represented[:id] == to_string(reblog.id) assert represented[:reblog][:id] == to_string(activity.id) assert represented[:emojis] == [] + assert_schema(represented, "Status", Pleroma.Web.ApiSpec.spec()) end test "a peertube video" do @@ -418,6 +466,23 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do assert represented[:id] == to_string(activity.id) assert length(represented[:media_attachments]) == 1 + assert_schema(represented, "Status", Pleroma.Web.ApiSpec.spec()) + end + + test "funkwhale audio" do + user = insert(:user) + + {:ok, object} = + Pleroma.Object.Fetcher.fetch_object_from_id( + "https://channels.tests.funkwhale.audio/federation/music/uploads/42342395-0208-4fee-a38d-259a6dae0871" + ) + + %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"]) + + represented = StatusView.render("show.json", %{for: user, activity: activity}) + + assert represented[:id] == to_string(activity.id) + assert length(represented[:media_attachments]) == 1 end test "a Mobilizon event" do @@ -517,13 +582,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do {:ok, activity} = CommonAPI.post(user, %{ - "status" => "drink more water" + status: "drink more water" }) result = StatusView.render("show.json", %{activity: activity, for: other_user}) assert result[:account][:pleroma][:relationship] == AccountView.render("relationship.json", %{user: other_user, target: user}) + + assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec()) end test "embeds a relationship in the account in reposts" do @@ -532,7 +599,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do {:ok, activity} = CommonAPI.post(user, %{ - "status" => "˙˙ɐʎns" + status: "˙˙ɐʎns" }) {:ok, activity, _object} = CommonAPI.repeat(activity.id, other_user) @@ -544,6 +611,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do assert result[:reblog][:account][:pleroma][:relationship] == AccountView.render("relationship.json", %{user: user, target: user}) + + assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec()) end test "visibility/list" do @@ -551,8 +620,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do {:ok, list} = Pleroma.List.create("foo", user) - {:ok, activity} = - CommonAPI.post(user, %{"status" => "foobar", "visibility" => "list:#{list.id}"}) + {:ok, activity} = CommonAPI.post(user, %{status: "foobar", visibility: "list:#{list.id}"}) status = StatusView.render("show.json", activity: activity) @@ -566,5 +634,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do assert status.length == listen_activity.data["object"]["length"] assert status.title == listen_activity.data["object"]["title"] + assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec()) end end diff --git a/test/web/mastodon_api/views/push_subscription_view_test.exs b/test/web/mastodon_api/views/subscription_view_test.exs index 4e4f5b7e6..981524c0e 100644 --- a/test/web/mastodon_api/views/push_subscription_view_test.exs +++ b/test/web/mastodon_api/views/subscription_view_test.exs @@ -1,11 +1,11 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only -defmodule Pleroma.Web.MastodonAPI.PushSubscriptionViewTest do +defmodule Pleroma.Web.MastodonAPI.SubscriptionViewTest do use Pleroma.DataCase import Pleroma.Factory - alias Pleroma.Web.MastodonAPI.PushSubscriptionView, as: View + alias Pleroma.Web.MastodonAPI.SubscriptionView, as: View alias Pleroma.Web.Push test "Represent a subscription" do @@ -18,6 +18,6 @@ defmodule Pleroma.Web.MastodonAPI.PushSubscriptionViewTest do server_key: Keyword.get(Push.vapid_config(), :public_key) } - assert expected == View.render("push_subscription.json", %{subscription: subscription}) + assert expected == View.render("show.json", %{subscription: subscription}) end end |