# tests/core/test_dispatcher.py import pytest from core.handler import EventDispatcher from core.protocol import ( IncomingCommand, IncomingMessage, IncomingCallback, OutgoingMessage, Attachment, ) from core.chat import ChatManager from core.auth import AuthManager from core.settings import SettingsManager from core.store import InMemoryStore from sdk.mock import MockPlatformClient @pytest.fixture def dispatcher(): platform = MockPlatformClient() store = InMemoryStore() return EventDispatcher( platform=platform, chat_mgr=ChatManager(platform, store), auth_mgr=AuthManager(platform, store), settings_mgr=SettingsManager(platform, store), ) async def test_dispatch_command_to_handler(dispatcher): called_with = {} async def my_handler(event, **kwargs): called_with["event"] = event return [OutgoingMessage(chat_id=event.chat_id, text="ok")] dispatcher.register(IncomingCommand, "ping", my_handler) cmd = IncomingCommand(user_id="u1", platform="telegram", chat_id="C1", command="ping") result = await dispatcher.dispatch(cmd) assert called_with["event"] is cmd assert result[0].text == "ok" async def test_dispatch_unknown_command_returns_empty(dispatcher): cmd = IncomingCommand(user_id="u1", platform="telegram", chat_id="C1", command="unknown") result = await dispatcher.dispatch(cmd) assert result == [] async def test_dispatch_message_to_catchall(dispatcher): async def catch_all(event, **kwargs): return [OutgoingMessage(chat_id=event.chat_id, text="caught")] dispatcher.register(IncomingMessage, "*", catch_all) msg = IncomingMessage(user_id="u1", platform="telegram", chat_id="C1", text="hello") result = await dispatcher.dispatch(msg) assert result[0].text == "caught" async def test_dispatch_routes_audio_before_catchall(dispatcher): async def audio_handler(event, **kwargs): return [OutgoingMessage(chat_id=event.chat_id, text="audio")] async def catch_all(event, **kwargs): return [OutgoingMessage(chat_id=event.chat_id, text="text")] dispatcher.register(IncomingMessage, "audio", audio_handler) dispatcher.register(IncomingMessage, "*", catch_all) audio_msg = IncomingMessage( user_id="u1", platform="telegram", chat_id="C1", text="", attachments=[Attachment(type="audio")], ) text_msg = IncomingMessage(user_id="u1", platform="telegram", chat_id="C1", text="hi") assert (await dispatcher.dispatch(audio_msg))[0].text == "audio" assert (await dispatcher.dispatch(text_msg))[0].text == "text" async def test_dispatch_routes_document_before_catchall(dispatcher): async def document_handler(event, **kwargs): return [OutgoingMessage(chat_id=event.chat_id, text="document")] async def catch_all(event, **kwargs): return [OutgoingMessage(chat_id=event.chat_id, text="text")] dispatcher.register(IncomingMessage, "document", document_handler) dispatcher.register(IncomingMessage, "*", catch_all) document_msg = IncomingMessage( user_id="u1", platform="matrix", chat_id="C1", text="", attachments=[Attachment(type="document", workspace_path="surfaces/matrix/u1/file.pdf")], ) assert (await dispatcher.dispatch(document_msg))[0].text == "document" async def test_dispatch_callback_by_action(dispatcher): async def confirm_handler(event, **kwargs): return [OutgoingMessage(chat_id=event.chat_id, text="confirmed")] dispatcher.register(IncomingCallback, "confirm", confirm_handler) cb = IncomingCallback(user_id="u1", platform="telegram", chat_id="C1", action="confirm") result = await dispatcher.dispatch(cb) assert result[0].text == "confirmed"