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)
def test_coupon_applied_on_site_offer(self): """Coupon offer supersedes site offer.""" self.mock_access_token_response() self.mock_account_api(self.request, self.user.username, data={'is_active': True}) product_price = 100 site_offer_discount = 20 voucher_discount = 10 voucher, product = prepare_voucher(benefit_value=voucher_discount) stockrecord = product.stockrecords.first() stockrecord.price_excl_tax = product_price stockrecord.save() _range = factories.RangeFactory(includes_all_products=True) site_offer = factories.ConditionalOfferFactory( offer_type=ConditionalOffer.SITE, benefit=factories.BenefitFactory(range=_range, value=site_offer_discount), condition=factories.ConditionFactory(type=Condition.COVERAGE, value=1, range=_range)) self.basket.add_product(product) # Only site offer is applied to the basket. self.assert_basket_discounts([site_offer]) # Only the voucher offer is applied to the basket. self.client.post(reverse('basket:vouchers-add'), data={'code': voucher.code}) self.assert_basket_discounts( expected_voucher_discounts=[voucher.offers.first()]) # Site offer discount is still present after removing voucher. self.client.post( reverse('basket:vouchers-remove', kwargs={'pk': voucher.id})) self.assert_basket_discounts([site_offer])
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))
def test_change_priority_of_offers_in_batches(self, offset, limit, priority): """Test that command changes priority of voucher offers in batches.""" ent_offer_count = 30 for idx in range(ent_offer_count): factories.ConditionalOfferFactory( name='ENT Offer {}'.format(idx), offer_type=ConditionalOffer.VOUCHER, priority=priority ) update_offer_cnt = limit if offset + limit <= ent_offer_count else ent_offer_count - offset offers_list = [ '{}. ENT Offer {}'.format(idx + 1, val) for idx, val in enumerate(range(offset, offset + update_offer_cnt)) ] offer_names = '\n'.join(offers_list) expected = [ ( LOGGER_NAME, 'WARNING', 'Conditional offers to be updated\n{offer_names}'.format( offer_names=offer_names, ) ) ] with patch(self.YES_NO_PATCH_LOCATION) as mocked_yes_no: mocked_yes_no.return_value = True with LogCapture(LOGGER_NAME) as log: call_command('change_priority_of_offers', offset=offset, limit=limit, priority=priority) log_msg = 'Operation completed. {} conditional offers updated successfully.'.format(update_offer_cnt) expected.append( ( LOGGER_NAME, 'INFO', log_msg ) ) log.check(*expected)
def test_condition_satisfied_for_enterprise_switch_off(self): """Verify a condition is satisfied.""" Switch.objects.update_or_create( name=ENTERPRISE_OFFERS_FOR_COUPONS_SWITCH, defaults={'active': False}) valid_user_email = 'valid@{domain}'.format( domain=self.valid_sub_domain) basket = factories.BasketFactory( site=self.site, owner=factories.UserFactory(email=valid_user_email)) _range = factories.RangeFactory(products=[ self.product, ], course_seat_types='verified', enterprise_customer=str( uuid4()).decode('utf-8'), catalog_query='*:*') benefit = factories.BenefitFactory(range=_range) offer = factories.ConditionalOfferFactory(benefit=benefit) with patch.object(benefit, 'get_applicable_lines', return_value=[1]): basket.add_product(self.product) self.assertTrue(offer.is_condition_satisfied(basket))
def test_creating_offer_with_null_partner(self): """Verify creating ConditionalOffer with no partner specified""" offer = factories.ConditionalOfferFactory() self.assertEqual(offer.partner, None)
def test_creating_offer_with_invalid_max_global_applications( self, max_uses): """Verify creating ConditionalOffer with invalid max global applications value raises validation error.""" with self.assertRaises(ValidationError): factories.ConditionalOfferFactory(max_global_applications=max_uses)
def test_creating_offer_with_valid_max_global_applications(self): """Verify creating ConditionalOffer with valid max global applications value.""" offer = factories.ConditionalOfferFactory(max_global_applications=5) self.assertEqual(offer.max_global_applications, 5)
def test_creating_offer_with_invalid_email_domains(self, email_domains): """Verify creating ConditionalOffer with invalid email domains raises validation error.""" with self.assertRaises(ValidationError): factories.ConditionalOfferFactory(email_domains=email_domains)
def test_creating_offer_with_valid_email_domains(self, email_domains): """Verify creating ConditionalOffer with valid email domains.""" offer = factories.ConditionalOfferFactory(email_domains=email_domains) self.assertEqual(offer.email_domains, email_domains)
def test_creating_offer_with_null_site(self): """Verify creating ConditionalOffer with no site specified""" offer = factories.ConditionalOfferFactory() self.assertEqual(offer.site, None)
def test_creating_offer_with_site(self): """Verify creating ConditionalOffer with site specified""" offer = factories.ConditionalOfferFactory(site=self.site) self.assertEqual(offer.site, self.site)
def setUp(self): super().setUp() self.basket = factories.create_basket(empty=True) # Create range and add one product to it. rng = factories.RangeFactory(name='All products', includes_all_products=True) self.product = factories.ProductFactory() rng.add_product(self.product) # Create offer #1. condition1 = factories.ConditionFactory( range=rng, type=factories.ConditionFactory._meta.model.COUNT, value=D('2'), ) benefit1 = factories.BenefitFactory( range=rng, type=factories.BenefitFactory._meta.model.MULTIBUY, value=None, ) self.offer1 = factories.ConditionalOfferFactory( condition=condition1, benefit=benefit1, slug='offer-1', start_datetime=now(), name='Test offer #1', priority=1, ) # Create offer #2. condition2 = factories.ConditionFactory( range=rng, type=factories.ConditionFactory._meta.model.COUNT, value=D('1'), ) benefit2 = factories.BenefitFactory( range=rng, type=factories.BenefitFactory._meta.model.PERCENTAGE, value=D('5'), ) self.offer2 = factories.ConditionalOfferFactory( condition=condition2, benefit=benefit2, slug='offer-2', start_datetime=now(), name='Test offer #2', ) # Create offer #3. condition3 = factories.ConditionFactory( range=rng, type=factories.ConditionFactory._meta.model.COUNT, value=D('1'), ) benefit3 = factories.BenefitFactory( range=rng, type=factories.BenefitFactory._meta.model.MULTIBUY, value=None, ) self.offer3 = factories.ConditionalOfferFactory( condition=condition3, benefit=benefit3, slug='offer-3', start_datetime=now(), name='Test offer #3', exclusive=False, ) # Create offer #4. condition4 = factories.ConditionFactory( range=rng, type=factories.ConditionFactory._meta.model.COUNT, value=D('1'), ) benefit4 = factories.BenefitFactory( range=rng, type=factories.BenefitFactory._meta.model.MULTIBUY, value=None, ) self.offer4 = factories.ConditionalOfferFactory( condition=condition4, benefit=benefit4, slug='offer-4', start_datetime=now(), name='Test offer #4', exclusive=False, priority=3, )
def setUp(self): super().setUp() self.basket = factories.create_basket(empty=True) # Create range and add one product to it. rng = factories.RangeFactory(name='All products', includes_all_products=True) self.product = factories.ProductFactory() rng.add_product(self.product) # Create offer #1. condition1 = factories.ConditionFactory( range=rng, type=factories.ConditionFactory._meta.model.COUNT, value=D('2'), ) benefit1 = factories.BenefitFactory( range=rng, type=factories.BenefitFactory._meta.model.MULTIBUY, value=None, ) self.offer1 = factories.ConditionalOfferFactory( condition=condition1, benefit=benefit1, slug='offer-1', start_datetime=now(), name='Test offer #1', priority=1, ) # Create offer #2. condition2 = factories.ConditionFactory( range=rng, type=factories.ConditionFactory._meta.model.VALUE, value=D('1.99'), ) benefit2 = factories.BenefitFactory( range=rng, type=factories.BenefitFactory._meta.model.MULTIBUY, value=None, ) self.offer2 = factories.ConditionalOfferFactory( condition=condition2, benefit=benefit2, slug='offer-2', start_datetime=now(), name='Test offer #2', ) # Create offer #3. condition3 = factories.ConditionFactory( range=rng, type=factories.ConditionFactory._meta.model.COVERAGE, value=1, ) benefit3 = factories.BenefitFactory( range=rng, type=factories.BenefitFactory._meta.model.MULTIBUY, value=None, ) self.offer3 = factories.ConditionalOfferFactory( condition=condition3, benefit=benefit3, slug='offer-3', start_datetime=now(), name='Test offer #3', ) # Prepare `BasketView` to use `get_upsell_messages` method in tests. self.view = BasketView() self.view.request = RequestFactory().get(reverse('basket:summary')) self.view.request.user = factories.UserFactory() self.view.args = [] self.view.kwargs = {}