632 lines
23 KiB
Python
632 lines
23 KiB
Python
"""Тесты работы с закупами."""
|
||
|
||
import datetime
|
||
|
||
import pytest
|
||
from fastapi import HTTPException
|
||
|
||
from src import domain, dto, usecase
|
||
from tests.conftest import MockDatabase
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_create_placement_with_public_invite_link(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||
"""Создание закупа с публичной пригласительной ссылкой."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
target_channel = domain.TargetChannel(
|
||
telegram_id=-1001234567890,
|
||
title='Target Channel',
|
||
username='targetchannel',
|
||
user_id=user.id,
|
||
status=domain.TargetChannelStatus.ACTIVE,
|
||
)
|
||
await mock_database.upsert_target_channel(target_channel)
|
||
|
||
external_channel = domain.ExternalChannel(
|
||
telegram_id=-1009876543210,
|
||
title='External Channel',
|
||
username='externalchannel',
|
||
description='Ad channel',
|
||
subscribers_count=50000,
|
||
user_id=user.id,
|
||
)
|
||
await mock_database.create_external_channel(external_channel)
|
||
|
||
creative = domain.Creative(
|
||
name='Summer Sale',
|
||
text='Подписывайтесь на наш канал по ссылке: {link}',
|
||
target_channel_id=target_channel.id,
|
||
user_id=user.id,
|
||
status=domain.CreativeStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_creative(creative)
|
||
|
||
placement_date = datetime.datetime.now(datetime.UTC)
|
||
input_data = dto.CreatePlacementInput(
|
||
target_channel_id=target_channel.id,
|
||
external_channel_id=external_channel.id,
|
||
creative_id=creative.id,
|
||
placement_date=placement_date,
|
||
cost=5000.0,
|
||
comment='Утреннее размещение',
|
||
ad_post_url='https://t.me/externalchannel/123',
|
||
invite_link_type=domain.InviteLinkType.PUBLIC,
|
||
)
|
||
|
||
result = await usecases.create_placement(input_data, user.id)
|
||
|
||
assert result.target_channel_id == target_channel.id
|
||
assert result.external_channel_id == external_channel.id
|
||
assert result.creative_id == creative.id
|
||
assert result.cost == 5000.0
|
||
assert result.comment == 'Утреннее размещение'
|
||
assert result.invite_link_type == domain.InviteLinkType.PUBLIC
|
||
assert result.invite_link.startswith('https://t.me/+public_link_')
|
||
assert result.status == domain.PlacementStatus.ACTIVE
|
||
assert result.subscriptions_count == 0
|
||
|
||
# Проверяем, что счётчик закупов у креатива увеличился
|
||
updated_creative = await mock_database.get_creative(user.id, creative.id)
|
||
assert updated_creative is not None
|
||
assert updated_creative.placements_count == 1
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_create_placement_with_approval_invite_link(
|
||
usecases: usecase.Usecase, mock_database: MockDatabase
|
||
) -> None:
|
||
"""Создание закупа с пригласительной ссылкой, требующей одобрения."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
target_channel = domain.TargetChannel(
|
||
telegram_id=-1001234567890,
|
||
title='Target Channel',
|
||
username='targetchannel',
|
||
user_id=user.id,
|
||
status=domain.TargetChannelStatus.ACTIVE,
|
||
)
|
||
await mock_database.upsert_target_channel(target_channel)
|
||
|
||
external_channel = domain.ExternalChannel(
|
||
telegram_id=-1009876543210,
|
||
title='External Channel',
|
||
username='externalchannel',
|
||
description=None,
|
||
subscribers_count=30000,
|
||
user_id=user.id,
|
||
)
|
||
await mock_database.create_external_channel(external_channel)
|
||
|
||
creative = domain.Creative(
|
||
name='Premium Creative',
|
||
text='Эксклюзивный контент: {link}',
|
||
target_channel_id=target_channel.id,
|
||
user_id=user.id,
|
||
status=domain.CreativeStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_creative(creative)
|
||
|
||
placement_date = datetime.datetime.now(datetime.UTC)
|
||
input_data = dto.CreatePlacementInput(
|
||
target_channel_id=target_channel.id,
|
||
external_channel_id=external_channel.id,
|
||
creative_id=creative.id,
|
||
placement_date=placement_date,
|
||
invite_link_type=domain.InviteLinkType.APPROVAL,
|
||
)
|
||
|
||
result = await usecases.create_placement(input_data, user.id)
|
||
|
||
assert result.invite_link_type == domain.InviteLinkType.APPROVAL
|
||
assert 'approval_link_' in result.invite_link
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_create_placement_invalid_target_channel(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||
"""Создание закупа для несуществующего целевого канала вызывает ошибку."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
import uuid
|
||
|
||
fake_target_id = uuid.uuid4()
|
||
fake_external_id = uuid.uuid4()
|
||
fake_creative_id = uuid.uuid4()
|
||
|
||
input_data = dto.CreatePlacementInput(
|
||
target_channel_id=fake_target_id,
|
||
external_channel_id=fake_external_id,
|
||
creative_id=fake_creative_id,
|
||
placement_date=datetime.datetime.now(datetime.UTC),
|
||
)
|
||
|
||
with pytest.raises(HTTPException) as exc_info:
|
||
await usecases.create_placement(input_data, user.id)
|
||
assert exc_info.value.status_code == 404
|
||
assert 'Target channel' in str(exc_info.value.detail)
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_get_user_placements(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||
"""Получение списка закупов пользователя."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
target_channel = domain.TargetChannel(
|
||
telegram_id=-1001234567890,
|
||
title='Target Channel',
|
||
username='targetchannel',
|
||
user_id=user.id,
|
||
status=domain.TargetChannelStatus.ACTIVE,
|
||
)
|
||
await mock_database.upsert_target_channel(target_channel)
|
||
|
||
external_channel = domain.ExternalChannel(
|
||
telegram_id=-1009876543210,
|
||
title='External Channel',
|
||
username='externalchannel',
|
||
description=None,
|
||
subscribers_count=20000,
|
||
user_id=user.id,
|
||
)
|
||
await mock_database.create_external_channel(external_channel)
|
||
|
||
creative = domain.Creative(
|
||
name='Test Creative',
|
||
text='Test text',
|
||
target_channel_id=target_channel.id,
|
||
user_id=user.id,
|
||
status=domain.CreativeStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_creative(creative)
|
||
|
||
# Создаём два закупа
|
||
placement1 = domain.Placement(
|
||
target_channel_id=target_channel.id,
|
||
external_channel_id=external_channel.id,
|
||
creative_id=creative.id,
|
||
user_id=user.id,
|
||
placement_date=datetime.datetime.now(datetime.UTC),
|
||
cost=3000.0,
|
||
invite_link='https://t.me/+link1',
|
||
invite_link_type=domain.InviteLinkType.PUBLIC,
|
||
status=domain.PlacementStatus.ACTIVE,
|
||
)
|
||
placement2 = domain.Placement(
|
||
target_channel_id=target_channel.id,
|
||
external_channel_id=external_channel.id,
|
||
creative_id=creative.id,
|
||
user_id=user.id,
|
||
placement_date=datetime.datetime.now(datetime.UTC) - datetime.timedelta(days=1),
|
||
cost=4000.0,
|
||
invite_link='https://t.me/+link2',
|
||
invite_link_type=domain.InviteLinkType.PUBLIC,
|
||
status=domain.PlacementStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_placement(placement1)
|
||
await mock_database.create_placement(placement2)
|
||
|
||
result = await usecases.get_placements(dto.GetPlacementsInput(user_id=user.id))
|
||
|
||
assert len(result.placements) == 2
|
||
# Проверяем сортировку по дате размещения (новые первые)
|
||
assert result.placements[0].id == placement1.id
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_get_placements_filtered_by_target_channel(
|
||
usecases: usecase.Usecase, mock_database: MockDatabase
|
||
) -> None:
|
||
"""Получение закупов, отфильтрованных по целевому каналу."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
target1 = domain.TargetChannel(
|
||
telegram_id=-1001234567890,
|
||
title='Target 1',
|
||
username='target1',
|
||
user_id=user.id,
|
||
status=domain.TargetChannelStatus.ACTIVE,
|
||
)
|
||
target2 = domain.TargetChannel(
|
||
telegram_id=-1001234567891,
|
||
title='Target 2',
|
||
username='target2',
|
||
user_id=user.id,
|
||
status=domain.TargetChannelStatus.ACTIVE,
|
||
)
|
||
await mock_database.upsert_target_channel(target1)
|
||
await mock_database.upsert_target_channel(target2)
|
||
|
||
external_channel = domain.ExternalChannel(
|
||
telegram_id=-1009876543210,
|
||
title='External Channel',
|
||
username='externalchannel',
|
||
description=None,
|
||
subscribers_count=15000,
|
||
user_id=user.id,
|
||
)
|
||
await mock_database.create_external_channel(external_channel)
|
||
|
||
creative1 = domain.Creative(
|
||
name='Creative 1',
|
||
text='Text 1',
|
||
target_channel_id=target1.id,
|
||
user_id=user.id,
|
||
status=domain.CreativeStatus.ACTIVE,
|
||
)
|
||
creative2 = domain.Creative(
|
||
name='Creative 2',
|
||
text='Text 2',
|
||
target_channel_id=target2.id,
|
||
user_id=user.id,
|
||
status=domain.CreativeStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_creative(creative1)
|
||
await mock_database.create_creative(creative2)
|
||
|
||
placement1 = domain.Placement(
|
||
target_channel_id=target1.id,
|
||
external_channel_id=external_channel.id,
|
||
creative_id=creative1.id,
|
||
user_id=user.id,
|
||
placement_date=datetime.datetime.now(datetime.UTC),
|
||
invite_link='https://t.me/+link1',
|
||
invite_link_type=domain.InviteLinkType.PUBLIC,
|
||
status=domain.PlacementStatus.ACTIVE,
|
||
)
|
||
placement2 = domain.Placement(
|
||
target_channel_id=target2.id,
|
||
external_channel_id=external_channel.id,
|
||
creative_id=creative2.id,
|
||
user_id=user.id,
|
||
placement_date=datetime.datetime.now(datetime.UTC),
|
||
invite_link='https://t.me/+link2',
|
||
invite_link_type=domain.InviteLinkType.PUBLIC,
|
||
status=domain.PlacementStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_placement(placement1)
|
||
await mock_database.create_placement(placement2)
|
||
|
||
result = await usecases.get_placements(dto.GetPlacementsInput(user_id=user.id, target_channel_id=target1.id))
|
||
|
||
assert len(result.placements) == 1
|
||
assert result.placements[0].target_channel_id == target1.id
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_get_placements_filtered_by_creative(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||
"""Получение закупов, отфильтрованных по креативу - для оценки эффективности креатива."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
target_channel = domain.TargetChannel(
|
||
telegram_id=-1001234567890,
|
||
title='Target Channel',
|
||
username='targetchannel',
|
||
user_id=user.id,
|
||
status=domain.TargetChannelStatus.ACTIVE,
|
||
)
|
||
await mock_database.upsert_target_channel(target_channel)
|
||
|
||
external_channel = domain.ExternalChannel(
|
||
telegram_id=-1009876543210,
|
||
title='External Channel',
|
||
username='externalchannel',
|
||
description=None,
|
||
subscribers_count=25000,
|
||
user_id=user.id,
|
||
)
|
||
await mock_database.create_external_channel(external_channel)
|
||
|
||
creative1 = domain.Creative(
|
||
name='Creative A',
|
||
text='Вариант A',
|
||
target_channel_id=target_channel.id,
|
||
user_id=user.id,
|
||
status=domain.CreativeStatus.ACTIVE,
|
||
)
|
||
creative2 = domain.Creative(
|
||
name='Creative B',
|
||
text='Вариант B',
|
||
target_channel_id=target_channel.id,
|
||
user_id=user.id,
|
||
status=domain.CreativeStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_creative(creative1)
|
||
await mock_database.create_creative(creative2)
|
||
|
||
# Создаём закупы с разными креативами
|
||
placement1 = domain.Placement(
|
||
target_channel_id=target_channel.id,
|
||
external_channel_id=external_channel.id,
|
||
creative_id=creative1.id,
|
||
user_id=user.id,
|
||
placement_date=datetime.datetime.now(datetime.UTC),
|
||
invite_link='https://t.me/+link1',
|
||
invite_link_type=domain.InviteLinkType.PUBLIC,
|
||
status=domain.PlacementStatus.ACTIVE,
|
||
)
|
||
placement2 = domain.Placement(
|
||
target_channel_id=target_channel.id,
|
||
external_channel_id=external_channel.id,
|
||
creative_id=creative2.id,
|
||
user_id=user.id,
|
||
placement_date=datetime.datetime.now(datetime.UTC),
|
||
invite_link='https://t.me/+link2',
|
||
invite_link_type=domain.InviteLinkType.PUBLIC,
|
||
status=domain.PlacementStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_placement(placement1)
|
||
await mock_database.create_placement(placement2)
|
||
|
||
result = await usecases.get_placements(dto.GetPlacementsInput(user_id=user.id, creative_id=creative1.id))
|
||
|
||
assert len(result.placements) == 1
|
||
assert result.placements[0].creative_id == creative1.id
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_archive_placement(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||
"""Архивирование закупа - убирает его из активной статистики."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
target_channel = domain.TargetChannel(
|
||
telegram_id=-1001234567890,
|
||
title='Target Channel',
|
||
username='targetchannel',
|
||
user_id=user.id,
|
||
status=domain.TargetChannelStatus.ACTIVE,
|
||
)
|
||
await mock_database.upsert_target_channel(target_channel)
|
||
|
||
external_channel = domain.ExternalChannel(
|
||
telegram_id=-1009876543210,
|
||
title='External Channel',
|
||
username='externalchannel',
|
||
description=None,
|
||
subscribers_count=18000,
|
||
user_id=user.id,
|
||
)
|
||
await mock_database.create_external_channel(external_channel)
|
||
|
||
creative = domain.Creative(
|
||
name='Test Creative',
|
||
text='Test text',
|
||
target_channel_id=target_channel.id,
|
||
user_id=user.id,
|
||
status=domain.CreativeStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_creative(creative)
|
||
|
||
placement = domain.Placement(
|
||
target_channel_id=target_channel.id,
|
||
external_channel_id=external_channel.id,
|
||
creative_id=creative.id,
|
||
user_id=user.id,
|
||
placement_date=datetime.datetime.now(datetime.UTC),
|
||
invite_link='https://t.me/+link1',
|
||
invite_link_type=domain.InviteLinkType.PUBLIC,
|
||
status=domain.PlacementStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_placement(placement)
|
||
|
||
result = await usecases.archive_placement(placement.id, user.id)
|
||
|
||
assert result.status == domain.PlacementStatus.ARCHIVED
|
||
|
||
# Проверяем, что архивированный закуп не возвращается по умолчанию
|
||
placements_list = await usecases.get_placements(dto.GetPlacementsInput(user_id=user.id))
|
||
assert len(placements_list.placements) == 0
|
||
|
||
# Проверяем, что архивированный закуп возвращается с флагом include_archived
|
||
placements_with_archived = await usecases.get_placements(
|
||
dto.GetPlacementsInput(user_id=user.id, include_archived=True)
|
||
)
|
||
assert len(placements_with_archived.placements) == 1
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_update_placement(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||
"""Редактирование закупа - обновление стоимости, комментария, даты."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
target_channel = domain.TargetChannel(
|
||
telegram_id=-1001234567890,
|
||
title='Target Channel',
|
||
username='targetchannel',
|
||
user_id=user.id,
|
||
status=domain.TargetChannelStatus.ACTIVE,
|
||
)
|
||
await mock_database.upsert_target_channel(target_channel)
|
||
|
||
external_channel = domain.ExternalChannel(
|
||
telegram_id=-1009876543210,
|
||
title='External Channel',
|
||
username='externalchannel',
|
||
description=None,
|
||
subscribers_count=22000,
|
||
user_id=user.id,
|
||
)
|
||
await mock_database.create_external_channel(external_channel)
|
||
|
||
creative = domain.Creative(
|
||
name='Test Creative',
|
||
text='Test text',
|
||
target_channel_id=target_channel.id,
|
||
user_id=user.id,
|
||
status=domain.CreativeStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_creative(creative)
|
||
|
||
old_date = datetime.datetime.now(datetime.UTC) - datetime.timedelta(days=1)
|
||
placement = domain.Placement(
|
||
target_channel_id=target_channel.id,
|
||
external_channel_id=external_channel.id,
|
||
creative_id=creative.id,
|
||
user_id=user.id,
|
||
placement_date=old_date,
|
||
cost=3000.0,
|
||
comment='Старый комментарий',
|
||
invite_link='https://t.me/+link1',
|
||
invite_link_type=domain.InviteLinkType.PUBLIC,
|
||
status=domain.PlacementStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_placement(placement)
|
||
|
||
new_date = datetime.datetime.now(datetime.UTC)
|
||
update_input = dto.UpdatePlacementInput(
|
||
placement_date=new_date,
|
||
cost=3500.0,
|
||
comment='Обновлённый комментарий',
|
||
ad_post_url='https://t.me/externalchannel/456',
|
||
)
|
||
result = await usecases.update_placement(placement.id, update_input, user.id)
|
||
|
||
assert result.placement_date == new_date
|
||
assert result.cost == 3500.0
|
||
assert result.comment == 'Обновлённый комментарий'
|
||
assert result.ad_post_url == 'https://t.me/externalchannel/456'
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_delete_placement(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||
"""Удаление закупа - уменьшает счётчик закупов у креатива."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
target_channel = domain.TargetChannel(
|
||
telegram_id=-1001234567890,
|
||
title='Target Channel',
|
||
username='targetchannel',
|
||
user_id=user.id,
|
||
status=domain.TargetChannelStatus.ACTIVE,
|
||
)
|
||
await mock_database.upsert_target_channel(target_channel)
|
||
|
||
external_channel = domain.ExternalChannel(
|
||
telegram_id=-1009876543210,
|
||
title='External Channel',
|
||
username='externalchannel',
|
||
description=None,
|
||
subscribers_count=28000,
|
||
user_id=user.id,
|
||
)
|
||
await mock_database.create_external_channel(external_channel)
|
||
|
||
creative = domain.Creative(
|
||
name='Test Creative',
|
||
text='Test text',
|
||
target_channel_id=target_channel.id,
|
||
user_id=user.id,
|
||
status=domain.CreativeStatus.ACTIVE,
|
||
placements_count=1,
|
||
)
|
||
await mock_database.create_creative(creative)
|
||
|
||
placement = domain.Placement(
|
||
target_channel_id=target_channel.id,
|
||
external_channel_id=external_channel.id,
|
||
creative_id=creative.id,
|
||
user_id=user.id,
|
||
placement_date=datetime.datetime.now(datetime.UTC),
|
||
invite_link='https://t.me/+link1',
|
||
invite_link_type=domain.InviteLinkType.PUBLIC,
|
||
status=domain.PlacementStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_placement(placement)
|
||
|
||
await usecases.delete_placement(dto.DeletePlacementInput(placement_id=placement.id, user_id=user.id))
|
||
|
||
# Проверяем, что закуп удалён
|
||
placements_list = await usecases.get_placements(dto.GetPlacementsInput(user_id=user.id, include_archived=True))
|
||
assert len(placements_list.placements) == 0
|
||
|
||
# Проверяем, что счётчик закупов у креатива уменьшился
|
||
updated_creative = await mock_database.get_creative(user.id, creative.id)
|
||
assert updated_creative is not None
|
||
assert updated_creative.placements_count == 0
|
||
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_multiple_placements_same_creative(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||
"""Создание нескольких закупов с одним креативом - для A/B тестирования в разных каналах."""
|
||
user = domain.User(telegram_id=123456, username='testuser')
|
||
await mock_database.create_user(user)
|
||
|
||
target_channel = domain.TargetChannel(
|
||
telegram_id=-1001234567890,
|
||
title='Target Channel',
|
||
username='targetchannel',
|
||
user_id=user.id,
|
||
status=domain.TargetChannelStatus.ACTIVE,
|
||
)
|
||
await mock_database.upsert_target_channel(target_channel)
|
||
|
||
external1 = domain.ExternalChannel(
|
||
telegram_id=-1009876543210,
|
||
title='External 1',
|
||
username='external1',
|
||
description=None,
|
||
subscribers_count=10000,
|
||
user_id=user.id,
|
||
)
|
||
external2 = domain.ExternalChannel(
|
||
telegram_id=-1009876543211,
|
||
title='External 2',
|
||
username='external2',
|
||
description=None,
|
||
subscribers_count=20000,
|
||
user_id=user.id,
|
||
)
|
||
await mock_database.create_external_channel(external1)
|
||
await mock_database.create_external_channel(external2)
|
||
|
||
creative = domain.Creative(
|
||
name='Universal Creative',
|
||
text='Универсальный текст',
|
||
target_channel_id=target_channel.id,
|
||
user_id=user.id,
|
||
status=domain.CreativeStatus.ACTIVE,
|
||
)
|
||
await mock_database.create_creative(creative)
|
||
|
||
# Создаём два закупа с одним креативом в разных внешних каналах
|
||
input1 = dto.CreatePlacementInput(
|
||
target_channel_id=target_channel.id,
|
||
external_channel_id=external1.id,
|
||
creative_id=creative.id,
|
||
placement_date=datetime.datetime.now(datetime.UTC),
|
||
cost=2000.0,
|
||
)
|
||
input2 = dto.CreatePlacementInput(
|
||
target_channel_id=target_channel.id,
|
||
external_channel_id=external2.id,
|
||
creative_id=creative.id,
|
||
placement_date=datetime.datetime.now(datetime.UTC),
|
||
cost=4000.0,
|
||
)
|
||
|
||
result1 = await usecases.create_placement(input1, user.id)
|
||
result2 = await usecases.create_placement(input2, user.id)
|
||
|
||
# Проверяем, что созданы два разных закупа
|
||
assert result1.id != result2.id
|
||
assert result1.invite_link != result2.invite_link
|
||
|
||
# Проверяем, что счётчик креатива увеличился на 2
|
||
updated_creative = await mock_database.get_creative(user.id, creative.id)
|
||
assert updated_creative is not None
|
||
assert updated_creative.placements_count == 2
|
||
|
||
# Проверяем фильтрацию по креативу
|
||
placements_for_creative = await usecases.get_placements(
|
||
dto.GetPlacementsInput(user_id=user.id, creative_id=creative.id)
|
||
)
|
||
assert len(placements_for_creative.placements) == 2
|