Example #1
0
    def setUp(self):
        """
        Test set up.
        """
        super(TestEnterpriseCustomerReportingConfigAdminForm, self).setUp()

        self.ent_customer1 = EnterpriseCustomerFactory()
        self.ent_customer2 = EnterpriseCustomerFactory()

        self.ent_catalogs1 = [
            EnterpriseCustomerCatalogFactory(
                enterprise_customer=self.ent_customer1) for _ in range(3)
        ]
        self.ent_catalogs2 = [
            EnterpriseCustomerCatalogFactory(
                enterprise_customer=self.ent_customer2) for _ in range(2)
        ]

        self.form_data = {
            'enterprise_customer': self.ent_customer1.uuid,
            'data_type': 'progress',
            'report_type': 'csv',
            'delivery_method': 'email',
            'frequency': 'daily',
            'hour_of_day': 1,
            'email': '*****@*****.**',
            'decrypted_password': '******',
        }
    def test_delete_catalog(self, api_client_mock):
        enterprise_catalog = EnterpriseCustomerCatalogFactory()
        enterprise_catalog_uuid = enterprise_catalog.uuid
        api_client_mock.return_value.get_enterprise_catalog.return_value = True
        enterprise_catalog.delete()

        # Verify the API was called correctly and the catalog was deleted
        api_client_mock.return_value.delete_enterprise_catalog.assert_called_with(enterprise_catalog_uuid)
        self.assertFalse(EnterpriseCustomerCatalog.objects.exists())
    def test_get_course_specific_consent_improperly_configured_course_catalog(
            self, course_catalog_api_client_mock, *args):  # pylint: disable=unused-argument,invalid-name
        course_id = 'course-v1:edX+DemoX+Demo_Course'

        course_catalog_api_client_mock.side_effect = ImproperlyConfigured(
            "There is no active CatalogIntegration.")
        self._login()
        enterprise_customer = EnterpriseCustomerFactory(
            name='Starfleet Academy',
            enable_data_sharing_consent=True,
            enforce_data_sharing_consent='at_enrollment',
        )
        content_filter = {
            'key': [
                course_id,
            ]
        }
        EnterpriseCustomerCatalogFactory(
            enterprise_customer=enterprise_customer,
            content_filter=content_filter)
        ecu = EnterpriseCustomerUserFactory(
            user_id=self.user.id, enterprise_customer=enterprise_customer)
        EnterpriseCourseEnrollment.objects.create(enterprise_customer_user=ecu,
                                                  course_id=course_id)
        params = {
            'course_id': course_id,
            'enterprise_customer_uuid': str(enterprise_customer.uuid),
            'next': 'https://google.com',
            'failure_url': 'https://facebook.com',
            'defer_creation': True,
        }
        with mock.patch('enterprise.views.render') as mock_render:
            mock_render.return_value = HttpResponse()
            self.client.get(self.url, data=params)
            assert mock_render.call_args_list[0][1]['status'] == 404
