Files
telegram-helper-bot/tests/test_deepseek_service.py
2026-02-02 00:54:23 +03:00

126 lines
4.9 KiB
Python
Raw Permalink 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.
"""
Тесты для helper_bot.services.scoring.deepseek_service (DeepSeekService).
"""
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from helper_bot.services.scoring.deepseek_service import DeepSeekService
from helper_bot.services.scoring.exceptions import (
DeepSeekAPIError,
ScoringError,
TextTooShortError,
)
@pytest.mark.unit
class TestDeepSeekServiceInit:
"""Тесты инициализации DeepSeekService."""
def test_init_with_api_key_enabled(self):
"""При переданном api_key сервис включён."""
with patch(
"helper_bot.services.scoring.deepseek_service.httpx.AsyncClient", None
):
service = DeepSeekService(api_key="key")
assert service.is_enabled is True
assert service.source_name == "deepseek"
def test_init_without_api_key_disabled(self):
"""Без api_key сервис отключён."""
service = DeepSeekService(api_key=None)
assert service.is_enabled is False
def test_init_default_url_and_model(self):
"""Используются DEFAULT_API_URL и DEFAULT_MODEL."""
service = DeepSeekService(api_key="k")
assert service.api_url == DeepSeekService.DEFAULT_API_URL
assert service.model == DeepSeekService.DEFAULT_MODEL
@pytest.mark.unit
class TestDeepSeekServiceHelpers:
"""Тесты _clean_text и _parse_score_response."""
def test_clean_text_strips_and_collapses_whitespace(self):
"""_clean_text убирает лишние пробелы и переносы."""
service = DeepSeekService(api_key="k")
assert service._clean_text(" a b \n c ") == "a b c"
def test_clean_text_empty_returns_empty(self):
"""_clean_text для пустой строки возвращает ''."""
service = DeepSeekService(api_key="k")
assert service._clean_text("") == ""
assert service._clean_text(" ") == ""
def test_parse_score_response_valid_number(self):
"""_parse_score_response парсит число."""
service = DeepSeekService(api_key="k")
assert service._parse_score_response("0.75") == 0.75
assert service._parse_score_response("1.0") == 1.0
assert service._parse_score_response("0") == 0.0
def test_parse_score_response_clamps_to_range(self):
"""_parse_score_response ограничивает значение 0.01.0."""
service = DeepSeekService(api_key="k")
assert service._parse_score_response("1.5") == 1.0
assert service._parse_score_response("-0.1") == 0.0
def test_parse_score_response_invalid_raises(self):
"""_parse_score_response при невалидном ответе выбрасывает DeepSeekAPIError."""
service = DeepSeekService(api_key="k")
with pytest.raises(DeepSeekAPIError, match="распарсить"):
service._parse_score_response("not a number")
@pytest.mark.unit
@pytest.mark.asyncio
class TestDeepSeekServiceCalculateScore:
"""Тесты calculate_score."""
@pytest.fixture
def service(self):
"""Сервис с api_key."""
return DeepSeekService(api_key="key", min_text_length=3)
async def test_disabled_raises_scoring_error(self, service):
"""При отключённом сервисе — ScoringError."""
service._enabled = False
with pytest.raises(ScoringError, match="отключен"):
await service.calculate_score("достаточно длинный текст")
async def test_text_too_short_raises(self, service):
"""Текст короче min_text_length — TextTooShortError."""
with pytest.raises(TextTooShortError, match="короткий"):
await service.calculate_score("ab")
async def test_success_returns_scoring_result(self, service):
"""Успешный запрос возвращает ScoringResult."""
with patch.object(
service,
"_make_api_request",
new_callable=AsyncMock,
return_value=0.82,
):
result = await service.calculate_score("Текст поста для оценки")
assert result.score == 0.82
assert result.source == "deepseek"
assert result.model == service.model
@pytest.mark.unit
class TestDeepSeekServiceStats:
"""Тесты get_stats."""
def test_get_stats_returns_dict(self):
"""get_stats возвращает словарь с enabled, model, api_url, timeout, max_retries."""
service = DeepSeekService(api_key="k", timeout=60, max_retries=5)
stats = service.get_stats()
assert stats["enabled"] is True
assert stats["model"] == service.model
assert stats["api_url"] == service.api_url
assert stats["timeout"] == 60
assert stats["max_retries"] == 5