diff --git a/engine/apps/schedules/tasks/notify_about_empty_shifts_in_schedule.py b/engine/apps/schedules/tasks/notify_about_empty_shifts_in_schedule.py index afdf789cb..836dbeb69 100644 --- a/engine/apps/schedules/tasks/notify_about_empty_shifts_in_schedule.py +++ b/engine/apps/schedules/tasks/notify_about_empty_shifts_in_schedule.py @@ -1,6 +1,7 @@ import pytz from celery.utils.log import get_task_logger from django.core.cache import cache +from django.db.models import Q from django.utils import timezone from apps.slack.utils import format_datetime_to_slack_with_time, post_message_to_channel @@ -24,14 +25,14 @@ def check_empty_shifts_in_schedule(schedule_pk): @shared_dedicated_queue_retry_task() def start_notify_about_empty_shifts_in_schedule(): - from apps.schedules.models import OnCallScheduleICal + from apps.schedules.models import OnCallSchedule task_logger.info("Start start_notify_about_empty_shifts_in_schedule") today = timezone.now().date() week_ago = today - timezone.timedelta(days=7) - schedules = OnCallScheduleICal.objects.filter( - empty_shifts_report_sent_at__lte=week_ago, + schedules = OnCallSchedule.objects.filter( + Q(empty_shifts_report_sent_at__lte=week_ago) | Q(empty_shifts_report_sent_at__isnull=True), slack_channel__isnull=False, organization__deleted_at__isnull=True, ) diff --git a/engine/apps/schedules/tasks/notify_about_gaps_in_schedule.py b/engine/apps/schedules/tasks/notify_about_gaps_in_schedule.py index 5047943e0..1ef7ed248 100644 --- a/engine/apps/schedules/tasks/notify_about_gaps_in_schedule.py +++ b/engine/apps/schedules/tasks/notify_about_gaps_in_schedule.py @@ -1,6 +1,7 @@ import pytz from celery.utils.log import get_task_logger from django.core.cache import cache +from django.db.models import Q from django.utils import timezone from apps.slack.utils import format_datetime_to_slack_with_time, post_message_to_channel @@ -30,7 +31,7 @@ def start_notify_about_gaps_in_schedule(): today = timezone.now().date() week_ago = today - timezone.timedelta(days=7) schedules = OnCallSchedule.objects.filter( - gaps_report_sent_at__lte=week_ago, + Q(gaps_report_sent_at__lte=week_ago) | Q(gaps_report_sent_at__isnull=True), slack_channel__isnull=False, organization__deleted_at__isnull=True, ) diff --git a/engine/apps/schedules/tests/test_notify_about_empty_shifts_in_schedule.py b/engine/apps/schedules/tests/test_notify_about_empty_shifts_in_schedule.py index 2c6bb0913..1790fd7c8 100644 --- a/engine/apps/schedules/tests/test_notify_about_empty_shifts_in_schedule.py +++ b/engine/apps/schedules/tests/test_notify_about_empty_shifts_in_schedule.py @@ -5,8 +5,8 @@ from django.utils import timezone from apps.api.permissions import LegacyAccessControlRole -from apps.schedules.models import CustomOnCallShift, OnCallScheduleWeb -from apps.schedules.tasks import notify_about_empty_shifts_in_schedule_task +from apps.schedules.models import CustomOnCallShift, OnCallScheduleCalendar, OnCallScheduleICal, OnCallScheduleWeb +from apps.schedules.tasks import notify_about_empty_shifts_in_schedule_task, start_notify_about_empty_shifts_in_schedule @pytest.mark.django_db @@ -174,3 +174,45 @@ def test_empty_non_empty_shifts_trigger_notification( schedule.refresh_from_db() assert empty_shifts_report_sent_at != schedule.empty_shifts_report_sent_at assert schedule.has_empty_shifts + + +@pytest.mark.parametrize( + "schedule_class", + [OnCallScheduleWeb, OnCallScheduleICal, OnCallScheduleCalendar], +) +@pytest.mark.parametrize( + "report_sent_days_ago,expected_call", + [(8, True), (6, False), (None, True)], +) +@pytest.mark.django_db +def test_start_notify_about_empty_shifts( + make_slack_team_identity, + make_slack_channel, + make_organization, + make_schedule, + schedule_class, + report_sent_days_ago, + expected_call, +): + slack_team_identity = make_slack_team_identity() + slack_channel = make_slack_channel(slack_team_identity) + organization = make_organization(slack_team_identity=slack_team_identity) + + sent = timezone.now() - datetime.timedelta(days=report_sent_days_ago) if report_sent_days_ago else None + schedule = make_schedule( + organization, + schedule_class=schedule_class, + name="test_schedule", + slack_channel=slack_channel, + empty_shifts_report_sent_at=sent, + ) + + with patch( + "apps.schedules.tasks.notify_about_empty_shifts_in_schedule.notify_about_empty_shifts_in_schedule_task.apply_async" + ) as mock_notify: + start_notify_about_empty_shifts_in_schedule() + + if expected_call: + mock_notify.assert_called_once_with((schedule.pk,)) + else: + mock_notify.assert_not_called() diff --git a/engine/apps/schedules/tests/test_notify_about_gaps_in_schedule.py b/engine/apps/schedules/tests/test_notify_about_gaps_in_schedule.py index d775c77b7..5e35cf066 100644 --- a/engine/apps/schedules/tests/test_notify_about_gaps_in_schedule.py +++ b/engine/apps/schedules/tests/test_notify_about_gaps_in_schedule.py @@ -4,8 +4,8 @@ import pytest from django.utils import timezone -from apps.schedules.models import CustomOnCallShift, OnCallScheduleWeb -from apps.schedules.tasks import notify_about_gaps_in_schedule_task +from apps.schedules.models import CustomOnCallShift, OnCallScheduleCalendar, OnCallScheduleICal, OnCallScheduleWeb +from apps.schedules.tasks import notify_about_gaps_in_schedule_task, start_notify_about_gaps_in_schedule @pytest.mark.django_db @@ -286,3 +286,45 @@ def test_gaps_later_than_7_days_no_triggering_notification( schedule.refresh_from_db() assert gaps_report_sent_at != schedule.gaps_report_sent_at assert schedule.has_gaps is False + + +@pytest.mark.parametrize( + "schedule_class", + [OnCallScheduleWeb, OnCallScheduleICal, OnCallScheduleCalendar], +) +@pytest.mark.parametrize( + "report_sent_days_ago,expected_call", + [(8, True), (6, False), (None, True)], +) +@pytest.mark.django_db +def test_start_notify_about_gaps( + make_slack_team_identity, + make_slack_channel, + make_organization, + make_schedule, + schedule_class, + report_sent_days_ago, + expected_call, +): + slack_team_identity = make_slack_team_identity() + slack_channel = make_slack_channel(slack_team_identity) + organization = make_organization(slack_team_identity=slack_team_identity) + + sent = timezone.now() - datetime.timedelta(days=report_sent_days_ago) if report_sent_days_ago else None + schedule = make_schedule( + organization, + schedule_class=schedule_class, + name="test_schedule", + slack_channel=slack_channel, + gaps_report_sent_at=sent, + ) + + with patch( + "apps.schedules.tasks.notify_about_gaps_in_schedule.notify_about_gaps_in_schedule_task.apply_async" + ) as mock_notify: + start_notify_about_gaps_in_schedule() + + if expected_call: + mock_notify.assert_called_once_with((schedule.pk,)) + else: + mock_notify.assert_not_called()