test.py 1.5 KB

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