test_fixcategoriestree.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. from io import StringIO
  2. from django.core.management import call_command
  3. from django.test import TestCase
  4. from ...acl import ACL_CACHE
  5. from ...cache.test import assert_invalidates_cache
  6. from ..management.commands import fixcategoriestree
  7. from ..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(
  20. name="Test", slug="test", parent=Category.objects.root_category()
  21. )
  22. self.fetch_categories()
  23. def assertValidTree(self, expected_tree):
  24. root = Category.objects.root_category()
  25. queryset = Category.objects.filter(tree_id=root.tree_id).order_by("lft")
  26. current_tree = []
  27. for category in queryset:
  28. current_tree.append(
  29. (category, category.get_level(), category.lft, category.rght)
  30. )
  31. for i, category in enumerate(expected_tree):
  32. _category = current_tree[i]
  33. if category[0] != _category[0]:
  34. self.fail(
  35. ("expected category at index #%s to be %s, " "found %s instead")
  36. % (i, category[0], _category[0])
  37. )
  38. if category[1] != _category[1]:
  39. self.fail(
  40. ("expected level at index #%s to be %s, " "found %s instead")
  41. % (i, category[1], _category[1])
  42. )
  43. if category[2] != _category[2]:
  44. self.fail(
  45. ("expected lft at index #%s to be %s, " "found %s instead")
  46. % (i, category[2], _category[2])
  47. )
  48. if category[3] != _category[3]:
  49. self.fail(
  50. ("expected lft at index #%s to be %s, " "found %s instead")
  51. % (i, category[3], _category[3])
  52. )
  53. def fetch_categories(self):
  54. """gets a fresh version from the database"""
  55. self.root = Category.objects.root_category()
  56. self.first_category = Category.objects.get(slug="first-category")
  57. self.test_category = Category.objects.get(slug="test")
  58. def test_fix_categories_tree_unaffected(self):
  59. """Command should not affect a healthy three"""
  60. tree_id = self.root.tree_id
  61. run_command()
  62. self.fetch_categories()
  63. self.assertValidTree(
  64. [
  65. (self.root, 0, 1, 6),
  66. (self.first_category, 1, 2, 3),
  67. (self.test_category, 1, 4, 5),
  68. ]
  69. )
  70. self.assertEqual(self.root.tree_id, tree_id, msg="tree_id changed by command")
  71. def test_fix_categories_tree_affected(self):
  72. """Command should fix a broken tree"""
  73. # Root node with too narrow lft/rght range
  74. Category.objects.filter(id=self.root.id).update(lft=1, rght=4)
  75. # Make conflicting/identical lft/rght range
  76. Category.objects.filter(id=self.test_category.id).update(lft=2, rght=3)
  77. run_command()
  78. self.fetch_categories()
  79. self.assertValidTree(
  80. [
  81. (self.root, 0, 1, 6),
  82. (self.test_category, 1, 2, 3),
  83. (self.first_category, 1, 4, 5),
  84. ]
  85. )
  86. def test_fixing_categories_tree_invalidates_acl_cache(self):
  87. with assert_invalidates_cache(ACL_CACHE):
  88. run_command()