from __future__ import annotations import pytest from yuxi.channel.channels.dingtalk.adapter import DingTalkAdapter from yuxi.channel.channels.dingtalk.config import DingTalkConfig from yuxi.channel.channels.dingtalk.translator import DingTalkTranslator from yuxi.channel.domain.model.shared.channel_type import ChannelType class TestDingTalkTranslator: def test_translate_p2p_message(self) -> None: raw = { "event": { "message": { "message_id": "msg-001", "content": "hello", "chat_type": "p2p", }, "sender": { "sender_id": {"user_id": "user-123"}, }, } } msg = DingTalkTranslator.translate_event(raw) assert msg.message_id == "msg-001" assert msg.content == "hello" assert msg.channel_type == ChannelType.DINGTALK assert msg.sender.id == "user-123" assert msg.metadata["is_group"] is False assert msg.metadata["group_id"] == "" def test_translate_group_message(self) -> None: raw = { "event": { "message": { "message_id": "msg-002", "content": "group hello", "chat_type": "group", "chat_id": "chat-456", }, "sender": { "sender_id": {"user_id": "user-789"}, }, } } msg = DingTalkTranslator.translate_event(raw) assert msg.metadata["is_group"] is True assert msg.metadata["group_id"] == "chat-456" def test_translate_missing_fields_defaults(self) -> None: raw = {} msg = DingTalkTranslator.translate_event(raw) assert msg.message_id == "" assert msg.content == "" assert msg.sender.id == "" class TestDingTalkConfig: def test_defaults(self) -> None: config = DingTalkConfig() assert config.client_id == "" assert config.client_secret == "" assert config.ws_enabled is True def test_with_values(self) -> None: config = DingTalkConfig(client_id="id1", client_secret="secret1", ws_enabled=False) assert config.client_id == "id1" assert config.client_secret == "secret1" assert config.ws_enabled is False class TestDingTalkAdapter: def test_channel_type(self) -> None: adapter = DingTalkAdapter(client_id="test", client_secret="test", ws_enabled=False) assert adapter.channel_type == ChannelType.DINGTALK.value def test_get_default_config(self) -> None: config = DingTalkAdapter.get_default_config() assert "client_id" in config assert "client_secret" in config assert "ws_enabled" in config @pytest.mark.asyncio async def test_is_healthy_before_open(self) -> None: adapter = DingTalkAdapter(client_id="test", client_secret="test", ws_enabled=False) assert await adapter.is_healthy() is False @pytest.mark.asyncio async def test_is_healthy_after_open(self) -> None: adapter = DingTalkAdapter(client_id="test", client_secret="test", ws_enabled=False) await adapter.open() assert await adapter.is_healthy() is True @pytest.mark.asyncio async def test_close(self) -> None: adapter = DingTalkAdapter(client_id="test", client_secret="test", ws_enabled=False) await adapter.open() await adapter.close() assert await adapter.is_healthy() is False @pytest.mark.asyncio async def test_receive_message(self) -> None: adapter = DingTalkAdapter(client_id="test", client_secret="test", ws_enabled=False) raw = { "event": { "message": {"message_id": "m1", "content": "hi", "chat_type": "p2p"}, "sender": {"sender_id": {"user_id": "u1"}}, } } msg = await adapter.receive_message(raw) assert msg.message_id == "m1" assert msg.content == "hi" @pytest.mark.asyncio async def test_send_typing_is_noop(self) -> None: adapter = DingTalkAdapter(client_id="test", client_secret="test", ws_enabled=False) await adapter.send_typing("session-1") @pytest.mark.asyncio async def test_send_media_returns_false(self) -> None: adapter = DingTalkAdapter(client_id="test", client_secret="test", ws_enabled=False) result = await adapter.send_media("session-1", url="http://x", media_type="image", metadata={}) assert result is False @pytest.mark.asyncio async def test_send_message_without_token_returns_failure(self) -> None: adapter = DingTalkAdapter(client_id="test", client_secret="test", ws_enabled=False) result = await adapter.send_message("session-1", "hello", channel_type="dingtalk", metadata={}) assert result.success is False def test_ws_connection_is_none_when_disabled(self) -> None: adapter = DingTalkAdapter(client_id="test", client_secret="test", ws_enabled=False) assert adapter.ws_connection is None def test_route_contributor_has_router(self) -> None: adapter = DingTalkAdapter(client_id="test", client_secret="test", ws_enabled=False) contributor = adapter.route_contributor assert contributor.router is not None