Example #1
0
    def test_is_single_use_range_condition_satisfied(self):
        """
        Verify that the condition for a single use coupon is only satisfied by single-product baskets.
        """
        valid_user_email = 'valid@{domain}'.format(domain=self.valid_sub_domain)
        basket = factories.BasketFactory(site=self.site, owner=factories.UserFactory(email=valid_user_email))
        product1 = self.create_entitlement_product()
        product2 = self.create_entitlement_product()

        _range = factories.RangeFactory()
        _range.course_seat_types = ','.join(Range.ALLOWED_SEAT_TYPES)
        _range.catalog_query = 'uuid:*'
        benefit = factories.BenefitFactory(range=_range)
        offer = factories.ConditionalOfferFactory(benefit=benefit)
        offer.set_voucher(
            factories.VoucherFactory(usage='Single-use')
        )
        self.mock_access_token_response()
        self.mock_catalog_query_contains_endpoint(
            course_run_ids=[], course_uuids=[product1.attr.UUID, product2.attr.UUID], absent_ids=[],
            query=benefit.range.catalog_query, discovery_api_url=self.site_configuration.discovery_api_url
        )

        # Verify that each product individually satisfies the condition
        basket.add_product(product1)
        self.assertTrue(offer.is_condition_satisfied(basket))

        basket.flush()
        basket.add_product(product2)
        self.assertTrue(offer.is_condition_satisfied(basket))

        # Verify that the offer cannot be applied to a multi-product basket
        basket.add_product(product1)
        self.assertFalse(offer.is_condition_satisfied(basket))
Example #2
0
 def test_add_multiple_products_and_use_voucher(self, usage):
     """ Verify the basket accepts multiple products and a single use voucher. """
     products = ProductFactory.create_batch(
         3, stockrecords__partner=self.partner)
     voucher = factories.VoucherFactory(usage=usage)
     product_range = factories.RangeFactory(products=products)
     voucher.offers.add(
         factories.ConditionalOfferFactory(
             benefit=factories.BenefitFactory(range=product_range),
             condition=factories.ConditionFactory(range=product_range)))
     qs = urllib.urlencode(
         {
             'sku': [
                 product.stockrecords.first().partner_sku
                 for product in products
             ],
             'code':
             voucher.code
         }, True)
     url = '{root}?{qs}'.format(root=self.path, qs=qs)
     response = self.client.get(url)
     self.assertEqual(response.status_code, 303)
     basket = response.wsgi_request.basket
     self.assertEqual(basket.status, Basket.OPEN)
     self.assertTrue(basket.contains_voucher(voucher.code))
    def test_transfers_vouchers_to_new_basket(self):
        baskets = [factories.BasketFactory(), factories.BasketFactory()]
        voucher = factories.VoucherFactory()
        baskets[0].vouchers.add(voucher)
        baskets[1].merge(baskets[0])

        self.assertEqual(1, baskets[1].vouchers.all().count())
    def test_single_usage(self):
        user = AnonymousUser()
        basket = factories.create_basket()
        creator = OrderCreator()

        voucher = factories.VoucherFactory(usage=Voucher.SINGLE_USE)
        voucher.offers.add(factories.create_offer(offer_type='Voucher'))
        basket.vouchers.add(voucher)

        surcharges = SurchargeApplicator().get_applicable_surcharges(basket)

        place_order(creator,
                    surcharges=surcharges,
                    basket=basket,
                    order_number='12346',
                    user=user)
        assert voucher.applications.count() == 1

        # Make sure the voucher usage is rechecked
        with pytest.raises(ValueError):
            place_order(creator,
                        surcharges=surcharges,
                        basket=basket,
                        order_number='12347',
                        user=user)
Example #5
0
    def test_expired_voucher(self):
        user = AnonymousUser()
        basket = factories.create_basket()
        creator = OrderCreator()

        voucher = factories.VoucherFactory(usage=Voucher.SINGLE_USE)
        voucher.offers.add(factories.create_offer(offer_type='Voucher'))
        basket.vouchers.add(voucher)
        voucher.end_datetime = timezone.now() - datetime.timedelta(days=100)
        voucher.save()
        place_order(creator, basket=basket, order_number='12346', user=user)
        assert voucher.applications.count() == 0
