diff --git a/lib/pleroma/list.ex b/lib/pleroma/list.ex
index c5db1cb62..08a94c62c 100644
--- a/lib/pleroma/list.ex
+++ b/lib/pleroma/list.ex
@@ -84,22 +84,11 @@ def get_lists_from_activity(%Activity{actor: ap_id}) do
end
# Get lists to which the account belongs.
- def get_lists_account_belongs(%User{} = owner, account_id) do
- user = User.get_cached_by_id(account_id)
-
- query =
- from(
- l in Pleroma.List,
- where:
- l.user_id == ^owner.id and
- fragment(
- "? = ANY(?)",
- ^user.follower_address,
- l.following
- )
- )
-
- Repo.all(query)
+ def get_lists_account_belongs(%User{} = owner, user) do
+ Pleroma.List
+ |> where([l], l.user_id == ^owner.id)
+ |> where([l], fragment("? = ANY(?)", ^user.follower_address, l.following))
+ |> Repo.all()
end
def rename(%Pleroma.List{} = list, title) do
diff --git a/lib/pleroma/web/admin_api/views/report_view.ex b/lib/pleroma/web/admin_api/views/report_view.ex
index 8c06364a3..101a74c63 100644
--- a/lib/pleroma/web/admin_api/views/report_view.ex
+++ b/lib/pleroma/web/admin_api/views/report_view.ex
@@ -43,7 +43,7 @@ def render("show.json", %{report: report, user: user, account: account, statuses
end
defp merge_account_views(%User{} = user) do
- Pleroma.Web.MastodonAPI.AccountView.render("account.json", %{user: user})
+ Pleroma.Web.MastodonAPI.AccountView.render("show.json", %{user: user})
|> Map.merge(Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user}))
end
diff --git a/lib/pleroma/web/chat_channel.ex b/lib/pleroma/web/chat_channel.ex
index b543909f1..08841a3e8 100644
--- a/lib/pleroma/web/chat_channel.ex
+++ b/lib/pleroma/web/chat_channel.ex
@@ -22,7 +22,7 @@ def handle_in("new_msg", %{"text" => text}, %{assigns: %{user_name: user_name}}
if String.length(text) > 0 do
author = User.get_cached_by_nickname(user_name)
- author = Pleroma.Web.MastodonAPI.AccountView.render("account.json", user: author)
+ author = Pleroma.Web.MastodonAPI.AccountView.render("show.json", user: author)
message = ChatChannelState.add_message(%{text: text, author: author})
broadcast!(socket, "new_msg", message)
diff --git a/lib/pleroma/web/controller_helper.ex b/lib/pleroma/web/controller_helper.ex
index e90bf842e..83b884ba9 100644
--- a/lib/pleroma/web/controller_helper.ex
+++ b/lib/pleroma/web/controller_helper.ex
@@ -68,4 +68,11 @@ def add_link_headers(conn, activities, extra_params \\ %{}) do
conn
end
end
+
+ def assign_account_by_id(%{params: %{"id" => id}} = conn, _) do
+ case Pleroma.User.get_cached_by_id(id) do
+ %Pleroma.User{} = account -> assign(conn, :account, account)
+ nil -> Pleroma.Web.MastodonAPI.FallbackController.call(conn, {:error, :not_found}) |> halt()
+ end
+ end
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
new file mode 100644
index 000000000..df14ad66f
--- /dev/null
+++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex
@@ -0,0 +1,304 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.AccountController do
+ use Pleroma.Web, :controller
+
+ import Pleroma.Web.ControllerHelper,
+ only: [add_link_headers: 2, truthy_param?: 1, assign_account_by_id: 2, json_response: 3]
+
+ alias Pleroma.Emoji
+ alias Pleroma.Plugs.RateLimiter
+ alias Pleroma.User
+ alias Pleroma.Web.ActivityPub.ActivityPub
+ alias Pleroma.Web.CommonAPI
+ alias Pleroma.Web.MastodonAPI.ListView
+ alias Pleroma.Web.MastodonAPI.MastodonAPI
+ alias Pleroma.Web.MastodonAPI.StatusView
+ alias Pleroma.Web.OAuth.Token
+ alias Pleroma.Web.TwitterAPI.TwitterAPI
+
+ @relations [:follow, :unfollow]
+ @needs_account ~W(followers following lists follow unfollow mute unmute block unblock)a
+
+ plug(RateLimiter, {:relations_id_action, params: ["id", "uri"]} when action in @relations)
+ plug(RateLimiter, :relations_actions when action in @relations)
+ plug(RateLimiter, :app_account_creation when action == :create)
+ plug(:assign_account_by_id when action in @needs_account)
+
+ action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
+
+ @doc "POST /api/v1/accounts"
+ def create(
+ %{assigns: %{app: app}} = conn,
+ %{"username" => nickname, "email" => _, "password" => _, "agreement" => true} = params
+ ) do
+ params =
+ params
+ |> Map.take([
+ "email",
+ "captcha_solution",
+ "captcha_token",
+ "captcha_answer_data",
+ "token",
+ "password"
+ ])
+ |> Map.put("nickname", nickname)
+ |> Map.put("fullname", params["fullname"] || nickname)
+ |> Map.put("bio", params["bio"] || "")
+ |> Map.put("confirm", params["password"])
+
+ with {:ok, user} <- TwitterAPI.register_user(params, need_confirmation: true),
+ {:ok, token} <- Token.create_token(app, user, %{scopes: app.scopes}) do
+ json(conn, %{
+ token_type: "Bearer",
+ access_token: token.token,
+ scope: app.scopes,
+ created_at: Token.Utils.format_created_at(token)
+ })
+ else
+ {:error, errors} -> json_response(conn, :bad_request, errors)
+ end
+ end
+
+ def create(%{assigns: %{app: _app}} = conn, _) do
+ render_error(conn, :bad_request, "Missing parameters")
+ end
+
+ def create(conn, _) do
+ render_error(conn, :forbidden, "Invalid credentials")
+ end
+
+ @doc "GET /api/v1/accounts/verify_credentials"
+ def verify_credentials(%{assigns: %{user: user}} = conn, _) do
+ chat_token = Phoenix.Token.sign(conn, "user socket", user.id)
+
+ render(conn, "show.json",
+ user: user,
+ for: user,
+ with_pleroma_settings: true,
+ with_chat_token: chat_token
+ )
+ end
+
+ @doc "PATCH /api/v1/accounts/update_credentials"
+ def update_credentials(%{assigns: %{user: original_user}} = conn, params) do
+ user = original_user
+
+ user_params =
+ %{}
+ |> add_if_present(params, "display_name", :name)
+ |> add_if_present(params, "note", :bio, fn value -> {:ok, User.parse_bio(value, user)} end)
+ |> add_if_present(params, "avatar", :avatar, fn value ->
+ with %Plug.Upload{} <- value,
+ {:ok, object} <- ActivityPub.upload(value, type: :avatar) do
+ {:ok, object.data}
+ end
+ end)
+
+ emojis_text = (user_params["display_name"] || "") <> (user_params["note"] || "")
+
+ user_info_emojis =
+ user.info
+ |> Map.get(:emoji, [])
+ |> Enum.concat(Emoji.Formatter.get_emoji_map(emojis_text))
+ |> Enum.dedup()
+
+ info_params =
+ [
+ :no_rich_text,
+ :locked,
+ :hide_followers_count,
+ :hide_follows_count,
+ :hide_followers,
+ :hide_follows,
+ :hide_favorites,
+ :show_role,
+ :skip_thread_containment,
+ :discoverable
+ ]
+ |> Enum.reduce(%{}, fn key, acc ->
+ add_if_present(acc, params, to_string(key), key, &{:ok, truthy_param?(&1)})
+ end)
+ |> add_if_present(params, "default_scope", :default_scope)
+ |> add_if_present(params, "fields", :fields, fn fields ->
+ fields = Enum.map(fields, fn f -> Map.update!(f, "value", &AutoLinker.link(&1)) end)
+
+ {:ok, fields}
+ end)
+ |> add_if_present(params, "fields", :raw_fields)
+ |> add_if_present(params, "pleroma_settings_store", :pleroma_settings_store, fn value ->
+ {:ok, Map.merge(user.info.pleroma_settings_store, value)}
+ end)
+ |> add_if_present(params, "header", :banner, fn value ->
+ with %Plug.Upload{} <- value,
+ {:ok, object} <- ActivityPub.upload(value, type: :banner) do
+ {:ok, object.data}
+ end
+ end)
+ |> add_if_present(params, "pleroma_background_image", :background, fn value ->
+ with %Plug.Upload{} <- value,
+ {:ok, object} <- ActivityPub.upload(value, type: :background) do
+ {:ok, object.data}
+ end
+ end)
+ |> Map.put(:emoji, user_info_emojis)
+
+ changeset =
+ user
+ |> User.update_changeset(user_params)
+ |> User.change_info(&User.Info.profile_update(&1, info_params))
+
+ with {:ok, user} <- User.update_and_set_cache(changeset) do
+ if original_user != user, do: CommonAPI.update(user)
+
+ render(conn, "show.json", user: user, for: user, with_pleroma_settings: true)
+ else
+ _e -> render_error(conn, :forbidden, "Invalid request")
+ end
+ end
+
+ defp add_if_present(map, params, params_field, map_field, value_function \\ &{:ok, &1}) do
+ with true <- Map.has_key?(params, params_field),
+ {:ok, new_value} <- value_function.(params[params_field]) do
+ Map.put(map, map_field, new_value)
+ else
+ _ -> map
+ end
+ end
+
+ @doc "GET /api/v1/accounts/relationships"
+ def relationships(%{assigns: %{user: user}} = conn, %{"id" => id}) do
+ targets = User.get_all_by_ids(List.wrap(id))
+
+ render(conn, "relationships.json", user: user, targets: targets)
+ end
+
+ # 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, [])
+
+ @doc "GET /api/v1/accounts/:id"
+ def show(%{assigns: %{user: for_user}} = conn, %{"id" => nickname_or_id}) do
+ with %User{} = user <- User.get_cached_by_nickname_or_id(nickname_or_id, for: for_user),
+ true <- User.auth_active?(user) || user.id == for_user.id || User.superuser?(for_user) do
+ render(conn, "show.json", user: user, for: for_user)
+ else
+ _e -> render_error(conn, :not_found, "Can't find user")
+ end
+ end
+
+ @doc "GET /api/v1/accounts/:id/statuses"
+ def statuses(%{assigns: %{user: reading_user}} = conn, params) do
+ with %User{} = user <- User.get_cached_by_nickname_or_id(params["id"], for: reading_user) do
+ params = Map.put(params, "tag", params["tagged"])
+ activities = ActivityPub.fetch_user_activities(user, reading_user, params)
+
+ conn
+ |> add_link_headers(activities)
+ |> put_view(StatusView)
+ |> render("index.json", activities: activities, for: reading_user, as: :activity)
+ end
+ end
+
+ @doc "GET /api/v1/accounts/:id/followers"
+ def followers(%{assigns: %{user: for_user, account: user}} = conn, params) do
+ followers =
+ cond do
+ for_user && user.id == for_user.id -> MastodonAPI.get_followers(user, params)
+ user.info.hide_followers -> []
+ true -> MastodonAPI.get_followers(user, params)
+ end
+
+ conn
+ |> add_link_headers(followers)
+ |> render("index.json", for: for_user, users: followers, as: :user)
+ end
+
+ @doc "GET /api/v1/accounts/:id/following"
+ def following(%{assigns: %{user: for_user, account: user}} = conn, params) do
+ followers =
+ cond do
+ for_user && user.id == for_user.id -> MastodonAPI.get_friends(user, params)
+ user.info.hide_follows -> []
+ true -> MastodonAPI.get_friends(user, params)
+ end
+
+ conn
+ |> add_link_headers(followers)
+ |> render("index.json", for: for_user, users: followers, as: :user)
+ end
+
+ @doc "GET /api/v1/accounts/:id/lists"
+ def lists(%{assigns: %{user: user, account: account}} = conn, _params) do
+ lists = Pleroma.List.get_lists_account_belongs(user, account)
+
+ conn
+ |> put_view(ListView)
+ |> render("index.json", lists: lists)
+ end
+
+ @doc "POST /api/v1/accounts/:id/follow"
+ def follow(%{assigns: %{user: %{id: id}, account: %{id: id}}}, _params) do
+ {:error, :not_found}
+ end
+
+ def follow(%{assigns: %{user: follower, account: followed}} = conn, _params) do
+ with {:ok, follower} <- MastodonAPI.follow(follower, followed, conn.params) do
+ render(conn, "relationship.json", user: follower, target: followed)
+ else
+ {:error, message} -> json_response(conn, :forbidden, %{error: message})
+ end
+ end
+
+ @doc "POST /api/v1/accounts/:id/unfollow"
+ def unfollow(%{assigns: %{user: %{id: id}, account: %{id: id}}}, _params) do
+ {:error, :not_found}
+ end
+
+ def unfollow(%{assigns: %{user: follower, account: followed}} = conn, _params) do
+ with {:ok, follower} <- CommonAPI.unfollow(follower, followed) do
+ render(conn, "relationship.json", user: follower, target: followed)
+ end
+ end
+
+ @doc "POST /api/v1/accounts/:id/mute"
+ def mute(%{assigns: %{user: muter, account: muted}} = conn, params) do
+ notifications? = params |> Map.get("notifications", true) |> truthy_param?()
+
+ with {:ok, muter} <- User.mute(muter, muted, notifications?) do
+ render(conn, "relationship.json", user: muter, target: muted)
+ else
+ {:error, message} -> json_response(conn, :forbidden, %{error: message})
+ end
+ end
+
+ @doc "POST /api/v1/accounts/:id/unmute"
+ def unmute(%{assigns: %{user: muter, account: muted}} = conn, _params) do
+ with {:ok, muter} <- User.unmute(muter, muted) do
+ render(conn, "relationship.json", user: muter, target: muted)
+ else
+ {:error, message} -> json_response(conn, :forbidden, %{error: message})
+ end
+ end
+
+ @doc "POST /api/v1/accounts/:id/block"
+ def block(%{assigns: %{user: blocker, account: blocked}} = conn, _params) do
+ with {:ok, blocker} <- User.block(blocker, blocked),
+ {:ok, _activity} <- ActivityPub.block(blocker, blocked) do
+ render(conn, "relationship.json", user: blocker, target: blocked)
+ else
+ {:error, message} -> json_response(conn, :forbidden, %{error: message})
+ end
+ end
+
+ @doc "POST /api/v1/accounts/:id/unblock"
+ def unblock(%{assigns: %{user: blocker, account: blocked}} = conn, _params) do
+ with {:ok, blocker} <- User.unblock(blocker, blocked),
+ {:ok, _activity} <- ActivityPub.unblock(blocker, blocked) do
+ render(conn, "relationship.json", user: blocker, target: blocked)
+ else
+ {:error, message} -> json_response(conn, :forbidden, %{error: message})
+ end
+ end
+end
diff --git a/lib/pleroma/web/mastodon_api/controllers/follow_request_controller.ex b/lib/pleroma/web/mastodon_api/controllers/follow_request_controller.ex
index 267014b97..ce7b625ee 100644
--- a/lib/pleroma/web/mastodon_api/controllers/follow_request_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/follow_request_controller.ex
@@ -17,7 +17,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestController do
def index(%{assigns: %{user: followed}} = conn, _params) do
follow_requests = User.get_follow_requests(followed)
- render(conn, "accounts.json", for: followed, users: follow_requests, as: :user)
+ render(conn, "index.json", for: followed, users: follow_requests, as: :user)
end
@doc "POST /api/v1/follow_requests/:id/authorize"
diff --git a/lib/pleroma/web/mastodon_api/controllers/list_controller.ex b/lib/pleroma/web/mastodon_api/controllers/list_controller.ex
index 2873deda8..50f42bee5 100644
--- a/lib/pleroma/web/mastodon_api/controllers/list_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/list_controller.ex
@@ -49,7 +49,7 @@ def list_accounts(%{assigns: %{user: user, list: list}} = conn, _) do
with {:ok, users} <- Pleroma.List.get_following(list) do
conn
|> put_view(AccountView)
- |> render("accounts.json", for: user, users: users, as: :user)
+ |> render("index.json", for: user, users: users, as: :user)
end
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex
index 3bdcea0f7..30a2bf0e0 100644
--- a/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex
@@ -5,14 +5,11 @@
defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
use Pleroma.Web, :controller
- import Pleroma.Web.ControllerHelper,
- only: [json_response: 3, add_link_headers: 2, truthy_param?: 1]
+ import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
- alias Ecto.Changeset
alias Pleroma.Activity
alias Pleroma.Bookmark
alias Pleroma.Config
- alias Pleroma.Emoji
alias Pleroma.HTTP
alias Pleroma.Object
alias Pleroma.Pagination
@@ -26,8 +23,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.AppView
- alias Pleroma.Web.MastodonAPI.ListView
- alias Pleroma.Web.MastodonAPI.MastodonAPI
alias Pleroma.Web.MastodonAPI.MastodonView
alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.MediaProxy
@@ -38,20 +33,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
alias Pleroma.Web.TwitterAPI.TwitterAPI
require Logger
- require Pleroma.Constants
- @rate_limited_relations_actions ~w(follow unfollow)a
-
- plug(
- RateLimiter,
- {:relations_id_action, params: ["id", "uri"]} when action in @rate_limited_relations_actions
- )
-
- plug(RateLimiter, :relations_actions when action in @rate_limited_relations_actions)
- plug(RateLimiter, :app_account_creation when action == :account_register)
- plug(RateLimiter, :search when action in [:search, :search2, :account_search])
plug(RateLimiter, :password_reset when action == :password_reset)
- plug(RateLimiter, :account_confirmation_resend when action == :account_confirmation_resend)
@local_mastodon_name "Mastodon-Local"
@@ -74,180 +57,6 @@ def create_app(conn, params) do
end
end
- defp add_if_present(
- map,
- params,
- params_field,
- map_field,
- value_function \\ fn x -> {:ok, x} end
- ) do
- if Map.has_key?(params, params_field) do
- case value_function.(params[params_field]) do
- {:ok, new_value} -> Map.put(map, map_field, new_value)
- :error -> map
- end
- else
- map
- end
- end
-
- def update_credentials(%{assigns: %{user: user}} = conn, params) do
- original_user = user
-
- user_params =
- %{}
- |> add_if_present(params, "display_name", :name)
- |> add_if_present(params, "note", :bio, fn value -> {:ok, User.parse_bio(value, user)} end)
- |> add_if_present(params, "avatar", :avatar, fn value ->
- with %Plug.Upload{} <- value,
- {:ok, object} <- ActivityPub.upload(value, type: :avatar) do
- {:ok, object.data}
- else
- _ -> :error
- end
- end)
-
- emojis_text = (user_params["display_name"] || "") <> (user_params["note"] || "")
-
- user_info_emojis =
- user.info
- |> Map.get(:emoji, [])
- |> Enum.concat(Emoji.Formatter.get_emoji_map(emojis_text))
- |> Enum.dedup()
-
- info_params =
- [
- :no_rich_text,
- :locked,
- :hide_followers_count,
- :hide_follows_count,
- :hide_followers,
- :hide_follows,
- :hide_favorites,
- :show_role,
- :skip_thread_containment,
- :discoverable
- ]
- |> Enum.reduce(%{}, fn key, acc ->
- add_if_present(acc, params, to_string(key), key, fn value ->
- {:ok, truthy_param?(value)}
- end)
- end)
- |> add_if_present(params, "default_scope", :default_scope)
- |> add_if_present(params, "fields", :fields, fn fields ->
- fields = Enum.map(fields, fn f -> Map.update!(f, "value", &AutoLinker.link(&1)) end)
-
- {:ok, fields}
- end)
- |> add_if_present(params, "fields", :raw_fields)
- |> add_if_present(params, "pleroma_settings_store", :pleroma_settings_store, fn value ->
- {:ok, Map.merge(user.info.pleroma_settings_store, value)}
- end)
- |> add_if_present(params, "header", :banner, fn value ->
- with %Plug.Upload{} <- value,
- {:ok, object} <- ActivityPub.upload(value, type: :banner) do
- {:ok, object.data}
- else
- _ -> :error
- end
- end)
- |> add_if_present(params, "pleroma_background_image", :background, fn value ->
- with %Plug.Upload{} <- value,
- {:ok, object} <- ActivityPub.upload(value, type: :background) do
- {:ok, object.data}
- else
- _ -> :error
- end
- end)
- |> Map.put(:emoji, user_info_emojis)
-
- changeset =
- user
- |> User.update_changeset(user_params)
- |> User.change_info(&User.Info.profile_update(&1, info_params))
-
- with {:ok, user} <- User.update_and_set_cache(changeset) do
- if original_user != user, do: CommonAPI.update(user)
-
- json(
- conn,
- AccountView.render("account.json", %{user: user, for: user, with_pleroma_settings: true})
- )
- else
- _e -> render_error(conn, :forbidden, "Invalid request")
- end
- end
-
- def update_avatar(%{assigns: %{user: user}} = conn, %{"img" => ""}) do
- change = Changeset.change(user, %{avatar: nil})
- {:ok, user} = User.update_and_set_cache(change)
- CommonAPI.update(user)
-
- json(conn, %{url: nil})
- end
-
- def update_avatar(%{assigns: %{user: user}} = conn, params) do
- {:ok, object} = ActivityPub.upload(params, type: :avatar)
- change = Changeset.change(user, %{avatar: object.data})
- {:ok, user} = User.update_and_set_cache(change)
- CommonAPI.update(user)
- %{"url" => [%{"href" => href} | _]} = object.data
-
- json(conn, %{url: href})
- end
-
- def update_banner(%{assigns: %{user: user}} = conn, %{"banner" => ""}) do
- new_info = %{"banner" => %{}}
-
- with {:ok, user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
- CommonAPI.update(user)
- json(conn, %{url: nil})
- end
- end
-
- def update_banner(%{assigns: %{user: user}} = conn, params) do
- with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner),
- new_info <- %{"banner" => object.data},
- {:ok, user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
- CommonAPI.update(user)
- %{"url" => [%{"href" => href} | _]} = object.data
-
- json(conn, %{url: href})
- end
- end
-
- def update_background(%{assigns: %{user: user}} = conn, %{"img" => ""}) do
- new_info = %{"background" => %{}}
-
- with {:ok, _user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
- json(conn, %{url: nil})
- end
- end
-
- def update_background(%{assigns: %{user: user}} = conn, params) do
- with {:ok, object} <- ActivityPub.upload(params, type: :background),
- new_info <- %{"background" => object.data},
- {:ok, _user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
- %{"url" => [%{"href" => href} | _]} = object.data
-
- json(conn, %{url: href})
- end
- end
-
- def verify_credentials(%{assigns: %{user: user}} = conn, _) do
- chat_token = Phoenix.Token.sign(conn, "user socket", user.id)
-
- account =
- AccountView.render("account.json", %{
- user: user,
- for: user,
- with_pleroma_settings: true,
- with_chat_token: chat_token
- })
-
- json(conn, account)
- end
-
def verify_app_credentials(%{assigns: %{user: _user, token: token}} = conn, _) do
with %Token{app: %App{} = app} <- Repo.preload(token, :app) do
conn
@@ -256,16 +65,6 @@ def verify_app_credentials(%{assigns: %{user: _user, token: token}} = conn, _) d
end
end
- def user(%{assigns: %{user: for_user}} = conn, %{"id" => nickname_or_id}) do
- with %User{} = user <- User.get_cached_by_nickname_or_id(nickname_or_id, for: for_user),
- true <- User.auth_active?(user) || user.id == for_user.id || User.superuser?(for_user) do
- account = AccountView.render("account.json", %{user: user, for: for_user})
- json(conn, account)
- else
- _e -> render_error(conn, :not_found, "Can't find user")
- end
- end
-
@mastodon_api_level "2.7.2"
def masto_instance(conn, _params) do
@@ -318,25 +117,6 @@ def custom_emojis(conn, _params) do
json(conn, mastodon_emoji)
end
- def user_statuses(%{assigns: %{user: reading_user}} = conn, params) do
- with %User{} = user <- User.get_cached_by_nickname_or_id(params["id"], for: reading_user) do
- params =
- params
- |> Map.put("tag", params["tagged"])
-
- activities = ActivityPub.fetch_user_activities(user, reading_user, params)
-
- conn
- |> add_link_headers(activities)
- |> put_view(StatusView)
- |> render("index.json", %{
- activities: activities,
- for: reading_user,
- as: :activity
- })
- end
- end
-
def get_poll(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Object{} = object <- Object.get_by_id_and_maybe_refetch(id, interval: 60),
%Activity{} = activity <- Activity.get_create_by_object_ap_id(object.data["id"]),
@@ -387,17 +167,6 @@ def poll_vote(%{assigns: %{user: user}} = conn, %{"id" => id, "choices" => choic
end
end
- def relationships(%{assigns: %{user: user}} = conn, %{"id" => id}) do
- targets = User.get_all_by_ids(List.wrap(id))
-
- conn
- |> put_view(AccountView)
- |> render("relationships.json", %{user: user, targets: targets})
- end
-
- # 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,
%{"id" => id, "description" => description} = _
@@ -453,65 +222,13 @@ def get_mascot(%{assigns: %{user: user}} = conn, _params) do
json(conn, mascot)
end
- def followers(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params) do
- with %User{} = user <- User.get_cached_by_id(id),
- followers <- MastodonAPI.get_followers(user, params) do
- followers =
- cond do
- for_user && user.id == for_user.id -> followers
- user.info.hide_followers -> []
- true -> followers
- end
-
- conn
- |> add_link_headers(followers)
- |> put_view(AccountView)
- |> render("accounts.json", %{for: for_user, users: followers, as: :user})
- end
- end
-
- def following(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params) do
- with %User{} = user <- User.get_cached_by_id(id),
- followers <- MastodonAPI.get_friends(user, params) do
- followers =
- cond do
- for_user && user.id == for_user.id -> followers
- user.info.hide_follows -> []
- true -> followers
- end
-
- conn
- |> add_link_headers(followers)
- |> put_view(AccountView)
- |> render("accounts.json", %{for: for_user, users: followers, as: :user})
- end
- end
-
- def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
- with {_, %User{} = followed} <- {:followed, User.get_cached_by_id(id)},
- {_, true} <- {:followed, follower.id != followed.id},
- {:ok, follower} <- MastodonAPI.follow(follower, followed, conn.params) do
- conn
- |> put_view(AccountView)
- |> render("relationship.json", %{user: follower, target: followed})
- else
- {:followed, _} ->
- {:error, :not_found}
-
- {:error, message} ->
- conn
- |> put_status(:forbidden)
- |> json(%{error: message})
- end
- end
-
- def follow(%{assigns: %{user: follower}} = conn, %{"uri" => uri}) do
+ def follows(%{assigns: %{user: follower}} = conn, %{"uri" => uri}) do
with {_, %User{} = followed} <- {:followed, User.get_cached_by_nickname(uri)},
{_, true} <- {:followed, follower.id != followed.id},
{:ok, follower, followed, _} <- CommonAPI.follow(follower, followed) do
conn
|> put_view(AccountView)
- |> render("account.json", %{user: followed, for: follower})
+ |> render("show.json", %{user: followed, for: follower})
else
{:followed, _} ->
{:error, :not_found}
@@ -523,123 +240,20 @@ def follow(%{assigns: %{user: follower}} = conn, %{"uri" => uri}) do
end
end
- def unfollow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
- with {_, %User{} = followed} <- {:followed, User.get_cached_by_id(id)},
- {_, true} <- {:followed, follower.id != followed.id},
- {:ok, follower} <- CommonAPI.unfollow(follower, followed) do
- conn
- |> put_view(AccountView)
- |> render("relationship.json", %{user: follower, target: followed})
- else
- {:followed, _} ->
- {:error, :not_found}
-
- error ->
- error
- end
- end
-
- def mute(%{assigns: %{user: muter}} = conn, %{"id" => id} = params) do
- notifications =
- if Map.has_key?(params, "notifications"),
- do: params["notifications"] in [true, "True", "true", "1"],
- else: true
-
- with %User{} = muted <- User.get_cached_by_id(id),
- {:ok, muter} <- User.mute(muter, muted, notifications) do
- conn
- |> put_view(AccountView)
- |> render("relationship.json", %{user: muter, target: muted})
- else
- {:error, message} ->
- conn
- |> put_status(:forbidden)
- |> json(%{error: message})
- end
- end
-
- def unmute(%{assigns: %{user: muter}} = conn, %{"id" => id}) do
- with %User{} = muted <- User.get_cached_by_id(id),
- {:ok, muter} <- User.unmute(muter, muted) do
- conn
- |> put_view(AccountView)
- |> render("relationship.json", %{user: muter, target: muted})
- else
- {:error, message} ->
- conn
- |> put_status(:forbidden)
- |> json(%{error: message})
- end
- end
-
def mutes(%{assigns: %{user: user}} = conn, _) do
with muted_accounts <- User.muted_users(user) do
- res = AccountView.render("accounts.json", users: muted_accounts, for: user, as: :user)
+ res = AccountView.render("index.json", users: muted_accounts, for: user, as: :user)
json(conn, res)
end
end
- def block(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do
- with %User{} = blocked <- User.get_cached_by_id(id),
- {:ok, blocker} <- User.block(blocker, blocked),
- {:ok, _activity} <- ActivityPub.block(blocker, blocked) do
- conn
- |> put_view(AccountView)
- |> render("relationship.json", %{user: blocker, target: blocked})
- else
- {:error, message} ->
- conn
- |> put_status(:forbidden)
- |> json(%{error: message})
- end
- end
-
- def unblock(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do
- with %User{} = blocked <- User.get_cached_by_id(id),
- {:ok, blocker} <- User.unblock(blocker, blocked),
- {:ok, _activity} <- ActivityPub.unblock(blocker, blocked) do
- conn
- |> put_view(AccountView)
- |> render("relationship.json", %{user: blocker, target: blocked})
- else
- {:error, message} ->
- conn
- |> put_status(:forbidden)
- |> json(%{error: message})
- end
- end
-
def blocks(%{assigns: %{user: user}} = conn, _) do
with blocked_accounts <- User.blocked_users(user) do
- res = AccountView.render("accounts.json", users: blocked_accounts, for: user, as: :user)
+ res = AccountView.render("index.json", users: blocked_accounts, for: user, as: :user)
json(conn, res)
end
end
- def subscribe(%{assigns: %{user: user}} = conn, %{"id" => id}) do
- with %User{} = subscription_target <- User.get_cached_by_id(id),
- {:ok, subscription_target} = User.subscribe(user, subscription_target) do
- conn
- |> put_view(AccountView)
- |> render("relationship.json", %{user: user, target: subscription_target})
- else
- nil -> {:error, :not_found}
- e -> e
- end
- end
-
- def unsubscribe(%{assigns: %{user: user}} = conn, %{"id" => id}) do
- with %User{} = subscription_target <- User.get_cached_by_id(id),
- {:ok, subscription_target} = User.unsubscribe(user, subscription_target) do
- conn
- |> put_view(AccountView)
- |> render("relationship.json", %{user: user, target: subscription_target})
- else
- nil -> {:error, :not_found}
- e -> e
- end
- end
-
def favourites(%{assigns: %{user: user}} = conn, params) do
params =
params
@@ -657,37 +271,6 @@ def favourites(%{assigns: %{user: user}} = conn, params) do
|> render("index.json", %{activities: activities, for: user, as: :activity})
end
- def user_favourites(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params) do
- with %User{} = user <- User.get_by_id(id),
- false <- user.info.hide_favorites do
- params =
- params
- |> Map.put("type", "Create")
- |> Map.put("favorited_by", user.ap_id)
- |> Map.put("blocking_user", for_user)
-
- recipients =
- if for_user do
- [Pleroma.Constants.as_public()] ++ [for_user.ap_id | for_user.following]
- else
- [Pleroma.Constants.as_public()]
- end
-
- activities =
- recipients
- |> ActivityPub.fetch_activities(params)
- |> Enum.reverse()
-
- conn
- |> add_link_headers(activities)
- |> put_view(StatusView)
- |> render("index.json", %{activities: activities, for: for_user, as: :activity})
- else
- nil -> {:error, :not_found}
- true -> render_error(conn, :forbidden, "Can't get favorites")
- end
- end
-
def bookmarks(%{assigns: %{user: user}} = conn, params) do
user = User.get_cached_by_id(user.id)
@@ -705,14 +288,6 @@ def bookmarks(%{assigns: %{user: user}} = conn, params) do
|> render("index.json", %{activities: activities, for: user, as: :activity})
end
- def account_lists(%{assigns: %{user: user}} = conn, %{"id" => account_id}) do
- lists = Pleroma.List.get_lists_account_belongs(user, account_id)
-
- conn
- |> put_view(ListView)
- |> render("index.json", %{lists: lists})
- end
-
def index(%{assigns: %{user: user}} = conn, _params) do
token = get_session(conn, :oauth_token)
@@ -721,8 +296,7 @@ def index(%{assigns: %{user: user}} = conn, _params) do
limit = Config.get([:instance, :limit])
- accounts =
- Map.put(%{}, user.id, AccountView.render("account.json", %{user: user, for: user}))
+ accounts = Map.put(%{}, user.id, AccountView.render("show.json", %{user: user, for: user}))
initial_state =
%{
@@ -943,49 +517,6 @@ defp fetch_suggestion_id(attrs) do
end
end
- def account_register(
- %{assigns: %{app: app}} = conn,
- %{"username" => nickname, "email" => _, "password" => _, "agreement" => true} = params
- ) do
- params =
- params
- |> Map.take([
- "email",
- "captcha_solution",
- "captcha_token",
- "captcha_answer_data",
- "token",
- "password"
- ])
- |> Map.put("nickname", nickname)
- |> Map.put("fullname", params["fullname"] || nickname)
- |> Map.put("bio", params["bio"] || "")
- |> Map.put("confirm", params["password"])
-
- with {:ok, user} <- TwitterAPI.register_user(params, need_confirmation: true),
- {:ok, token} <- Token.create_token(app, user, %{scopes: app.scopes}) do
- json(conn, %{
- token_type: "Bearer",
- access_token: token.token,
- scope: app.scopes,
- created_at: Token.Utils.format_created_at(token)
- })
- else
- {:error, errors} ->
- conn
- |> put_status(:bad_request)
- |> json(errors)
- end
- end
-
- def account_register(%{assigns: %{app: _app}} = conn, _) do
- render_error(conn, :bad_request, "Missing parameters")
- end
-
- def account_register(conn, _) do
- render_error(conn, :forbidden, "Invalid credentials")
- end
-
def password_reset(conn, params) do
nickname_or_email = params["email"] || params["nickname"]
@@ -1002,16 +533,6 @@ def password_reset(conn, params) do
end
end
- def account_confirmation_resend(conn, params) do
- nickname_or_email = params["email"] || params["nickname"]
-
- with %User{} = user <- User.get_by_nickname_or_email(nickname_or_email),
- {:ok, _} <- User.try_send_confirmation_email(user) do
- conn
- |> json_response(:no_content, "")
- end
- end
-
def try_render(conn, target, params)
when is_binary(target) do
case render(conn, target, params) do
diff --git a/lib/pleroma/web/mastodon_api/controllers/search_controller.ex b/lib/pleroma/web/mastodon_api/controllers/search_controller.ex
index c91713773..3fc89d645 100644
--- a/lib/pleroma/web/mastodon_api/controllers/search_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/search_controller.ex
@@ -22,7 +22,7 @@ def account_search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) d
conn
|> put_view(AccountView)
- |> render("accounts.json", users: accounts, for: user, as: :user)
+ |> render("index.json", users: accounts, for: user, as: :user)
end
def search2(conn, params), do: do_search(:v2, conn, params)
@@ -72,7 +72,7 @@ defp search_options(params, user) do
defp resource_search(_, "accounts", query, options) do
accounts = with_fallback(fn -> User.search(query, options) end)
- AccountView.render("accounts.json", users: accounts, for: options[:for_user], as: :user)
+ AccountView.render("index.json", users: accounts, for: options[:for_user], as: :user)
end
defp resource_search(_, "statuses", query, options) do
diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
index f4de9285b..3c6987a5f 100644
--- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex
@@ -231,7 +231,7 @@ def favourited_by(%{assigns: %{user: user}} = conn, %{"id" => id}) do
conn
|> put_view(AccountView)
- |> render("accounts.json", for: user, users: users, as: :user)
+ |> render("index.json", for: user, users: users, as: :user)
else
{:visible, false} -> {:error, :not_found}
_ -> json(conn, [])
@@ -251,7 +251,7 @@ def reblogged_by(%{assigns: %{user: user}} = conn, %{"id" => id}) do
conn
|> put_view(AccountView)
- |> render("accounts.json", for: user, users: users, as: :user)
+ |> render("index.json", for: user, users: users, as: :user)
else
{:visible, false} -> {:error, :not_found}
_ -> json(conn, [])
diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex
index 8cf9e9d5c..99169ef95 100644
--- a/lib/pleroma/web/mastodon_api/views/account_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/account_view.ex
@@ -11,15 +11,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MediaProxy
- def render("accounts.json", %{users: users} = opts) do
+ def render("index.json", %{users: users} = opts) do
users
- |> render_many(AccountView, "account.json", opts)
+ |> render_many(AccountView, "show.json", opts)
|> Enum.filter(&Enum.any?/1)
end
- def render("account.json", %{user: user} = opts) do
+ def render("show.json", %{user: user} = opts) do
if User.visible_for?(user, opts[:for]),
- do: do_render("account.json", opts),
+ do: do_render("show.json", opts),
else: %{}
end
@@ -66,7 +66,7 @@ def render("relationships.json", %{user: user, targets: targets}) do
render_many(targets, AccountView, "relationship.json", user: user, as: :target)
end
- defp do_render("account.json", %{user: user} = opts) do
+ defp do_render("show.json", %{user: user} = opts) do
display_name = HTML.strip_tags(user.name || user.nickname)
image = User.avatar_url(user) |> MediaProxy.url()
diff --git a/lib/pleroma/web/mastodon_api/views/conversation_view.ex b/lib/pleroma/web/mastodon_api/views/conversation_view.ex
index 2c5767dd8..e9d2735b3 100644
--- a/lib/pleroma/web/mastodon_api/views/conversation_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/conversation_view.ex
@@ -32,7 +32,7 @@ def render("participation.json", %{participation: participation, for: user}) do
%{
id: participation.id |> to_string(),
- accounts: render(AccountView, "accounts.json", users: users, as: :user),
+ accounts: render(AccountView, "index.json", users: users, as: :user),
unread: !participation.read,
last_status: render(StatusView, "show.json", activity: activity, for: user)
}
diff --git a/lib/pleroma/web/mastodon_api/views/notification_view.ex b/lib/pleroma/web/mastodon_api/views/notification_view.ex
index 05110a192..60b58dc90 100644
--- a/lib/pleroma/web/mastodon_api/views/notification_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/notification_view.ex
@@ -29,7 +29,7 @@ def render("show.json", %{
id: to_string(notification.id),
type: mastodon_type,
created_at: CommonAPI.Utils.to_masto_date(notification.inserted_at),
- account: AccountView.render("account.json", %{user: actor, for: user}),
+ account: AccountView.render("show.json", %{user: actor, for: user}),
pleroma: %{
is_seen: notification.seen
}
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index d398f7853..bc527ad1b 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -108,7 +108,7 @@ def render(
id: to_string(activity.id),
uri: activity_object.data["id"],
url: activity_object.data["id"],
- account: AccountView.render("account.json", %{user: user, for: opts[:for]}),
+ account: AccountView.render("show.json", %{user: user, for: opts[:for]}),
in_reply_to_id: nil,
in_reply_to_account_id: nil,
reblog: reblogged,
@@ -258,7 +258,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
id: to_string(activity.id),
uri: object.data["id"],
url: url,
- account: AccountView.render("account.json", %{user: user, for: opts[:for]}),
+ account: AccountView.render("show.json", %{user: user, for: opts[:for]}),
in_reply_to_id: reply_to && to_string(reply_to.id),
in_reply_to_account_id: reply_to_user && to_string(reply_to_user.id),
reblog: nil,
@@ -376,7 +376,7 @@ def render("listen.json", %{activity: %Activity{data: %{"type" => "Listen"}} = a
%{
id: activity.id,
- account: AccountView.render("account.json", %{user: user, for: opts[:for]}),
+ account: AccountView.render("show.json", %{user: user, for: opts[:for]}),
created_at: created_at,
title: object.data["title"] |> HTML.strip_tags(),
artist: object.data["artist"] |> HTML.strip_tags(),
diff --git a/lib/pleroma/web/pleroma_api/controllers/account_controller.ex b/lib/pleroma/web/pleroma_api/controllers/account_controller.ex
new file mode 100644
index 000000000..63c44086c
--- /dev/null
+++ b/lib/pleroma/web/pleroma_api/controllers/account_controller.ex
@@ -0,0 +1,143 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.PleromaAPI.AccountController do
+ use Pleroma.Web, :controller
+
+ import Pleroma.Web.ControllerHelper,
+ only: [json_response: 3, add_link_headers: 2, assign_account_by_id: 2]
+
+ alias Ecto.Changeset
+ alias Pleroma.Plugs.RateLimiter
+ alias Pleroma.User
+ alias Pleroma.Web.ActivityPub.ActivityPub
+ alias Pleroma.Web.CommonAPI
+ alias Pleroma.Web.MastodonAPI.StatusView
+
+ require Pleroma.Constants
+
+ plug(RateLimiter, :account_confirmation_resend when action == :confirmation_resend)
+ plug(:assign_account_by_id when action in [:favourites, :subscribe, :unsubscribe])
+ plug(:put_view, Pleroma.Web.MastodonAPI.AccountView)
+
+ @doc "POST /api/v1/pleroma/accounts/confirmation_resend"
+ def confirmation_resend(conn, params) do
+ nickname_or_email = params["email"] || params["nickname"]
+
+ with %User{} = user <- User.get_by_nickname_or_email(nickname_or_email),
+ {:ok, _} <- User.try_send_confirmation_email(user) do
+ json_response(conn, :no_content, "")
+ end
+ end
+
+ @doc "PATCH /api/v1/pleroma/accounts/update_avatar"
+ def update_avatar(%{assigns: %{user: user}} = conn, %{"img" => ""}) do
+ {:ok, user} =
+ user
+ |> Changeset.change(%{avatar: nil})
+ |> User.update_and_set_cache()
+
+ CommonAPI.update(user)
+
+ json(conn, %{url: nil})
+ end
+
+ def update_avatar(%{assigns: %{user: user}} = conn, params) do
+ {:ok, %{data: data}} = ActivityPub.upload(params, type: :avatar)
+ {:ok, user} = user |> Changeset.change(%{avatar: data}) |> User.update_and_set_cache()
+ %{"url" => [%{"href" => href} | _]} = data
+
+ CommonAPI.update(user)
+
+ json(conn, %{url: href})
+ end
+
+ @doc "PATCH /api/v1/pleroma/accounts/update_banner"
+ def update_banner(%{assigns: %{user: user}} = conn, %{"banner" => ""}) do
+ new_info = %{"banner" => %{}}
+
+ with {:ok, user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
+ CommonAPI.update(user)
+ json(conn, %{url: nil})
+ end
+ end
+
+ def update_banner(%{assigns: %{user: user}} = conn, params) do
+ with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner),
+ new_info <- %{"banner" => object.data},
+ {:ok, user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
+ CommonAPI.update(user)
+ %{"url" => [%{"href" => href} | _]} = object.data
+
+ json(conn, %{url: href})
+ end
+ end
+
+ @doc "PATCH /api/v1/pleroma/accounts/update_background"
+ def update_background(%{assigns: %{user: user}} = conn, %{"img" => ""}) do
+ new_info = %{"background" => %{}}
+
+ with {:ok, _user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
+ json(conn, %{url: nil})
+ end
+ end
+
+ def update_background(%{assigns: %{user: user}} = conn, params) do
+ with {:ok, object} <- ActivityPub.upload(params, type: :background),
+ new_info <- %{"background" => object.data},
+ {:ok, _user} <- User.update_info(user, &User.Info.profile_update(&1, new_info)) do
+ %{"url" => [%{"href" => href} | _]} = object.data
+
+ json(conn, %{url: href})
+ end
+ end
+
+ @doc "GET /api/v1/pleroma/accounts/:id/favourites"
+ def favourites(%{assigns: %{account: %{info: %{hide_favorites: true}}}} = conn, _params) do
+ render_error(conn, :forbidden, "Can't get favorites")
+ end
+
+ def favourites(%{assigns: %{user: for_user, account: user}} = conn, params) do
+ params =
+ params
+ |> Map.put("type", "Create")
+ |> Map.put("favorited_by", user.ap_id)
+ |> Map.put("blocking_user", for_user)
+
+ recipients =
+ if for_user do
+ [Pleroma.Constants.as_public()] ++ [for_user.ap_id | for_user.following]
+ else
+ [Pleroma.Constants.as_public()]
+ end
+
+ activities =
+ recipients
+ |> ActivityPub.fetch_activities(params)
+ |> Enum.reverse()
+
+ conn
+ |> add_link_headers(activities)
+ |> put_view(StatusView)
+ |> render("index.json", activities: activities, for: for_user, as: :activity)
+ end
+
+ @doc "POST /api/v1/pleroma/accounts/:id/subscribe"
+ def subscribe(%{assigns: %{user: user, account: subscription_target}} = conn, _params) do
+ with {:ok, subscription_target} <- User.subscribe(user, subscription_target) do
+ render(conn, "relationship.json", user: user, target: subscription_target)
+ else
+ {:error, message} -> json_response(conn, :forbidden, %{error: message})
+ end
+ end
+
+ @doc "POST /api/v1/pleroma/accounts/:id/unsubscribe"
+ def unsubscribe(%{assigns: %{user: user, account: subscription_target}} = conn, _params) do
+ with {:ok, subscription_target} <- User.unsubscribe(user, subscription_target) do
+ render(conn, "relationship.json", user: user, target: subscription_target)
+ else
+ {:error, message} -> json_response(conn, :forbidden, %{error: message})
+ end
+ end
+end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 9fd13c2fd..f6c74896f 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -287,24 +287,40 @@ defmodule Pleroma.Web.Router do
end
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
- pipe_through(:authenticated_api)
-
scope [] do
+ pipe_through(:authenticated_api)
pipe_through(:oauth_read)
get("/conversations/:id/statuses", PleromaAPIController, :conversation_statuses)
get("/conversations/:id", PleromaAPIController, :conversation)
end
scope [] do
+ pipe_through(:authenticated_api)
pipe_through(:oauth_write)
patch("/conversations/:id", PleromaAPIController, :update_conversation)
post("/notifications/read", PleromaAPIController, :read_notification)
+
+ patch("/accounts/update_avatar", AccountController, :update_avatar)
+ patch("/accounts/update_banner", AccountController, :update_banner)
+ patch("/accounts/update_background", AccountController, :update_background)
+ post("/scrobble", ScrobbleController, :new_scrobble)
end
scope [] do
- pipe_through(:oauth_write)
- post("/scrobble", ScrobbleController, :new_scrobble)
+ pipe_through(:api)
+ pipe_through(:oauth_read_or_public)
+ get("/accounts/:id/favourites", AccountController, :favourites)
end
+
+ scope [] do
+ pipe_through(:authenticated_api)
+ pipe_through(:oauth_follow)
+
+ post("/accounts/:id/subscribe", AccountController, :subscribe)
+ post("/accounts/:id/unsubscribe", AccountController, :unsubscribe)
+ end
+
+ post("/accounts/confirmation_resend", AccountController, :confirmation_resend)
end
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
@@ -319,11 +335,11 @@ defmodule Pleroma.Web.Router do
scope [] do
pipe_through(:oauth_read)
- get("/accounts/verify_credentials", MastodonAPIController, :verify_credentials)
+ get("/accounts/verify_credentials", AccountController, :verify_credentials)
- get("/accounts/relationships", MastodonAPIController, :relationships)
+ get("/accounts/relationships", AccountController, :relationships)
- get("/accounts/:id/lists", MastodonAPIController, :account_lists)
+ get("/accounts/:id/lists", AccountController, :lists)
get("/accounts/:id/identity_proofs", MastodonAPIController, :empty_array)
get("/follow_requests", FollowRequestController, :index)
@@ -364,7 +380,7 @@ defmodule Pleroma.Web.Router do
scope [] do
pipe_through(:oauth_write)
- patch("/accounts/update_credentials", MastodonAPIController, :update_credentials)
+ patch("/accounts/update_credentials", AccountController, :update_credentials)
post("/statuses", StatusController, :create)
delete("/statuses/:id", StatusController, :delete)
@@ -400,10 +416,6 @@ defmodule Pleroma.Web.Router do
put("/filters/:id", FilterController, :update)
delete("/filters/:id", FilterController, :delete)
- patch("/pleroma/accounts/update_avatar", MastodonAPIController, :update_avatar)
- patch("/pleroma/accounts/update_banner", MastodonAPIController, :update_banner)
- patch("/pleroma/accounts/update_background", MastodonAPIController, :update_background)
-
get("/pleroma/mascot", MastodonAPIController, :get_mascot)
put("/pleroma/mascot", MastodonAPIController, :set_mascot)
@@ -413,23 +425,19 @@ defmodule Pleroma.Web.Router do
scope [] do
pipe_through(:oauth_follow)
- post("/follows", MastodonAPIController, :follow)
- post("/accounts/:id/follow", MastodonAPIController, :follow)
-
- post("/accounts/:id/unfollow", MastodonAPIController, :unfollow)
- post("/accounts/:id/block", MastodonAPIController, :block)
- post("/accounts/:id/unblock", MastodonAPIController, :unblock)
- post("/accounts/:id/mute", MastodonAPIController, :mute)
- post("/accounts/:id/unmute", MastodonAPIController, :unmute)
+ post("/follows", MastodonAPIController, :follows)
+ post("/accounts/:id/follow", AccountController, :follow)
+ post("/accounts/:id/unfollow", AccountController, :unfollow)
+ post("/accounts/:id/block", AccountController, :block)
+ post("/accounts/:id/unblock", AccountController, :unblock)
+ post("/accounts/:id/mute", AccountController, :mute)
+ post("/accounts/:id/unmute", AccountController, :unmute)
post("/follow_requests/:id/authorize", FollowRequestController, :authorize)
post("/follow_requests/:id/reject", FollowRequestController, :reject)
post("/domain_blocks", DomainBlockController, :create)
delete("/domain_blocks", DomainBlockController, :delete)
-
- post("/pleroma/accounts/:id/subscribe", MastodonAPIController, :subscribe)
- post("/pleroma/accounts/:id/unsubscribe", MastodonAPIController, :unsubscribe)
end
scope [] do
@@ -451,7 +459,7 @@ defmodule Pleroma.Web.Router do
scope "/api/v1", Pleroma.Web.MastodonAPI do
pipe_through(:api)
- post("/accounts", MastodonAPIController, :account_register)
+ post("/accounts", AccountController, :create)
get("/instance", MastodonAPIController, :masto_instance)
get("/instance/peers", MastodonAPIController, :peers)
@@ -468,12 +476,6 @@ defmodule Pleroma.Web.Router do
get("/accounts/search", SearchController, :account_search)
- post(
- "/pleroma/accounts/confirmation_resend",
- MastodonAPIController,
- :account_confirmation_resend
- )
-
scope [] do
pipe_through(:oauth_read_or_public)
@@ -487,14 +489,12 @@ defmodule Pleroma.Web.Router do
get("/polls/:id", MastodonAPIController, :get_poll)
- get("/accounts/:id/statuses", MastodonAPIController, :user_statuses)
- get("/accounts/:id/followers", MastodonAPIController, :followers)
- get("/accounts/:id/following", MastodonAPIController, :following)
- get("/accounts/:id", MastodonAPIController, :user)
+ get("/accounts/:id/statuses", AccountController, :statuses)
+ get("/accounts/:id/followers", AccountController, :followers)
+ get("/accounts/:id/following", AccountController, :following)
+ get("/accounts/:id", AccountController, :show)
get("/search", SearchController, :search)
-
- get("/pleroma/accounts/:id/favourites", MastodonAPIController, :user_favourites)
end
end
diff --git a/test/list_test.exs b/test/list_test.exs
index ba79251da..e7b23915b 100644
--- a/test/list_test.exs
+++ b/test/list_test.exs
@@ -113,10 +113,10 @@ test "getting own lists a given user belongs to" do
{:ok, not_owned_list} = Pleroma.List.follow(not_owned_list, member_1)
{:ok, not_owned_list} = Pleroma.List.follow(not_owned_list, member_2)
- lists_1 = Pleroma.List.get_lists_account_belongs(owner, member_1.id)
+ lists_1 = Pleroma.List.get_lists_account_belongs(owner, member_1)
assert owned_list in lists_1
refute not_owned_list in lists_1
- lists_2 = Pleroma.List.get_lists_account_belongs(owner, member_2.id)
+ lists_2 = Pleroma.List.get_lists_account_belongs(owner, member_2)
assert owned_list in lists_2
refute not_owned_list in lists_2
end
diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs
index 2c6357fe6..193d6d301 100644
--- a/test/web/activity_pub/transmogrifier_test.exs
+++ b/test/web/activity_pub/transmogrifier_test.exs
@@ -1231,7 +1231,7 @@ test "it can handle Listen activities" do
{:ok, activity} = CommonAPI.listen(user, %{"title" => "lain radio episode 1"})
- {:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
+ {:ok, _modified} = Transmogrifier.prepare_outgoing(activity.data)
end
end
diff --git a/test/web/admin_api/views/report_view_test.exs b/test/web/admin_api/views/report_view_test.exs
index 35b6947a0..475705857 100644
--- a/test/web/admin_api/views/report_view_test.exs
+++ b/test/web/admin_api/views/report_view_test.exs
@@ -21,12 +21,12 @@ test "renders a report" do
content: nil,
actor:
Map.merge(
- AccountView.render("account.json", %{user: user}),
+ AccountView.render("show.json", %{user: user}),
Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user})
),
account:
Map.merge(
- AccountView.render("account.json", %{user: other_user}),
+ AccountView.render("show.json", %{user: other_user}),
Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: other_user})
),
statuses: [],
@@ -53,12 +53,12 @@ test "includes reported statuses" do
content: nil,
actor:
Map.merge(
- AccountView.render("account.json", %{user: user}),
+ AccountView.render("show.json", %{user: user}),
Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user})
),
account:
Map.merge(
- AccountView.render("account.json", %{user: other_user}),
+ AccountView.render("show.json", %{user: other_user}),
Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: other_user})
),
statuses: [StatusView.render("show.json", %{activity: activity})],
diff --git a/test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs
similarity index 100%
rename from test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs
rename to test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs
diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs
new file mode 100644
index 000000000..8c8017838
--- /dev/null
+++ b/test/web/mastodon_api/controllers/account_controller_test.exs
@@ -0,0 +1,852 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
+ use Pleroma.Web.ConnCase
+
+ alias Pleroma.Repo
+ alias Pleroma.User
+ alias Pleroma.Web.ActivityPub.ActivityPub
+ alias Pleroma.Web.CommonAPI
+ alias Pleroma.Web.OAuth.Token
+
+ import Pleroma.Factory
+
+ describe "account fetching" do
+ test "works by id" do
+ user = insert(:user)
+
+ conn =
+ build_conn()
+ |> get("/api/v1/accounts/#{user.id}")
+
+ assert %{"id" => id} = json_response(conn, 200)
+ assert id == to_string(user.id)
+
+ conn =
+ build_conn()
+ |> get("/api/v1/accounts/-1")
+
+ assert %{"error" => "Can't find user"} = json_response(conn, 404)
+ end
+
+ test "works by nickname" do
+ user = insert(:user)
+
+ conn =
+ build_conn()
+ |> get("/api/v1/accounts/#{user.nickname}")
+
+ assert %{"id" => id} = json_response(conn, 200)
+ assert id == user.id
+ end
+
+ test "works by nickname for remote users" do
+ limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
+ Pleroma.Config.put([:instance, :limit_to_local_content], false)
+ user = insert(:user, nickname: "user@example.com", local: false)
+
+ conn =
+ build_conn()
+ |> get("/api/v1/accounts/#{user.nickname}")
+
+ Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
+ assert %{"id" => id} = json_response(conn, 200)
+ assert id == user.id
+ end
+
+ test "respects limit_to_local_content == :all for remote user nicknames" do
+ limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
+ Pleroma.Config.put([:instance, :limit_to_local_content], :all)
+
+ user = insert(:user, nickname: "user@example.com", local: false)
+
+ conn =
+ build_conn()
+ |> get("/api/v1/accounts/#{user.nickname}")
+
+ Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
+ assert json_response(conn, 404)
+ end
+
+ test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do
+ limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
+ Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
+
+ user = insert(:user, nickname: "user@example.com", local: false)
+ reading_user = insert(:user)
+
+ conn =
+ build_conn()
+ |> get("/api/v1/accounts/#{user.nickname}")
+
+ assert json_response(conn, 404)
+
+ conn =
+ build_conn()
+ |> assign(:user, reading_user)
+ |> get("/api/v1/accounts/#{user.nickname}")
+
+ Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
+ assert %{"id" => id} = json_response(conn, 200)
+ assert id == user.id
+ end
+
+ test "accounts fetches correct account for nicknames beginning with numbers", %{conn: conn} do
+ # Need to set an old-style integer ID to reproduce the problem
+ # (these are no longer assigned to new accounts but were preserved
+ # for existing accounts during the migration to flakeIDs)
+ user_one = insert(:user, %{id: 1212})
+ user_two = insert(:user, %{nickname: "#{user_one.id}garbage"})
+
+ resp_one =
+ conn
+ |> get("/api/v1/accounts/#{user_one.id}")
+
+ resp_two =
+ conn
+ |> get("/api/v1/accounts/#{user_two.nickname}")
+
+ resp_three =
+ conn
+ |> get("/api/v1/accounts/#{user_two.id}")
+
+ acc_one = json_response(resp_one, 200)
+ acc_two = json_response(resp_two, 200)
+ acc_three = json_response(resp_three, 200)
+ refute acc_one == acc_two
+ assert acc_two == acc_three
+ end
+ end
+
+ describe "user timelines" do
+ test "gets a users statuses", %{conn: conn} do
+ user_one = insert(:user)
+ user_two = insert(:user)
+ user_three = insert(:user)
+
+ {:ok, user_three} = User.follow(user_three, user_one)
+
+ {:ok, activity} = CommonAPI.post(user_one, %{"status" => "HI!!!"})
+
+ {:ok, direct_activity} =
+ CommonAPI.post(user_one, %{
+ "status" => "Hi, @#{user_two.nickname}.",
+ "visibility" => "direct"
+ })
+
+ {:ok, private_activity} =
+ CommonAPI.post(user_one, %{"status" => "private", "visibility" => "private"})
+
+ resp =
+ conn
+ |> get("/api/v1/accounts/#{user_one.id}/statuses")
+
+ assert [%{"id" => id}] = json_response(resp, 200)
+ assert id == to_string(activity.id)
+
+ resp =
+ conn
+ |> assign(:user, user_two)
+ |> get("/api/v1/accounts/#{user_one.id}/statuses")
+
+ assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
+ assert id_one == to_string(direct_activity.id)
+ assert id_two == to_string(activity.id)
+
+ resp =
+ conn
+ |> assign(:user, user_three)
+ |> get("/api/v1/accounts/#{user_one.id}/statuses")
+
+ assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
+ assert id_one == to_string(private_activity.id)
+ assert id_two == to_string(activity.id)
+ end
+
+ test "unimplemented pinned statuses feature", %{conn: conn} do
+ note = insert(:note_activity)
+ user = User.get_cached_by_ap_id(note.data["actor"])
+
+ conn =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
+
+ assert json_response(conn, 200) == []
+ end
+
+ test "gets an users media", %{conn: conn} do
+ note = insert(:note_activity)
+ user = User.get_cached_by_ap_id(note.data["actor"])
+
+ file = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image.jpg"),
+ filename: "an_image.jpg"
+ }
+
+ {:ok, %{id: media_id}} = ActivityPub.upload(file, actor: user.ap_id)
+
+ {:ok, image_post} = CommonAPI.post(user, %{"status" => "cofe", "media_ids" => [media_id]})
+
+ conn =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "true"})
+
+ assert [%{"id" => id}] = json_response(conn, 200)
+ assert id == to_string(image_post.id)
+
+ conn =
+ build_conn()
+ |> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "1"})
+
+ assert [%{"id" => id}] = json_response(conn, 200)
+ assert id == to_string(image_post.id)
+ end
+
+ test "gets a user's statuses without reblogs", %{conn: conn} do
+ user = insert(:user)
+ {:ok, post} = CommonAPI.post(user, %{"status" => "HI!!!"})
+ {:ok, _, _} = CommonAPI.repeat(post.id, user)
+
+ conn =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "true"})
+
+ assert [%{"id" => id}] = json_response(conn, 200)
+ assert id == to_string(post.id)
+
+ conn =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "1"})
+
+ assert [%{"id" => id}] = json_response(conn, 200)
+ assert id == to_string(post.id)
+ end
+
+ test "filters user's statuses by a hashtag", %{conn: conn} do
+ user = insert(:user)
+ {:ok, post} = CommonAPI.post(user, %{"status" => "#hashtag"})
+ {:ok, _post} = CommonAPI.post(user, %{"status" => "hashtag"})
+
+ conn =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/statuses", %{"tagged" => "hashtag"})
+
+ assert [%{"id" => id}] = json_response(conn, 200)
+ assert id == to_string(post.id)
+ end
+ end
+
+ describe "followers" do
+ test "getting followers", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user)
+ {:ok, user} = User.follow(user, other_user)
+
+ conn =
+ conn
+ |> get("/api/v1/accounts/#{other_user.id}/followers")
+
+ assert [%{"id" => id}] = json_response(conn, 200)
+ assert id == to_string(user.id)
+ end
+
+ test "getting followers, hide_followers", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user, %{info: %{hide_followers: true}})
+ {:ok, _user} = User.follow(user, other_user)
+
+ conn =
+ conn
+ |> get("/api/v1/accounts/#{other_user.id}/followers")
+
+ assert [] == json_response(conn, 200)
+ end
+
+ test "getting followers, hide_followers, same user requesting", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user, %{info: %{hide_followers: true}})
+ {:ok, _user} = User.follow(user, other_user)
+
+ conn =
+ conn
+ |> assign(:user, other_user)
+ |> get("/api/v1/accounts/#{other_user.id}/followers")
+
+ refute [] == json_response(conn, 200)
+ end
+
+ test "getting followers, pagination", %{conn: conn} do
+ user = insert(:user)
+ follower1 = insert(:user)
+ follower2 = insert(:user)
+ follower3 = insert(:user)
+ {:ok, _} = User.follow(follower1, user)
+ {:ok, _} = User.follow(follower2, user)
+ {:ok, _} = User.follow(follower3, user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+
+ res_conn =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/followers?since_id=#{follower1.id}")
+
+ assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200)
+ assert id3 == follower3.id
+ assert id2 == follower2.id
+
+ res_conn =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/followers?max_id=#{follower3.id}")
+
+ assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200)
+ assert id2 == follower2.id
+ assert id1 == follower1.id
+
+ res_conn =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/followers?limit=1&max_id=#{follower3.id}")
+
+ assert [%{"id" => id2}] = json_response(res_conn, 200)
+ assert id2 == follower2.id
+
+ assert [link_header] = get_resp_header(res_conn, "link")
+ assert link_header =~ ~r/min_id=#{follower2.id}/
+ assert link_header =~ ~r/max_id=#{follower2.id}/
+ end
+ end
+
+ describe "following" do
+ test "getting following", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user)
+ {:ok, user} = User.follow(user, other_user)
+
+ conn =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/following")
+
+ assert [%{"id" => id}] = json_response(conn, 200)
+ assert id == to_string(other_user.id)
+ end
+
+ test "getting following, hide_follows", %{conn: conn} do
+ user = insert(:user, %{info: %{hide_follows: true}})
+ other_user = insert(:user)
+ {:ok, user} = User.follow(user, other_user)
+
+ conn =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/following")
+
+ assert [] == json_response(conn, 200)
+ end
+
+ test "getting following, hide_follows, same user requesting", %{conn: conn} do
+ user = insert(:user, %{info: %{hide_follows: true}})
+ other_user = insert(:user)
+ {:ok, user} = User.follow(user, other_user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/accounts/#{user.id}/following")
+
+ refute [] == json_response(conn, 200)
+ end
+
+ test "getting following, pagination", %{conn: conn} do
+ user = insert(:user)
+ following1 = insert(:user)
+ following2 = insert(:user)
+ following3 = insert(:user)
+ {:ok, _} = User.follow(user, following1)
+ {:ok, _} = User.follow(user, following2)
+ {:ok, _} = User.follow(user, following3)
+
+ conn =
+ conn
+ |> assign(:user, user)
+
+ res_conn =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/following?since_id=#{following1.id}")
+
+ assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200)
+ assert id3 == following3.id
+ assert id2 == following2.id
+
+ res_conn =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/following?max_id=#{following3.id}")
+
+ assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200)
+ assert id2 == following2.id
+ assert id1 == following1.id
+
+ res_conn =
+ conn
+ |> get("/api/v1/accounts/#{user.id}/following?limit=1&max_id=#{following3.id}")
+
+ assert [%{"id" => id2}] = json_response(res_conn, 200)
+ assert id2 == following2.id
+
+ assert [link_header] = get_resp_header(res_conn, "link")
+ assert link_header =~ ~r/min_id=#{following2.id}/
+ assert link_header =~ ~r/max_id=#{following2.id}/
+ end
+ end
+
+ describe "follow/unfollow" do
+ test "following / unfollowing a user", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/accounts/#{other_user.id}/follow")
+
+ assert %{"id" => _id, "following" => true} = json_response(conn, 200)
+
+ user = User.get_cached_by_id(user.id)
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> post("/api/v1/accounts/#{other_user.id}/unfollow")
+
+ assert %{"id" => _id, "following" => false} = json_response(conn, 200)
+
+ user = User.get_cached_by_id(user.id)
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> post("/api/v1/follows", %{"uri" => other_user.nickname})
+
+ assert %{"id" => id} = json_response(conn, 200)
+ assert id == to_string(other_user.id)
+ end
+
+ test "following without reblogs" do
+ follower = insert(:user)
+ followed = insert(:user)
+ other_user = insert(:user)
+
+ conn =
+ build_conn()
+ |> assign(:user, follower)
+ |> post("/api/v1/accounts/#{followed.id}/follow?reblogs=false")
+
+ assert %{"showing_reblogs" => false} = json_response(conn, 200)
+
+ {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hey"})
+ {:ok, reblog, _} = CommonAPI.repeat(activity.id, followed)
+
+ conn =
+ build_conn()
+ |> assign(:user, User.get_cached_by_id(follower.id))
+ |> get("/api/v1/timelines/home")
+
+ assert [] == json_response(conn, 200)
+
+ conn =
+ build_conn()
+ |> assign(:user, follower)
+ |> post("/api/v1/accounts/#{followed.id}/follow?reblogs=true")
+
+ assert %{"showing_reblogs" => true} = json_response(conn, 200)
+
+ conn =
+ build_conn()
+ |> assign(:user, User.get_cached_by_id(follower.id))
+ |> get("/api/v1/timelines/home")
+
+ expected_activity_id = reblog.id
+ assert [%{"id" => ^expected_activity_id}] = json_response(conn, 200)
+ end
+
+ test "following / unfollowing errors" do
+ user = insert(:user)
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+
+ # self follow
+ conn_res = post(conn, "/api/v1/accounts/#{user.id}/follow")
+ assert %{"error" => "Record not found"} = json_response(conn_res, 404)
+
+ # self unfollow
+ user = User.get_cached_by_id(user.id)
+ conn_res = post(conn, "/api/v1/accounts/#{user.id}/unfollow")
+ assert %{"error" => "Record not found"} = json_response(conn_res, 404)
+
+ # self follow via uri
+ user = User.get_cached_by_id(user.id)
+ conn_res = post(conn, "/api/v1/follows", %{"uri" => user.nickname})
+ assert %{"error" => "Record not found"} = json_response(conn_res, 404)
+
+ # follow non existing user
+ conn_res = post(conn, "/api/v1/accounts/doesntexist/follow")
+ assert %{"error" => "Record not found"} = json_response(conn_res, 404)
+
+ # follow non existing user via uri
+ conn_res = post(conn, "/api/v1/follows", %{"uri" => "doesntexist"})
+ assert %{"error" => "Record not found"} = json_response(conn_res, 404)
+
+ # unfollow non existing user
+ conn_res = post(conn, "/api/v1/accounts/doesntexist/unfollow")
+ assert %{"error" => "Record not found"} = json_response(conn_res, 404)
+ end
+ end
+
+ describe "mute/unmute" do
+ test "with notifications", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/accounts/#{other_user.id}/mute")
+
+ response = json_response(conn, 200)
+
+ assert %{"id" => _id, "muting" => true, "muting_notifications" => true} = response
+ user = User.get_cached_by_id(user.id)
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> post("/api/v1/accounts/#{other_user.id}/unmute")
+
+ response = json_response(conn, 200)
+ assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response
+ end
+
+ test "without notifications", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/accounts/#{other_user.id}/mute", %{"notifications" => "false"})
+
+ response = json_response(conn, 200)
+
+ assert %{"id" => _id, "muting" => true, "muting_notifications" => false} = response
+ user = User.get_cached_by_id(user.id)
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> post("/api/v1/accounts/#{other_user.id}/unmute")
+
+ response = json_response(conn, 200)
+ assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response
+ end
+ end
+
+ describe "pinned statuses" do
+ setup do
+ user = insert(:user)
+ {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!"})
+
+ [user: user, activity: activity]
+ end
+
+ test "returns pinned statuses", %{conn: conn, user: user, activity: activity} do
+ {:ok, _} = CommonAPI.pin(activity.id, user)
+
+ result =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
+ |> json_response(200)
+
+ id_str = to_string(activity.id)
+
+ assert [%{"id" => ^id_str, "pinned" => true}] = result
+ end
+ end
+
+ test "blocking / unblocking a user", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/accounts/#{other_user.id}/block")
+
+ assert %{"id" => _id, "blocking" => true} = json_response(conn, 200)
+
+ user = User.get_cached_by_id(user.id)
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> post("/api/v1/accounts/#{other_user.id}/unblock")
+
+ assert %{"id" => _id, "blocking" => false} = json_response(conn, 200)
+ 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
+ |> post("/api/v1/apps", %{
+ client_name: "client_name",
+ redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
+ scopes: "read, write, follow"
+ })
+
+ %{
+ "client_id" => client_id,
+ "client_secret" => client_secret,
+ "id" => _,
+ "name" => "client_name",
+ "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob",
+ "vapid_key" => _,
+ "website" => nil
+ } = json_response(conn, 200)
+
+ conn =
+ conn
+ |> post("/oauth/token", %{
+ grant_type: "client_credentials",
+ client_id: client_id,
+ client_secret: client_secret
+ })
+
+ assert %{"access_token" => token, "refresh_token" => refresh, "scope" => scope} =
+ json_response(conn, 200)
+
+ assert token
+ token_from_db = Repo.get_by(Token, token: token)
+ assert token_from_db
+ assert refresh
+ assert scope == "read write follow"
+
+ conn =
+ build_conn()
+ |> put_req_header("authorization", "Bearer " <> token)
+ |> post("/api/v1/accounts", %{
+ username: "lain",
+ email: "lain@example.org",
+ password: "PlzDontHackLain",
+ bio: "Test Bio",
+ agreement: true
+ })
+
+ %{
+ "access_token" => token,
+ "created_at" => _created_at,
+ "scope" => _scope,
+ "token_type" => "Bearer"
+ } = json_response(conn, 200)
+
+ token_from_db = Repo.get_by(Token, token: token)
+ assert token_from_db
+ token_from_db = Repo.preload(token_from_db, :user)
+ assert token_from_db.user
+
+ 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)
+
+ conn =
+ put_req_header(conn, "authorization", "Bearer " <> app_token.token)
+ |> Map.put(:remote_ip, {15, 15, 15, 15})
+
+ for i <- 1..5 do
+ conn =
+ conn
+ |> post("/api/v1/accounts", %{
+ username: "#{i}lain",
+ email: "#{i}lain@example.org",
+ password: "PlzDontHackLain",
+ agreement: true
+ })
+
+ %{
+ "access_token" => token,
+ "created_at" => _created_at,
+ "scope" => _scope,
+ "token_type" => "Bearer"
+ } = json_response(conn, 200)
+
+ token_from_db = Repo.get_by(Token, token: token)
+ assert token_from_db
+ token_from_db = Repo.preload(token_from_db, :user)
+ assert token_from_db.user
+
+ assert token_from_db.user.info.confirmation_pending
+ end
+
+ conn =
+ conn
+ |> post("/api/v1/accounts", %{
+ username: "6lain",
+ email: "6lain@example.org",
+ password: "PlzDontHackLain",
+ agreement: true
+ })
+
+ 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)
+
+ [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}]
+ |> Stream.zip(valid_params)
+ |> Enum.each(fn {ip, {attr, _}} ->
+ res =
+ conn
+ |> Map.put(:remote_ip, ip)
+ |> post("/api/v1/accounts", Map.delete(valid_params, attr))
+ |> json_response(400)
+
+ assert res == %{"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/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 "verify_credentials" do
+ test "verify_credentials", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/accounts/verify_credentials")
+
+ response = json_response(conn, 200)
+
+ assert %{"id" => id, "source" => %{"privacy" => "public"}} = response
+ assert response["pleroma"]["chat_token"]
+ assert id == to_string(user.id)
+ end
+
+ test "verify_credentials default scope unlisted", %{conn: conn} do
+ user = insert(:user, %{info: %User.Info{default_scope: "unlisted"}})
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/accounts/verify_credentials")
+
+ assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = json_response(conn, 200)
+ assert id == to_string(user.id)
+ end
+
+ test "locked accounts", %{conn: conn} do
+ user = insert(:user, %{info: %User.Info{default_scope: "private"}})
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/accounts/verify_credentials")
+
+ assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200)
+ assert id == to_string(user.id)
+ end
+ end
+
+ describe "user relationships" do
+ test "returns the relationships for the current user", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user)
+ {:ok, user} = User.follow(user, other_user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/accounts/relationships", %{"id" => [other_user.id]})
+
+ assert [relationship] = json_response(conn, 200)
+
+ assert to_string(other_user.id) == relationship["id"]
+ end
+
+ test "returns an empty list on a 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
+end
diff --git a/test/web/mastodon_api/controllers/domain_block_controller_test.exs b/test/web/mastodon_api/controllers/domain_block_controller_test.exs
index 3c3558385..25a279cdc 100644
--- a/test/web/mastodon_api/controllers/domain_block_controller_test.exs
+++ b/test/web/mastodon_api/controllers/domain_block_controller_test.exs
@@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.DomainBlockControllerTest do
- use Pleroma.Web.ConnCase, async: true
+ use Pleroma.Web.ConnCase
alias Pleroma.User
diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs
index 46b035770..f2f8c0578 100644
--- a/test/web/mastodon_api/mastodon_api_controller_test.exs
+++ b/test/web/mastodon_api/mastodon_api_controller_test.exs
@@ -15,7 +15,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.OAuth.App
- alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.Push
import ExUnit.CaptureLog
@@ -23,8 +22,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
import Swoosh.TestAssertions
import Tesla.Mock
- @image "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
-
setup do
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
@@ -33,33 +30,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
clear_config([:instance, :public])
clear_config([:rich_media, :enabled])
- test "verify_credentials", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/accounts/verify_credentials")
-
- response = json_response(conn, 200)
-
- assert %{"id" => id, "source" => %{"privacy" => "public"}} = response
- assert response["pleroma"]["chat_token"]
- assert id == to_string(user.id)
- end
-
- test "verify_credentials default scope unlisted", %{conn: conn} do
- user = insert(:user, %{info: %User.Info{default_scope: "unlisted"}})
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/accounts/verify_credentials")
-
- assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = json_response(conn, 200)
- assert id == to_string(user.id)
- end
-
test "apps/verify_credentials", %{conn: conn} do
token = insert(:oauth_token)
@@ -80,101 +50,6 @@ test "apps/verify_credentials", %{conn: conn} do
assert expected == json_response(conn, 200)
end
- test "user avatar can be set", %{conn: conn} do
- user = insert(:user)
- avatar_image = File.read!("test/fixtures/avatar_data_uri")
-
- conn =
- conn
- |> assign(:user, user)
- |> patch("/api/v1/pleroma/accounts/update_avatar", %{img: avatar_image})
-
- user = refresh_record(user)
-
- assert %{
- "name" => _,
- "type" => _,
- "url" => [
- %{
- "href" => _,
- "mediaType" => _,
- "type" => _
- }
- ]
- } = user.avatar
-
- assert %{"url" => _} = json_response(conn, 200)
- end
-
- test "user avatar can be reset", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> patch("/api/v1/pleroma/accounts/update_avatar", %{img: ""})
-
- user = User.get_cached_by_id(user.id)
-
- assert user.avatar == nil
-
- assert %{"url" => nil} = json_response(conn, 200)
- end
-
- test "can set profile banner", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> patch("/api/v1/pleroma/accounts/update_banner", %{"banner" => @image})
-
- user = refresh_record(user)
- assert user.info.banner["type"] == "Image"
-
- assert %{"url" => _} = json_response(conn, 200)
- end
-
- test "can reset profile banner", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> patch("/api/v1/pleroma/accounts/update_banner", %{"banner" => ""})
-
- user = refresh_record(user)
- assert user.info.banner == %{}
-
- assert %{"url" => nil} = json_response(conn, 200)
- end
-
- test "background image can be set", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> patch("/api/v1/pleroma/accounts/update_background", %{"img" => @image})
-
- user = refresh_record(user)
- assert user.info.background["type"] == "Image"
- assert %{"url" => _} = json_response(conn, 200)
- end
-
- test "background image can be reset", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> patch("/api/v1/pleroma/accounts/update_background", %{"img" => ""})
-
- user = refresh_record(user)
- assert user.info.background == %{}
- assert %{"url" => nil} = json_response(conn, 200)
- end
-
test "creates an oauth app", %{conn: conn} do
user = insert(:user)
app_attrs = build(:oauth_app)
@@ -202,153 +77,6 @@ test "creates an oauth app", %{conn: conn} do
assert expected == json_response(conn, 200)
end
- describe "user timelines" do
- test "gets a users statuses", %{conn: conn} do
- user_one = insert(:user)
- user_two = insert(:user)
- user_three = insert(:user)
-
- {:ok, user_three} = User.follow(user_three, user_one)
-
- {:ok, activity} = CommonAPI.post(user_one, %{"status" => "HI!!!"})
-
- {:ok, direct_activity} =
- CommonAPI.post(user_one, %{
- "status" => "Hi, @#{user_two.nickname}.",
- "visibility" => "direct"
- })
-
- {:ok, private_activity} =
- CommonAPI.post(user_one, %{"status" => "private", "visibility" => "private"})
-
- resp =
- conn
- |> get("/api/v1/accounts/#{user_one.id}/statuses")
-
- assert [%{"id" => id}] = json_response(resp, 200)
- assert id == to_string(activity.id)
-
- resp =
- conn
- |> assign(:user, user_two)
- |> get("/api/v1/accounts/#{user_one.id}/statuses")
-
- assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
- assert id_one == to_string(direct_activity.id)
- assert id_two == to_string(activity.id)
-
- resp =
- conn
- |> assign(:user, user_three)
- |> get("/api/v1/accounts/#{user_one.id}/statuses")
-
- assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
- assert id_one == to_string(private_activity.id)
- assert id_two == to_string(activity.id)
- end
-
- test "unimplemented pinned statuses feature", %{conn: conn} do
- note = insert(:note_activity)
- user = User.get_cached_by_ap_id(note.data["actor"])
-
- conn =
- conn
- |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
-
- assert json_response(conn, 200) == []
- end
-
- test "gets an users media", %{conn: conn} do
- note = insert(:note_activity)
- user = User.get_cached_by_ap_id(note.data["actor"])
-
- file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- {:ok, %{id: media_id}} = ActivityPub.upload(file, actor: user.ap_id)
-
- {:ok, image_post} = CommonAPI.post(user, %{"status" => "cofe", "media_ids" => [media_id]})
-
- conn =
- conn
- |> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "true"})
-
- assert [%{"id" => id}] = json_response(conn, 200)
- assert id == to_string(image_post.id)
-
- conn =
- build_conn()
- |> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "1"})
-
- assert [%{"id" => id}] = json_response(conn, 200)
- assert id == to_string(image_post.id)
- end
-
- test "gets a user's statuses without reblogs", %{conn: conn} do
- user = insert(:user)
- {:ok, post} = CommonAPI.post(user, %{"status" => "HI!!!"})
- {:ok, _, _} = CommonAPI.repeat(post.id, user)
-
- conn =
- conn
- |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "true"})
-
- assert [%{"id" => id}] = json_response(conn, 200)
- assert id == to_string(post.id)
-
- conn =
- conn
- |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "1"})
-
- assert [%{"id" => id}] = json_response(conn, 200)
- assert id == to_string(post.id)
- end
-
- test "filters user's statuses by a hashtag", %{conn: conn} do
- user = insert(:user)
- {:ok, post} = CommonAPI.post(user, %{"status" => "#hashtag"})
- {:ok, _post} = CommonAPI.post(user, %{"status" => "hashtag"})
-
- conn =
- conn
- |> get("/api/v1/accounts/#{user.id}/statuses", %{"tagged" => "hashtag"})
-
- assert [%{"id" => id}] = json_response(conn, 200)
- assert id == to_string(post.id)
- end
- end
-
- describe "user relationships" do
- test "returns the relationships for the current user", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
- {:ok, user} = User.follow(user, other_user)
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/accounts/relationships", %{"id" => [other_user.id]})
-
- assert [relationship] = json_response(conn, 200)
-
- assert to_string(other_user.id) == relationship["id"]
- end
-
- test "returns an empty list on a 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
setup do
user = insert(:user)
@@ -386,101 +114,6 @@ test "returns uploaded image", %{conn: conn, image: image} do
end
end
- describe "locked accounts" do
- test "verify_credentials", %{conn: conn} do
- user = insert(:user, %{info: %User.Info{default_scope: "private"}})
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/accounts/verify_credentials")
-
- assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200)
- assert id == to_string(user.id)
- end
- end
-
- describe "account fetching" do
- test "works by id" do
- user = insert(:user)
-
- conn =
- build_conn()
- |> get("/api/v1/accounts/#{user.id}")
-
- assert %{"id" => id} = json_response(conn, 200)
- assert id == to_string(user.id)
-
- conn =
- build_conn()
- |> get("/api/v1/accounts/-1")
-
- assert %{"error" => "Can't find user"} = json_response(conn, 404)
- end
-
- test "works by nickname" do
- user = insert(:user)
-
- conn =
- build_conn()
- |> get("/api/v1/accounts/#{user.nickname}")
-
- assert %{"id" => id} = json_response(conn, 200)
- assert id == user.id
- end
-
- test "works by nickname for remote users" do
- limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
- Pleroma.Config.put([:instance, :limit_to_local_content], false)
- user = insert(:user, nickname: "user@example.com", local: false)
-
- conn =
- build_conn()
- |> get("/api/v1/accounts/#{user.nickname}")
-
- Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
- assert %{"id" => id} = json_response(conn, 200)
- assert id == user.id
- end
-
- test "respects limit_to_local_content == :all for remote user nicknames" do
- limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
- Pleroma.Config.put([:instance, :limit_to_local_content], :all)
-
- user = insert(:user, nickname: "user@example.com", local: false)
-
- conn =
- build_conn()
- |> get("/api/v1/accounts/#{user.nickname}")
-
- Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
- assert json_response(conn, 404)
- end
-
- test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do
- limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
- Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
-
- user = insert(:user, nickname: "user@example.com", local: false)
- reading_user = insert(:user)
-
- conn =
- build_conn()
- |> get("/api/v1/accounts/#{user.nickname}")
-
- assert json_response(conn, 404)
-
- conn =
- build_conn()
- |> assign(:user, reading_user)
- |> get("/api/v1/accounts/#{user.nickname}")
-
- Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
- assert %{"id" => id} = json_response(conn, 200)
- assert id == user.id
- end
- end
-
describe "/api/v1/pleroma/mascot" do
test "mascot upload", %{conn: conn} do
user = insert(:user)
@@ -549,362 +182,6 @@ test "mascot retrieving", %{conn: conn} do
end
end
- test "getting followers", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
- {:ok, user} = User.follow(user, other_user)
-
- conn =
- conn
- |> get("/api/v1/accounts/#{other_user.id}/followers")
-
- assert [%{"id" => id}] = json_response(conn, 200)
- assert id == to_string(user.id)
- end
-
- test "getting followers, hide_followers", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user, %{info: %{hide_followers: true}})
- {:ok, _user} = User.follow(user, other_user)
-
- conn =
- conn
- |> get("/api/v1/accounts/#{other_user.id}/followers")
-
- assert [] == json_response(conn, 200)
- end
-
- test "getting followers, hide_followers, same user requesting", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user, %{info: %{hide_followers: true}})
- {:ok, _user} = User.follow(user, other_user)
-
- conn =
- conn
- |> assign(:user, other_user)
- |> get("/api/v1/accounts/#{other_user.id}/followers")
-
- refute [] == json_response(conn, 200)
- end
-
- test "getting followers, pagination", %{conn: conn} do
- user = insert(:user)
- follower1 = insert(:user)
- follower2 = insert(:user)
- follower3 = insert(:user)
- {:ok, _} = User.follow(follower1, user)
- {:ok, _} = User.follow(follower2, user)
- {:ok, _} = User.follow(follower3, user)
-
- conn =
- conn
- |> assign(:user, user)
-
- res_conn =
- conn
- |> get("/api/v1/accounts/#{user.id}/followers?since_id=#{follower1.id}")
-
- assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200)
- assert id3 == follower3.id
- assert id2 == follower2.id
-
- res_conn =
- conn
- |> get("/api/v1/accounts/#{user.id}/followers?max_id=#{follower3.id}")
-
- assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200)
- assert id2 == follower2.id
- assert id1 == follower1.id
-
- res_conn =
- conn
- |> get("/api/v1/accounts/#{user.id}/followers?limit=1&max_id=#{follower3.id}")
-
- assert [%{"id" => id2}] = json_response(res_conn, 200)
- assert id2 == follower2.id
-
- assert [link_header] = get_resp_header(res_conn, "link")
- assert link_header =~ ~r/min_id=#{follower2.id}/
- assert link_header =~ ~r/max_id=#{follower2.id}/
- end
-
- test "getting following", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
- {:ok, user} = User.follow(user, other_user)
-
- conn =
- conn
- |> get("/api/v1/accounts/#{user.id}/following")
-
- assert [%{"id" => id}] = json_response(conn, 200)
- assert id == to_string(other_user.id)
- end
-
- test "getting following, hide_follows", %{conn: conn} do
- user = insert(:user, %{info: %{hide_follows: true}})
- other_user = insert(:user)
- {:ok, user} = User.follow(user, other_user)
-
- conn =
- conn
- |> get("/api/v1/accounts/#{user.id}/following")
-
- assert [] == json_response(conn, 200)
- end
-
- test "getting following, hide_follows, same user requesting", %{conn: conn} do
- user = insert(:user, %{info: %{hide_follows: true}})
- other_user = insert(:user)
- {:ok, user} = User.follow(user, other_user)
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/accounts/#{user.id}/following")
-
- refute [] == json_response(conn, 200)
- end
-
- test "getting following, pagination", %{conn: conn} do
- user = insert(:user)
- following1 = insert(:user)
- following2 = insert(:user)
- following3 = insert(:user)
- {:ok, _} = User.follow(user, following1)
- {:ok, _} = User.follow(user, following2)
- {:ok, _} = User.follow(user, following3)
-
- conn =
- conn
- |> assign(:user, user)
-
- res_conn =
- conn
- |> get("/api/v1/accounts/#{user.id}/following?since_id=#{following1.id}")
-
- assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200)
- assert id3 == following3.id
- assert id2 == following2.id
-
- res_conn =
- conn
- |> get("/api/v1/accounts/#{user.id}/following?max_id=#{following3.id}")
-
- assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200)
- assert id2 == following2.id
- assert id1 == following1.id
-
- res_conn =
- conn
- |> get("/api/v1/accounts/#{user.id}/following?limit=1&max_id=#{following3.id}")
-
- assert [%{"id" => id2}] = json_response(res_conn, 200)
- assert id2 == following2.id
-
- assert [link_header] = get_resp_header(res_conn, "link")
- assert link_header =~ ~r/min_id=#{following2.id}/
- assert link_header =~ ~r/max_id=#{following2.id}/
- end
-
- test "following / unfollowing a user", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/accounts/#{other_user.id}/follow")
-
- assert %{"id" => _id, "following" => true} = json_response(conn, 200)
-
- user = User.get_cached_by_id(user.id)
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> post("/api/v1/accounts/#{other_user.id}/unfollow")
-
- assert %{"id" => _id, "following" => false} = json_response(conn, 200)
-
- user = User.get_cached_by_id(user.id)
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> post("/api/v1/follows", %{"uri" => other_user.nickname})
-
- assert %{"id" => id} = json_response(conn, 200)
- assert id == to_string(other_user.id)
- end
-
- test "following without reblogs" do
- follower = insert(:user)
- followed = insert(:user)
- other_user = insert(:user)
-
- conn =
- build_conn()
- |> assign(:user, follower)
- |> post("/api/v1/accounts/#{followed.id}/follow?reblogs=false")
-
- assert %{"showing_reblogs" => false} = json_response(conn, 200)
-
- {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hey"})
- {:ok, reblog, _} = CommonAPI.repeat(activity.id, followed)
-
- conn =
- build_conn()
- |> assign(:user, User.get_cached_by_id(follower.id))
- |> get("/api/v1/timelines/home")
-
- assert [] == json_response(conn, 200)
-
- conn =
- build_conn()
- |> assign(:user, follower)
- |> post("/api/v1/accounts/#{followed.id}/follow?reblogs=true")
-
- assert %{"showing_reblogs" => true} = json_response(conn, 200)
-
- conn =
- build_conn()
- |> assign(:user, User.get_cached_by_id(follower.id))
- |> get("/api/v1/timelines/home")
-
- expected_activity_id = reblog.id
- assert [%{"id" => ^expected_activity_id}] = json_response(conn, 200)
- end
-
- test "following / unfollowing errors" do
- user = insert(:user)
-
- conn =
- build_conn()
- |> assign(:user, user)
-
- # self follow
- conn_res = post(conn, "/api/v1/accounts/#{user.id}/follow")
- assert %{"error" => "Record not found"} = json_response(conn_res, 404)
-
- # self unfollow
- user = User.get_cached_by_id(user.id)
- conn_res = post(conn, "/api/v1/accounts/#{user.id}/unfollow")
- assert %{"error" => "Record not found"} = json_response(conn_res, 404)
-
- # self follow via uri
- user = User.get_cached_by_id(user.id)
- conn_res = post(conn, "/api/v1/follows", %{"uri" => user.nickname})
- assert %{"error" => "Record not found"} = json_response(conn_res, 404)
-
- # follow non existing user
- conn_res = post(conn, "/api/v1/accounts/doesntexist/follow")
- assert %{"error" => "Record not found"} = json_response(conn_res, 404)
-
- # follow non existing user via uri
- conn_res = post(conn, "/api/v1/follows", %{"uri" => "doesntexist"})
- assert %{"error" => "Record not found"} = json_response(conn_res, 404)
-
- # unfollow non existing user
- conn_res = post(conn, "/api/v1/accounts/doesntexist/unfollow")
- assert %{"error" => "Record not found"} = json_response(conn_res, 404)
- end
-
- describe "mute/unmute" do
- test "with notifications", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/accounts/#{other_user.id}/mute")
-
- response = json_response(conn, 200)
-
- assert %{"id" => _id, "muting" => true, "muting_notifications" => true} = response
- user = User.get_cached_by_id(user.id)
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> post("/api/v1/accounts/#{other_user.id}/unmute")
-
- response = json_response(conn, 200)
- assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response
- end
-
- test "without notifications", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/accounts/#{other_user.id}/mute", %{"notifications" => "false"})
-
- response = json_response(conn, 200)
-
- assert %{"id" => _id, "muting" => true, "muting_notifications" => false} = response
- user = User.get_cached_by_id(user.id)
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> post("/api/v1/accounts/#{other_user.id}/unmute")
-
- response = json_response(conn, 200)
- assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response
- end
- end
-
- 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")
-
- assert %{"id" => _id, "subscribing" => true} = json_response(conn, 200)
-
- 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 %{"error" => "Record not found"} = json_response(conn, 404)
- end
- end
-
test "getting a list of mutes", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
@@ -920,27 +197,6 @@ test "getting a list of mutes", %{conn: conn} do
assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
end
- test "blocking / unblocking a user", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/accounts/#{other_user.id}/block")
-
- assert %{"id" => _id, "blocking" => true} = json_response(conn, 200)
-
- user = User.get_cached_by_id(user.id)
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> post("/api/v1/accounts/#{other_user.id}/unblock")
-
- assert %{"id" => _id, "blocking" => false} = json_response(conn, 200)
- end
-
test "getting a list of blocks", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
@@ -1017,199 +273,6 @@ test "returns the favorites of a user", %{conn: conn} do
assert [] = json_response(third_conn, 200)
end
- describe "getting favorites timeline of specified user" do
- setup do
- [current_user, user] = insert_pair(:user, %{info: %{hide_favorites: false}})
- [current_user: current_user, user: user]
- end
-
- test "returns list of statuses favorited by specified user", %{
- conn: conn,
- current_user: current_user,
- user: user
- } do
- [activity | _] = insert_pair(:note_activity)
- CommonAPI.favorite(activity.id, user)
-
- response =
- conn
- |> assign(:user, current_user)
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response(:ok)
-
- [like] = response
-
- assert length(response) == 1
- assert like["id"] == activity.id
- end
-
- test "returns favorites for specified user_id when user is not logged in", %{
- conn: conn,
- user: user
- } do
- activity = insert(:note_activity)
- CommonAPI.favorite(activity.id, user)
-
- response =
- conn
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response(:ok)
-
- assert length(response) == 1
- end
-
- test "returns favorited DM only when user is logged in and he is one of recipients", %{
- conn: conn,
- current_user: current_user,
- user: user
- } do
- {:ok, direct} =
- CommonAPI.post(current_user, %{
- "status" => "Hi @#{user.nickname}!",
- "visibility" => "direct"
- })
-
- CommonAPI.favorite(direct.id, user)
-
- response =
- conn
- |> assign(:user, current_user)
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response(:ok)
-
- assert length(response) == 1
-
- anonymous_response =
- conn
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response(:ok)
-
- assert Enum.empty?(anonymous_response)
- end
-
- test "does not return others' favorited DM when user is not one of recipients", %{
- conn: conn,
- current_user: current_user,
- user: user
- } do
- user_two = insert(:user)
-
- {:ok, direct} =
- CommonAPI.post(user_two, %{
- "status" => "Hi @#{user.nickname}!",
- "visibility" => "direct"
- })
-
- CommonAPI.favorite(direct.id, user)
-
- response =
- conn
- |> assign(:user, current_user)
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response(:ok)
-
- assert Enum.empty?(response)
- end
-
- test "paginates favorites using since_id and max_id", %{
- conn: conn,
- current_user: current_user,
- user: user
- } do
- activities = insert_list(10, :note_activity)
-
- Enum.each(activities, fn activity ->
- CommonAPI.favorite(activity.id, user)
- end)
-
- third_activity = Enum.at(activities, 2)
- seventh_activity = Enum.at(activities, 6)
-
- response =
- conn
- |> assign(:user, current_user)
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites", %{
- since_id: third_activity.id,
- max_id: seventh_activity.id
- })
- |> json_response(:ok)
-
- assert length(response) == 3
- refute third_activity in response
- refute seventh_activity in response
- end
-
- test "limits favorites using limit parameter", %{
- conn: conn,
- current_user: current_user,
- user: user
- } do
- 7
- |> insert_list(:note_activity)
- |> Enum.each(fn activity ->
- CommonAPI.favorite(activity.id, user)
- end)
-
- response =
- conn
- |> assign(:user, current_user)
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites", %{limit: "3"})
- |> json_response(:ok)
-
- assert length(response) == 3
- end
-
- test "returns empty response when user does not have any favorited statuses", %{
- conn: conn,
- current_user: current_user,
- user: user
- } do
- response =
- conn
- |> assign(:user, current_user)
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
- |> json_response(:ok)
-
- assert Enum.empty?(response)
- end
-
- test "returns 404 error when specified user is not exist", %{conn: conn} do
- conn = get(conn, "/api/v1/pleroma/accounts/test/favourites")
-
- assert json_response(conn, 404) == %{"error" => "Record not found"}
- end
-
- test "returns 403 error when user has hidden own favorites", %{
- conn: conn,
- current_user: current_user
- } do
- user = insert(:user, %{info: %{hide_favorites: true}})
- activity = insert(:note_activity)
- CommonAPI.favorite(activity.id, user)
-
- conn =
- conn
- |> assign(:user, current_user)
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
-
- assert json_response(conn, 403) == %{"error" => "Can't get favorites"}
- end
-
- test "hides favorites for new users by default", %{conn: conn, current_user: current_user} do
- user = insert(:user)
- activity = insert(:note_activity)
- CommonAPI.favorite(activity.id, user)
-
- conn =
- conn
- |> assign(:user, current_user)
- |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
-
- assert user.info.hide_favorites
- assert json_response(conn, 403) == %{"error" => "Can't get favorites"}
- end
- end
-
test "get instance information", %{conn: conn} do
conn = get(conn, "/api/v1/instance")
assert result = json_response(conn, 200)
@@ -1294,29 +357,6 @@ test "put settings", %{conn: conn} do
assert user.info.settings == %{"programming" => "socks"}
end
- describe "pinned statuses" do
- setup do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!"})
-
- [user: user, activity: activity]
- end
-
- test "returns pinned statuses", %{conn: conn, user: user, activity: activity} do
- {:ok, _} = CommonAPI.pin(activity.id, user)
-
- result =
- conn
- |> assign(:user, user)
- |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
- |> json_response(200)
-
- id_str = to_string(activity.id)
-
- assert [%{"id" => ^id_str, "pinned" => true}] = result
- end
- end
-
describe "link headers" do
test "preserves parameters in link headers", %{conn: conn} do
user = insert(:user)
@@ -1349,32 +389,6 @@ test "preserves parameters in link headers", %{conn: conn} do
end
end
- test "accounts fetches correct account for nicknames beginning with numbers", %{conn: conn} do
- # Need to set an old-style integer ID to reproduce the problem
- # (these are no longer assigned to new accounts but were preserved
- # for existing accounts during the migration to flakeIDs)
- user_one = insert(:user, %{id: 1212})
- user_two = insert(:user, %{nickname: "#{user_one.id}garbage"})
-
- resp_one =
- conn
- |> get("/api/v1/accounts/#{user_one.id}")
-
- resp_two =
- conn
- |> get("/api/v1/accounts/#{user_two.nickname}")
-
- resp_three =
- conn
- |> get("/api/v1/accounts/#{user_two.id}")
-
- acc_one = json_response(resp_one, 200)
- acc_two = json_response(resp_two, 200)
- acc_three = json_response(resp_three, 200)
- refute acc_one == acc_two
- assert acc_two == acc_three
- end
-
describe "custom emoji" do
test "with tags", %{conn: conn} do
[emoji | _body] =
@@ -1471,172 +485,6 @@ test "redirects to the getting-started page when referer is not present", %{conn
end
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
- |> post("/api/v1/apps", %{
- client_name: "client_name",
- redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
- scopes: "read, write, follow"
- })
-
- %{
- "client_id" => client_id,
- "client_secret" => client_secret,
- "id" => _,
- "name" => "client_name",
- "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob",
- "vapid_key" => _,
- "website" => nil
- } = json_response(conn, 200)
-
- conn =
- conn
- |> post("/oauth/token", %{
- grant_type: "client_credentials",
- client_id: client_id,
- client_secret: client_secret
- })
-
- assert %{"access_token" => token, "refresh_token" => refresh, "scope" => scope} =
- json_response(conn, 200)
-
- assert token
- token_from_db = Repo.get_by(Token, token: token)
- assert token_from_db
- assert refresh
- assert scope == "read write follow"
-
- conn =
- build_conn()
- |> put_req_header("authorization", "Bearer " <> token)
- |> post("/api/v1/accounts", %{
- username: "lain",
- email: "lain@example.org",
- password: "PlzDontHackLain",
- bio: "Test Bio",
- agreement: true
- })
-
- %{
- "access_token" => token,
- "created_at" => _created_at,
- "scope" => _scope,
- "token_type" => "Bearer"
- } = json_response(conn, 200)
-
- token_from_db = Repo.get_by(Token, token: token)
- assert token_from_db
- token_from_db = Repo.preload(token_from_db, :user)
- assert token_from_db.user
-
- 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)
-
- conn =
- put_req_header(conn, "authorization", "Bearer " <> app_token.token)
- |> Map.put(:remote_ip, {15, 15, 15, 15})
-
- for i <- 1..5 do
- conn =
- conn
- |> post("/api/v1/accounts", %{
- username: "#{i}lain",
- email: "#{i}lain@example.org",
- password: "PlzDontHackLain",
- agreement: true
- })
-
- %{
- "access_token" => token,
- "created_at" => _created_at,
- "scope" => _scope,
- "token_type" => "Bearer"
- } = json_response(conn, 200)
-
- token_from_db = Repo.get_by(Token, token: token)
- assert token_from_db
- token_from_db = Repo.preload(token_from_db, :user)
- assert token_from_db.user
-
- assert token_from_db.user.info.confirmation_pending
- end
-
- conn =
- conn
- |> post("/api/v1/accounts", %{
- username: "6lain",
- email: "6lain@example.org",
- password: "PlzDontHackLain",
- agreement: true
- })
-
- 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)
-
- [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}]
- |> Stream.zip(valid_params)
- |> Enum.each(fn {ip, {attr, _}} ->
- res =
- conn
- |> Map.put(:remote_ip, ip)
- |> post("/api/v1/accounts", Map.delete(valid_params, attr))
- |> json_response(400)
-
- assert res == %{"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
test "returns poll entity for object id", %{conn: conn} do
user = insert(:user)
@@ -1861,42 +709,6 @@ test "it returns 400 when user is not local", %{conn: conn, user: user} do
end
end
- describe "POST /api/v1/pleroma/accounts/confirmation_resend" do
- setup do
- {:ok, user} =
- insert(:user)
- |> User.change_info(&User.Info.confirmation_changeset(&1, need_confirmation: true))
- |> Repo.update()
-
- assert user.info.confirmation_pending
-
- [user: user]
- end
-
- clear_config([:instance, :account_activation_required]) do
- Config.put([:instance, :account_activation_required], true)
- end
-
- test "resend account confirmation email", %{conn: conn, user: user} do
- conn
- |> assign(:user, user)
- |> post("/api/v1/pleroma/accounts/confirmation_resend?email=#{user.email}")
- |> json_response(:no_content)
-
- ObanHelpers.perform_all()
-
- email = Pleroma.Emails.UserEmail.account_confirmation_email(user)
- notify_email = Config.get([:instance, :notify_email])
- instance_name = Config.get([:instance, :name])
-
- assert_email_sent(
- from: {instance_name, notify_email},
- to: {user.name, user.email},
- html_body: email.html_body
- )
- end
- end
-
describe "GET /api/v1/suggestions" do
setup do
user = insert(:user)
@@ -2034,23 +846,6 @@ test "redirect to root page", %{conn: conn} do
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)
diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/web/mastodon_api/views/account_view_test.exs
index d965f76bf..62b2ab7e3 100644
--- a/test/web/mastodon_api/views/account_view_test.exs
+++ b/test/web/mastodon_api/views/account_view_test.exs
@@ -88,7 +88,7 @@ test "Represent a user account" do
}
}
- assert expected == AccountView.render("account.json", %{user: user})
+ assert expected == AccountView.render("show.json", %{user: user})
end
test "Represent the user account for the account owner" do
@@ -106,7 +106,7 @@ test "Represent the user account for the account owner" do
assert %{
pleroma: %{notification_settings: ^notification_settings},
source: %{privacy: ^privacy}
- } = AccountView.render("account.json", %{user: user, for: user})
+ } = AccountView.render("show.json", %{user: user, for: user})
end
test "Represent a Service(bot) account" do
@@ -160,13 +160,13 @@ test "Represent a Service(bot) account" do
}
}
- assert expected == AccountView.render("account.json", %{user: user})
+ assert expected == AccountView.render("show.json", %{user: user})
end
test "Represent a deactivated user for an admin" do
admin = insert(:user, %{info: %{is_admin: true}})
deactivated_user = insert(:user, %{info: %{deactivated: true}})
- represented = AccountView.render("account.json", %{user: deactivated_user, for: admin})
+ represented = AccountView.render("show.json", %{user: deactivated_user, for: admin})
assert represented[:pleroma][:deactivated] == true
end
@@ -348,27 +348,27 @@ test "represent an embedded relationship" do
}
}
- assert expected == AccountView.render("account.json", %{user: user, for: other_user})
+ assert expected == AccountView.render("show.json", %{user: user, for: other_user})
end
test "returns the settings store if the requesting user is the represented user and it's requested specifically" do
user = insert(:user, %{info: %User.Info{pleroma_settings_store: %{fe: "test"}}})
result =
- AccountView.render("account.json", %{user: user, for: user, with_pleroma_settings: true})
+ AccountView.render("show.json", %{user: user, for: user, with_pleroma_settings: true})
assert result.pleroma.settings_store == %{:fe => "test"}
- result = AccountView.render("account.json", %{user: user, with_pleroma_settings: true})
+ result = AccountView.render("show.json", %{user: user, with_pleroma_settings: true})
assert result.pleroma[:settings_store] == nil
- result = AccountView.render("account.json", %{user: user, for: user})
+ result = AccountView.render("show.json", %{user: user, for: user})
assert result.pleroma[:settings_store] == nil
end
test "sanitizes display names" do
user = insert(:user, name: "")
- result = AccountView.render("account.json", %{user: user})
+ result = AccountView.render("show.json", %{user: user})
refute result.display_name == ""
end
@@ -391,7 +391,7 @@ test "shows when follows/followers stats are hidden and sets follow/follower cou
followers_count: 0,
following_count: 0,
pleroma: %{hide_follows_count: true, hide_followers_count: true}
- } = AccountView.render("account.json", %{user: user})
+ } = AccountView.render("show.json", %{user: user})
end
test "shows when follows/followers are hidden" do
@@ -404,7 +404,7 @@ test "shows when follows/followers are hidden" do
followers_count: 1,
following_count: 1,
pleroma: %{hide_follows: true, hide_followers: true}
- } = AccountView.render("account.json", %{user: user})
+ } = AccountView.render("show.json", %{user: user})
end
test "shows actual follower/following count to the account owner" do
@@ -416,7 +416,7 @@ test "shows actual follower/following count to the account owner" do
assert %{
followers_count: 1,
following_count: 1
- } = AccountView.render("account.json", %{user: user, for: user})
+ } = AccountView.render("show.json", %{user: user, for: user})
end
end
@@ -425,65 +425,65 @@ test "shows zero when no follow requests are pending" do
user = insert(:user)
assert %{follow_requests_count: 0} =
- AccountView.render("account.json", %{user: user, for: user})
+ AccountView.render("show.json", %{user: user, for: user})
other_user = insert(:user)
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
assert %{follow_requests_count: 0} =
- AccountView.render("account.json", %{user: user, for: user})
+ AccountView.render("show.json", %{user: user, for: user})
end
test "shows non-zero when follow requests are pending" do
user = insert(:user, %{info: %{locked: true}})
- assert %{locked: true} = AccountView.render("account.json", %{user: user, for: user})
+ assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
other_user = insert(:user)
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
assert %{locked: true, follow_requests_count: 1} =
- AccountView.render("account.json", %{user: user, for: user})
+ AccountView.render("show.json", %{user: user, for: user})
end
test "decreases when accepting a follow request" do
user = insert(:user, %{info: %{locked: true}})
- assert %{locked: true} = AccountView.render("account.json", %{user: user, for: user})
+ assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
other_user = insert(:user)
{:ok, other_user, user, _activity} = CommonAPI.follow(other_user, user)
assert %{locked: true, follow_requests_count: 1} =
- AccountView.render("account.json", %{user: user, for: user})
+ AccountView.render("show.json", %{user: user, for: user})
{:ok, _other_user} = CommonAPI.accept_follow_request(other_user, user)
assert %{locked: true, follow_requests_count: 0} =
- AccountView.render("account.json", %{user: user, for: user})
+ AccountView.render("show.json", %{user: user, for: user})
end
test "decreases when rejecting a follow request" do
user = insert(:user, %{info: %{locked: true}})
- assert %{locked: true} = AccountView.render("account.json", %{user: user, for: user})
+ assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
other_user = insert(:user)
{:ok, other_user, user, _activity} = CommonAPI.follow(other_user, user)
assert %{locked: true, follow_requests_count: 1} =
- AccountView.render("account.json", %{user: user, for: user})
+ AccountView.render("show.json", %{user: user, for: user})
{:ok, _other_user} = CommonAPI.reject_follow_request(other_user, user)
assert %{locked: true, follow_requests_count: 0} =
- AccountView.render("account.json", %{user: user, for: user})
+ AccountView.render("show.json", %{user: user, for: user})
end
test "shows non-zero when historical unapproved requests are present" do
user = insert(:user, %{info: %{locked: true}})
- assert %{locked: true} = AccountView.render("account.json", %{user: user, for: user})
+ assert %{locked: true} = AccountView.render("show.json", %{user: user, for: user})
other_user = insert(:user)
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
@@ -491,7 +491,7 @@ test "shows non-zero when historical unapproved requests are present" do
{:ok, user} = User.update_info(user, &User.Info.user_upgrade(&1, %{locked: false}))
assert %{locked: false, follow_requests_count: 1} =
- AccountView.render("account.json", %{user: user, for: user})
+ AccountView.render("show.json", %{user: user, for: user})
end
end
end
diff --git a/test/web/mastodon_api/views/notification_view_test.exs b/test/web/mastodon_api/views/notification_view_test.exs
index 86268fcfa..81ab82e2b 100644
--- a/test/web/mastodon_api/views/notification_view_test.exs
+++ b/test/web/mastodon_api/views/notification_view_test.exs
@@ -27,7 +27,7 @@ test "Mention notification" do
id: to_string(notification.id),
pleroma: %{is_seen: false},
type: "mention",
- account: AccountView.render("account.json", %{user: user, for: mentioned_user}),
+ account: AccountView.render("show.json", %{user: user, for: mentioned_user}),
status: StatusView.render("show.json", %{activity: activity, for: mentioned_user}),
created_at: Utils.to_masto_date(notification.inserted_at)
}
@@ -50,7 +50,7 @@ test "Favourite notification" do
id: to_string(notification.id),
pleroma: %{is_seen: false},
type: "favourite",
- account: AccountView.render("account.json", %{user: another_user, for: user}),
+ account: AccountView.render("show.json", %{user: another_user, for: user}),
status: StatusView.render("show.json", %{activity: create_activity, for: user}),
created_at: Utils.to_masto_date(notification.inserted_at)
}
@@ -72,7 +72,7 @@ test "Reblog notification" do
id: to_string(notification.id),
pleroma: %{is_seen: false},
type: "reblog",
- account: AccountView.render("account.json", %{user: another_user, for: user}),
+ account: AccountView.render("show.json", %{user: another_user, for: user}),
status: StatusView.render("show.json", %{activity: reblog_activity, for: user}),
created_at: Utils.to_masto_date(notification.inserted_at)
}
@@ -92,7 +92,7 @@ test "Follow notification" do
id: to_string(notification.id),
pleroma: %{is_seen: false},
type: "follow",
- account: AccountView.render("account.json", %{user: follower, for: followed}),
+ account: AccountView.render("show.json", %{user: follower, for: followed}),
created_at: Utils.to_masto_date(notification.inserted_at)
}
diff --git a/test/web/mastodon_api/views/status_view_test.exs b/test/web/mastodon_api/views/status_view_test.exs
index 683132f8d..8df23d0a8 100644
--- a/test/web/mastodon_api/views/status_view_test.exs
+++ b/test/web/mastodon_api/views/status_view_test.exs
@@ -103,7 +103,7 @@ test "a note activity" do
id: to_string(note.id),
uri: object_data["id"],
url: Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, note),
- account: AccountView.render("account.json", %{user: user}),
+ account: AccountView.render("show.json", %{user: user}),
in_reply_to_id: nil,
in_reply_to_account_id: nil,
card: nil,
diff --git a/test/web/pleroma_api/controllers/account_controller_test.exs b/test/web/pleroma_api/controllers/account_controller_test.exs
new file mode 100644
index 000000000..3b4665afd
--- /dev/null
+++ b/test/web/pleroma_api/controllers/account_controller_test.exs
@@ -0,0 +1,395 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
+ use Pleroma.Web.ConnCase
+
+ alias Pleroma.Config
+ alias Pleroma.Repo
+ alias Pleroma.Tests.ObanHelpers
+ alias Pleroma.User
+ alias Pleroma.Web.CommonAPI
+
+ import Pleroma.Factory
+ import Swoosh.TestAssertions
+
+ @image "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
+
+ describe "POST /api/v1/pleroma/accounts/confirmation_resend" do
+ setup do
+ {:ok, user} =
+ insert(:user)
+ |> User.change_info(&User.Info.confirmation_changeset(&1, need_confirmation: true))
+ |> Repo.update()
+
+ assert user.info.confirmation_pending
+
+ [user: user]
+ end
+
+ clear_config([:instance, :account_activation_required]) do
+ Config.put([:instance, :account_activation_required], true)
+ end
+
+ test "resend account confirmation email", %{conn: conn, user: user} do
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/pleroma/accounts/confirmation_resend?email=#{user.email}")
+ |> json_response(:no_content)
+
+ ObanHelpers.perform_all()
+
+ email = Pleroma.Emails.UserEmail.account_confirmation_email(user)
+ notify_email = Config.get([:instance, :notify_email])
+ instance_name = Config.get([:instance, :name])
+
+ assert_email_sent(
+ from: {instance_name, notify_email},
+ to: {user.name, user.email},
+ html_body: email.html_body
+ )
+ end
+ end
+
+ describe "PATCH /api/v1/pleroma/accounts/update_avatar" do
+ test "user avatar can be set", %{conn: conn} do
+ user = insert(:user)
+ avatar_image = File.read!("test/fixtures/avatar_data_uri")
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> patch("/api/v1/pleroma/accounts/update_avatar", %{img: avatar_image})
+
+ user = refresh_record(user)
+
+ assert %{
+ "name" => _,
+ "type" => _,
+ "url" => [
+ %{
+ "href" => _,
+ "mediaType" => _,
+ "type" => _
+ }
+ ]
+ } = user.avatar
+
+ assert %{"url" => _} = json_response(conn, 200)
+ end
+
+ test "user avatar can be reset", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> patch("/api/v1/pleroma/accounts/update_avatar", %{img: ""})
+
+ user = User.get_cached_by_id(user.id)
+
+ assert user.avatar == nil
+
+ assert %{"url" => nil} = json_response(conn, 200)
+ end
+ end
+
+ describe "PATCH /api/v1/pleroma/accounts/update_banner" do
+ test "can set profile banner", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> patch("/api/v1/pleroma/accounts/update_banner", %{"banner" => @image})
+
+ user = refresh_record(user)
+ assert user.info.banner["type"] == "Image"
+
+ assert %{"url" => _} = json_response(conn, 200)
+ end
+
+ test "can reset profile banner", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> patch("/api/v1/pleroma/accounts/update_banner", %{"banner" => ""})
+
+ user = refresh_record(user)
+ assert user.info.banner == %{}
+
+ assert %{"url" => nil} = json_response(conn, 200)
+ end
+ end
+
+ describe "PATCH /api/v1/pleroma/accounts/update_background" do
+ test "background image can be set", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> patch("/api/v1/pleroma/accounts/update_background", %{"img" => @image})
+
+ user = refresh_record(user)
+ assert user.info.background["type"] == "Image"
+ assert %{"url" => _} = json_response(conn, 200)
+ end
+
+ test "background image can be reset", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> patch("/api/v1/pleroma/accounts/update_background", %{"img" => ""})
+
+ user = refresh_record(user)
+ assert user.info.background == %{}
+ assert %{"url" => nil} = json_response(conn, 200)
+ end
+ end
+
+ describe "getting favorites timeline of specified user" do
+ setup do
+ [current_user, user] = insert_pair(:user, %{info: %{hide_favorites: false}})
+ [current_user: current_user, user: user]
+ end
+
+ test "returns list of statuses favorited by specified user", %{
+ conn: conn,
+ current_user: current_user,
+ user: user
+ } do
+ [activity | _] = insert_pair(:note_activity)
+ CommonAPI.favorite(activity.id, user)
+
+ response =
+ conn
+ |> assign(:user, current_user)
+ |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
+ |> json_response(:ok)
+
+ [like] = response
+
+ assert length(response) == 1
+ assert like["id"] == activity.id
+ end
+
+ test "returns favorites for specified user_id when user is not logged in", %{
+ conn: conn,
+ user: user
+ } do
+ activity = insert(:note_activity)
+ CommonAPI.favorite(activity.id, user)
+
+ response =
+ conn
+ |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
+ |> json_response(:ok)
+
+ assert length(response) == 1
+ end
+
+ test "returns favorited DM only when user is logged in and he is one of recipients", %{
+ conn: conn,
+ current_user: current_user,
+ user: user
+ } do
+ {:ok, direct} =
+ CommonAPI.post(current_user, %{
+ "status" => "Hi @#{user.nickname}!",
+ "visibility" => "direct"
+ })
+
+ CommonAPI.favorite(direct.id, user)
+
+ response =
+ conn
+ |> assign(:user, current_user)
+ |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
+ |> json_response(:ok)
+
+ assert length(response) == 1
+
+ anonymous_response =
+ conn
+ |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
+ |> json_response(:ok)
+
+ assert Enum.empty?(anonymous_response)
+ end
+
+ test "does not return others' favorited DM when user is not one of recipients", %{
+ conn: conn,
+ current_user: current_user,
+ user: user
+ } do
+ user_two = insert(:user)
+
+ {:ok, direct} =
+ CommonAPI.post(user_two, %{
+ "status" => "Hi @#{user.nickname}!",
+ "visibility" => "direct"
+ })
+
+ CommonAPI.favorite(direct.id, user)
+
+ response =
+ conn
+ |> assign(:user, current_user)
+ |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
+ |> json_response(:ok)
+
+ assert Enum.empty?(response)
+ end
+
+ test "paginates favorites using since_id and max_id", %{
+ conn: conn,
+ current_user: current_user,
+ user: user
+ } do
+ activities = insert_list(10, :note_activity)
+
+ Enum.each(activities, fn activity ->
+ CommonAPI.favorite(activity.id, user)
+ end)
+
+ third_activity = Enum.at(activities, 2)
+ seventh_activity = Enum.at(activities, 6)
+
+ response =
+ conn
+ |> assign(:user, current_user)
+ |> get("/api/v1/pleroma/accounts/#{user.id}/favourites", %{
+ since_id: third_activity.id,
+ max_id: seventh_activity.id
+ })
+ |> json_response(:ok)
+
+ assert length(response) == 3
+ refute third_activity in response
+ refute seventh_activity in response
+ end
+
+ test "limits favorites using limit parameter", %{
+ conn: conn,
+ current_user: current_user,
+ user: user
+ } do
+ 7
+ |> insert_list(:note_activity)
+ |> Enum.each(fn activity ->
+ CommonAPI.favorite(activity.id, user)
+ end)
+
+ response =
+ conn
+ |> assign(:user, current_user)
+ |> get("/api/v1/pleroma/accounts/#{user.id}/favourites", %{limit: "3"})
+ |> json_response(:ok)
+
+ assert length(response) == 3
+ end
+
+ test "returns empty response when user does not have any favorited statuses", %{
+ conn: conn,
+ current_user: current_user,
+ user: user
+ } do
+ response =
+ conn
+ |> assign(:user, current_user)
+ |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
+ |> json_response(:ok)
+
+ assert Enum.empty?(response)
+ end
+
+ test "returns 404 error when specified user is not exist", %{conn: conn} do
+ conn = get(conn, "/api/v1/pleroma/accounts/test/favourites")
+
+ assert json_response(conn, 404) == %{"error" => "Record not found"}
+ end
+
+ test "returns 403 error when user has hidden own favorites", %{
+ conn: conn,
+ current_user: current_user
+ } do
+ user = insert(:user, %{info: %{hide_favorites: true}})
+ activity = insert(:note_activity)
+ CommonAPI.favorite(activity.id, user)
+
+ conn =
+ conn
+ |> assign(:user, current_user)
+ |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
+
+ assert json_response(conn, 403) == %{"error" => "Can't get favorites"}
+ end
+
+ test "hides favorites for new users by default", %{conn: conn, current_user: current_user} do
+ user = insert(:user)
+ activity = insert(:note_activity)
+ CommonAPI.favorite(activity.id, user)
+
+ conn =
+ conn
+ |> assign(:user, current_user)
+ |> get("/api/v1/pleroma/accounts/#{user.id}/favourites")
+
+ assert user.info.hide_favorites
+ assert json_response(conn, 403) == %{"error" => "Can't get favorites"}
+ end
+ end
+
+ 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")
+
+ assert %{"id" => _id, "subscribing" => true} = json_response(conn, 200)
+
+ 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 %{"error" => "Record not found"} = json_response(conn, 404)
+ end
+ end
+end
diff --git a/test/web/pleroma_api/emoji_api_controller_test.exs b/test/web/pleroma_api/controllers/emoji_api_controller_test.exs
similarity index 98%
rename from test/web/pleroma_api/emoji_api_controller_test.exs
rename to test/web/pleroma_api/controllers/emoji_api_controller_test.exs
index 93a507a01..5f74460e8 100644
--- a/test/web/pleroma_api/emoji_api_controller_test.exs
+++ b/test/web/pleroma_api/controllers/emoji_api_controller_test.exs
@@ -1,3 +1,7 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
use Pleroma.Web.ConnCase
diff --git a/test/web/pleroma_api/pleroma_api_controller_test.exs b/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs
similarity index 100%
rename from test/web/pleroma_api/pleroma_api_controller_test.exs
rename to test/web/pleroma_api/controllers/pleroma_api_controller_test.exs
diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs
index bf1e233f5..d1d61d11a 100644
--- a/test/web/twitter_api/twitter_api_test.exs
+++ b/test/web/twitter_api/twitter_api_test.exs
@@ -29,8 +29,8 @@ test "it registers a new user and returns the user." do
fetched_user = User.get_cached_by_nickname("lain")
- assert AccountView.render("account.json", %{user: user}) ==
- AccountView.render("account.json", %{user: fetched_user})
+ assert AccountView.render("show.json", %{user: user}) ==
+ AccountView.render("show.json", %{user: fetched_user})
end
test "it registers a new user with empty string in bio and returns the user." do
@@ -47,8 +47,8 @@ test "it registers a new user with empty string in bio and returns the user." do
fetched_user = User.get_cached_by_nickname("lain")
- assert AccountView.render("account.json", %{user: user}) ==
- AccountView.render("account.json", %{user: fetched_user})
+ assert AccountView.render("show.json", %{user: user}) ==
+ AccountView.render("show.json", %{user: fetched_user})
end
test "it sends confirmation email if :account_activation_required is specified in instance config" do
@@ -148,8 +148,8 @@ test "returns user on success" do
assert invite.used == true
- assert AccountView.render("account.json", %{user: user}) ==
- AccountView.render("account.json", %{user: fetched_user})
+ assert AccountView.render("show.json", %{user: user}) ==
+ AccountView.render("show.json", %{user: fetched_user})
end
test "returns error on invalid token" do
@@ -213,8 +213,8 @@ test "returns error on expired token" do
{:ok, user} = TwitterAPI.register_user(data)
fetched_user = User.get_cached_by_nickname("vinny")
- assert AccountView.render("account.json", %{user: user}) ==
- AccountView.render("account.json", %{user: fetched_user})
+ assert AccountView.render("show.json", %{user: user}) ==
+ AccountView.render("show.json", %{user: fetched_user})
end
{:ok, data: data, check_fn: check_fn}
@@ -288,8 +288,8 @@ test "returns user on success, after him registration fails" do
assert invite.used == true
- assert AccountView.render("account.json", %{user: user}) ==
- AccountView.render("account.json", %{user: fetched_user})
+ assert AccountView.render("show.json", %{user: user}) ==
+ AccountView.render("show.json", %{user: fetched_user})
data = %{
"nickname" => "GrimReaper",
@@ -339,8 +339,8 @@ test "returns user on success" do
refute invite.used
- assert AccountView.render("account.json", %{user: user}) ==
- AccountView.render("account.json", %{user: fetched_user})
+ assert AccountView.render("show.json", %{user: user}) ==
+ AccountView.render("show.json", %{user: fetched_user})
end
test "error after max uses" do
@@ -363,8 +363,8 @@ test "error after max uses" do
invite = Repo.get_by(UserInviteToken, token: invite.token)
assert invite.used == true
- assert AccountView.render("account.json", %{user: user}) ==
- AccountView.render("account.json", %{user: fetched_user})
+ assert AccountView.render("show.json", %{user: user}) ==
+ AccountView.render("show.json", %{user: fetched_user})
data = %{
"nickname" => "GrimReaper",