File size: 5,042 Bytes
8ede856
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
"""Telegram 模块 Mock 工具。

提供统一的 Telegram 相关模块 mock 设置,避免在测试文件中重复定义。
"""

import sys
from unittest.mock import AsyncMock, MagicMock

import pytest


def create_mock_telegram_modules():
    """创建 Telegram 相关的 mock 模块。

    Returns:
        dict: 包含 telegram 和相关模块的 mock 对象
    """
    mock_telegram = MagicMock()
    mock_telegram.BotCommand = MagicMock
    mock_telegram.Update = MagicMock
    mock_telegram.constants = MagicMock()
    mock_telegram.constants.ChatType = MagicMock()
    mock_telegram.constants.ChatType.PRIVATE = "private"
    mock_telegram.constants.ChatAction = MagicMock()
    mock_telegram.constants.ChatAction.TYPING = "typing"
    mock_telegram.constants.ChatAction.UPLOAD_VOICE = "upload_voice"
    mock_telegram.constants.ChatAction.UPLOAD_DOCUMENT = "upload_document"
    mock_telegram.constants.ChatAction.UPLOAD_PHOTO = "upload_photo"
    mock_telegram.error = MagicMock()
    mock_telegram.error.BadRequest = Exception
    mock_telegram.ReactionTypeCustomEmoji = MagicMock
    mock_telegram.ReactionTypeEmoji = MagicMock

    mock_telegram_ext = MagicMock()
    mock_telegram_ext.ApplicationBuilder = MagicMock
    mock_telegram_ext.ContextTypes = MagicMock
    mock_telegram_ext.ExtBot = MagicMock
    mock_telegram_ext.filters = MagicMock()
    mock_telegram_ext.filters.ALL = MagicMock()
    mock_telegram_ext.MessageHandler = MagicMock

    # Mock telegramify_markdown
    mock_telegramify = MagicMock()
    mock_telegramify.markdownify = lambda text, **kwargs: text

    # Mock apscheduler
    mock_apscheduler = MagicMock()
    mock_apscheduler.schedulers = MagicMock()
    mock_apscheduler.schedulers.asyncio = MagicMock()
    mock_apscheduler.schedulers.asyncio.AsyncIOScheduler = MagicMock
    mock_apscheduler.schedulers.background = MagicMock()
    mock_apscheduler.schedulers.background.BackgroundScheduler = MagicMock

    return {
        "telegram": mock_telegram,
        "telegram.ext": mock_telegram_ext,
        "telegramify_markdown": mock_telegramify,
        "apscheduler": mock_apscheduler,
    }


@pytest.fixture(scope="module", autouse=True)
def mock_telegram_modules():
    """Mock Telegram 相关模块的 fixture。

    自动应用于使用此 fixture 的测试模块。
    """
    mocks = create_mock_telegram_modules()
    monkeypatch = pytest.MonkeyPatch()

    monkeypatch.setitem(sys.modules, "telegram", mocks["telegram"])
    monkeypatch.setitem(sys.modules, "telegram.constants", mocks["telegram"].constants)
    monkeypatch.setitem(sys.modules, "telegram.error", mocks["telegram"].error)
    monkeypatch.setitem(sys.modules, "telegram.ext", mocks["telegram.ext"])
    monkeypatch.setitem(sys.modules, "telegramify_markdown", mocks["telegramify_markdown"])
    monkeypatch.setitem(sys.modules, "apscheduler", mocks["apscheduler"])
    monkeypatch.setitem(
        sys.modules, "apscheduler.schedulers", mocks["apscheduler"].schedulers
    )
    monkeypatch.setitem(
        sys.modules,
        "apscheduler.schedulers.asyncio",
        mocks["apscheduler"].schedulers.asyncio,
    )
    monkeypatch.setitem(
        sys.modules,
        "apscheduler.schedulers.background",
        mocks["apscheduler"].schedulers.background,
    )
    yield
    monkeypatch.undo()


class MockTelegramBuilder:
    """构建 Telegram 测试 mock 对象的工具类。"""

    @staticmethod
    def create_bot():
        """创建 mock Telegram bot 实例。"""
        bot = MagicMock()
        bot.username = "test_bot"
        bot.id = 12345678
        bot.base_url = "https://api.telegram.org/bottest_token_123/"
        bot.send_message = AsyncMock()
        bot.send_photo = AsyncMock()
        bot.send_document = AsyncMock()
        bot.send_voice = AsyncMock()
        bot.send_chat_action = AsyncMock()
        bot.delete_my_commands = AsyncMock()
        bot.set_my_commands = AsyncMock()
        bot.set_message_reaction = AsyncMock()
        bot.edit_message_text = AsyncMock()
        bot.send_message_draft = AsyncMock()
        return bot

    @staticmethod
    def create_application():
        """创建 mock Telegram Application 实例。"""
        from tests.fixtures.helpers import NoopAwaitable

        app = MagicMock()
        app.bot = MagicMock()
        app.bot.username = "test_bot"
        app.bot.base_url = "https://api.telegram.org/bottest_token_123/"
        app.initialize = AsyncMock()
        app.start = AsyncMock()
        app.stop = AsyncMock()
        app.add_handler = MagicMock()
        app.updater = MagicMock()
        app.updater.start_polling = MagicMock(return_value=NoopAwaitable())
        app.updater.stop = AsyncMock()
        return app

    @staticmethod
    def create_scheduler():
        """创建 mock APScheduler 实例。"""
        scheduler = MagicMock()
        scheduler.add_job = MagicMock()
        scheduler.start = MagicMock()
        scheduler.running = True
        scheduler.shutdown = MagicMock()
        return scheduler