def test_inactive_waiting_course_enrollment(self): """ Test that when a waiting program enrollment has waiting program course enrollments with a status of 'inactive' the course enrollment created after calling link_program_enrollments will be inactive """ program_enrollment = self._create_waiting_enrollment( self.program, '0001') active_enrollment = self._create_waiting_course_enrollment( program_enrollment, self.fruit_course) inactive_enrollment = self._create_waiting_course_enrollment( program_enrollment, self.animal_course, status='inactive') link_program_enrollments_to_lms_users(self.program, {'0001': self.user_1.username}) self._assert_program_enrollment(self.user_1, self.program, '0001') active_enrollment.refresh_from_db() self.assertIsNotNone(active_enrollment.course_enrollment) self.assertEqual(active_enrollment.course_enrollment.course.id, self.fruit_course) self.assertTrue(active_enrollment.course_enrollment.is_active) inactive_enrollment.refresh_from_db() self.assertIsNotNone(inactive_enrollment.course_enrollment) self.assertEqual(inactive_enrollment.course_enrollment.course.id, self.animal_course) self.assertFalse(inactive_enrollment.course_enrollment.is_active)
def handle(self, program_uuid, user_items, *args, **options): ext_keys_to_usernames = self.parse_user_items(user_items) try: link_program_enrollments_to_lms_users(program_uuid, ext_keys_to_usernames) except Exception as e: raise CommandError(e)
def test_link_only_specified_program(self): """ Test that when there are two waiting program enrollments with the same external user key, only the specified program's program enrollment will be linked """ program_enrollment = self._create_waiting_enrollment( self.program, '0001') self._create_waiting_course_enrollment(program_enrollment, self.fruit_course) self._create_waiting_course_enrollment(program_enrollment, self.animal_course) another_program_enrollment = self._create_waiting_enrollment( self.other_program, '0001') self._create_waiting_course_enrollment(another_program_enrollment, self.fruit_course) self._create_waiting_course_enrollment(another_program_enrollment, self.animal_course) link_program_enrollments_to_lms_users(self.program, {'0001': self.user_1.username}) self._assert_program_enrollment(self.user_1, self.program, '0001') self._assert_user_enrolled_in_program_courses(self.user_1, self.program, self.fruit_course, self.animal_course) self._assert_no_user(another_program_enrollment)
def test_invalid_uuid(self): self._create_waiting_enrollment(self.program, 'learner-0') with self.assertRaisesMessage(ValueError, 'badly formed hexadecimal UUID string'): link_program_enrollments_to_lms_users( 'notauuid::thisisntauuid', { 'learner-0': self.user_1.username, })
def test_None(self): self._create_waiting_enrollment(self.program, 'learner-0') msg = 'external_user_key or username cannot be None' with self.assertRaisesMessage(ValueError, msg): link_program_enrollments_to_lms_users(self.program, { None: self.user_1.username, }) with self.assertRaisesMessage(ValueError, msg): link_program_enrollments_to_lms_users('notauuid::thisisntauuid', { 'learner-0': None, })
def post(self, request): """ Link the given program enrollments and lms users """ program_uuid = request.POST.get('program_uuid', '').strip() text = request.POST.get('text', '') successes = [] errors = [] if not program_uuid or not text: error = 'You must provide both a program uuid and a comma separated list of external_student_key, username' errors = [error] else: reader = csv.DictReader(text.splitlines(), fieldnames=('external_key', 'username')) ext_key_to_lms_username = { (item['external_key'] or '').strip(): (item['username'] or '').strip() for item in reader } try: link_errors = link_program_enrollments_to_lms_users(program_uuid, ext_key_to_lms_username) except ValueError as e: errors = [str(e)] else: successes = [str(item) for item in ext_key_to_lms_username.items() if item not in link_errors] errors = [message for message in link_errors.values()] return render_to_response( TEMPLATE_PATH, { 'successes': successes, 'errors': errors, 'program_uuid': program_uuid, 'text': text, } )
def test_enrollment_already_linked_to_different_user(self): self._create_waiting_enrollment(self.program, '0001') enrollment = ProgramEnrollmentFactory.create( program_uuid=self.program, external_user_key='0003', ) user_3 = enrollment.user self._assert_no_program_enrollment(self.user_1, self.program, refresh=False) self._assert_no_program_enrollment(self.user_2, self.program, refresh=False) self._assert_program_enrollment(user_3, self.program, '0003', refresh=False) with LogCapture() as logger: errors = link_program_enrollments_to_lms_users( self.program, { '0001': self.user_1.username, '0003': self.user_2.username, }) expected_error_msg = get_existing_user_message( enrollment, self.user_2) logger.check_present((LOG_PATH, 'WARNING', expected_error_msg)) self.assertDictEqual( errors, {('0003', self.user_2.username): expected_error_msg}) self._assert_program_enrollment(self.user_1, self.program, '0001') self._assert_no_program_enrollment(self.user_2, self.program) self._assert_program_enrollment(user_3, self.program, '0003')
def test_user_not_found(self): self._create_waiting_enrollment(self.program, '0001') enrollment_2 = self._create_waiting_enrollment(self.program, '0002') with LogCapture() as logger: errors = link_program_enrollments_to_lms_users( self.program, { '0001': self.user_1.username, '0002': 'nonexistant-user', }) expected_error_msg = NO_LMS_USER_TPL.format('nonexistant-user') logger.check_present((LOG_PATH, 'WARNING', expected_error_msg)) self.assertDictEqual( errors, {('0002', 'nonexistant-user'): expected_error_msg}) self._assert_program_enrollment(self.user_1, self.program, '0001') self._assert_no_user(enrollment_2)
def test_error_enrolling_in_course(self): nonexistant_course = CourseKey.from_string( 'course-v1:edX+Zilch+Bupkis') program_enrollment_1 = self._create_waiting_enrollment( self.program, '0001') course_enrollment_1 = self._create_waiting_course_enrollment( program_enrollment_1, nonexistant_course) course_enrollment_2 = self._create_waiting_course_enrollment( program_enrollment_1, self.animal_course) program_enrollment_2 = self._create_waiting_enrollment( self.program, '0002') self._create_waiting_course_enrollment(program_enrollment_2, self.fruit_course) self._create_waiting_course_enrollment(program_enrollment_2, self.animal_course) msg = COURSE_ENROLLMENT_ERR_TPL.format(user=self.user_1.username, course=nonexistant_course) with LogCapture() as logger: errors = link_program_enrollments_to_lms_users( self.program, { '0001': self.user_1.username, '0002': self.user_2.username }) logger.check_present((LOG_PATH, 'ERROR', msg)) self.assertDictEqual( errors, {('0001', self.user_1.username): 'NonExistentCourseError: ' + msg}) self._assert_no_program_enrollment(self.user_1, self.program) self._assert_no_user(program_enrollment_1) course_enrollment_1.refresh_from_db() self.assertIsNone(course_enrollment_1.course_enrollment) course_enrollment_2.refresh_from_db() self.assertIsNone(course_enrollment_2.course_enrollment) self._assert_user_enrolled_in_program_courses(self.user_2, self.program, self.animal_course, self.fruit_course)
def _program_enrollment_not_found(self): """ Helper for test_program_not_found_* tests. tries to link user_1 to '0001' and user_2 to '0002' in program asserts that user_2 was not linked because the enrollment was not found """ with LogCapture() as logger: errors = link_program_enrollments_to_lms_users( self.program, { '0001': self.user_1.username, '0002': self.user_2.username, }) expected_error_msg = NO_PROGRAM_ENROLLMENT_TPL.format( program_uuid=self.program, external_student_key='0002') logger.check_present((LOG_PATH, 'WARNING', expected_error_msg)) self.assertDictEqual( errors, {('0002', self.user_2.username): expected_error_msg}) self._assert_program_enrollment(self.user_1, self.program, '0001') self._assert_no_program_enrollment(self.user_2, self.program)
def test_integrity_error(self): existing_program_enrollment = self._create_waiting_enrollment( self.program, 'learner-0') existing_program_enrollment.user = self.user_1 existing_program_enrollment.save() program_enrollment_1 = self._create_waiting_enrollment( self.program, '0001') self._create_waiting_enrollment(self.program, '0002') msg = 'Integrity error while linking program enrollments' with LogCapture() as logger: errors = link_program_enrollments_to_lms_users( self.program, { '0001': self.user_1.username, '0002': self.user_2.username, }) logger.check_present((LOG_PATH, 'ERROR', msg)) self.assertEqual(len(errors), 1) self.assertIn('UNIQUE constraint failed', errors[('0001', self.user_1.username)]) self._assert_no_user(program_enrollment_1) self._assert_program_enrollment(self.user_2, self.program, '0002')