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")
    def test_description(self):
        basket = BasketFactory()
        product = ProductFactory(title="A product")
        basket.add_product(product)

        line = basket.lines.first()
        self.assertEqual(line.description, "A product")
 def test_create_line_reference(self):
     basket = BasketFactory()
     product = ProductFactory(title="A product")
     option = OptionFactory(name="product_option", code="product_option")
     option_product = ProductFactory(title='Asunción')
     options = [{'option': option, 'value': option_product}]
     basket.add_product(product, options=options)
def filled_basket():
    basket = BasketFactory()
    product1 = ProductFactory()
    product2 = ProductFactory()
    basket.add_product(product1, quantity=10)
    basket.add_product(product2, quantity=20)
    return basket
Beispiel #5
0
    def test_description_with_attributes(self):
        basket = BasketFactory()
        product = ProductFactory(title="A product")
        basket.add_product(product)

        line = basket.lines.first()
        BasketLineAttributeFactory(line=line, value=u"\u2603", option__name="with")
        self.assertEqual(line.description, u"A product (with = '\u2603')")
 def test_is_satisfied_free_basket(self):
     """ Ensure the condition returns False if the basket total is zero. """
     offer = factories.EnterpriseOfferFactory(partner=self.partner,
                                              condition=self.condition)
     basket = BasketFactory(site=self.site, owner=self.user)
     test_product = factories.ProductFactory(
         stockrecords__price_excl_tax=0,
         stockrecords__partner__short_code='test')
     basket.add_product(test_product)
     self.assertFalse(self.condition.is_satisfied(offer, basket))
Beispiel #7
0
    def test_description_with_attributes(self):
        basket = BasketFactory()
        product = ProductFactory(title="A product")
        basket.add_product(product)

        line = basket.lines.first()
        BasketLineAttributeFactory(line=line,
                                   value='\u2603',
                                   option__name='with')
        self.assertEqual(line.description, "A product (with = '\u2603')")
    def test_get_basket_with_multiple_existing_baskets(self):
        """ If the user already has multiple open baskets, verify the middleware merges the existing
        baskets, and returns the merged basket. """
        self.request.user = self.create_user()
        basket = BasketFactory(owner=self.request.user, site=self.site)
        basket2 = BasketFactory(owner=self.request.user, site=self.site)
        self.assertEqual(basket, self.middleware.get_basket(self.request))

        # The latter baskets should always be merged into the earlier basket.
        basket2 = Basket.objects.get(id=basket2.id)
        self.assertEqual(basket2.status, Basket.MERGED)
Beispiel #9
0
 def setUp(self):
     super(DynamicConditionTests, self).setUp()
     self.condition = Condition.objects.get(
         proxy_class=
         'ecommerce.extensions.offer.dynamic_conditional_offer.DynamicDiscountCondition'
     ).proxy()
     self.offer = ConditionalOffer.objects.get(
         name='dynamic_conditional_offer')
     self.basket = BasketFactory(site=self.site, owner=self.create_user())
     self.seat_product_class, __ = ProductClass.objects.get_or_create(
         name=SEAT_PRODUCT_CLASS_NAME)
    def _create_order(self, price, mode='verified'):
        seat = self.course.create_or_update_seat(mode, False, price, None)

        basket = BasketFactory(owner=self.user, site=self.site)
        basket.add_product(seat, 1)
        order = create_order(number=1,
                             basket=basket,
                             user=self.user,
                             site=self.site)
        order.total_excl_tax = price
        return seat, order
 def test_is_satisfied_wrong_enterprise(self):
     """ Ensure the condition returns false if the learner is associated with a different EnterpriseCustomer. """
     offer = factories.EnterpriseOfferFactory(partner=self.partner,
                                              condition=self.condition)
     basket = BasketFactory(site=self.site, owner=self.user)
     basket.add_product(self.course_run.seat_products[0])
     self.mock_enterprise_learner_api(
         learner_id=self.user.id,
         course_run_id=self.course_run.id,
     )
     self.assertFalse(self.condition.is_satisfied(offer, basket))
