test_update_email_handler.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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 EmailUpdate
  8. from flaskbb.user.models import User
  9. from flaskbb.user.services.update import DefaultEmailUpdateHandler
  10. def random_email():
  11. return "{}@not.real.at.all".format(str(uuid4()))
  12. class TestDefaultEmailUpdateHandler(object):
  13. def test_raises_stop_validation_if_errors_occur(
  14. self, mocker, user, database, plugin_manager
  15. ):
  16. validator = mocker.Mock(spec=ChangeSetValidator)
  17. validator.validate.side_effect = ValidationError(
  18. "new_email", "That's not even valid"
  19. )
  20. hook_impl = mocker.Mock(spec=ChangeSetPostProcessor)
  21. plugin_manager.register(self.impl(hook_impl))
  22. email_change = EmailUpdate(user.email, random_email())
  23. handler = DefaultEmailUpdateHandler(
  24. db=database, validators=[validator], plugin_manager=plugin_manager
  25. )
  26. with pytest.raises(StopValidation) as excinfo:
  27. handler.apply_changeset(user, email_change)
  28. assert excinfo.value.reasons == [("new_email", "That's not even valid")]
  29. hook_impl.post_process_changeset.assert_not_called()
  30. def test_raises_persistence_error_if_save_fails(
  31. self, mocker, user, plugin_manager
  32. ):
  33. email_change = EmailUpdate(user.email, random_email())
  34. db = mocker.Mock()
  35. db.session.commit.side_effect = Exception("no")
  36. hook_impl = mocker.Mock(spec=ChangeSetPostProcessor)
  37. plugin_manager.register(self.impl(hook_impl))
  38. handler = DefaultEmailUpdateHandler(
  39. db=db, validators=[], plugin_manager=plugin_manager
  40. )
  41. with pytest.raises(PersistenceError) as excinfo:
  42. handler.apply_changeset(user, email_change)
  43. assert "Could not update email" in str(excinfo.value)
  44. hook_impl.post_process_changeset.assert_not_called()
  45. def test_actually_updates_email(
  46. self, user, database, mocker, plugin_manager
  47. ):
  48. new_email = random_email()
  49. email_change = EmailUpdate("test", new_email)
  50. hook_impl = mocker.Mock(spec=ChangeSetPostProcessor)
  51. plugin_manager.register(self.impl(hook_impl))
  52. handler = DefaultEmailUpdateHandler(
  53. db=database, validators=[], plugin_manager=plugin_manager
  54. )
  55. handler.apply_changeset(user, email_change)
  56. same_user = User.query.get(user.id)
  57. assert same_user.email == new_email
  58. hook_impl.post_process_changeset.assert_called_once_with(
  59. user=user, email_update=email_change
  60. )
  61. @staticmethod
  62. def impl(post_processor):
  63. class Impl:
  64. @HookimplMarker("flaskbb")
  65. def flaskbb_email_updated(self, user, email_update):
  66. post_processor.post_process_changeset(
  67. user=user, email_update=email_update
  68. )
  69. return Impl()