diff --git a/openedx/core/djangoapps/schedules/management/commands/tests/upsell_base.py b/openedx/core/djangoapps/schedules/management/commands/tests/upsell_base.py index 7b38c52285..d9b9855326 100644 --- a/openedx/core/djangoapps/schedules/management/commands/tests/upsell_base.py +++ b/openedx/core/djangoapps/schedules/management/commands/tests/upsell_base.py @@ -1,7 +1,8 @@ from collections import namedtuple import datetime import ddt -from mock import patch +from freezegun import freeze_time +from mock import patch, PropertyMock import itertools from edx_ace.utils.date import serialize @@ -11,9 +12,47 @@ from courseware.models import DynamicUpgradeDeadlineConfiguration @ddt.ddt +@freeze_time('2017-08-01 00:00:00', tz_offset=0, tick=True) class ScheduleUpsellTestMixin(object): UpsellTestCase = namedtuple('UpsellTestCase', 'set_deadline, deadline_offset, expect_upsell') + def _setup_schedule_and_dates(self, set_deadline=True, deadline_offset=7): + """ + Creates and returns a schedule according to the provided upsell deadline values. + Also returns the offset and target_day as computed for messaging. + """ + current_day, offset, target_day, _ = self._get_dates() + + upgrade_deadline = None + if set_deadline: + upgrade_deadline = current_day + datetime.timedelta(days=deadline_offset) + + schedule = self._schedule_factory( + upgrade_deadline=upgrade_deadline + ) + return schedule, offset, target_day + + def _send_message_task(self, schedule, offset, target_day): + """ + Calls the task for sending a message to the given schedule and for the given + offset and target_day. Returns the message that would have been sent. + """ + sent_messages = [] + with patch.object(self.task, 'async_send_task') as mock_schedule_send: + mock_schedule_send.apply_async = lambda args, *_a, **_kw: sent_messages.append(args[1]) + self.task().apply(kwargs=dict( + site_id=self.site_config.site.id, target_day_str=serialize(target_day), day_offset=offset, + bin_num=self._calculate_bin_for_user(schedule.enrollment.user), + )) + self.assertEqual(len(sent_messages), 1) + return Message.from_string(sent_messages[0]) + + def _contains_upsell(self, message): + """ + Returns whether the given message would contain upsell text. + """ + return message.context["show_upsell"] + @ddt.data( *itertools.product( (True, False), # enable DynamicUpgradeDeadlineConfiguration @@ -26,30 +65,33 @@ class ScheduleUpsellTestMixin(object): ) @ddt.unpack def test_upsell(self, enable_config, testcase): - DynamicUpgradeDeadlineConfiguration.objects.create(enabled=enable_config) + # Make sure the new entry in the config model has a time + # later than the frozen time for it to be effective. + with freeze_time('2017-08-01 01:00:00'): + DynamicUpgradeDeadlineConfiguration.objects.create(enabled=enable_config) - current_day, offset, target_day, _ = self._get_dates() - upgrade_deadline = None - if testcase.set_deadline: - upgrade_deadline = current_day + datetime.timedelta(days=testcase.deadline_offset) - - schedule = self._schedule_factory( - upgrade_deadline=upgrade_deadline + schedule, offset, target_day = self._setup_schedule_and_dates( + set_deadline=testcase.set_deadline, + deadline_offset=testcase.deadline_offset, ) + message = self._send_message_task(schedule, offset, target_day) - sent_messages = [] - with patch.object(self.task, 'async_send_task') as mock_schedule_send: - mock_schedule_send.apply_async = lambda args, *_a, **_kw: sent_messages.append(args[1]) - self.task().apply(kwargs=dict( - site_id=self.site_config.site.id, target_day_str=serialize(target_day), day_offset=offset, - bin_num=self._calculate_bin_for_user(schedule.enrollment.user), - )) - self.assertEqual(len(sent_messages), 1) - - found_upsell = self._contains_upsell(sent_messages[0]) + found_upsell = self._contains_upsell(message) expect_upsell = enable_config and testcase.expect_upsell self.assertEqual(found_upsell, expect_upsell) - def _contains_upsell(self, message_str): - message = Message.from_string(message_str) - return message.context["show_upsell"] + @ddt.data('es', 'es-es', 'es-419') + def test_upsell_translated(self, course_language): + schedule, offset, target_day = self._setup_schedule_and_dates() + + with patch( + 'openedx.core.djangoapps.content.course_overviews.models.CourseOverview.closest_released_language', + new_callable=PropertyMock + ) as mock_course_language: + mock_course_language.return_value = course_language + message = self._send_message_task(schedule, offset, target_day) + + self.assertEqual( + message.context['user_schedule_upgrade_deadline_time'], + u'8 de Agosto de 2017', + ) diff --git a/openedx/core/djangoapps/schedules/resolvers.py b/openedx/core/djangoapps/schedules/resolvers.py index 4edf290d27..6c0fd9ecec 100644 --- a/openedx/core/djangoapps/schedules/resolvers.py +++ b/openedx/core/djangoapps/schedules/resolvers.py @@ -8,7 +8,6 @@ from django.contrib.auth.models import User from django.contrib.staticfiles.templatetags.staticfiles import static from django.core.urlresolvers import reverse from django.db.models import F, Q -from django.utils.formats import dateformat, get_format from edx_ace.recipient_resolver import RecipientResolver from edx_ace.recipient import Recipient @@ -21,6 +20,7 @@ from openedx.core.djangoapps.schedules.models import Schedule, ScheduleExperienc from openedx.core.djangoapps.schedules.utils import PrefixedDebugLoggerMixin from openedx.core.djangoapps.ace_common.template_context import get_base_template_context from openedx.core.djangoapps.site_configuration.models import SiteConfiguration +from openedx.core.djangolib.translation_utils import translate_date from openedx.features.course_experience import course_home_url_name LOG = logging.getLogger(__name__) @@ -313,13 +313,9 @@ def _get_upsell_information_for_schedule(user, schedule): if has_verified_upgrade_link: template_context['upsell_link'] = verified_upgrade_link - template_context['user_schedule_upgrade_deadline_time'] = dateformat.format( - enrollment.dynamic_upgrade_deadline, - get_format( - 'DATE_FORMAT', - lang=course.closest_released_language, - use_l10n=True - ) + template_context['user_schedule_upgrade_deadline_time'] = translate_date( + date=enrollment.dynamic_upgrade_deadline, + language=course.closest_released_language, ) template_context['show_upsell'] = has_verified_upgrade_link diff --git a/openedx/core/djangolib/translation_utils.py b/openedx/core/djangolib/translation_utils.py new file mode 100644 index 0000000000..f0b0803f30 --- /dev/null +++ b/openedx/core/djangolib/translation_utils.py @@ -0,0 +1,20 @@ +from django.utils.translation import ugettext as _, override +from django.utils.formats import dateformat, get_format + + +def translate_date(date, language, date_format='DATE_FORMAT'): + """ + Converts the provided date object into a string, while translating + its value for the given language. Both the format of the date + as well as its values (i.e., name of the Month) are translated. + + For example: + date = datetime.datetime(2017, 12, 23) + date_in_spanish = translate_date(date, 'es') + assert date_in_spanish = '12 de Deciembre de 2017' + """ + with override(language): + return dateformat.format( + date, + get_format(date_format, lang=language, use_l10n=True), + )