Example #4
0
    def test_no_response_doesnt_get_cached(self):
        """
        Response doesn't get cached when empty.
        """
        EnterpriseCustomerCatalogFactory(
            enterprise_customer=self.enterprise_customer, )
        enterprise_catalog_uuid = str(
            self.enterprise_customer.enterprise_customer_catalogs.first().uuid)

        api_resource_name = 'enterprise_catalogs'
        cache_key = get_cache_key(
            resource=api_resource_name,
            querystring={},
            traverse_pagination=False,
            resource_id=enterprise_catalog_uuid,
        )

        cached_enterprise_api_response = cache.get(cache_key)
        assert cached_enterprise_api_response is None

        self.mock_empty_response('enterprise-catalogs-detail',
                                 enterprise_catalog_uuid)
        client = enterprise_api.EnterpriseApiClient(self.user)
        response = client._load_data(  # pylint: disable=protected-access
            resource=api_resource_name,
            resource_id=enterprise_catalog_uuid,
        )
        assert not response

        # The empty response is not cached.
        cached_api_response = cache.get(cache_key)
        assert not cached_api_response
    def test_handle_consent_enrollment_with_professional_course_mode(
            self,
            registry_mock,
            enrollment_api_client_mock,
            track_enrollment_mock,
            *args
    ):  # pylint: disable=unused-argument
        """
        Verify that user is redirected to course in case the provided
        course mode is audit track.
        """
        course_id = self.demo_course_id
        enterprise_customer = EnterpriseCustomerFactory(
            name='Starfleet Academy',
            enable_data_sharing_consent=True,
            enforce_data_sharing_consent='at_enrollment',
            enable_audit_enrollment=True,
        )
        enterprise_catalog = EnterpriseCustomerCatalogFactory(enterprise_customer=enterprise_customer)
        faker = FakerFactory.create()
        provider_id = faker.slug()  # pylint: disable=no-member
        self._setup_registry_mock(registry_mock, provider_id)
        EnterpriseCustomerIdentityProviderFactory(provider_id=provider_id, enterprise_customer=enterprise_customer)
        enterprise_customer_user = EnterpriseCustomerUserFactory(
            user_id=self.user.id,
            enterprise_customer=enterprise_customer
        )
        enrollment_client = enrollment_api_client_mock.return_value
        enrollment_client.get_course_modes.return_value = self.dummy_demo_course_modes
        self._login()
        handle_consent_enrollment_url = self._append_fresh_login_param(
            '{consent_enrollment_url}?{params}'.format(
                consent_enrollment_url=reverse(
                    'enterprise_handle_consent_enrollment', args=[enterprise_customer.uuid, course_id]
                ),
                params=urlencode({
                    'course_mode': 'professional',
                    'catalog': enterprise_catalog.uuid
                })
            )
        )
        response = self.client.get(handle_consent_enrollment_url)
        redirect_url = LMS_START_PREMIUM_COURSE_FLOW_URL.format(course_id=course_id)
        redirect_url += '?catalog={catalog_uuid}'.format(
            catalog_uuid=enterprise_catalog.uuid
        )
        self.assertRedirects(response, redirect_url, fetch_redirect_response=False)

        self.assertTrue(EnterpriseCourseEnrollment.objects.filter(
            enterprise_customer_user__enterprise_customer=enterprise_customer,
            enterprise_customer_user__user_id=enterprise_customer_user.user_id,
            course_id=course_id
        ).exists())

        track_enrollment_mock.assert_called_once_with(
            'course-landing-page-enrollment',
            enterprise_customer_user.user_id,
            course_id,
            handle_consent_enrollment_url,
        )
 def test_default_content_filter(self, default_content_filter, expected_content_filter):
     """
     Test that `EnterpriseCustomerCatalog`.content_filter is saved with correct default content filter.
     """
     with override_settings(ENTERPRISE_CUSTOMER_CATALOG_DEFAULT_CONTENT_FILTER=default_content_filter):
         enterprise_catalog = EnterpriseCustomerCatalogFactory()
         assert enterprise_catalog.content_filter == expected_content_filter
Example #7
0
 def setUp(self):
     self.user = UserFactory.create(is_staff=True, is_active=True)
     self.enterprise_customer = EnterpriseCustomerFactory(
         name='Starfleet Academy', )
     self.enterprise_catalog = EnterpriseCustomerCatalogFactory(
         enterprise_customer=self.enterprise_customer)
     super().setUp()
    def test_get_content_metadata_with_enterprise_catalogs(self):
        """
        Verify that the client method `get_content_metadata` works as expected.
        """
        EnterpriseCustomerCatalogFactory(
            enterprise_customer=self.enterprise_customer,
        )
        uuid = str(self.enterprise_customer.uuid)
        course_run_ids = ['course-v1:edX+DemoX+Demo_Course_1', 'course-v1:edX+DemoX+Demo_Course_2']

        self.mock_ent_courses_api_with_pagination(
            enterprise_uuid=uuid,
            course_run_ids=course_run_ids
        )

        enterprise_catalog_uuid = str(self.enterprise_customer.enterprise_customer_catalogs.first().uuid)
        self.mock_enterprise_customer_catalogs(enterprise_catalog_uuid)

        api_resource_name = 'enterprise-customer'
        cache_key = get_cache_key(
            resource=api_resource_name,
            querystring={},
            resource_id=uuid,
            traverse_pagination=False,
        )
        cached_enterprise_api_response = cache.get(cache_key)
        self.assertIsNone(cached_enterprise_api_response)

        # Verify that by default enterprise client fetches all the course runs associated with the catalog.
        client = enterprise_api.EnterpriseApiClient(self.user)
        course_runs = client.get_content_metadata(self.enterprise_customer)
        assert len(course_runs) == 5
