From fc696a1b89f32a0f95debf9b5bc488732d3b56d6 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu, 16 Jul 2026 14:34:27 -0700 Subject: [PATCH] Fix: correctly handle date-only recurring ical events (#6875) --- src/widgets/calendar/integrations/ical.jsx | 8 ++++ .../calendar/integrations/ical.test.jsx | 39 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/widgets/calendar/integrations/ical.jsx b/src/widgets/calendar/integrations/ical.jsx index fb8219d7b..bad4a6ac9 100644 --- a/src/widgets/calendar/integrations/ical.jsx +++ b/src/widgets/calendar/integrations/ical.jsx @@ -85,6 +85,14 @@ export default function Integration({ config, params, setEvents, hideErrors, tim const getOcurrencesFromRange = (event) => { if (!event.rrule) { if (event.dtstart.compare(rangeStart) >= 0 && event.dtend.compare(rangeEnd) <= 0) { + if (event.type === "vevent" && event.dtstart.isDate && event.dtend.isDate) { + const occurrences = []; + for (const date = event.dtstart.clone(); date.compare(event.dtend) < 0; date.day += 1) { + occurrences.push(date.clone()); + } + return occurrences; + } + return [event.dtstart]; } diff --git a/src/widgets/calendar/integrations/ical.test.jsx b/src/widgets/calendar/integrations/ical.test.jsx index cd1764c37..bd0b4f873 100644 --- a/src/widgets/calendar/integrations/ical.test.jsx +++ b/src/widgets/calendar/integrations/ical.test.jsx @@ -61,4 +61,43 @@ describe("widgets/calendar/integrations/ical", () => { expect(event.url).toBe("https://example.com"); expect(event.isCompleted).toBe(false); }); + + it("adds an all-day event on every day before its exclusive end date", async () => { + useWidgetAPI.mockReturnValue({ + data: { + data: [ + "BEGIN:VCALENDAR", + "VERSION:2.0", + "PRODID:-//Homepage Test//iCal Multi-Day Event//EN", + "BEGIN:VEVENT", + "UID:multi-day-all-day@example.test", + "DTSTAMP:20260716T000000Z", + "DTSTART;VALUE=DATE:20260716", + "DTEND;VALUE=DATE:20260719", + "SUMMARY:Three-day PTO", + "END:VEVENT", + "END:VCALENDAR", + "", + ].join("\n"), + }, + error: undefined, + }); + + const setEvents = vi.fn(); + render( + , + ); + + await waitFor(() => expect(setEvents).toHaveBeenCalled()); + + const updater = setEvents.mock.calls[0][0]; + const entries = Object.values(updater({})); + expect(entries.map((event) => event.date.toISODate()).sort()).toEqual(["2026-07-16", "2026-07-17", "2026-07-18"]); + }); });