@@ -228,4 +228,11 @@ defmodule Pleroma.Object do | |||
_ -> :noop | |||
end | |||
end | |||
@doc "Updates data field of an object" | |||
def update_data(%Object{data: data} = object, attrs \\ %{}) do | |||
object | |||
|> Object.change(%{data: Map.merge(data || %{}, attrs)}) | |||
|> Repo.update() | |||
end | |||
end |
@@ -499,6 +499,11 @@ defmodule Pleroma.User do | |||
|> Repo.all() | |||
end | |||
def get_all_by_ids(ids) do | |||
from(u in __MODULE__, where: u.id in ^ids) | |||
|> Repo.all() | |||
end | |||
# This is mostly an SPC migration fix. This guesses the user nickname by taking the last part | |||
# of the ap_id and the domain and tries to get that user | |||
def get_by_guessed_nickname(ap_id) do | |||
@@ -770,6 +775,19 @@ defmodule Pleroma.User do | |||
|> update_and_set_cache() | |||
end | |||
def update_mascot(user, url) do | |||
info_changeset = | |||
User.Info.mascot_update( | |||
user.info, | |||
url | |||
) | |||
user | |||
|> change() | |||
|> put_embed(:info, info_changeset) | |||
|> update_and_set_cache() | |||
end | |||
@spec maybe_fetch_follow_information(User.t()) :: User.t() | |||
def maybe_fetch_follow_information(user) do | |||
with {:ok, user} <- fetch_follow_information(user) do | |||
@@ -917,9 +935,7 @@ defmodule Pleroma.User do | |||
def unsubscribe(unsubscriber, %{ap_id: ap_id}) do | |||
with %User{} = user <- get_cached_by_ap_id(ap_id) do | |||
info_cng = | |||
user.info | |||
|> User.Info.remove_from_subscribers(unsubscriber.ap_id) | |||
info_cng = User.Info.remove_from_subscribers(user.info, unsubscriber.ap_id) | |||
change(user) | |||
|> put_embed(:info, info_cng) | |||
@@ -447,8 +447,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
grouped_activities <- Enum.group_by(activities, fn %{id: id} -> id < activity.id end) do | |||
result = %{ | |||
ancestors: | |||
StatusView.render( | |||
"index.json", | |||
StatusView.render("index.json", | |||
for: user, | |||
activities: grouped_activities[true] || [], | |||
as: :activity | |||
@@ -456,8 +455,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
|> Enum.reverse(), | |||
# credo:disable-for-previous-line Credo.Check.Refactor.PipeChainStart | |||
descendants: | |||
StatusView.render( | |||
"index.json", | |||
StatusView.render("index.json", | |||
for: user, | |||
activities: grouped_activities[false] || [], | |||
as: :activity | |||
@@ -746,9 +744,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
end | |||
def relationships(%{assigns: %{user: user}} = conn, %{"id" => id}) do | |||
id = List.wrap(id) | |||
q = from(u in User, where: u.id in ^id) | |||
targets = Repo.all(q) | |||
targets = User.get_all_by_ids(List.wrap(id)) | |||
conn | |||
|> put_view(AccountView) | |||
@@ -758,19 +754,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
# Instead of returning a 400 when no "id" params is present, Mastodon returns an empty array. | |||
def relationships(%{assigns: %{user: _user}} = conn, _), do: json(conn, []) | |||
def update_media(%{assigns: %{user: user}} = conn, data) do | |||
with %Object{} = object <- Repo.get(Object, data["id"]), | |||
def update_media( | |||
%{assigns: %{user: user}} = conn, | |||
%{"id" => id, "description" => description} = _ | |||
) | |||
when is_binary(description) do | |||
with %Object{} = object <- Repo.get(Object, id), | |||
true <- Object.authorize_mutation(object, user), | |||
true <- is_binary(data["description"]), | |||
description <- data["description"] do | |||
new_data = %{object.data | "name" => description} | |||
{:ok, _} = | |||
object | |||
|> Object.change(%{data: new_data}) | |||
|> Repo.update() | |||
attachment_data = Map.put(new_data, "id", object.id) | |||
{:ok, %Object{data: data}} <- Object.update_data(object, %{"name" => description}) do | |||
attachment_data = Map.put(data, "id", object.id) | |||
conn | |||
|> put_view(StatusView) | |||
@@ -778,6 +770,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
end | |||
end | |||
def update_media(_conn, _data), do: {:error, :bad_request} | |||
def upload(%{assigns: %{user: user}} = conn, %{"file" => file} = data) do | |||
with {:ok, object} <- | |||
ActivityPub.upload( | |||
@@ -796,34 +790,23 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
def set_mascot(%{assigns: %{user: user}} = conn, %{"file" => file}) do | |||
with {:ok, object} <- ActivityPub.upload(file, actor: User.ap_id(user)), | |||
%{} = attachment_data <- Map.put(object.data, "id", object.id), | |||
%{type: type} = rendered <- | |||
StatusView.render("attachment.json", %{attachment: attachment_data}) do | |||
# Reject if not an image | |||
if type == "image" do | |||
# Sure! | |||
# Save to the user's info | |||
info_changeset = User.Info.mascot_update(user.info, rendered) | |||
user_changeset = | |||
user | |||
|> Changeset.change() | |||
|> Changeset.put_embed(:info, info_changeset) | |||
{:ok, _user} = User.update_and_set_cache(user_changeset) | |||
conn | |||
|> json(rendered) | |||
else | |||
%{type: "image"} = rendered <- | |||
StatusView.render("attachment.json", %{attachment: attachment_data}), | |||
{:ok, _user} = User.update_mascot(user, rendered) do | |||
json(conn, rendered) | |||
else | |||
%{type: _type} = _ -> | |||
render_error(conn, :unsupported_media_type, "mascots can only be images") | |||
end | |||
e -> | |||
e | |||
end | |||
end | |||
def get_mascot(%{assigns: %{user: user}} = conn, _params) do | |||
mascot = User.get_mascot(user) | |||
conn | |||
|> json(mascot) | |||
json(conn, mascot) | |||
end | |||
def favourited_by(%{assigns: %{user: user}} = conn, %{"id" => id}) do | |||
@@ -1119,10 +1102,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
|> put_view(AccountView) | |||
|> render("relationship.json", %{user: user, target: subscription_target}) | |||
else | |||
{:error, message} -> | |||
conn | |||
|> put_status(:forbidden) | |||
|> json(%{error: message}) | |||
nil -> {:error, :not_found} | |||
e -> e | |||
end | |||
end | |||
@@ -1133,10 +1114,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
|> put_view(AccountView) | |||
|> render("relationship.json", %{user: user, target: subscription_target}) | |||
else | |||
{:error, message} -> | |||
conn | |||
|> put_status(:forbidden) | |||
|> json(%{error: message}) | |||
nil -> {:error, :not_found} | |||
e -> e | |||
end | |||
end | |||
@@ -1207,8 +1186,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
def account_lists(%{assigns: %{user: user}} = conn, %{"id" => account_id}) do | |||
lists = Pleroma.List.get_lists_account_belongs(user, account_id) | |||
res = ListView.render("lists.json", lists: lists) | |||
json(conn, res) | |||
conn | |||
|> put_view(ListView) | |||
|> render("index.json", %{lists: lists}) | |||
end | |||
def list_timeline(%{assigns: %{user: user}} = conn, %{"list_id" => id} = params) do | |||
@@ -1363,7 +1344,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
@doc "Local Mastodon FE login init action" | |||
def login(conn, %{"code" => auth_token}) do | |||
with {:ok, app} <- get_or_make_app(), | |||
%Authorization{} = auth <- Repo.get_by(Authorization, token: auth_token, app_id: app.id), | |||
{:ok, auth} <- Authorization.get_by_token(app, auth_token), | |||
{:ok, token} <- Token.exchange_token(app, auth) do | |||
conn | |||
|> put_session(:oauth_token, token.token) | |||
@@ -1375,9 +1356,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
def login(conn, _) do | |||
with {:ok, app} <- get_or_make_app() do | |||
path = | |||
o_auth_path( | |||
conn, | |||
:authorize, | |||
o_auth_path(conn, :authorize, | |||
response_type: "code", | |||
client_id: app.client_id, | |||
redirect_uri: ".", | |||
@@ -1399,31 +1378,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
end | |||
end | |||
@spec get_or_make_app() :: {:ok, App.t()} | {:error, Ecto.Changeset.t()} | |||
defp get_or_make_app do | |||
find_attrs = %{client_name: @local_mastodon_name, redirect_uris: "."} | |||
scopes = ["read", "write", "follow", "push"] | |||
with %App{} = app <- Repo.get_by(App, find_attrs) do | |||
{:ok, app} = | |||
if app.scopes == scopes do | |||
{:ok, app} | |||
else | |||
app | |||
|> Changeset.change(%{scopes: scopes}) | |||
|> Repo.update() | |||
end | |||
{:ok, app} | |||
else | |||
_e -> | |||
cs = | |||
App.register_changeset( | |||
%App{}, | |||
Map.put(find_attrs, :scopes, scopes) | |||
) | |||
Repo.insert(cs) | |||
end | |||
App.get_or_make( | |||
%{client_name: @local_mastodon_name, redirect_uris: "."}, | |||
["read", "write", "follow", "push"] | |||
) | |||
end | |||
def logout(conn, _) do | |||
@@ -1432,26 +1392,13 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
|> redirect(to: "/") | |||
end | |||
def relationship_noop(%{assigns: %{user: user}} = conn, %{"id" => id}) do | |||
Logger.debug("Unimplemented, returning unmodified relationship") | |||
with %User{} = target <- User.get_cached_by_id(id) do | |||
conn | |||
|> put_view(AccountView) | |||
|> render("relationship.json", %{user: user, target: target}) | |||
end | |||
end | |||
# Stubs for unimplemented mastodon api | |||
# | |||
def empty_array(conn, _) do | |||
Logger.debug("Unimplemented, returning an empty array") | |||
json(conn, []) | |||
end | |||
def empty_object(conn, _) do | |||
Logger.debug("Unimplemented, returning an empty object") | |||
json(conn, %{}) | |||
end | |||
def get_filters(%{assigns: %{user: user}} = conn, _) do | |||
filters = Filter.get_filters(user) | |||
res = FilterView.render("filters.json", filters: filters) | |||
@@ -1570,7 +1517,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
json(conn, data) | |||
else | |||
_e -> | |||
%{} | |||
json(conn, %{}) | |||
end | |||
end | |||
@@ -1623,7 +1570,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
end | |||
end | |||
def account_register(%{assigns: %{app: _app}} = conn, _params) do | |||
def account_register(%{assigns: %{app: _app}} = conn, _) do | |||
render_error(conn, :bad_request, "Missing parameters") | |||
end | |||
@@ -1682,15 +1629,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
end | |||
end | |||
def try_render(conn, target, params) | |||
when is_binary(target) do | |||
defp try_render(conn, target, params) | |||
when is_binary(target) do | |||
case render(conn, target, params) do | |||
nil -> render_error(conn, :not_implemented, "Can't display this activity") | |||
res -> res | |||
end | |||
end | |||
def try_render(conn, _, _) do | |||
defp try_render(conn, _, _) do | |||
render_error(conn, :not_implemented, "Can't display this activity") | |||
end | |||
@@ -5,6 +5,7 @@ | |||
defmodule Pleroma.Web.OAuth.App do | |||
use Ecto.Schema | |||
import Ecto.Changeset | |||
alias Pleroma.Repo | |||
@type t :: %__MODULE__{} | |||
@@ -39,4 +40,29 @@ defmodule Pleroma.Web.OAuth.App do | |||
changeset | |||
end | |||
end | |||
@doc """ | |||
Gets app by attrs or create new with attrs. | |||
And updates the scopes if need. | |||
""" | |||
@spec get_or_make(map(), list(String.t())) :: {:ok, App.t()} | {:error, Ecto.Changeset.t()} | |||
def get_or_make(attrs, scopes) do | |||
with %__MODULE__{} = app <- Repo.get_by(__MODULE__, attrs) do | |||
update_scopes(app, scopes) | |||
else | |||
_e -> | |||
%__MODULE__{} | |||
|> register_changeset(Map.put(attrs, :scopes, scopes)) | |||
|> Repo.insert() | |||
end | |||
end | |||
defp update_scopes(%__MODULE__{} = app, []), do: {:ok, app} | |||
defp update_scopes(%__MODULE__{scopes: scopes} = app, scopes), do: {:ok, app} | |||
defp update_scopes(%__MODULE__{} = app, scopes) do | |||
app | |||
|> change(%{scopes: scopes}) | |||
|> Repo.update() | |||
end | |||
end |
@@ -29,7 +29,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do | |||
captcha_enabled = Pleroma.Config.get([Pleroma.Captcha, :enabled]) | |||
# true if captcha is disabled or enabled and valid, false otherwise | |||
captcha_ok = | |||
if !captcha_enabled do | |||
if not captcha_enabled do | |||
:ok | |||
else | |||
Pleroma.Captcha.validate( | |||
@@ -1551,6 +1551,17 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
assert to_string(other_user.id) == relationship["id"] | |||
end | |||
test "returns an empty list when bad request", %{conn: conn} do | |||
user = insert(:user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/api/v1/accounts/relationships", %{}) | |||
assert [] = json_response(conn, 200) | |||
end | |||
end | |||
describe "media upload" do | |||
@@ -1752,70 +1763,72 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
end | |||
end | |||
test "mascot upload", %{conn: conn} do | |||
user = insert(:user) | |||
describe "/api/v1/pleroma/mascot" do | |||
test "mascot upload", %{conn: conn} do | |||
user = insert(:user) | |||
non_image_file = %Plug.Upload{ | |||
content_type: "audio/mpeg", | |||
path: Path.absname("test/fixtures/sound.mp3"), | |||
filename: "sound.mp3" | |||
} | |||
non_image_file = %Plug.Upload{ | |||
content_type: "audio/mpeg", | |||
path: Path.absname("test/fixtures/sound.mp3"), | |||
filename: "sound.mp3" | |||
} | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> put("/api/v1/pleroma/mascot", %{"file" => non_image_file}) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> put("/api/v1/pleroma/mascot", %{"file" => non_image_file}) | |||
assert json_response(conn, 415) | |||
assert json_response(conn, 415) | |||
file = %Plug.Upload{ | |||
content_type: "image/jpg", | |||
path: Path.absname("test/fixtures/image.jpg"), | |||
filename: "an_image.jpg" | |||
} | |||
file = %Plug.Upload{ | |||
content_type: "image/jpg", | |||
path: Path.absname("test/fixtures/image.jpg"), | |||
filename: "an_image.jpg" | |||
} | |||
conn = | |||
build_conn() | |||
|> assign(:user, user) | |||
|> put("/api/v1/pleroma/mascot", %{"file" => file}) | |||
conn = | |||
build_conn() | |||
|> assign(:user, user) | |||
|> put("/api/v1/pleroma/mascot", %{"file" => file}) | |||
assert %{"id" => _, "type" => image} = json_response(conn, 200) | |||
end | |||
assert %{"id" => _, "type" => image} = json_response(conn, 200) | |||
end | |||
test "mascot retrieving", %{conn: conn} do | |||
user = insert(:user) | |||
# When user hasn't set a mascot, we should just get pleroma tan back | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/api/v1/pleroma/mascot") | |||
test "mascot retrieving", %{conn: conn} do | |||
user = insert(:user) | |||
# When user hasn't set a mascot, we should just get pleroma tan back | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/api/v1/pleroma/mascot") | |||
assert %{"url" => url} = json_response(conn, 200) | |||
assert url =~ "pleroma-fox-tan-smol" | |||
assert %{"url" => url} = json_response(conn, 200) | |||
assert url =~ "pleroma-fox-tan-smol" | |||
# When a user sets their mascot, we should get that back | |||
file = %Plug.Upload{ | |||
content_type: "image/jpg", | |||
path: Path.absname("test/fixtures/image.jpg"), | |||
filename: "an_image.jpg" | |||
} | |||
# When a user sets their mascot, we should get that back | |||
file = %Plug.Upload{ | |||
content_type: "image/jpg", | |||
path: Path.absname("test/fixtures/image.jpg"), | |||
filename: "an_image.jpg" | |||
} | |||
conn = | |||
build_conn() | |||
|> assign(:user, user) | |||
|> put("/api/v1/pleroma/mascot", %{"file" => file}) | |||
conn = | |||
build_conn() | |||
|> assign(:user, user) | |||
|> put("/api/v1/pleroma/mascot", %{"file" => file}) | |||
assert json_response(conn, 200) | |||
assert json_response(conn, 200) | |||
user = User.get_cached_by_id(user.id) | |||
user = User.get_cached_by_id(user.id) | |||
conn = | |||
build_conn() | |||
|> assign(:user, user) | |||
|> get("/api/v1/pleroma/mascot") | |||
conn = | |||
build_conn() | |||
|> assign(:user, user) | |||
|> get("/api/v1/pleroma/mascot") | |||
assert %{"url" => url, "type" => "image"} = json_response(conn, 200) | |||
assert url =~ "an_image" | |||
assert %{"url" => url, "type" => "image"} = json_response(conn, 200) | |||
assert url =~ "an_image" | |||
end | |||
end | |||
test "hashtag timeline", %{conn: conn} do | |||
@@ -2183,23 +2196,51 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
end | |||
end | |||
test "subscribing / unsubscribing to a user", %{conn: conn} do | |||
user = insert(:user) | |||
subscription_target = insert(:user) | |||
describe "subscribing / unsubscribing" do | |||
test "subscribing / unsubscribing to a user", %{conn: conn} do | |||
user = insert(:user) | |||
subscription_target = insert(:user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/pleroma/accounts/#{subscription_target.id}/subscribe") | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/pleroma/accounts/#{subscription_target.id}/subscribe") | |||
assert %{"id" => _id, "subscribing" => true} = json_response(conn, 200) | |||
assert %{"id" => _id, "subscribing" => true} = json_response(conn, 200) | |||
conn = | |||
build_conn() | |||
|> assign(:user, user) | |||
|> post("/api/v1/pleroma/accounts/#{subscription_target.id}/unsubscribe") | |||
conn = | |||
build_conn() | |||
|> assign(:user, user) | |||
|> post("/api/v1/pleroma/accounts/#{subscription_target.id}/unsubscribe") | |||
assert %{"id" => _id, "subscribing" => false} = json_response(conn, 200) | |||
end | |||
end | |||
describe "subscribing" do | |||
test "returns 404 when subscription_target not found", %{conn: conn} do | |||
user = insert(:user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/pleroma/accounts/target_id/subscribe") | |||
assert %{"error" => "Record not found"} = json_response(conn, 404) | |||
end | |||
end | |||
describe "unsubscribing" do | |||
test "returns 404 when subscription_target not found", %{conn: conn} do | |||
user = insert(:user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/pleroma/accounts/target_id/unsubscribe") | |||
assert %{"id" => _id, "subscribing" => false} = json_response(conn, 200) | |||
assert %{"error" => "Record not found"} = json_response(conn, 404) | |||
end | |||
end | |||
test "getting a list of mutes", %{conn: conn} do | |||
@@ -2814,6 +2855,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
} | |||
} | |||
end | |||
test "returns empty object when id invalid", %{conn: conn} do | |||
response = | |||
conn | |||
|> get("/api/v1/statuses/9eoozpwTul5mjSEDRI/card") | |||
|> json_response(200) | |||
assert response == %{} | |||
end | |||
end | |||
test "bookmarks" do | |||
@@ -3133,6 +3183,18 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
assert conn.status == 302 | |||
assert redirected_to(conn) == path | |||
end | |||
end | |||
describe "GET /web/login" do | |||
test "redirects to /oauth/authorize", %{conn: conn} do | |||
app = insert(:oauth_app, client_name: "Mastodon-Local", redirect_uris: ".") | |||
conn = get(conn, "/web/login", %{}) | |||
assert conn.status == 302 | |||
assert redirected_to(conn) == | |||
"/oauth/authorize?response_type=code&client_id=#{app.client_id}&redirect_uri=.&scope=read+write+follow+push" | |||
end | |||
test "redirects to the getting-started page when referer is not present", %{conn: conn} do | |||
app = insert(:oauth_app, client_name: "Mastodon-Local", redirect_uris: ".") | |||
@@ -3143,6 +3205,18 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
assert conn.status == 302 | |||
assert redirected_to(conn) == "/web/getting-started" | |||
end | |||
test "redirects to the getting-started page when user assigned", %{conn: conn} do | |||
user = insert(:user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/web/login", %{}) | |||
assert conn.status == 302 | |||
assert redirected_to(conn) == "/web/getting-started" | |||
end | |||
end | |||
describe "scheduled activities" do | |||
@@ -3401,6 +3475,17 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
end | |||
describe "create account by app" do | |||
setup do | |||
valid_params = %{ | |||
username: "lain", | |||
email: "lain@example.org", | |||
password: "PlzDontHackLain", | |||
agreement: true | |||
} | |||
[valid_params: valid_params] | |||
end | |||
test "Account registration via Application", %{conn: conn} do | |||
conn = | |||
conn | |||
@@ -3444,6 +3529,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
username: "lain", | |||
email: "lain@example.org", | |||
password: "PlzDontHackLain", | |||
bio: "Test Bio", | |||
agreement: true | |||
}) | |||
@@ -3462,6 +3548,18 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
assert token_from_db.user.info.confirmation_pending | |||
end | |||
test "returns error when user already registred", %{conn: conn, valid_params: valid_params} do | |||
_user = insert(:user, email: "lain@example.org") | |||
app_token = insert(:oauth_token, user: nil) | |||
conn = | |||
conn | |||
|> put_req_header("authorization", "Bearer " <> app_token.token) | |||
res = post(conn, "/api/v1/accounts", valid_params) | |||
assert json_response(res, 400) == %{"error" => "{\"email\":[\"has already been taken\"]}"} | |||
end | |||
test "rate limit", %{conn: conn} do | |||
app_token = insert(:oauth_token, user: nil) | |||
@@ -3505,6 +3603,41 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
assert json_response(conn, :too_many_requests) == %{"error" => "Throttled"} | |||
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) | |||
res = post(conn, "/api/v1/accounts", valid_params) | |||
assert json_response(res, 200) | |||
Enum.each(valid_params, fn {attr, _} -> | |||
res = | |||
conn | |||
|> Map.put( | |||
:remote_ip, | |||
{:rand.uniform(15), :rand.uniform(15), :rand.uniform(15), :rand.uniform(15)} | |||
) | |||
|> post("/api/v1/accounts", Map.delete(valid_params, attr)) | |||
assert json_response(res, 400) == %{"error" => "Missing parameters"} | |||
end) | |||
end | |||
test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do | |||
conn = | |||
conn | |||
|> put_req_header("authorization", "Bearer " <> "invalid-token") | |||
res = post(conn, "/api/v1/accounts", valid_params) | |||
assert json_response(res, 403) == %{"error" => "Invalid credentials"} | |||
end | |||
end | |||
describe "GET /api/v1/polls/:id" do | |||
@@ -3988,4 +4121,115 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
] | |||
end | |||
end | |||
describe "PUT /api/v1/media/:id" do | |||
setup do | |||
actor = insert(:user) | |||
file = %Plug.Upload{ | |||
content_type: "image/jpg", | |||
path: Path.absname("test/fixtures/image.jpg"), | |||
filename: "an_image.jpg" | |||
} | |||
{:ok, %Object{} = object} = | |||
ActivityPub.upload( | |||
file, | |||
actor: User.ap_id(actor), | |||
description: "test-m" | |||
) | |||
[actor: actor, object: object] | |||
end | |||
test "updates name of media", %{conn: conn, actor: actor, object: object} do | |||
media = | |||
conn | |||
|> assign(:user, actor) | |||
|> put("/api/v1/media/#{object.id}", %{"description" => "test-media"}) | |||
|> json_response(:ok) | |||
assert media["description"] == "test-media" | |||
assert refresh_record(object).data["name"] == "test-media" | |||
end | |||
test "returns error wheb request is bad", %{conn: conn, actor: actor, object: object} do | |||
media = | |||
conn | |||
|> assign(:user, actor) | |||
|> put("/api/v1/media/#{object.id}", %{}) | |||
|> json_response(400) | |||
assert media == %{"error" => "bad_request"} | |||
end | |||
end | |||
describe "DELETE /auth/sign_out" do | |||
test "redirect to root page", %{conn: conn} do | |||
user = insert(:user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> delete("/auth/sign_out") | |||
assert conn.status == 302 | |||
assert redirected_to(conn) == "/" | |||
end | |||
end | |||
describe "GET /api/v1/accounts/:id/lists - account_lists" do | |||
test "returns lists to which the account belongs", %{conn: conn} do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
assert {:ok, %Pleroma.List{} = list} = Pleroma.List.create("Test List", user) | |||
{:ok, %{following: _following}} = Pleroma.List.follow(list, other_user) | |||
res = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/api/v1/accounts/#{other_user.id}/lists") | |||
|> json_response(200) | |||
assert res == [%{"id" => to_string(list.id), "title" => "Test List"}] | |||
end | |||
end | |||
describe "empty_array, stubs for mastodon api" do | |||
test "GET /api/v1/accounts/:id/identity_proofs", %{conn: conn} do | |||
user = insert(:user) | |||
res = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/api/v1/accounts/#{user.id}/identity_proofs") | |||
|> json_response(200) | |||
assert res == [] | |||
end | |||
test "GET /api/v1/endorsements", %{conn: conn} do | |||
user = insert(:user) | |||
res = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/api/v1/endorsements") | |||
|> json_response(200) | |||
assert res == [] | |||
end | |||
test "GET /api/v1/trends", %{conn: conn} do | |||
user = insert(:user) | |||
res = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/api/v1/trends") | |||
|> json_response(200) | |||
assert res == [] | |||
end | |||
end | |||
end |
@@ -0,0 +1,33 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.OAuth.AppTest do | |||
use Pleroma.DataCase | |||
alias Pleroma.Web.OAuth.App | |||
import Pleroma.Factory | |||
describe "get_or_make/2" do | |||
test "gets exist app" do | |||
attrs = %{client_name: "Mastodon-Local", redirect_uris: "."} | |||
app = insert(:oauth_app, Map.merge(attrs, %{scopes: ["read", "write"]})) | |||
{:ok, %App{} = exist_app} = App.get_or_make(attrs, []) | |||
assert exist_app == app | |||
end | |||
test "make app" do | |||
attrs = %{client_name: "Mastodon-Local", redirect_uris: "."} | |||
{:ok, %App{} = app} = App.get_or_make(attrs, ["write"]) | |||
assert app.scopes == ["write"] | |||
end | |||
test "gets exist app and updates scopes" do | |||
attrs = %{client_name: "Mastodon-Local", redirect_uris: "."} | |||
app = insert(:oauth_app, Map.merge(attrs, %{scopes: ["read", "write"]})) | |||
{:ok, %App{} = exist_app} = App.get_or_make(attrs, ["read", "write", "follow", "push"]) | |||
assert exist_app.id == app.id | |||
assert exist_app.scopes == ["read", "write", "follow", "push"] | |||
end | |||
end | |||
end |