0
0
mirror of https://github.com/wagtail/wagtail.git synced 2024-11-29 17:36:49 +01:00

Add checks to ensure LockableMixin is applied before RevisionMixin

This commit is contained in:
Sage Abdullah 2022-12-12 10:39:54 +00:00
parent 8dcc292d26
commit e1041b242d
No known key found for this signature in database
GPG Key ID: EB1A33CC51CC0217
2 changed files with 80 additions and 0 deletions

View File

@ -801,6 +801,32 @@ class LockableMixin(models.Model):
class Meta:
abstract = True
@classmethod
def check(cls, **kwargs):
return [
*super().check(**kwargs),
*cls._check_revision_mixin(),
]
@classmethod
def _check_revision_mixin(cls):
mro = cls.mro()
error = checks.Error(
"LockableMixin must be applied before RevisionMixin.",
hint="Move LockableMixin in the model's base classes before RevisionMixin.",
obj=cls,
id="wagtailcore.E005",
)
try:
if mro.index(RevisionMixin) < mro.index(LockableMixin):
return [error]
except ValueError:
# LockableMixin can be used without RevisionMixin.
return []
return []
def with_content_json(self, content):
"""
Similar to :meth:`RevisionMixin.with_content_json`,

View File

@ -0,0 +1,54 @@
from django.apps import apps
from django.core import checks
from django.db import models
from django.test import TestCase
from wagtail.models import LockableMixin, RevisionMixin
class TestLockableMixin(TestCase):
def tearDown(self):
# Unregister the models from the overall model registry
# so that it doesn't break tests elsewhere.
# We can probably replace this with Django's @isolate_apps decorator.
for package in ("wagtailcore", "wagtail.tests"):
try:
for model in (
"lockablewithoutrevisionmodel",
"lockableincorrectrevisionmodel",
"lockablewithrevisionmodel",
):
del apps.all_models[package][model]
except KeyError:
pass
apps.clear_cache()
def test_lockable_mixin_only(self):
class LockableWithoutRevisionModel(LockableMixin, models.Model):
pass
self.assertEqual(LockableWithoutRevisionModel.check(), [])
def test_incorrect_revision_mixin_order(self):
class LockableIncorrectRevisionModel(
RevisionMixin, LockableMixin, models.Model
):
pass
self.assertEqual(
LockableIncorrectRevisionModel.check(),
[
checks.Error(
"LockableMixin must be applied before RevisionMixin.",
hint="Move LockableMixin in the model's base classes before RevisionMixin.",
obj=LockableIncorrectRevisionModel,
id="wagtailcore.E005",
)
],
)
def test_correct_revision_mixin_order(self):
class LockableWithRevisionModel(LockableMixin, RevisionMixin, models.Model):
pass
self.assertEqual(LockableWithRevisionModel.check(), [])