# -*- coding: utf-8 -*- """ Тесты для сервиса кошелька (WalletService). Используем TenantTestCase для корректной работы с tenant-системой. """ from decimal import Decimal from django.core.cache import cache from django_tenants.test.cases import TenantTestCase from customers.models import Customer from customers.services.wallet_service import WalletService class WalletServiceTestCase(TenantTestCase): """Тесты WalletService.""" def setUp(self): """Создаём тестового клиента.""" self.customer = Customer.objects.create(name="Тестовый клиент") cache.clear() def tearDown(self): cache.clear() def test_create_transaction_deposit(self): """create_transaction создаёт пополнение с положительной суммой.""" txn = WalletService.create_transaction( customer=self.customer, amount=Decimal('50.00'), transaction_type='deposit', description='Тестовое пополнение' ) self.assertEqual(txn.signed_amount, Decimal('50.00')) self.assertEqual(txn.transaction_type, 'deposit') self.assertEqual(txn.balance_after, Decimal('50.00')) self.assertEqual(self.customer.wallet_balance, Decimal('50.00')) def test_create_transaction_spend(self): """create_transaction создаёт списание с отрицательной суммой.""" # Сначала пополняем WalletService.create_transaction( customer=self.customer, amount=Decimal('100.00'), transaction_type='deposit' ) # Затем списываем txn = WalletService.create_transaction( customer=self.customer, amount=Decimal('30.00'), transaction_type='spend', description='Тестовое списание' ) self.assertEqual(txn.signed_amount, Decimal('-30.00')) self.assertEqual(txn.transaction_type, 'spend') self.assertEqual(txn.balance_after, Decimal('70.00')) self.assertEqual(self.customer.wallet_balance, Decimal('70.00')) def test_create_transaction_spend_insufficient_funds(self): """Списание при недостаточном балансе вызывает ValueError.""" with self.assertRaises(ValueError) as context: WalletService.create_transaction( customer=self.customer, amount=Decimal('100.00'), transaction_type='spend' ) self.assertIn('Недостаточно средств', str(context.exception)) def test_adjust_balance_positive(self): """Положительная корректировка увеличивает баланс.""" txn = WalletService.adjust_balance( customer_id=self.customer.pk, amount=Decimal('75.00'), description='Тестовое пополнение администратором', user=None ) self.assertEqual(txn.signed_amount, Decimal('75.00')) self.assertEqual(txn.transaction_type, 'adjustment') self.assertEqual(self.customer.wallet_balance, Decimal('75.00')) def test_adjust_balance_negative(self): """Отрицательная корректировка уменьшает баланс.""" # Сначала пополняем WalletService.adjust_balance( customer_id=self.customer.pk, amount=Decimal('100.00'), description='Начальное пополнение', user=None ) # Отрицательная корректировка txn = WalletService.adjust_balance( customer_id=self.customer.pk, amount=Decimal('-40.00'), description='Списание администратором', user=None ) self.assertEqual(txn.signed_amount, Decimal('-40.00')) self.assertEqual(self.customer.wallet_balance, Decimal('60.00')) def test_adjust_balance_negative_insufficient(self): """Отрицательная корректировка с недостаточным балансом вызывает ValueError.""" with self.assertRaises(ValueError) as context: WalletService.adjust_balance( customer_id=self.customer.pk, amount=Decimal('-50.00'), description='Списание', user=None ) self.assertIn('отрицательному балансу', str(context.exception)) def test_adjust_balance_requires_description(self): """Корректировка без описания вызывает ValueError.""" with self.assertRaises(ValueError) as context: WalletService.adjust_balance( customer_id=self.customer.pk, amount=Decimal('50.00'), description='', user=None ) self.assertIn('Описание обязательно', str(context.exception)) def test_adjust_balance_zero_amount_fails(self): """Корректировка с нулевой суммой вызывает ValueError.""" with self.assertRaises(ValueError) as context: WalletService.adjust_balance( customer_id=self.customer.pk, amount=Decimal('0'), description='Нулевая корректировка', user=None ) self.assertIn('не может быть нулевой', str(context.exception))