Files
aiturk-hermes-ide/tests/gateway/relay/test_handoff_relay_aliasing.py
T

77 lines
3.0 KiB
Python

"""Unit tests for /handoff platform aliasing over relay (Phase 1 parity).
Symptom fixed: on a relay-fronted gateway, ``/handoff discord`` was rejected
in TWO places even though "discord" is deliverable through the relay adapter:
1. The CLI pre-check (``cli_commands_mixin._handle_handoff_command``) looked
up ``gw_config.platforms.get(DISCORD)`` — only a RELAY entry exists.
2. The gateway watcher (``run.py _process_handoff``) did a literal
``adapters.get(discord)`` — the adapter is registered under RELAY.
Both now resolve fronted platforms through the same alias-aware machinery the
delivery router uses (``resolve_delivery_transport`` — native adapter wins;
relay eligible only when its authenticated transport advertises the logical
platform). These tests cover the resolver semantics the watcher depends on,
plus the CLI pre-check's env-derived fronted set.
"""
from __future__ import annotations
import pytest
from gateway.config import GatewayConfig, Platform, PlatformConfig
from gateway.delivery import resolve_delivery_transport
class _RelayStub:
"""Minimal relay adapter double advertising a fronted-platform set."""
def __init__(self, fronted):
self._fronted = set(fronted)
self.sent = []
def fronts_platform(self, platform):
value = getattr(platform, "value", platform)
return str(value) in self._fronted
async def send_for_platform(self, logical_platform, chat_id, content, reply_to=None, metadata=None):
self.sent.append((getattr(logical_platform, "value", logical_platform), chat_id, content, metadata))
return type("R", (), {"success": True, "message_id": "m-1", "error": None})()
async def send(self, chat_id, content, reply_to=None, metadata=None): # pragma: no cover
raise AssertionError("relay transport must use send_for_platform, not send")
def _config_with(platforms):
cfg = GatewayConfig()
cfg.platforms = platforms
return cfg
class TestHandoffRelayAliasing:
def test_fronted_platform_resolves_to_relay_adapter(self):
"""The watcher's exact miss: adapters holds only RELAY, target is discord."""
relay = _RelayStub({"discord"})
cfg = _config_with({Platform.RELAY: PlatformConfig(enabled=True)})
transport = resolve_delivery_transport(
Platform.DISCORD, cfg, {Platform.RELAY: relay}
)
assert transport is not None
assert transport.adapter is relay
assert transport.is_relay is True
class TestCliHandoffFrontedSet:
"""The CLI pre-check derives the fronted set from deploy env (no live adapter)."""
def test_fronted_set_from_env(self, monkeypatch):
monkeypatch.setenv("GATEWAY_RELAY_PLATFORMS", "discord,telegram")
monkeypatch.delenv("GATEWAY_RELAY_BOT_IDS", raising=False)
from gateway.relay import relay_platform_identities
fronted = {p for p, _ in relay_platform_identities()}
assert "discord" in fronted
assert "telegram" in fronted
assert "slack" not in fronted