test_user_changeemail_api.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. from django.core import mail
  2. from django.urls import reverse
  3. from ...conf.test import override_dynamic_settings
  4. from ..test import AuthenticatedUserTestCase, create_test_user
  5. class UserChangeEmailTests(AuthenticatedUserTestCase):
  6. """tests for user change email RPC (/api/users/1/change-email/)"""
  7. def setUp(self):
  8. super().setUp()
  9. self.link = "/api/users/%s/change-email/" % self.user.pk
  10. def test_unsupported_methods(self):
  11. """api isn't supporting GET"""
  12. response = self.client.get(self.link)
  13. self.assertEqual(response.status_code, 405)
  14. def test_empty_input(self):
  15. """api errors correctly for empty input"""
  16. response = self.client.post(self.link, data={})
  17. self.assertEqual(response.status_code, 400)
  18. self.assertEqual(
  19. response.json(),
  20. {
  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, data={"new_email": "new@email.com", "password": "Lor3mIpsum"}
  29. )
  30. self.assertEqual(response.status_code, 400)
  31. self.assertEqual(
  32. response.json(), {"password": ["Entered password is invalid."]}
  33. )
  34. def test_invalid_input(self):
  35. """api errors correctly for invalid input"""
  36. response = self.client.post(
  37. self.link, data={"new_email": "", "password": self.USER_PASSWORD}
  38. )
  39. self.assertEqual(response.status_code, 400)
  40. self.assertEqual(
  41. response.json(), {"new_email": ["This field may not be blank."]}
  42. )
  43. response = self.client.post(
  44. self.link, data={"new_email": "newmail", "password": self.USER_PASSWORD}
  45. )
  46. self.assertEqual(response.status_code, 400)
  47. self.assertEqual(
  48. response.json(), {"new_email": ["Enter a valid email address."]}
  49. )
  50. def test_email_taken(self):
  51. """api validates email usage"""
  52. taken_email = "otheruser@example.com"
  53. create_test_user("OtherUser", taken_email)
  54. response = self.client.post(
  55. self.link, data={"new_email": taken_email, "password": self.USER_PASSWORD}
  56. )
  57. self.assertEqual(response.status_code, 400)
  58. self.assertEqual(
  59. response.json(), {"new_email": ["This e-mail address is not available."]}
  60. )
  61. @override_dynamic_settings(enable_sso=True)
  62. def test_email_change_fails_when_sso_is_enabled(self):
  63. response = self.client.post(
  64. self.link,
  65. data={"new_email": "new@email.com", "password": self.USER_PASSWORD},
  66. )
  67. self.assertEqual(response.status_code, 403)
  68. @override_dynamic_settings(forum_address="http://test.com/")
  69. def test_change_email(self):
  70. """api allows users to change their e-mail addresses"""
  71. new_email = "new@email.com"
  72. response = self.client.post(
  73. self.link, data={"new_email": new_email, "password": self.USER_PASSWORD}
  74. )
  75. self.assertEqual(response.status_code, 200)
  76. self.assertIn("Confirm e-mail change", mail.outbox[0].subject)
  77. for line in [l.strip() for l in mail.outbox[0].body.splitlines()]:
  78. if line.startswith("http://"):
  79. token = line.rstrip("/").split("/")[-1]
  80. break
  81. else:
  82. self.fail("E-mail sent didn't contain confirmation url")
  83. response = self.client.get(
  84. reverse("misago:options-confirm-email-change", kwargs={"token": token})
  85. )
  86. self.assertEqual(response.status_code, 200)
  87. self.reload_user()
  88. self.assertEqual(self.user.email, new_email)
  89. @override_dynamic_settings(forum_address="http://test.com/")
  90. def test_change_email_user_password_whitespace(self):
  91. """api supports users with whitespace around their passwords"""
  92. user_password = " old password "
  93. new_email = "new@email.com"
  94. self.user.set_password(user_password)
  95. self.user.save()
  96. self.login_user(self.user)
  97. response = self.client.post(
  98. self.link, data={"new_email": new_email, "password": user_password}
  99. )
  100. self.assertEqual(response.status_code, 200)
  101. self.assertIn("Confirm e-mail change", mail.outbox[0].subject)
  102. for line in [l.strip() for l in mail.outbox[0].body.splitlines()]:
  103. if line.startswith("http://"):
  104. token = line.rstrip("/").split("/")[-1]
  105. break
  106. else:
  107. self.fail("E-mail sent didn't contain confirmation url")
  108. response = self.client.get(
  109. reverse("misago:options-confirm-email-change", kwargs={"token": token})
  110. )
  111. self.assertEqual(response.status_code, 200)
  112. self.reload_user()
  113. self.assertEqual(self.user.email, new_email)