Beispiel #12
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'))
    def test_get_basket_with_siteless_basket(self):
        """ Verify the method should ignores baskets without a site. """
        self.request.user = self.create_user()
        basket = BasketFactory(owner=self.request.user, site=self.site)
        siteless_basket = BasketFactory(owner=self.request.user,
                                        status=Basket.OPEN)
        self.assertEqual(basket, self.middleware.get_basket(self.request))

        # Verify the site-less basket is unchanged
        actual = Basket.objects.get(id=siteless_basket.id)
        self.assertEqual(siteless_basket, actual)
        self.assertEqual(siteless_basket.status, Basket.OPEN)
Beispiel #14
0
 def test_apply_voucher_on_basket_and_check_discount_with_valid_voucher(self):
     """
     Tests apply_voucher_on_basket_and_check_discount when called with valid voucher
     applies voucher and returns the correct values.
     """
     basket = BasketFactory(owner=self.request.user, site=self.request.site)
     voucher, product = prepare_voucher()
     basket.add_product(product, 1)
     applied, msg = apply_voucher_on_basket_and_check_discount(voucher, self.request, basket)
     self.assertEqual(applied, True)
     self.assertIsNotNone(basket.applied_offers())
     self.assertEqual(msg, "Coupon code '{code}' added to basket.".format(code=voucher.code))
 def test_is_satisfied_no_course_product(self):
     """ Ensure the condition returns false if the basket contains a product not associated with a course run. """
     offer = factories.EnterpriseOfferFactory(partner=self.partner,
                                              condition=self.condition)
     basket = BasketFactory(site=self.site, owner=self.user)
     basket.add_product(self.test_product)
     self.mock_enterprise_learner_api(
         learner_id=self.user.id,
         enterprise_customer_uuid=str(
             self.condition.enterprise_customer_uuid),
         course_run_id=self.course_run.id,
     )
     self.assertFalse(self.condition.is_satisfied(offer, basket))
Beispiel #16
0
    def test_unsupported_product_class(self, mock_log_error, mock_update_course_enrollment):
        """ Verify Sailthru is not contacted for non-seat products. """
        coupon = self.create_coupon()
        basket = BasketFactory(owner=self.user, site=self.site)
        basket.add_product(coupon, 1)
        process_basket_addition(None, request=self.request, user=self.user, product=coupon, basket=basket)
        self.assertFalse(mock_update_course_enrollment.called)
        self.assertFalse(mock_log_error.called)

        order = create_order(number=1, basket=basket, user=self.user)
        process_checkout_complete(None, order=order, request=None)
        self.assertFalse(mock_update_course_enrollment.called)
        self.assertFalse(mock_log_error.called)
Beispiel #17
0
 def test_apply_voucher_on_basket_and_check_discount_with_invalid_product(self):
     """
     Tests apply_voucher_on_basket_and_check_discount when called with invalid product
     does not apply voucher and returns the correct values.
     """
     basket = BasketFactory(owner=self.request.user, site=self.request.site)
     product = ProductFactory(stockrecords__partner__short_code='test1', stockrecords__price_excl_tax=0)
     voucher, __ = prepare_voucher(_range=RangeFactory(products=[product]))
     basket.add_product(product, 1)
     applied, msg = apply_voucher_on_basket_and_check_discount(voucher, self.request, basket)
     self.assertEqual(applied, False)
     self.assertEqual(basket.applied_offers(), {})
     self.assertEqual(msg, 'Basket does not qualify for coupon code {code}.'.format(code=voucher.code))
Beispiel #18
0
 def test_apply_voucher_on_basket_and_check_discount_with_multiple_vouchers(self):
     """
     Tests apply_voucher_on_basket_and_check_discount when called with a basket already
     containing a valid voucher it only checks the new voucher.
     """
     basket = BasketFactory(owner=self.request.user, site=self.request.site)
     product = ProductFactory(stockrecords__partner__short_code='test1', stockrecords__price_excl_tax=10)
     invalid_voucher, __ = prepare_voucher(code='TEST1')
     valid_voucher, __ = prepare_voucher(code='TEST2', _range=RangeFactory(products=[product]))
     basket.add_product(product, 1)
     basket.vouchers.add(valid_voucher)
     applied, msg = apply_voucher_on_basket_and_check_discount(invalid_voucher, self.request, basket)
     self.assertEqual(applied, False)
     self.assertEqual(msg, 'Basket does not qualify for coupon code {code}.'.format(code=invalid_voucher.code))
