Files
octopus/myproject/test_category_validation.py

187 lines
6.7 KiB
Python
Raw 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.
"""
Скрипт для тестирования защиты от циклических ссылок в категориях
"""
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)