Example #9
0
    def test_get_content_metadata_with_enterprise_catalog_set_to_none(self):
        """
        Verify that the client method `get_content_metadata` returns courses from
        associated EnterpriseCustomerCatalog objects only if EnterpriseCustomer.catalog is set to None.
        """
        EnterpriseCustomerCatalogFactory(
            enterprise_customer=self.enterprise_customer, )

        enterprise_catalog_uuid = str(
            self.enterprise_customer.enterprise_customer_catalogs.first().uuid)
        self.mock_enterprise_customer_catalogs(enterprise_catalog_uuid)

        api_resource_name = 'enterprise-customer'
        cache_key = get_cache_key(
            resource=api_resource_name,
            querystring={},
            resource_id=str(self.enterprise_customer.uuid),
            traverse_pagination=False,
        )
        cached_enterprise_api_response = cache.get(cache_key)
        self.assertIsNone(cached_enterprise_api_response)

        # Verify that by default enterprise client fetches all the course runs associated with the enterprise catalog.
        client = enterprise_api.EnterpriseApiClient(self.user)
        course_runs = client.get_content_metadata(self.enterprise_customer)
        assert len(course_runs) == 3
    def test_update_catalog_without_existing_service_catalog(
            self, api_client_mock):
        enterprise_catalog = EnterpriseCustomerCatalogFactory()
        api_client_mock.return_value.get_enterprise_catalog.return_value = {}

        enterprise_catalog.title = 'New title'
        enterprise_catalog.save()

        # Verify the API was called and the catalog is the same as there were no real updates
        api_client_mock.return_value.create_enterprise_catalog.assert_called_with(
            str(enterprise_catalog.uuid),
            str(enterprise_catalog.enterprise_customer.uuid),
            enterprise_catalog.enterprise_customer.name,
            enterprise_catalog.title, enterprise_catalog.content_filter,
            enterprise_catalog.enabled_course_modes,
            enterprise_catalog.publish_audit_enrollment_urls)
Example #11
0
 def setUp(self):
     super(EnterpriseCustomerCatalogAdminTests, self).setUp()
     self.catalog_admin = EnterpriseCustomerCatalogAdmin(
         EnterpriseCustomerCatalog, AdminSite)
     self.request = RequestFactory()
     self.request.user = UserFactory(is_staff=True)
     self.enterprise_catalog = EnterpriseCustomerCatalogFactory()
     self.enterprise_catalog_uuid = self.enterprise_catalog.uuid
     self.form = None  # The form isn't important for the current tests as we don't change any logic there
Example #12
0
    def test_update_enterprise_catalog_query(self, api_client_mock):
        """
        Tests the update_enterprise_query post_save signal.

        Creates an EnterpriseCatalogQuery instance and two separate EnterpriseCatalog
        instances that are associated with the query. The query's content filter is then
        updated to see if the changes are applied across both related catalogs. Additionally,
        there is a test to see if the sync is sent to the EnterpriseCatalogApi service
        which is done through the mock api client.
        """
        content_filter_1 = OrderedDict({
            'content_type': 'course1',
        })
        content_filter_2 = OrderedDict({
            'content_type': 'course2',
        })

        test_query = EnterpriseCatalogQueryFactory(
            content_filter=content_filter_1
        )
        enterprise_catalog_1 = EnterpriseCustomerCatalogFactory(
            sync_enterprise_catalog_query=True,
            enterprise_catalog_query=test_query
        )
        enterprise_catalog_2 = EnterpriseCustomerCatalogFactory(
            sync_enterprise_catalog_query=True,
            enterprise_catalog_query=test_query
        )

        test_query.content_filter = content_filter_2
        test_query.save()

        enterprise_catalog_1.refresh_from_db()
        enterprise_catalog_2.refresh_from_db()

        self.assertEqual(enterprise_catalog_1.content_filter, content_filter_2)
        self.assertEqual(enterprise_catalog_2.content_filter, content_filter_2)

        api_client_mock.return_value.get_enterprise_catalog.return_value = True

        # verify that the mock api was called when saving the catalog after updating the query
        # enterprise_catalog_2 was most recently modified so the last call should be for that
        api_client_mock.return_value.update_enterprise_catalog.assert_called_with(
            enterprise_catalog_2.uuid,
            enterprise_customer=str(enterprise_catalog_2.enterprise_customer.uuid),
            enterprise_customer_name=enterprise_catalog_2.enterprise_customer.name,
            title=enterprise_catalog_2.title,
            content_filter=enterprise_catalog_2.content_filter,
            enabled_course_modes=enterprise_catalog_2.enabled_course_modes,
            publish_audit_enrollment_urls=enterprise_catalog_2.publish_audit_enrollment_urls
        )
        api_client_mock.return_value.refresh_catalogs.assert_called_with([enterprise_catalog_2])
    def test_create_catalog(self, api_client_mock):
        api_client_mock.return_value.get_enterprise_catalog.return_value = {}
        enterprise_catalog = EnterpriseCustomerCatalogFactory()

        # Verify the API was called and the catalog "was created" (even though it already was)
        # This method is a little weird in that the object is sort of created / not-created at the same time
        api_client_mock.return_value.create_enterprise_catalog.assert_called_with(
            str(enterprise_catalog.uuid),
            str(enterprise_catalog.enterprise_customer.uuid),
            enterprise_catalog.enterprise_customer.name,
            enterprise_catalog.title, enterprise_catalog.content_filter,
            enterprise_catalog.enabled_course_modes,
            enterprise_catalog.publish_audit_enrollment_urls)
