Commit f3f7e78e by Sofiya Semenova

educator-1101 view/request certificate button logic on progress page and dashboard

parent 821253bf
...@@ -1565,6 +1565,7 @@ class ProgressPageTests(ProgressPageBaseTests): ...@@ -1565,6 +1565,7 @@ class ProgressPageTests(ProgressPageBaseTests):
'lms.djangoapps.grades.new.course_grade.CourseGrade.summary', 'lms.djangoapps.grades.new.course_grade.CourseGrade.summary',
PropertyMock(return_value={'grade': 'Pass', 'percent': 0.75, 'section_breakdown': [], 'grade_breakdown': {}}) PropertyMock(return_value={'grade': 'Pass', 'percent': 0.75, 'section_breakdown': [], 'grade_breakdown': {}})
) )
@patch('courseware.views.views.is_course_passed', PropertyMock(return_value=True))
def test_message_for_audit_mode(self): def test_message_for_audit_mode(self):
""" Verify that message appears on progress page, if learner is enrolled """ Verify that message appears on progress page, if learner is enrolled
in audit mode. in audit mode.
...@@ -1579,6 +1580,7 @@ class ProgressPageTests(ProgressPageBaseTests): ...@@ -1579,6 +1580,7 @@ class ProgressPageTests(ProgressPageBaseTests):
u'You are enrolled in the audit track for this course. The audit track does not include a certificate.' u'You are enrolled in the audit track for this course. The audit track does not include a certificate.'
) )
@patch('courseware.views.views.is_course_passed', PropertyMock(return_value=True))
def test_invalidated_cert_data(self): def test_invalidated_cert_data(self):
""" """
Verify that invalidated cert data is returned if cert is invalidated. Verify that invalidated cert data is returned if cert is invalidated.
...@@ -1597,6 +1599,7 @@ class ProgressPageTests(ProgressPageBaseTests): ...@@ -1597,6 +1599,7 @@ class ProgressPageTests(ProgressPageBaseTests):
self.assertEqual(response.cert_status, 'invalidated') self.assertEqual(response.cert_status, 'invalidated')
self.assertEqual(response.title, 'Your certificate has been invalidated') self.assertEqual(response.title, 'Your certificate has been invalidated')
@patch('courseware.views.views.is_course_passed', PropertyMock(return_value=True))
def test_downloadable_get_cert_data(self): def test_downloadable_get_cert_data(self):
""" """
Verify that downloadable cert data is returned if cert is downloadable. Verify that downloadable cert data is returned if cert is downloadable.
...@@ -1611,6 +1614,7 @@ class ProgressPageTests(ProgressPageBaseTests): ...@@ -1611,6 +1614,7 @@ class ProgressPageTests(ProgressPageBaseTests):
self.assertEqual(response.cert_status, 'downloadable') self.assertEqual(response.cert_status, 'downloadable')
self.assertEqual(response.title, 'Your certificate is available') self.assertEqual(response.title, 'Your certificate is available')
@patch('courseware.views.views.is_course_passed', PropertyMock(return_value=True))
def test_generating_get_cert_data(self): def test_generating_get_cert_data(self):
""" """
Verify that generating cert data is returned if cert is generating. Verify that generating cert data is returned if cert is generating.
...@@ -1625,6 +1629,7 @@ class ProgressPageTests(ProgressPageBaseTests): ...@@ -1625,6 +1629,7 @@ class ProgressPageTests(ProgressPageBaseTests):
self.assertEqual(response.cert_status, 'generating') self.assertEqual(response.cert_status, 'generating')
self.assertEqual(response.title, "We're working on it...") self.assertEqual(response.title, "We're working on it...")
@patch('courseware.views.views.is_course_passed', PropertyMock(return_value=True))
def test_unverified_get_cert_data(self): def test_unverified_get_cert_data(self):
""" """
Verify that unverified cert data is returned if cert is unverified. Verify that unverified cert data is returned if cert is unverified.
...@@ -1639,6 +1644,7 @@ class ProgressPageTests(ProgressPageBaseTests): ...@@ -1639,6 +1644,7 @@ class ProgressPageTests(ProgressPageBaseTests):
self.assertEqual(response.cert_status, 'unverified') self.assertEqual(response.cert_status, 'unverified')
self.assertEqual(response.title, "Certificate unavailable") self.assertEqual(response.title, "Certificate unavailable")
@patch('courseware.views.views.is_course_passed', PropertyMock(return_value=True))
def test_request_get_cert_data(self): def test_request_get_cert_data(self):
""" """
Verify that requested cert data is returned if cert is to be requested. Verify that requested cert data is returned if cert is to be requested.
......
...@@ -77,6 +77,7 @@ from openedx.core.djangoapps.credit.api import ( ...@@ -77,6 +77,7 @@ from openedx.core.djangoapps.credit.api import (
is_credit_course, is_credit_course,
is_user_eligible_for_credit is_user_eligible_for_credit
) )
from openedx.core.djangoapps.certificates.config import waffle as certificates_waffle
from openedx.core.djangoapps.models.course_details import CourseDetails from openedx.core.djangoapps.models.course_details import CourseDetails
from openedx.core.djangoapps.monitoring_utils import set_custom_metrics_for_course_key from openedx.core.djangoapps.monitoring_utils import set_custom_metrics_for_course_key
from openedx.core.djangoapps.plugin_api.views import EdxFragmentView from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
...@@ -888,9 +889,8 @@ def _progress(request, course_key, student_id): ...@@ -888,9 +889,8 @@ def _progress(request, course_key, student_id):
'masquerade': masquerade, 'masquerade': masquerade,
'supports_preview_menu': True, 'supports_preview_menu': True,
'student': student, 'student': student,
'passed': is_course_passed(course, grade_summary),
'credit_course_requirements': _credit_course_requirements(course_key, student), 'credit_course_requirements': _credit_course_requirements(course_key, student),
'certificate_data': _get_cert_data(student, course, course_key, is_active, enrollment_mode), 'certificate_data': _get_cert_data(student, course, course_key, is_active, enrollment_mode, grade_summary),
} }
context.update( context.update(
get_experiment_user_metadata_context( get_experiment_user_metadata_context(
...@@ -905,7 +905,7 @@ def _progress(request, course_key, student_id): ...@@ -905,7 +905,7 @@ def _progress(request, course_key, student_id):
return response return response
def _get_cert_data(student, course, course_key, is_active, enrollment_mode): def _get_cert_data(student, course, course_key, is_active, enrollment_mode, grade_summary=None):
"""Returns students course certificate related data. """Returns students course certificate related data.
Arguments: Arguments:
...@@ -914,13 +914,14 @@ def _get_cert_data(student, course, course_key, is_active, enrollment_mode): ...@@ -914,13 +914,14 @@ def _get_cert_data(student, course, course_key, is_active, enrollment_mode):
course_key (CourseKey): Course identifier for course. course_key (CourseKey): Course identifier for course.
is_active (Bool): Boolean value to check if course is active. is_active (Bool): Boolean value to check if course is active.
enrollment_mode (String): Course mode in which student is enrolled. enrollment_mode (String): Course mode in which student is enrolled.
grade_summary (dict): Student grade details.
Returns: Returns:
returns dict if course certificate is available else None. returns dict if course certificate is available else None.
""" """
from lms.djangoapps.courseware.courses import get_course_by_id from lms.djangoapps.courseware.courses import get_course_by_id
if enrollment_mode == CourseMode.AUDIT: if not CourseMode.is_eligible_for_certificate(enrollment_mode):
return CertData( return CertData(
CertificateStatuses.audit_passing, CertificateStatuses.audit_passing,
_('Your enrollment: Audit track'), _('Your enrollment: Audit track'),
...@@ -937,14 +938,22 @@ def _get_cert_data(student, course, course_key, is_active, enrollment_mode): ...@@ -937,14 +938,22 @@ def _get_cert_data(student, course, course_key, is_active, enrollment_mode):
course = get_course_by_id(course_key) course = get_course_by_id(course_key)
may_view_certificate = course.self_paced or course.may_certify() may_view_certificate = course.self_paced or course.may_certify()
show_message = all([ switches = certificates_waffle.waffle()
switches_enabled = (switches.is_enabled(certificates_waffle.SELF_PACED_ONLY) and
switches.is_enabled(certificates_waffle.INSTRUCTOR_PACED_ONLY))
student_cert_generation_enabled = certs_api.cert_generation_enabled(course_key) if not switches_enabled else True
# Don't show certificate information if:
# 1) the learner has not passed the course
# 2) the course is not active
# 3) auto-generated certs flags are not enabled, but student cert generation is not enabled either
# 4) the learner may not view the certificate, based on the course's advanced course settings.
if not all([
is_course_passed(course, grade_summary),
is_active, is_active,
CourseMode.is_eligible_for_certificate(enrollment_mode), student_cert_generation_enabled,
certs_api.cert_generation_enabled(course_key),
may_view_certificate may_view_certificate
]) ]):
if not show_message:
return None return None
if certs_api.is_certificate_invalid(student, course_key): if certs_api.is_certificate_invalid(student, course_key):
...@@ -958,53 +967,44 @@ def _get_cert_data(student, course, course_key, is_active, enrollment_mode): ...@@ -958,53 +967,44 @@ def _get_cert_data(student, course, course_key, is_active, enrollment_mode):
cert_downloadable_status = certs_api.certificate_downloadable_status(student, course_key) cert_downloadable_status = certs_api.certificate_downloadable_status(student, course_key)
generating_certificate_message = CertData(
CertificateStatuses.generating,
_("We're working on it..."),
_(
"We're creating your certificate. You can keep working in your courses and a link "
"to it will appear here and on your Dashboard when it is ready."
),
download_url=None,
cert_web_view_url=None
)
if cert_downloadable_status['is_downloadable']: if cert_downloadable_status['is_downloadable']:
cert_status = CertificateStatuses.downloadable
title = _('Your certificate is available')
msg = _("You've earned a certificate for this course.")
if certs_api.has_html_certificates_enabled(course_key, course): if certs_api.has_html_certificates_enabled(course_key, course):
if certs_api.get_active_web_certificate(course) is not None: if certs_api.get_active_web_certificate(course) is not None:
cert_web_view_url = certs_api.get_certificate_url(
course_id=course_key, uuid=cert_downloadable_status['uuid']
)
return CertData( return CertData(
cert_status, CertificateStatuses.downloadable,
title, _('Your certificate is available'),
msg, _("You've earned a certificate for this course."),
download_url=None, download_url=None,
cert_web_view_url=cert_web_view_url cert_web_view_url=certs_api.get_certificate_url(
course_id=course_key, uuid=cert_downloadable_status['uuid']
)
) )
else: else:
return CertData( # If there is an error, the user should see the generating certificate message
CertificateStatuses.generating, # until a new certificate is generated.
_("We're working on it..."), return generating_certificate_message
_(
"We're creating your certificate. You can keep working in your courses and a link "
"to it will appear here and on your Dashboard when it is ready."
),
download_url=None,
cert_web_view_url=None
)
return CertData( return CertData(
cert_status, CertificateStatuses.downloadable,
title, _('Your certificate is available'),
msg, _("You've earned a certificate for this course."),
download_url=cert_downloadable_status['download_url'], download_url=cert_downloadable_status['download_url'],
cert_web_view_url=None cert_web_view_url=None
) )
if cert_downloadable_status['is_generating']: if cert_downloadable_status['is_generating']:
return CertData( return generating_certificate_message
CertificateStatuses.generating,
_("We're working on it..."),
_(
"We're creating your certificate. You can keep working in your courses and a link to "
"it will appear here and on your Dashboard when it is ready."
),
download_url=None,
cert_web_view_url=None
)
# If the learner is in verified modes and the student did not have # If the learner is in verified modes and the student did not have
# their ID verified, we need to show message to ask learner to verify their ID first # their ID verified, we need to show message to ask learner to verify their ID first
......
...@@ -56,10 +56,9 @@ from django.utils.http import urlquote_plus ...@@ -56,10 +56,9 @@ from django.utils.http import urlquote_plus
${_("Course Progress for Student '{username}' ({email})").format(username=student.username, email=student.email)} ${_("Course Progress for Student '{username}' ({email})").format(username=student.username, email=student.email)}
</h2> </h2>
%if certificate_data:
<div class="wrapper-msg wrapper-auto-cert"> <div class="wrapper-msg wrapper-auto-cert">
<div id="errors-info" class="errors-info"></div> <div id="errors-info" class="errors-info"></div>
%if passed: %if certificate_data:
<div class="auto-cert-message" id="course-success"> <div class="auto-cert-message" id="course-success">
<div class="has-actions"> <div class="has-actions">
<% post_url = reverse('generate_user_cert', args=[unicode(course.id)]) %> <% post_url = reverse('generate_user_cert', args=[unicode(course.id)]) %>
...@@ -80,7 +79,6 @@ from django.utils.http import urlquote_plus ...@@ -80,7 +79,6 @@ from django.utils.http import urlquote_plus
</div> </div>
%endif %endif
</div> </div>
%endif
%if not course.disable_progress_graph: %if not course.disable_progress_graph:
<div class="grade-detail-graph" id="grade-detail-graph"></div> <div class="grade-detail-graph" id="grade-detail-graph"></div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment