public void FixTimeZoneComponentOrder_EventHasNoTimeZones_DoesntChangeEvent() { string input = @"BEGIN:VCALENDAR PRODID:-//bitfire web engineering//DAVdroid 0.8.4.1 (ical4j 2.0-beta1)//EN VERSION:2.0 BEGIN:VEVENT DTSTAMP:20150925T061111Z UID:566745d3-04ed-497a-9d1b-47db1bb12629 DTSTART;TZID=Europe/Vienna:20151125T133500 DTEND;TZID=Europe/Vienna:20151125T151500 SUMMARY:EZG-ILV EDV_F1.03 - MGS-1 LOCATION:EDV_F1.03 DESCRIPTION:EZG-ILV\nHesinaGe\nMGS-1 \nEDV_F1.03 CLASS:PUBLIC LAST-MODIFIED:20150927T175324Z TRANSP:OPAQUE SEQUENCE:2 END:VEVENT END:VCALENDAR "; var processed = CalendarDataPreprocessor.FixTimeZoneComponentOrderNoThrow(input); Assert.That(processed, Is.EqualTo(input)); AssertCanDeserialize(processed); }
public void FixTimeZoneComponentOrder_CalenderDataIsNull_ReturnsNull() { Assert.That(CalendarDataPreprocessor.FixTimeZoneComponentOrderNoThrow(null), Is.Null); }
public void FixTimeZoneComponentOrder_EventHasMultipleTimeZomes() { string input = @"BEGIN:VCALENDAR BEGIN:VTIMEZONE TZID:Europe/Vienna X-LIC-LOCATION:Europe/Vienna BEGIN:STANDARD TZNAME:CET DTSTART:19901027T030000 END:STANDARD BEGIN:DAYLIGHT TZNAME:CEST DTSTART:19800329T020000 END:DAYLIGHT END:VTIMEZONE BEGIN:VTIMEZONE TZID:Blablubb X-LIC-LOCATION:SomewhereElse BEGIN:STANDARD TZNAME:CET DTSTART:19601027T030000 END:STANDARD BEGIN:DAYLIGHT TZNAME:CEST DTSTART:19500329T020000 END:DAYLIGHT END:VTIMEZONE BEGIN:VEVENT SUMMARY:Termin END:VEVENT END:VCALENDAR "; string expected = @"BEGIN:VCALENDAR BEGIN:VTIMEZONE TZID:Europe/Vienna X-LIC-LOCATION:Europe/Vienna BEGIN:DAYLIGHT TZNAME:CEST DTSTART:19800329T020000 END:DAYLIGHT BEGIN:STANDARD TZNAME:CET DTSTART:19901027T030000 END:STANDARD END:VTIMEZONE BEGIN:VTIMEZONE TZID:Blablubb X-LIC-LOCATION:SomewhereElse BEGIN:DAYLIGHT TZNAME:CEST DTSTART:19500329T020000 END:DAYLIGHT BEGIN:STANDARD TZNAME:CET DTSTART:19601027T030000 END:STANDARD END:VTIMEZONE BEGIN:VEVENT SUMMARY:Termin END:VEVENT END:VCALENDAR "; var processed = CalendarDataPreprocessor.FixTimeZoneComponentOrderNoThrow(input); Assert.That(processed, Is.EqualTo(expected)); }
public void FixTimeZoneComponentOrder_TestRealEvent() { string input = @"BEGIN:VCALENDAR PRODID:-//bitfire web engineering//DAVdroid 0.8.4.1 (ical4j 2.0-beta1)//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Vienna TZURL:http://tzurl.org/zoneinfo/Europe/Vienna X-LIC-LOCATION:Europe/Vienna BEGIN:DAYLIGHT TZOFFSETFROM:+0100 TZOFFSETTO:+0200 TZNAME:CEST DTSTART:19810329T020000 RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+0200 TZOFFSETTO:+0100 TZNAME:CET DTSTART:19961027T030000 RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU END:STANDARD BEGIN:STANDARD TZOFFSETFROM:+010521 TZOFFSETTO:+0100 TZNAME:CET DTSTART:18930401T000000 RDATE:18930401T000000 END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:+0100 TZOFFSETTO:+0200 TZNAME:CEST DTSTART:19160501T000000 RDATE:19160501T000000 RDATE:19170416T030000 RDATE:19180415T030000 RDATE:19200405T030000 RDATE:19400401T030000 RDATE:19430329T030000 RDATE:19440403T030000 RDATE:19450402T030000 RDATE:19460414T030000 RDATE:19470406T030000 RDATE:19480418T030000 RDATE:19800406T000000 END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+0200 TZOFFSETTO:+0100 TZNAME:CET DTSTART:19161001T010000 RDATE:19161001T010000 RDATE:19170917T030000 RDATE:19180916T030000 RDATE:19200913T030000 RDATE:19421102T030000 RDATE:19431004T030000 RDATE:19441002T030000 RDATE:19450412T030000 RDATE:19461006T030000 RDATE:19471005T030000 RDATE:19481003T030000 RDATE:19800928T000000 RDATE:19810927T030000 RDATE:19820926T030000 RDATE:19830925T030000 RDATE:19840930T030000 RDATE:19850929T030000 RDATE:19860928T030000 RDATE:19870927T030000 RDATE:19880925T030000 RDATE:19890924T030000 RDATE:19900930T030000 RDATE:19910929T030000 RDATE:19920927T030000 RDATE:19930926T030000 RDATE:19940925T030000 RDATE:19950924T030000 END:STANDARD BEGIN:STANDARD TZOFFSETFROM:+0100 TZOFFSETTO:+0100 TZNAME:CET DTSTART:19200101T000000 RDATE:19200101T000000 RDATE:19460101T000000 RDATE:19810101T000000 END:STANDARD END:VTIMEZONE BEGIN:VEVENT DTSTAMP:20150925T061111Z UID:566745d3-04ed-497a-9d1b-47db1bb12629 DTSTART;TZID=Europe/Vienna:20151125T133500 DTEND;TZID=Europe/Vienna:20151125T151500 SUMMARY:EZG-ILV EDV_F1.03 - MGS-1 LOCATION:EDV_F1.03 DESCRIPTION:EZG-ILV\nHesinaGe\nMGS-1 \nEDV_F1.03 CLASS:PUBLIC LAST-MODIFIED:20150927T175324Z TRANSP:OPAQUE SEQUENCE:2 END:VEVENT END:VCALENDAR "; string expected = @"BEGIN:VCALENDAR PRODID:-//bitfire web engineering//DAVdroid 0.8.4.1 (ical4j 2.0-beta1)//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Europe/Vienna TZURL:http://tzurl.org/zoneinfo/Europe/Vienna X-LIC-LOCATION:Europe/Vienna BEGIN:STANDARD TZOFFSETFROM:+010521 TZOFFSETTO:+0100 TZNAME:CET DTSTART:18930401T000000 RDATE:18930401T000000 END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:+0100 TZOFFSETTO:+0200 TZNAME:CEST DTSTART:19160501T000000 RDATE:19160501T000000 RDATE:19170416T030000 RDATE:19180415T030000 RDATE:19200405T030000 RDATE:19400401T030000 RDATE:19430329T030000 RDATE:19440403T030000 RDATE:19450402T030000 RDATE:19460414T030000 RDATE:19470406T030000 RDATE:19480418T030000 RDATE:19800406T000000 END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+0200 TZOFFSETTO:+0100 TZNAME:CET DTSTART:19161001T010000 RDATE:19161001T010000 RDATE:19170917T030000 RDATE:19180916T030000 RDATE:19200913T030000 RDATE:19421102T030000 RDATE:19431004T030000 RDATE:19441002T030000 RDATE:19450412T030000 RDATE:19461006T030000 RDATE:19471005T030000 RDATE:19481003T030000 RDATE:19800928T000000 RDATE:19810927T030000 RDATE:19820926T030000 RDATE:19830925T030000 RDATE:19840930T030000 RDATE:19850929T030000 RDATE:19860928T030000 RDATE:19870927T030000 RDATE:19880925T030000 RDATE:19890924T030000 RDATE:19900930T030000 RDATE:19910929T030000 RDATE:19920927T030000 RDATE:19930926T030000 RDATE:19940925T030000 RDATE:19950924T030000 END:STANDARD BEGIN:STANDARD TZOFFSETFROM:+0100 TZOFFSETTO:+0100 TZNAME:CET DTSTART:19200101T000000 RDATE:19200101T000000 RDATE:19460101T000000 RDATE:19810101T000000 END:STANDARD BEGIN:DAYLIGHT TZOFFSETFROM:+0100 TZOFFSETTO:+0200 TZNAME:CEST DTSTART:19810329T020000 RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+0200 TZOFFSETTO:+0100 TZNAME:CET DTSTART:19961027T030000 RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU END:STANDARD END:VTIMEZONE BEGIN:VEVENT DTSTAMP:20150925T061111Z UID:566745d3-04ed-497a-9d1b-47db1bb12629 DTSTART;TZID=Europe/Vienna:20151125T133500 DTEND;TZID=Europe/Vienna:20151125T151500 SUMMARY:EZG-ILV EDV_F1.03 - MGS-1 LOCATION:EDV_F1.03 DESCRIPTION:EZG-ILV\nHesinaGe\nMGS-1 \nEDV_F1.03 CLASS:PUBLIC LAST-MODIFIED:20150927T175324Z TRANSP:OPAQUE SEQUENCE:2 END:VEVENT END:VCALENDAR "; var processed = CalendarDataPreprocessor.FixTimeZoneComponentOrderNoThrow(input); Assert.That(processed, Is.EqualTo(expected)); AssertCanDeserialize(processed); }
public void FixTimeZoneComponentOrder_StartTimeOfOneComponentIsNotParseable_IgnoresComnponentAndAddsItAfterSortedConmponents() { string input = @"BEGIN:VCALENDAR BEGIN:VTIMEZONE TZID:Europe/Vienna X-LIC-LOCATION:Europe/Vienna BEGIN:STANDARD TZNAME:CET DTSTART:19961027T030000 END:STANDARD BEGIN:DAYLIGHT TZNAME:CEST DTSTART:19810329T020000 END:DAYLIGHT BEGIN:STANDARD TZNAME:CET DTSTART:19200101T000000 END:STANDARD BEGIN:DAYLIGHT TZNAME:CEST DTSTART:xxxxxxxxxxxxxxxxxxxxxxx END:DAYLIGHT BEGIN:STANDARD TZNAME:CET DTSTART:19161001T010000 END:STANDARD BEGIN:STANDARD TZNAME:CET DTSTART:18930401T000000 END:STANDARD END:VTIMEZONE BEGIN:VEVENT SUMMARY:Termin END:VEVENT END:VCALENDAR "; string expected = @"BEGIN:VCALENDAR BEGIN:VTIMEZONE TZID:Europe/Vienna X-LIC-LOCATION:Europe/Vienna BEGIN:STANDARD TZNAME:CET DTSTART:18930401T000000 END:STANDARD BEGIN:STANDARD TZNAME:CET DTSTART:19161001T010000 END:STANDARD BEGIN:STANDARD TZNAME:CET DTSTART:19200101T000000 END:STANDARD BEGIN:DAYLIGHT TZNAME:CEST DTSTART:19810329T020000 END:DAYLIGHT BEGIN:STANDARD TZNAME:CET DTSTART:19961027T030000 END:STANDARD BEGIN:DAYLIGHT TZNAME:CEST DTSTART:xxxxxxxxxxxxxxxxxxxxxxx END:DAYLIGHT END:VTIMEZONE BEGIN:VEVENT SUMMARY:Termin END:VEVENT END:VCALENDAR "; var processed = CalendarDataPreprocessor.FixTimeZoneComponentOrderNoThrow(input); Assert.That(processed, Is.EqualTo(expected)); }
private Task <IReadOnlyList <EntityWithId <WebResourceName, IICalendar> > > ParallelDeserialize(IReadOnlyList <EntityWithId <WebResourceName, string> > serializedEntities, ILoadEntityLogger logger) { return(Task.Factory.StartNew(() => { var result = new List <EntityWithId <WebResourceName, IICalendar> >(); Parallel.ForEach( serializedEntities, () => Tuple.Create(new iCalendarSerializer(), new List <Tuple <WebResourceName, IICalendar> >()), (serialized, loopState, threadLocal) => { IICalendar calendar; string normalizedICalData, fixedICalData; // fix some linebreak issues with Open-Xchange if (serialized.Entity.Contains("\r\r\n")) { normalizedICalData = CalendarDataPreprocessor.NormalizeLineBreaks(serialized.Entity); } else { normalizedICalData = serialized.Entity; } // emClient sets DTSTART in VTIMEZONE to year 0001, which causes a 90 sec delay in DDay.iCal to evaluate the recurrence rule. // If we find such a DTSTART we replace it 0001 with 1970 since the historic data is not valid anyway and avoid the performance issue. if (normalizedICalData.Contains("DTSTART:00010101")) { fixedICalData = CalendarDataPreprocessor.FixInvalidDTSTARTInTimeZoneNoThrow(normalizedICalData); s_logger.InfoFormat("Changed DTSTART from year 0001 to 1970 in VTIMEZONE of ICalData '{0}'.", serialized.Id); } else { fixedICalData = normalizedICalData; } if (TryDeserializeCalendar(fixedICalData, out calendar, serialized.Id, threadLocal.Item1, NullLoadEntityLogger.Instance)) { threadLocal.Item2.Add(Tuple.Create(serialized.Id, calendar)); } else { // maybe deserialization failed because of the iCal-TimeZone-Bug => try to fix it var fixedICalData2 = CalendarDataPreprocessor.FixTimeZoneComponentOrderNoThrow(fixedICalData); if (TryDeserializeCalendar(fixedICalData2, out calendar, serialized.Id, threadLocal.Item1, logger)) { threadLocal.Item2.Add(Tuple.Create(serialized.Id, calendar)); s_logger.Info(string.Format("Deserialized ICalData with reordering of TimeZone data '{0}'.", serialized.Id)); } } return threadLocal; }, threadLocal => { lock (result) { foreach (var calendar in threadLocal.Item2) { result.Add(EntityWithId.Create(calendar.Item1, calendar.Item2)); } } }); IReadOnlyList <EntityWithId <WebResourceName, IICalendar> > readOnlyResult = result; return readOnlyResult; })); }