AI-Trend-Scout/tests/bot/test_hottest_command.py

103 lines
3.1 KiB
Python

import uuid
import pytest
from unittest.mock import AsyncMock, MagicMock
from aiogram.types import Message, InlineKeyboardMarkup
from datetime import datetime
from src.bot.handlers import get_router
from src.processor.dto import EnrichedNewsItemDTO
@pytest.fixture
def mock_storage():
return AsyncMock()
@pytest.fixture
def mock_processor():
processor = MagicMock()
processor.get_info.return_value = {"model": "test-model"}
return processor
@pytest.fixture
def allowed_chat_id():
return "123456789"
@pytest.fixture
def router(mock_storage, mock_processor, allowed_chat_id):
return get_router(mock_storage, mock_processor, allowed_chat_id)
def get_handler(router, callback_name):
for handler in router.message.handlers:
if handler.callback.__name__ == callback_name:
return handler.callback
raise ValueError(f"Handler {callback_name} not found")
@pytest.mark.asyncio
async def test_command_hottest_handler_success(router, mock_storage, allowed_chat_id):
"""
Test that /hottest command calls get_top_ranked and returns a list of items.
"""
# 1. Arrange
handler = get_handler(router, "command_hottest_handler")
message = AsyncMock()
message.chat = MagicMock()
message.chat.id = int(allowed_chat_id)
message.answer = AsyncMock()
mock_items = [
EnrichedNewsItemDTO(
title=f"Hot News {i}",
url=f"https://example.com/{i}",
content_text=f"Content {i}",
source="Source",
timestamp=datetime.now(),
relevance_score=10-i,
summary_ru=f"Сводка {i}",
anomalies_detected=[],
category="Tech"
) for i in range(3)
]
mock_storage.get_top_ranked.return_value = mock_items
# 2. Act
await handler(message=message)
# 3. Assert
mock_storage.get_top_ranked.assert_called_once_with(limit=10)
message.answer.assert_called_once()
args, kwargs = message.answer.call_args
assert "Top 10 Hottest Trends:" in args[0]
assert "reply_markup" in kwargs
assert isinstance(kwargs["reply_markup"], InlineKeyboardMarkup)
# Check if all 3 items are in the markup
markup = kwargs["reply_markup"]
assert len(markup.inline_keyboard) == 3
# Check if icons and scores are present
button_text = markup.inline_keyboard[0][0].text
assert "🔥" in button_text
assert "[10/10]" in button_text
assert "Hot News 0" in button_text
@pytest.mark.asyncio
async def test_command_hottest_handler_empty(router, mock_storage, allowed_chat_id):
"""
Test that /hottest command handles empty results correctly.
"""
# 1. Arrange
handler = get_handler(router, "command_hottest_handler")
message = AsyncMock()
message.chat = MagicMock()
message.chat.id = int(allowed_chat_id)
message.answer = AsyncMock()
mock_storage.get_top_ranked.return_value = []
# 2. Act
await handler(message=message)
# 3. Assert
mock_storage.get_top_ranked.assert_called_once_with(limit=10)
message.answer.assert_called_once_with("No hot trends found yet.")