Добавлены новые методы для получения статистики постов пользователей, информации о последних постах и количестве банов. Обновлены запросы в репозиториях для сортировки пользователей по дате бана. Исправлены вызовы функций форматирования сообщений для администраторов. Обновлены тесты для проверки новых функциональностей.

This commit is contained in:
2026-02-28 21:30:08 +03:00
parent e2a6944ed8
commit 694cf1c106
18 changed files with 1296 additions and 144 deletions

View File

@@ -274,9 +274,9 @@ class TestBlacklistRepository:
# Нормализуем SQL запрос (убираем лишние пробелы и переносы строк)
actual_query = " ".join(call_args[0][0].split())
expected_query = "SELECT user_id, message_for_user, date_to_unban, created_at, ban_author FROM blacklist LIMIT ?, ?"
expected_query = "SELECT user_id, message_for_user, date_to_unban, created_at, ban_author FROM blacklist ORDER BY created_at DESC LIMIT ? OFFSET ?"
assert actual_query == expected_query
assert call_args[0][1] == (0, 10)
assert call_args[0][1] == (10, 0)
# Проверяем логирование
blacklist_repository.logger.info.assert_called_once_with(
@@ -310,7 +310,7 @@ class TestBlacklistRepository:
# Нормализуем SQL запрос (убираем лишние пробелы и переносы строк)
actual_query = " ".join(call_args[0][0].split())
expected_query = "SELECT user_id, message_for_user, date_to_unban, created_at, ban_author FROM blacklist"
expected_query = "SELECT user_id, message_for_user, date_to_unban, created_at, ban_author FROM blacklist ORDER BY created_at DESC"
assert actual_query == expected_query
# Проверяем, что параметры пустые (без лимитов)
assert len(call_args[0]) == 1 # Только SQL запрос, без параметров

View File

@@ -85,7 +85,7 @@ class TestPostPublishService:
return call
@patch("helper_bot.handlers.callback.services.send_text_message")
@patch("helper_bot.handlers.callback.services.get_text_message")
@patch("helper_bot.handlers.callback.services.get_publish_text")
async def test_publish_post_text_success(
self, mock_get_text, mock_send_text, service, mock_call_text, mock_db
):
@@ -214,7 +214,7 @@ class TestPostPublishService:
@patch("helper_bot.handlers.callback.services.send_photo_message")
@patch("helper_bot.handlers.callback.services.send_text_message")
@patch("helper_bot.handlers.callback.services.get_text_message")
@patch("helper_bot.handlers.callback.services.get_publish_text")
async def test_publish_post_photo_success(
self, mock_get_text, mock_send_text, mock_send_photo, service, mock_db
):
@@ -239,7 +239,7 @@ class TestPostPublishService:
@patch("helper_bot.handlers.callback.services.send_video_message")
@patch("helper_bot.handlers.callback.services.send_text_message")
@patch("helper_bot.handlers.callback.services.get_text_message")
@patch("helper_bot.handlers.callback.services.get_publish_text")
async def test_publish_post_video_success(
self, mock_get_text, mock_send_text, mock_send_video, service, mock_db
):
@@ -285,7 +285,7 @@ class TestPostPublishService:
@patch("helper_bot.handlers.callback.services.send_audio_message")
@patch("helper_bot.handlers.callback.services.send_text_message")
@patch("helper_bot.handlers.callback.services.get_text_message")
@patch("helper_bot.handlers.callback.services.get_publish_text")
async def test_publish_post_audio_success(
self, mock_get_text, mock_send_text, mock_send_audio, service, mock_db
):
@@ -499,7 +499,7 @@ class TestPostPublishService:
@patch("helper_bot.handlers.callback.services.send_media_group_to_channel")
@patch("helper_bot.handlers.callback.services.send_text_message")
@patch("helper_bot.handlers.callback.services.get_text_message")
@patch("helper_bot.handlers.callback.services.get_publish_text")
async def test_publish_media_group_success(
self, mock_get_text, mock_send_text, mock_send_media, service, mock_db
):

View File

@@ -29,6 +29,11 @@ class TestPrivateHandlers:
db.add_message = AsyncMock()
db.update_helper_message = AsyncMock()
db.update_user_activity = AsyncMock()
db.get_user_posts_stats = AsyncMock(return_value=(5, 2, 3))
db.get_last_post_by_author = AsyncMock(return_value="Last post text")
db.get_user_by_id = AsyncMock(return_value=Mock(date_added=1704067200))
db.get_user_ban_count = AsyncMock(return_value=0)
db.get_last_ban_info = AsyncMock(return_value=None)
return db
@pytest.fixture
@@ -257,6 +262,7 @@ class TestPrivateHandlers:
"""resend_message_in_group при PRE_CHAT переводит в START и отправляет question."""
handlers = create_private_handlers(mock_db, mock_settings)
mock_state.get_state = AsyncMock(return_value=FSM_STATES["PRE_CHAT"])
mock_message.bot.send_message = AsyncMock(return_value=Mock(message_id=100))
with pytest.MonkeyPatch().context() as m:
m.setattr(
"helper_bot.handlers.private.private_handlers.get_reply_keyboard",
@@ -267,9 +273,7 @@ class TestPrivateHandlers:
lambda x, y: "Question?",
)
await handlers.resend_message_in_group_for_message(mock_message, mock_state)
mock_message.forward.assert_called_once_with(
chat_id=mock_settings.group_for_message
)
mock_message.bot.send_message.assert_called_once()
mock_state.set_state.assert_called_once_with(FSM_STATES["START"])
@pytest.mark.asyncio
@@ -279,6 +283,7 @@ class TestPrivateHandlers:
"""resend_message_in_group при CHAT оставляет в CHAT и отправляет question с leave markup."""
handlers = create_private_handlers(mock_db, mock_settings)
mock_state.get_state = AsyncMock(return_value=FSM_STATES["CHAT"])
mock_message.bot.send_message = AsyncMock(return_value=Mock(message_id=100))
with pytest.MonkeyPatch().context() as m:
m.setattr(
"helper_bot.handlers.private.private_handlers.get_reply_keyboard_leave_chat",
@@ -289,9 +294,7 @@ class TestPrivateHandlers:
lambda x, y: "Question?",
)
await handlers.resend_message_in_group_for_message(mock_message, mock_state)
mock_message.forward.assert_called_once_with(
chat_id=mock_settings.group_for_message
)
mock_message.bot.send_message.assert_called_once()
mock_message.answer.assert_called()
@pytest.mark.asyncio

View File

@@ -665,7 +665,7 @@ class TestSendMessageFunctions:
assert result == mock_sent_message
mock_message.bot.send_photo.assert_called_once_with(
chat_id=123, caption="Подпись к фото", photo="photo.jpg"
chat_id=123, caption="Подпись к фото", photo="photo.jpg", parse_mode="HTML"
)
@pytest.mark.asyncio
@@ -684,7 +684,7 @@ class TestSendMessageFunctions:
assert result == mock_sent_message
mock_message.bot.send_video.assert_called_once_with(
chat_id=123, caption="Подпись к видео", video="video.mp4"
chat_id=123, caption="Подпись к видео", video="video.mp4", parse_mode="HTML"
)
@@ -722,8 +722,9 @@ class TestUtilityFunctions:
"""Тест получения списка заблокированных пользователей"""
mock_db = AsyncMock()
mock_db.get_banned_users_from_db_with_limits.return_value = [
(123, "Spam", 1704067200), # user_id, ban_reason, unban_date (timestamp)
(456, "Violation", 1704153600),
# user_id, ban_reason, unban_date (timestamp), ban_date (timestamp)
(123, "Spam", 1704067200, 1703980800),
(456, "Violation", 1704153600, 1704067200),
]
mock_db.get_username.return_value = None
mock_db.get_full_name_by_id.return_value = "Test User"
@@ -734,18 +735,16 @@ class TestUtilityFunctions:
assert "Test User" in result
assert "Spam" in result
assert "Violation" in result
assert "<b>Дата бана:</b>" in result
@pytest.mark.asyncio
async def test_get_banned_users_list_with_string_timestamp(self):
"""Тест получения списка заблокированных пользователей со строковым timestamp"""
mock_db = AsyncMock()
mock_db.get_banned_users_from_db_with_limits.return_value = [
(
123,
"Spam",
"1704067200",
), # user_id, ban_reason, unban_date (string timestamp)
(456, "Violation", "1704153600"),
# user_id, ban_reason, unban_date (string timestamp), ban_date (string timestamp)
(123, "Spam", "1704067200", "1703980800"),
(456, "Violation", "1704153600", "1704067200"),
]
mock_db.get_username.return_value = None
mock_db.get_full_name_by_id.return_value = "Test User"
@@ -756,6 +755,7 @@ class TestUtilityFunctions:
assert "Test User" in result
assert "Spam" in result
assert "Violation" in result
assert "<b>Дата бана:</b>" in result
@pytest.mark.asyncio
async def test_get_banned_users_buttons(self):