Ejemplo n.º 1
0
class TestOfferApplicator(TestCase):

    def setUp(self):
        self.applicator = Applicator()
        self.basket = Basket.objects.create()
        self.product = create_product(price=D('100'))
        rng = G(models.Range, includes_all_products=True)
        self.condition = G(models.Condition, range=rng, type="Value",
                           value=D('100'))
        self.benefit = G(models.Benefit, range=rng, type="Absolute",
                         value=D('10'))

    def test_applies_offer_multiple_times_by_default(self):
        self.basket.add_product(self.product, 5)
        offer = models.ConditionalOffer(
            id="test", condition=self.condition, benefit=self.benefit)
        discounts = self.applicator.get_basket_discounts(
            self.basket, [offer])
        self.assertEqual(5, discounts["test"]['freq'])

    def test_respects_maximum_applications_field(self):
        self.basket.add_product(self.product, 5)
        offer = models.ConditionalOffer(
            id="test", condition=self.condition, benefit=self.benefit,
            max_applications=1)
        discounts = self.applicator.get_basket_discounts(
            self.basket, [offer])
        self.assertEqual(1, discounts["test"]['freq'])
Ejemplo n.º 2
0
class TestOfferApplicator(TestCase):

    def setUp(self):
        self.applicator = Applicator()
        self.basket = factories.create_basket(empty=True)
        rng = G(models.Range, includes_all_products=True)
        self.condition = G(models.Condition, range=rng, type="Value",
                           value=D('100'), proxy_class=None)
        self.benefit = G(models.Benefit, range=rng, type="Absolute",
                         value=D('10'))

    def test_applies_offer_multiple_times_by_default(self):
        add_product(self.basket, D('100'), 5)
        offer = models.ConditionalOffer(
            id="test", condition=self.condition, benefit=self.benefit)
        self.applicator.apply_offers(self.basket, [offer])
        self.assertEqual(5, self.basket.offer_applications.applications["test"]['freq'])

    def test_respects_maximum_applications_field(self):
        add_product(self.basket, D('100'), 5)
        offer = models.ConditionalOffer(
            id="test", condition=self.condition, benefit=self.benefit,
            max_basket_applications=1)
        self.applicator.apply_offers(self.basket, [offer])
        self.assertEqual(1, self.basket.offer_applications.applications["test"]['freq'])
Ejemplo n.º 3
0
class TestOfferApplicator(TestCase):

    def setUp(self):
        self.applicator = Applicator()
        self.basket = BasketFactory()
        rng = RangeFactory(includes_all_products=True)
        self.condition = ConditionFactory(
            range=rng, type=ConditionFactory._meta.model.VALUE,
            value=D('100'), proxy_class=None)
        self.benefit = BenefitFactory(
            range=rng, type=BenefitFactory._meta.model.FIXED,
            value=D('10'))

    def test_applies_offer_multiple_times_by_default(self):
        add_product(self.basket, D('100'), 5)
        offer = ConditionalOfferFactory(
            pk=1, condition=self.condition, benefit=self.benefit)
        self.applicator.apply
        self.applicator.apply_offers(self.basket, [offer])
        line = self.basket.all_lines()[0]
        self.assertTrue(line.quantity_with_offer_discount(offer) == 5)

    def test_respects_maximum_applications_field(self):
        add_product(self.basket, D('100'), 5)
        offer = ConditionalOfferFactory(
            pk=1, condition=self.condition, benefit=self.benefit,
            max_basket_applications=1)
        self.applicator.apply_offers(self.basket, [offer])
        line = self.basket.all_lines()[0]
        self.assertTrue(line.quantity_with_offer_discount(offer) == 5)
        applications = self.basket.offer_applications.applications
        self.assertTrue(applications[1]['freq'] == 1)

    def test_uses_offers_in_order_of_descending_priority(self):
        self.applicator.get_site_offers = Mock(
            return_value=[models.ConditionalOffer(
                name="offer1", condition=self.condition, benefit=self.benefit,
                priority=1)])

        self.applicator.get_user_offers = Mock(
            return_value=[models.ConditionalOffer(
                name="offer2", condition=self.condition, benefit=self.benefit,
                priority=-1)])

        offers = self.applicator.get_offers(self.basket)
        priorities = [offer.priority for offer in offers]
        self.assertEqual(sorted(priorities, reverse=True), priorities)

    def test_get_site_offers(self):
        models.ConditionalOffer.objects.create(
            name="globaloffer", condition=self.condition,
            benefit=self.benefit, offer_type=models.ConditionalOffer.SITE)
        models.ConditionalOffer.objects.create(
            name="sessionoffer", condition=self.condition,
            benefit=self.benefit, offer_type=models.ConditionalOffer.SESSION)

        site_offers = Applicator().get_site_offers()
        # Only one offer should be returned
        self.assertEqual(len(site_offers), 1)
        self.assertEqual(site_offers[0].name, "globaloffer")
