From f868a6b4243e21bb51b9e51917950416a0003a48 Mon Sep 17 00:00:00 2001 From: Nelson Kopliku Date: Thu, 8 Aug 2024 15:34:38 +0200 Subject: [PATCH] Expose info about existence of prev/next page --- .../openapi/v1/schema/activity_log.ex | 104 ++++++++++++++---- lib/trento_web/views/v1/activity_log_view.ex | 6 +- test/trento/activity_log_test.exs | 31 ++++++ 3 files changed, 116 insertions(+), 25 deletions(-) diff --git a/lib/trento_web/openapi/v1/schema/activity_log.ex b/lib/trento_web/openapi/v1/schema/activity_log.ex index ca9a087556..fd84bd5b68 100644 --- a/lib/trento_web/openapi/v1/schema/activity_log.ex +++ b/lib/trento_web/openapi/v1/schema/activity_log.ex @@ -6,37 +6,95 @@ defmodule TrentoWeb.OpenApi.V1.Schema.ActivityLog do defmodule ActivityLogEntries do @moduledoc false - OpenApiSpex.schema(%{ - type: :array, - items: %Schema{ - title: "ActivityLogEntries", - type: :object, + OpenApiSpex.schema( + %{ + type: :array, + items: %Schema{ + title: "ActivityLogEntries", + type: :object, + additionalProperties: false, + properties: %{ + id: %Schema{ + type: :string, + format: :uuid, + description: "UUID (v4) of Activity Log entry." + }, + type: %Schema{ + type: :string, + description: "Type of Activity Log entry." + }, + actor: %Schema{ + type: :string, + description: "Actor causing an Activity Log entry. E.g. System or a specific user." + }, + metadata: %Schema{ + type: :object + }, + occurred_on: %Schema{ + type: :string, + description: "Timestamp upon Activity Log entry insertion." + } + }, + required: [:id, :type, :actor, :metadata, :occurred_on] + } + }, + struct?: false + ) + end + + defmodule Pagination do + @moduledoc false + OpenApiSpex.schema( + %{ + title: "Pagination", + description: "Pagination metadata for the current list.", additionalProperties: false, + type: :object, properties: %{ - id: %Schema{ + start_cursor: %Schema{ type: :string, - format: :uuid, - description: "UUID (v4) of Activity Log entry." + description: "Cursor pointing to the start of the list.", + nullable: true }, - type: %Schema{ + end_cursor: %Schema{ type: :string, - description: "Type of Activity Log entry." + description: "Cursor pointing to the end of the list.", + nullable: true }, - actor: %Schema{ - type: :string, - description: "Actor causing an Activity Log entry. E.g. System or a specific user." + has_next_page: %Schema{ + type: :boolean, + description: "Flag indicating if there are more pages after the current one.", + nullable: false }, - metadata: %Schema{ - type: :object + has_previous_page: %Schema{ + type: :boolean, + description: "Flag indicating if there are more pages before the current one.", + nullable: false }, - occurred_on: %Schema{ - type: :string, - description: "Timestamp upon Activity Log entry insertion." + first: %Schema{ + type: :integer, + description: + "Number of elements requested from the beginning of the list (forward navigation).", + nullable: true + }, + last: %Schema{ + type: :integer, + description: + "Number of elements requested from the end of the list (backward navigation).", + nullable: true } }, - required: [:id, :type, :actor, :metadata, :occurred_on] - } - }) + required: [ + :start_cursor, + :end_cursor, + :has_next_page, + :has_previous_page, + :first, + :last + ] + }, + struct?: false + ) end defmodule ActivityLog do @@ -49,9 +107,7 @@ defmodule TrentoWeb.OpenApi.V1.Schema.ActivityLog do type: :object, properties: %{ data: ActivityLogEntries, - pagination: %Schema{ - type: :object - } + pagination: Pagination }, required: [:data, :pagination] }, diff --git a/lib/trento_web/views/v1/activity_log_view.ex b/lib/trento_web/views/v1/activity_log_view.ex index 1e6f31548a..cb93537855 100644 --- a/lib/trento_web/views/v1/activity_log_view.ex +++ b/lib/trento_web/views/v1/activity_log_view.ex @@ -23,6 +23,8 @@ defmodule TrentoWeb.V1.ActivityLogView do %{ end_cursor: end_cursor, start_cursor: start_cursor, + has_next_page?: has_next_page, + has_previous_page?: has_previous_page, flop: %{ first: first, last: last @@ -34,7 +36,9 @@ defmodule TrentoWeb.V1.ActivityLogView do start_cursor: start_cursor, end_cursor: end_cursor, first: first, - last: last + last: last, + has_next_page: has_next_page, + has_previous_page: has_previous_page } end end diff --git a/test/trento/activity_log_test.exs b/test/trento/activity_log_test.exs index 539bab1c9c..9a13100f56 100644 --- a/test/trento/activity_log_test.exs +++ b/test/trento/activity_log_test.exs @@ -295,5 +295,36 @@ defmodule Trento.ActivityLogTest do assert length(next_logs_alt) == length(next_logs) assert next_logs_alt == next_logs end + + test "should expose information about the existence of previous or next page to navigate to" do + insert_list(100, :activity_log_entry) + + assert {:ok, _, + %{has_previous_page?: false, has_next_page?: true, start_cursor: start_cursor}} = + ActivityLog.list_activity_log(%{first: 5}) + + assert {:ok, [], + %{ + end_cursor: nil, + start_cursor: nil + }} = + ActivityLog.list_activity_log(%{last: 5, before: start_cursor}) + + assert {:ok, _, %{has_previous_page?: true, has_next_page?: true}} = + ActivityLog.list_activity_log(%{first: 5, after: start_cursor}) + + assert {:ok, _, %{has_previous_page?: true, has_next_page?: false, end_cursor: end_cursor}} = + ActivityLog.list_activity_log(%{last: 5}) + + assert {:ok, [], + %{ + end_cursor: nil, + start_cursor: nil + }} = + ActivityLog.list_activity_log(%{first: 5, after: end_cursor}) + + assert {:ok, _, %{has_previous_page?: true, has_next_page?: true}} = + ActivityLog.list_activity_log(%{last: 5, before: end_cursor}) + end end end