You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

233 lines
8.6 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. from unittest.mock import patch
  2. from hc.payments.models import Subscription
  3. from hc.test import BaseTestCase
  4. class UpdateSubscriptionTestCase(BaseTestCase):
  5. def _setup_mock(self, mock):
  6. """ Set up Braintree calls that the controller will use. """
  7. mock.Subscription.create.return_value.is_success = True
  8. mock.Subscription.create.return_value.subscription.id = "t-sub-id"
  9. def run_update(self, plan_id="P20", nonce="fake-nonce"):
  10. form = {"plan_id": plan_id, "nonce": nonce}
  11. self.client.login(username="[email protected]", password="password")
  12. return self.client.post("/pricing/update/", form, follow=True)
  13. @patch("hc.payments.models.braintree")
  14. def test_it_works(self, mock):
  15. self._setup_mock(mock)
  16. self.profile.sms_limit = 0
  17. self.profile.sms_sent = 1
  18. self.profile.save()
  19. r = self.run_update()
  20. self.assertRedirects(r, "/accounts/profile/billing/")
  21. self.assertContains(r, "Your billing plan has been updated!")
  22. # Subscription should be filled out:
  23. sub = Subscription.objects.get(user=self.alice)
  24. self.assertEqual(sub.subscription_id, "t-sub-id")
  25. self.assertEqual(sub.plan_id, "P20")
  26. self.assertEqual(sub.plan_name, "Business ($20 / month)")
  27. # User's profile should have a higher limits
  28. self.profile.refresh_from_db()
  29. self.assertEqual(self.profile.ping_log_limit, 1000)
  30. self.assertEqual(self.profile.check_limit, 100)
  31. self.assertEqual(self.profile.team_limit, 9)
  32. self.assertEqual(self.profile.sms_limit, 50)
  33. self.assertEqual(self.profile.sms_sent, 0)
  34. # braintree.Subscription.cancel should have not been called
  35. # because there was no previous subscription
  36. self.assertFalse(mock.Subscription.cancel.called)
  37. self.assertTrue(mock.Subscription.create.called)
  38. @patch("hc.payments.models.braintree")
  39. def test_supporter_works(self, mock):
  40. self._setup_mock(mock)
  41. self.profile.sms_limit = 0
  42. self.profile.sms_sent = 1
  43. self.profile.save()
  44. r = self.run_update("S5")
  45. self.assertRedirects(r, "/accounts/profile/billing/")
  46. # Subscription should be filled out:
  47. sub = Subscription.objects.get(user=self.alice)
  48. self.assertEqual(sub.subscription_id, "t-sub-id")
  49. self.assertEqual(sub.plan_id, "S5")
  50. self.assertEqual(sub.plan_name, "Supporter ($5 / month)")
  51. # User's profile should have adjusted limits
  52. self.profile.refresh_from_db()
  53. self.assertEqual(self.profile.ping_log_limit, 1000)
  54. self.assertEqual(self.profile.check_limit, 20)
  55. self.assertEqual(self.profile.team_limit, 2)
  56. self.assertEqual(self.profile.sms_limit, 5)
  57. self.assertEqual(self.profile.sms_sent, 0)
  58. # braintree.Subscription.cancel should have not been called
  59. assert not mock.Subscription.cancel.called
  60. @patch("hc.payments.models.braintree")
  61. def test_yearly_works(self, mock):
  62. self._setup_mock(mock)
  63. self.profile.sms_limit = 0
  64. self.profile.sms_sent = 1
  65. self.profile.save()
  66. r = self.run_update("Y192")
  67. self.assertRedirects(r, "/accounts/profile/billing/")
  68. # Subscription should be filled out:
  69. sub = Subscription.objects.get(user=self.alice)
  70. self.assertEqual(sub.subscription_id, "t-sub-id")
  71. self.assertEqual(sub.plan_id, "Y192")
  72. self.assertEqual(sub.plan_name, "Business ($192 / year)")
  73. # User's profile should have a higher limits
  74. self.profile.refresh_from_db()
  75. self.assertEqual(self.profile.ping_log_limit, 1000)
  76. self.assertEqual(self.profile.check_limit, 100)
  77. self.assertEqual(self.profile.team_limit, 9)
  78. self.assertEqual(self.profile.sms_limit, 50)
  79. self.assertEqual(self.profile.sms_sent, 0)
  80. # braintree.Subscription.cancel should have not been called
  81. assert not mock.Subscription.cancel.called
  82. @patch("hc.payments.models.braintree")
  83. def test_plus_works(self, mock):
  84. self._setup_mock(mock)
  85. self.profile.sms_limit = 0
  86. self.profile.sms_sent = 1
  87. self.profile.save()
  88. r = self.run_update("P80")
  89. self.assertRedirects(r, "/accounts/profile/billing/")
  90. # Subscription should be filled out:
  91. sub = Subscription.objects.get(user=self.alice)
  92. self.assertEqual(sub.subscription_id, "t-sub-id")
  93. self.assertEqual(sub.plan_id, "P80")
  94. self.assertEqual(sub.plan_name, "Business Plus ($80 / month)")
  95. # User's profile should have a higher limits
  96. self.profile.refresh_from_db()
  97. self.assertEqual(self.profile.ping_log_limit, 1000)
  98. self.assertEqual(self.profile.check_limit, 1000)
  99. self.assertEqual(self.profile.team_limit, 500)
  100. self.assertEqual(self.profile.sms_limit, 500)
  101. self.assertEqual(self.profile.sms_sent, 0)
  102. # braintree.Subscription.cancel should have not been called
  103. assert not mock.Subscription.cancel.called
  104. @patch("hc.payments.models.braintree")
  105. def test_it_cancels(self, mock):
  106. self._setup_mock(mock)
  107. self.sub = Subscription(user=self.alice)
  108. self.sub.subscription_id = "test-id"
  109. self.sub.plan_id = "P20"
  110. self.sub.plan_name = "Business ($20/mo)"
  111. self.sub.save()
  112. self.profile.sms_limit = 1
  113. self.profile.sms_sent = 1
  114. self.profile.save()
  115. r = self.run_update("")
  116. self.assertRedirects(r, "/accounts/profile/billing/")
  117. self.assertContains(r, "Your billing plan has been updated!")
  118. # Subscription should be cleared
  119. sub = Subscription.objects.get(user=self.alice)
  120. self.assertEqual(sub.subscription_id, "")
  121. self.assertEqual(sub.plan_id, "")
  122. self.assertEqual(sub.plan_name, "")
  123. # User's profile should have standard limits
  124. self.profile.refresh_from_db()
  125. self.assertEqual(self.profile.ping_log_limit, 100)
  126. self.assertEqual(self.profile.check_limit, 20)
  127. self.assertEqual(self.profile.team_limit, 2)
  128. self.assertEqual(self.profile.sms_limit, 5)
  129. self.assertTrue(mock.Subscription.cancel.called)
  130. def test_bad_plan_id(self):
  131. r = self.run_update(plan_id="this-is-wrong")
  132. self.assertEqual(r.status_code, 400)
  133. @patch("hc.payments.models.braintree")
  134. def test_it_cancels_previous_subscription(self, mock):
  135. self._setup_mock(mock)
  136. sub = Subscription(user=self.alice)
  137. sub.subscription_id = "prev-sub"
  138. sub.save()
  139. r = self.run_update()
  140. self.assertRedirects(r, "/accounts/profile/billing/")
  141. self.assertTrue(mock.Subscription.cancel.called)
  142. @patch("hc.payments.models.braintree")
  143. def test_subscription_creation_failure(self, mock):
  144. mock.Subscription.create.return_value.is_success = False
  145. mock.Subscription.create.return_value.message = "sub failure"
  146. r = self.run_update()
  147. self.assertRedirects(r, "/accounts/profile/billing/")
  148. self.assertContains(r, "sub failure")
  149. @patch("hc.payments.models.braintree")
  150. def test_failed_plan_change_resets_limits(self, mock):
  151. # Initial state: the user has a subscription and a high check limit:
  152. sub = Subscription.objects.for_user(self.alice)
  153. sub.subscription_id = "old-sub-id"
  154. sub.save()
  155. self.profile.check_limit = 1000
  156. self.profile.save()
  157. # Simulate a subscription creation failure:
  158. mock.Subscription.create.return_value.is_success = False
  159. mock.Subscription.create.return_value.message = "sub failure"
  160. r = self.run_update()
  161. # It should cancel the current plan
  162. self.assertTrue(mock.Subscription.cancel.called)
  163. # It should clear out the limits:
  164. self.profile.refresh_from_db()
  165. self.assertEqual(self.profile.check_limit, 20)
  166. # And it should show the error message from API:
  167. self.assertRedirects(r, "/accounts/profile/billing/")
  168. self.assertContains(r, "sub failure")
  169. @patch("hc.payments.models.braintree")
  170. def test_it_updates_payment_method(self, mock):
  171. # Initial state: the user has a subscription and a high check limit:
  172. sub = Subscription.objects.for_user(self.alice)
  173. sub.plan_id = "P20"
  174. sub.subscription_id = "old-sub-id"
  175. sub.save()
  176. r = self.run_update()
  177. # It should update the existing subscription
  178. self.assertTrue(mock.Subscription.update.called)
  179. self.assertRedirects(r, "/accounts/profile/billing/")
  180. self.assertContains(r, "Your payment method has been updated!")