Merge pull request #742 from grafana/matiasb/web-schedules-all-day-as-datetime

Update web schedule events to return all-day start/end as datetimes
This commit is contained in:
Matias Bordese 2022-11-03 14:54:28 -03:00 committed by GitHub
commit b1a664df3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 85 additions and 18 deletions

View file

@ -264,7 +264,13 @@ class ScheduleView(
if filter_by is not None and filter_by != EVENTS_FILTER_BY_FINAL:
filter_by = OnCallSchedule.PRIMARY if filter_by == EVENTS_FILTER_BY_ROTATION else OnCallSchedule.OVERRIDES
events = schedule.filter_events(
user_tz, starting_date, days=days, with_empty=True, with_gap=resolve_schedule, filter_by=filter_by
user_tz,
starting_date,
days=days,
with_empty=True,
with_gap=resolve_schedule,
filter_by=filter_by,
all_day_datetime=True,
)
else: # return final schedule
events = schedule.final_events(user_tz, starting_date, days)

View file

@ -202,7 +202,16 @@ class OnCallSchedule(PolymorphicModel):
"""Return public primary keys for all users referenced in the schedule."""
return set()
def filter_events(self, user_timezone, starting_date, days, with_empty=False, with_gap=False, filter_by=None):
def filter_events(
self,
user_timezone,
starting_date,
days,
with_empty=False,
with_gap=False,
filter_by=None,
all_day_datetime=False,
):
"""Return filtered events from schedule."""
shifts = (
list_of_oncall_shifts_from_ical(
@ -212,13 +221,18 @@ class OnCallSchedule(PolymorphicModel):
)
events = []
for shift in shifts:
all_day = type(shift["start"]) == datetime.date
start = shift["start"]
all_day = type(start) == datetime.date
# fix confusing end date for all-day event
end = shift["end"] - timezone.timedelta(days=1) if all_day else shift["end"]
if all_day and all_day_datetime:
start = datetime.datetime.combine(start, datetime.datetime.min.time(), tzinfo=pytz.UTC)
end = datetime.datetime.combine(end, datetime.datetime.max.time(), tzinfo=pytz.UTC)
is_gap = shift.get("is_gap", False)
shift_json = {
"all_day": all_day,
"start": shift["start"],
# fix confusing end date for all-day event
"end": shift["end"] - timezone.timedelta(days=1) if all_day else shift["end"],
"start": start,
"end": end,
"users": [
{
"display_name": user.username,
@ -246,7 +260,9 @@ class OnCallSchedule(PolymorphicModel):
def final_events(self, user_tz, starting_date, days):
"""Return schedule final events, after resolving shifts and overrides."""
events = self.filter_events(user_tz, starting_date, days=days, with_empty=True, with_gap=True)
events = self.filter_events(
user_tz, starting_date, days=days, with_empty=True, with_gap=True, all_day_datetime=True
)
events = self._resolve_schedule(events)
return events

View file

@ -30,6 +30,20 @@ SUMMARY:@Alex
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20210127
DTEND;VALUE=DATE:20210129
DTSTAMP:20210127T154139Z
UID:7q00jpu4hdlr9e3j4fftbv7kt8@google.com
CREATED:20210127T143802Z
DESCRIPTION:
LAST-MODIFIED:20210127T143802Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:@Alice
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=Asia/Yekaterinburg:20210127T130000
DTEND;TZID=Asia/Yekaterinburg:20210127T220000
DTSTAMP:20210127T154139Z

View file

@ -45,8 +45,9 @@ def test_recurring_ical_events_with_all_day_event(get_ical):
parsed_iso_day_to_check - timezone.timedelta(days=1),
parsed_iso_day_to_check + timezone.timedelta(days=1),
)
assert len(events) == 4
assert len(events) == 5
assert events[0]["SUMMARY"] == "@Alex"
assert events[1]["SUMMARY"] == "@Bob"
assert events[2]["SUMMARY"] == "@Bernard Desruisseaux"
assert events[1]["SUMMARY"] == "@Alice"
assert events[2]["SUMMARY"] == "@Bob"
assert events[3]["SUMMARY"] == "@Bernard Desruisseaux"
assert events[4]["SUMMARY"] == "@Bernard Desruisseaux"

View file

@ -91,7 +91,7 @@ def test_shifts_dict_all_day_middle_event(make_organization, make_schedule, get_
parsed_iso_day_to_check = datetime.datetime.fromisoformat(day_to_check_iso).replace(tzinfo=pytz.UTC)
requested_date = (parsed_iso_day_to_check - timezone.timedelta(days=1)).date()
shifts = list_of_oncall_shifts_from_ical(schedule, requested_date, days=3, with_empty_shifts=True)
assert len(shifts) == 4
assert len(shifts) == 5
for s in shifts:
start = s["start"].date() if isinstance(s["start"], datetime.datetime) else s["start"]
end = s["end"].date() if isinstance(s["end"], datetime.datetime) else s["end"]

View file

@ -235,7 +235,7 @@ def test_filter_events_ical_all_day(make_organization, make_user_for_organizatio
organization = make_organization()
schedule = make_schedule(organization, schedule_class=OnCallScheduleCalendar)
schedule.cached_ical_file_primary = calendar.to_ical()
for u in ("@Bernard Desruisseaux", "@Bob", "@Alex"):
for u in ("@Bernard Desruisseaux", "@Bob", "@Alex", "@Alice"):
make_user_for_organization(organization, username=u)
# clear users pks <-> organization cache (persisting between tests)
memoized_users_in_ical.cache_clear()
@ -246,14 +246,44 @@ def test_filter_events_ical_all_day(make_organization, make_user_for_organizatio
events = schedule.final_events("UTC", start_date, days=2)
expected_events = [
# all_day, users, start
(False, ["@Bernard Desruisseaux"], datetime.datetime(2021, 1, 26, 8, 0, tzinfo=pytz.UTC)),
(True, ["@Alex"], datetime.date(2021, 1, 27)),
(False, ["@Bob"], datetime.datetime(2021, 1, 27, 8, 0, tzinfo=pytz.UTC)),
# all_day, users, start, end
(
False,
["@Bernard Desruisseaux"],
datetime.datetime(2021, 1, 26, 8, 0, tzinfo=pytz.UTC),
datetime.datetime(2021, 1, 26, 17, 0, tzinfo=pytz.UTC),
),
(
True,
["@Alex"],
datetime.datetime(2021, 1, 27, 0, 0, tzinfo=pytz.UTC),
datetime.datetime(2021, 1, 27, 23, 59, 59, 999999, tzinfo=pytz.UTC),
),
(
True,
["@Alice"],
datetime.datetime(2021, 1, 27, 0, 0, tzinfo=pytz.UTC),
datetime.datetime(2021, 1, 28, 23, 59, 59, 999999, tzinfo=pytz.UTC),
),
(
False,
["@Bob"],
datetime.datetime(2021, 1, 27, 8, 0, tzinfo=pytz.UTC),
datetime.datetime(2021, 1, 27, 17, 0, tzinfo=pytz.UTC),
),
]
expected = [
{"all_day": all_day, "users": users, "start": start, "end": end}
for all_day, users, start, end in expected_events
]
expected = [{"all_day": all_day, "users": users, "start": start} for all_day, users, start in expected_events]
returned = [
{"all_day": e["all_day"], "users": [u["display_name"] for u in e["users"]], "start": e["start"]} for e in events
{
"all_day": e["all_day"],
"users": [u["display_name"] for u in e["users"]],
"start": e["start"],
"end": e["end"],
}
for e in events
]
assert returned == expected