Skip to content
Open
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
87 changes: 87 additions & 0 deletions apps/common/tests/pagination_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import typing
from unittest.mock import patch

from strawberry_django.settings import DEFAULT_DJANGO_SETTINGS

from apps.project.factories import OrganizationFactory, ProjectFactory
from apps.project.models import ProjectStatusEnum
from apps.user.factories import UserFactory
from main.tests import TestCase

_MAX_LIMIT = 5


def _patched_settings():
return {**DEFAULT_DJANGO_SETTINGS, "PAGINATION_MAX_LIMIT": _MAX_LIMIT}


QUERY_WITH_PAGINATION = """
query($pagination: OffsetPaginationInput) {
publicProjects(pagination: $pagination) {
totalCount
pageInfo {
limit
offset
}
results {
id
}
}
}
"""

QUERY_NO_PAGINATION = """
query {
publicProjects {
totalCount
results {
id
}
}
}
"""


@patch("strawberry_django.pagination.strawberry_django_settings", _patched_settings)
class TestPaginationMaxLimit(TestCase):
"""Verify that PAGINATION_MAX_LIMIT is enforced on paginated endpoints."""

@classmethod
@typing.override
def setUpTestData(cls):
user = UserFactory.create()
user_resource_kwargs = dict(
created_by=user,
modified_by=user,
)
organization = OrganizationFactory.create(**user_resource_kwargs)
ProjectFactory.create_batch(
7,
status=ProjectStatusEnum.PUBLISHED,
requesting_organization=organization,
**user_resource_kwargs,
)

def test_limit_above_max_is_capped(self):
resp = self.query_check(QUERY_WITH_PAGINATION, variables={"pagination": {"limit": 10, "offset": 0}})
data = resp["data"]["publicProjects"]
assert data["totalCount"] == 7
assert len(data["results"]) == _MAX_LIMIT

def test_limit_at_max_is_accepted(self):
resp = self.query_check(QUERY_WITH_PAGINATION, variables={"pagination": {"limit": _MAX_LIMIT, "offset": 0}})
data = resp["data"]["publicProjects"]
assert data["pageInfo"]["limit"] == _MAX_LIMIT
assert len(data["results"]) == _MAX_LIMIT

def test_limit_below_max_is_unchanged(self):
resp = self.query_check(QUERY_WITH_PAGINATION, variables={"pagination": {"limit": 3, "offset": 0}})
data = resp["data"]["publicProjects"]
assert data["pageInfo"]["limit"] == 3
assert len(data["results"]) == 3

def test_no_pagination_uses_default_limit(self):
resp = self.query_check(QUERY_NO_PAGINATION)
data = resp["data"]["publicProjects"]
assert data["totalCount"] == 7
assert len(data["results"]) == _MAX_LIMIT
1 change: 1 addition & 0 deletions main/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ def urlparse(value) -> ParseResult:
"TYPE_DESCRIPTION_FROM_MODEL_DOCSTRING": True,
"MUTATIONS_DEFAULT_HANDLE_ERRORS": True,
"PAGINATION_DEFAULT_LIMIT": 20,
"PAGINATION_MAX_LIMIT": 100,
"DEFAULT_PK_FIELD_NAME": "id",
}

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ dependencies = [
"gunicorn~=20.1.0",
"psycopg2-binary",
"sentry-sdk",
"strawberry-graphql-django~=0.57.0",
"strawberry-graphql-django~=0.86.0",
"django-choices-field", # Required by strawberry-graphql-django
"django-health-check",
"cachetools",
Expand Down
1 change: 1 addition & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2702,6 +2702,7 @@ union UpdateTutorialPayload = OperationInfo | TutorialTypeMutationResponseType

union UpdateTutorialStatusPayload = OperationInfo | TutorialTypeMutationResponseType

"""Represents a file upload."""
scalar Upload

"""
Expand Down
Loading
Loading