170 lines
6.4 KiB
Python
170 lines
6.4 KiB
Python
"""Тесты подключения целевых каналов."""
|
||
|
||
import pytest
|
||
from fastapi import HTTPException
|
||
|
||
from src import domain, dto, usecase
|
||
from tests.conftest import MockDatabase, MockTelegramWriter
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_connect_new_channel_success(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||
"""Подключение нового канала с правами администратора."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
input_data = dto.ConnectTargetChanInput(
|
||
telegram_id=-1001234567890,
|
||
title='Test Channel',
|
||
username='testchannel',
|
||
user_telegram_id=123456,
|
||
bot_permissions=dto.ChannelBotPermissions(
|
||
is_admin=True,
|
||
can_invite_users=True,
|
||
can_restrict_members=True,
|
||
),
|
||
)
|
||
|
||
result = await usecases.connect_target_chan(input_data)
|
||
|
||
assert result.telegram_id == -1001234567890
|
||
assert result.title == 'Test Channel'
|
||
assert result.status == domain.TargetChannelStatus.ACTIVE
|
||
assert result.is_active is True # проверка обратной совместимости
|
||
|
||
# Проверяем, что канал сохранён
|
||
channel = await mock_database.get_target_channel(user.id, telegram_id=-1001234567890)
|
||
assert channel is not None
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_connect_channel_without_admin_rights(
|
||
usecases: usecase.Usecase, mock_database: MockDatabase, mock_telegram: MockTelegramWriter
|
||
) -> None:
|
||
"""Канал без прав администратора не подключается."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
input_data = dto.ConnectTargetChanInput(
|
||
telegram_id=-1001234567890,
|
||
title='Test Channel',
|
||
username='testchannel',
|
||
user_telegram_id=123456,
|
||
bot_permissions=dto.ChannelBotPermissions(
|
||
is_admin=False,
|
||
can_invite_users=False,
|
||
can_restrict_members=False,
|
||
),
|
||
)
|
||
|
||
with pytest.raises(HTTPException) as exc_info:
|
||
await usecases.connect_target_chan(input_data)
|
||
|
||
assert exc_info.value.status_code == 403
|
||
# Проверяем, что бот отправил предупреждение
|
||
assert len(mock_telegram.sent_messages) == 1
|
||
assert 'не является админом' in mock_telegram.sent_messages[0]['text']
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_connect_channel_without_required_permissions(
|
||
usecases: usecase.Usecase, mock_database: MockDatabase, mock_telegram: MockTelegramWriter
|
||
) -> None:
|
||
"""Канал без необходимых прав не подключается."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
input_data = dto.ConnectTargetChanInput(
|
||
telegram_id=-1001234567890,
|
||
title='Test Channel',
|
||
username='testchannel',
|
||
user_telegram_id=123456,
|
||
bot_permissions=dto.ChannelBotPermissions(
|
||
is_admin=True,
|
||
can_invite_users=False, # Отсутствует необходимое право
|
||
can_restrict_members=True,
|
||
),
|
||
)
|
||
|
||
with pytest.raises(HTTPException) as exc_info:
|
||
await usecases.connect_target_chan(input_data)
|
||
|
||
assert exc_info.value.status_code == 403
|
||
assert len(mock_telegram.sent_messages) == 1
|
||
assert 'не имеет необходимых прав' in mock_telegram.sent_messages[0]['text']
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_connect_channel_user_not_found(usecases: usecase.Usecase, mock_telegram: MockTelegramWriter) -> None:
|
||
"""Подключение канала неавторизованным пользователем вызывает ошибку."""
|
||
input_data = dto.ConnectTargetChanInput(
|
||
telegram_id=-1001234567890,
|
||
title='Test Channel',
|
||
username='testchannel',
|
||
user_telegram_id=999999, # Несуществующий пользователь
|
||
bot_permissions=dto.ChannelBotPermissions(
|
||
is_admin=True,
|
||
can_invite_users=True,
|
||
can_restrict_members=True,
|
||
),
|
||
)
|
||
|
||
with pytest.raises(HTTPException) as exc_info:
|
||
await usecases.connect_target_chan(input_data)
|
||
|
||
assert exc_info.value.status_code == 404
|
||
assert 'not found' in str(exc_info.value.detail).lower()
|
||
assert len(mock_telegram.sent_messages) == 1
|
||
assert 'авторизоваться' in mock_telegram.sent_messages[0]['text']
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_get_user_target_channels(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||
"""Получение списка каналов пользователя."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
channel1 = domain.TargetChannel(
|
||
telegram_id=-1001234567890,
|
||
title='Channel 1',
|
||
username='channel1',
|
||
user_id=user.id,
|
||
status=domain.TargetChannelStatus.ACTIVE,
|
||
)
|
||
channel2 = domain.TargetChannel(
|
||
telegram_id=-1001234567891,
|
||
title='Channel 2',
|
||
username='channel2',
|
||
user_id=user.id,
|
||
status=domain.TargetChannelStatus.ACTIVE,
|
||
)
|
||
await mock_database.upsert_target_channel(channel1)
|
||
await mock_database.upsert_target_channel(channel2)
|
||
|
||
result = await usecases.get_user_target_chans(dto.GetUserTargetChansInput(user_id=user.id))
|
||
|
||
assert len(result.target_channels) == 2
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_disconnect_target_channel(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||
"""Отключение целевого канала."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
channel = domain.TargetChannel(
|
||
telegram_id=-1001234567890,
|
||
title='Test Channel',
|
||
username='testchannel',
|
||
user_id=user.id,
|
||
status=domain.TargetChannelStatus.ACTIVE,
|
||
)
|
||
await mock_database.upsert_target_channel(channel)
|
||
|
||
await usecases.disconnect_target_chan(dto.DisconnectTargetChanInput(channel_id=channel.id, user_id=user.id))
|
||
|
||
# Проверяем, что канал стал неактивным
|
||
updated_channel = await mock_database.get_target_channel(user.id, channel_id=channel.id)
|
||
assert updated_channel is not None
|
||
assert updated_channel.status == domain.TargetChannelStatus.INACTIVE
|