Files
smart-org/apps/api/tests/test_pagination.py
T
mjalmoudy94 717e53a7ce نسخهٔ وب مستقل — پلتفرم نیروی کار هوش مصنوعی
مخزن اختصاصی برنامهٔ وب؛ محتوای پوشهٔ web در ریشهٔ مخزن قرار گرفت.
تاریخچهٔ پروژهٔ ربات (agy-bot) در این مخزن وجود ندارد و هیچ وابستگی runtime به آن نیست.
2026-10-13 00:39:28 +03:30

97 lines
3.4 KiB
Python

"""§20 — list endpoints are paginated.
Every tenant-scoped list is unbounded in principle: an organization can create
thousands of tasks. Without a page size the API would happily serialize all of
them, so these tests pin the contract that a list is capped and that ``offset``
walks the result set.
"""
from __future__ import annotations
import pytest
import pytest_asyncio
from httpx import AsyncClient
from tests.conftest import auth_header, signup
# Fixtures resolve from conftest by name, so ``seeded`` needs no import here;
# importing it would shadow this parameter (ruff F811) and read as unused (F401).
@pytest_asyncio.fixture(autouse=True)
async def _platform_seed(seeded):
return seeded
async def test_tasks_list_is_paginated(client: AsyncClient):
token = (await signup(client, "page-tasks@example.com"))["access_token"]
headers = auth_header(token)
org_id = (
await client.post("/api/organizations", json={"name": "سازمان صفحه"}, headers=headers)
).json()["id"]
for index in range(5):
created = await client.post(
f"/api/organizations/{org_id}/tasks",
json={"title": f"کار {index}"},
headers=headers,
)
assert created.status_code == 201, created.text
page_one = await client.get(
f"/api/organizations/{org_id}/tasks", params={"limit": 2}, headers=headers
)
assert page_one.status_code == 200, page_one.text
assert len(page_one.json()) == 2, "limit must cap the page size"
page_two = await client.get(
f"/api/organizations/{org_id}/tasks",
params={"limit": 2, "offset": 2},
headers=headers,
)
assert len(page_two.json()) == 2
# Pages must not overlap: offset walks the ordering rather than repeating it.
ids_one = {t["id"] for t in page_one.json()}
ids_two = {t["id"] for t in page_two.json()}
assert not (ids_one & ids_two), "consecutive pages returned the same row"
everything = await client.get(
f"/api/organizations/{org_id}/tasks", params={"limit": 500}, headers=headers
)
assert len(everything.json()) == 5
@pytest.mark.parametrize("bad", [{"limit": 0}, {"limit": 501}, {"offset": -1}])
async def test_out_of_range_pagination_is_rejected(client: AsyncClient, bad: dict):
token = (await signup(client, f"page-bad-{abs(hash(str(bad))) % 10**6}@example.com"))[
"access_token"
]
headers = auth_header(token)
org_id = (
await client.post(
"/api/organizations", json={"name": "سازمان اعتبار"}, headers=headers
)
).json()["id"]
response = await client.get(
f"/api/organizations/{org_id}/tasks", params=bad, headers=headers
)
assert response.status_code == 422, response.text
async def test_projects_and_employees_accept_pagination(client: AsyncClient):
"""The parameter is accepted consistently across the tenant-scoped lists."""
token = (await signup(client, "page-multi@example.com"))["access_token"]
headers = auth_header(token)
org_id = (
await client.post("/api/organizations", json={"name": "سازمان چندگانه"}, headers=headers)
).json()["id"]
for path in ("projects", "employees", "threads", "tasks"):
response = await client.get(
f"/api/organizations/{org_id}/{path}",
params={"limit": 10, "offset": 0},
headers=headers,
)
assert response.status_code == 200, f"{path}: {response.text}"