Files
hms-licht-ton/backend/tests/test_models.py
T
A0 Implementation Engineer e62ece1c06 feat: T03 backend core – FastAPI + DB models + Equipment API + Redis cache + health + tests
- FastAPI app with CORS, lifespan handlers
- Pydantic Settings config (DB, Redis, CORS, SMTP, JWT, Rentman)
- SQLAlchemy async engine + session (DeclarativeBase)
- 6 DB models: EquipmentCache, RentalRequest, RentalRequestItem, Contact, AdminUser, SyncLog
- Pydantic schemas: EquipmentItem, EquipmentDetail, PaginatedEquipment, ContactCreate, ContactResponse
- Redis cache helper: set/get/delete_pattern, rate limiting, equipment key builders
- Equipment router: list (search/category/sort/pagination), detail, categories – all cached
- Contact router: POST with Pydantic validation + rate limiting (5/min)
- Health router: GET /api/health with DB + Redis status
- 28 pytest tests (all pass, 90% coverage)
- Dockerfile, requirements.txt, pytest.ini, test_report.md
2026-07-09 01:26:45 +02:00

99 lines
3.1 KiB
Python

"""Tests for SQLAlchemy model definitions and table creation."""
from datetime import date
import pytest
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from app.models.admin_user import AdminUser
from app.models.contact import Contact
from app.models.equipment import EquipmentCache
from app.models.rental_request import RentalRequest, RentalRequestItem
from app.models.sync_log import SyncLog
@pytest.mark.asyncio
async def test_equipment_cache_model(db_session: AsyncSession):
"""EquipmentCache model can be instantiated and queried."""
item = EquipmentCache(
rentman_id="999", name="Test Speaker", number="TS-001",
category="Lautsprecher", description="Test item",
)
db_session.add(item)
await db_session.commit()
await db_session.refresh(item)
assert item.id is not None
assert item.rentman_id == "999"
assert item.available is True
@pytest.mark.asyncio
async def test_rental_request_model(db_session: AsyncSession):
"""RentalRequest and RentalRequestItem models work with relationships."""
req = RentalRequest(
reference_number="HMS-2026-00001",
event_name="Test Event",
date_start=date(2026, 8, 15),
date_end=date(2026, 8, 16),
contact_name="Max Mustermann",
contact_email="max@example.com",
)
db_session.add(req)
await db_session.commit()
await db_session.refresh(req)
item = RentalRequestItem(
rental_request_id=req.id,
equipment_name="Test Speaker",
quantity=2,
)
db_session.add(item)
await db_session.commit()
# Use explicit query with selectinload to avoid lazy loading in async
result = await db_session.execute(
select(RentalRequest).options(selectinload(RentalRequest.items)).where(RentalRequest.id == req.id)
)
loaded_req = result.scalar_one()
assert len(loaded_req.items) == 1
assert loaded_req.items[0].quantity == 2
@pytest.mark.asyncio
async def test_contact_model(db_session: AsyncSession):
"""Contact model can store a contact form submission."""
contact = Contact(
name="Max", email="max@example.com", message="Hello",
privacy_consent=True,
)
db_session.add(contact)
await db_session.commit()
await db_session.refresh(contact)
assert contact.id is not None
assert contact.email_sent is False
@pytest.mark.asyncio
async def test_admin_user_model(db_session: AsyncSession):
"""AdminUser model stores username and password hash."""
user = AdminUser(username="admin", password_hash="hashed_secret")
db_session.add(user)
await db_session.commit()
await db_session.refresh(user)
assert user.id is not None
assert user.username == "admin"
@pytest.mark.asyncio
async def test_sync_log_model(db_session: AsyncSession):
"""SyncLog model stores sync metadata."""
log = SyncLog(sync_type="equipment", status="running")
db_session.add(log)
await db_session.commit()
await db_session.refresh(log)
assert log.id is not None
assert log.status == "running"
assert log.items_processed == 0