Files
geointel/backend/tests/test_detection_result_pagination.py
T
Jens faeb58ef6d
GeoIntel release gates / Compile, test, contracts and builds (push) Successful in 1m49s
GeoIntel release gates / Python and npm vulnerability policy (push) Successful in 21s
GeoIntel release gates / Production AI image, SBOM and container scan (push) Successful in 5m39s
GeoIntel release gates / Deploy exact gated revision to Unraid (push) Failing after 58m43s
Initial public release
2026-08-31 21:56:53 +02:00

87 lines
2.5 KiB
Python

"""Loading a run's results must not depend on the run being small.
``/detection/runs/{id}/detections`` and its GeoJSON sibling returned every
persisted detection. A regional run holds tens of thousands, so the endpoints
the map and the results table call after every run grew without bound. The
counts stay complete; what is transferred does not.
"""
from __future__ import annotations
import uuid
import pytest
from app.services.detection_service import DetectionService
class _Detection:
def __init__(self, index: int) -> None:
self.id = uuid.uuid4()
self.index = index
def _rows(count: int) -> list[_Detection]:
return [_Detection(index) for index in range(count)]
def test_a_page_is_returned_with_the_complete_total() -> None:
page, total, truncated = DetectionService.paginate(_rows(1_000), limit=100, offset=0)
assert len(page) == 100
assert total == 1_000
assert truncated is True
def test_the_offset_walks_the_population() -> None:
page, total, _ = DetectionService.paginate(_rows(10), limit=3, offset=6)
assert [row.index for row in page] == [6, 7, 8]
assert total == 10
def test_an_offset_past_the_end_yields_an_empty_page_not_an_error() -> None:
page, total, truncated = DetectionService.paginate(_rows(5), limit=10, offset=50)
assert page == []
assert total == 5
assert truncated is True
def test_a_population_inside_one_page_is_not_reported_as_truncated() -> None:
page, total, truncated = DetectionService.paginate(_rows(7), limit=100, offset=0)
assert len(page) == 7
assert total == 7
assert truncated is False
def test_a_zero_limit_returns_everything_for_callers_that_need_it() -> None:
page, total, truncated = DetectionService.paginate(_rows(2_500), limit=0, offset=0)
assert len(page) == 2_500
assert total == 2_500
assert truncated is False
def test_a_negative_offset_is_treated_as_the_start() -> None:
page, _, _ = DetectionService.paginate(_rows(4), limit=2, offset=-5)
assert [row.index for row in page] == [0, 1]
@pytest.mark.parametrize("limit", [1, 2, 3])
def test_paging_covers_the_population_exactly_once(limit: int) -> None:
rows = _rows(7)
seen: list[int] = []
offset = 0
while True:
page, total, _ = DetectionService.paginate(rows, limit=limit, offset=offset)
if not page:
break
seen.extend(row.index for row in page)
offset += limit
assert seen == list(range(7))
assert total == 7