From 5bfb322f1ed6a1b49517cc2f673c73ccd4f7d932 Mon Sep 17 00:00:00 2001 From: Tyler Hallada Date: Wed, 11 Oct 2017 15:12:27 -0400 Subject: [PATCH] Don't send RET emails after course end --- .../course_overviews/tests/factories.py | 4 +++- .../tests/test_send_recurring_nudge.py | 22 +++++++++++++++++++ openedx/core/djangoapps/schedules/tasks.py | 8 ++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/openedx/core/djangoapps/content/course_overviews/tests/factories.py b/openedx/core/djangoapps/content/course_overviews/tests/factories.py index c9878e1481..f412fda062 100644 --- a/openedx/core/djangoapps/content/course_overviews/tests/factories.py +++ b/openedx/core/djangoapps/content/course_overviews/tests/factories.py @@ -1,6 +1,7 @@ import json import factory +from django.utils.timezone import get_current_timezone from factory.django import DjangoModelFactory from ..models import CourseOverview @@ -14,7 +15,8 @@ class CourseOverviewFactory(DjangoModelFactory): version = CourseOverview.VERSION pre_requisite_courses = [] - start = factory.Faker('past_datetime') + start = factory.Faker('past_datetime', tzinfo=get_current_timezone()) + end = factory.Faker('future_datetime', tzinfo=get_current_timezone()) org = 'edX' @factory.lazy_attribute 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 5674a9e3ea..049f519f5f 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 @@ -18,6 +18,7 @@ from opaque_keys.edx.locator import CourseLocator from course_modes.models import CourseMode from course_modes.tests.factories import CourseModeFactory from courseware.models import DynamicUpgradeDeadlineConfiguration +from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory from openedx.core.djangoapps.schedules import resolvers, tasks from openedx.core.djangoapps.schedules.management.commands import send_recurring_nudge as nudge from openedx.core.djangoapps.schedules.tests.factories import ScheduleConfigFactory, ScheduleFactory @@ -140,6 +141,27 @@ class TestSendRecurringNudge(FilteredQueryCountMixin, CacheIsolationTestCase): # is null. self.assertEqual(mock_schedule_send.apply_async.call_count, 0) + @patch.object(tasks, '_recurring_nudge_schedule_send') + def test_send_after_course_end(self, mock_schedule_send): + user1 = UserFactory.create(id=tasks.RECURRING_NUDGE_NUM_BINS) + + schedule = ScheduleFactory.create( + start=datetime.datetime(2017, 8, 3, 20, 34, 30, tzinfo=pytz.UTC), + enrollment__user=user1, + ) + schedule.enrollment.course = CourseOverviewFactory() + schedule.enrollment.course.end = datetime.datetime.now() - datetime.timedelta(days=1) + + test_time = datetime.datetime(2017, 8, 3, 20, tzinfo=pytz.UTC) + test_time_str = serialize(test_time) + + tasks.recurring_nudge_schedule_bin.apply_async( + self.site_config.site.id, target_day_str=test_time_str, day_offset=-3, bin_num=0, + org_list=[schedule.enrollment.course.org], + ) + + self.assertFalse(mock_schedule_send.apply_async.called) + @patch.object(tasks, 'ace') def test_delivery_disabled(self, mock_ace): ScheduleConfigFactory.create(site=self.site_config.site, deliver_recurring_nudge=False) diff --git a/openedx/core/djangoapps/schedules/tasks.py b/openedx/core/djangoapps/schedules/tasks.py index 054c7a175d..018d2b2d8d 100644 --- a/openedx/core/djangoapps/schedules/tasks.py +++ b/openedx/core/djangoapps/schedules/tasks.py @@ -9,7 +9,7 @@ from django.contrib.sites.models import Site from django.contrib.staticfiles.templatetags.staticfiles import static from django.core.exceptions import ValidationError from django.core.urlresolvers import reverse -from django.db.models import F, Min +from django.db.models import F, Min, Q from django.db.utils import DatabaseError from django.utils.formats import dateformat, get_format import pytz @@ -112,7 +112,7 @@ def recurring_nudge_schedule_bin( def _recurring_nudge_schedules_for_bin(site, target_day, bin_num, org_list, exclude_orgs=False): - beginning_of_day = target_day.replace(hour=0, minute=0, second=0) + beginning_of_day = target_day.replace(hour=0, minute=0, second=0, microsecond=0) schedules = get_schedules_with_target_date_by_bin_and_orgs( schedule_date_field='start', target_date=beginning_of_day, @@ -186,7 +186,7 @@ def _upgrade_reminder_schedule_send(site_id, msg_str): def _upgrade_reminder_schedules_for_bin(site, target_day, bin_num, org_list, exclude_orgs=False): - beginning_of_day = target_day.replace(hour=0, minute=0, second=0) + beginning_of_day = target_day.replace(hour=0, minute=0, second=0, microsecond=0) schedules = get_schedules_with_target_date_by_bin_and_orgs( schedule_date_field='upgrade_deadline', @@ -332,6 +332,7 @@ def get_schedules_with_target_date_by_bin_and_orgs(schedule_date_field, target_d exclude_orgs -- boolean indicating whether the returned Schedules should exclude (True) the course_orgs in org_list or strictly include (False) them (default: False) """ + today = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) schedule_date_equals_target_date_filter = { 'courseenrollment__schedule__{}__gte'.format(schedule_date_field): target_date, 'courseenrollment__schedule__{}__lt'.format(schedule_date_field): target_date + datetime.timedelta(days=1), @@ -355,6 +356,7 @@ def get_schedules_with_target_date_by_bin_and_orgs(schedule_date_field, target_d ).prefetch_related( 'enrollment__course__modes' ).filter( + Q(enrollment__course__end__isnull=True) | Q(enrollment__course__end__gte=today), enrollment__user__in=users, enrollment__is_active=True, **schedule_date_equals_target_date_filter