From fbc8a13410be9046303ed5be24be618ed4c95d82 Mon Sep 17 00:00:00 2001 From: Zia Fazal Date: Mon, 2 Nov 2015 17:25:37 +0500 Subject: [PATCH] convert string to bytestring before passing it to urllib.quote_plus further improvement in handling of unicode data --- .../certificates/tests/test_webview_views.py | 36 +++++++++++++++++++ lms/djangoapps/certificates/views/webview.py | 23 ++++++++---- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/lms/djangoapps/certificates/tests/test_webview_views.py b/lms/djangoapps/certificates/tests/test_webview_views.py index 0e52758b72..44dc9223ea 100644 --- a/lms/djangoapps/certificates/tests/test_webview_views.py +++ b/lms/djangoapps/certificates/tests/test_webview_views.py @@ -1,6 +1,8 @@ +# -*- coding: utf-8 -*- """Tests for certificates views. """ import json +import ddt from uuid import uuid4 from nose.plugins.attrib import attr from mock import patch @@ -48,6 +50,7 @@ FEATURES_WITH_CUSTOM_CERTS_ENABLED.update(FEATURES_WITH_CERTS_ENABLED) @attr('shard_1') +@ddt.ddt class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): """ Tests for the certificates web/html views @@ -133,6 +136,7 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): course name: ${accomplishment_copy_course_name} mode: ${course_mode} ${accomplishment_copy_course_description} + ${twitter_url} """ @@ -615,3 +619,35 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): response = self.client.get(test_url) self.assertEqual(response.status_code, 200) self.assertContains(response, 'mode: {}'.format(mode)) + + @ddt.data(True, False) + def test_certificate_custom_template_with_unicode_data(self, custom_certs_enabled): + """ + Tests custom template renders properly with unicode data. + """ + mode = 'honor' + self._add_course_certificates(count=1, signatory_count=2) + self._create_custom_template(mode=mode) + with patch.dict("django.conf.settings.FEATURES", { + "CERTIFICATES_HTML_VIEW": True, + "CUSTOM_CERTIFICATE_TEMPLATES_ENABLED": custom_certs_enabled + }): + test_url = get_certificate_url( + user_id=self.user.id, + course_id=unicode(self.course.id) + ) + with patch.dict("django.conf.settings.SOCIAL_SHARING_SETTINGS", { + "CERTIFICATE_TWITTER": True, + "CERTIFICATE_TWITTER_TEXT": u"nền tảng học tập" + }): + with patch('django.http.HttpRequest.build_absolute_uri') as mock_abs_uri: + mock_abs_uri.return_value = '='.join(['http://localhost/?param', u'é']) + with patch('certificates.api.get_course_organizations') as mock_get_orgs: + mock_get_orgs.return_value = [] + response = self.client.get(test_url) + self.assertEqual(response.status_code, 200) + if custom_certs_enabled: + self.assertContains(response, 'mode: {}'.format(mode)) + else: + self.assertContains(response, "Tweet this Accomplishment") + self.assertContains(response, 'https://twitter.com/intent/tweet') diff --git a/lms/djangoapps/certificates/views/webview.py b/lms/djangoapps/certificates/views/webview.py index 6377648d82..e075e1378a 100644 --- a/lms/djangoapps/certificates/views/webview.py +++ b/lms/djangoapps/certificates/views/webview.py @@ -11,6 +11,7 @@ from django.contrib.auth.models import User from django.http import HttpResponse from django.template import RequestContext from django.utils.translation import ugettext as _ +from django.utils.encoding import smart_str from django.core.urlresolvers import reverse from courseware.courses import course_image_url @@ -416,10 +417,12 @@ def render_html_view(request, user_id, course_id): ) ) context['share_url'] = share_url - twitter_url = 'https://twitter.com/intent/tweet?text={twitter_share_text}&url={share_url}'.format( - twitter_share_text=context['twitter_share_text'], - share_url=urllib.quote_plus(share_url) - ) + twitter_url = '' + if context.get('twitter_share_enabled', False): + twitter_url = 'https://twitter.com/intent/tweet?text={twitter_share_text}&url={share_url}'.format( + twitter_share_text=smart_str(context['twitter_share_text']), + share_url=urllib.quote_plus(smart_str(share_url)) + ) context['twitter_url'] = twitter_url context['full_course_image_url'] = request.build_absolute_uri(course_image_url(course)) @@ -432,10 +435,10 @@ def render_html_view(request, user_id, course_id): course.id, course.display_name, user_certificate.mode, - request.build_absolute_uri(get_certificate_url( + smart_str(request.build_absolute_uri(get_certificate_url( user_id=user.id, course_id=unicode(course.id) - )) + ))) ) else: context['linked_in_url'] = None @@ -471,7 +474,13 @@ def render_html_view(request, user_id, course_id): if settings.FEATURES.get('CUSTOM_CERTIFICATE_TEMPLATES_ENABLED', False): custom_template = get_certificate_template(course_key, user_certificate.mode) if custom_template: - template = Template(custom_template) + template = Template( + custom_template, + output_encoding='utf-8', + input_encoding='utf-8', + default_filters=['decode.utf8'], + encoding_errors='replace', + ) context = RequestContext(request, context) return HttpResponse(template.render(context))