Exemplo n.º 1
0
    def _configure(self, mode, upgrade_deadline=None, verification_deadline=None):
        """Configure course modes and deadlines. """
        course_mode = CourseModeFactory.create(
            mode_slug=mode,
            mode_display_name=mode,
        )

        if upgrade_deadline is not None:
            course_mode.upgrade_deadline = upgrade_deadline
            course_mode.save()

        VerificationDeadline.set_deadline(self.course.id, verification_deadline)

        return CourseModeForm(instance=course_mode)
Exemplo n.º 2
0
    def test_remember_donation_for_course(self):
        # Create the course modes
        CourseModeFactory.create(mode_slug='honor', course_id=self.course.id)
        CourseModeFactory.create(mode_slug='verified',
                                 course_id=self.course.id,
                                 min_price=1)

        # Choose the mode (POST request)
        choose_track_url = reverse('course_modes_choose',
                                   args=[str(self.course.id)])
        self.client.post(choose_track_url,
                         self.POST_PARAMS_FOR_COURSE_MODE['verified'])

        # Expect that the contribution amount is stored in the user's session
        assert 'donation_for_course' in self.client.session
        assert str(
            self.course.id) in self.client.session['donation_for_course']

        actual_amount = self.client.session['donation_for_course'][str(
            self.course.id)]
        expected_amount = decimal.Decimal(
            self.POST_PARAMS_FOR_COURSE_MODE['verified']['contribution'])
        assert actual_amount == expected_amount
Exemplo n.º 3
0
    def test_no_id_redirect(self):
        # Create the course modes
        CourseModeFactory.create(mode_slug=CourseMode.NO_ID_PROFESSIONAL_MODE,
                                 course_id=self.course.id,
                                 min_price=100)

        # Enroll the user in the test course
        CourseEnrollmentFactory(is_active=False,
                                mode=CourseMode.NO_ID_PROFESSIONAL_MODE,
                                course_id=self.course.id,
                                user=self.user)

        # Configure whether we're upgrading or not
        url = reverse('course_modes_choose',
                      args=[six.text_type(self.course.id)])
        response = self.client.get(url)
        # Check whether we were correctly redirected
        purchase_workflow = "?purchase_workflow=single"
        start_flow_url = reverse('verify_student_start_flow',
                                 args=[six.text_type(self.course.id)
                                       ]) + purchase_workflow
        with mock_payment_processors():
            self.assertRedirects(response, start_flow_url)
Exemplo n.º 4
0
    def test_suggested_prices(self, price_list):

        # Create the course modes
        for mode in ('audit', 'honor'):
            CourseModeFactory.create(mode_slug=mode, course_id=self.course.id)

        CourseModeFactory.create(mode_slug='verified',
                                 course_id=self.course.id,
                                 suggested_prices=price_list)

        # Enroll the user in the test course to emulate
        # automatic enrollment
        CourseEnrollmentFactory(is_active=True,
                                course_id=self.course.id,
                                user=self.user)

        # Verify that the prices render correctly
        response = self.client.get(
            reverse('course_modes_choose', args=[str(self.course.id)]),
            follow=False,
        )

        assert response.status_code == 200
Exemplo n.º 5
0
    def test_certificate_info_in_response(self):
        """
        Test that certificate has been created and rendered properly with non-audit course mode.
        """
        CourseModeFactory.create(course_id=self.course.id,
                                 mode_slug='verified')
        response = self.client.ajax_post(
            self._url(), data=CERTIFICATE_JSON_WITH_SIGNATORIES)

        self.assertEqual(response.status_code, 201)

        # in html response
        result = self.client.get_html(self._url())
        self.assertContains(result, 'Test certificate')
        self.assertContains(result, 'Test description')

        # in JSON response
        response = self.client.get_json(self._url())
        data = json.loads(response.content.decode('utf-8'))
        self.assertEqual(len(data), 1)
        self.assertEqual(data[0]['name'], 'Test certificate')
        self.assertEqual(data[0]['description'], 'Test description')
        self.assertEqual(data[0]['version'], CERTIFICATE_SCHEMA_VERSION)
