diff --git a/common/djangoapps/student/tests/test_certificates.py b/common/djangoapps/student/tests/test_certificates.py index 03d5b66e00..dea4192a90 100644 --- a/common/djangoapps/student/tests/test_certificates.py +++ b/common/djangoapps/student/tests/test_certificates.py @@ -59,8 +59,7 @@ class CertificateDisplayTest(ModuleStoreTestCase): def test_linked_student_to_web_view_credential(self, enrollment_mode): test_url = get_certificate_url( user_id=self.user.id, - course_id=unicode(self.course.id), - verify_uuid='abcdefg12345678' + course_id=unicode(self.course.id) ) self._create_certificate(enrollment_mode) diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index 1420aa5432..20c3e6d3ae 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -309,8 +309,7 @@ def _cert_info(user, course, cert_status, course_mode): if get_active_web_certificate(course) is not None: certificate_url = get_certificate_url( user_id=user.id, - course_id=unicode(course.id), - verify_uuid=None + course_id=unicode(course.id) ) status_dict.update({ 'show_cert_web_view': True, diff --git a/lms/djangoapps/certificates/api.py b/lms/djangoapps/certificates/api.py index 58b2b48a9f..b0e352588f 100644 --- a/lms/djangoapps/certificates/api.py +++ b/lms/djangoapps/certificates/api.py @@ -10,6 +10,7 @@ from django.conf import settings from django.core.urlresolvers import reverse from eventtracking import tracker +from opaque_keys.edx.keys import CourseKey from xmodule.modulestore.django import modulestore @@ -18,7 +19,8 @@ from certificates.models import ( certificate_status_for_student, CertificateGenerationCourseSetting, CertificateGenerationConfiguration, - ExampleCertificateSet + ExampleCertificateSet, + GeneratedCertificate ) from certificates.queue import XQueueCertInterface @@ -253,18 +255,32 @@ def example_certificates_status(course_key): # pylint: disable=no-member -def get_certificate_url(user_id, course_id, verify_uuid): +def get_certificate_url(user_id, course_id): """ :return certificate url """ + url = "" if settings.FEATURES.get('CERTIFICATES_HTML_VIEW', False): - return u'{url}'.format( - url=reverse( - 'cert_html_view', - kwargs=dict(user_id=str(user_id), course_id=unicode(course_id)) - ) + url = reverse( + 'cert_html_view', kwargs=dict(user_id=str(user_id), course_id=unicode(course_id)) ) - return '{url}{uuid}'.format(url=settings.CERTIFICATES_STATIC_VERIFY_URL, uuid=verify_uuid) + else: + try: + if isinstance(course_id, basestring): + course_id = CourseKey.from_string(course_id) + user_certificate = GeneratedCertificate.objects.get( + user=user_id, + course_id=course_id + ) + url = user_certificate.download_url + except GeneratedCertificate.DoesNotExist: + log.critical( + 'Unable to lookup certificate\n' + 'user id: %d\n' + 'course: %s', user_id, unicode(course_id) + ) + + return url def get_active_web_certificate(course, is_preview_mode=None): @@ -293,7 +309,7 @@ def emit_certificate_event(event_name, user, course_id, course=None, event_data= data = { 'user_id': user.id, 'course_id': unicode(course_id), - 'certificate_url': get_certificate_url(user.id, course_id, event_data['certificate_id']) + 'certificate_url': get_certificate_url(user.id, course_id) } event_data = event_data or {} event_data.update(data) diff --git a/lms/djangoapps/certificates/tests/test_api.py b/lms/djangoapps/certificates/tests/test_api.py index 043bdf6639..bc3f100665 100644 --- a/lms/djangoapps/certificates/tests/test_api.py +++ b/lms/djangoapps/certificates/tests/test_api.py @@ -148,7 +148,7 @@ class GenerateUserCertificatesTest(EventTestMixin, ModuleStoreTestCase): '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, cert.verify_uuid), + 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' @@ -177,6 +177,14 @@ class GenerateUserCertificatesTest(EventTestMixin, ModuleStoreTestCase): cert = GeneratedCertificate.objects.get(user=self.student, course_id=self.course.id) self.assertEqual(cert.status, CertificateStatuses.downloadable) + @patch.dict(settings.FEATURES, {'CERTIFICATES_HTML_VIEW': False}) + def test_cert_url_empty_with_invalid_certificate(self): + """ + Test certificate url is empty if html view is not enabled and certificate is not yet generated + """ + url = certs_api.get_certificate_url(self.student.id, self.course.id) + self.assertEqual(url, "") + @contextmanager def _mock_passing_grade(self): """Mock the grading function to always return a passing grade. """ diff --git a/lms/djangoapps/certificates/tests/test_views.py b/lms/djangoapps/certificates/tests/test_views.py index e4f3eb7b80..c8ebbaa4ee 100644 --- a/lms/djangoapps/certificates/tests/test_views.py +++ b/lms/djangoapps/certificates/tests/test_views.py @@ -308,8 +308,7 @@ class MicrositeCertificatesViewsTests(ModuleStoreTestCase): self.assertEquals(config.configuration, test_configuration_string) test_url = get_certificate_url( user_id=self.user.id, - course_id=unicode(self.course.id), - verify_uuid=self.cert.verify_uuid + course_id=unicode(self.course.id) ) self._add_course_certificates(count=1, signatory_count=2) response = self.client.get(test_url) @@ -319,6 +318,7 @@ class MicrositeCertificatesViewsTests(ModuleStoreTestCase): self.assertIn('Microsite title', response.content) @patch("microsite_configuration.microsite.get_value", fakemicrosite) + @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) def test_html_view_microsite_configuration_missing(self): test_configuration_string = """{ "default": { @@ -342,8 +342,7 @@ class MicrositeCertificatesViewsTests(ModuleStoreTestCase): self.assertEquals(config.configuration, test_configuration_string) test_url = get_certificate_url( user_id=self.user.id, - course_id=unicode(self.course.id), - verify_uuid=self.cert.verify_uuid + course_id=unicode(self.course.id) ) self._add_course_certificates(count=1, signatory_count=2) response = self.client.get(test_url) @@ -379,6 +378,7 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): course_id=self.course_id, verify_uuid=uuid4(), download_uuid=uuid4(), + download_url="http://www.example.com/certificates/download", grade="0.95", key='the_key', distinction=True, @@ -429,8 +429,7 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): def test_render_html_view_valid_certificate(self): test_url = get_certificate_url( user_id=self.user.id, - course_id=unicode(self.course.id), - verify_uuid=self.cert.verify_uuid + course_id=unicode(self.course.id) ) self._add_course_certificates(count=1, signatory_count=2) response = self.client.get(test_url) @@ -452,8 +451,7 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): def test_render_html_view_with_valid_signatories(self): test_url = get_certificate_url( user_id=self.user.id, - course_id=unicode(self.course.id), - verify_uuid=self.cert.verify_uuid + course_id=unicode(self.course.id) ) self._add_course_certificates(count=1, signatory_count=2) response = self.client.get(test_url) @@ -469,8 +467,7 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): # if certificate in descriptor has not course_title then course name should not be overridden with this title. test_url = get_certificate_url( user_id=self.user.id, - course_id=unicode(self.course.id), - verify_uuid=self.cert.verify_uuid + course_id=unicode(self.course.id) ) test_certificates = [ { @@ -493,8 +490,7 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): def test_certificate_view_without_org_logo(self): test_url = get_certificate_url( user_id=self.user.id, - course_id=unicode(self.course.id), - verify_uuid=self.cert.verify_uuid + course_id=unicode(self.course.id) ) test_certificates = [ { @@ -516,8 +512,7 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): def test_render_html_view_without_signatories(self): test_url = get_certificate_url( user_id=self.user.id, - course_id=unicode(self.course), - verify_uuid=self.cert.verify_uuid + course_id=unicode(self.course) ) self._add_course_certificates(count=1, signatory_count=0) response = self.client.get(test_url) @@ -528,17 +523,15 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): def test_render_html_view_disabled_feature_flag_returns_static_url(self): test_url = get_certificate_url( user_id=self.user.id, - course_id=unicode(self.course.id), - verify_uuid=self.cert.verify_uuid + course_id=unicode(self.course.id) ) - self.assertIn(str(self.cert.verify_uuid), test_url) + self.assertIn(str(self.cert.download_url), test_url) @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) def test_render_html_view_invalid_course_id(self): test_url = get_certificate_url( user_id=self.user.id, - course_id='az/23423/4vs', - verify_uuid=self.cert.verify_uuid + course_id='az/23423/4vs' ) response = self.client.get(test_url) @@ -548,8 +541,7 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): def test_render_html_view_invalid_course(self): test_url = get_certificate_url( user_id=self.user.id, - course_id='missing/course/key', - verify_uuid=self.cert.verify_uuid + course_id='missing/course/key' ) response = self.client.get(test_url) self.assertIn('invalid', response.content) @@ -558,8 +550,7 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): def test_render_html_view_invalid_user(self): test_url = get_certificate_url( user_id=111, - course_id=unicode(self.course.id), - verify_uuid=self.cert.verify_uuid + course_id=unicode(self.course.id) ) response = self.client.get(test_url) self.assertIn('invalid', response.content) @@ -570,8 +561,7 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): self.assertEqual(len(GeneratedCertificate.objects.all()), 0) test_url = get_certificate_url( user_id=self.user.id, - course_id=unicode(self.course.id), - verify_uuid=self.cert.verify_uuid + course_id=unicode(self.course.id) ) response = self.client.get(test_url) self.assertIn('invalid', response.content) @@ -587,8 +577,7 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): self._add_course_certificates(count=1, signatory_count=2) test_url = get_certificate_url( user_id=self.user.id, - course_id=unicode(self.course.id), - verify_uuid=self.cert.verify_uuid + course_id=unicode(self.course.id) ) response = self.client.get(test_url + '?preview=honor') self.assertNotIn(self.course.display_name, response.content) @@ -606,8 +595,7 @@ 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), - verify_uuid=self.cert.verify_uuid + course_id=unicode(self.course.id) ) response = self.client.get(test_url) self.assertIn("Invalid Certificate", response.content) @@ -619,8 +607,7 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): self.recreate_tracker() test_url = get_certificate_url( user_id=self.user.id, - course_id=unicode(self.course.id), - verify_uuid=self.cert.verify_uuid + course_id=unicode(self.course.id) ) response = self.client.get(test_url) self.assertEqual(response.status_code, 200) @@ -642,8 +629,7 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): def test_evidence_event_sent(self): cert_url = get_certificate_url( user_id=self.user.id, - course_id=self.course_id, - verify_uuid=self.cert.verify_uuid + course_id=self.course_id ) test_url = '{}?evidence_visit=1'.format(cert_url) self.recreate_tracker() diff --git a/lms/djangoapps/certificates/views.py b/lms/djangoapps/certificates/views.py index 7d0c7bf40a..c11be79ee3 100644 --- a/lms/djangoapps/certificates/views.py +++ b/lms/djangoapps/certificates/views.py @@ -439,8 +439,7 @@ def _update_certificate_context(context, course, user, user_certificate): user_certificate.mode, get_certificate_url( user_id=user.id, - course_id=unicode(course.id), - verify_uuid=user_certificate.verify_uuid + course_id=unicode(course.id) ) ) diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index e5b69c0952..ff07c49950 100644 --- a/lms/djangoapps/courseware/tests/test_views.py +++ b/lms/djangoapps/courseware/tests/test_views.py @@ -861,8 +861,7 @@ class ProgressPageTests(ModuleStoreTestCase): self.assertContains(resp, u"You can now view your certificate") cert_url = certs_api.get_certificate_url( user_id=self.user.id, - course_id=self.course.id, - verify_uuid=certificate.verify_uuid + course_id=self.course.id ) self.assertContains(resp, cert_url) diff --git a/lms/djangoapps/courseware/views.py b/lms/djangoapps/courseware/views.py index de5252bbfe..2896dad7a6 100644 --- a/lms/djangoapps/courseware/views.py +++ b/lms/djangoapps/courseware/views.py @@ -1088,8 +1088,7 @@ def _progress(request, course_key, student_id): 'cert_web_view_url': u'{url}'.format( url=certs_api.get_certificate_url( user_id=student.id, - course_id=unicode(course.id), - verify_uuid=None + course_id=unicode(course.id) ) ) }) diff --git a/lms/envs/aws.py b/lms/envs/aws.py index 5a497f425f..c11231db00 100644 --- a/lms/envs/aws.py +++ b/lms/envs/aws.py @@ -668,9 +668,6 @@ EDXNOTES_INTERNAL_API = ENV_TOKENS.get('EDXNOTES_INTERNAL_API', EDXNOTES_INTERNA CREDIT_PROVIDER_SECRET_KEYS = AUTH_TOKENS.get("CREDIT_PROVIDER_SECRET_KEYS", {}) -############ CERTIFICATE VERIFICATION URL (STATIC FILES) ########### -ENV_TOKENS.get('CERTIFICATES_STATIC_VERIFY_URL', CERTIFICATES_STATIC_VERIFY_URL) - ##################### LTI Provider ##################### if FEATURES.get('ENABLE_LTI_PROVIDER'): INSTALLED_APPS += ('lti_provider',) diff --git a/lms/envs/common.py b/lms/envs/common.py index 63cb891399..fb747bbbf0 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -2098,9 +2098,6 @@ REGISTRATION_EXTRA_FIELDS = { CERT_NAME_SHORT = "Certificate" CERT_NAME_LONG = "Certificate of Achievement" -############ CERTIFICATE VERIFICATION URL (STATIC FILES) ########### -CERTIFICATES_STATIC_VERIFY_URL = "https://verify-test.edx.org/cert/" - #################### Badgr OpenBadges generation ####################### # Be sure to set up images for course modes using the BadgeImageConfiguration model in the certificates app. BADGR_API_TOKEN = None