Ejemplo n.º 4
0
class TestOfferApplicator(TestCase):
    def setUp(self):
        self.applicator = Applicator()
        self.basket = factories.create_basket(empty=True)
        rng = G(models.Range, includes_all_products=True)
        self.condition = G(models.Condition,
                           range=rng,
                           type="Value",
                           value=D('100'),
                           proxy_class=None)
        self.benefit = G(models.Benefit,
                         range=rng,
                         type="Absolute",
                         value=D('10'))

    def test_applies_offer_multiple_times_by_default(self):
        add_product(self.basket, D('100'), 5)
        offer = models.ConditionalOffer(id="test",
                                        condition=self.condition,
                                        benefit=self.benefit)
        self.applicator.apply_offers(self.basket, [offer])
        self.assertEqual(
            5, self.basket.offer_applications.applications["test"]['freq'])

    def test_respects_maximum_applications_field(self):
        add_product(self.basket, D('100'), 5)
        offer = models.ConditionalOffer(id="test",
                                        condition=self.condition,
                                        benefit=self.benefit,
                                        max_basket_applications=1)
        self.applicator.apply_offers(self.basket, [offer])
        self.assertEqual(
            1, self.basket.offer_applications.applications["test"]['freq'])
Ejemplo n.º 5
0
class TestOfferApplicator(TestCase):

    def setUp(self):
        self.applicator = Applicator()
        self.basket = BasketFactory()
        rng = RangeFactory(includes_all_products=True)
        self.condition = ConditionFactory(
            range=rng, type=ConditionFactory._meta.model.VALUE,
            value=D('100'), proxy_class=None)
        self.benefit = BenefitFactory(
            range=rng, type=BenefitFactory._meta.model.FIXED,
            value=D('10'))

    def test_applies_offer_multiple_times_by_default(self):
        add_product(self.basket, D('100'), 5)
        offer = ConditionalOfferFactory(
            pk=1, condition=self.condition, benefit=self.benefit)
        self.applicator.apply
        self.applicator.apply_offers(self.basket, [offer])
        line = self.basket.all_lines()[0]
        self.assertTrue(line.quantity_with_offer_discount(offer) == 5)

    def test_respects_maximum_applications_field(self):
        add_product(self.basket, D('100'), 5)
        offer = ConditionalOfferFactory(
            pk=1, condition=self.condition, benefit=self.benefit,
            max_basket_applications=1)
        self.applicator.apply_offers(self.basket, [offer])
        line = self.basket.all_lines()[0]
        self.assertTrue(line.quantity_with_offer_discount(offer) == 5)
        applications = self.basket.offer_applications.applications
        self.assertTrue(applications[1]['freq'] == 1)

    def test_uses_offers_in_order_of_descending_priority(self):
        self.applicator.get_site_offers = Mock(
            return_value=[models.ConditionalOffer(
                name="offer1", condition=self.condition, benefit=self.benefit,
                priority=1)])

        self.applicator.get_user_offers = Mock(
            return_value=[models.ConditionalOffer(
                name="offer2", condition=self.condition, benefit=self.benefit,
                priority=-1)])

        offers = self.applicator.get_offers(self.basket)
        priorities = [offer.priority for offer in offers]
        self.assertEqual(sorted(priorities, reverse=True), priorities)

    def test_get_site_offers(self):
        models.ConditionalOffer.objects.create(
            name="globaloffer", condition=self.condition,
            benefit=self.benefit, offer_type=models.ConditionalOffer.SITE)
        models.ConditionalOffer.objects.create(
            name="sessionoffer", condition=self.condition,
            benefit=self.benefit, offer_type=models.ConditionalOffer.SESSION)

        site_offers = Applicator().get_site_offers()
        # Only one offer should be returned
        self.assertEqual(len(site_offers), 1)
        self.assertEqual(site_offers[0].name, "globaloffer")
Ejemplo n.º 6
0
class TestOfferApplicator(TestCase):
    def setUp(self):
        self.applicator = Applicator()
        self.basket = Basket.objects.create()
        self.product = create_product(price=D('100'))
        rng = G(models.Range, includes_all_products=True)
        self.condition = G(models.Condition,
                           range=rng,
                           type="Value",
                           value=D('100'))
        self.benefit = G(models.Benefit,
                         range=rng,
                         type="Absolute",
                         value=D('10'))

    def test_applies_offer_multiple_times_by_default(self):
        self.basket.add_product(self.product, 5)
        offer = models.ConditionalOffer(id="test",
                                        condition=self.condition,
                                        benefit=self.benefit)
        discounts = self.applicator.get_basket_discounts(self.basket, [offer])
        self.assertEqual(5, discounts["test"]['freq'])

    def test_respects_maximum_applications_field(self):
        self.basket.add_product(self.product, 5)
        offer = models.ConditionalOffer(id="test",
                                        condition=self.condition,
                                        benefit=self.benefit,
                                        max_applications=1)
        discounts = self.applicator.get_basket_discounts(self.basket, [offer])
        self.assertEqual(1, discounts["test"]['freq'])
Ejemplo n.º 7
0
    def setUp(self):
        # Flush the cache
        conn = get_redis_connection('redis')
        conn.flushall()

        self.condition_product = factories.ProductFactory()
        condition_range = factories.RangeFactory()
        condition_range.add_product(self.condition_product)
        self.condition = BluelightCountCondition.objects.create(
            range=condition_range,
            type=Condition.COUNT,
            value=2)

        self.benefit_product = factories.ProductFactory()
        benefit_range = factories.RangeFactory()
        benefit_range.add_product(self.benefit_product)
        self.benefit = BluelightAbsoluteDiscountBenefit.objects.create(
            range=benefit_range,
            type=Benefit.FIXED,
            value=D('3.00'))

        self.offer = ConditionalOffer(
            id=1, condition=self.condition, benefit=self.benefit)
        self.basket = factories.create_basket(empty=True)

        self.applicator = Applicator()