Exemplo n.º 6
0
    def test_expiration_banner_with_expired_upgrade_deadline(self):
        """
        Ensure that a user accessing a course with an expired upgrade deadline
        will still see the course expiration banner without the upgrade related text.
        """
        past = datetime(2010, 1, 1, tzinfo=UTC)
        CourseDurationLimitConfig.objects.create(enabled=True,
                                                 enabled_as_of=past)
        course = CourseFactory.create(start=now() - timedelta(days=10))
        CourseModeFactory.create(course_id=course.id,
                                 mode_slug=CourseMode.AUDIT)
        CourseModeFactory.create(course_id=course.id,
                                 mode_slug=CourseMode.VERIFIED,
                                 expiration_datetime=past)
        user = UserFactory(password=self.TEST_PASSWORD)
        self.client.login(username=user.username, password=self.TEST_PASSWORD)
        CourseEnrollment.enroll(user, course.id, mode=CourseMode.AUDIT)

        url = course_home_url(course)
        response = self.client.get(url)
        bannerText = get_expiration_banner_text(user, course)
        self.assertContains(response, bannerText, html=True)
        self.assertContains(response, TEST_BANNER_CLASS)
Exemplo n.º 7
0
    def test_access_denied_fragment_for_full_access_users(self):
        """
        Test that Full Access users do not see the access_denied_fragment or access_denied_message
        """
        mock_request = RequestFactory().get('/')
        mock_course = Mock(id=self.course_key, user_partitions={})
        mock_block = Mock(scope_ids=Mock(usage_id=Mock(course_key=mock_course.id)))

        CourseModeFactory.create(course_id=mock_course.id, mode_slug='verified')

        global_staff = GlobalStaffFactory.create()
        ContentTypeGatingConfig.objects.create(enabled=False, studio_override_enabled=True)

        partition = create_content_gating_partition(mock_course)

        with patch(
            'crum.get_current_request',
            return_value=mock_request
        ):
            fragment = partition.access_denied_fragment(mock_block, global_staff, FULL_ACCESS, 'test_allowed_group')
            assert fragment is None
            message = partition.access_denied_message(mock_block.scope_ids.usage_id, global_staff, FULL_ACCESS, 'test_allowed_group')
            assert message is None
Exemplo n.º 8
0
    def setUp(self):
        super().setUp()
        self.service = EnrollmentsService()
        self.course_modes = [
            CourseMode.AUDIT,
            CourseMode.EXECUTIVE_EDUCATION,
            CourseMode.HONOR,
            CourseMode.MASTERS,
            CourseMode.PROFESSIONAL,
            CourseMode.VERIFIED
        ]
        self.course = CourseOverviewFactory.create(enable_proctored_exams=True)

        for index in range(len(self.course_modes)):
            course_mode = self.course_modes[index]
            course_id = self.course.id

            CourseModeFactory.create(mode_slug=course_mode, course_id=course_id)
            user = UserFactory(
                username=f'user{index}',
                email=f'LEARNER{index}@example.com'
            )
            CourseEnrollment.enroll(user, course_id, mode=course_mode)
