def test_ace_send_happy_path(self, _mock_get_template): patch_policies(self, [StubPolicy([ChannelType.PUSH])]) mock_channel = Mock( name=u'test_channel', channel_type=ChannelType.EMAIL ) patch_channels(self, [mock_channel]) recipient = Recipient(username=u'testuser') msg = Message( app_label=u'testapp', name=u'testmessage', recipient=recipient, ) ace.send(msg) mock_channel.deliver.assert_called_once_with( msg, RenderedEmail( from_name=TEMPLATES[u'testapp/edx_ace/testmessage/email/from_name.txt'].render(), subject=TEMPLATES[u'testapp/edx_ace/testmessage/email/subject.txt'].render(), body_html=TEMPLATES[u'testapp/edx_ace/testmessage/email/body.html'].render(), head_html=TEMPLATES[u'testapp/edx_ace/testmessage/email/head.html'].render(), body=TEMPLATES[u'testapp/edx_ace/testmessage/email/body.txt'].render(), ), )
def test_templates(self, message_count, day): user = UserFactory.create() schedules = [ ScheduleFactory.create( upgrade_deadline=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_time = datetime.datetime(2017, 8, 3, 19, tzinfo=pytz.UTC) test_time_str = serialize(test_time) patch_policies(self, [StubPolicy([ChannelType.PUSH])]) mock_channel = Mock(name='test_channel', channel_type=ChannelType.EMAIL) patch_channels(self, [mock_channel]) sent_messages = [] templates_override = deepcopy(settings.TEMPLATES) templates_override[0]['OPTIONS'][ 'string_if_invalid'] = "TEMPLATE WARNING - MISSING VARIABLE [%s]" with self.settings(TEMPLATES=templates_override): with patch.object( tasks, '_upgrade_reminder_schedule_send') as mock_schedule_send: mock_schedule_send.apply_async = lambda args, *_a, **_kw: sent_messages.append( args) with self.assertNumQueries(3): tasks.upgrade_reminder_schedule_bin( self.site_config.site.id, target_day_str=test_time_str, day_offset=day, bin_num=user.id % tasks.UPGRADE_REMINDER_NUM_BINS, org_list=[schedules[0].enrollment.course.org], ) self.assertEqual(len(sent_messages), message_count) for args in sent_messages: tasks._upgrade_reminder_schedule_send(*args) self.assertEqual(mock_channel.deliver.call_count, message_count) for (_name, (_msg, email), _kwargs) in mock_channel.deliver.mock_calls: for template in attr.astuple(email): self.assertNotIn("TEMPLATE WARNING", template)
def _assert_template_for_offset(self, offset, message_count): current_day, offset, target_day, upgrade_deadline = self._get_dates( offset) user = UserFactory.create() for course_index in range(message_count): self._schedule_factory( offset=offset, 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.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_FIRST_MATCH if self.queries_deadline_for_each_course: # one query per course for opt-out and one for course modes num_expected_queries += (message_count * 2) - 1 else: num_expected_queries += 1 with self.assertNumQueries(num_expected_queries, table_blacklist=WAFFLE_TABLES): 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(user), )) num_expected_messages = 1 if self.consolidates_emails_for_learner else message_count self.assertEqual(len(sent_messages), num_expected_messages) with self.assertNumQueries(NUM_QUERIES_PER_MESSAGE_DELIVERY): with patch('analytics.track') as mock_analytics_track: self.deliver_task(*sent_messages[0]) self.assertEqual(mock_analytics_track.call_count, 1) 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) return mock_channel.deliver.mock_calls
def test_templates(self, message_count, day): user = UserFactory.create() schedules = [ ScheduleFactory.create(start=datetime.datetime(2017, 8, 1, 19, 44, 30, tzinfo=pytz.UTC), enrollment__user=user, enrollment__course__id=CourseLocator( 'edX', 'toy', 'Hour{}'.format(idx))) for idx in range(message_count) ] test_time_str = serialize( datetime.datetime(2017, 8, 1, 19, tzinfo=pytz.UTC)) patch_policies(self, [StubPolicy([ChannelType.PUSH])]) mock_channel = Mock(name='test_channel', channel_type=ChannelType.EMAIL) patch_channels(self, [mock_channel]) sent_messages = [] templates_override = deepcopy(settings.TEMPLATES) templates_override[0]['OPTIONS'][ 'string_if_invalid'] = "TEMPLATE WARNING - MISSING VARIABLE [%s]" with self.settings(TEMPLATES=templates_override): with patch.object( tasks, '_recurring_nudge_schedule_send') as mock_schedule_send: mock_schedule_send.apply_async = lambda args, *_a, **_kw: sent_messages.append( args) with self.assertNumQueries(2): tasks.recurring_nudge_schedule_hour( self.site_config.site.id, day, test_time_str, [schedules[0].enrollment.course.org], ) self.assertEqual(len(sent_messages), 1) 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)
def setUp(self): super(TestDelivery, self).setUp() self.mock_channel = Mock(name=u'test_channel', channel_type=ChannelType.EMAIL) patch_channels(self, [self.mock_channel]) self.recipient = Recipient(username=str(sentinel.username)) self.message = Message( app_label=str(sentinel.app_label), name=str(sentinel.name), recipient=self.recipient, ) self.current_time = datetime.datetime.utcnow().replace(tzinfo=tzutc())
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)
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_time = datetime.datetime(2017, 8, 3, 19, tzinfo=pytz.UTC) test_time_str = serialize(test_time) 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(tasks, '_recurring_nudge_schedule_send') as mock_schedule_send: mock_schedule_send.apply_async = lambda args, *_a, **_kw: sent_messages.append(args) with self.assertNumQueries(NUM_QUERIES_WITH_MATCHES, table_blacklist=WAFFLE_TABLES): tasks.recurring_nudge_schedule_bin( self.site_config.site.id, target_day_str=test_time_str, day_offset=day, bin_num=self._calculate_bin_for_user(user), org_list=[schedules[0].enrollment.course.org], ) 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)
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(tasks, '_recurring_nudge_schedule_send') as mock_schedule_send: mock_schedule_send.apply_async = lambda args, *_a, **_kw: sent_messages.append(args) with self.assertNumQueries(NUM_QUERIES_WITH_MATCHES, table_blacklist=WAFFLE_TABLES): tasks.recurring_nudge_schedule_bin( self.site_config.site.id, target_day_str=test_datetime_str, day_offset=day, bin_num=self._calculate_bin_for_user(user), org_list=[schedules[0].enrollment.course.org], ) 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)
def test_templates(self, message_count, day): settings.TEMPLATES[0]['OPTIONS']['string_if_invalid'] = "TEMPLATE WARNING - MISSING VARIABLE [%s]" user = UserFactory.create() schedules = [ ScheduleFactory.create( start=datetime.datetime(2017, 8, 1, 19, 44, 30, tzinfo=pytz.UTC), enrollment__user=user, enrollment__course__id=CourseLocator('edX', 'toy', 'Hour{}'.format(idx)) ) for idx in range(message_count) ] test_time_str = serialize(datetime.datetime(2017, 8, 1, 19, tzinfo=pytz.UTC)) patch_policies(self, [StubPolicy([ChannelType.PUSH])]) mock_channel = Mock( name='test_channel', channel_type=ChannelType.EMAIL ) patch_channels(self, [mock_channel]) sent_messages = [] with patch.object(tasks, '_recurring_nudge_schedule_send') as mock_schedule_send: mock_schedule_send.apply_async = lambda args, *_a, **_kw: sent_messages.append(args) with self.assertNumQueries(2): tasks.recurring_nudge_schedule_hour( self.site_config.site.id, day, test_time_str, [schedules[0].enrollment.course.org], ) self.assertEqual(len(sent_messages), 1) 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)
def test_templates(self, message_count, day): DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True) now = datetime.datetime.now(pytz.UTC) future_date = now + datetime.timedelta(days=21) user = UserFactory.create() schedules = [ ScheduleFactory.create(upgrade_deadline=future_date, enrollment__user=user, enrollment__course__id=CourseLocator( 'edX', 'toy', 'Course{}'.format(course_num))) for course_num in range(message_count) ] for schedule in schedules: schedule.enrollment.course.self_paced = True schedule.enrollment.course.save() CourseModeFactory(course_id=schedule.enrollment.course.id, mode_slug=CourseMode.VERIFIED, expiration_datetime=future_date) test_time = future_date test_time_str = serialize(test_time) patch_policies(self, [StubPolicy([ChannelType.PUSH])]) mock_channel = Mock(name='test_channel', channel_type=ChannelType.EMAIL) patch_channels(self, [mock_channel]) sent_messages = [] templates_override = deepcopy(settings.TEMPLATES) templates_override[0]['OPTIONS'][ 'string_if_invalid'] = "TEMPLATE WARNING - MISSING VARIABLE [%s]" with self.settings(TEMPLATES=templates_override): with patch.object( tasks, '_upgrade_reminder_schedule_send') 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, however, # since we create a new course for each schedule in this test, we expect there to be one per message num_expected_queries = NUM_QUERIES_WITH_MATCHES + NUM_QUERIES_WITH_DEADLINE + message_count with self.assertNumQueries(num_expected_queries, table_blacklist=WAFFLE_TABLES): tasks.upgrade_reminder_schedule_bin( self.site_config.site.id, target_day_str=test_time_str, day_offset=day, bin_num=user.id % tasks.UPGRADE_REMINDER_NUM_BINS, org_list=[schedules[0].enrollment.course.org], ) self.assertEqual(len(sent_messages), message_count) for args in sent_messages: tasks._upgrade_reminder_schedule_send(*args) self.assertEqual(mock_channel.deliver.call_count, message_count) for (_name, (_msg, email), _kwargs) in mock_channel.deliver.mock_calls: for template in attr.astuple(email): self.assertNotIn("TEMPLATE WARNING", template)
def test_templates(self, message_count, day): 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__id=CourseLocator('edX', 'toy', 'Course{}'.format(course_num)) ) for course_num in range(message_count) ] for schedule in schedules: schedule.enrollment.course.self_paced = True schedule.enrollment.course.end = future_datetime + datetime.timedelta(days=30) schedule.enrollment.course.save() CourseModeFactory( course_id=schedule.enrollment.course.id, mode_slug=CourseMode.VERIFIED, expiration_datetime=future_datetime ) 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(tasks, '_upgrade_reminder_schedule_send') 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, however, # since we create a new course for each schedule in this test, we expect there to be one per message num_expected_queries = NUM_QUERIES_WITH_MATCHES + NUM_QUERIES_WITH_DEADLINE + message_count with self.assertNumQueries(num_expected_queries, table_blacklist=WAFFLE_TABLES): tasks.upgrade_reminder_schedule_bin( self.site_config.site.id, target_day_str=test_datetime_str, day_offset=day, bin_num=self._calculate_bin_for_user(user), org_list=[schedules[0].enrollment.course.org], ) self.assertEqual(len(sent_messages), message_count) # Load the site (which we query per message sent) # Check the schedule config with self.assertNumQueries(1 + message_count): for args in sent_messages: tasks._upgrade_reminder_schedule_send(*args) self.assertEqual(mock_channel.deliver.call_count, message_count) for (_name, (_msg, email), _kwargs) in mock_channel.deliver.mock_calls: for template in attr.astuple(email): self.assertNotIn("TEMPLATE WARNING", template)