"""Тесты меню команд: допустимые имена и синхронизация при старте.""" from __future__ import annotations import re from bot.commands_menu import BOT_COMMANDS, ensure_commands class FakeBot: def __init__(self, current: list) -> None: self.current = current self.set_calls: list[list] = [] async def get_my_commands(self) -> list: return self.current async def set_my_commands(self, commands: list) -> None: self.set_calls.append(commands) class BrokenBot: async def get_my_commands(self) -> list: raise RuntimeError("telegram unavailable") def test_command_names_are_telegram_compatible() -> None: names = [command.command for command in BOT_COMMANDS] assert len(names) == len(set(names)) for name in names: assert re.fullmatch(r"[a-z0-9_]{1,32}", name), name for command in BOT_COMMANDS: assert command.description async def test_menu_is_set_when_empty() -> None: bot = FakeBot([]) assert await ensure_commands(bot) is True assert len(bot.set_calls) == 1 assert [command.command for command in bot.set_calls[0]] == [command.command for command in BOT_COMMANDS] async def test_menu_is_not_touched_when_actual() -> None: bot = FakeBot(list(BOT_COMMANDS)) assert await ensure_commands(bot) is False assert bot.set_calls == [] async def test_menu_updates_when_different() -> None: bot = FakeBot([BOT_COMMANDS[0]]) assert await ensure_commands(bot) is True assert len(bot.set_calls[0]) == len(BOT_COMMANDS) async def test_telegram_error_does_not_crash_startup() -> None: assert await ensure_commands(BrokenBot()) is False # type: ignore[arg-type]