"""Pytest fixtures. Uses an isolated temp SQLite DB + media dir and the deterministic MockEmbedder so the whole suite is fast and reproducible (spec ยง17).""" from __future__ import annotations import os import tempfile from pathlib import Path import pytest # Configure the app via env BEFORE importing it (settings are read at import time). _TMP = Path(tempfile.mkdtemp(prefix="pawtrace_test_")) os.environ["DATABASE_URL"] = f"sqlite:///{(_TMP / 'test.db').as_posix()}" os.environ["MEDIA_DIR"] = str(_TMP / "media") os.environ["EMBEDDER"] = "mock" os.environ["BREED_CLASSIFIER"] = "mock" # never load the HF breed model in tests os.environ["NOTIFIER"] = "console" os.environ["ZIP_CENTROID_FILE"] = str( Path(__file__).resolve().parents[2] / "data" / "zip_centroids.csv" ) os.environ["RATE_LIMIT_REPORTS_PER_MINUTE"] = "1000" os.environ["REVIEW_THRESHOLD"] = "0.55" os.environ["STRONG_THRESHOLD"] = "0.80" from fastapi.testclient import TestClient # noqa: E402 from app.db import engine # noqa: E402 from app.main import app # noqa: E402 from app.models import Base # noqa: E402 @pytest.fixture(autouse=True) def _fresh_db(): Base.metadata.drop_all(bind=engine) Base.metadata.create_all(bind=engine) yield Base.metadata.drop_all(bind=engine) @pytest.fixture def client(): return TestClient(app) def _png_bytes(seed: int = 1) -> bytes: from scripts.make_sample_images import make_image return make_image(seed) @pytest.fixture def sample_image(): return _png_bytes @pytest.fixture def owner_token(client): r = client.post( "/auth/register", json={ "name": "Owner One", "email": "owner1@example.com", "password": "password123", "zip": "20001", }, ) assert r.status_code == 201, r.text return r.json()["access_token"] @pytest.fixture def admin_token(): """Create an admin user directly and mint a token (register only makes owners).""" from app.db import SessionLocal from app.models import User from app.models.base import UserRole from app.security import create_access_token, hash_password db = SessionLocal() try: user = User( name="Admin", email="admin_fixture@example.com", zip="20001", password_hash=hash_password("password123"), role=UserRole.admin, ) db.add(user) db.commit() db.refresh(user) return create_access_token(user.id) finally: db.close() def auth(token: str) -> dict: return {"Authorization": f"Bearer {token}"}