from __future__ import annotations from unittest.mock import AsyncMock, MagicMock import pytest from yuxi.channels.adapters.wechat.wecom.send import ( build_wecom_file_payload, build_wecom_image_payload, build_wecom_miniprogram_payload, build_wecom_news_payload, build_wecom_text_payload, build_wecom_video_payload, build_wecom_voice_payload, ) from yuxi.channels.adapters.wechat.mp.send import ( build_mp_news_payload, ) class TestBuildWeComPayloads: def test_build_text_payload_basic(self): payload = build_wecom_text_payload("agent1", "user1", "hello") assert payload["msgtype"] == "text" assert payload["agentid"] == "agent1" assert payload["touser"] == "user1" assert payload["text"]["content"] == "hello" assert payload["safe"] == 0 def test_build_text_payload_truncated(self): long_text = "x" * 3000 payload = build_wecom_text_payload("agent1", "user1", long_text) assert len(payload["text"]["content"]) <= 2048 def test_build_text_payload_with_reply(self): payload = build_wecom_text_payload( "agent1", "user1", "reply text", reply_to_msg_id="msg_123", reply_to_user="sender", ) assert payload["_reply_to_msg_id"] == "msg_123" assert payload["_reply_to_user"] == "sender" def test_build_text_payload_reply_prefix(self): payload = build_wecom_text_payload( "agent1", "user1", "short text", reply_to_msg_id="msg_123", reply_to_user="小明", ) assert "「回复 @小明」" in str(payload["text"]["content"]) def test_build_image_payload(self): payload = build_wecom_image_payload("agent1", "user1", "media_123") assert payload["msgtype"] == "image" assert payload["image"]["media_id"] == "media_123" def test_build_file_payload(self): payload = build_wecom_file_payload("agent1", "user1", "file_media") assert payload["msgtype"] == "file" assert payload["file"]["media_id"] == "file_media" def test_build_voice_payload(self): payload = build_wecom_voice_payload("agent1", "user1", "voice_media") assert payload["msgtype"] == "voice" assert payload["voice"]["media_id"] == "voice_media" def test_build_video_payload(self): payload = build_wecom_video_payload("agent1", "user1", "video_media", "标题", "描述") assert payload["msgtype"] == "video" assert payload["video"]["title"] == "标题" assert payload["video"]["description"] == "描述" def test_build_news_payload(self): articles = [{"title": "新闻1", "url": "http://example.com"}] payload = build_wecom_news_payload("agent1", "user1", articles) assert payload["msgtype"] == "news" assert payload["news"]["articles"] == articles def test_build_miniprogram_payload(self): payload = build_wecom_miniprogram_payload( "agent1", "user1", "小程序标题", "wxappid", "pages/index", "thumb_123" ) assert payload["msgtype"] == "miniprogram_notice" assert payload["miniprogram_notice"]["appid"] == "wxappid" assert payload["miniprogram_notice"]["title"] == "小程序标题" class TestBuildMpPayloads: def test_build_mp_news_payload(self): articles = [{"title": "图文", "url": "http://example.com"}] payload = build_mp_news_payload("user1", articles) assert payload["touser"] == "user1" assert payload["msgtype"] == "news" assert len(payload["news"]["articles"]) == 1 def test_build_mp_news_payload_multiple_articles(self): articles = [ {"title": "A", "url": "http://a.com"}, {"title": "B", "url": "http://b.com"}, ] payload = build_mp_news_payload("user1", articles) assert len(payload["news"]["articles"]) == 2