test_update_details_handler.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. from uuid import uuid4
  2. import pytest
  3. from pluggy import HookimplMarker
  4. from flaskbb.core.exceptions import PersistenceError, StopValidation, ValidationError
  5. from flaskbb.core.changesets import ChangeSetValidator, ChangeSetPostProcessor
  6. from flaskbb.core.user.update import UserDetailsChange
  7. from flaskbb.user.models import User
  8. from flaskbb.user.services.update import DefaultDetailsUpdateHandler
  9. class TestDefaultDetailsUpdateHandler(object):
  10. def test_raises_stop_validation_if_errors_occur(
  11. self, mock, user, database, plugin_manager
  12. ):
  13. validator = mock.Mock(spec=ChangeSetValidator)
  14. validator.validate.side_effect = ValidationError(
  15. "location", "Dont be from there"
  16. )
  17. details = UserDetailsChange()
  18. hook_impl = mock.Mock(spec=ChangeSetPostProcessor)
  19. plugin_manager.register(self.impl(hook_impl))
  20. handler = DefaultDetailsUpdateHandler(
  21. validators=[validator], db=database, plugin_manager=plugin_manager
  22. )
  23. with pytest.raises(StopValidation) as excinfo:
  24. handler.apply_changeset(user, details)
  25. assert excinfo.value.reasons == [("location", "Dont be from there")]
  26. hook_impl.post_process_changeset.assert_not_called()
  27. def test_raises_persistence_error_if_save_fails(self, mock, user, plugin_manager):
  28. details = UserDetailsChange()
  29. db = mock.Mock()
  30. db.session.commit.side_effect = Exception("no")
  31. hook_impl = mock.Mock(spec=ChangeSetPostProcessor)
  32. plugin_manager.register(self.impl(hook_impl))
  33. handler = DefaultDetailsUpdateHandler(
  34. validators=[], db=db, plugin_manager=plugin_manager
  35. )
  36. with pytest.raises(PersistenceError) as excinfo:
  37. handler.apply_changeset(user, details)
  38. assert "Could not update details" in str(excinfo.value)
  39. hook_impl.post_process_changeset.assert_not_called()
  40. def test_actually_updates_users_details(self, user, database, plugin_manager, mock):
  41. location = str(uuid4())
  42. details = UserDetailsChange(location=location)
  43. hook_impl = mock.Mock(spec=ChangeSetPostProcessor)
  44. plugin_manager.register(self.impl(hook_impl))
  45. handler = DefaultDetailsUpdateHandler(
  46. db=database, plugin_manager=plugin_manager
  47. )
  48. handler.apply_changeset(user, details)
  49. same_user = User.query.get(user.id)
  50. assert same_user.location == location
  51. hook_impl.post_process_changeset.assert_called_once_with(
  52. user=user, details_update=details
  53. )
  54. @staticmethod
  55. def impl(post_processor):
  56. class Impl:
  57. @HookimplMarker("flaskbb")
  58. def flaskbb_details_updated(self, user, details_update):
  59. post_processor.post_process_changeset(
  60. user=user, details_update=details_update
  61. )
  62. return Impl()