from __future__ import annotations
from fastapi.testclient import TestClient
import pytest
from app.api.main import app
from app.core.schemas import (
AnalysisResult,
CurrentUserResponse,
ModelCapability,
RuntimeMetadata,
SessionResponse,
ValidationMetadata,
)
@pytest.fixture(autouse=True)
def auth_override(monkeypatch):
monkeypatch.setattr(
"app.api.main.require_user",
lambda _request, _settings: type(
"User",
(),
{"id": "user-123", "display_name": "Test User", "authenticated": True},
)(),
)
monkeypatch.setattr(
"app.api.main.get_optional_user",
lambda _request: type(
"User",
(),
{
"id": "user-123",
"username": "tester",
"display_name": "Test User",
"avatar_url": "https://example.com/avatar.png",
"authenticated": True,
},
)(),
)
def test_healthz_returns_runtime_flags() -> None:
with TestClient(app) as client:
response = client.get("/healthz")
assert response.status_code == 200
payload = response.json()
assert payload["status"] == "ok"
assert "cuda_available" in payload
assert "dtype_preference" in payload
def test_analyze_delegates_to_runtime(monkeypatch) -> None:
def fake_compute_attribution_analysis(**_kwargs):
return AnalysisResult(
question="Why?",
model_name="fake-model",
answer="Because.",
raw_trace_text="Alpha.",
normalized_trace_text="Alpha.",
sentences=["Alpha."],
sentence_token_ranges=[(0, 1)],
suppression_matrix=[[0.0]],
raw_suppression_matrix=[[0.0]],
outgoing_importance=[0.0],
incoming_importance=[0.0],
top_edges=[],
runtime_metadata=RuntimeMetadata(
device="cpu",
capability=ModelCapability(supports_attribution=True, layer_count=2, attention_impl="eager"),
),
validation_metadata=ValidationMetadata(enabled=False, top_k=0),
)
monkeypatch.setattr("app.api.main.compute_attribution_analysis", fake_compute_attribution_analysis)
with TestClient(app) as client:
response = client.post(
"/api/analyze",
json={
"question": "Why?",
"max_new_tokens": 8,
"validate_top_k": 0,
},
)
assert response.status_code == 200
payload = response.json()
assert payload["answer"] == "Because."
assert payload["model_name"] == "fake-model"
def test_me_reports_current_user() -> None:
with TestClient(app) as client:
response = client.get("/api/me")
assert response.status_code == 200
payload = CurrentUserResponse.model_validate(response.json())
assert payload.authenticated is True
assert payload.username == "tester"
def test_root_serves_frontend() -> None:
with TestClient(app) as client:
response = client.get("/")
assert response.status_code == 200
assert "Thought Anchors" in response.text
def test_session_routes_use_service(monkeypatch) -> None:
class FakeSessionService:
def __init__(self) -> None:
self.payload = {
"id": "session-123",
"status": "completed",
"question": "Why?",
"model_name": "fake-model",
"error": None,
"created_at": "2026-04-06T00:00:00+00:00",
"updated_at": "2026-04-06T00:00:05+00:00",
"answer": "Because.",
"raw_trace_text": "Alpha.",
"normalized_trace_text": "Alpha.",
"sentences": ["Alpha."],
"generation_metadata": {"max_new_tokens": 8},
"analysis": AnalysisResult(
question="Why?",
model_name="fake-model",
answer="Because.",
raw_trace_text="Alpha.",
normalized_trace_text="Alpha.",
sentences=["Alpha."],
sentence_token_ranges=[(0, 1)],
suppression_matrix=[[0.0]],
raw_suppression_matrix=[[0.0]],
outgoing_importance=[0.0],
incoming_importance=[0.0],
top_edges=[],
runtime_metadata=RuntimeMetadata(
device="cpu",
capability=ModelCapability(
supports_attribution=True,
layer_count=2,
attention_impl="eager",
),
),
validation_metadata=ValidationMetadata(enabled=False, top_k=0),
).model_dump(),
}
def create_session(self, _request, **_kwargs):
return SessionResponse.model_validate(self.payload)
def get_session_payload(self, _session_id: str, **_kwargs):
return self.payload
def start_analysis(self, _session_id: str, **_kwargs):
return SessionResponse.model_validate(self.payload)
def list_sessions(self, _owner_id: str, **_kwargs):
return [self.payload]
def get_analysis_result(self, _session_id: str, **_kwargs):
return AnalysisResult.model_validate(self.payload["analysis"])
monkeypatch.setattr("app.api.main.get_session_service", lambda: FakeSessionService())
with TestClient(app) as client:
listing = client.get("/api/sessions")
created = client.post("/api/sessions", json={"question": "Why?"})
session = client.get("/api/sessions/session-123")
result = client.get("/api/sessions/session-123/result")
exported_json = client.get("/api/sessions/session-123/export.json")
exported_csv = client.get("/api/sessions/session-123/export.csv")
assert listing.status_code == 200
assert created.status_code == 200
assert session.status_code == 200
assert result.status_code == 200
assert exported_json.status_code == 200
assert exported_csv.status_code == 200
assert created.json()["id"] == "session-123"
assert session.json()["answer"] == "Because."
assert result.json()["analysis"]["model_name"] == "fake-model"