"""Shared fixtures for unit + integration tests.""" from __future__ import annotations import os from collections.abc import Iterator import pytest from fastapi.testclient import TestClient from sqlalchemy.orm import Session # In-process integration/E2E tests drive the app with *mock* embeddings # (bag-of-words, cosine ~0.1–0.8), not the live aipi model — so the honesty # gate is calibrated to the mock's distribution, mirroring tests/e2e/ # conftest.py. Must be set before ``app.main`` (below) caches settings. # The production default stays 0.62 (app/config.py, A8 revised). os.environ.setdefault("BOR_RELEVANCE_THRESHOLD", "0.30") # Phase 16: single-admin auth is fail-loud — create_app() refuses to boot # without both vars, and app.main (imported below) builds the app at # import time. Set known test values first, same pattern as the threshold. ADMIN_PASSWORD = "test-admin-password" SESSION_SECRET = "test-session-secret-0123456789abcdef0123456789abcdef" os.environ.setdefault("BOR_ADMIN_PASSWORD", ADMIN_PASSWORD) os.environ.setdefault("BOR_SESSION_SECRET", SESSION_SECRET) from app.db import SessionLocal, db_available # noqa: E402 from app.main import app as fastapi_app # noqa: E402 @pytest.fixture() def client() -> TestClient: return TestClient(fastapi_app) @pytest.fixture() def admin_client(client: TestClient) -> TestClient: """A client signed in as the single admin (phase 16). TestClient keeps its cookie jar across requests, so one login covers every subsequent request of the test. Use it for the admin-only surface (``GET /api/docs``, ``/api/steering``). """ r = client.post("/api/login", json={"password": ADMIN_PASSWORD}) assert r.status_code == 204, f"admin login failed: {r.status_code} {r.text}" return client @pytest.fixture() def db() -> Iterator[Session]: """Real Postgres session (``podman compose up -d db``). Skips with clear instructions when the database is not running, so the suite degrades gracefully on a machine without the stack started. """ if not db_available(): pytest.skip("Postgres not reachable — run `podman compose up -d db` first") session = SessionLocal() try: yield session finally: session.close()