File size: 2,595 Bytes
de1e3fc
 
 
 
 
 
 
 
 
 
 
6213763
de1e3fc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""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}"}