diff --git a/openedx/core/djangoapps/schedules/management/commands/tests/test_send_recurring_nudge.py b/openedx/core/djangoapps/schedules/management/commands/tests/test_send_recurring_nudge.py index 50398a0287..14aa3598c5 100644 --- a/openedx/core/djangoapps/schedules/management/commands/tests/test_send_recurring_nudge.py +++ b/openedx/core/djangoapps/schedules/management/commands/tests/test_send_recurring_nudge.py @@ -1,14 +1,10 @@ import datetime import itertools -from copy import deepcopy from unittest import skipUnless -import attr import ddt import pytz from django.conf import settings -from edx_ace.channel import ChannelType -from edx_ace.test_utils import StubPolicy, patch_channels, patch_policies from edx_ace.utils.date import serialize from edx_ace.message import Message from mock import Mock, patch @@ -57,57 +53,6 @@ class TestSendRecurringNudge(ScheduleBaseEmailTestBase): enqueue_config = 'enqueue_recurring_nudge' expected_offsets = (-3, -10) - @ddt.data(*itertools.product((1, 10, 100), (-3, -10))) - @ddt.unpack - def test_templates(self, message_count, day): - - user = UserFactory.create() - schedules = [ - ScheduleFactory.create( - start=datetime.datetime(2017, 8, 3, 19, 44, 30, tzinfo=pytz.UTC), - enrollment__user=user, - enrollment__course__id=CourseLocator('edX', 'toy', 'Course{}'.format(course_num)) - ) - for course_num in range(message_count) - ] - - test_datetime = datetime.datetime(2017, 8, 3, 19, tzinfo=pytz.UTC) - test_datetime_str = serialize(test_datetime) - - patch_policies(self, [StubPolicy([ChannelType.PUSH])]) - mock_channel = Mock( - name='test_channel', - channel_type=ChannelType.EMAIL - ) - patch_channels(self, [mock_channel]) - - sent_messages = [] - - with self.settings(TEMPLATES=self._get_template_overrides()): - with patch.object(self.tested_task, 'async_send_task') as mock_schedule_send: - mock_schedule_send.apply_async = lambda args, *_a, **_kw: sent_messages.append(args) - - with self.assertNumQueries(NUM_QUERIES_WITH_MATCHES + NUM_QUERIES_NO_ORG_LIST, table_blacklist=WAFFLE_TABLES): - self.tested_task.apply(kwargs=dict( - site_id=self.site_config.site.id, target_day_str=test_datetime_str, day_offset=day, - bin_num=self._calculate_bin_for_user(user), - )) - - self.assertEqual(len(sent_messages), 1) - - # Load the site - # Check the schedule config - with self.assertNumQueries(2): - for args in sent_messages: - tasks._recurring_nudge_schedule_send(*args) - - self.assertEqual(mock_channel.deliver.call_count, 1) - for (_name, (_msg, email), _kwargs) in mock_channel.deliver.mock_calls: - for template in attr.astuple(email): - self.assertNotIn("TEMPLATE WARNING", template) - self.assertNotIn("{{", template) - self.assertNotIn("}}", template) - def test_user_in_course_with_verified_coursemode_receives_upsell(self): user = UserFactory.create() course_id = CourseLocator('edX', 'toy', 'Course1') @@ -233,11 +178,6 @@ class TestSendRecurringNudge(ScheduleBaseEmailTestBase): return sent_messages - def _get_template_overrides(self): - templates_override = deepcopy(settings.TEMPLATES) - templates_override[0]['OPTIONS']['string_if_invalid'] = "TEMPLATE WARNING - MISSING VARIABLE [%s]" - return templates_override - def _calculate_bin_for_user(self, user): return user.id % resolvers.RECURRING_NUDGE_NUM_BINS diff --git a/openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py b/openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py index b73894f64d..5d8c10de88 100644 --- a/openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py +++ b/openedx/core/djangoapps/schedules/management/commands/tests/test_send_upgrade_reminder.py @@ -1,15 +1,11 @@ import datetime -from copy import deepcopy import logging from unittest import skipUnless -import attr import ddt import pytz from django.conf import settings from edx_ace import Message -from edx_ace.channel import ChannelType -from edx_ace.test_utils import StubPolicy, patch_channels, patch_policies from edx_ace.utils.date import serialize from mock import Mock, patch from opaque_keys.edx.keys import CourseKey @@ -75,80 +71,6 @@ class TestUpgradeReminder(ScheduleBaseEmailTestBase): expiration_datetime=datetime.datetime.now(pytz.UTC) + datetime.timedelta(days=30), ) - @ddt.data(1, 10, 100) - def test_templates(self, message_count): - now = datetime.datetime.now(pytz.UTC) - future_datetime = now + datetime.timedelta(days=21) - - user = UserFactory.create() - schedules = [ - ScheduleFactory.create( - upgrade_deadline=future_datetime, - enrollment__user=user, - enrollment__course__self_paced=True, - enrollment__course__end=future_datetime + datetime.timedelta(days=30), - enrollment__course__id=CourseLocator('edX', 'toy', 'Course{}'.format(course_num)) - ) - for course_num in range(message_count) - ] - - for schedule in schedules: - CourseModeFactory( - course_id=schedule.enrollment.course.id, - mode_slug=CourseMode.VERIFIED, - expiration_datetime=future_datetime - ) - - course_switch_queries = len(set(s.enrollment.course.id for s in schedules)) - org_switch_queries = len(set(s.enrollment.course.id.org for s in schedules)) - - test_datetime = future_datetime - test_datetime_str = serialize(test_datetime) - - patch_policies(self, [StubPolicy([ChannelType.PUSH])]) - mock_channel = Mock( - name='test_channel', - channel_type=ChannelType.EMAIL - ) - patch_channels(self, [mock_channel]) - - sent_messages = [] - - with self.settings(TEMPLATES=self._get_template_overrides()): - with patch.object(self.tested_task, 'async_send_task') as mock_schedule_send: - mock_schedule_send.apply_async = lambda args, *_a, **_kw: sent_messages.append(args) - - # we execute one query per course to see if it's opted out of dynamic upgrade deadlines - num_expected_queries = ( - NUM_QUERIES_FIRST_MATCH + NUM_QUERIES_NO_ORG_LIST + course_switch_queries + org_switch_queries - ) - - with self.assertNumQueries(num_expected_queries, table_blacklist=WAFFLE_TABLES): - self.tested_task.apply(kwargs=dict( - site_id=self.site_config.site.id, target_day_str=test_datetime_str, day_offset=2, - bin_num=self._calculate_bin_for_user(user), - )) - - self.assertEqual(len(sent_messages), 1) - - # Load the site (which we query per message sent) - # Check the schedule config - with self.assertNumQueries(2): - for args in sent_messages: - tasks._upgrade_reminder_schedule_send(*args) - - self.assertEqual(mock_channel.deliver.call_count, 1) - for (_name, (_msg, email), _kwargs) in mock_channel.deliver.mock_calls: - for template in attr.astuple(email): - self.assertNotIn("TEMPLATE WARNING", template) - self.assertNotIn("{{", template) - self.assertNotIn("}}", template) - - def _get_template_overrides(self): - templates_override = deepcopy(settings.TEMPLATES) - templates_override[0]['OPTIONS']['string_if_invalid'] = "TEMPLATE WARNING - MISSING VARIABLE [%s]" - return templates_override - def _calculate_bin_for_user(self, user): return user.id % resolvers.UPGRADE_REMINDER_NUM_BINS diff --git a/openedx/core/djangoapps/schedules/management/commands/tests/tools.py b/openedx/core/djangoapps/schedules/management/commands/tests/tools.py index 8d1f6b9be1..0f8e55c0a4 100644 --- a/openedx/core/djangoapps/schedules/management/commands/tests/tools.py +++ b/openedx/core/djangoapps/schedules/management/commands/tests/tools.py @@ -1,13 +1,18 @@ +from copy import deepcopy import datetime import ddt import logging +import attr +from django.conf import settings from freezegun import freeze_time from mock import Mock, patch import pytz from courseware.models import DynamicUpgradeDeadlineConfiguration +from edx_ace.channel import ChannelType from edx_ace.utils.date import serialize +from edx_ace.test_utils import StubPolicy, patch_channels, patch_policies from opaque_keys.edx.keys import CourseKey from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangoapps.site_configuration.tests.factories import SiteConfigurationFactory, SiteFactory @@ -75,6 +80,11 @@ class ScheduleBaseEmailTestBase(SharedModuleStoreTestCase): DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True) + def _get_template_overrides(self): + templates_override = deepcopy(settings.TEMPLATES) + templates_override[0]['OPTIONS']['string_if_invalid'] = "TEMPLATE WARNING - MISSING VARIABLE [%s]" + return templates_override + def test_command_task_binding(self): self.assertEqual(self.tested_command.async_send_task, self.tested_task) @@ -316,3 +326,56 @@ class ScheduleBaseEmailTestBase(SharedModuleStoreTestCase): )) self.assertEqual(mock_schedule_send.apply_async.call_count, 1) self.assertFalse(mock_ace.send.called) + + @ddt.data(1, 10, 100) + def test_templates(self, message_count): + for offset in self.expected_offsets: + self._assert_template_for_offset(offset, message_count) + self.clear_caches() + + def _assert_template_for_offset(self, offset, message_count): + current_day, offset, target_day = self._get_dates(offset) + + user = UserFactory.create() + for course_index in range(message_count): + ScheduleFactory.create( + start=target_day, + upgrade_deadline=target_day, + enrollment__course__self_paced=True, + enrollment__user=user, + enrollment__course__id=CourseKey.from_string('edX/toy/course{}'.format(course_index)) + ) + + patch_policies(self, [StubPolicy([ChannelType.PUSH])]) + mock_channel = Mock( + name='test_channel', + channel_type=ChannelType.EMAIL + ) + patch_channels(self, [mock_channel]) + + sent_messages = [] + with self.settings(TEMPLATES=self._get_template_overrides()): + with patch.object(self.tested_task, 'async_send_task') as mock_schedule_send: + mock_schedule_send.apply_async = lambda args, *_a, **_kw: sent_messages.append(args) + + num_expected_queries = NUM_QUERIES_NO_ORG_LIST + NUM_QUERIES_FIRST_MATCH + if self.has_course_queries: + num_expected_queries += message_count + + with self.assertNumQueries(num_expected_queries, table_blacklist=WAFFLE_TABLES): + self.tested_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(user), + )) + self.assertEqual(len(sent_messages), 1) + + with self.assertNumQueries(2): + for args in sent_messages: + self.deliver_task(*args) + + self.assertEqual(mock_channel.deliver.call_count, 1) + for (_name, (_msg, email), _kwargs) in mock_channel.deliver.mock_calls: + for template in attr.astuple(email): + self.assertNotIn("TEMPLATE WARNING", template) + self.assertNotIn("{{", template) + self.assertNotIn("}}", template)