discordBot/tests/test_commands_stats.py
deadzilla f4d267d254 fix: !stats исключает CategoryChannel из подсчёта каналов
guild.channels содержит все типы включая CategoryChannel.
Категории — это контейнеры для группировки, а не каналы.

Изменено:
  - commands/stats.py: filter по isinstance(CategoryChannel)
  - console_commands/stats.py: аналогичный фильтр
  - test_commands_stats.py: тест test_stats_excludes_categories
  - Итого: 234 теста
2026-06-12 17:01:53 +05:00

119 lines
4.3 KiB
Python

"""Тесты для команды !stats."""
import pytest
from unittest.mock import AsyncMock, MagicMock
class TestStatsCommand:
"""Тесты Discord-команды stats."""
def _make_mock_guild(self, channel_count=5, member_count=100):
"""Создать mock-сервер."""
guild = MagicMock()
guild.channels = [MagicMock() for _ in range(channel_count)]
guild.member_count = member_count
return guild
async def test_stats_sends_embed(self):
"""Команда stats отправляет embed-сообщение."""
from commands.stats import Stats
mock_ctx = MagicMock()
mock_ctx.bot.latency = 0.035
mock_ctx.bot.guilds = []
mock_ctx.send = AsyncMock(return_value=None)
cog = Stats()
await cog.stats(cog, mock_ctx)
mock_ctx.send.assert_awaited_once()
call_args = mock_ctx.send.call_args
embed = call_args[1]["embed"] if call_args[1] else call_args[0][0]
assert embed.title == "Статистика серверов"
async def test_stats_correct_values(self):
"""Значения серверов, каналов и пользователей считаются верно."""
from commands.stats import Stats
guild1 = self._make_mock_guild(channel_count=10, member_count=200)
guild2 = self._make_mock_guild(channel_count=5, member_count=50)
mock_ctx = MagicMock()
mock_ctx.bot.latency = 0.035
mock_ctx.bot.guilds = [guild1, guild2]
mock_ctx.send = AsyncMock(return_value=None)
cog = Stats()
await cog.stats(cog, mock_ctx)
call_args = mock_ctx.send.call_args
embed = call_args[1]["embed"] if call_args[1] else call_args[0][0]
fields = {f.name: f.value for f in embed.fields}
assert fields["Серверов"] == "2"
assert fields["Каналов"] == "15"
assert fields["Пользователей"] == "250"
assert "35.0 мс" in fields["Пинг"]
async def test_stats_empty_guilds(self):
"""Пустой список серверов не вызывает ошибок."""
from commands.stats import Stats
mock_ctx = MagicMock()
mock_ctx.bot.latency = 0.050
mock_ctx.bot.guilds = []
mock_ctx.send = AsyncMock(return_value=None)
cog = Stats()
await cog.stats(cog, mock_ctx)
call_args = mock_ctx.send.call_args
embed = call_args[1]["embed"] if call_args[1] else call_args[0][0]
fields = {f.name: f.value for f in embed.fields}
assert fields["Серверов"] == "0"
assert fields["Каналов"] == "0"
assert fields["Пользователей"] == "0"
async def test_stats_none_member_count(self):
"""member_count=None не вызывает ошибок."""
from commands.stats import Stats
guild = self._make_mock_guild(channel_count=3, member_count=None)
mock_ctx = MagicMock()
mock_ctx.bot.latency = 0.040
mock_ctx.bot.guilds = [guild]
mock_ctx.send = AsyncMock(return_value=None)
cog = Stats()
await cog.stats(cog, mock_ctx)
call_args = mock_ctx.send.call_args
embed = call_args[1]["embed"] if call_args[1] else call_args[0][0]
fields = {f.name: f.value for f in embed.fields}
assert fields["Пользователей"] == "0"
async def test_stats_excludes_categories(self):
"""Категории не входят в счётчик каналов."""
import discord
from commands.stats import Stats
guild = MagicMock()
text_ch = MagicMock()
voice_ch = MagicMock()
category_ch = MagicMock(spec=discord.CategoryChannel)
guild.channels = [text_ch, voice_ch, category_ch]
guild.member_count = 50
mock_ctx = MagicMock()
mock_ctx.bot.latency = 0.040
mock_ctx.bot.guilds = [guild]
mock_ctx.send = AsyncMock(return_value=None)
cog = Stats()
await cog.stats(cog, mock_ctx)
call_args = mock_ctx.send.call_args
embed = call_args[1]["embed"] if call_args[1] else call_args[0][0]
fields = {f.name: f.value for f in embed.fields}
assert fields["Каналов"] == "2" # text + voice, категория исключена