Beispiel #19
0
    def test_voucher_errors(self):
        """ Test data when voucher error happen"""
        basket = BasketFactory(site=self.site)
        voucher, product = prepare_voucher(code='test101')
        basket.vouchers.add(voucher)
        basket.add_product(product)

        with mock.patch('ecommerce.extensions.api.serializers.VoucherSerializer', side_effect=ValueError):
            response = self.client.get(self.path, HTTP_AUTHORIZATION=self.token)
            self.assertIsNone(response.json()['results'][0]['vouchers'])

        with mock.patch('ecommerce.extensions.api.serializers.VoucherSerializer', side_effect=AttributeError):
            response = self.client.get(self.path, HTTP_AUTHORIZATION=self.token)
            self.assertIsNone(response.json()['results'][0]['vouchers'])
 def test_get_basket_with_single_existing_basket(self,
                                                 mock_set_custom_metric):
     """ If the user already has one open basket, verify the middleware returns the basket. """
     self.request.user = self.create_user()
     basket = BasketFactory(owner=self.request.user, site=self.site)
     self.assertEqual(basket, self.middleware.get_basket(self.request))
     mock_set_custom_metric.assert_called_with('basket_id', basket.id)
 def test_is_satisfied_true(self):
     """ Ensure the condition returns true if all basket requirements are met. """
     offer = factories.EnterpriseOfferFactory(partner=self.partner, condition=self.condition)
     basket = BasketFactory(site=self.site, owner=self.user)
     basket.add_product(self.course_run.seat_products[0])
     self.mock_enterprise_learner_api(
         learner_id=self.user.id,
         enterprise_customer_uuid=str(self.condition.enterprise_customer_uuid),
         course_run_id=self.course_run.id,
     )
     self.mock_catalog_contains_course_runs(
         [self.course_run.id],
         self.condition.enterprise_customer_uuid,
         enterprise_customer_catalog_uuid=self.condition.enterprise_customer_catalog_uuid,
     )
     self.assertTrue(self.condition.is_satisfied(offer, basket))
 def test_is_satisfied_for_anonymous_user(self):
     """ Ensure the condition returns false for an anonymous user. """
     offer = factories.EnterpriseOfferFactory(partner=self.partner, condition=self.condition)
     basket = BasketFactory(site=self.site, owner=None)
     basket.add_product(self.course_run.seat_products[0])
     self.mock_enterprise_learner_api(
         learner_id=self.user.id,
         enterprise_customer_uuid=str(self.condition.enterprise_customer_uuid),
         course_run_id=self.course_run.id,
     )
     self.mock_catalog_contains_course_runs(
         [self.course_run.id],
         self.condition.enterprise_customer_uuid,
         enterprise_customer_catalog_uuid=self.condition.enterprise_customer_catalog_uuid,
     )
     self.assertFalse(self.condition.is_satisfied(offer, basket))
Beispiel #23
0
    def test_basket_information(self):
        """ Test data return by the Api"""
        basket = BasketFactory(site=self.site)
        voucher, product = prepare_voucher(code='test101')
        basket.vouchers.add(voucher)
        basket.add_product(product)
        PaymentProcessorResponse.objects.create(basket=basket, transaction_id='PAY-123', processor_name='paypal',
                                                response=json.dumps({'state': 'approved'}))
        response = self.client.get(self.path, HTTP_AUTHORIZATION=self.token)

        self.assertEqual(response.status_code, 200)
        content = response.json()
        self.assertEqual(content['results'][0]['id'], basket.id)
        self.assertEqual(content['results'][0]['status'], basket.status)
        self.assertIsNotNone(content['results'][0]['vouchers'])
        self.assertEqual(content['results'][0]['payment_status'], "Accepted")