Example #6
0
 def _create_coupon_product_with_note_attribute(self, note):
     """Helper method that creates a coupon product with note attribute set."""
     coupon_product = factories.ProductFactory(
         title=self.COUPON_PRODUCT_TITLE,
         product_class=self.coupon_product_class)
     voucher = factories.VoucherFactory()
     coupon_vouchers = CouponVouchers.objects.create(coupon=coupon_product)
     coupon_vouchers.vouchers.add(voucher)
     coupon_product.attr.coupon_vouchers = coupon_vouchers
     coupon_product.attr.note = note
     coupon_product.save()
     return coupon_product
Example #7
0
    def _create_coupon_and_voucher(self, enterprise_contract_metadata=None):
        """
        Create and link the coupon product and voucher, and return the coupon_code and voucher.
        """
        coupon = self.create_coupon_product()
        voucher = factories.VoucherFactory()
        voucher.offers.add(self.discount_offer)
        coupon_vouchers = CouponVouchers.objects.create(coupon=coupon)
        coupon_vouchers.vouchers.add(voucher)

        coupon.attr.enterprise_contract_metadata = enterprise_contract_metadata
        coupon.attr.coupon_vouchers = coupon_vouchers
        coupon.save()
        return coupon.attr.coupon_vouchers.vouchers.first().code, voucher
Example #8
0
    def test_post_valid(self):
        voucher = factories.VoucherFactory(num_basket_additions=5)

        data = {'code': voucher.code}
        request = RequestFactory().post('/', data=data)
        request.basket.save()
        request.basket.vouchers.add(voucher)

        view = views.VoucherRemoveView.as_view()
        response = view(request, pk=voucher.pk)
        self.assertEqual(response.status_code, 302)

        voucher = voucher.__class__.objects.get(pk=voucher.pk)
        self.assertEqual(voucher.num_basket_additions, 4)
    def test_voucher_single_usage(self):
        user = AnonymousUser()
        creator = OrderCreator()
        product = factories.ProductFactory()
        voucher = factories.VoucherFactory(usage=Voucher.SINGLE_USE)
        voucher.offers.add(factories.create_offer(offer_type='Voucher'))

        # Make the order creator a bit more slow too reliable trigger
        # concurrency issues
        org_create_order_model = OrderCreator.create_order_model

        def new_create_order_model(*args, **kwargs):
            time.sleep(0.5)
            return org_create_order_model(creator, *args, **kwargs)

        creator.create_order_model = new_create_order_model

        org_record_voucher_usage = OrderCreator.record_voucher_usage

        def record_voucher_usage(*args, **kwargs):
            time.sleep(0.5)
            return org_record_voucher_usage(creator, *args, **kwargs)

        creator.record_voucher_usage = record_voucher_usage

        # Start 5 threads to place an order concurrently
        def worker():
            order_number = threading.current_thread().name

            basket = factories.BasketFactory()
            basket.add_product(product)
            basket.vouchers.add(voucher)

            surcharges = SurchargeApplicator().get_applicable_surcharges(
                basket)
            place_order(creator,
                        surcharges=surcharges,
                        basket=basket,
                        order_number=order_number,
                        user=user)

        exceptions = run_concurrently(worker, num_threads=5)

        voucher.refresh_from_db()
        assert all(isinstance(x, ValueError) for x in exceptions), exceptions
        assert len(exceptions) == 4
        assert voucher.applications.count() == 1

        assert Order.objects.count() == 1
Example #10
0
    def test_post_valid(self):
        voucher = factories.VoucherFactory()
        self.assertTrue(voucher.is_active())

        data = {
            'code': voucher.code
        }
        request = RequestFactory().post('/', data=data)
        request.basket.save()

        view = views.VoucherAddView.as_view()
        response = view(request)
        self.assertEqual(response.status_code, 302)

        voucher = voucher.__class__.objects.get(pk=voucher.pk)
        self.assertEqual(voucher.num_basket_additions, 1, msg=self._get_voucher_message(request))
Example #11
0
 def _create_coupon_product_with_attributes(self,
                                            note='note',
                                            notify_email=None):
     """Helper method that creates a coupon product with note and notify_email attributes."""
     coupon_product = factories.ProductFactory(
         title=self.COUPON_PRODUCT_TITLE,
         product_class=self.coupon_product_class,
         categories=[])
     voucher = factories.VoucherFactory()
     coupon_vouchers = CouponVouchers.objects.create(coupon=coupon_product)
     coupon_vouchers.vouchers.add(voucher)
     coupon_product.attr.coupon_vouchers = coupon_vouchers
     coupon_product.attr.note = note
     if notify_email:
         coupon_product.attr.notify_email = notify_email
     coupon_product.save()
     return coupon_product