From ea3a323581b1bb3a97a53b6a535549d9abf53e99 Mon Sep 17 00:00:00 2001 From: sam detweiler Date: Tue, 17 Sep 2024 01:01:49 -0500 Subject: [PATCH] add fix for sliceMultiDayEvents (#3543) sliceMultiDayEvents occasionally gets the number of events wrong and produces too many rows Math.ceil() rounds up over 1.04 so we get an abnormal count then the calcs for the midnight loop control used different moment() functions, producing different results fixes #3542 --- CHANGELOG.md | 1 + modules/default/calendar/calendar.js | 5 +- .../modules/calendar/sliceMultiDayEvents.js | 30 ++++++++++ tests/electron/modules/calendar_spec.js | 18 ++++++ tests/mocks/sliceMultiDayEvents.ics | 58 +++++++++++++++++++ 5 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 tests/configs/modules/calendar/sliceMultiDayEvents.js create mode 100644 tests/mocks/sliceMultiDayEvents.ics diff --git a/CHANGELOG.md b/CHANGELOG.md index b601450f..9741ac3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ _This release is scheduled to be released on 2024-10-01._ - [core] add check for node_helper loading for multiple instances of same module (#3502) - [weather] Fixed issue for respecting unit config on broadcasted notifications - [tests] Fixes calendar test by moving it from e2e to electron with fixed date (#3532) +- [calendar] fixed sliceMultiDayEvents getting wrong count and displaying incorrect entries, Europe/Berlin (#3542) ## [2.28.0] - 2024-07-01 diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js index 31ad4f5e..f952bc59 100644 --- a/modules/default/calendar/calendar.js +++ b/modules/default/calendar/calendar.js @@ -636,7 +636,7 @@ Module.register("calendar", { * if sliceMultiDayEvents is set to true, multiday events (events exceeding at least one midnight) are sliced into days, * otherwise, esp. in dateheaders mode it is not clear how long these events are. */ - const maxCount = Math.ceil((event.endDate - 1 - moment(event.startDate, "x").endOf("day").format("x")) / ONE_DAY) + 1; + const maxCount = Math.round((event.endDate - 1 - moment(event.startDate, "x").endOf("day").format("x")) / ONE_DAY) + 1; if (this.config.sliceMultiDayEvents && maxCount > 1) { const splitEvents = []; let midnight @@ -644,6 +644,7 @@ Module.register("calendar", { .clone() .startOf("day") .add(1, "day") + .endOf("day") .format("x"); let count = 1; while (event.endDate > midnight) { @@ -656,7 +657,7 @@ Module.register("calendar", { event.startDate = midnight; count += 1; - midnight = moment(midnight, "x").add(1, "day").format("x"); // next day + midnight = moment(midnight, "x").add(1, "day").endOf("day").format("x"); // next day } // Last day event.title += ` (${count}/${maxCount})`; diff --git a/tests/configs/modules/calendar/sliceMultiDayEvents.js b/tests/configs/modules/calendar/sliceMultiDayEvents.js new file mode 100644 index 00000000..ebcf2cec --- /dev/null +++ b/tests/configs/modules/calendar/sliceMultiDayEvents.js @@ -0,0 +1,30 @@ +let config = { + timeFormat: 12, + + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + hideDuplicates: false, + maximumEntries: 100, + sliceMultiDayEvents: true, + calendars: [ + { + maximumEntries: 100, + url: "http://localhost:8080/tests/mocks/sliceMultiDayEvents.ics" + } + ] + } + } + ] +}; + +Date.now = () => { + return new Date("01 Sept 2024 10:38:00 GMT+2:00").valueOf(); +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/electron/modules/calendar_spec.js b/tests/electron/modules/calendar_spec.js index 5624b51b..8731c3cd 100644 --- a/tests/electron/modules/calendar_spec.js +++ b/tests/electron/modules/calendar_spec.js @@ -129,4 +129,22 @@ describe("Calendar module", () => { await expect(doTestCount()).resolves.toBe(2); }); }); + + /* + * RRULE TESTS: + * Add any tests that check rrule functionality here. + */ + describe("sliceMultiDayEvents", () => { + it("Issue #3452 split multiday in Europe", async () => { + await helpers.startApplication("tests/configs/modules/calendar/sliceMultiDayEvents.js", "01 Sept 2024 10:38:00 GMT+02:00", ["js/electron.js"], "Europe/Berlin"); + expect(global.page).not.toBeNull(); + const loc = await global.page.locator(".calendar .event"); + const elem = loc.first(); + await elem.waitFor(); + expect(elem).not.toBeNull(); + const cnt = await loc.count(); + expect(cnt).toBe(6); + }); + }); + }); diff --git a/tests/mocks/sliceMultiDayEvents.ics b/tests/mocks/sliceMultiDayEvents.ics new file mode 100644 index 00000000..d477246f --- /dev/null +++ b/tests/mocks/sliceMultiDayEvents.ics @@ -0,0 +1,58 @@ +BEGIN:VCALENDAR +PRODID:-//Google Inc//Google Calendar 70.9054//EN +VERSION:2.0 +CALSCALE:GREGORIAN +METHOD:PUBLISH +X-WR-CALNAME:Dirk Test +X-WR-TIMEZONE:Europe/Berlin +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240918 +DTEND;VALUE=DATE:20240919 +DTSTAMP:20240916T084410Z +UID:2crbv1ijljc2kt9jclkgu5hqa0@google.com +CREATED:20240916T083831Z +LAST-MODIFIED:20240916T083831Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:1 day single +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240919 +DTEND;VALUE=DATE:20240920 +RRULE:FREQ=YEARLY +DTSTAMP:20240916T084410Z +UID:6gb19havnq6vp2qput51e5rmml@google.com +CREATED:20240916T083850Z +LAST-MODIFIED:20240916T083850Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:1 day repeat +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240920 +DTEND;VALUE=DATE:20240922 +DTSTAMP:20240916T084410Z +UID:06e9u1trbqi3jbvstvq4qqutau@google.com +CREATED:20240916T083902Z +LAST-MODIFIED:20240916T083902Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:2 day single +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240923 +DTEND;VALUE=DATE:20240925 +RRULE:FREQ=YEARLY +DTSTAMP:20240916T084410Z +UID:0ui78rk6hpcv8rmbb6nuonhmgg@google.com +CREATED:20240916T083919Z +LAST-MODIFIED:20240916T083919Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:2 day repeat +TRANSP:TRANSPARENT +END:VEVENT +END:VCALENDAR \ No newline at end of file