# co-gahusb/tests/test_server.py import os os.environ["CO_BUS_KEY"] = "test-key" # config.CO_BUS_KEY는 import 시점에 한 번 읽히므로, 다른 테스트 모듈이 app.config를 # 먼저 import하면 빈 값으로 굳는다. import 순서와 무관하게 모듈 속성을 직접 강제한다. from app import config config.CO_BUS_KEY = "test-key" from starlette.testclient import TestClient from app.server import app def test_health_open_without_auth(): client = TestClient(app) res = client.get("/health") assert res.status_code == 200 assert res.json()["status"] == "ok" def test_mcp_requires_bearer(): client = TestClient(app) res = client.post("/mcp", json={}) assert res.status_code == 401 def test_mcp_wrong_key_rejected(): client = TestClient(app) res = client.post("/mcp", json={}, headers={"Authorization": "Bearer wrong"}) assert res.status_code == 401 def test_mcp_valid_auth_passes_dns_host_check(): # 유효한 키는 인증 게이트를 통과하고, MCP DNS-rebinding Host 검증에 막혀선 안 된다. # TestClient 기본 Host="testserver"는 localhost가 아니므로, 보호가 켜져 있으면 421. # 컨텍스트 매니저로 써야 lifespan(세션 매니저 task group)이 기동되어 MCP 핸들러까지 도달. with TestClient(app) as client: res = client.post( "/mcp", headers={ "Authorization": "Bearer test-key", "Content-Type": "application/json", "Accept": "application/json, text/event-stream", }, json={ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "smoke", "version": "0"}, }, }, ) assert res.status_code != 401 # 인증 통과 assert res.status_code != 421 # Host 검증에 막히면 안 됨