From e3c64211e0e593bd906fb0a8c2eeb0c3d59c621d Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 2 Apr 2018 11:24:11 +0200 Subject: [PATCH] Added tests for ICal parser --- src/calanonsync/caldav_test.go | 334 +++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 src/calanonsync/caldav_test.go diff --git a/src/calanonsync/caldav_test.go b/src/calanonsync/caldav_test.go new file mode 100644 index 0000000..4c81197 --- /dev/null +++ b/src/calanonsync/caldav_test.go @@ -0,0 +1,334 @@ +package main + +import ( + "strings" + "testing" + "time" +) + +func TestParseICal(t *testing.T) { + t.Run("Complex", func(t *testing.T) { + i, err := ParseICal(strings.NewReader(icsWithTZ)) + if err != nil { + t.Fatalf("Parse failed: %s", err) + } + + if i.Summary() != "WithTZ" { + t.Error("Summary is wrong.") + } + if i.UID() != "e726899a5ca4c9e478842669bac9688144bb95d9" { + t.Error("UID is wrong") + } + if i.Start().Format(ICAL_TIME) != "20180411T170000" { + t.Error("Start time wrong") + } + if i.End().Format(ICAL_TIME) != "20180411T210000" { + t.Error("End time wrong") + } + // No "Z" at the end --> local time zone. + if i.Start().Location() != time.Local { + t.Error("Timezone is wrong") + } + }) + t.Run("Simple", func(t *testing.T) { + i, err := ParseICal(strings.NewReader(icsSimple)) + if err != nil { + t.Fatalf("Parse failed: %s", err) + } + + if i.Summary() != "Anon" { + t.Error("Summary is wrong.") + } + if i.Start().Format(ICAL_TIME) != "20180308T113000" { + t.Error("Start time wrong") + } + if i.End().Format(ICAL_TIME) != "20180308T130000" { + t.Error("End time wrong") + } + // "Z" at the end --> UTC. + if i.Start().Location() != time.UTC { + t.Error("Start time should be UTC") + } + }) + t.Run("First event only", func(t *testing.T) { + i, err := ParseICal(strings.NewReader(icsMultiEvents)) + if err != nil { + t.Fatalf("Parse failed: %s", err) + } + + if i.Summary() != "First" { + t.Error("Summary is wrong.") + } + if i.UID() != "123" { + t.Error("UID is wrong.") + } + + // Check that our sub slice is correct: + if i.eventData[0] != "UID:123" { + t.Error("First line is wrong") + } + if i.eventData[len(i.eventData)-1] != "LAST-MODIFIED:20180401T182238Z" { + t.Error("Last line is wrong") + } + }) +} + +const icsWithTZ = `BEGIN:VCALENDAR +PRODID:-//Ximian//NONSGML Evolution Calendar//EN +VERSION:2.0 +CALSCALE:GREGORIAN +BEGIN:VTIMEZONE +TZID:/freeassociation.sourceforge.net/Europe/Berlin +X-LIC-LOCATION:Europe/Berlin +BEGIN:DAYLIGHT +TZNAME:CEST +DTSTART:19160429T230000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;UNTIL=19160430T220000Z;BYMONTH=4;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +DTSTART:19161007T010000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;UNTIL=19160930T230000Z;BYMONTH=10;BYDAY=1SU +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +DTSTART:19170416T020000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;UNTIL=19180415T010000Z;BYMONTH=4;BYDAY=3MO +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +DTSTART:19170917T030000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;UNTIL=19180916T010000Z;BYMONTH=9;BYDAY=3MO +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +DTSTART:19400402T020000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;UNTIL=19400401T010000Z;BYMONTH=4;BYDAY=1MO +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +DTSTART:19421105T030000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;UNTIL=19421102T010000Z;BYMONTH=11;BYDAY=1MO +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +DTSTART:19430326T020000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;UNTIL=19430329T010000Z;BYMONTH=3;BYDAY=-1MO +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +DTSTART:19431001T030000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;UNTIL=19441002T010000Z;BYMONTH=10;BYDAY=1MO +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +DTSTART:19440402T020000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;UNTIL=19450402T000000Z;BYMONTH=4;BYDAY=1MO +END:DAYLIGHT +BEGIN:DAYLIGHT +TZNAME:CEMT +DTSTART:19450524T020000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0300 +RRULE:FREQ=YEARLY;UNTIL=19450523T230000Z;BYMONTH=5;BYDAY=-2TH +END:DAYLIGHT +BEGIN:DAYLIGHT +TZNAME:CEST +DTSTART:19450924T030000 +TZOFFSETFROM:+0300 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;UNTIL=19450924T020000Z;BYMONTH=9;BYDAY=-1MO +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +DTSTART:19451118T030000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;UNTIL=19451118T020000Z;BYMONTH=11;BYDAY=3SU +END:STANDARD +BEGIN:STANDARD +TZNAME:CET +DTSTART:19460102T000000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;UNTIL=19451231T220000Z;BYMONTH=1;BYDAY=1TU +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +DTSTART:19460408T020000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;UNTIL=19460414T010000Z;BYMONTH=4;BYDAY=2SU +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +DTSTART:19461001T030000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;UNTIL=19461007T010000Z;BYMONTH=10;BYDAY=1MO +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +DTSTART:19470401T030000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;UNTIL=19470406T010000Z;BYMONTH=4;BYDAY=1SU +END:DAYLIGHT +BEGIN:DAYLIGHT +TZNAME:CEMT +DTSTART:19470513T030000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0300 +RRULE:FREQ=YEARLY;UNTIL=19470511T000000Z;BYMONTH=5;BYDAY=2SU +END:DAYLIGHT +BEGIN:DAYLIGHT +TZNAME:CEST +DTSTART:19470624T030000 +TZOFFSETFROM:+0300 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;UNTIL=19470629T020000Z;BYMONTH=6;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +DTSTART:19471007T030000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;UNTIL=19491002T020000Z;BYMONTH=10;BYDAY=1SU +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +DTSTART:19480415T020000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;UNTIL=19480418T010000Z;BYMONTH=4;BYDAY=3SU +END:DAYLIGHT +BEGIN:DAYLIGHT +TZNAME:CEST +DTSTART:19490408T020000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;UNTIL=19490410T010000Z;BYMONTH=4;BYDAY=2SU +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +DTSTART:19800102T000000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;UNTIL=19791231T220000Z;BYMONTH=1;BYDAY=1TU +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +DTSTART:19800401T020000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;UNTIL=19800406T010000Z;BYMONTH=4;BYDAY=1SU +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +DTSTART:19800930T030000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;UNTIL=19950924T010000Z;BYMONTH=9;BYDAY=-1SU +END:STANDARD +BEGIN:DAYLIGHT +TZNAME:CEST +DTSTART:19810325T020000 +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +END:DAYLIGHT +BEGIN:STANDARD +TZNAME:CET +DTSTART:19961028T030000 +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +UID:e726899a5ca4c9e478842669bac9688144bb95d9 +DTSTAMP:20180312T092638Z +DTSTART;TZID=/freeassociation.sourceforge.net/Europe/Berlin:20180411T170000 + +DTEND;TZID=/freeassociation.sourceforge.net/Europe/Berlin:20180411T210000 +SEQUENCE:2 +SUMMARY:WithTZ +TRANSP:OPAQUE +CLASS:PUBLIC +CREATED:20180313T074119Z +LAST-MODIFIED:20180313T074119Z +END:VEVENT +END:VCALENDAR` + +const icsWithDateOnly = `BEGIN:VCALENDAR +PRODID:+//IDN bitfire.at//DAVdroid/1.10.1.1-gplay ical4j/2.x +VERSION:2.0 +BEGIN:VEVENT +DTSTAMP:20180308T192428Z +UID:b3cf0d84-b746-420c-8642-3b107ddfd834 +SUMMARY:WholeDay +DTSTART;VALUE=DATE:20180407 +DTEND;VALUE=DATE:20180409 +STATUS:CONFIRMED +TRANSP:TRANSPARENT +CLASS:PUBLIC +END:VEVENT +END:VCALENDAR` + +const icsSimple = `BEGIN:VCALENDAR +PRODID:-//aksdb//calanonsync//EN +VERSION:2.0 +BEGIN:VEVENT +UID:0A6768CB8B086C58F2942757C6E515DF +SUMMARY:Anon +CLASS:PUBLIC +DTSTART:20180308T113000Z +DTEND:20180308T130000Z +CREATED:20180401T182238Z +DTSTAMP:20180401T182238Z +LAST-MODIFIED:20180401T182238Z +END:VEVENT +END:VCALENDAR` + +const icsMultiEvents = `BEGIN:VCALENDAR +PRODID:-//some//thing//EN +VERSION:2.0 +BEGIN:VEVENT +UID:123 +SUMMARY:First +CLASS:PUBLIC +DTSTART:20180308T113000Z +DTEND:20180308T130000Z +CREATED:20180401T182238Z +DTSTAMP:20180401T182238Z +LAST-MODIFIED:20180401T182238Z +END:VEVENT +BEGIN:VEVENT +UID:456 +SUMMARY:Second +CLASS:PUBLIC +DTSTART:20180309T113000Z +DTEND:20180309T130000Z +CREATED:20180401T182238Z +DTSTAMP:20180401T182238Z +LAST-MODIFIED:20180401T182239Z +END:VEVENT +END:VCALENDAR`