feat: упростить вывод команды !hp, добавить тесты

- Убран discord.Embed в пользу простого текста без timestamp ошибки
- Добавлены разделители = вокруг заголовка
- Создан tests/test_help_discord.py с 2 тестами для Discord команды
- Создан tests/test_help_console.py с 2 тестами для консольной команды
- Закрыто: AttributeError 'Message' object has no attribute 'timestamp'
This commit is contained in:
deadzilla 2026-06-02 23:14:37 +05:00
parent 5a3fcb06c4
commit 2188a7d3fd
4 changed files with 122 additions and 23 deletions

View File

@ -86,6 +86,8 @@ tests/ # pytest-тесты
test_commands_pg.py # Pg cog
test_bot.py # инициализация бота
test_morning_runner.py# тесты morning runner-а
test_help_discord.py # команда !hp — проверка формата вывода и контента (2 теста)
test_help_console.py # консольная help — проверка списка команд (2 теста)
ISSUES.md # Задачи и баг-трекер проекта
pytest.ini # Конфигурация pytest
```
@ -121,7 +123,7 @@ python -m pytest tests/ -v
| `test_bot.py` | инициализация бота | 7 |
| `test_morning_runner.py` | morning runner-а | 68 |
**Итого: 258 тестов.**
**Итого: 262 теста (4 новых для help).**
## API и внешние сервисы

View File

@ -11,15 +11,7 @@ class Help(commands.Cog):
await self._show_help(ctx)
async def _show_help(self, ctx: commands.Context):
"""Вывести список команд в формате Embed."""
embed = discord.Embed(
title="Discord Bot Help",
description="Доступные команды бота для Магнитогорска",
colour=discord.Color.blue(),
timestamp=ctx.message.timestamp,
)
# Список команд с описанием
"""Вывести список команд в простом текстовом формате."""
commands_list = [
("!pg", "Прогноз погоды в Магнитогорске"),
("!nw", "Топ-5 статей и топ-5 новостей AI с Habr"),
@ -28,21 +20,16 @@ class Help(commands.Cog):
("!msg <текст>", "Повторить текст в чате"),
]
# Формирование текстового блока команд
value_lines = ["**Доступные команды:**"]
message = "Discord Bot — Доступные команды\n"
message += "=" * 40 + "\n\n"
for cmd_name, description in commands_list:
value_lines.append(f"• `{cmd_name}` — {description}")
message += f"{cmd_name}{description}\n"
full_text = "\n".join(value_lines)
message += "\n" + "=" * 40
# Проверка длины текста (макс 1024 символа для поля embed)
if len(full_text) > 1024:
full_text = full_text[:1021] + "..."
await ctx.send(message)
embed.add_field(
name="Описание",
value=full_text,
inline=False,
)
await ctx.send(embed=embed)
if __name__ == "__main__":
print("Cog loaded!")

View File

@ -0,0 +1,54 @@
"""Тесты для консольной команды help."""
import io
from contextlib import redirect_stdout
from unittest.mock import MagicMock
class TestHelpCommandConsole:
"""Тесты для консольной команды help."""
def test_stop_event_check(self):
"""Проверка работы с остановленным ботом."""
from console_commands.help import help
stop_event = MagicMock()
stop_event.is_set.return_value = True
f = io.StringIO()
with redirect_stdout(f):
result = help(stop_event, MagicMock())
assert result is None
def test_output_contains_all_commands(self):
"""Проверка наличия всех команд в выводе."""
from console_commands.help import help
stop_event = MagicMock()
stop_event.is_set.return_value = False
f = io.StringIO()
with redirect_stdout(f):
help(stop_event, MagicMock())
output = f.getvalue()
# Discord команды
assert "!pg" in output
assert "!nw" in output
assert "!morning" in output
assert "!cat" in output
assert "!msg" in output
# Консольные команды
assert "help" in output
assert "pogoda" in output
assert "news" in output
assert "morning" in output
assert "cat" in output
assert "stop" in output
if __name__ == "__main__":
pytest.main([__file__, "-v"])

View File

@ -0,0 +1,56 @@
"""Тесты для команды !hp (help)."""
import pytest
from unittest.mock import AsyncMock, MagicMock
class TestHelpCommandDiscord:
"""Тесты для команды help на Discord."""
async def test_show_help_sends_simple_text(self):
"""Проверка, что команда отправляет простое текстовое сообщение."""
from commands.help import Help
mock_ctx = MagicMock()
mock_ctx.send = AsyncMock(return_value=None)
helper = Help()
await helper._show_help(mock_ctx)
mock_ctx.send.assert_awaited_once()
async def test_show_help_message_content(self):
"""Проверка содержания отправленного сообщения."""
from commands.help import Help
message_calls = []
def send_side_effect(text: str, *args, **kwargs):
message_calls.append(text)
return MagicMock()
mock_ctx = MagicMock()
mock_ctx.send = AsyncMock(side_effect=send_side_effect)
helper = Help()
await helper._show_help(mock_ctx)
assert len(message_calls) == 1
message = message_calls[0]
# Проверка структуры сообщения
assert "Discord Bot — Доступные команды" in message
assert "=" * 40 in message
# Проверяем наличие всех команд без кавычек
commands = ["!pg", "!nw", "!morning", "!cat", "!msg"]
for cmd in commands:
assert cmd in message, f"Команда {cmd} не найдена"
# Проверяем разделение тире между командой и описанием
lines = [l.strip() for l in message.split("\n") if "" in l]
assert len(lines) >= 5
if __name__ == "__main__":
pytest.main([__file__, "-v"])