Skip to content

Commit ac9844c

Browse files
committed
refs #134 -- check callback configuration at startup/app loading
1 parent 3a09712 commit ac9844c

File tree

4 files changed

+109
-2
lines changed

4 files changed

+109
-2
lines changed

demo/tests/test_post_save_callbacks.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
from __future__ import unicode_literals
33

44
from copy import deepcopy
5+
from django.core.exceptions import ImproperlyConfigured
56
from django.core.urlresolvers import reverse
6-
from django.test import override_settings
7+
from django.conf import settings
8+
from django.test import TestCase, override_settings
79

810
from rest_framework.test import APITestCase
911

1012
from formidable.models import Formidable
13+
from formidable.views import check_callback_configuration
1114

1215
from . import form_data, form_data_items
1316

@@ -173,3 +176,60 @@ def test_update_callback_is_non_existent(self):
173176
)
174177
self.assertEqual(res.status_code, 200)
175178
self.assertEqual(logger_error.call_count, 1)
179+
180+
181+
class ConfigurationLoadingTestCases(TestCase):
182+
183+
@override_settings()
184+
def test_all_deleted(self):
185+
del settings.FORMIDABLE_POST_UPDATE_CALLBACK_SUCCESS
186+
del settings.FORMIDABLE_POST_UPDATE_CALLBACK_FAIL
187+
del settings.FORMIDABLE_POST_CREATE_CALLBACK_SUCCESS
188+
del settings.FORMIDABLE_POST_CREATE_CALLBACK_FAIL
189+
self.assertTrue(check_callback_configuration())
190+
191+
@override_settings(
192+
FORMIDABLE_POST_UPDATE_CALLBACK_SUCCESS=None,
193+
FORMIDABLE_POST_UPDATE_CALLBACK_FAIL=None,
194+
FORMIDABLE_POST_CREATE_CALLBACK_SUCCESS=None,
195+
FORMIDABLE_POST_CREATE_CALLBACK_FAIL=None
196+
)
197+
def test_all_none(self):
198+
self.assertTrue(check_callback_configuration())
199+
200+
@override_settings(
201+
FORMIDABLE_POST_UPDATE_CALLBACK_SUCCESS='',
202+
FORMIDABLE_POST_UPDATE_CALLBACK_FAIL='',
203+
FORMIDABLE_POST_CREATE_CALLBACK_SUCCESS='',
204+
FORMIDABLE_POST_CREATE_CALLBACK_FAIL=''
205+
)
206+
def test_all_empty(self):
207+
self.assertTrue(check_callback_configuration())
208+
209+
@override_settings(
210+
FORMIDABLE_POST_UPDATE_CALLBACK_SUCCESS='non.existing',
211+
)
212+
def test_update_success_unknown(self):
213+
with self.assertRaises(ImproperlyConfigured):
214+
check_callback_configuration()
215+
216+
@override_settings(
217+
FORMIDABLE_POST_UPDATE_CALLBACK_FAIL='non.existing',
218+
)
219+
def test_update_fail_unknown(self):
220+
with self.assertRaises(ImproperlyConfigured):
221+
check_callback_configuration()
222+
223+
@override_settings(
224+
FORMIDABLE_POST_CREATE_CALLBACK_SUCCESS='non.existing',
225+
)
226+
def test_create_success_unknown(self):
227+
with self.assertRaises(ImproperlyConfigured):
228+
check_callback_configuration()
229+
230+
@override_settings(
231+
FORMIDABLE_POST_CREATE_CALLBACK_FAIL='non.existing',
232+
)
233+
def test_create_fail_unknown(self):
234+
with self.assertRaises(ImproperlyConfigured):
235+
check_callback_configuration()

formidable/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
default_app_config = 'formidable.app.FormidableConfig'

formidable/app.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""
2+
Django-formidable app definition.
3+
4+
The :class:`FormidableConfig` checks various configuration settings:
5+
6+
* post-update and post-create callbacks
7+
"""
8+
9+
from django.apps import AppConfig
10+
11+
12+
class FormidableConfig(AppConfig):
13+
"""
14+
Formidable application configuration class. Runs various checks.
15+
"""
16+
name = 'formidable'
17+
18+
def ready(self):
19+
"""
20+
Run various checks when ready
21+
"""
22+
from .views import check_callback_configuration
23+
check_callback_configuration()

formidable/views.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import logging
55

66
from django.conf import settings
7+
from django.core.exceptions import ImproperlyConfigured
78
from django.db.models import Prefetch
89

910
import six
@@ -31,17 +32,39 @@
3132
def extract_function(func_name):
3233
"""
3334
Return a function out of a namespace
35+
36+
Return None if the function is not loadable
3437
"""
3538
func = None
3639
try:
3740
func = import_from_string(func_name, '')
38-
except ImportError:
41+
except (ImportError, ValueError):
3942
logger.error(
4043
"An error has occurred impossible to import %s", func_name
4144
)
4245
return func
4346

4447

48+
def check_callback_configuration():
49+
settings_names = (
50+
'FORMIDABLE_POST_UPDATE_CALLBACK_SUCCESS',
51+
'FORMIDABLE_POST_UPDATE_CALLBACK_FAIL',
52+
'FORMIDABLE_POST_CREATE_CALLBACK_SUCCESS',
53+
'FORMIDABLE_POST_CREATE_CALLBACK_FAIL',
54+
)
55+
settings_values = map(
56+
lambda k: (k, getattr(settings, k, None)),
57+
settings_names)
58+
settings_values = filter(lambda item: item[1], settings_values)
59+
for key, value in settings_values:
60+
func = extract_function(value)
61+
if not func:
62+
raise ImproperlyConfigured(
63+
"Settings {} points to a non-existant function: `{}`".format(
64+
key, value))
65+
return True
66+
67+
4568
class CallbackMixin(object):
4669
success_callback_settings = ''
4770
failure_callback_settings = ''

0 commit comments

Comments
 (0)