Check possible split events in range when resolving schedule (#2828)

When an event is split because of a swap request, we were including the
original event if it was supposed to be in progress during the requested
time span.
This commit is contained in:
Matias Bordese 2023-08-18 10:58:31 -03:00 committed by GitHub
parent 10e8270b40
commit ad00187968
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 2 deletions

View file

@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed UTC conversion for escalation chain step of timerange
([#2781](https://github.com/grafana/oncall/issues/2781))
### Fixed
- Check for possible split events in range when resolving schedule ([#2828](https://github.com/grafana/oncall/pull/2828))
## v1.3.24 (2023-08-17)
### Added

View file

@ -812,6 +812,10 @@ class OnCallSchedule(PolymorphicModel):
# exclude events without active users
continue
if ev["start"] >= datetime_end or ev["end"] <= datetime_start:
# avoid including split events which now are outside the requested time range
continue
# api/terraform shifts could be missing a priority; assume None means 0
priority = ev["priority_level"] or 0
if priority != current_priority or current_type != ev["calendar_type"]:

View file

@ -2094,6 +2094,62 @@ def test_swap_request_split_end(
assert events[1]["users"][0]["pk"] == user.public_primary_key
@pytest.mark.django_db
def test_swap_request_split_final_events_range(
make_organization,
make_user_for_organization,
make_schedule,
make_on_call_shift,
make_shift_swap_request,
):
organization = make_organization()
user = make_user_for_organization(organization)
other_user = make_user_for_organization(organization)
schedule = make_schedule(organization, schedule_class=OnCallScheduleWeb)
today = timezone.now().replace(hour=0, minute=0, second=0, microsecond=0)
start = today + timezone.timedelta(hours=10)
duration = timezone.timedelta(hours=8)
data = {
"start": start,
"rotation_start": start,
"duration": duration,
"priority_level": 1,
"frequency": CustomOnCallShift.FREQUENCY_DAILY,
"schedule": schedule,
}
on_call_shift = make_on_call_shift(
organization=organization, shift_type=CustomOnCallShift.TYPE_ROLLING_USERS_EVENT, **data
)
on_call_shift.add_rolling_users([[user]])
tomorrow = today + timezone.timedelta(days=1)
# setup swap request
swap_request = make_shift_swap_request(
schedule,
user,
swap_start=tomorrow + timezone.timedelta(hours=16),
swap_end=tomorrow + timezone.timedelta(hours=18),
)
swap_request.take(other_user)
# check final events for tomorrow while swap in progress
now = tomorrow + timezone.timedelta(hours=16, minutes=10)
events = schedule.final_events(now, now)
assert len(events) == 1
expected = [
# start, end, on-call user
(
tomorrow + timezone.timedelta(hours=16),
tomorrow + timezone.timedelta(hours=18),
other_user.public_primary_key,
),
]
returned = [(e["start"], e["end"], e["users"][0]["pk"]) for e in events]
assert returned == expected
@pytest.mark.django_db
@pytest.mark.parametrize("swap_taken", [False, True])
def test_swap_request_split_both(

View file

@ -190,7 +190,7 @@ def test_get_schedule_score_weekdays(
assert response.json() == {
"total_score": 86,
"comments": [
{"type": "warning", "text": "Schedule has gaps (28% not covered)"},
{"type": "warning", "text": "Schedule has gaps (29% not covered)"},
{"type": "info", "text": "Schedule is perfectly balanced"},
],
"overloaded_users": [],
@ -351,7 +351,7 @@ def test_get_schedule_score_all_week_imbalanced_weekends(
{
"id": user.public_primary_key,
"username": user.username,
"score": 28,
"score": 29,
}
for user in users[:4]
],