PageRenderTime 49ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/go/billing/tests/test_forms.py

https://github.com/praekelt/vumi-go
Python | 226 lines | 188 code | 38 blank | 0 comment | 4 complexity | c419b70dd82eb1438b7caea970085cfd MD5 | raw file
  1. from decimal import Decimal, Context
  2. from go.vumitools.tests.helpers import djangotest_imports
  3. with djangotest_imports(globals()):
  4. from django.forms.models import modelformset_factory
  5. from go.base.tests.helpers import GoDjangoTestCase, DjangoVumiApiHelper
  6. from go.billing import settings as app_settings
  7. from go.billing.forms import (
  8. MessageCostForm, cost_rounded_to_zero, BaseCreditLoadFormSet,
  9. CreditLoadForm, TagPoolForm)
  10. from go.billing.models import TagPool, Account, Transaction
  11. class TestBillingFormsModule(GoDjangoTestCase):
  12. def test_cost_rounded_to_zero(self):
  13. for value, result in [
  14. ('1.0', False), ('0.0', False),
  15. ('0.1', False), ('0.05', True),
  16. ]:
  17. context = Context()
  18. d = Decimal(value).quantize(Decimal('0.1'), context=context)
  19. if result:
  20. self.assertTrue(cost_rounded_to_zero(d, context),
  21. "value was %r" % (value,))
  22. else:
  23. self.assertFalse(cost_rounded_to_zero(d, context),
  24. "value was %r" % (value,))
  25. class TestMessageCostForm(GoDjangoTestCase):
  26. def setUp(self):
  27. self.vumi_helper = self.add_helper(DjangoVumiApiHelper())
  28. self.user_helper = self.vumi_helper.make_django_user()
  29. self.user = self.user_helper.get_django_user()
  30. self.tag_pool = TagPool(name=u"pool", description=u"description")
  31. self.tag_pool.save()
  32. self.account = Account.objects.get(user=self.user)
  33. def patch_quantization(self, quantization):
  34. self.monkey_patch(
  35. app_settings, 'QUANTIZATION_EXPONENT', quantization)
  36. def mk_form(self, **kw):
  37. data = {
  38. 'tag_pool': self.tag_pool.pk,
  39. 'message_direction': 'Inbound',
  40. 'message_cost': '0.0',
  41. 'storage_cost': '0.0',
  42. 'session_cost': '0.0',
  43. 'session_unit_cost': '0.0',
  44. 'session_unit_length': '0.0',
  45. 'session_unit_time': '0.0',
  46. 'markup_percent': '0.0',
  47. }
  48. data.update(kw)
  49. return MessageCostForm(data=data)
  50. def test_validate_no_costs(self):
  51. mc = self.mk_form(markup_percent='10.0')
  52. self.assertTrue(mc.is_valid())
  53. def test_validate_message_cost_not_rounded_to_zero(self):
  54. mc = self.mk_form(message_cost='1.0', markup_percent='10.0')
  55. self.assertTrue(mc.is_valid())
  56. def test_validate_message_cost_rounded_to_zero(self):
  57. self.patch_quantization(Decimal('0.1'))
  58. mc = self.mk_form(message_cost='0.001',
  59. markup_percent='0.1')
  60. self.assertFalse(mc.is_valid())
  61. self.assertEqual(mc.errors, {
  62. '__all__': [
  63. 'The resulting cost per message (in credits) was rounded'
  64. ' to 0.',
  65. ],
  66. })
  67. def test_validate_storage_cost_not_rounded_to_zero(self):
  68. mc = self.mk_form(storage_cost='1.0', markup_percent='10.0')
  69. self.assertTrue(mc.is_valid())
  70. def test_validate_storage_cost_rounded_to_zero(self):
  71. self.patch_quantization(Decimal('0.1'))
  72. mc = self.mk_form(storage_cost='0.001',
  73. markup_percent='0.1')
  74. self.assertFalse(mc.is_valid())
  75. self.assertEqual(mc.errors, {
  76. '__all__': [
  77. 'The resulting storage cost per message (in credits) was'
  78. ' rounded to 0.',
  79. ],
  80. })
  81. def test_validate_session_cost_not_rounded_to_zero(self):
  82. mc = self.mk_form(session_cost='1.0', markup_percent='10.0')
  83. self.assertTrue(mc.is_valid())
  84. def test_validate_session_cost_rounded_to_zero(self):
  85. self.patch_quantization(Decimal('0.1'))
  86. mc = self.mk_form(session_cost='0.001',
  87. markup_percent='0.1')
  88. self.assertFalse(mc.is_valid())
  89. self.assertEqual(mc.errors, {
  90. '__all__': [
  91. 'The resulting cost per session (in credits) was rounded'
  92. ' to 0.',
  93. ],
  94. })
  95. def test_validate_session_length_cost_not_rounded_to_zero(self):
  96. mc = self.mk_form(session_unit_cost='1.0', markup_percent='10.0')
  97. self.assertTrue(mc.is_valid())
  98. def test_validate_session_length_cost_rounded_to_zero(self):
  99. self.patch_quantization(Decimal('0.1'))
  100. mc = self.mk_form(session_unit_cost='0.001', markup_percent='0.1')
  101. self.assertFalse(mc.is_valid())
  102. self.assertEqual(mc.errors, {
  103. '__all__': [
  104. 'The resulting cost per session time length (in credits) was'
  105. ' rounded to 0.',
  106. ],
  107. })
  108. def test_validate_no_account_and_no_tag_pool(self):
  109. mc = self.mk_form(account=None, tag_pool=None)
  110. self.assertTrue(mc.is_valid())
  111. def test_validate_account_and_no_tag_pool(self):
  112. mc = self.mk_form(account=self.account.pk, tag_pool=None)
  113. self.assertFalse(mc.is_valid())
  114. self.assertEqual(mc.errors, {
  115. '__all__': [
  116. "Message costs with an empty tag pool value and a non-empty"
  117. " account value are not currently supported by the billing"
  118. " API's message cost look up.",
  119. ],
  120. })
  121. class TestCreditLoadForm(GoDjangoTestCase):
  122. def setUp(self):
  123. self.vumi_helper = self.add_helper(DjangoVumiApiHelper())
  124. self.user_helper = self.vumi_helper.make_django_user()
  125. self.user = self.user_helper.get_django_user()
  126. self.account = Account.objects.get(user=self.user)
  127. def mk_formset(self, **kw):
  128. CreditLoadFormSet = modelformset_factory(
  129. Account, form=CreditLoadForm, formset=BaseCreditLoadFormSet,
  130. fields=('account_number',), extra=0)
  131. data = {
  132. 'form-TOTAL_FORMS': '1',
  133. 'form-INITIAL_FORMS': '1',
  134. 'form-0-id': self.account.id,
  135. 'form-0-account_number': self.account.account_number,
  136. 'form-0-credit_amount': '10',
  137. }
  138. data.update(kw)
  139. queryset = Account.objects.filter(pk=self.account.pk)
  140. formset = CreditLoadFormSet(data, queryset=queryset)
  141. return formset
  142. def test_load_credits(self):
  143. self.account.last_topup_balance = Decimal('20.0')
  144. self.account.save()
  145. formset = self.mk_formset()
  146. self.assertTrue(formset.is_valid())
  147. [form] = list(formset)
  148. self.assertEqual(self.account.credit_balance, Decimal('0.0'))
  149. self.assertEqual(self.account.last_topup_balance, Decimal('20.0'))
  150. form.load_credits()
  151. account = Account.objects.get(user=self.user)
  152. self.assertEqual(account.credit_balance, Decimal('10.0'))
  153. self.assertEqual(account.last_topup_balance, Decimal('10.0'))
  154. [transaction] = Transaction.objects.filter(
  155. account_number=self.account.account_number).all()
  156. self.assertEqual(transaction.status, Transaction.STATUS_COMPLETED)
  157. self.assertEqual(transaction.credit_amount, Decimal('10.0'))
  158. class TestTagPoolForm(GoDjangoTestCase):
  159. def setUp(self):
  160. self.vumi_helper = self.add_helper(DjangoVumiApiHelper())
  161. self.vumi_helper.setup_tagpool('pool', ['tag-1', 'tag-2'])
  162. def mk_form(self, **kw):
  163. data = {
  164. 'name': 'pool',
  165. 'description': 'A dummy tag pool',
  166. }
  167. data.update(kw)
  168. return TagPoolForm(data=data)
  169. def test_name_choices(self):
  170. form = TagPoolForm()
  171. self.assertEqual(form.fields['name'].choices, [
  172. ('', '---------'),
  173. ('pool', 'pool'),
  174. ])
  175. def test_valid_form(self):
  176. form = self.mk_form()
  177. self.assertTrue(form.is_valid())
  178. def test_invalid_form(self):
  179. form = self.mk_form(name='unknown')
  180. self.assertFalse(form.is_valid())
  181. self.assertEqual(form.errors, {
  182. 'name': [
  183. 'Select a valid choice. unknown is not one of the available'
  184. ' choices.',
  185. ]
  186. })