Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

condition_tests.py 8.5KB

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