test.py 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. from contextlib import ContextDecorator, ExitStack, contextmanager
  2. from functools import wraps
  3. from unittest.mock import patch
  4. from .useracl import get_user_acl
  5. __all__ = ["patch_user_acl"]
  6. class patch_user_acl(ContextDecorator, ExitStack):
  7. """Testing utility that patches get_user_acl results
  8. Can be used as decorator or context manager.
  9. Patch should be a dict or callable.
  10. """
  11. _acl_patches = []
  12. def __init__(self, acl_patch):
  13. super().__init__()
  14. self.acl_patch = acl_patch
  15. def patched_get_user_acl(self, user, cache_versions):
  16. user_acl = get_user_acl(user, cache_versions)
  17. self.apply_acl_patches(user, user_acl)
  18. return user_acl
  19. def apply_acl_patches(self, user, user_acl):
  20. for acl_patch in self._acl_patches:
  21. self.apply_acl_patch(user, user_acl, acl_patch)
  22. def apply_acl_patch(self, user, user_acl, acl_patch):
  23. if callable(acl_patch):
  24. acl_patch(user, user_acl)
  25. else:
  26. user_acl.update(acl_patch)
  27. def __enter__(self):
  28. super().__enter__()
  29. self.enter_context(self.enable_acl_patch())
  30. self.enter_context(self.patch_user_acl())
  31. @contextmanager
  32. def enable_acl_patch(self):
  33. try:
  34. self._acl_patches.append(self.acl_patch)
  35. yield
  36. finally:
  37. self._acl_patches.pop(-1)
  38. def patch_user_acl(self):
  39. return patch(
  40. "misago.acl.useracl.get_user_acl",
  41. side_effect=self.patched_get_user_acl,
  42. )