Exemplo n.º 9
0
    def test_generate_example_certs_with_verified_mode(self):
        # Create verified and honor modes for the course
        CourseModeFactory.create(course_id=self.COURSE_KEY, mode_slug='honor')
        CourseModeFactory.create(course_id=self.COURSE_KEY, mode_slug='verified')

        # Generate certificates for the course
        with self._mock_xqueue() as mock_queue:
            certs_api.generate_example_certificates(self.COURSE_KEY)

        # Verify that the appropriate certs were added to the queue
        self._assert_certs_in_queue(mock_queue, 2)

        # Verify that the certificate status is "started"
        self._assert_cert_status(
            {
                'description': 'verified',
                'status': 'started'
            },
            {
                'description': 'honor',
                'status': 'started'
            }
        )
    def test_verified_course(self):
        course = CourseFactory.create(
            start=now() - timedelta(days=30),
            run='test',
            display_name='test',
        )
        CourseModeFactory.create(mode_slug=CourseMode.VERIFIED,
                                 course_id=course.id,
                                 min_price=10,
                                 sku=str(uuid4().hex))

        response = self.client.get(self.url, {'course_id': str(course.id)})
        assert response.status_code == 200
        result = response.data
        assert 'basket_url' in result
        assert bool(result['basket_url'])
        expected = {
            'show_upsell': True,
            'price': '$10',
            'basket_url': result['basket_url'],
            # Example basket_url: u'/verify_student/upgrade/org.0/course_0/test/'
        }
        assert result == expected
Exemplo n.º 11
0
    def _check_verification_status_off(self, mode, value):
        """
        Check that the css class and the status message are not in the dashboard html.
        """
        CourseModeFactory.create(mode_slug=mode, course_id=self.course.id)
        CourseEnrollment.enroll(self.user,
                                self.course.location.course_key,
                                mode=mode)

        if mode == 'verified':
            # Simulate a successful verification attempt
            attempt = self.create_and_submit_attempt_for_user(self.user)
            attempt.approve()

        response = self.client.get(reverse('dashboard'))

        if mode == 'audit':
            # Audit mode does not have a banner.  Assert no banner element.
            self.assertEqual(pq(response.content)(".sts-enrollment").length, 0)
        else:
            self.assertNotContains(response,
                                   "class=\"course {0}\"".format(mode))
            self.assertNotContains(response, value)
Exemplo n.º 12
0
 def _admin_form(self, mode, upgrade_deadline=None):
     """Load the course mode admin form. """
     course_mode = CourseModeFactory.create(
         course_id=self.course.id,
         mode_slug=mode,
     )
     return CourseModeForm({
         "course": str(self.course.id),
         "mode_slug": mode,
         "mode_display_name": mode,
         "_expiration_datetime": upgrade_deadline,
         "currency": "usd",
         "min_price": 10,
     }, instance=course_mode)
Exemplo n.º 13
0
    def test_no_id_redirect(self):
        # Create the course modes
        CourseModeFactory.create(mode_slug=CourseMode.NO_ID_PROFESSIONAL_MODE,
                                 course_id=self.course.id,
                                 min_price=100)

        # Enroll the user in the test course
        CourseEnrollmentFactory(is_active=False,
                                mode=CourseMode.NO_ID_PROFESSIONAL_MODE,
                                course_id=self.course.id,
                                user=self.user)

        # Configure whether we're upgrading or not
        url = reverse('course_modes_choose',
                      args=[six.text_type(self.course.id)])
        response = self.client.get(url)

        start_flow_url = IDVerificationService.get_verify_location(
            course_id=self.course.id)
        # Check whether we were correctly redirected
        self.assertRedirects(response,
                             start_flow_url,
                             fetch_redirect_response=False)
Exemplo n.º 14
0
    def test_course_upgrade_notification(self, ecommerce_enabled,
                                         has_verified_mode, has_entitlement,
                                         sku, should_display):
        """
        Upgrade notification for a course should appear if:
            - Ecommerce service is enabled
            - The course has a paid/verified mode
            - The user doesn't have an entitlement for the course
            - The course has an associated SKU
        """
        with patch.object(EcommerceService,
                          'is_enabled',
                          return_value=ecommerce_enabled):
            course = CourseFactory.create()

            if has_verified_mode:
                CourseModeFactory.create(
                    course_id=course.id,
                    mode_slug='verified',
                    mode_display_name='Verified',
                    expiration_datetime=datetime.now(pytz.UTC) +
                    timedelta(days=1),
                    sku=sku)

            enrollment = CourseEnrollmentFactory(user=self.user,
                                                 course_id=course.id)

            if has_entitlement:
                CourseEntitlementFactory(user=self.user,
                                         enrollment_course_run=enrollment)

            response = self.client.get(reverse('dashboard'))
            html_fragment = '<div class="message message-upsell has-actions is-shown">'
            if should_display:
                self.assertContains(response, html_fragment)
            else:
                self.assertNotContains(response, html_fragment)
