From 126b76821fe7d9574f370b3296a2d33b22b1d6b4 Mon Sep 17 00:00:00 2001 From: sam detweiler Date: Mon, 16 Sep 2024 16:12:30 -0500 Subject: [PATCH] add fix for sliceMultiDayEvents #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 9db5f2669a..bd75d22455 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ _This release is scheduled to be released on 2024-10-01._ - [weather] Fixed issue with the UK Met Office provider following a change in their API paths and header info. - [core] add check for node_helper loading for multiple instances of same module (#3502) - [weather] Fixed issue for respecting unit config on broadcasted notifications +- [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 31ad4f5ea0..f952bc5956 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 0000000000..ebcf2cec4f --- /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 bf10ecd752..cb05c84873 100644 --- a/tests/electron/modules/calendar_spec.js +++ b/tests/electron/modules/calendar_spec.js @@ -155,4 +155,22 @@ describe("Calendar module", () => { expect(cnt).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 0000000000..d477246f16 --- /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