mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-01-20 03:40:26 +00:00
2) У промогрупп появится приоритет 3) У пользователя может быть несколько промогрупп, но влиять будет только с наивысшим приоритетом 4) К промокодам можно будет добавить промогруппу. Все активировавшие промокод получат её 5) При выводе пользователей с промогруппой будет также выводиться ссылка на каждого. Можно будет отследить сливы промокодов "для своих". Я в целом это добавлю во все места, где пользователь выводится в админке 6) Исправить баг исчезновения триалки при пополнении 7) Исправить падающие тесты и добавить новых 8) Трафик: 0 ГБ в тестовой подписке исправить на Трафик: Безлимит
207 lines
5.1 KiB
Python
207 lines
5.1 KiB
Python
"""
|
|
Fixtures for promocode and promo group testing
|
|
"""
|
|
import pytest
|
|
from types import SimpleNamespace
|
|
from unittest.mock import AsyncMock
|
|
from datetime import datetime, timedelta
|
|
|
|
from app.database.models import PromoCodeType
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_promo_group():
|
|
"""Sample PromoGroup object for testing"""
|
|
return SimpleNamespace(
|
|
id=1,
|
|
name="Test VIP Group",
|
|
priority=50,
|
|
server_discount_percent=20,
|
|
traffic_discount_percent=15,
|
|
device_discount_percent=10,
|
|
period_discounts={30: 10, 60: 15, 90: 20},
|
|
is_default=False,
|
|
auto_assign_total_spent_kopeks=None,
|
|
auto_assign_enabled=False,
|
|
addon_discount_enabled=True
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_user():
|
|
"""Sample User object for testing"""
|
|
return SimpleNamespace(
|
|
id=1,
|
|
telegram_id=123456789,
|
|
username="testuser",
|
|
full_name="Test User",
|
|
balance_kopeks=0,
|
|
language="ru",
|
|
has_had_paid_subscription=False,
|
|
total_spent_kopeks=0
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_promocode_balance():
|
|
"""Balance type promocode"""
|
|
return SimpleNamespace(
|
|
id=1,
|
|
code="BALANCE100",
|
|
type=PromoCodeType.BALANCE.value,
|
|
balance_bonus_kopeks=10000, # 100 rubles
|
|
subscription_days=0,
|
|
max_uses=100,
|
|
current_uses=10,
|
|
is_active=True,
|
|
promo_group_id=None,
|
|
promo_group=None,
|
|
valid_until=None,
|
|
created_at=datetime.utcnow(),
|
|
updated_at=datetime.utcnow(),
|
|
created_by=1
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_promocode_subscription():
|
|
"""Subscription days type promocode"""
|
|
return SimpleNamespace(
|
|
id=2,
|
|
code="SUB30",
|
|
type=PromoCodeType.SUBSCRIPTION_DAYS.value,
|
|
balance_bonus_kopeks=0,
|
|
subscription_days=30,
|
|
max_uses=50,
|
|
current_uses=5,
|
|
is_active=True,
|
|
promo_group_id=None,
|
|
promo_group=None,
|
|
valid_until=datetime.utcnow() + timedelta(days=60),
|
|
created_at=datetime.utcnow(),
|
|
updated_at=datetime.utcnow(),
|
|
created_by=1
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_promocode_promo_group(sample_promo_group):
|
|
"""Promo group type promocode"""
|
|
return SimpleNamespace(
|
|
id=3,
|
|
code="VIPGROUP",
|
|
type=PromoCodeType.PROMO_GROUP.value,
|
|
balance_bonus_kopeks=0,
|
|
subscription_days=0,
|
|
max_uses=100,
|
|
current_uses=20,
|
|
is_active=True,
|
|
promo_group_id=sample_promo_group.id,
|
|
promo_group=sample_promo_group,
|
|
valid_until=None,
|
|
created_at=datetime.utcnow(),
|
|
updated_at=datetime.utcnow(),
|
|
created_by=1
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_promocode_invalid():
|
|
"""Invalid/expired promocode"""
|
|
return SimpleNamespace(
|
|
id=4,
|
|
code="EXPIRED",
|
|
type=PromoCodeType.BALANCE.value,
|
|
balance_bonus_kopeks=5000,
|
|
subscription_days=0,
|
|
max_uses=10,
|
|
current_uses=10, # Used up
|
|
is_active=False,
|
|
promo_group_id=None,
|
|
promo_group=None,
|
|
valid_until=datetime.utcnow() - timedelta(days=1), # Expired
|
|
created_at=datetime.utcnow() - timedelta(days=30),
|
|
updated_at=datetime.utcnow(),
|
|
created_by=1
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_db_session():
|
|
"""Mock AsyncSession"""
|
|
db = AsyncMock()
|
|
db.commit = AsyncMock()
|
|
db.rollback = AsyncMock()
|
|
db.refresh = AsyncMock()
|
|
db.get = AsyncMock()
|
|
db.execute = AsyncMock()
|
|
db.add = AsyncMock()
|
|
return db
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_has_user_promo_group():
|
|
"""Mock has_user_promo_group function"""
|
|
return AsyncMock(return_value=False)
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_add_user_to_promo_group():
|
|
"""Mock add_user_to_promo_group function"""
|
|
return AsyncMock()
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_get_promo_group_by_id(sample_promo_group):
|
|
"""Mock get_promo_group_by_id function"""
|
|
return AsyncMock(return_value=sample_promo_group)
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_get_user_by_id(sample_user):
|
|
"""Mock get_user_by_id function"""
|
|
return AsyncMock(return_value=sample_user)
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_get_promocode_by_code():
|
|
"""Mock get_promocode_by_code function"""
|
|
return AsyncMock()
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_check_user_promocode_usage():
|
|
"""Mock check_user_promocode_usage function"""
|
|
return AsyncMock(return_value=False)
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_create_promocode_use():
|
|
"""Mock create_promocode_use function"""
|
|
return AsyncMock()
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_remnawave_service():
|
|
"""Mock RemnaWaveService"""
|
|
service = AsyncMock()
|
|
service.create_remnawave_user = AsyncMock()
|
|
service.update_remnawave_user = AsyncMock()
|
|
return service
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_subscription_service():
|
|
"""Mock SubscriptionService"""
|
|
service = AsyncMock()
|
|
service.create_remnawave_user = AsyncMock()
|
|
service.update_remnawave_user = AsyncMock()
|
|
return service
|
|
|
|
|
|
# Helper function to create a valid promocode property mock
|
|
def make_promocode_valid(promocode):
|
|
"""Helper to make promocode appear valid (is_valid property)"""
|
|
promocode.is_valid = True
|
|
return promocode
|