claire/tests/test_agent_peer_mode.py

42 lines
1.4 KiB
Python
Raw Permalink Normal View History

"""Peer-mode app: serves the sync API, never becomes a second orchestrator.
Structural guarantee `create_app(peer_mode=True)` must serve /api/v1/* (incl.
/sync/*) but NOT mount MCP/SPA and NOT bootstrap the orchestrator.
"""
from __future__ import annotations
from pathlib import Path
from fastapi.testclient import TestClient
from claire.web.app import create_app
def test_peer_mode_serves_sync_but_not_orchestrator(tmp_path: Path, monkeypatch) -> None:
# Spy: if peer mode ever bootstrapped the orchestrator, this trips.
import claire.orchestrator.bootstrap as boot
called = {"v": False}
def _spy(**_kw):
called["v"] = True
return None
monkeypatch.setattr(boot, "ensure_running", _spy)
app = create_app(
config_path=tmp_path / "claire.toml",
db_path=tmp_path / "claire.db",
sync_secret=None, # disable HMAC so the route returns 200, not 401
peer_mode=True,
)
with TestClient(app) as client: # `with` runs the lifespan
assert client.get("/api/v1/health").status_code == 200
# /sync/* IS served in peer mode (200 with auth disabled).
assert client.get("/api/v1/sync/cursor").status_code == 200
# MCP + SPA are NOT mounted in peer mode.
assert client.get("/mcp/").status_code == 404
assert called["v"] is False # orchestrator never bootstrapped