fix(dashboard): paginate CEO dashboard ticket fetch to respect API cap
The CEO dashboard requested /api/tickets?page_size=500, but the API caps page_size at 200 (le=200 in app/routers/tickets.py), so the request returned 422 and every KPI/chart rendered zeros. - ceo.html: fetch all tickets by looping pages of page_size=200 until total items are collected (with a safety bound), keeping KPIs accurate as volume grows past 200. - tests: add test suite anchoring the pagination contract — page_size=500 returns 422, page_size=200 returns items/total/page/page_size, and a page loop collects every ticket without duplicates. - pyproject: enable pytest-asyncio auto mode and tests/ discovery. - .gitignore: un-ignore committed tests/test_*.py.
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
"""Shared fixtures for the Denya OneCare test suite.
|
||||
|
||||
Sets DATABASE_URL to an isolated temp SQLite file BEFORE importing any app
|
||||
module (the engine is created at import time), then provisions tables and
|
||||
seed data per test.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
_TMP_DIR = tempfile.mkdtemp(prefix="denya-test-")
|
||||
os.environ["DATABASE_URL"] = f"sqlite+aiosqlite:///{_TMP_DIR}/test.db"
|
||||
|
||||
import pytest_asyncio
|
||||
from httpx import ASGITransport, AsyncClient
|
||||
|
||||
from app.core.database import Base, async_session_factory, engine
|
||||
from app.main import app
|
||||
from app.models.ticket import Ticket
|
||||
from app.services.seed import seed_categories, seed_units, seed_users
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def client():
|
||||
"""Async test client with a fresh, seeded database per test."""
|
||||
async with engine.begin() as conn:
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
async with async_session_factory() as session:
|
||||
await seed_users(session)
|
||||
await session.commit()
|
||||
# json_path=None → built-in fallback units (apartment_mapping.json is not committed)
|
||||
await seed_units(session, json_path=None)
|
||||
await session.commit()
|
||||
await seed_categories(session)
|
||||
await session.commit()
|
||||
|
||||
transport = ASGITransport(app=app)
|
||||
async with AsyncClient(transport=transport, base_url="http://test") as c:
|
||||
yield c
|
||||
|
||||
async with engine.begin() as conn:
|
||||
await conn.run_sync(Base.metadata.drop_all)
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def seed_tickets():
|
||||
"""Insert `n` tickets directly into the DB; returns the count inserted."""
|
||||
|
||||
async def _seed(n: int) -> int:
|
||||
async with async_session_factory() as session:
|
||||
for i in range(n):
|
||||
session.add(
|
||||
Ticket(
|
||||
ticket_number=f"PAV-TEST-{i:05d}",
|
||||
status="Logged",
|
||||
priority="medium",
|
||||
description=f"Test ticket {i}",
|
||||
)
|
||||
)
|
||||
await session.commit()
|
||||
return n
|
||||
|
||||
return _seed
|
||||
Reference in New Issue
Block a user