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
c3b78ea9
Commit
c3b78ea9
authored
Jun 15, 2015
by
Matt Drayer
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #8448 from edx/ziafazal/SOL-886
certificates event tracking SOL-886
parents
c28003b5
6afaa3cc
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
420 additions
and
22 deletions
+420
-22
common/test/acceptance/fixtures/certificates.py
+46
-0
common/test/acceptance/pages/lms/certificate_page.py
+52
-0
common/test/acceptance/tests/lms/test_certificate_web_view.py
+86
-0
common/test/db_fixtures/certificates_web_view.json
+76
-0
lms/djangoapps/certificates/api.py
+44
-6
lms/djangoapps/certificates/models.py
+13
-3
lms/djangoapps/certificates/queue.py
+5
-3
lms/djangoapps/certificates/tests/test_api.py
+17
-3
lms/djangoapps/certificates/tests/test_views.py
+28
-2
lms/djangoapps/certificates/views.py
+17
-3
lms/djangoapps/courseware/views.py
+1
-1
lms/envs/common.py
+9
-0
lms/templates/certificates/_accomplishment-banner.html
+26
-1
No files found.
common/test/acceptance/fixtures/certificates.py
0 → 100644
View file @
c3b78ea9
"""
Tools for creating certificates config fixture data.
"""
import
json
from
.
import
STUDIO_BASE_URL
from
.base
import
StudioApiFixture
class
CertificateConfigFixtureError
(
Exception
):
"""
Error occurred while installing certificate config fixture.
"""
pass
class
CertificateConfigFixture
(
StudioApiFixture
):
"""
Fixture to create certificates configuration for a course
"""
certificates
=
[]
def
__init__
(
self
,
course_id
,
certificates_data
):
self
.
course_id
=
course_id
self
.
certificates
=
certificates_data
super
(
CertificateConfigFixture
,
self
)
.
__init__
()
def
install
(
self
):
"""
Push the certificates config data to certificate endpoint.
"""
response
=
self
.
session
.
post
(
'{}/certificates/{}'
.
format
(
STUDIO_BASE_URL
,
self
.
course_id
),
data
=
json
.
dumps
(
self
.
certificates
),
headers
=
self
.
headers
)
if
not
response
.
ok
:
raise
CertificateConfigFixtureError
(
"Could not create certificate {0}. Status was {1}"
.
format
(
json
.
dumps
(
self
.
certificates
),
response
.
status_code
)
)
return
self
common/test/acceptance/pages/lms/certificate_page.py
0 → 100644
View file @
c3b78ea9
# -*- coding: utf-8 -*-
"""
Module for Certificates pages.
"""
from
bok_choy.page_object
import
PageObject
from
.
import
BASE_URL
class
CertificatePage
(
PageObject
):
"""
Certificate web view page.
"""
url_path
=
"certificates"
def
__init__
(
self
,
browser
,
user_id
,
course_id
):
"""Initialize the page.
Arguments:
browser (Browser): The browser instance.
user_id: id of the user whom certificate is awarded
course_id: course key of the course where certificate is awarded
"""
super
(
CertificatePage
,
self
)
.
__init__
(
browser
)
self
.
user_id
=
user_id
self
.
course_id
=
course_id
def
is_browser_on_page
(
self
):
""" Checks if certificate web view page is being viewed """
return
self
.
q
(
css
=
'section.about-accomplishments'
)
.
present
@property
def
url
(
self
):
"""
Construct a URL to the page
"""
return
BASE_URL
+
"/"
+
self
.
url_path
+
"/user/"
+
self
.
user_id
+
"/course/"
+
self
.
course_id
@property
def
accomplishment_banner
(
self
):
"""
returns accomplishment banner.
"""
return
self
.
q
(
css
=
'section.banner-user'
)
@property
def
add_to_linkedin_profile_button
(
self
):
"""
returns add to LinkedIn profile button
"""
return
self
.
q
(
css
=
'a.action-linkedin-profile'
)
common/test/acceptance/tests/lms/test_certificate_web_view.py
0 → 100644
View file @
c3b78ea9
"""
Acceptance tests for the certificate web view feature.
"""
from
..helpers
import
UniqueCourseTest
,
EventsTestMixin
from
nose.plugins.attrib
import
attr
from
...fixtures.course
import
CourseFixture
from
...fixtures.certificates
import
CertificateConfigFixture
from
...pages.lms.auto_auth
import
AutoAuthPage
from
...pages.lms.certificate_page
import
CertificatePage
@attr
(
'shard_5'
)
class
CertificateWebViewTest
(
EventsTestMixin
,
UniqueCourseTest
):
"""
Tests for verifying certificate web view features
"""
def
setUp
(
self
):
super
(
CertificateWebViewTest
,
self
)
.
setUp
()
# set same course number as we have in fixture json
self
.
course_info
[
'number'
]
=
"335535897951379478207964576572017930000"
test_certificate_config
=
{
'id'
:
1
,
'name'
:
'Certificate name'
,
'description'
:
'Certificate description'
,
'course_title'
:
'Course title override'
,
'signatories'
:
[],
'version'
:
1
,
'is_active'
:
True
}
course_settings
=
{
'certificates'
:
test_certificate_config
}
self
.
course_fixture
=
CourseFixture
(
self
.
course_info
[
"org"
],
self
.
course_info
[
"number"
],
self
.
course_info
[
"run"
],
self
.
course_info
[
"display_name"
],
settings
=
course_settings
)
self
.
course_fixture
.
install
()
self
.
user_id
=
"99"
# we have createad a user with this id in fixture
self
.
cert_fixture
=
CertificateConfigFixture
(
self
.
course_id
,
test_certificate_config
)
# Load certificate web view page for use by the tests
self
.
certificate_page
=
CertificatePage
(
self
.
browser
,
self
.
user_id
,
self
.
course_id
)
def
log_in_as_unique_user
(
self
):
"""
Log in as a valid lms user.
"""
AutoAuthPage
(
self
.
browser
,
username
=
"testcert"
,
email
=
"cert@example.com"
,
password
=
"testuser"
,
course_id
=
self
.
course_id
)
.
visit
()
def
test_page_has_accomplishments_banner
(
self
):
"""
Scenario: User accomplishment banner should be present if logged in user is the one who is awarded
the certificate
Given there is a course with certificate configuration
And I have passed the course and certificate is generated
When I view the certificate web view page
Then I should see the accomplishment banner
And When I click on `Add to Profile` button `edx.certificate.shared` event should be emitted
"""
self
.
cert_fixture
.
install
()
self
.
log_in_as_unique_user
()
self
.
certificate_page
.
visit
()
self
.
assertTrue
(
self
.
certificate_page
.
accomplishment_banner
.
visible
)
self
.
assertTrue
(
self
.
certificate_page
.
add_to_linkedin_profile_button
.
visible
)
self
.
certificate_page
.
add_to_linkedin_profile_button
.
click
()
actual_events
=
self
.
wait_for_events
(
event_filter
=
{
'event_type'
:
'edx.certificate.shared'
},
number_of_matches
=
1
)
expected_events
=
[
{
'event'
:
{
'user_id'
:
self
.
user_id
,
'course_id'
:
self
.
course_id
}
}
]
self
.
assert_events_match
(
expected_events
,
actual_events
)
common/test/db_fixtures/certificates_web_view.json
0 → 100644
View file @
c3b78ea9
[
{
"pk"
:
99
,
"model"
:
"auth.user"
,
"fields"
:
{
"date_joined"
:
"2015-06-12 11:02:13"
,
"username"
:
"testcert"
,
"first_name"
:
"john"
,
"last_name"
:
"doe"
,
"email"
:
"cert@example.com"
,
"password"
:
"testuser"
,
"is_staff"
:
false
,
"is_active"
:
true
}
},
{
"pk"
:
99
,
"model"
:
"student.userprofile"
,
"fields"
:
{
"user"
:
99
,
"name"
:
"test cert"
,
"courseware"
:
"course.xml"
,
"allow_certificate"
:
true
}
},
{
"pk"
:
99
,
"model"
:
"student.registration"
,
"fields"
:
{
"user"
:
99
,
"activation_key"
:
"52bfac10384d49219385dcd4cc17177p"
}
},
{
"pk"
:
2
,
"model"
:
"certificates.certificatehtmlviewconfiguration"
,
"fields"
:
{
"change_date"
:
"2050-05-15 11:02:13"
,
"changed_by"
:
99
,
"enabled"
:
true
,
"configuration"
:
"{
\"
default
\"
: {
\"
accomplishment_class_append
\"
:
\"
accomplishment-certificate
\"
,
\"
platform_name
\"
:
\"
edX
\"
,
\"
company_privacy_url
\"
:
\"
http://www.edx.org/edx-privacy-policy
\"
,
\"
company_about_url
\"
:
\"
http://www.edx.org/about-us
\"
,
\"
company_tos_url
\"
:
\"
http://www.edx.org/edx-terms-service
\"
,
\"
company_verified_certificate_url
\"
:
\"
http://www.edx.org/verified-certificate
\"
,
\"
document_stylesheet_url_application
\"
:
\"
/static/certificates/sass/main-ltr.css
\"
,
\"
logo_src
\"
:
\"
/static/certificates/images/logo-edx.svg
\"
,
\"
logo_url
\"
:
\"
http://www.edx.org
\"
},
\"
honor
\"
: {
\"
certificate_type
\"
:
\"
Honor Code
\"
,
\"
document_body_class_append
\"
:
\"
is-honorcode
\"
},
\"
verified
\"
: {
\"
certificate_type
\"
:
\"
Verified
\"
,
\"
document_body_class_append
\"
:
\"
is-idverified
\"
},
\"
xseries
\"
: {
\"
certificate_type
\"
:
\"
XSeries
\"
,
\"
document_body_class_append
\"
:
\"
is-xseries
\"
}}"
}
},
{
"pk"
:
1
,
"model"
:
"certificates.generatedcertificate"
,
"fields"
:
{
"user"
:
99
,
"download_url"
:
"http://www.edx.org/certificates/downloand"
,
"grade"
:
"0.8"
,
"course_id"
:
"course-v1:test_org+335535897951379478207964576572017930000+test_run"
,
"key"
:
""
,
"distinction"
:
true
,
"status"
:
"downloadable"
,
"verify_uuid"
:
"52bfac10394d49219385dcd4cc17177e"
,
"download_uuid"
:
"52bfac10394d49219385dcd4cc17177r"
,
"name"
:
"testcert"
,
"created_date"
:
"2015-06-12 11:02:13"
,
"modified_date"
:
"2015-06-12 11:02:13"
,
"error_reason"
:
""
,
"mode"
:
"honor"
}
},
{
"pk"
:
1
,
"model"
:
"student.linkedinaddtoprofileconfiguration"
,
"fields"
:
{
"change_date"
:
"2050-06-15 11:02:13"
,
"changed_by"
:
99
,
"enabled"
:
true
,
"dashboard_tracking_code"
:
"edx-course-v1&TESTCOURSE"
,
"company_identifier"
:
"7nTFLiuDkkQkdELSpruCwD4F6jzqtTFsx3PfJUIT2qHqXRLG1"
,
"trk_partner_name"
:
"edx"
}
}
]
lms/djangoapps/certificates/api.py
View file @
c3b78ea9
...
...
@@ -9,10 +9,12 @@ import logging
from
django.conf
import
settings
from
django.core.urlresolvers
import
reverse
from
eventtracking
import
tracker
from
xmodule.modulestore.django
import
modulestore
from
certificates.models
import
(
CertificateStatuses
as
cert_status
,
CertificateStatuses
,
certificate_status_for_student
,
CertificateGenerationCourseSetting
,
CertificateGenerationConfiguration
,
...
...
@@ -24,13 +26,14 @@ from certificates.queue import XQueueCertInterface
log
=
logging
.
getLogger
(
"edx.certificate"
)
def
generate_user_certificates
(
student
,
course_key
,
course
=
None
,
insecure
=
False
):
def
generate_user_certificates
(
student
,
course_key
,
course
=
None
,
insecure
=
False
,
generation_mode
=
'batch'
):
"""
It will add the add-cert request into the xqueue.
A new record will be created to track the certificate
generation task. If an error occurs while adding the certificate
to the queue, the task will have status 'error'.
to the queue, the task will have status 'error'. It also emits
`edx.certificate.created` event for analytics.
Args:
student (User)
...
...
@@ -40,12 +43,23 @@ def generate_user_certificates(student, course_key, course=None, insecure=False)
course (Course): Optionally provide the course object; if not provided
it will be loaded.
insecure - (Boolean)
generation_mode - who has requested certificate generation. Its value should `batch`
in case of django command and `self` if student initiated the request.
"""
xqueue
=
XQueueCertInterface
()
if
insecure
:
xqueue
.
use_https
=
False
generate_pdf
=
not
has_html_certificates_enabled
(
course_key
,
course
)
return
xqueue
.
add_cert
(
student
,
course_key
,
course
=
course
,
generate_pdf
=
generate_pdf
)
status
,
cert
=
xqueue
.
add_cert
(
student
,
course_key
,
course
=
course
,
generate_pdf
=
generate_pdf
)
if
status
in
[
CertificateStatuses
.
generating
,
CertificateStatuses
.
downloadable
]:
emit_certificate_event
(
'created'
,
student
,
course_key
,
course
,
{
'user_id'
:
student
.
id
,
'course_id'
:
unicode
(
course_key
),
'certificate_id'
:
cert
.
verify_uuid
,
'enrollment_mode'
:
cert
.
mode
,
'generation_mode'
:
generation_mode
})
return
status
def
regenerate_user_certificates
(
student
,
course_key
,
course
=
None
,
...
...
@@ -95,11 +109,12 @@ def certificate_downloadable_status(student, course_key):
response_data
=
{
'is_downloadable'
:
False
,
'is_generating'
:
True
if
current_status
[
'status'
]
in
[
cert_status
.
generating
,
cert_status
.
error
]
else
False
,
'is_generating'
:
True
if
current_status
[
'status'
]
in
[
CertificateStatuses
.
generating
,
CertificateStatuses
.
error
]
else
False
,
'download_url'
:
None
}
if
current_status
[
'status'
]
==
cert_statu
s
.
downloadable
:
if
current_status
[
'status'
]
==
CertificateStatuse
s
.
downloadable
:
response_data
[
'is_downloadable'
]
=
True
response_data
[
'download_url'
]
=
current_status
[
'download_url'
]
...
...
@@ -259,3 +274,26 @@ def get_active_web_certificate(course, is_preview_mode=None):
if
config
.
get
(
'is_active'
)
or
is_preview_mode
:
return
config
return
None
def
emit_certificate_event
(
event_name
,
user
,
course_id
,
course
=
None
,
event_data
=
None
):
"""
Emits certificate event.
"""
event_name
=
'.'
.
join
([
'edx'
,
'certificate'
,
event_name
])
if
course
is
None
:
course
=
modulestore
()
.
get_course
(
course_id
,
depth
=
0
)
context
=
{
'org_id'
:
course
.
org
,
'course_id'
:
unicode
(
course_id
)
}
data
=
{
'user_id'
:
user
.
id
,
'course_id'
:
unicode
(
course_id
),
'certificate_url'
:
get_certificate_url
(
user
.
id
,
course_id
)
}
event_data
=
event_data
or
{}
event_data
.
update
(
data
)
with
tracker
.
get_tracker
()
.
context
(
event_name
,
context
):
tracker
.
emit
(
event_name
,
event_data
)
lms/djangoapps/certificates/models.py
View file @
c3b78ea9
...
...
@@ -81,6 +81,15 @@ class CertificateStatuses(object):
unavailable
=
'unavailable'
class
CertificateSocialNetworks
(
object
):
"""
Enum for certificate social networks
"""
linkedin
=
'LinkedIn'
facebook
=
'Facebook'
twitter
=
'Twitter'
class
CertificateWhitelist
(
models
.
Model
):
"""
Tracks students who are whitelisted, all users
...
...
@@ -139,10 +148,11 @@ class GeneratedCertificate(models.Model):
def
handle_post_cert_generated
(
sender
,
instance
,
**
kwargs
):
# pylint: disable=no-self-argument, unused-argument
"""
Handles post_save signal of GeneratedCertificate, and mark user collected
course milestone entry if user has passed the course
or certificate status is 'generating
'.
course milestone entry if user has passed the course
.
User is assumed to have passed the course if certificate status is either 'generating' or 'downloadable
'.
"""
if
settings
.
FEATURES
.
get
(
'ENABLE_PREREQUISITE_COURSES'
)
and
instance
.
status
==
CertificateStatuses
.
generating
:
allowed_cert_states
=
[
CertificateStatuses
.
generating
,
CertificateStatuses
.
downloadable
]
if
settings
.
FEATURES
.
get
(
'ENABLE_PREREQUISITE_COURSES'
)
and
instance
.
status
in
allowed_cert_states
:
fulfill_course_milestone
(
instance
.
course_id
,
instance
.
user
)
...
...
lms/djangoapps/certificates/queue.py
View file @
c3b78ea9
...
...
@@ -187,7 +187,8 @@ class XQueueCertInterface(object):
will be skipped.
generate_pdf - Boolean should a message be sent in queue to generate certificate PDF
Will change the certificate status to 'generating'.
Will change the certificate status to 'generating' or
`downloadable` in case of web view certificates.
Certificate must be in the 'unavailable', 'error',
'deleted' or 'generating' state.
...
...
@@ -201,7 +202,7 @@ class XQueueCertInterface(object):
If a student does not have a passing grade the status
will change to status.notpassing
Returns the student's status
Returns the student's status
and newly created certificate instance
"""
valid_statuses
=
[
...
...
@@ -215,6 +216,7 @@ class XQueueCertInterface(object):
cert_status
=
certificate_status_for_student
(
student
,
course_id
)[
'status'
]
new_status
=
cert_status
cert
=
None
if
cert_status
not
in
valid_statuses
:
LOGGER
.
warning
(
...
...
@@ -389,7 +391,7 @@ class XQueueCertInterface(object):
new_status
)
return
new_status
return
new_status
,
cert
def
add_example_cert
(
self
,
example_cert
):
"""Add a task to create an example certificate.
...
...
lms/djangoapps/certificates/tests/test_api.py
View file @
c3b78ea9
...
...
@@ -15,6 +15,7 @@ from student.models import CourseEnrollment
from
student.tests.factories
import
UserFactory
from
course_modes.tests.factories
import
CourseModeFactory
from
config_models.models
import
cache
from
util.testing
import
EventTestMixin
from
certificates
import
api
as
certs_api
from
certificates.models
import
(
...
...
@@ -112,15 +113,19 @@ class CertificateDownloadableStatusTests(ModuleStoreTestCase):
@attr
(
'shard_1'
)
@override_settings
(
CERT_QUEUE
=
'certificates'
)
class
GenerateUserCertificatesTest
(
ModuleStoreTestCase
):
class
GenerateUserCertificatesTest
(
EventTestMixin
,
ModuleStoreTestCase
):
"""Tests for generating certificates for students. """
ERROR_REASON
=
"Kaboom!"
def
setUp
(
self
):
super
(
GenerateUserCertificatesTest
,
self
)
.
setUp
()
super
(
GenerateUserCertificatesTest
,
self
)
.
setUp
(
'certificates.api.tracker'
)
self
.
student
=
UserFactory
()
self
.
student
=
UserFactory
.
create
(
email
=
'joe_user@edx.org'
,
username
=
'joeuser'
,
password
=
'foo'
)
self
.
student_no_cert
=
UserFactory
()
self
.
course
=
CourseFactory
.
create
(
org
=
'edx'
,
...
...
@@ -139,6 +144,15 @@ class GenerateUserCertificatesTest(ModuleStoreTestCase):
# Verify that the certificate has status 'generating'
cert
=
GeneratedCertificate
.
objects
.
get
(
user
=
self
.
student
,
course_id
=
self
.
course
.
id
)
self
.
assertEqual
(
cert
.
status
,
CertificateStatuses
.
generating
)
self
.
assert_event_emitted
(
'edx.certificate.created'
,
user_id
=
self
.
student
.
id
,
course_id
=
unicode
(
self
.
course
.
id
),
certificate_url
=
certs_api
.
get_certificate_url
(
self
.
student
.
id
,
self
.
course
.
id
),
certificate_id
=
cert
.
verify_uuid
,
enrollment_mode
=
cert
.
mode
,
generation_mode
=
'batch'
)
def
test_xqueue_submit_task_error
(
self
):
with
self
.
_mock_passing_grade
():
...
...
lms/djangoapps/certificates/tests/test_views.py
View file @
c3b78ea9
...
...
@@ -27,7 +27,8 @@ from certificates.models import (
GeneratedCertificate
,
BadgeAssertion
,
CertificateStatuses
,
CertificateHtmlViewConfiguration
CertificateHtmlViewConfiguration
,
CertificateSocialNetworks
,
)
from
certificates.tests.factories
import
(
...
...
@@ -593,12 +594,37 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
def
test_render_html_view_invalid_certificate_configuration
(
self
):
test_url
=
get_certificate_url
(
user_id
=
self
.
user
.
id
,
course_id
=
unicode
(
self
.
course
.
id
)
# pylint: disable=no-member
course_id
=
unicode
(
self
.
course
.
id
)
)
response
=
self
.
client
.
get
(
test_url
)
self
.
assertIn
(
"Invalid Certificate"
,
response
.
content
)
@override_settings
(
FEATURES
=
FEATURES_WITH_CERTS_ENABLED
)
def
test_certificate_evidence_event_emitted
(
self
):
self
.
client
.
logout
()
self
.
_add_course_certificates
(
count
=
1
,
signatory_count
=
2
)
self
.
recreate_tracker
()
test_url
=
get_certificate_url
(
user_id
=
self
.
user
.
id
,
course_id
=
unicode
(
self
.
course
.
id
)
)
response
=
self
.
client
.
get
(
test_url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
actual_event
=
self
.
get_event
()
self
.
assertEqual
(
actual_event
[
'name'
],
'edx.certificate.evidence_visited'
)
assert_event_matches
(
{
'user_id'
:
self
.
user
.
id
,
'certificate_id'
:
unicode
(
self
.
cert
.
verify_uuid
),
'enrollment_mode'
:
self
.
cert
.
mode
,
'certificate_url'
:
test_url
,
'course_id'
:
unicode
(
self
.
course
.
id
),
'social_network'
:
CertificateSocialNetworks
.
linkedin
},
actual_event
[
'data'
]
)
@override_settings
(
FEATURES
=
FEATURES_WITH_CERTS_ENABLED
)
def
test_evidence_event_sent
(
self
):
test_url
=
get_certificate_url
(
user_id
=
self
.
user
.
id
,
course_id
=
self
.
course_id
)
+
'?evidence_visit=1'
self
.
recreate_tracker
()
...
...
lms/djangoapps/certificates/views.py
View file @
c3b78ea9
...
...
@@ -17,15 +17,21 @@ from django.views.decorators.csrf import csrf_exempt
from
django.views.decorators.http
import
require_POST
from
capa.xqueue_interface
import
XQUEUE_METRIC_NAME
from
certificates.api
import
get_active_web_certificate
,
get_certificate_url
,
generate_user_certificates
from
certificates.api
import
(
get_active_web_certificate
,
get_certificate_url
,
generate_user_certificates
,
emit_certificate_event
)
from
certificates.models
import
(
certificate_status_for_student
,
CertificateStatuses
,
GeneratedCertificate
,
ExampleCertificate
,
CertificateHtmlViewConfiguration
,
BadgeAssertion
)
from
certificates.queue
import
XQueueCertInterface
CertificateSocialNetworks
,
BadgeAssertion
)
from
edxmako.shortcuts
import
render_to_response
from
util.views
import
ensure_valid_course_key
from
xmodule.modulestore.django
import
modulestore
...
...
@@ -588,6 +594,14 @@ def render_html_view(request, user_id, course_id):
if
microsite_config_key
:
context
.
update
(
configuration
.
get
(
microsite_config_key
,
{}))
# track certificate evidence_visited event for analytics when certificate_user and accessing_user are different
if
request
.
user
and
request
.
user
.
id
!=
user
.
id
:
emit_certificate_event
(
'evidence_visited'
,
user
,
course_id
,
course
,
{
'certificate_id'
:
user_certificate
.
verify_uuid
,
'enrollment_mode'
:
user_certificate
.
mode
,
'social_network'
:
CertificateSocialNetworks
.
linkedin
})
# Append/Override the existing view context values with any course-specific static values from Advanced Settings
context
.
update
(
course
.
cert_html_view_overrides
)
...
...
lms/djangoapps/courseware/views.py
View file @
c3b78ea9
...
...
@@ -1337,7 +1337,7 @@ def generate_user_cert(request, course_id):
# mark the certificate with "error" status, so it can be re-run
# with a management command. From the user's perspective,
# it will appear that the certificate task was submitted successfully.
certs_api
.
generate_user_certificates
(
student
,
course
.
id
)
certs_api
.
generate_user_certificates
(
student
,
course
.
id
,
course
=
course
,
generation_mode
=
'self'
)
_track_successful_certificate_generation
(
student
.
id
,
course
.
id
)
return
HttpResponse
()
...
...
lms/envs/common.py
View file @
c3b78ea9
...
...
@@ -1318,6 +1318,11 @@ ccx_js = sorted(rooted_glob(PROJECT_ROOT / 'static', 'js/ccx/**/*.js'))
discovery_js
=
[
'js/discovery/main.js'
]
certificates_web_view_js
=
[
'js/vendor/jquery.min.js'
,
'js/vendor/jquery.cookie.js'
,
'js/src/logger.js'
,
]
PIPELINE_CSS
=
{
'style-vendor'
:
{
...
...
@@ -1538,6 +1543,10 @@ PIPELINE_JS = {
'discovery'
:
{
'source_filenames'
:
discovery_js
,
'output_filename'
:
'js/discovery.js'
},
'certificates_wv'
:
{
'source_filenames'
:
certificates_web_view_js
,
'output_filename'
:
'js/certificates/web_view.js'
}
}
...
...
lms/templates/certificates/_accomplishment-banner.html
View file @
c3b78ea9
<
%!
from
django
.
utils
.
translation
import
ugettext
as
_
%
>
<
%
namespace
name=
'static'
file=
'../static_content.html'
/>
<
%
block
name=
"js_extra"
>
<
%
static:js
group=
'certificates_wv'
/>
<script
type=
"text/javascript"
>
$
(
document
).
ready
(
function
()
{
$
.
ajaxSetup
({
headers
:
{
'X-CSRFToken'
:
$
.
cookie
(
'csrftoken'
)
},
dataType
:
'json'
});
$
(
".action-linkedin-profile"
).
click
(
function
()
{
var
data
=
{
user_id
:
'${accomplishment_user_id}'
,
course_id
:
$
(
this
).
data
(
'course-id'
),
enrollment_mode
:
$
(
this
).
data
(
'certificate-mode'
),
certificate_id
:
'${certificate_id_number}'
,
certificate_url
:
window
.
location
.
href
,
social_network
:
'LinkedIn'
};
Logger
.
log
(
'edx.certificate.shared'
,
data
);
});
});
</script>
</
%
block>
<div
class=
"wrapper-banner wrapper-banner-user"
>
<section
class=
"banner banner-user"
>
...
...
@@ -34,4 +58,4 @@
</div>
</div>
</section>
</div>
</div>
\ No newline at end of file
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