167 lines
5.0 KiB
Python
167 lines
5.0 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
from wf_mcp.admin_surface import BrokerAdminHandlers, TransparentAdminHandlers
|
|
from wf_mcp.broker import WfMcpService
|
|
from wf_mcp.models import BrokerConfig, ConnectionConfig
|
|
from wf_mcp.storage import FileStore
|
|
|
|
|
|
def test_broker_admin_handlers_list_connections_and_events(tmp_path: Path) -> None:
|
|
service = WfMcpService(store=FileStore(tmp_path / "admin_broker_store"))
|
|
service.register_connection(
|
|
ConnectionConfig(id="demo.personal", server="demo", account="personal")
|
|
)
|
|
handlers = BrokerAdminHandlers(service)
|
|
|
|
connections = _run(handlers.list_connections())
|
|
events = _run(handlers.get_broker_events())
|
|
|
|
assert connections[0]["id"] == "demo.personal"
|
|
assert connections[0]["server"] == "demo"
|
|
assert events[0]["kind"] == "connection_registered"
|
|
assert events[0]["connection_id"] == "demo.personal"
|
|
|
|
sources = _run(handlers.list_sources(limit=100))
|
|
|
|
source_ids = {source["id"] for source in sources["sources"]}
|
|
assert "wf.std" in source_ids
|
|
assert "wf.admin" in source_ids
|
|
assert sources["total"] >= 2
|
|
|
|
|
|
def test_broker_admin_handlers_report_failed_refresh_payload(tmp_path: Path) -> None:
|
|
service = WfMcpService(store=FileStore(tmp_path / "admin_refresh_store"))
|
|
handlers = BrokerAdminHandlers(service)
|
|
|
|
payload = _run(handlers.refresh_connection_catalog("missing.personal"))
|
|
|
|
assert payload["connection_id"] == "missing.personal"
|
|
assert payload["refreshed"] is False
|
|
assert payload["error_type"] == "KeyError"
|
|
|
|
|
|
def test_transparent_admin_handlers_delegate_config_operations(tmp_path: Path) -> None:
|
|
runtime = FakeProxyAdminRuntime(tmp_path)
|
|
handlers = TransparentAdminHandlers(runtime)
|
|
|
|
connections = handlers.list_connections()
|
|
statuses = handlers.get_connection_statuses()
|
|
config = handlers.get_config()
|
|
add_payload = handlers.add_connection(
|
|
connection_id="demo.work",
|
|
server="demo",
|
|
account="work",
|
|
)
|
|
|
|
assert connections[0]["id"] == "demo.personal"
|
|
assert statuses[0]["transport"] == "stdio"
|
|
assert config["source"] == "manager"
|
|
assert add_payload["action"] == "add_connection"
|
|
assert runtime.manager.added[0]["connection_id"] == "demo.work"
|
|
|
|
|
|
async def _await_value(value: Any) -> Any:
|
|
return await value
|
|
|
|
|
|
def _run(value: Any) -> Any:
|
|
import asyncio
|
|
|
|
return asyncio.run(_await_value(value))
|
|
|
|
|
|
@dataclass
|
|
class FakeManager:
|
|
added: list[dict[str, Any]]
|
|
|
|
def get_payload(self) -> dict[str, Any]:
|
|
return {"source": "manager"}
|
|
|
|
def add_connection(
|
|
self,
|
|
*,
|
|
connection_id: str,
|
|
server: str,
|
|
account: str,
|
|
metadata: dict[str, Any] | None = None,
|
|
enabled: bool = True,
|
|
) -> dict[str, Any]:
|
|
self.added.append(
|
|
{
|
|
"connection_id": connection_id,
|
|
"server": server,
|
|
"account": account,
|
|
"metadata": metadata,
|
|
"enabled": enabled,
|
|
}
|
|
)
|
|
return {"action": "add_connection", "ok": True}
|
|
|
|
def update_connection(
|
|
self,
|
|
*,
|
|
connection_id: str,
|
|
server: str | None = None,
|
|
account: str | None = None,
|
|
metadata: dict[str, Any] | None = None,
|
|
enabled: bool | None = None,
|
|
) -> dict[str, Any]:
|
|
return {"action": "update_connection", "connection_id": connection_id}
|
|
|
|
def set_connection_enabled(
|
|
self,
|
|
connection_id: str,
|
|
*,
|
|
enabled: bool,
|
|
) -> dict[str, Any]:
|
|
return {
|
|
"action": "update_connection",
|
|
"connection_id": connection_id,
|
|
"enabled": enabled,
|
|
}
|
|
|
|
def remove_connection(self, connection_id: str) -> dict[str, Any]:
|
|
return {"action": "remove_connection", "connection_id": connection_id}
|
|
|
|
|
|
class FakeProxyAdminRuntime:
|
|
def __init__(self, tmp_path: Path) -> None:
|
|
self.manager = FakeManager(added=[])
|
|
self._config = BrokerConfig(
|
|
store_root=tmp_path / "transparent_admin_handlers_store",
|
|
connections=[
|
|
ConnectionConfig(
|
|
id="demo.personal",
|
|
server="demo",
|
|
account="personal",
|
|
metadata={"transport": "stdio"},
|
|
)
|
|
],
|
|
)
|
|
|
|
def current_config(self) -> BrokerConfig:
|
|
return self._config
|
|
|
|
def require_manager(self) -> FakeManager:
|
|
return self.manager
|
|
|
|
def reload(self) -> dict[str, Any]:
|
|
return {"ok": True, "reloaded": True}
|
|
|
|
async def list_proxy_tools_page(
|
|
self,
|
|
*,
|
|
connection_id: str | None = None,
|
|
query: str | None = None,
|
|
limit: int = 50,
|
|
cursor: str | None = None,
|
|
) -> dict[str, Any]:
|
|
return {"tools": [], "nextCursor": None, "total": 0}
|
|
|
|
async def get_proxy_tool(self, proxy_name: str) -> dict[str, Any]:
|
|
return {"proxy_name": proxy_name}
|