From 4bb1ef1119b1dbbc6a8dbd18ce0d3a7578978b52 Mon Sep 17 00:00:00 2001 From: Matias Bordese Date: Wed, 30 Aug 2023 23:02:10 -0300 Subject: [PATCH 1/3] Truncate exported final shifts to match the requested period --- .../apps/public_api/tests/test_schedules.py | 48 ++++++++++++++++++- engine/apps/public_api/views/schedules.py | 7 +-- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/engine/apps/public_api/tests/test_schedules.py b/engine/apps/public_api/tests/test_schedules.py index 539034486b..f26b0d8a98 100644 --- a/engine/apps/public_api/tests/test_schedules.py +++ b/engine/apps/public_api/tests/test_schedules.py @@ -969,7 +969,7 @@ def test_oncall_shifts_export_from_ical_schedule( client = APIClient() url = reverse("api-public:schedules-final-shifts", kwargs={"pk": schedule.public_primary_key}) - response = client.get(f"{url}?start_date=2023-07-01&end_date=2023-08-01", format="json", HTTP_AUTHORIZATION=token) + response = client.get(f"{url}?start_date=2023-07-01&end_date=2023-07-31", format="json", HTTP_AUTHORIZATION=token) assert response.status_code == status.HTTP_200_OK expected_on_call_times = { @@ -1006,7 +1006,7 @@ def test_oncall_shifts_export_from_api_schedule( client = APIClient() url = reverse("api-public:schedules-final-shifts", kwargs={"pk": schedule.public_primary_key}) - response = client.get(f"{url}?start_date=2023-07-01&end_date=2023-08-01", format="json", HTTP_AUTHORIZATION=token) + response = client.get(f"{url}?start_date=2023-07-01&end_date=2023-07-31", format="json", HTTP_AUTHORIZATION=token) assert response.status_code == status.HTTP_200_OK expected_on_call_times = { @@ -1014,3 +1014,47 @@ def test_oncall_shifts_export_from_api_schedule( user2.public_primary_key: 30, # daily 2h * 15d } assert_expected_shifts_export_response(response, (user1, user2), expected_on_call_times) + + +@pytest.mark.django_db +def test_oncall_shifts_export_truncate_events( + make_organization_and_user_with_token, + make_user, + make_schedule, + make_on_call_shift, +): + organization, _, token = make_organization_and_user_with_token() + + user1_email = "alice909450945045@example.com" + user1_username = "alice" + + user1 = make_user(organization=organization, email=user1_email, username=user1_username) + + user1_public_primary_key = user1.public_primary_key + schedule = make_schedule(organization, schedule_class=OnCallScheduleWeb) + + # 24h shifts starting 9am on Mo, We and Fr + start_date = timezone.datetime(2023, 1, 1, 9, 0, 0, tzinfo=pytz.UTC) + make_on_call_shift( + organization=organization, + schedule=schedule, + shift_type=CustomOnCallShift.TYPE_ROLLING_USERS_EVENT, + frequency=CustomOnCallShift.FREQUENCY_DAILY, + priority_level=1, + interval=1, + by_day=["MO", "WE", "FR"], + start=start_date, + rolling_users=[{user1.pk: user1_public_primary_key}], + rotation_start=start_date, + duration=timezone.timedelta(hours=24), + ) + + client = APIClient() + + # request shifts on a Tu (ie. 00:00 - 09:00) + url = reverse("api-public:schedules-final-shifts", kwargs={"pk": schedule.public_primary_key}) + response = client.get(f"{url}?start_date=2023-01-03&end_date=2023-01-03", format="json", HTTP_AUTHORIZATION=token) + assert response.status_code == status.HTTP_200_OK + + expected_on_call_times = {user1.public_primary_key: 9} + assert_expected_shifts_export_response(response, (user1,), expected_on_call_times) diff --git a/engine/apps/public_api/views/schedules.py b/engine/apps/public_api/views/schedules.py index d8c5ec5c28..88b1fe26ab 100644 --- a/engine/apps/public_api/views/schedules.py +++ b/engine/apps/public_api/views/schedules.py @@ -145,7 +145,7 @@ def final_shifts(self, request, pk): datetime_start = datetime.datetime.combine(start_date, datetime.time.min, tzinfo=pytz.UTC) datetime_end = datetime_start + datetime.timedelta( - days=days_between_start_and_end - 1, hours=23, minutes=59, seconds=59 + days=days_between_start_and_end, hours=23, minutes=59, seconds=59 ) final_schedule_events: ScheduleEvents = schedule.final_events(datetime_start, datetime_end) @@ -158,8 +158,9 @@ def final_shifts(self, request, pk): "user_pk": user["pk"], "user_email": user["email"], "user_username": user["display_name"], - "shift_start": event["start"], - "shift_end": event["end"], + # truncate shift start/end exceeding the requested period + "shift_start": event["start"] if event["start"] >= datetime_start else datetime_start, + "shift_end": event["end"] if event["end"] <= datetime_end else datetime_end, } for event in final_schedule_events for user in event["users"] From 270c8e50ab56a0d621f696a01baba21fde2fac1b Mon Sep 17 00:00:00 2001 From: Matias Bordese Date: Wed, 30 Aug 2023 23:06:07 -0300 Subject: [PATCH 2/3] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3a660d23b..22c393546e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Performance and UX tweaks to integrations page ([#2869](https://github.com/grafana/oncall/pull/2869)) - Expand users details in filter swaps internal endpoint ([#2921](https://github.com/grafana/oncall/pull/2921)) +- Truncate exported final shifts to match the requested period ([#2924](https://github.com/grafana/oncall/pull/2924)) ### Fixed From 4005a74dcd8e492afe128b528843d36b29ef9eb8 Mon Sep 17 00:00:00 2001 From: Matias Bordese Date: Wed, 30 Aug 2023 23:34:23 -0300 Subject: [PATCH 3/3] Update test --- engine/apps/public_api/tests/test_schedules.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/engine/apps/public_api/tests/test_schedules.py b/engine/apps/public_api/tests/test_schedules.py index f26b0d8a98..3834c8df5d 100644 --- a/engine/apps/public_api/tests/test_schedules.py +++ b/engine/apps/public_api/tests/test_schedules.py @@ -1024,11 +1024,7 @@ def test_oncall_shifts_export_truncate_events( make_on_call_shift, ): organization, _, token = make_organization_and_user_with_token() - - user1_email = "alice909450945045@example.com" - user1_username = "alice" - - user1 = make_user(organization=organization, email=user1_email, username=user1_username) + user1 = make_user(organization=organization) user1_public_primary_key = user1.public_primary_key schedule = make_schedule(organization, schedule_class=OnCallScheduleWeb) @@ -1056,5 +1052,5 @@ def test_oncall_shifts_export_truncate_events( response = client.get(f"{url}?start_date=2023-01-03&end_date=2023-01-03", format="json", HTTP_AUTHORIZATION=token) assert response.status_code == status.HTTP_200_OK - expected_on_call_times = {user1.public_primary_key: 9} + expected_on_call_times = {user1_public_primary_key: 9} assert_expected_shifts_export_response(response, (user1,), expected_on_call_times)