import sys from contextlib import contextmanager from io import StringIO from shutil import rmtree as _rmtree from tempfile import _exists, mkdtemp, template from django.contrib.auth import get_user_model from django.test.utils import override_settings from django.utils.translation import activate, get_language from cms.apphook_pool import apphook_pool class NULL: pass class StdOverride: def __init__(self, std='out', buffer=None): self.std = std self.buffer = buffer or StringIO() def __enter__(self): setattr(sys, 'std%s' % self.std, self.buffer) return self.buffer def __exit__(self, type, value, traceback): setattr(sys, 'std%s' % self.std, getattr(sys, '__std%s__' % self.std)) class StdoutOverride(StdOverride): """ This overrides Python's the standard output and redirects it to a StringIO object, so that on can test the output of the program. example: lines = None with StdoutOverride() as buffer: # print stuff lines = buffer.getvalue() """ def __init__(self, buffer=None): super().__init__('out', buffer) class LanguageOverride: def __init__(self, language): self.newlang = language def __enter__(self): self.oldlang = get_language() activate(self.newlang) def __exit__(self, type, value, traceback): activate(self.oldlang) class TemporaryDirectory: """Create and return a temporary directory. This has the same behavior as mkdtemp but can be used as a context manager. For example: with TemporaryDirectory() as tmpdir: ... Upon exiting the context, the directory and everything contained in it are removed. """ def __init__(self, suffix="", prefix=template, dir=None): self.name = mkdtemp(suffix, prefix, dir) def __enter__(self): return self.name def cleanup(self): if _exists(self.name): _rmtree(self.name) def __exit__(self, exc, value, tb): self.cleanup() class UserLoginContext: def __init__(self, testcase, user): self.testcase = testcase self.user = user def __enter__(self): loginok = self.testcase.client.login(username=getattr(self.user, get_user_model().USERNAME_FIELD), password=getattr(self.user, get_user_model().USERNAME_FIELD)) self.old_user = getattr(self.testcase, 'user', None) self.testcase.user = self.user self.testcase.assertTrue(loginok) def __exit__(self, exc, value, tb): self.testcase.user = self.old_user if not self.testcase.user: delattr(self.testcase, 'user') self.testcase.client.logout() class ChangeModel: """ Changes attributes on a model while within the context. These changes *ARE* saved to the database for the context! """ def __init__(self, instance, **overrides): self.instance = instance self.overrides = overrides def __enter__(self): self.old = {} for key, value in self.overrides.items(): self.old[key] = getattr(self.instance, key, NULL) setattr(self.instance, key, value) self.instance.save() def __exit__(self, exc, value, tb): for key in self.overrides.keys(): old_value = self.old[key] if old_value is NULL: delattr(self.instance, key) else: setattr(self.instance, key, old_value) self.instance.save() @contextmanager def disable_logger(logger): old = logger.disabled logger.disabled = True yield logger.disabled = old @contextmanager def apphooks(*hooks): _apphooks = apphook_pool.apphooks _apps = apphook_pool.apps _discovered = apphook_pool.discovered apphook_pool.clear() for hook in hooks: apphook_pool.register(hook) try: yield finally: apphook_pool.apphooks = _apphooks apphook_pool.apps = _apps apphook_pool.discovered = _discovered @contextmanager def signal_tester(*signals): env = SignalTester() for signal in signals: signal.connect(env) try: yield env finally: for signal in signals: signal.disconnect(env) class SignalTester: def __init__(self): self.call_count = 0 self.calls = [] def __call__(self, *args, **kwargs): self.call_count += 1 self.calls.append((args, kwargs)) @contextmanager def override_placeholder_conf(CMS_PLACEHOLDER_CONF): from cms.utils.placeholder import _clear_placeholder_conf_cache # Call _get_placeholder_settings after changing the setting with override_settings(CMS_PLACEHOLDER_CONF=CMS_PLACEHOLDER_CONF): _clear_placeholder_conf_cache() # Clear cache if needed yield # Call _get_placeholder_settings after resetting the setting _clear_placeholder_conf_cache() # Clear cache if needed