From 3d6b4353f9c9abe88c10f40bfe6c30564b01c615 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sat, 28 Feb 2026 23:24:25 +0300 Subject: [PATCH] Refactor imports across multiple files to improve code organization and readability. --- database/async_db.py | 1 + database/base.py | 1 + database/repositories/migration_repository.py | 1 + helper_bot/handlers/admin/admin_handlers.py | 19 ++++----- helper_bot/handlers/admin/dependencies.py | 1 + .../handlers/admin/rate_limit_handlers.py | 1 + helper_bot/handlers/admin/utils.py | 1 + .../handlers/callback/callback_handlers.py | 1 + .../handlers/callback/dependency_factory.py | 1 + helper_bot/handlers/callback/services.py | 1 + helper_bot/handlers/private/services.py | 29 +++++++++----- helper_bot/handlers/voice/services.py | 1 + helper_bot/handlers/voice/voice_handler.py | 1 + helper_bot/main.py | 1 + .../middlewares/blacklist_middleware.py | 1 + .../middlewares/dependencies_middleware.py | 1 + .../middlewares/rate_limit_middleware.py | 1 + .../services/scoring/deepseek_service.py | 1 + helper_bot/services/scoring/rag_client.py | 6 ++- .../services/scoring/scoring_manager.py | 5 ++- helper_bot/utils/auto_unban_scheduler.py | 1 + helper_bot/utils/base_dependency_factory.py | 3 +- helper_bot/utils/helper_func.py | 5 ++- helper_bot/utils/rate_limiter.py | 1 + helper_bot/utils/s3_storage.py | 1 + scripts/create_bot_settings_table.py | 6 +-- tests/conftest.py | 2 +- tests/conftest_message_repository.py | 1 + tests/conftest_post_repository.py | 1 + tests/test_admin_dependencies.py | 1 + tests/test_admin_handlers.py | 1 + tests/test_admin_repository.py | 1 + tests/test_admin_utils.py | 1 + tests/test_album_middleware.py | 1 + tests/test_async_db.py | 1 + tests/test_audio_file_service.py | 1 + tests/test_audio_repository.py | 1 + tests/test_audio_repository_schema.py | 1 + tests/test_auto_moderation_service.py | 9 ++--- tests/test_auto_unban_integration.py | 1 + tests/test_auto_unban_scheduler.py | 1 + tests/test_blacklist_history_repository.py | 1 + tests/test_blacklist_middleware.py | 1 + tests/test_blacklist_repository.py | 1 + tests/test_bot_settings_repository.py | 40 ++++++++++++------- tests/test_callback_dependency_factory.py | 1 + tests/test_callback_handlers.py | 1 + tests/test_callback_services.py | 1 + tests/test_decorators.py | 1 + tests/test_deepseek_service.py | 1 + tests/test_dependencies_middleware.py | 1 + tests/test_improved_media_processing.py | 1 + tests/test_keyboards_and_filters.py | 1 + tests/test_main.py | 1 + tests/test_message_repository.py | 1 + tests/test_message_repository_integration.py | 1 + tests/test_metrics_middleware.py | 1 + tests/test_post_repository.py | 1 + tests/test_post_repository_integration.py | 1 + tests/test_post_service.py | 1 + tests/test_rag_client.py | 1 + tests/test_rate_limit_middleware.py | 1 + tests/test_rate_limit_monitor.py | 1 + tests/test_rate_limiter.py | 1 + tests/test_refactored_admin_handlers.py | 1 + tests/test_refactored_group_handlers.py | 1 + tests/test_refactored_private_handlers.py | 1 + tests/test_s3_storage.py | 1 + tests/test_scoring_services.py | 1 + tests/test_server_prometheus.py | 1 + tests/test_text_middleware.py | 1 + tests/test_utils.py | 3 +- tests/test_voice_bot_architecture.py | 1 + tests/test_voice_constants.py | 1 + tests/test_voice_exceptions.py | 1 + tests/test_voice_handler.py | 1 + tests/test_voice_services.py | 1 + tests/test_voice_utils.py | 1 + 78 files changed, 141 insertions(+), 53 deletions(-) diff --git a/database/async_db.py b/database/async_db.py index a142a66..f36a324 100644 --- a/database/async_db.py +++ b/database/async_db.py @@ -2,6 +2,7 @@ from datetime import datetime from typing import Any, Dict, List, Optional, Tuple import aiosqlite + from database.models import ( Admin, AudioMessage, diff --git a/database/base.py b/database/base.py index 4fb6fb0..ca32425 100644 --- a/database/base.py +++ b/database/base.py @@ -2,6 +2,7 @@ import os from typing import Optional import aiosqlite + from logs.custom_logger import logger diff --git a/database/repositories/migration_repository.py b/database/repositories/migration_repository.py index 628ecee..8c7a02b 100644 --- a/database/repositories/migration_repository.py +++ b/database/repositories/migration_repository.py @@ -1,6 +1,7 @@ """Репозиторий для работы с миграциями базы данных.""" import aiosqlite + from database.base import DatabaseConnection diff --git a/helper_bot/handlers/admin/admin_handlers.py b/helper_bot/handlers/admin/admin_handlers.py index 468f234..862d088 100644 --- a/helper_bot/handlers/admin/admin_handlers.py +++ b/helper_bot/handlers/admin/admin_handlers.py @@ -1,6 +1,7 @@ from aiogram import F, Router, types from aiogram.filters import Command, MagicData, StateFilter from aiogram.fsm.context import FSMContext + from helper_bot.filters.main import ChatTypeFilter from helper_bot.handlers.admin.dependencies import AdminAccessMiddleware from helper_bot.handlers.admin.exceptions import ( @@ -138,7 +139,9 @@ async def get_banned_users( keyboard = create_keyboard_with_pagination( 1, len(buttons_list), buttons_list, "unlock" ) - await message.answer(text=message_text, reply_markup=keyboard, parse_mode="HTML") + await message.answer( + text=message_text, reply_markup=keyboard, parse_mode="HTML" + ) else: await message.answer( text="В списке заблокированных пользователей никого нет" @@ -217,12 +220,8 @@ async def get_ml_stats(message: types.Message, state: FSMContext, **kwargs): lines.append(f" • API URL: {rag.get('api_url', 'N/A')}") if "enabled" in rag: if rag.get("enabled"): - lines.append( - f" • Статус: ⚠️ Включен, но API не отвечает" - ) - lines.append( - f" • Проверьте доступность сервиса и API ключ" - ) + lines.append(f" • Статус: ⚠️ Включен, но API не отвечает") + lines.append(f" • Проверьте доступность сервиса и API ключ") else: lines.append(f" • Статус: ❌ Отключен") @@ -460,8 +459,7 @@ async def process_publish_threshold( except ValueError as e: await message.answer( - f"❌ Неверное значение: {e}\n" - "Введите число от 0.0 до 1.0 (например: 0.8)" + f"❌ Неверное значение: {e}\n" "Введите число от 0.0 до 1.0 (например: 0.8)" ) except Exception as e: logger.error(f"Ошибка изменения порога публикации: {e}") @@ -503,8 +501,7 @@ async def process_decline_threshold( except ValueError as e: await message.answer( - f"❌ Неверное значение: {e}\n" - "Введите число от 0.0 до 1.0 (например: 0.4)" + f"❌ Неверное значение: {e}\n" "Введите число от 0.0 до 1.0 (например: 0.4)" ) except Exception as e: logger.error(f"Ошибка изменения порога отклонения: {e}") diff --git a/helper_bot/handlers/admin/dependencies.py b/helper_bot/handlers/admin/dependencies.py index 9774837..89a486f 100644 --- a/helper_bot/handlers/admin/dependencies.py +++ b/helper_bot/handlers/admin/dependencies.py @@ -7,6 +7,7 @@ except ImportError: from aiogram import BaseMiddleware from aiogram.types import TelegramObject + from helper_bot.utils.base_dependency_factory import get_global_instance from helper_bot.utils.helper_func import check_access from logs.custom_logger import logger diff --git a/helper_bot/handlers/admin/rate_limit_handlers.py b/helper_bot/handlers/admin/rate_limit_handlers.py index 143e9fb..2837121 100644 --- a/helper_bot/handlers/admin/rate_limit_handlers.py +++ b/helper_bot/handlers/admin/rate_limit_handlers.py @@ -6,6 +6,7 @@ from aiogram import F, Router, types from aiogram.filters import Command, MagicData from aiogram.fsm.context import FSMContext from aiogram.types import FSInputFile + from helper_bot.filters.main import ChatTypeFilter from helper_bot.middlewares.dependencies_middleware import DependenciesMiddleware diff --git a/helper_bot/handlers/admin/utils.py b/helper_bot/handlers/admin/utils.py index b9cf51c..74fea5c 100644 --- a/helper_bot/handlers/admin/utils.py +++ b/helper_bot/handlers/admin/utils.py @@ -3,6 +3,7 @@ from typing import Optional from aiogram import types from aiogram.fsm.context import FSMContext + from helper_bot.handlers.admin.exceptions import AdminError from helper_bot.keyboards.keyboards import get_reply_keyboard_admin from logs.custom_logger import logger diff --git a/helper_bot/handlers/callback/callback_handlers.py b/helper_bot/handlers/callback/callback_handlers.py index 1c34304..f652ceb 100644 --- a/helper_bot/handlers/callback/callback_handlers.py +++ b/helper_bot/handlers/callback/callback_handlers.py @@ -7,6 +7,7 @@ from aiogram import F, Router from aiogram.filters import MagicData from aiogram.fsm.context import FSMContext from aiogram.types import CallbackQuery + from helper_bot.handlers.admin.utils import format_user_info from helper_bot.handlers.voice.constants import CALLBACK_DELETE, CALLBACK_SAVE from helper_bot.handlers.voice.services import AudioFileService diff --git a/helper_bot/handlers/callback/dependency_factory.py b/helper_bot/handlers/callback/dependency_factory.py index 3a4ca99..a8b376f 100644 --- a/helper_bot/handlers/callback/dependency_factory.py +++ b/helper_bot/handlers/callback/dependency_factory.py @@ -3,6 +3,7 @@ from typing import Callable from aiogram import Bot from aiogram.client.default import DefaultBotProperties from aiogram.fsm.context import FSMContext + from helper_bot.utils.base_dependency_factory import get_global_instance from .services import BanService, PostPublishService diff --git a/helper_bot/handlers/callback/services.py b/helper_bot/handlers/callback/services.py index 40dba23..910d852 100644 --- a/helper_bot/handlers/callback/services.py +++ b/helper_bot/handlers/callback/services.py @@ -4,6 +4,7 @@ from typing import Any, Dict from aiogram import Bot, types from aiogram.types import CallbackQuery + from helper_bot.keyboards.keyboards import create_keyboard_for_ban_reason from helper_bot.utils.helper_func import ( delete_user_blacklist, diff --git a/helper_bot/handlers/private/services.py b/helper_bot/handlers/private/services.py index d7436b3..13004ac 100644 --- a/helper_bot/handlers/private/services.py +++ b/helper_bot/handlers/private/services.py @@ -12,6 +12,7 @@ from typing import Any, Callable, Dict, Protocol, Union # Third-party imports from aiogram import types from aiogram.types import FSInputFile + from database.models import TelegramPost, User from helper_bot.keyboards import get_reply_keyboard_for_post @@ -171,7 +172,9 @@ class UserService: Returns: Отформатированное сообщение для админов """ - safe_full_name = html.escape(full_name) if full_name else "Неизвестный пользователь" + safe_full_name = ( + html.escape(full_name) if full_name else "Неизвестный пользователь" + ) safe_username = html.escape(username) if username else None safe_message_text = html.escape(message_text) if message_text else "" @@ -198,7 +201,9 @@ class UserService: # Получаем дату регистрации user_info = await self.db.get_user_by_id(user_id) if user_info and user_info.date_added: - date_added = datetime.fromtimestamp(user_info.date_added).strftime("%d.%m.%Y") + date_added = datetime.fromtimestamp(user_info.date_added).strftime( + "%d.%m.%Y" + ) else: date_added = "Неизвестно" @@ -332,9 +337,7 @@ class PostService: if self.scoring_manager: await self.scoring_manager.add_submitted_post(text, post_id, rag_score) except Exception as e: - logger.warning( - f"PostService: Ошибка добавления поста в submitted: {e}" - ) + logger.warning(f"PostService: Ошибка добавления поста в submitted: {e}") async def _get_scores_with_error_handling(self, text: str) -> tuple: """ @@ -526,7 +529,9 @@ class PostService: # Сохраняем скоры если есть if ml_scores_json: asyncio.create_task( - self._save_scores_background(sent_message.message_id, ml_scores_json) + self._save_scores_background( + sent_message.message_id, ml_scores_json + ) ) # Индексируем пост в RAG @@ -544,7 +549,9 @@ class PostService: text="Твой пост был выложен🥰", ) except Exception as e: - logger.warning(f"PostService: Не удалось уведомить автора {author_id}: {e}") + logger.warning( + f"PostService: Не удалось уведомить автора {author_id}: {e}" + ) logger.info( f"PostService: Пост авто-опубликован в {self.settings.main_public}, " @@ -562,7 +569,9 @@ class PostService: try: await self.scoring_manager.on_post_declined(original_text) except Exception as e: - logger.warning(f"PostService: Ошибка обучения RAG на отклоненном посте: {e}") + logger.warning( + f"PostService: Ошибка обучения RAG на отклоненном посте: {e}" + ) # Уведомляем автора try: @@ -1471,8 +1480,6 @@ class AutoModerationService: text=message_text, parse_mode="HTML", ) - logger.info( - f"AutoModeration: Лог отправлен в IMPORTANT_LOGS ({action})" - ) + logger.info(f"AutoModeration: Лог отправлен в IMPORTANT_LOGS ({action})") except Exception as e: logger.error(f"AutoModeration: Ошибка отправки лога: {e}") diff --git a/helper_bot/handlers/voice/services.py b/helper_bot/handlers/voice/services.py index cc68ff8..36808ee 100644 --- a/helper_bot/handlers/voice/services.py +++ b/helper_bot/handlers/voice/services.py @@ -7,6 +7,7 @@ from pathlib import Path from typing import List, Optional, Tuple from aiogram.types import FSInputFile + from helper_bot.handlers.voice.constants import ( MESSAGE_DELAY_1, MESSAGE_DELAY_2, diff --git a/helper_bot/handlers/voice/voice_handler.py b/helper_bot/handlers/voice/voice_handler.py index f3124b6..3ea223e 100644 --- a/helper_bot/handlers/voice/voice_handler.py +++ b/helper_bot/handlers/voice/voice_handler.py @@ -6,6 +6,7 @@ from aiogram import F, Router, types from aiogram.filters import Command, MagicData, StateFilter from aiogram.fsm.context import FSMContext from aiogram.types import FSInputFile + from helper_bot.filters.main import ChatTypeFilter from helper_bot.handlers.private.constants import BUTTON_TEXTS, FSM_STATES from helper_bot.handlers.voice.constants import * diff --git a/helper_bot/main.py b/helper_bot/main.py index 942888b..f055db6 100644 --- a/helper_bot/main.py +++ b/helper_bot/main.py @@ -6,6 +6,7 @@ from aiogram import Bot, Dispatcher from aiogram.client.default import DefaultBotProperties from aiogram.fsm.storage.memory import MemoryStorage from aiogram.fsm.strategy import FSMStrategy + from helper_bot.handlers.admin import admin_router from helper_bot.handlers.callback import callback_router from helper_bot.handlers.group import group_router diff --git a/helper_bot/middlewares/blacklist_middleware.py b/helper_bot/middlewares/blacklist_middleware.py index 05bdd17..32279e2 100644 --- a/helper_bot/middlewares/blacklist_middleware.py +++ b/helper_bot/middlewares/blacklist_middleware.py @@ -4,6 +4,7 @@ from typing import Any, Dict from aiogram import BaseMiddleware, types from aiogram.types import CallbackQuery, Message, TelegramObject + from helper_bot.utils.base_dependency_factory import get_global_instance from logs.custom_logger import logger diff --git a/helper_bot/middlewares/dependencies_middleware.py b/helper_bot/middlewares/dependencies_middleware.py index ce266c0..d18c28c 100644 --- a/helper_bot/middlewares/dependencies_middleware.py +++ b/helper_bot/middlewares/dependencies_middleware.py @@ -2,6 +2,7 @@ from typing import Any, Dict from aiogram import BaseMiddleware from aiogram.types import TelegramObject + from helper_bot.utils.base_dependency_factory import get_global_instance from logs.custom_logger import logger diff --git a/helper_bot/middlewares/rate_limit_middleware.py b/helper_bot/middlewares/rate_limit_middleware.py index 83d9ef0..c50ef88 100644 --- a/helper_bot/middlewares/rate_limit_middleware.py +++ b/helper_bot/middlewares/rate_limit_middleware.py @@ -7,6 +7,7 @@ from typing import Any, Awaitable, Callable, Dict, Union from aiogram import BaseMiddleware from aiogram.exceptions import TelegramAPIError, TelegramRetryAfter from aiogram.types import CallbackQuery, ChatMemberUpdated, InlineQuery, Message, Update + from helper_bot.utils.rate_limiter import telegram_rate_limiter from logs.custom_logger import logger diff --git a/helper_bot/services/scoring/deepseek_service.py b/helper_bot/services/scoring/deepseek_service.py index a365323..4f9cc23 100644 --- a/helper_bot/services/scoring/deepseek_service.py +++ b/helper_bot/services/scoring/deepseek_service.py @@ -9,6 +9,7 @@ import json from typing import List, Optional import httpx + from helper_bot.utils.metrics import track_errors, track_time from logs.custom_logger import logger diff --git a/helper_bot/services/scoring/rag_client.py b/helper_bot/services/scoring/rag_client.py index 5aa937f..da31e1e 100644 --- a/helper_bot/services/scoring/rag_client.py +++ b/helper_bot/services/scoring/rag_client.py @@ -8,6 +8,7 @@ from dataclasses import dataclass from typing import Any, Dict, List, Optional import httpx + from helper_bot.utils.metrics import track_errors, track_time from logs.custom_logger import logger @@ -483,7 +484,10 @@ class RagApiClient: @track_time("add_submitted_post", "rag_client") async def add_submitted_post( - self, text: str, post_id: Optional[int] = None, rag_score: Optional[float] = None + self, + text: str, + post_id: Optional[int] = None, + rag_score: Optional[float] = None, ) -> bool: """ Добавляет пост в коллекцию submitted для поиска похожих. diff --git a/helper_bot/services/scoring/scoring_manager.py b/helper_bot/services/scoring/scoring_manager.py index 8a332c8..f95812b 100644 --- a/helper_bot/services/scoring/scoring_manager.py +++ b/helper_bot/services/scoring/scoring_manager.py @@ -244,7 +244,10 @@ class ScoringManager: @track_time("add_submitted_post", "scoring_manager") async def add_submitted_post( - self, text: str, post_id: Optional[int] = None, rag_score: Optional[float] = None + self, + text: str, + post_id: Optional[int] = None, + rag_score: Optional[float] = None, ) -> bool: """ Добавляет пост в коллекцию submitted для поиска похожих. diff --git a/helper_bot/utils/auto_unban_scheduler.py b/helper_bot/utils/auto_unban_scheduler.py index d46a688..91550b5 100644 --- a/helper_bot/utils/auto_unban_scheduler.py +++ b/helper_bot/utils/auto_unban_scheduler.py @@ -4,6 +4,7 @@ from typing import Optional from apscheduler.schedulers.asyncio import AsyncIOScheduler from apscheduler.triggers.cron import CronTrigger + from helper_bot.utils.base_dependency_factory import get_global_instance from logs.custom_logger import logger diff --git a/helper_bot/utils/base_dependency_factory.py b/helper_bot/utils/base_dependency_factory.py index 58143a5..e3e1971 100644 --- a/helper_bot/utils/base_dependency_factory.py +++ b/helper_bot/utils/base_dependency_factory.py @@ -2,8 +2,9 @@ import os import sys from typing import Optional -from database.async_db import AsyncBotDB from dotenv import load_dotenv + +from database.async_db import AsyncBotDB from helper_bot.utils.s3_storage import S3StorageService from logs.custom_logger import logger diff --git a/helper_bot/utils/helper_func.py b/helper_bot/utils/helper_func.py index 6d94c14..133bd5f 100644 --- a/helper_bot/utils/helper_func.py +++ b/helper_bot/utils/helper_func.py @@ -24,6 +24,7 @@ from aiogram.types import ( InputMediaPhoto, InputMediaVideo, ) + from database.models import TelegramPost from helper_bot.utils.base_dependency_factory import ( BaseDependencyFactory, @@ -1065,7 +1066,9 @@ async def get_banned_users_list(offset: int, bot_db): user_ids - лист кортежей [(user_name: user_id)] """ items_per_page = 9 - users = await bot_db.get_banned_users_from_db_with_limits(limit=items_per_page, offset=offset) + users = await bot_db.get_banned_users_from_db_with_limits( + limit=items_per_page, offset=offset + ) message = "Список заблокированных пользователей:\n" for user in users: diff --git a/helper_bot/utils/rate_limiter.py b/helper_bot/utils/rate_limiter.py index 07dff74..78d891f 100644 --- a/helper_bot/utils/rate_limiter.py +++ b/helper_bot/utils/rate_limiter.py @@ -8,6 +8,7 @@ from dataclasses import dataclass from typing import Any, Callable, Dict, Optional from aiogram.exceptions import TelegramAPIError, TelegramRetryAfter + from logs.custom_logger import logger from .metrics import metrics diff --git a/helper_bot/utils/s3_storage.py b/helper_bot/utils/s3_storage.py index 5b5dfc6..dbbf2d6 100644 --- a/helper_bot/utils/s3_storage.py +++ b/helper_bot/utils/s3_storage.py @@ -8,6 +8,7 @@ from pathlib import Path from typing import Optional import aioboto3 + from logs.custom_logger import logger diff --git a/scripts/create_bot_settings_table.py b/scripts/create_bot_settings_table.py index a13c033..4a6c262 100644 --- a/scripts/create_bot_settings_table.py +++ b/scripts/create_bot_settings_table.py @@ -67,16 +67,14 @@ async def main(db_path: str) -> None: await conn.execute("PRAGMA foreign_keys = ON") if not await table_exists(conn, "bot_settings"): - await conn.execute( - """ + await conn.execute(""" CREATE TABLE bot_settings ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, key TEXT NOT NULL UNIQUE, value TEXT NOT NULL, updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')) ) - """ - ) + """) logger.info("Таблица bot_settings создана") for key, value in DEFAULT_SETTINGS: diff --git a/tests/conftest.py b/tests/conftest.py index 041e950..96cb8d7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -13,10 +13,10 @@ if str(_project_root) not in sys.path: import pytest from aiogram.fsm.context import FSMContext from aiogram.types import Chat, Message, User -from database.async_db import AsyncBotDB # Импортируем моки в самом начале import tests.mocks +from database.async_db import AsyncBotDB # Настройка pytest-asyncio pytest_plugins = ("pytest_asyncio",) diff --git a/tests/conftest_message_repository.py b/tests/conftest_message_repository.py index 0793b59..90f7b8b 100644 --- a/tests/conftest_message_repository.py +++ b/tests/conftest_message_repository.py @@ -3,6 +3,7 @@ import tempfile from datetime import datetime import pytest + from database.models import UserMessage from database.repositories.message_repository import MessageRepository diff --git a/tests/conftest_post_repository.py b/tests/conftest_post_repository.py index 56c26b5..8c660ce 100644 --- a/tests/conftest_post_repository.py +++ b/tests/conftest_post_repository.py @@ -5,6 +5,7 @@ from datetime import datetime from unittest.mock import AsyncMock, Mock import pytest + from database.models import MessageContentLink, PostContent, TelegramPost from database.repositories.post_repository import PostRepository diff --git a/tests/test_admin_dependencies.py b/tests/test_admin_dependencies.py index 9c9da2a..fda702c 100644 --- a/tests/test_admin_dependencies.py +++ b/tests/test_admin_dependencies.py @@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest + from helper_bot.handlers.admin.dependencies import ( AdminAccessMiddleware, get_bot_db, diff --git a/tests/test_admin_handlers.py b/tests/test_admin_handlers.py index 430c22f..2f807c4 100644 --- a/tests/test_admin_handlers.py +++ b/tests/test_admin_handlers.py @@ -7,6 +7,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest from aiogram import types from aiogram.fsm.context import FSMContext + from helper_bot.handlers.admin.admin_handlers import ( admin_panel, cancel_ban_process, diff --git a/tests/test_admin_repository.py b/tests/test_admin_repository.py index 5e9f5c9..1eee060 100644 --- a/tests/test_admin_repository.py +++ b/tests/test_admin_repository.py @@ -3,6 +3,7 @@ from datetime import datetime from unittest.mock import AsyncMock, MagicMock, Mock, patch import pytest + from database.models import Admin from database.repositories.admin_repository import AdminRepository diff --git a/tests/test_admin_utils.py b/tests/test_admin_utils.py index 52f8940..57e661d 100644 --- a/tests/test_admin_utils.py +++ b/tests/test_admin_utils.py @@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest + from helper_bot.handlers.admin.exceptions import AdminError from helper_bot.handlers.admin.utils import ( escape_html, diff --git a/tests/test_album_middleware.py b/tests/test_album_middleware.py index 2502da8..adf7eae 100644 --- a/tests/test_album_middleware.py +++ b/tests/test_album_middleware.py @@ -6,6 +6,7 @@ import asyncio from unittest.mock import AsyncMock, MagicMock, patch import pytest + from helper_bot.middlewares.album_middleware import AlbumGetter, AlbumMiddleware diff --git a/tests/test_async_db.py b/tests/test_async_db.py index fdb2cab..02b9b3f 100644 --- a/tests/test_async_db.py +++ b/tests/test_async_db.py @@ -1,6 +1,7 @@ from unittest.mock import AsyncMock, Mock, patch import pytest + from database.async_db import AsyncBotDB diff --git a/tests/test_audio_file_service.py b/tests/test_audio_file_service.py index ca68bb7..7d298ed 100644 --- a/tests/test_audio_file_service.py +++ b/tests/test_audio_file_service.py @@ -3,6 +3,7 @@ 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 diff --git a/tests/test_audio_repository.py b/tests/test_audio_repository.py index 0ee248f..5ed86fe 100644 --- a/tests/test_audio_repository.py +++ b/tests/test_audio_repository.py @@ -3,6 +3,7 @@ from datetime import datetime, timezone from unittest.mock import AsyncMock, MagicMock, Mock, patch import pytest + from database.models import AudioListenRecord, AudioMessage, AudioModerate from database.repositories.audio_repository import AudioRepository diff --git a/tests/test_audio_repository_schema.py b/tests/test_audio_repository_schema.py index d084df3..ed57604 100644 --- a/tests/test_audio_repository_schema.py +++ b/tests/test_audio_repository_schema.py @@ -3,6 +3,7 @@ from datetime import datetime, timezone from unittest.mock import AsyncMock, MagicMock, Mock, patch import pytest + from database.repositories.audio_repository import AudioRepository diff --git a/tests/test_auto_moderation_service.py b/tests/test_auto_moderation_service.py index bb78822..c2dd6ea 100644 --- a/tests/test_auto_moderation_service.py +++ b/tests/test_auto_moderation_service.py @@ -3,6 +3,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest + from helper_bot.handlers.private.services import AutoModerationService, BotSettings @@ -108,9 +109,7 @@ class TestAutoModerationService: assert result == "manual" @pytest.mark.asyncio - async def test_check_auto_action_publish_at_exact_threshold( - self, service, mock_db - ): + async def test_check_auto_action_publish_at_exact_threshold(self, service, mock_db): """Тест: возвращает publish когда score равен порогу.""" mock_db.get_auto_moderation_settings.return_value = { "auto_publish_enabled": True, @@ -124,9 +123,7 @@ class TestAutoModerationService: assert result == "publish" @pytest.mark.asyncio - async def test_check_auto_action_decline_at_exact_threshold( - self, service, mock_db - ): + async def test_check_auto_action_decline_at_exact_threshold(self, service, mock_db): """Тест: возвращает decline когда score равен порогу.""" mock_db.get_auto_moderation_settings.return_value = { "auto_publish_enabled": False, diff --git a/tests/test_auto_unban_integration.py b/tests/test_auto_unban_integration.py index 1b7bd99..1bb82b6 100644 --- a/tests/test_auto_unban_integration.py +++ b/tests/test_auto_unban_integration.py @@ -4,6 +4,7 @@ from datetime import datetime, timedelta, timezone from unittest.mock import AsyncMock, Mock, patch import pytest + from helper_bot.utils.auto_unban_scheduler import AutoUnbanScheduler diff --git a/tests/test_auto_unban_scheduler.py b/tests/test_auto_unban_scheduler.py index bcf1c9b..7f64bef 100644 --- a/tests/test_auto_unban_scheduler.py +++ b/tests/test_auto_unban_scheduler.py @@ -3,6 +3,7 @@ from datetime import datetime, timedelta, timezone from unittest.mock import AsyncMock, Mock, patch import pytest + from helper_bot.utils.auto_unban_scheduler import ( AutoUnbanScheduler, get_auto_unban_scheduler, diff --git a/tests/test_blacklist_history_repository.py b/tests/test_blacklist_history_repository.py index 5d7a7ef..828a222 100644 --- a/tests/test_blacklist_history_repository.py +++ b/tests/test_blacklist_history_repository.py @@ -3,6 +3,7 @@ from datetime import datetime from unittest.mock import AsyncMock, Mock, patch import pytest + from database.models import BlacklistHistoryRecord from database.repositories.blacklist_history_repository import ( BlacklistHistoryRepository, diff --git a/tests/test_blacklist_middleware.py b/tests/test_blacklist_middleware.py index 5bda9b6..e3b6a29 100644 --- a/tests/test_blacklist_middleware.py +++ b/tests/test_blacklist_middleware.py @@ -6,6 +6,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest from aiogram.types import CallbackQuery, Message + from helper_bot.middlewares.blacklist_middleware import BlacklistMiddleware diff --git a/tests/test_blacklist_repository.py b/tests/test_blacklist_repository.py index 0443820..5b323a7 100644 --- a/tests/test_blacklist_repository.py +++ b/tests/test_blacklist_repository.py @@ -3,6 +3,7 @@ from datetime import datetime from unittest.mock import AsyncMock, MagicMock, Mock, patch import pytest + from database.models import BlacklistUser from database.repositories.blacklist_repository import BlacklistRepository diff --git a/tests/test_bot_settings_repository.py b/tests/test_bot_settings_repository.py index 8b02a2e..47b44dd 100644 --- a/tests/test_bot_settings_repository.py +++ b/tests/test_bot_settings_repository.py @@ -3,6 +3,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest + from database.repositories.bot_settings_repository import BotSettingsRepository @@ -115,11 +116,14 @@ class TestBotSettingsRepository: @pytest.mark.asyncio async def test_get_auto_moderation_settings(self, repository): """Тест получения всех настроек авто-модерации.""" - with patch.object( - repository, "get_bool_setting", new_callable=AsyncMock - ) as mock_bool, patch.object( - repository, "get_float_setting", new_callable=AsyncMock - ) as mock_float: + with ( + patch.object( + repository, "get_bool_setting", new_callable=AsyncMock + ) as mock_bool, + patch.object( + repository, "get_float_setting", new_callable=AsyncMock + ) as mock_float, + ): mock_bool.side_effect = [True, False] mock_float.side_effect = [0.8, 0.4] @@ -133,11 +137,14 @@ class TestBotSettingsRepository: @pytest.mark.asyncio async def test_toggle_auto_publish(self, repository): """Тест переключения авто-публикации.""" - with patch.object( - repository, "get_bool_setting", new_callable=AsyncMock - ) as mock_get, patch.object( - repository, "set_bool_setting", new_callable=AsyncMock - ) as mock_set: + with ( + patch.object( + repository, "get_bool_setting", new_callable=AsyncMock + ) as mock_get, + patch.object( + repository, "set_bool_setting", new_callable=AsyncMock + ) as mock_set, + ): mock_get.return_value = False result = await repository.toggle_auto_publish() @@ -148,11 +155,14 @@ class TestBotSettingsRepository: @pytest.mark.asyncio async def test_toggle_auto_decline(self, repository): """Тест переключения авто-отклонения.""" - with patch.object( - repository, "get_bool_setting", new_callable=AsyncMock - ) as mock_get, patch.object( - repository, "set_bool_setting", new_callable=AsyncMock - ) as mock_set: + with ( + patch.object( + repository, "get_bool_setting", new_callable=AsyncMock + ) as mock_get, + patch.object( + repository, "set_bool_setting", new_callable=AsyncMock + ) as mock_set, + ): mock_get.return_value = True result = await repository.toggle_auto_decline() diff --git a/tests/test_callback_dependency_factory.py b/tests/test_callback_dependency_factory.py index 3bdb285..8a36079 100644 --- a/tests/test_callback_dependency_factory.py +++ b/tests/test_callback_dependency_factory.py @@ -5,6 +5,7 @@ from unittest.mock import MagicMock, patch import pytest + from helper_bot.handlers.callback.dependency_factory import ( get_ban_service, get_post_publish_service, diff --git a/tests/test_callback_handlers.py b/tests/test_callback_handlers.py index 0fd1caf..7f85b78 100644 --- a/tests/test_callback_handlers.py +++ b/tests/test_callback_handlers.py @@ -3,6 +3,7 @@ from datetime import datetime from unittest.mock import AsyncMock, MagicMock, Mock, patch import pytest + from helper_bot.handlers.callback.callback_handlers import ( change_page, delete_voice_message, diff --git a/tests/test_callback_services.py b/tests/test_callback_services.py index 3ec7b20..216f6b9 100644 --- a/tests/test_callback_services.py +++ b/tests/test_callback_services.py @@ -6,6 +6,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest from aiogram.types import CallbackQuery, Message + from helper_bot.handlers.callback.constants import CONTENT_TYPE_MEDIA_GROUP from helper_bot.handlers.callback.exceptions import ( PostNotFoundError, diff --git a/tests/test_decorators.py b/tests/test_decorators.py index ca8bbd5..479f8c8 100644 --- a/tests/test_decorators.py +++ b/tests/test_decorators.py @@ -6,6 +6,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest from aiogram import types + from helper_bot.handlers.group.decorators import error_handler as group_error_handler from helper_bot.handlers.private.decorators import ( error_handler as private_error_handler, diff --git a/tests/test_deepseek_service.py b/tests/test_deepseek_service.py index 91e9fb4..6575cbd 100644 --- a/tests/test_deepseek_service.py +++ b/tests/test_deepseek_service.py @@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest + from helper_bot.services.scoring.deepseek_service import DeepSeekService from helper_bot.services.scoring.exceptions import ( DeepSeekAPIError, diff --git a/tests/test_dependencies_middleware.py b/tests/test_dependencies_middleware.py index fdd4c12..c345b94 100644 --- a/tests/test_dependencies_middleware.py +++ b/tests/test_dependencies_middleware.py @@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest + from helper_bot.middlewares.dependencies_middleware import DependenciesMiddleware diff --git a/tests/test_improved_media_processing.py b/tests/test_improved_media_processing.py index d2baf83..05d78e7 100644 --- a/tests/test_improved_media_processing.py +++ b/tests/test_improved_media_processing.py @@ -8,6 +8,7 @@ from unittest.mock import AsyncMock, MagicMock, Mock, patch import pytest from aiogram import types + from helper_bot.utils.helper_func import ( add_in_db_media, add_in_db_media_mediagroup, diff --git a/tests/test_keyboards_and_filters.py b/tests/test_keyboards_and_filters.py index c83aa37..74a5cb9 100644 --- a/tests/test_keyboards_and_filters.py +++ b/tests/test_keyboards_and_filters.py @@ -7,6 +7,7 @@ from aiogram.types import ( KeyboardButton, ReplyKeyboardMarkup, ) + from database.async_db import AsyncBotDB from helper_bot.filters.main import ChatTypeFilter from helper_bot.keyboards.keyboards import ( diff --git a/tests/test_main.py b/tests/test_main.py index 0a492c2..0991cbc 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -6,6 +6,7 @@ import asyncio from unittest.mock import AsyncMock, MagicMock, patch import pytest + from helper_bot.main import start_bot, start_bot_with_retry diff --git a/tests/test_message_repository.py b/tests/test_message_repository.py index 2fdbceb..b8f2557 100644 --- a/tests/test_message_repository.py +++ b/tests/test_message_repository.py @@ -3,6 +3,7 @@ from datetime import datetime from unittest.mock import AsyncMock, MagicMock import pytest + from database.models import UserMessage from database.repositories.message_repository import MessageRepository diff --git a/tests/test_message_repository_integration.py b/tests/test_message_repository_integration.py index 8e129ab..84c3b3a 100644 --- a/tests/test_message_repository_integration.py +++ b/tests/test_message_repository_integration.py @@ -4,6 +4,7 @@ import tempfile from datetime import datetime import pytest + from database.models import UserMessage from database.repositories.message_repository import MessageRepository diff --git a/tests/test_metrics_middleware.py b/tests/test_metrics_middleware.py index 999152a..80e1a4b 100644 --- a/tests/test_metrics_middleware.py +++ b/tests/test_metrics_middleware.py @@ -7,6 +7,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest from aiogram.types import Message + from helper_bot.middlewares.metrics_middleware import ( DatabaseMetricsMiddleware, ErrorMetricsMiddleware, diff --git a/tests/test_post_repository.py b/tests/test_post_repository.py index dd982bd..797be28 100644 --- a/tests/test_post_repository.py +++ b/tests/test_post_repository.py @@ -3,6 +3,7 @@ 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 diff --git a/tests/test_post_repository_integration.py b/tests/test_post_repository_integration.py index 43bb399..d485fec 100644 --- a/tests/test_post_repository_integration.py +++ b/tests/test_post_repository_integration.py @@ -4,6 +4,7 @@ import tempfile from datetime import datetime import pytest + from database.models import MessageContentLink, PostContent, TelegramPost from database.repositories.post_repository import PostRepository diff --git a/tests/test_post_service.py b/tests/test_post_service.py index 591fb6b..ffabd2b 100644 --- a/tests/test_post_service.py +++ b/tests/test_post_service.py @@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, Mock, patch import pytest from aiogram import types + from database.models import TelegramPost, User from helper_bot.handlers.private.services import BotSettings, PostService diff --git a/tests/test_rag_client.py b/tests/test_rag_client.py index 9a812eb..241c4c6 100644 --- a/tests/test_rag_client.py +++ b/tests/test_rag_client.py @@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest + from helper_bot.services.scoring.exceptions import ( InsufficientExamplesError, ScoringError, diff --git a/tests/test_rate_limit_middleware.py b/tests/test_rate_limit_middleware.py index 640b52f..ebf0c83 100644 --- a/tests/test_rate_limit_middleware.py +++ b/tests/test_rate_limit_middleware.py @@ -6,6 +6,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest from aiogram.types import CallbackQuery, Message, Update + from helper_bot.middlewares.rate_limit_middleware import RateLimitMiddleware diff --git a/tests/test_rate_limit_monitor.py b/tests/test_rate_limit_monitor.py index 8f4bff3..ef55a23 100644 --- a/tests/test_rate_limit_monitor.py +++ b/tests/test_rate_limit_monitor.py @@ -7,6 +7,7 @@ from collections import deque from unittest.mock import patch import pytest + from helper_bot.utils.rate_limit_monitor import ( RateLimitMonitor, RateLimitStats, diff --git a/tests/test_rate_limiter.py b/tests/test_rate_limiter.py index 2a72d45..ed3e7bd 100644 --- a/tests/test_rate_limiter.py +++ b/tests/test_rate_limiter.py @@ -7,6 +7,7 @@ import time from unittest.mock import AsyncMock, MagicMock, patch import pytest + from helper_bot.config.rate_limit_config import RateLimitSettings, get_rate_limit_config from helper_bot.utils.rate_limit_monitor import ( RateLimitMonitor, diff --git a/tests/test_refactored_admin_handlers.py b/tests/test_refactored_admin_handlers.py index 3f212d6..7633715 100644 --- a/tests/test_refactored_admin_handlers.py +++ b/tests/test_refactored_admin_handlers.py @@ -3,6 +3,7 @@ from unittest.mock import AsyncMock, Mock, patch import pytest from aiogram import types from aiogram.fsm.context import FSMContext + from helper_bot.handlers.admin.exceptions import ( InvalidInputError, UserAlreadyBannedError, diff --git a/tests/test_refactored_group_handlers.py b/tests/test_refactored_group_handlers.py index 5a8b15b..464c95f 100644 --- a/tests/test_refactored_group_handlers.py +++ b/tests/test_refactored_group_handlers.py @@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, Mock import pytest from aiogram import types from aiogram.fsm.context import FSMContext + from helper_bot.handlers.group.constants import ERROR_MESSAGES, FSM_STATES from helper_bot.handlers.group.exceptions import ( NoReplyToMessageError, diff --git a/tests/test_refactored_private_handlers.py b/tests/test_refactored_private_handlers.py index 434a7e6..515eb2c 100644 --- a/tests/test_refactored_private_handlers.py +++ b/tests/test_refactored_private_handlers.py @@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, Mock, patch import pytest 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 ( PrivateHandlers, diff --git a/tests/test_s3_storage.py b/tests/test_s3_storage.py index ac5bab8..214fc78 100644 --- a/tests/test_s3_storage.py +++ b/tests/test_s3_storage.py @@ -7,6 +7,7 @@ from pathlib import Path from unittest.mock import AsyncMock, MagicMock, patch import pytest + from helper_bot.utils.s3_storage import S3StorageService diff --git a/tests/test_scoring_services.py b/tests/test_scoring_services.py index 9dbce67..c7d427d 100644 --- a/tests/test_scoring_services.py +++ b/tests/test_scoring_services.py @@ -137,6 +137,7 @@ class TestVectorStore: """Создает VectorStore для тестов.""" try: import numpy as np + from helper_bot.services.scoring.vector_store import VectorStore return VectorStore(vector_dim=768, max_examples=100) diff --git a/tests/test_server_prometheus.py b/tests/test_server_prometheus.py index 5e6dc55..42631a5 100644 --- a/tests/test_server_prometheus.py +++ b/tests/test_server_prometheus.py @@ -6,6 +6,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest from aiohttp import web + from helper_bot.server_prometheus import ( MetricsServer, start_metrics_server, diff --git a/tests/test_text_middleware.py b/tests/test_text_middleware.py index 6187382..63c64b1 100644 --- a/tests/test_text_middleware.py +++ b/tests/test_text_middleware.py @@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest + from helper_bot.middlewares.text_middleware import BulkTextMiddleware diff --git a/tests/test_utils.py b/tests/test_utils.py index 53b3c4d..b57d253 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -2,8 +2,9 @@ import os from datetime import datetime from unittest.mock import AsyncMock, Mock, patch -import helper_bot.utils.messages as messages # Import for patching constants import pytest + +import helper_bot.utils.messages as messages # Import for patching constants from database.async_db import AsyncBotDB from helper_bot.utils.base_dependency_factory import ( BaseDependencyFactory, diff --git a/tests/test_voice_bot_architecture.py b/tests/test_voice_bot_architecture.py index 3788d51..9f7b7bc 100644 --- a/tests/test_voice_bot_architecture.py +++ b/tests/test_voice_bot_architecture.py @@ -3,6 +3,7 @@ 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.utils import ( diff --git a/tests/test_voice_constants.py b/tests/test_voice_constants.py index ab3eec1..b6774ef 100644 --- a/tests/test_voice_constants.py +++ b/tests/test_voice_constants.py @@ -1,4 +1,5 @@ import pytest + from helper_bot.handlers.voice.constants import ( BTN_LISTEN, BTN_SPEAK, diff --git a/tests/test_voice_exceptions.py b/tests/test_voice_exceptions.py index f94349b..38d8150 100644 --- a/tests/test_voice_exceptions.py +++ b/tests/test_voice_exceptions.py @@ -1,4 +1,5 @@ import pytest + from helper_bot.handlers.voice.exceptions import ( AudioProcessingError, VoiceBotError, diff --git a/tests/test_voice_handler.py b/tests/test_voice_handler.py index 304bfc8..af1fff9 100644 --- a/tests/test_voice_handler.py +++ b/tests/test_voice_handler.py @@ -3,6 +3,7 @@ from unittest.mock import AsyncMock, MagicMock, Mock, patch import pytest 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 diff --git a/tests/test_voice_services.py b/tests/test_voice_services.py index 75de09a..8448d82 100644 --- a/tests/test_voice_services.py +++ b/tests/test_voice_services.py @@ -3,6 +3,7 @@ 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 diff --git a/tests/test_voice_utils.py b/tests/test_voice_utils.py index f744ac0..50de559 100644 --- a/tests/test_voice_utils.py +++ b/tests/test_voice_utils.py @@ -3,6 +3,7 @@ from unittest.mock import Mock, patch import pytest from aiogram import types + from helper_bot.handlers.voice.utils import ( format_time_ago, get_last_message_text,