"""The A2A surface: the Agent Card, and how the subject token is read.""" from __future__ import annotations from catalogue_agent.a2a_server import _subject_token, build_agent_card from catalogue_agent.config import Settings class _Call: def __init__(self, headers: dict[str, str]) -> None: self.state = {"headers": headers} class _Context: def __init__(self, headers: dict[str, str] | None) -> None: self.call_context = _Call(headers) if headers is not None else None def _settings() -> Settings: return Settings(client_secret="s3cret") # type: ignore[call-arg] def test_agent_card_exposes_a_decision_shaped_skill() -> None: """Never a generic `query`. An agent that offers "ask me anything about my domain" has become a data proxy, and the per-domain scoping the estate relies on stops meaning anything. """ card = build_agent_card(_settings()) ids = [s.id for s in card.skills] assert ids == ["describe_catalog"] assert not any(s.id in {"query", "search", "execute"} for s in card.skills) def test_agent_card_declares_protocol_1_0() -> None: """Without this the SDK assumes 0.3 and refuses 1.0 traffic.""" iface = build_agent_card(_settings()).supported_interfaces[0] assert iface.protocol_version == "1.0" assert iface.protocol_binding == "JSONRPC" def test_bearer_prefix_is_stripped_case_insensitively() -> None: assert _subject_token(_Context({"authorization": "Bearer abc"})) == "abc" assert _subject_token(_Context({"Authorization": "bearer abc"})) == "abc" assert _subject_token(_Context({"authorization": "abc"})) == "abc" def test_absent_token_yields_none_rather_than_an_empty_string() -> None: """The executor branches on None to fail the task loudly. An empty string would be sent to Keycloak and produce a confusing 400 instead of a clear "no token on the request". """ assert _subject_token(_Context({})) is None assert _subject_token(_Context(None)) is None