from __future__ import annotations import pytest from yuxi.channels.adapters.wechat.format import ( map_bridge_msg_type, map_mp_msg_type, map_wecom_msg_type, truncate_text, ) from yuxi.channels.models import MessageType class TestTruncateText: def test_text_within_limit_returns_unchanged(self): assert truncate_text("hello", 10) == "hello" def test_text_exactly_at_limit_returns_unchanged(self): text = "a" * 100 result = truncate_text(text, 100) assert result == text assert len(result) == 100 def test_text_exceeds_limit_truncates_with_marker(self): text = "hello world this is a longer message!!!" result = truncate_text(text, 30) assert len(result) <= 30 assert result.endswith("\n...(内容过长已截断)") def test_very_long_text_truncation(self): text = "x" * 5000 result = truncate_text(text, 2048) assert len(result) == 2048 assert result.endswith("\n...(内容过长已截断)") def test_empty_string(self): result = truncate_text("", 10) assert result == "" def test_text_shorter_than_marker_clip_to_one_char(self): result = truncate_text("ab", 3) assert result == "ab" def test_text_just_below_limit(self): text = "a" * 49 result = truncate_text(text, 50) assert result == text def test_text_one_over_limit(self): text = "a" * 51 result = truncate_text(text, 50) assert len(result) == 50 def test_unicode_text_truncation(self): text = "你好世界!" * 100 result = truncate_text(text, 50) assert len(result) == 50 def test_limit_smaller_than_marker(self): text = "hello" result = truncate_text(text, 3) assert result.endswith("\n...(内容过长已截断)") class TestMapWeComMsgType: def test_text(self): assert map_wecom_msg_type("text") == MessageType.TEXT def test_image(self): assert map_wecom_msg_type("image") == MessageType.IMAGE def test_voice(self): assert map_wecom_msg_type("voice") == MessageType.AUDIO def test_video(self): assert map_wecom_msg_type("video") == MessageType.VIDEO def test_file(self): assert map_wecom_msg_type("file") == MessageType.FILE def test_location(self): assert map_wecom_msg_type("location") == MessageType.LOCATION def test_unknown_type_defaults_to_text(self): assert map_wecom_msg_type("unknown_type") == MessageType.TEXT def test_empty_string_defaults_to_text(self): assert map_wecom_msg_type("") == MessageType.TEXT class TestMapMpMsgType: def test_text(self): assert map_mp_msg_type("text") == MessageType.TEXT def test_image(self): assert map_mp_msg_type("image") == MessageType.IMAGE def test_voice(self): assert map_mp_msg_type("voice") == MessageType.AUDIO def test_video(self): assert map_mp_msg_type("video") == MessageType.VIDEO def test_location(self): assert map_mp_msg_type("location") == MessageType.LOCATION def test_mp_has_no_file_type_defaults_to_text(self): assert map_mp_msg_type("file") == MessageType.TEXT def test_unknown_type_defaults_to_text(self): assert map_mp_msg_type("sticker") == MessageType.TEXT class TestMapBridgeMsgType: def test_text_type_1(self): assert map_bridge_msg_type(1) == MessageType.TEXT def test_image_type_3(self): assert map_bridge_msg_type(3) == MessageType.IMAGE def test_audio_type_34(self): assert map_bridge_msg_type(34) == MessageType.AUDIO def test_video_type_43(self): assert map_bridge_msg_type(43) == MessageType.VIDEO def test_location_type_48(self): assert map_bridge_msg_type(48) == MessageType.LOCATION def test_file_type_49(self): assert map_bridge_msg_type(49) == MessageType.FILE def test_unknown_integer_defaults_to_text(self): assert map_bridge_msg_type(999) == MessageType.TEXT def test_zero_defaults_to_text(self): assert map_bridge_msg_type(0) == MessageType.TEXT def test_negative_defaults_to_text(self): assert map_bridge_msg_type(-1) == MessageType.TEXT