74 lines
3.7 KiB
Python
74 lines
3.7 KiB
Python
import asyncio
|
|
from datetime import datetime, timedelta, timezone
|
|
|
|
from sqlalchemy import select, update
|
|
|
|
from src.core.database import async_session_maker
|
|
from src.core.models import Winner, WinnerVerification, User
|
|
from src.core.services import UserService, LotteryService, ParticipationService
|
|
from src.core.redraw_services import redraw_unclaimed
|
|
from src.core.chat_services import ChatSettingsService, BanService, ChatPermissionService
|
|
from src.core.user_management import UserManagementService
|
|
|
|
|
|
async def run(call, *args):
|
|
async with async_session_maker() as session:
|
|
return await call(session, *args)
|
|
|
|
|
|
async def test_parallel_redraw_replaces_only_expired_unclaimed_prizes_once():
|
|
async with async_session_maker() as session:
|
|
users = [await UserService.get_or_create_user(session, 800 + i) for i in range(4)]
|
|
lottery = await LotteryService.create_lottery(session, "Draw", "", ["First", "Second"], users[0].id)
|
|
lottery_id = lottery.id
|
|
for user in users:
|
|
await ParticipationService.add_participant(session, lottery_id, user.id)
|
|
await LotteryService.conduct_draw(session, lottery_id)
|
|
winners = await LotteryService.get_winners(session, lottery_id)
|
|
claimed_id = winners[0].id
|
|
winners[0].is_claimed = True
|
|
winners[1].is_notified = True
|
|
winners[1].created_at = datetime.now(timezone.utc) - timedelta(days=2)
|
|
await session.commit()
|
|
results = await asyncio.gather(*(run(redraw_unclaimed, lottery_id) for _ in range(5)))
|
|
assert sum(len(result) for result in results) == 1
|
|
async with async_session_maker() as session:
|
|
remaining = await LotteryService.get_winners(session, lottery_id)
|
|
assert len(remaining) == 2
|
|
assert (await session.get(Winner, claimed_id)).is_claimed
|
|
assert {winner.prize for winner in remaining} == {"First", "Second"}
|
|
|
|
|
|
async def test_chat_settings_created_once_under_concurrency():
|
|
settings = await asyncio.gather(*(run(ChatSettingsService.get_or_create_settings) for _ in range(8)))
|
|
assert {item.id for item in settings} == {1}
|
|
|
|
|
|
async def test_both_admin_interfaces_clear_chat_bans():
|
|
async with async_session_maker() as session:
|
|
admin = await UserService.get_or_create_user(session, 850)
|
|
user = await UserService.get_or_create_user(session, 851)
|
|
user.is_registered = True
|
|
await session.commit()
|
|
await BanService.ban_user(session, user.id, user.telegram_id, admin.id)
|
|
assert not (await ChatPermissionService.can_send_message(session, 851))[0]
|
|
await UserManagementService.unban_user_in_chat(session, user.id)
|
|
assert (await ChatPermissionService.can_send_message(session, 851))[0]
|
|
await BanService.ban_user(session, user.id, user.telegram_id, admin.id)
|
|
assert await BanService.unban_user(session, 851)
|
|
assert (await ChatPermissionService.can_send_message(session, 851))[0]
|
|
|
|
|
|
async def test_lottery_delete_includes_verification_children():
|
|
async with async_session_maker() as session:
|
|
user = await UserService.get_or_create_user(session, 870)
|
|
lottery = await LotteryService.create_lottery(session, "Draw", "", ["Prize"], user.id)
|
|
await ParticipationService.add_participant(session, lottery.id, user.id)
|
|
await LotteryService.conduct_draw(session, lottery.id)
|
|
winner = (await LotteryService.get_winners(session, lottery.id))[0]
|
|
session.add(WinnerVerification(winner_id=winner.id, verification_token="test-token",
|
|
expires_at=datetime.now(timezone.utc) + timedelta(days=1)))
|
|
await session.commit()
|
|
assert await LotteryService.delete_lottery(session, lottery.id)
|
|
assert not list((await session.scalars(select(WinnerVerification))).all())
|