Files
octopus/myproject/customers/tests/test_wallet_service.py
Andrey Smakotin dbbac933af Добавлены тесты защиты системного клиента и рефакторинг структуры тестов
- Создан новый класс 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)
2025-12-28 00:32:45 +03:00

143 lines
5.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- 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))