Merge pull request #17165 from edx/noraiz/EDUCATOR-1994

auto certs for professional and no-id-professional enrollment modes
This commit is contained in:
Noraiz Anwar
2018-01-18 12:52:05 +05:00
committed by GitHub
2 changed files with 74 additions and 7 deletions

View File

@@ -16,6 +16,7 @@ from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification
from openedx.core.djangoapps.certificates.api import auto_certificate_generation_enabled
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.signals.signals import COURSE_GRADE_NOW_PASSED, LEARNER_NOW_VERIFIED
from course_modes.models import CourseMode
from student.models import CourseEnrollment
@@ -81,17 +82,40 @@ def _listen_for_id_verification_status_changed(sender, user, **kwargs): # pylin
def fire_ungenerated_certificate_task(user, course_key, expected_verification_status=None):
"""
Helper function to fire un-generated certificate tasks
Helper function to fire certificate generation task.
Auto-generation of certificates is available for following course modes:
1- VERIFIED
2- CREDIT_MODE
3- PROFESSIONAL
4- NO_ID_PROFESSIONAL_MODE
The 'mode_is_verified' query is copied from the GeneratedCertificate model,
but is done here in an attempt to reduce traffic to the workers.
If the learner is verified and their cert has the 'unverified' status,
we regenerate the cert.
Certificate generation task is fired to either generate a certificate
when there is no generated certificate for user in a particular course or
update a certificate if it has 'unverified' status.
Task is fired to attempt an update to a certificate
with 'unverified' status as this method is called when a user is
successfully verified, any certificate associated
with such user can now be verified.
NOTE: Purpose of restricting other course modes (HONOR and AUDIT) from auto-generation is to reduce
traffic to workers.
"""
allowed_enrollment_modes_list = [
CourseMode.VERIFIED,
CourseMode.CREDIT_MODE,
CourseMode.PROFESSIONAL,
CourseMode.NO_ID_PROFESSIONAL_MODE,
]
enrollment_mode, __ = CourseEnrollment.enrollment_mode_for_user(user, course_key)
mode_is_verified = enrollment_mode in GeneratedCertificate.VERIFIED_CERTS_MODES
cert = GeneratedCertificate.certificate_for_student(user, course_key)
if mode_is_verified and (cert is None or cert.status == 'unverified'):
generate_learner_certificate = (
enrollment_mode in allowed_enrollment_modes_list and (cert is None or cert.status == 'unverified')
)
if generate_learner_certificate:
kwargs = {
'student': unicode(user.id),
'course_key': unicode(course_key)

View File

@@ -2,6 +2,7 @@
Unit tests for enabling self-generated certificates for self-paced courses
and disabling for instructor-paced courses.
"""
import ddt
import mock
from certificates import api as certs_api
@@ -11,6 +12,7 @@ from certificates.models import (
GeneratedCertificate,
CertificateStatuses,
)
from certificates.signals import fire_ungenerated_certificate_task
from lms.djangoapps.grades.course_grade_factory import CourseGradeFactory
from lms.djangoapps.grades.tests.utils import mock_passing_grade
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification
@@ -286,3 +288,44 @@ class LearnerTrackChangeCertsTest(ModuleStoreTestCase):
'expected_verification_status': SoftwareSecurePhotoVerification.STATUS.approved
}
)
@ddt.ddt
class CertificateGenerationTaskTest(ModuleStoreTestCase):
"""
Tests for certificate generation task.
"""
def setUp(self):
super(CertificateGenerationTaskTest, self).setUp()
self.course = CourseFactory.create()
@ddt.data(
('professional', True),
('verified', True),
('no-id-professional', True),
('credit', True),
('audit', False),
('honor', False),
)
@ddt.unpack
def test_fire_ungenerated_certificate_task_allowed_modes(self, enrollment_mode, should_create):
"""
Test that certificate generation task is fired for only modes that are
allowed to generate certificates automatically.
"""
self.user = UserFactory.create()
self.enrollment = CourseEnrollmentFactory(
user=self.user,
course_id=self.course.id,
is_active=True,
mode=enrollment_mode
)
with mock.patch(
'lms.djangoapps.certificates.signals.generate_certificate.apply_async',
return_value=None
) as mock_generate_certificate_apply_async:
with waffle.waffle().override(waffle.AUTO_CERTIFICATE_GENERATION, active=True):
fire_ungenerated_certificate_task(self.user, self.course.id)
task_created = mock_generate_certificate_apply_async.called
self.assertEqual(task_created, should_create)