Добавлены тесты защиты системного клиента и рефакторинг структуры тестов
- Создан новый класс SystemCustomerProtectionTestCase с 5 критичными тестами - Тест создания системного клиента с правильными атрибутами - Тест защиты от удаления системного клиента (ValidationError) - Тест защиты email системного клиента от изменения - Тест защиты флага is_system_customer от изменения - Тест что обычные клиенты не затронуты защитой - Исправлена логика в Customer.save(): проверка теперь использует original.is_system_customer - Добавлен импорт ValidationError из django.core.exceptions - Рефакторинг структуры тестов customers: - Разделены тесты по отдельным модулям в папке customers/tests/ - test_search_strategies.py - тесты стратегий поиска - test_system_customer.py - тесты защиты системного клиента - test_wallet_balance.py - тесты баланса кошелька - test_wallet_service.py - тесты WalletService - test_wallet_model.py - тесты модели WalletTransaction - Обновлён анализ тестов: 50 тестов (было 45), все проходят успешно - Критичная функциональность POS системы теперь покрыта тестами - Учтена tenant-система (используется TenantTestCase)
This commit is contained in:
111
myproject/customers/tests/test_wallet_balance.py
Normal file
111
myproject/customers/tests/test_wallet_balance.py
Normal file
@@ -0,0 +1,111 @@
|
||||
# -*- 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'))
|
||||
Reference in New Issue
Block a user