test_user_changeemail_api.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. from django.contrib.auth import get_user_model
  2. from django.core import mail
  3. from django.urls import reverse
  4. from misago.users.testutils import AuthenticatedUserTestCase
  5. UserModel = get_user_model()
  6. class UserChangeEmailTests(AuthenticatedUserTestCase):
  7. """tests for user change email RPC (/api/users/1/change-email/)"""
  8. def setUp(self):
  9. super().setUp()
  10. self.link = '/api/users/%s/change-email/' % self.user.pk
  11. def test_unsupported_methods(self):
  12. """api isn't supporting GET"""
  13. response = self.client.get(self.link)
  14. self.assertEqual(response.status_code, 405)
  15. def test_empty_input(self):
  16. """api errors correctly for empty input"""
  17. response = self.client.post(self.link, data={})
  18. self.assertEqual(response.status_code, 400)
  19. self.assertEqual(
  20. response.json(), {
  21. 'new_email': ["This field is required."],
  22. 'password': ["This field is required."],
  23. }
  24. )
  25. def test_invalid_password(self):
  26. """api errors correctly for invalid password"""
  27. response = self.client.post(
  28. self.link,
  29. data={
  30. 'new_email': 'new@email.com',
  31. 'password': 'Lor3mIpsum',
  32. },
  33. )
  34. self.assertContains(response, 'password is invalid', status_code=400)
  35. def test_invalid_input(self):
  36. """api errors correctly for invalid input"""
  37. response = self.client.post(
  38. self.link,
  39. data={
  40. 'new_email': '',
  41. 'password': self.USER_PASSWORD,
  42. },
  43. )
  44. self.assertEqual(response.status_code, 400)
  45. self.assertEqual(response.json(), {
  46. 'new_email': ["This field may not be blank."],
  47. })
  48. response = self.client.post(
  49. self.link,
  50. data={
  51. 'new_email': 'newmail',
  52. 'password': self.USER_PASSWORD,
  53. },
  54. )
  55. self.assertEqual(response.status_code, 400)
  56. self.assertEqual(response.json(), {
  57. 'new_email': ["Enter a valid email address."],
  58. })
  59. def test_email_taken(self):
  60. """api validates email usage"""
  61. UserModel.objects.create_user('BobBoberson', 'new@email.com', 'Pass.123')
  62. response = self.client.post(
  63. self.link,
  64. data={
  65. 'new_email': 'new@email.com',
  66. 'password': self.USER_PASSWORD,
  67. },
  68. )
  69. self.assertContains(response, 'not available', status_code=400)
  70. def test_change_email(self):
  71. """api allows users to change their e-mail addresses"""
  72. new_email = 'new@email.com'
  73. response = self.client.post(
  74. self.link,
  75. data={
  76. 'new_email': new_email,
  77. 'password': self.USER_PASSWORD,
  78. },
  79. )
  80. self.assertEqual(response.status_code, 200)
  81. self.assertIn('Confirm e-mail change', mail.outbox[0].subject)
  82. for line in [l.strip() for l in mail.outbox[0].body.splitlines()]:
  83. if line.startswith('http://'):
  84. token = line.rstrip('/').split('/')[-1]
  85. break
  86. else:
  87. self.fail("E-mail sent didn't contain confirmation url")
  88. response = self.client.get(
  89. reverse(
  90. 'misago:options-confirm-email-change',
  91. kwargs={
  92. 'token': token,
  93. },
  94. )
  95. )
  96. self.assertEqual(response.status_code, 200)
  97. self.reload_user()
  98. self.assertEqual(self.user.email, new_email)
  99. def test_change_email_user_password_whitespace(self):
  100. """api supports users with whitespace around their passwords"""
  101. user_password = ' old password '
  102. new_password = ' N3wP@55w0rd '
  103. new_email = 'new@email.com'
  104. self.user.set_password(user_password)
  105. self.user.save()
  106. self.login_user(self.user)
  107. response = self.client.post(
  108. self.link,
  109. data={
  110. 'new_email': new_email,
  111. 'password': user_password,
  112. },
  113. )
  114. self.assertEqual(response.status_code, 200)
  115. self.assertIn('Confirm e-mail change', mail.outbox[0].subject)
  116. for line in [l.strip() for l in mail.outbox[0].body.splitlines()]:
  117. if line.startswith('http://'):
  118. token = line.rstrip('/').split('/')[-1]
  119. break
  120. else:
  121. self.fail("E-mail sent didn't contain confirmation url")
  122. response = self.client.get(
  123. reverse(
  124. 'misago:options-confirm-email-change',
  125. kwargs={
  126. 'token': token,
  127. },
  128. )
  129. )
  130. self.assertEqual(response.status_code, 200)
  131. self.reload_user()
  132. self.assertEqual(self.user.email, new_email)