Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

condition_tests.py 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. from decimal import Decimal as D
  2. from django.test import TestCase
  3. import mock
  4. from oscar.apps.offer import models
  5. from oscar.test import factories
  6. from oscar.test.basket import add_product
  7. class TestCountCondition(TestCase):
  8. def setUp(self):
  9. self.range = models.Range.objects.create(
  10. name="All products range", includes_all_products=True)
  11. self.basket = factories.create_basket(empty=True)
  12. self.condition = models.CountCondition(
  13. range=self.range, type="Count", value=2)
  14. self.offer = mock.Mock()
  15. def test_is_not_satified_by_empty_basket(self):
  16. self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
  17. def test_not_discountable_product_fails_condition(self):
  18. prod1, prod2 = factories.create_product(), factories.create_product()
  19. prod2.is_discountable = False
  20. prod2.save()
  21. add_product(self.basket, product=prod1)
  22. add_product(self.basket, product=prod2)
  23. self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
  24. def test_empty_basket_fails_partial_condition(self):
  25. self.assertFalse(self.condition.is_partially_satisfied(self.offer, self.basket))
  26. def test_smaller_quantity_basket_passes_partial_condition(self):
  27. add_product(self.basket)
  28. self.assertTrue(self.condition.is_partially_satisfied(self.offer, self.basket))
  29. def test_smaller_quantity_basket_upsell_message(self):
  30. add_product(self.basket)
  31. self.assertTrue('Buy 1 more product from ' in
  32. self.condition.get_upsell_message(self.offer, self.basket))
  33. def test_matching_quantity_basket_fails_partial_condition(self):
  34. add_product(self.basket, quantity=2)
  35. self.assertFalse(self.condition.is_partially_satisfied(self.offer, self.basket))
  36. def test_matching_quantity_basket_passes_condition(self):
  37. add_product(self.basket, quantity=2)
  38. self.assertTrue(self.condition.is_satisfied(self.offer, self.basket))
  39. def test_greater_quantity_basket_passes_condition(self):
  40. add_product(self.basket, quantity=3)
  41. self.assertTrue(self.condition.is_satisfied(self.offer, self.basket))
  42. def test_consumption(self):
  43. add_product(self.basket, quantity=3)
  44. self.condition.consume_items(self.offer, self.basket, [])
  45. self.assertEqual(1, self.basket.all_lines()[0].quantity_without_discount)
  46. def test_is_satisfied_accounts_for_consumed_items(self):
  47. add_product(self.basket, quantity=3)
  48. self.condition.consume_items(self.offer, self.basket, [])
  49. self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
  50. class ValueConditionTest(TestCase):
  51. def setUp(self):
  52. self.range = models.Range.objects.create(
  53. name="All products range", includes_all_products=True)
  54. self.basket = factories.create_basket(empty=True)
  55. self.condition = models.ValueCondition(
  56. range=self.range, type="Value", value=D('10.00'))
  57. self.offer = mock.Mock()
  58. self.item = factories.create_product(price=D('5.00'))
  59. self.expensive_item = factories.create_product(price=D('15.00'))
  60. def test_empty_basket_fails_condition(self):
  61. self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
  62. def test_empty_basket_fails_partial_condition(self):
  63. self.assertFalse(self.condition.is_partially_satisfied(self.offer, self.basket))
  64. def test_less_value_basket_fails_condition(self):
  65. add_product(self.basket, D('5'))
  66. self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
  67. def test_not_discountable_item_fails_condition(self):
  68. product = factories.create_product(is_discountable=False)
  69. add_product(self.basket, D('15'), product=product)
  70. self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
  71. def test_upsell_message(self):
  72. add_product(self.basket, D('5'))
  73. self.assertTrue('Spend' in self.condition.get_upsell_message(self.offer, self.basket))
  74. def test_matching_basket_fails_partial_condition(self):
  75. add_product(self.basket, D('5'), 2)
  76. self.assertFalse(self.condition.is_partially_satisfied(self.offer, self.basket))
  77. def test_less_value_basket_passes_partial_condition(self):
  78. add_product(self.basket, D('5'), 1)
  79. self.assertTrue(self.condition.is_partially_satisfied(self.offer, self.basket))
  80. def test_matching_basket_passes_condition(self):
  81. add_product(self.basket, D('5'), 2)
  82. self.assertTrue(self.condition.is_satisfied(self.offer, self.basket))
  83. def test_greater_than_basket_passes_condition(self):
  84. add_product(self.basket, D('5'), 3)
  85. self.assertTrue(self.condition.is_satisfied(self.offer, self.basket))
  86. def test_consumption(self):
  87. add_product(self.basket, D('5'), 3)
  88. self.condition.consume_items(self.offer, self.basket, [])
  89. self.assertEqual(1, self.basket.all_lines()[0].quantity_without_discount)
  90. def test_consumption_with_high_value_product(self):
  91. add_product(self.basket, D('15'), 1)
  92. self.condition.consume_items(self.offer, self.basket, [])
  93. self.assertEqual(0, self.basket.all_lines()[0].quantity_without_discount)
  94. def test_is_consumed_respects_quantity_consumed(self):
  95. add_product(self.basket, D('15'), 1)
  96. self.assertTrue(self.condition.is_satisfied(self.offer, self.basket))
  97. self.condition.consume_items(self.offer, self.basket, [])
  98. self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
  99. class TestCoverageCondition(TestCase):
  100. def setUp(self):
  101. self.products = [factories.create_product(), factories.create_product()]
  102. self.range = models.Range.objects.create(name="Some products")
  103. for product in self.products:
  104. self.range.add_product(product)
  105. self.range.add_product(product)
  106. self.basket = factories.create_basket(empty=True)
  107. self.condition = models.CoverageCondition(
  108. range=self.range, type="Coverage", value=2)
  109. self.offer = mock.Mock()
  110. def test_empty_basket_fails(self):
  111. self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
  112. def test_empty_basket_fails_partial_condition(self):
  113. self.assertFalse(self.condition.is_partially_satisfied(self.offer, self.basket))
  114. def test_single_item_fails(self):
  115. add_product(self.basket, product=self.products[0])
  116. self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
  117. def test_not_discountable_item_fails(self):
  118. self.products[0].is_discountable = False
  119. self.products[0].save()
  120. add_product(self.basket, product=self.products[0])
  121. add_product(self.basket, product=self.products[1])
  122. self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
  123. def test_single_item_passes_partial_condition(self):
  124. add_product(self.basket, product=self.products[0])
  125. self.assertTrue(self.condition.is_partially_satisfied(self.offer, self.basket))
  126. def test_upsell_message(self):
  127. add_product(self.basket, product=self.products[0])
  128. self.assertTrue(
  129. 'Buy 1 more' in self.condition.get_upsell_message(self.offer, self.basket))
  130. def test_duplicate_item_fails(self):
  131. add_product(self.basket, quantity=2, product=self.products[0])
  132. self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
  133. def test_duplicate_item_passes_partial_condition(self):
  134. add_product(self.basket, quantity=2, product=self.products[0])
  135. self.assertTrue(self.condition.is_partially_satisfied(self.offer, self.basket))
  136. def test_covering_items_pass(self):
  137. add_product(self.basket, product=self.products[0])
  138. add_product(self.basket, product=self.products[1])
  139. self.assertTrue(self.condition.is_satisfied(self.offer, self.basket))
  140. def test_covering_items_fail_partial_condition(self):
  141. add_product(self.basket, product=self.products[0])
  142. add_product(self.basket, product=self.products[1])
  143. self.assertFalse(self.condition.is_partially_satisfied(self.offer, self.basket))
  144. def test_covering_items_are_consumed(self):
  145. add_product(self.basket, product=self.products[0])
  146. add_product(self.basket, product=self.products[1])
  147. self.condition.consume_items(self.offer, self.basket, [])
  148. self.assertEqual(0, self.basket.num_items_without_discount)
  149. def test_consumed_items_checks_affected_items(self):
  150. # Create new offer
  151. range = models.Range.objects.create(name="All products", includes_all_products=True)
  152. cond = models.CoverageCondition(range=range, type="Coverage", value=2)
  153. # Get 4 distinct products in the basket
  154. self.products.extend(
  155. [factories.create_product(), factories.create_product()])
  156. for product in self.products:
  157. add_product(self.basket, product=product)
  158. self.assertTrue(cond.is_satisfied(self.offer, self.basket))
  159. cond.consume_items(self.offer, self.basket, [])
  160. self.assertEqual(2, self.basket.num_items_without_discount)
  161. self.assertTrue(cond.is_satisfied(self.offer, self.basket))
  162. cond.consume_items(self.offer, self.basket, [])
  163. self.assertEqual(0, self.basket.num_items_without_discount)