41 lines
1.4 KiB
Python
41 lines
1.4 KiB
Python
"""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
|