test.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. from contextlib import ExitStack
  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(ExitStack):
  7. """Testing utility that patches get_user_acl results
  8. Can be used as decorator or context manager.
  9. Accepts one or two arguments:
  10. - patch_user_acl(acl_patch)
  11. - patch_user_acl(user, acl_patch)
  12. Patch should be a dict or callable.
  13. """
  14. def __init__(self, *args):
  15. super().__init__()
  16. self._global_patch = None
  17. self._user_patches = {}
  18. if len(args) == 2:
  19. user, patch = args
  20. self._user_patches[user.id] = patch
  21. elif len(args) == 1:
  22. self._global_patch = args[0]
  23. else:
  24. raise ValueError("patch_user_acl takes one or two arguments.")
  25. def patched_get_user_acl(self, user, cache_versions):
  26. user_acl = get_user_acl(user, cache_versions)
  27. self.apply_acl_patches(user, user_acl)
  28. return user_acl
  29. def apply_acl_patches(self, user, user_acl):
  30. if self._global_patch:
  31. self.apply_acl_patch(user, user_acl, self._global_patch)
  32. if user.id in self._user_patches:
  33. user_acl_patch = self._user_patches[user.id]
  34. self.apply_acl_patch(user, user_acl, user_acl_patch)
  35. def apply_acl_patch(self, user, user_acl, acl_patch):
  36. if callable(acl_patch):
  37. acl_patch(user, user_acl)
  38. else:
  39. user_acl.update(acl_patch)
  40. def __enter__(self):
  41. super().__enter__()
  42. self.enter_context(
  43. patch(
  44. "misago.acl.useracl.get_user_acl",
  45. side_effect=self.patched_get_user_acl,
  46. )
  47. )
  48. def __call__(self, f):
  49. @wraps(f)
  50. def inner(*args, **kwargs):
  51. with self:
  52. with patch(
  53. "misago.acl.useracl.get_user_acl",
  54. side_effect=self.patched_get_user_acl,
  55. ):
  56. return f(*args, **kwargs)
  57. return inner