|
@@ -0,0 +1,83 @@
|
|
|
|
+from django.core.management import call_command
|
|
|
|
+from django.test import TestCase
|
|
|
|
+from django.utils.six import StringIO
|
|
|
|
+
|
|
|
|
+from misago.categories.management.commands import fixcategoriestree
|
|
|
|
+from misago.categories.models import Category
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def run_command():
|
|
|
|
+ """Run the management command"""
|
|
|
|
+ command = fixcategoriestree.Command()
|
|
|
|
+ out = StringIO()
|
|
|
|
+ call_command(command, stdout=out)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class FixCategoriesTreeTests(TestCase):
|
|
|
|
+ """
|
|
|
|
+ The purpose is the verify that the management command
|
|
|
|
+ fixes the lft/rght values of the thread category tree.
|
|
|
|
+ """
|
|
|
|
+ def setUp(self):
|
|
|
|
+ Category.objects.create(name='Test', slug='test', parent=Category.objects.root_category())
|
|
|
|
+ self.fetch_categories()
|
|
|
|
+
|
|
|
|
+ def assertValidTree(self, expected_tree):
|
|
|
|
+ root = Category.objects.root_category()
|
|
|
|
+ queryset = Category.objects.filter(tree_id=root.tree_id).order_by('lft')
|
|
|
|
+
|
|
|
|
+ current_tree = []
|
|
|
|
+ for category in queryset:
|
|
|
|
+ current_tree.append((category, category.get_level(), category.lft, category.rght))
|
|
|
|
+
|
|
|
|
+ for i, category in enumerate(expected_tree):
|
|
|
|
+ _category = current_tree[i]
|
|
|
|
+ if category[0] != _category[0]:
|
|
|
|
+ self.fail(('expected category at index #%s to be %s, '
|
|
|
|
+ 'found %s instead') % (i, category[0], _category[0]))
|
|
|
|
+ if category[1] != _category[1]:
|
|
|
|
+ self.fail(('expected level at index #%s to be %s, '
|
|
|
|
+ 'found %s instead') % (i, category[1], _category[1]))
|
|
|
|
+ if category[2] != _category[2]:
|
|
|
|
+ self.fail(('expected lft at index #%s to be %s, '
|
|
|
|
+ 'found %s instead') % (i, category[2], _category[2]))
|
|
|
|
+ if category[3] != _category[3]:
|
|
|
|
+ self.fail(('expected lft at index #%s to be %s, '
|
|
|
|
+ 'found %s instead') % (i, category[3], _category[3]))
|
|
|
|
+
|
|
|
|
+ def fetch_categories(self):
|
|
|
|
+ """gets a fresh version from the database"""
|
|
|
|
+ self.root = Category.objects.root_category()
|
|
|
|
+ self.first_category = Category.objects.get(slug='first-category')
|
|
|
|
+ self.test_category = Category.objects.get(slug='test')
|
|
|
|
+
|
|
|
|
+ def test_fix_categories_tree_unaffected(self):
|
|
|
|
+ """Command should not affect a healthy three"""
|
|
|
|
+ tree_id = self.root.tree_id
|
|
|
|
+ run_command()
|
|
|
|
+
|
|
|
|
+ self.fetch_categories()
|
|
|
|
+
|
|
|
|
+ self.assertValidTree([
|
|
|
|
+ (self.root, 0, 1, 6),
|
|
|
|
+ (self.first_category, 1, 2, 3),
|
|
|
|
+ (self.test_category, 1, 4, 5),
|
|
|
|
+ ])
|
|
|
|
+
|
|
|
|
+ self.assertEqual(self.root.tree_id, tree_id, msg="tree_id changed by command")
|
|
|
|
+
|
|
|
|
+ def test_fix_categories_tree_affected(self):
|
|
|
|
+ """Command should fix a broken tree"""
|
|
|
|
+ # Root node with too narrow lft/rght range
|
|
|
|
+ Category.objects.filter(id=self.root.id).update(lft=1, rght=4)
|
|
|
|
+ # Make conflicting/identical lft/rght range
|
|
|
|
+ Category.objects.filter(id=self.test_category.id).update(lft=2, rght=3)
|
|
|
|
+
|
|
|
|
+ run_command()
|
|
|
|
+ self.fetch_categories()
|
|
|
|
+
|
|
|
|
+ self.assertValidTree([
|
|
|
|
+ (self.root, 0, 1, 6),
|
|
|
|
+ (self.test_category, 1, 2, 3),
|
|
|
|
+ (self.first_category, 1, 4, 5),
|
|
|
|
+ ])
|