Exemplo n.º 15
0
    def test_access_denied_fragment_for_null_request(self):
        """
        Verifies the access denied fragment is visible when HTTP request is not available.

        Given the HTTP request instance is None
        Then set the mobile_app context variable to False
        And the fragment should be created successfully
        """
        mock_request = None
        mock_course = Mock(id=self.course_key, user_partitions={})
        mock_block = Mock(scope_ids=Mock(usage_id=Mock(course_key=mock_course.id)))
        CourseModeFactory.create(course_id=mock_course.id, mode_slug='audit')
        CourseModeFactory.create(course_id=mock_course.id, mode_slug='verified')
        global_staff = GlobalStaffFactory.create()
        ContentTypeGatingConfig.objects.create(enabled=True, enabled_as_of=datetime(2018, 1, 1))
        partition = create_content_gating_partition(mock_course)

        with patch(
            'crum.get_current_request',
            return_value=mock_request
        ):
            fragment = partition.access_denied_fragment(mock_block, global_staff, LIMITED_ACCESS, [FULL_ACCESS])

        assert fragment is not None
Exemplo n.º 16
0
    def test_professional_enrollment(self, mode):
        # The only course mode is professional ed
        CourseModeFactory.create(mode_slug=mode, course_id=self.course.id, min_price=1)

        # Go to the "choose your track" page
        choose_track_url = reverse('course_modes_choose', args=[str(self.course.id)])
        response = self.client.get(choose_track_url)

        # Since the only available track is professional ed, expect that
        # we're redirected immediately to the start of the payment flow.
        start_flow_url = IDVerificationService.get_verify_location(course_id=self.course.id)
        self.assertRedirects(response, start_flow_url, fetch_redirect_response=False)

        # Now enroll in the course
        CourseEnrollmentFactory(
            user=self.user,
            is_active=True,
            mode=mode,
            course_id=str(self.course.id),
        )

        # Expect that this time we're redirected to the dashboard (since we're already registered)
        response = self.client.get(choose_track_url)
        self.assertRedirects(response, reverse('dashboard'))
Exemplo n.º 17
0
    def setUp(self):
        """ Setup components used by each refund test."""
        super().setUp()
        self.user = UserFactory.create(password=self.USER_PASSWORD)
        self.verified_mode = CourseModeFactory.create(
            course_id=self.course.id,
            mode_slug='verified',
            mode_display_name='Verified',
            expiration_datetime=datetime.now(pytz.UTC) + timedelta(days=1)
        )

        self.enrollment = CourseEnrollment.enroll(self.user, self.course.id, mode='verified')

        self.client = Client()
        cache.clear()
Exemplo n.º 18
0
    def test_get_visible_sessions_for_entitlement_expired_mode(self, mock_get_edx_api_data):
        """
        Test retrieval of visible session entitlements.
        """
        catalog_course_run = CourseRunFactory.create()
        catalog_course = CourseFactory(course_runs=[catalog_course_run])
        mock_get_edx_api_data.return_value = catalog_course
        course_key = CourseKey.from_string(catalog_course_run.get('key'))
        course_overview = CourseOverviewFactory.create(id=course_key, start=self.tomorrow)
        CourseModeFactory.create(
            mode_slug=CourseMode.VERIFIED,
            min_price=100,
            course_id=course_overview.id,
            expiration_datetime=now() - timedelta(days=1)
        )
        course_enrollment = CourseEnrollmentFactory(
            user=self.user, course=course_overview, mode=CourseMode.VERIFIED
        )
        entitlement = CourseEntitlementFactory(
            user=self.user, enrollment_course_run=course_enrollment, mode=CourseMode.VERIFIED
        )

        session_entitlements = get_visible_sessions_for_entitlement(entitlement)
        self.assertEqual(session_entitlements, [catalog_course_run])
    def test_expired_verified_mode(self):
        course = CourseFactory.create(
            start=now() - timedelta(days=30),
            run='test',
            display_name='test',
        )
        CourseModeFactory.create(
            mode_slug=CourseMode.VERIFIED,
            course_id=course.id,
            min_price=10,
            sku=str(uuid4().hex),
            expiration_datetime=now() - timedelta(days=30),
        )

        response = self.client.get(self.url, {'course_id': str(course.id)})
        assert response.status_code == 200
        expected = {
            'show_upsell': False,
            'upsell_flag': True,
            'experiment_bucket': 1,
            'user_upsell': True,
            'basket_url': None,  # Expired verified mode means no basket link
        }
        assert response.data == expected
