test.py 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. from django.core import mail
  2. from django.shortcuts import reverse
  3. from django.test import override_settings
  4. from model_bakery import baker
  5. from rest_framework.test import APITestCase
  6. from glitchtip import test_utils # pylint: disable=unused-import
  7. from glitchtip.test_utils.test_case import GlitchTipTestCase
  8. from organizations_ext.models import OrganizationUserRole
  9. from projects.models import UserProjectAlert
  10. from ..models import User
  11. class UserRegistrationTestCase(APITestCase):
  12. def test_create_user(self):
  13. url = reverse("rest_register")
  14. data = {
  15. "email": "test@example.com",
  16. "password1": "hunter222",
  17. "password2": "hunter222",
  18. }
  19. res = self.client.post(url, data)
  20. self.assertEqual(res.status_code, 204)
  21. def test_create_user_with_tags(self):
  22. url = reverse("rest_register")
  23. data = {
  24. "email": "test@example.com",
  25. "password1": "hunter222",
  26. "password2": "hunter222",
  27. "tags": "?utm_campaign=test&utm_source=test&utm_medium=test&utm_medium=test",
  28. }
  29. res = self.client.post(url, data)
  30. self.assertEqual(res.status_code, 204)
  31. self.assertTrue(
  32. User.objects.filter(analytics__register__utm_campaign="test").exists()
  33. )
  34. def test_closed_registration(self):
  35. """Only first user may register"""
  36. url = reverse("rest_register")
  37. user1_data = {
  38. "email": "test1@example.com",
  39. "password1": "hunter222",
  40. "password2": "hunter222",
  41. }
  42. user2_data = {
  43. "email": "test2@example.com",
  44. "password1": "hunter222",
  45. "password2": "hunter222",
  46. }
  47. with override_settings(ENABLE_USER_REGISTRATION=False):
  48. res = self.client.post(url, user1_data)
  49. self.assertEqual(res.status_code, 204)
  50. res = self.client.post(url, user2_data)
  51. self.assertEqual(res.status_code, 403)
  52. class UsersTestCase(GlitchTipTestCase):
  53. def setUp(self):
  54. self.create_user_and_project()
  55. def test_list(self):
  56. url = reverse("user-list")
  57. res = self.client.get(url)
  58. self.assertContains(res, self.user.email)
  59. def test_retrieve(self):
  60. url = reverse("user-detail", args=["me"])
  61. res = self.client.get(url)
  62. self.assertContains(res, self.user.email)
  63. def test_destroy(self):
  64. other_user = baker.make("users.user")
  65. url = reverse("user-detail", args=[other_user.pk])
  66. res = self.client.delete(url)
  67. self.assertEqual(
  68. res.status_code, 404, "User should not be able to delete other users"
  69. )
  70. url = reverse("user-detail", args=[self.user.pk])
  71. res = self.client.delete(url)
  72. self.assertEqual(
  73. res.status_code, 400, "Not allowed to destroy owned organization"
  74. )
  75. # Delete organization to allow user deletion
  76. self.organization.delete()
  77. res = self.client.delete(url)
  78. self.assertEqual(res.status_code, 204)
  79. self.assertFalse(User.objects.filter(pk=self.user.pk).exists())
  80. def test_organization_members_list(self):
  81. other_user = baker.make("users.user")
  82. other_organization = baker.make("organizations_ext.Organization")
  83. other_organization.add_user(other_user, OrganizationUserRole.ADMIN)
  84. user2 = baker.make("users.User")
  85. self.organization.add_user(user2, OrganizationUserRole.MEMBER)
  86. url = reverse("organization-members-list", args=[self.organization.slug])
  87. res = self.client.get(url)
  88. self.assertContains(res, user2.email)
  89. self.assertNotContains(res, other_user.email)
  90. # Can't view members of groups you don't belong to
  91. url = reverse("organization-members-list", args=[other_organization.slug])
  92. res = self.client.get(url)
  93. self.assertNotContains(res, other_user.email)
  94. def test_emails_retrieve(self):
  95. email_address = baker.make("account.EmailAddress", user=self.user)
  96. another_user = baker.make("users.user")
  97. another_email_address = baker.make("account.EmailAddress", user=another_user)
  98. url = reverse("user-emails-list", args=["me"])
  99. res = self.client.get(url)
  100. self.assertContains(res, email_address.email)
  101. self.assertNotContains(res, another_email_address.email)
  102. def test_emails_confirm(self):
  103. email_address = baker.make("account.EmailAddress", user=self.user)
  104. url = reverse("user-emails-list", args=["me"]) + "confirm/"
  105. data = {"email": email_address.email}
  106. res = self.client.post(url, data)
  107. self.assertEqual(res.status_code, 204)
  108. self.assertEqual(len(mail.outbox), 1)
  109. def test_emails_create(self):
  110. url = reverse("user-emails-list", args=["me"])
  111. new_email = "new@exmaple.com"
  112. data = {"email": new_email}
  113. res = self.client.post(url, data)
  114. self.assertContains(res, new_email, status_code=201)
  115. self.assertTrue(
  116. self.user.emailaddress_set.filter(email=new_email, verified=False).exists()
  117. )
  118. self.assertEqual(len(mail.outbox), 1)
  119. # Ensure token is valid and can verify email
  120. body = mail.outbox[0].body
  121. key = body[body.find("confirm-email") :].split("/")[1]
  122. url = reverse("rest_verify_email")
  123. data = {"key": key}
  124. res = self.client.post(url, data)
  125. self.assertTrue(
  126. self.user.emailaddress_set.filter(email=new_email, verified=True).exists()
  127. )
  128. def test_emails_create_dupe_email(self):
  129. url = reverse("user-emails-list", args=["me"])
  130. email_address = baker.make("account.EmailAddress", user=self.user)
  131. data = {"email": email_address.email}
  132. res = self.client.post(url, data)
  133. self.assertContains(res, "this account", status_code=400)
  134. def test_emails_create_dupe_email_other_user(self):
  135. url = reverse("user-emails-list", args=["me"])
  136. email_address = baker.make("account.EmailAddress")
  137. data = {"email": email_address.email}
  138. res = self.client.post(url, data)
  139. self.assertContains(res, "another account", status_code=400)
  140. def test_emails_set_primary(self):
  141. url = reverse("user-emails-list", args=["me"])
  142. email_address = baker.make(
  143. "account.EmailAddress", verified=True, user=self.user
  144. )
  145. data = {"email": email_address.email}
  146. res = self.client.put(url, data)
  147. self.assertContains(res, email_address.email, status_code=200)
  148. self.assertTrue(
  149. self.user.emailaddress_set.filter(
  150. email=email_address.email, primary=True
  151. ).exists()
  152. )
  153. extra_email = baker.make("account.EmailAddress", verified=True, user=self.user)
  154. data = {"email": extra_email.email}
  155. res = self.client.put(url, data)
  156. self.assertEqual(self.user.emailaddress_set.filter(primary=True).count(), 1)
  157. def test_emails_destroy(self):
  158. url = reverse("user-emails-list", args=["me"])
  159. email_address = baker.make(
  160. "account.EmailAddress", verified=True, primary=False, user=self.user
  161. )
  162. data = {"email": email_address.email}
  163. res = self.client.delete(url, data)
  164. self.assertEqual(res.status_code, 204)
  165. self.assertFalse(
  166. self.user.emailaddress_set.filter(email=email_address.email).exists()
  167. )
  168. def test_notifications_retrieve(self):
  169. url = reverse("user-detail", args=["me"]) + "notifications/"
  170. res = self.client.get(url)
  171. self.assertContains(res, "subscribeByDefault")
  172. def test_notifications_update(self):
  173. url = reverse("user-detail", args=["me"]) + "notifications/"
  174. data = {"subscribeByDefault": False}
  175. res = self.client.put(url, data)
  176. self.assertFalse(res.data.get("subscribeByDefault"))
  177. self.user.refresh_from_db()
  178. self.assertFalse(self.user.subscribe_by_default)
  179. def test_alerts_retrieve(self):
  180. url = reverse("user-detail", args=["me"]) + "notifications/alerts/"
  181. alert = baker.make(
  182. "projects.UserProjectAlert", user=self.user, project=self.project
  183. )
  184. res = self.client.get(url)
  185. self.assertContains(res, self.project.id)
  186. self.assertEqual(res.data[self.project.id], alert.status)
  187. def test_alerts_update(self):
  188. url = reverse("user-detail", args=["me"]) + "notifications/alerts/"
  189. # Set to alert to On
  190. data = '{"' + str(self.project.id) + '":1}'
  191. res = self.client.put(url, data, content_type="application/json")
  192. self.assertEqual(res.status_code, 204)
  193. self.assertEqual(UserProjectAlert.objects.all().count(), 1)
  194. self.assertEqual(UserProjectAlert.objects.first().status, 1)
  195. # Set to alert to Off
  196. data = '{"' + str(self.project.id) + '":0}'
  197. res = self.client.put(url, data, content_type="application/json")
  198. self.assertEqual(res.status_code, 204)
  199. self.assertEqual(UserProjectAlert.objects.first().status, 0)
  200. # Set to alert to "default"
  201. data = '{"' + str(self.project.id) + '":-1}'
  202. res = self.client.put(url, data, content_type="application/json")
  203. self.assertEqual(res.status_code, 204)
  204. # Default deletes the row
  205. self.assertEqual(UserProjectAlert.objects.all().count(), 0)
  206. def test_reset_password(self):
  207. """
  208. Social accounts weren't getting reset password emails. This
  209. approximates the issue by testing an account that has an
  210. unusable password.
  211. """
  212. url = reverse("rest_password_reset")
  213. # Normal behavior
  214. self.client.post(url, {"email": self.user.email})
  215. self.assertEqual(len(mail.outbox), 1)
  216. user_without_password = baker.make("users.User")
  217. user_without_password.set_unusable_password()
  218. user_without_password.save()
  219. self.assertFalse(user_without_password.has_usable_password())
  220. self.client.post(url, {"email": user_without_password.email})
  221. self.assertEqual(len(mail.outbox), 2)