def test_list(self):
        """The list endpoint should return only products with current site's partner."""
        ProductFactory.create_batch(3, stockrecords__partner=PartnerFactory())

        response = self.client.get(PRODUCT_LIST_PATH)
        self.assertEqual(Product.objects.count(), 5)
        self.assertEqual(response.status_code, 200)
        results = [
            self.serialize_product(p) for p in self.course.products.all()
        ]
        expected = {
            'count': 2,
            'next': None,
            'previous': None,
            'results': results
        }
        self.assertDictEqual(response.json(), expected)

        # If no products exist, the view should return an empty result set.
        Product.objects.all().delete()
        response = self.client.get(PRODUCT_LIST_PATH)
        self.assertEqual(response.status_code, 200)
        expected = {'count': 0, 'next': None, 'previous': None, 'results': []}
        self.assertDictEqual(response.json(), expected)
Example #2
0
    def test_with_both_unavailable_and_available_products(self):
        """ Verify the basket ignores unavailable products and continue with available products. """
        products = ProductFactory.create_batch(3, stockrecords__partner=self.partner)

        products[0].expires = pytz.utc.localize(datetime.datetime.min)
        products[0].save()
        self.assertFalse(Selector().strategy().fetch_for_product(products[0]).availability.is_available_to_buy)

        qs = urllib.urlencode({
            'sku': [product.stockrecords.first().partner_sku for product in products],
        }, 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)
Example #3
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)
        product_range = factories.RangeFactory(products=products)
        voucher, __ = prepare_voucher(_range=product_range, usage=usage)

        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 setUp(self):
        super(EnterpriseCustomerConditionTests, self).setUp()
        self.user = UserFactory()
        self.condition = factories.EnterpriseCustomerConditionFactory()

        self.test_product = ProductFactory(stockrecords__price_excl_tax=10,
                                           categories=[])
        self.course_run = CourseFactory(partner=self.partner)
        self.course_run.create_or_update_seat('verified', True, Decimal(100))

        self.entitlement = create_or_update_course_entitlement(
            'verified', 100, self.partner, 'edX-DemoX', 'edX Demo Entitlement')
        self.entitlement_stock_record = StockRecord.objects.filter(
            product=self.entitlement).first()
        self.entitlement_catalog = Catalog.objects.create(partner=self.partner)
        self.entitlement_catalog.stock_records.add(
            self.entitlement_stock_record)
