Skip to content

Commit

Permalink
Cache not invalidated for query using Case annotation for ManyToManyF…
Browse files Browse the repository at this point in the history
…ield
  • Loading branch information
sdolemelipone committed Jul 10, 2024
1 parent 60101f7 commit cc444ae
Showing 1 changed file with 42 additions and 0 deletions.
42 changes: 42 additions & 0 deletions cachalot/tests/test_case_annotation_bug.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from django.contrib.auth.models import Permission
from django.db.models import Case, When, BooleanField
from django.test import TransactionTestCase

from cachalot.tests.models import TestChild
from cachalot.api import invalidate


class TestAnnotationFilteringBug(TransactionTestCase):
databases = ["default"]
def get_child_permissions(self, child):
# Dumb query which returns all Permission objects in a ManyToMany relationship
perms = child.permissions.all().values_list("pk", flat=True)
return Permission.objects.annotate(
is_related=Case(When(pk__in=perms, then=True), default=False,
output_field=BooleanField())
).filter(is_related=True)

def test_result_is_incorrectly_cached(self):
child = TestChild.objects.create()
permission_A, permission_B = Permission.objects.all()[:2]
child.permissions.add(permission_A)
self.assertEqual(len(self.get_child_permissions(child)), 1)
self.assertSequenceEqual(self.get_child_permissions(child), [permission_A])
child.permissions.add(permission_B)
self.assertEqual(len(self.get_child_permissions(child)), 2) # Fails
self.assertSequenceEqual(
self.get_child_permissions(child), [permission_A, permission_B]
)

def test_result_is_correct_if_cache_cleared(self):
child = TestChild.objects.create()
permission_A, permission_B = Permission.objects.all()[:2]
child.permissions.add(permission_A)
self.assertEqual(len(self.get_child_permissions(child)), 1)
self.assertSequenceEqual(self.get_child_permissions(child), [permission_A])
child.permissions.add(permission_B)
invalidate(db_alias="default")
self.assertEqual(len(self.get_child_permissions(child)), 2) # Passes
self.assertSequenceEqual(
self.get_child_permissions(child), [permission_A, permission_B]
)

0 comments on commit cc444ae

Please sign in to comment.