| """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 |
|
|
| |
| _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" |
| 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 |
|
|
| from app.db import engine |
| from app.main import app |
| from app.models import Base |
|
|
|
|
| @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}"} |
|
|