# -*- coding: utf-8 -*- """ Тесты для вычисления баланса кошелька. Используем TenantTestCase для корректной работы с tenant-системой. """ from decimal import Decimal from django.core.cache import cache from django_tenants.test.cases import TenantTestCase from customers.models import Customer, WalletTransaction class WalletBalanceCalculationTestCase(TenantTestCase): """Тесты вычисления баланса кошелька из транзакций.""" def setUp(self): """Создаём тестового клиента и очищаем кеш.""" self.customer = Customer.objects.create(name="Тестовый клиент") cache.clear() def tearDown(self): """Очищаем кеш после каждого теста.""" cache.clear() def test_empty_wallet_returns_zero(self): """Пустой кошелёк должен возвращать 0.""" self.assertEqual(self.customer.wallet_balance, Decimal('0')) def test_single_deposit(self): """Одно пополнение корректно учитывается.""" WalletTransaction.objects.create( customer=self.customer, signed_amount=Decimal('100.00'), transaction_type='deposit', balance_category='money' ) cache.clear() self.assertEqual(self.customer.wallet_balance, Decimal('100.00')) def test_single_spend(self): """Списание корректно учитывается (отрицательная сумма).""" # Сначала пополняем WalletTransaction.objects.create( customer=self.customer, signed_amount=Decimal('100.00'), transaction_type='deposit', balance_category='money' ) # Затем списываем WalletTransaction.objects.create( customer=self.customer, signed_amount=Decimal('-30.00'), transaction_type='spend', balance_category='money' ) cache.clear() self.assertEqual(self.customer.wallet_balance, Decimal('70.00')) def test_multiple_operations(self): """Несколько операций подряд вычисляются корректно.""" operations = [ ('deposit', Decimal('200.00')), ('spend', Decimal('-50.00')), ('deposit', Decimal('100.00')), ('spend', Decimal('-80.00')), ('adjustment', Decimal('10.00')), ] for txn_type, signed_amount in operations: WalletTransaction.objects.create( customer=self.customer, signed_amount=signed_amount, transaction_type=txn_type, balance_category='money' ) cache.clear() # 200 - 50 + 100 - 80 + 10 = 180 self.assertEqual(self.customer.wallet_balance, Decimal('180.00')) def test_amount_property_returns_absolute(self): """Property amount возвращает абсолютное значение.""" txn = WalletTransaction.objects.create( customer=self.customer, signed_amount=Decimal('-50.00'), transaction_type='spend', balance_category='money' ) self.assertEqual(txn.amount, Decimal('50.00')) def test_cache_invalidation(self): """Кеш инвалидируется методом invalidate_wallet_cache.""" # Первый вызов - баланс 0 self.assertEqual(self.customer.wallet_balance, Decimal('0')) # Добавляем транзакцию напрямую (без сервиса) WalletTransaction.objects.create( customer=self.customer, signed_amount=Decimal('100.00'), transaction_type='deposit', balance_category='money' ) # Без инвалидации кеша - всё ещё 0 (закешировано) self.assertEqual(self.customer.get_wallet_balance(use_cache=True), Decimal('0')) # После инвалидации - 100 self.customer.invalidate_wallet_cache() self.assertEqual(self.customer.wallet_balance, Decimal('100.00'))