Exemplo n.º 20
0
    def test_certificate_header_data(self):
        """
        Test that get_certificate_header_context from lms.djangoapps.certificates api
        returns data customized according to site branding.
        """
        # Generate certificates for the course
        CourseModeFactory.create(course_id=self.COURSE_KEY, mode_slug=CourseMode.HONOR)
        data = certs_api.get_certificate_header_context(is_secure=True)

        # Make sure there are not unexpected keys in dict returned by 'get_certificate_header_context'
        six.assertCountEqual(
            self,
            list(data.keys()),
            ['logo_src', 'logo_url']
        )
        self.assertIn(
            self.configuration['logo_image_url'],
            data['logo_src']
        )

        self.assertIn(
            self.configuration['SITE_NAME'],
            data['logo_url']
        )
Exemplo n.º 21
0
    def test_delete_course_mode_happy_path(self):
        new_mode = CourseModeFactory.create(
            course_id=self.course_key,
            mode_slug='bachelors',
            mode_display_name='Bachelors',
            min_price=1000,
        )
        self.client.login(username=self.global_staff.username,
                          password=self.user_password)
        url = self.get_url(mode_slug='bachelors')

        response = self.client.delete(url)

        assert status.HTTP_204_NO_CONTENT == response.status_code
        assert 0 == CourseMode.objects.filter(course_id=self.course_key,
                                              mode_slug='bachelors').count()
        self.addCleanup(lambda mode: mode.delete(), new_mode)
Exemplo n.º 22
0
    def test_course_mode_info(self):
        verified_mode = CourseModeFactory.create(
            course_id=self.course.id,
            mode_slug='verified',
            mode_display_name='Verified',
            expiration_datetime=datetime.now(pytz.UTC) + timedelta(days=1)
        )
        enrollment = CourseEnrollment.enroll(self.user, self.course.id)
        course_mode_info = complete_course_mode_info(self.course.id, enrollment)
        assert course_mode_info['show_upsell']
        assert course_mode_info['days_for_upsell'] == 1

        verified_mode.expiration_datetime = datetime.now(pytz.UTC) + timedelta(days=-1)
        verified_mode.save()
        course_mode_info = complete_course_mode_info(self.course.id, enrollment)
        assert not course_mode_info['show_upsell']
        assert course_mode_info['days_for_upsell'] is None
Exemplo n.º 23
0
    def test_display_after_discounted_price(
            self, discounted_price, is_enterprise_enabled,
            mock_get_course_final_price, mock_enterprise_customer_for_request):
        verified_mode = CourseModeFactory.create(mode_slug='verified',
                                                 course_id=self.course.id,
                                                 sku='dummy')
        CourseEnrollmentFactory(is_active=True,
                                course_id=self.course.id,
                                user=self.user)

        mock_enterprise_customer_for_request.return_value = {
            'name': 'dummy'
        } if is_enterprise_enabled else {}
        mock_get_course_final_price.return_value = discounted_price
        url = reverse('course_modes_choose', args=[self.course.id])
        response = self.client.get(url)

        if is_enterprise_enabled:
            self.assertContains(response, discounted_price)
        self.assertContains(response, verified_mode.min_price)
