Add support for reconfiguring handlers in tests

Signed-off-by: Aleksi Häkli <aleksi.hakli@iki.fi>
This commit is contained in:
Aleksi Häkli 2019-02-16 18:32:32 +02:00 committed by Aleksi Häkli
parent b120fc6fde
commit d1eb64679b
No known key found for this signature in database
GPG key ID: 3E7146964D726BBE
2 changed files with 23 additions and 2 deletions

View file

@ -3,6 +3,7 @@ from logging import getLogger
from django.contrib.auth.signals import user_logged_in
from django.contrib.auth.signals import user_logged_out
from django.contrib.auth.signals import user_login_failed
from django.core.signals import setting_changed
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.dispatch import Signal
@ -32,14 +33,14 @@ class ProxyHandler:
implementation = None # concrete handler that is bootstrapped by the Django application loader
@classmethod
def initialize(cls):
def initialize(cls, force=False):
"""
Fetch and initialize concrete handler implementation and memoize it to avoid reinitialization.
This method is re-entrant and can be called multiple times.
"""
if cls.implementation is None:
if force or cls.implementation is None:
cls.implementation = import_string(settings.AXES_HANDLER)()
@classmethod
@ -124,3 +125,14 @@ def handle_post_save_access_attempt(*args, **kwargs):
@receiver(post_delete, sender=AccessAttempt)
def handle_post_delete_access_attempt(*args, **kwargs):
ProxyHandler.post_delete_access_attempt(*args, **kwargs)
@receiver(setting_changed)
def handle_setting_changed(sender, setting, value, enter, **kwargs): # pylint: disable=unused-argument
"""
Reinitialize handler implementation if a relevant setting changes
in e.g. application reconfiguration or during testing.
"""
if enter and setting == 'AXES_HANDLER':
ProxyHandler.initialize(force=enter)

View file

@ -16,6 +16,15 @@ class ProxyHandlerTestCase(TestCase):
self.user = MagicMock()
self.instance = MagicMock()
@patch('axes.signals.import_string', return_value=AxesHandler)
def test_setting_changed_signal_triggers_handler_reimport(self, importer):
self.assertEqual(0, importer.call_count)
with self.settings(
AXES_HANDLER='axes.handlers.AxesHandler'
):
self.assertEqual(1, importer.call_count)
@patch('axes.signals.ProxyHandler.implementation', None)
@patch('axes.signals.import_string', return_value=AxesHandler)
def test_initialize(self, importer):