test_password.py 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import json
  2. import pytest
  3. from werkzeug.security import check_password_hash
  4. from flaskbb.auth.services import password
  5. from flaskbb.core.exceptions import StopValidation, ValidationError
  6. from flaskbb.core.tokens import Token, TokenActions, TokenError
  7. from flaskbb.user.models import User
  8. class SimpleTokenSerializer:
  9. @staticmethod
  10. def dumps(token):
  11. return json.dumps({'user_id': token.user_id, 'op': token.operation})
  12. @staticmethod
  13. def loads(raw_token):
  14. loaded = json.loads(raw_token)
  15. return Token(user_id=loaded['user_id'], operation=loaded['op'])
  16. class TestPasswordReset(object):
  17. def test_raises_token_error_if_not_a_password_reset(self):
  18. service = password.ResetPasswordService(
  19. SimpleTokenSerializer, User, []
  20. )
  21. raw_token = SimpleTokenSerializer.dumps(
  22. Token(user_id=1, operation=TokenActions.ACTIVATE_ACCOUNT)
  23. )
  24. with pytest.raises(TokenError) as excinfo:
  25. service.reset_password(
  26. raw_token, "some@e.mail", "a great password!"
  27. )
  28. assert "invalid" in str(excinfo.value)
  29. def test_raises_StopValidation_if_verifiers_fail(self):
  30. token = SimpleTokenSerializer.dumps(
  31. Token(user_id=1, operation=TokenActions.RESET_PASSWORD)
  32. )
  33. def verifier(*a, **k):
  34. raise ValidationError('attr', 'no')
  35. service = password.ResetPasswordService(
  36. SimpleTokenSerializer, User, [verifier]
  37. )
  38. with pytest.raises(StopValidation) as excinfo:
  39. service.reset_password(token, "an@e.mail", "great password!")
  40. assert ("attr", "no") in excinfo.value.reasons
  41. def test_sets_user_password_to_provided_if_verifiers_pass(self, Fred):
  42. token = SimpleTokenSerializer.dumps(
  43. Token(user_id=Fred.id, operation=TokenActions.RESET_PASSWORD)
  44. )
  45. service = password.ResetPasswordService(
  46. SimpleTokenSerializer, User, []
  47. )
  48. service.reset_password(token, Fred.email, "newpasswordwhodis")
  49. assert check_password_hash(Fred.password, "newpasswordwhodis")
  50. # need fred to initiate Users
  51. def test_initiate_raises_if_user_doesnt_exist(self, Fred):
  52. service = password.ResetPasswordService(
  53. SimpleTokenSerializer, User, []
  54. )
  55. with pytest.raises(ValidationError) as excinfo:
  56. service.initiate_password_reset('lol@doesnt.exist')
  57. assert excinfo.value.attribute == 'email'
  58. assert excinfo.value.reason == 'Invalid email'
  59. def test_calls_send_reset_token_successfully_if_user_exists(
  60. self, Fred, mocker
  61. ):
  62. service = password.ResetPasswordService(
  63. SimpleTokenSerializer, User, []
  64. )
  65. mock = mocker.MagicMock()
  66. with mocker.patch(
  67. 'flaskbb.auth.services.password.send_reset_token.delay', mock
  68. ):
  69. service.initiate_password_reset(Fred.email)
  70. token = SimpleTokenSerializer.dumps(
  71. Token(user_id=Fred.id, operation=TokenActions.RESET_PASSWORD)
  72. )
  73. mock.assert_called_once_with(
  74. token=token, username=Fred.username, email=Fred.email
  75. )