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.

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