diff --git a/lms/djangoapps/certificates/tests/test_webview_views.py b/lms/djangoapps/certificates/tests/test_webview_views.py index fadda9ce0a..90898dd2cd 100644 --- a/lms/djangoapps/certificates/tests/test_webview_views.py +++ b/lms/djangoapps/certificates/tests/test_webview_views.py @@ -212,6 +212,15 @@ class CertificatesViewsTests(CommonCertificatesTestCase): Tests for the certificates web/html views """ + def setUp(self): + super(CertificatesViewsTests, self).setUp() + self.mock_course_run_details = { + 'content_language': 'en', + 'start': '2013-02-05T05:00:00Z', + 'end': '2013-03-05T05:00:00Z', + 'max_effort': '10' + } + @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) def test_linkedin_share_url(self): """ @@ -921,7 +930,7 @@ class CertificatesViewsTests(CommonCertificatesTestCase): Tests custom template search and rendering. This test should check template matching when org={org}, course={course}, mode={mode}. """ - mock_get_course_run_details.return_value = {'content_language': 'en'} + mock_get_course_run_details.return_value = self.mock_course_run_details self._add_course_certificates(count=1, signatory_count=2) self._create_custom_named_template('test_template_1_course', org_id=1, mode='honor', course_key=unicode(self.course.id)) self._create_custom_named_template('test_template_2_course', org_id=1, mode='verified', course_key=unicode(self.course.id)) @@ -951,7 +960,7 @@ class CertificatesViewsTests(CommonCertificatesTestCase): match org and mode. This test should check template matching when org={org}, course=Null, mode={mode}. """ - mock_get_course_run_details.return_value = {'content_language': 'en'} + mock_get_course_run_details.return_value = self.mock_course_run_details othercourse = CourseFactory.create( org='cstX', number='cst_22', display_name='custom template course' ) @@ -984,7 +993,7 @@ class CertificatesViewsTests(CommonCertificatesTestCase): Tests custom template search when we have a single template for a organization. This test should check template matching when org={org}, course=Null, mode=null. """ - mock_get_course_run_details.return_value = {'content_language': 'en'} + mock_get_course_run_details.return_value = self.mock_course_run_details self._add_course_certificates(count=1, signatory_count=2) self._create_custom_named_template('test_template_1_course', org_id=1, mode=None) # Correct template self._create_custom_named_template('test_template_2_course', org_id=1, mode='verified') # wrong mode @@ -1007,7 +1016,7 @@ class CertificatesViewsTests(CommonCertificatesTestCase): Tests custom template search if we have a single template for a course mode. This test should check template matching when org=null, course=Null, mode={mode}. """ - mock_get_course_run_details.return_value = {'content_language': 'en'} + mock_get_course_run_details.return_value = self.mock_course_run_details mode = 'honor' self._add_course_certificates(count=1, signatory_count=2) self._create_custom_named_template('test_template_1_course', org_id=None, mode=mode) # Correct template @@ -1039,7 +1048,10 @@ class CertificatesViewsTests(CommonCertificatesTestCase): right_language = 'es' wrong_language = 'fr' mock_get_org_id.return_value = 1 - mock_get_course_run_details.return_value = {'content_language': 'es'} + course_run_details = self.mock_course_run_details + course_run_details.update({'content_language': 'es'}) + mock_get_course_run_details.return_value = course_run_details + CertificateGenerationCourseSetting.set_language_specific_templates_enabled_for_course(self.course.id, True) self._add_course_certificates(count=1, signatory_count=2) @@ -1082,7 +1094,9 @@ class CertificatesViewsTests(CommonCertificatesTestCase): right_language = 'es' wrong_language = 'fr' mock_get_org_id.return_value = 1 - mock_get_course_run_details.return_value = {'content_language': 'es'} + course_run_details = self.mock_course_run_details + course_run_details.update({'content_language': 'es'}) + mock_get_course_run_details.return_value = course_run_details CertificateGenerationCourseSetting.set_language_specific_templates_enabled_for_course(self.course.id, True) self._add_course_certificates(count=1, signatory_count=2) @@ -1124,7 +1138,9 @@ class CertificatesViewsTests(CommonCertificatesTestCase): right_language = 'es' wrong_language = 'fr' mock_get_org_id.return_value = 1 - mock_get_course_run_details.return_value = {'content_language': 'es'} + course_run_details = self.mock_course_run_details + course_run_details.update({'content_language': 'es'}) + mock_get_course_run_details.return_value = course_run_details CertificateGenerationCourseSetting.set_language_specific_templates_enabled_for_course(self.course.id, True) self._add_course_certificates(count=1, signatory_count=2) @@ -1165,7 +1181,9 @@ class CertificatesViewsTests(CommonCertificatesTestCase): right_language = 'es' wrong_language = 'fr' mock_get_org_id.return_value = 1 - mock_get_course_run_details.return_value = {'content_language': 'es'} + course_run_details = self.mock_course_run_details + course_run_details.update({'content_language': 'es'}) + mock_get_course_run_details.return_value = course_run_details CertificateGenerationCourseSetting.set_language_specific_templates_enabled_for_course(self.course.id, True) self._add_course_certificates(count=1, signatory_count=2) @@ -1206,7 +1224,9 @@ class CertificatesViewsTests(CommonCertificatesTestCase): right_language = 'es' wrong_language = 'fr' mock_get_org_id.return_value = 1 - mock_get_course_run_details.return_value = {'content_language': 'es-419'} + course_run_details = self.mock_course_run_details + course_run_details.update({'content_language': 'es-419'}) + mock_get_course_run_details.return_value = course_run_details CertificateGenerationCourseSetting.set_language_specific_templates_enabled_for_course(self.course.id, True) self._add_course_certificates(count=1, signatory_count=2) @@ -1242,7 +1262,7 @@ class CertificatesViewsTests(CommonCertificatesTestCase): """ Tests custom template renders properly with unicode data. """ - mock_get_course_run_details.return_value = {'content_language': 'en'} + mock_get_course_run_details.return_value = self.mock_course_run_details mode = 'honor' self._add_course_certificates(count=1, signatory_count=2) self._create_custom_template(mode=mode) @@ -1276,7 +1296,7 @@ class CertificatesViewsTests(CommonCertificatesTestCase): """ Tests certificate template asset display by slug using static.certificate_asset_url method. """ - mock_get_course_run_details.return_value = {'content_language': 'en'} + mock_get_course_run_details.return_value = self.mock_course_run_details self._add_course_certificates(count=1, signatory_count=2) self._create_custom_template(mode='honor') test_url = get_certificate_url( diff --git a/lms/djangoapps/certificates/views/webview.py b/lms/djangoapps/certificates/views/webview.py index e7c6ce3c29..22d247bd8a 100644 --- a/lms/djangoapps/certificates/views/webview.py +++ b/lms/djangoapps/certificates/views/webview.py @@ -5,6 +5,7 @@ Certificate HTML webview. import logging import urllib from datetime import datetime +from dateutil import parser from uuid import uuid4 import pytz @@ -252,7 +253,16 @@ def _update_course_context(request, context, course, course_key, platform_name): if CertificateGenerationCourseSetting.is_language_specific_templates_enabled_for_course(course_key): fields = ['start', 'end', 'max_effort', 'content_language'] course_run_data = get_course_run_details(course_key, fields) - context.update(course_run_data) + if course_run_data['start'] and course_run_data['end'] and course_run_data['max_effort']: + # Calculate duration of the course run in weeks, multiplied by max_effort for total Hours of Effort + try: + start = parser.parse(course_run_data['start']) + end = parser.parse(course_run_data['end']) + max_effort = int(course_run_data['max_effort']) + context['hours_of_effort'] = ((end - start).days / 7) * max_effort + except ValueError: + log.exception('Error occurred while parsing course run details') + context['content_language'] = course_run_data['content_language'] def _update_social_context(request, context, course, user, user_certificate, platform_name): diff --git a/openedx/core/lib/edx_api_utils.py b/openedx/core/lib/edx_api_utils.py index 85dd4dffac..00d009e201 100644 --- a/openedx/core/lib/edx_api_utils.py +++ b/openedx/core/lib/edx_api_utils.py @@ -19,12 +19,7 @@ def get_fields(fields, response): """Extracts desired fields from the API response""" results = {} for field in fields: - try: - results[field] = response[field] - # TODO: Determine what exception would be raised here if response does not have the specified field - except: - msg = '{resource} does not have the attribute {field}'.format(resource, field) - log.exception(msg) + results[field] = response.get(field) return results