您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

test_models.py 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. import datetime
  2. from decimal import Decimal as D
  3. import pytest
  4. from django.core import exceptions
  5. from django.test import TestCase
  6. from django.utils.timezone import utc
  7. from django.utils.translation import gettext_lazy as _
  8. from oscar.apps.voucher.models import Voucher
  9. from oscar.core.compat import get_user_model
  10. from oscar.core.loading import get_model
  11. from oscar.test.factories import (
  12. ConditionFactory, OrderFactory, RangeFactory, UserFactory, VoucherFactory,
  13. VoucherSetFactory, create_basket, create_offer, create_product)
  14. START_DATETIME = datetime.datetime(2011, 1, 1).replace(tzinfo=utc)
  15. END_DATETIME = datetime.datetime(2012, 1, 1).replace(tzinfo=utc)
  16. User = get_user_model()
  17. ConditionalOffer = get_model('offer', 'ConditionalOffer')
  18. class TestSavingAVoucher(TestCase):
  19. def test_saves_code_as_uppercase(self):
  20. voucher = VoucherFactory(
  21. code='lower',
  22. start_datetime=START_DATETIME, end_datetime=END_DATETIME)
  23. self.assertEqual('LOWER', voucher.code)
  24. def test_verifies_dates_are_sensible(self):
  25. with self.assertRaises(exceptions.ValidationError):
  26. voucher = Voucher.objects.create(
  27. code='lower', start_datetime=END_DATETIME,
  28. end_datetime=START_DATETIME)
  29. voucher.clean()
  30. class TestAVoucher(TestCase):
  31. def setUp(self):
  32. self.voucher = VoucherFactory(
  33. start_datetime=START_DATETIME, end_datetime=END_DATETIME)
  34. def test_is_active_between_start_and_end_dates(self):
  35. test = datetime.datetime(2011, 6, 10).replace(tzinfo=utc)
  36. self.assertTrue(self.voucher.is_active(test))
  37. def test_is_active_on_end_date(self):
  38. self.assertTrue(self.voucher.is_active(END_DATETIME))
  39. def test_is_active_on_start_date(self):
  40. self.assertTrue(self.voucher.is_active(START_DATETIME))
  41. def test_is_inactive_outside_of_start_and_end_dates(self):
  42. test = datetime.datetime(2012, 3, 10).replace(tzinfo=utc)
  43. self.assertFalse(self.voucher.is_active(test))
  44. def test_increments_total_discount_when_recording_usage(self):
  45. self.voucher.record_discount({'discount': D('10.00')})
  46. self.assertEqual(self.voucher.total_discount, D('10.00'))
  47. self.voucher.record_discount({'discount': D('10.00')})
  48. self.assertEqual(self.voucher.total_discount, D('20.00'))
  49. class TestMultiuseVoucher(TestCase):
  50. def setUp(self):
  51. self.voucher = VoucherFactory(usage=Voucher.MULTI_USE)
  52. def test_is_available_to_same_user_multiple_times(self):
  53. user, order = UserFactory(), OrderFactory()
  54. for i in range(10):
  55. self.voucher.record_usage(order, user)
  56. is_voucher_available_to_user, __ = self.voucher.is_available_to_user(user=user)
  57. self.assertTrue(is_voucher_available_to_user)
  58. class TestOncePerCustomerVoucher(TestCase):
  59. def setUp(self):
  60. self.voucher = VoucherFactory(usage=Voucher.ONCE_PER_CUSTOMER)
  61. def test_is_available_to_a_user_once(self):
  62. user, order = UserFactory(), OrderFactory()
  63. is_voucher_available_to_user, __ = self.voucher.is_available_to_user(user=user)
  64. self.assertTrue(is_voucher_available_to_user)
  65. self.voucher.record_usage(order, user)
  66. is_voucher_available_to_user, __ = self.voucher.is_available_to_user(user=user)
  67. self.assertFalse(is_voucher_available_to_user)
  68. def test_is_available_to_different_users(self):
  69. users, order = [UserFactory(), UserFactory()], OrderFactory()
  70. for user in users:
  71. is_voucher_available_to_user, __ = self.voucher.is_available_to_user(user=user)
  72. self.assertTrue(is_voucher_available_to_user)
  73. self.voucher.record_usage(order, user)
  74. is_voucher_available_to_user, __ = self.voucher.is_available_to_user(user=user)
  75. self.assertFalse(is_voucher_available_to_user)
  76. class TestVoucherDelete(TestCase):
  77. def setUp(self):
  78. product = create_product(price=100)
  79. self.offer_range = RangeFactory(products=[product])
  80. self.offer_condition = ConditionFactory(range=self.offer_range, value=2)
  81. def test_related_offer_deleted(self):
  82. # Voucher with offer name corresponding to it as used in the dashboard
  83. voucher_name = "Voucher"
  84. voucher = VoucherFactory(name=voucher_name, code="VOUCHER")
  85. voucher.offers.add(
  86. create_offer(
  87. name=_("Offer for voucher '%s'") % voucher_name,
  88. offer_type='Voucher',
  89. range=self.offer_range,
  90. condition=self.offer_condition
  91. )
  92. )
  93. voucher.delete()
  94. self.assertFalse(
  95. ConditionalOffer.objects.filter(
  96. name=_("Offer for voucher '%s'") % voucher_name,
  97. offer_type=ConditionalOffer.VOUCHER
  98. ).exists())
  99. def test_related_offer_different_name_not_deleted(self):
  100. # Voucher with offer named differently
  101. voucher = VoucherFactory(name="Voucher", code="VOUCHER")
  102. voucher.offers.add(
  103. create_offer(
  104. name="Different name test",
  105. offer_type='Voucher',
  106. range=self.offer_range,
  107. condition=self.offer_condition
  108. )
  109. )
  110. offer_ids = list(voucher.offers.all().values_list('pk', flat=True))
  111. voucher.delete()
  112. count_offers = ConditionalOffer.objects.filter(id__in=offer_ids).count()
  113. assert len(offer_ids) == count_offers
  114. def test_related_offer_different_type_not_deleted(self):
  115. # Voucher with offer not of type "Voucher"
  116. voucher_name = "Voucher"
  117. voucher = VoucherFactory(name=voucher_name, code="VOUCHER")
  118. voucher.offers.add(
  119. create_offer(
  120. name=_("Offer for voucher '%s'") % voucher_name,
  121. offer_type='Site',
  122. range=self.offer_range,
  123. condition=self.offer_condition
  124. )
  125. )
  126. offer_ids = list(voucher.offers.all().values_list('pk', flat=True))
  127. voucher.delete()
  128. count_offers = ConditionalOffer.objects.filter(id__in=offer_ids).count()
  129. assert len(offer_ids) == count_offers
  130. def test_multiple_related_offers_not_deleted(self):
  131. # Voucher with already used offer
  132. voucher_name = "Voucher 1"
  133. offer = create_offer(
  134. name=_("Offer for voucher '%s'") % voucher_name,
  135. offer_type='Voucher',
  136. range=self.offer_range,
  137. condition=self.offer_condition
  138. )
  139. voucher1 = VoucherFactory(name=voucher_name, code="VOUCHER1")
  140. voucher1.offers.add(offer)
  141. voucher2 = VoucherFactory(name="Voucher 2", code="VOUCHER2")
  142. voucher2.offers.add(offer)
  143. offer_ids = list(voucher1.offers.all().values_list('pk', flat=True))
  144. voucher1.delete()
  145. count_offers = ConditionalOffer.objects.filter(id__in=offer_ids).count()
  146. assert len(offer_ids) == count_offers
  147. class TestAvailableForBasket(TestCase):
  148. def setUp(self):
  149. self.basket = create_basket(empty=True)
  150. self.product = create_product(price=100)
  151. range = RangeFactory(products=[self.product])
  152. condition = ConditionFactory(range=range, value=2)
  153. self.voucher = VoucherFactory()
  154. self.voucher.offers.add(create_offer(offer_type='Voucher', range=range, condition=condition))
  155. def test_is_available_for_basket(self):
  156. self.basket.add_product(product=self.product)
  157. is_voucher_available_for_basket, __ = self.voucher.is_available_for_basket(self.basket)
  158. self.assertFalse(is_voucher_available_for_basket)
  159. self.basket.add_product(product=self.product)
  160. is_voucher_available_for_basket, __ = self.voucher.is_available_for_basket(self.basket)
  161. self.assertTrue(is_voucher_available_for_basket)
  162. @pytest.mark.django_db
  163. class TestVoucherSet(object):
  164. def test_factory(self):
  165. voucherset = VoucherSetFactory()
  166. assert voucherset.count == voucherset.vouchers.count()
  167. code = voucherset.vouchers.first().code
  168. assert len(code) == 14
  169. assert code.count('-') == 2
  170. assert str(voucherset) == voucherset.name
  171. assert voucherset.offer
  172. for voucher in voucherset.vouchers.all():
  173. assert voucherset.offer in voucher.offers.all()
  174. def test_min_count(self):
  175. voucherset = VoucherSetFactory(count=20)
  176. assert voucherset.count == 20
  177. voucherset.count = 10
  178. voucherset.save()
  179. voucherset.refresh_from_db()
  180. assert voucherset.count == 20
  181. def test_num_basket_additions(self):
  182. voucherset = VoucherSetFactory()
  183. num_additions = voucherset.num_basket_additions
  184. assert num_additions == 0
  185. def test_num_orders(self):
  186. voucherset = VoucherSetFactory()
  187. assert voucherset.num_orders == 0
  188. user, order = UserFactory(), OrderFactory()
  189. voucher = voucherset.vouchers.first()
  190. voucher.record_usage(order, user)
  191. assert voucherset.num_orders == 1