WIP: Temporary commit for branch move

This commit is contained in:
2025-08-26 02:14:11 +03:00
parent ee9eafa09f
commit 7b6abe2a0e
44 changed files with 4783 additions and 2383 deletions

234
tests/conftest.py Normal file
View File

@@ -0,0 +1,234 @@
import pytest
import asyncio
import os
import sys
from unittest.mock import Mock, AsyncMock, patch
from aiogram.types import Message, User, Chat
from aiogram.fsm.context import FSMContext
from database.db import BotDB
# Импортируем моки в самом начале
import tests.mocks
@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_message():
"""Создает базовый мок сообщения для тестов"""
message = Mock(spec=Message)
message.from_user = Mock(spec=User)
message.from_user.id = 123456
message.from_user.full_name = "Test User"
message.from_user.username = "testuser"
message.from_user.first_name = "Test"
message.from_user.is_bot = False
message.from_user.language_code = "ru"
message.chat = Mock(spec=Chat)
message.chat.id = 123456
message.chat.type = "private"
message.message_id = 1
message.text = "/start"
message.forward = AsyncMock()
message.answer = AsyncMock()
message.answer_sticker = AsyncMock()
message.bot.send_message = AsyncMock()
return message
@pytest.fixture
def mock_state():
"""Создает мок состояния FSM для тестов"""
state = Mock(spec=FSMContext)
state.set_state = AsyncMock()
state.get_state = AsyncMock(return_value="START")
return state
@pytest.fixture
def mock_db():
"""Создает мок базы данных для тестов"""
db = Mock(spec=BotDB)
db.user_exists = Mock(return_value=False)
db.add_new_user_in_db = Mock()
db.update_date_for_user = Mock()
db.update_username_and_full_name = Mock()
db.add_post_in_db = Mock()
db.update_info_about_stickers = Mock()
db.add_new_message_in_db = Mock()
db.get_info_about_stickers = Mock(return_value=False)
db.get_username_and_full_name = Mock(return_value=("testuser", "Test User"))
return db
@pytest.fixture
def mock_bot():
"""Создает мок бота для тестов"""
bot = AsyncMock()
bot.send_message = AsyncMock()
bot.delete_webhook = AsyncMock()
return bot
@pytest.fixture
def mock_dispatcher():
"""Создает мок диспетчера для тестов"""
dispatcher = AsyncMock()
dispatcher.include_routers = Mock()
dispatcher.start_polling = AsyncMock()
return dispatcher
@pytest.fixture
def test_settings():
"""Возвращает тестовые настройки"""
return {
'Telegram': {
'bot_token': 'test_token_123',
'preview_link': False,
'group_for_posts': '-1001234567890',
'group_for_message': '-1001234567891',
'main_public': '-1001234567892',
'group_for_logs': '-1001234567893',
'important_logs': '-1001234567894'
},
'Settings': {
'logs': True,
'test': False
}
}
@pytest.fixture
def mock_factory(test_settings, mock_db):
"""Создает мок фабрики зависимостей"""
factory = Mock()
factory.settings = test_settings
factory.get_db = Mock(return_value=mock_db)
factory.database = mock_db
return factory
@pytest.fixture
def sample_photo_message(mock_message):
"""Создает сообщение с фото для тестов"""
mock_message.content_type = 'photo'
mock_message.caption = 'Тестовое фото'
mock_message.media_group_id = None
mock_message.photo = [Mock()]
mock_message.photo[-1].file_id = 'photo_file_id'
return mock_message
@pytest.fixture
def sample_video_message(mock_message):
"""Создает сообщение с видео для тестов"""
mock_message.content_type = 'video'
mock_message.caption = 'Тестовое видео'
mock_message.media_group_id = None
mock_message.video = Mock()
mock_message.video.file_id = 'video_file_id'
return mock_message
@pytest.fixture
def sample_audio_message(mock_message):
"""Создает сообщение с аудио для тестов"""
mock_message.content_type = 'audio'
mock_message.caption = 'Тестовое аудио'
mock_message.media_group_id = None
mock_message.audio = Mock()
mock_message.audio.file_id = 'audio_file_id'
return mock_message
@pytest.fixture
def sample_voice_message(mock_message):
"""Создает голосовое сообщение для тестов"""
mock_message.content_type = 'voice'
mock_message.media_group_id = None
mock_message.voice = Mock()
mock_message.voice.file_id = 'voice_file_id'
return mock_message
@pytest.fixture
def sample_video_note_message(mock_message):
"""Создает видеокружок для тестов"""
mock_message.content_type = 'video_note'
mock_message.media_group_id = None
mock_message.video_note = Mock()
mock_message.video_note.file_id = 'video_note_file_id'
return mock_message
@pytest.fixture
def sample_media_group(mock_message):
"""Создает медиагруппу для тестов"""
mock_message.media_group_id = 'group_123'
mock_message.content_type = 'photo'
album = [mock_message]
album[0].caption = 'Подпись к медиагруппе'
return album
@pytest.fixture
def sample_text_message(mock_message):
"""Создает текстовое сообщение для тестов"""
mock_message.content_type = 'text'
mock_message.text = 'Тестовое текстовое сообщение'
mock_message.media_group_id = None
return mock_message
@pytest.fixture
def sample_document_message(mock_message):
"""Создает сообщение с документом для тестов"""
mock_message.content_type = 'document'
mock_message.media_group_id = None
return mock_message
# Маркеры для категоризации тестов
def pytest_configure(config):
"""Настройка маркеров pytest"""
config.addinivalue_line(
"markers", "asyncio: mark test as async"
)
config.addinivalue_line(
"markers", "slow: mark test as slow"
)
config.addinivalue_line(
"markers", "integration: mark test as integration test"
)
config.addinivalue_line(
"markers", "unit: mark test as unit test"
)
# Автоматическая маркировка тестов
def pytest_collection_modifyitems(config, items):
"""Автоматически маркирует тесты по их расположению"""
for item in items:
# Маркируем асинхронные тесты
if "async" in item.name or "Async" in item.name:
item.add_marker(pytest.mark.asyncio)
# Маркируем интеграционные тесты
if "integration" in item.name.lower() or "Integration" in str(item.cls):
item.add_marker(pytest.mark.integration)
# Маркируем unit тесты
if "unit" in item.name.lower() or "Unit" in str(item.cls):
item.add_marker(pytest.mark.unit)
# Маркируем медленные тесты
if "slow" in item.name.lower() or "Slow" in str(item.cls):
item.add_marker(pytest.mark.slow)