Exemplo n.º 1
0
    def test_handle_post_order_for_bulk_purchase(self, __):
        """
        Ensure that the bulk purchase order is linked to the provided business
        client when the method `handle_post_order` is invoked.
        """
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)

        course = CourseFactory(partner=self.partner)
        course.create_or_update_seat('verified',
                                     True,
                                     50,
                                     create_enrollment_code=True)
        enrollment_code = Product.objects.get(
            product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        user = UserFactory()
        basket = BasketFactory(owner=user, site=self.site)
        basket.add_product(enrollment_code, quantity=1)
        order = create_order(number=1, basket=basket, user=user)
        request_data = {
            'organization': 'Dummy Business Client',
            PURCHASER_BEHALF_ATTRIBUTE: 'False',
        }
        # Manually add organization and purchaser attributes on the basket for testing
        basket_add_organization_attribute(basket, request_data)

        EdxOrderPlacementMixin().handle_post_order(order)

        # Now verify that a new business client has been created in current
        # order is now linked with that client through Invoice model.
        business_client = BusinessClient.objects.get(
            name=request_data['organization'])
        assert Invoice.objects.get(
            order=order).business_client == business_client
Exemplo n.º 2
0
    def test_create_seat_with_enrollment_code(self):
        """Verify an enrollment code product is created."""
        course = CourseFactory()
        seat_type = 'verified'
        price = 5
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        course.create_or_update_seat(seat_type,
                                     True,
                                     price,
                                     self.partner,
                                     create_enrollment_code=True)

        enrollment_code = Product.objects.get(
            product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        self.assertEqual(enrollment_code.attr.course_key, course.id)
        self.assertEqual(enrollment_code.attr.seat_type, seat_type)

        # Second time should skip over the enrollment code creation logic but result in the same data
        course.create_or_update_seat(seat_type, True, price, self.partner)
        enrollment_code = Product.objects.get(
            product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        self.assertEqual(enrollment_code.attr.course_key, course.id)
        self.assertEqual(enrollment_code.attr.seat_type, seat_type)

        stock_record = StockRecord.objects.get(product=enrollment_code)
        self.assertEqual(stock_record.price_excl_tax, price)
        self.assertEqual(stock_record.price_currency,
                         settings.OSCAR_DEFAULT_CURRENCY)
        self.assertEqual(stock_record.partner, self.partner)
Exemplo n.º 3
0
    def test_publish(self):
        """ Verify the view publishes course data to LMS. """
        course_id = self.course.id
        path = reverse('api:v2:course-publish', kwargs={'pk': course_id})

        # Method should return a 500 if the switch is inactive
        toggle_switch('publish_course_modes_to_lms', False)

        response = self.client.post(path)
        msg = 'Course [{course_id}] was not published to LMS ' \
              'because the switch [publish_course_modes_to_lms] is disabled.'
        self.assert_publish_response(response, 500, msg)

        toggle_switch('publish_course_modes_to_lms', True)

        with mock.patch.object(LMSPublisher, 'publish') as mock_publish:
            # If publish fails, return a 500
            mock_publish.return_value = False
            response = self.client.post(path)
            self.assert_publish_response(
                response, 500,
                'An error occurred while publishing [{course_id}] to LMS.')

            # If publish succeeds, return a 200
            mock_publish.return_value = True
            response = self.client.post(path)
            self.assert_publish_response(
                response, 200,
                'Course [{course_id}] was successfully published to LMS.')
Exemplo n.º 4
0
    def test_handle_post_order_for_seat_purchase(self, __):
        """
        Ensure that the single seat purchase order is not linked any business
        client when the method `handle_post_order` is invoked.
        """
        toggle_switch(ENROLLMENT_CODE_SWITCH, False)

        course = CourseFactory(partner=self.partner)
        verified_product = course.create_or_update_seat('verified', True, 50)
        user = UserFactory()
        basket = BasketFactory(owner=user, site=self.site)
        basket.add_product(verified_product, quantity=1)
        order = create_order(number=1, basket=basket, user=user)
        request_data = {
            'organization': 'Dummy Business Client',
            PURCHASER_BEHALF_ATTRIBUTE: 'False',
        }
        # Manually add organization and purchaser attributes on the basket for testing
        basket_add_organization_attribute(basket, request_data)

        EdxOrderPlacementMixin().handle_post_order(order)

        # Now verify that the single seat order is not linked to business
        # client by checking that there is no record for BusinessClient.
        assert not BusinessClient.objects.all()
Exemplo n.º 5
0
 def setUp(self):
     super(BasketUtilsTransactionTests, self).setUp()
     self.request.user = self.create_user()
     self.site_configuration.utm_cookie_name = 'test.edx.utm'
     toggle_switch(DISABLE_REPEAT_ORDER_CHECK_SWITCH_NAME, False)
     BasketAttributeType.objects.get_or_create(name=BUNDLE)
     Option.objects.get_or_create(name='Course Entitlement', code='course_entitlement', type=Option.OPTIONAL)
Exemplo n.º 6
0
    def test_enrollment_code_seat_type(self):
        """Verify the correct seat type attribute is retrieved."""
        course = CourseFactory()
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        course.create_or_update_seat('verified',
                                     False,
                                     10,
                                     self.partner,
                                     create_enrollment_code=True)
        enrollment_code = Product.objects.get(
            product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        self.create_basket_and_add_product(enrollment_code)
        self.mock_dynamic_catalog_course_runs_api(course_run=course)

        response = self.client.get(self.path)
        self.assertEqual(response.status_code, 200)
        self.assertFalse(response.context['is_bulk_purchase'])

        # Enable enrollment codes
        self.site.siteconfiguration.enable_enrollment_codes = True
        self.site.siteconfiguration.save()

        response = self.client.get(self.path)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(response.context['is_bulk_purchase'])
        line_data = response.context['formset_lines_data'][0][1]
        self.assertEqual(line_data['seat_type'],
                         _(enrollment_code.attr.seat_type.capitalize()))
Exemplo n.º 7
0
    def test_dummy_web_profiles(self, enabled_profile_name, mock_payment):
        """
        Verify that the payment creation payload references a web profile when one is enabled with the expected name.
        This should occur when the create_and_set_webprofile waffle is disabled.
        """
        toggle_switch('create_and_set_webprofile', False)
        mock_payment_instance = mock.Mock()
        # NOTE: This is necessary to avoid the issue in https://code.djangoproject.com/ticket/25493.
        mock_payment_instance.id = FuzzyInteger(low=1).fuzz()
        mock_payment_instance.to_dict.return_value = {}
        mock_payment_instance.links = [
            mock.Mock(rel='approval_url', href='dummy')
        ]
        mock_payment.return_value = mock_payment_instance

        if enabled_profile_name is not None:
            PaypalWebProfile.objects.create(name=enabled_profile_name,
                                            id='test-profile-id')

        self.processor.get_transaction_parameters(self.basket,
                                                  request=self.request)
        payment_creation_payload = mock_payment.call_args[0][0]
        if enabled_profile_name == Paypal.DEFAULT_PROFILE_NAME:
            self.assertEqual(payment_creation_payload['experience_profile_id'],
                             'test-profile-id')
        else:
            self.assertNotIn('experience_profile_id', payment_creation_payload)
Exemplo n.º 8
0
    def create_course_seat_and_enrollment_code(self,
                                               seat_type='verified',
                                               price=10,
                                               id_verification=False,
                                               expires=None):
        """
        Create a new course, seat and enrollment code.
        In order to create an enrollment code the waffle switch and site configuration
        value for enrollment codes need to be turned on.

        Args:
            seat_type (str): Seat type.
            price (int): Seat price.
            id_verification (bool): Whether or not an ID verification is necessary for the seat.
            expires (datetime): Seat and enrollment code expiration date.
        Returns:
            The newly created course, seat and enrollment code.
        """
        course = CourseFactory()
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        site_configuration = self.site.siteconfiguration
        site_configuration.enable_enrollment_codes = True
        site_configuration.save()

        seat = course.create_or_update_seat(seat_type,
                                            id_verification,
                                            price,
                                            self.partner,
                                            expires=expires,
                                            create_enrollment_code=True)
        enrollment_code = Product.objects.get(
            product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        return course, seat, enrollment_code
Exemplo n.º 9
0
    def test_web_profile_with_exception(self, mock_web_profile_init,
                                        mock_payment, mock_logger):
        """
        Verify that the payment creation payload does not reference a web profile if its creation results in exception.
        This should occur when the create_and_set_webprofile waffle is enabled.
        """
        toggle_switch('create_and_set_webprofile', True)
        mock_payment_instance = mock.Mock()
        # NOTE: This is necessary to avoid the issue in https://code.djangoproject.com/ticket/25493.
        mock_payment_instance.id = FuzzyInteger(low=1).fuzz()
        mock_payment_instance.to_dict.return_value = {}
        mock_payment_instance.links = [
            mock.Mock(rel='approval_url', href='dummy')
        ]
        mock_payment.return_value = mock_payment_instance

        Paypal.resolve_paypal_locale = mock.Mock(return_value="valid_locale")
        mock_web_profile_init.side_effect = Exception(
            'MissingConfig Exception')

        self.processor.get_transaction_parameters(self.basket,
                                                  request=self.request)
        payment_creation_payload = mock_payment.call_args[0][0]
        self.assertNotIn('experience_profile_id', payment_creation_payload)
        self.assertRaises(Exception('MissingConfig Exception'))

        msg = 'Creating PayPal WebProfile resulted in exception. Will continue without one.'
        mock_logger.warning.assert_any_call(msg)
Exemplo n.º 10
0
    def test_track_completed_enrollment_order(self):
        """ Make sure we do not send GA events for Enrollment Code orders """
        with mock.patch(
                'ecommerce.extensions.checkout.signals.track_segment_event'
        ) as mock_track:

            toggle_switch(ENROLLMENT_CODE_SWITCH, True)
            site_config = self.site.siteconfiguration
            site_config.enable_enrollment_codes = True
            site_config.save()

            course = CourseFactory()
            course.create_or_update_seat('verified',
                                         True,
                                         50,
                                         self.partner,
                                         create_enrollment_code=True)
            enrollment_code = Product.objects.get(
                product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)

            basket = BasketFactory(owner=self.user, site=self.site)
            basket.add_product(enrollment_code)

            order = factories.create_order(basket=basket, user=self.user)
            track_completed_order(None, order)
            assert not mock_track.called
Exemplo n.º 11
0
    def test_seat_products(self):
        """
        Verify the method returns a list containing purchasable course seats.

        These seats should be the child products.
        """
        # Create a new course and verify it has a parent product, but no children.
        course = CourseFactory()
        self.assertEqual(course.products.count(), 1)
        self.assertEqual(len(course.seat_products), 0)

        # Create the seat products
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        seats = [
            course.create_or_update_seat('honor', False, 0, self.partner),
            course.create_or_update_seat('verified',
                                         True,
                                         50,
                                         self.partner,
                                         create_enrollment_code=True)
        ]
        self.assertEqual(course.products.count(), 4)

        # The property should return only the child seats.
        self.assertEqual(set(course.seat_products), set(seats))
Exemplo n.º 12
0
    def setUp(self):
        super(PaymentProcessorListViewTests, self).setUp()
        self.token = self.generate_jwt_token_header(self.create_user())
        toggle_switch(
            settings.PAYMENT_PROCESSOR_SWITCH_PREFIX + DummyProcessor.NAME,
            True)
        toggle_switch(
            settings.PAYMENT_PROCESSOR_SWITCH_PREFIX +
            AnotherDummyProcessor.NAME, True)

        site_config, __ = SiteConfiguration.objects.get_or_create(site__id=1)

        old_payment_processors = site_config.payment_processors
        site_config.payment_processors = ",".join(
            [DummyProcessor.NAME, AnotherDummyProcessor.NAME])
        site_config.save()

        def reset_site_config():
            """ Reset method - resets site_config to pre-test state """
            site_config.payment_processors = old_payment_processors
            site_config.save()

        self.addCleanup(reset_site_config)

        # Clear the view cache
        TieredCache.dangerous_clear_all_tiers()
Exemplo n.º 13
0
    def test_web_profile_with_invalid_locale(self, mock_web_profile, mock_payment, mock_logger):
        """
        Verify that the payment creation payload does not reference a web profile when an invalid locale is chosen.
        This should occur when the create_and_set_webprofile waffle is enabled.
        """
        toggle_switch('create_and_set_webprofile', True)
        mock_payment_instance = mock.Mock()
        # NOTE: This is necessary to avoid the issue in https://code.djangoproject.com/ticket/25493.
        mock_payment_instance.id = FuzzyInteger(low=1).fuzz()
        mock_payment_instance.to_dict.return_value = {}
        mock_payment_instance.links = [mock.Mock(rel='approval_url', href='dummy')]
        mock_payment.return_value = mock_payment_instance

        Paypal.resolve_paypal_locale = mock.Mock(return_value='invalid_locale')
        mock_web_profile_instance = mock.Mock()
        mock_web_profile_instance.create = mock.Mock(return_value=False)
        mock_web_profile_instance.error = 'invalid_config'
        mock_web_profile.return_value = mock_web_profile_instance

        self.processor.get_transaction_parameters(self.basket, request=self.request)
        payment_creation_payload = mock_payment.call_args[0][0]
        self.assertNotIn('experience_profile_id', payment_creation_payload)

        msg = 'Web profile creation encountered error [%s]. Will continue without one' % (
            mock_web_profile_instance.error
        )
        mock_logger.warning.assert_any_call(msg)
Exemplo n.º 14
0
    def test_web_profile_with_valid_locale(self, mock_web_profile, mock_payment, mock_logger):
        """
        Verify that the payment creation payload references a web profile when a valid locale is chosen
        This should occur when the create_and_set_webprofile waffle is enabled.
        """
        toggle_switch('create_and_set_webprofile', True)
        mock_payment_instance = mock.Mock()
        # NOTE: This is necessary to avoid the issue in https://code.djangoproject.com/ticket/25493.
        mock_payment_instance.id = FuzzyInteger(low=1).fuzz()
        mock_payment_instance.to_dict.return_value = {}
        mock_payment_instance.links = [mock.Mock(rel='approval_url', href='dummy')]
        mock_payment.return_value = mock_payment_instance

        Paypal.resolve_paypal_locale = mock.Mock(return_value='valid_locale')
        mock_web_profile_instance = mock.Mock()
        mock_web_profile_instance.id = 'test-profile-id'
        mock_web_profile_instance.presentation.locale_code = 'valid_locale'
        mock_web_profile.create = mock.Mock(return_value=True)
        mock_web_profile.return_value = mock_web_profile_instance

        self.processor.get_transaction_parameters(self.basket, request=self.request)
        payment_creation_payload = mock_payment.call_args[0][0]
        self.assertEqual(payment_creation_payload['experience_profile_id'], 'test-profile-id')

        msg = 'Web Profile[%s] for locale %s created successfully' % (
            mock_web_profile_instance.id,
            mock_web_profile_instance.presentation.locale_code
        )
        mock_logger.info.assert_any_call(msg)
Exemplo n.º 15
0
    def test_enrollment_code_seat_type_filter(self):
        """ Verify that the ENROLLMENT_CODE_SEAT_TYPES constant is properly applied during seat creation """
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        course = Course.objects.create(id='test/course/123',
                                       name='Test Course 123')

        # Audit seat products should not have a corresponding enrollment code
        course.create_or_update_seat('audit', False, 0, self.partner)
        with self.assertRaises(Product.DoesNotExist):
            enrollment_code = Product.objects.get(
                product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)

        # Honor seat products should not have a corresponding enrollment code
        course.create_or_update_seat('honor', False, 0, self.partner)
        with self.assertRaises(Product.DoesNotExist):
            enrollment_code = Product.objects.get(
                product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)

        # Verified seat products should have a corresponding enrollment code
        course.create_or_update_seat('verified', True, 10, self.partner)
        enrollment_code = Product.objects.get(
            product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        self.assertEqual(enrollment_code.attr.course_key, course.id)
        self.assertEqual(enrollment_code.attr.seat_type, 'verified')

        # One parent product, three seat products, one enrollment code product (verified) -> five total products
        self.assertEqual(course.products.count(), 5)
        self.assertEqual(len(course.seat_products),
                         3)  # Definitely three seat products...
Exemplo n.º 16
0
    def test_publish(self):
        """ Verify the view publishes course data to LMS. """
        course_id = self.course.id
        path = reverse('api:v2:course-publish', kwargs={'pk': course_id})

        # Method should return a 500 if the switch is inactive
        toggle_switch('publish_course_modes_to_lms', False)

        response = self.client.post(path)
        msg = 'Course [{course_id}] was not published to LMS ' \
              'because the switch [publish_course_modes_to_lms] is disabled.'
        self.assert_publish_response(response, 500, msg)

        toggle_switch('publish_course_modes_to_lms', True)

        with mock.patch.object(LMSPublisher, 'publish') as mock_publish:
            # If publish fails, return a 500
            mock_publish.return_value = False
            response = self.client.post(path)
            self.assert_publish_response(response, 500, 'An error occurred while publishing [{course_id}] to LMS.')

            # If publish succeeds, return a 200
            mock_publish.return_value = True
            response = self.client.post(path)
            self.assert_publish_response(response, 200, 'Course [{course_id}] was successfully published to LMS.')
Exemplo n.º 17
0
    def test_no_switch_link(self):
        """Verify response does not contain variables for the switch link if seat does not have an EC."""
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        ec_course = CourseFactory()
        no_ec_course = CourseFactory()
        seat_without_ec = no_ec_course.create_or_update_seat(
            'verified', False, 10, self.partner)
        seat_with_ec = ec_course.create_or_update_seat(
            'verified', False, 10, self.partner, create_enrollment_code=True)
        self.create_basket_and_add_product(seat_without_ec)
        self.mock_dynamic_catalog_course_runs_api(course_run=no_ec_course)

        response = self.client.get(self.path)
        self.assertFalse(response.context['switch_link_text'])
        self.assertFalse(response.context['partner_sku'])

        # Enable enrollment codes
        self.site.siteconfiguration.enable_enrollment_codes = True
        self.site.siteconfiguration.save()

        Basket.objects.all().delete()
        self.create_basket_and_add_product(seat_with_ec)
        self.mock_dynamic_catalog_course_runs_api(course_run=ec_course)

        response = self.client.get(self.path)
        enrollment_code = Product.objects.get(
            product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        enrollment_code_stockrecord = StockRecord.objects.get(
            product=enrollment_code)
        self.assertTrue(response.context['switch_link_text'])
        self.assertEqual(response.context['partner_sku'],
                         enrollment_code_stockrecord.partner_sku)
Exemplo n.º 18
0
    def test_enrolled_verified_student_for_enrollment_code(
            self, mode, id_verification):
        """
        Verify the view return HTTP 303 if the student is enrolled as verified and purchasing enrollment code
        (The Enrollment API call being used returns an inactive enrollment record in this case)
        """
        course = CourseFactory()
        self.mock_enrollment_api_success_enrolled(course.id, mode=mode)
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        course.create_or_update_seat(mode,
                                     id_verification,
                                     10,
                                     self.partner,
                                     create_enrollment_code=True)
        product = Product.objects.get(
            product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        stock_record = StockRecordFactory(product=product,
                                          partner=self.partner)
        catalog = Catalog.objects.create(partner=self.partner)
        catalog.stock_records.add(stock_record)

        url = '{path}?sku={sku}'.format(path=self.path,
                                        sku=stock_record.partner_sku)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 303)
        self.assertEqual(response.reason_phrase, "SEE OTHER")
        self.assertEqual(response.wsgi_request.path_info,
                         '/basket/single-item/')
        self.assertEqual(response.wsgi_request.GET['sku'],
                         stock_record.partner_sku)
Exemplo n.º 19
0
    def test_successful_order_for_bulk_purchase(self):
        """
        Verify the view redirects to the Receipt page when the Order has been
        successfully placed for bulk purchase and also that the order is linked
        to the provided business client.
        """
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)

        course = CourseFactory()
        course.create_or_update_seat('verified', True, 50, create_enrollment_code=True)
        enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        self.basket = create_basket(owner=self.user, site=self.site)
        self.basket.add_product(enrollment_code, quantity=1)

        # The basket should not have an associated order if no payment was made.
        self.assertFalse(Order.objects.filter(basket=self.basket).exists())

        request_data = self.generate_notification(
            self.basket,
            billing_address=self.billing_address,
        )
        request_data.update({'organization': 'Dummy Business Client'})
        request_data.update({PURCHASER_BEHALF_ATTRIBUTE: "False"})
        # Manually add organization and purchaser attributes on the basket for testing
        basket_add_organization_attribute(self.basket, request_data)

        response = self.client.post(self.path, request_data)
        self.assertTrue(Order.objects.filter(basket=self.basket).exists())
        self.assertEqual(response.status_code, 302)

        # Now verify that a new business client has been created and current
        # order is now linked with that client through Invoice model.
        order = Order.objects.filter(basket=self.basket).first()
        business_client = BusinessClient.objects.get(name=request_data['organization'])
        assert Invoice.objects.get(order=order).business_client == business_client
Exemplo n.º 20
0
    def test_signals_disabled(self, mock_log_error):
        """ Verify Sailthru is not contacted if the signals are disabled. """
        toggle_switch('sailthru_enable', False)
        process_checkout_complete(None)
        self.assertFalse(mock_log_error.called)

        process_basket_addition(None)
        self.assertFalse(mock_log_error.called)
Exemplo n.º 21
0
 def test_waffle_switches_clear_cache(self):
     """ Tests that adding a new Switch resets processor cache """
     self.assert_processor_list_matches(
         [DummyProcessor.NAME, AnotherDummyProcessor.NAME])
     toggle_switch(
         settings.PAYMENT_PROCESSOR_SWITCH_PREFIX + DummyProcessor.NAME,
         False)
     self.assert_processor_list_matches([AnotherDummyProcessor.NAME])
Exemplo n.º 22
0
    def test_signals_disabled(self, mock_log_error):
        """ Verify Sailthru is not contacted if the signals are disabled. """
        toggle_switch('sailthru_enable', False)
        process_checkout_complete(None)
        self.assertFalse(mock_log_error.called)

        process_basket_addition(None)
        self.assertFalse(mock_log_error.called)
Exemplo n.º 23
0
 def test_edit_view_with_disable_switch(self):
     """ Test that edit refund page still works even if the switch is disabled. """
     toggle_switch(REFUND_LIST_VIEW_SWITCH, False)
     refund = RefundFactory()
     edit_page_url = reverse('admin:refund_refund_change',
                             args=(refund.id, ))
     response = self.client.get(edit_page_url)
     self.assertEqual(response.status_code, 200)
     self.assertContains(response, refund.order.number)
Exemplo n.º 24
0
 def test_mode_for_seat(self, certificate_type, id_verification_required, mode):
     """ Verify the correct enrollment mode is returned for a given seat. """
     course = Course.objects.create(id='edx/Demo_Course/DemoX')
     toggle_switch(ENROLLMENT_CODE_SWITCH, True)
     seat = course.create_or_update_seat(certificate_type, id_verification_required, 10.00, self.partner)
     self.assertEqual(mode_for_seat(seat), mode)
     enrollment_code = course.enrollment_code_product
     if enrollment_code:  # We should only have enrollment codes for allowed types
         self.assertEqual(mode_for_seat(enrollment_code), mode)
Exemplo n.º 25
0
 def test_changelist_view_disable_switch(self):
     """ Overridden template will load on the list page, if the switch is disabled. """
     toggle_switch(ORDER_LIST_VIEW_SWITCH, False)
     response = self.client.get(self.order_page_url)
     self.assertEqual(response.status_code, 200)
     self.assertContains(
         response,
         'List view is temporarily disabled due to large number of records.'
     )
Exemplo n.º 26
0
 def test_mode_for_product(self, certificate_type, id_verification_required, mode):
     """ Verify the correct enrollment mode is returned for a given seat. """
     course = CourseFactory(id='edx/Demo_Course/DemoX', site=self.site)
     toggle_switch(ENROLLMENT_CODE_SWITCH, True)
     seat = course.create_or_update_seat(certificate_type, id_verification_required, 10.00, self.partner)
     self.assertEqual(mode_for_product(seat), mode)
     enrollment_code = course.enrollment_code_product
     if enrollment_code:  # We should only have enrollment codes for allowed types
         self.assertEqual(mode_for_product(enrollment_code), mode)
Exemplo n.º 27
0
    def test_successful_payment_for_bulk_purchase(self):
        """
        Verify that when a Order has been successfully placed for bulk
        purchase then that order is linked to the provided business client.
        """
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)

        course = CourseFactory()
        course.create_or_update_seat('verified',
                                     True,
                                     50,
                                     self.partner,
                                     create_enrollment_code=True)
        basket = create_basket(owner=self.user, site=self.site)
        enrollment_code = Product.objects.get(
            product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        basket.add_product(enrollment_code, quantity=1)
        basket.strategy = Selector().strategy()

        data = self.generate_form_data(basket.id)
        data.update({'organization': 'Dummy Business Client'})

        # Manually add organization attribute on the basket for testing
        basket_add_organization_attribute(basket, data)

        card_type = 'American Express'
        label = '1986'
        charge = stripe.Charge.construct_from(
            {
                'id': '2404',
                'source': {
                    'brand': card_type,
                    'last4': label,
                },
            }, 'fake-key')

        billing_address = BillingAddressFactory()
        with mock.patch.object(Stripe,
                               'get_address_from_token') as address_mock:
            address_mock.return_value = billing_address

            with mock.patch.object(stripe.Charge, 'create') as charge_mock:
                charge_mock.return_value = charge
                response = self.client.post(self.path, data)

            address_mock.assert_called_once_with(data['stripe_token'])

        self.assert_successful_order_response(response, basket.order_number)
        self.assert_order_created(basket, billing_address, card_type, label)

        # Now verify that a new business client has been created and current
        # order is now linked with that client through Invoice model.
        order = Order.objects.filter(basket=basket).first()
        business_client = BusinessClient.objects.get(name=data['organization'])
        assert Invoice.objects.get(
            order=order).business_client == business_client
Exemplo n.º 28
0
 def setUp(self):
     super(EnrollmentCodeFulfillmentModuleTests, self).setUp()
     toggle_switch(ENROLLMENT_CODE_SWITCH, True)
     course = CourseFactory()
     course.create_or_update_seat('verified', True, 50, self.partner)
     enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
     user = UserFactory()
     basket = BasketFactory()
     basket.add_product(enrollment_code, self.QUANTITY)
     self.order = factories.create_order(number=1, basket=basket, user=user)
Exemplo n.º 29
0
 def setUp(self):
     super(EnrollmentCodeFulfillmentModuleTests, self).setUp()
     toggle_switch(ENROLLMENT_CODE_SWITCH, True)
     course = CourseFactory()
     course.create_or_update_seat('verified', True, 50, self.partner, create_enrollment_code=True)
     enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
     user = UserFactory()
     basket = BasketFactory(owner=user, site=self.site)
     basket.add_product(enrollment_code, self.QUANTITY)
     self.order = create_order(number=1, basket=basket, user=user)
Exemplo n.º 30
0
    def test_just_return_signals(self, mock_log_error):
        """
        Ensure that disabling Sailthru just returns
        """
        toggle_switch('sailthru_enable', False)
        process_checkout_complete(None)
        self.assertFalse(mock_log_error.called)

        process_basket_addition(None)
        self.assertFalse(mock_log_error.called)
Exemplo n.º 31
0
    def test_just_return_signals(self, mock_log_error):
        """
        Ensure that disabling Sailthru just returns
        """
        toggle_switch('sailthru_enable', False)
        process_checkout_complete(None)
        self.assertFalse(mock_log_error.called)

        process_basket_addition(None)
        self.assertFalse(mock_log_error.called)
Exemplo n.º 32
0
 def test_prepare_basket_for_purchased_enrollment_code(self):
     """
     Test prepare_basket returns basket with product even if its already been purchased by user
     """
     course = CourseFactory()
     toggle_switch(ENROLLMENT_CODE_SWITCH, True)
     course.create_or_update_seat('verified', False, 10, self.partner, create_enrollment_code=True)
     enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
     with mock.patch.object(UserAlreadyPlacedOrder, 'user_already_placed_order', return_value=True):
         basket = prepare_basket(self.request, [enrollment_code])
         self.assertIsNotNone(basket)
Exemplo n.º 33
0
    def test_discovery_api_client_without_multitenancy(self):
        """ Verify the property returns a Discovery API client with settings url. """
        toggle_switch('use_multi_tenant_discovery_api_urls', False)
        token = self.mock_access_token_response()
        client = self.site_configuration.discovery_api_client
        client_store = client._store  # pylint: disable=protected-access
        client_auth = client_store['session'].auth

        self.assertEqual(client_store['base_url'], 'https://fake.domain.com/api/v1/')
        self.assertIsInstance(client_auth, SuppliedJwtAuth)
        self.assertEqual(client_auth.token, token)
Exemplo n.º 34
0
 def test_changelist_view_disable_switch(self):
     """ Overridden template will load on the list page, if the switch is disabled. """
     toggle_switch(REFUND_LIST_VIEW_SWITCH, False)
     response = self.client.get(self.refund_page_url)
     msg = 'Refund administration has been disabled due to the load on the database. ' \
           'This functionality can be restored by activating the {switch_name} Waffle switch. ' \
           'Be careful when re-activating this switch!'.format(switch_name=REFUND_LIST_VIEW_SWITCH)
     self.assertEqual(response.status_code, 200)
     message = list(response.context['messages'])[0]
     self.assertEqual(message.level, messages.WARNING)
     self.assertEqual(message.message, msg)
Exemplo n.º 35
0
 def test_prepare_basket_embargo_with_enrollment_code(self):
     """ Verify a basket is returned after adding enrollment code. """
     self.site_configuration.enable_embargo_check = True
     self.mock_access_token_response()
     self.mock_embargo_api(body=json.dumps({'access': True}))
     toggle_switch(ENROLLMENT_CODE_SWITCH, True)
     course = CourseFactory()
     course.create_or_update_seat('verified', False, 10, self.partner, create_enrollment_code=True)
     product = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
     basket = prepare_basket(self.request, [product])
     self.assertEqual(basket.lines.count(), 1)
    def test_view_response(self):
        """ Verify the endpoint returns a successful response when the user is able to checkout. """
        toggle_switch(settings.PAYMENT_PROCESSOR_SWITCH_PREFIX + DummyProcessorWithUrl.NAME, True)
        response = self.client.post(self.path, data=self.data)
        self.assertEqual(response.status_code, 200)

        basket = Basket.objects.get(id=1)
        self.assertEqual(basket.status, Basket.FROZEN)
        response_data = json.loads(response.content)
        self.assertEqual(response_data['payment_form_data']['transaction_param'], 'test_trans_param')
        self.assertEqual(response_data['payment_page_url'], 'test_processor.edx')
        self.assertEqual(response_data['payment_processor'], 'dummy_with_url')
Exemplo n.º 37
0
    def setUp(self):
        super(BasketSummaryViewTests, self).setUp()
        self.user = self.create_user()
        self.client.login(username=self.user.username, password=self.password)
        self.course = CourseFactory(name='BasketSummaryTest')
        site_configuration = self.site.siteconfiguration

        site_configuration.payment_processors = DummyProcessor.NAME
        site_configuration.client_side_payment_processor = DummyProcessor.NAME
        site_configuration.save()

        toggle_switch(settings.PAYMENT_PROCESSOR_SWITCH_PREFIX + DummyProcessor.NAME, True)
Exemplo n.º 38
0
 def test_enrollment_code_seat_type(self):
     """Verify the correct seat type attribute is retrieved."""
     course = CourseFactory()
     toggle_switch(ENROLLMENT_CODE_SWITCH, True)
     course.create_or_update_seat('verified', False, 10, self.partner)
     enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
     self.create_basket_and_add_product(enrollment_code)
     self.mock_course_api_response(course)
     response = self.client.get(self.path)
     self.assertEqual(response.status_code, 200)
     line_data = response.context['formset_lines_data'][0][1]
     self.assertEqual(line_data['seat_type'], _(enrollment_code.attr.seat_type.capitalize()))
Exemplo n.º 39
0
    def test_get_entitlement_voucher_with_enterprise_feature_disabled(self):
        """
        Verify that method "get_entitlement_voucher" doesn't call the
        enterprise service API and returns no voucher if the enterprise
        feature is disabled.
        """
        self.mock_enterprise_learner_api()
        toggle_switch(settings.ENABLE_ENTERPRISE_ON_RUNTIME_SWITCH, False)

        entitlement_voucher = get_entitlement_voucher(self.request, self.course.products.first())
        self._assert_num_requests(0)
        self.assertIsNone(entitlement_voucher)
Exemplo n.º 40
0
 def test_basket_switch_data(self):
     """Verify the correct basket switch data (single vs. multi quantity) is retrieved."""
     course = CourseFactory()
     toggle_switch(ENROLLMENT_CODE_SWITCH, True)
     course.create_or_update_seat('invalid', False, 10, self.partner)
     seat = course.create_or_update_seat('verified', False, 10, self.partner)
     seat_sku = StockRecord.objects.get(product=seat).partner_sku
     enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
     ec_sku = StockRecord.objects.get(product=enrollment_code).partner_sku
     __, partner_sku = get_basket_switch_data(seat)
     self.assertEqual(partner_sku, ec_sku)
     __, partner_sku = get_basket_switch_data(enrollment_code)
     self.assertEqual(partner_sku, seat_sku)
Exemplo n.º 41
0
    def setUp(self):
        super(SailthruTests, self).setUp()
        self.request_factory = RequestFactory()
        self.request = self.request_factory.get("foo")
        self.request.COOKIES['sailthru_bid'] = 'cookie_bid'
        self.request.site = self.site
        self.user = UserFactory.create(username='******', email=TEST_EMAIL)

        toggle_switch('sailthru_enable', True)

        # create some test course objects
        self.course_id = 'edX/toy/2012_Fall'
        self.course_url = 'http://lms.testserver.fake/courses/edX/toy/2012_Fall/info'
        self.course = Course.objects.create(id=self.course_id, name='Demo Course')
Exemplo n.º 42
0
    def test_post_checkout_callback(self):
        """
        When the post_checkout signal is emitted, the receiver should attempt
        to fulfill the newly-placed order and send receipt email.
        """
        httpretty.register_uri(
            httpretty.GET, get_lms_url('api/credit/v1/providers/ASU'),
            body='{"display_name": "Hogwarts"}',
            content_type="application/json"
        )
        toggle_switch('ENABLE_NOTIFICATIONS', True)
        course = Course.objects.create(id='edX/DemoX/Demo_Course', name='Demo Course')
        seat = course.create_or_update_seat('credit', False, 50, self.partner, 'ASU', None, 2)

        basket = BasketFactory()
        basket.add_product(seat, 1)
        order = factories.create_order(number=1, basket=basket, user=self.user)
        with mock.patch('threadlocals.threadlocals.get_current_request') as mock_gcr:
            mock_gcr.return_value = self.request
            send_course_purchase_email(None, order=order)
        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].from_email, self.site_configuration.from_email)
        self.assertEqual(mail.outbox[0].subject, 'Order Receipt')
        self.assertEqual(
            mail.outbox[0].body,
            '\nPayment confirmation for: {course_title}'
            '\n\nDear {full_name},'
            '\n\nThank you for purchasing {credit_hours} credit hours from {credit_provider} for {course_title}. '
            'A charge will appear on your credit or debit card statement with a company name of "{platform_name}".'
            '\n\nTo receive your course credit, you must also request credit at the {credit_provider} website. '
            'For a link to request credit from {credit_provider}, or to see the status of your credit request, '
            'go to your {platform_name} dashboard.'
            '\n\nTo explore other credit-eligible courses, visit the {platform_name} website. '
            'We add new courses frequently!'
            '\n\nTo view your payment information, visit the following website.'
            '\n{receipt_url}'
            '\n\nThank you. We hope you enjoyed your course!'
            '\nThe {platform_name} team'
            '\n\nYou received this message because you purchased credit hours for {course_title}, '
            'an {platform_name} course.\n'.format(
                course_title=order.lines.first().product.title,
                full_name=self.user.get_full_name(),
                credit_hours=2,
                credit_provider='Hogwarts',
                platform_name=get_current_request().site.name,
                receipt_url=get_lms_url('{}?orderNum={}'.format(settings.RECEIPT_PAGE_PATH, order.number))
            )
        )
Exemplo n.º 43
0
    def test_serialize_seat_with_enrollment_code(self):
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        seat = self.course.create_or_update_seat('verified', False, 10, self.partner)
        stock_record = seat.stockrecords.first()
        ec_stock_record = StockRecord.objects.get(product__product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)

        actual = self.publisher.serialize_seat_for_commerce_api(seat)
        expected = {
            'name': 'verified',
            'currency': 'USD',
            'price': int(stock_record.price_excl_tax),
            'sku': stock_record.partner_sku,
            'bulk_sku': ec_stock_record.partner_sku,
            'expires': None,
        }
        self.assertDictEqual(actual, expected)
Exemplo n.º 44
0
    def test_handle_with_false_switch(self):
        """ Verify the management command does not save data to the database if commit is false"""
        self._mock_lms_apis()
        toggle_switch('publish_course_modes_to_lms', False)

        with mock.patch.object(LMSPublisher, 'publish') as mock_publish:
            call_command(
                'migrate_course',
                self.course_id,
                access_token=ACCESS_TOKEN,
                commit=True,
                partner=self.partner.short_code
            )

            # Verify that the migrated course was published back to the LMS
            self.assertFalse(mock_publish.called)
Exemplo n.º 45
0
    def setUp(self):
        super(SailthruSignalTests, self).setUp()
        self.request_factory = RequestFactory()
        self.request = self.request_factory.get("foo")
        self.request.COOKIES['sailthru_bid'] = CAMPAIGN_COOKIE
        self.request.site = self.site
        self.user = UserFactory.create(username='******', email=TEST_EMAIL)

        toggle_switch('sailthru_enable', True)

        # create some test course objects
        self.course_id = 'edX/toy/2012_Fall'
        self.course_url = 'http://lms.testserver.fake/courses/edX/toy/2012_Fall/info'
        self.course = Course.objects.create(id=self.course_id, name='Demo Course')

        self.basket_attribute_type, __ = BasketAttributeType.objects.get_or_create(name=SAILTHRU_CAMPAIGN)
Exemplo n.º 46
0
    def test_create_seat_with_enrollment_code(self):
        """Verify an enrollment code product is created."""
        course = CourseFactory()
        seat_type = 'verified'
        price = 5
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        course.create_or_update_seat(seat_type, True, price, self.partner)

        enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        self.assertEqual(enrollment_code.attr.course_key, course.id)
        self.assertEqual(enrollment_code.attr.seat_type, seat_type)

        stock_record = StockRecord.objects.get(product=enrollment_code)
        self.assertEqual(stock_record.price_excl_tax, price)
        self.assertEqual(stock_record.price_currency, settings.OSCAR_DEFAULT_CURRENCY)
        self.assertEqual(stock_record.partner, self.partner)
Exemplo n.º 47
0
    def test_prepare_basket_enrollment_with_voucher(self):
        """Verify the basket does not contain a voucher if enrollment code is added to it."""
        course = CourseFactory()
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        course.create_or_update_seat('verified', False, 10, self.partner, create_enrollment_code=True)
        enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        voucher, product = prepare_voucher()

        basket = prepare_basket(self.request, product, voucher)
        self.assertIsNotNone(basket)
        self.assertEqual(basket.all_lines()[0].product, product)
        self.assertTrue(basket.contains_a_voucher)

        basket = prepare_basket(self.request, enrollment_code, voucher)
        self.assertIsNotNone(basket)
        self.assertEqual(basket.all_lines()[0].product, enrollment_code)
        self.assertFalse(basket.contains_a_voucher)
Exemplo n.º 48
0
 def test_get_transaction_parameters_with_retry(self):
     """Verify the processor returns the appropriate parameters required to complete a transaction after a retry"""
     toggle_switch('PAYPAL_RETRY_ATTEMPTS', True)
     self.mock_oauth2_response()
     response_error = self.get_payment_creation_error_response_mock()
     response_success = self.get_payment_creation_response_mock(self.basket)
     self.mock_api_responses(
         '/v1/payments/payment',
         [
             {'body': response_error, 'status': 200},
             {'body': response_success, 'status': 200}
         ]
     )
     self._assert_transaction_parameters_retry(
         response_success,
         'Creating PayPal payment for basket [{}] was unsuccessful. Will retry.'.format(self.basket.id)
     )
Exemplo n.º 49
0
    def setUp(self):
        super(EntitlementsTests, self).setUp()
        self.learner = self.create_user(is_staff=True)
        self.client.login(username=self.learner.username, password=self.password)

        # Enable enterprise functionality
        toggle_switch(settings.ENABLE_ENTERPRISE_ON_RUNTIME_SWITCH, True)

        self.course = CourseFactory(id='edx/Demo_Course/DemoX')
        course_seat = self.course.create_or_update_seat('verified', False, 100, partner=self.partner)
        stock_record = StockRecord.objects.get(product=course_seat)
        self.catalog = Catalog.objects.create(partner=self.partner)
        self.catalog.stock_records.add(stock_record)

        self.request.user = self.learner
        self.request.site = self.site
        self.request.strategy = DefaultStrategy()
Exemplo n.º 50
0
    def prepare_course_seat_and_enrollment_code(self, seat_type='verified', id_verification=False):
        """Helper function that creates a new course, enables enrollment codes and creates a new
        seat and enrollment code for it.

        Args:
            seat_type (str): Seat/certification type.
            is_verification (bool): Whether or not id verification is required for the seat.
        Returns:
            The newly created course, seat and enrollment code.
        """
        course = CourseFactory()
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        self.site.siteconfiguration.enable_enrollment_codes = True
        self.site.siteconfiguration.save()
        seat = course.create_or_update_seat(seat_type, id_verification, 10, self.partner, create_enrollment_code=True)
        enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        return course, seat, enrollment_code
Exemplo n.º 51
0
    def test_seat_products(self):
        """
        Verify the method returns a list containing purchasable course seats.

        These seats should be the child products.
        """
        # Create a new course and verify it has a parent product, but no children.
        course = CourseFactory()
        self.assertEqual(course.products.count(), 1)
        self.assertEqual(len(course.seat_products), 0)

        # Create the seat products
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        seats = [course.create_or_update_seat('honor', False, 0, self.partner),
                 course.create_or_update_seat('verified', True, 50, self.partner)]
        self.assertEqual(course.products.count(), 4)

        # The property should return only the child seats.
        self.assertEqual(set(course.seat_products), set(seats))
Exemplo n.º 52
0
    def test_post_checkout_callback(self):
        """
        When the post_checkout signal is emitted, the receiver should attempt
        to fulfill the newly-placed order and send receipt email.
        """
        httpretty.register_uri(
            httpretty.GET, get_lms_url('api/credit/v1/providers/ASU'),
            body='{"display_name": "Hogwarts"}',
            content_type="application/json"
        )
        toggle_switch('ENABLE_NOTIFICATIONS', True)
        user = UserFactory()
        course = Course.objects.create(id='edX/DemoX/Demo_Course', name='Demo Course')
        partner = self.create_partner('edx')
        seat = course.create_or_update_seat('credit', False, 50, partner, 'ASU', None, 2)

        basket = BasketFactory()
        basket.add_product(seat, 1)
        order = factories.create_order(number=1, basket=basket, user=user)
        send_course_purchase_email(None, order=order)
        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].subject, 'Order Receipt')
        self.assertEqual(
            mail.outbox[0].body,
            '\nReceipt Confirmation for: {course_name}'
            '\n\nHi {full_name},\n\n'
            'Thank you for purchasing {credit_hour} credit hours from {provider_name} for {course_name}.'
            ' The charge below will appear on your next credit or debit card statement with a '
            'company name of {platform_name}.\n\nYou can see the status the status of your credit request or '
            'complete the credit request process on your {platform_name} dashboard\nTo browse other '
            'credit-eligible courses visit the edX website. More courses are added all the time.\n\n'
            'Thank you and congratulation on your achievement. We hope you enjoy the course!\n\n'
            'To view receipt please visit the link below'
            '\n\n{receipt_url}\n\n'
            '{platform_name} team\n\nThe edX team\n'.format(
                course_name=order.lines.first().product.title,
                full_name=user.get_full_name(),
                credit_hour=2,
                provider_name='Hogwarts',
                platform_name=settings.PLATFORM_NAME,
                receipt_url=get_lms_url('/commerce/checkout/receipt/?basket_id={}'.format(order.basket.id))
            )
        )
Exemplo n.º 53
0
    def setUp(self):
        super(BasketSummaryViewTests, self).setUp()
        self.user = self.create_user()
        self.client.login(username=self.user.username, password=self.password)
        self.course = CourseFactory(name='BasketSummaryTest')
        site_configuration = SiteConfiguration.objects.get(site__id=1)

        old_payment_processors = site_configuration.payment_processors
        site_configuration.payment_processors = DummyProcessor.NAME
        site_configuration.save()

        def reset_site_config():
            """ Reset method - resets site_config to pre-test state """
            site_configuration.payment_processors = old_payment_processors
            site_configuration.save()

        self.addCleanup(reset_site_config)

        toggle_switch(settings.PAYMENT_PROCESSOR_SWITCH_PREFIX + DummyProcessor.NAME, True)
Exemplo n.º 54
0
    def test_enrolled_verified_student_for_enrollment_code(self, mode, id_verification):
        """
        Verify the view return HTTP 303 if the student is enrolled as verified and purchasing enrollment code
        (The Enrollment API call being used returns an inactive enrollment record in this case)
        """
        course = CourseFactory()
        self.mock_enrollment_api_success_enrolled(course.id, mode=mode)
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        course.create_or_update_seat(mode, id_verification, 10, self.partner, create_enrollment_code=True)
        product = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        stock_record = StockRecordFactory(product=product, partner=self.partner)
        catalog = Catalog.objects.create(partner=self.partner)
        catalog.stock_records.add(stock_record)

        url = '{path}?sku={sku}'.format(path=self.path, sku=stock_record.partner_sku)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 303)
        self.assertEqual(response.reason_phrase, "SEE OTHER")
        self.assertEqual(response.wsgi_request.path_info, '/basket/single-item/')
        self.assertEqual(response.wsgi_request.GET['sku'], stock_record.partner_sku)
Exemplo n.º 55
0
    def test_unexpected_payment_execution_with_retry_attempt(self):
        """Verify that, when the switch is active, failure to execute a payment
        results in one, or more, retry attempts. If all attempts fail, verify a
        GatewayError is raised.
        """
        toggle_switch('PAYPAL_RETRY_ATTEMPTS', True)
        self.processor.retry_attempts = 1
        self.mock_oauth2_response()
        self.mock_payment_creation_response(self.basket, find=True)
        self.mock_payment_execution_response(self.basket)

        with mock.patch.object(paypalrestsdk.Payment, 'success', return_value=False):
            logger_name = 'ecommerce.extensions.payment.processors.paypal'
            with LogCapture(logger_name) as paypal_logger:
                self.assertRaises(GatewayError, self.processor.handle_processor_response, self.RETURN_DATA, self.basket)

                # Each failure response is saved into db.
                payment_processor_responses = self.assert_processor_multiple_response_recorded()

                paypal_logger.check(
                    (
                        logger_name, 'WARNING', self.processor_response_log.format(
                            attempt_count=1,
                            entry_id=payment_processor_responses[0]
                        )
                    ),
                    (
                        logger_name, 'WARNING', self.processor_response_log.format(
                            attempt_count=2,
                            entry_id=payment_processor_responses[1]
                        )
                    ),
                    (
                        logger_name, 'ERROR',
                        u"Failed to execute PayPal payment [{payment_id}]. "
                        u"PayPal's response was recorded in entry [{entry_id}].".format(
                            payment_id=self.PAYMENT_ID,
                            entry_id=payment_processor_responses[1]
                        )
                    ),
                )
Exemplo n.º 56
0
    def test_enrollment_code_seat_type_filter(self):
        """ Verify that the ENROLLMENT_CODE_SEAT_TYPES constant is properly applied during seat creation """
        toggle_switch(ENROLLMENT_CODE_SWITCH, True)
        course = Course.objects.create(id='test/course/123', name='Test Course 123')

        # Audit seat products should not have a corresponding enrollment code
        course.create_or_update_seat('audit', False, 0, self.partner)
        with self.assertRaises(Product.DoesNotExist):
            enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)

        # Honor seat products should not have a corresponding enrollment code
        course.create_or_update_seat('honor', False, 0, self.partner)
        with self.assertRaises(Product.DoesNotExist):
            enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)

        # Verified seat products should have a corresponding enrollment code
        course.create_or_update_seat('verified', True, 10, self.partner)
        enrollment_code = Product.objects.get(product_class__name=ENROLLMENT_CODE_PRODUCT_CLASS_NAME)
        self.assertEqual(enrollment_code.attr.course_key, course.id)
        self.assertEqual(enrollment_code.attr.seat_type, 'verified')

        # One parent product, three seat products, one enrollment code product (verified) -> five total products
        self.assertEqual(course.products.count(), 5)
        self.assertEqual(len(course.seat_products), 3)  # Definitely three seat products...
