Initial commit: Django inventory system
This commit is contained in:
186
myproject/test_category_validation.py
Normal file
186
myproject/test_category_validation.py
Normal file
@@ -0,0 +1,186 @@
|
||||
"""
|
||||
Скрипт для тестирования защиты от циклических ссылок в категориях
|
||||
"""
|
||||
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)
|
||||
Reference in New Issue
Block a user