@@ -0,0 +1,49 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Activity.Queries do | |||
@moduledoc """ | |||
Contains queries for Activity. | |||
""" | |||
import Ecto.Query, only: [from: 2] | |||
@type query :: Ecto.Queryable.t() | Activity.t() | |||
alias Pleroma.Activity | |||
@spec by_actor(query, String.t()) :: query | |||
def by_actor(query \\ Activity, actor) do | |||
from( | |||
activity in query, | |||
where: fragment("(?)->>'actor' = ?", activity.data, ^actor) | |||
) | |||
end | |||
@spec by_object_id(query, String.t()) :: query | |||
def by_object_id(query \\ Activity, object_id) do | |||
from(activity in query, | |||
where: | |||
fragment( | |||
"coalesce((?)->'object'->>'id', (?)->>'object') = ?", | |||
activity.data, | |||
activity.data, | |||
^object_id | |||
) | |||
) | |||
end | |||
@spec by_type(query, String.t()) :: query | |||
def by_type(query \\ Activity, activity_type) do | |||
from( | |||
activity in query, | |||
where: fragment("(?)->>'type' = ?", activity.data, ^activity_type) | |||
) | |||
end | |||
@spec limit(query, pos_integer()) :: query | |||
def limit(query \\ Activity, limit) do | |||
from(activity in query, limit: ^limit) | |||
end | |||
end |
@@ -109,15 +109,19 @@ defmodule Pleroma.List do | |||
end | |||
def create(title, %User{} = creator) do | |||
list = %Pleroma.List{user_id: creator.id, title: title} | |||
Repo.transaction(fn -> | |||
list = Repo.insert!(list) | |||
list | |||
|> change(ap_id: "#{creator.ap_id}/lists/#{list.id}") | |||
|> Repo.update!() | |||
end) | |||
changeset = title_changeset(%Pleroma.List{user_id: creator.id}, %{title: title}) | |||
if changeset.valid? do | |||
Repo.transaction(fn -> | |||
list = Repo.insert!(changeset) | |||
list | |||
|> change(ap_id: "#{creator.ap_id}/lists/#{list.id}") | |||
|> Repo.update!() | |||
end) | |||
else | |||
{:error, changeset} | |||
end | |||
end | |||
def follow(%Pleroma.List{following: following} = list, %User{} = followed) do | |||
@@ -150,8 +150,6 @@ defmodule Pleroma.Object do | |||
def update_and_set_cache(changeset) do | |||
with {:ok, object} <- Repo.update(changeset) do | |||
set_cache(object) | |||
else | |||
e -> e | |||
end | |||
end | |||
@@ -139,7 +139,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do | |||
# Splice in the child object if we have one. | |||
activity = | |||
if !is_nil(object) do | |||
if not is_nil(object) do | |||
Map.put(activity, :object, object) | |||
else | |||
activity | |||
@@ -341,12 +341,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do | |||
end | |||
end | |||
def unlike( | |||
%User{} = actor, | |||
%Object{} = object, | |||
activity_id \\ nil, | |||
local \\ true | |||
) do | |||
def unlike(%User{} = actor, %Object{} = object, activity_id \\ nil, local \\ true) do | |||
with %Activity{} = like_activity <- get_existing_like(actor.ap_id, object), | |||
unlike_data <- make_unlike_data(actor, like_activity, activity_id), | |||
{:ok, unlike_activity} <- insert(unlike_data, local), | |||
@@ -309,42 +309,42 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do | |||
end | |||
def update_outbox( | |||
%{assigns: %{user: user}} = conn, | |||
%{assigns: %{user: %User{nickname: nickname} = user}} = conn, | |||
%{"nickname" => nickname} = params | |||
) do | |||
if nickname == user.nickname do | |||
actor = user.ap_id() | |||
params = | |||
params | |||
|> Map.drop(["id"]) | |||
|> Map.put("actor", actor) | |||
|> Transmogrifier.fix_addressing() | |||
actor = user.ap_id() | |||
with {:ok, %Activity{} = activity} <- handle_user_activity(user, params) do | |||
conn | |||
|> put_status(:created) | |||
|> put_resp_header("location", activity.data["id"]) | |||
|> json(activity.data) | |||
else | |||
{:error, message} -> | |||
conn | |||
|> put_status(:bad_request) | |||
|> json(message) | |||
end | |||
else | |||
err = | |||
dgettext("errors", "can't update outbox of %{nickname} as %{as_nickname}", | |||
nickname: nickname, | |||
as_nickname: user.nickname | |||
) | |||
params = | |||
params | |||
|> Map.drop(["id"]) | |||
|> Map.put("actor", actor) | |||
|> Transmogrifier.fix_addressing() | |||
with {:ok, %Activity{} = activity} <- handle_user_activity(user, params) do | |||
conn | |||
|> put_status(:forbidden) | |||
|> json(err) | |||
|> put_status(:created) | |||
|> put_resp_header("location", activity.data["id"]) | |||
|> json(activity.data) | |||
else | |||
{:error, message} -> | |||
conn | |||
|> put_status(:bad_request) | |||
|> json(message) | |||
end | |||
end | |||
def update_outbox(%{assigns: %{user: user}} = conn, %{"nickname" => nickname} = _) do | |||
err = | |||
dgettext("errors", "can't update outbox of %{nickname} as %{as_nickname}", | |||
nickname: nickname, | |||
as_nickname: user.nickname | |||
) | |||
conn | |||
|> put_status(:forbidden) | |||
|> json(err) | |||
end | |||
def errors(conn, {:error, :not_found}) do | |||
conn | |||
|> put_status(:not_found) | |||
@@ -166,6 +166,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
@doc """ | |||
Enqueues an activity for federation if it's local | |||
""" | |||
@spec maybe_federate(any()) :: :ok | |||
def maybe_federate(%Activity{local: true} = activity) do | |||
if Pleroma.Config.get!([:instance, :federating]) do | |||
priority = | |||
@@ -256,44 +257,24 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
@doc """ | |||
Returns an existing like if a user already liked an object | |||
""" | |||
@spec get_existing_like(String.t(), map()) :: Activity.t() | nil | |||
def get_existing_like(actor, %{data: %{"id" => id}}) do | |||
query = | |||
from( | |||
activity in Activity, | |||
where: fragment("(?)->>'actor' = ?", activity.data, ^actor), | |||
# this is to use the index | |||
where: | |||
fragment( | |||
"coalesce((?)->'object'->>'id', (?)->>'object') = ?", | |||
activity.data, | |||
activity.data, | |||
^id | |||
), | |||
where: fragment("(?)->>'type' = 'Like'", activity.data) | |||
) | |||
Repo.one(query) | |||
actor | |||
|> Activity.Queries.by_actor() | |||
|> Activity.Queries.by_object_id(id) | |||
|> Activity.Queries.by_type("Like") | |||
|> Activity.Queries.limit(1) | |||
|> Repo.one() | |||
end | |||
@doc """ | |||
Returns like activities targeting an object | |||
""" | |||
def get_object_likes(%{data: %{"id" => id}}) do | |||
query = | |||
from( | |||
activity in Activity, | |||
# this is to use the index | |||
where: | |||
fragment( | |||
"coalesce((?)->'object'->>'id', (?)->>'object') = ?", | |||
activity.data, | |||
activity.data, | |||
^id | |||
), | |||
where: fragment("(?)->>'type' = 'Like'", activity.data) | |||
) | |||
Repo.all(query) | |||
id | |||
|> Activity.Queries.by_object_id() | |||
|> Activity.Queries.by_type("Like") | |||
|> Repo.all() | |||
end | |||
def is_emoji?(emoji) do | |||
@@ -306,6 +287,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
|> Map.put("content", emoji) | |||
end | |||
@spec make_like_data(User.t(), map(), String.t()) :: map() | |||
def make_like_data( | |||
%User{ap_id: ap_id} = actor, | |||
%{data: %{"actor" => object_actor_id, "id" => id}} = object, | |||
@@ -325,7 +307,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
|> List.delete(actor.ap_id) | |||
|> List.delete(object_actor.follower_address) | |||
data = %{ | |||
%{ | |||
"type" => "Like", | |||
"actor" => ap_id, | |||
"object" => id, | |||
@@ -333,38 +315,49 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
"cc" => cc, | |||
"context" => object.data["context"] | |||
} | |||
if activity_id, do: Map.put(data, "id", activity_id), else: data | |||
|> maybe_put("id", activity_id) | |||
end | |||
@spec update_element_in_object(String.t(), list(any), Object.t()) :: | |||
{:ok, Object.t()} | {:error, Ecto.Changeset.t()} | |||
def update_element_in_object(property, element, object) do | |||
with new_data <- | |||
object.data | |||
|> Map.put("#{property}_count", length(element)) | |||
|> Map.put("#{property}s", element), | |||
changeset <- Changeset.change(object, data: new_data), | |||
{:ok, object} <- Object.update_and_set_cache(changeset) do | |||
{:ok, object} | |||
end | |||
end | |||
data = | |||
Map.merge( | |||
object.data, | |||
%{"#{property}_count" => length(element), "#{property}s" => element} | |||
) | |||
def update_likes_in_object(likes, object) do | |||
update_element_in_object("like", likes, object) | |||
object | |||
|> Changeset.change(data: data) | |||
|> Object.update_and_set_cache() | |||
end | |||
@spec add_like_to_object(Activity.t(), Object.t()) :: | |||
{:ok, Object.t()} | {:error, Ecto.Changeset.t()} | |||
def add_like_to_object(%Activity{data: %{"actor" => actor}}, object) do | |||
likes = if is_list(object.data["likes"]), do: object.data["likes"], else: [] | |||
with likes <- [actor | likes] |> Enum.uniq() do | |||
update_likes_in_object(likes, object) | |||
end | |||
[actor | fetch_likes(object)] | |||
|> Enum.uniq() | |||
|> update_likes_in_object(object) | |||
end | |||
@spec remove_like_from_object(Activity.t(), Object.t()) :: | |||
{:ok, Object.t()} | {:error, Ecto.Changeset.t()} | |||
def remove_like_from_object(%Activity{data: %{"actor" => actor}}, object) do | |||
likes = if is_list(object.data["likes"]), do: object.data["likes"], else: [] | |||
object | |||
|> fetch_likes() | |||
|> List.delete(actor) | |||
|> update_likes_in_object(object) | |||
end | |||
with likes <- likes |> List.delete(actor) do | |||
update_likes_in_object(likes, object) | |||
defp update_likes_in_object(likes, object) do | |||
update_element_in_object("like", likes, object) | |||
end | |||
defp fetch_likes(object) do | |||
if is_list(object.data["likes"]) do | |||
object.data["likes"] | |||
else | |||
[] | |||
end | |||
end | |||
@@ -415,7 +408,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
%User{ap_id: followed_id} = _followed, | |||
activity_id | |||
) do | |||
data = %{ | |||
%{ | |||
"type" => "Follow", | |||
"actor" => follower_id, | |||
"to" => [followed_id], | |||
@@ -423,10 +416,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
"object" => followed_id, | |||
"state" => "pending" | |||
} | |||
data = if activity_id, do: Map.put(data, "id", activity_id), else: data | |||
data | |||
|> maybe_put("id", activity_id) | |||
end | |||
def fetch_latest_follow(%User{ap_id: follower_id}, %User{ap_id: followed_id}) do | |||
@@ -488,7 +478,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
activity_id, | |||
false | |||
) do | |||
data = %{ | |||
%{ | |||
"type" => "Announce", | |||
"actor" => ap_id, | |||
"object" => id, | |||
@@ -496,8 +486,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
"cc" => [], | |||
"context" => object.data["context"] | |||
} | |||
if activity_id, do: Map.put(data, "id", activity_id), else: data | |||
|> maybe_put("id", activity_id) | |||
end | |||
def make_announce_data( | |||
@@ -506,7 +495,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
activity_id, | |||
true | |||
) do | |||
data = %{ | |||
%{ | |||
"type" => "Announce", | |||
"actor" => ap_id, | |||
"object" => id, | |||
@@ -514,8 +503,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
"cc" => [Pleroma.Constants.as_public()], | |||
"context" => object.data["context"] | |||
} | |||
if activity_id, do: Map.put(data, "id", activity_id), else: data | |||
|> maybe_put("id", activity_id) | |||
end | |||
@doc """ | |||
@@ -526,7 +514,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
%Activity{data: %{"context" => context}} = activity, | |||
activity_id | |||
) do | |||
data = %{ | |||
%{ | |||
"type" => "Undo", | |||
"actor" => ap_id, | |||
"object" => activity.data, | |||
@@ -534,8 +522,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
"cc" => [Pleroma.Constants.as_public()], | |||
"context" => context | |||
} | |||
if activity_id, do: Map.put(data, "id", activity_id), else: data | |||
|> maybe_put("id", activity_id) | |||
end | |||
def make_unlike_data( | |||
@@ -543,7 +530,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
%Activity{data: %{"context" => context}} = activity, | |||
activity_id | |||
) do | |||
data = %{ | |||
%{ | |||
"type" => "Undo", | |||
"actor" => ap_id, | |||
"object" => activity.data, | |||
@@ -551,8 +538,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
"cc" => [Pleroma.Constants.as_public()], | |||
"context" => context | |||
} | |||
if activity_id, do: Map.put(data, "id", activity_id), else: data | |||
|> maybe_put("id", activity_id) | |||
end | |||
def add_announce_to_object( | |||
@@ -583,14 +569,13 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
#### Unfollow-related helpers | |||
def make_unfollow_data(follower, followed, follow_activity, activity_id) do | |||
data = %{ | |||
%{ | |||
"type" => "Undo", | |||
"actor" => follower.ap_id, | |||
"to" => [followed.ap_id], | |||
"object" => follow_activity.data | |||
} | |||
if activity_id, do: Map.put(data, "id", activity_id), else: data | |||
|> maybe_put("id", activity_id) | |||
end | |||
#### Block-related helpers | |||
@@ -620,25 +605,23 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
end | |||
def make_block_data(blocker, blocked, activity_id) do | |||
data = %{ | |||
%{ | |||
"type" => "Block", | |||
"actor" => blocker.ap_id, | |||
"to" => [blocked.ap_id], | |||
"object" => blocked.ap_id | |||
} | |||
if activity_id, do: Map.put(data, "id", activity_id), else: data | |||
|> maybe_put("id", activity_id) | |||
end | |||
def make_unblock_data(blocker, blocked, block_activity, activity_id) do | |||
data = %{ | |||
%{ | |||
"type" => "Undo", | |||
"actor" => blocker.ap_id, | |||
"to" => [blocked.ap_id], | |||
"object" => block_activity.data | |||
} | |||
if activity_id, do: Map.put(data, "id", activity_id), else: data | |||
|> maybe_put("id", activity_id) | |||
end | |||
#### Create-related helpers | |||
@@ -809,4 +792,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
Repo.all(query) | |||
end | |||
defp maybe_put(map, _key, nil), do: map | |||
defp maybe_put(map, key, value), do: Map.put(map, key, value) | |||
end |
@@ -0,0 +1,34 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.MastodonAPI.FallbackController do | |||
use Pleroma.Web, :controller | |||
def call(conn, {:error, %Ecto.Changeset{} = changeset}) do | |||
error_message = | |||
changeset | |||
|> Ecto.Changeset.traverse_errors(fn {message, _opt} -> message end) | |||
|> Enum.map_join(", ", fn {_k, v} -> v end) | |||
conn | |||
|> put_status(:unprocessable_entity) | |||
|> json(%{error: error_message}) | |||
end | |||
def call(conn, {:error, :not_found}) do | |||
render_error(conn, :not_found, "Record not found") | |||
end | |||
def call(conn, {:error, error_message}) do | |||
conn | |||
|> put_status(:bad_request) | |||
|> json(%{error: error_message}) | |||
end | |||
def call(conn, _) do | |||
conn | |||
|> put_status(:internal_server_error) | |||
|> json(dgettext("errors", "Something went wrong")) | |||
end | |||
end |
@@ -0,0 +1,84 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.MastodonAPI.ListController do | |||
use Pleroma.Web, :controller | |||
alias Pleroma.User | |||
alias Pleroma.Web.MastodonAPI.AccountView | |||
plug(:list_by_id_and_user when action not in [:index, :create]) | |||
action_fallback(Pleroma.Web.MastodonAPI.FallbackController) | |||
# GET /api/v1/lists | |||
def index(%{assigns: %{user: user}} = conn, opts) do | |||
lists = Pleroma.List.for_user(user, opts) | |||
render(conn, "index.json", lists: lists) | |||
end | |||
# POST /api/v1/lists | |||
def create(%{assigns: %{user: user}} = conn, %{"title" => title}) do | |||
with {:ok, %Pleroma.List{} = list} <- Pleroma.List.create(title, user) do | |||
render(conn, "show.json", list: list) | |||
end | |||
end | |||
# GET /api/v1/lists/:id | |||
def show(%{assigns: %{list: list}} = conn, _) do | |||
render(conn, "show.json", list: list) | |||
end | |||
# PUT /api/v1/lists/:id | |||
def update(%{assigns: %{list: list}} = conn, %{"title" => title}) do | |||
with {:ok, list} <- Pleroma.List.rename(list, title) do | |||
render(conn, "show.json", list: list) | |||
end | |||
end | |||
# DELETE /api/v1/lists/:id | |||
def delete(%{assigns: %{list: list}} = conn, _) do | |||
with {:ok, _list} <- Pleroma.List.delete(list) do | |||
json(conn, %{}) | |||
end | |||
end | |||
# GET /api/v1/lists/:id/accounts | |||
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) | |||
end | |||
end | |||
# POST /api/v1/lists/:id/accounts | |||
def add_to_list(%{assigns: %{list: list}} = conn, %{"account_ids" => account_ids}) do | |||
Enum.each(account_ids, fn account_id -> | |||
with %User{} = followed <- User.get_cached_by_id(account_id) do | |||
Pleroma.List.follow(list, followed) | |||
end | |||
end) | |||
json(conn, %{}) | |||
end | |||
# DELETE /api/v1/lists/:id/accounts | |||
def remove_from_list(%{assigns: %{list: list}} = conn, %{"account_ids" => account_ids}) do | |||
Enum.each(account_ids, fn account_id -> | |||
with %User{} = followed <- User.get_cached_by_id(account_id) do | |||
Pleroma.List.unfollow(list, followed) | |||
end | |||
end) | |||
json(conn, %{}) | |||
end | |||
defp list_by_id_and_user(%{assigns: %{user: user}, params: %{"id" => id}} = conn, _) do | |||
case Pleroma.List.get(id, user) do | |||
%Pleroma.List{} = list -> assign(conn, :list, list) | |||
nil -> conn |> render_error(:not_found, "List not found") |> halt() | |||
end | |||
end | |||
end |
@@ -83,7 +83,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
@local_mastodon_name "Mastodon-Local" | |||
action_fallback(:errors) | |||
action_fallback(Pleroma.Web.MastodonAPI.FallbackController) | |||
def create_app(conn, params) do | |||
scopes = Scopes.fetch_scopes(params, ["read"]) | |||
@@ -189,7 +189,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
info_cng = User.Info.profile_update(user.info, info_params) | |||
with changeset <- User.update_changeset(user, user_params), | |||
changeset <- Ecto.Changeset.put_embed(changeset, :info, info_cng), | |||
changeset <- Changeset.put_embed(changeset, :info, info_cng), | |||
{:ok, user} <- User.update_and_set_cache(changeset) do | |||
if original_user != user do | |||
CommonAPI.update(user) | |||
@@ -225,7 +225,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
def update_banner(%{assigns: %{user: user}} = conn, %{"banner" => ""}) do | |||
with new_info <- %{"banner" => %{}}, | |||
info_cng <- User.Info.profile_update(user.info, new_info), | |||
changeset <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng), | |||
changeset <- Changeset.change(user) |> Changeset.put_embed(:info, info_cng), | |||
{:ok, user} <- User.update_and_set_cache(changeset) do | |||
CommonAPI.update(user) | |||
@@ -237,7 +237,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner), | |||
new_info <- %{"banner" => object.data}, | |||
info_cng <- User.Info.profile_update(user.info, new_info), | |||
changeset <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng), | |||
changeset <- Changeset.change(user) |> Changeset.put_embed(:info, info_cng), | |||
{:ok, user} <- User.update_and_set_cache(changeset) do | |||
CommonAPI.update(user) | |||
%{"url" => [%{"href" => href} | _]} = object.data | |||
@@ -249,7 +249,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
def update_background(%{assigns: %{user: user}} = conn, %{"img" => ""}) do | |||
with new_info <- %{"background" => %{}}, | |||
info_cng <- User.Info.profile_update(user.info, new_info), | |||
changeset <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng), | |||
changeset <- Changeset.change(user) |> Changeset.put_embed(:info, info_cng), | |||
{:ok, _user} <- User.update_and_set_cache(changeset) do | |||
json(conn, %{url: nil}) | |||
end | |||
@@ -259,7 +259,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
with {:ok, object} <- ActivityPub.upload(params, type: :background), | |||
new_info <- %{"background" => object.data}, | |||
info_cng <- User.Info.profile_update(user.info, new_info), | |||
changeset <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng), | |||
changeset <- Changeset.change(user) |> Changeset.put_embed(:info, info_cng), | |||
{:ok, _user} <- User.update_and_set_cache(changeset) do | |||
%{"url" => [%{"href" => href} | _]} = object.data | |||
@@ -806,8 +806,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
user_changeset = | |||
user | |||
|> Ecto.Changeset.change() | |||
|> Ecto.Changeset.put_embed(:info, info_changeset) | |||
|> Changeset.change() | |||
|> Changeset.put_embed(:info, info_changeset) | |||
{:ok, _user} = User.update_and_set_cache(user_changeset) | |||
@@ -1205,88 +1205,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
|> render("index.json", %{activities: activities, for: user, as: :activity}) | |||
end | |||
def get_lists(%{assigns: %{user: user}} = conn, opts) do | |||
lists = Pleroma.List.for_user(user, opts) | |||
res = ListView.render("lists.json", lists: lists) | |||
json(conn, res) | |||
end | |||
def get_list(%{assigns: %{user: user}} = conn, %{"id" => id}) do | |||
with %Pleroma.List{} = list <- Pleroma.List.get(id, user) do | |||
res = ListView.render("list.json", list: list) | |||
json(conn, res) | |||
else | |||
_e -> render_error(conn, :not_found, "Record not found") | |||
end | |||
end | |||
def account_lists(%{assigns: %{user: user}} = conn, %{"id" => account_id}) do | |||
lists = Pleroma.List.get_lists_account_belongs(user, account_id) | |||
res = ListView.render("lists.json", lists: lists) | |||
json(conn, res) | |||
end | |||
def delete_list(%{assigns: %{user: user}} = conn, %{"id" => id}) do | |||
with %Pleroma.List{} = list <- Pleroma.List.get(id, user), | |||
{:ok, _list} <- Pleroma.List.delete(list) do | |||
json(conn, %{}) | |||
else | |||
_e -> | |||
json(conn, dgettext("errors", "error")) | |||
end | |||
end | |||
def create_list(%{assigns: %{user: user}} = conn, %{"title" => title}) do | |||
with {:ok, %Pleroma.List{} = list} <- Pleroma.List.create(title, user) do | |||
res = ListView.render("list.json", list: list) | |||
json(conn, res) | |||
end | |||
end | |||
def add_to_list(%{assigns: %{user: user}} = conn, %{"id" => id, "account_ids" => accounts}) do | |||
accounts | |||
|> Enum.each(fn account_id -> | |||
with %Pleroma.List{} = list <- Pleroma.List.get(id, user), | |||
%User{} = followed <- User.get_cached_by_id(account_id) do | |||
Pleroma.List.follow(list, followed) | |||
end | |||
end) | |||
json(conn, %{}) | |||
end | |||
def remove_from_list(%{assigns: %{user: user}} = conn, %{"id" => id, "account_ids" => accounts}) do | |||
accounts | |||
|> Enum.each(fn account_id -> | |||
with %Pleroma.List{} = list <- Pleroma.List.get(id, user), | |||
%User{} = followed <- User.get_cached_by_id(account_id) do | |||
Pleroma.List.unfollow(list, followed) | |||
end | |||
end) | |||
json(conn, %{}) | |||
end | |||
def list_accounts(%{assigns: %{user: user}} = conn, %{"id" => id}) do | |||
with %Pleroma.List{} = list <- Pleroma.List.get(id, user), | |||
{:ok, users} = Pleroma.List.get_following(list) do | |||
conn | |||
|> put_view(AccountView) | |||
|> render("accounts.json", %{for: user, users: users, as: :user}) | |||
end | |||
end | |||
def rename_list(%{assigns: %{user: user}} = conn, %{"id" => id, "title" => title}) do | |||
with %Pleroma.List{} = list <- Pleroma.List.get(id, user), | |||
{:ok, list} <- Pleroma.List.rename(list, title) do | |||
res = ListView.render("list.json", list: list) | |||
json(conn, res) | |||
else | |||
_e -> | |||
json(conn, dgettext("errors", "error")) | |||
end | |||
end | |||
def list_timeline(%{assigns: %{user: user}} = conn, %{"list_id" => id} = params) do | |||
with %Pleroma.List{title: _title, following: following} <- Pleroma.List.get(id, user) do | |||
params = | |||
@@ -1420,8 +1344,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
def put_settings(%{assigns: %{user: user}} = conn, %{"data" => settings} = _params) do | |||
info_cng = User.Info.mastodon_settings_update(user.info, settings) | |||
with changeset <- Ecto.Changeset.change(user), | |||
changeset <- Ecto.Changeset.put_embed(changeset, :info, info_cng), | |||
with changeset <- Changeset.change(user), | |||
changeset <- Changeset.put_embed(changeset, :info, info_cng), | |||
{:ok, _user} <- User.update_and_set_cache(changeset) do | |||
json(conn, %{}) | |||
else | |||
@@ -1485,7 +1409,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
{:ok, app} | |||
else | |||
app | |||
|> Ecto.Changeset.change(%{scopes: scopes}) | |||
|> Changeset.change(%{scopes: scopes}) | |||
|> Repo.update() | |||
end | |||
@@ -1587,35 +1511,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do | |||
json(conn, %{}) | |||
end | |||
# fallback action | |||
# | |||
def errors(conn, {:error, %Changeset{} = changeset}) do | |||
error_message = | |||
changeset | |||
|> Changeset.traverse_errors(fn {message, _opt} -> message end) | |||
|> Enum.map_join(", ", fn {_k, v} -> v end) | |||
conn | |||
|> put_status(:unprocessable_entity) | |||
|> json(%{error: error_message}) | |||
end | |||
def errors(conn, {:error, :not_found}) do | |||
render_error(conn, :not_found, "Record not found") | |||
end | |||
def errors(conn, {:error, error_message}) do | |||
conn | |||
|> put_status(:bad_request) | |||
|> json(%{error: error_message}) | |||
end | |||
def errors(conn, _) do | |||
conn | |||
|> put_status(:internal_server_error) | |||
|> json(dgettext("errors", "Something went wrong")) | |||
end | |||
def suggestions(%{assigns: %{user: user}} = conn, _) do | |||
suggestions = Config.get(:suggestions) | |||
@@ -64,8 +64,6 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionController do | |||
end | |||
def errors(conn, _) do | |||
conn | |||
|> put_status(:internal_server_error) | |||
|> json(dgettext("errors", "Something went wrong")) | |||
Pleroma.Web.MastodonAPI.FallbackController.call(conn, nil) | |||
end | |||
end |
@@ -6,11 +6,11 @@ defmodule Pleroma.Web.MastodonAPI.ListView do | |||
use Pleroma.Web, :view | |||
alias Pleroma.Web.MastodonAPI.ListView | |||
def render("lists.json", %{lists: lists} = opts) do | |||
render_many(lists, ListView, "list.json", opts) | |||
def render("index.json", %{lists: lists} = opts) do | |||
render_many(lists, ListView, "show.json", opts) | |||
end | |||
def render("list.json", %{list: list}) do | |||
def render("show.json", %{list: list}) do | |||
%{ | |||
id: to_string(list.id), | |||
title: list.title | |||
@@ -312,9 +312,9 @@ defmodule Pleroma.Web.Router do | |||
get("/scheduled_statuses", MastodonAPIController, :scheduled_statuses) | |||
get("/scheduled_statuses/:id", MastodonAPIController, :show_scheduled_status) | |||
get("/lists", MastodonAPIController, :get_lists) | |||
get("/lists/:id", MastodonAPIController, :get_list) | |||
get("/lists/:id/accounts", MastodonAPIController, :list_accounts) | |||
get("/lists", ListController, :index) | |||
get("/lists/:id", ListController, :show) | |||
get("/lists/:id/accounts", ListController, :list_accounts) | |||
get("/domain_blocks", MastodonAPIController, :domain_blocks) | |||
@@ -355,12 +355,12 @@ defmodule Pleroma.Web.Router do | |||
post("/media", MastodonAPIController, :upload) | |||
put("/media/:id", MastodonAPIController, :update_media) | |||
delete("/lists/:id", MastodonAPIController, :delete_list) | |||
post("/lists", MastodonAPIController, :create_list) | |||
put("/lists/:id", MastodonAPIController, :rename_list) | |||
delete("/lists/:id", ListController, :delete) | |||
post("/lists", ListController, :create) | |||
put("/lists/:id", ListController, :update) | |||
post("/lists/:id/accounts", MastodonAPIController, :add_to_list) | |||
delete("/lists/:id/accounts", MastodonAPIController, :remove_from_list) | |||
post("/lists/:id/accounts", ListController, :add_to_list) | |||
delete("/lists/:id/accounts", ListController, :remove_from_list) | |||
post("/filters", MastodonAPIController, :create_filter) | |||
get("/filters/:id", MastodonAPIController, :get_filter) | |||
@@ -15,6 +15,13 @@ defmodule Pleroma.ListTest do | |||
assert title == "title" | |||
end | |||
test "validates title" do | |||
user = insert(:user) | |||
assert {:error, changeset} = Pleroma.List.create("", user) | |||
assert changeset.errors == [title: {"can't be blank", [validation: :required]}] | |||
end | |||
test "getting a list not belonging to the user" do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
@@ -207,13 +207,15 @@ defmodule Pleroma.Factory do | |||
object = Object.normalize(note_activity) | |||
user = insert(:user) | |||
data = %{ | |||
"id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(), | |||
"actor" => user.ap_id, | |||
"type" => "Like", | |||
"object" => object.data["id"], | |||
"published_at" => DateTime.utc_now() |> DateTime.to_iso8601() | |||
} | |||
data = | |||
%{ | |||
"id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(), | |||
"actor" => user.ap_id, | |||
"type" => "Like", | |||
"object" => object.data["id"], | |||
"published_at" => DateTime.utc_now() |> DateTime.to_iso8601() | |||
} | |||
|> Map.merge(attrs[:data_attrs] || %{}) | |||
%Pleroma.Activity{ | |||
data: data | |||
@@ -21,6 +21,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do | |||
:ok | |||
end | |||
clear_config([:instance, :federating]) | |||
describe "streaming out participations" do | |||
test "it streams them out" do | |||
user = insert(:user) | |||
@@ -698,6 +700,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do | |||
end | |||
describe "like an object" do | |||
test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do | |||
Pleroma.Config.put([:instance, :federating], true) | |||
note_activity = insert(:note_activity) | |||
assert object_activity = Object.normalize(note_activity) | |||
user = insert(:user) | |||
{:ok, like_activity, _object} = ActivityPub.like(user, object_activity) | |||
assert called(Pleroma.Web.Federator.publish(like_activity, 5)) | |||
end | |||
test "returns exist activity if object already liked" do | |||
note_activity = insert(:note_activity) | |||
assert object_activity = Object.normalize(note_activity) | |||
user = insert(:user) | |||
{:ok, like_activity, _object} = ActivityPub.like(user, object_activity) | |||
{:ok, like_activity_exist, _object} = ActivityPub.like(user, object_activity) | |||
assert like_activity == like_activity_exist | |||
end | |||
test "adds a like activity to the db" do | |||
note_activity = insert(:note_activity) | |||
assert object = Object.normalize(note_activity) | |||
@@ -728,6 +753,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do | |||
end | |||
describe "unliking" do | |||
test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do | |||
Pleroma.Config.put([:instance, :federating], true) | |||
note_activity = insert(:note_activity) | |||
object = Object.normalize(note_activity) | |||
user = insert(:user) | |||
{:ok, object} = ActivityPub.unlike(user, object) | |||
refute called(Pleroma.Web.Federator.publish()) | |||
{:ok, _like_activity, object} = ActivityPub.like(user, object) | |||
assert object.data["like_count"] == 1 | |||
{:ok, unlike_activity, _, object} = ActivityPub.unlike(user, object) | |||
assert object.data["like_count"] == 0 | |||
assert called(Pleroma.Web.Federator.publish(unlike_activity, 5)) | |||
end | |||
test "unliking a previously liked object" do | |||
note_activity = insert(:note_activity) | |||
object = Object.normalize(note_activity) | |||
@@ -14,6 +14,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do | |||
import Pleroma.Factory | |||
require Pleroma.Constants | |||
describe "fetch the latest Follow" do | |||
test "fetches the latest Follow activity" do | |||
%Activity{data: %{"type" => "Follow"}} = activity = insert(:follow_activity) | |||
@@ -87,6 +89,32 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do | |||
end | |||
end | |||
describe "make_unlike_data/3" do | |||
test "returns data for unlike activity" do | |||
user = insert(:user) | |||
like_activity = insert(:like_activity, data_attrs: %{"context" => "test context"}) | |||
assert Utils.make_unlike_data(user, like_activity, nil) == %{ | |||
"type" => "Undo", | |||
"actor" => user.ap_id, | |||
"object" => like_activity.data, | |||
"to" => [user.follower_address, like_activity.data["actor"]], | |||
"cc" => [Pleroma.Constants.as_public()], | |||
"context" => like_activity.data["context"] | |||
} | |||
assert Utils.make_unlike_data(user, like_activity, "9mJEZK0tky1w2xD2vY") == %{ | |||
"type" => "Undo", | |||
"actor" => user.ap_id, | |||
"object" => like_activity.data, | |||
"to" => [user.follower_address, like_activity.data["actor"]], | |||
"cc" => [Pleroma.Constants.as_public()], | |||
"context" => like_activity.data["context"], | |||
"id" => "9mJEZK0tky1w2xD2vY" | |||
} | |||
end | |||
end | |||
describe "make_like_data" do | |||
setup do | |||
user = insert(:user) | |||
@@ -299,4 +327,78 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do | |||
assert Repo.get(Activity, follow_activity_two.id).data["state"] == "reject" | |||
end | |||
end | |||
describe "update_element_in_object/3" do | |||
test "updates likes" do | |||
user = insert(:user) | |||
activity = insert(:note_activity) | |||
object = Object.normalize(activity) | |||
assert {:ok, updated_object} = | |||
Utils.update_element_in_object( | |||
"like", | |||
[user.ap_id], | |||
object | |||
) | |||
assert updated_object.data["likes"] == [user.ap_id] | |||
assert updated_object.data["like_count"] == 1 | |||
end | |||
end | |||
describe "add_like_to_object/2" do | |||
test "add actor to likes" do | |||
user = insert(:user) | |||
user2 = insert(:user) | |||
object = insert(:note) | |||
assert {:ok, updated_object} = | |||
Utils.add_like_to_object( | |||
%Activity{data: %{"actor" => user.ap_id}}, | |||
object | |||
) | |||
assert updated_object.data["likes"] == [user.ap_id] | |||
assert updated_object.data["like_count"] == 1 | |||
assert {:ok, updated_object2} = | |||
Utils.add_like_to_object( | |||
%Activity{data: %{"actor" => user2.ap_id}}, | |||
updated_object | |||
) | |||
assert updated_object2.data["likes"] == [user2.ap_id, user.ap_id] | |||
assert updated_object2.data["like_count"] == 2 | |||
end | |||
end | |||
describe "remove_like_from_object/2" do | |||
test "removes ap_id from likes" do | |||
user = insert(:user) | |||
user2 = insert(:user) | |||
object = insert(:note, data: %{"likes" => [user.ap_id, user2.ap_id], "like_count" => 2}) | |||
assert {:ok, updated_object} = | |||
Utils.remove_like_from_object( | |||
%Activity{data: %{"actor" => user.ap_id}}, | |||
object | |||
) | |||
assert updated_object.data["likes"] == [user2.ap_id] | |||
assert updated_object.data["like_count"] == 1 | |||
end | |||
end | |||
describe "get_existing_like/2" do | |||
test "fetches existing like" do | |||
note_activity = insert(:note_activity) | |||
assert object = Object.normalize(note_activity) | |||
user = insert(:user) | |||
refute Utils.get_existing_like(user.ap_id, object) | |||
{:ok, like_activity, _object} = ActivityPub.like(user, object) | |||
assert ^like_activity = Utils.get_existing_like(user.ap_id, object) | |||
end | |||
end | |||
end |
@@ -0,0 +1,166 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.MastodonAPI.ListControllerTest do | |||
use Pleroma.Web.ConnCase | |||
alias Pleroma.Repo | |||
import Pleroma.Factory | |||
test "creating a list", %{conn: conn} do | |||
user = insert(:user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/lists", %{"title" => "cuties"}) | |||
assert %{"title" => title} = json_response(conn, 200) | |||
assert title == "cuties" | |||
end | |||
test "renders error for invalid params", %{conn: conn} do | |||
user = insert(:user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/lists", %{"title" => nil}) | |||
assert %{"error" => "can't be blank"} == json_response(conn, :unprocessable_entity) | |||
end | |||
test "listing a user's lists", %{conn: conn} do | |||
user = insert(:user) | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/lists", %{"title" => "cuties"}) | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/lists", %{"title" => "cofe"}) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/api/v1/lists") | |||
assert [ | |||
%{"id" => _, "title" => "cofe"}, | |||
%{"id" => _, "title" => "cuties"} | |||
] = json_response(conn, :ok) | |||
end | |||
test "adding users to a list", %{conn: conn} do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("name", user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) | |||
assert %{} == json_response(conn, 200) | |||
%Pleroma.List{following: following} = Pleroma.List.get(list.id, user) | |||
assert following == [other_user.follower_address] | |||
end | |||
test "removing users from a list", %{conn: conn} do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
third_user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("name", user) | |||
{:ok, list} = Pleroma.List.follow(list, other_user) | |||
{:ok, list} = Pleroma.List.follow(list, third_user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> delete("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) | |||
assert %{} == json_response(conn, 200) | |||
%Pleroma.List{following: following} = Pleroma.List.get(list.id, user) | |||
assert following == [third_user.follower_address] | |||
end | |||
test "listing users in a list", %{conn: conn} do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("name", user) | |||
{:ok, list} = Pleroma.List.follow(list, other_user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) | |||
assert [%{"id" => id}] = json_response(conn, 200) | |||
assert id == to_string(other_user.id) | |||
end | |||
test "retrieving a list", %{conn: conn} do | |||
user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("name", user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/api/v1/lists/#{list.id}") | |||
assert %{"id" => id} = json_response(conn, 200) | |||
assert id == to_string(list.id) | |||
end | |||
test "renders 404 if list is not found", %{conn: conn} do | |||
user = insert(:user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/api/v1/lists/666") | |||
assert %{"error" => "List not found"} = json_response(conn, :not_found) | |||
end | |||
test "renaming a list", %{conn: conn} do | |||
user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("name", user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> put("/api/v1/lists/#{list.id}", %{"title" => "newname"}) | |||
assert %{"title" => name} = json_response(conn, 200) | |||
assert name == "newname" | |||
end | |||
test "validates title when renaming a list", %{conn: conn} do | |||
user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("name", user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> put("/api/v1/lists/#{list.id}", %{"title" => " "}) | |||
assert %{"error" => "can't be blank"} == json_response(conn, :unprocessable_entity) | |||
end | |||
test "deleting a list", %{conn: conn} do | |||
user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("name", user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> delete("/api/v1/lists/#{list.id}") | |||
assert %{} = json_response(conn, 200) | |||
assert is_nil(Repo.get(Pleroma.List, list.id)) | |||
end | |||
end |
@@ -927,106 +927,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do | |||
end | |||
end | |||
describe "lists" do | |||
test "creating a list", %{conn: conn} do | |||
user = insert(:user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/lists", %{"title" => "cuties"}) | |||
assert %{"title" => title} = json_response(conn, 200) | |||
assert title == "cuties" | |||
end | |||
test "adding users to a list", %{conn: conn} do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("name", user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> post("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) | |||
assert %{} == json_response(conn, 200) | |||
%Pleroma.List{following: following} = Pleroma.List.get(list.id, user) | |||
assert following == [other_user.follower_address] | |||
end | |||
test "removing users from a list", %{conn: conn} do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
third_user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("name", user) | |||
{:ok, list} = Pleroma.List.follow(list, other_user) | |||
{:ok, list} = Pleroma.List.follow(list, third_user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> delete("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) | |||
assert %{} == json_response(conn, 200) | |||
%Pleroma.List{following: following} = Pleroma.List.get(list.id, user) | |||
assert following == [third_user.follower_address] | |||
end | |||
test "listing users in a list", %{conn: conn} do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("name", user) | |||
{:ok, list} = Pleroma.List.follow(list, other_user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) | |||
assert [%{"id" => id}] = json_response(conn, 200) | |||
assert id == to_string(other_user.id) | |||
end | |||
test "retrieving a list", %{conn: conn} do | |||
user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("name", user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> get("/api/v1/lists/#{list.id}") | |||
assert %{"id" => id} = json_response(conn, 200) | |||
assert id == to_string(list.id) | |||
end | |||
test "renaming a list", %{conn: conn} do | |||
user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("name", user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> put("/api/v1/lists/#{list.id}", %{"title" => "newname"}) | |||
assert %{"title" => name} = json_response(conn, 200) | |||
assert name == "newname" | |||
end | |||
test "deleting a list", %{conn: conn} do | |||
user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("name", user) | |||
conn = | |||
conn | |||
|> assign(:user, user) | |||
|> delete("/api/v1/lists/#{list.id}") | |||
assert %{} = json_response(conn, 200) | |||
assert is_nil(Repo.get(Pleroma.List, list.id)) | |||
end | |||
describe "list timelines" do | |||
test "list timeline", %{conn: conn} do | |||
user = insert(:user) | |||
other_user = insert(:user) | |||
@@ -7,7 +7,7 @@ defmodule Pleroma.Web.MastodonAPI.ListViewTest do | |||
import Pleroma.Factory | |||
alias Pleroma.Web.MastodonAPI.ListView | |||
test "Represent a list" do | |||
test "show" do | |||
user = insert(:user) | |||
title = "mortal enemies" | |||
{:ok, list} = Pleroma.List.create(title, user) | |||
@@ -17,6 +17,16 @@ defmodule Pleroma.Web.MastodonAPI.ListViewTest do | |||
title: title | |||
} | |||
assert expected == ListView.render("list.json", %{list: list}) | |||
assert expected == ListView.render("show.json", %{list: list}) | |||
end | |||
test "index" do | |||
user = insert(:user) | |||
{:ok, list} = Pleroma.List.create("my list", user) | |||
{:ok, list2} = Pleroma.List.create("cofe", user) | |||
assert [%{id: _, title: "my list"}, %{id: _, title: "cofe"}] = | |||
ListView.render("index.json", lists: [list, list2]) | |||
end | |||
end |