tests.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. from unittest.mock import patch
  2. from unittest import skipIf
  3. from django.shortcuts import reverse
  4. from django.conf import settings
  5. from django.utils import timezone
  6. from rest_framework.test import APITestCase
  7. from model_bakery import baker
  8. from freezegun import freeze_time
  9. from glitchtip import test_utils # pylint: disable=unused-import
  10. class SubscriptionAPITestCase(APITestCase):
  11. def setUp(self):
  12. self.user = baker.make("users.user")
  13. self.organization = baker.make("organizations_ext.Organization")
  14. self.organization.add_user(self.user)
  15. self.client.force_login(self.user)
  16. self.url = reverse("subscription-list")
  17. def test_list(self):
  18. customer = baker.make("djstripe.Customer", subscriber=self.organization)
  19. subscription = baker.make(
  20. "djstripe.Subscription", customer=customer, livemode=False
  21. )
  22. subscription2 = baker.make("djstripe.Subscription", livemode=False)
  23. subscription3 = baker.make(
  24. "djstripe.Subscription", customer=customer, livemode=True
  25. )
  26. res = self.client.get(self.url)
  27. self.assertContains(res, subscription.id)
  28. self.assertNotContains(res, subscription2.id)
  29. self.assertNotContains(res, subscription3.id)
  30. def test_detail(self):
  31. customer = baker.make("djstripe.Customer", subscriber=self.organization)
  32. subscription = baker.make(
  33. "djstripe.Subscription",
  34. customer=customer,
  35. livemode=False,
  36. created=timezone.make_aware(timezone.datetime(2020, 1, 2)),
  37. )
  38. # Should only get most recent
  39. baker.make(
  40. "djstripe.Subscription",
  41. customer=customer,
  42. livemode=False,
  43. created=timezone.make_aware(timezone.datetime(2020, 1, 1)),
  44. )
  45. baker.make("djstripe.Subscription")
  46. url = reverse("subscription-detail", args=[self.organization.slug])
  47. res = self.client.get(url)
  48. self.assertContains(res, subscription.id)
  49. def test_events_count(self):
  50. customer = baker.make("djstripe.Customer", subscriber=self.organization)
  51. baker.make(
  52. "djstripe.Subscription",
  53. customer=customer,
  54. livemode=False,
  55. current_period_start=timezone.make_aware(timezone.datetime(2020, 1, 2)),
  56. current_period_end=timezone.make_aware(timezone.datetime(2020, 2, 2)),
  57. )
  58. url = (
  59. reverse("subscription-detail", args=[self.organization.slug])
  60. + "events_count/"
  61. )
  62. with freeze_time(timezone.datetime(2020, 3, 1)):
  63. baker.make("events.Event", issue__project__organization=self.organization)
  64. with freeze_time(timezone.datetime(2020, 1, 5)):
  65. baker.make("events.Event")
  66. baker.make("events.Event", issue__project__organization=self.organization)
  67. baker.make(
  68. "performance.TransactionEvent", group__project__organization=self.organization
  69. )
  70. res = self.client.get(url)
  71. self.assertEqual(
  72. res.data,
  73. {"eventCount": 1, "transactionEventCount": 1, "uptimeCheckEventCount": 0},
  74. )
  75. def test_events_count_without_customer(self):
  76. """
  77. Due to async nature of Stripe integration, a customer may not exist
  78. """
  79. baker.make("djstripe.Subscription", livemode=False)
  80. url = (
  81. reverse("subscription-detail", args=[self.organization.slug])
  82. + "events_count/"
  83. )
  84. res = self.client.get(url)
  85. self.assertEqual(sum(res.data.values()), 0)
  86. @patch("djstripe.models.Customer.subscribe")
  87. def test_create(self, djstripe_customer_subscribe_mock):
  88. customer = baker.make(
  89. "djstripe.Customer", subscriber=self.organization, livemode=False
  90. )
  91. plan = baker.make("djstripe.Plan", amount=0)
  92. subscription = baker.make(
  93. "djstripe.Subscription", customer=customer, livemode=False,
  94. )
  95. djstripe_customer_subscribe_mock.return_value = subscription
  96. data = {"plan": plan.id, "organization": self.organization.id}
  97. res = self.client.post(self.url, data)
  98. self.assertEqual(res.data["plan"], plan.id)
  99. def test_create_invalid_org(self):
  100. """ Only owners may create subscriptions """
  101. user = baker.make("users.user") # Non owner member
  102. plan = baker.make("djstripe.Plan", amount=0)
  103. self.organization.add_user(user)
  104. self.client.force_login(user)
  105. data = {"plan": plan.id, "organization": self.organization.id}
  106. res = self.client.post(self.url, data)
  107. self.assertEqual(res.status_code, 400)
  108. class ProductAPITestCase(APITestCase):
  109. def test_product_list(self):
  110. plan = baker.make(
  111. "djstripe.Plan",
  112. amount=0,
  113. livemode=False,
  114. active=True,
  115. product__active=True,
  116. product__livemode=False,
  117. product__metadata={"events": 10},
  118. )
  119. inactive_plan = baker.make(
  120. "djstripe.Plan",
  121. amount=0,
  122. livemode=False,
  123. active=False,
  124. product__active=False,
  125. product__livemode=False,
  126. product__metadata={"events": 10},
  127. )
  128. user = baker.make("users.user")
  129. self.client.force_login(user)
  130. res = self.client.get(reverse("product-list"))
  131. self.assertContains(res, plan.id)
  132. self.assertNotContains(res, inactive_plan.id)
  133. class StripeAPITestCase(APITestCase):
  134. @skipIf(
  135. settings.STRIPE_TEST_PUBLIC_KEY == "fake", "requires real Stripe test API key"
  136. )
  137. def test_create_checkout(self):
  138. url = reverse("create-stripe-subscription-checkout")
  139. plan = baker.make(
  140. "djstripe.Plan",
  141. amount=1,
  142. livemode=False,
  143. active=True,
  144. id="price_HNfVNr3ohLWkmv",
  145. description="Small - 100k events",
  146. product__active=True,
  147. product__livemode=False,
  148. )
  149. user = baker.make("users.user")
  150. organization = baker.make("organizations_ext.Organization")
  151. organization.add_user(user)
  152. self.client.force_login(user)
  153. data = {"plan": plan.id, "organization": organization.id}
  154. res = self.client.post(url, data)
  155. self.assertEqual(res.status_code, 200)
  156. @skipIf(
  157. settings.STRIPE_TEST_PUBLIC_KEY == "fake", "requires real Stripe test API key"
  158. )
  159. def test_manage_billing(self):
  160. url = reverse("create-billing-portal")
  161. user = baker.make("users.user")
  162. organization = baker.make("organizations_ext.Organization")
  163. organization.add_user(user)
  164. self.client.force_login(user)
  165. data = {"organization": organization.id}
  166. res = self.client.post(url, data)
  167. self.assertEqual(res.status_code, 200)
  168. class SubscriptionIntegrationAPITestCase(APITestCase):
  169. def setUp(self):
  170. self.user = baker.make("users.user")
  171. self.organization = baker.make("organizations_ext.Organization")
  172. self.organization.add_user(self.user)
  173. # Make these in this manner to avoid syncing data to stripe actual
  174. self.plan = baker.make("djstripe.Plan", active=True, amount=0)
  175. self.customer = baker.make(
  176. "djstripe.Customer", subscriber=self.organization, livemode=False
  177. )
  178. self.client.force_login(self.user)
  179. self.list_url = reverse("subscription-list")
  180. self.detail_url = reverse("subscription-detail", args=[self.organization.slug])
  181. @patch("djstripe.models.Customer.subscribe")
  182. def test_new_org_flow(self, djstripe_customer_subscribe_mock):
  183. """ Test checking if subscription exists and when not, creating a free tier one """
  184. res = self.client.get(self.detail_url)
  185. self.assertFalse(res.data["id"]) # No subscription, user should create one
  186. subscription = baker.make(
  187. "djstripe.Subscription", customer=self.customer, livemode=False,
  188. )
  189. djstripe_customer_subscribe_mock.return_value = subscription
  190. data = {"plan": self.plan.id, "organization": self.organization.id}
  191. res = self.client.post(self.list_url, data)
  192. self.assertContains(res, self.plan.id, status_code=201)
  193. djstripe_customer_subscribe_mock.assert_called_once()
  194. res = self.client.get(self.detail_url)
  195. self.assertEqual(res.data["id"], subscription.id)