Files
remnawave-bedolaga-telegram…/tests/crud/test_promocode_crud.py
T
c0mrade 9a2aea038a chore: add uv package manager and ruff linter configuration
- Add pyproject.toml with uv and ruff configuration
- Pin Python version to 3.13 via .python-version
- Add Makefile commands: lint, format, fix
- Apply ruff formatting to entire codebase
- Remove unused imports (base64 in yookassa/simple_subscription)
- Update .gitignore for new config files
2026-01-24 17:45:27 +03:00

138 lines
3.8 KiB
Python

"""
Tests for Promocode CRUD operations - focus on promo_group_id integration
"""
from unittest.mock import AsyncMock, MagicMock
from app.database.crud.promocode import (
create_promocode,
get_promocode_by_code,
get_promocodes_list,
)
from app.database.models import PromoCodeType
# Import fixtures
async def test_create_promocode_with_promo_group_id(
sample_promo_group,
mock_db_session,
):
"""
Test creating a promocode with promo_group_id
Scenario:
- Create PROMO_GROUP type promocode
- promo_group_id should be saved
- Database operations should be called correctly
"""
# Execute
promocode = await create_promocode(
db=mock_db_session,
code='TESTGROUP',
type=PromoCodeType.PROMO_GROUP,
balance_bonus_kopeks=0,
subscription_days=0,
max_uses=100,
valid_until=None,
created_by=1,
promo_group_id=sample_promo_group.id,
)
# Assertions
assert promocode.code == 'TESTGROUP'
assert promocode.type == PromoCodeType.PROMO_GROUP.value
assert promocode.promo_group_id == sample_promo_group.id
# Verify database operations
mock_db_session.add.assert_called_once()
mock_db_session.commit.assert_awaited_once()
mock_db_session.refresh.assert_awaited_once()
async def test_create_promocode_without_promo_group_id(mock_db_session):
"""
Test creating a promocode without promo_group_id (other types)
Scenario:
- Create BALANCE type promocode
- promo_group_id should be None
"""
# Execute
promocode = await create_promocode(
db=mock_db_session,
code='BALANCE100',
type=PromoCodeType.BALANCE,
balance_bonus_kopeks=10000,
subscription_days=0,
max_uses=50,
valid_until=None,
created_by=1,
promo_group_id=None,
)
# Assertions
assert promocode.code == 'BALANCE100'
assert promocode.type == PromoCodeType.BALANCE.value
assert promocode.promo_group_id is None
async def test_get_promocode_by_code_loads_promo_group(
sample_promocode_promo_group,
mock_db_session,
):
"""
Test that get_promocode_by_code loads promo_group relationship
Scenario:
- Query promocode by code
- Verify selectinload was used for promo_group
- Verify promo_group data is accessible
"""
# Setup mock result
mock_result = AsyncMock()
mock_result.scalar_one_or_none = lambda: sample_promocode_promo_group
mock_db_session.execute = AsyncMock(return_value=mock_result)
# Execute
promocode = await get_promocode_by_code(mock_db_session, 'VIPGROUP')
# Assertions
assert promocode is not None
assert promocode.code == 'VIPGROUP'
assert promocode.promo_group is not None
assert promocode.promo_group.name == 'Test VIP Group'
# Verify execute was called (query was executed)
mock_db_session.execute.assert_awaited_once()
async def test_get_promocodes_list_loads_promo_groups(
sample_promocode_promo_group,
mock_db_session,
):
"""
Test that get_promocodes_list loads promo_group relationships
Scenario:
- Query list of promocodes
- Verify selectinload was used for promo_group
- Verify all promocodes have accessible promo_group data
"""
# Setup mock result
mock_result = AsyncMock()
mock_result.scalars = MagicMock(return_value=MagicMock(all=MagicMock(return_value=[sample_promocode_promo_group])))
mock_db_session.execute = AsyncMock(return_value=mock_result)
# Execute
promocodes = await get_promocodes_list(mock_db_session, offset=0, limit=10)
# Assertions
assert len(promocodes) == 1
assert promocodes[0].promo_group is not None
assert promocodes[0].promo_group.name == 'Test VIP Group'
# Verify execute was called
mock_db_session.execute.assert_awaited_once()