Beispiel #24
0
    def test_prepare_basket_applies_valid_voucher_argument(self):
        """
            Tests that prepare_basket applies a valid voucher passed as an
            an argument, even when there is also a valid voucher already on
            the basket.
        """
        product = ProductFactory(stockrecords__partner__short_code='test1',
                                 stockrecords__price_excl_tax=100)
        new_range = RangeFactory(products=[product])
        new_voucher, __ = prepare_voucher(code='xyz',
                                          _range=new_range,
                                          benefit_value=10)
        existing_voucher, __ = prepare_voucher(code='test',
                                               _range=new_range,
                                               benefit_value=50)

        basket = BasketFactory(owner=self.request.user, site=self.request.site)
        basket.vouchers.add(existing_voucher)
        self.assertEqual(basket.vouchers.count(), 1)

        basket = prepare_basket(self.request, [product], new_voucher)
        self.assertIsNotNone(basket)
        self.assertEqual(basket.vouchers.count(), 1)
        self.assertEqual(basket.vouchers.first().code, 'XYZ')
        self.assertEqual(basket.total_discount, 10.00)
    def test_is_satisfied_when_owner_has_no_assignment(self, mock_request):
        """
        Ensure that condition returns expected result the basket owner has no assignments.

        # voucher has free slots(3) available, no offer assignment for basket owner,
        # assignments(2) exist for other users, voucher has some redemptions(num_orders = 2)
        # basket owner is allowed to redeem the voucher
        """
        mock_request.return_value = self.request
        code = 'TA7WCQD3T4C7GHZ4'
        num_orders = 2
        max_global_applications = 7

        enterprise_offer = factories.EnterpriseOfferFactory(
            max_global_applications=max_global_applications)
        voucher = factories.VoucherFactory(usage=Voucher.MULTI_USE,
                                           code=code,
                                           num_orders=num_orders)
        voucher.offers.add(enterprise_offer)

        factories.OfferAssignmentFactory(offer=enterprise_offer,
                                         code=code,
                                         user_email='*****@*****.**')
        factories.OfferAssignmentFactory(offer=enterprise_offer,
                                         code=code,
                                         user_email='*****@*****.**')

        basket = BasketFactory(site=self.site,
                               owner=UserFactory(email='*****@*****.**'))
        basket.vouchers.add(voucher)

        assert self.condition.is_satisfied(enterprise_offer, basket) is True
