test_fixcategoriestree.py 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. from io import StringIO
  2. from django.core.management import call_command
  3. from django.test import TestCase
  4. from misago.acl import ACL_CACHE
  5. from misago.cache.test import assert_invalidates_cache
  6. from misago.categories.management.commands import fixcategoriestree
  7. from misago.categories.models import Category
  8. def run_command():
  9. """Run the management command"""
  10. command = fixcategoriestree.Command()
  11. out = StringIO()
  12. call_command(command, stdout=out)
  13. class FixCategoriesTreeTests(TestCase):
  14. """
  15. The purpose is the verify that the management command
  16. fixes the lft/rght values of the thread category tree.
  17. """
  18. def setUp(self):
  19. Category.objects.create(name='Test', slug='test', parent=Category.objects.root_category())
  20. self.fetch_categories()
  21. def assertValidTree(self, expected_tree):
  22. root = Category.objects.root_category()
  23. queryset = Category.objects.filter(tree_id=root.tree_id).order_by('lft')
  24. current_tree = []
  25. for category in queryset:
  26. current_tree.append((category, category.get_level(), category.lft, category.rght))
  27. for i, category in enumerate(expected_tree):
  28. _category = current_tree[i]
  29. if category[0] != _category[0]:
  30. self.fail(('expected category at index #%s to be %s, '
  31. 'found %s instead') % (i, category[0], _category[0]))
  32. if category[1] != _category[1]:
  33. self.fail(('expected level at index #%s to be %s, '
  34. 'found %s instead') % (i, category[1], _category[1]))
  35. if category[2] != _category[2]:
  36. self.fail(('expected lft at index #%s to be %s, '
  37. 'found %s instead') % (i, category[2], _category[2]))
  38. if category[3] != _category[3]:
  39. self.fail(('expected lft at index #%s to be %s, '
  40. 'found %s instead') % (i, category[3], _category[3]))
  41. def fetch_categories(self):
  42. """gets a fresh version from the database"""
  43. self.root = Category.objects.root_category()
  44. self.first_category = Category.objects.get(slug='first-category')
  45. self.test_category = Category.objects.get(slug='test')
  46. def test_fix_categories_tree_unaffected(self):
  47. """Command should not affect a healthy three"""
  48. tree_id = self.root.tree_id
  49. run_command()
  50. self.fetch_categories()
  51. self.assertValidTree([
  52. (self.root, 0, 1, 6),
  53. (self.first_category, 1, 2, 3),
  54. (self.test_category, 1, 4, 5),
  55. ])
  56. self.assertEqual(self.root.tree_id, tree_id, msg="tree_id changed by command")
  57. def test_fix_categories_tree_affected(self):
  58. """Command should fix a broken tree"""
  59. # Root node with too narrow lft/rght range
  60. Category.objects.filter(id=self.root.id).update(lft=1, rght=4)
  61. # Make conflicting/identical lft/rght range
  62. Category.objects.filter(id=self.test_category.id).update(lft=2, rght=3)
  63. run_command()
  64. self.fetch_categories()
  65. self.assertValidTree([
  66. (self.root, 0, 1, 6),
  67. (self.test_category, 1, 2, 3),
  68. (self.first_category, 1, 4, 5),
  69. ])
  70. def test_fixing_categories_tree_invalidates_acl_cache(self):
  71. with assert_invalidates_cache(ACL_CACHE):
  72. run_command()