Fixcaldates2 fix calendar module date processing, using node-ical@0.20.1 (#3587)

here is an updated test version of the fixes for all kinds of calendar
date problems.

NOTE: the changed branch name
NOTE: this used the node-cal@0.19.0 library UNCHANGED

best to make a new folder and git clone there

git clone https://github.com/sdetweil/MagicMirror
cd MagicMirror
git checkout fixcaldates2 // <------ note this is a changed branch name
npm run install-mm
copy your config.js and custom.css from the prior folder
and the non-default modules you have installed…

this ONLY changes the default calendar
but DOES ship an updated node-ical library too

if you need to fall back, just rename the folders around again so that
your original is called MagicMirror

all the testcases for node-ical and MagicMirror execute successfully.

the ‘BIG’ change here is to get the local NON-TZ dates for the
rrule.between()

all the checking and conversion code is commented out or not used
the node-ical fixes are for excluded dates (exdate) values being
adjusted for DST/STD time… waiting to submit that PR

one fix in calendar.js for checking if a past date was too far back,
but it never checked to see IF the event date was in the past… (before
today) so it chopped off too many

and one change in calendarfetcher.js to put out a better diagnostic
message of the parsed data… (exdate was excluded cause JSON stringify
couldn’t convert the complex structure)

I added the tests you all have documented

please re-pull and checkout the new branch (I deleted the old branch)
and npm run install-mm again

---------

Co-authored-by: Veeck <github@veeck.de>
This commit is contained in:
sam detweiler
2024-12-07 02:51:11 -06:00
committed by GitHub
parent 291ae8546c
commit 19bd76ab93
33 changed files with 1182 additions and 113 deletions

View File

@@ -0,0 +1,35 @@
let config = {
address: "0.0.0.0",
ipWhitelist: [],
timeFormat: 24,
units: "metric",
modules: [
{
module: "calendar",
position: "bottom_bar",
config: {
fade: false,
hideDuplicates: false,
maximumEntries: 100,
urgency: 0,
dateFormat: "Do.MMM, HH:mm",
fullDayEventDateFormat: "Do.MMM",
timeFormat: "absolute",
getRelative: 0,
maximumNumberOfDays: 28,
calendars: [
{
maximumEntries: 100,
url: "http://localhost:8080/tests/mocks/3_move_first_allday_repeating_event.ics"
}
]
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@@ -0,0 +1,33 @@
let config = {
address: "0.0.0.0",
ipWhitelist: [],
timeFormat: 24,
modules: [
{
module: "calendar",
position: "bottom_bar",
config: {
fade: false,
urgency: 0,
dateFormat: "Do.MMM, HH:mm",
fullDayEventDateFormat: "Do.MMM",
timeFormat: "absolute",
getRelative: 0,
maximumNumberOfDays: 28,
showEnd: true,
calendars: [
{
maximumEntries: 100,
url: "http://localhost:8080/tests/mocks/end_of_day_berlin_moved.ics"
}
]
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@@ -0,0 +1,33 @@
let config = {
address: "0.0.0.0",
ipWhitelist: [],
timeFormat: 24,
modules: [
{
module: "calendar",
position: "bottom_bar",
config: {
fade: false,
urgency: 0,
dateFormat: "Do.MMM, HH:mm",
fullDayEventDateFormat: "Do.MMM",
timeFormat: "absolute",
getRelative: 0,
maximumNumberOfDays: 28,
showEnd: true,
calendars: [
{
maximumEntries: 100,
url: "http://localhost:8080/tests/mocks/RepeatingEvent.Oct21.ics"
}
]
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@@ -0,0 +1,33 @@
let config = {
address: "0.0.0.0",
ipWhitelist: [],
timeFormat: 24,
modules: [
{
module: "calendar",
position: "bottom_bar",
config: {
fade: false,
urgency: 0,
dateFormat: "Do.MMM, HH:mm",
fullDayEventDateFormat: "Do.MMM",
timeFormat: "absolute",
getRelative: 0,
maximumNumberOfDays: 28,
showEnd: true,
calendars: [
{
maximumEntries: 100,
url: "http://localhost:8080/tests/mocks/whole_day_moved_over_dst_change_berlin.ics"
}
]
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@@ -0,0 +1,33 @@
let config = {
address: "0.0.0.0",
ipWhitelist: [],
timeFormat: 24,
modules: [
{
module: "calendar",
position: "bottom_bar",
config: {
fade: false,
urgency: 0,
dateFormat: "Do.MMM, HH:mm",
fullDayEventDateFormat: "Do.MMM",
timeFormat: "absolute",
getRelative: 0,
maximumNumberOfDays: 20,
calendars: [
{
maximumEntries: 100,
//url: "http://localhost:8080/tests/mocks/chicago_late_in_timezone.ics"
url: "http://localhost:8080/tests/mocks/chicago_late_in_timezone.ics"
}
]
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@@ -0,0 +1,34 @@
let config = {
address: "0.0.0.0",
ipWhitelist: [],
timeFormat: 24,
modules: [
{
module: "calendar",
position: "bottom_bar",
config: {
fade: false,
urgency: 0,
dateFormat: "Do.MMM, HH:mm",
dateEndFormat: "Do.MMM, HH:mm",
fullDayEventDateFormat: "Do.MMM",
timeFormat: "absolute",
getRelative: 0,
maximumNumberOfDays: 28,
showEnd: true,
calendars: [
{
maximumEntries: 100,
url: "http://localhost:8080/tests/mocks/diff_tz_start_end.ics"
}
]
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@@ -0,0 +1,33 @@
let config = {
address: "0.0.0.0",
ipWhitelist: [],
timeFormat: 24,
modules: [
{
module: "calendar",
position: "bottom_bar",
config: {
fade: false,
urgency: 0,
dateFormat: "Do.MMM, HH:mm",
fullDayEventDateFormat: "Do.MMM",
timeFormat: "absolute",
getRelative: 0,
maximumNumberOfDays: 28,
showEnd: true,
calendars: [
{
maximumEntries: 100,
url: "http://localhost:8080/tests/mocks/end_of_day_berlin_moved.ics"
}
]
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@@ -0,0 +1,33 @@
let config = {
address: "0.0.0.0",
ipWhitelist: [],
timeFormat: 24,
modules: [
{
module: "calendar",
position: "bottom_bar",
config: {
fade: false,
urgency: 0,
dateFormat: "Do.MMM, HH:mm",
dateEndFormat: "Do.MMM, HH:mm",
fullDayEventDateFormat: "Do.MMM",
timeFormat: "absolute",
getRelative: 0,
showEnd: true,
calendars: [
{
maximumEntries: 100,
url: "http://localhost:8080/tests/mocks/event_with_time_over_multiple_days_non_repeating.ics"
}
]
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@@ -0,0 +1,34 @@
let config = {
address: "0.0.0.0",
ipWhitelist: [],
timeFormat: 24,
modules: [
{
module: "calendar",
position: "bottom_bar",
config: {
fade: false,
urgency: 0,
dateFormat: "Do.MMM, HH:mm",
dateEndFormat: "Do.MMM, HH:mm",
fullDayEventDateFormat: "Do.MMM",
timeFormat: "absolute",
getRelative: 0,
showEnd: true,
showEndsOnlyWithDuration: true,
calendars: [
{
maximumEntries: 100,
url: "http://localhost:8080/tests/mocks/event_with_time_over_multiple_days_non_repeating.ics"
}
]
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@@ -0,0 +1,33 @@
let config = {
address: "0.0.0.0",
ipWhitelist: [],
timeFormat: 24,
modules: [
{
module: "calendar",
position: "bottom_bar",
config: {
fade: false,
urgency: 0,
dateFormat: "Do.MMM, HH:mm",
fullDayEventDateFormat: "Do.MMM",
timeFormat: "absolute",
getRelative: 0,
maximumNumberOfDays: 28,
showEnd: true,
calendars: [
{
maximumEntries: 100,
url: "http://localhost:8080/tests/mocks/exdate_and_recurrence_together.ics"
}
]
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@@ -0,0 +1,32 @@
let config = {
address: "0.0.0.0",
ipWhitelist: [],
timeFormat: 24,
modules: [
{
module: "calendar",
position: "bottom_bar",
config: {
fade: false,
urgency: 0,
dateFormat: "Do.MMM, HH:mm",
fullDayEventDateFormat: "Do.MMM",
timeFormat: "absolute",
getRelative: 0,
showEnd: true,
calendars: [
{
maximumEntries: 100,
url: "http://localhost:8080/tests/mocks/fullday_event_over_multiple_days_nonrepeating.ics"
}
]
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@@ -0,0 +1,33 @@
let config = {
address: "0.0.0.0",
ipWhitelist: [],
timeFormat: 12,
modules: [
{
module: "calendar",
position: "bottom_bar",
config: {
hideDuplicates: false,
maximumEntries: 100,
sliceMultiDayEvents: true,
dateFormat: "MMM Do, HH:mm",
timeFormat: "absolute",
getRelative: 0,
urgency: 0,
calendars: [
{
maximumEntries: 100,
url: "http://localhost:8080/tests/mocks/germany_at_end_of_day_repeating.ics"
}
]
}
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}

View File

@@ -89,4 +89,37 @@ describe("Compliments module", () => {
});
});
});
describe("Feature remote compliments file", () => {
describe("get list from remote file", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/modules/compliments/compliments_file.js");
await helpers.getDocument();
});
it("shows 'Remote compliment file works!' as only anytime list set", async () => {
//await helpers.startApplication("tests/configs/modules/compliments/compliments_file.js", "01 Jan 2022 10:00:00 GMT");
await expect(doTest(["Remote compliment file works!"])).resolves.toBe(true);
});
// afterAll(async () =>{
// await helpers.stopApplication()
// });
});
describe("get list from remote file w update", () => {
beforeAll(async () => {
await helpers.startApplication("tests/configs/modules/compliments/compliments_file_change.js");
await helpers.getDocument();
});
it("shows 'test in morning' as test time set to 10am", async () => {
//await helpers.startApplication("tests/configs/modules/compliments/compliments_file_change.js", "01 Jan 2022 10:00:00 GMT");
await expect(doTest(["Remote compliment file works!"])).resolves.toBe(true);
await new Promise((r) => setTimeout(r, 10000));
await expect(doTest(["test in morning"])).resolves.toBe(true);
});
// afterAll(async () =>{
// await helpers.stopApplication()
// });
});
});
});

View File

@@ -22,6 +22,21 @@ describe("Calendar module", () => {
return await loc.count();
};
const first = 0;
const second = 1;
const third = 2;
const last = -1;
// get results of table row and column, can select specific row of results,
// row is 0 based index -1 is last, 0 is first... need 10th(human count), use 9 as row
// uses playwright nth locator syntax
const doTestTableContent = async (table_row, table_column, content, row = first) => {
const elem = await global.page.locator(table_row);
const date = await global.page.locator(table_column).locator(`nth=${row}`);
await expect(date.textContent()).resolves.toContain(content);
return true;
};
afterEach(async () => {
await helpers.stopApplication();
});
@@ -147,4 +162,121 @@ describe("Calendar module", () => {
});
});
describe("sliceMultiDayEvents direct count", () => {
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");
await expect(doTestCount()).resolves.toBe(6);
});
});
describe("germany timezone", () => {
it("Issue #unknown fullday timezone East of UTC edge", async () => {
await helpers.startApplication("tests/configs/modules/calendar/germany_at_end_of_day_repeating.js", "01 Oct 2024 10:38:00 GMT+02:00", ["js/electron.js"], "Europe/Berlin");
await expect(doTestTableContent(".calendar .event", ".time", "Oct 22nd, 23:00", first)).resolves.toBe(true);
});
});
describe("germany all day repeating moved (recurrence and exdate)", () => {
it("Issue #unknown fullday timezone East of UTC event moved", async () => {
await helpers.startApplication("tests/configs/modules/calendar/3_move_first_allday_repeating_event.js", "01 Oct 2024 10:38:00 GMT+02:00", ["js/electron.js"], "Europe/Berlin");
await expect(doTestTableContent(".calendar .event", ".time", "12th.Oct")).resolves.toBe(true);
});
});
describe("chicago late in timezone", () => {
it("Issue #unknown rrule US close to timezone edge", async () => {
await helpers.startApplication("tests/configs/modules/calendar/chicago_late_in_timezone.js", "01 Sept 2024 10:38:00 GMT-5:00", ["js/electron.js"], "America/Chicago");
await expect(doTestTableContent(".calendar .event", ".time", "10th.Sep, 20:15")).resolves.toBe(true);
});
});
describe("berlin late in day event moved, viewed from berlin", () => {
it("Issue #unknown rrule ETC+2 close to timezone edge", async () => {
await helpers.startApplication("tests/configs/modules/calendar/end_of_day_berlin_moved.js", "08 Oct 2024 12:30:00 GMT+02:00", ["js/electron.js"], "Europe/Berlin");
await expect(doTestTableContent(".calendar .event", ".time", "24th.Oct, 23:00-00:00", last)).resolves.toBe(true);
});
});
describe("berlin late in day event moved, viewed from sydney", () => {
it("Issue #unknown rrule ETC+2 close to timezone edge", async () => {
await helpers.startApplication("tests/configs/modules/calendar/end_of_day_berlin_moved.js", "08 Oct 2024 12:30:00 GMT+02:00", ["js/electron.js"], "Australia/Sydney");
await expect(doTestTableContent(".calendar .event", ".time", "25th.Oct, 01:00-02:00", last)).resolves.toBe(true);
});
});
describe("berlin late in day event moved, viewed from chicago", () => {
it("Issue #unknown rrule ETC+2 close to timezone edge", async () => {
await helpers.startApplication("tests/configs/modules/calendar/end_of_day_berlin_moved.js", "08 Oct 2024 12:30:00 GMT+02:00", ["js/electron.js"], "America/Chicago");
await expect(doTestTableContent(".calendar .event", ".time", "24th.Oct, 16:00-17:00", last)).resolves.toBe(true);
});
});
describe("berlin multi-events inside offset", () => {
it("some events before DST. some after midnight", async () => {
await helpers.startApplication("tests/configs/modules/calendar/berlin_multi.js", "08 Oct 2024 12:30:00 GMT+02:00", ["js/electron.js"], "Europe/Berlin");
await expect(doTestTableContent(".calendar .event", ".time", "30th.Oct, 00:00-01:00", last)).resolves.toBe(true);
await expect(doTestTableContent(".calendar .event", ".time", "21st.Oct, 00:00-01:00", first)).resolves.toBe(true);
});
});
describe("berlin whole day repeating, start moved after end", () => {
it("some events before DST. some after", async () => {
await helpers.startApplication("tests/configs/modules/calendar/berlin_whole_day_event_moved_over_dst_change.js", "08 Oct 2024 12:30:00 GMT+02:00", ["js/electron.js"], "Europe/Berlin");
await expect(doTestTableContent(".calendar .event", ".time", "30th.Oct", last)).resolves.toBe(true);
await expect(doTestTableContent(".calendar .event", ".time", "27th.Oct", first)).resolves.toBe(true);
});
});
describe("berlin 11pm-midnight", () => {
it("right inside the offset, before midnight", async () => {
await helpers.startApplication("tests/configs/modules/calendar/berlin_end_of_day_repeating.js", "08 Oct 2024 12:30:00 GMT+02:00", ["js/electron.js"], "Europe/Berlin");
await expect(doTestTableContent(".calendar .event", ".time", "24th.Oct, 23:00-00:00", last)).resolves.toBe(true);
await expect(doTestTableContent(".calendar .event", ".time", "22nd.Oct, 23:00-00:00", first)).resolves.toBe(true);
});
});
describe("both moved and delete events in recurring list", () => {
it("with moved before and after original", async () => {
await helpers.startApplication("tests/configs/modules/calendar/exdate_and_recurrence_together.js", "08 Oct 2024 12:30:00 GMT-07:00", ["js/electron.js"], "America/Los_Angeles");
// moved after end at oct 26
await expect(doTestTableContent(".calendar .event", ".time", "27th.Oct, 14:30-15:30", last)).resolves.toBe(true);
// moved before start at oct 23
await expect(doTestTableContent(".calendar .event", ".time", "22nd.Oct, 14:30-15:30", first)).resolves.toBe(true);
// remaining original 4th, now 3rd
await expect(doTestTableContent(".calendar .event", ".time", "26th.Oct, 14:30-15:30", second)).resolves.toBe(true);
});
});
describe("one event diff tz", () => {
it("start/end in diff timezones", async () => {
await helpers.startApplication("tests/configs/modules/calendar/diff_tz_start_end.js", "08 Oct 2024 12:30:00 GMT-07:00", ["js/electron.js"], "America/Chicago");
// just
await expect(doTestTableContent(".calendar .event", ".time", "29th.Oct, 05:00-30th.Oct, 18:00", first)).resolves.toBe(true);
});
});
describe("one event non repeating", () => {
it("fullday non-repeating", async () => {
await helpers.startApplication("tests/configs/modules/calendar/fullday_event_over_multiple_days_nonrepeating.js", "08 Oct 2024 12:30:00 GMT-07:00", ["js/electron.js"], "America/Chicago");
// just
await expect(doTestTableContent(".calendar .event", ".time", "25th.Oct-30th.Oct", first)).resolves.toBe(true);
});
});
describe("one event no end display", () => {
it("don't display end", async () => {
await helpers.startApplication("tests/configs/modules/calendar/event_with_time_over_multiple_days_non_repeating_no_display_end.js", "08 Oct 2024 12:30:00 GMT-07:00", ["js/electron.js"], "America/Chicago");
// just
await expect(doTestTableContent(".calendar .event", ".time", "25th.Oct, 20:00", first)).resolves.toBe(true);
});
});
describe("display end display end", () => {
it("display end", async () => {
await helpers.startApplication("tests/configs/modules/calendar/event_with_time_over_multiple_days_non_repeating_display_end.js", "08 Oct 2024 12:30:00 GMT-07:00", ["js/electron.js"], "America/Chicago");
// just
await expect(doTestTableContent(".calendar .event", ".time", "25th.Oct, 20:00-26th.Oct, 06:00", first)).resolves.toBe(true);
});
});
});

View File

@@ -88,7 +88,7 @@ describe("Compliments module", () => {
});
});
describe("get updated list from remote file", () => {
it("shows 'test in morning' as test time set to 10am", async () => {
it("shows 'test in morning'", async () => {
await helpers.startApplication("tests/configs/modules/compliments/compliments_file_change.js", "01 Jan 2022 10:00:00 GMT");
await expect(doTest(["Remote compliment file works!"])).resolves.toBe(true);
await new Promise((r) => setTimeout(r, 10000));

View File

@@ -0,0 +1,35 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:TestCal
X-WR-TIMEZONE:Europe/Berlin
X-WR-CALDESC:Calendar for testing purposes
BEGIN:VEVENT
DTSTART;VALUE=DATE:20241011
DTEND;VALUE=DATE:20241012
RRULE:FREQ=WEEKLY;WKST=MO;COUNT=5;BYDAY=FR
DTSTAMP:20241009T153220Z
UID:2m6mt1p89l2anl74915ur3hsgm@google.com
CREATED:20241009T153058Z
LAST-MODIFIED:20241009T153205Z
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:TestCal_AllDayRepeatingEvent
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20241012
DTEND;VALUE=DATE:20241013
DTSTAMP:20241009T153220Z
UID:2m6mt1p89l2anl74915ur3hsgm@google.com
RECURRENCE-ID;VALUE=DATE:20241011
CREATED:20241009T153058Z
LAST-MODIFIED:20241009T153205Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:TestCal_AllDayRepeatingEvent
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR

View File

@@ -0,0 +1,28 @@
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART;TZID=Europe/Berlin:20241028T000000
DTEND;TZID=Europe/Berlin:20241028T010000
RRULE:FREQ=DAILY;COUNT=3
DTSTAMP:20241020T093758Z
UID:053fdshnnibo92lu97rsoeqoti@google.com
CREATED:20241020T093230Z
LAST-MODIFIED:20241020T093230Z
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:RepeatingEventWeekAfterToday
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=Europe/Berlin:20241021T000000
DTEND;TZID=Europe/Berlin:20241021T010000
RRULE:FREQ=DAILY;COUNT=3
DTSTAMP:20241020T093758Z
UID:1a6kk47pp61k4td2h9rlf0lv69@google.com
CREATED:20241020T093255Z
LAST-MODIFIED:20241020T093437Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:RepeatingEventDayAfterToday
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

View File

@@ -0,0 +1,15 @@
BEGIN:VEVENT
CREATED:20240904T053053Z
DTEND;TZID=America/Chicago:20240910T211500
DTSTAMP:20240925T005517Z
DTSTART;TZID=America/Chicago:20240910T201500
LAST-MODIFIED:20240925T005515Z
LOCATION:Dance Class
RELATED-TO;RELTYPE=X-CALENDARSERVER-RECURRENCE-SET:2D48CA37-FCE5-4E16-871
9-1F47160BDBA3
RRULE:FREQ=WEEKLY;UNTIL=20250601T011500Z
SEQUENCE:3
SUMMARY:Wife Barre Class
UID:39669340-7AFD-4685-9BD6-6CE4B715486E
X-APPLE-CREATOR-IDENTITY:com.apple.mobilecal
END:VEVENT

View File

@@ -1,5 +1,3 @@
{
"morning": ["test in morning"],
"afternoon": ["test in afternoon"],
"evening": ["test in evening"]
"anytime": ["test in morning"]
}

View File

@@ -0,0 +1,14 @@
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20241029T100000Z
DTEND:20241030T230000Z
DTSTAMP:20241022T203806Z
UID:04ivnntdi20rqsk0iesabsdhmj@google.com
CREATED:20241022T203738Z
LAST-MODIFIED:20241022T203738Z
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:start/end on diff tz
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

View File

@@ -0,0 +1,54 @@
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:test for mirror
X-WR-TIMEZONE:America/Chicago
X-WR-CALDESC:used to test mirror
BEGIN:VTIMEZONE
TZID:Europe/Berlin
X-LIC-LOCATION:Europe/Berlin
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:GMT+2
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:GMT+1
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=Europe/Berlin:20241021T230000
DTEND;TZID=Europe/Berlin:20241022T000000
RRULE:FREQ=DAILY;WKST=SU;COUNT=3
DTSTAMP:20241019T133432Z
UID:0kj3dtvgskhhpli1392n111145@google.com
CREATED:20241018T213040Z
LAST-MODIFIED:20241018T213126Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:test
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=Europe/Berlin:20241024T230000
DTEND;TZID=Europe/Berlin:20241025T000000
DTSTAMP:20241019T133432Z
UID:0kj3dtvgskhhpli1392n111145@google.com
RECURRENCE-ID;TZID=Europe/Berlin:20241021T230000
CREATED:20241018T213040Z
LAST-MODIFIED:20241018T213126Z
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:test
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

View File

@@ -0,0 +1,14 @@
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20241026T010000Z
DTEND:20241026T110000Z
DTSTAMP:20241024T153358Z
UID:4maud6s79m41a99pj2g7j5km0a@google.com
CREATED:20241024T153313Z
LAST-MODIFIED:20241024T153330Z
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Sleep over at Bobs
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

View File

@@ -0,0 +1,48 @@
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART;TZID=America/Los_Angeles:20241023T143000
DTEND;TZID=America/Los_Angeles:20241023T153000
RRULE:FREQ=DAILY;COUNT=4
EXDATE;TZID=America/Los_Angeles:20241025T143000
DTSTAMP:20241021T193426Z
UID:18rd721lfqpue2o08icsqek198@google.com
CREATED:20241021T192450Z
DESCRIPTION:we will move one entry and delete another  ending w 3 of the 4 
start/end\, middle moved after end and 3rd deleted
LAST-MODIFIED:20241021T193419Z
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:recurrence and exclusion together
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=America/Los_Angeles:20241022T143000
DTEND;TZID=America/Los_Angeles:20241022T153000
DTSTAMP:20241021T193426Z
UID:18rd721lfqpue2o08icsqek198@google.com
RECURRENCE-ID;TZID=America/Los_Angeles:20241023T143000
CREATED:20241021T192450Z
DESCRIPTION:we will move one entry and delete another  ending w 3 of the 4 
start/end\, middle moved after end and 3rd deleted
LAST-MODIFIED:20241021T193419Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:recurrence and exclusion together
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=America/Los_Angeles:20241027T143000
DTEND;TZID=America/Los_Angeles:20241027T153000
DTSTAMP:20241021T193426Z
UID:18rd721lfqpue2o08icsqek198@google.com
RECURRENCE-ID;TZID=America/Los_Angeles:20241024T143000
CREATED:20241021T192450Z
DESCRIPTION:we will move one entry and delete another  ending w 3 of the 4 
start/end\, middle moved after end and 3rd deleted
LAST-MODIFIED:20241021T193419Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:recurrence and exclusion together
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

View File

@@ -0,0 +1,15 @@
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART;VALUE=DATE:20241025
DTEND;VALUE=DATE:20241031
DTSTAMP:20241023T141110Z
UID:60nobfcu0ct96jgsh5nhcia24b@google.com
CREATED:20241023T141019Z
DESCRIPTION:test for all day end viewing
LAST-MODIFIED:20241023T141019Z
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:simple all day event over many days (not repeating)
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR

View File

@@ -0,0 +1,15 @@
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART;TZID=Europe/Berlin:20241022T230000
DTEND;TZID=Europe/Berlin:20241023T000000
RRULE:FREQ=DAILY;WKST=MO;COUNT=4
DTSTAMP:20241009T153220Z
UID:2m6mt1p89l2anl74915ur3hsgm@google.com
CREATED:20241009T153058Z
LAST-MODIFIED:20241009T153205Z
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:TestCal_AllDayRepeatingEvent
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR

View File

@@ -0,0 +1,28 @@
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART;VALUE=DATE:20241027
DTEND;VALUE=DATE:20241028
RRULE:FREQ=DAILY;WKST=SU;COUNT=3
DTSTAMP:20241020T152634Z
UID:14nv8jl8d6dvdbl477lod4fftf@google.com
CREATED:20241020T152434Z
LAST-MODIFIED:20241020T152536Z
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:test whole day moved
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20241030
DTEND;VALUE=DATE:20241031
DTSTAMP:20241020T152634Z
UID:14nv8jl8d6dvdbl477lod4fftf@google.com
RECURRENCE-ID;VALUE=DATE:20241028
CREATED:20241020T152434Z
LAST-MODIFIED:20241020T152536Z
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:test whole day moved
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR