Foundation (phase 01, verified): - FastAPI app: /api/health, /api/suggestions, /api/chat (placeholder), static frontend served locally (no CDN) - Postgres 17 + pgvector via db/Containerfile + compose.yaml (podman compose up -d db), Alembic initial migration (documents, chunks with vector(768), query_log) - LLM client targeting https://aipi.reeseapps.com/v1 (turbo/embed); scripts/llm_probe.py verified models + 768-dim embeddings live - Conditional debugpy: imported only when DEBUGPY=1 (attach on demand, :5678); logging config for clean single-line logs - Frontend shell: mobile-first chat + Sources pages, tokens, a11y baselines - Tests: 24 unit+integration (99% coverage on app/), ruff + pyright clean, Playwright smoke E2E (3 tests) against a deterministic mock LLM - Planning: .agent/PLAN.md (architecture + LOCKED decisions), AGENTS.md, 6 user stories, 7 phase files (one story / one phase / one Playwright suite each)
50 lines
1.5 KiB
Python
50 lines
1.5 KiB
Python
"""Integration tests: HTTP API surface (no database required)."""
|
|
from __future__ import annotations
|
|
|
|
|
|
def test_health_reports_ok(client) -> None:
|
|
r = client.get("/api/health")
|
|
assert r.status_code == 200
|
|
body = r.json()
|
|
assert body["status"] == "ok"
|
|
assert body["db"] in {"up", "down"}
|
|
assert body["version"]
|
|
|
|
|
|
def test_suggestions_returns_list(client) -> None:
|
|
r = client.get("/api/suggestions")
|
|
assert r.status_code == 200
|
|
suggestions = r.json()["suggestions"]
|
|
assert isinstance(suggestions, list)
|
|
assert all(isinstance(s, str) and s for s in suggestions)
|
|
|
|
|
|
def test_index_html_served_locally(client) -> None:
|
|
"""No-CDN check: the page is served by FastAPI and references only
|
|
same-origin assets (no https:// script/link tags)."""
|
|
r = client.get("/")
|
|
assert r.status_code == 200
|
|
assert "Brain of Reese" in r.text
|
|
assert 'src="https://' not in r.text
|
|
assert 'href="https://' not in r.text
|
|
|
|
|
|
def test_styles_and_js_served(client) -> None:
|
|
assert client.get("/assets/styles.css").status_code == 200
|
|
assert client.get("/assets/app.js").status_code == 200
|
|
|
|
|
|
def test_chat_placeholder_roundtrip(client) -> None:
|
|
r = client.post("/api/chat", json={"message": "hello brain"})
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert data["ok"] is True
|
|
assert "neurons" in data["answer"]
|
|
assert data["deflected"] is False
|
|
assert data["sources"] == []
|
|
|
|
|
|
def test_chat_requires_message(client) -> None:
|
|
r = client.post("/api/chat", json={"message": ""})
|
|
assert r.status_code == 422
|