test.py 10 KB

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