from __future__ import annotations from fastapi.testclient import TestClient def test_app_boots_and_health_responds(monkeypatch): from tests.unit.test_settings import _minimal_env for k, v in _minimal_env().items(): monkeypatch.setenv(k, v) from cerbero_mcp.__main__ import _make_app from cerbero_mcp.settings import Settings app = _make_app(Settings()) c = TestClient(app) r = c.get("/health") assert r.status_code == 200 assert r.json()["status"] == "healthy" r = c.get("/openapi.json") assert r.status_code == 200 spec = r.json() paths = spec["paths"].keys() assert any(p.startswith("/mcp-deribit/") for p in paths) assert any(p.startswith("/mcp-hyperliquid/") for p in paths) assert any(p.startswith("/mcp-macro/") for p in paths) assert any(p.startswith("/mcp-sentiment/") for p in paths) # Unified common interface owns the cross-cutting data tools assert "/mcp/tools/get_instruments" in paths assert "/mcp/tools/get_historical" in paths assert "/mcp/tools/get_indicators" in paths # get_instruments / get_historical / get_indicators are common-only assert "/mcp-deribit/tools/get_instruments" not in paths assert "/mcp-deribit/tools/get_historical" not in paths assert "/mcp-deribit/tools/get_technical_indicators" not in paths assert "/mcp-hyperliquid/tools/get_historical" not in paths assert "/mcp-hyperliquid/tools/get_indicators" not in paths # The standalone consensus router has been folded into /mcp assert not any(p.startswith("/mcp-cross/") for p in paths) # Bybit and Alpaca have been retired from the API surface assert not any(p.startswith("/mcp-bybit/") for p in paths) assert not any(p.startswith("/mcp-alpaca/") for p in paths) def test_apidocs_available_after_boot(monkeypatch): from tests.unit.test_settings import _minimal_env for k, v in _minimal_env().items(): monkeypatch.setenv(k, v) from cerbero_mcp.__main__ import _make_app from cerbero_mcp.settings import Settings c = TestClient(_make_app(Settings())) r = c.get("/apidocs") assert r.status_code == 200 assert "Cerbero MCP" in r.text