test_user_changeemail_api.py 4.5 KB

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