Ejemplo n.º 8
0
 def setUp(self):
     self.applicator = Applicator()
     self.basket = BasketFactory()
     rng = RangeFactory(includes_all_products=True)
     self.condition = ConditionFactory(
         range=rng, type=ConditionFactory._meta.model.VALUE,
         value=D('100'), proxy_class=None)
     self.benefit = BenefitFactory(
         range=rng, type=BenefitFactory._meta.model.FIXED,
         value=D('10'))
Ejemplo n.º 9
0
 def setUp(self):
     self.applicator = Applicator()
     rng = RangeFactory(includes_all_products=True)
     self.condition = ConditionFactory(
         range=rng, type=ConditionFactory._meta.model.VALUE,
         value=D('100'), proxy_class=None)
     self.benefit = BenefitFactory(
         range=rng, type=BenefitFactory._meta.model.FIXED,
         value=D('10'), max_affected_items=1)
     self.basket = factories.create_basket()
     self.line = self.basket.all_lines()[0]
Ejemplo n.º 10
0
class TestOfferApplicator(TestCase):
    def setUp(self):
        self.applicator = Applicator()
        self.basket = factories.create_basket(empty=True)
        rng = G(models.Range, includes_all_products=True)
        self.condition = G(models.Condition,
                           range=rng,
                           type="Value",
                           value=D('100'),
                           proxy_class=None)
        self.benefit = G(models.Benefit,
                         range=rng,
                         type="Absolute",
                         value=D('10'))

    def test_applies_offer_multiple_times_by_default(self):
        add_product(self.basket, D('100'), 5)
        offer = models.ConditionalOffer(id="test",
                                        condition=self.condition,
                                        benefit=self.benefit)
        self.applicator.apply_offers(self.basket, [offer])
        applications = self.basket.offer_applications.applications
        self.assertEqual(5, applications["test"]['freq'])

    def test_respects_maximum_applications_field(self):
        add_product(self.basket, D('100'), 5)
        offer = models.ConditionalOffer(id="test",
                                        condition=self.condition,
                                        benefit=self.benefit,
                                        max_basket_applications=1)
        self.applicator.apply_offers(self.basket, [offer])
        applications = self.basket.offer_applications.applications
        self.assertEqual(1, applications["test"]['freq'])

    def test_uses_offers_in_order_of_descending_priority(self):
        self.applicator.get_site_offers = Mock(return_value=[
            models.ConditionalOffer(name="offer1",
                                    condition=self.condition,
                                    benefit=self.benefit,
                                    priority=1)
        ])

        self.applicator.get_user_offers = Mock(return_value=[
            models.ConditionalOffer(name="offer2",
                                    condition=self.condition,
                                    benefit=self.benefit,
                                    priority=-1)
        ])

        offers = self.applicator.get_offers(self.basket)
        priorities = [offer.priority for offer in offers]
        self.assertEqual(sorted(priorities, reverse=True), priorities)
Ejemplo n.º 11
0
class TestOfferApplicator(TestCase):
    def setUp(self):
        self.applicator = Applicator()
        self.basket = BasketFactory()
        rng = RangeFactory(includes_all_products=True)
        self.condition = ConditionFactory(
            range=rng,
            type=ConditionFactory._meta.model.VALUE,
            value=D('100'),
            proxy_class=None)
        self.benefit = BenefitFactory(range=rng,
                                      type=BenefitFactory._meta.model.FIXED,
                                      value=D('10'),
                                      max_affected_items=1)

    def test_applies_offer_multiple_times_by_default(self):
        add_product(self.basket, D('100'), 5)
        offer = ConditionalOfferFactory(pk=1,
                                        condition=self.condition,
                                        benefit=self.benefit)
        self.applicator.apply_offers(self.basket, [offer])
        applications = self.basket.offer_applications.applications
        self.assertEqual(5, applications[1]['freq'])

    def test_respects_maximum_applications_field(self):
        add_product(self.basket, D('100'), 5)
        offer = ConditionalOfferFactory(pk=1,
                                        condition=self.condition,
                                        benefit=self.benefit,
                                        max_basket_applications=1)
        self.applicator.apply_offers(self.basket, [offer])
        applications = self.basket.offer_applications.applications
        self.assertEqual(1, applications[1]['freq'])

    def test_uses_offers_in_order_of_descending_priority(self):
        self.applicator.get_site_offers = Mock(return_value=[
            models.ConditionalOffer(name="offer1",
                                    condition=self.condition,
                                    benefit=self.benefit,
                                    priority=1)
        ])

        self.applicator.get_user_offers = Mock(return_value=[
            models.ConditionalOffer(name="offer2",
                                    condition=self.condition,
                                    benefit=self.benefit,
                                    priority=-1)
        ])

        offers = self.applicator.get_offers(self.basket)
        priorities = [offer.priority for offer in offers]
        self.assertEqual(sorted(priorities, reverse=True), priorities)