def test_partial_successful_refresh_catalog():
    catalog1 = EnterpriseCustomerCatalogFactory()
    catalog2 = EnterpriseCustomerCatalogFactory()
    task_id = '17812314511'
    responses.add(
        responses.POST,
        _url("enterprise-catalogs/{catalog_uuid}/refresh_metadata/".format(
            catalog_uuid=catalog1.uuid)),
        json={'async_task_id': task_id},
    )
    responses.add(
        responses.POST,
        _url("enterprise-catalogs/{catalog_uuid}/refresh_metadata/".format(
            catalog_uuid=catalog2.uuid)),
        body=ConnectionError(),
    )
    client = enterprise_catalog.EnterpriseCatalogApiClient(
        'staff-user-goes-here')
    refreshed_catalogs, failed_to_refresh_catalogs = client.refresh_catalogs(
        EnterpriseCustomerCatalog.objects.all())
    assert failed_to_refresh_catalogs[0] == catalog2.uuid
    assert len(refreshed_catalogs.items()) == 1
    assert refreshed_catalogs.get(catalog1.uuid) == task_id
def test_failing_refresh_catalog():
    catalog = EnterpriseCustomerCatalogFactory()
    responses.add(
        responses.POST,
        _url("enterprise-catalogs/{catalog_uuid}/refresh_metadata/".format(
            catalog_uuid=catalog.uuid)),
        body=ConnectionError(),
    )
    client = enterprise_catalog.EnterpriseCatalogApiClient(
        'staff-user-goes-here')
    refreshed_catalogs, failed_to_refresh_catalogs = client.refresh_catalogs(
        EnterpriseCustomerCatalog.objects.all())
    assert failed_to_refresh_catalogs[0] == catalog.uuid
    assert len(refreshed_catalogs.items()) == 0
    def setUp(self):
        self.enterprise_customer = EnterpriseCustomerFactory()
        self.enterprise_customer_catalog = EnterpriseCustomerCatalogFactory(
            enterprise_customer=self.enterprise_customer
        )
        self.config = CornerstoneEnterpriseCustomerConfiguration(
            enterprise_customer=self.enterprise_customer,
            catalogs_to_transmit=str(self.enterprise_customer_catalog.uuid),
            active=True
        )
        self.config.save()
        self.user = UserFactory()
        self.demo_course_run_id = 'course-v1:edX+DemoX+Demo_Course_1'

        super(TestCornerstoneEnterpriseCustomerConfiguration, self).setUp()
Example #17
0
    def test_get_content_metadata_with_catalogs_to_transmit(
            self, mock_load_data):
        """
        Verify that the client method `get_content_metadata` returns courses
        from catalogs passed in 'catalogs_to_transmit' parameter.
        """
        enterprise_catalog = EnterpriseCustomerCatalogFactory(
            enterprise_customer=self.enterprise_customer)
        client = enterprise_api.EnterpriseApiClient(self.user)
        # get_content_metadata will transmit the 'enterprise_customer' catalogs
        client.get_content_metadata(self.enterprise_customer)
        assert mock_load_data.called
        assert mock_load_data.call_args[1]['resource_id'] == str(
            enterprise_catalog.uuid)

        other_catalog = EnterpriseCustomerCatalogFactory()
        # get_content_metadata will transmit the catalogs which are being passed in 'catalogs_to_transmit'
        client.get_content_metadata(
            self.enterprise_customer,
            enterprise_catalogs=EnterpriseCustomerCatalog.objects.filter(
                uuid=other_catalog.uuid))
        assert mock_load_data.called
        assert mock_load_data.call_args[1]['resource_id'] == str(
            other_catalog.uuid)
