Skip to content

Commit

Permalink
Test case for paginating multiple response types
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaoming committed May 7, 2024
1 parent 9dcebe9 commit 9b5adac
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 10 deletions.
28 changes: 18 additions & 10 deletions ninja/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@
from abc import ABC, abstractmethod
from functools import partial, wraps
from math import inf
from typing import Any, AsyncGenerator, Callable, Iterator, List, Optional, Tuple, Type, Union
from typing import (
Any,
AsyncGenerator,
Callable,
Iterator,
List,
Optional,
Tuple,
Type,
Union,
)

from django.db.models import QuerySet
from django.http import HttpRequest
Expand Down Expand Up @@ -204,7 +214,7 @@ async def view_with_pagination(request: HttpRequest, **kwargs: Any) -> Any:
if type(items) is tuple and len(items) == 2:
status_code = items[0]
items = items[1]

result = await paginator.apaginate_queryset(
items, pagination=pagination_params, request=request, **kwargs
)
Expand Down Expand Up @@ -236,7 +246,6 @@ def view_with_pagination(request: HttpRequest, **kwargs: Any) -> Any:
status_code = None

# The decorated view function has returned <status_code>, items
print(type(items))
if type(items) is tuple and len(items) == 2:
status_code = items[0]
items = items[1]
Expand All @@ -249,7 +258,7 @@ def view_with_pagination(request: HttpRequest, **kwargs: Any) -> Any:
result[paginator.items_attribute]
)
# ^ forcing queryset evaluation #TODO: check why pydantic did not do it here

if status_code is not None:
return status_code, result
else:
Expand Down Expand Up @@ -297,9 +306,8 @@ class PagedSome:
items: List[Some]
count: int
"""

for status_code, item_schema in _find_collection_response(op):

for status_code, item_schema in _find_collection_response(op):
# Switching schema to Output schema
try:
new_name = f"Paged{item_schema.__name__}"
Expand Down Expand Up @@ -331,14 +339,14 @@ def _find_collection_response(op: Operation) -> Iterator[Tuple[int, Any]]:
continue

model = resp_model.__annotations__["response"]

# It's possible that we could restrict this to only extend
# response codes 2xx
if is_collection_type(model):
item_schema = get_collection_args(model)[0]
yield code, item_schema

if item_schema is None:
raise ConfigError(
f'"{op.view_func}" has no collection response (e.g. response=List[SomeSchema])'
)
raise ConfigError(
f'"{op.view_func}" has no collection response (e.g. response=List[SomeSchema])'
)
18 changes: 18 additions & 0 deletions tests/test_pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ def items_9(request):
return list(range(100))


@api.get("/items_12", response={101: int, 200: List[Any], 220: List[Any]})
@paginate(PageNumberPagination, page_size=10, pass_parameter="page_info")
def items_12(request, **kwargs):
return 220, ITEMS + [kwargs["page_info"]]


client = TestClient(api)


Expand Down Expand Up @@ -326,6 +332,18 @@ def test_case9():
}


def test_case12_status_code():
page = 11
response = client.get(f"/items_12?page={page}")
assert response.status_code == 220
assert response.json() == {"items": [{"page": 11}], "count": 101}

schema = api.get_openapi_schema()["paths"]["/api/items_12"]["get"]

assert schema["responses"][200] == {'description': 'OK', 'content': {'application/json': {'schema': {'$ref': '#/components/schemas/PagedAny'}}}}
assert schema["responses"][220] == {'description': 'Unknown Status Code', 'content': {'application/json': {'schema': {'$ref': '#/components/schemas/PagedAny'}}}}


@override_settings(NINJA_PAGINATION_MAX_LIMIT=1000)
def test_10_max_limit_set():
# reload to apply django settings
Expand Down

0 comments on commit 9b5adac

Please sign in to comment.