Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

condition_tests.py 8.5KB

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