mirror of
https://github.com/jazzband/django-constance.git
synced 2026-03-16 22:40:24 +00:00
Add a Django system check... (#326)
* Add a Django system check that CONFIG_FIELDSETS accounts for all of CONFIG * Fix test (don't actually modify values when submitting form) and restore python2 compatibility
This commit is contained in:
parent
d495f1b3bf
commit
2948dff3cc
5 changed files with 131 additions and 5 deletions
|
|
@ -1,4 +1,5 @@
|
|||
from django.utils.functional import LazyObject
|
||||
from . import checks
|
||||
|
||||
__version__ = '2.4.0'
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ from django.utils.module_loading import import_string
|
|||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from . import LazyConfig, settings
|
||||
from .checks import get_inconsistent_fieldnames
|
||||
|
||||
|
||||
config = LazyConfig()
|
||||
|
|
@ -163,11 +164,7 @@ class ConstanceForm(forms.Form):
|
|||
if not settings.CONFIG_FIELDSETS:
|
||||
return cleaned_data
|
||||
|
||||
field_name_list = []
|
||||
for fieldset_title, fields_list in settings.CONFIG_FIELDSETS.items():
|
||||
for field_name in fields_list:
|
||||
field_name_list.append(field_name)
|
||||
if field_name_list and set(set(settings.CONFIG.keys()) - set(field_name_list)):
|
||||
if get_inconsistent_fieldnames():
|
||||
raise forms.ValidationError(_('CONSTANCE_CONFIG_FIELDSETS is missing '
|
||||
'field(s) that exists in CONSTANCE_CONFIG.'))
|
||||
|
||||
|
|
|
|||
42
constance/checks.py
Normal file
42
constance/checks.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
from django.core import checks
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from . import settings
|
||||
|
||||
|
||||
@checks.register("constance")
|
||||
def check_fieldsets(*args, **kwargs):
|
||||
"""
|
||||
A Django system check to make sure that, if defined, CONFIG_FIELDSETS accounts for
|
||||
every entry in settings.CONFIG.
|
||||
"""
|
||||
if hasattr(settings, "CONFIG_FIELDSETS") and settings.CONFIG_FIELDSETS:
|
||||
inconsistent_fieldnames = get_inconsistent_fieldnames()
|
||||
if inconsistent_fieldnames:
|
||||
return [
|
||||
checks.Warning(
|
||||
_(
|
||||
"CONSTANCE_CONFIG_FIELDSETS is missing "
|
||||
"field(s) that exists in CONSTANCE_CONFIG."
|
||||
),
|
||||
hint=", ".join(sorted(inconsistent_fieldnames)),
|
||||
obj="settings.CONSTANCE_CONFIG",
|
||||
id="constance.E001",
|
||||
)
|
||||
]
|
||||
return []
|
||||
|
||||
|
||||
def get_inconsistent_fieldnames():
|
||||
"""
|
||||
Returns a set of keys from settings.CONFIG that are not accounted for in
|
||||
settings.CONFIG_FIELDSETS.
|
||||
If there are no fieldnames in settings.CONFIG_FIELDSETS, returns an empty set.
|
||||
"""
|
||||
field_name_list = []
|
||||
for fieldset_title, fields_list in settings.CONFIG_FIELDSETS.items():
|
||||
for field_name in fields_list:
|
||||
field_name_list.append(field_name)
|
||||
if not field_name_list:
|
||||
return {}
|
||||
return set(set(settings.CONFIG.keys()) - set(field_name_list))
|
||||
|
|
@ -3,6 +3,7 @@ from django.contrib import admin
|
|||
from django.contrib.auth.models import User, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.template.defaultfilters import linebreaksbr
|
||||
from django.test import TestCase, RequestFactory
|
||||
from django.utils import six
|
||||
|
|
@ -74,6 +75,46 @@ class TestAdmin(TestCase):
|
|||
self.assertContains(response, '<h2>Numbers</h2>')
|
||||
self.assertContains(response, '<h2>Text</h2>')
|
||||
|
||||
@mock.patch('constance.settings.CONFIG_FIELDSETS', {
|
||||
'FieldSetOne': ('INT_VALUE',)
|
||||
})
|
||||
@mock.patch('constance.settings.CONFIG', {
|
||||
'INT_VALUE': (1, 'some int'),
|
||||
})
|
||||
@mock.patch('constance.settings.IGNORE_ADMIN_VERSION_CHECK', True)
|
||||
def test_submit(self):
|
||||
"""
|
||||
Test that submitting the admin page results in an http redirect when
|
||||
everything is in order.
|
||||
"""
|
||||
self.client.login(username='admin', password='nimda')
|
||||
request = self.rf.post('/admin/constance/config/', data={
|
||||
"INT_VALUE": settings.CONFIG['INT_VALUE'][0],
|
||||
"version": "123",
|
||||
})
|
||||
request.user = self.superuser
|
||||
request._dont_enforce_csrf_checks = True
|
||||
with mock.patch("constance.admin.ConstanceForm.save"):
|
||||
with mock.patch("django.contrib.messages.add_message"):
|
||||
response = self.options.changelist_view(request, {})
|
||||
self.assertIsInstance(response, HttpResponseRedirect)
|
||||
|
||||
@mock.patch('constance.settings.CONFIG_FIELDSETS', {
|
||||
'Numbers': ('LONG_VALUE', 'INT_VALUE',),
|
||||
'Text': ('STRING_VALUE', 'UNICODE_VALUE'),
|
||||
})
|
||||
def test_inconsistent_fieldset_submit(self):
|
||||
"""
|
||||
Test that the admin page warns users if the CONFIG_FIELDSETS setting
|
||||
doesn't account for every field in CONFIG.
|
||||
"""
|
||||
self.client.login(username='admin', password='nimda')
|
||||
request = self.rf.post('/admin/constance/config/', data=None)
|
||||
request.user = self.superuser
|
||||
request._dont_enforce_csrf_checks = True
|
||||
response = self.options.changelist_view(request, {})
|
||||
self.assertContains(response, 'is missing field(s)')
|
||||
|
||||
@mock.patch('constance.settings.CONFIG_FIELDSETS', {
|
||||
'Numbers': ('LONG_VALUE', 'INT_VALUE',),
|
||||
})
|
||||
|
|
|
|||
45
tests/test_checks.py
Normal file
45
tests/test_checks.py
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import datetime
|
||||
from decimal import Decimal
|
||||
import mock
|
||||
|
||||
from constance.admin import get_values
|
||||
from constance.checks import check_fieldsets, get_inconsistent_fieldnames
|
||||
from constance.management.commands.constance import _set_constance_value
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.test import TestCase
|
||||
from constance import settings
|
||||
|
||||
|
||||
class ChecksTestCase(TestCase):
|
||||
@mock.patch("constance.settings.CONFIG_FIELDSETS", {"Set1": settings.CONFIG.keys()})
|
||||
def test_get_inconsistent_fieldnames_none(self):
|
||||
"""
|
||||
Test that get_inconsistent_fieldnames returns an empty set and no checks fail
|
||||
if CONFIG_FIELDSETS accounts for every key in settings.CONFIG.
|
||||
"""
|
||||
self.assertFalse(get_inconsistent_fieldnames())
|
||||
self.assertEqual(0, len(check_fieldsets()))
|
||||
|
||||
@mock.patch(
|
||||
"constance.settings.CONFIG_FIELDSETS",
|
||||
{"Set1": list(settings.CONFIG.keys())[:-1]},
|
||||
)
|
||||
def test_get_inconsistent_fieldnames_one(self):
|
||||
"""
|
||||
Test that get_inconsistent_fieldnames returns a set and the check fails
|
||||
if CONFIG_FIELDSETS does not account for every key in settings.CONFIG.
|
||||
"""
|
||||
self.assertTrue(get_inconsistent_fieldnames())
|
||||
self.assertEqual(1, len(check_fieldsets()))
|
||||
|
||||
@mock.patch(
|
||||
"constance.settings.CONFIG_FIELDSETS", {}
|
||||
)
|
||||
def test_check_fieldsets(self):
|
||||
"""
|
||||
check_fieldsets should not output warning if CONFIG_FIELDSETS is not defined.
|
||||
"""
|
||||
del settings.CONFIG_FIELDSETS
|
||||
self.assertEqual(0, len(check_fieldsets()))
|
||||
Loading…
Reference in a new issue