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.
- 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)
### Fixed

View File

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

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),
responses: %{
200 => ok_response(),
403 => Operation.response("Error", "application/json", ApiError),
500 => Operation.response("Error", "application/json", ApiError)
},
security: [%{"oAuth" => ["write:follow"]}]

View File

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

View File

@ -5,7 +5,6 @@
defmodule Pleroma.Web.TwitterAPI.Controller do
use Pleroma.Web, :controller
alias Pleroma.Notification
alias Pleroma.User
alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.Plugs.EnsurePublicOrAuthenticatedPlug
@ -14,11 +13,6 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
require Logger
plug(
OAuthScopesPlug,
%{scopes: ["write:notifications"]} when action == :mark_notifications_as_read
)
plug(
:skip_plug,
[OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :confirm_email
@ -67,31 +61,4 @@ defp json_reply(conn, status, json) do
|> put_resp_content_type("application/json")
|> send_resp(status, json)
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

View File

@ -10,12 +10,12 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
alias Pleroma.Config
alias Pleroma.Emoji
alias Pleroma.Healthcheck
alias Pleroma.Notification
alias Pleroma.User
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Plugs.OAuthScopesPlug
alias Pleroma.Web.WebFinger
plug(Pleroma.Web.ApiSpec.CastAndValidate when action != :remote_subscribe)
plug(Pleroma.Web.Plugs.FederatingPlug when action == :remote_subscribe)
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
with %User{} = user <- User.get_cached_by_nickname(nick),
@ -62,17 +62,6 @@ def remote_subscribe(conn, %{"user" => %{"nickname" => nick, "profile" => profil
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
render(conn, "frontend_configurations.json")
end
@ -92,13 +81,17 @@ def update_notificaton_settings(%{assigns: %{user: user}} = conn, params) do
end
end
def change_password(%{assigns: %{user: user}} = conn, params) do
case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
def change_password(%{assigns: %{user: user}} = conn, %{
password: password,
new_password: new_password,
new_password_confirmation: new_password_confirmation
}) do
case CommonAPI.Utils.confirm_current_password(user, password) do
{:ok, user} ->
with {:ok, _user} <-
User.reset_password(user, %{
password: params["new_password"],
password_confirmation: params["new_password_confirmation"]
password: new_password,
password_confirmation: new_password_confirmation
}) do
json(conn, %{status: "success"})
else
@ -115,10 +108,10 @@ def change_password(%{assigns: %{user: user}} = conn, params) do
end
end
def change_email(%{assigns: %{user: user}} = conn, params) do
case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
def change_email(%{assigns: %{user: user}} = conn, %{password: password, email: email}) do
case CommonAPI.Utils.confirm_current_password(user, password) do
{: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"})
else
{:error, changeset} ->
@ -135,7 +128,7 @@ def change_email(%{assigns: %{user: user}} = conn, params) do
end
def delete_account(%{assigns: %{user: user}} = conn, params) do
password = params["password"] || ""
password = params[:password] || ""
case CommonAPI.Utils.confirm_current_password(user, password) do
{:ok, user} ->
@ -148,7 +141,7 @@ def delete_account(%{assigns: %{user: user}} = conn, params) do
end
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} ->
User.set_activation_async(user, false)
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"})
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
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
refute response_1 == response_2
@ -881,7 +881,7 @@ test "following without reblogs" do
assert [] ==
conn
|> get("/api/v1/timelines/home")
|> json_response(200)
|> json_response_and_validate_schema(200)
assert %{"showing_reblogs" => true} =
conn
@ -892,7 +892,7 @@ test "following without reblogs" do
assert [%{"id" => ^reblog_id}] =
conn
|> get("/api/v1/timelines/home")
|> json_response(200)
|> json_response_and_validate_schema(200)
end
test "following with reblogs" do
@ -910,7 +910,7 @@ test "following with reblogs" do
assert [%{"id" => ^reblog_id}] =
conn
|> get("/api/v1/timelines/home")
|> json_response(200)
|> json_response_and_validate_schema(200)
assert %{"showing_reblogs" => false} =
conn
@ -921,7 +921,7 @@ test "following with reblogs" do
assert [] ==
conn
|> get("/api/v1/timelines/home")
|> json_response(200)
|> json_response_and_validate_schema(200)
end
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")
assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200)
assert %{"ancestors" => [], "descendants" => []} ==
json_response_and_validate_schema(res_conn, 200)
end
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
|> get("/api/v1/media/#{object.id}")
|> json_response(403)
|> json_response_and_validate_schema(403)
end
end
end

View File

@ -82,6 +82,7 @@ test "posting a status", %{conn: conn} do
"sensitive" => 0
})
# Idempotency plug response means detection fail
assert %{"id" => second_id} = json_response(conn_two, 200)
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"]))
|> 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
@ -1913,7 +1914,7 @@ test "posting a local only status" do
local = Utils.as_local_public()
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)
end

View File

@ -905,10 +905,10 @@ defp ensure_authenticated_access(base_uri) do
%{conn: auth_conn} = oauth_access(["read:statuses"])
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")
assert length(json_response(res_conn, 200)) == 2
assert length(json_response_and_validate_schema(res_conn, 200)) == 2
end
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
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
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
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
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)
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")
assert json_response(res_conn, :unauthorized) == error_response
assert json_response_and_validate_schema(res_conn, :unauthorized) == error_response
ensure_authenticated_access(base_uri)
end
@ -966,11 +966,11 @@ test "with `%{local: true, federated: false}`, forbids unauthenticated access to
clear_config([:restrict_unauthenticated, :timelines, :federated], false)
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
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)
end

View File

@ -20,7 +20,7 @@ test "put settings", %{conn: conn} do
|> assign(:token, insert(:oauth_token, user: user, scopes: ["write:accounts"]))
|> 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)
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."} ==
json_response(conn, 403)
else
assert json_response(conn, 200)
assert json_response_and_validate_schema(conn, 200)
end
end
end

View File

@ -7,59 +7,10 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.OAuth.Token
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
setup do
{:ok, user} =

View File

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