MICROBA-1055 Require a valid enrollment mode, even on the allowlist (#27012)
This commit is contained in:
@@ -15,3 +15,15 @@ def get_paid_modes_for_course(course_run_id):
|
||||
A list of paid modes (strings) that the course has attached to it.
|
||||
"""
|
||||
return _CourseMode.paid_modes_for_course(course_run_id)
|
||||
|
||||
|
||||
def is_eligible_for_certificate(mode_slug, status=None):
|
||||
"""
|
||||
Returns whether or not the given mode_slug is eligible for a
|
||||
certificate. Currently all modes other than 'audit' grant a
|
||||
certificate. Note that audit enrollments which existed prior
|
||||
to December 2015 *were* given certificates, so there will be
|
||||
GeneratedCertificate records with mode='audit' which are
|
||||
eligible.
|
||||
"""
|
||||
return _CourseMode.is_eligible_for_certificate(mode_slug, status)
|
||||
|
||||
@@ -22,12 +22,15 @@ won't necessarily have a course certificate available to them. To receive a
|
||||
downloadable allowlist course certificate, the following things must be true at
|
||||
the time the certificate is generated:
|
||||
|
||||
* The user must be enrolled in the course
|
||||
* The user must have an enrollment in the course
|
||||
|
||||
* The enrollment mode must be eligible for a certificate
|
||||
* The enrollment does not need to be active
|
||||
|
||||
* The user must have an approved, unexpired, ID verification
|
||||
* The user must be on the allowlist for the course run (see the CertificateWhitelist model)
|
||||
* The user must not have an invalidated certificate for the course run (see the CertificateInvalidation model)
|
||||
* Certificate generation must be enabled for the course run
|
||||
* Automatic certificate generation must be enabled
|
||||
* The user must be on the allowlist for the course run (see the *CertificateWhitelist* model)
|
||||
* The user must not have an invalidated certificate for the course run (see the *CertificateInvalidation* model)
|
||||
* Automatic certificate generation must be globally enabled
|
||||
|
||||
Note: the above requirements were written for the allowlist, which assumes the
|
||||
CourseWaffleFlag *certificates_revamp.use_allowlist* has been enabled for the
|
||||
|
||||
@@ -10,6 +10,7 @@ import logging
|
||||
|
||||
from edx_toggles.toggles import LegacyWaffleFlagNamespace
|
||||
|
||||
from common.djangoapps.course_modes import api as modes_api
|
||||
from common.djangoapps.student.models import CourseEnrollment
|
||||
from lms.djangoapps.certificates.models import (
|
||||
CertificateInvalidation,
|
||||
@@ -164,6 +165,11 @@ def _can_generate_allowlist_certificate(user, course_key):
|
||||
log.info(f'{user.id} : {course_key} does not have an enrollment. Certificate cannot be generated.')
|
||||
return False
|
||||
|
||||
if not modes_api.is_eligible_for_certificate(enrollment_mode):
|
||||
log.info(f'{user.id} : {course_key} has an enrollment mode of {enrollment_mode}, which is not eligible for an '
|
||||
f'allowlist certificate. Certificate cannot be generated.')
|
||||
return False
|
||||
|
||||
if not IDVerificationService.user_is_verified(user):
|
||||
log.info(f'{user.id} does not have a verified id. Certificate cannot be generated.')
|
||||
return False
|
||||
|
||||
@@ -15,6 +15,7 @@ from lxml.etree import ParserError, XMLSyntaxError
|
||||
from requests.auth import HTTPBasicAuth
|
||||
|
||||
from capa.xqueue_interface import XQueueInterface, make_hashkey, make_xheader
|
||||
from common.djangoapps.course_modes import api as modes_api
|
||||
from common.djangoapps.course_modes.models import CourseMode
|
||||
from common.djangoapps.student.models import CourseEnrollment, UserProfile
|
||||
from lms.djangoapps.certificates.models import CertificateStatuses as status
|
||||
@@ -289,7 +290,7 @@ class XQueueCertInterface:
|
||||
user_is_verified = IDVerificationService.user_is_verified(student)
|
||||
cert_mode = enrollment_mode
|
||||
|
||||
is_eligible_for_certificate = CourseMode.is_eligible_for_certificate(enrollment_mode, cert_status)
|
||||
is_eligible_for_certificate = modes_api.is_eligible_for_certificate(enrollment_mode, cert_status)
|
||||
if is_whitelisted and not is_eligible_for_certificate:
|
||||
# check if audit certificates are enabled for audit mode
|
||||
is_eligible_for_certificate = enrollment_mode != CourseMode.AUDIT or \
|
||||
|
||||
@@ -195,6 +195,23 @@ class AllowlistTests(ModuleStoreTestCase):
|
||||
CertificateWhitelistFactory.create(course_id=key, user=u)
|
||||
assert not _can_generate_allowlist_certificate(u, key)
|
||||
|
||||
def test_can_generate_audit(self):
|
||||
"""
|
||||
Test handling when user is enrolled in audit mode
|
||||
"""
|
||||
u = UserFactory()
|
||||
cr = CourseFactory()
|
||||
key = cr.id # pylint: disable=no-member
|
||||
CourseEnrollmentFactory(
|
||||
user=u,
|
||||
course_id=key,
|
||||
is_active=True,
|
||||
mode="audit",
|
||||
)
|
||||
CertificateWhitelistFactory.create(course_id=key, user=u)
|
||||
|
||||
assert not _can_generate_allowlist_certificate(u, key)
|
||||
|
||||
def test_can_generate_not_whitelisted(self):
|
||||
"""
|
||||
Test handling when user is not whitelisted
|
||||
|
||||
@@ -21,6 +21,7 @@ from testfixtures import LogCapture
|
||||
# and verify that items are being correctly added to the queue
|
||||
# in our `XQueueCertInterface` implementation.
|
||||
from capa.xqueue_interface import XQueueInterface
|
||||
from common.djangoapps.course_modes import api as modes_api
|
||||
from common.djangoapps.course_modes.models import CourseMode
|
||||
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
|
||||
from lms.djangoapps.certificates.models import (
|
||||
@@ -91,7 +92,7 @@ class XQueueCertInterfaceAddCertificateTest(ModuleStoreTestCase):
|
||||
id=self.course.id
|
||||
)
|
||||
mock_send = self.add_cert_to_queue(mode)
|
||||
if CourseMode.is_eligible_for_certificate(mode):
|
||||
if modes_api.is_eligible_for_certificate(mode):
|
||||
self.assert_certificate_generated(mock_send, mode, template_name)
|
||||
else:
|
||||
self.assert_ineligible_certificate_generated(mock_send, mode)
|
||||
|
||||
Reference in New Issue
Block a user