# -*- coding: utf-8 -*- """ Тесты защиты системного клиента от изменений и удаления. Системный клиент используется для анонимных продаж в POS системе и должен быть защищён от случайного изменения или удаления. Используем TenantTestCase для корректной работы с tenant-системой. """ from django.core.exceptions import ValidationError from django_tenants.test.cases import TenantTestCase from customers.models import Customer class SystemCustomerProtectionTestCase(TenantTestCase): """ Тесты защиты системного клиента от изменений и удаления. Системный клиент используется для анонимных продаж в POS системе и должен быть защищён от случайного изменения или удаления. """ def setUp(self): """Создаём системного клиента для тестов.""" self.system_customer, created = Customer.get_or_create_system_customer() self.regular_customer = Customer.objects.create( name="Обычный клиент", email="regular@test.com" ) def test_get_or_create_system_customer_creates_with_correct_attributes(self): """ Метод get_or_create_system_customer() создаёт клиента с правильными атрибутами. Проверяем: - Фиксированный email: system@pos.customer - Флаг is_system_customer = True - Правильное имя и заметки """ # Удаляем существующего системного клиента для чистоты теста Customer.objects.filter(is_system_customer=True).delete() # Создаём через метод класса customer, created = Customer.get_or_create_system_customer() # Проверяем, что клиент действительно создан self.assertTrue(created, "Системный клиент должен быть создан") # Проверяем атрибуты self.assertEqual(customer.email, "system@pos.customer") self.assertTrue(customer.is_system_customer) self.assertEqual(customer.name, "АНОНИМНЫЙ ПОКУПАТЕЛЬ (POS)") self.assertIn("SYSTEM_CUSTOMER", customer.notes) # Проверяем идемпотентность - повторный вызов возвращает того же клиента customer2, created2 = Customer.get_or_create_system_customer() self.assertFalse(created2, "Системный клиент не должен создаваться повторно") self.assertEqual(customer.pk, customer2.pk, "Должен вернуться тот же клиент") def test_system_customer_cannot_be_deleted(self): """ Системный клиент защищён от удаления через метод delete(). При попытке удаления должен подниматься ValidationError. Это критично для работы POS системы. """ with self.assertRaises(ValidationError) as context: self.system_customer.delete() self.assertIn("Нельзя удалить системного клиента", str(context.exception)) # Проверяем, что клиент действительно не удалён self.assertTrue( Customer.objects.filter(pk=self.system_customer.pk).exists(), "Системный клиент не должен быть удалён" ) def test_system_customer_email_cannot_be_changed(self): """ Email системного клиента защищён от изменения. Фиксированный email "system@pos.customer" используется для поиска системного клиента в POS системе. Изменение приведёт к сбоям. """ original_email = self.system_customer.email # Пытаемся изменить email self.system_customer.email = "hacker@evil.com" with self.assertRaises(ValidationError) as context: self.system_customer.save() self.assertIn("Нельзя изменить email системного клиента", str(context.exception)) # Проверяем, что email остался прежним в БД self.system_customer.refresh_from_db() self.assertEqual(self.system_customer.email, original_email) def test_system_customer_flag_cannot_be_removed(self): """ Флаг is_system_customer защищён от изменения. Нельзя "превратить" системного клиента в обычного, это нарушит логику POS системы. """ # Пытаемся снять флаг системного клиента self.system_customer.is_system_customer = False with self.assertRaises(ValidationError) as context: self.system_customer.save() self.assertIn("Нельзя изменить флаг системного клиента", str(context.exception)) # Проверяем, что флаг остался True в БД self.system_customer.refresh_from_db() self.assertTrue(self.system_customer.is_system_customer) def test_regular_customer_can_be_deleted_normally(self): """ Обычный клиент (не системный) может быть удалён без ограничений. Защита применяется ТОЛЬКО к системному клиенту. Это гарантирует, что мы не сломали обычный функционал удаления. """ customer_pk = self.regular_customer.pk # Удаление должно пройти успешно self.regular_customer.delete() # Проверяем, что клиент действительно удалён self.assertFalse( Customer.objects.filter(pk=customer_pk).exists(), "Обычный клиент должен быть удалён" )