test.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. from contextlib import ContextDecorator, ExitStack, contextmanager
  2. from functools import wraps
  3. from unittest.mock import patch
  4. from .forms import get_permissions_forms
  5. from .useracl import get_user_acl
  6. __all__ = ["patch_user_acl"]
  7. class patch_user_acl(ContextDecorator, ExitStack):
  8. """Testing utility that patches get_user_acl results
  9. Can be used as decorator or context manager.
  10. Patch should be a dict or callable.
  11. """
  12. _acl_patches = []
  13. def __init__(self, acl_patch):
  14. super().__init__()
  15. self.acl_patch = acl_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. for acl_patch in self._acl_patches:
  22. self.apply_acl_patch(user, user_acl, acl_patch)
  23. def apply_acl_patch(self, user, user_acl, acl_patch):
  24. if callable(acl_patch):
  25. acl_patch(user, user_acl)
  26. else:
  27. user_acl.update(acl_patch)
  28. def __enter__(self):
  29. super().__enter__()
  30. self.enter_context(self.enable_acl_patch())
  31. self.enter_context(self.patch_user_acl())
  32. @contextmanager
  33. def enable_acl_patch(self):
  34. try:
  35. self._acl_patches.append(self.acl_patch)
  36. yield
  37. finally:
  38. self._acl_patches.pop(-1)
  39. def patch_user_acl(self):
  40. return patch(
  41. "misago.acl.useracl.get_user_acl", side_effect=self.patched_get_user_acl
  42. )
  43. def mock_role_form_data(model, data):
  44. """
  45. In order for form to don't fail submission, all permission fields need
  46. to receive values. This function populates data dict with default values
  47. for permissions, making form validation pass
  48. """
  49. for form in get_permissions_forms(model):
  50. for field in form:
  51. if field.value() is True:
  52. data[field.html_name] = 1
  53. elif field.value() is False:
  54. data[field.html_name] = 0
  55. else:
  56. data[field.html_name] = field.value()
  57. return data