"""Shared pytest fixtures for the ``chicken_babies_site`` suite. Key fixtures: - ``db_engine``: a session-scoped SQLAlchemy engine pointed at a temp-file SQLite database. Migrations + seed run once per test session. Per the CLAUDE.md mandate, tests do NOT mock the DB — they use a real SQLite file so behavior matches production. - ``clean_db_engine``: a function-scoped engine with migrations applied but seed NOT run, for tests that need to exercise the first-boot path. """ from __future__ import annotations from pathlib import Path from typing import Iterator import pytest from sqlalchemy import Engine from app.db import build_engine, run_migrations from app.models.seed import run_seed @pytest.fixture(scope="session") def db_engine(tmp_path_factory: pytest.TempPathFactory) -> Iterator[Engine]: """Return a migrated + seeded SQLite engine shared across the session. Uses a real on-disk file (NOT ``:memory:``) because the CLAUDE.md project rules forbid mocking the DB in auth / magic-link tests, and doing the same here keeps the behavior identical to production. """ db_path: Path = tmp_path_factory.mktemp("db") / "test.db" engine = build_engine(f"sqlite:///{db_path}") run_migrations(engine) run_seed(engine) yield engine engine.dispose() @pytest.fixture def clean_db_engine(tmp_path: Path) -> Iterator[Engine]: """Return a fresh engine with tables created but NO seed data. Function-scoped so each test that uses it starts with a virgin database — useful for asserting first-run seed behavior and migration idempotency without contaminating the session-scoped ``db_engine``. """ db_path = tmp_path / "clean.db" engine = build_engine(f"sqlite:///{db_path}") run_migrations(engine) yield engine engine.dispose()