Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
3e805fa6
Commit
3e805fa6
authored
Jun 22, 2017
by
Gregory Martin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add cert task firing on whitelist append
parent
95460dd1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
123 additions
and
5 deletions
+123
-5
lms/djangoapps/certificates/__init__.py
+0
-3
lms/djangoapps/certificates/apps.py
+22
-0
lms/djangoapps/certificates/signals.py
+40
-1
lms/djangoapps/certificates/tests/test_signals.py
+61
-1
No files found.
lms/djangoapps/certificates/__init__.py
View file @
3e805fa6
""" Certificates app """
# this is here to support registering the signals in signals.py
from
.
import
signals
lms/djangoapps/certificates/apps.py
0 → 100644
View file @
3e805fa6
"""
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
lms/djangoapps/certificates/signals.py
View file @
3e805fa6
"""
"""
Signal handler for enabling/disabling self-generated certificates based on the course-pacing.
Signal handler for enabling/disabling self-generated certificates based on the course-pacing.
"""
"""
import
logging
from
celery.task
import
task
from
celery.task
import
task
from
django.db.models.signals
import
post_save
from
django.dispatch
import
receiver
from
django.dispatch
import
receiver
from
opaque_keys.edx.keys
import
CourseKey
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
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"
)
@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
def
_listen_for_course_pacing_changed
(
sender
,
course_key
,
course_self_paced
,
**
kwargs
):
# pylint: disable=unused-argument
"""
"""
...
...
lms/djangoapps/certificates/tests/test_signals.py
View file @
3e805fa6
...
@@ -2,10 +2,14 @@
...
@@ -2,10 +2,14 @@
Unit tests for enabling self-generated certificates for self-paced courses
Unit tests for enabling self-generated certificates for self-paced courses
and disabling for instructor-paced courses.
and disabling for instructor-paced courses.
"""
"""
import
mock
from
certificates
import
api
as
certs_api
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
certificates.signals
import
_listen_for_course_pacing_changed
from
openedx.core.djangoapps.self_paced.models
import
SelfPacedConfiguration
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.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.tests.factories
import
CourseFactory
...
@@ -40,3 +44,59 @@ class SelfGeneratedCertsSignalTest(ModuleStoreTestCase):
...
@@ -40,3 +44,59 @@ class SelfGeneratedCertsSignalTest(ModuleStoreTestCase):
_listen_for_course_pacing_changed
(
'store'
,
self
.
course
.
id
,
self
.
course
.
self_paced
)
_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
# verify that self-generation of cert is disabled for instructor-paced course
self
.
assertFalse
(
certs_api
.
cert_generation_enabled
(
self
.
course
.
id
))
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
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment