test_registration.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import pytest
  2. from pluggy import HookimplMarker
  3. from flaskbb.auth.services.registration import RegistrationService
  4. from flaskbb.core.auth.registration import (
  5. RegistrationFailureHandler,
  6. RegistrationPostProcessor,
  7. UserRegistrationInfo,
  8. UserValidator,
  9. )
  10. from flaskbb.core.exceptions import (
  11. PersistenceError,
  12. StopValidation,
  13. ValidationError,
  14. )
  15. from flaskbb.user.models import User
  16. pytestmark = pytest.mark.usefixtures("default_settings")
  17. class RaisingValidator(UserValidator):
  18. def validate(self, user_info):
  19. raise ValidationError("username", "nope")
  20. class TestRegistrationService(object):
  21. fred = UserRegistrationInfo(
  22. username="Fred",
  23. password="Fred",
  24. email="fred@fred.com",
  25. language="fred",
  26. group=4,
  27. )
  28. def test_raises_stop_validation_if_validators_fail(
  29. self, plugin_manager, database
  30. ):
  31. service = self._get_service(plugin_manager, database)
  32. plugin_manager.register(self.impls(validator=RaisingValidator()))
  33. with pytest.raises(StopValidation) as excinfo:
  34. service.register(self.fred)
  35. assert ("username", "nope") in excinfo.value.reasons
  36. def test_calls_failure_handlers_if_validation_fails(
  37. self, plugin_manager, database, mocker
  38. ):
  39. service = self._get_service(plugin_manager, database)
  40. failure = mocker.MagicMock(spec=RegistrationFailureHandler)
  41. plugin_manager.register(
  42. self.impls(validator=RaisingValidator(), failure=failure)
  43. )
  44. with pytest.raises(StopValidation) as excinfo:
  45. service.register(self.fred)
  46. failure.assert_called_once_with(self.fred, excinfo.value.reasons)
  47. def test_registers_user_if_everything_is_good(
  48. self, database, plugin_manager
  49. ):
  50. service = self._get_service(plugin_manager, database)
  51. service.register(self.fred)
  52. actual_fred = User.query.filter(User.username == "Fred").one()
  53. assert actual_fred.id is not None
  54. def test_calls_post_processors_if_user_registration_works(
  55. self, database, plugin_manager, mocker
  56. ):
  57. service = self._get_service(plugin_manager, database)
  58. post_process = mocker.MagicMock(spec=RegistrationPostProcessor)
  59. plugin_manager.register(self.impls(post_process=post_process))
  60. fred = service.register(self.fred)
  61. post_process.assert_called_once_with(fred)
  62. def test_raises_persistenceerror_if_saving_user_goes_wrong(
  63. self, database, plugin_manager, Fred
  64. ):
  65. service = self._get_service(plugin_manager, database)
  66. with pytest.raises(PersistenceError):
  67. service.register(self.fred)
  68. @staticmethod
  69. def _get_service(plugin_manager, db):
  70. return RegistrationService(plugins=plugin_manager, users=User, db=db)
  71. @staticmethod
  72. def impls(validator=None, failure=None, post_process=None):
  73. impl = HookimplMarker("flaskbb")
  74. class Impls:
  75. if validator is not None:
  76. @impl
  77. def flaskbb_gather_registration_validators(self):
  78. return [validator]
  79. if failure is not None:
  80. @impl
  81. def flaskbb_registration_failure_handler(
  82. self, user_info, failures
  83. ):
  84. failure(user_info, failures)
  85. if post_process is not None:
  86. @impl
  87. def flaskbb_registration_post_processor(self, user):
  88. post_process(user)
  89. return Impls()