Ejemplo n.º 12
0
 def setUp(self):
     self.applicator = Applicator()
     self.basket = factories.create_basket(empty=True)
     rng = G(models.Range, includes_all_products=True)
     self.condition = G(models.Condition,
                        range=rng,
                        type="Value",
                        value=D('100'),
                        proxy_class=None)
     self.benefit = G(models.Benefit,
                      range=rng,
                      type="Absolute",
                      value=D('10'))
Ejemplo n.º 13
0
 def setUp(self):
     self.applicator = Applicator()
     self.basket = Basket.objects.create()
     self.product = create_product(price=D('100'))
     rng = G(models.Range, includes_all_products=True)
     self.condition = G(models.Condition,
                        range=rng,
                        type="Value",
                        value=D('100'))
     self.benefit = G(models.Benefit,
                      range=rng,
                      type="Absolute",
                      value=D('10'))
Ejemplo n.º 14
0
class TestAnAbsoluteDiscountAppliedWithCountConditionOnDifferentRange(TestCase):
    def setUp(self):
        # Flush the cache
        conn = get_redis_connection('redis')
        conn.flushall()

        self.condition_product = factories.ProductFactory()
        condition_range = factories.RangeFactory()
        condition_range.add_product(self.condition_product)
        self.condition = BluelightCountCondition.objects.create(
            range=condition_range,
            type=Condition.COUNT,
            value=2)

        self.benefit_product = factories.ProductFactory()
        benefit_range = factories.RangeFactory()
        benefit_range.add_product(self.benefit_product)
        self.benefit = BluelightAbsoluteDiscountBenefit.objects.create(
            range=benefit_range,
            type=Benefit.FIXED,
            value=D('3.00'))

        self.offer = ConditionalOffer(
            id=1, condition=self.condition, benefit=self.benefit)
        self.basket = factories.create_basket(empty=True)

        self.applicator = Applicator()


    def test_succcessful_application_consumes_correctly(self):
        add_product(self.basket, product=self.condition_product, quantity=2)
        add_product(self.basket, product=self.benefit_product, quantity=1)

        self.applicator.apply_offers(self.basket, [self.offer])

        discounts = self.basket.offer_applications.offer_discounts
        self.assertEqual(len(discounts), 1)
        self.assertEqual(discounts[0]['freq'], 1)


    def test_condition_is_consumed_correctly(self):
        # Testing an error case reported on the mailing list
        add_product(self.basket, product=self.condition_product, quantity=3)
        add_product(self.basket, product=self.benefit_product, quantity=2)

        self.applicator.apply_offers(self.basket, [self.offer])

        discounts = self.basket.offer_applications.offer_discounts
        self.assertEqual(len(discounts), 1)
        self.assertEqual(discounts[0]['freq'], 1)
Ejemplo n.º 15
0
    def test_non_negative_basket_lines_values(self):
        # absolute benefit is larger than the line price
        rng = models.Range.objects.create(name="", includes_all_products=True)
        benefit1 = models.Benefit.objects.create(type=models.Benefit.FIXED,
                                                 range=rng,
                                                 value=D('100'))
        benefit2 = models.Benefit.objects.create(type=models.Benefit.FIXED,
                                                 range=rng,
                                                 value=D('100'))
        condition = models.ValueCondition.objects.create(
            range=rng, type=models.Condition.VALUE, value=D('10'))
        models.ConditionalOffer.objects.create(name='offer1',
                                               benefit=benefit1,
                                               condition=condition,
                                               exclusive=False)
        models.ConditionalOffer.objects.create(name='offer2',
                                               benefit=benefit2,
                                               condition=condition,
                                               exclusive=False)

        basket = factories.create_basket(empty=True)
        add_products(basket, [(D('20'), 1)])

        Applicator().apply(basket)
        assert len(basket.offer_applications) == 2
        line = basket.all_lines().first()
        assert line.line_price_excl_tax_incl_discounts == D(0)
        assert line.line_price_incl_tax_incl_discounts == D(0)
        assert basket.total_incl_tax == 0
Ejemplo n.º 16
0
 def setUp(self):
     self.applicator = Applicator()
     self.basket = Basket.objects.create()
     self.product = create_product(price=D("100"))
     rng = G(models.Range, includes_all_products=True)
     self.condition = G(models.Condition, range=rng, type="Value", value=D("100"), proxy_class=None)
     self.benefit = G(models.Benefit, range=rng, type="Absolute", value=D("10"))
Ejemplo n.º 17
0
 def apply_20percent_shipping_offer(self):
     """Shipping offer 20% off"""
     range = Range.objects.create(name="All products range",
                                 includes_all_products=True)
     benefit = Benefit.objects.create(
         range=range, type=Benefit.SHIPPING_PERCENTAGE, value=20)
     offer = factories.create_offer(range=range, benefit=benefit)
     Applicator().apply_offers(self.basket, [offer])
Ejemplo n.º 18
0
 def setUp(self):
     self.applicator = Applicator()
     self.basket = factories.create_basket(empty=True)
     rng = G(models.Range, includes_all_products=True)
     self.condition = G(models.Condition, range=rng, type="Value",
                        value=D('100'), proxy_class=None)
     self.benefit = G(models.Benefit, range=rng, type="Absolute",
                      value=D('10'))
