From 344c72b3e2d045a946df90d30a222b4ad2531d26 Mon Sep 17 00:00:00 2001 From: Matjaz Gregoric <mtyaka@gmail.com> Date: Sun, 18 Sep 2016 12:59:03 +0200 Subject: [PATCH] Use non-ascii PLATFORM_NAME in tests. It should help catch unicode encoding problems earlier. This also updates python-saml dependency to a version that includes a patch for unicode strings. --- cms/djangoapps/contentstore/tests/tests.py | 2 +- cms/djangoapps/contentstore/views/tests/test_programs.py | 2 +- cms/djangoapps/maintenance/tests.py | 2 +- cms/envs/bok_choy.env.json | 2 +- common/djangoapps/external_auth/tests/test_shib.py | 2 +- common/djangoapps/microsite_configuration/tests/test_microsites.py | 6 +++--- common/djangoapps/student/tests/test_email.py | 8 ++++---- common/djangoapps/student/tests/test_linkedin.py | 18 +++++++++++------- common/djangoapps/student/tests/test_login.py | 2 +- common/djangoapps/student/tests/tests.py | 13 +++++++------ common/djangoapps/third_party_auth/tests/test_views.py | 7 +++++-- common/test/acceptance/tests/lms/test_lms.py | 10 ++++++++-- common/test/acceptance/tests/studio/test_studio_outline.py | 11 +++++++---- lms/djangoapps/bulk_email/tests/test_email.py | 3 ++- lms/djangoapps/certificates/tests/test_webview_views.py | 2 +- lms/djangoapps/courseware/features/lti.py | 8 +++++++- lms/djangoapps/courseware/tests/test_views.py | 4 ++-- lms/djangoapps/courseware/views/views.py | 40 +++++++++++++++++++++++----------------- lms/djangoapps/shoppingcart/tests/test_models.py | 2 +- lms/djangoapps/static_template_view/tests/test_views.py | 2 +- lms/djangoapps/verify_student/tests/test_views.py | 2 +- lms/envs/bok_choy.env.json | 2 +- lms/envs/test.py | 3 ++- openedx/core/djangoapps/api_admin/widgets.py | 2 +- openedx/core/djangoapps/user_api/tests/test_views.py | 35 +++++++++++++++++++---------------- requirements/edx/post.txt | 12 +++++++----- 26 files changed, 119 insertions(+), 83 deletions(-) diff --git a/cms/djangoapps/contentstore/tests/tests.py b/cms/djangoapps/contentstore/tests/tests.py index 386bbbd..5c18e04 100644 --- a/cms/djangoapps/contentstore/tests/tests.py +++ b/cms/djangoapps/contentstore/tests/tests.py @@ -236,7 +236,7 @@ class AuthTestCase(ContentStoreTestCase): # check the the HTML has links to the right login page. Note that this is merely a content # check and thus could be fragile should the wording change on this page expected = 'You can now <a href="' + reverse('login') + '">sign in</a>.' - self.assertIn(expected, resp.content) + self.assertIn(expected, resp.content.decode('utf-8')) def test_private_pages_auth(self): """Make sure pages that do require login work.""" diff --git a/cms/djangoapps/contentstore/views/tests/test_programs.py b/cms/djangoapps/contentstore/views/tests/test_programs.py index b2f4db0..0d6dff1 100644 --- a/cms/djangoapps/contentstore/views/tests/test_programs.py +++ b/cms/djangoapps/contentstore/views/tests/test_programs.py @@ -64,7 +64,7 @@ class TestProgramListing(ProgramsApiConfigMixin, ProgramsDataMixin, SharedModule self.mock_programs_api(data={'results': []}) response = self.client.get(self.studio_home) - self.assertIn(Text("You haven't created any programs yet."), response.content) + self.assertIn(Text("You haven't created any programs yet."), response.content.decode('utf-8')) # When data is provided, expect a program listing. self.mock_programs_api() diff --git a/cms/djangoapps/maintenance/tests.py b/cms/djangoapps/maintenance/tests.py index a10eede..08a5c08 100644 --- a/cms/djangoapps/maintenance/tests.py +++ b/cms/djangoapps/maintenance/tests.py @@ -120,7 +120,7 @@ class MaintenanceViewAccessTests(MaintenanceViewTestCase): response = self.client.get(url) self.assertContains( response, - 'Must be {platform_name} staff to perform this action.'.format(platform_name=settings.PLATFORM_NAME), + u'Must be {platform_name} staff to perform this action.'.format(platform_name=settings.PLATFORM_NAME), status_code=403 ) diff --git a/cms/envs/bok_choy.env.json b/cms/envs/bok_choy.env.json index 068c750..3819be7 100644 --- a/cms/envs/bok_choy.env.json +++ b/cms/envs/bok_choy.env.json @@ -97,7 +97,7 @@ "LOG_DIR": "** OVERRIDDEN **", "MEDIA_URL": "/media/", "MKTG_URL_LINK_MAP": {}, - "PLATFORM_NAME": "edX", + "PLATFORM_NAME": "édX", "SERVER_EMAIL": "devops@example.com", "SESSION_COOKIE_DOMAIN": null, "SITE_NAME": "localhost", diff --git a/common/djangoapps/external_auth/tests/test_shib.py b/common/djangoapps/external_auth/tests/test_shib.py index 62615bb..bfd4511 100644 --- a/common/djangoapps/external_auth/tests/test_shib.py +++ b/common/djangoapps/external_auth/tests/test_shib.py @@ -209,7 +209,7 @@ class ShibSPTest(CacheIsolationTestCase): else: self.assertEqual(response.status_code, 200) self.assertContains(response, - ("Preferences for {platform_name}" + (u"Preferences for {platform_name}" .format(platform_name=settings.PLATFORM_NAME))) # no audit logging calls self.assertEquals(len(audit_log_calls), 0) diff --git a/common/djangoapps/microsite_configuration/tests/test_microsites.py b/common/djangoapps/microsite_configuration/tests/test_microsites.py index 6073d09..49e1c1b 100644 --- a/common/djangoapps/microsite_configuration/tests/test_microsites.py +++ b/common/djangoapps/microsite_configuration/tests/test_microsites.py @@ -22,13 +22,13 @@ class MicrositeTests(TestCase): """ def test_breadcrumbs(self): crumbs = ['my', 'less specific', 'Page'] - expected = u'my | less specific | Page | edX' + expected = u'my | less specific | Page | {}'.format(settings.PLATFORM_NAME) title = configuration_helpers.page_title_breadcrumbs(*crumbs) self.assertEqual(expected, title) def test_unicode_title(self): crumbs = [u'øo', u'π tastes gréât', u'驴'] - expected = u'øo | π tastes gréât | 驴 | edX' + expected = u'øo | π tastes gréât | 驴 | {}'.format(settings.PLATFORM_NAME) title = configuration_helpers.page_title_breadcrumbs(*crumbs) self.assertEqual(expected, title) @@ -38,7 +38,7 @@ class MicrositeTests(TestCase): def test_breadcrumb_tag(self): crumbs = ['my', 'less specific', 'Page'] - expected = u'my | less specific | Page | edX' + expected = u'my | less specific | Page | {}'.format(settings.PLATFORM_NAME) title = configuration_tags.page_title_breadcrumbs_tag(None, *crumbs) self.assertEqual(expected, title) diff --git a/common/djangoapps/student/tests/test_email.py b/common/djangoapps/student/tests/test_email.py index f13db30..16bc351 100644 --- a/common/djangoapps/student/tests/test_email.py +++ b/common/djangoapps/student/tests/test_email.py @@ -70,23 +70,23 @@ class EmailTestMixin(object): class ActivationEmailTests(TestCase): """Test sending of the activation email. """ - ACTIVATION_SUBJECT = "Activate Your edX Account" + ACTIVATION_SUBJECT = u"Activate Your {} Account".format(settings.PLATFORM_NAME) # Text fragments we expect in the body of an email # sent from an OpenEdX installation. OPENEDX_FRAGMENTS = [ - "Thank you for creating an account with {platform}!".format(platform=settings.PLATFORM_NAME), + u"Thank you for creating an account with {platform}!".format(platform=settings.PLATFORM_NAME), "http://edx.org/activate/", ( "Check the help section of the " - "{platform} website".format(platform=settings.PLATFORM_NAME) + u"{platform} website".format(platform=settings.PLATFORM_NAME) ) ] # Text fragments we expect in the body of an email # sent from an EdX-controlled domain. EDX_DOMAIN_FRAGMENTS = [ - "Thank you for creating an account with {platform}!".format(platform=settings.PLATFORM_NAME), + u"Thank you for creating an account with {platform}!".format(platform=settings.PLATFORM_NAME), "http://edx.org/activate/", "https://www.edx.org/contact-us", "This email message was automatically sent by edx.org" diff --git a/common/djangoapps/student/tests/test_linkedin.py b/common/djangoapps/student/tests/test_linkedin.py index ef39946..12139eb 100644 --- a/common/djangoapps/student/tests/test_linkedin.py +++ b/common/djangoapps/student/tests/test_linkedin.py @@ -2,8 +2,9 @@ """Tests for LinkedIn Add to Profile configuration. """ import ddt -from urllib import urlencode +from urllib import urlencode, quote +from django.conf import settings from django.test import TestCase from opaque_keys.edx.locator import CourseLocator from student.models import LinkedInAddToProfileConfiguration @@ -18,10 +19,10 @@ class LinkedInAddToProfileUrlTests(TestCase): CERT_URL = u"http://s3.edx/cert" @ddt.data( - ('honor', u'edX+Honor+Code+Certificate+for+Test+Course+%E2%98%83'), - ('verified', u'edX+Verified+Certificate+for+Test+Course+%E2%98%83'), - ('professional', u'edX+Professional+Certificate+for+Test+Course+%E2%98%83'), - ('default_mode', u'edX+Certificate+for+Test+Course+%E2%98%83') + ('honor', u'Honor+Code+Certificate+for+Test+Course+%E2%98%83'), + ('verified', u'Verified+Certificate+for+Test+Course+%E2%98%83'), + ('professional', u'Professional+Certificate+for+Test+Course+%E2%98%83'), + ('default_mode', u'Certificate+for+Test+Course+%E2%98%83') ) @ddt.unpack def test_linked_in_url(self, cert_mode, expected_cert_name): @@ -33,10 +34,13 @@ class LinkedInAddToProfileUrlTests(TestCase): expected_url = ( 'http://www.linkedin.com/profile/add' '?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&' - 'pfCertificationName={expected_cert_name}&' + 'pfCertificationName={platform_name}+{expected_cert_name}&' 'pfCertificationUrl=http%3A%2F%2Fs3.edx%2Fcert&' 'source=o' - ).format(expected_cert_name=expected_cert_name) + ).format( + expected_cert_name=expected_cert_name, + platform_name=quote(settings.PLATFORM_NAME.encode('utf-8')) + ) actual_url = config.add_to_profile_url( self.COURSE_KEY, diff --git a/common/djangoapps/student/tests/test_login.py b/common/djangoapps/student/tests/test_login.py index 6f48965..4ce14fd 100644 --- a/common/djangoapps/student/tests/test_login.py +++ b/common/djangoapps/student/tests/test_login.py @@ -505,7 +505,7 @@ class ExternalAuthShibTest(ModuleStoreTestCase): noshib_response = self.client.get(TARGET_URL, follow=True) self.assertEqual(noshib_response.redirect_chain[-1], ('http://testserver/login?next={url}'.format(url=TARGET_URL), 302)) - self.assertContains(noshib_response, ("Sign in or Register | {platform_name}" + self.assertContains(noshib_response, (u"Sign in or Register | {platform_name}" .format(platform_name=settings.PLATFORM_NAME))) self.assertEqual(noshib_response.status_code, 200) diff --git a/common/djangoapps/student/tests/tests.py b/common/djangoapps/student/tests/tests.py index 529d3a3..adefb22 100644 --- a/common/djangoapps/student/tests/tests.py +++ b/common/djangoapps/student/tests/tests.py @@ -6,6 +6,7 @@ from datetime import datetime, timedelta import json import logging import unittest +from urllib import quote import ddt from django.conf import settings @@ -440,12 +441,12 @@ class DashboardTest(ModuleStoreTestCase): self.assertIn('Add Certificate to LinkedIn', response.content) expected_url = ( - 'http://www.linkedin.com/profile/add' - '?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&' - 'pfCertificationName=edX+Honor+Code+Certificate+for+Omega&' - 'pfCertificationUrl=www.edx.org&' - 'source=o' - ) + u'http://www.linkedin.com/profile/add' + u'?_ed=0_mC_o2MizqdtZEmkVXjH4eYwMj4DnkCWrZP_D9&' + u'pfCertificationName={platform}+Honor+Code+Certificate+for+Omega&' + u'pfCertificationUrl=www.edx.org&' + u'source=o' + ).format(platform=quote(settings.PLATFORM_NAME.encode('utf-8'))) self.assertContains(response, escape(expected_url)) @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') diff --git a/common/djangoapps/third_party_auth/tests/test_views.py b/common/djangoapps/third_party_auth/tests/test_views.py index 29d14b0..138b170 100644 --- a/common/djangoapps/third_party_auth/tests/test_views.py +++ b/common/djangoapps/third_party_auth/tests/test_views.py @@ -6,6 +6,9 @@ import ddt from lxml import etree from onelogin.saml2.errors import OneLogin_Saml2_Error import unittest + +from django.conf import settings + from .testutil import AUTH_FEATURE_ENABLED, SAMLTestCase # Define some XML namespaces: @@ -39,9 +42,9 @@ class SAMLMetadataTest(SAMLTestCase): self.enable_saml() self.check_metadata_contacts( xml=self._fetch_metadata(), - tech_name="edX Support", + tech_name=u"{} Support".format(settings.PLATFORM_NAME), tech_email="technical@example.com", - support_name="edX Support", + support_name=u"{} Support".format(settings.PLATFORM_NAME), support_email="technical@example.com" ) diff --git a/common/test/acceptance/tests/lms/test_lms.py b/common/test/acceptance/tests/lms/test_lms.py index b223f23..9238dd0 100644 --- a/common/test/acceptance/tests/lms/test_lms.py +++ b/common/test/acceptance/tests/lms/test_lms.py @@ -175,7 +175,10 @@ class LoginFromCombinedPageTest(UniqueCourseTest): # The user will be redirected somewhere and then back to the login page: msg_text = self.login_page.wait_for_auth_status_message() self.assertIn("You have successfully signed into Dummy", msg_text) - self.assertIn("To link your accounts, sign in now using your edX password", msg_text) + self.assertIn( + u"To link your accounts, sign in now using your édX password", + msg_text + ) # Now login with username and password: self.login_page.login(email=email, password=password) @@ -337,7 +340,10 @@ class RegisterFromCombinedPageTest(UniqueCourseTest): # Verify that the expected errors are displayed. errors = self.register_page.wait_for_errors() self.assertIn(u'Please enter your Public username.', errors) - self.assertIn(u'You must agree to the edX Terms of Service and Honor Code', errors) + self.assertIn( + u'You must agree to the édX Terms of Service and Honor Code', + errors + ) self.assertIn(u'Please select your Country.', errors) self.assertIn(u'Please tell us your favorite movie.', errors) diff --git a/common/test/acceptance/tests/studio/test_studio_outline.py b/common/test/acceptance/tests/studio/test_studio_outline.py index 6a18e3c..b99c0b4 100644 --- a/common/test/acceptance/tests/studio/test_studio_outline.py +++ b/common/test/acceptance/tests/studio/test_studio_outline.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Acceptance tests for studio related to the outline page. """ @@ -1604,10 +1605,12 @@ class DeprecationWarningMessageTest(CourseOutlineTest): """ HEADING_TEXT = 'This course uses features that are no longer supported.' COMPONENT_LIST_HEADING = 'You must delete or replace the following components.' - ADVANCE_MODULES_REMOVE_TEXT = ('To avoid errors, edX strongly recommends that you remove unsupported features ' - 'from the course advanced settings. To do this, go to the Advanced Settings ' - 'page, locate the "Advanced Module List" setting, and then delete the following ' - 'modules from the list.') + ADVANCE_MODULES_REMOVE_TEXT = ( + u'To avoid errors, édX strongly recommends that you remove unsupported features ' + u'from the course advanced settings. To do this, go to the Advanced Settings ' + u'page, locate the "Advanced Module List" setting, and then delete the following ' + u'modules from the list.' + ) DEFAULT_DISPLAYNAME = "Deprecated Component" def _add_deprecated_advance_modules(self, block_types): diff --git a/lms/djangoapps/bulk_email/tests/test_email.py b/lms/djangoapps/bulk_email/tests/test_email.py index 9a5d354..fefc497 100644 --- a/lms/djangoapps/bulk_email/tests/test_email.py +++ b/lms/djangoapps/bulk_email/tests/test_email.py @@ -9,6 +9,7 @@ from nose.plugins.attrib import attr import os from unittest import skipIf +from django.conf import settings from django.core import mail from django.core.mail.message import forbid_multi_line_headers from django.core.urlresolvers import reverse @@ -503,7 +504,7 @@ class TestCourseEmailContext(SharedModuleStoreTestCase): """ This test tests that the bulk email context uses http or https urls as appropriate. """ - self.assertEquals(email_context['platform_name'], 'edX') + self.assertEquals(email_context['platform_name'], settings.PLATFORM_NAME) self.assertEquals(email_context['course_title'], self.course_title) self.assertEquals(email_context['course_url'], '{}://edx.org/courses/{}/{}/{}/'.format(scheme, diff --git a/lms/djangoapps/certificates/tests/test_webview_views.py b/lms/djangoapps/certificates/tests/test_webview_views.py index 86b2356..85e9c9e 100644 --- a/lms/djangoapps/certificates/tests/test_webview_views.py +++ b/lms/djangoapps/certificates/tests/test_webview_views.py @@ -190,7 +190,7 @@ class CertificatesViewsTests(CommonCertificatesTestCase): params = OrderedDict([ ('_ed', '0_0dPSPyS070e0HsE9HNz_13_d11_',), ('pfCertificationName', '{platform_name} Honor Code Certificate for {course_name}'.format( - platform_name=settings.PLATFORM_NAME, + platform_name=settings.PLATFORM_NAME.encode('utf-8'), course_name=self.course.display_name, ),), ('pfCertificationUrl', self.request.build_absolute_uri(test_url),), diff --git a/lms/djangoapps/courseware/features/lti.py b/lms/djangoapps/courseware/features/lti.py index 4e5f958..6901eb2 100644 --- a/lms/djangoapps/courseware/features/lti.py +++ b/lms/djangoapps/courseware/features/lti.py @@ -272,7 +272,13 @@ def check_lti_popup(parent_window): # For verification, iterate through the window titles and make sure that # both are there. tabs = [] - expected_tabs = [u'LTI | Test Section | {0} Courseware | edX'.format(TEST_COURSE_NAME), u'TEST TITLE'] + expected_tabs = [ + u'LTI | Test Section | {course} Courseware | {platform}'.format( + course=TEST_COURSE_NAME, + platform=settings.PLATFORM_NAME + ), + u'TEST TITLE' + ] for window in windows: world.browser.switch_to_window(window) diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index 08e1d0c..066b231 100644 --- a/lms/djangoapps/courseware/tests/test_views.py +++ b/lms/djangoapps/courseware/tests/test_views.py @@ -1773,9 +1773,9 @@ class GenerateUserCertTests(ModuleStoreTestCase): self.client.logout() resp = self.client.post(self.url) self.assertEqual(resp.status_code, HttpResponseBadRequest.status_code) - self.assertIn("You must be signed in to {platform_name} to create a certificate.".format( + self.assertIn(u"You must be signed in to {platform_name} to create a certificate.".format( platform_name=settings.PLATFORM_NAME - ), resp.content) + ), resp.content.decode('utf-8')) class ActivateIDCheckerBlock(XBlock): diff --git a/lms/djangoapps/courseware/views/views.py b/lms/djangoapps/courseware/views/views.py index 611a883..3ac3e2b 100644 --- a/lms/djangoapps/courseware/views/views.py +++ b/lms/djangoapps/courseware/views/views.py @@ -767,8 +767,8 @@ def _get_cert_data(student, course, course_key, is_active, enrollment_mode): if enrollment_mode == CourseMode.AUDIT: return CertData( CertificateStatuses.audit_passing, - 'Your enrollment: Audit track', - 'You are enrolled in the audit track for this course. The audit track does not include a certificate.', + _('Your enrollment: Audit track'), + _('You are enrolled in the audit track for this course. The audit track does not include a certificate.'), download_url=None, cert_web_view_url=None ) @@ -784,8 +784,8 @@ def _get_cert_data(student, course, course_key, is_active, enrollment_mode): if certs_api.is_certificate_invalid(student, course_key): return CertData( CertificateStatuses.invalidated, - 'Your certificate has been invalidated', - 'Please contact your course team if you have any questions.', + _('Your certificate has been invalidated'), + _('Please contact your course team if you have any questions.'), download_url=None, cert_web_view_url=None ) @@ -794,8 +794,8 @@ def _get_cert_data(student, course, course_key, is_active, enrollment_mode): if cert_downloadable_status['is_downloadable']: cert_status = CertificateStatuses.downloadable - title = 'Your certificate is available' - msg = 'You can keep working for a higher grade, or request your certificate now.' + title = _('Your certificate is available') + msg = _('You can keep working for a higher grade, or request your certificate now.') if certs_api.has_html_certificates_enabled(course_key, course): if certs_api.get_active_web_certificate(course) is not None: cert_web_view_url = certs_api.get_certificate_url( @@ -805,9 +805,11 @@ def _get_cert_data(student, course, course_key, is_active, enrollment_mode): else: return 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.", + _("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 ) @@ -819,9 +821,11 @@ def _get_cert_data(student, course, course_key, is_active, enrollment_mode): if cert_downloadable_status['is_generating']: return 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.", + _("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 ) @@ -835,17 +839,19 @@ def _get_cert_data(student, course, course_key, is_active, enrollment_mode): platform_name = configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME) return CertData( CertificateStatuses.unverified, - 'Certificate unavailable', - 'You have not received a certificate because you do not have a current {platform_name} verified ' - 'identity.'.format(platform_name=platform_name), + _('Certificate unavailable'), + _( + 'You have not received a certificate because you do not have a current {platform_name} ' + 'verified identity.' + ).format(platform_name=platform_name), download_url=None, cert_web_view_url=None ) return CertData( CertificateStatuses.requesting, - 'Congratulations, you qualified for a certificate!', - 'You can keep working for a higher grade, or request your certificate now.', + _('Congratulations, you qualified for a certificate!'), + _('You can keep working for a higher grade, or request your certificate now.'), download_url=None, cert_web_view_url=None ) diff --git a/lms/djangoapps/shoppingcart/tests/test_models.py b/lms/djangoapps/shoppingcart/tests/test_models.py index a21973d..05d6253 100644 --- a/lms/djangoapps/shoppingcart/tests/test_models.py +++ b/lms/djangoapps/shoppingcart/tests/test_models.py @@ -1106,7 +1106,7 @@ class DonationTest(ModuleStoreTestCase): donation, donation_type="general", unit_cost=self.COST, - line_desc="Donation for edX" + line_desc=u"Donation for {}".format(settings.PLATFORM_NAME) ) def test_donate_to_course(self): diff --git a/lms/djangoapps/static_template_view/tests/test_views.py b/lms/djangoapps/static_template_view/tests/test_views.py index 92ab0e4..45550f0 100644 --- a/lms/djangoapps/static_template_view/tests/test_views.py +++ b/lms/djangoapps/static_template_view/tests/test_views.py @@ -50,7 +50,7 @@ class MarketingSiteViewTests(TestCase): resp = self.client.get(url) self.assertContains( resp, - 'There has been a 500 error on the <em>{platform_name}</em> servers'.format( + u'There has been a 500 error on the <em>{platform_name}</em> servers'.format( platform_name=settings.PLATFORM_NAME ), status_code=500 diff --git a/lms/djangoapps/verify_student/tests/test_views.py b/lms/djangoapps/verify_student/tests/test_views.py index 3d9833c..14a2f9d 100644 --- a/lms/djangoapps/verify_student/tests/test_views.py +++ b/lms/djangoapps/verify_student/tests/test_views.py @@ -2491,7 +2491,7 @@ class TestEmailMessageWithCustomICRVBlock(ModuleStoreTestCase): self.assertIn("Thanks,", body) self.assertIn( - "The {platform_name} team".format( + u"The {platform_name} team".format( platform_name=settings.PLATFORM_NAME ), body diff --git a/lms/envs/bok_choy.env.json b/lms/envs/bok_choy.env.json index 4bb4250..493e2ad 100644 --- a/lms/envs/bok_choy.env.json +++ b/lms/envs/bok_choy.env.json @@ -118,7 +118,7 @@ "ROOT": "root", "SITEMAP.XML": "sitemap_xml" }, - "PLATFORM_NAME": "edX", + "PLATFORM_NAME": "édX", "REGISTRATION_EXTENSION_FORM": "openedx.core.djangoapps.user_api.tests.test_helpers.TestCaseForm", "REGISTRATION_EXTRA_FIELDS": { "level_of_education": "optional", diff --git a/lms/envs/test.py b/lms/envs/test.py index def7a84..6d5781b 100644 --- a/lms/envs/test.py +++ b/lms/envs/test.py @@ -424,7 +424,8 @@ FEATURES['CLASS_DASHBOARD'] = True import openid.oidutil openid.oidutil.log = lambda message, level=0: None -PLATFORM_NAME = "edX" +# Include a non-ascii character in PLATFORM_NAME to uncover possible UnicodeEncodeErrors in tests. +PLATFORM_NAME = u"édX" SITE_NAME = "edx.org" # set up some testing for microsites diff --git a/openedx/core/djangoapps/api_admin/widgets.py b/openedx/core/djangoapps/api_admin/widgets.py index 4430e3c..1841daf 100644 --- a/openedx/core/djangoapps/api_admin/widgets.py +++ b/openedx/core/djangoapps/api_admin/widgets.py @@ -29,7 +29,7 @@ class TermsOfServiceCheckboxInput(CheckboxInput): link_end='</a>', ) - html = '<input{{}} /> <label class="tos-checkbox-label" for="{id}">{label}</label>'.format( + html = u'<input{{}} /> <label class="tos-checkbox-label" for="{id}">{label}</label>'.format( id=final_attrs['id'], label=label ) diff --git a/openedx/core/djangoapps/user_api/tests/test_views.py b/openedx/core/djangoapps/user_api/tests/test_views.py index bb190b7..b47b909 100644 --- a/openedx/core/djangoapps/user_api/tests/test_views.py +++ b/openedx/core/djangoapps/user_api/tests/test_views.py @@ -588,7 +588,7 @@ class LoginSessionViewTest(UserAPITestCase): "required": True, "label": "Email", "placeholder": "username@domain.com", - "instructions": "The email address you used to register with {platform_name}".format( + "instructions": u"The email address you used to register with {platform_name}".format( platform_name=settings.PLATFORM_NAME ), "restrictions": { @@ -756,7 +756,7 @@ class PasswordResetViewTest(UserAPITestCase): "required": True, "label": "Email", "placeholder": "username@domain.com", - "instructions": "The email address you used to register with {platform_name}".format( + "instructions": u"The email address you used to register with {platform_name}".format( platform_name=settings.PLATFORM_NAME ), "restrictions": { @@ -1126,7 +1126,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): "name": "goals", "type": "textarea", "required": False, - "label": "Tell us why you're interested in {platform_name}".format( + "label": u"Tell us why you're interested in {platform_name}".format( platform_name=settings.PLATFORM_NAME ) } @@ -1185,7 +1185,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): self._assert_reg_field( {"honor_code": "required"}, { - "label": "I agree to the {platform_name} {link_label}".format( + "label": u"I agree to the {platform_name} {link_label}".format( platform_name=settings.PLATFORM_NAME, link_label=link_label ), @@ -1194,7 +1194,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): "type": "checkbox", "required": True, "errorMessages": { - "required": "You must agree to the {platform_name} {link_label}".format( + "required": u"You must agree to the {platform_name} {link_label}".format( platform_name=settings.PLATFORM_NAME, link_label=link_label ) @@ -1209,7 +1209,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): self._assert_reg_field( {"honor_code": "required"}, { - "label": "I agree to the {platform_name} {link_label}".format( + "label": u"I agree to the {platform_name} {link_label}".format( platform_name=settings.PLATFORM_NAME, link_label=link_label ), @@ -1218,7 +1218,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): "type": "checkbox", "required": True, "errorMessages": { - "required": "You must agree to the {platform_name} {link_label}".format( + "required": u"You must agree to the {platform_name} {link_label}".format( platform_name=settings.PLATFORM_NAME, link_label=link_label ) @@ -1239,7 +1239,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): self._assert_reg_field( {"honor_code": "required", "terms_of_service": "required"}, { - "label": "I agree to the {platform_name} {link_label}".format( + "label": u"I agree to the {platform_name} {link_label}".format( platform_name=settings.PLATFORM_NAME, link_label=link_label ), @@ -1248,7 +1248,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): "type": "checkbox", "required": True, "errorMessages": { - "required": "You must agree to the {platform_name} {link_label}".format( + "required": u"You must agree to the {platform_name} {link_label}".format( platform_name=settings.PLATFORM_NAME, link_label=link_label ) @@ -1261,7 +1261,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): self._assert_reg_field( {"honor_code": "required", "terms_of_service": "required"}, { - "label": "I agree to the {platform_name} {link_label}".format( + "label": u"I agree to the {platform_name} {link_label}".format( platform_name=settings.PLATFORM_NAME, link_label=link_label ), @@ -1270,7 +1270,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): "type": "checkbox", "required": True, "errorMessages": { - "required": "You must agree to the {platform_name} {link_label}".format( + "required": u"You must agree to the {platform_name} {link_label}".format( platform_name=settings.PLATFORM_NAME, link_label=link_label ) @@ -1286,7 +1286,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): self._assert_reg_field( {"honor_code": "required", "terms_of_service": "required"}, { - "label": "I agree to the {platform_name} Honor Code".format( + "label": u"I agree to the {platform_name} Honor Code".format( platform_name=settings.PLATFORM_NAME ), "name": "honor_code", @@ -1294,7 +1294,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): "type": "checkbox", "required": True, "errorMessages": { - "required": "You must agree to the {platform_name} Honor Code".format( + "required": u"You must agree to the {platform_name} Honor Code".format( platform_name=settings.PLATFORM_NAME ) } @@ -1305,7 +1305,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): self._assert_reg_field( {"honor_code": "required", "terms_of_service": "required"}, { - "label": "I agree to the {platform_name} Terms of Service".format( + "label": u"I agree to the {platform_name} Terms of Service".format( platform_name=settings.PLATFORM_NAME ), "name": "terms_of_service", @@ -1313,7 +1313,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): "type": "checkbox", "required": True, "errorMessages": { - "required": "You must agree to the {platform_name} Terms of Service".format( # pylint: disable=line-too-long + "required": u"You must agree to the {platform_name} Terms of Service".format( # pylint: disable=line-too-long platform_name=settings.PLATFORM_NAME ) } @@ -1479,7 +1479,10 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): self.assertEqual(len(mail.outbox), 1) sent_email = mail.outbox[0] self.assertEqual(sent_email.to, [self.EMAIL]) - self.assertEqual(sent_email.subject, "Activate Your edX Account") + self.assertEqual( + sent_email.subject, + u"Activate Your {platform} Account".format(platform=settings.PLATFORM_NAME) + ) self.assertIn( u"you need to activate your {platform} account".format(platform=settings.PLATFORM_NAME), sent_email.body diff --git a/requirements/edx/post.txt b/requirements/edx/post.txt index d16778b..bd16192 100644 --- a/requirements/edx/post.txt +++ b/requirements/edx/post.txt @@ -10,8 +10,10 @@ # python-saml only after lxml has been successfully installed. # In addition, we are currently utilizing a forked version of python-saml, -# managed by OpenCraft, which features enhanced logging. We will return to -# the official version of python-saml on PyPI when -# https://github.com/onelogin/python-saml/pull/159 (or its derivative) has -# been incorporated into the main project. -git+https://github.com/open-craft/python-saml.git@87d4c18865e4997061ec62fd0e8d1e070b92e4e7#egg=python-saml==2.1.9 +# managed by OpenCraft, which features enhanced logging and improved +# unicode support. We will return to the official version of python-saml +# on PyPI when these pull requests (or their derivatives) have been +# incorporated into the main project. +# https://github.com/onelogin/python-saml/pull/159 +# https://github.com/onelogin/python-saml/pull/164 +git+https://github.com/open-craft/python-saml.git@7f7dc389abeba44c1dac154d6aafcbe4187ae221#egg=python-saml==2.1.9 -- libgit2 0.26.0