diff --git a/lms/djangoapps/instructor_task/tasks_helper.py b/lms/djangoapps/instructor_task/tasks_helper.py index 8808db2a5a..f0ef86eb43 100644 --- a/lms/djangoapps/instructor_task/tasks_helper.py +++ b/lms/djangoapps/instructor_task/tasks_helper.py @@ -1421,7 +1421,11 @@ def generate_students_certificates( task_progress.update_task_state(extra_meta=current_step) statuses_to_regenerate = task_input.get('statuses_to_regenerate', []) - students_require_certs = students_require_certificate(course_id, enrolled_students, statuses_to_regenerate) + if students is not None and not statuses_to_regenerate: + # We want to skip 'filtering students' only when students are given and statuses to regenerate are not + students_require_certs = enrolled_students + else: + students_require_certs = students_require_certificate(course_id, enrolled_students, statuses_to_regenerate) if statuses_to_regenerate: # Mark existing generated certificates as 'unavailable' before regenerating diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py index 6a8b087f39..5d4b5f0627 100644 --- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py +++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py @@ -1650,7 +1650,7 @@ class TestCertificateGeneration(InstructorTaskModuleTestCase): result ) - def test_certificate_regeneration_for_students(self): + def test_certificate_regeneration_for_statuses_to_regenerate(self): """ Verify that certificates are regenerated for all eligible students enrolled in a course whose generated certificate statuses lies in the list 'statuses_to_regenerate' given in task_input. @@ -1937,3 +1937,78 @@ class TestCertificateGeneration(InstructorTaskModuleTestCase): if cert.status == CertificateStatuses.unavailable and cert.grade == default_grade] self.assertEquals(len(unavailable_certificates), 2) + + def test_certificate_regeneration_for_students(self): + """ + Verify that certificates are regenerated for all students passed in task_input. + """ + # create 10 students + students = [self.create_student(username='student_{}'.format(i), email='student_{}@example.com'.format(i)) + for i in xrange(1, 11)] + + # mark 2 students to have certificates generated already + for student in students[:2]: + GeneratedCertificateFactory.create( + user=student, + course_id=self.course.id, + status=CertificateStatuses.downloadable, + mode='honor' + ) + + # mark 3 students to have certificates generated with status 'error' + for student in students[2:5]: + GeneratedCertificateFactory.create( + user=student, + course_id=self.course.id, + status=CertificateStatuses.error, + mode='honor' + ) + + # mark 6th students to have certificates generated with status 'deleted' + for student in students[5:6]: + GeneratedCertificateFactory.create( + user=student, + course_id=self.course.id, + status=CertificateStatuses.deleted, + mode='honor' + ) + + # mark 7th students to have certificates generated with status 'norpassing' + for student in students[6:7]: + GeneratedCertificateFactory.create( + user=student, + course_id=self.course.id, + status=CertificateStatuses.notpassing, + mode='honor' + ) + + # white-list 7 students + for student in students[:7]: + CertificateWhitelistFactory.create(user=student, course_id=self.course.id, whitelist=True) + + current_task = Mock() + current_task.update_state = Mock() + + # Certificates should be regenerated for students having generated certificates with status + # 'downloadable' or 'error' which are total of 5 students in this test case + task_input = {'students': [student.id for student in students]} + + with patch('instructor_task.tasks_helper._get_current_task') as mock_current_task: + mock_current_task.return_value = current_task + with patch('capa.xqueue_interface.XQueueInterface.send_to_queue') as mock_queue: + mock_queue.return_value = (0, "Successfully queued") + result = generate_students_certificates( + None, None, self.course.id, task_input, 'certificates generated' + ) + + self.assertDictContainsSubset( + { + 'action_name': 'certificates generated', + 'total': 10, + 'attempted': 10, + 'succeeded': 7, + 'failed': 3, + 'skipped': 0, + }, + result + )