def test_successful_refresh_catalog():
    catalog = EnterpriseCustomerCatalogFactory()
    task_id = '17812314511'
    responses.add(
        responses.POST,
        _url("enterprise-catalogs/{catalog_uuid}/refresh_metadata/".format(
            catalog_uuid=catalog.uuid)),
        json={'async_task_id': task_id},
    )
    client = enterprise_catalog.EnterpriseCatalogApiClient(
        'staff-user-goes-here')
    refreshed_catalogs, failed_to_refresh_catalogs = client.refresh_catalogs(
        EnterpriseCustomerCatalog.objects.all())
    assert refreshed_catalogs.get(catalog.uuid) == task_id
    assert len(failed_to_refresh_catalogs) == 0
    def test_clean(self):
        """
        Test the custom clean method of model.
        """
        # with valid catalog uuids in 'catalogs_to_transmit', clean will not raise any exception.
        self.config.clean()

        # with invalid catalog uuids in 'catalogs_to_transmit', clean will raise 'ValidationError'.
        self.config.catalogs_to_transmit = "fake-uuid,"
        self.config.save()
        with raises(ValidationError):
            self.config.clean()

        self.config.catalogs_to_transmit = str(EnterpriseCustomerCatalogFactory().uuid)
        self.config.save()
        with raises(ValidationError):
            self.config.clean()
    def test_get_course_specific_consent(self, defer_creation,
                                         existing_course_enrollment,
                                         course_start_date,
                                         course_api_client_mock,
                                         course_catalog_api_client_mock,
                                         *args):  # pylint: disable=unused-argument,invalid-name
        course_id = 'course-v1:edX+DemoX+Demo_Course'
        course_key = 'edX+DemoX'
        course_catalog_api_client_mock.return_value.course_in_catalog.return_value = True
        content_filter = {
            'key': [
                course_id,
            ]
        }
        course_catalog_api_client_mock.return_value.get_course_id.return_value = course_key
        course_run_details = {
            'start': course_start_date,
            'title': 'Demo Course'
        }
        course_catalog_api_client_mock.return_value.get_course_run.return_value = course_run_details

        client = course_api_client_mock.return_value
        client.get_course_details.return_value = {
            'name': 'edX Demo Course',
        }
        self._login()
        enterprise_customer = EnterpriseCustomerFactory(
            name='Starfleet Academy',
            enable_data_sharing_consent=True,
            enforce_data_sharing_consent='at_enrollment',
        )
        EnterpriseCustomerCatalogFactory(
            enterprise_customer=enterprise_customer,
            content_filter=content_filter)
        ecu = EnterpriseCustomerUserFactory(
            user_id=self.user.id, enterprise_customer=enterprise_customer)
        if existing_course_enrollment:
            EnterpriseCourseEnrollment.objects.create(
                enterprise_customer_user=ecu, course_id=course_id)
        params = {
            'enterprise_customer_uuid': str(enterprise_customer.uuid),
            'course_id': course_id,
            'next': 'https://google.com',
            'failure_url': 'https://facebook.com',
        }
        if defer_creation:
            params['defer_creation'] = True
        response = self.client.get(self.url, data=params)
        assert response.status_code == 200
        expected_prompt = (
            'To access this course, you must first consent to share your learning achievements '
            'with <b>Starfleet Academy</b>.')
        expected_alert = (
            'In order to start this course and use your discount, <b>you must</b> consent to share your '
            'course data with Starfleet Academy.')
        expected_course_start_date = ''
        if course_start_date:
            expected_course_start_date = parse(
                course_run_details['start']).strftime('%B %d, %Y')

        for key, value in {
                'platform_name':
                'Test platform',
                'platform_description':
                'Test description',
                'tagline':
                "High-quality online learning opportunities from the world's best universities",
                'header_logo_alt_text':
                'Test platform home page',
                'consent_request_prompt':
                expected_prompt,
                'requested_permissions_header':
            ('Per the <a href="#consent-policy-dropdown-bar" '
             'class="policy-dropdown-link background-input" id="policy-dropdown-link">'
             'Data Sharing Policy</a>, <b>Starfleet Academy</b> would like to know about:'
             ),
                'confirmation_alert_prompt':
                expected_alert,
                'sharable_items_footer':
            ('My permission applies only to data from courses or programs that are sponsored by '
             'Starfleet Academy, and not to data from any Test platform courses or programs that '
             'I take on my own. I understand that I may withdraw my permission only by fully unenrolling '
             'from any courses or programs that are sponsored by Starfleet Academy.'
             ),
                'course_id':
                'course-v1:edX+DemoX+Demo_Course',
                'redirect_url':
                'https://google.com',
                'course_specific':
                True,
                'defer_creation':
                defer_creation,
                'welcome_text':
                'Welcome to Test platform.',
                'sharable_items_note_header':
                'Please note',
                'LMS_SEGMENT_KEY':
                settings.LMS_SEGMENT_KEY,
                'LMS_ROOT_URL':
                'http://lms.example.com',
                'course_start_date':
                expected_course_start_date,
                'enterprise_customer':
                enterprise_customer,
                'enterprise_welcome_text':
            ("You have left the <strong>Starfleet Academy</strong> website and are now on the "
             "Test platform site. Starfleet Academy has partnered with Test platform to offer you "
             "high-quality, always available learning programs to help you advance your knowledge "
             "and career. <br/>Please note that Test platform has a different "
             "<a href='https://www.edx.org/edx-privacy-policy' target='_blank'>Privacy Policy </a> "
             "from Starfleet Academy."),
        }.items():
            assert response.context[key] == value  # pylint:disable=no-member
    def test_post_course_specific_consent(
            self, defer_creation, consent_provided, expected_redirect_url,
            course_id, license_uuid, reverse_mock,
            course_catalog_api_client_mock, enterprise_catalog_api_client_mock,
            mock_enrollment_api_client, *args):  # pylint: disable=unused-argument,invalid-name
        self._login()
        enterprise_customer = EnterpriseCustomerFactory(
            name='Starfleet Academy',
            enable_data_sharing_consent=True,
            enforce_data_sharing_consent='at_enrollment',
        )
        content_filter = {
            'key': [
                course_id,
            ]
        }
        EnterpriseCustomerCatalogFactory(
            enterprise_customer=enterprise_customer,
            content_filter=content_filter)
        ecu = EnterpriseCustomerUserFactory(
            user_id=self.user.id, enterprise_customer=enterprise_customer)
        enterprise_enrollment = EnterpriseCourseEnrollment.objects.create(
            enterprise_customer_user=ecu,
            course_id=course_id,
        )
        dsc = DataSharingConsentFactory(
            username=self.user.username,
            course_id=course_id,
            enterprise_customer=enterprise_customer,
            granted=consent_provided)

        course_catalog_api_client_mock.return_value.program_exists.return_value = True
        course_catalog_api_client_mock.return_value.get_course_id.return_value = 'edX+DemoX'

        mock_enterprise_catalog_api_client = enterprise_catalog_api_client_mock.return_value
        mock_enterprise_catalog_api_client.enterprise_contains_content_items.return_value = True

        reverse_mock.return_value = '/dashboard'
        course_mode = 'verified'
        mock_enrollment_api_client.return_value.get_course_modes.return_value = [
            course_mode
        ]
        post_data = {
            'enterprise_customer_uuid': enterprise_customer.uuid,
            'course_id': course_id,
            'redirect_url': '/successful_enrollment',
            'failure_url': '/failure_url',
        }
        if defer_creation:
            post_data['defer_creation'] = True
        if consent_provided:
            post_data['data_sharing_consent'] = consent_provided
        if license_uuid:
            post_data['license_uuid'] = license_uuid

        resp = self.client.post(self.url, post_data)

        assert resp.url.endswith(expected_redirect_url)  # pylint: disable=no-member
        assert resp.status_code == 302
        if not defer_creation:
            dsc.refresh_from_db()
            assert dsc.granted is consent_provided

        # we'll only create an enrollment record if (1) creation is not deferred, (2) consent has not been provided,
        # (3) we provide a license_uuid, and (4) we provide a course _run_ id
        if not defer_creation and not consent_provided and license_uuid and course_id.endswith(
                'Demo_Course'):
            assert LicensedEnterpriseCourseEnrollment.objects.filter(
                enterprise_course_enrollment=enterprise_enrollment,
                license_uuid=license_uuid,
            ).exists() is True

            mock_enrollment_api_client.return_value.enroll_user_in_course.assert_called_once_with(
                self.user.username, course_id, course_mode)

        if not license_uuid:
            assert not mock_enrollment_api_client.return_value.enroll_user_in_course.called