Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions api/schemas/pagination.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from enum import Enum
from typing import Any
from typing import Annotated, Any

from pydantic import BaseModel, Field
from pydantic import BaseModel, BeforeValidator, Field

from api.environment import settings

Expand All @@ -13,10 +13,22 @@ class PaginationOrderOptions(str, Enum):
desc = "desc"


def limit_to_max_pagination_value(value: Any) -> int:
"""Ensures that users cannot exceed the maximum pagination limit

Needs to be run prior to normal validation to prevent a validation error from getting thrown
by the framework.
"""
value = int(value)
if value > settings.pagination_max_limit:
value = settings.pagination_max_limit
return value


class PaginationOptions(BaseModel):
"""Query string options to adjust pagination"""

limit: int = Field(
limit: Annotated[int, BeforeValidator(limit_to_max_pagination_value)] = Field(
settings.pagination_default_limit, gt=0, le=settings.pagination_max_limit
)
offset: int = 0
Expand Down
15 changes: 14 additions & 1 deletion api/tests/cards/test_cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from api.models.release import Release, UserRelease
from api.services.card import create_card

from ..utils import create_user_token
from ..utils import create_user_token, monkeypatch_settings


def names_from_results(response):
Expand Down Expand Up @@ -210,6 +210,19 @@ def test_pagination_paging(client: TestClient, session: db.Session):
assert data["next"] is not None


def test_pagination_exceed_limit(client: TestClient, session: db.Session, monkeypatch):
"""Exceeding the max pagination limit results in getting the max limit back"""
monkeypatch_settings(
monkeypatch, {"pagination_max_limit": 4, "pagination_default_limit": 2}
)
response = client.get("/v2/cards", params={"limit": 5})
assert response.status_code == 200
data = response.json()
assert data["count"] == 10
assert len(data["results"]) == 4
assert data["next"] is not None


def test_pagination_negative_offsets(client: TestClient, session: db.Session):
"""A number that would result in a negative offset must result in no offset"""
# Verify that previous links work properly with arbitrary offsets that would make them negative
Expand Down