Exemplo n.º 24
0
    def setUp(self):
        super(BulkUnenrollTests, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments
        self.course = CourseFactory.create()
        self.audit_mode = CourseModeFactory.create(
            course_id=self.course.id,
            mode_slug='audit',
            mode_display_name='Audit',
        )

        self.user_info = [('amy', '*****@*****.**', 'password'),
                          ('rory', '*****@*****.**', 'password'),
                          ('river', '*****@*****.**', 'password')]
        self.enrollments = []
        self.users = []

        for username, email, password in self.user_info:
            user = UserFactory.create(username=username,
                                      email=email,
                                      password=password)
            self.users.append(user)
            self.enrollments.append(
                CourseEnrollment.enroll(user, self.course.id, mode='audit'))
Exemplo n.º 25
0
    def test_all_modes_for_courses(self):
        now_dt = now()
        future = now_dt + timedelta(days=1)
        past = now_dt - timedelta(days=1)

        # Unexpired, no expiration date
        CourseModeFactory.create(
            course_id=self.course_key,
            mode_display_name="Honor No Expiration",
            mode_slug="honor_no_expiration",
            expiration_datetime=None
        )

        # Unexpired, expiration date in future
        CourseModeFactory.create(
            course_id=self.course_key,
            mode_display_name="Honor Not Expired",
            mode_slug="honor_not_expired",
            expiration_datetime=future
        )

        # Expired
        CourseModeFactory.create(
            course_id=self.course_key,
            mode_display_name="Verified Expired",
            mode_slug="verified_expired",
            expiration_datetime=past
        )

        # We should get all of these back when querying for *all* course modes,
        # including ones that have expired.
        other_course_key = CourseLocator(org="not", course="a", run="course")
        all_modes = CourseMode.all_modes_for_courses([self.course_key, other_course_key])
        assert len(all_modes[self.course_key]) == 3
        assert all_modes[self.course_key][0].name == 'Honor No Expiration'
        assert all_modes[self.course_key][1].name == 'Honor Not Expired'
        assert all_modes[self.course_key][2].name == 'Verified Expired'

        # Check that we get a default mode for when no course mode is available
        assert len(all_modes[other_course_key]) == 1
        assert all_modes[other_course_key][0] == CourseMode.DEFAULT_MODE
Exemplo n.º 26
0
 def setUp(self):
     self.course_overview = CourseOverviewFactory.create()
     CourseModeFactory.create(course_id=self.course_overview.id, mode_slug='audit')
     CourseModeFactory.create(course_id=self.course_overview.id, mode_slug='verified')
     self.user = UserFactory.create()
     super(TestContentTypeGatingConfig, self).setUp()
Exemplo n.º 27
0
    def test_linked_in_add_to_profile_btn_with_certificate(self):
        # If user has a certificate with valid linked-in config then Add Certificate to LinkedIn button
        # should be visible. and it has URL value with valid parameters.
        self.client.login(username="******", password="******")

        linkedin_config = LinkedInAddToProfileConfiguration.objects.create(
            company_identifier='1337', enabled=True)
        CourseModeFactory.create(course_id=self.course.id,
                                 mode_slug='verified',
                                 mode_display_name='verified',
                                 expiration_datetime=datetime.now(pytz.UTC) -
                                 timedelta(days=1))
        CourseEnrollment.enroll(self.user, self.course.id, mode='honor')
        self.course.certificate_available_date = datetime.now(
            pytz.UTC) - timedelta(days=1)
        self.course.start = datetime.now(pytz.UTC) - timedelta(days=2)
        self.course.end = datetime.now(pytz.UTC) - timedelta(days=1)
        self.course.display_name = 'Omega'
        self.course = self.update_course(self.course, self.user.id)

        cert = GeneratedCertificateFactory.create(
            user=self.user,
            course_id=self.course.id,
            status=CertificateStatuses.downloadable,
            mode='honor',
            grade='67',
            download_url='https://www.edx.org')
        response = self.client.get(reverse('dashboard'))

        assert response.status_code == 200
        self.assertContains(response, 'Add Certificate to LinkedIn')

        # We can switch to this and the commented out assertContains once edx-platform reaches Python 3.8
        # expected_url = (
        #     'https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME&'
        #     'name={platform}+Honor+Code+Certificate+for+Omega&certUrl={cert_url}&'
        #     'organizationId={company_identifier}'
        # ).format(
        #     platform=quote(settings.PLATFORM_NAME.encode('utf-8')),
        #     cert_url=quote(cert.download_url, safe=''),
        #     company_identifier=linkedin_config.company_identifier,
        # )

        # self.assertContains(response, escape(expected_url))

        # These can be removed (in favor of the above) once we are on Python 3.8. Fails in 3.5 because of dict ordering
        self.assertContains(
            response,
            escape(
                'https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME'
            ))
        self.assertContains(
            response,
            escape('&name={platform}+Honor+Code+Certificate+for+Omega'.format(
                platform=quote(settings.PLATFORM_NAME.encode('utf-8')))))
        self.assertContains(
            response,
            escape('&certUrl={cert_url}'.format(
                cert_url=quote(cert.download_url, safe=''))))
        self.assertContains(
            response,
            escape('&organizationId={company_identifier}'.format(
                company_identifier=linkedin_config.company_identifier)))
Exemplo n.º 28
0
    def _create_course(cls,
                       run,
                       display_name,
                       modes,
                       component_types,
                       expired_upgrade_deadline=False):
        """
        Helper method to create a course
        Arguments:
            run (str): name of course run
            display_name (str): display name of course
            modes (list of str): list of modes/tracks this course should have
            component_types (list of str): list of problem types this course should have
        Returns:
             (dict): {
                'course': (CourseBlockWithMixins): course definition
                'blocks': (dict) {
                    'block_category_1': XBlock representing that block,
                    'block_category_2': XBlock representing that block,
                    ....
             }
        """
        start_date = timezone.now() - timedelta(weeks=1)
        course = CourseFactory.create(run=run,
                                      display_name=display_name,
                                      start=start_date)

        for mode in modes:
            if expired_upgrade_deadline and mode == 'verified':
                CourseModeFactory.create(
                    course_id=course.id,
                    mode_slug=mode,
                    expiration_datetime=start_date + timedelta(days=365),
                )
            else:
                CourseModeFactory.create(course_id=course.id, mode_slug=mode)

        with cls.store.bulk_operations(course.id):
            blocks_dict = {}
            chapter = ItemFactory.create(
                parent=course,
                display_name='Overview',
            )
            blocks_dict['chapter'] = ItemFactory.create(
                parent=course,
                category='chapter',
                display_name='Week 1',
            )
            blocks_dict['sequential'] = ItemFactory.create(
                parent=chapter,
                category='sequential',
                display_name='Lesson 1',
            )
            blocks_dict['vertical'] = ItemFactory.create(
                parent=blocks_dict['sequential'],
                category='vertical',
                display_name='Lesson 1 Vertical - Unit 1',
            )

            for component_type in component_types:
                block = ItemFactory.create(parent=blocks_dict['vertical'],
                                           category=component_type,
                                           graded=True,
                                           metadata={} if
                                           (component_type == 'html'
                                            or len(modes) == 1) else METADATA)
                blocks_dict[component_type] = block
                # Intersperse HTML so that the content-gating renders in all blocks
                ItemFactory.create(
                    parent=blocks_dict['vertical'],
                    category='html',
                    graded=False,
                )

            return {
                'course': course,
                'blocks': blocks_dict,
            }
Exemplo n.º 29
0
 def setUp(self):
     self.course_overview = CourseOverviewFactory.create()
     CourseModeFactory.create(course_id=self.course_overview.id, mode_slug='audit')
     CourseModeFactory.create(course_id=self.course_overview.id, mode_slug='verified')
     self.user = UserFactory.create()
     super().setUp()