Include utility modules, shared channels, prompts, read-only skills, wardrobe memory and regression tests. Externalize legacy credentials and exclude private runtime state.
81 lines
3.2 KiB
Python
81 lines
3.2 KiB
Python
"""Telegram Help must retain inline buttons in both command and chat modes."""
|
|
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
from types import SimpleNamespace
|
|
from unittest.mock import AsyncMock, patch
|
|
|
|
BASE = Path(__file__).resolve().parents[1]
|
|
sys.path[:0] = [str(BASE / "bot-utility"), str(BASE)]
|
|
|
|
import main
|
|
|
|
|
|
class FakeTGChannel:
|
|
tg_username = "test_bot"
|
|
|
|
@staticmethod
|
|
def is_admin(uid):
|
|
return True
|
|
|
|
|
|
def private_message(text="/help"):
|
|
return SimpleNamespace(
|
|
from_user=SimpleNamespace(id=123, is_bot=False),
|
|
chat=SimpleNamespace(id=123, type="private"),
|
|
text=text,
|
|
caption=None,
|
|
photo=[],
|
|
entities=[],
|
|
)
|
|
|
|
|
|
class TelegramHelpTests(unittest.IsolatedAsyncioTestCase):
|
|
async def run_root_help(self, mode):
|
|
bot = SimpleNamespace(send_message=AsyncMock(), id=999)
|
|
store = SimpleNamespace(get_mode=lambda *args: mode)
|
|
with patch.object(main, "ModeStore", return_value=store), \
|
|
patch.object(main.identity, "resolve", return_value=1), \
|
|
patch.object(main.help_ui, "chat_help", new=AsyncMock(return_value="chat help")) as chat_help, \
|
|
patch.object(main, "handle_message", new=AsyncMock()) as dispatch:
|
|
await main.make_tg_handler(FakeTGChannel())(private_message(), bot)
|
|
return bot, chat_help, dispatch
|
|
|
|
async def test_command_root_help_has_buttons(self):
|
|
bot, chat_help, dispatch = await self.run_root_help("command")
|
|
kwargs = bot.send_message.await_args.kwargs
|
|
self.assertIsNotNone(kwargs.get("reply_markup"))
|
|
self.assertIn("服务列表", bot.send_message.await_args.args[1])
|
|
chat_help.assert_not_awaited()
|
|
dispatch.assert_not_awaited()
|
|
|
|
async def test_chat_root_help_has_buttons_and_skips_legacy_dispatch(self):
|
|
bot, chat_help, dispatch = await self.run_root_help("chat")
|
|
kwargs = bot.send_message.await_args.kwargs
|
|
self.assertIsNotNone(kwargs.get("reply_markup"))
|
|
self.assertEqual(bot.send_message.await_args.args[1], "chat help")
|
|
chat_help.assert_awaited_once_with(1, None, True)
|
|
dispatch.assert_not_awaited()
|
|
|
|
async def test_chat_help_callback_keeps_buttons_and_mode_aware_content(self):
|
|
bot = SimpleNamespace(send_message=AsyncMock())
|
|
callback = SimpleNamespace(
|
|
from_user=SimpleNamespace(id=123),
|
|
message=SimpleNamespace(chat=SimpleNamespace(id=123, type="private")),
|
|
data="help:1",
|
|
answer=AsyncMock(),
|
|
)
|
|
store = SimpleNamespace(get_mode=lambda *args: "chat")
|
|
with patch.object(main, "ModeStore", return_value=store), \
|
|
patch.object(main.identity, "resolve", return_value=1), \
|
|
patch.object(main.help_ui, "chat_help", new=AsyncMock(return_value="setu chat help")) as chat_help:
|
|
await main.make_tg_help_callback(FakeTGChannel())(callback, bot)
|
|
chat_help.assert_awaited_once_with(1, "setu", True)
|
|
self.assertEqual(bot.send_message.await_args.args[1], "setu chat help")
|
|
self.assertIsNotNone(bot.send_message.await_args.kwargs.get("reply_markup"))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|