Files
telegram-helper-bot/tests/test_auto_moderation_service.py
Andrey 3d6b4353f9
All checks were successful
CI pipeline / Test & Code Quality (push) Successful in 34s
Refactor imports across multiple files to improve code organization and readability.
2026-02-28 23:24:25 +03:00

220 lines
7.6 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.
"""Тесты для AutoModerationService."""
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from helper_bot.handlers.private.services import AutoModerationService, BotSettings
class TestAutoModerationService:
"""Тесты для сервиса авто-модерации."""
@pytest.fixture
def mock_db(self):
"""Создает мок базы данных."""
db = MagicMock()
db.get_auto_moderation_settings = AsyncMock()
return db
@pytest.fixture
def settings(self):
"""Создает настройки бота."""
return BotSettings(
group_for_posts="-123",
group_for_message="-456",
main_public="@test_channel",
group_for_logs="-789",
important_logs="-999",
preview_link="false",
logs="false",
test="false",
)
@pytest.fixture
def service(self, mock_db, settings):
"""Создает экземпляр сервиса."""
return AutoModerationService(mock_db, settings)
@pytest.mark.asyncio
async def test_check_auto_action_returns_manual_when_score_is_none(
self, service, mock_db
):
"""Тест: возвращает manual когда score равен None."""
result = await service.check_auto_action(None)
assert result == "manual"
@pytest.mark.asyncio
async def test_check_auto_action_returns_publish_when_score_above_threshold(
self, service, mock_db
):
"""Тест: возвращает publish когда score выше порога."""
mock_db.get_auto_moderation_settings.return_value = {
"auto_publish_enabled": True,
"auto_decline_enabled": False,
"auto_publish_threshold": 0.8,
"auto_decline_threshold": 0.4,
}
result = await service.check_auto_action(0.9)
assert result == "publish"
@pytest.mark.asyncio
async def test_check_auto_action_returns_decline_when_score_below_threshold(
self, service, mock_db
):
"""Тест: возвращает decline когда score ниже порога."""
mock_db.get_auto_moderation_settings.return_value = {
"auto_publish_enabled": False,
"auto_decline_enabled": True,
"auto_publish_threshold": 0.8,
"auto_decline_threshold": 0.4,
}
result = await service.check_auto_action(0.3)
assert result == "decline"
@pytest.mark.asyncio
async def test_check_auto_action_returns_manual_when_disabled(
self, service, mock_db
):
"""Тест: возвращает manual когда авто-действия отключены."""
mock_db.get_auto_moderation_settings.return_value = {
"auto_publish_enabled": False,
"auto_decline_enabled": False,
"auto_publish_threshold": 0.8,
"auto_decline_threshold": 0.4,
}
result = await service.check_auto_action(0.9)
assert result == "manual"
@pytest.mark.asyncio
async def test_check_auto_action_returns_manual_when_score_in_middle(
self, service, mock_db
):
"""Тест: возвращает manual когда score между порогами."""
mock_db.get_auto_moderation_settings.return_value = {
"auto_publish_enabled": True,
"auto_decline_enabled": True,
"auto_publish_threshold": 0.8,
"auto_decline_threshold": 0.4,
}
result = await service.check_auto_action(0.6)
assert result == "manual"
@pytest.mark.asyncio
async def test_check_auto_action_publish_at_exact_threshold(self, service, mock_db):
"""Тест: возвращает publish когда score равен порогу."""
mock_db.get_auto_moderation_settings.return_value = {
"auto_publish_enabled": True,
"auto_decline_enabled": False,
"auto_publish_threshold": 0.8,
"auto_decline_threshold": 0.4,
}
result = await service.check_auto_action(0.8)
assert result == "publish"
@pytest.mark.asyncio
async def test_check_auto_action_decline_at_exact_threshold(self, service, mock_db):
"""Тест: возвращает decline когда score равен порогу."""
mock_db.get_auto_moderation_settings.return_value = {
"auto_publish_enabled": False,
"auto_decline_enabled": True,
"auto_publish_threshold": 0.8,
"auto_decline_threshold": 0.4,
}
result = await service.check_auto_action(0.4)
assert result == "decline"
@pytest.mark.asyncio
async def test_log_auto_action_publish(self, service, settings):
"""Тест отправки лога для авто-публикации."""
mock_bot = MagicMock()
mock_bot.send_message = AsyncMock()
await service.log_auto_action(
bot=mock_bot,
action="publish",
author_id=12345,
author_name="Test User",
author_username="testuser",
rag_score=0.85,
post_text="Test post text",
)
mock_bot.send_message.assert_called_once()
call_kwargs = mock_bot.send_message.call_args[1]
assert call_kwargs["chat_id"] == settings.important_logs
assert "АВТО-ПУБЛИКАЦИЯ" in call_kwargs["text"]
assert "Test User" in call_kwargs["text"]
assert "0.85" in call_kwargs["text"]
@pytest.mark.asyncio
async def test_log_auto_action_decline(self, service, settings):
"""Тест отправки лога для авто-отклонения."""
mock_bot = MagicMock()
mock_bot.send_message = AsyncMock()
await service.log_auto_action(
bot=mock_bot,
action="decline",
author_id=12345,
author_name="Test User",
author_username="testuser",
rag_score=0.25,
post_text="Test post text",
)
mock_bot.send_message.assert_called_once()
call_kwargs = mock_bot.send_message.call_args[1]
assert "АВТО-ОТКЛОНЕНИЕ" in call_kwargs["text"]
@pytest.mark.asyncio
async def test_log_auto_action_handles_exception(self, service):
"""Тест обработки исключения при отправке лога."""
mock_bot = MagicMock()
mock_bot.send_message = AsyncMock(side_effect=Exception("Network error"))
# Не должно выбрасывать исключение
await service.log_auto_action(
bot=mock_bot,
action="publish",
author_id=12345,
author_name="Test User",
author_username="testuser",
rag_score=0.85,
post_text="Test post text",
)
@pytest.mark.asyncio
async def test_log_auto_action_truncates_long_text(self, service):
"""Тест обрезки длинного текста в логе."""
mock_bot = MagicMock()
mock_bot.send_message = AsyncMock()
long_text = "a" * 300
await service.log_auto_action(
bot=mock_bot,
action="publish",
author_id=12345,
author_name="Test User",
author_username="testuser",
rag_score=0.85,
post_text=long_text,
)
call_kwargs = mock_bot.send_message.call_args[1]
# Текст должен быть обрезан до 200 символов + "..."
assert "..." in call_kwargs["text"]