Exemplo n.º 57
0
    def setUp(self):
        super(CheckoutPageTest, self).setUp()
        self.switch = toggle_switch('ENABLE_CREDIT_APP', True)

        user = self.create_user(is_superuser=False)
        self.create_access_token(user)
        self.client.login(username=user.username, password=self.password)
        self.course_name = 'credit course'
        self.provider = 'ASU'
        self.price = 100
        self.thumbnail_url = 'http://www.edx.org/course.jpg'
        self.credit_hours = 2
        self.eligibility_url = get_lms_url('/api/credit/v1/eligibility/')
        self.provider_url = get_lms_url('/api/credit/v1/providers/')

        # Create the course
        self.course = Course.objects.create(
            id='edx/Demo_Course/DemoX',
            name=self.course_name,
            thumbnail_url=self.thumbnail_url
        )

        self.provider_data = [
            {
                'enable_integration': False,
                'description': 'Arizona State University',
                'url': 'https://credit.example.com/',
                'status_url': 'https://credit.example.com/status',
                'thumbnail_url': 'http://edX/DemoX/asset/images_course_image.jpg',
                'fulfillment_instructions': 'Sample fulfilment requirement.',
                'display_name': 'Arizona State University',
                'id': 'ASU'
            }
        ]

        self.eligibilities = [
            {
                'deadline': '2016-10-28T09:56:44Z',
                'course_key': 'edx/cs01/2015'
            }
        ]
Exemplo n.º 58
0
    def setUp(self):
        super(CheckoutPageTest, self).setUp()
        self.switch = toggle_switch('ENABLE_CREDIT_APP', True)
        user = self.create_user(is_superuser=False)
        self.client.login(username=user.username, password=self.password)
        self.course_name = 'credit course'
        self.provider = 'ASU'
        self.price = 100
        self.thumbnail_url = 'http://www.edx.org/course.jpg'
        self.credit_hours = 2
        # Create the course
        self.course = Course.objects.create(
            id=u'edx/Demo_Course/DemoX',
            name=self.course_name,
            thumbnail_url=self.thumbnail_url
        )

        # Create the credit seat
        self.seat = self.course.create_or_update_seat(
            'credit', True, self.price, self.provider, credit_hours=self.credit_hours
        )
Exemplo n.º 59
0
 def setUp(self):
     super(CommandTests, self).setUp()
     toggle_switch('publish_course_modes_to_lms', True)
Exemplo n.º 60
0
 def setUp(self):
     super(MigratedCourseTests, self).setUp()
     toggle_switch('publish_course_modes_to_lms', True)