""" API surface tests — bearer-token enforcement and route registration order. The app is exercised without its lifespan: auth runs before any handler, so a 503 ("Gateway not initialized") proves the token was accepted. """ import httpx import pytest from pydantic import SecretStr from starlette.routing import Match import main from config import get_settings TOKEN = "test-token-for-suite" @pytest.fixture def token_enabled(monkeypatch): monkeypatch.setattr(get_settings(), "api_token", SecretStr(TOKEN)) @pytest.fixture async def client(): transport = httpx.ASGITransport(app=main.app) async with httpx.AsyncClient(transport=transport, base_url="http://test") as c: yield c class TestBearerToken: async def test_missing_token_rejected(self, token_enabled, client): resp = await client.get("/api/v1/calls/active") assert resp.status_code == 401 assert resp.headers["www-authenticate"] == "Bearer" async def test_wrong_token_rejected(self, token_enabled, client): resp = await client.get( "/api/v1/calls/active", headers={"Authorization": "Bearer wrong"} ) assert resp.status_code == 401 async def test_valid_token_reaches_handler(self, token_enabled, client): resp = await client.get( "/api/v1/calls/active", headers={"Authorization": f"Bearer {TOKEN}"} ) # No lifespan ran, so the handler itself 503s — auth was accepted assert resp.status_code == 503 async def test_empty_token_disables_auth(self, monkeypatch, client): monkeypatch.setattr(get_settings(), "api_token", SecretStr("")) resp = await client.get("/api/v1/calls/active") assert resp.status_code == 503 async def test_query_param_token_accepted(self, token_enabled, client): """