class TestAnAbsoluteDiscountAppliedWithCountConditionOnDifferentRange(TestCase):
    def setUp(self):
        self.condition_product = factories.ProductFactory()
        condition_range = factories.RangeFactory()
        condition_range.add_product(self.condition_product)
        self.condition = BluelightCountCondition.objects.create(
            range=condition_range,
            type=Condition.COUNT,
            value=2)

        self.benefit_product = factories.ProductFactory()
        benefit_range = factories.RangeFactory()
        benefit_range.add_product(self.benefit_product)
        self.benefit = BluelightAbsoluteDiscountBenefit.objects.create(
            range=benefit_range,
            type=Benefit.FIXED,
            value=D('3.00'))

        self.offer = ConditionalOffer(
            id=1, condition=self.condition, benefit=self.benefit)
        self.basket = factories.create_basket(empty=True)

        self.applicator = Applicator()


    def test_succcessful_application_consumes_correctly(self):
        add_product(self.basket, product=self.condition_product, quantity=2)
        add_product(self.basket, product=self.benefit_product, quantity=1)

        self.applicator.apply_offers(self.basket, [self.offer])

        discounts = self.basket.offer_applications.offer_discounts
        self.assertEqual(len(discounts), 1)
        self.assertEqual(discounts[0]['freq'], 1)


    def test_condition_is_consumed_correctly(self):
        # Testing an error case reported on the mailing list
        add_product(self.basket, product=self.condition_product, quantity=3)
        add_product(self.basket, product=self.benefit_product, quantity=2)

        self.applicator.apply_offers(self.basket, [self.offer])

        discounts = self.basket.offer_applications.offer_discounts
        self.assertEqual(len(discounts), 1)
        self.assertEqual(discounts[0]['freq'], 1)
Ejemplo n.º 20
0
class TestOfferApplicator(TestCase):

    def setUp(self):
        self.applicator = Applicator()
        self.basket = BasketFactory()
        rng = RangeFactory(includes_all_products=True)
        self.condition = ConditionFactory(
            range=rng, type=ConditionFactory._meta.model.VALUE,
            value=D('100'), proxy_class=None)
        self.benefit = BenefitFactory(
            range=rng, type=BenefitFactory._meta.model.FIXED,
            value=D('10'), max_affected_items=1)

    def test_applies_offer_multiple_times_by_default(self):
        add_product(self.basket, D('100'), 5)
        offer = ConditionalOfferFactory(
            pk=1, condition=self.condition, benefit=self.benefit)
        self.applicator.apply_offers(self.basket, [offer])
        applications = self.basket.offer_applications.applications
        self.assertEqual(5, applications[1]['freq'])

    def test_respects_maximum_applications_field(self):
        add_product(self.basket, D('100'), 5)
        offer = ConditionalOfferFactory(
            pk=1, condition=self.condition, benefit=self.benefit,
            max_basket_applications=1)
        self.applicator.apply_offers(self.basket, [offer])
        applications = self.basket.offer_applications.applications
        self.assertEqual(1, applications[1]['freq'])

    def test_uses_offers_in_order_of_descending_priority(self):
        self.applicator.get_site_offers = Mock(
            return_value=[models.ConditionalOffer(
                name="offer1", condition=self.condition, benefit=self.benefit,
                priority=1)])

        self.applicator.get_user_offers = Mock(
            return_value=[models.ConditionalOffer(
                name="offer2", condition=self.condition, benefit=self.benefit,
                priority=-1)])

        offers = self.applicator.get_offers(self.basket)
        priorities = [offer.priority for offer in offers]
        self.assertEqual(sorted(priorities, reverse=True), priorities)
Ejemplo n.º 21
0
    def test_apply_offer_with_multibuy_benefit_and_count_condition(self):
        rng = RangeFactory(includes_all_products=True)
        condition = ConditionFactory(range=rng,
                                     type=ConditionFactory._meta.model.COUNT,
                                     value=1)
        benefit = BenefitFactory(range=rng,
                                 type=BenefitFactory._meta.model.MULTIBUY,
                                 value=1)
        offer = ConditionalOfferFactory(condition=condition, benefit=benefit)

        add_product(self.basket, D('100'), 5)

        applicator = Applicator()
        applicator.apply_offers(self.basket, [offer])
        line = self.basket.all_lines()[0]
        assert line.quantity_with_offer_discount(offer) == 1

        self.basket.refresh_from_db()
        assert self.basket.total_discount == D('100')
Ejemplo n.º 22
0
 def setUp(self):
     self.applicator = Applicator()
     self.basket = BasketFactory()
     rng = RangeFactory(includes_all_products=True)
     self.condition = ConditionFactory(
         range=rng, type=ConditionFactory._meta.model.VALUE,
         value=D('100'), proxy_class=None)
     self.benefit = BenefitFactory(
         range=rng, type=BenefitFactory._meta.model.FIXED,
         value=D('10'), max_affected_items=1)
