From eb1a29640f2d7c7d3daca0626b2beb623903c9cd Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Tue, 8 Mar 2022 21:26:05 -0500 Subject: [PATCH] Add pagination to AdminAPI.AnnouncementController.index --- lib/pleroma/announcement.ex | 7 +++ .../controllers/announcement_controller.ex | 9 +++- .../admin/announcement_operation.ex | 16 +++++++ .../announcement_controller_test.exs | 48 +++++++++++++++++++ 4 files changed, 78 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/announcement.ex b/lib/pleroma/announcement.ex index 8c15d5bdf..6c11eff7e 100644 --- a/lib/pleroma/announcement.ex +++ b/lib/pleroma/announcement.ex @@ -61,6 +61,13 @@ def list_all do |> Repo.all() end + def list_paginated(%{limit: limited_number, offset: offset_number}) do + __MODULE__ + |> limit(^limited_number) + |> offset(^offset_number) + |> Repo.all() + end + def get_by_id(id) do Repo.get_by(__MODULE__, id: id) end diff --git a/lib/pleroma/web/admin_api/controllers/announcement_controller.ex b/lib/pleroma/web/admin_api/controllers/announcement_controller.ex index 6195e582a..6ad5fc12c 100644 --- a/lib/pleroma/web/admin_api/controllers/announcement_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/announcement_controller.ex @@ -16,8 +16,13 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementController do defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.Admin.AnnouncementOperation - def index(conn, _params) do - announcements = Announcement.list_all() + defp default_limit, do: 20 + + def index(conn, params) do + limit = Map.get(params, :limit, default_limit()) + offset = Map.get(params, :offset, 0) + + announcements = Announcement.list_paginated(%{limit: limit, offset: offset}) render(conn, "index.json", announcements: announcements) end diff --git a/lib/pleroma/web/api_spec/operations/admin/announcement_operation.ex b/lib/pleroma/web/api_spec/operations/admin/announcement_operation.ex index cdf04d357..58a039e72 100644 --- a/lib/pleroma/web/api_spec/operations/admin/announcement_operation.ex +++ b/lib/pleroma/web/api_spec/operations/admin/announcement_operation.ex @@ -21,8 +21,24 @@ def index_operation do summary: "Retrieve a list of announcements", operationId: "AdminAPI.AnnouncementController.index", security: [%{"oAuth" => ["admin:read"]}], + parameters: [ + Operation.parameter( + :limit, + :query, + %Schema{type: :integer, minimum: 1}, + "the maximum number of announcements to return" + ), + Operation.parameter( + :offset, + :query, + %Schema{type: :integer, minimum: 0}, + "the offset of the first announcement to return" + ) + | admin_api_params() + ], responses: %{ 200 => Operation.response("Response", "application/json", list_of_announcements()), + 400 => Operation.response("Forbidden", "application/json", ApiError), 403 => Operation.response("Forbidden", "application/json", ApiError) } } diff --git a/test/pleroma/web/admin_api/controllers/announcement_controller_test.exs b/test/pleroma/web/admin_api/controllers/announcement_controller_test.exs index c6b2163d0..56da1c6aa 100644 --- a/test/pleroma/web/admin_api/controllers/announcement_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/announcement_controller_test.exs @@ -30,6 +30,54 @@ test "it lists all announcements", %{conn: conn} do assert [%{"id" => ^id}] = response end + + test "it paginates announcements", %{conn: conn} do + _announcements = Enum.map(0..20, fn _ -> insert(:announcement) end) + + response = + conn + |> get("/api/v1/pleroma/admin/announcements") + |> json_response_and_validate_schema(:ok) + + assert length(response) == 20 + end + + test "it paginates announcements with custom params", %{conn: conn} do + announcements = Enum.map(0..20, fn _ -> insert(:announcement) end) + + response = + conn + |> get("/api/v1/pleroma/admin/announcements", limit: 5, offset: 7) + |> json_response_and_validate_schema(:ok) + + assert length(response) == 5 + assert Enum.at(response, 0)["id"] == Enum.at(announcements, 7).id + end + + test "it returns empty list with out-of-bounds offset", %{conn: conn} do + _announcements = Enum.map(0..20, fn _ -> insert(:announcement) end) + + response = + conn + |> get("/api/v1/pleroma/admin/announcements", offset: 21) + |> json_response_and_validate_schema(:ok) + + assert [] = response + end + + test "it rejects invalid pagination params", %{conn: conn} do + conn + |> get("/api/v1/pleroma/admin/announcements", limit: 0) + |> json_response_and_validate_schema(400) + + conn + |> get("/api/v1/pleroma/admin/announcements", limit: -1) + |> json_response_and_validate_schema(400) + + conn + |> get("/api/v1/pleroma/admin/announcements", offset: -1) + |> json_response_and_validate_schema(400) + end end describe "GET /api/v1/pleroma/admin/announcements/:id" do