Beispiel #26
0
    def test_attribute_cookie_data_affiliate_cookie_lifecycle(self):
        """ Verify a basket is returned and referral captured if there is cookie info """

        # If there is no cookie info, verify no referral is created.
        basket = BasketFactory(owner=self.request.user, site=self.request.site)
        attribute_cookie_data(basket, self.request)
        with self.assertRaises(Referral.DoesNotExist):
            Referral.objects.get(basket=basket)

        # If there is cookie info, verify a referral is captured
        affiliate_id = 'test_affiliate'
        self.request.COOKIES['affiliate_id'] = affiliate_id
        attribute_cookie_data(basket, self.request)
        # test affiliate id from cookie saved in referral
        referral = Referral.objects.get(basket_id=basket.id)
        self.assertEqual(referral.affiliate_id, affiliate_id)

        # update cookie
        new_affiliate_id = 'new_affiliate'
        self.request.COOKIES['affiliate_id'] = new_affiliate_id
        attribute_cookie_data(basket, self.request)

        # test new affiliate id saved
        referral = Referral.objects.get(basket_id=basket.id)
        self.assertEqual(referral.affiliate_id, new_affiliate_id)

        # expire cookie
        del self.request.COOKIES['affiliate_id']
        attribute_cookie_data(basket, self.request)

        # test referral record is deleted when no cookie set
        with self.assertRaises(Referral.DoesNotExist):
            Referral.objects.get(basket_id=basket.id)
    def assert_condition(self, voucher_type, assignments,
                         expected_condition_result):
        """
        Verify that condition works as expected for different vouchers and assignments.
        """
        for assignment in assignments:
            code = assignment['code']
            email = assignment['user_email']
            # In some cases individual assignments have their own expected result
            expected_condition_result = assignment.get(
                'result', expected_condition_result)

            voucher = Voucher.objects.get(usage=voucher_type, code=code)
            basket = BasketFactory(site=self.site,
                                   owner=UserFactory(email=email))
            basket.vouchers.add(voucher)

            is_condition_satisfied = self.condition.is_satisfied(
                voucher.enterprise_offer, basket)
            assert is_condition_satisfied == expected_condition_result

            # update the `num_orders` so that we can also verify the redemptions check
            # also update the offer assignment status
            if expected_condition_result:
                voucher.num_orders += 1
                voucher.save()
                assignment = OfferAssignment.objects.filter(
                    offer=voucher.enterprise_offer,
                    code=code,
                    user_email=email).exclude(
                        status__in=[OFFER_REDEEMED, OFFER_ASSIGNMENT_REVOKED
                                    ]).first()
                if assignment:
                    assignment.status = OFFER_REDEEMED
                    assignment.save()
    def test_is_satisfied_with_different_users(self, mock_request):
        """
        Ensure that condition returns expected result when wrong user is try to redeem the voucher.

        # code = 'ASD' assigned_to = '*****@*****.**'
        # code = 'ZXC' assigned_to = '*****@*****.**'
        # [email protected] try to redeem `ASD` code
        # `is_satisfied` should return False
        """
        mock_request.return_value = self.request

        voucher1 = factories.VoucherFactory(usage=Voucher.SINGLE_USE,
                                            code='ASD')
        voucher2 = factories.VoucherFactory(usage=Voucher.SINGLE_USE,
                                            code='ZXC')

        enterprise_offers = factories.EnterpriseOfferFactory.create_batch(2)
        voucher1.offers.add(enterprise_offers[0])
        voucher2.offers.add(enterprise_offers[1])

        basket = BasketFactory(site=self.site,
                               owner=UserFactory(email='*****@*****.**'))
        basket.vouchers.add(voucher1)

        factories.OfferAssignmentFactory(offer=enterprise_offers[0],
                                         code=voucher1.code,
                                         user_email='*****@*****.**')
        factories.OfferAssignmentFactory(offer=enterprise_offers[1],
                                         code=voucher2.code,
                                         user_email='*****@*****.**')

        assert self.condition.is_satisfied(enterprise_offers[1],
                                           basket) is False
 def test_is_satisfied_empty_basket(self):
     """ Ensure the condition returns False if the basket is empty. """
     offer = factories.EnterpriseOfferFactory(partner=self.partner,
                                              condition=self.condition)
     basket = BasketFactory(site=self.site, owner=self.user)
     self.assertTrue(basket.is_empty)
     self.assertFalse(self.condition.is_satisfied(offer, basket))
Beispiel #30
0
    def test_attribute_cookie_data_multiple_cookies(self):
        """ Verify a basket is returned and referral captured. """
        utm_source = 'test-source'
        utm_medium = 'test-medium'
        utm_campaign = 'test-campaign'
        utm_term = 'test-term'
        utm_content = 'test-content'
        utm_created_at = 1475590280823

        utm_cookie = {
            'utm_source': utm_source,
            'utm_medium': utm_medium,
            'utm_campaign': utm_campaign,
            'utm_term': utm_term,
            'utm_content': utm_content,
            'created_at': utm_created_at,
        }

        affiliate_id = 'affiliate'

        self.request.COOKIES[
            self.site_configuration.utm_cookie_name] = json.dumps(utm_cookie)
        self.request.COOKIES['affiliate_id'] = affiliate_id
        basket = BasketFactory(owner=self.request.user, site=self.request.site)
        attribute_cookie_data(basket, self.request)

        # test affiliate id & UTM data from cookie saved in referral
        referral = Referral.objects.get(basket_id=basket.id)
        expected_created_at = datetime.datetime.fromtimestamp(
            int(utm_created_at) / float(1000), tz=pytz.UTC)
        self.assertEqual(referral.utm_source, utm_source)
        self.assertEqual(referral.utm_medium, utm_medium)
        self.assertEqual(referral.utm_campaign, utm_campaign)
        self.assertEqual(referral.utm_term, utm_term)
        self.assertEqual(referral.utm_content, utm_content)
        self.assertEqual(referral.utm_created_at, expected_created_at)
        self.assertEqual(referral.affiliate_id, affiliate_id)

        # expire 1 cookie
        del self.request.COOKIES[self.site_configuration.utm_cookie_name]
        attribute_cookie_data(basket, self.request)

        # test affiliate id still saved in referral but utm data removed
        referral = Referral.objects.get(basket_id=basket.id)
        self.assertEqual(referral.utm_source, '')
        self.assertEqual(referral.utm_medium, '')
        self.assertEqual(referral.utm_campaign, '')
        self.assertEqual(referral.utm_term, '')
        self.assertEqual(referral.utm_content, '')
        self.assertIsNone(referral.utm_created_at)
        self.assertEqual(referral.affiliate_id, affiliate_id)

        # expire other cookie
        del self.request.COOKIES['affiliate_id']
        attribute_cookie_data(basket, self.request)

        # test referral record is deleted when no cookies are set
        with self.assertRaises(Referral.DoesNotExist):
            Referral.objects.get(basket_id=basket.id)
