Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/bitfireAT/ical4android.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRicki Hirner <hirner@bitfire.at>2022-07-11 22:21:08 +0300
committerRicki Hirner <hirner@bitfire.at>2022-07-11 22:34:39 +0300
commit61e94122401b2c6e9b7e4366697abe29b683ec3d (patch)
treed1e219f853cb9f175a749ec3e247089dfe7f3e8e
parente826c28c4553bad692e0959563a16dfa6993e88b (diff)
Move validator to validation package
-rw-r--r--src/androidTest/java/at/bitfire/ical4android/AndroidEventTest.kt6
-rw-r--r--src/main/java/at/bitfire/ical4android/AndroidEvent.kt1
-rw-r--r--src/main/java/at/bitfire/ical4android/Event.kt1
-rw-r--r--src/main/java/at/bitfire/ical4android/EventValidator.kt90
-rw-r--r--src/main/java/at/bitfire/ical4android/validation/EventValidator.kt98
-rw-r--r--src/main/java/at/bitfire/ical4android/validation/ICalPreprocessor.kt5
-rw-r--r--src/main/java/at/bitfire/ical4android/validation/RruleUntilAfterStartRule.kt1
-rw-r--r--src/test/java/at/bitfire/ical4android/validation/EventValidatorTest.kt (renamed from src/test/java/at/bitfire/ical4android/EventValidatorTest.kt)198
8 files changed, 204 insertions, 196 deletions
diff --git a/src/androidTest/java/at/bitfire/ical4android/AndroidEventTest.kt b/src/androidTest/java/at/bitfire/ical4android/AndroidEventTest.kt
index 6fafc9f..ef0e67f 100644
--- a/src/androidTest/java/at/bitfire/ical4android/AndroidEventTest.kt
+++ b/src/androidTest/java/at/bitfire/ical4android/AndroidEventTest.kt
@@ -10,9 +10,7 @@ import android.content.ContentUris
import android.content.ContentValues
import android.database.DatabaseUtils
import android.net.Uri
-import android.provider.CalendarContract
import android.provider.CalendarContract.*
-import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.rule.GrantPermissionRule
import at.bitfire.ical4android.MiscUtils.ContentProviderClientHelper.closeCompat
@@ -21,7 +19,6 @@ import at.bitfire.ical4android.impl.TestCalendar
import at.bitfire.ical4android.impl.TestEvent
import at.bitfire.ical4android.util.AndroidTimeUtils
import net.fortuna.ical4j.model.*
-import net.fortuna.ical4j.model.Date
import net.fortuna.ical4j.model.component.VAlarm
import net.fortuna.ical4j.model.parameter.*
import net.fortuna.ical4j.model.property.*
@@ -31,7 +28,6 @@ import org.junit.Assert.*
import java.net.URI
import java.time.Duration
import java.time.Period
-import java.util.*
class AndroidEventTest {
@@ -430,7 +426,7 @@ class AndroidEventTest {
assertEquals("20200601T000000Z,20210601T000000Z,20220601T000000Z", values.get(Events.RDATE))
}
- @Test
+ @Test
fun testBuildEvent_AllDay_DtEnd_Duration_NonRecurring() {
val values = buildEvent(false) {
dtStart = DtStart(Date("20200601"))
diff --git a/src/main/java/at/bitfire/ical4android/AndroidEvent.kt b/src/main/java/at/bitfire/ical4android/AndroidEvent.kt
index 1ce809e..062c1cf 100644
--- a/src/main/java/at/bitfire/ical4android/AndroidEvent.kt
+++ b/src/main/java/at/bitfire/ical4android/AndroidEvent.kt
@@ -25,6 +25,7 @@ import at.bitfire.ical4android.util.TimeApiExtensions.toLocalDate
import at.bitfire.ical4android.util.TimeApiExtensions.toLocalTime
import at.bitfire.ical4android.util.TimeApiExtensions.toRfc5545Duration
import at.bitfire.ical4android.util.TimeApiExtensions.toZonedDateTime
+import at.bitfire.ical4android.validation.EventValidator
import net.fortuna.ical4j.model.*
import net.fortuna.ical4j.model.Date
import net.fortuna.ical4j.model.component.VAlarm
diff --git a/src/main/java/at/bitfire/ical4android/Event.kt b/src/main/java/at/bitfire/ical4android/Event.kt
index daf1236..acf49a4 100644
--- a/src/main/java/at/bitfire/ical4android/Event.kt
+++ b/src/main/java/at/bitfire/ical4android/Event.kt
@@ -6,6 +6,7 @@ package at.bitfire.ical4android
import at.bitfire.ical4android.DateUtils.isDateTime
import at.bitfire.ical4android.ICalendar.Companion.CALENDAR_NAME
+import at.bitfire.ical4android.validation.EventValidator
import net.fortuna.ical4j.data.CalendarOutputter
import net.fortuna.ical4j.data.ParserException
import net.fortuna.ical4j.model.*
diff --git a/src/main/java/at/bitfire/ical4android/EventValidator.kt b/src/main/java/at/bitfire/ical4android/EventValidator.kt
deleted file mode 100644
index 85ef2da..0000000
--- a/src/main/java/at/bitfire/ical4android/EventValidator.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-/***************************************************************************************************
- * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
- **************************************************************************************************/
-
-package at.bitfire.ical4android
-
-import at.bitfire.ical4android.util.TimeApiExtensions.toIcal4jDate
-import at.bitfire.ical4android.util.TimeApiExtensions.toLocalDate
-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
-
-/**
- * Sometimes CalendarStorage or servers respond with invalid event definitions. Here we try to
- * validate, repair and assume whatever seems appropriate before denying the whole event.
- */
-class EventValidator {
-
- companion object {
-
- fun repair(e: Event) {
- val dtStart = correctStartAndEndTime(e)
- sameTypeForDtStartAndRruleUntil(dtStart, e.rRules)
- removeRRulesWithUntilBeforeDtStart(dtStart, e.rRules)
- }
-
- /**
- * Ensure proper start and end time
- */
- fun correctStartAndEndTime(e: Event): DtStart {
- if (e.dtStart == null)
- throw InvalidCalendarException("Event without start time")
- else if (e.dtEnd != null && e.dtStart!!.date > e.dtEnd!!.date) {
- Ical4Android.log.warning("DTSTART after DTEND; removing DTEND")
- e.dtEnd = null
- }
- return e.dtStart!!
- }
-
- /**
- * Tries to make the value type of UNTIL and DTSTART the same (both DATE or DATETIME).
- */
- fun sameTypeForDtStartAndRruleUntil(dtStart: DtStart, rRules: MutableList<RRule>) {
- if (DateUtils.isDate(dtStart)) {
- for (rRule in rRules) {
- rRule.recur.until?.let { until ->
- if (until is DateTime) {
- Ical4Android.log.warning("DTSTART has DATE, but UNTIL has DATETIME; making UNTIL have DATE only")
- rRule.recur.until = Date(until.toLocalDate().toIcal4jDate())
- }
- }
- }
- } else if (DateUtils.isDateTime(dtStart)) {
- for (rRule in rRules) {
- rRule.recur.until?.let { until ->
- if (until !is DateTime) {
- Ical4Android.log.warning("DTSTART has DATETIME, but UNTIL has DATE; making UNTIL have DATETIME")
- rRule.recur.until = DateTime(until)
- }
- }
- }
- } else
- throw InvalidCalendarException("Event with invalid DTSTART value")
- }
-
- /**
- * Will remove the RRULES of an event where UNTIL lies before DTSTART
- */
- fun removeRRulesWithUntilBeforeDtStart(dtStart: DtStart, rRules: MutableList<RRule>) {
- val iter = rRules.iterator()
- while (iter.hasNext()) {
- val rRule = iter.next()
-
- // drop invalid RRULEs
- if (hasUntilBeforeDtStart(dtStart, rRule))
- iter.remove()
- }
- }
-
- /**
- * Checks whether UNTIL of an RRULE lies before DTSTART
- */
- fun hasUntilBeforeDtStart(dtStart: DtStart, rRule: RRule): Boolean {
- val until = rRule.recur.until ?: return false
- return until < dtStart.date
- }
-
- }
-} \ No newline at end of file
diff --git a/src/main/java/at/bitfire/ical4android/validation/EventValidator.kt b/src/main/java/at/bitfire/ical4android/validation/EventValidator.kt
new file mode 100644
index 0000000..a1b6d96
--- /dev/null
+++ b/src/main/java/at/bitfire/ical4android/validation/EventValidator.kt
@@ -0,0 +1,98 @@
+/***************************************************************************************************
+ * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
+ **************************************************************************************************/
+
+package at.bitfire.ical4android.validation
+
+import at.bitfire.ical4android.DateUtils
+import at.bitfire.ical4android.Event
+import at.bitfire.ical4android.Ical4Android
+import at.bitfire.ical4android.InvalidCalendarException
+import at.bitfire.ical4android.util.TimeApiExtensions.toIcal4jDate
+import at.bitfire.ical4android.util.TimeApiExtensions.toLocalDate
+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
+
+/**
+ * Sometimes calendar apps or servers provide invalid event definitions, which are then
+ * saved in the calendar provider. This class tries to validate, repair and assume
+ * whatever seems appropriate to avoid sending invalid events (that may be rejected by servers).
+ */
+object EventValidator {
+
+ /**
+ * Repair an event so that it's more conforming to iCalendar standard. This will
+ * be used before an event is uploaded to a server to reduce the cases where the
+ * servers reject uploaded events.
+ */
+ fun repair(e: Event) {
+ val dtStart = correctStartAndEndTime(e)
+ sameTypeForDtStartAndRruleUntil(dtStart, e.rRules)
+ removeRRulesWithUntilBeforeDtStart(dtStart, e.rRules)
+ }
+
+
+ /**
+ * Ensure proper start and end time
+ */
+ fun correctStartAndEndTime(e: Event): DtStart {
+ if (e.dtStart == null)
+ throw InvalidCalendarException("Event without start time")
+ else if (e.dtEnd != null && e.dtStart!!.date > e.dtEnd!!.date) {
+ Ical4Android.log.warning("DTSTART after DTEND; removing DTEND")
+ e.dtEnd = null
+ }
+ return e.dtStart!!
+ }
+
+ /**
+ * Tries to make the value type of UNTIL and DTSTART the same (both DATE or DATETIME).
+ */
+ fun sameTypeForDtStartAndRruleUntil(dtStart: DtStart, rRules: MutableList<RRule>) {
+ if (DateUtils.isDate(dtStart)) {
+ for (rRule in rRules) {
+ rRule.recur.until?.let { until ->
+ if (until is DateTime) {
+ Ical4Android.log.warning("DTSTART has DATE, but UNTIL has DATETIME; making UNTIL have DATE only")
+ rRule.recur.until = Date(until.toLocalDate().toIcal4jDate())
+ }
+ }
+ }
+ } else if (DateUtils.isDateTime(dtStart)) {
+ for (rRule in rRules) {
+ rRule.recur.until?.let { until ->
+ if (until !is DateTime) {
+ Ical4Android.log.warning("DTSTART has DATETIME, but UNTIL has DATE; making UNTIL have DATETIME")
+ rRule.recur.until = DateTime(until)
+ }
+ }
+ }
+ } else
+ throw InvalidCalendarException("Event with invalid DTSTART value")
+ }
+
+ /**
+ * Will remove the RRULES of an event where UNTIL lies before DTSTART
+ */
+ fun removeRRulesWithUntilBeforeDtStart(dtStart: DtStart, rRules: MutableList<RRule>) {
+ val iter = rRules.iterator()
+ while (iter.hasNext()) {
+ val rRule = iter.next()
+
+ // drop invalid RRULEs
+ if (hasUntilBeforeDtStart(dtStart, rRule))
+ iter.remove()
+ }
+ }
+
+ /**
+ * Checks whether UNTIL of an RRULE lies before DTSTART
+ */
+ fun hasUntilBeforeDtStart(dtStart: DtStart, rRule: RRule): Boolean {
+ val until = rRule.recur.until ?: return false
+ return until < dtStart.date
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/at/bitfire/ical4android/validation/ICalPreprocessor.kt b/src/main/java/at/bitfire/ical4android/validation/ICalPreprocessor.kt
index 41f7e86..c58d1b7 100644
--- a/src/main/java/at/bitfire/ical4android/validation/ICalPreprocessor.kt
+++ b/src/main/java/at/bitfire/ical4android/validation/ICalPreprocessor.kt
@@ -19,11 +19,12 @@ import java.util.*
import java.util.logging.Level
/**
- * Applies some rules to increase compatibility or parsed iCalendars:
+ * Applies some rules to increase compatibility of parsed (incoming) iCalendars:
*
* - [CreatedPropertyRule] to make sure CREATED is UTC
- * - [DatePropertyRule], [DateListPropertyRule]: to rename Outlook-specific TZID parameters
+ * - [DatePropertyRule], [DateListPropertyRule] to rename Outlook-specific TZID parameters
* (like "W. Europe Standard Time" to an Android-friendly name like "Europe/Vienna")
+ * - [RruleUntilAfterStartRule] to remove RRULEs with UNTIL before DTSTART
*
*/
object ICalPreprocessor {
diff --git a/src/main/java/at/bitfire/ical4android/validation/RruleUntilAfterStartRule.kt b/src/main/java/at/bitfire/ical4android/validation/RruleUntilAfterStartRule.kt
index f1d2bd5..44d264f 100644
--- a/src/main/java/at/bitfire/ical4android/validation/RruleUntilAfterStartRule.kt
+++ b/src/main/java/at/bitfire/ical4android/validation/RruleUntilAfterStartRule.kt
@@ -4,7 +4,6 @@
package at.bitfire.ical4android.validation
-import at.bitfire.ical4android.EventValidator
import net.fortuna.ical4j.model.Property
import net.fortuna.ical4j.model.component.VEvent
import net.fortuna.ical4j.model.property.RRule
diff --git a/src/test/java/at/bitfire/ical4android/EventValidatorTest.kt b/src/test/java/at/bitfire/ical4android/validation/EventValidatorTest.kt
index f4ccaf6..86d580e 100644
--- a/src/test/java/at/bitfire/ical4android/EventValidatorTest.kt
+++ b/src/test/java/at/bitfire/ical4android/validation/EventValidatorTest.kt
@@ -2,14 +2,18 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
**************************************************************************************************/
-package at.bitfire.ical4android
-
-import net.fortuna.ical4j.model.*
+package at.bitfire.ical4android.validation
+
+import at.bitfire.ical4android.Event
+import at.bitfire.ical4android.InvalidCalendarException
+import net.fortuna.ical4j.model.Date
+import net.fortuna.ical4j.model.DateTime
+import net.fortuna.ical4j.model.Recur
+import net.fortuna.ical4j.model.TimeZoneRegistryFactory
import net.fortuna.ical4j.model.property.DtEnd
import net.fortuna.ical4j.model.property.DtStart
import net.fortuna.ical4j.model.property.RRule
import org.junit.Assert.*
-
import org.junit.Test
import java.io.StringReader
@@ -30,12 +34,13 @@ class EventValidatorTest {
}
assertThrows(InvalidCalendarException("Event without start time").javaClass) {
- 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()
+ 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()
}
}
@@ -49,13 +54,14 @@ class EventValidatorTest {
EventValidator.correctStartAndEndTime(event)
assertNull(event.dtEnd)
- val event1 = Event.eventsFromReader(StringReader("BEGIN:VCALENDAR\n" +
- "BEGIN:VEVENT\n" +
- "UID:51d8529a-5844-4609-918b-2891b855e0e8\n" +
- "DTSTART;VALUE=DATE:20211117\n" + // DATE
- "DTEND;VALUE=DATE:20211116\n" + // DATE
- "END:VEVENT\n" +
- "END:VCALENDAR")).first()
+ val event1 = Event.eventsFromReader(StringReader(
+ "BEGIN:VCALENDAR\n" +
+ "BEGIN:VEVENT\n" +
+ "UID:51d8529a-5844-4609-918b-2891b855e0e8\n" +
+ "DTSTART;VALUE=DATE:20211117\n" + // DATE
+ "DTEND;VALUE=DATE:20211116\n" + // DATE
+ "END:VEVENT\n" +
+ "END:VCALENDAR")).first()
assertNull(event1.dtEnd)
}
@@ -76,22 +82,24 @@ class EventValidatorTest {
assertEquals(DateTime("20211115T001100Z"), event.dtStart!!.date)
assertEquals(DateTime("20251214T001100Z"), event.rRules.first.recur.until)
- val event1 = Event.eventsFromReader(StringReader("BEGIN:VCALENDAR\n" +
- "BEGIN:VEVENT\n" +
- "UID:51d8529a-5844-4609-918b-2891b855e0e8\n" +
- "DTSTART;VALUE=DATE:20211115\n" + // DATE
- "RRULE:FREQ=MONTHLY;UNTIL=20231214;BYMONTHDAY=15\n" + // DATE
- "END:VEVENT\n" +
- "END:VCALENDAR")).first()
+ val event1 = Event.eventsFromReader(StringReader(
+ "BEGIN:VCALENDAR\n" +
+ "BEGIN:VEVENT\n" +
+ "UID:51d8529a-5844-4609-918b-2891b855e0e8\n" +
+ "DTSTART;VALUE=DATE:20211115\n" + // DATE
+ "RRULE:FREQ=MONTHLY;UNTIL=20231214;BYMONTHDAY=15\n" + // DATE
+ "END:VEVENT\n" +
+ "END:VCALENDAR")).first()
assertEquals(Date("20231214"), event1.rRules.first.recur.until)
- val event2 = Event.eventsFromReader(StringReader("BEGIN:VCALENDAR\n" +
- "BEGIN:VEVENT\n" +
- "UID:381fb26b-2da5-4dd2-94d7-2e0874128aa7\n" +
- "DTSTART;VALUE=DATE:20080215\n" + // DATE
- "RRULE:FREQ=YEARLY;UNTIL=20230216;BYMONTHDAY=15\n" + // DATE
- "END:VEVENT\n" +
- "END:VCALENDAR")).first()
+ val event2 = Event.eventsFromReader(StringReader(
+ "BEGIN:VCALENDAR\n" +
+ "BEGIN:VEVENT\n" +
+ "UID:381fb26b-2da5-4dd2-94d7-2e0874128aa7\n" +
+ "DTSTART;VALUE=DATE:20080215\n" + // DATE
+ "RRULE:FREQ=YEARLY;UNTIL=20230216;BYMONTHDAY=15\n" + // DATE
+ "END:VEVENT\n" +
+ "END:VCALENDAR")).first()
assertEquals(Date("20230216"), event2.rRules.first.recur.until)
}
@@ -109,23 +117,25 @@ class EventValidatorTest {
assertEquals(1639440000000, event.rRules.first.recur.until.time)
assertEquals(Date("20211214"), event.rRules.first.recur.until)
- val event1 = Event.eventsFromReader(StringReader("BEGIN:VCALENDAR\n" +
- "BEGIN:VEVENT\n" +
- "UID:51d8529a-5844-4609-918b-2891b855e0e8\n" +
- "DTSTART;VALUE=DATE:20211115\n" + // DATE
- "RRULE:FREQ=MONTHLY;UNTIL=20211214T235959;BYMONTHDAY=15\n"+ // DATETIME (no timezone)
- "END:VEVENT\n" +
- "END:VCALENDAR")).first()
+ val event1 = Event.eventsFromReader(StringReader(
+ "BEGIN:VCALENDAR\n" +
+ "BEGIN:VEVENT\n" +
+ "UID:51d8529a-5844-4609-918b-2891b855e0e8\n" +
+ "DTSTART;VALUE=DATE:20211115\n" + // DATE
+ "RRULE:FREQ=MONTHLY;UNTIL=20211214T235959;BYMONTHDAY=15\n" + // DATETIME (no timezone)
+ "END:VEVENT\n" +
+ "END:VCALENDAR")).first()
assertEquals(1639440000000, event1.rRules.first.recur.until.time)
assertEquals(Date("20211214"), event1.rRules.first.recur.until)
- val event2 = Event.eventsFromReader(StringReader("BEGIN:VCALENDAR\n" +
- "BEGIN:VEVENT\n" +
- "UID:381fb26b-2da5-4dd2-94d7-2e0874128aa7\n" +
- "DTSTART;VALUE=DATE:20080215\n" + // DATE
- "RRULE:FREQ=YEARLY;UNTIL=20230214T000000Z;BYMONTHDAY=15\n"+ // DATETIME (with timezone)
- "END:VEVENT\n" +
- "END:VCALENDAR")).first()
+ val event2 = Event.eventsFromReader(StringReader(
+ "BEGIN:VCALENDAR\n" +
+ "BEGIN:VEVENT\n" +
+ "UID:381fb26b-2da5-4dd2-94d7-2e0874128aa7\n" +
+ "DTSTART;VALUE=DATE:20080215\n" + // DATE
+ "RRULE:FREQ=YEARLY;UNTIL=20230214T000000Z;BYMONTHDAY=15\n" + // DATETIME (with timezone)
+ "END:VEVENT\n" +
+ "END:VCALENDAR")).first()
assertEquals(Date("20230214"), event2.rRules.first.recur.until)
}
@@ -143,22 +153,24 @@ class EventValidatorTest {
EventValidator.sameTypeForDtStartAndRruleUntil(event.dtStart!!, event.rRules)
assertEquals(DateTime("20211214", tzReg.getTimeZone("UTC")), event.rRules.first.recur.until)
- val event1 = Event.eventsFromReader(StringReader("BEGIN:VCALENDAR\n" +
- "BEGIN:VEVENT\n" +
- "UID:51d8529a-5844-4609-918b-2891b855e0e8\n" +
- "DTSTART;TZID=America/New_York:20211115T000000\n" + // DATETIME (with timezone)
- "RRULE:FREQ=MONTHLY;UNTIL=20211214;BYMONTHDAY=15\n" + // DATE
- "END:VEVENT\n" +
- "END:VCALENDAR")).first()
+ val event1 = Event.eventsFromReader(StringReader(
+ "BEGIN:VCALENDAR\n" +
+ "BEGIN:VEVENT\n" +
+ "UID:51d8529a-5844-4609-918b-2891b855e0e8\n" +
+ "DTSTART;TZID=America/New_York:20211115T000000\n" + // DATETIME (with timezone)
+ "RRULE:FREQ=MONTHLY;UNTIL=20211214;BYMONTHDAY=15\n" + // DATE
+ "END:VEVENT\n" +
+ "END:VCALENDAR")).first()
assertEquals(DateTime("20211214"), event1.rRules.first.recur.until)
- val event2 = Event.eventsFromReader(StringReader("BEGIN:VCALENDAR\n" +
- "BEGIN:VEVENT\n" +
- "UID:381fb26b-2da5-4dd2-94d7-2e0874128aa7\n" +
- "DTSTART;VALUE=DATETIME:20080215T001100\n" + // DATETIME (no timezone)
- "RRULE:FREQ=YEARLY;UNTIL=20230214;BYMONTHDAY=15\n" + // DATE
- "END:VEVENT\n" +
- "END:VCALENDAR")).first()
+ val event2 = Event.eventsFromReader(StringReader(
+ "BEGIN:VCALENDAR\n" +
+ "BEGIN:VEVENT\n" +
+ "UID:381fb26b-2da5-4dd2-94d7-2e0874128aa7\n" +
+ "DTSTART;VALUE=DATETIME:20080215T001100\n" + // DATETIME (no timezone)
+ "RRULE:FREQ=YEARLY;UNTIL=20230214;BYMONTHDAY=15\n" + // DATE
+ "END:VEVENT\n" +
+ "END:VCALENDAR")).first()
assertEquals(DateTime("20230214"), event2.rRules.first.recur.until)
}
@@ -169,9 +181,7 @@ class EventValidatorTest {
fun testHasUntilBeforeDtStart_DtStartTime_RRuleNoUntil() {
assertFalse(
EventValidator.hasUntilBeforeDtStart(
- DtStart(DateTime("20220531T010203")),
- RRule()
- )
+ DtStart(DateTime("20220531T010203")), RRule())
)
}
@@ -180,31 +190,29 @@ class EventValidatorTest {
fun testHasUntilBeforeDtStart_DtStartDate_RRuleUntil_TimeBeforeDtStart() {
assertTrue(
EventValidator.hasUntilBeforeDtStart(DtStart("20220912"), RRule(Recur.Builder()
- .frequency(Recur.Frequency.DAILY)
- .until(DateTime("20220911T235959Z"))
- .build())))
+ .frequency(Recur.Frequency.DAILY)
+ .until(DateTime("20220911T235959Z"))
+ .build()))
+ )
}
@Test
fun testHasUntilBeforeDtStart_DtStartDate_RRuleUntil_DateBeforeDtStart() {
assertTrue(
EventValidator.hasUntilBeforeDtStart(DtStart("20220531"), RRule(Recur.Builder()
- .frequency(Recur.Frequency.DAILY)
- .until(DateTime("20220530"))
- .build())))
+ .frequency(Recur.Frequency.DAILY)
+ .until(DateTime("20220530"))
+ .build()))
+ )
}
@Test
fun testHasUntilBeforeDtStart_DtStartDate_RRuleUntil_TimeAfterDtStart() {
assertFalse(
- EventValidator.hasUntilBeforeDtStart(
- DtStart("20200912"), RRule(
- Recur.Builder()
- .frequency(Recur.Frequency.DAILY)
- .until(DateTime("20220912T000001Z"))
- .build()
- )
- )
+ EventValidator.hasUntilBeforeDtStart(DtStart("20200912"), RRule(Recur.Builder()
+ .frequency(Recur.Frequency.DAILY)
+ .until(DateTime("20220912T000001Z"))
+ .build()))
)
}
@@ -213,45 +221,39 @@ class EventValidatorTest {
fun testHasUntilBeforeDtStart_DtStartTime_RRuleUntil_DateBeforeDtStart() {
assertTrue(
EventValidator.hasUntilBeforeDtStart(DtStart(DateTime("20220531T010203")), RRule(Recur.Builder()
- .frequency(Recur.Frequency.DAILY)
- .until(Date("20220530"))
- .build())))
+ .frequency(Recur.Frequency.DAILY)
+ .until(Date("20220530"))
+ .build()))
+ )
}
@Test
fun testHasUntilBeforeDtStart_DtStartTime_RRuleUntil_TimeBeforeDtStart() {
assertTrue(
EventValidator.hasUntilBeforeDtStart(DtStart(DateTime("20220531T010203")), RRule(Recur.Builder()
- .frequency(Recur.Frequency.DAILY)
- .until(DateTime("20220531T010202"))
- .build())))
+ .frequency(Recur.Frequency.DAILY)
+ .until(DateTime("20220531T010202"))
+ .build()))
+ )
}
@Test
fun testHasUntilBeforeDtStart_DtStartTime_RRuleUntil_TimeAtDtStart() {
assertFalse(
- EventValidator.hasUntilBeforeDtStart(
- DtStart(DateTime("20220531T010203")), RRule(
- Recur.Builder()
- .frequency(Recur.Frequency.DAILY)
- .until(DateTime("20220531T010203"))
- .build()
- )
- )
+ EventValidator.hasUntilBeforeDtStart(DtStart(DateTime("20220531T010203")), RRule(Recur.Builder()
+ .frequency(Recur.Frequency.DAILY)
+ .until(DateTime("20220531T010203"))
+ .build()))
)
}
@Test
fun testHasUntilBeforeDtStart_DtStartTime_RRuleUntil_TimeAfterDtStart() {
assertFalse(
- EventValidator.hasUntilBeforeDtStart(
- DtStart(DateTime("20220531T010203")), RRule(
- Recur.Builder()
- .frequency(Recur.Frequency.DAILY)
- .until(DateTime("20220531T010204"))
- .build()
- )
- )
+ EventValidator.hasUntilBeforeDtStart(DtStart(DateTime("20220531T010203")), RRule(Recur.Builder()
+ .frequency(Recur.Frequency.DAILY)
+ .until(DateTime("20220531T010204"))
+ .build()))
)
}