class FilenamePrefixGeneratorTestCase(TestCase): """ Tests for course_filename_prefix_generator """ @ddt.data(CourseLocator(org='foo', course='bar', run='baz'), CourseKey.from_string('foo/bar/baz')) def test_locators(self, course_key): self.assertEqual(course_filename_prefix_generator(course_key), u'foo_bar_baz') @ddt.data(CourseLocator(org='foo', course='bar', run='baz'), CourseKey.from_string('foo/bar/baz')) def test_custom_separator(self, course_key): self.assertEqual(course_filename_prefix_generator(course_key, separator='-'), u'foo-bar-baz')
def test_kwargs_in_update_state(self): destination_course_key = CourseLocator("org", "course", "run") source_course_key = CourseLocator("source_org", "source_course", "source_run") CourseRerunState.objects.update_state( course_key=destination_course_key, new_state='state1', allow_not_found=True, source_course_key=source_course_key, ) found_action_state = CourseRerunState.objects.find_first(course_key=destination_course_key) self.assertEquals(source_course_key, found_action_state.source_course_key)
def test_course_listing_errored_deleted_courses(self): """ Create good courses, courses that won't load, and deleted courses which still have roles. Test course listing. """ course_location = CourseLocator('testOrg', 'testCourse', 'RunBabyRun') self._create_course_with_access_groups(course_location, self.user) course_location = CourseLocator('doomedCourse', 'testCourse', 'RunBabyRun') course = self._create_course_with_access_groups( course_location, self.user) course.delete() courses_list, __ = _accessible_courses_list_from_groups(self.request) self.assertEqual(len(courses_list), 1, courses_list)
def setUp(self): super(TestCourseRerunStateManager, self).setUp() self.source_course_key = CourseLocator("source_org", "source_course_num", "source_run") self.course_key = CourseLocator("test_org", "test_course_num", "test_run") self.created_user = UserFactory() self.display_name = "destination course name" self.expected_rerun_state = { 'created_user': self.created_user, 'updated_user': self.created_user, 'course_key': self.course_key, 'source_course_key': self.source_course_key, "display_name": self.display_name, 'action': CourseRerunUIStateManager.ACTION, 'should_display': True, 'message': "", }
class FilenameGeneratorTestCase(TestCase): """ Tests for course_and_time_based_filename_generator """ NOW = datetime.strptime('1974-06-22T01:02:03', '%Y-%m-%dT%H:%M:%S').replace(tzinfo=UTC) def setUp(self): super(FilenameGeneratorTestCase, self).setUp() datetime_patcher = patch.object(util.file, 'datetime', Mock(wraps=datetime)) mocked_datetime = datetime_patcher.start() mocked_datetime.now.return_value = self.NOW self.addCleanup(datetime_patcher.stop) @ddt.data(CourseLocator(org='foo', course='bar', run='baz'), CourseKey.from_string('foo/bar/baz')) def test_filename_generator(self, course_key): """ Tests that the generator creates names based on course_id, base name, and date. """ self.assertEqual( u'foo_bar_baz_file_1974-06-22-010203', course_and_time_based_filename_generator(course_key, 'file')) self.assertEqual( u'foo_bar_baz_base_name_ø_1974-06-22-010203', course_and_time_based_filename_generator(course_key, ' base` name ø '))
def setUp(self): super(TestStatus, self).setUp() # Clear the cache between test runs. cache.clear() self.course_key = CourseLocator(org='TestOrg', course='TestCourse', run='TestRun')
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 = Mock(username="******", id="1") survey_url = "http://a_survey.com" course = Mock( end_of_course_survey_url=survey_url, certificates_display_behavior='end', id=CourseLocator(org="x", course="y", run="z"), ) if cert_grade is not None: cert_status = {'status': 'generating', 'grade': six.text_type(cert_grade), 'mode': 'honor'} else: cert_status = {'status': 'generating', 'mode': 'honor'} 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': six.text_type(expected_grade), 'mode': 'honor', 'linked_in_url': None, 'can_unenroll': False, } )
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 = Mock(username="******", id="1") survey_url = "http://a_survey.com" course = Mock( end_of_course_survey_url=survey_url, certificates_display_behavior='end', id=CourseLocator(org="x", course="y", run="z"), ) cert_status = {'status': 'generating', 'mode': 'honor'} with patch('lms.djangoapps.grades.course_grade_factory.CourseGradeFactory.read') as patch_persisted_grade: patch_persisted_grade.return_value = None self.assertEqual( _cert_info(user, course, cert_status), { 'status': 'processing', 'show_survey_button': False, 'can_unenroll': True, } )
def setUp(self): super(TestStatus, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments # Clear the cache between test runs. cache.clear() self.course_key = CourseLocator(org='TestOrg', course='TestCourse', run='TestRun')
def create_course_states(starting_course_num, ending_course_num, state, should_display=True): """ Creates a list of course state tuples by creating unique course locators with course-numbers from starting_course_num to ending_course_num. """ CourseState = namedtuple('CourseState', 'course_key, state, should_display') return [ CourseState(CourseLocator("org", "course", "run" + str(num)), state, should_display) for num in range(starting_course_num, ending_course_num) ]
def setUp(self): super().setUp() self.block = BlockMock(name='block', scope_ids=ScopeIds(None, None, None, 'dummy')) self.course_key = CourseLocator("org", "course", "run") self.runtime = LmsModuleSystem( static_url='/static', track_function=Mock(), get_module=Mock(), course_id=self.course_key, user=Mock(), descriptor_runtime=Mock(), )
def test_change_enrollment_modes(self): user = User.objects.create(username="******", email="*****@*****.**") course_id = CourseLocator("edX", "Test101", "2013") CourseEnrollment.enroll(user, course_id, "audit") self.assert_enrollment_event_was_emitted(user, course_id) CourseEnrollment.enroll(user, course_id, "honor") self.assert_enrollment_mode_change_event_was_emitted(user, course_id, "honor") # same enrollment mode does not emit an event CourseEnrollment.enroll(user, course_id, "honor") self.assert_no_events_were_emitted() CourseEnrollment.enroll(user, course_id, "audit") self.assert_enrollment_mode_change_event_was_emitted(user, course_id, "audit")
def setUp(self): super().setUp() self.course_id = CourseLocator("org", "course", "run") self.user = UserFactory.create() self.runtime = LmsModuleSystem( static_url='/static', track_function=Mock(), get_module=Mock(), user=self.user, course_id=self.course_id, descriptor_runtime=Mock(), ) self.scope = 'course' self.key = 'key1' self.mock_block = Mock() self.mock_block.service_declaration.return_value = 'needs'
def test_update_transcription_service_credentials_for_vem(self, mock_client, mock_logger): """ Test that if waffle flag `ENABLE_VEM_PIPELINE` is on for course, then credentials are successfully posted to VEM. """ self.add_vem_client() course_key = CourseLocator("test_org", "test_course_num", "test_run") credentials_payload = { 'username': '******', 'api_key': '12345678', 'course_key': course_key } mock_client.request.return_value.ok = True # Try updating the transcription service credentials with override_waffle_flag(waffle_flags()[ENABLE_VEM_PIPELINE], active=True): error_response, is_updated = update_3rd_party_transcription_service_credentials(**credentials_payload) # Making sure log.exception is not called. self.assertDictEqual(error_response, {}) self.assertFalse(mock_logger.exception.called) self.assertTrue(is_updated)
def test_courses_list_with_ccx_courses(self): """ Tests that CCX courses are filtered in course listing. """ # Create a course and assign access roles to user. course_location = CourseLocator('Org1', 'Course1', 'Course1') course = self._create_course_with_access_groups( course_location, self.user) # Create a ccx course key and add assign access roles to user. ccx_course_key = CCXLocator.from_course_locator(course.id, '1') self._add_role_access_to_user(self.user, ccx_course_key) # Test that CCX courses are filtered out. courses_list, __ = _accessible_courses_list_from_groups(self.request) self.assertEqual(len(courses_list), 1) self.assertNotIn(ccx_course_key, [course.id for course in courses_list]) # Get all courses which user has access. instructor_courses = UserBasedRole( self.user, CourseInstructorRole.ROLE).courses_with_role() staff_courses = UserBasedRole( self.user, CourseStaffRole.ROLE).courses_with_role() all_courses = (instructor_courses | staff_courses) # Verify that CCX course exists in access but filtered by `_accessible_courses_list_from_groups`. self.assertIn(ccx_course_key, [access.course_id for access in all_courses]) # Verify that CCX courses are filtered out while iterating over all courses mocked_ccx_course = Mock(id=ccx_course_key) with patch( 'openedx.core.djangoapps.content.course_overviews.models.CourseOverview.get_all_courses', return_value=[mocked_ccx_course], ): courses_iter, __ = _accessible_courses_iter_for_tests(self.request) self.assertEqual(len(list(courses_iter)), 0)
def test_cert_info(self): user = Mock(username="******", id="1") survey_url = "http://a_survey.com" course = Mock( end_of_course_survey_url=survey_url, certificates_display_behavior='end', id=CourseLocator(org="x", course="y", run="z"), ) self.assertEqual( _cert_info(user, course, None), { 'status': 'processing', 'show_survey_button': False, 'can_unenroll': True, } ) cert_status = {'status': 'unavailable'} self.assertEqual( _cert_info(user, course, cert_status), { 'status': 'processing', 'show_survey_button': False, 'mode': None, 'linked_in_url': None, 'can_unenroll': True, } ) cert_status = {'status': 'generating', 'grade': '0.67', 'mode': 'honor'} with patch('lms.djangoapps.grades.course_grade_factory.CourseGradeFactory.read') as patch_persisted_grade: patch_persisted_grade.return_value = Mock(percent=1.0) self.assertEqual( _cert_info(user, course, cert_status), { 'status': 'generating', 'show_survey_button': True, 'survey_url': survey_url, 'grade': '1.0', 'mode': 'honor', 'linked_in_url': None, 'can_unenroll': False, } ) cert_status = {'status': 'generating', 'grade': '0.67', 'mode': 'honor'} self.assertEqual( _cert_info(user, course, cert_status), { 'status': 'generating', 'show_survey_button': True, 'survey_url': survey_url, 'grade': '0.67', 'mode': 'honor', 'linked_in_url': None, 'can_unenroll': False, } ) download_url = 'http://s3.edx/cert' cert_status = { 'status': 'downloadable', 'grade': '0.67', 'download_url': download_url, 'mode': 'honor' } self.assertEqual( _cert_info(user, course, cert_status), { 'status': 'downloadable', 'download_url': download_url, 'show_survey_button': True, 'survey_url': survey_url, 'grade': '0.67', 'mode': 'honor', 'linked_in_url': None, 'can_unenroll': False, } ) cert_status = { 'status': 'notpassing', 'grade': '0.67', 'download_url': download_url, 'mode': 'honor' } self.assertEqual( _cert_info(user, course, cert_status), { 'status': 'notpassing', 'show_survey_button': True, 'survey_url': survey_url, 'grade': '0.67', 'mode': 'honor', 'linked_in_url': None, 'can_unenroll': True, } ) # Test a course that doesn't have a survey specified course2 = Mock(end_of_course_survey_url=None, id=CourseLocator(org="a", course="b", run="c")) cert_status = { 'status': 'notpassing', 'grade': '0.67', 'download_url': download_url, 'mode': 'honor' } self.assertEqual( _cert_info(user, course2, cert_status), { 'status': 'notpassing', 'show_survey_button': False, 'grade': '0.67', 'mode': 'honor', 'linked_in_url': None, 'can_unenroll': True, } ) # test when the display is unavailable or notpassing, we get the correct results out course2.certificates_display_behavior = 'early_no_info' cert_status = {'status': 'unavailable'} self.assertEqual( _cert_info(user, course2, cert_status), { 'status': 'processing', 'show_survey_button': False, 'can_unenroll': True, } ) cert_status = { 'status': 'notpassing', 'grade': '0.67', 'download_url': download_url, 'mode': 'honor' } self.assertEqual( _cert_info(user, course2, cert_status), { 'status': 'processing', 'show_survey_button': False, 'can_unenroll': True, } )
def setUp(self): super(TestCourseActionStateManagerBase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.course_key = CourseLocator("test_org", "test_course_num", "test_run")
def setUp(self): super().setUp() self.course_key = CourseLocator("test_org", "test_course_num", "test_run")
class FilenamePrefixGeneratorTestCase(TestCase): """ Tests for course_filename_prefix_generator """ @ddt.data( CourseLocator(org='foo', course='bar', run='baz'), CourseKey.from_string('foo/bar/baz'), CCXLocator.from_course_locator( CourseLocator(org='foo', course='bar', run='baz'), '1'), ) def test_locators(self, course_key): """ Test filename prefix genaration from multiple course key formats. Test that the filename prefix is generated from a CCX course locator or a course key. If the filename is generated for a CCX course but the related 'ENABLE_COURSE_FILENAME_CCX_SUFFIX' feature is not turned on, the generated filename shouldn't contain the CCX course ID. """ assert course_filename_prefix_generator(course_key) == 'foo_bar_baz' @ddt.data( [CourseLocator(org='foo', course='bar', run='baz'), 'foo_bar_baz'], [CourseKey.from_string('foo/bar/baz'), 'foo_bar_baz'], [ CCXLocator.from_course_locator( CourseLocator(org='foo', course='bar', run='baz'), '1'), 'foo_bar_baz_ccx_1' ], ) @ddt.unpack @override_settings(FEATURES={'ENABLE_COURSE_FILENAME_CCX_SUFFIX': True}) def test_include_ccx_id(self, course_key, expected_filename): """ Test filename prefix genaration from multiple course key formats. Test that the filename prefix is generated from a CCX course locator or a course key. If the filename is generated for a CCX course but the related 'ENABLE_COURSE_FILENAME_CCX_SUFFIX' feature is not turned on, the generated filename shouldn't contain the CCX course ID. """ assert course_filename_prefix_generator( course_key) == expected_filename @ddt.data(CourseLocator(org='foo', course='bar', run='baz'), CourseKey.from_string('foo/bar/baz')) def test_custom_separator(self, course_key): """ Test filename prefix is generated with a custom separator. The filename should be build up from the course locator separated by a custom separator. """ assert course_filename_prefix_generator(course_key, separator='-') == 'foo-bar-baz' @ddt.data( [CourseLocator(org='foo', course='bar', run='baz'), 'foo-bar-baz'], [CourseKey.from_string('foo/bar/baz'), 'foo-bar-baz'], [ CCXLocator.from_course_locator( CourseLocator(org='foo', course='bar', run='baz'), '1'), 'foo-bar-baz-ccx-1' ], ) @ddt.unpack @override_settings(FEATURES={'ENABLE_COURSE_FILENAME_CCX_SUFFIX': True}) def test_custom_separator_including_ccx_id(self, course_key, expected_filename): """ Test filename prefix is generated with a custom separator. The filename should be build up from the course locator separated by a custom separator including the CCX ID if the related 'ENABLE_COURSE_FILENAME_CCX_SUFFIX' is turned on. """ assert course_filename_prefix_generator( course_key, separator='-') == expected_filename
def setUp(self): super(TestCourseActionStateManagerBase, self).setUp() self.course_key = CourseLocator("test_org", "test_course_num", "test_run")