test.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. from functools import wraps
  2. from unittest.mock import patch
  3. from .useracl import get_user_acl
  4. __all__ = ["patch_user_acl"]
  5. class patch_user_acl:
  6. """Testing utility that patches get_user_acl results
  7. Patch should be a dict or callable.
  8. Can be used as decorator or context manager.
  9. """
  10. _global_patch = None
  11. _user_patches = {}
  12. def __init__(self, global_patch=None):
  13. self._global_patch = global_patch
  14. def patch_user_acl(self, user, patch):
  15. self._user_patches[user.id] = patch
  16. def patched_get_user_acl(self, user, cache_versions):
  17. user_acl = get_user_acl(user, cache_versions)
  18. self.apply_acl_patches(user, user_acl)
  19. return user_acl
  20. def apply_acl_patches(self, user, user_acl):
  21. if self._global_patch:
  22. self.apply_acl_patch(user, user_acl, self._global_patch)
  23. if user.id in self._user_patches:
  24. user_acl_patch = self._user_patches[user.id]
  25. self.apply_acl_patch(user, user_acl, user_acl_patch)
  26. def apply_acl_patch(self, user, user_acl, acl_patch):
  27. if callable(acl_patch):
  28. acl_patch(user, user_acl)
  29. else:
  30. user_acl.update(acl_patch)
  31. def __enter__(self):
  32. return self
  33. def __exit__(self, *_):
  34. self._user_patches = {}
  35. def __call__(self, f):
  36. @wraps(f)
  37. def inner(*args, **kwargs):
  38. with self:
  39. with patch(
  40. "misago.acl.useracl.get_user_acl",
  41. side_effect=self.patched_get_user_acl,
  42. ):
  43. new_args = args + (self.patch_user_acl,)
  44. return f(*new_args, **kwargs)
  45. return inner