Переписал почти все тесты

feat: улучшено логирование и обработка скорингов в PostService и RagApiClient

- Добавлены отладочные сообщения для передачи скорингов в функции обработки постов.
- Обновлено логирование успешного получения скорингов из RAG API с дополнительной информацией.
- Оптимизирована обработка скорингов в функции get_text_message для улучшения отладки.
- Обновлены тесты для проверки новых функциональных возможностей и обработки ошибок.
This commit is contained in:
2026-01-30 00:55:47 +03:00
parent e87f4af82f
commit a5faa4bdc6
27 changed files with 4320 additions and 8 deletions

View File

@@ -0,0 +1,176 @@
"""
Тесты для helper_bot.handlers.admin.dependencies: AdminAccessMiddleware, get_bot_db, get_settings.
"""
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from helper_bot.handlers.admin.dependencies import (
AdminAccessMiddleware,
get_bot_db,
get_settings,
)
@pytest.mark.unit
@pytest.mark.asyncio
class TestAdminAccessMiddleware:
"""Тесты для AdminAccessMiddleware."""
@pytest.fixture
def middleware(self):
"""Экземпляр middleware."""
return AdminAccessMiddleware()
@pytest.fixture
def mock_handler(self):
"""Мок handler."""
return AsyncMock(return_value="handler_result")
@patch("helper_bot.handlers.admin.dependencies.check_access", new_callable=AsyncMock)
async def test_access_granted_calls_handler(self, mock_check_access, middleware, mock_handler):
"""При доступе разрешён вызывается handler с event и data."""
mock_check_access.return_value = True
event = MagicMock()
event.from_user = MagicMock()
event.from_user.id = 123
event.from_user.username = "admin"
data = {"bot_db": MagicMock()}
result = await middleware(mock_handler, event, data)
mock_check_access.assert_awaited_once_with(123, data["bot_db"])
mock_handler.assert_awaited_once_with(event, data)
assert result == "handler_result"
@patch("helper_bot.handlers.admin.dependencies.check_access", new_callable=AsyncMock)
async def test_access_denied_answers_and_does_not_call_handler(
self, mock_check_access, middleware, mock_handler
):
"""При доступе запрещён отправляется ответ и handler не вызывается."""
mock_check_access.return_value = False
event = MagicMock()
event.from_user = MagicMock()
event.from_user.id = 456
event.from_user.username = "user"
event.answer = AsyncMock()
data = {"bot_db": MagicMock()}
result = await middleware(mock_handler, event, data)
mock_check_access.assert_awaited_once()
event.answer.assert_awaited_once_with("Доступ запрещен!")
mock_handler.assert_not_awaited()
assert result is None
@patch("helper_bot.handlers.admin.dependencies.check_access", new_callable=AsyncMock)
@patch("helper_bot.handlers.admin.dependencies.get_global_instance")
async def test_fallback_get_db_from_global_when_bot_db_missing(
self, mock_get_global, mock_check_access, middleware, mock_handler
):
"""Если bot_db нет в data, берётся из get_global_instance().get_db()."""
mock_check_access.return_value = True
mock_bdf = MagicMock()
mock_bdf.get_db.return_value = MagicMock()
mock_get_global.return_value = mock_bdf
event = MagicMock()
event.from_user = MagicMock()
event.from_user.id = 1
event.from_user.username = "u"
data = {}
await middleware(mock_handler, event, data)
mock_get_global.assert_called_once()
mock_bdf.get_db.assert_called_once()
mock_check_access.assert_awaited_once_with(1, mock_bdf.get_db.return_value)
@patch("helper_bot.handlers.admin.dependencies.check_access", new_callable=AsyncMock)
async def test_event_without_from_user_calls_handler(self, mock_check_access, middleware, mock_handler):
"""Если у event нет from_user, handler вызывается (проверка доступа не выполняется)."""
class EventWithoutUser:
pass
event = EventWithoutUser()
data = {}
result = await middleware(mock_handler, event, data)
mock_check_access.assert_not_awaited()
mock_handler.assert_awaited_once_with(event, data)
assert result == "handler_result"
@patch("helper_bot.handlers.admin.dependencies.check_access", new_callable=AsyncMock)
async def test_handler_typeerror_missing_data_calls_handler_without_data(
self, mock_check_access, middleware
):
"""При TypeError из-за отсутствия data вызывается handler(event) без data."""
mock_check_access.return_value = True
call_count = 0
async def handler(event, data=None):
nonlocal call_count
call_count += 1
if call_count == 1 and data is not None:
raise TypeError("missing 1 required positional argument: 'data'")
return "ok"
handler.__name__ = "test_handler"
event = MagicMock()
event.from_user = MagicMock()
event.from_user.id = 1
event.from_user.username = "u"
data = {"bot_db": MagicMock()}
result = await middleware(handler, event, data)
assert call_count == 2
assert result == "ok"
@patch("helper_bot.handlers.admin.dependencies.check_access", new_callable=AsyncMock)
async def test_handler_other_exception_reraises(self, mock_check_access, middleware):
"""При другом исключении в handler оно пробрасывается."""
mock_check_access.return_value = True
async def handler(event, data):
raise ValueError("other error")
event = MagicMock()
event.from_user = MagicMock()
event.from_user.id = 1
event.from_user.username = "u"
data = {"bot_db": MagicMock()}
with pytest.raises(ValueError, match="other error"):
await middleware(handler, event, data)
@pytest.mark.unit
class TestDependencyProviders:
"""Тесты для get_bot_db и get_settings."""
@patch("helper_bot.handlers.admin.dependencies.get_global_instance")
def test_get_bot_db_returns_bdf_get_db(self, mock_get_global):
"""get_bot_db возвращает bdf.get_db()."""
mock_bdf = MagicMock()
mock_db = MagicMock()
mock_bdf.get_db.return_value = mock_db
mock_get_global.return_value = mock_bdf
result = get_bot_db()
mock_get_global.assert_called_once()
mock_bdf.get_db.assert_called_once()
assert result is mock_db
@patch("helper_bot.handlers.admin.dependencies.get_global_instance")
def test_get_settings_returns_bdf_settings(self, mock_get_global):
"""get_settings возвращает bdf.settings."""
mock_bdf = MagicMock()
mock_bdf.settings = {"Telegram": {"bot_token": "x"}}
mock_get_global.return_value = mock_bdf
result = get_settings()
mock_get_global.assert_called_once()
assert result == {"Telegram": {"bot_token": "x"}}