feat: добавлена система миграций БД и CI/CD пайплайны
- Создана система отслеживания миграций (MigrationRepository, таблица migrations) - Добавлен скрипт apply_migrations.py для автоматического применения миграций - Созданы CI/CD пайплайны (.github/workflows/ci.yml, deploy.yml) - Обновлена документация по миграциям в database-patterns.md - Миграции применяются автоматически при деплое в продакшн
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
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 unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.types import Chat, Message, User
|
||||
from database.async_db import AsyncBotDB
|
||||
|
||||
# Импортируем моки в самом начале
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import pytest
|
||||
import tempfile
|
||||
import os
|
||||
import tempfile
|
||||
from datetime import datetime
|
||||
from database.repositories.message_repository import MessageRepository
|
||||
|
||||
import pytest
|
||||
from database.models import UserMessage
|
||||
from database.repositories.message_repository import MessageRepository
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import pytest
|
||||
import asyncio
|
||||
import os
|
||||
import tempfile
|
||||
from datetime import datetime
|
||||
from unittest.mock import Mock, AsyncMock
|
||||
from unittest.mock import AsyncMock, Mock
|
||||
|
||||
import pytest
|
||||
from database.models import MessageContentLink, PostContent, TelegramPost
|
||||
from database.repositories.post_repository import PostRepository
|
||||
from database.models import TelegramPost, PostContent, MessageContentLink
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
"""
|
||||
Моки для тестового окружения
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import sys
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
|
||||
# Патчим загрузку настроек до импорта модулей
|
||||
def setup_test_mocks():
|
||||
"""Настройка моков для тестов"""
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch, MagicMock
|
||||
from datetime import datetime
|
||||
import time
|
||||
from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
from database.repositories.admin_repository import AdminRepository
|
||||
import pytest
|
||||
from database.models import Admin
|
||||
from database.repositories.admin_repository import AdminRepository
|
||||
|
||||
|
||||
class TestAdminRepository:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch
|
||||
from database.async_db import AsyncBotDB
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch, MagicMock, mock_open
|
||||
from datetime import datetime
|
||||
import time
|
||||
from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, mock_open, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.handlers.voice.exceptions import (DatabaseError,
|
||||
FileOperationError)
|
||||
from helper_bot.handlers.voice.services import AudioFileService
|
||||
from helper_bot.handlers.voice.exceptions import FileOperationError, DatabaseError
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch, MagicMock
|
||||
from datetime import datetime
|
||||
import time
|
||||
from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from database.models import AudioListenRecord, AudioMessage, AudioModerate
|
||||
from database.repositories.audio_repository import AudioRepository
|
||||
from database.models import AudioMessage, AudioListenRecord, AudioModerate
|
||||
|
||||
|
||||
class TestAudioRepository:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch, MagicMock
|
||||
from datetime import datetime
|
||||
import time
|
||||
from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from database.repositories.audio_repository import AudioRepository
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import pytest
|
||||
import sqlite3
|
||||
import os
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from unittest.mock import Mock, patch, AsyncMock
|
||||
import sqlite3
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.utils.auto_unban_scheduler import AutoUnbanScheduler
|
||||
|
||||
|
||||
@@ -155,8 +155,9 @@ class TestAutoUnbanIntegration:
|
||||
}
|
||||
|
||||
# Создаем реальный экземпляр базы данных с тестовым файлом
|
||||
from database.async_db import AsyncBotDB
|
||||
import os
|
||||
|
||||
from database.async_db import AsyncBotDB
|
||||
mock_factory.database = AsyncBotDB(test_db_path)
|
||||
|
||||
return mock_factory
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import pytest
|
||||
import asyncio
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from unittest.mock import Mock, patch, AsyncMock
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
from helper_bot.utils.auto_unban_scheduler import AutoUnbanScheduler, get_auto_unban_scheduler
|
||||
import pytest
|
||||
from helper_bot.utils.auto_unban_scheduler import (AutoUnbanScheduler,
|
||||
get_auto_unban_scheduler)
|
||||
|
||||
|
||||
class TestAutoUnbanScheduler:
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch
|
||||
from datetime import datetime
|
||||
import time
|
||||
from datetime import datetime
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
from database.repositories.blacklist_history_repository import BlacklistHistoryRepository
|
||||
import pytest
|
||||
from database.models import BlacklistHistoryRecord
|
||||
from database.repositories.blacklist_history_repository import \
|
||||
BlacklistHistoryRepository
|
||||
|
||||
|
||||
class TestBlacklistHistoryRepository:
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch, MagicMock
|
||||
from datetime import datetime
|
||||
import time
|
||||
from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
from database.repositories.blacklist_repository import BlacklistRepository
|
||||
import pytest
|
||||
from database.models import BlacklistUser
|
||||
from database.repositories.blacklist_repository import BlacklistRepository
|
||||
|
||||
|
||||
class TestBlacklistRepository:
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch, MagicMock
|
||||
from datetime import datetime
|
||||
import time
|
||||
from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.handlers.callback.callback_handlers import (
|
||||
save_voice_message,
|
||||
delete_voice_message
|
||||
)
|
||||
from helper_bot.handlers.voice.constants import CALLBACK_SAVE, CALLBACK_DELETE
|
||||
delete_voice_message, save_voice_message)
|
||||
from helper_bot.handlers.voice.constants import CALLBACK_DELETE, CALLBACK_SAVE
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
||||
@@ -2,18 +2,15 @@
|
||||
Тесты для улучшенных методов обработки медиа
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import os
|
||||
import tempfile
|
||||
from unittest.mock import Mock, AsyncMock, patch, MagicMock
|
||||
from aiogram import types
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from aiogram import types
|
||||
from helper_bot.utils.helper_func import (
|
||||
download_file,
|
||||
add_in_db_media,
|
||||
add_in_db_media_mediagroup,
|
||||
send_media_group_message_to_private_chat
|
||||
)
|
||||
add_in_db_media, add_in_db_media_mediagroup, download_file,
|
||||
send_media_group_message_to_private_chat)
|
||||
|
||||
|
||||
class TestDownloadFile:
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import pytest
|
||||
from unittest.mock import Mock, patch, AsyncMock
|
||||
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
from helper_bot.keyboards.keyboards import (
|
||||
get_reply_keyboard,
|
||||
get_reply_keyboard_admin,
|
||||
get_reply_keyboard_for_post,
|
||||
get_reply_keyboard_leave_chat,
|
||||
create_keyboard_with_pagination
|
||||
)
|
||||
from helper_bot.filters.main import ChatTypeFilter
|
||||
import pytest
|
||||
from aiogram.types import (InlineKeyboardButton, InlineKeyboardMarkup,
|
||||
KeyboardButton, ReplyKeyboardMarkup)
|
||||
from database.async_db import AsyncBotDB
|
||||
from helper_bot.filters.main import ChatTypeFilter
|
||||
from helper_bot.keyboards.keyboards import (create_keyboard_with_pagination,
|
||||
get_reply_keyboard,
|
||||
get_reply_keyboard_admin,
|
||||
get_reply_keyboard_for_post,
|
||||
get_reply_keyboard_leave_chat)
|
||||
|
||||
|
||||
class TestKeyboards:
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import pytest
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
from database.repositories.message_repository import MessageRepository
|
||||
|
||||
import pytest
|
||||
from database.models import UserMessage
|
||||
from database.repositories.message_repository import MessageRepository
|
||||
|
||||
|
||||
class TestMessageRepository:
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import pytest
|
||||
import asyncio
|
||||
import tempfile
|
||||
import os
|
||||
import tempfile
|
||||
from datetime import datetime
|
||||
from database.repositories.message_repository import MessageRepository
|
||||
|
||||
import pytest
|
||||
from database.models import UserMessage
|
||||
from database.repositories.message_repository import MessageRepository
|
||||
|
||||
|
||||
class TestMessageRepositoryIntegration:
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import pytest
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
from database.models import MessageContentLink, PostContent, TelegramPost
|
||||
from database.repositories.post_repository import PostRepository
|
||||
from database.models import TelegramPost, PostContent, MessageContentLink
|
||||
|
||||
|
||||
class TestPostRepository:
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import pytest
|
||||
import asyncio
|
||||
import os
|
||||
import tempfile
|
||||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
from database.models import MessageContentLink, PostContent, TelegramPost
|
||||
from database.repositories.post_repository import PostRepository
|
||||
from database.models import TelegramPost, PostContent, MessageContentLink
|
||||
|
||||
|
||||
class TestPostRepositoryIntegration:
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
"""Tests for PostService"""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, MagicMock, patch
|
||||
from datetime import datetime
|
||||
from aiogram import types
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
from helper_bot.handlers.private.services import PostService, BotSettings
|
||||
import pytest
|
||||
from aiogram import types
|
||||
from database.models import TelegramPost, User
|
||||
from helper_bot.handlers.private.services import BotSettings, PostService
|
||||
|
||||
|
||||
class TestPostService:
|
||||
|
||||
@@ -3,19 +3,18 @@
|
||||
"""
|
||||
import asyncio
|
||||
import time
|
||||
import pytest
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
from helper_bot.utils.rate_limiter import (
|
||||
RateLimitConfig,
|
||||
ChatRateLimiter,
|
||||
GlobalRateLimiter,
|
||||
RetryHandler,
|
||||
TelegramRateLimiter,
|
||||
send_with_rate_limit
|
||||
)
|
||||
from helper_bot.utils.rate_limit_monitor import RateLimitMonitor, RateLimitStats, record_rate_limit_request
|
||||
from helper_bot.config.rate_limit_config import RateLimitSettings, get_rate_limit_config
|
||||
import pytest
|
||||
from helper_bot.config.rate_limit_config import (RateLimitSettings,
|
||||
get_rate_limit_config)
|
||||
from helper_bot.utils.rate_limit_monitor import (RateLimitMonitor,
|
||||
RateLimitStats,
|
||||
record_rate_limit_request)
|
||||
from helper_bot.utils.rate_limiter import (ChatRateLimiter, GlobalRateLimiter,
|
||||
RateLimitConfig, RetryHandler,
|
||||
TelegramRateLimiter,
|
||||
send_with_rate_limit)
|
||||
|
||||
|
||||
class TestRateLimitConfig:
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch
|
||||
from aiogram import types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
|
||||
from helper_bot.handlers.admin.services import AdminService, User, BannedUser
|
||||
from helper_bot.handlers.admin.exceptions import (
|
||||
UserNotFoundError,
|
||||
UserAlreadyBannedError,
|
||||
InvalidInputError
|
||||
)
|
||||
from helper_bot.handlers.admin.exceptions import (InvalidInputError,
|
||||
UserAlreadyBannedError,
|
||||
UserNotFoundError)
|
||||
from helper_bot.handlers.admin.services import AdminService, BannedUser, User
|
||||
|
||||
|
||||
class TestAdminService:
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
"""Tests for refactored group handlers"""
|
||||
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, MagicMock
|
||||
from aiogram import types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
|
||||
from helper_bot.handlers.group.group_handlers import (
|
||||
create_group_handlers, GroupHandlers
|
||||
)
|
||||
from helper_bot.handlers.group.constants import ERROR_MESSAGES, FSM_STATES
|
||||
from helper_bot.handlers.group.exceptions import (NoReplyToMessageError,
|
||||
UserNotFoundError)
|
||||
from helper_bot.handlers.group.group_handlers import (GroupHandlers,
|
||||
create_group_handlers)
|
||||
from helper_bot.handlers.group.services import AdminReplyService
|
||||
from helper_bot.handlers.group.exceptions import NoReplyToMessageError, UserNotFoundError
|
||||
from helper_bot.handlers.group.constants import FSM_STATES, ERROR_MESSAGES
|
||||
|
||||
|
||||
class TestGroupHandlers:
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
"""Tests for refactored private handlers"""
|
||||
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, MagicMock
|
||||
from aiogram import types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
|
||||
from helper_bot.handlers.private.constants import BUTTON_TEXTS, FSM_STATES
|
||||
from helper_bot.handlers.private.private_handlers import (
|
||||
create_private_handlers, PrivateHandlers
|
||||
)
|
||||
PrivateHandlers, create_private_handlers)
|
||||
from helper_bot.handlers.private.services import BotSettings
|
||||
from helper_bot.handlers.private.constants import FSM_STATES, BUTTON_TEXTS
|
||||
|
||||
|
||||
class TestPrivateHandlers:
|
||||
|
||||
@@ -1,39 +1,24 @@
|
||||
import pytest
|
||||
from unittest.mock import Mock, patch, AsyncMock
|
||||
from datetime import datetime
|
||||
import os
|
||||
from datetime import datetime
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
from helper_bot.utils.helper_func import (
|
||||
get_first_name,
|
||||
get_text_message,
|
||||
determine_anonymity,
|
||||
check_username_and_full_name,
|
||||
safe_html_escape,
|
||||
download_file,
|
||||
prepare_media_group_from_middlewares,
|
||||
add_in_db_media_mediagroup,
|
||||
add_in_db_media,
|
||||
send_media_group_message_to_private_chat,
|
||||
send_media_group_to_channel,
|
||||
send_text_message,
|
||||
send_photo_message,
|
||||
send_video_message,
|
||||
send_video_note_message,
|
||||
send_audio_message,
|
||||
send_voice_message,
|
||||
check_access,
|
||||
add_days_to_date,
|
||||
get_banned_users_list,
|
||||
get_banned_users_buttons,
|
||||
delete_user_blacklist,
|
||||
update_user_info,
|
||||
check_user_emoji,
|
||||
get_random_emoji
|
||||
)
|
||||
from helper_bot.utils.messages import get_message
|
||||
from helper_bot.utils.base_dependency_factory import BaseDependencyFactory, get_global_instance
|
||||
import helper_bot.utils.messages as messages # Import for patching constants
|
||||
import pytest
|
||||
from database.async_db import AsyncBotDB
|
||||
import helper_bot.utils.messages as messages # Import for patching constants
|
||||
from helper_bot.utils.base_dependency_factory import (BaseDependencyFactory,
|
||||
get_global_instance)
|
||||
from helper_bot.utils.helper_func import (
|
||||
add_days_to_date, add_in_db_media, add_in_db_media_mediagroup,
|
||||
check_access, check_user_emoji, check_username_and_full_name,
|
||||
delete_user_blacklist, determine_anonymity, download_file,
|
||||
get_banned_users_buttons, get_banned_users_list, get_first_name,
|
||||
get_random_emoji, get_text_message, prepare_media_group_from_middlewares,
|
||||
safe_html_escape, send_audio_message,
|
||||
send_media_group_message_to_private_chat, send_media_group_to_channel,
|
||||
send_photo_message, send_text_message, send_video_message,
|
||||
send_video_note_message, send_voice_message, update_user_info)
|
||||
from helper_bot.utils.messages import get_message
|
||||
|
||||
|
||||
class TestHelperFunctions:
|
||||
"""Тесты для вспомогательных функций"""
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.handlers.voice.exceptions import (AudioProcessingError,
|
||||
VoiceMessageError)
|
||||
from helper_bot.handlers.voice.services import VoiceBotService
|
||||
from helper_bot.handlers.voice.exceptions import VoiceMessageError, AudioProcessingError
|
||||
from helper_bot.handlers.voice.utils import get_last_message_text, validate_voice_message, get_user_emoji_safe
|
||||
from helper_bot.handlers.voice.utils import (get_last_message_text,
|
||||
get_user_emoji_safe,
|
||||
validate_voice_message)
|
||||
|
||||
|
||||
class TestVoiceBotService:
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
import pytest
|
||||
from helper_bot.handlers.voice.constants import (
|
||||
BUTTON_COMMAND_MAPPING,
|
||||
COMMAND_MAPPING,
|
||||
CALLBACK_COMMAND_MAPPING,
|
||||
VOICE_BOT_NAME,
|
||||
STATE_START,
|
||||
STATE_STANDUP_WRITE,
|
||||
BTN_SPEAK,
|
||||
BTN_LISTEN,
|
||||
CMD_START,
|
||||
CMD_HELP,
|
||||
CMD_RESTART,
|
||||
CMD_EMOJI,
|
||||
CMD_REFRESH,
|
||||
CALLBACK_SAVE,
|
||||
CALLBACK_DELETE
|
||||
)
|
||||
from helper_bot.handlers.voice.constants import (BTN_LISTEN, BTN_SPEAK,
|
||||
BUTTON_COMMAND_MAPPING,
|
||||
CALLBACK_COMMAND_MAPPING,
|
||||
CALLBACK_DELETE,
|
||||
CALLBACK_SAVE, CMD_EMOJI,
|
||||
CMD_HELP, CMD_REFRESH,
|
||||
CMD_RESTART, CMD_START,
|
||||
COMMAND_MAPPING,
|
||||
STATE_STANDUP_WRITE,
|
||||
STATE_START, VOICE_BOT_NAME)
|
||||
|
||||
|
||||
class TestVoiceConstants:
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import pytest
|
||||
from helper_bot.handlers.voice.exceptions import (
|
||||
VoiceMessageError,
|
||||
AudioProcessingError,
|
||||
VoiceBotError
|
||||
)
|
||||
from helper_bot.handlers.voice.exceptions import (AudioProcessingError,
|
||||
VoiceBotError,
|
||||
VoiceMessageError)
|
||||
|
||||
|
||||
class TestVoiceExceptions:
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch, MagicMock
|
||||
from aiogram import types
|
||||
from aiogram.fsm.context import FSMContext
|
||||
|
||||
from helper_bot.handlers.voice.constants import (STATE_STANDUP_WRITE,
|
||||
STATE_START)
|
||||
from helper_bot.handlers.voice.voice_handler import VoiceHandlers
|
||||
from helper_bot.handlers.voice.constants import STATE_START, STATE_STANDUP_WRITE
|
||||
|
||||
|
||||
class TestVoiceHandler:
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch, MagicMock
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.handlers.voice.exceptions import (AudioProcessingError,
|
||||
VoiceMessageError)
|
||||
from helper_bot.handlers.voice.services import VoiceBotService
|
||||
from helper_bot.handlers.voice.exceptions import VoiceMessageError, AudioProcessingError
|
||||
|
||||
|
||||
class TestVoiceBotService:
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import pytest
|
||||
from unittest.mock import Mock, patch
|
||||
from datetime import datetime, timedelta
|
||||
from aiogram import types
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from helper_bot.handlers.voice.utils import (
|
||||
get_last_message_text,
|
||||
validate_voice_message,
|
||||
get_user_emoji_safe,
|
||||
format_time_ago,
|
||||
plural_time
|
||||
)
|
||||
import pytest
|
||||
from aiogram import types
|
||||
from helper_bot.handlers.voice.utils import (format_time_ago,
|
||||
get_last_message_text,
|
||||
get_user_emoji_safe, plural_time,
|
||||
validate_voice_message)
|
||||
|
||||
|
||||
class TestVoiceUtils:
|
||||
@@ -120,7 +117,7 @@ class TestVoiceUtils:
|
||||
def test_format_time_ago_minutes(self):
|
||||
"""Тест форматирования времени в минутах"""
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
# Создаем дату 30 минут назад
|
||||
test_date = (datetime.now() - timedelta(minutes=30)).strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
@@ -133,7 +130,7 @@ class TestVoiceUtils:
|
||||
def test_format_time_ago_hours(self):
|
||||
"""Тест форматирования времени в часах"""
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
# Создаем дату 2 часа назад
|
||||
test_date = (datetime.now() - timedelta(hours=2)).strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
@@ -145,7 +142,7 @@ class TestVoiceUtils:
|
||||
def test_format_time_ago_days(self):
|
||||
"""Тест форматирования времени в днях"""
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
# Создаем дату 3 дня назад
|
||||
test_date = (datetime.now() - timedelta(days=3)).strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user