Files
telegram-helper-bot/tests/test_message_repository.py
2026-02-01 22:49:25 +03:00

206 lines
8.8 KiB
Python
Raw 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.
import asyncio
from datetime import datetime
from unittest.mock import AsyncMock, MagicMock
import pytest
from database.models import UserMessage
from database.repositories.message_repository import MessageRepository
class TestMessageRepository:
"""Тесты для MessageRepository."""
@pytest.fixture
def mock_db_path(self):
"""Фикстура для пути к тестовой БД."""
return ":memory:"
@pytest.fixture
def message_repository(self, mock_db_path):
"""Фикстура для MessageRepository."""
return MessageRepository(mock_db_path)
@pytest.fixture
def sample_message(self):
"""Фикстура для тестового сообщения."""
return UserMessage(
message_text="Тестовое сообщение",
user_id=12345,
telegram_message_id=67890,
date=int(datetime.now().timestamp())
)
@pytest.fixture
def sample_message_no_date(self):
"""Фикстура для тестового сообщения без даты."""
return UserMessage(
message_text="Тестовое сообщение без даты",
user_id=12345,
telegram_message_id=67891,
date=None
)
@pytest.mark.asyncio
async def test_create_tables(self, message_repository):
"""Тест создания таблиц."""
# Мокаем _execute_query
message_repository._execute_query = AsyncMock()
await message_repository.create_tables()
message_repository._execute_query.assert_called_once()
call_args = message_repository._execute_query.call_args[0][0]
assert "CREATE TABLE IF NOT EXISTS user_messages" in call_args
assert "telegram_message_id INTEGER NOT NULL" in call_args
assert "date INTEGER NOT NULL" in call_args
assert "FOREIGN KEY (user_id) REFERENCES our_users (user_id) ON DELETE CASCADE" in call_args
@pytest.mark.asyncio
async def test_add_message_with_date(self, message_repository, sample_message):
"""Тест добавления сообщения с датой."""
# Мокаем _execute_query
message_repository._execute_query = AsyncMock()
await message_repository.add_message(sample_message)
message_repository._execute_query.assert_called_once()
call_args = message_repository._execute_query.call_args
query = call_args[0][0]
params = call_args[0][1]
assert "INSERT INTO user_messages" in query
assert "VALUES (?, ?, ?, ?)" in query
assert params == (
sample_message.message_text,
sample_message.user_id,
sample_message.telegram_message_id,
sample_message.date
)
@pytest.mark.asyncio
async def test_add_message_without_date(self, message_repository, sample_message_no_date):
"""Тест добавления сообщения без даты (должна генерироваться автоматически)."""
# Мокаем _execute_query
message_repository._execute_query = AsyncMock()
await message_repository.add_message(sample_message_no_date)
# Проверяем, что дата была установлена
assert sample_message_no_date.date is not None
assert isinstance(sample_message_no_date.date, int)
assert sample_message_no_date.date > 0
message_repository._execute_query.assert_called_once()
call_args = message_repository._execute_query.call_args
params = call_args[0][1]
assert params[3] == sample_message_no_date.date # date field
@pytest.mark.asyncio
async def test_add_message_logs_correctly(self, message_repository, sample_message):
"""Тест логирования при добавлении сообщения."""
# Мокаем _execute_query и logger
message_repository._execute_query = AsyncMock()
message_repository.logger = MagicMock()
await message_repository.add_message(sample_message)
message_repository.logger.info.assert_called_once()
log_message = message_repository.logger.info.call_args[0][0]
assert f"telegram_message_id={sample_message.telegram_message_id}" in log_message
@pytest.mark.asyncio
async def test_get_user_by_message_id_found(self, message_repository):
"""Тест получения пользователя по message_id (пользователь найден)."""
message_id = 67890
expected_user_id = 12345
# Мокаем _execute_query_with_result
message_repository._execute_query_with_result = AsyncMock(
return_value=[[expected_user_id]]
)
result = await message_repository.get_user_by_message_id(message_id)
assert result == expected_user_id
message_repository._execute_query_with_result.assert_called_once_with(
"SELECT user_id FROM user_messages WHERE telegram_message_id = ?",
(message_id,)
)
@pytest.mark.asyncio
async def test_get_user_by_message_id_not_found(self, message_repository):
"""Тест получения пользователя по message_id (пользователь не найден)."""
message_id = 99999
# Мокаем _execute_query_with_result
message_repository._execute_query_with_result = AsyncMock(return_value=[])
result = await message_repository.get_user_by_message_id(message_id)
assert result is None
message_repository._execute_query_with_result.assert_called_once_with(
"SELECT user_id FROM user_messages WHERE telegram_message_id = ?",
(message_id,)
)
@pytest.mark.asyncio
async def test_get_user_by_message_id_empty_result(self, message_repository):
"""Тест получения пользователя по message_id (пустой результат)."""
message_id = 99999
# Мокаем _execute_query_with_result
message_repository._execute_query_with_result = AsyncMock(return_value=[[]])
result = await message_repository.get_user_by_message_id(message_id)
assert result is None
@pytest.mark.asyncio
async def test_add_message_handles_exception(self, message_repository, sample_message):
"""Тест обработки исключений при добавлении сообщения."""
# Мокаем _execute_query для вызова исключения
message_repository._execute_query = AsyncMock(side_effect=Exception("Database error"))
with pytest.raises(Exception, match="Database error"):
await message_repository.add_message(sample_message)
@pytest.mark.asyncio
async def test_get_user_by_message_id_handles_exception(self, message_repository):
"""Тест обработки исключений при получении пользователя."""
# Мокаем _execute_query_with_result для вызова исключения
message_repository._execute_query_with_result = AsyncMock(
side_effect=Exception("Database error")
)
with pytest.raises(Exception, match="Database error"):
await message_repository.get_user_by_message_id(12345)
@pytest.mark.asyncio
async def test_add_message_with_zero_date(self, message_repository):
"""Тест добавления сообщения с датой равной 0 (должна генерироваться новая)."""
message = UserMessage(
message_text="Тестовое сообщение с нулевой датой",
user_id=12345,
telegram_message_id=67892,
date=0
)
# Мокаем _execute_query
message_repository._execute_query = AsyncMock()
await message_repository.add_message(message)
# Проверяем, что дата была изменена с 0 (теперь это происходит только если date is None)
# В текущей реализации дата 0 считается валидной и не изменяется
assert isinstance(message.date, int)
assert message.date >= 0
message_repository._execute_query.assert_called_once()
params = message_repository._execute_query.call_args[0][1]
assert params[3] == message.date # date field
if __name__ == "__main__":
pytest.main([__file__])