Files
PrimoExampleBot/tests/database/test_roles.py
2025-08-30 07:39:44 +07:00

208 lines
8.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pytest
from typing import List, Dict
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from database import Role, RoleRegion, BotDatabase
@pytest.mark.asyncio
class TestRoleSystem:
"""Тесты для системы ролей с полной строгой типизацией"""
async def test_role_creation(self, test_db: BotDatabase, test_session: AsyncSession) -> None:
"""
Тест создания ролей.
Проверяет, что тестовые роли существуют в базе.
"""
stmt = select(Role)
result = await test_session.execute(stmt)
roles: List[Role] = result.scalars().all()
assert len(roles) >= 5
role_names: List[str] = [role.name for role in roles]
assert "Альбедо" in role_names
assert "Нахида" in role_names
assert "Кафка" in role_names
async def test_assign_role(
self, test_db: BotDatabase, test_session: AsyncSession, test_user: int
) -> None:
"""
Тест назначения роли пользователю.
Проверяет успешное назначение свободной роли и правильное сохранение в БД.
"""
user_id: int = test_user
# Освобождаем роль на всякий случай
await test_db.release_role("Альбедо")
# Назначаем роль
success: bool = await test_db.assign_role("Альбедо", user_id)
assert success, "Не удалось назначить роль"
# Проверяем, что роль действительно назначена
stmt = select(Role).where(Role.name == "Альбедо")
result = await test_session.execute(stmt)
role: Role = result.scalar_one()
assert role.occupied_by == user_id
async def test_assign_occupied_role(
self, test_db: BotDatabase, test_session: AsyncSession, test_user: int
) -> None:
"""
Тест назначения уже занятой роли.
Проверяет, что нельзя назначить роль, если она уже занята другим пользователем.
"""
user_id: int = test_user
other_user_id: int = 999000111
await test_db.release_role("Альбедо")
await test_db.add_user(other_user_id, "other_user", "Other User")
# Назначаем роль первому пользователю
success_first: bool = await test_db.assign_role("Альбедо", user_id)
assert success_first, "Не удалось назначить роль первому пользователю"
# Пытаемся назначить ту же роль другому пользователю
success_second: bool = await test_db.assign_role("Альбедо", other_user_id)
assert not success_second, "Нельзя назначить занятую роль"
async def test_release_role(
self, test_db: BotDatabase, test_session: AsyncSession, test_user: int
) -> None:
"""
Тест освобождения роли.
Проверяет, что роль успешно освобождается.
"""
user_id: int = test_user
await test_db.release_role("Нахида")
success_assign: bool = await test_db.assign_role("Нахида", user_id)
assert success_assign
success_release: bool = await test_db.release_role("Нахида")
assert success_release
stmt = select(Role).where(Role.name == "Нахида")
result = await test_session.execute(stmt)
role: Role = result.scalar_one()
assert role.occupied_by is None
async def test_release_unoccupied_role(self, test_db: BotDatabase) -> None:
"""
Тест освобождения свободной роли.
Проверяет, что нельзя освободить уже свободную роль.
"""
await test_db.release_role("Кафка")
success: bool = await test_db.release_role("Кафка")
assert not success, "Нельзя освободить свободную роль"
async def test_get_user_roles(
self, test_db: BotDatabase, test_session: AsyncSession, test_user: int
) -> None:
"""
Тест получения ролей пользователя.
Проверяет, что возвращается корректный список назначенных ролей.
"""
user_id: int = test_user
await test_db.release_role("Альбедо")
await test_db.release_role("Нахида")
success1: bool = await test_db.assign_role("Альбедо", user_id)
success2: bool = await test_db.assign_role("Нахида", user_id)
assert success1 and success2
roles: List[str] = await test_db.get_roles_by_user(user_id)
assert len(roles) == 2
assert "Альбедо" in roles
assert "Нахида" in roles
async def test_get_available_roles(
self, test_db: BotDatabase, test_session: AsyncSession, test_user: int
) -> None:
"""
Тест получения доступных ролей.
Проверяет, что назначенные роли не включены в список свободных.
"""
user_id: int = test_user
# Освобождаем все роли
for role_name in ["Альбедо", "Нахида", "Кафка", "Броння", "Чжун Ли"]:
await test_db.release_role(role_name)
# Назначаем одну роль
success: bool = await test_db.assign_role("Альбедо", user_id)
assert success
available_roles: List[Role] = await test_db.get_available_roles()
role_names: List[str] = [role.name for role in available_roles]
assert "Альбедо" not in role_names
assert len(available_roles) > 0
for role in available_roles:
assert role.occupied_by is None
async def test_get_occupied_roles(
self, test_db: BotDatabase, test_session: AsyncSession, test_user: int
) -> None:
"""
Тест получения занятых ролей.
Проверяет, что все назначенные роли возвращаются корректно.
"""
user_id: int = test_user
await test_db.release_role("Альбедо")
await test_db.release_role("Нахида")
success1: bool = await test_db.assign_role("Альбедо", user_id)
success2: bool = await test_db.assign_role("Нахида", user_id)
assert success1 and success2
occupied_roles: List[Role] = await test_db.get_occupied_roles()
role_names: List[str] = [role.name for role in occupied_roles]
assert "Альбедо" in role_names
assert "Нахида" in role_names
assert len(occupied_roles) >= 2
async def test_region_filter(
self, test_db: BotDatabase, test_session: AsyncSession
) -> None:
"""
Тест фильтрации ролей по регионам.
Проверяет, что метод возвращает роли только указанного региона.
"""
await test_db.release_role("Альбедо")
mondstadt_roles: List[Role] = await test_db.get_available_roles(RoleRegion.MONDSTADT)
assert len(mondstadt_roles) == 1
assert mondstadt_roles[0].name == "Альбедо"
assert mondstadt_roles[0].region == RoleRegion.MONDSTADT
async def test_region_stats(
self, test_db: BotDatabase, test_session: AsyncSession, test_user: int
) -> None:
"""
Тест статистики по регионам.
Проверяет, что метод возвращает корректное количество занятых ролей по регионам.
"""
user_id: int = test_user
await test_db.release_role("Альбедо")
await test_db.release_role("Нахида")
success1: bool = await test_db.assign_role("Альбедо", user_id)
success2: bool = await test_db.assign_role("Нахида", user_id)
assert success1 and success2
stats: Dict[RoleRegion, Dict[str, int]] = await test_db.get_region_stats()
assert RoleRegion.MONDSTADT in stats
assert RoleRegion.SUMERU in stats
assert stats[RoleRegion.MONDSTADT]["occupied"] == 1
assert stats[RoleRegion.MONDSTADT]["total"] == 1