Ejemplo n.º 23
0
    def setUp(self):
        self.condition_product = factories.ProductFactory()
        condition_range = factories.RangeFactory()
        condition_range.add_product(self.condition_product)
        self.condition = models.CountCondition.objects.create(
            range=condition_range, type=models.Condition.COUNT, value=2)

        self.benefit_product = factories.ProductFactory()
        benefit_range = factories.RangeFactory()
        benefit_range.add_product(self.benefit_product)
        self.benefit = models.AbsoluteDiscountBenefit.objects.create(
            range=benefit_range, type=models.Benefit.FIXED, value=D('3.00'))

        self.offer = models.ConditionalOffer(id=1,
                                             condition=self.condition,
                                             benefit=self.benefit)
        self.basket = factories.create_basket(empty=True)

        self.applicator = Applicator()
Ejemplo n.º 24
0
class TestOfferApplicator(TestCase):

    def setUp(self):
        self.applicator = Applicator()
        self.basket = factories.create_basket(empty=True)
        rng = G(models.Range, includes_all_products=True)
        self.condition = G(models.Condition, range=rng, type="Value",
                           value=D('100'), proxy_class=None)
        self.benefit = G(models.Benefit, range=rng, type="Absolute",
                         value=D('10'))

    def test_applies_offer_multiple_times_by_default(self):
        add_product(self.basket, D('100'), 5)
        offer = models.ConditionalOffer(
            id="test", condition=self.condition, benefit=self.benefit)
        self.applicator.apply_offers(self.basket, [offer])
        applications = self.basket.offer_applications.applications
        self.assertEqual(5, applications["test"]['freq'])

    def test_respects_maximum_applications_field(self):
        add_product(self.basket, D('100'), 5)
        offer = models.ConditionalOffer(
            id="test", condition=self.condition, benefit=self.benefit,
            max_basket_applications=1)
        self.applicator.apply_offers(self.basket, [offer])
        applications = self.basket.offer_applications.applications
        self.assertEqual(1, applications["test"]['freq'])

    def test_uses_offers_in_order_of_descending_priority(self):
        self.applicator.get_site_offers = Mock(
            return_value=[models.ConditionalOffer(
                name="offer1", condition=self.condition, benefit=self.benefit,
                priority=1)])

        self.applicator.get_user_offers = Mock(
            return_value=[models.ConditionalOffer(
                name="offer2", condition=self.condition, benefit=self.benefit,
                priority=-1)])

        offers = self.applicator.get_offers(Mock(), self.basket)
        priorities = [offer.priority for offer in offers]
        self.assertEqual(sorted(priorities, reverse=True), priorities)
Ejemplo n.º 25
0
    def test_get_site_offers(self):
        models.ConditionalOffer.objects.create(
            name="globaloffer", condition=self.condition,
            benefit=self.benefit, offer_type=models.ConditionalOffer.SITE)
        models.ConditionalOffer.objects.create(
            name="sessionoffer", condition=self.condition,
            benefit=self.benefit, offer_type=models.ConditionalOffer.SESSION)

        site_offers = Applicator().get_site_offers()
        # Only one offer should be returned
        self.assertEqual(len(site_offers), 1)
        self.assertEqual(site_offers[0].name, "globaloffer")
Ejemplo n.º 26
0
    def post(self, request, *args, **kwargs):
        """
        Place an order.

        We fetch the txn details again and then proceed with oscar's standard
        payment details view for placing the order.
        """
        try:
            payer_id = request.POST['payer_id']
            token = request.POST['token']
        except KeyError:
            # Probably suspicious manipulation if we get here
            messages.error(
                self.request,
                _("A problem occurred communicating with PayPal - please try again later"
                  ))
            return HttpResponseRedirect(reverse('basket:summary'))
        try:
            self.fetch_paypal_data(payer_id, token)
        except PayPalError:
            # Unable to fetch txn details from PayPal - we have to bail out
            messages.error(
                self.request,
                _("A problem occurred communicating with PayPal - please try again later"
                  ))
            return HttpResponseRedirect(reverse('basket:summary'))

        # Pass the user email so it can be stored with the order
        order_kwargs = {}  # 'guest_email': self.txn.value('EMAIL')}

        # Lookup the frozen basket that this txn corresponds to
        try:
            self.basket = Basket.objects.get(id=kwargs['basket_id'],
                                             status=Basket.FROZEN)
            Applicator().apply(request, self.basket)
            request.basket = self.basket
        except Basket.DoesNotExist:
            messages.error(
                self.request,
                _("No basket was found that corresponds to your "
                  "PayPal transaction"))
            return HttpResponseRedirect(reverse('basket:summary'))

        return self.submit(self.basket, order_kwargs=order_kwargs)
    def setUp(self):
        self.condition_product = factories.ProductFactory()
        condition_range = factories.RangeFactory()
        condition_range.add_product(self.condition_product)
        self.condition = BluelightCountCondition.objects.create(
            range=condition_range,
            type=Condition.COUNT,
            value=2)

        self.benefit_product = factories.ProductFactory()
        benefit_range = factories.RangeFactory()
        benefit_range.add_product(self.benefit_product)
        self.benefit = BluelightAbsoluteDiscountBenefit.objects.create(
            range=benefit_range,
            type=Benefit.FIXED,
            value=D('3.00'))

        self.offer = ConditionalOffer(
            id=1, condition=self.condition, benefit=self.benefit)
        self.basket = factories.create_basket(empty=True)

        self.applicator = Applicator()
