MICROBA-1055 Listen for course enrollment mode change (#27029)

This commit is contained in:
Christie Rice
2021-03-16 14:06:46 -04:00
committed by GitHub
parent 6a868108c2
commit 6b7d63af09
2 changed files with 80 additions and 2 deletions

View File

@@ -7,8 +7,10 @@ import logging
from django.db.models.signals import post_save
from django.dispatch import receiver
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
from common.djangoapps.student.signals import ENROLLMENT_TRACK_UPDATED
from lms.djangoapps.certificates.generation_handler import (
generate_allowlist_certificate_task,
is_using_certificate_allowlist_and_is_on_allowlist
@@ -145,6 +147,22 @@ def _listen_for_id_verification_status_changed(sender, user, **kwargs): # pylin
))
@receiver(ENROLLMENT_TRACK_UPDATED)
def _listen_for_enrollment_mode_change(sender, user, course_key, mode, **kwargs): # pylint: disable=unused-argument
"""
Listen for the signal indicating that a user's enrollment mode has changed.
If possible, grant the user a course certificate. Note that we intentionally do not revoke certificates here, even
if the user has moved to the audit track.
"""
if modes_api.is_eligible_for_certificate(mode):
if is_using_certificate_allowlist_and_is_on_allowlist(user, course_key):
log.info(f'{course_key} is using allowlist certificates, and the user {user.id} is on its allowlist. '
f'Attempt will be made to generate an allowlist certificate since the enrollment mode is now '
f'{mode}.')
generate_allowlist_certificate_task(user, course_key)
def _fire_ungenerated_certificate_task(user, course_key, expected_verification_status=None):
"""
Helper function to fire certificate generation task.

View File

@@ -58,9 +58,9 @@ class SelfGeneratedCertsSignalTest(ModuleStoreTestCase):
assert not cert_generation_enabled(course.id)
class WhitelistGeneratedCertificatesTest(ModuleStoreTestCase):
class AllowlistGeneratedCertificatesTest(ModuleStoreTestCase):
"""
Tests for whitelisted student auto-certificate generation
Tests for allowlisted student auto-certificate generation
"""
def setUp(self):
@@ -573,3 +573,63 @@ class CertificateGenerationTaskTest(ModuleStoreTestCase):
_fire_ungenerated_certificate_task(self.user, self.course.id)
task_created = mock_generate_certificate_apply_async.called
assert task_created == should_create
@override_waffle_flag(CERTIFICATES_USE_ALLOWLIST, active=True)
@override_waffle_flag(AUTO_CERTIFICATE_GENERATION_SWITCH, active=True)
class EnrollmentModeChangeCertsTest(ModuleStoreTestCase):
"""
Tests for certificate generation task firing when the user's enrollment mode changes
"""
def setUp(self):
super().setUp()
self.user = UserFactory.create()
self.verified_course = CourseFactory.create(
self_paced=True,
)
self.verified_course_key = self.verified_course.id # pylint: disable=no-member
self.verified_enrollment = CourseEnrollmentFactory(
user=self.user,
course_id=self.verified_course_key,
is_active=True,
mode='verified',
)
CertificateWhitelistFactory(
user=self.user,
course_id=self.verified_course_key
)
self.audit_course = CourseFactory.create(self_paced=False)
self.audit_course_key = self.audit_course.id # pylint: disable=no-member
self.audit_enrollment = CourseEnrollmentFactory(
user=self.user,
course_id=self.audit_course_key,
is_active=True,
mode='audit',
)
CertificateWhitelistFactory(
user=self.user,
course_id=self.audit_course_key
)
def test_audit_to_verified(self):
"""
Test that we try to generate a certificate when the user switches from audit to verified
"""
with mock.patch(
'lms.djangoapps.certificates.signals.generate_allowlist_certificate_task',
return_value=None
) as mock_allowlist_task:
self.audit_enrollment.change_mode('verified')
mock_allowlist_task.assert_called_with(self.user, self.audit_course_key)
def test_verified_to_audit(self):
"""
Test that we do not try to generate a certificate when the user switches from verified to audit
"""
with mock.patch(
'lms.djangoapps.certificates.signals.generate_allowlist_certificate_task',
return_value=None
) as mock_allowlist_task:
self.verified_enrollment.change_mode('audit')
mock_allowlist_task.assert_not_called()