Commit b8aa3052 by Gregory Martin Committed by GitHub

Merge pull request #15813 from edx/yro/update_cert

Update Certificate Task Call
parents 839b5320 b19d8059
......@@ -235,6 +235,7 @@ class XQueueCertInterface(object):
status.auditing,
status.audit_passing,
status.audit_notpassing,
status.unverified,
]
cert_status = certificate_status_for_student(student, course_id)['status']
......
......@@ -6,10 +6,12 @@ import logging
from django.db.models.signals import post_save
from django.dispatch import receiver
from certificates.models import \
CertificateGenerationCourseSetting, \
CertificateWhitelist, \
from certificates.models import (
CertificateGenerationCourseSetting,
CertificateWhitelist,
CertificateStatuses,
GeneratedCertificate
)
from certificates.tasks import generate_certificate
from courseware import courses
from lms.djangoapps.grades.new.course_grade_factory import CourseGradeFactory
......@@ -97,10 +99,16 @@ def _listen_for_track_change(sender, user, **kwargs): # pylint: disable=unused-
def fire_ungenerated_certificate_task(user, course_key):
"""
Helper function to fire un-generated certificate tasks
:param user: A User object.
:param course_id: A CourseKey object.
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.
"""
if GeneratedCertificate.certificate_for_student(user, course_key) is None:
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_certificate.apply_async(kwargs={
'student': unicode(user.id),
'course_key': unicode(course_key),
......
......@@ -520,8 +520,11 @@ class GenerateUserCertificatesTest(EventTestMixin, WebCertificateTestMixin, Modu
def test_generate_user_certificates_with_unverified_cert_status(self):
"""
Generate user certificate will not raise exception in case of certificate is None.
Generate user certificate when the certificate is unverified
will trigger an update to the certificate if the user has since
verified.
"""
self._setup_course_certificate()
# generate certificate with unverified status.
GeneratedCertificateFactory.create(
user=self.student,
......@@ -531,9 +534,9 @@ class GenerateUserCertificatesTest(EventTestMixin, WebCertificateTestMixin, Modu
)
with mock_passing_grade():
with self._mock_queue(is_successful=False):
with self._mock_queue():
status = certs_api.generate_user_certificates(self.student, self.course.id)
self.assertEqual(status, None)
self.assertEqual(status, 'generating')
@patch.dict(settings.FEATURES, {'CERTIFICATES_HTML_VIEW': True})
def test_new_cert_requests_returns_generating_for_html_certificate(self):
......
......@@ -61,7 +61,19 @@ class WhitelistGeneratedCertificatesTest(ModuleStoreTestCase):
super(WhitelistGeneratedCertificatesTest, self).setUp()
self.course = CourseFactory.create(self_paced=True)
self.user = UserFactory.create()
CourseEnrollmentFactory(
user=self.user,
course_id=self.course.id,
is_active=True,
mode="verified",
)
self.ip_course = CourseFactory.create(self_paced=False)
CourseEnrollmentFactory(
user=self.user,
course_id=self.ip_course.id,
is_active=True,
mode="verified",
)
def test_cert_generation_on_whitelist_append_self_paced(self):
"""
......@@ -137,6 +149,11 @@ class PassingGradeCertsTest(ModuleStoreTestCase):
is_active=True,
mode="verified",
)
attempt = SoftwareSecurePhotoVerification.objects.create(
user=self.user,
status='submitted'
)
attempt.approve()
def test_cert_generation_on_passing_self_paced(self):
with mock.patch(
......@@ -204,7 +221,7 @@ class LearnerTrackChangeCertsTest(ModuleStoreTestCase):
user=self.user_one,
course_id=self.course_one.id,
is_active=True,
mode='honor',
mode='verified',
)
self.user_two = UserFactory.create()
self.course_two = CourseFactory.create(self_paced=False)
......@@ -212,18 +229,18 @@ class LearnerTrackChangeCertsTest(ModuleStoreTestCase):
user=self.user_two,
course_id=self.course_two.id,
is_active=True,
mode='honor'
mode='verified'
)
with mock_passing_grade():
grade_factory = CourseGradeFactory()
grade_factory.update(self.user_one, self.course_one)
grade_factory.update(self.user_two, self.course_two)
def test_cert_generation_on_photo_verification_self_paced(self):
with mock.patch(
'lms.djangoapps.certificates.signals.generate_certificate.apply_async',
return_value=None
) as mock_generate_certificate_apply_async:
with mock_passing_grade():
grade_factory = CourseGradeFactory()
grade_factory.update(self.user_one, self.course_one)
with waffle.waffle().override(waffle.SELF_PACED_ONLY, active=True):
mock_generate_certificate_apply_async.assert_not_called()
attempt = SoftwareSecurePhotoVerification.objects.create(
......@@ -241,10 +258,6 @@ class LearnerTrackChangeCertsTest(ModuleStoreTestCase):
'lms.djangoapps.certificates.signals.generate_certificate.apply_async',
return_value=None
) as mock_generate_certificate_apply_async:
with mock_passing_grade():
grade_factory = CourseGradeFactory()
grade_factory.update(self.user_two, self.course_two)
with waffle.waffle().override(waffle.INSTRUCTOR_PACED_ONLY, active=True):
mock_generate_certificate_apply_async.assert_not_called()
attempt = SoftwareSecurePhotoVerification.objects.create(
......
......@@ -1007,8 +1007,9 @@ def _get_cert_data(student, course, course_key, is_active, enrollment_mode):
# If the learner is in verified modes and the student did not have
# their ID verified, we need to show message to ask learner to verify their ID first
missing_required_verification = enrollment_mode in CourseMode.VERIFIED_MODES and \
not SoftwareSecurePhotoVerification.user_is_verified(student)
missing_required_verification = (
enrollment_mode in CourseMode.VERIFIED_MODES and not SoftwareSecurePhotoVerification.user_is_verified(student)
)
if missing_required_verification or cert_downloadable_status['is_unverified']:
platform_name = configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment