Update daily shifts by day to handle changed week start (#2263)
Related to https://github.com/grafana/oncall/issues/2118#issuecomment-1592889257
This commit is contained in:
parent
85beacaeb0
commit
91461991de
2 changed files with 88 additions and 6 deletions
|
|
@ -324,12 +324,14 @@ class CustomOnCallShift(models.Model):
|
|||
break
|
||||
last_start = start
|
||||
day = CustomOnCallShift.ICAL_WEEKDAY_MAP[start.weekday()]
|
||||
if (user_group_id, day, i) in combinations:
|
||||
all_rotations_checked = True
|
||||
break
|
||||
# double-check day is valid (when until is set, we may get unexpected days)
|
||||
if day in self.by_day:
|
||||
if (user_group_id, day, i) in combinations:
|
||||
all_rotations_checked = True
|
||||
break
|
||||
|
||||
starting_dates.append(start)
|
||||
combinations.append((user_group_id, day, i))
|
||||
starting_dates.append(start)
|
||||
combinations.append((user_group_id, day, i))
|
||||
# get next event date following the original rule
|
||||
event_ical = self.generate_ical(start, 1, None, 1, time_zone, custom_rrule=day_by_day_rrule)
|
||||
start = self.get_rotation_date(event_ical, get_next_date=True, interval=1)
|
||||
|
|
@ -386,7 +388,10 @@ class CustomOnCallShift(models.Model):
|
|||
if self.frequency is not None and self.by_day and start is not None:
|
||||
start_day = CustomOnCallShift.ICAL_WEEKDAY_MAP[start.weekday()]
|
||||
if start_day not in self.by_day:
|
||||
expected_start_day = min(CustomOnCallShift.ICAL_WEEKDAY_REVERSE_MAP[d] for d in self.by_day)
|
||||
# when calculating first start date, make sure to sort days using week_start
|
||||
sorted_days = [i % 7 for i in range(self.week_start, self.week_start + 7)]
|
||||
selected_days = [CustomOnCallShift.ICAL_WEEKDAY_REVERSE_MAP[d] for d in self.by_day]
|
||||
expected_start_day = [d for d in sorted_days if d in selected_days][0]
|
||||
delta = (expected_start_day - start.weekday()) % 7
|
||||
start = start + datetime.timedelta(days=delta)
|
||||
|
||||
|
|
|
|||
|
|
@ -1712,3 +1712,80 @@ def test_until_rrule_must_be_utc(
|
|||
expected_rrule = f"RRULE:FREQ=WEEKLY;UNTIL={ical_rrule_until}Z;INTERVAL=4;WKST=SU"
|
||||
|
||||
assert expected_rrule in ical_data
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_week_start_changed_daily_shift(
|
||||
make_organization_and_user,
|
||||
make_schedule,
|
||||
make_on_call_shift,
|
||||
):
|
||||
organization, user_1 = make_organization_and_user()
|
||||
schedule = make_schedule(organization, schedule_class=OnCallScheduleWeb, time_zone="Europe/Warsaw")
|
||||
|
||||
now = timezone.now().replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
today_weekday = now.weekday()
|
||||
last_sunday = now - timezone.timedelta(days=7 + (today_weekday + 1) % 7)
|
||||
last_saturday = last_sunday - timezone.timedelta(days=1)
|
||||
|
||||
# set week start to Sunday, so first event should be on last_sunday itself
|
||||
data = {
|
||||
"priority_level": 1,
|
||||
"start": last_saturday,
|
||||
"rotation_start": last_sunday,
|
||||
"duration": timezone.timedelta(seconds=3600),
|
||||
"frequency": CustomOnCallShift.FREQUENCY_DAILY,
|
||||
"by_day": ["MO", "SU"],
|
||||
"week_start": 5, # SU
|
||||
"interval": 1,
|
||||
"schedule": schedule,
|
||||
}
|
||||
on_call_shift = make_on_call_shift(
|
||||
organization=organization, shift_type=CustomOnCallShift.TYPE_ROLLING_USERS_EVENT, **data
|
||||
)
|
||||
rolling_users = [[user_1]]
|
||||
on_call_shift.add_rolling_users(rolling_users)
|
||||
|
||||
ical_data = on_call_shift.convert_to_ical()
|
||||
expected_start = "DTSTART;VALUE=DATE-TIME:{}T000000Z".format(last_sunday.strftime("%Y%m%d"))
|
||||
assert expected_start in ical_data
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_week_start_changed_daily_shift_until(
|
||||
make_organization_and_user,
|
||||
make_schedule,
|
||||
make_on_call_shift,
|
||||
):
|
||||
organization, user_1 = make_organization_and_user()
|
||||
schedule = make_schedule(organization, schedule_class=OnCallScheduleWeb, time_zone="Europe/Warsaw")
|
||||
|
||||
now = timezone.now().replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
today_weekday = now.weekday()
|
||||
last_sunday = now - timezone.timedelta(days=7 + (today_weekday + 1) % 7)
|
||||
last_saturday = last_sunday - timezone.timedelta(days=1)
|
||||
thursday = last_sunday + timezone.timedelta(days=4)
|
||||
|
||||
data = {
|
||||
"priority_level": 1,
|
||||
"start": last_saturday,
|
||||
"rotation_start": last_sunday,
|
||||
"duration": timezone.timedelta(seconds=3600),
|
||||
"frequency": CustomOnCallShift.FREQUENCY_DAILY,
|
||||
"by_day": ["MO", "SU"],
|
||||
"week_start": 5, # SU
|
||||
"interval": 1,
|
||||
"until": thursday,
|
||||
"schedule": schedule,
|
||||
}
|
||||
on_call_shift = make_on_call_shift(
|
||||
organization=organization, shift_type=CustomOnCallShift.TYPE_ROLLING_USERS_EVENT, **data
|
||||
)
|
||||
rolling_users = [[user_1]]
|
||||
on_call_shift.add_rolling_users(rolling_users)
|
||||
|
||||
ical_data = on_call_shift.convert_to_ical()
|
||||
# setting UNTIL to Thursday was generating extra events for current week Wednesday and Thursday
|
||||
unexpected_by_days = ("BYDAY=WE", "BYDAY=TH")
|
||||
for unexpected in unexpected_by_days:
|
||||
assert unexpected not in ical_data
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue