diff options
author | Ricki Hirner <hirner@bitfire.at> | 2022-08-28 21:44:50 +0300 |
---|---|---|
committer | Ricki Hirner <hirner@bitfire.at> | 2022-08-28 22:14:29 +0300 |
commit | 5a889101b1c88d359e4817f1b3dcfad7d7824fd5 (patch) | |
tree | 1ed3e039b45ab815fdc21b1b7dffe54aa97d594f | |
parent | ce6d454862a69c7078d2d4c419bf68da63f5ad25 (diff) |
Fix Time API methods not existing on Android (closes bitfireAT/davx5#125)
- move all tests that use Time API or other desugared APIs to Android unit tests
- move resources for tests
- don't use LocalTime.ofInstant() because it requires API level 31 and is not desugared
- fix Locale test
- added warning to src/test/README.txt
- update Kotlin and slf4j dependency
-rw-r--r-- | build.gradle | 4 | ||||
-rw-r--r-- | src/androidTest/java/at/bitfire/ical4android/AndroidTimeUtilsTest.kt (renamed from src/test/java/at/bitfire/ical4android/AndroidTimeUtilsTest.kt) | 4 | ||||
-rw-r--r-- | src/androidTest/java/at/bitfire/ical4android/BatchOperationTest.kt | 4 | ||||
-rw-r--r-- | src/androidTest/java/at/bitfire/ical4android/DateUtilsTest.kt (renamed from src/test/java/at/bitfire/ical4android/DateUtilsTest.kt) | 0 | ||||
-rw-r--r-- | src/androidTest/java/at/bitfire/ical4android/EventTest.kt (renamed from src/test/java/at/bitfire/ical4android/EventTest.kt) | 7 | ||||
-rw-r--r-- | src/androidTest/java/at/bitfire/ical4android/ICalPreprocessorTest.kt (renamed from src/test/java/at/bitfire/ical4android/ICalPreprocessorTest.kt) | 0 | ||||
-rw-r--r-- | src/androidTest/java/at/bitfire/ical4android/ICalendarTest.kt (renamed from src/test/java/at/bitfire/ical4android/ICalendarTest.kt) | 98 | ||||
-rw-r--r-- | src/androidTest/java/at/bitfire/ical4android/Ical4jTest.kt (renamed from src/test/java/at/bitfire/ical4android/Ical4jTest.kt) | 20 | ||||
-rw-r--r-- | src/androidTest/java/at/bitfire/ical4android/LocaleNonWesternDigitsTest.kt | 24 | ||||
-rw-r--r-- | src/androidTest/java/at/bitfire/ical4android/TaskTest.kt (renamed from src/test/java/at/bitfire/ical4android/TaskTest.kt) | 0 | ||||
-rw-r--r-- | src/androidTest/java/at/bitfire/ical4android/TimeApiExtensionsTest.kt (renamed from src/test/java/at/bitfire/ical4android/TimeApiExtensionsTest.kt) | 0 | ||||
-rw-r--r-- | src/androidTest/java/at/bitfire/ical4android/impl/TestEvent.kt | 1 | ||||
-rw-r--r-- | src/androidTest/java/at/bitfire/ical4android/impl/TestJtxIcalObject.kt | 4 | ||||
-rw-r--r-- | src/androidTest/java/at/bitfire/ical4android/validation/EventValidatorTest.kt (renamed from src/test/java/at/bitfire/ical4android/validation/EventValidatorTest.kt) | 38 | ||||
-rw-r--r-- | src/androidTest/resources/events/all-day-0sec.ics (renamed from src/test/resources/events/all-day-0sec.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/all-day-10days.ics (renamed from src/test/resources/events/all-day-10days.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/all-day-1day.ics (renamed from src/test/resources/events/all-day-1day.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/dst-only-vtimezone.ics (renamed from src/test/resources/events/dst-only-vtimezone.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/event-on-that-day.ics (renamed from src/test/resources/events/event-on-that-day.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/latin1.ics (renamed from src/test/resources/events/latin1.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/multiple.ics (renamed from src/test/resources/events/multiple.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/one-event-with-exception-one-without.ics (renamed from src/test/resources/events/one-event-with-exception-one-without.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/one-event-with-multiple-exceptions-one-without.ics (renamed from src/test/resources/events/one-event-with-multiple-exceptions-one-without.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/outlook1.ics (renamed from src/test/resources/events/outlook1.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/recurring-only-exception.ics (renamed from src/test/resources/events/recurring-only-exception.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/recurring-with-exception1.ics (renamed from src/test/resources/events/recurring-with-exception1.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/two-events-without-exceptions.ics (renamed from src/test/resources/events/two-events-without-exceptions.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/two-line-description-without-crlf.ics (renamed from src/test/resources/events/two-line-description-without-crlf.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/utf8.ics (renamed from src/test/resources/events/utf8.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/events/vienna-evolution.ics (renamed from src/test/resources/events/vienna-evolution.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/tasks/empty-priority.ics (renamed from src/test/resources/tasks/empty-priority.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/tasks/latin1.ics (renamed from src/test/resources/tasks/latin1.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/tasks/most-fields1.ics (renamed from src/test/resources/tasks/most-fields1.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/tasks/most-fields2.ics (renamed from src/test/resources/tasks/most-fields2.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/tasks/rfc5545-sample1.ics (renamed from src/test/resources/tasks/rfc5545-sample1.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/tasks/utf8.ics (renamed from src/test/resources/tasks/utf8.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/tz/Karachi.ics (renamed from src/test/resources/tz/Karachi.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/tz/Mogadishu.ics (renamed from src/test/resources/tz/Mogadishu.ics) | 0 | ||||
-rw-r--r-- | src/androidTest/resources/tz/Vienna.ics (renamed from src/test/resources/tz/Vienna.ics) | 0 | ||||
-rw-r--r-- | src/main/java/at/bitfire/ical4android/validation/EventValidator.kt | 30 | ||||
-rw-r--r-- | src/test/README.txt | 6 |
41 files changed, 141 insertions, 99 deletions
diff --git a/build.gradle b/build.gradle index 169b324..866151f 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { ext.versions = [ - kotlin: '1.7.0', + kotlin: '1.7.10', dokka: '1.5.0', ical4j: '3.2.5', // latest Apache Commons versions that don't require Java 8 (Android 7) @@ -99,7 +99,7 @@ dependencies { // noinspection GradleDependency implementation "commons-io:commons-io:${versions.commonsIO}" - implementation 'org.slf4j:slf4j-jdk14:1.7.32' + implementation 'org.slf4j:slf4j-jdk14:1.7.36' implementation 'androidx.core:core-ktx:1.8.0' androidTestImplementation 'androidx.test:core:1.4.0' diff --git a/src/test/java/at/bitfire/ical4android/AndroidTimeUtilsTest.kt b/src/androidTest/java/at/bitfire/ical4android/AndroidTimeUtilsTest.kt index 2c68b95..9cb7653 100644 --- a/src/test/java/at/bitfire/ical4android/AndroidTimeUtilsTest.kt +++ b/src/androidTest/java/at/bitfire/ical4android/AndroidTimeUtilsTest.kt @@ -7,8 +7,6 @@ package at.bitfire.ical4android import at.bitfire.ical4android.util.AndroidTimeUtils import net.fortuna.ical4j.data.CalendarBuilder import net.fortuna.ical4j.model.* -import net.fortuna.ical4j.model.Date -import net.fortuna.ical4j.model.TimeZone import net.fortuna.ical4j.model.component.VTimeZone import net.fortuna.ical4j.model.parameter.TzId import net.fortuna.ical4j.model.parameter.Value @@ -19,11 +17,9 @@ import net.fortuna.ical4j.model.property.RDate import net.fortuna.ical4j.util.TimeZones import org.junit.Assert.* import org.junit.Test -import java.io.InputStreamReader import java.io.StringReader import java.time.Duration import java.time.Period -import java.util.* class AndroidTimeUtilsTest { diff --git a/src/androidTest/java/at/bitfire/ical4android/BatchOperationTest.kt b/src/androidTest/java/at/bitfire/ical4android/BatchOperationTest.kt index 27debf5..66310df 100644 --- a/src/androidTest/java/at/bitfire/ical4android/BatchOperationTest.kt +++ b/src/androidTest/java/at/bitfire/ical4android/BatchOperationTest.kt @@ -20,8 +20,8 @@ import net.fortuna.ical4j.model.property.Attendee import net.fortuna.ical4j.model.property.DtEnd import net.fortuna.ical4j.model.property.DtStart import org.junit.* -import org.junit.Assert.* - +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull import java.net.URI import java.util.* diff --git a/src/test/java/at/bitfire/ical4android/DateUtilsTest.kt b/src/androidTest/java/at/bitfire/ical4android/DateUtilsTest.kt index 395b8da..395b8da 100644 --- a/src/test/java/at/bitfire/ical4android/DateUtilsTest.kt +++ b/src/androidTest/java/at/bitfire/ical4android/DateUtilsTest.kt diff --git a/src/test/java/at/bitfire/ical4android/EventTest.kt b/src/androidTest/java/at/bitfire/ical4android/EventTest.kt index 6842974..f114bf3 100644 --- a/src/test/java/at/bitfire/ical4android/EventTest.kt +++ b/src/androidTest/java/at/bitfire/ical4android/EventTest.kt @@ -1,6 +1,7 @@ /*************************************************************************************************** * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details. **************************************************************************************************/ + package at.bitfire.ical4android import net.fortuna.ical4j.model.Date @@ -325,8 +326,8 @@ class EventTest { } private fun parseCalendar(fname: String, charset: Charset = Charsets.UTF_8): List<Event> = - javaClass.classLoader!!.getResourceAsStream("events/$fname").use { stream -> - return Event.eventsFromReader(InputStreamReader(stream, charset)) - } + javaClass.classLoader!!.getResourceAsStream("events/$fname").use { stream -> + return Event.eventsFromReader(InputStreamReader(stream, charset)) + } } diff --git a/src/test/java/at/bitfire/ical4android/ICalPreprocessorTest.kt b/src/androidTest/java/at/bitfire/ical4android/ICalPreprocessorTest.kt index e1d614b..e1d614b 100644 --- a/src/test/java/at/bitfire/ical4android/ICalPreprocessorTest.kt +++ b/src/androidTest/java/at/bitfire/ical4android/ICalPreprocessorTest.kt diff --git a/src/test/java/at/bitfire/ical4android/ICalendarTest.kt b/src/androidTest/java/at/bitfire/ical4android/ICalendarTest.kt index f2693be..ee0b944 100644 --- a/src/test/java/at/bitfire/ical4android/ICalendarTest.kt +++ b/src/androidTest/java/at/bitfire/ical4android/ICalendarTest.kt @@ -53,15 +53,17 @@ class ICalendarTest { @Test fun testFromReader_calendarProperties() { val calendar = ICalendar.fromReader( - StringReader("BEGIN:VCALENDAR\n" + - "VERSION:2.0\n" + - "METHOD:PUBLISH\n" + - "PRODID:something\n" + - "X-WR-CALNAME:Some Calendar\n" + - "COLOR:darkred\n" + - "X-APPLE-CALENDAR-COLOR:#123456\n" + - "END:VCALENDAR" - )) + StringReader( + "BEGIN:VCALENDAR\n" + + "VERSION:2.0\n" + + "METHOD:PUBLISH\n" + + "PRODID:something\n" + + "X-WR-CALNAME:Some Calendar\n" + + "COLOR:darkred\n" + + "X-APPLE-CALENDAR-COLOR:#123456\n" + + "END:VCALENDAR" + ) + ) assertEquals("Some Calendar", calendar.getProperty<Property>(ICalendar.CALENDAR_NAME).value) assertEquals("darkred", calendar.getProperty<Property>(Color.PROPERTY_NAME).value) assertEquals("#123456", calendar.getProperty<Property>(ICalendar.CALENDAR_COLOR).value) @@ -141,28 +143,31 @@ class ICalendarTest { @Test fun testTimezoneDefToTzId_Valid() { - assertEquals("US-Eastern", ICalendar.timezoneDefToTzId("BEGIN:VCALENDAR\n" + - "PRODID:-//Example Corp.//CalDAV Client//EN\n" + - "VERSION:2.0\n" + - "BEGIN:VTIMEZONE\n" + - "TZID:US-Eastern\n" + - "LAST-MODIFIED:19870101T000000Z\n" + - "BEGIN:STANDARD\n" + - "DTSTART:19671029T020000\n" + - "RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10\n" + - "TZOFFSETFROM:-0400\n" + - "TZOFFSETTO:-0500\n" + - "TZNAME:Eastern Standard Time (US & Canada)\n" + - "END:STANDARD\n" + - "BEGIN:DAYLIGHT\n" + - "DTSTART:19870405T020000\n" + - "RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4\n" + - "TZOFFSETFROM:-0500\n" + - "TZOFFSETTO:-0400\n" + - "TZNAME:Eastern Daylight Time (US & Canada)\n" + - "END:DAYLIGHT\n" + - "END:VTIMEZONE\n" + - "END:VCALENDAR")) + assertEquals("US-Eastern", ICalendar.timezoneDefToTzId( + "BEGIN:VCALENDAR\n" + + "PRODID:-//Example Corp.//CalDAV Client//EN\n" + + "VERSION:2.0\n" + + "BEGIN:VTIMEZONE\n" + + "TZID:US-Eastern\n" + + "LAST-MODIFIED:19870101T000000Z\n" + + "BEGIN:STANDARD\n" + + "DTSTART:19671029T020000\n" + + "RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10\n" + + "TZOFFSETFROM:-0400\n" + + "TZOFFSETTO:-0500\n" + + "TZNAME:Eastern Standard Time (US & Canada)\n" + + "END:STANDARD\n" + + "BEGIN:DAYLIGHT\n" + + "DTSTART:19870405T020000\n" + + "RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4\n" + + "TZOFFSETFROM:-0500\n" + + "TZOFFSETTO:-0400\n" + + "TZNAME:Eastern Daylight Time (US & Canada)\n" + + "END:DAYLIGHT\n" + + "END:VTIMEZONE\n" + + "END:VCALENDAR" + ) + ) } @Test @@ -171,10 +176,14 @@ class ICalendarTest { assertNull(ICalendar.timezoneDefToTzId("/* invalid content */")) // time zone without TZID - assertNull(ICalendar.timezoneDefToTzId("BEGIN:VCALENDAR\n" + - "PRODID:-//Inverse inc./SOGo 2.2.10//EN\n" + - "VERSION:2.0\n" + - "END:VCALENDAR")) + assertNull( + ICalendar.timezoneDefToTzId( + "BEGIN:VCALENDAR\n" + + "PRODID:-//Inverse inc./SOGo 2.2.10//EN\n" + + "VERSION:2.0\n" + + "END:VCALENDAR" + ) + ) } @@ -182,8 +191,9 @@ class ICalendarTest { fun testVAlarmToMin_TriggerDuration_Negative() { // TRIGGER;REL=START:-P1DT1H1M29S val (ref, min) = ICalendar.vAlarmToMin( - VAlarm(Duration.parse("-P1DT1H1M29S")), - Event(), false)!! + VAlarm(Duration.parse("-P1DT1H1M29S")), + Event(), false + )!! assertEquals(Related.START, ref) assertEquals(60*24 + 60 + 1, min) } @@ -192,8 +202,9 @@ class ICalendarTest { fun testVAlarmToMin_TriggerDuration_OnlySeconds() { // TRIGGER;REL=START:-PT3600S val (ref, min) = ICalendar.vAlarmToMin( - VAlarm(Duration.parse("-PT3600S")), - Event(), false)!! + VAlarm(Duration.parse("-PT3600S")), + Event(), false + )!! assertEquals(Related.START, ref) assertEquals(60, min) } @@ -202,8 +213,9 @@ class ICalendarTest { fun testVAlarmToMin_TriggerDuration_Positive() { // TRIGGER;REL=START:P1DT1H1M30S (alarm *after* start) val (ref, min) = ICalendar.vAlarmToMin( - VAlarm(Duration.parse("P1DT1H1M30S")), - Event(), false)!! + VAlarm(Duration.parse("P1DT1H1M30S")), + Event(), false + )!! assertEquals(Related.START, ref) assertEquals(-(60*24 + 60 + 1), min) } @@ -270,8 +282,8 @@ class ICalendarTest { val event = Event() event.dtStart = DtStart(Date(currentTime)) val (ref, min) = ICalendar.vAlarmToMin( - VAlarm(Period.parse("-P1W1D")), - event, false + VAlarm(Period.parse("-P1W1D")), + event, false )!! assertEquals(Related.START, ref) assertEquals(8*24*60, min) diff --git a/src/test/java/at/bitfire/ical4android/Ical4jTest.kt b/src/androidTest/java/at/bitfire/ical4android/Ical4jTest.kt index ad8d11b..7bd9292 100644 --- a/src/test/java/at/bitfire/ical4android/Ical4jTest.kt +++ b/src/androidTest/java/at/bitfire/ical4android/Ical4jTest.kt @@ -21,14 +21,18 @@ class Ical4jTest { @Test fun testEmailParameter() { // https://github.com/ical4j/ical4j/issues/418 - val e = Event.eventsFromReader(StringReader("BEGIN:VCALENDAR\n" + - "VERSION:2.0\n" + - "BEGIN:VEVENT\n" + - "SUMMARY:Test\n" + - "DTSTART;VALUE=DATE:20200702\n" + - "ATTENDEE;EMAIL=attendee1@example.com:sample:attendee1\n" + - "END:VEVENT\n" + - "END:VCALENDAR")).first() + val e = Event.eventsFromReader( + StringReader( + "BEGIN:VCALENDAR\n" + + "VERSION:2.0\n" + + "BEGIN:VEVENT\n" + + "SUMMARY:Test\n" + + "DTSTART;VALUE=DATE:20200702\n" + + "ATTENDEE;EMAIL=attendee1@example.com:sample:attendee1\n" + + "END:VEVENT\n" + + "END:VCALENDAR" + ) + ).first() assertEquals("attendee1@example.com", e.attendees.first.getParameter<Email>(Parameter.EMAIL).value) } diff --git a/src/androidTest/java/at/bitfire/ical4android/LocaleNonWesternDigitsTest.kt b/src/androidTest/java/at/bitfire/ical4android/LocaleNonWesternDigitsTest.kt index 81f0783..81f91c1 100644 --- a/src/androidTest/java/at/bitfire/ical4android/LocaleNonWesternDigitsTest.kt +++ b/src/androidTest/java/at/bitfire/ical4android/LocaleNonWesternDigitsTest.kt @@ -5,8 +5,9 @@ package at.bitfire.ical4android import net.fortuna.ical4j.model.property.TzOffsetFrom +import org.junit.AfterClass import org.junit.Assert.assertEquals -import org.junit.Before +import org.junit.BeforeClass import org.junit.ComparisonFailure import org.junit.Test import java.time.ZoneOffset @@ -15,13 +16,22 @@ import java.util.* class LocaleNonWesternDigitsTest { companion object { - val locale = Locale("fa", "ir", "u-un-arabext") - } + val origLocale = Locale.getDefault() + val testLocale = Locale("fa", "ir", "u-un-arabext") + + @BeforeClass + @JvmStatic + fun setFaIrArabLocale() { + assertEquals("Persian (Iran) locale not available", "fa", testLocale.language) + Locale.setDefault(testLocale) + } + + @AfterClass + @JvmStatic + fun resetLocale() { + Locale.setDefault(origLocale) + } - @Before - fun verifyLocale() { - assertEquals("Persian (Iran) locale not available", "fa", locale.language) - Locale.setDefault(locale) } @Test diff --git a/src/test/java/at/bitfire/ical4android/TaskTest.kt b/src/androidTest/java/at/bitfire/ical4android/TaskTest.kt index cbe0bcc..cbe0bcc 100644 --- a/src/test/java/at/bitfire/ical4android/TaskTest.kt +++ b/src/androidTest/java/at/bitfire/ical4android/TaskTest.kt diff --git a/src/test/java/at/bitfire/ical4android/TimeApiExtensionsTest.kt b/src/androidTest/java/at/bitfire/ical4android/TimeApiExtensionsTest.kt index 44a02a0..44a02a0 100644 --- a/src/test/java/at/bitfire/ical4android/TimeApiExtensionsTest.kt +++ b/src/androidTest/java/at/bitfire/ical4android/TimeApiExtensionsTest.kt diff --git a/src/androidTest/java/at/bitfire/ical4android/impl/TestEvent.kt b/src/androidTest/java/at/bitfire/ical4android/impl/TestEvent.kt index f9c9571..11270a1 100644 --- a/src/androidTest/java/at/bitfire/ical4android/impl/TestEvent.kt +++ b/src/androidTest/java/at/bitfire/ical4android/impl/TestEvent.kt @@ -5,7 +5,6 @@ package at.bitfire.ical4android.impl import android.content.ContentValues -import android.provider.CalendarContract import android.provider.CalendarContract.Events import at.bitfire.ical4android.* import java.util.* diff --git a/src/androidTest/java/at/bitfire/ical4android/impl/TestJtxIcalObject.kt b/src/androidTest/java/at/bitfire/ical4android/impl/TestJtxIcalObject.kt index 57615fb..a1397e9 100644 --- a/src/androidTest/java/at/bitfire/ical4android/impl/TestJtxIcalObject.kt +++ b/src/androidTest/java/at/bitfire/ical4android/impl/TestJtxIcalObject.kt @@ -5,7 +5,9 @@ package at.bitfire.ical4android.impl import android.content.ContentValues -import at.bitfire.ical4android.* +import at.bitfire.ical4android.JtxCollection +import at.bitfire.ical4android.JtxICalObject +import at.bitfire.ical4android.JtxICalObjectFactory class TestJtxIcalObject(testCollection: JtxCollection<JtxICalObject>): JtxICalObject(testCollection) { diff --git a/src/test/java/at/bitfire/ical4android/validation/EventValidatorTest.kt b/src/androidTest/java/at/bitfire/ical4android/validation/EventValidatorTest.kt index c64d0d7..2af3fe8 100644 --- a/src/test/java/at/bitfire/ical4android/validation/EventValidatorTest.kt +++ b/src/androidTest/java/at/bitfire/ical4android/validation/EventValidatorTest.kt @@ -16,34 +16,34 @@ import net.fortuna.ical4j.model.property.RRule import org.junit.Assert.* import org.junit.Test import java.io.StringReader -import java.util.* class EventValidatorTest { - val tzReg = TimeZoneRegistryFactory.getInstance().createRegistry() + companion object { + val tzReg = TimeZoneRegistryFactory.getInstance().createRegistry() + } // DTSTART and DTEND - @Test - fun testEnsureCorrectStartAndEndTime_noDtStart() { - assertThrows(InvalidCalendarException::class.java) { - val event = Event().apply { - dtEnd = DtEnd(DateTime("20000105T000000")) // DATETIME - // no dtStart - } - EventValidator.correctStartAndEndTime(event) + @Test(expected = InvalidCalendarException::class) + fun testEnsureCorrectStartAndEndTime_noDtStart_DateTime() { + val event = Event().apply { + dtEnd = DtEnd(DateTime("20000105T000000")) // DATETIME + // no dtStart } + EventValidator.correctStartAndEndTime(event) + } - assertThrows(InvalidCalendarException::class.java) { - Event.eventsFromReader(StringReader( - "BEGIN:VCALENDAR\n" + - "BEGIN:VEVENT\n" + - "UID:51d8529a-5844-4609-918b-2891b855e0e8\n" + - "DTEND;VALUE=DATE:20211116\n" + // DATE - "END:VEVENT\n" + - "END:VCALENDAR")).first() - } + @Test(expected = InvalidCalendarException::class) + fun testEnsureCorrectStartAndEndTime_noDtStart_Date() { + Event.eventsFromReader(StringReader( + "BEGIN:VCALENDAR\n" + + "BEGIN:VEVENT\n" + + "UID:51d8529a-5844-4609-918b-2891b855e0e8\n" + + "DTEND;VALUE=DATE:20211116\n" + // DATE + "END:VEVENT\n" + + "END:VCALENDAR")).first() } @Test diff --git a/src/test/resources/events/all-day-0sec.ics b/src/androidTest/resources/events/all-day-0sec.ics index 07679f2..07679f2 100644 --- a/src/test/resources/events/all-day-0sec.ics +++ b/src/androidTest/resources/events/all-day-0sec.ics diff --git a/src/test/resources/events/all-day-10days.ics b/src/androidTest/resources/events/all-day-10days.ics index 52e6dbd..52e6dbd 100644 --- a/src/test/resources/events/all-day-10days.ics +++ b/src/androidTest/resources/events/all-day-10days.ics diff --git a/src/test/resources/events/all-day-1day.ics b/src/androidTest/resources/events/all-day-1day.ics index 506d295..506d295 100644 --- a/src/test/resources/events/all-day-1day.ics +++ b/src/androidTest/resources/events/all-day-1day.ics diff --git a/src/test/resources/events/dst-only-vtimezone.ics b/src/androidTest/resources/events/dst-only-vtimezone.ics index e49d74d..e49d74d 100644 --- a/src/test/resources/events/dst-only-vtimezone.ics +++ b/src/androidTest/resources/events/dst-only-vtimezone.ics diff --git a/src/test/resources/events/event-on-that-day.ics b/src/androidTest/resources/events/event-on-that-day.ics index 0ccbd4f..0ccbd4f 100644 --- a/src/test/resources/events/event-on-that-day.ics +++ b/src/androidTest/resources/events/event-on-that-day.ics diff --git a/src/test/resources/events/latin1.ics b/src/androidTest/resources/events/latin1.ics index 20d97d0..20d97d0 100644 --- a/src/test/resources/events/latin1.ics +++ b/src/androidTest/resources/events/latin1.ics diff --git a/src/test/resources/events/multiple.ics b/src/androidTest/resources/events/multiple.ics index 6e300ab..6e300ab 100644 --- a/src/test/resources/events/multiple.ics +++ b/src/androidTest/resources/events/multiple.ics diff --git a/src/test/resources/events/one-event-with-exception-one-without.ics b/src/androidTest/resources/events/one-event-with-exception-one-without.ics index 182711b..182711b 100644 --- a/src/test/resources/events/one-event-with-exception-one-without.ics +++ b/src/androidTest/resources/events/one-event-with-exception-one-without.ics diff --git a/src/test/resources/events/one-event-with-multiple-exceptions-one-without.ics b/src/androidTest/resources/events/one-event-with-multiple-exceptions-one-without.ics index bff4528..bff4528 100644 --- a/src/test/resources/events/one-event-with-multiple-exceptions-one-without.ics +++ b/src/androidTest/resources/events/one-event-with-multiple-exceptions-one-without.ics diff --git a/src/test/resources/events/outlook1.ics b/src/androidTest/resources/events/outlook1.ics index 000afaa..000afaa 100644 --- a/src/test/resources/events/outlook1.ics +++ b/src/androidTest/resources/events/outlook1.ics diff --git a/src/test/resources/events/recurring-only-exception.ics b/src/androidTest/resources/events/recurring-only-exception.ics index 26012e1..26012e1 100644 --- a/src/test/resources/events/recurring-only-exception.ics +++ b/src/androidTest/resources/events/recurring-only-exception.ics diff --git a/src/test/resources/events/recurring-with-exception1.ics b/src/androidTest/resources/events/recurring-with-exception1.ics index 0382497..0382497 100644 --- a/src/test/resources/events/recurring-with-exception1.ics +++ b/src/androidTest/resources/events/recurring-with-exception1.ics diff --git a/src/test/resources/events/two-events-without-exceptions.ics b/src/androidTest/resources/events/two-events-without-exceptions.ics index be6290f..be6290f 100644 --- a/src/test/resources/events/two-events-without-exceptions.ics +++ b/src/androidTest/resources/events/two-events-without-exceptions.ics diff --git a/src/test/resources/events/two-line-description-without-crlf.ics b/src/androidTest/resources/events/two-line-description-without-crlf.ics index 03c8b62..03c8b62 100644 --- a/src/test/resources/events/two-line-description-without-crlf.ics +++ b/src/androidTest/resources/events/two-line-description-without-crlf.ics diff --git a/src/test/resources/events/utf8.ics b/src/androidTest/resources/events/utf8.ics index 87171a9..87171a9 100644 --- a/src/test/resources/events/utf8.ics +++ b/src/androidTest/resources/events/utf8.ics diff --git a/src/test/resources/events/vienna-evolution.ics b/src/androidTest/resources/events/vienna-evolution.ics index 5f11911..5f11911 100644 --- a/src/test/resources/events/vienna-evolution.ics +++ b/src/androidTest/resources/events/vienna-evolution.ics diff --git a/src/test/resources/tasks/empty-priority.ics b/src/androidTest/resources/tasks/empty-priority.ics index 69ad1ae..69ad1ae 100644 --- a/src/test/resources/tasks/empty-priority.ics +++ b/src/androidTest/resources/tasks/empty-priority.ics diff --git a/src/test/resources/tasks/latin1.ics b/src/androidTest/resources/tasks/latin1.ics index b3502de..b3502de 100644 --- a/src/test/resources/tasks/latin1.ics +++ b/src/androidTest/resources/tasks/latin1.ics diff --git a/src/test/resources/tasks/most-fields1.ics b/src/androidTest/resources/tasks/most-fields1.ics index ff4dbb0..ff4dbb0 100644 --- a/src/test/resources/tasks/most-fields1.ics +++ b/src/androidTest/resources/tasks/most-fields1.ics diff --git a/src/test/resources/tasks/most-fields2.ics b/src/androidTest/resources/tasks/most-fields2.ics index f6c7215..f6c7215 100644 --- a/src/test/resources/tasks/most-fields2.ics +++ b/src/androidTest/resources/tasks/most-fields2.ics diff --git a/src/test/resources/tasks/rfc5545-sample1.ics b/src/androidTest/resources/tasks/rfc5545-sample1.ics index 18d53df..18d53df 100644 --- a/src/test/resources/tasks/rfc5545-sample1.ics +++ b/src/androidTest/resources/tasks/rfc5545-sample1.ics diff --git a/src/test/resources/tasks/utf8.ics b/src/androidTest/resources/tasks/utf8.ics index 67aaa1e..67aaa1e 100644 --- a/src/test/resources/tasks/utf8.ics +++ b/src/androidTest/resources/tasks/utf8.ics diff --git a/src/test/resources/tz/Karachi.ics b/src/androidTest/resources/tz/Karachi.ics index 1515d2b..1515d2b 100644 --- a/src/test/resources/tz/Karachi.ics +++ b/src/androidTest/resources/tz/Karachi.ics diff --git a/src/test/resources/tz/Mogadishu.ics b/src/androidTest/resources/tz/Mogadishu.ics index b5e4fd3..b5e4fd3 100644 --- a/src/test/resources/tz/Mogadishu.ics +++ b/src/androidTest/resources/tz/Mogadishu.ics diff --git a/src/test/resources/tz/Vienna.ics b/src/androidTest/resources/tz/Vienna.ics index 5b0f65f..5b0f65f 100644 --- a/src/test/resources/tz/Vienna.ics +++ b/src/androidTest/resources/tz/Vienna.ics diff --git a/src/main/java/at/bitfire/ical4android/validation/EventValidator.kt b/src/main/java/at/bitfire/ical4android/validation/EventValidator.kt index ac0e108..d8ee48c 100644 --- a/src/main/java/at/bitfire/ical4android/validation/EventValidator.kt +++ b/src/main/java/at/bitfire/ical4android/validation/EventValidator.kt @@ -12,11 +12,13 @@ import at.bitfire.ical4android.util.TimeApiExtensions.toIcal4jDate import at.bitfire.ical4android.util.TimeApiExtensions.toIcal4jDateTime import at.bitfire.ical4android.util.TimeApiExtensions.toLocalDate import at.bitfire.ical4android.util.TimeApiExtensions.toZoneIdCompat -import net.fortuna.ical4j.model.Date import net.fortuna.ical4j.model.DateTime import net.fortuna.ical4j.model.property.DtStart import net.fortuna.ical4j.model.property.RRule -import java.time.* +import net.fortuna.ical4j.util.TimeZones +import java.time.LocalTime +import java.time.ZonedDateTime +import java.util.* /** * Sometimes CalendarStorage or servers respond with invalid event definitions. Here we try to @@ -63,17 +65,27 @@ class EventValidator(val e: Event) { rRule.recur.until?.let { until -> if (until !is DateTime) { Ical4Android.log.warning("DTSTART has DATETIME, but UNTIL has DATE; copying time from DTSTART to UNTIL") - val timeZone = if (dtStart.timeZone != null) - dtStart.timeZone.toZoneIdCompat() + val dtStartTimeZone = if (dtStart.timeZone != null) + dtStart.timeZone else if (dtStart.isUtc) - ZoneOffset.UTC + TimeZones.getUtcTimeZone() else /* floating time */ - ZoneId.systemDefault() + TimeZone.getDefault() + + val dtStartCal = Calendar.getInstance(dtStartTimeZone).apply { + time = dtStart.date + } + val dtStartTime = LocalTime.of( + dtStartCal.get(Calendar.HOUR_OF_DAY), + dtStartCal.get(Calendar.MINUTE), + dtStartCal.get(Calendar.SECOND) + ) + rRule.recur.until = ZonedDateTime.of( - until.toLocalDate(), // date from until - LocalTime.ofInstant(dtStart.date.toInstant(), timeZone), // time from dtStart - timeZone + until.toLocalDate(), // date from until + dtStartTime, // time from dtStart + dtStartTimeZone.toZoneIdCompat() ).toIcal4jDateTime() } } diff --git a/src/test/README.txt b/src/test/README.txt new file mode 100644 index 0000000..60a244a --- /dev/null +++ b/src/test/README.txt @@ -0,0 +1,6 @@ + +ATTENTION! + +Do not use JVM unit tests for methods the use the Time API or other APIs that behave +differently in normal JVMs and the Android JVM. Especially do not write JVM unit tests +that use APIs that are desugared in Android. Use Android unit tests (androidTest) instead. |