Ejemplo n.º 28
0
    def get(self, request, *args, **kwargs):
        """
        Fetch details about the successful transaction from
        PayPal.  We use these details to show a preview of
        the order with a 'submit' button to place it.
        """
        try:
            payer_id = request.GET['PayerID']
            token = request.GET['token']
        except KeyError:
            # Manipulation - redirect to basket page with warning message
            messages.error(self.request,
                           _("Unable to determine PayPal transaction details"))
            return HttpResponseRedirect(reverse('basket:summary'))

        try:
            self.fetch_paypal_data(payer_id, token)
        except PayPalError:
            messages.error(
                self.request,
                _("A problem occurred communicating with PayPal - please try again later"
                  ))
            return HttpResponseRedirect(reverse('basket:summary'))

        # Lookup the frozen basket that this txn corresponds to
        try:
            self.basket = Basket.objects.get(id=kwargs['basket_id'],
                                             status=Basket.FROZEN)
            Applicator().apply(request, self.basket)
            request.basket = self.basket
        except Basket.DoesNotExist:
            messages.error(
                self.request,
                _("No basket was found that corresponds to your "
                  "PayPal transaction"))
            return HttpResponseRedirect(reverse('basket:summary'))

        return super(SuccessResponseView, self).get(request, *args, **kwargs)
Ejemplo n.º 29
0
class TestBasketLineForm(TestCase):
    def setUp(self):
        self.applicator = Applicator()
        rng = RangeFactory(includes_all_products=True)
        self.condition = ConditionFactory(
            range=rng,
            type=ConditionFactory._meta.model.VALUE,
            value=D('100'),
            proxy_class=None)
        self.benefit = BenefitFactory(range=rng,
                                      type=BenefitFactory._meta.model.FIXED,
                                      value=D('10'),
                                      max_affected_items=1)
        self.basket = factories.create_basket()
        self.line = self.basket.all_lines()[0]

    def mock_availability_return_value(self, is_available, reason=''):
        policy = self.line.purchase_info.availability
        policy.is_purchase_permitted = mock.MagicMock(
            return_value=(is_available, reason))

    def build_form(self, quantity=None):
        if quantity is None:
            quantity = self.line.quantity
        return forms.BasketLineForm(strategy=self.basket.strategy,
                                    data={'quantity': quantity},
                                    instance=self.line)

    def test_enforces_availability_policy_for_valid_quantities(self):
        self.mock_availability_return_value(True)
        form = self.build_form()
        self.assertTrue(form.is_valid())

    def test_enforces_availability_policy_for_invalid_quantities(self):
        self.mock_availability_return_value(False, "Some reason")
        form = self.build_form()
        self.assertFalse(form.is_valid())
        self.assertEqual(form.errors['quantity'], ['Some reason'])

    def test_skips_availability_policy_for_zero_quantities(self):
        self.mock_availability_return_value(True)
        form = self.build_form(quantity=0)
        self.assertTrue(form.is_valid())

    def test_enforces_max_line_quantity_for_new_product(self):
        invalid_qty = settings.OSCAR_MAX_BASKET_QUANTITY_THRESHOLD + 1
        form = self.build_form(quantity=invalid_qty)
        self.assertFalse(form.is_valid())

    @override_settings(OSCAR_MAX_BASKET_QUANTITY_THRESHOLD=10)
    def test_enforce_max_line_quantity_for_existing_product(self):
        self.basket.flush()
        product = factories.create_product(num_in_stock=20)
        add_product(self.basket, D('100'), 4, product)
        self.line = self.basket.all_lines()[0]
        form = self.build_form(quantity=6)
        self.assertTrue(form.is_valid())
        form.save()
        form = self.build_form(quantity=11)
        self.assertFalse(form.is_valid())

    def test_line_quantity_max_attribute_per_num_available(self):
        self.basket.flush()
        product = factories.create_product(num_in_stock=20)
        add_product(self.basket, D('100'), 4, product)
        self.line = self.basket.all_lines()[0]
        form = self.build_form()
        self.assertIn('max="20"', str(form['quantity']))

    @override_settings(OSCAR_MAX_BASKET_QUANTITY_THRESHOLD=10)
    def test_line_quantity_max_attribute_per_basket_threshold(self):
        self.basket.flush()
        product = factories.create_product(num_in_stock=20)
        add_product(self.basket, D('100'), 4, product)
        self.line = self.basket.all_lines()[0]
        form = self.build_form()
        self.assertIn('max="6"', str(form['quantity']))

    def test_basketline_formset_ordering(self):
        # when we use a unordered queryset in the Basketlineformset, the
        # discounts will be lost because django will query the database
        # again to enforce ordered results
        add_product(self.basket, D('100'), 5)
        offer = ConditionalOfferFactory(pk=1,
                                        condition=self.condition,
                                        benefit=self.benefit)

        # now we force an unordered queryset so we can see that our discounts
        # will disappear due to a new ordering query (see django/forms/model.py)
        default_line_ordering = Line._meta.ordering
        Line._meta.ordering = []
        self.basket._lines = self.basket.lines.all()

        self.applicator.apply_offers(self.basket, [offer])
        formset = formsets.BasketLineFormSet(strategy=self.basket.strategy,
                                             queryset=self.basket.all_lines())

        # the discount is in all_lines():
        self.assertTrue(self.basket.all_lines()[0].has_discount)

        # but not in the formset
        self.assertFalse(formset.forms[0].instance.has_discount)

        # Restore the ordering on the line
        Line._meta.ordering = default_line_ordering

        # clear the cached lines and apply the offer again
        self.basket._lines = None
        self.applicator.apply_offers(self.basket, [offer])

        formset = formsets.BasketLineFormSet(strategy=self.basket.strategy,
                                             queryset=self.basket.all_lines())
        self.assertTrue(formset.forms[0].instance.has_discount)
