AI-Trend-Scout/tests/bot/test_exporters.py
Artur Mukhamadiev e1c7f47f8f Feature: Add /get_hottest command for exporting top trends
:Release Notes:
- Added a new Telegram command `/get_hottest <number> [format]` to export the top `N` trends as a CSV or Markdown file.

:Detailed Notes:
- Created `ITrendExporter` interface and concrete `CsvTrendExporter` and `MarkdownTrendExporter` implementations for formatting DTOs.
- Updated `src/bot/handlers.py` to include `command_get_hottest_handler` mapping to `/get_hottest`.
- Used `BufferedInputFile` to stream generated files asynchronously directly to Telegram without disk I/O.
- Fixed unrelated pipeline test failures regarding `EphemeralClient` usage with ChromaDB.

:Testing Performed:
- Implemented TDD with `pytest` for parsing parameters, exporting logic, and handling empty DB scenarios.
- Ran the full test suite (90 tests) which completed successfully.

:QA Notes:
- Fully covered the new handler using `pytest-asyncio` and `aiogram` mocked objects.

:Issues Addressed:
- Resolves request to export high-relevance parsed entries.

Change-Id: I25dd90f1e4491ba298682518d835259bffab4190
2026-03-19 14:53:20 +03:00

82 lines
3.3 KiB
Python

import pytest
from datetime import datetime
from src.processor.dto import EnrichedNewsItemDTO
from src.bot.exporters import CsvTrendExporter, MarkdownTrendExporter
@pytest.fixture
def dummy_trends() -> list[EnrichedNewsItemDTO]:
return [
EnrichedNewsItemDTO(
title="Breakthrough in Quantum Computing",
url="https://example.com/quantum",
content_text="Scientists achieve a major milestone...",
source="TechNews",
timestamp=datetime(2023, 10, 27, 12, 0),
relevance_score=9,
summary_ru="Прорыв в квантовых вычислениях...",
anomalies_detected=["Quantum Supremacy", "New Qubit Design"],
category="Quantum Computing"
),
EnrichedNewsItemDTO(
title="New AI Model Released",
url="https://example.com/ai",
content_text="A new AI model has been released...",
source="AITimes",
timestamp=datetime(2023, 10, 27, 13, 0),
relevance_score=8,
summary_ru="Выпущен новый ИИ...",
anomalies_detected=[],
category="Artificial Intelligence"
)
]
@pytest.mark.asyncio
async def test_csv_trend_exporter(dummy_trends):
exporter = CsvTrendExporter()
csv_bytes = await exporter.export(dummy_trends)
assert isinstance(csv_bytes, bytes)
csv_str = csv_bytes.decode('utf-8')
lines = csv_str.strip().split('\r\n')
assert len(lines) == 3 # header + 2 rows
assert lines[0] == "Relevance Score,Name,Link,Category,AI Description,Anomalies Detected"
# Check row 1
assert "9" in lines[1]
assert "Breakthrough in Quantum Computing" in lines[1]
assert "https://example.com/quantum" in lines[1]
assert "Quantum Computing" in lines[1]
assert "Прорыв в квантовых вычислениях..." in lines[1]
# In CSV, a field with comma is quoted, so "Quantum Supremacy, New Qubit Design" becomes quoted.
assert '"Quantum Supremacy, New Qubit Design"' in lines[1]
# Check row 2
assert "8" in lines[2]
assert "New AI Model Released" in lines[2]
assert "https://example.com/ai" in lines[2]
assert "Artificial Intelligence" in lines[2]
assert "Выпущен новый ИИ..." in lines[2]
assert "AITimes" not in lines[2] # source is not exported
@pytest.mark.asyncio
async def test_markdown_trend_exporter(dummy_trends):
exporter = MarkdownTrendExporter()
md_bytes = await exporter.export(dummy_trends)
assert isinstance(md_bytes, bytes)
md_str = md_bytes.decode('utf-8')
lines = md_str.strip().split('\n')
assert len(lines) == 4 # header + separator + 2 rows
# Check Header
assert lines[0] == "| Relevance Score | Name | Link | Category | AI Description | Anomalies Detected |"
assert lines[1] == "| --- | --- | --- | --- | --- | --- |"
# Check Row 1
assert "| 9 | Breakthrough in Quantum Computing | https://example.com/quantum | Quantum Computing | Прорыв в квантовых вычислениях... | Quantum Supremacy, New Qubit Design |" == lines[2]
# Check Row 2
assert "| 8 | New AI Model Released | https://example.com/ai | Artificial Intelligence | Выпущен новый ИИ... | |" == lines[3]