diff --git a/tests/utils.py b/tests/utils.py index b20f2bce..8367b2cf 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -14,7 +14,9 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import functools +from django.conf import settings from django.db.models import signals @@ -34,3 +36,53 @@ def signals_switch(): disconnect_signals, reconnect_signals = signals_switch() + + +def set_settings(**new_settings): + """Decorator for set django settings that will be only available during the + wrapped-function execution. + + For example: + @set_settings(FOO='bar') + def myfunc(): + ... + + @set_settings(FOO='bar') + class TestCase: + ... + """ + def decorator(testcase): + if type(testcase) is type: + namespace = {"OVERRIDE_SETTINGS": new_settings, "ORIGINAL_SETTINGS": {}} + wrapper = type(testcase.__name__, (SettingsTestCase, testcase), namespace) + else: + @functools.wraps(testcase) + def wrapper(*args, **kwargs): + old_settings = override_settings(new_settings) + try: + testcase(*args, **kwargs) + finally: + override_settings(old_settings) + + return wrapper + + return decorator + + +def override_settings(new_settings): + old_settings = {} + for name, new_value in new_settings.items(): + old_settings[name] = getattr(settings, name, None) + setattr(settings, name, new_value) + return old_settings + + +class SettingsTestCase(object): + @classmethod + def setup_class(cls): + cls.ORIGINAL_SETTINGS = override_settings(cls.OVERRIDE_SETTINGS) + + @classmethod + def teardown_class(cls): + override_settings(cls.ORIGINAL_SETTINGS) + cls.OVERRIDE_SETTINGS.clear()