discordBot/tests/test_commands_news.py
deadzilla 1a6b7043ad fix: применить ruff format к 7 файлам
ruff format --check падает на 7 файлах (не 5 как было указано).
Изменения — чистое форматирование: line wrapping, trailing commas, blank lines.
Никаких логических изменений.

Файлы: bot.py, tests/test_commands_news.py, tests/test_commands_pg.py,
tests/test_fetch_weather.py, tests/test_help_command.py,
tests/test_morning_runner.py, utils/pogoda.py
2026-07-22 21:58:55 +05:00

158 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Тесты для commands/news.py — команда !nw."""
import sys
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
ROOT_DIR = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT_DIR))
def make_context() -> MagicMock:
"""Создать мокированный ctx."""
ctx = MagicMock()
ctx.author.name = "TestUser"
ctx.send = AsyncMock(return_value=None)
return ctx
class TestNewsInit:
"""Тесты инициализации News cog."""
def test_news_cog_instantiates(self) -> None:
"""News должен создаваться без параметров."""
from commands.news import News
cog = News()
assert cog is not None
def test_news_has_command(self) -> None:
"""News должен содержать команду nw."""
from commands.news import News
cog = News()
assert cog.nw.name == "nw"
class TestNewsCommand:
"""Тесты команды !nw."""
def _make_articles(self, count: int = 3) -> list[dict]:
return [
{
"title": f"Статья {i}",
"link": f"https://habr.com/article/{i}",
"pub_date": f"Mon, 28 May 2026 10:00:00 +0000",
"creator": "author",
"tags": [],
}
for i in range(1, count + 1)
]
@pytest.mark.asyncio
async def test_nw_success_articles_and_posts(self) -> None:
"""Успешный ответ API для статей и постов."""
from commands.news import News
cog = News()
ctx = make_context()
articles = self._make_articles(3)
posts = self._make_articles(2)
with patch("commands.news.fetch_rss", new_callable=AsyncMock) as mock_rss:
mock_rss.side_effect = [articles, posts]
await cog.nw(cog, ctx)
ctx.send.assert_awaited_once()
call_count = mock_rss.await_count
assert call_count == 2 # статьи + посты
@pytest.mark.asyncio
async def test_nw_articles_none(self) -> None:
"""fetch_rss вернул None для статей -> fallback сообщение."""
from commands.news import News
cog = News()
ctx = make_context()
with patch("commands.news.fetch_rss", new_callable=AsyncMock) as mock_rss:
mock_rss.return_value = None
await cog.nw(cog, ctx)
ctx.send.assert_awaited_once()
content = ctx.send.call_args[0][0]
assert "Не удалось получить новости" in content
@pytest.mark.asyncio
async def test_nw_empty_articles(self) -> None:
"""Пустой список статей -> 'Новостей пока нет'."""
from commands.news import News
cog = News()
ctx = make_context()
with patch("commands.news.fetch_rss", new_callable=AsyncMock) as mock_rss:
mock_rss.return_value = []
await cog.nw(cog, ctx)
ctx.send.assert_awaited_once()
content = ctx.send.call_args[0][0]
assert "Новостей пока нет" in content
@pytest.mark.asyncio
async def test_nw_posts_none(self) -> None:
"""fetch_rss вернул None для постов -> fallback в сообщение."""
from commands.news import News
cog = News()
ctx = make_context()
articles = self._make_articles(2)
with patch("commands.news.fetch_rss", new_callable=AsyncMock) as mock_rss:
mock_rss.side_effect = [articles, None]
await cog.nw(cog, ctx)
ctx.send.assert_awaited_once()
content = ctx.send.call_args[0][0]
assert "Не удалось получить новости" in content
@pytest.mark.asyncio
async def test_nw_posts_empty(self) -> None:
"""Пустой список постов -> 'Новостей пока нет' для постов."""
from commands.news import News
cog = News()
ctx = make_context()
articles = self._make_articles(2)
with patch("commands.news.fetch_rss", new_callable=AsyncMock) as mock_rss:
mock_rss.side_effect = [articles, []]
await cog.nw(cog, ctx)
ctx.send.assert_awaited_once()
content = ctx.send.call_args[0][0]
# Second "Новостей пока нет" for posts section
count = content.count("Новостей пока нет")
assert count >= 1
@pytest.mark.asyncio
async def test_nw_limits_articles_to_5(self) -> None:
"""Более 5 статей -> truncate_message обрежет."""
from commands.news import News
cog = News()
ctx = make_context()
articles = self._make_articles(20)
posts = self._make_articles(20)
with patch("commands.news.fetch_rss", new_callable=AsyncMock) as mock_rss:
mock_rss.side_effect = [articles, posts]
await cog.nw(cog, ctx)
ctx.send.assert_awaited_once()
content = ctx.send.call_args[0][0]
# truncate_message limits to 2000 chars for plain text
assert len(content) <= 2003 # 2000 + "..."