from datetime import datetime, timezone from fastapi.testclient import TestClient from app.config import Settings from app.main import create_app from app.models import ProviderUsage from app.providers.base import UsageProvider class StubProvider(UsageProvider): def __init__(self, provider: str, status: str): super().__init__(provider, 1, 'test') self.status = status async def _fetch_usage(self): return ProviderUsage(provider=self.provider, status=self.status, source='test', last_successful_update=datetime.now(timezone.utc) if self.status == 'ok' else None) def test_health_index_and_demo_usage(): settings = Settings(demo_mode=True) with TestClient(create_app(settings)) as client: assert client.get('/health').json() == {'status': 'ok'} index = client.get('/') assert index.status_code == 200 assert 'AI USAGE' in index.text asset = client.get('/static/style.css') assert asset.status_code == 200 assert 'provider-card' in asset.text usage = client.get('/api/usage') assert usage.status_code == 200 assert usage.headers['cache-control'] == 'no-store' body = usage.json() assert body['demo_mode'] is True assert body['codex']['status'] == 'ok' assert body['devin']['status'] == 'ok' datetime.fromisoformat(body['server_time']) def test_provider_errors_are_independent(): settings = Settings(codex_timeout=1, devin_timeout=1) providers = (StubProvider('codex', 'ok'), StubProvider('devin', 'error')) with TestClient(create_app(settings, providers)) as client: body = client.get('/api/usage').json() assert body['codex']['status'] == 'ok' assert body['devin']['status'] == 'error' assert body['devin']['error'] == 'Unable to retrieve usage information' def test_disabled_provider_is_normalized(): settings = Settings(demo_mode=True, codex_enabled=False) with TestClient(create_app(settings)) as client: body = client.get('/api/usage').json() assert body['codex']['status'] == 'disabled' assert body['codex']['limits'] == []