Items 1-5, 9, 11 from denya-wahab-feedback-s2: - Category.show_in_form (alert-only flag): Gas Leak hidden from issue picker but kept urgent for SLA/alert and reporting; emergency quick path on the new-issue form creates urgent tickets via include_hidden categories. - Seed: Aluminum/Glass, Carpentry, Mould & Damp (Medium default) maintenance categories; Lost Property renamed Missing Item (+ sub). - One alembic migration: add show_in_form (backfill True, Gas Leak False) + data rename Lost Property -> Missing Item. - Property -> Building -> Apartment cascade with searchable apartment combobox on the new-issue form and ticket list filters; /api/tickets/units gains building filter + /units/grouped variant; /api/tickets gains additive building/unit_id filters. apartment_mapping.json committed (deterministic). - Group-by-priority toggle on /tickets (four sections + unknown bucket, age-sortable, composes with filters, URL deep links), FM dashboard active tickets, and CS dashboard priority card click-through. - Tests: 13 new (category visibility, seed idempotency/sync, unit grouping, ticket building/unit filters).
68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
"""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 (same data as the committed
|
|
# apartment_mapping.json, kept deterministic for tests)
|
|
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
|