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:
parent
5a3fcb06c4
commit
2188a7d3fd
@ -86,6 +86,8 @@ tests/ # pytest-тесты
|
|||||||
test_commands_pg.py # Pg cog
|
test_commands_pg.py # Pg cog
|
||||||
test_bot.py # инициализация бота
|
test_bot.py # инициализация бота
|
||||||
test_morning_runner.py# тесты morning runner-а
|
test_morning_runner.py# тесты morning runner-а
|
||||||
|
test_help_discord.py # команда !hp — проверка формата вывода и контента (2 теста)
|
||||||
|
test_help_console.py # консольная help — проверка списка команд (2 теста)
|
||||||
ISSUES.md # Задачи и баг-трекер проекта
|
ISSUES.md # Задачи и баг-трекер проекта
|
||||||
pytest.ini # Конфигурация pytest
|
pytest.ini # Конфигурация pytest
|
||||||
```
|
```
|
||||||
@ -121,7 +123,7 @@ python -m pytest tests/ -v
|
|||||||
| `test_bot.py` | инициализация бота | 7 |
|
| `test_bot.py` | инициализация бота | 7 |
|
||||||
| `test_morning_runner.py` | morning runner-а | 68 |
|
| `test_morning_runner.py` | morning runner-а | 68 |
|
||||||
|
|
||||||
**Итого: 258 тестов.**
|
**Итого: 262 теста (4 новых для help).**
|
||||||
|
|
||||||
## API и внешние сервисы
|
## API и внешние сервисы
|
||||||
|
|
||||||
|
|||||||
@ -11,15 +11,7 @@ class Help(commands.Cog):
|
|||||||
await self._show_help(ctx)
|
await self._show_help(ctx)
|
||||||
|
|
||||||
async def _show_help(self, ctx: commands.Context):
|
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 = [
|
commands_list = [
|
||||||
("!pg", "Прогноз погоды в Магнитогорске"),
|
("!pg", "Прогноз погоды в Магнитогорске"),
|
||||||
("!nw", "Топ-5 статей и топ-5 новостей AI с Habr"),
|
("!nw", "Топ-5 статей и топ-5 новостей AI с Habr"),
|
||||||
@ -28,21 +20,16 @@ class Help(commands.Cog):
|
|||||||
("!msg <текст>", "Повторить текст в чате"),
|
("!msg <текст>", "Повторить текст в чате"),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Формирование текстового блока команд
|
message = "Discord Bot — Доступные команды\n"
|
||||||
value_lines = ["**Доступные команды:**"]
|
message += "=" * 40 + "\n\n"
|
||||||
|
|
||||||
for cmd_name, description in commands_list:
|
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)
|
await ctx.send(message)
|
||||||
if len(full_text) > 1024:
|
|
||||||
full_text = full_text[:1021] + "..."
|
|
||||||
|
|
||||||
embed.add_field(
|
|
||||||
name="Описание",
|
|
||||||
value=full_text,
|
|
||||||
inline=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
await ctx.send(embed=embed)
|
if __name__ == "__main__":
|
||||||
|
print("Cog loaded!")
|
||||||
|
|||||||
54
tests/test_help_console.py
Normal file
54
tests/test_help_console.py
Normal 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"])
|
||||||
56
tests/test_help_discord.py
Normal file
56
tests/test_help_discord.py
Normal 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"])
|
||||||
Loading…
x
Reference in New Issue
Block a user