137 lines
4.4 KiB
Python
137 lines
4.4 KiB
Python
"""Тесты для commands/cat.py — команда !cat."""
|
||
|
||
import sys
|
||
from pathlib import Path
|
||
from unittest.mock import AsyncMock, MagicMock, patch
|
||
|
||
import discord
|
||
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 TestCatInit:
|
||
"""Тесты инициализации Cat cog."""
|
||
|
||
def test_cat_cog_instantiates(self) -> None:
|
||
"""Cat должен создаваться без параметров."""
|
||
from commands.cat import Cat
|
||
|
||
cog = Cat()
|
||
assert cog is not None
|
||
|
||
def test_cat_has_command(self) -> None:
|
||
"""Cat должен содержать команду cat."""
|
||
from commands.cat import Cat
|
||
|
||
cog = Cat()
|
||
assert cog.cat.name == "cat"
|
||
|
||
|
||
class TestCatCommand:
|
||
"""Тесты команды !cat."""
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_cat_success(self) -> None:
|
||
"""Успешный ответ API -> embed с котиком."""
|
||
from commands.cat import Cat
|
||
|
||
cog = Cat()
|
||
ctx = make_context()
|
||
|
||
with patch("commands.cat.fetch_cat", new_callable=AsyncMock) as mock:
|
||
mock.return_value = "https://example.com/cat.jpg"
|
||
await cog.cat(cog, ctx)
|
||
|
||
ctx.send.assert_awaited_once()
|
||
embed = ctx.send.call_args[1]["embed"]
|
||
assert embed.title == "Котик для тебя!"
|
||
assert embed.image.url == "https://example.com/cat.jpg"
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_cat_api_returns_none(self) -> None:
|
||
"""API вернул None -> fallback сообщение."""
|
||
from commands.cat import Cat
|
||
|
||
cog = Cat()
|
||
ctx = make_context()
|
||
|
||
with patch("commands.cat.fetch_cat", new_callable=AsyncMock) as mock:
|
||
mock.return_value = None
|
||
await cog.cat(cog, ctx)
|
||
|
||
ctx.send.assert_awaited_once()
|
||
content = ctx.send.call_args[0][0]
|
||
assert "Не удалось получить котика" in content
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_cat_embed_color_orange(self) -> None:
|
||
"""Embed должен быть оранжевого цвета."""
|
||
from commands.cat import Cat
|
||
|
||
cog = Cat()
|
||
ctx = make_context()
|
||
|
||
with patch("commands.cat.fetch_cat", new_callable=AsyncMock) as mock:
|
||
mock.return_value = "https://example.com/cat.jpg"
|
||
await cog.cat(cog, ctx)
|
||
|
||
embed = ctx.send.call_args[1]["embed"]
|
||
assert embed.color == discord.Color.orange()
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_cat_image_set_via_set_image(self) -> None:
|
||
"""URL должен быть установлен через embed.set_image."""
|
||
from commands.cat import Cat
|
||
|
||
cog = Cat()
|
||
ctx = make_context()
|
||
|
||
with patch("commands.cat.fetch_cat", new_callable=AsyncMock) as mock:
|
||
mock.return_value = "https://example.com/cat.jpg"
|
||
await cog.cat(cog, ctx)
|
||
|
||
embed = ctx.send.call_args[1]["embed"]
|
||
assert embed.image is not None
|
||
assert embed.image.url == "https://example.com/cat.jpg"
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_cat_with_special_url(self) -> None:
|
||
"""URL со спецсимволами должен корректно встраиваться."""
|
||
from commands.cat import Cat
|
||
|
||
cog = Cat()
|
||
ctx = make_context()
|
||
|
||
with patch("commands.cat.fetch_cat", new_callable=AsyncMock) as mock:
|
||
mock.return_value = "https://example.com/cat.jpg?size=large&format=webp"
|
||
await cog.cat(cog, ctx)
|
||
|
||
embed = ctx.send.call_args[1]["embed"]
|
||
assert embed.image.url == "https://example.com/cat.jpg?size=large&format=webp"
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_cat_send_raises(self) -> None:
|
||
"""Ошибка при отправке — fetch_cat вызывался."""
|
||
from commands.cat import Cat
|
||
|
||
cog = Cat()
|
||
ctx = make_context()
|
||
ctx.send.side_effect = Exception("channel error")
|
||
|
||
with patch("commands.cat.fetch_cat", new_callable=AsyncMock) as mock:
|
||
mock.return_value = "https://example.com/cat.jpg"
|
||
with pytest.raises(Exception, match="channel error"):
|
||
await cog.cat(cog, ctx)
|
||
|
||
mock.assert_awaited_once()
|