--- /dev/null
+# 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
|> 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 =
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
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)
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)
--- /dev/null
+# 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
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)
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)
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