Ejemplo n.º 30
0
class TestBasketLineForm(TestCase):

    def setUp(self):
        self.applicator = Applicator()
        rng = RangeFactory(includes_all_products=True)
        self.condition = ConditionFactory(
            range=rng, type=ConditionFactory._meta.model.VALUE,
            value=D('100'), proxy_class=None)
        self.benefit = BenefitFactory(
            range=rng, type=BenefitFactory._meta.model.FIXED,
            value=D('10'), max_affected_items=1)
        self.basket = factories.create_basket()
        self.line = self.basket.all_lines()[0]

    def mock_availability_return_value(self, is_available, reason=''):
        policy = self.line.purchase_info.availability
        policy.is_purchase_permitted = mock.MagicMock(
            return_value=(is_available, reason))

    def build_form(self, quantity=None):
        if quantity is None:
            quantity = self.line.quantity
        return forms.BasketLineForm(
            strategy=self.basket.strategy,
            data={'quantity': quantity},
            instance=self.line)

    def test_enforces_availability_policy_for_valid_quantities(self):
        self.mock_availability_return_value(True)
        form = self.build_form()
        self.assertTrue(form.is_valid())

    def test_enforces_availability_policy_for_invalid_quantities(self):
        self.mock_availability_return_value(False, "Some reason")
        form = self.build_form()
        self.assertFalse(form.is_valid())
        self.assertEqual(
            form.errors['quantity'], ['Some reason'])

    def test_skips_availability_policy_for_zero_quantities(self):
        self.mock_availability_return_value(True)
        form = self.build_form(quantity=0)
        self.assertTrue(form.is_valid())

    def test_enforces_max_line_quantity_for_new_product(self):
        invalid_qty = settings.OSCAR_MAX_BASKET_QUANTITY_THRESHOLD + 1
        form = self.build_form(quantity=invalid_qty)
        self.assertFalse(form.is_valid())

    @override_settings(OSCAR_MAX_BASKET_QUANTITY_THRESHOLD=10)
    def test_enforce_max_line_quantity_for_existing_product(self):
        self.basket.flush()
        product = factories.create_product(num_in_stock=20)
        add_product(self.basket, D('100'), 4, product)
        self.line = self.basket.all_lines()[0]
        form = self.build_form(quantity=6)
        self.assertTrue(form.is_valid())
        form.save()
        form = self.build_form(quantity=11)
        self.assertFalse(form.is_valid())

    def test_line_quantity_max_attribute_per_num_available(self):
        self.basket.flush()
        product = factories.create_product(num_in_stock=20)
        add_product(self.basket, D('100'), 4, product)
        self.line = self.basket.all_lines()[0]
        form = self.build_form()
        self.assertIn('max="20"', str(form['quantity']))

    @override_settings(OSCAR_MAX_BASKET_QUANTITY_THRESHOLD=10)
    def test_line_quantity_max_attribute_per_basket_threshold(self):
        self.basket.flush()
        product = factories.create_product(num_in_stock=20)
        add_product(self.basket, D('100'), 4, product)
        self.line = self.basket.all_lines()[0]
        form = self.build_form()
        self.assertIn('max="6"', str(form['quantity']))

    def test_basketline_formset_ordering(self):
        # when we use a unordered queryset in the Basketlineformset, the
        # discounts will be lost because django will query the database
        # again to enforce ordered results
        add_product(self.basket, D('100'), 5)
        offer = ConditionalOfferFactory(
            pk=1, condition=self.condition, benefit=self.benefit)

        # now we force an unordered queryset so we can see that our discounts
        # will disappear due to a new ordering query (see django/forms/model.py)
        default_line_ordering = Line._meta.ordering
        Line._meta.ordering = []
        self.basket._lines = self.basket.lines.all()

        self.applicator.apply_offers(self.basket, [offer])
        formset = formsets.BasketLineFormSet(
            strategy=self.basket.strategy,
            queryset=self.basket.all_lines())

        # the discount is in all_lines():
        self.assertTrue(self.basket.all_lines()[0].has_discount)

        # but not in the formset
        self.assertFalse(formset.forms[0].instance.has_discount)

        # Restore the ordering on the line
        Line._meta.ordering = default_line_ordering

        # clear the cached lines and apply the offer again
        self.basket._lines = None
        self.applicator.apply_offers(self.basket, [offer])

        formset = formsets.BasketLineFormSet(
            strategy=self.basket.strategy,
            queryset=self.basket.all_lines())
        self.assertTrue(formset.forms[0].instance.has_discount)