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)
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)
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)
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))
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)
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)
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)
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)
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)
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)
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)
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))
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
def setUp(self): super(ProgramCourseRunSeatsConditionTests, self).setUp() self.condition = factories.ProgramCourseRunSeatsConditionFactory() self.test_product = ProductFactory()