Merge branch 'tests/openapi-everywhere' into 'develop'

Put OpenAPI ~everywhere in tests

See merge request pleroma/pleroma!3324
This commit is contained in:
Haelwenn 2021-06-04 18:53:09 +00:00
commit 0c56f9de0d
17 changed files with 389 additions and 209 deletions

View file

@ -25,6 +25,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Don't crash so hard when email settings are invalid. - Don't crash so hard when email settings are invalid.
- Checking activated Upload Filters for required commands. - Checking activated Upload Filters for required commands.
### Removed
- **Breaking**: Remove deprecated `/api/qvitter/statuses/notifications/read` (replaced by `/api/v1/pleroma/notifications/read`)
## Unreleased (Patch) ## Unreleased (Patch)
### Fixed ### Fixed

View file

@ -105,6 +105,7 @@ def show_operation do
responses: %{ responses: %{
200 => Operation.response("Media", "application/json", Attachment), 200 => Operation.response("Media", "application/json", Attachment),
401 => Operation.response("Media", "application/json", ApiError), 401 => Operation.response("Media", "application/json", ApiError),
403 => Operation.response("Media", "application/json", ApiError),
422 => Operation.response("Media", "application/json", ApiError) 422 => Operation.response("Media", "application/json", ApiError)
} }
} }

View file

@ -115,7 +115,8 @@ def hashtag_operation do
], ],
operationId: "TimelineController.hashtag", operationId: "TimelineController.hashtag",
responses: %{ responses: %{
200 => Operation.response("Array of Status", "application/json", array_of_statuses()) 200 => Operation.response("Array of Status", "application/json", array_of_statuses()),
401 => Operation.response("Error", "application/json", ApiError)
} }
} }
end end

View file

@ -0,0 +1,219 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
alias OpenApiSpex.Operation
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Schemas.ApiError
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
apply(__MODULE__, operation, [])
end
def emoji_operation do
%Operation{
tags: ["Emojis"],
summary: "List all custom emojis",
operationId: "UtilController.emoji",
parameters: [],
responses: %{
200 =>
Operation.response("List", "application/json", %Schema{
type: :object,
additionalProperties: %Schema{
type: :object,
properties: %{
image_url: %Schema{type: :string},
tags: %Schema{type: :array, items: %Schema{type: :string}}
}
},
example: %{
"firefox" => %{
"image_url" => "/emoji/firefox.png",
"tag" => ["Fun"]
}
}
})
}
}
end
def frontend_configurations_operation do
%Operation{
tags: ["Configuration"],
summary: "Dump frontend configurations",
operationId: "UtilController.frontend_configurations",
parameters: [],
responses: %{
200 =>
Operation.response("List", "application/json", %Schema{
type: :object,
additionalProperties: %Schema{type: :object}
})
}
}
end
def change_password_operation do
%Operation{
tags: ["Account credentials"],
summary: "Change account password",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.change_password",
parameters: [
Operation.parameter(:password, :query, :string, "Current password", required: true),
Operation.parameter(:new_password, :query, :string, "New password", required: true),
Operation.parameter(
:new_password_confirmation,
:query,
:string,
"New password, confirmation",
required: true
)
],
responses: %{
200 =>
Operation.response("Success", "application/json", %Schema{
type: :object,
properties: %{status: %Schema{type: :string, example: "success"}}
}),
400 => Operation.response("Error", "application/json", ApiError),
403 => Operation.response("Error", "application/json", ApiError)
}
}
end
def change_email_operation do
%Operation{
tags: ["Account credentials"],
summary: "Change account email",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.change_email",
parameters: [
Operation.parameter(:password, :query, :string, "Current password", required: true),
Operation.parameter(:email, :query, :string, "New email", required: true)
],
requestBody: nil,
responses: %{
200 =>
Operation.response("Success", "application/json", %Schema{
type: :object,
properties: %{status: %Schema{type: :string, example: "success"}}
}),
400 => Operation.response("Error", "application/json", ApiError),
403 => Operation.response("Error", "application/json", ApiError)
}
}
end
def update_notificaton_settings_operation do
%Operation{
tags: ["Accounts"],
summary: "Update Notification Settings",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.update_notificaton_settings",
parameters: [
Operation.parameter(
:block_from_strangers,
:query,
BooleanLike,
"blocks notifications from accounts you do not follow"
),
Operation.parameter(
:hide_notification_contents,
:query,
BooleanLike,
"removes the contents of a message from the push notification"
)
],
requestBody: nil,
responses: %{
200 =>
Operation.response("Success", "application/json", %Schema{
type: :object,
properties: %{status: %Schema{type: :string, example: "success"}}
}),
400 => Operation.response("Error", "application/json", ApiError)
}
}
end
def disable_account_operation do
%Operation{
tags: ["Account credentials"],
summary: "Disable Account",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.disable_account",
parameters: [
Operation.parameter(:password, :query, :string, "Password")
],
responses: %{
200 =>
Operation.response("Success", "application/json", %Schema{
type: :object,
properties: %{status: %Schema{type: :string, example: "success"}}
}),
403 => Operation.response("Error", "application/json", ApiError)
}
}
end
def delete_account_operation do
%Operation{
tags: ["Account credentials"],
summary: "Delete Account",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.delete_account",
parameters: [
Operation.parameter(:password, :query, :string, "Password")
],
responses: %{
200 =>
Operation.response("Success", "application/json", %Schema{
type: :object,
properties: %{status: %Schema{type: :string, example: "success"}}
}),
403 => Operation.response("Error", "application/json", ApiError)
}
}
end
def captcha_operation do
%Operation{
summary: "Get a captcha",
operationId: "UtilController.captcha",
parameters: [],
responses: %{
200 => Operation.response("Success", "application/json", %Schema{type: :object})
}
}
end
def healthcheck_operation do
%Operation{
tags: ["Accounts"],
summary: "Quick status check on the instance",
security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.healthcheck",
parameters: [],
responses: %{
200 => Operation.response("Healthy", "application/json", %Schema{type: :object}),
503 =>
Operation.response("Disabled or Unhealthy", "application/json", %Schema{type: :object})
}
}
end
def remote_subscribe_operation do
%Operation{
tags: ["Accounts"],
summary: "Remote Subscribe",
operationId: "UtilController.remote_subscribe",
parameters: [],
responses: %{200 => Operation.response("Web Page", "test/html", %Schema{type: :string})}
}
end
end

