|
| 1 | +import asyncio |
| 2 | +import importlib |
| 3 | +import sys |
| 4 | +from unittest.mock import MagicMock, patch |
| 5 | + |
| 6 | +import pytest |
| 7 | + |
| 8 | +import astrbot.api.message_components as Comp |
| 9 | +from tests.fixtures.helpers import ( |
| 10 | + create_mock_file, |
| 11 | + create_mock_update, |
| 12 | + make_platform_config, |
| 13 | +) |
| 14 | +from tests.fixtures.mocks.telegram import create_mock_telegram_modules |
| 15 | + |
| 16 | +_TELEGRAM_PLATFORM_ADAPTER = None |
| 17 | + |
| 18 | + |
| 19 | +def _load_telegram_adapter(): |
| 20 | + global _TELEGRAM_PLATFORM_ADAPTER |
| 21 | + if _TELEGRAM_PLATFORM_ADAPTER is not None: |
| 22 | + return _TELEGRAM_PLATFORM_ADAPTER |
| 23 | + |
| 24 | + mocks = create_mock_telegram_modules() |
| 25 | + patched_modules = { |
| 26 | + "telegram": mocks["telegram"], |
| 27 | + "telegram.constants": mocks["telegram"].constants, |
| 28 | + "telegram.error": mocks["telegram"].error, |
| 29 | + "telegram.ext": mocks["telegram.ext"], |
| 30 | + "telegramify_markdown": mocks["telegramify_markdown"], |
| 31 | + "apscheduler": mocks["apscheduler"], |
| 32 | + "apscheduler.schedulers": mocks["apscheduler"].schedulers, |
| 33 | + "apscheduler.schedulers.asyncio": mocks["apscheduler"].schedulers.asyncio, |
| 34 | + "apscheduler.schedulers.background": mocks["apscheduler"].schedulers.background, |
| 35 | + } |
| 36 | + with patch.dict(sys.modules, patched_modules): |
| 37 | + sys.modules.pop("astrbot.core.platform.sources.telegram.tg_adapter", None) |
| 38 | + module = importlib.import_module("astrbot.core.platform.sources.telegram.tg_adapter") |
| 39 | + _TELEGRAM_PLATFORM_ADAPTER = module.TelegramPlatformAdapter |
| 40 | + return _TELEGRAM_PLATFORM_ADAPTER |
| 41 | + |
| 42 | + |
| 43 | +def _build_context() -> MagicMock: |
| 44 | + context = MagicMock() |
| 45 | + context.bot.username = "test_bot" |
| 46 | + context.bot.id = 12345678 |
| 47 | + return context |
| 48 | + |
| 49 | + |
| 50 | +@pytest.mark.asyncio |
| 51 | +async def test_telegram_document_caption_populates_message_text_and_plain(): |
| 52 | + TelegramPlatformAdapter = _load_telegram_adapter() |
| 53 | + adapter = TelegramPlatformAdapter( |
| 54 | + make_platform_config("telegram"), |
| 55 | + {}, |
| 56 | + asyncio.Queue(), |
| 57 | + ) |
| 58 | + document = create_mock_file("https://api.telegram.org/file/test/report.md") |
| 59 | + document.file_name = "report.md" |
| 60 | + mention = MagicMock(type="mention", offset=0, length=6) |
| 61 | + update = create_mock_update( |
| 62 | + message_text=None, |
| 63 | + document=document, |
| 64 | + caption="@alice 请总结这份文档", |
| 65 | + caption_entities=[mention], |
| 66 | + ) |
| 67 | + |
| 68 | + result = await adapter.convert_message(update, _build_context()) |
| 69 | + |
| 70 | + assert result is not None |
| 71 | + assert result.message_str == "@alice 请总结这份文档" |
| 72 | + assert any(isinstance(component, Comp.File) for component in result.message) |
| 73 | + assert any( |
| 74 | + isinstance(component, Comp.Plain) |
| 75 | + and component.text == "@alice 请总结这份文档" |
| 76 | + for component in result.message |
| 77 | + ) |
| 78 | + assert any( |
| 79 | + isinstance(component, Comp.At) and component.qq == "alice" |
| 80 | + for component in result.message |
| 81 | + ) |
| 82 | + |
| 83 | + |
| 84 | +@pytest.mark.asyncio |
| 85 | +async def test_telegram_video_caption_populates_message_text_and_plain(): |
| 86 | + TelegramPlatformAdapter = _load_telegram_adapter() |
| 87 | + adapter = TelegramPlatformAdapter( |
| 88 | + make_platform_config("telegram"), |
| 89 | + {}, |
| 90 | + asyncio.Queue(), |
| 91 | + ) |
| 92 | + video = create_mock_file("https://api.telegram.org/file/test/lesson.mp4") |
| 93 | + video.file_name = "lesson.mp4" |
| 94 | + update = create_mock_update( |
| 95 | + message_text=None, |
| 96 | + video=video, |
| 97 | + caption="这段视频讲了什么", |
| 98 | + ) |
| 99 | + |
| 100 | + result = await adapter.convert_message(update, _build_context()) |
| 101 | + |
| 102 | + assert result is not None |
| 103 | + assert result.message_str == "这段视频讲了什么" |
| 104 | + assert any(isinstance(component, Comp.Video) for component in result.message) |
| 105 | + assert any( |
| 106 | + isinstance(component, Comp.Plain) and component.text == "这段视频讲了什么" |
| 107 | + for component in result.message |
| 108 | + ) |
0 commit comments