Beispiel #31
0
    def test_is_satisfied_with_exception_for_enrollments(self):
        """ The method should return True despite having an error at the enrollment check, given 1 course run seat
        corresponding to each course in the program. """
        offer = factories.ProgramOfferFactory(partner=self.partner, condition=self.condition)
        basket = BasketFactory(site=self.site, owner=UserFactory())
        program = self.mock_program_detail_endpoint(
            self.condition.program_uuid,
            self.site_configuration.discovery_api_url
        )
        for course in program['courses']:
            course_run = Course.objects.get(id=course['course_runs'][0]['key'])
            for seat in course_run.seat_products:
                if seat.attr.id_verification_required:
                    basket.add_product(seat)

        self.mock_user_data(basket.owner.username, mocked_api='enrollments', owned_products=None, response_code=400)
        self.assertTrue(self.condition.is_satisfied(offer, basket))
Beispiel #32
0
class DynamicConditionTests(TestCase):
    """
    Tests to make sure that the dynamic discount condition correctly compute whether to give a discount
    """
    def setUp(self):
        super(DynamicConditionTests, self).setUp()
        self.condition = Condition.objects.get(
            proxy_class=
            'ecommerce.extensions.offer.dynamic_conditional_offer.DynamicDiscountCondition'
        ).proxy()
        self.offer = ConditionalOffer.objects.get(
            name='dynamic_conditional_offer')
        self.basket = BasketFactory(site=self.site, owner=self.create_user())

    def test_name(self):
        self.assertTrue(self.condition.name == 'dynamic_discount_condition')

    @override_flag(DYNAMIC_DISCOUNT_FLAG, active=True)
    @patch('crum.get_current_request')
    @patch(
        'ecommerce.extensions.offer.dynamic_conditional_offer.jwt_decode_handler',
        side_effect=_mock_jwt_decode_handler)
    @ddt.data(
        {
            'discount_applicable': True,
            'discount_percent': 15
        },
        {
            'discount_applicable': False,
            'discount_percent': 15
        },
        None,
    )
    def test_is_satisfied_true(self, discount_jwt, jwt_decode_handler,
                               request):  # pylint: disable=unused-argument
        request.return_value = Mock(method='GET',
                                    GET={'discount_jwt': discount_jwt})
        product = ProductFactory(stockrecords__price_excl_tax=10,
                                 categories=[])
        self.basket.add_product(product)
        if discount_jwt and discount_jwt.get('discount_applicable') is True:
            self.assertTrue(
                self.condition.is_satisfied(self.offer, self.basket))
        else:
            self.assertFalse(
                self.condition.is_satisfied(self.offer, self.basket))
