class EligibleCertificateManagerTest(SharedModuleStoreTestCase): """ Test the GeneratedCertificate model's object manager for filtering out ineligible certs. """ def setUp(self): super(EligibleCertificateManagerTest, self).setUp() self.user = UserFactory() self.course1 = CourseOverviewFactory() self.course2 = CourseOverviewFactory( id=CourseKey.from_string('{}a'.format(self.course1.id)) ) self.eligible_cert = GeneratedCertificateFactory.create( status=CertificateStatuses.downloadable, user=self.user, course_id=self.course1.id ) self.ineligible_cert = GeneratedCertificateFactory.create( status=CertificateStatuses.audit_passing, user=self.user, course_id=self.course2.id ) def test_filter_ineligible_certificates(self): """ Verify that the EligibleAvailableCertificateManager filters out certificates marked as ineligible, and that the default object manager for GeneratedCertificate does not filter them out. """ self.assertEqual(list( GeneratedCertificate.eligible_available_certificates.filter(user=self.user)), [self.eligible_cert] ) self.assertEqual( list(GeneratedCertificate.objects.filter(user=self.user)), [self.eligible_cert, self.ineligible_cert] ) def test_filter_certificates_for_nonexistent_courses(self): """ Verify that the EligibleAvailableCertificateManager filters out certificates for courses with no CourseOverview. """ self.course1.delete() self.assertFalse(GeneratedCertificate.eligible_available_certificates.filter( user=self.user) )
def test_config_overrides(self, global_setting, site_setting, org_setting, course_setting, reverse_order): """ Test that the stacked configuration overrides happen in the correct order and priority. This is tested by exhaustively setting each combination of contexts, and validating that only the lowest level context that is set to not-None is applied. """ # Add a bunch of configuration outside the contexts that are being tested, to make sure # there are no leaks of configuration across contexts non_test_course_enabled = CourseOverviewFactory.create(org='non-test-org-enabled') non_test_course_disabled = CourseOverviewFactory.create(org='non-test-org-disabled') non_test_site_cfg_enabled = SiteConfigurationFactory.create( values={'course_org_filter': non_test_course_enabled.org} ) non_test_site_cfg_disabled = SiteConfigurationFactory.create( values={'course_org_filter': non_test_course_disabled.org} ) CourseDurationLimitConfig.objects.create(course=non_test_course_enabled, enabled=True) CourseDurationLimitConfig.objects.create(course=non_test_course_disabled, enabled=False) CourseDurationLimitConfig.objects.create(org=non_test_course_enabled.org, enabled=True) CourseDurationLimitConfig.objects.create(org=non_test_course_disabled.org, enabled=False) CourseDurationLimitConfig.objects.create(site=non_test_site_cfg_enabled.site, enabled=True) CourseDurationLimitConfig.objects.create(site=non_test_site_cfg_disabled.site, enabled=False) # Set up test objects test_course = CourseOverviewFactory.create(org='test-org') test_site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': test_course.org}) if reverse_order: CourseDurationLimitConfig.objects.create(site=test_site_cfg.site, enabled=site_setting) CourseDurationLimitConfig.objects.create(org=test_course.org, enabled=org_setting) CourseDurationLimitConfig.objects.create(course=test_course, enabled=course_setting) CourseDurationLimitConfig.objects.create(enabled=global_setting) else: CourseDurationLimitConfig.objects.create(enabled=global_setting) CourseDurationLimitConfig.objects.create(course=test_course, enabled=course_setting) CourseDurationLimitConfig.objects.create(org=test_course.org, enabled=org_setting) CourseDurationLimitConfig.objects.create(site=test_site_cfg.site, enabled=site_setting) expected_global_setting = self._resolve_settings([global_setting]) expected_site_setting = self._resolve_settings([global_setting, site_setting]) expected_org_setting = self._resolve_settings([global_setting, site_setting, org_setting]) expected_course_setting = self._resolve_settings([global_setting, site_setting, org_setting, course_setting]) self.assertEqual(expected_global_setting, CourseDurationLimitConfig.current().enabled) self.assertEqual(expected_site_setting, CourseDurationLimitConfig.current(site=test_site_cfg.site).enabled) self.assertEqual(expected_org_setting, CourseDurationLimitConfig.current(org=test_course.org).enabled) self.assertEqual(expected_course_setting, CourseDurationLimitConfig.current(course_key=test_course.id).enabled)
def setUpClass(cls): super(TaskTestCase, cls).setUpClass() cls.discussion_id = 'dummy_discussion_id' cls.course = CourseOverviewFactory.create(language='fr') # Patch the comment client user save method so it does not try # to create a new cc user when creating a django user with mock.patch('student.models.cc.User.save'): cls.thread_author = UserFactory( username='******', password='******', email='email' ) cls.comment_author = UserFactory( username='******', password='******', email='email' ) CourseEnrollmentFactory( user=cls.thread_author, course_id=cls.course.id ) CourseEnrollmentFactory( user=cls.comment_author, course_id=cls.course.id ) config = ForumsConfig.current() config.enabled = True config.save() cls.create_thread_and_comments()
def test_unpublished_sessions_for_entitlement_when_enrolled(self, mock_get_edx_api_data): """ Test unpublished course runs are part of visible session entitlements when the user is enrolled. """ catalog_course_run = CourseRunFactory.create(status=COURSE_UNPUBLISHED) 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_id=unicode(course_overview.id), 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_caching_org(self): course = CourseOverviewFactory.create(org='test-org') site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': course.org}) org_config = ContentTypeGatingConfig(org=course.org, enabled=True, enabled_as_of=datetime(2018, 1, 1)) org_config.save() # Check that the org value is not retrieved from cache after save with self.assertNumQueries(2): self.assertTrue(ContentTypeGatingConfig.current(org=course.org).enabled) # Check that the org value can be retrieved from cache after read with self.assertNumQueries(0): self.assertTrue(ContentTypeGatingConfig.current(org=course.org).enabled) org_config.enabled = False org_config.save() # Check that the org value in cache was deleted on save with self.assertNumQueries(2): self.assertFalse(ContentTypeGatingConfig.current(org=course.org).enabled) global_config = ContentTypeGatingConfig(enabled=True, enabled_as_of=datetime(2018, 1, 1)) global_config.save() # Check that the org value is not updated in cache by changing the global value with self.assertNumQueries(0): self.assertFalse(ContentTypeGatingConfig.current(org=course.org).enabled) site_config = ContentTypeGatingConfig(site=site_cfg.site, enabled=True, enabled_as_of=datetime(2018, 1, 1)) site_config.save() # Check that the org value is not updated in cache by changing the site value with self.assertNumQueries(0): self.assertFalse(ContentTypeGatingConfig.current(org=course.org).enabled)
def setUp(self): super(TestModels, self).setUp() self.course = CourseOverviewFactory.create( start=now() ) self.enrollment = CourseEnrollmentFactory.create(course_id=self.course.id) self.user = UserFactory() self.client.login(username=self.user.username, password=TEST_PASSWORD)
def test_all_current_course_configs(self): # Set up test objects for global_setting in (True, False, None): CourseDurationLimitConfig.objects.create(enabled=global_setting, enabled_as_of=datetime(2018, 1, 1)) for site_setting in (True, False, None): test_site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': []}) CourseDurationLimitConfig.objects.create( site=test_site_cfg.site, enabled=site_setting, enabled_as_of=datetime(2018, 1, 1) ) for org_setting in (True, False, None): test_org = "{}-{}".format(test_site_cfg.id, org_setting) test_site_cfg.values['course_org_filter'].append(test_org) test_site_cfg.save() CourseDurationLimitConfig.objects.create( org=test_org, enabled=org_setting, enabled_as_of=datetime(2018, 1, 1) ) for course_setting in (True, False, None): test_course = CourseOverviewFactory.create( org=test_org, id=CourseLocator(test_org, 'test_course', 'run-{}'.format(course_setting)) ) CourseDurationLimitConfig.objects.create( course=test_course, enabled=course_setting, enabled_as_of=datetime(2018, 1, 1) ) with self.assertNumQueries(4): all_configs = CourseDurationLimitConfig.all_current_course_configs() # Deliberatly using the last all_configs that was checked after the 3rd pass through the global_settings loop # We should be creating 3^4 courses (3 global values * 3 site values * 3 org values * 3 course values) # Plus 1 for the edX/toy/2012_Fall course self.assertEqual(len(all_configs), 3**4 + 1) # Point-test some of the final configurations self.assertEqual( all_configs[CourseLocator('7-True', 'test_course', 'run-None')], { 'enabled': (True, Provenance.org), 'enabled_as_of': (datetime(2018, 1, 1, 5, tzinfo=pytz.UTC), Provenance.run), } ) self.assertEqual( all_configs[CourseLocator('7-True', 'test_course', 'run-False')], { 'enabled': (False, Provenance.run), 'enabled_as_of': (datetime(2018, 1, 1, 5, tzinfo=pytz.UTC), Provenance.run), } ) self.assertEqual( all_configs[CourseLocator('7-None', 'test_course', 'run-None')], { 'enabled': (True, Provenance.site), 'enabled_as_of': (datetime(2018, 1, 1, 5, tzinfo=pytz.UTC), Provenance.run), } )
def test_unfulfilled_entitlement(self, mock_course_overview, mock_pseudo_session, mock_course_runs, mock_get_programs): """ When a learner has an unfulfilled entitlement, their course dashboard should have: - a hidden 'View Course' button - the text 'In order to view the course you must select a session:' - an unhidden course-entitlement-selection-container - a related programs message """ program = ProgramFactory() CourseEntitlementFactory.create(user=self.user, course_uuid=program['courses'][0]['uuid']) mock_get_programs.return_value = [program] course_key = CourseKey.from_string('course-v1:FAKE+FA1-MA1.X+3T2017') mock_course_overview.return_value = CourseOverviewFactory.create(start=self.TOMORROW, id=course_key) mock_course_runs.return_value = [ { 'key': six.text_type(course_key), 'enrollment_end': str(self.TOMORROW), 'pacing_type': 'instructor_paced', 'type': 'verified', 'status': 'published' } ] mock_pseudo_session.return_value = { 'key': six.text_type(course_key), 'type': 'verified' } response = self.client.get(self.path) self.assertIn('class="course-target-link enter-course hidden"', response.content) self.assertIn('You must select a session to access the course.', response.content) self.assertIn('<div class="course-entitlement-selection-container ">', response.content) self.assertIn('Related Programs:', response.content) # If an entitlement has already been redeemed by the user for a course run, do not let the run be selectable enrollment = CourseEnrollmentFactory( user=self.user, course_id=six.text_type(mock_course_overview.return_value.id), mode=CourseMode.VERIFIED ) CourseEntitlementFactory.create( user=self.user, course_uuid=program['courses'][0]['uuid'], enrollment_course_run=enrollment ) mock_course_runs.return_value = [ { 'key': 'course-v1:edX+toy+2012_Fall', 'enrollment_end': str(self.TOMORROW), 'pacing_type': 'instructor_paced', 'type': 'verified', 'status': 'published' } ] response = self.client.get(self.path) # There should be two entitlements on the course page, one prompting for a mandatory session, but no # select option for the courses as there is only the single course run which has already been redeemed self.assertEqual(response.content.count('<li class="course-item">'), 2) self.assertIn('You must select a session to access the course.', response.content) self.assertNotIn('To access the course, select a session.', response.content)
def setUp(self): self.student = UserFactory.create(username='******') self.course = CourseOverviewFactory.create( self_paced=True # Any option to allow the certificate to be viewable for the course ) self.certificate = GeneratedCertificateFactory( user=self.student, mode='verified', course_id=self.course.id, status='downloadable' )
def setUpClass(cls): super(ListViewTestMixin, cls).setUpClass() cls.program_uuid = '00000000-1111-2222-3333-444444444444' cls.curriculum_uuid = 'aaaaaaaa-1111-2222-3333-444444444444' cls.other_curriculum_uuid = 'bbbbbbbb-1111-2222-3333-444444444444' cls.course_id = CourseKey.from_string('course-v1:edX+ToyX+Toy_Course') _ = CourseOverviewFactory.create(id=cls.course_id) cls.password = '******' cls.student = UserFactory.create(username='******', password=cls.password) cls.global_staff = GlobalStaffFactory.create(username='******', password=cls.password)
def setUpClass(cls): cls.course_key = CourseKey.from_string('course-v1:edX+DemoX+Demo_Course') cls.course = CourseOverviewFactory.create(id=cls.course_key) cls.audit_mode = CourseModeFactory.create( course_id=cls.course_key, mode_slug='audit', mode_display_name='Audit', min_price=0, ) cls.verified_mode = CourseModeFactory.create( course_id=cls.course_key, mode_slug='verified', mode_display_name='Verified', min_price=25, ) # use these to make sure we don't fetch data for other courses cls.other_course_key = CourseKey.from_string('course-v1:edX+DemoX+Other_Course') cls.other_course = CourseOverviewFactory.create(id=cls.other_course_key) cls.other_mode = CourseModeFactory.create( course_id=cls.other_course_key, mode_slug='other-audit', mode_display_name='Other Audit', min_price=0, )
def setUpClass(cls): super(CertificatesListRestApiTest, cls).setUpClass() cls.course = CourseFactory.create( org='edx', number='verified', display_name='Verified Course', self_paced=True, ) cls.course_overview = CourseOverviewFactory.create( id=cls.course.id, display_org_with_default='edx', display_name='Verified Course', cert_html_view_enabled=True, self_paced=True, )
def setUp(self): super(CertificatesApiTestCase, self).setUp() self.course = CourseOverviewFactory.create( start=datetime(2017, 1, 1, tzinfo=pytz.UTC), end=datetime(2017, 1, 31, tzinfo=pytz.UTC), certificate_available_date=None ) self.user = UserFactory.create() self.enrollment = CourseEnrollmentFactory( user=self.user, course_id=self.course.id, is_active=True, mode='audit', ) self.certificate = MockGeneratedCertificate( user=self.user, course_id=self.course.id )
def test_get_visible_sessions_for_entitlement(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) course_enrollment = CourseEnrollmentFactory( user=self.user, course_id=unicode(course_overview.id), 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 setUp(self): super(EligibleCertificateManagerTest, self).setUp() self.user = UserFactory() self.course1 = CourseOverviewFactory() self.course2 = CourseOverviewFactory( id=CourseKey.from_string('{}a'.format(self.course1.id)) ) self.eligible_cert = GeneratedCertificateFactory.create( status=CertificateStatuses.downloadable, user=self.user, course_id=self.course1.id ) self.ineligible_cert = GeneratedCertificateFactory.create( status=CertificateStatuses.audit_passing, user=self.user, course_id=self.course2.id )
def test_fulfilled_entitlement(self, mock_course_key, mock_course_overview, mock_course_runs, mock_get_programs): """ When a learner has a fulfilled entitlement, their course dashboard should have: - exactly one course item, meaning it: - has an entitlement card - does NOT have a course card referencing the selected session - an unhidden Change or Leave Session button - a related programs message """ mocked_course_overview = CourseOverviewFactory( start=self.TOMORROW, self_paced=True, enrollment_end=self.TOMORROW) mock_course_overview.return_value = mocked_course_overview mock_course_key.return_value = mocked_course_overview.id course_enrollment = CourseEnrollmentFactory( user=self.user, course_id=unicode(mocked_course_overview.id)) mock_course_runs.return_value = [{ 'key': str(mocked_course_overview.id), 'enrollment_end': str(mocked_course_overview.enrollment_end), 'pacing_type': 'self_paced', 'type': 'verified', 'status': 'published' }] entitlement = CourseEntitlementFactory( user=self.user, enrollment_course_run=course_enrollment) program = ProgramFactory() program['courses'][0]['course_runs'] = [{ 'key': unicode(mocked_course_overview.id) }] program['courses'][0]['uuid'] = entitlement.course_uuid mock_get_programs.return_value = [program] response = self.client.get(self.path) self.assertEqual(response.content.count('<li class="course-item">'), 1) self.assertIn('<button class="change-session btn-link "', response.content) self.assertIn('Related Programs:', response.content)
def test_cert_grade(self, persisted_grade, cert_grade): """ Tests that the higher of the persisted grade and the grade from the certs table is used on the learner dashboard. """ expected_grade = max( filter(lambda x: x is not None, [persisted_grade, cert_grade])) user = UserFactory.create() survey_url = "http://a_survey.com" course = CourseOverviewFactory.create( end_of_course_survey_url=survey_url, certificates_display_behavior='end', ) if cert_grade is not None: cert_status = { 'status': 'generating', 'grade': str(cert_grade), 'mode': 'honor', 'uuid': None } else: cert_status = { 'status': 'generating', 'mode': 'honor', 'uuid': None } with patch( 'lms.djangoapps.grades.course_grade_factory.CourseGradeFactory.read' ) as patch_persisted_grade: patch_persisted_grade.return_value = Mock(percent=persisted_grade) self.assertEqual( _cert_info(user, course, cert_status), { 'status': 'generating', 'show_survey_button': True, 'survey_url': survey_url, 'grade': str(expected_grade), 'mode': 'honor', 'linked_in_url': None, 'can_unenroll': False, })
def setUp(self): super(AwardCourseCertificatesTestCase, self).setUp() self.course = CourseOverviewFactory.create( self_paced=True # Any option to allow the certificate to be viewable for the course ) self.student = UserFactory.create(username='******') # Instantiate the Certificate first so that the config doesn't execute issuance self.certificate = GeneratedCertificateFactory.create( user=self.student, mode='verified', course_id=self.course.id, status='downloadable' ) self.create_credentials_config() self.site = SiteFactory() ClientFactory.create(name='credentials') UserFactory.create(username=settings.CREDENTIALS_SERVICE_USERNAME)
def test_unfulfilled_expired_entitlement(self, mock_course_overview, mock_course_runs): """ When a learner has an unfulfilled, expired entitlement, a card should NOT appear on the dashboard. This use case represents either an entitlement that the user waited too long to fulfill, or an entitlement for which they received a refund. """ CourseEntitlementFactory(user=self.user, created=self.THREE_YEARS_AGO, expired_at=datetime.datetime.now()) mock_course_overview.return_value = CourseOverviewFactory( start=self.TOMORROW) mock_course_runs.return_value = [{ 'key': 'course-v1:FAKE+FA1-MA1.X+3T2017', 'enrollment_end': str(self.TOMORROW), 'pacing_type': 'instructor_paced', 'type': 'verified' }] response = self.client.get(self.path) self.assertEqual(response.content.count('<li class="course-item">'), 0)
def test_unpublished_sessions_for_entitlement(self, mock_get_edx_api_data): """ Test unpublished course runs are not part of visible session entitlements when the user is not enrolled. """ catalog_course_run = CourseRunFactory.create(status=COURSE_UNPUBLISHED) 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) entitlement = CourseEntitlementFactory(user=self.user, mode=CourseMode.VERIFIED) session_entitlements = get_visible_sessions_for_entitlement( entitlement) self.assertEqual(session_entitlements, [])
def setUp(self): super().setUp() freezer = freeze_time(datetime(2013, 10, 3, 8, 24, 55, tzinfo=pytz.utc)) self.addCleanup(freezer.stop) freezer.start() self.course = CourseOverviewFactory() self.user = UserFactory() self.request = RequestFactory().request() self.request.site = SiteFactory() self.request.user = self.user self.site_config = SiteConfigurationFactory.create( site_values={'course_org_filter': self.course.org} ) self.user_calendar_sync_config = UserCalendarSyncConfigFactory.create( user=self.user, course_key=self.course.id, )
def test_caching_course(self): course = CourseOverviewFactory.create(org='test-org') site_cfg = SiteConfigurationFactory.create(values={'course_org_filter': course.org}) course_config = ContentTypeGatingConfig(course=course, enabled=True, enabled_as_of=date(2018, 1, 1)) course_config.save() # Check that the org value is not retrieved from cache after save with self.assertNumQueries(2): self.assertTrue(ContentTypeGatingConfig.current(course_key=course.id).enabled) # Check that the org value can be retrieved from cache after read with self.assertNumQueries(0): self.assertTrue(ContentTypeGatingConfig.current(course_key=course.id).enabled) course_config.enabled = False course_config.save() # Check that the org value in cache was deleted on save with self.assertNumQueries(2): self.assertFalse(ContentTypeGatingConfig.current(course_key=course.id).enabled) global_config = ContentTypeGatingConfig(enabled=True, enabled_as_of=date(2018, 1, 1)) global_config.save() # Check that the org value is not updated in cache by changing the global value with self.assertNumQueries(0): self.assertFalse(ContentTypeGatingConfig.current(course_key=course.id).enabled) site_config = ContentTypeGatingConfig(site=site_cfg.site, enabled=True, enabled_as_of=date(2018, 1, 1)) site_config.save() # Check that the org value is not updated in cache by changing the site value with self.assertNumQueries(0): self.assertFalse(ContentTypeGatingConfig.current(course_key=course.id).enabled) org_config = ContentTypeGatingConfig(org=course.org, enabled=True, enabled_as_of=date(2018, 1, 1)) org_config.save() # Check that the org value is not updated in cache by changing the site value with self.assertNumQueries(0): self.assertFalse(ContentTypeGatingConfig.current(course_key=course.id).enabled)
def test_email_settings_fulfilled_entitlement(self, mock_email_feature, mock_get_course_runs): """ Assert that the Email Settings action is shown when the user has a fulfilled entitlement. """ mock_email_feature.return_value = True course_overview = CourseOverviewFactory(start=self.TOMORROW, self_paced=True, enrollment_end=self.TOMORROW) course_enrollment = CourseEnrollmentFactory(user=self.user) entitlement = CourseEntitlementFactory( user=self.user, enrollment_course_run=course_enrollment) course_runs = [{ 'key': unicode(course_overview.id), 'uuid': entitlement.course_uuid }] mock_get_course_runs.return_value = course_runs response = self.client.get(self.path) self.assertEqual( pq(response.content)(self.EMAIL_SETTINGS_ELEMENT_ID).length, 1)
def setUp(self): super(AwardCourseCertificatesTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.available_date = datetime.now(pytz.UTC) + timedelta(days=1) self.course = CourseOverviewFactory.create( self_paced= True, # Any option to allow the certificate to be viewable for the course certificate_available_date=self.available_date, ) self.student = UserFactory.create(username='******') # Instantiate the Certificate first so that the config doesn't execute issuance self.certificate = GeneratedCertificateFactory.create( user=self.student, mode='verified', course_id=self.course.id, status='downloadable') self.create_credentials_config() self.site = SiteFactory() ApplicationFactory.create(name='credentials') UserFactory.create(username=settings.CREDENTIALS_SERVICE_USERNAME)
def test_fulfilled_expired_entitlement(self, mock_course_overview, mock_course_runs, mock_get_programs): """ When a learner has a fulfilled entitlement that is expired, their course dashboard should have: - exactly one course item, meaning it: - has an entitlement card - Message that the learner can no longer change sessions - a related programs message """ mocked_course_overview = CourseOverviewFactory(start=TOMORROW, self_paced=True, enrollment_end=TOMORROW) mock_course_overview.return_value = mocked_course_overview course_enrollment = CourseEnrollmentFactory(user=self.user, course_id=str(mocked_course_overview.id), created=THREE_YEARS_AGO) # lint-amnesty, pylint: disable=line-too-long mock_course_runs.return_value = [{ 'key': str(mocked_course_overview.id), 'enrollment_end': str(mocked_course_overview.enrollment_end), 'pacing_type': 'self_paced', 'type': 'verified', 'status': 'published' }] entitlement = CourseEntitlementFactory(user=self.user, enrollment_course_run=course_enrollment, created=THREE_YEARS_AGO) # lint-amnesty, pylint: disable=line-too-long program = ProgramFactory() program['courses'][0]['course_runs'] = [{ 'key': str(mocked_course_overview.id) }] program['courses'][0]['uuid'] = entitlement.course_uuid mock_get_programs.return_value = [program] response = self.client.get(self.path) self.assertContains(response, '<li class="course-item">', count=1) self.assertContains(response, 'You can no longer change sessions.') self.assertContains(response, 'Related Programs:')
def setUpClass(cls): """ Set up test data """ super().setUpClass() catalog_org = CatalogOrganizationFactory.create( key=cls.organization_key) cls.program = ProgramFactory.create( uuid=cls.program_uuid, authoring_organizations=[catalog_org]) organization = OrganizationFactory.create( short_name=cls.organization_key) SAMLProviderConfigFactory.create(organization=organization) catalog_course_id_str = 'course-v1:edX+ToyX' course_run_id_str = f'{catalog_course_id_str}+Toy_Course' cls.course_id = CourseKey.from_string(course_run_id_str) CourseOverviewFactory(id=cls.course_id) course_run = CourseRunFactory(key=course_run_id_str) cls.course = CourseFactory(key=catalog_course_id_str, course_runs=[course_run]) cls.student_1 = UserFactory(username='******') cls.student_2 = UserFactory(username='******')
def _create_test_course_with_default_grading_policy( cls, display_name, run): """ Utility method to create a course with a default grading policy """ course = CourseFactory.create(display_name=display_name, run=run) _ = CourseOverviewFactory.create(id=course.id) chapter = ItemFactory.create( category='chapter', parent_location=course.location, display_name="Chapter 1", ) # create a problem for each type and minimum count needed by the grading policy # A section is not considered if the student answers less than "min_count" problems for grading_type, min_count in (("Homework", 12), ("Lab", 12), ("Midterm Exam", 1), ("Final Exam", 1)): for num in xrange(min_count): section = ItemFactory.create( category='sequential', parent_location=chapter.location, due=datetime(2017, 12, 18, 11, 30, 00), display_name='Sequential {} {}'.format(grading_type, num), format=grading_type, graded=True, ) vertical = ItemFactory.create( category='vertical', parent_location=section.location, display_name='Vertical {} {}'.format(grading_type, num), ) ItemFactory.create( category='problem', parent_location=vertical.location, display_name='Problem {} {}'.format(grading_type, num), ) return course
def test_unfulfilled_expired_entitlement(self, mock_course_overview, mock_course_runs): """ When a learner has an unfulfilled, expired entitlement, their course dashboard should have: - a hidden 'View Course' button - a message saying that they can no longer select a session """ CourseEntitlementFactory(user=self.user, created=self.THREE_YEARS_AGO) mock_course_overview.return_value = CourseOverviewFactory( start=self.TOMORROW) mock_course_runs.return_value = [{ 'key': 'course-v1:FAKE+FA1-MA1.X+3T2017', 'enrollment_end': self.TOMORROW, 'pacing_type': 'instructor_paced', 'type': 'verified' }] response = self.client.get(self.path) self.assertIn('class="enter-course hidden"', response.content) self.assertIn('You can no longer select a session', response.content) self.assertNotIn( '<div class="course-entitlement-selection-container ">', response.content)
def test_get_extra_course_about_context( mock_get_lang_names, mock_get_pre_requisite_courses_not_completed, mock_testing_env, request): """ Test if the context is being returned correctly by the get_extra_course_about_context function """ user = UserFactory() request.user = user course = CourseOverviewFactory(self_paced=True, effort=EFFORT, language='en') CourseEnrollmentFactory(user=user, course=course) MultilingualCourseFactory(course=course) course_languages_with_ids = [(course.id, 'English')] mock_get_lang_names.return_value = course_languages_with_ids mock_get_pre_requisite_courses_not_completed.return_value = None mock_testing_env.return_value = False enroll_popup_message = ( f'Warning: If you wish to change the language of this course, your progress in the following ' f'course(s) will be erased.<br>{course.display_name_with_default}') expected_context = { 'course_languages': course_languages_with_ids, 'course_requirements': None, 'total_enrollments': 1, 'self_paced': True, 'effort': EFFORT, 'is_course_passed': False, 'has_certificate': None, 'has_user_enrolled_in_course_group_courses': True, 'has_generated_cert_for_any_course_group_course': False, 'enroll_popup_message': enroll_popup_message, 'cannot_enroll_message': '' } assert get_extra_course_about_context(request, course) == expected_context
def test_get_course_info_for_application_review(courses, user_with_profile): """ Tests that `get_course_info_for_application_review` returns expected data for application review. """ course1 = courses['test_course1'] course2 = courses['test_course2'] course3 = CourseOverviewFactory() CourseEnrollmentFactory(user=user_with_profile, course=course2) PersistentCourseGradeFactory( user_id=user_with_profile.id, course_id=course2.id, percent_grade=1.0, letter_grade='A' ) CourseEnrollmentFactory(user=user_with_profile, course=course3) actual_courses_info = get_course_info_for_application_review([course1, course2, course3], user_with_profile) expected_courses_info = { course1.display_name: NOT_STARTED, course2.display_name: '100%', course3.display_name: IN_PROGRESS, } assert actual_courses_info == expected_courses_info
def setUp(self): super().setUp() self.available_date = datetime.now(pytz.UTC) + timedelta(days=1) self.course = CourseOverviewFactory.create( self_paced=True, # Any option to allow the certificate to be viewable for the course certificate_available_date=self.available_date, certificates_display_behavior=CertificatesDisplayBehaviors.END_WITH_DATE ) self.student = UserFactory.create(username='******') # Instantiate the Certificate first so that the config doesn't execute issuance self.certificate = GeneratedCertificateFactory.create( user=self.student, mode='verified', course_id=self.course.id, status='downloadable' ) self.create_credentials_config() self.site = SiteFactory() ApplicationFactory.create(name='credentials') UserFactory.create(username=settings.CREDENTIALS_SERVICE_USERNAME)
def test_grade_appears_before_course_end_date(self): """ Verify that learners are not able to see their final grade before the end of course in the learner dashboard """ self.course_key = CourseKey.from_string( 'course-v1:edX+DemoX+Demo_Course') # lint-amnesty, pylint: disable=attribute-defined-outside-init self.course = CourseOverviewFactory.create( id=self.course_key, end_date=self.TOMORROW, # lint-amnesty, pylint: disable=attribute-defined-outside-init certificate_available_date=self.THREE_YEARS_AGO, lowest_passing_grade=0.3) self.course_enrollment = CourseEnrollmentFactory( course_id=self.course.id, user=self.user) # lint-amnesty, pylint: disable=attribute-defined-outside-init GeneratedCertificateFactory(status='notpassing', course_id=self.course.id, user=self.user, grade=0.45) response = self.client.get(reverse('dashboard')) # The final grade does not appear before the course has ended self.assertContains(response, 'Your final grade:') self.assertContains(response, '<span class="grade-value">45%</span>')
def test_grade_not_appears_before_cert_available_date(self): """ Verify that learners are able to see their final grade of the course in the learner dashboard after the course had ended """ self.course_key = CourseKey.from_string( 'course-v1:edX+DemoX+Demo_Course') self.course = CourseOverviewFactory.create( id=self.course_key, end_date=self.THREE_YEARS_AGO, certificate_available_date=self.TOMORROW, lowest_passing_grade=0.3) self.course_enrollment = CourseEnrollmentFactory( course_id=self.course.id, user=self.user) GeneratedCertificateFactory(status='notpassing', course_id=self.course.id, user=self.user, grade=0.45) response = self.client.get(reverse('dashboard')) self.assertNotContains(response, 'Your final grade:') self.assertNotContains(response, '<span class="grade-value">45%</span>')
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)
def test_unfulfilled_entitlement(self, mock_course_overview, mock_course_runs): """ When a learner has an unfulfilled entitlement, their course dashboard should have: - a hidden 'View Course' button - the text 'In order to view the course you must select a session:' - an unhidden course-entitlement-selection-container """ CourseEntitlementFactory(user=self.user) mock_course_overview.return_value = CourseOverviewFactory( start=self.TOMORROW) mock_course_runs.return_value = [{ 'key': 'course-v1:FAKE+FA1-MA1.X+3T2017', 'enrollment_end': self.TOMORROW, 'pacing_type': 'instructor_paced', 'type': 'verified' }] response = self.client.get(self.path) self.assertIn('class="enter-course hidden"', response.content) self.assertIn('You must select a session to access the course.', response.content) self.assertIn('<div class="course-entitlement-selection-container ">', response.content)
def test_cert_grade_no_grades(self): """ Tests that the default cert info is returned when the learner has no persisted grade or grade in the certs table. """ user = UserFactory.create() survey_url = "http://a_survey.com" course = CourseOverviewFactory.create( end_of_course_survey_url=survey_url, certificates_display_behavior='end', ) cert_status = {'status': 'generating', 'mode': 'honor', 'uuid': None} with patch( 'lms.djangoapps.grades.course_grade_factory.CourseGradeFactory.read' ) as patch_persisted_grade: patch_persisted_grade.return_value = None assert _cert_info(user, course, cert_status) == { 'status': 'processing', 'show_survey_button': False, 'can_unenroll': True }
def setUp(self): """ Add courses with the end date set to various values """ super().setUp() # Base course has no end date (so is active) self.course.end = None self.course.display_name = 'Active Course 1' self.ORG = self.course.location.org self.save_course() CourseOverviewFactory.create(id=self.course.id, org=self.ORG) # Active course has end date set to tomorrow self.active_course = CourseFactory.create( display_name='Active Course 2', org=self.ORG, end=self.TOMORROW, ) CourseOverviewFactory.create( id=self.active_course.id, org=self.ORG, end=self.TOMORROW, ) # Archived course has end date set to yesterday self.archived_course = CourseFactory.create( display_name='Archived Course', org=self.ORG, end=self.YESTERDAY, ) CourseOverviewFactory.create( id=self.archived_course.id, org=self.ORG, end=self.YESTERDAY, ) # Base user has global staff access self.assertTrue(GlobalStaff().has_user(self.user)) # Staff user just has course staff access self.staff, self.staff_password = self.create_non_staff_user() for course in (self.course, self.active_course, self.archived_course): CourseStaffRole(course.id).add_users(self.staff)
def test_get_visible_sessions_for_entitlement(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) 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_all_current_course_configs(self): # Set up test objects for global_setting in (True, False, None): ContentTypeGatingConfig.objects.create(enabled=global_setting, enabled_as_of=datetime(2018, 1, 1)) for site_setting in (True, False, None): test_site_cfg = SiteConfigurationFactory.create( site_values={'course_org_filter': []} ) ContentTypeGatingConfig.objects.create(site=test_site_cfg.site, enabled=site_setting, enabled_as_of=datetime(2018, 1, 1)) for org_setting in (True, False, None): test_org = "{}-{}".format(test_site_cfg.id, org_setting) test_site_cfg.site_values['course_org_filter'].append(test_org) test_site_cfg.save() ContentTypeGatingConfig.objects.create(org=test_org, enabled=org_setting, enabled_as_of=datetime(2018, 1, 1)) for course_setting in (True, False, None): test_course = CourseOverviewFactory.create( org=test_org, id=CourseLocator(test_org, 'test_course', 'run-{}'.format(course_setting)) ) ContentTypeGatingConfig.objects.create(course=test_course, enabled=course_setting, enabled_as_of=datetime(2018, 1, 1)) with self.assertNumQueries(4): all_configs = ContentTypeGatingConfig.all_current_course_configs() # Deliberatly using the last all_configs that was checked after the 3rd pass through the global_settings loop # We should be creating 3^4 courses (3 global values * 3 site values * 3 org values * 3 course values) # Plus 1 for the edX/toy/2012_Fall course assert len(all_configs) == ((3 ** 4) + 1) # Point-test some of the final configurations assert all_configs[CourseLocator('7-True', 'test_course', 'run-None')] == {'enabled': (True, Provenance.org), 'enabled_as_of': (datetime(2018, 1, 1, 0, tzinfo=pytz.UTC), Provenance.run), 'studio_override_enabled': (None, Provenance.default)} assert all_configs[CourseLocator('7-True', 'test_course', 'run-False')] == {'enabled': (False, Provenance.run), 'enabled_as_of': (datetime(2018, 1, 1, 0, tzinfo=pytz.UTC), Provenance.run), 'studio_override_enabled': (None, Provenance.default)} assert all_configs[CourseLocator('7-None', 'test_course', 'run-None')] == {'enabled': (True, Provenance.site), 'enabled_as_of': (datetime(2018, 1, 1, 0, tzinfo=pytz.UTC), Provenance.run), 'studio_override_enabled': (None, Provenance.default)}
def _create_test_course_with_default_grading_policy(cls, display_name, run): """ Utility method to create a course with a default grading policy """ course = CourseFactory.create(display_name=display_name, run=run) _ = CourseOverviewFactory.create(id=course.id) chapter = ItemFactory.create( category='chapter', parent_location=course.location, display_name="Chapter 1", ) # create a problem for each type and minimum count needed by the grading policy # A section is not considered if the student answers less than "min_count" problems for grading_type, min_count in (("Homework", 12), ("Lab", 12), ("Midterm Exam", 1), ("Final Exam", 1)): for num in xrange(min_count): section = ItemFactory.create( category='sequential', parent_location=chapter.location, due=datetime(2017, 12, 18, 11, 30, 00), display_name=u'Sequential {} {}'.format(grading_type, num), format=grading_type, graded=True, ) vertical = ItemFactory.create( category='vertical', parent_location=section.location, display_name=u'Vertical {} {}'.format(grading_type, num), ) ItemFactory.create( category='problem', parent_location=vertical.location, display_name=u'Problem {} {}'.format(grading_type, num), ) return course
def test_sessions_for_entitlement_course_runs(self, mock_course_overview, mock_course_runs): """ When a learner has a fulfilled entitlement for a course run in the past, there should be no availableSession data passed to the JS view. When a learner has a fulfilled entitlement for a course run enrollment ending in the future, there should not be an empty availableSession variable. When a learner has a fulfilled entitlement for a course that doesn't have an enrollment ending, there should not be an empty availableSession variable. NOTE: We commented out the assertions to move this to the catalog utils test suite. """ # noAvailableSessions = "availableSessions: '[]'" # Test an enrollment end in the past mocked_course_overview = CourseOverviewFactory.create( start=self.TOMORROW, end=self.THREE_YEARS_FROM_NOW, self_paced=True, enrollment_end=self.THREE_YEARS_AGO ) mock_course_overview.return_value = mocked_course_overview course_enrollment = CourseEnrollmentFactory(user=self.user, course_id=six.text_type(mocked_course_overview.id)) mock_course_runs.return_value = [ { 'key': str(mocked_course_overview.id), 'enrollment_end': str(mocked_course_overview.enrollment_end), 'pacing_type': 'self_paced', 'type': 'verified', 'status': 'published' } ] CourseEntitlementFactory(user=self.user, enrollment_course_run=course_enrollment) # response = self.client.get(self.path) # self.assertIn(noAvailableSessions, response.content) # Test an enrollment end in the future sets an availableSession mocked_course_overview.enrollment_end = self.TOMORROW mocked_course_overview.save() mock_course_overview.return_value = mocked_course_overview mock_course_runs.return_value = [ { 'key': str(mocked_course_overview.id), 'enrollment_end': str(mocked_course_overview.enrollment_end), 'pacing_type': 'self_paced', 'type': 'verified', 'status': 'published' } ] # response = self.client.get(self.path) # self.assertNotIn(noAvailableSessions, response.content) # Test an enrollment end that doesn't exist sets an availableSession mocked_course_overview.enrollment_end = None mocked_course_overview.save() mock_course_overview.return_value = mocked_course_overview mock_course_runs.return_value = [ { 'key': str(mocked_course_overview.id), 'enrollment_end': None, 'pacing_type': 'self_paced', 'type': 'verified', 'status': 'published' } ]
def test_config_overrides(self, global_setting, site_setting, org_setting, course_setting): """ Test that the stacked configuration overrides happen in the correct order and priority. This is tested by exhaustively setting each combination of contexts, and validating that only the lowest level context that is set to not-None is applied. """ # Add a bunch of configuration outside the contexts that are being tested, to make sure # there are no leaks of configuration across contexts non_test_course_enabled = CourseOverviewFactory.create( org='non-test-org-enabled') non_test_course_disabled = CourseOverviewFactory.create( org='non-test-org-disabled') non_test_site_cfg_enabled = SiteConfigurationFactory.create( site_values={'course_org_filter': non_test_course_enabled.org}) non_test_site_cfg_disabled = SiteConfigurationFactory.create( site_values={'course_org_filter': non_test_course_disabled.org}) ContentTypeGatingConfig.objects.create(course=non_test_course_enabled, enabled=True, enabled_as_of=datetime( 2018, 1, 1)) ContentTypeGatingConfig.objects.create(course=non_test_course_disabled, enabled=False) ContentTypeGatingConfig.objects.create(org=non_test_course_enabled.org, enabled=True, enabled_as_of=datetime( 2018, 1, 1)) ContentTypeGatingConfig.objects.create( org=non_test_course_disabled.org, enabled=False) ContentTypeGatingConfig.objects.create( site=non_test_site_cfg_enabled.site, enabled=True, enabled_as_of=datetime(2018, 1, 1)) ContentTypeGatingConfig.objects.create( site=non_test_site_cfg_disabled.site, enabled=False) # Set up test objects test_course = CourseOverviewFactory.create(org='test-org') test_site_cfg = SiteConfigurationFactory.create( site_values={'course_org_filter': test_course.org}) ContentTypeGatingConfig.objects.create(enabled=global_setting, enabled_as_of=datetime( 2018, 1, 1)) ContentTypeGatingConfig.objects.create(course=test_course, enabled=course_setting, enabled_as_of=datetime( 2018, 1, 1)) ContentTypeGatingConfig.objects.create(org=test_course.org, enabled=org_setting, enabled_as_of=datetime( 2018, 1, 1)) ContentTypeGatingConfig.objects.create(site=test_site_cfg.site, enabled=site_setting, enabled_as_of=datetime( 2018, 1, 1)) all_settings = [ global_setting, site_setting, org_setting, course_setting ] expected_global_setting = self._resolve_settings([global_setting]) expected_site_setting = self._resolve_settings( [global_setting, site_setting]) expected_org_setting = self._resolve_settings( [global_setting, site_setting, org_setting]) expected_course_setting = self._resolve_settings( [global_setting, site_setting, org_setting, course_setting]) assert expected_global_setting == ContentTypeGatingConfig.current( ).enabled assert expected_site_setting == ContentTypeGatingConfig.current( site=test_site_cfg.site).enabled assert expected_org_setting == ContentTypeGatingConfig.current( org=test_course.org).enabled assert expected_course_setting == ContentTypeGatingConfig.current( course_key=test_course.id).enabled
def test_caching_course(self): course = CourseOverviewFactory.create(org='test-org') site_cfg = SiteConfigurationFactory.create( site_values={'course_org_filter': course.org}) course_config = CourseDurationLimitConfig(course=course, enabled=True, enabled_as_of=datetime(2018, 1, 1, tzinfo=pytz.UTC)) # lint-amnesty, pylint: disable=line-too-long course_config.save() RequestCache.clear_all_namespaces() # Check that the org value is not retrieved from cache after save with self.assertNumQueries(2): assert CourseDurationLimitConfig.current( course_key=course.id).enabled RequestCache.clear_all_namespaces() # Check that the org value can be retrieved from cache after read with self.assertNumQueries(0): assert CourseDurationLimitConfig.current( course_key=course.id).enabled course_config.enabled = False course_config.save() RequestCache.clear_all_namespaces() # Check that the org value in cache was deleted on save with self.assertNumQueries(2): assert not CourseDurationLimitConfig.current( course_key=course.id).enabled global_config = CourseDurationLimitConfig(enabled=True, enabled_as_of=datetime( 2018, 1, 1, tzinfo=pytz.UTC)) global_config.save() RequestCache.clear_all_namespaces() # Check that the org value is not updated in cache by changing the global value with self.assertNumQueries(0): assert not CourseDurationLimitConfig.current( course_key=course.id).enabled site_config = CourseDurationLimitConfig(site=site_cfg.site, enabled=True, enabled_as_of=datetime(2018, 1, 1, tzinfo=pytz.UTC)) # lint-amnesty, pylint: disable=line-too-long site_config.save() RequestCache.clear_all_namespaces() # Check that the org value is not updated in cache by changing the site value with self.assertNumQueries(0): assert not CourseDurationLimitConfig.current( course_key=course.id).enabled org_config = CourseDurationLimitConfig(org=course.org, enabled=True, enabled_as_of=datetime(2018, 1, 1, tzinfo=pytz.UTC)) # lint-amnesty, pylint: disable=line-too-long org_config.save() RequestCache.clear_all_namespaces() # Check that the org value is not updated in cache by changing the site value with self.assertNumQueries(0): assert not CourseDurationLimitConfig.current( course_key=course.id).enabled
def test_query_counts(self): # Test student with no certificates student_no_cert = UserFactory.create(password=self.user_password) with self.assertNumQueries(22): resp = self.get_response( AuthType.jwt, requesting_user=student_no_cert, requested_user=student_no_cert, ) self.assertEqual(resp.status_code, status.HTTP_200_OK) self.assertEqual(len(resp.data), 0) # Test student with 1 certificate with self.assertNumQueries(17): resp = self.get_response( AuthType.jwt, requesting_user=self.student, requested_user=self.student, ) self.assertEqual(resp.status_code, status.HTTP_200_OK) self.assertEqual(len(resp.data), 1) # Test student with 2 certificates student_2_certs = UserFactory.create(password=self.user_password) course = CourseFactory.create( org='edx', number='test', display_name='Test Course', self_paced=True, ) CourseOverviewFactory.create( id=course.id, display_org_with_default='edx', display_name='Test Course', cert_html_view_enabled=True, self_paced=True, ) GeneratedCertificateFactory.create( user=student_2_certs, course_id=self.course.id, status=CertificateStatuses.downloadable, mode='verified', download_url='www.google.com', grade="0.88", ) GeneratedCertificateFactory.create( user=student_2_certs, course_id=course.id, status=CertificateStatuses.downloadable, mode='verified', download_url='www.google.com', grade="0.88", ) with self.assertNumQueries(17): resp = self.get_response( AuthType.jwt, requesting_user=student_2_certs, requested_user=student_2_certs, ) self.assertEqual(resp.status_code, status.HTTP_200_OK) self.assertEqual(len(resp.data), 2)
def setUpClass(cls): super(GradebookViewTestBase, cls).setUpClass() cls.namespaced_url = 'grades_api:v1:course_gradebook' cls.waffle_flag = waffle_flags()[WRITABLE_GRADEBOOK] cls.course = CourseFactory.create(display_name='test-course', run='run-1') cls.course_key = cls.course.id cls.course_overview = CourseOverviewFactory.create(id=cls.course.id) cls.chapter_1 = ItemFactory.create( category='chapter', parent_location=cls.course.location, display_name="Chapter 1", ) cls.chapter_2 = ItemFactory.create( category='chapter', parent_location=cls.course.location, display_name="Chapter 2", ) cls.subsections = { cls.chapter_1.location: [ ItemFactory.create( category='sequential', parent_location=cls.chapter_1.location, due=datetime(2017, 12, 18, 11, 30, 00), display_name='HW 1', format='Homework', graded=True, ), ItemFactory.create( category='sequential', parent_location=cls.chapter_1.location, due=datetime(2017, 12, 18, 11, 30, 00), display_name='Lab 1', format='Lab', graded=True, ), ], cls.chapter_2.location: [ ItemFactory.create( category='sequential', parent_location=cls.chapter_2.location, due=datetime(2017, 12, 18, 11, 30, 00), display_name='HW 2', format='Homework', graded=True, ), ItemFactory.create( category='sequential', parent_location=cls.chapter_2.location, due=datetime(2017, 12, 18, 11, 30, 00), display_name='Lab 2', format='Lab', graded=True, ), ], } cls.course_data = CourseData(None, course=cls.course) # we have to force the collection of course data from the block_structure API # so that CourseGrade.course_data objects can later have a non-null effective_structure _ = cls.course_data.collected_structure
def setUp(self): self.course_overview = CourseOverviewFactory.create() self.user = UserFactory.create() super(TestContentTypeGatingConfig, self).setUp()
def setUp(self): super().setUp() for _ in range(3): CourseOverviewFactory.create()
def setUp(self): super(TestModels, self).setUp() self.course = CourseOverviewFactory.create(start=datetime.utcnow()) self.enrollment = CourseEnrollmentFactory.create( course_id=self.course.id)
def setUp(self): super(FeatureEnabledTestCase, self).setUp() self.course = CourseOverviewFactory.create()
def setUp(self): self.course_overview = CourseOverviewFactory.create() self.user = UserFactory.create() super(TestCourseDurationLimitConfig, self).setUp()
def setUp(self): super(TestCourseOverviewSerializer, self).setUp() CourseOverviewFactory.create()
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()