Example #5
0
    def test_add_multiple_products_to_basket(self):
        """ Verify the basket accepts multiple products. """
        products = ProductFactory.create_batch(
            3, stockrecords__partner=self.partner)
        qs = urllib.urlencode(
            {
                'sku': [
                    product.stockrecords.first().partner_sku
                    for product in products
                ]
            }, 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.assertEqual(basket.lines.count(), len(products))
Example #6
0
    def test_track_completed_discounted_order_with_voucher(self):
        """ An event including coupon information should be sent to Segment"""
        with mock.patch('ecommerce.extensions.checkout.signals.track_segment_event') as mock_track:
            # Orders may be discounted by percent
            percent_benefit = 66
            product = ProductFactory(categories=[], stockrecords__price_currency='USD')
            _range = factories.RangeFactory(products=[product], )
            voucher, product = prepare_voucher(_range=_range, benefit_value=percent_benefit)

            basket = factories.BasketFactory(owner=self.user, site=self.site)
            basket.add_product(product)
            basket.vouchers.add(voucher)
            Applicator().apply(basket, user=basket.owner, request=self.request)

            order = factories.create_order(basket=basket, user=self.user)
            track_completed_order(None, order)
            properties = self._generate_event_properties(order, voucher)
            mock_track.assert_called_once_with(order.site, order.user, 'Order Completed', properties, traits=properties)
Example #7
0
    def setUp(self):
        super(BasketCalculateViewTests, self).setUp()
        self.products = ProductFactory.create_batch(
            3, stockrecords__partner=self.partner)
        qs = urllib.urlencode(
            {
                'sku': [
                    product.stockrecords.first().partner_sku
                    for product in self.products
                ]
            }, True)
        self.path = reverse('api:v2:baskets:calculate')
        self.url = '{root}?{qs}'.format(root=self.path, qs=qs)
        self.range = factories.RangeFactory(includes_all_products=True)
        self.product_total = sum(product.stockrecords.first().price_excl_tax
                                 for product in self.products)

        self.user = self.create_user(is_staff=True)
        self.client.login(username=self.user.username, password=self.password)
Example #8
0
 def test_not_already_purchased_products(self):
     """
     Test user can purchase products which have not been already purchased
     """
     products = ProductFactory.create_batch(
         3, stockrecords__partner=self.partner)
     qs = urllib.urlencode(
         {
             'sku': [
                 product.stockrecords.first().partner_sku
                 for product in products
             ]
         }, True)
     url = '{root}?{qs}'.format(root=self.path, qs=qs)
     with mock.patch.object(UserAlreadyPlacedOrder,
                            'user_already_placed_order',
                            return_value=False):
         response = self.client.get(url)
         self.assertEqual(response.status_code, 303)
Example #9
0
 def test_one_already_purchased_product(self):
     """
     Test prepare_basket removes already purchased product and checkout for the rest of products
     """
     order = create_order(site=self.site, user=self.user)
     products = ProductFactory.create_batch(
         3, stockrecords__partner=self.partner)
     products.append(OrderLine.objects.get(order=order).product)
     qs = urllib.urlencode(
         {
             'sku': [
                 product.stockrecords.first().partner_sku
                 for product in products
             ]
         }, True)
     url = '{root}?{qs}'.format(root=self.path, qs=qs)
     response = self.client.get(url)
     basket = response.wsgi_request.basket
     self.assertEqual(response.status_code, 303)
     self.assertEqual(basket.lines.count(), len(products) - 1)
Example #10
0
    def test_track_completed_discounted_order_with_offer(self):
        """ An event including a discount but no coupon should be sent to Segment"""
        with mock.patch('ecommerce.extensions.checkout.signals.track_segment_event') as mock_track:
            # Orders may be discounted by a fixed value
            offer_discount = 5
            product = ProductFactory(categories=[], stockrecords__price_currency='USD')
            _range = factories.RangeFactory(products=[product], )
            site_offer = factories.ConditionalOfferFactory(
                offer_type=ConditionalOffer.SITE,
                benefit=factories.BenefitFactory(range=_range, value=offer_discount),
                condition=factories.ConditionFactory(type=Condition.COVERAGE, value=1, range=_range)
            )

            basket = factories.BasketFactory(owner=self.user, site=self.site)
            basket.add_product(product)
            Applicator().apply_offers(basket, [site_offer])

            order = factories.create_order(basket=basket, user=self.user)
            track_completed_order(None, order)
            properties = self._generate_event_properties(order)
            mock_track.assert_called_once_with(order.site, order.user, 'Order Completed', properties, traits=properties)
Example #11
0
    def test_track_completed_discounted_order_with_voucher_with_offer(self):
        with mock.patch('ecommerce.extensions.checkout.signals.track_segment_event') as mock_track:
            # Orders may be discounted by a fixed value
            fixed_benefit = 5.00
            offer_discount = 6
            product = ProductFactory(categories=[], stockrecords__price_currency='USD')
            _range = factories.RangeFactory(products=[product], )
            voucher, product = prepare_voucher(_range=_range, benefit_value=fixed_benefit, benefit_type=Benefit.FIXED)
            factories.ConditionalOfferFactory(
                offer_type=ConditionalOffer.SITE,
                benefit=factories.BenefitFactory(range=_range, value=offer_discount),
                condition=factories.ConditionFactory(type=Condition.COVERAGE, value=1, range=_range)
            )

            basket = factories.BasketFactory(owner=self.user, site=self.site)
            basket.add_product(product)
            basket.vouchers.add(voucher)
            Applicator().apply(basket, user=basket.owner, request=self.request)

            order = factories.create_order(basket=basket, user=self.user)
            track_completed_order(None, order)
            properties = self._generate_event_properties(order, voucher)
            mock_track.assert_called_once_with(order.site, order.user, 'Order Completed', properties, traits=properties)
Example #12
0
 def test_generate_sku_with_unexpected_product_class(self):
     """Verify the method raises an exception for unsupported product class."""
     product = ProductFactory()
     with self.assertRaises(Exception):
         generate_sku(product, self.partner)
Example #13
0
 def test_no_voucher_error_msg(self):
     """ Verify correct error message is returned when voucher can't be found. """
     self.basket.add_product(ProductFactory())
     self.assert_form_valid_message(
         "Coupon code '{code}' does not exist.".format(code=COUPON_CODE))
Example #14
0
 def setUp(self):
     super(ProgramCourseRunSeatsConditionTests, self).setUp()
     self.condition = factories.ProgramCourseRunSeatsConditionFactory()
     self.test_product = ProductFactory(stockrecords__price_excl_tax=10,
                                        categories=[])
     self.site.siteconfiguration.enable_partial_program = True
Example #15
0
 def setUp(self):
     super(ProgramCourseRunSeatsConditionTests, self).setUp()
     self.condition = factories.ProgramCourseRunSeatsConditionFactory()
     self.test_product = ProductFactory()