"""End-to-end integration tests for the FusionAGI API.""" from __future__ import annotations starlette = __import__("pytest").importorskip("starlette") fastapi = __import__("pytest").importorskip("fastapi") from starlette.testclient import TestClient # noqa: E402 from fusionagi.api.app import create_app # noqa: E402 def _client() -> TestClient: app = create_app(cors_origins=["*"]) return TestClient(app) class TestSessionLifecycle: """Test the full session lifecycle: create → prompt → response.""" def test_create_session(self) -> None: c = _client() resp = c.post("/v1/sessions", json={"user_id": "test-user"}) assert resp.status_code == 200 data = resp.json() assert "session_id" in data def test_prompt_requires_session(self) -> None: c = _client() resp = c.post("/v1/sessions", json={"user_id": "test-user"}) sid = resp.json()["session_id"] resp = c.post(f"/v1/sessions/{sid}/prompt", json={"prompt": "Hello"}) assert resp.status_code == 200 def test_unknown_session_returns_error(self) -> None: c = _client() resp = c.post("/v1/sessions/nonexistent/prompt", json={"prompt": "Hello"}) assert resp.status_code in (404, 422, 500) class TestAdminEndpoints: """Test admin API endpoints.""" def test_system_status(self) -> None: c = _client() resp = c.get("/v1/admin/status") assert resp.status_code == 200 data = resp.json() assert data["status"] == "healthy" assert "uptime_seconds" in data def test_list_voices(self) -> None: c = _client() resp = c.get("/v1/admin/voices") assert resp.status_code == 200 assert isinstance(resp.json(), list) def test_add_voice(self) -> None: c = _client() resp = c.post("/v1/admin/voices", json={"name": "Test Voice", "language": "en-US"}) assert resp.status_code == 200 assert resp.json()["name"] == "Test Voice" def test_ethics_endpoint(self) -> None: c = _client() resp = c.get("/v1/admin/ethics") assert resp.status_code == 200 assert isinstance(resp.json(), list) def test_consequences_endpoint(self) -> None: c = _client() resp = c.get("/v1/admin/consequences") assert resp.status_code == 200 def test_insights_endpoint(self) -> None: c = _client() resp = c.get("/v1/admin/insights") assert resp.status_code == 200 def test_conversation_style(self) -> None: c = _client() resp = c.post("/v1/admin/conversation-style", json={"formality": "formal", "verbosity": "concise"}) assert resp.status_code == 200 def test_telemetry(self) -> None: c = _client() resp = c.get("/v1/admin/telemetry") assert resp.status_code == 200 assert "traces" in resp.json() class TestTenantEndpoints: """Test multi-tenant API.""" def test_current_tenant_default(self) -> None: c = _client() resp = c.get("/v1/admin/tenants/current") assert resp.status_code == 200 data = resp.json() assert data["tenant_id"] == "default" assert data["is_default"] is True def test_current_tenant_custom(self) -> None: c = _client() resp = c.get("/v1/admin/tenants/current", headers={"X-Tenant-ID": "acme"}) assert resp.status_code == 200 assert resp.json()["tenant_id"] == "acme" def test_list_tenants(self) -> None: c = _client() resp = c.get("/v1/admin/tenants") assert resp.status_code == 200 assert "tenants" in resp.json() def test_create_tenant(self) -> None: c = _client() resp = c.post("/v1/admin/tenants", json={"id": "test-org", "name": "Test Org"}) assert resp.status_code == 200 assert resp.json()["id"] == "test-org" class TestPluginEndpoints: """Test plugin marketplace API.""" def test_list_plugins(self) -> None: c = _client() resp = c.get("/v1/admin/plugins") assert resp.status_code == 200 data = resp.json() assert "available" in data assert "installed" in data def test_register_and_install_plugin(self) -> None: c = _client() resp = c.post("/v1/admin/plugins", json={ "id": "test-plugin", "name": "Test Plugin", "description": "A test plugin", "version": "1.0.0", }) assert resp.status_code == 200 assert resp.json()["id"] == "test-plugin" resp = c.post("/v1/admin/plugins/test-plugin/install") assert resp.status_code == 200 assert resp.json()["status"] == "installed" class TestBackupEndpoints: """Test backup/restore API.""" def test_list_backups(self) -> None: c = _client() resp = c.get("/v1/admin/backups") assert resp.status_code == 200 assert "backups" in resp.json() class TestVersionNegotiation: """Test API version negotiation.""" def test_version_endpoint(self) -> None: c = _client() resp = c.get("/version") assert resp.status_code == 200 data = resp.json() assert "current_version" in data assert "supported_versions" in data def test_version_header(self) -> None: c = _client() resp = c.get("/v1/admin/status") assert "x-api-version" in resp.headers def test_unsupported_version(self) -> None: c = _client() resp = c.get("/v1/admin/status", headers={"Accept-Version": "99"}) assert resp.status_code == 400 class TestSSEStreaming: """Test SSE streaming endpoint.""" def test_sse_endpoint_exists(self) -> None: c = _client() resp = c.post("/v1/sessions/test-session/stream/sse", json={"prompt": "Hi"}) assert resp.status_code == 200 assert resp.headers["content-type"].startswith("text/event-stream") class TestOpenAICompat: """Test OpenAI-compatible endpoints.""" def test_models_list(self) -> None: c = _client() resp = c.get("/v1/models") assert resp.status_code == 200 data = resp.json() assert "data" in data