Commit 3739cc45 by Omar Al-Ithawi

Make the course lang override platform lang

parent d2945320
...@@ -37,6 +37,7 @@ Other tags that may be used (surrounded by one curly brace on each side): ...@@ -37,6 +37,7 @@ Other tags that may be used (surrounded by one curly brace on each side):
{platform_name} : the name of the platform {platform_name} : the name of the platform
{course_title} : the name of the course {course_title} : the name of the course
{course_root} : the URL path to the root of the course {course_root} : the URL path to the root of the course
{course_language} : the course language. The default is None.
{course_url} : the course's full URL {course_url} : the course's full URL
{email} : the user's email address {email} : the user's email address
{account_settings_url} : URL at which users can change account preferences {account_settings_url} : URL at which users can change account preferences
......
...@@ -110,6 +110,7 @@ def _get_course_email_context(course): ...@@ -110,6 +110,7 @@ def _get_course_email_context(course):
email_context = { email_context = {
'course_title': course_title, 'course_title': course_title,
'course_root': course_root, 'course_root': course_root,
'course_language': course.language,
'course_url': course_url, 'course_url': course_url,
'course_image_url': image_url, 'course_image_url': image_url,
'course_end_date': course_end_date, 'course_end_date': course_end_date,
...@@ -351,7 +352,7 @@ def _filter_optouts_from_recipients(to_list, course_id): ...@@ -351,7 +352,7 @@ def _filter_optouts_from_recipients(to_list, course_id):
return to_list, num_optout return to_list, num_optout
def _get_source_address(course_id, course_title, truncate=True): def _get_source_address(course_id, course_title, course_language, truncate=True):
""" """
Calculates an email address to be used as the 'from-address' for sent emails. Calculates an email address to be used as the 'from-address' for sent emails.
...@@ -374,7 +375,12 @@ def _get_source_address(course_id, course_title, truncate=True): ...@@ -374,7 +375,12 @@ def _get_source_address(course_id, course_title, truncate=True):
# character appears. # character appears.
course_name = re.sub(r"[^\w.-]", '_', course_id.course) course_name = re.sub(r"[^\w.-]", '_', course_id.course)
with override_language(settings.LANGUAGE_CODE): # Use course.language if present
language = course_language if course_language else settings.LANGUAGE_CODE
with override_language(language):
# RFC2821 requires the byte order of the email address to be the name then email
# e.g. "John Doe <email@example.com>"
# Although the display will be flipped in RTL languages, the byte order is still the same.
from_addr_format = u'{name} {email}'.format( from_addr_format = u'{name} {email}'.format(
# Translators: Bulk email from address e.g. ("Physics 101" Course Staff) # Translators: Bulk email from address e.g. ("Physics 101" Course Staff)
name=_('"{course_title}" Course Staff'), name=_('"{course_title}" Course Staff'),
...@@ -481,10 +487,11 @@ def _send_course_email(entry_id, email_id, to_list, global_email_context, subtas ...@@ -481,10 +487,11 @@ def _send_course_email(entry_id, email_id, to_list, global_email_context, subtas
subtask_status.increment(skipped=num_optout) subtask_status.increment(skipped=num_optout)
course_title = global_email_context['course_title'] course_title = global_email_context['course_title']
course_language = global_email_context['course_language']
# use the email from address in the CourseEmail, if it is present, otherwise compute it # use the email from address in the CourseEmail, if it is present, otherwise compute it
from_addr = course_email.from_addr if course_email.from_addr else \ from_addr = course_email.from_addr if course_email.from_addr else \
_get_source_address(course_email.course_id, course_title) _get_source_address(course_email.course_id, course_title, course_language)
# use the CourseEmailTemplate that was associated with the CourseEmail # use the CourseEmailTemplate that was associated with the CourseEmail
course_email_template = course_email.get_template() course_email_template = course_email.get_template()
......
...@@ -8,6 +8,7 @@ from mock import patch, Mock ...@@ -8,6 +8,7 @@ from mock import patch, Mock
from nose.plugins.attrib import attr from nose.plugins.attrib import attr
import os import os
from unittest import skipIf from unittest import skipIf
import ddt
from django.conf import settings from django.conf import settings
from django.core import mail from django.core import mail
...@@ -133,9 +134,10 @@ class EmailSendFromDashboardTestCase(SharedModuleStoreTestCase): ...@@ -133,9 +134,10 @@ class EmailSendFromDashboardTestCase(SharedModuleStoreTestCase):
BulkEmailFlag.objects.all().delete() BulkEmailFlag.objects.all().delete()
@attr(shard=1) class SendEmailWithMockedUgettextMixin(object):
@patch.dict(settings.FEATURES, {'ENABLE_INSTRUCTOR_EMAIL': True, 'REQUIRE_COURSE_EMAIL_AUTH': False}) """
class TestLocalizedFromAddress(EmailSendFromDashboardTestCase): Mock uggetext for EmailSendFromDashboardTestCase.
"""
def send_email(self): def send_email(self):
""" """
Sends a dummy email to check the `from_addr` translation. Sends a dummy email to check the `from_addr` translation.
...@@ -165,11 +167,20 @@ class TestLocalizedFromAddress(EmailSendFromDashboardTestCase): ...@@ -165,11 +167,20 @@ class TestLocalizedFromAddress(EmailSendFromDashboardTestCase):
return mail.outbox[0] return mail.outbox[0]
@attr(shard=1)
@patch.dict(settings.FEATURES, {'ENABLE_INSTRUCTOR_EMAIL': True, 'REQUIRE_COURSE_EMAIL_AUTH': False})
@ddt.ddt
class LocalizedFromAddressPlatformLangTestCase(SendEmailWithMockedUgettextMixin, EmailSendFromDashboardTestCase):
"""
Tests to ensure that the bulk email has the "From" address localized according to LANGUAGE_CODE.
"""
@override_settings(LANGUAGE_CODE='en') @override_settings(LANGUAGE_CODE='en')
def test_english_platform(self): def test_english_platform(self):
""" """
Ensures that the source-code language (English) works well. Ensures that the source-code language (English) works well.
""" """
self.assertIsNone(self.course.language) # Sanity check
message = self.send_email() message = self.send_email()
self.assertRegexpMatches(message.from_email, '.*Course Staff.*') self.assertRegexpMatches(message.from_email, '.*Course Staff.*')
...@@ -178,11 +189,45 @@ class TestLocalizedFromAddress(EmailSendFromDashboardTestCase): ...@@ -178,11 +189,45 @@ class TestLocalizedFromAddress(EmailSendFromDashboardTestCase):
""" """
Tests the fake Esperanto language to ensure proper gettext calls. Tests the fake Esperanto language to ensure proper gettext calls.
""" """
self.assertIsNone(self.course.language) # Sanity check
message = self.send_email() message = self.send_email()
self.assertRegexpMatches(message.from_email, '@EO .* Course Staff@') self.assertRegexpMatches(message.from_email, '@EO .* Course Staff@')
@attr(shard=1) @attr(shard=1)
@patch.dict(settings.FEATURES, {'ENABLE_INSTRUCTOR_EMAIL': True, 'REQUIRE_COURSE_EMAIL_AUTH': False})
@ddt.ddt
class LocalizedFromAddressCourseLangTestCase(SendEmailWithMockedUgettextMixin, EmailSendFromDashboardTestCase):
"""
Test if the bulk email "From" address uses the course.language if present instead of LANGUAGE_CODE.
This is similiar to LocalizedFromAddressTestCase but creating a different test case to allow
changing the class-wide course object.
"""
@classmethod
def setUpClass(cls):
"""
Creates a different course.
"""
super(LocalizedFromAddressCourseLangTestCase, cls).setUpClass()
course_title = u"ẗëṡẗ イэ"
cls.course = CourseFactory.create(
display_name=course_title,
language='ar',
default_store=ModuleStoreEnum.Type.split
)
@override_settings(LANGUAGE_CODE='eo')
def test_esperanto_platform_arabic_course(self):
"""
The course language should override the platform's.
"""
message = self.send_email()
self.assertRegexpMatches(message.from_email, '@AR .* Course Staff@')
@attr(shard=1)
@patch('bulk_email.models.html_to_text', Mock(return_value='Mocking CourseEmail.text_message', autospec=True)) @patch('bulk_email.models.html_to_text', Mock(return_value='Mocking CourseEmail.text_message', autospec=True))
class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase): class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase):
""" """
...@@ -444,7 +489,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase) ...@@ -444,7 +489,7 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase)
instructor = InstructorFactory(course_key=course.id) instructor = InstructorFactory(course_key=course.id)
unexpected_from_addr = _get_source_address( unexpected_from_addr = _get_source_address(
course.id, course.display_name, truncate=False course.id, course.display_name, course_language=None, truncate=False
) )
__, encoded_unexpected_from_addr = forbid_multi_line_headers( __, encoded_unexpected_from_addr = forbid_multi_line_headers(
"from", unexpected_from_addr, 'utf-8' "from", unexpected_from_addr, 'utf-8'
......
...@@ -440,6 +440,7 @@ class TestBulkEmailInstructorTask(InstructorTaskCourseTestCase): ...@@ -440,6 +440,7 @@ class TestBulkEmailInstructorTask(InstructorTaskCourseTestCase):
result = _get_course_email_context(self.course) result = _get_course_email_context(self.course)
self.assertIn('course_title', result) self.assertIn('course_title', result)
self.assertIn('course_root', result) self.assertIn('course_root', result)
self.assertIn('course_language', result)
self.assertIn('course_url', result) self.assertIn('course_url', result)
self.assertIn('course_image_url', result) self.assertIn('course_image_url', result)
self.assertIn('course_end_date', result) self.assertIn('course_end_date', result)
......
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