from __future__ import annotations import asyncio from types import SimpleNamespace from fastapi import Response import app.a2a.router as a2a_module from app.a2a.models import A2ARpcRequest from app.core.models import CoreBusySlot import app.main as main_module import app.mcp.server as mcp_server_module import app.mcp.tools as mcp_tools_module class _DummyCoreService: def check_availability( self, start: str, end: str, calendar_ids: list[str] | None, ) -> SimpleNamespace: checked = calendar_ids or ["primary"] busy_slots = [CoreBusySlot(calendar_id=checked[0], start=start, end=end)] return SimpleNamespace( start=start, end=end, available=False, busy_slots=busy_slots, checked_calendars=checked, ) class _AllowAuthBackend: def authenticate( self, *, x_api_key: str | None, authorization: str | None, required_scopes: set[str], ) -> None: return None def test_availability_parity_rest_a2a_mcp(monkeypatch) -> None: dummy_core = _DummyCoreService() allow_auth = _AllowAuthBackend() monkeypatch.setattr(main_module, "core_service", dummy_core) monkeypatch.setattr(a2a_module, "core_service", dummy_core) monkeypatch.setattr(mcp_tools_module, "core_service", dummy_core) monkeypatch.setattr(a2a_module, "auth_backend", allow_auth) monkeypatch.setattr(mcp_tools_module, "auth_backend", allow_auth) rest_response = asyncio.run( main_module.availability( main_module.AvailabilityRequest( start="2026-03-10T09:00:00+01:00", end="2026-03-10T10:00:00+01:00", calendar_ids=["primary"], ) ) ).model_dump() a2a_response = a2a_module.a2a_rpc( A2ARpcRequest( jsonrpc="2.0", id="req-1", method="SendMessage", params={ "start": "2026-03-10T09:00:00+01:00", "end": "2026-03-10T10:00:00+01:00", "calendar_ids": ["primary"], }, ), Response(), ) assert a2a_response.error is None assert a2a_response.result is not None a2a_payload = a2a_response.result["availability"] mcp_payload = mcp_server_module.check_availability( start="2026-03-10T09:00:00+01:00", end="2026-03-10T10:00:00+01:00", calendar_ids=["primary"], ctx=None, ) assert rest_response == a2a_payload == mcp_payload