""" Скрипт для тестирования защиты от циклических ссылок в категориях """ import os import django os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') django.setup() from products.models import ProductCategory from django.core.exceptions import ValidationError def test_self_reference(): """Тест 1: Попытка сделать категорию родителем самой себя""" print("\n=== Тест 1: Самоссылка ===") try: cat = ProductCategory.objects.first() if not cat: print("[FAIL] Net kategorij v baze dlya testa") return False print(f"Kategoriya: {cat.name} (id={cat.pk})") cat.parent = cat cat.save() print("[FAIL] OSHIBKA: Samossylka ne byla zablokirovana!") return False except ValidationError as e: print("[OK] USPEKH: Samossylka zablokirovana") print(f" Soobshchenie: {e.message_dict.get('parent', [''])[0]}") return True def test_simple_cycle(): """Тест 2: Попытка создать цикл A → B → A""" print("\n=== Тест 2: Простой цикл A → B → A ===") try: # Получаем две категории categories = list(ProductCategory.objects.all()[:2]) if len(categories) < 2: print("❌ Недостаточно категорий в базе (нужно минимум 2)") return False cat_a, cat_b = categories print(f"Категория A: {cat_a.name} (id={cat_a.pk})") print(f"Категория B: {cat_b.name} (id={cat_b.pk})") # Создаем связь A → B cat_a.parent = None cat_a.save() cat_b.parent = cat_a cat_b.save() print(f"Создана связь: {cat_a.name} → {cat_b.name}") # Пытаемся создать цикл: B → A (создаст цикл A → B → A) cat_a.parent = cat_b cat_a.save() print("❌ ОШИБКА: Цикл не был заблокирован!") # Откатываем изменения cat_a.parent = None cat_b.parent = None cat_a.save() cat_b.save() return False except ValidationError as e: print(f"✅ УСПЕХ: Цикл заблокирован") print(f" Сообщение: {e.message_dict.get('parent', [''])[0]}") # Откатываем изменения cat_a.parent = None cat_b.parent = None cat_a.save() cat_b.save() return True def test_multi_level_cycle(): """Тест 3: Попытка создать многоуровневый цикл A → B → C → A""" print("\n=== Тест 3: Многоуровневый цикл A → B → C → A ===") try: # Получаем три категории categories = list(ProductCategory.objects.all()[:3]) if len(categories) < 3: print("❌ Недостаточно категорий в базе (нужно минимум 3)") return False cat_a, cat_b, cat_c = categories print(f"Категория A: {cat_a.name} (id={cat_a.pk})") print(f"Категория B: {cat_b.name} (id={cat_b.pk})") print(f"Категория C: {cat_c.name} (id={cat_c.pk})") # Создаем цепочку A → B → C cat_a.parent = None cat_a.save() cat_b.parent = cat_a cat_b.save() cat_c.parent = cat_b cat_c.save() print(f"Создана цепочка: {cat_a.name} → {cat_b.name} → {cat_c.name}") # Пытаемся замкнуть цикл: A.parent = C cat_a.parent = cat_c cat_a.save() print("❌ ОШИБКА: Многоуровневый цикл не был заблокирован!") # Откатываем изменения cat_a.parent = None cat_b.parent = None cat_c.parent = None cat_a.save() cat_b.save() cat_c.save() return False except ValidationError as e: print(f"✅ УСПЕХ: Многоуровневый цикл заблокирован") print(f" Сообщение: {e.message_dict.get('parent', [''])[0]}") # Откатываем изменения cat_a.parent = None cat_b.parent = None cat_c.parent = None cat_a.save() cat_b.save() cat_c.save() return True def test_normal_operations(): """Тест 4: Нормальные операции должны работать""" print("\n=== Тест 4: Нормальные операции ===") try: categories = list(ProductCategory.objects.all()[:2]) if len(categories) < 2: print("❌ Недостаточно категорий в базе") return False cat_a, cat_b = categories # Сбрасываем родителей cat_a.parent = None cat_b.parent = None cat_a.save() cat_b.save() # Создаем нормальную иерархию A → B cat_b.parent = cat_a cat_b.save() print(f"✅ УСПЕХ: Создана нормальная иерархия {cat_a.name} → {cat_b.name}") # Откатываем cat_b.parent = None cat_b.save() return True except ValidationError as e: print(f"❌ ОШИБКА: Нормальная операция была заблокирована!") print(f" Сообщение: {e}") return False if __name__ == '__main__': print("=" * 60) print("ТЕСТИРОВАНИЕ ЗАЩИТЫ ОТ ЦИКЛИЧЕСКИХ ССЫЛОК") print("=" * 60) results = [] results.append(("Тест самоссылки", test_self_reference())) results.append(("Тест простого цикла", test_simple_cycle())) results.append(("Тест многоуровневого цикла", test_multi_level_cycle())) results.append(("Тест нормальных операций", test_normal_operations())) print("\n" + "=" * 60) print("РЕЗУЛЬТАТЫ ТЕСТИРОВАНИЯ") print("=" * 60) for name, result in results: status = "✅ ПРОЙДЕН" if result else "❌ ПРОВАЛЕН" print(f"{name}: {status}") all_passed = all(result for _, result in results) print("\n" + "=" * 60) if all_passed: print("🎉 ВСЕ ТЕСТЫ ПРОЙДЕНЫ!") else: print("⚠️ НЕКОТОРЫЕ ТЕСТЫ ПРОВАЛЕНЫ") print("=" * 60)