Beispiel #33
0
    def test_is_satisfied_with_enrollments(self):
        """ The condition should be satisfied if one valid course run from each course is in either the
        basket or the user's enrolled courses and the site has enabled partial program offers. """
        offer = factories.ProgramOfferFactory(partner=self.partner,
                                              condition=self.condition)
        basket = BasketFactory(site=self.site, owner=UserFactory())
        program = self.mock_program_detail_endpoint(
            self.condition.program_uuid,
            self.site_configuration.discovery_api_url)

        # Extract one verified seat for each course
        verified_seats = []
        for course in program['courses']:
            course_run = Course.objects.get(id=course['course_runs'][0]['key'])
            for seat in course_run.seat_products:
                if seat.attr.id_verification_required:
                    verified_seats.append(seat)

        # Add verified enrollments for the first two program courses to the mock user data
        enrollments = [{
            'mode': 'verified',
            'course_details': {
                'course_id': program['courses'][0]['course_runs'][0]['key']
            }
        }, {
            'mode': 'verified',
            'course_details': {
                'course_id': program['courses'][1]['course_runs'][0]['key']
            }
        }]
        self.mock_user_data(basket.owner.username, owned_products=enrollments)

        # If the user has not added all of the remaining courses in the program to their basket,
        # the condition should not be satisfied
        basket.flush()
        for seat in verified_seats[2:len(verified_seats) - 1]:
            basket.add_product(seat)
        self.assertFalse(self.condition.is_satisfied(offer, basket))

        # When all courses in the program that the user is not already enrolled in are in their basket
        # and the site allows partial program completion, the condition should be satisfied
        basket.add_product(verified_seats[-1])
        self.assertTrue(self.condition.is_satisfied(offer, basket))

        # If the site does not allow partial program completion and the user does not have all of the program
        # courses in their basket, the condition should not be satisfied
        basket.site.siteconfiguration.enable_partial_program = False
        self.assertFalse(self.condition.is_satisfied(offer, basket))

        # Verify the user enrollments are cached
        basket.site.siteconfiguration.enable_partial_program = True
        httpretty.disable()
        with mock.patch('ecommerce.programs.conditions.get_program',
                        return_value=program):
            self.assertTrue(self.condition.is_satisfied(offer, basket))
 def test_is_satisfied_contains_content_items_failure(self):
     """ Ensure the condition returns false if the contains_content_item call fails. """
     offer = factories.EnterpriseOfferFactory(partner=self.partner, condition=self.condition)
     basket = BasketFactory(site=self.site, owner=self.user)
     basket.add_product(self.course_run.seat_products[0])
     self.mock_enterprise_learner_api(
         learner_id=self.user.id,
         enterprise_customer_uuid=str(self.condition.enterprise_customer_uuid),
         course_run_id=self.course_run.id,
     )
     self.mock_catalog_contains_course_runs(
         [self.course_run.id],
         self.condition.enterprise_customer_uuid,
         enterprise_customer_catalog_uuid=self.condition.enterprise_customer_catalog_uuid,
         contains_content=False,
         raise_exception=True
     )
     self.assertFalse(self.condition.is_satisfied(offer, basket))
 def test_absolute_benefit_offer_availability(self):
     """
     Verify that enterprise offer condition returns correct result for an absolute benefit with
     discount value greater than course price.
     """
     offer = factories.EnterpriseOfferFactory(
         partner=self.partner,
         benefit=factories.EnterpriseAbsoluteDiscountBenefitFactory(value=150),
         max_discount=Decimal(300),
         total_discount=Decimal(200)
     )
     basket = BasketFactory(site=self.site, owner=self.user)
     basket.add_product(self.course_run.seat_products[0])
     self.mock_catalog_contains_course_runs(
         [self.course_run.id],
         self.condition.enterprise_customer_uuid,
         enterprise_customer_catalog_uuid=self.condition.enterprise_customer_catalog_uuid,
     )
     self.assertTrue(self.condition.is_satisfied(offer, basket))
 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_basket_lines_queryset_is_ordered(self):
     # This is needed to make sure a formset is not performing the query
     # again with an order_by clause (losing all calculated discounts)
     basket = BasketFactory()
     product = ProductFactory(title="A product")
     another_product = ProductFactory(title="Another product")
     basket.add_product(product)
     basket.add_product(another_product)
     queryset = basket.all_lines()
     self.assertTrue(queryset.ordered)