tests.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  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",
  69. group__project__organization=self.organization,
  70. )
  71. baker.make(
  72. "releases.ReleaseFile",
  73. file__blob__size=1000000,
  74. release__organization=self.organization,
  75. _quantity=2,
  76. )
  77. res = self.client.get(url)
  78. self.assertEqual(
  79. res.data,
  80. {
  81. "eventCount": 1,
  82. "fileSizeMB": 2,
  83. "transactionEventCount": 1,
  84. "uptimeCheckEventCount": 0,
  85. },
  86. )
  87. def test_events_count_without_customer(self):
  88. """
  89. Due to async nature of Stripe integration, a customer may not exist
  90. """
  91. baker.make("djstripe.Subscription", livemode=False)
  92. url = (
  93. reverse("subscription-detail", args=[self.organization.slug])
  94. + "events_count/"
  95. )
  96. res = self.client.get(url)
  97. self.assertEqual(sum(res.data.values()), 0)
  98. @patch("djstripe.models.Customer.subscribe")
  99. def test_create(self, djstripe_customer_subscribe_mock):
  100. customer = baker.make(
  101. "djstripe.Customer", subscriber=self.organization, livemode=False
  102. )
  103. plan = baker.make("djstripe.Plan", amount=0)
  104. subscription = baker.make(
  105. "djstripe.Subscription",
  106. customer=customer,
  107. livemode=False,
  108. )
  109. djstripe_customer_subscribe_mock.return_value = subscription
  110. data = {"plan": plan.id, "organization": self.organization.id}
  111. res = self.client.post(self.url, data)
  112. self.assertEqual(res.data["plan"], plan.id)
  113. def test_create_invalid_org(self):
  114. """Only owners may create subscriptions"""
  115. user = baker.make("users.user") # Non owner member
  116. plan = baker.make("djstripe.Plan", amount=0)
  117. self.organization.add_user(user)
  118. self.client.force_login(user)
  119. data = {"plan": plan.id, "organization": self.organization.id}
  120. res = self.client.post(self.url, data)
  121. self.assertEqual(res.status_code, 400)
  122. class ProductAPITestCase(APITestCase):
  123. def test_product_list(self):
  124. plan = baker.make(
  125. "djstripe.Plan",
  126. amount=0,
  127. livemode=False,
  128. active=True,
  129. product__active=True,
  130. product__livemode=False,
  131. product__metadata={"events": 10},
  132. )
  133. inactive_plan = baker.make(
  134. "djstripe.Plan",
  135. amount=0,
  136. livemode=False,
  137. active=False,
  138. product__active=False,
  139. product__livemode=False,
  140. product__metadata={"events": 10},
  141. )
  142. user = baker.make("users.user")
  143. self.client.force_login(user)
  144. res = self.client.get(reverse("product-list"))
  145. self.assertContains(res, plan.id)
  146. self.assertNotContains(res, inactive_plan.id)
  147. class StripeAPITestCase(APITestCase):
  148. @skipIf(
  149. settings.STRIPE_TEST_PUBLIC_KEY == "fake", "requires real Stripe test API key"
  150. )
  151. def test_create_checkout(self):
  152. url = reverse("create-stripe-subscription-checkout")
  153. plan = baker.make(
  154. "djstripe.Plan",
  155. amount=1,
  156. livemode=False,
  157. active=True,
  158. id="price_HNfVNr3ohLWkmv",
  159. description="Small - 100k events",
  160. product__active=True,
  161. product__livemode=False,
  162. )
  163. user = baker.make("users.user")
  164. organization = baker.make("organizations_ext.Organization")
  165. organization.add_user(user)
  166. self.client.force_login(user)
  167. data = {"plan": plan.id, "organization": organization.id}
  168. res = self.client.post(url, data)
  169. self.assertEqual(res.status_code, 200)
  170. @skipIf(
  171. settings.STRIPE_TEST_PUBLIC_KEY == "fake", "requires real Stripe test API key"
  172. )
  173. def test_manage_billing(self):
  174. url = reverse("create-billing-portal")
  175. user = baker.make("users.user")
  176. organization = baker.make("organizations_ext.Organization")
  177. organization.add_user(user)
  178. self.client.force_login(user)
  179. data = {"organization": organization.id}
  180. res = self.client.post(url, data)
  181. self.assertEqual(res.status_code, 200)
  182. class SubscriptionIntegrationAPITestCase(APITestCase):
  183. def setUp(self):
  184. self.user = baker.make("users.user")
  185. self.organization = baker.make("organizations_ext.Organization")
  186. self.organization.add_user(self.user)
  187. # Make these in this manner to avoid syncing data to stripe actual
  188. self.plan = baker.make("djstripe.Plan", active=True, amount=0)
  189. self.customer = baker.make(
  190. "djstripe.Customer", subscriber=self.organization, livemode=False
  191. )
  192. self.client.force_login(self.user)
  193. self.list_url = reverse("subscription-list")
  194. self.detail_url = reverse("subscription-detail", args=[self.organization.slug])
  195. @patch("djstripe.models.Customer.subscribe")
  196. def test_new_org_flow(self, djstripe_customer_subscribe_mock):
  197. """Test checking if subscription exists and when not, creating a free tier one"""
  198. res = self.client.get(self.detail_url)
  199. self.assertFalse(res.data["id"]) # No subscription, user should create one
  200. subscription = baker.make(
  201. "djstripe.Subscription",
  202. customer=self.customer,
  203. livemode=False,
  204. )
  205. djstripe_customer_subscribe_mock.return_value = subscription
  206. data = {"plan": self.plan.id, "organization": self.organization.id}
  207. res = self.client.post(self.list_url, data)
  208. self.assertContains(res, self.plan.id, status_code=201)
  209. djstripe_customer_subscribe_mock.assert_called_once()
  210. res = self.client.get(self.detail_url)
  211. self.assertEqual(res.data["id"], subscription.id)