test_update_details_handler.py 2.9 KB

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