From 8c8c5d396ec422bac84221a3c8e98a58aed591b6 Mon Sep 17 00:00:00 2001 From: adilhussain540 Date: Thu, 7 Dec 2023 12:44:40 +0500 Subject: [PATCH 1/4] Introduce BaseQueryset to make sure cache gets deleted after bulk operations --- cookie_consent/models.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cookie_consent/models.py b/cookie_consent/models.py index c099328..c454ba2 100644 --- a/cookie_consent/models.py +++ b/cookie_consent/models.py @@ -29,6 +29,16 @@ class CookieGroupDict(TypedDict): # version: str +class BaseQueryset(models.query.QuerySet): + def delete(self): + super().delete() + delete_cache() + + def update(self, *args, **kwargs): + super().update(*args, **kwargs) + delete_cache() + + class CookieGroup(models.Model): varname = models.CharField( _("Variable name"), max_length=32, validators=[validate_cookie_name] @@ -48,6 +58,8 @@ class CookieGroup(models.Model): ordering = models.IntegerField(_("Ordering"), default=0) created = models.DateTimeField(_("Created"), auto_now_add=True, blank=True) + objects = BaseQueryset.as_manager() + class Meta: verbose_name = _("Cookie Group") verbose_name_plural = _("Cookie Groups") @@ -92,6 +104,8 @@ class Cookie(models.Model): domain = models.CharField(_("Domain"), max_length=250, blank=True) created = models.DateTimeField(_("Created"), auto_now_add=True, blank=True) + objects = BaseQueryset.as_manager() + class Meta: verbose_name = _("Cookie") verbose_name_plural = _("Cookies") From e3d47817866b01c85fbe59501e66a332a81aed2b Mon Sep 17 00:00:00 2001 From: adilhussain540 Date: Thu, 7 Dec 2023 12:45:24 +0500 Subject: [PATCH 2/4] Test bulk operations in models --- tests/test_models.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/test_models.py b/tests/test_models.py index 3637708..52bd30e 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +from unittest import mock + from django.core.exceptions import ValidationError from django.test import TestCase @@ -24,6 +26,18 @@ def test_get_version(self): self.cookie_group.get_version(), self.cookie.created.isoformat() ) + @mock.patch("cookie_consent.models.delete_cache") + def test_bulk_delete(self, mock_delete_cache): + CookieGroup.objects.filter(id=self.cookie_group.id).delete() + + self.assertEqual(mock_delete_cache.call_count, 1) + + @mock.patch("cookie_consent.models.delete_cache") + def test_bulk_update(self, mock_delete_cache): + CookieGroup.objects.filter(id=self.cookie_group.id).update(name="Optional2") + + self.assertEqual(mock_delete_cache.call_count, 1) + class CookieTest(TestCase): def setUp(self): @@ -42,6 +56,18 @@ def setUp(self): def test_varname(self): self.assertEqual(self.cookie.varname, "optional=foo:.example.com") + @mock.patch("cookie_consent.models.delete_cache") + def test_bulk_delete(self, mock_delete_cache): + Cookie.objects.filter(id=self.cookie.id).delete() + + self.assertEqual(mock_delete_cache.call_count, 1) + + @mock.patch("cookie_consent.models.delete_cache") + def test_bulk_update(self, mock_delete_cache): + Cookie.objects.filter(id=self.cookie.id).update(name="foo2") + + self.assertEqual(mock_delete_cache.call_count, 1) + class ValidateCookieNameTest(TestCase): def test_valid(self): From 8b48d3b7e51c01bb5530f378057f28b140f0a3ac Mon Sep 17 00:00:00 2001 From: adilhussain540 Date: Thu, 7 Dec 2023 14:25:30 +0500 Subject: [PATCH 3/4] Fix return values inside the BaseQueryset --- cookie_consent/models.py | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/cookie_consent/models.py b/cookie_consent/models.py index c454ba2..19f2483 100644 --- a/cookie_consent/models.py +++ b/cookie_consent/models.py @@ -19,6 +19,15 @@ ) +def clear_cache_after(func): + def wrapper(*args, **kwargs): + return_value = func(*args, **kwargs) + delete_cache() + return return_value + + return wrapper + + class CookieGroupDict(TypedDict): varname: str name: str @@ -30,13 +39,13 @@ class CookieGroupDict(TypedDict): class BaseQueryset(models.query.QuerySet): + @clear_cache_after def delete(self): - super().delete() - delete_cache() + return super().delete() - def update(self, *args, **kwargs): - super().update(*args, **kwargs) - delete_cache() + @clear_cache_after + def update(self, **kwargs): + return super().update(**kwargs) class CookieGroup(models.Model): @@ -74,13 +83,13 @@ def get_version(self) -> str: except IndexError: return "" + @clear_cache_after def delete(self, *args, **kwargs): super(CookieGroup, self).delete(*args, **kwargs) - delete_cache() + @clear_cache_after def save(self, *args, **kwargs): super(CookieGroup, self).save(*args, **kwargs) - delete_cache() def for_json(self) -> CookieGroupDict: return { @@ -121,13 +130,13 @@ def varname(self): def get_version(self): return self.created.isoformat() + @clear_cache_after def delete(self, *args, **kwargs): super(Cookie, self).delete(*args, **kwargs) - delete_cache() + @clear_cache_after def save(self, *args, **kwargs): super(Cookie, self).save(*args, **kwargs) - delete_cache() ACTION_ACCEPTED = 1 From 3d5351289237128c08c14564714e7e09f14b974f Mon Sep 17 00:00:00 2001 From: adilhussain540 Date: Thu, 7 Dec 2023 14:26:05 +0500 Subject: [PATCH 4/4] Update tests to assert return values of bulk actions --- tests/test_models.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tests/test_models.py b/tests/test_models.py index 52bd30e..3d2b0b0 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -28,14 +28,21 @@ def test_get_version(self): @mock.patch("cookie_consent.models.delete_cache") def test_bulk_delete(self, mock_delete_cache): - CookieGroup.objects.filter(id=self.cookie_group.id).delete() + deleted_objs_count, _ = CookieGroup.objects.filter( + id=self.cookie_group.id + ).delete() + # Deleting a CookieGroup also deletes the associated Cookies, that's why we expect a count of 2. + self.assertEqual(deleted_objs_count, 2) self.assertEqual(mock_delete_cache.call_count, 1) @mock.patch("cookie_consent.models.delete_cache") def test_bulk_update(self, mock_delete_cache): - CookieGroup.objects.filter(id=self.cookie_group.id).update(name="Optional2") + updated_objs_count = CookieGroup.objects.filter(id=self.cookie_group.id).update( + name="Optional2" + ) + self.assertEqual(updated_objs_count, 1) self.assertEqual(mock_delete_cache.call_count, 1) @@ -58,14 +65,18 @@ def test_varname(self): @mock.patch("cookie_consent.models.delete_cache") def test_bulk_delete(self, mock_delete_cache): - Cookie.objects.filter(id=self.cookie.id).delete() + deleted_objs_count, _ = Cookie.objects.filter(id=self.cookie.id).delete() + self.assertEqual(deleted_objs_count, 1) self.assertEqual(mock_delete_cache.call_count, 1) @mock.patch("cookie_consent.models.delete_cache") def test_bulk_update(self, mock_delete_cache): - Cookie.objects.filter(id=self.cookie.id).update(name="foo2") + updated_objs_count = Cookie.objects.filter(id=self.cookie.id).update( + name="foo2" + ) + self.assertEqual(updated_objs_count, 1) self.assertEqual(mock_delete_cache.call_count, 1)