Skip to content
Snippets Groups Projects
Commit 3e805fa6 authored by Gregory Martin's avatar Gregory Martin
Browse files

add cert task firing on whitelist append

parent 95460dd1
No related merge requests found
""" Certificates app """
# this is here to support registering the signals in signals.py
from . import signals
"""
Certificates Application Configuration
Signal handlers are connected here.
"""
from django.apps import AppConfig
class CertificatesConfig(AppConfig):
"""
Application Configuration for Certificates.
"""
name = u'certificates'
def ready(self):
"""
Connect handlers to signals.
"""
# Can't import models at module level in AppConfigs, and models get
# included from the signal handlers
from . import signals # pylint: disable=unused-variable
"""
Signal handler for enabling/disabling self-generated certificates based on the course-pacing.
"""
import logging
from celery.task import task
from django.db.models.signals import post_save
from django.dispatch import receiver
from opaque_keys.edx.keys import CourseKey
from certificates.models import CertificateGenerationCourseSetting
from .config import waffle
from certificates.models import CertificateGenerationCourseSetting, CertificateWhitelist
from certificates.tasks import generate_certificate
from courseware import courses
from openedx.core.djangoapps.models.course_details import COURSE_PACING_CHANGE
log = logging.getLogger(__name__)
@receiver(post_save, sender=CertificateWhitelist, dispatch_uid="append_certificate_whitelist")
def _listen_for_certificate_whitelist_append(sender, instance, **kwargs): # pylint: disable=unused-argument
switches = waffle.waffle()
# All flags enabled
if (
not switches.is_enabled(waffle.SELF_PACED_ONLY) and
not switches.is_enabled(waffle.INSTRUCTOR_PACED_ONLY)
):
return
# Only SELF_PACED_ONLY flag enabled
if not switches.is_enabled(waffle.INSTRUCTOR_PACED_ONLY):
if not courses.get_course_by_id(instance.course_id, depth=0).self_paced:
return
# Only INSTRUCTOR_PACED_ONLY flag enabled
if not switches.is_enabled(waffle.SELF_PACED_ONLY):
if courses.get_course_by_id(instance.course_id, depth=0).self_paced:
return
generate_certificate.apply_async(
student=instance.user,
course_key=instance.course_id,
)
log.info(u'Certificate generation task initiated for {user} : {course} via whitelist'.format(
user=instance.user.id,
course=instance.course_id
))
@receiver(COURSE_PACING_CHANGE, dispatch_uid="course_pacing_changed")
def _listen_for_course_pacing_changed(sender, course_key, course_self_paced, **kwargs): # pylint: disable=unused-argument
"""
......
......@@ -2,10 +2,14 @@
Unit tests for enabling self-generated certificates for self-paced courses
and disabling for instructor-paced courses.
"""
import mock
from certificates import api as certs_api
from certificates.models import CertificateGenerationConfiguration
from certificates.config import waffle
from certificates.models import CertificateGenerationConfiguration, CertificateWhitelist
from certificates.signals import _listen_for_course_pacing_changed
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
from student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
......@@ -40,3 +44,59 @@ class SelfGeneratedCertsSignalTest(ModuleStoreTestCase):
_listen_for_course_pacing_changed('store', self.course.id, self.course.self_paced)
# verify that self-generation of cert is disabled for instructor-paced course
self.assertFalse(certs_api.cert_generation_enabled(self.course.id))
class WhitelistGeneratedCertificatesTest(ModuleStoreTestCase):
"""
Tests for whitelisted student auto-certificate generation
"""
def setUp(self):
super(WhitelistGeneratedCertificatesTest, self).setUp()
self.course = CourseFactory.create(self_paced=True)
self.user = UserFactory.create()
self.ip_course = CourseFactory.create(self_paced=False)
def test_cert_generation_on_whitelist_append(self):
"""
Verify that signal is sent, received, and fires task based on various flag configs
"""
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.SELF_PACED_ONLY, active=False):
CertificateWhitelist.objects.create(
user=self.user,
course_id=self.course.id
)
mock_generate_certificate_apply_async.assert_not_called(
student=self.user,
course_key=self.course.id
)
with waffle.waffle().override(waffle.SELF_PACED_ONLY, active=True):
CertificateWhitelist.objects.create(
user=self.user,
course_id=self.course.id
)
mock_generate_certificate_apply_async.assert_called_with(
student=self.user,
course_key=self.course.id,
)
with waffle.waffle().override(waffle.INSTRUCTOR_PACED_ONLY, active=False):
CertificateWhitelist.objects.create(
user=self.user,
course_id=self.ip_course.id
)
mock_generate_certificate_apply_async.assert_not_called(
student=self.user,
course_key=self.ip_course.id
)
with waffle.waffle().override(waffle.INSTRUCTOR_PACED_ONLY, active=True):
CertificateWhitelist.objects.create(
user=self.user,
course_id=self.ip_course.id
)
mock_generate_certificate_apply_async.assert_called_with(
student=self.user,
course_key=self.ip_course.id
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment