import pytest import asyncio import os import tempfile from datetime import datetime from unittest.mock import Mock, AsyncMock from database.repositories.post_repository import PostRepository from database.models import TelegramPost, PostContent, MessageContentLink @pytest.fixture(scope="session") def event_loop(): """Создает event loop для асинхронных тестов""" loop = asyncio.get_event_loop_policy().new_event_loop() yield loop loop.close() @pytest.fixture def mock_post_repository(): """Создает мок PostRepository для unit тестов""" mock_repo = Mock(spec=PostRepository) mock_repo._execute_query = AsyncMock() mock_repo._execute_query_with_result = AsyncMock() mock_repo.logger = Mock() return mock_repo @pytest.fixture def sample_telegram_post(): """Создает тестовый объект TelegramPost""" return TelegramPost( message_id=12345, text="Тестовый пост для unit тестов", author_id=67890, helper_text_message_id=None, created_at=int(datetime.now().timestamp()) ) @pytest.fixture def sample_telegram_post_with_helper(): """Создает тестовый объект TelegramPost с helper сообщением""" return TelegramPost( message_id=12346, text="Тестовый пост с helper сообщением", author_id=67890, helper_text_message_id=99999, created_at=int(datetime.now().timestamp()) ) @pytest.fixture def sample_telegram_post_no_date(): """Создает тестовый объект TelegramPost без даты""" return TelegramPost( message_id=12347, text="Тестовый пост без даты", author_id=67890, helper_text_message_id=None, created_at=None ) @pytest.fixture def sample_post_content(): """Создает тестовый объект PostContent""" return PostContent( message_id=12345, content_name="/path/to/test/file.jpg", content_type="photo" ) @pytest.fixture def sample_message_content_link(): """Создает тестовый объект MessageContentLink""" return MessageContentLink( post_id=12345, message_id=67890 ) @pytest.fixture def mock_db_execute_query(): """Создает мок для _execute_query""" return AsyncMock() @pytest.fixture def mock_db_execute_query_with_result(): """Создает мок для _execute_query_with_result""" return AsyncMock() @pytest.fixture def mock_logger(): """Создает мок для logger""" return Mock() @pytest.fixture def temp_db_file(): """Создает временный файл БД для интеграционных тестов""" with tempfile.NamedTemporaryFile(suffix='.db', delete=False) as tmp_file: db_path = tmp_file.name yield db_path # Очищаем временный файл после тестов try: os.unlink(db_path) except OSError: pass @pytest.fixture def real_post_repository(temp_db_file): """Создает реальный PostRepository с временной БД для интеграционных тестов""" return PostRepository(temp_db_file) @pytest.fixture def sample_posts_batch(): """Создает набор тестовых постов для batch тестов""" return [ TelegramPost( message_id=10001, text="Первый тестовый пост", author_id=11111, helper_text_message_id=None, created_at=int(datetime.now().timestamp()) ), TelegramPost( message_id=10002, text="Второй тестовый пост", author_id=22222, helper_text_message_id=None, created_at=int(datetime.now().timestamp()) ), TelegramPost( message_id=10003, text="Третий тестовый пост", author_id=33333, helper_text_message_id=88888, created_at=int(datetime.now().timestamp()) ) ] @pytest.fixture def sample_content_batch(): """Создает набор тестового контента для batch тестов""" return [ (10001, "/path/to/photo1.jpg", "photo"), (10002, "/path/to/video1.mp4", "video"), (10003, "/path/to/audio1.mp3", "audio"), (10004, "/path/to/photo2.jpg", "photo"), (10005, "/path/to/video2.mp4", "video") ] @pytest.fixture def mock_database_connection(): """Создает мок для DatabaseConnection""" mock_conn = Mock() mock_conn._execute_query = AsyncMock() mock_conn._execute_query_with_result = AsyncMock() mock_conn.logger = Mock() return mock_conn @pytest.fixture def sample_helper_message_ids(): """Создает набор тестовых helper message ID""" return [11111, 22222, 33333, 44444, 55555] @pytest.fixture def sample_message_ids(): """Создает набор тестовых message ID""" return [10001, 10002, 10003, 10004, 10005] @pytest.fixture def sample_author_ids(): """Создает набор тестовых author ID""" return [11111, 22222, 33333, 44444, 55555] @pytest.fixture def mock_sql_queries(): """Создает мок для SQL запросов""" return { 'create_tables': [ "CREATE TABLE IF NOT EXISTS post_from_telegram_suggest", "CREATE TABLE IF NOT EXISTS content_post_from_telegram", "CREATE TABLE IF NOT EXISTS message_link_to_content" ], 'add_post': "INSERT INTO post_from_telegram_suggest", 'update_helper': "UPDATE post_from_telegram_suggest SET helper_text_message_id", 'add_content': "INSERT OR IGNORE INTO content_post_from_telegram", 'add_link': "INSERT OR IGNORE INTO message_link_to_content", 'get_content': "SELECT cpft.content_name, cpft.content_type", 'get_text': "SELECT text FROM post_from_telegram_suggest", 'get_ids': "SELECT mltc.message_id", 'get_author': "SELECT author_id FROM post_from_telegram_suggest" }