| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- from decimal import Decimal as D
-
- from django.test import TestCase
- import mock
-
- from oscar.apps.offer import models
- from oscar.test import factories
- from oscar.test.basket import add_product
- from tests.unit.offer import OfferTest
-
-
- class TestCountCondition(OfferTest):
-
- def setUp(self):
- super(TestCountCondition, self).setUp()
- self.condition = models.CountCondition(
- range=self.range, type="Count", value=2)
- self.offer = mock.Mock()
- self.offer.applies_to_tax_exclusive_prices = False
-
- def test_is_not_satified_by_empty_basket(self):
- self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_not_discountable_product_fails_condition(self):
- prod1, prod2 = factories.create_product(), factories.create_product()
- prod2.is_discountable = False
- prod2.save()
- add_product(self.basket, product=prod1)
- add_product(self.basket, product=prod2)
- self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_empty_basket_fails_partial_condition(self):
- self.assertFalse(self.condition.is_partially_satisfied(self.offer, self.basket))
-
- def test_smaller_quantity_basket_passes_partial_condition(self):
- add_product(self.basket)
- self.assertTrue(self.condition.is_partially_satisfied(self.offer, self.basket))
-
- def test_smaller_quantity_basket_upsell_message(self):
- add_product(self.basket)
- self.assertTrue('Buy 1 more product from ' in
- self.condition.get_upsell_message(self.offer, self.basket))
-
- def test_matching_quantity_basket_fails_partial_condition(self):
- add_product(self.basket, quantity=2)
- self.assertFalse(self.condition.is_partially_satisfied(self.offer, self.basket))
-
- def test_matching_quantity_basket_passes_condition(self):
- add_product(self.basket, quantity=2)
- self.assertTrue(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_greater_quantity_basket_passes_condition(self):
- add_product(self.basket, quantity=3)
- self.assertTrue(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_consumption(self):
- add_product(self.basket, quantity=3)
- self.condition.consume_items(self.offer, self.basket, [])
- self.assertEqual(1, self.basket.all_lines()[0].quantity_without_discount)
-
- def test_is_satisfied_accounts_for_consumed_items(self):
- add_product(self.basket, quantity=3)
- self.condition.consume_items(self.offer, self.basket, [])
- self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
-
-
- class ValueConditionTest(OfferTest):
- def setUp(self):
- super(ValueConditionTest, self).setUp()
- self.condition = models.ValueCondition(
- range=self.range, type="Value", value=D('10.00'))
- self.offer = mock.Mock()
- self.offer.applies_to_tax_exclusive_prices = False
- self.item = factories.create_product(price=D('5.00'))
- self.expensive_item = factories.create_product(price=D('15.00'))
-
- def test_empty_basket_fails_condition(self):
- self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_empty_basket_fails_partial_condition(self):
- self.assertFalse(self.condition.is_partially_satisfied(self.offer, self.basket))
-
- def test_less_value_basket_fails_condition(self):
- add_product(self.basket, D('5'))
- self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_not_discountable_item_fails_condition(self):
- product = factories.create_product(is_discountable=False)
- add_product(self.basket, D('15'), product=product)
- self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_upsell_message(self):
- add_product(self.basket, D('5'))
- self.assertTrue('Spend' in self.condition.get_upsell_message(self.offer, self.basket))
-
- def test_matching_basket_fails_partial_condition(self):
- add_product(self.basket, D('5'), 2)
- self.assertFalse(self.condition.is_partially_satisfied(self.offer, self.basket))
-
- def test_less_value_basket_passes_partial_condition(self):
- add_product(self.basket, D('5'), 1)
- self.assertTrue(self.condition.is_partially_satisfied(self.offer, self.basket))
-
- def test_matching_basket_passes_condition(self):
- add_product(self.basket, D('5'), 2)
- self.assertTrue(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_greater_than_basket_passes_condition(self):
- add_product(self.basket, D('5'), 3)
- self.assertTrue(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_consumption(self):
- add_product(self.basket, D('5'), 3)
- self.condition.consume_items(self.offer, self.basket, [])
- self.assertEqual(1, self.basket.all_lines()[0].quantity_without_discount)
-
- def test_consumption_with_high_value_product(self):
- add_product(self.basket, D('15'), 1)
- self.condition.consume_items(self.offer, self.basket, [])
- self.assertEqual(0, self.basket.all_lines()[0].quantity_without_discount)
-
- def test_is_consumed_respects_quantity_consumed(self):
- add_product(self.basket, D('15'), 1)
- self.assertTrue(self.condition.is_satisfied(self.offer, self.basket))
- self.condition.consume_items(self.offer, self.basket, [])
- self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
-
-
- class TestCoverageCondition(TestCase):
-
- def setUp(self):
- self.products = [factories.create_product(), factories.create_product()]
- self.range = models.Range.objects.create(name="Some products")
- for product in self.products:
- self.range.add_product(product)
- self.range.add_product(product)
- self.basket = factories.create_basket(empty=True)
- self.condition = models.CoverageCondition(
- range=self.range, type="Coverage", value=2)
- self.offer = mock.Mock()
- self.offer.applies_to_tax_exclusive_prices = False
-
- def test_empty_basket_fails(self):
- self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_empty_basket_fails_partial_condition(self):
- self.assertFalse(self.condition.is_partially_satisfied(self.offer, self.basket))
-
- def test_single_item_fails(self):
- add_product(self.basket, product=self.products[0])
- self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_not_discountable_item_fails(self):
- self.products[0].is_discountable = False
- self.products[0].save()
- add_product(self.basket, product=self.products[0])
- add_product(self.basket, product=self.products[1])
- self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_single_item_passes_partial_condition(self):
- add_product(self.basket, product=self.products[0])
- self.assertTrue(self.condition.is_partially_satisfied(self.offer, self.basket))
-
- def test_upsell_message(self):
- add_product(self.basket, product=self.products[0])
- self.assertTrue(
- 'Buy 1 more' in self.condition.get_upsell_message(self.offer, self.basket))
-
- def test_duplicate_item_fails(self):
- add_product(self.basket, quantity=2, product=self.products[0])
- self.assertFalse(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_duplicate_item_passes_partial_condition(self):
- add_product(self.basket, quantity=2, product=self.products[0])
- self.assertTrue(self.condition.is_partially_satisfied(self.offer, self.basket))
-
- def test_covering_items_pass(self):
- add_product(self.basket, product=self.products[0])
- add_product(self.basket, product=self.products[1])
- self.assertTrue(self.condition.is_satisfied(self.offer, self.basket))
-
- def test_covering_items_fail_partial_condition(self):
- add_product(self.basket, product=self.products[0])
- add_product(self.basket, product=self.products[1])
- self.assertFalse(self.condition.is_partially_satisfied(self.offer, self.basket))
-
- def test_covering_items_are_consumed(self):
- add_product(self.basket, product=self.products[0])
- add_product(self.basket, product=self.products[1])
- self.condition.consume_items(self.offer, self.basket, [])
- self.assertEqual(0, self.basket.num_items_without_discount)
-
- def test_consumed_items_checks_affected_items(self):
- # Create new offer
- range = models.Range.objects.create(name="All products", includes_all_products=True)
- cond = models.CoverageCondition(range=range, type="Coverage", value=2)
-
- # Get 4 distinct products in the basket
- self.products.extend(
- [factories.create_product(), factories.create_product()])
- for product in self.products:
- add_product(self.basket, product=product)
-
- self.assertTrue(cond.is_satisfied(self.offer, self.basket))
- cond.consume_items(self.offer, self.basket, [])
- self.assertEqual(2, self.basket.num_items_without_discount)
-
- self.assertTrue(cond.is_satisfied(self.offer, self.basket))
- cond.consume_items(self.offer, self.basket, [])
- self.assertEqual(0, self.basket.num_items_without_discount)
|