Files
brain-of-reese/tests/conftest.py
T
ducoterra d22d260b8b
Build and Push Containers / build-and-push-app (push) Successful in 5m43s
Build and Push Containers / build-and-push-db (push) Successful in 12s
phase: 91_admin_theme_tab
All verification is complete — this pass needed no code changes. Final report:

**Phase 91 — Admin Theme tab: final verification pass (all 6 tasks already in `complete/`)**

- Verified pre-paint theming end-to-end: `ui_settings` store + resolver, admin `GET/PUT /api/ui-settings`, `CachingMiddleware` inline-`<style id="bor-theme">` injection before `</head>` (incl. `/shared/<token>` prefix branch, unit-pinned), CSP sha256 exemption for the inline tag, Theme tab shell + `theme.js` editor, CSS-file theming fully retired.
- No defects found; zero changes made — working tree left exactly as the task executors left it.
- Tests: `uv run pytest --cov=app` → 1841 passed, 0 failed (TOTAL coverage **99%**; theming/ui_settings/caching all 100%); `uv run pytest tests/e2e/test_admin_theme_tab.py -v --no-cov` → **5 passed** in isolation.
- Lint/types: `uv run ruff check .` → All checks passed; `uv run pyright` → 0 errors, 0 warnings.
- Criteria: (1) unset deployment byte-identical, no `#bor-theme` anywhere — ✓ (unit no-op test + E2E reset byte-compare); `rg "BOR_THEME|themes/"` → single hit is the permitted doc-history comment in `frontend/index.html`. (2) admin-only gate + 403s for anonymous and token users — ✓ (E2E test 3). (3) saved theme inline before `</head>` on every page incl. `/shared/<token>`, computed `--brand` on first paint for admin + anonymous — ✓ (E2E test 2 + unit). (4) reset → byte-identical; 5 contrast pairs warn <4.5:1, non-blocking — ✓ (E2E tests 4–5). (5) suite green, >90% coverage, lint clean — ✓. (6) commit deferred to harness per rules.
- Notable: `.agents/PLAN.md` is absent from the repo — the phase overview's Design section was used as the binding spec; no deviation resulted.
- Next pending phase: **none** — 91 is the last phase in `todo/`.
2026-09-09 17:22:24 -04:00

87 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Shared fixtures for unit + integration tests."""
from __future__ import annotations
import json
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)
# Phase 61 (defect fix): the app under test must see the code DEFAULTS,
# not an operator's local (gitignored) ``.env`` — ``Settings`` loads
# ``env_file=".env"`` from the repo root, and a machine-specific corpus
# (e.g. ``BOR_SUGGESTIONS``, ``BOR_DOCS_REPO``) leaked into the tests
# broke the default-metadata pins. pydantic-settings ranks process env
# vars ABOVE the ``.env`` file, so force the defaults explicitly here,
# before ``app.main`` (below) caches settings. The suggestions default
# is derived from the class field so this can never drift from
# ``app/config.py``; docs-push stays inert (empty repo).
from app.config import Settings as _Settings # noqa: E402
os.environ["BOR_DOCS_REPO"] = ""
os.environ["BOR_SUGGESTIONS"] = json.dumps(_Settings.model_fields["suggestions"].default)
# Phase 62: the same leak class for the new UI customization settings —
# an operator's local ``.env`` may legitimately carry
# ``BOR_INPUT_PLACEHOLDER`` / ``BOR_FOOTER_TEXT``, and the
# default-metadata pins must see the code defaults (derived from
# the class fields, same pattern as the suggestions line above).
# (Phase 91, task 03: the retired CSS-file theme env var no longer
# exists — nothing to pin.)
os.environ["BOR_INPUT_PLACEHOLDER"] = _Settings.model_fields["input_placeholder"].default
os.environ["BOR_FOOTER_TEXT"] = _Settings.model_fields["footer_text"].default
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()