Backend: - ConversationTracker: Protocol + PostgresConversationTracker for lifecycle tracking - Error handler: ErrorCategory enum, classify_error(), with_retry() exponential backoff - Wire PostgresAnalyticsRecorder + ConversationTracker into ws_handler - Rate limiting (10 msg/10s per thread), edge case hardening - Health endpoint GET /api/health, version 0.5.0 - Demo seed data script + sample OpenAPI spec Frontend (all new): - React Router with NavBar (Chat / Replay / Dashboard / Review) - ReplayListPage + ReplayPage with ReplayTimeline component - DashboardPage with MetricCard, range selector, zero-state - ReviewPage for OpenAPI classification review - ErrorBanner for WebSocket disconnect handling - API client (api.ts) with typed fetch wrappers Infrastructure: - Frontend Dockerfile (multi-stage node -> nginx) - nginx.conf with SPA routing + API/WS proxy - docker-compose.yml with frontend service + healthchecks - .env.example files (root + backend) Documentation: - README.md with quick start and architecture - Agent configuration guide - OpenAPI import guide - Deployment guide - Demo script 48 new tests, 449 total passing, 92.87% coverage
43 lines
1.3 KiB
Python
43 lines
1.3 KiB
Python
"""Tests for app.main module."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from app.main import AGENTS_YAML, FRONTEND_DIST, app
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestMainModule:
|
|
def test_app_title(self) -> None:
|
|
assert app.title == "Smart Support"
|
|
|
|
def test_app_version(self) -> None:
|
|
assert app.version == "0.5.0"
|
|
|
|
def test_agents_yaml_path_exists(self) -> None:
|
|
assert AGENTS_YAML.name == "agents.yaml"
|
|
|
|
def test_frontend_dist_path(self) -> None:
|
|
assert "frontend" in str(FRONTEND_DIST)
|
|
assert "dist" in str(FRONTEND_DIST)
|
|
|
|
def test_websocket_route_registered(self) -> None:
|
|
routes = [r.path for r in app.routes if hasattr(r, "path")]
|
|
assert "/ws" in routes
|
|
|
|
def test_replay_router_registered(self) -> None:
|
|
routes = [r.path for r in app.routes if hasattr(r, "path")]
|
|
assert any("replay" in p or "conversations" in p for p in routes)
|
|
|
|
def test_analytics_router_registered(self) -> None:
|
|
routes = [r.path for r in app.routes if hasattr(r, "path")]
|
|
assert any("analytics" in p for p in routes)
|
|
|
|
def test_health_route_registered(self) -> None:
|
|
routes = [r.path for r in app.routes if hasattr(r, "path")]
|
|
assert "/api/health" in routes
|
|
|
|
def test_app_version_is_0_5_0(self) -> None:
|
|
assert app.version == "0.5.0"
|