Enhance /hottest command with optional limit
This commit is contained in:
parent
9fdb4b35cd
commit
a0eeba0918
@ -51,7 +51,7 @@ def get_router(storage: IVectorStore, processor: ILLMProvider, allowed_chat_id:
|
||||
"/start - Start the bot\n"
|
||||
"/help - Show this help message\n"
|
||||
"/latest [category] - Show the latest enriched news trends\n"
|
||||
"/hottest - Show top 10 ranked hot trends\n"
|
||||
"/hottest [limit] - Show top ranked hot trends (default 10, max 50)\n"
|
||||
"/search query - Search for news\n"
|
||||
"/stats - Show database statistics\n"
|
||||
"/params - Show LLM processor parameters\n"
|
||||
@ -95,11 +95,22 @@ def get_router(storage: IVectorStore, processor: ILLMProvider, allowed_chat_id:
|
||||
await message.answer("Latest news:", reply_markup=builder.as_markup())
|
||||
|
||||
@router.message(Command("hottest"))
|
||||
async def command_hottest_handler(message: Message) -> None:
|
||||
async def command_hottest_handler(message: Message, command: CommandObject) -> None:
|
||||
"""
|
||||
This handler receives messages with `/hottest` command
|
||||
"""
|
||||
items = await storage.get_top_ranked(limit=10)
|
||||
limit = 10
|
||||
if command.args:
|
||||
try:
|
||||
limit = int(command.args)
|
||||
if limit <= 0:
|
||||
limit = 10
|
||||
elif limit > 50:
|
||||
limit = 50
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
items = await storage.get_top_ranked(limit=limit)
|
||||
|
||||
if not items:
|
||||
await message.answer("No hot trends found yet.")
|
||||
@ -113,7 +124,7 @@ def get_router(storage: IVectorStore, processor: ILLMProvider, allowed_chat_id:
|
||||
callback_data=f"detail:{item_id}"
|
||||
))
|
||||
|
||||
await message.answer("Top 10 Hottest Trends:", reply_markup=builder.as_markup())
|
||||
await message.answer(f"Top {len(items)} Hottest Trends:", reply_markup=builder.as_markup())
|
||||
|
||||
@router.message(Command("search"))
|
||||
async def command_search_handler(message: Message, command: CommandObject) -> None:
|
||||
|
||||
@ -176,15 +176,16 @@ async def test_command_hottest_handler(router, mock_storage, allowed_chat_id, mo
|
||||
message = AsyncMock()
|
||||
message.chat.id = int(allowed_chat_id)
|
||||
message.answer = AsyncMock()
|
||||
command = CommandObject(prefix="/", command="hottest", args=None)
|
||||
|
||||
mock_storage.get_top_ranked.return_value = [mock_item]
|
||||
|
||||
await handler(message=message)
|
||||
await handler(message=message, command=command)
|
||||
|
||||
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 "Top 1 Hottest Trends:" in args[0]
|
||||
assert "reply_markup" in kwargs
|
||||
assert "🔥" in str(kwargs["reply_markup"])
|
||||
|
||||
@ -194,10 +195,11 @@ async def test_command_hottest_handler_empty(router, mock_storage, allowed_chat_
|
||||
message = AsyncMock()
|
||||
message.chat.id = int(allowed_chat_id)
|
||||
message.answer = AsyncMock()
|
||||
command = CommandObject(prefix="/", command="hottest", args=None)
|
||||
|
||||
mock_storage.get_top_ranked.return_value = []
|
||||
|
||||
await handler(message=message)
|
||||
await handler(message=message, command=command)
|
||||
|
||||
message.answer.assert_called_once_with("No hot trends found yet.")
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ import uuid
|
||||
import pytest
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
from aiogram.types import Message, InlineKeyboardMarkup
|
||||
from aiogram.filters import CommandObject
|
||||
from datetime import datetime
|
||||
|
||||
from src.bot.handlers import get_router
|
||||
@ -59,14 +60,15 @@ async def test_command_hottest_handler_success(router, mock_storage, allowed_cha
|
||||
mock_storage.get_top_ranked.return_value = mock_items
|
||||
|
||||
# 2. Act
|
||||
await handler(message=message)
|
||||
command = CommandObject(prefix='/', command='hottest', args=None)
|
||||
await handler(message=message, command=command)
|
||||
|
||||
# 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 "Top 3 Hottest Trends:" in args[0]
|
||||
assert "reply_markup" in kwargs
|
||||
assert isinstance(kwargs["reply_markup"], InlineKeyboardMarkup)
|
||||
|
||||
@ -95,8 +97,72 @@ async def test_command_hottest_handler_empty(router, mock_storage, allowed_chat_
|
||||
mock_storage.get_top_ranked.return_value = []
|
||||
|
||||
# 2. Act
|
||||
await handler(message=message)
|
||||
command = CommandObject(prefix='/', command='hottest', args=None)
|
||||
await handler(message=message, command=command)
|
||||
|
||||
# 3. Assert
|
||||
mock_storage.get_top_ranked.assert_called_once_with(limit=10)
|
||||
message.answer.assert_called_once_with("No hot trends found yet.")
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_command_hottest_handler_custom_limit(router, mock_storage, allowed_chat_id):
|
||||
"""
|
||||
Test that /hottest command with custom limit correctly passes it to storage.
|
||||
"""
|
||||
# 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
|
||||
command = CommandObject(prefix='/', command='hottest', args='25')
|
||||
await handler(message=message, command=command)
|
||||
|
||||
# 3. Assert
|
||||
mock_storage.get_top_ranked.assert_called_once_with(limit=25)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_command_hottest_handler_max_limit(router, mock_storage, allowed_chat_id):
|
||||
"""
|
||||
Test that /hottest command enforces maximum limit.
|
||||
"""
|
||||
# 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
|
||||
command = CommandObject(prefix='/', command='hottest', args='1000')
|
||||
await handler(message=message, command=command)
|
||||
|
||||
# 3. Assert
|
||||
mock_storage.get_top_ranked.assert_called_once_with(limit=50)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_command_hottest_handler_invalid_limit(router, mock_storage, allowed_chat_id):
|
||||
"""
|
||||
Test that /hottest command handles invalid limit by falling back to default.
|
||||
"""
|
||||
# 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
|
||||
command = CommandObject(prefix='/', command='hottest', args='invalid')
|
||||
await handler(message=message, command=command)
|
||||
|
||||
# 3. Assert
|
||||
mock_storage.get_top_ranked.assert_called_once_with(limit=10)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user