View file

@ -23,6 +23,7 @@ def follow_operation do
requestBody: request_body("Parameters", import_request(), required: true), requestBody: request_body("Parameters", import_request(), required: true),
responses: %{ responses: %{
200 => ok_response(), 200 => ok_response(),
403 => Operation.response("Error", "application/json", ApiError),
500 => Operation.response("Error", "application/json", ApiError) 500 => Operation.response("Error", "application/json", ApiError)
}, },
security: [%{"oAuth" => ["write:follow"]}] security: [%{"oAuth" => ["write:follow"]}]

View file

@ -624,12 +624,6 @@ defmodule Pleroma.Web.Router do
get("/oauth_tokens", TwitterAPI.Controller, :oauth_tokens) get("/oauth_tokens", TwitterAPI.Controller, :oauth_tokens)
delete("/oauth_tokens/:id", TwitterAPI.Controller, :revoke_token) delete("/oauth_tokens/:id", TwitterAPI.Controller, :revoke_token)
post(
"/qvitter/statuses/notifications/read",
TwitterAPI.Controller,
:mark_notifications_as_read
)
end end
scope "/", Pleroma.Web do scope "/", Pleroma.Web do

View file

@ -5,7 +5,6 @@
defmodule Pleroma.Web.TwitterAPI.Controller do defmodule Pleroma.Web.TwitterAPI.Controller do
use Pleroma.Web, :controller use Pleroma.Web, :controller
alias Pleroma.Notification
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.Plugs.EnsurePublicOrAuthenticatedPlug alias Pleroma.Web.Plugs.EnsurePublicOrAuthenticatedPlug
@ -14,11 +13,6 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
require Logger require Logger
plug(
OAuthScopesPlug,
%{scopes: ["write:notifications"]} when action == :mark_notifications_as_read
)
plug( plug(
:skip_plug, :skip_plug,
[OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :confirm_email [OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :confirm_email
@ -67,31 +61,4 @@ defp json_reply(conn, status, json) do
|> put_resp_content_type("application/json") |> put_resp_content_type("application/json")
|> send_resp(status, json) |> send_resp(status, json)
end end
def mark_notifications_as_read(
%{assigns: %{user: user}} = conn,
%{"latest_id" => latest_id} = params
) do
Notification.set_read_up_to(user, latest_id)
notifications = Notification.for_user(user, params)
conn
# XXX: This is a hack because pleroma-fe still uses that API.
|> put_view(Pleroma.Web.MastodonAPI.NotificationView)
|> render("index.json", %{notifications: notifications, for: user})
end
def mark_notifications_as_read(%{assigns: %{user: _user}} = conn, _) do
bad_request_reply(conn, "You need to specify latest_id")
end
defp bad_request_reply(conn, error_message) do
json = error_json(conn, error_message)
json_reply(conn, 400, json)
end
defp error_json(conn, error_message) do
%{"error" => error_message, "request" => conn.request_path} |> Jason.encode!()
end
end end

View file

@ -10,12 +10,12 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
alias Pleroma.Config alias Pleroma.Config
alias Pleroma.Emoji alias Pleroma.Emoji
alias Pleroma.Healthcheck alias Pleroma.Healthcheck
alias Pleroma.Notification
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Plugs.OAuthScopesPlug alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Web.WebFinger alias Pleroma.Web.WebFinger
plug(Pleroma.Web.ApiSpec.CastAndValidate when action != :remote_subscribe)
plug(Pleroma.Web.Plugs.FederatingPlug when action == :remote_subscribe) plug(Pleroma.Web.Plugs.FederatingPlug when action == :remote_subscribe)
plug( plug(
@ -30,7 +30,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
] ]
) )
plug(OAuthScopesPlug, %{scopes: ["write:notifications"]} when action == :notifications_read) defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TwitterUtilOperation
def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do
with %User{} = user <- User.get_cached_by_nickname(nick), with %User{} = user <- User.get_cached_by_nickname(nick),
@ -62,17 +62,6 @@ def remote_subscribe(conn, %{"user" => %{"nickname" => nick, "profile" => profil
end end
end end
def notifications_read(%{assigns: %{user: user}} = conn, %{"id" => notification_id}) do
with {:ok, _} <- Notification.read_one(user, notification_id) do
json(conn, %{status: "success"})
else
{:error, message} ->
conn
|> put_resp_content_type("application/json")
|> send_resp(403, Jason.encode!(%{"error" => message}))
end
end
def frontend_configurations(conn, _params) do def frontend_configurations(conn, _params) do
render(conn, "frontend_configurations.json") render(conn, "frontend_configurations.json")
end end
@ -92,13 +81,17 @@ def update_notificaton_settings(%{assigns: %{user: user}} = conn, params) do
end end
end end
def change_password(%{assigns: %{user: user}} = conn, params) do def change_password(%{assigns: %{user: user}} = conn, %{
case CommonAPI.Utils.confirm_current_password(user, params["password"]) do password: password,
new_password: new_password,
new_password_confirmation: new_password_confirmation
}) do
case CommonAPI.Utils.confirm_current_password(user, password) do
{:ok, user} -> {:ok, user} ->
with {:ok, _user} <- with {:ok, _user} <-
User.reset_password(user, %{ User.reset_password(user, %{
password: params["new_password"], password: new_password,
password_confirmation: params["new_password_confirmation"] password_confirmation: new_password_confirmation
}) do }) do
json(conn, %{status: "success"}) json(conn, %{status: "success"})
else else
@ -115,10 +108,10 @@ def change_password(%{assigns: %{user: user}} = conn, params) do
end end
end end
def change_email(%{assigns: %{user: user}} = conn, params) do def change_email(%{assigns: %{user: user}} = conn, %{password: password, email: email}) do
case CommonAPI.Utils.confirm_current_password(user, params["password"]) do case CommonAPI.Utils.confirm_current_password(user, password) do
{:ok, user} -> {:ok, user} ->
with {:ok, _user} <- User.change_email(user, params["email"]) do with {:ok, _user} <- User.change_email(user, email) do
json(conn, %{status: "success"}) json(conn, %{status: "success"})
else else
{:error, changeset} -> {:error, changeset} ->
@ -135,7 +128,7 @@ def change_email(%{assigns: %{user: user}} = conn, params) do
end end
def delete_account(%{assigns: %{user: user}} = conn, params) do def delete_account(%{assigns: %{user: user}} = conn, params) do
password = params["password"] || "" password = params[:password] || ""
case CommonAPI.Utils.confirm_current_password(user, password) do case CommonAPI.Utils.confirm_current_password(user, password) do
{:ok, user} -> {:ok, user} ->
@ -148,7 +141,7 @@ def delete_account(%{assigns: %{user: user}} = conn, params) do
end end
def disable_account(%{assigns: %{user: user}} = conn, params) do def disable_account(%{assigns: %{user: user}} = conn, params) do
case CommonAPI.Utils.confirm_current_password(user, params["password"]) do case CommonAPI.Utils.confirm_current_password(user, params[:password]) do
{:ok, user} -> {:ok, user} ->
User.set_activation_async(user, false) User.set_activation_async(user, false)
json(conn, %{status: "success"}) json(conn, %{status: "success"})

View file

@ -514,11 +514,11 @@ test "paginates a user's statuses", %{user: user, conn: conn} do
{:ok, post_2} = CommonAPI.post(user, %{status: "second post"}) {:ok, post_2} = CommonAPI.post(user, %{status: "second post"})
response_1 = get(conn, "/api/v1/accounts/#{user.id}/statuses?limit=1") response_1 = get(conn, "/api/v1/accounts/#{user.id}/statuses?limit=1")
assert [res] = json_response(response_1, 200) assert [res] = json_response_and_validate_schema(response_1, 200)
assert res["id"] == post_2.id assert res["id"] == post_2.id
response_2 = get(conn, "/api/v1/accounts/#{user.id}/statuses?limit=1&max_id=#{res["id"]}") response_2 = get(conn, "/api/v1/accounts/#{user.id}/statuses?limit=1&max_id=#{res["id"]}")
assert [res] = json_response(response_2, 200) assert [res] = json_response_and_validate_schema(response_2, 200)
assert res["id"] == post_1.id assert res["id"] == post_1.id
refute response_1 == response_2 refute response_1 == response_2
@ -881,7 +881,7 @@ test "following without reblogs" do
assert [] == assert [] ==
conn conn
|> get("/api/v1/timelines/home") |> get("/api/v1/timelines/home")
|> json_response(200) |> json_response_and_validate_schema(200)
assert %{"showing_reblogs" => true} = assert %{"showing_reblogs" => true} =
conn conn
@ -892,7 +892,7 @@ test "following without reblogs" do
assert [%{"id" => ^reblog_id}] = assert [%{"id" => ^reblog_id}] =
conn conn
|> get("/api/v1/timelines/home") |> get("/api/v1/timelines/home")
|> json_response(200) |> json_response_and_validate_schema(200)
end end
test "following with reblogs" do test "following with reblogs" do
@ -910,7 +910,7 @@ test "following with reblogs" do
assert [%{"id" => ^reblog_id}] = assert [%{"id" => ^reblog_id}] =
conn conn
|> get("/api/v1/timelines/home") |> get("/api/v1/timelines/home")
|> json_response(200) |> json_response_and_validate_schema(200)
assert %{"showing_reblogs" => false} = assert %{"showing_reblogs" => false} =
conn conn
@ -921,7 +921,7 @@ test "following with reblogs" do
assert [] == assert [] ==
conn conn
|> get("/api/v1/timelines/home") |> get("/api/v1/timelines/home")
|> json_response(200) |> json_response_and_validate_schema(200)
end end
test "following / unfollowing errors", %{user: user, conn: conn} do test "following / unfollowing errors", %{user: user, conn: conn} do

View file

@ -214,7 +214,8 @@ test "(vanilla) Mastodon frontend behaviour", %{user: user_one, conn: conn} do
res_conn = get(conn, "/api/v1/statuses/#{direct.id}/context") res_conn = get(conn, "/api/v1/statuses/#{direct.id}/context")
assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200) assert %{"ancestors" => [], "descendants" => []} ==
json_response_and_validate_schema(res_conn, 200)
end end
test "Removes a conversation", %{user: user_one, conn: conn} do test "Removes a conversation", %{user: user_one, conn: conn} do

View file

@ -140,7 +140,7 @@ test "it returns 403 if media object requested by non-owner", %{object: object,
conn conn
|> get("/api/v1/media/#{object.id}") |> get("/api/v1/media/#{object.id}")
|> json_response(403) |> json_response_and_validate_schema(403)
end end
end end
end end

View file

@ -82,6 +82,7 @@ test "posting a status", %{conn: conn} do
"sensitive" => 0 "sensitive" => 0
}) })
# Idempotency plug response means detection fail
assert %{"id" => second_id} = json_response(conn_two, 200) assert %{"id" => second_id} = json_response(conn_two, 200)
assert id == second_id assert id == second_id
@ -1559,7 +1560,7 @@ test "Repeated posts that are replies incorrectly have in_reply_to_id null", %{c
|> assign(:token, insert(:oauth_token, user: user3, scopes: ["read:statuses"])) |> assign(:token, insert(:oauth_token, user: user3, scopes: ["read:statuses"]))
|> get("api/v1/timelines/home") |> get("api/v1/timelines/home")
[reblogged_activity] = json_response(conn3, 200) [reblogged_activity] = json_response_and_validate_schema(conn3, 200)
assert reblogged_activity["reblog"]["in_reply_to_id"] == replied_to.id assert reblogged_activity["reblog"]["in_reply_to_id"] == replied_to.id
@ -1913,7 +1914,7 @@ test "posting a local only status" do
local = Utils.as_local_public() local = Utils.as_local_public()
assert %{"content" => "cofe", "id" => id, "visibility" => "local"} = assert %{"content" => "cofe", "id" => id, "visibility" => "local"} =
json_response(conn_one, 200) json_response_and_validate_schema(conn_one, 200)
assert %Activity{id: ^id, data: %{"to" => [^local]}} = Activity.get_by_id(id) assert %Activity{id: ^id, data: %{"to" => [^local]}} = Activity.get_by_id(id)
end end

View file

@ -905,10 +905,10 @@ defp ensure_authenticated_access(base_uri) do
%{conn: auth_conn} = oauth_access(["read:statuses"]) %{conn: auth_conn} = oauth_access(["read:statuses"])
res_conn = get(auth_conn, "#{base_uri}?local=true") res_conn = get(auth_conn, "#{base_uri}?local=true")
assert length(json_response(res_conn, 200)) == 1 assert length(json_response_and_validate_schema(res_conn, 200)) == 1
res_conn = get(auth_conn, "#{base_uri}?local=false") res_conn = get(auth_conn, "#{base_uri}?local=false")
assert length(json_response(res_conn, 200)) == 2 assert length(json_response_and_validate_schema(res_conn, 200)) == 2
end end
test "with default settings on private instances, returns 403 for unauthenticated users", %{ test "with default settings on private instances, returns 403 for unauthenticated users", %{
@ -922,7 +922,7 @@ test "with default settings on private instances, returns 403 for unauthenticate
for local <- [true, false] do for local <- [true, false] do
res_conn = get(conn, "#{base_uri}?local=#{local}") res_conn = get(conn, "#{base_uri}?local=#{local}")
assert json_response(res_conn, :unauthorized) == error_response assert json_response_and_validate_schema(res_conn, :unauthorized) == error_response
end end
ensure_authenticated_access(base_uri) ensure_authenticated_access(base_uri)
@ -939,7 +939,7 @@ test "with `%{local: true, federated: true}`, returns 403 for unauthenticated us
for local <- [true, false] do for local <- [true, false] do
res_conn = get(conn, "#{base_uri}?local=#{local}") res_conn = get(conn, "#{base_uri}?local=#{local}")
assert json_response(res_conn, :unauthorized) == error_response assert json_response_and_validate_schema(res_conn, :unauthorized) == error_response
end end
ensure_authenticated_access(base_uri) ensure_authenticated_access(base_uri)
@ -951,10 +951,10 @@ test "with `%{local: false, federated: true}`, forbids unauthenticated access to
clear_config([:restrict_unauthenticated, :timelines, :federated], true) clear_config([:restrict_unauthenticated, :timelines, :federated], true)
res_conn = get(conn, "#{base_uri}?local=true") res_conn = get(conn, "#{base_uri}?local=true")
assert length(json_response(res_conn, 200)) == 1 assert length(json_response_and_validate_schema(res_conn, 200)) == 1
res_conn = get(conn, "#{base_uri}?local=false") res_conn = get(conn, "#{base_uri}?local=false")
assert json_response(res_conn, :unauthorized) == error_response assert json_response_and_validate_schema(res_conn, :unauthorized) == error_response
ensure_authenticated_access(base_uri) ensure_authenticated_access(base_uri)
end end
@ -966,11 +966,11 @@ test "with `%{local: true, federated: false}`, forbids unauthenticated access to
clear_config([:restrict_unauthenticated, :timelines, :federated], false) clear_config([:restrict_unauthenticated, :timelines, :federated], false)
res_conn = get(conn, "#{base_uri}?local=true") res_conn = get(conn, "#{base_uri}?local=true")
assert json_response(res_conn, :unauthorized) == error_response assert json_response_and_validate_schema(res_conn, :unauthorized) == error_response
# Note: local activities get delivered as part of federated timeline # Note: local activities get delivered as part of federated timeline
res_conn = get(conn, "#{base_uri}?local=false") res_conn = get(conn, "#{base_uri}?local=false")
assert length(json_response(res_conn, 200)) == 2 assert length(json_response_and_validate_schema(res_conn, 200)) == 2
ensure_authenticated_access(base_uri) ensure_authenticated_access(base_uri)
end end

View file

@ -20,7 +20,7 @@ test "put settings", %{conn: conn} do
|> assign(:token, insert(:oauth_token, user: user, scopes: ["write:accounts"])) |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:accounts"]))
|> put("/api/web/settings", %{"data" => %{"programming" => "socks"}}) |> put("/api/web/settings", %{"data" => %{"programming" => "socks"}})
assert _result = json_response(conn, 200) assert %{} = json_response(conn, 200)
user = User.get_cached_by_ap_id(user.ap_id) user = User.get_cached_by_ap_id(user.ap_id)
assert user.mastofe_settings == %{"programming" => "socks"} assert user.mastofe_settings == %{"programming" => "socks"}

View file

@ -83,7 +83,7 @@ test "requires 'follow' or 'write:follows' permissions" do
assert %{"error" => "Insufficient permissions: follow | write:follows."} == assert %{"error" => "Insufficient permissions: follow | write:follows."} ==
json_response(conn, 403) json_response(conn, 403)
else else
assert json_response(conn, 200) assert json_response_and_validate_schema(conn, 200)
end end
end end
end end

View file

@ -7,59 +7,10 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token
import Pleroma.Factory import Pleroma.Factory
describe "POST /api/qvitter/statuses/notifications/read" do
test "without valid credentials", %{conn: conn} do
conn = post(conn, "/api/qvitter/statuses/notifications/read", %{"latest_id" => 1_234_567})
assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
end
test "with credentials, without any params" do
%{conn: conn} = oauth_access(["write:notifications"])
conn = post(conn, "/api/qvitter/statuses/notifications/read")
assert json_response(conn, 400) == %{
"error" => "You need to specify latest_id",
"request" => "/api/qvitter/statuses/notifications/read"
}
end
test "with credentials, with params" do
%{user: current_user, conn: conn} =
oauth_access(["read:notifications", "write:notifications"])
other_user = insert(:user)
{:ok, _activity} =
CommonAPI.post(other_user, %{
status: "Hey @#{current_user.nickname}"
})
response_conn =
conn
|> get("/api/v1/notifications")
[notification] = json_response(response_conn, 200)
assert notification["pleroma"]["is_seen"] == false
response_conn =
conn
|> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]})
[notification] = response = json_response(response_conn, 200)
assert length(response) == 1
assert notification["pleroma"]["is_seen"] == true
end
end
describe "GET /api/account/confirm_email/:id/:token" do describe "GET /api/account/confirm_email/:id/:token" do
setup do setup do
{:ok, user} = {:ok, user} =

View file

@ -25,11 +25,14 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
test "it updates notification settings", %{user: user, conn: conn} do test "it updates notification settings", %{user: user, conn: conn} do
conn conn
|> put("/api/pleroma/notification_settings", %{ |> put(
"block_from_strangers" => true, "/api/pleroma/notification_settings?#{
"bar" => 1 URI.encode_query(%{
}) block_from_strangers: true
|> json_response(:ok) })
}"
)
|> json_response_and_validate_schema(:ok)
user = refresh_record(user) user = refresh_record(user)
@ -41,8 +44,14 @@ test "it updates notification settings", %{user: user, conn: conn} do
test "it updates notification settings to enable hiding contents", %{user: user, conn: conn} do test "it updates notification settings to enable hiding contents", %{user: user, conn: conn} do
conn conn
|> put("/api/pleroma/notification_settings", %{"hide_notification_contents" => "1"}) |> put(
|> json_response(:ok) "/api/pleroma/notification_settings?#{
URI.encode_query(%{
hide_notification_contents: 1
})
}"
)
|> json_response_and_validate_schema(:ok)
user = refresh_record(user) user = refresh_record(user)
@ -70,7 +79,7 @@ test "returns everything in :pleroma, :frontend_configurations", %{conn: conn} d
response = response =
conn conn
|> get("/api/pleroma/frontend_configurations") |> get("/api/pleroma/frontend_configurations")
|> json_response(:ok) |> json_response_and_validate_schema(:ok)
assert response == Jason.encode!(config |> Enum.into(%{})) |> Jason.decode!() assert response == Jason.encode!(config |> Enum.into(%{})) |> Jason.decode!()
end end
@ -81,7 +90,7 @@ test "returns json with custom emoji with tags", %{conn: conn} do
emoji = emoji =
conn conn
|> get("/api/pleroma/emoji") |> get("/api/pleroma/emoji")
|> json_response(200) |> json_response_and_validate_schema(200)
assert Enum.all?(emoji, fn assert Enum.all?(emoji, fn
{_key, {_key,
@ -103,7 +112,7 @@ test "returns 503 when healthcheck disabled", %{conn: conn} do
response = response =
conn conn
|> get("/api/pleroma/healthcheck") |> get("/api/pleroma/healthcheck")
|> json_response(503) |> json_response_and_validate_schema(503)
assert response == %{} assert response == %{}
end end
@ -116,7 +125,7 @@ test "returns 200 when healthcheck enabled and all ok", %{conn: conn} do
response = response =
conn conn
|> get("/api/pleroma/healthcheck") |> get("/api/pleroma/healthcheck")
|> json_response(200) |> json_response_and_validate_schema(200)
assert %{ assert %{
"active" => _, "active" => _,
@ -136,7 +145,7 @@ test "returns 503 when healthcheck enabled and health is false", %{conn: conn} d
response = response =
conn conn
|> get("/api/pleroma/healthcheck") |> get("/api/pleroma/healthcheck")
|> json_response(503) |> json_response_and_validate_schema(503)
assert %{ assert %{
"active" => _, "active" => _,
@ -155,8 +164,8 @@ test "returns 503 when healthcheck enabled and health is false", %{conn: conn} d
test "with valid permissions and password, it disables the account", %{conn: conn, user: user} do test "with valid permissions and password, it disables the account", %{conn: conn, user: user} do
response = response =
conn conn
|> post("/api/pleroma/disable_account", %{"password" => "test"}) |> post("/api/pleroma/disable_account?password=test")
|> json_response(:ok) |> json_response_and_validate_schema(:ok)
assert response == %{"status" => "success"} assert response == %{"status" => "success"}
ObanHelpers.perform_all() ObanHelpers.perform_all()
@ -171,8 +180,8 @@ test "with valid permissions and invalid password, it returns an error", %{conn:
response = response =
conn conn
|> post("/api/pleroma/disable_account", %{"password" => "test1"}) |> post("/api/pleroma/disable_account?password=test1")
|> json_response(:ok) |> json_response_and_validate_schema(:ok)
assert response == %{"error" => "Invalid password."} assert response == %{"error" => "Invalid password."}
user = User.get_cached_by_id(user.id) user = User.get_cached_by_id(user.id)
@ -252,54 +261,61 @@ test "without permissions", %{conn: conn} do
conn = conn =
conn conn
|> assign(:token, nil) |> assign(:token, nil)
|> post("/api/pleroma/change_email") |> post(
"/api/pleroma/change_email?#{
URI.encode_query(%{password: "hi", email: "test@test.com"})
}"
)
assert json_response(conn, 403) == %{"error" => "Insufficient permissions: write:accounts."} assert json_response_and_validate_schema(conn, 403) == %{
"error" => "Insufficient permissions: write:accounts."
}
end end
test "with proper permissions and invalid password", %{conn: conn} do test "with proper permissions and invalid password", %{conn: conn} do
conn = conn =
post(conn, "/api/pleroma/change_email", %{ post(
"password" => "hi", conn,
"email" => "test@test.com" "/api/pleroma/change_email?#{
}) URI.encode_query(%{password: "hi", email: "test@test.com"})
}"
)
assert json_response(conn, 200) == %{"error" => "Invalid password."} assert json_response_and_validate_schema(conn, 200) == %{"error" => "Invalid password."}
end end
test "with proper permissions, valid password and invalid email", %{ test "with proper permissions, valid password and invalid email", %{
conn: conn conn: conn
} do } do
conn = conn =
post(conn, "/api/pleroma/change_email", %{ post(
"password" => "test", conn,
"email" => "foobar" "/api/pleroma/change_email?#{URI.encode_query(%{password: "test", email: "foobar"})}"
}) )
assert json_response(conn, 200) == %{"error" => "Email has invalid format."} assert json_response_and_validate_schema(conn, 200) == %{
"error" => "Email has invalid format."
}
end end
test "with proper permissions, valid password and no email", %{ test "with proper permissions, valid password and no email", %{
conn: conn conn: conn
} do } do
conn = conn = post(conn, "/api/pleroma/change_email?#{URI.encode_query(%{password: "test"})}")
post(conn, "/api/pleroma/change_email", %{
"password" => "test"
})
assert json_response(conn, 200) == %{"error" => "Email can't be blank."} assert %{"error" => "Missing field: email."} = json_response_and_validate_schema(conn, 400)
end end
test "with proper permissions, valid password and blank email", %{ test "with proper permissions, valid password and blank email", %{
conn: conn conn: conn
} do } do
conn = conn =
post(conn, "/api/pleroma/change_email", %{ post(
"password" => "test", conn,
"email" => "" "/api/pleroma/change_email?#{URI.encode_query(%{password: "test", email: ""})}"
}) )
assert json_response(conn, 200) == %{"error" => "Email can't be blank."} assert json_response_and_validate_schema(conn, 200) == %{"error" => "Email can't be blank."}
end end
test "with proper permissions, valid password and non unique email", %{ test "with proper permissions, valid password and non unique email", %{
@ -308,24 +324,28 @@ test "with proper permissions, valid password and non unique email", %{
user = insert(:user) user = insert(:user)
conn = conn =
post(conn, "/api/pleroma/change_email", %{ post(
"password" => "test", conn,
"email" => user.email "/api/pleroma/change_email?#{URI.encode_query(%{password: "test", email: user.email})}"
}) )
assert json_response(conn, 200) == %{"error" => "Email has already been taken."} assert json_response_and_validate_schema(conn, 200) == %{
"error" => "Email has already been taken."
}
end end
test "with proper permissions, valid password and valid email", %{ test "with proper permissions, valid password and valid email", %{
conn: conn conn: conn
} do } do
conn = conn =
post(conn, "/api/pleroma/change_email", %{ post(
"password" => "test", conn,
"email" => "cofe@foobar.com" "/api/pleroma/change_email?#{
}) URI.encode_query(%{password: "test", email: "cofe@foobar.com"})
}"
)
assert json_response(conn, 200) == %{"status" => "success"} assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"}
end end
end end
@ -336,20 +356,35 @@ test "without permissions", %{conn: conn} do
conn = conn =
conn conn
|> assign(:token, nil) |> assign(:token, nil)
|> post("/api/pleroma/change_password") |> post(
"/api/pleroma/change_password?#{
URI.encode_query(%{
password: "hi",
new_password: "newpass",
new_password_confirmation: "newpass"
})
}"
)
assert json_response(conn, 403) == %{"error" => "Insufficient permissions: write:accounts."} assert json_response_and_validate_schema(conn, 403) == %{
"error" => "Insufficient permissions: write:accounts."
}
end end
test "with proper permissions and invalid password", %{conn: conn} do test "with proper permissions and invalid password", %{conn: conn} do
conn = conn =
post(conn, "/api/pleroma/change_password", %{ post(
"password" => "hi", conn,
"new_password" => "newpass", "/api/pleroma/change_password?#{
"new_password_confirmation" => "newpass" URI.encode_query(%{
}) password: "hi",
new_password: "newpass",
new_password_confirmation: "newpass"
})
}"
)
assert json_response(conn, 200) == %{"error" => "Invalid password."} assert json_response_and_validate_schema(conn, 200) == %{"error" => "Invalid password."}
end end
test "with proper permissions, valid password and new password and confirmation not matching", test "with proper permissions, valid password and new password and confirmation not matching",
@ -357,13 +392,18 @@ test "with proper permissions, valid password and new password and confirmation
conn: conn conn: conn
} do } do
conn = conn =
post(conn, "/api/pleroma/change_password", %{ post(
"password" => "test", conn,
"new_password" => "newpass", "/api/pleroma/change_password?#{
"new_password_confirmation" => "notnewpass" URI.encode_query(%{
}) password: "test",
new_password: "newpass",
new_password_confirmation: "notnewpass"
})
}"
)
assert json_response(conn, 200) == %{ assert json_response_and_validate_schema(conn, 200) == %{
"error" => "New password does not match confirmation." "error" => "New password does not match confirmation."
} }
end end
@ -372,13 +412,14 @@ test "with proper permissions, valid password and invalid new password", %{
conn: conn conn: conn
} do } do
conn = conn =
post(conn, "/api/pleroma/change_password", %{ post(
"password" => "test", conn,
"new_password" => "", "/api/pleroma/change_password?#{
"new_password_confirmation" => "" URI.encode_query(%{password: "test", new_password: "", new_password_confirmation: ""})
}) }"
)
assert json_response(conn, 200) == %{ assert json_response_and_validate_schema(conn, 200) == %{
"error" => "New password can't be blank." "error" => "New password can't be blank."
} }
end end
@ -388,13 +429,18 @@ test "with proper permissions, valid password and matching new password and conf
user: user user: user
} do } do
conn = conn =
post(conn, "/api/pleroma/change_password", %{ post(
"password" => "test", conn,
"new_password" => "newpass", "/api/pleroma/change_password?#{
"new_password_confirmation" => "newpass" URI.encode_query(%{
}) password: "test",
new_password: "newpass",
new_password_confirmation: "newpass"
})
}"
)
assert json_response(conn, 200) == %{"status" => "success"} assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"}
fetched_user = User.get_cached_by_id(user.id) fetched_user = User.get_cached_by_id(user.id)
assert Pleroma.Password.Pbkdf2.verify_pass("newpass", fetched_user.password_hash) == true assert Pleroma.Password.Pbkdf2.verify_pass("newpass", fetched_user.password_hash) == true
end end
@ -409,7 +455,7 @@ test "without permissions", %{conn: conn} do
|> assign(:token, nil) |> assign(:token, nil)
|> post("/api/pleroma/delete_account") |> post("/api/pleroma/delete_account")
assert json_response(conn, 403) == assert json_response_and_validate_schema(conn, 403) ==
%{"error" => "Insufficient permissions: write:accounts."} %{"error" => "Insufficient permissions: write:accounts."}
end end
@ -417,14 +463,16 @@ test "with proper permissions and wrong or missing password", %{conn: conn} do
for params <- [%{"password" => "hi"}, %{}] do for params <- [%{"password" => "hi"}, %{}] do
ret_conn = post(conn, "/api/pleroma/delete_account", params) ret_conn = post(conn, "/api/pleroma/delete_account", params)
assert json_response(ret_conn, 200) == %{"error" => "Invalid password."} assert json_response_and_validate_schema(ret_conn, 200) == %{
"error" => "Invalid password."
}
end end
end end
test "with proper permissions and valid password", %{conn: conn, user: user} do test "with proper permissions and valid password", %{conn: conn, user: user} do
conn = post(conn, "/api/pleroma/delete_account", %{"password" => "test"}) conn = post(conn, "/api/pleroma/delete_account?password=test")
ObanHelpers.perform_all() ObanHelpers.perform_all()
assert json_response(conn, 200) == %{"status" => "success"} assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"}
user = User.get_by_id(user.id) user = User.get_by_id(user.id)
refute user.is_active refute user.is_active