def test_applies_correctly_to_basket_which_exceeds_condition(self):
     add_products(self.basket, [
         (D('4.00'), 4), (D('2.00'), 4)])
     result = self.benefit.apply(self.basket, self.condition, self.offer)
     self.assertEqual(D('2.00'), result.discount)
     self.assertEqual(3, self.basket.num_items_with_discount)
     self.assertEqual(5, self.basket.num_items_without_discount)
 def test_applies_correctly_to_basket_which_exceeds_condition(self):
     add_products(self.basket, [(D('12.00'), 2), (D('20.00'), 2)])
     result = self.benefit.apply(self.basket, self.condition, self.offer)
     self.assertEqual(1 * D('12.00') * D('0.2'), result.discount)
     # Should only consume the condition products
     self.assertEqual(2, self.basket.num_items_with_discount)
     self.assertEqual(2, self.basket.num_items_without_discount)
 def test_applies_correctly_to_basket_which_exceeds_condition_with_smaller_prices_than_discount_and_higher_prices_first(self):
     add_products(self.basket, [
         (D('2.00'), 2), (D('4.00'), 2)])
     result = self.benefit.apply(self.basket, self.condition, self.offer)
     self.assertEqual(D('3.00'), result.discount)
     self.assertEqual(4, self.basket.num_items_with_discount)
     self.assertEqual(0, self.basket.num_items_without_discount)
 def test_applies_correctly_to_basket_which_exceeds_condition(self):
     add_products(self.basket, [
         (D('12.00'), 2), (D('10.00'), 2)])
     result = self.benefit.apply(self.basket, self.condition)
     self.assertEqual(D('3.00'), result.discount)
     self.assertEqual(4, self.basket.num_items_with_discount)
     self.assertEqual(0, self.basket.num_items_without_discount)
    def test_consumes_correct_number_of_products_for_4_product_basket(self):
        basket = factories.create_basket(empty=True)
        add_products(basket, [(D('1'), 2), (D('1'), 2)])

        self.assertTrue(self.offer.is_condition_satisfied(basket))
        discount = self.offer.apply_benefit(basket)
        self.assertTrue(discount.discount > 0)
        self.assertEqual(3, basket.num_items_with_discount)
        self.assertEqual(1, basket.num_items_without_discount)
        self.assertFalse(self.offer.is_condition_satisfied(basket))
    def test_applies_correctly_to_basket_which_matches_condition_with_multiple_lines_and_lower_total_value(self):
        # Use a basket with 2 lines
        add_products(self.basket, [
            (D('1.00'), 1), (D('1.50'), 1)])
        result = self.benefit.apply(self.basket, self.condition, self.offer)

        self.assertTrue(result.is_successful)
        self.assertFalse(result.is_final)
        self.assertEqual(D('2.50'), result.discount)
        self.assertEqual(2, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)
 def test_rounding_error_for_multiple_products(self):
     add_products(self.basket,
                  [(D('7.00'), 1), (D('7.00'), 1), (D('7.00'), 1)])
     result = self.benefit.apply(self.basket, self.condition, self.offer)
     self.assertEqual(D('1.00'), result.discount)
     # Make sure discount together is the same as final discount
     # Rounding error would return 0.99 instead 1.00
     cumulative_discount = sum(
         line.discount_value for line in self.basket.all_lines())
     self.assertEqual(result.discount, cumulative_discount)
     self.assertEqual(3, self.basket.num_items_with_discount)
     self.assertEqual(0, self.basket.num_items_without_discount)
    def test_consumes_correct_number_of_products_for_6_product_basket(self):
        basket = factories.create_basket(empty=True)
        add_products(basket, [(D('1'), 3), (D('1'), 3)])

        # First application
        discount = self.offer.apply_benefit(basket)
        self.assertTrue(discount.discount > 0)
        self.assertEqual(3, basket.num_items_with_discount)
        self.assertEqual(3, basket.num_items_without_discount)

        # Second application
        discount = self.offer.apply_benefit(basket)
        self.assertTrue(discount.discount > 0)
        self.assertEqual(6, basket.num_items_with_discount)
    def test_applies_correctly_to_basket_which_matches_condition_with_multiple_lines(self):
        # Use a basket with 2 lines
        add_products(self.basket, [
            (D('12.00'), 1), (D('12.00'), 1)])
        result = self.benefit.apply(self.basket, self.condition, self.offer)

        self.assertTrue(result.is_successful)
        self.assertFalse(result.is_final)
        self.assertEqual(D('3.00'), result.discount)
        self.assertEqual(2, self.basket.num_items_with_discount)
        self.assertEqual(0, self.basket.num_items_without_discount)

        # Check the discount is applied equally to each line
        for line in self.basket.all_lines():
            self.assertEqual(D('1.50'), line.discount_value)
 def test_applies_correctly_to_multi_item_basket_which_matches_condition_but_with_lower_prices_than_discount(self):
     add_products(self.basket, [(D('2.00'), 6)])
     result = self.benefit.apply(self.basket, self.condition, self.offer)
     self.assertEqual(D('2.00'), result.discount)
     self.assertEqual(5, self.basket.num_items_with_discount)
     self.assertEqual(1, self.basket.num_items_without_discount)
 def test_applies_correctly_to_multi_item_basket_which_exceeds_condition_but_matches_boundary(self):
     add_products(self.basket, [(D('5.00'), 3)])
     result = self.benefit.apply(self.basket, self.condition, self.offer)
     self.assertEqual(D('3.00'), result.discount)
     self.assertEqual(2, self.basket.num_items_with_discount)
     self.assertEqual(1, self.basket.num_items_without_discount)
 def test_applies_correctly_to_single_item_basket_which_matches_condition(self):
     add_products(self.basket, [(D('10.00'), 1)])
     result = self.benefit.apply(self.basket, self.condition, self.offer)
     self.assertEqual(D('3.00'), result.discount)
     self.assertEqual(1, self.basket.num_items_with_discount)
     self.assertEqual(0, self.basket.num_items_without_discount)
 def test_applies_correctly_to_multi_item_basket_which_matches_condition(self):
     add_products(self.basket, [(D('5.00'), 2)])
     result = self.benefit.apply(self.basket, self.condition)
     self.assertEqual(D('3.00'), result.discount)
     self.assertEqual(2, self.basket.num_items_with_discount)
     self.assertEqual(0, self.basket.num_items_without_discount)
 def test_applies_correctly_to_basket_which_exceeds_condition_but_with_smaller_prices_than_discount(self):
     add_products(self.basket, [(D('2.00'), 2), (D('1.00'), 2)])
     result = self.benefit.apply(self.basket, self.condition)
     self.assertEqual(D('1.00'), result.discount)
     self.assertEqual(2, self.basket.num_items_with_discount)
     self.assertEqual(2, self.basket.num_items_without_discount)