Initial import of Shirobana bot backend

Include utility modules, shared channels, prompts, read-only skills, wardrobe memory and regression tests. Externalize legacy credentials and exclude private runtime state.
This commit is contained in:
RRRosmontis
2026-11-11 00:25:30 +08:00
commit 34089d0042
106 changed files with 28028 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
"""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()