Skip to content

Commit 5ddf446

Browse files
authored
Add tests for AndroidRecurringCalendar (#139)
* Add signatures for methods to be tested * Add tests for AndroidRecurringCalendar - Rename `testAddEventAndExceptions` to `testAddEventAndExceptions_and_GetById` - Implement `testFindEventAndExceptions` and `testFindEventAndExceptions_NotFound` - Implement `testGetById_NotFound` - Implement `testIterateEventAndExceptions` and `testIterateEventAndExceptions_NotFound` - Add helper function `insertRecurring` to reduce code duplication
1 parent 7dd5224 commit 5ddf446

File tree

2 files changed

+82
-26
lines changed

2 files changed

+82
-26
lines changed

lib/src/androidTest/kotlin/at/bitfire/synctools/storage/calendar/AndroidRecurringCalendarTest.kt

Lines changed: 77 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import org.junit.Assert.assertEquals
3030
import org.junit.Assert.assertNotEquals
3131
import org.junit.Assert.assertNull
3232
import org.junit.Assert.assertTrue
33+
import org.junit.Assert.fail
3334
import org.junit.Before
3435
import org.junit.Rule
3536
import org.junit.Test
@@ -68,32 +69,9 @@ class AndroidRecurringCalendarTest {
6869
// test CRUD
6970

7071
@Test
71-
fun testAddEventAndExceptions() {
72-
val now = 1754233504000 // Sun Aug 03 2025 15:05:04 GMT+0000
73-
val mainEvent = Entity(contentValuesOf(
74-
Events.CALENDAR_ID to calendar.id,
75-
Events._SYNC_ID to "recur1",
76-
Events.DTSTART to now,
77-
Events.EVENT_TIMEZONE to TimeZones.GMT_ID,
78-
Events.DURATION to "PT1H",
79-
Events.TITLE to "Main Event",
80-
Events.RRULE to "FREQ=DAILY;COUNT=3"
81-
))
82-
val event = EventAndExceptions(
83-
main = mainEvent,
84-
exceptions = listOf(
85-
Entity(contentValuesOf(
86-
Events.CALENDAR_ID to calendar.id,
87-
Events.ORIGINAL_SYNC_ID to "recur1",
88-
Events.DTSTART to now + 86400000,
89-
Events.DTEND to now + 86400000 + 2*3600000,
90-
Events.TITLE to "Exception"
91-
))
92-
)
93-
)
94-
72+
fun testAddEventAndExceptions_and_GetById() {
9573
// add event and exceptions
96-
val mainEventId = recurringCalendar.addEventAndExceptions(event)
74+
val (mainEventId, event) = insertRecurring(syncId = "testAddEventAndExceptions_and_GetById")
9775
val addedWithId = event.withId(mainEventId)
9876

9977
// verify that cleanUp was called
@@ -106,6 +84,49 @@ class AndroidRecurringCalendarTest {
10684
assertEventAndExceptionsEqual(addedWithId, event2!!, onlyFieldsInExpected = true)
10785
}
10886

87+
@Test
88+
fun testFindEventAndExceptions() {
89+
val (mainEventId, event) = insertRecurring(syncId = "testFindEventAndExceptions")
90+
val addedWithId = event.withId(mainEventId)
91+
val result = recurringCalendar.findEventAndExceptions("${Events._SYNC_ID}=?", arrayOf("testFindEventAndExceptions"))
92+
assertEventAndExceptionsEqual(addedWithId, result!!, onlyFieldsInExpected = true)
93+
}
94+
95+
@Test
96+
fun testFindEventAndExceptions_NotFound() {
97+
assertNull(recurringCalendar.findEventAndExceptions("${Events._SYNC_ID}=?", arrayOf("not-existent")))
98+
}
99+
100+
@Test
101+
fun testGetById_NotFound() {
102+
// make sure there's no event with id=1
103+
recurringCalendar.deleteEventAndExceptions(1)
104+
105+
assertNull(recurringCalendar.getById(1))
106+
}
107+
108+
@Test
109+
fun testIterateEventAndExceptions() {
110+
val (id1, event1) = insertRecurring(syncId = "testIterateEventAndExceptions1")
111+
val (id2, event2) = insertRecurring(syncId = "testIterateEventAndExceptions2")
112+
val result = mutableListOf<EventAndExceptions>()
113+
recurringCalendar.iterateEventAndExceptions(
114+
"${Events._SYNC_ID} IN (?, ?)",
115+
arrayOf("testIterateEventAndExceptions1", "testIterateEventAndExceptions2")
116+
) { result += it }
117+
val orderedResult = result.sortedBy { it.main.entityValues.getAsInteger(Events._ID) }
118+
assertEquals(2, orderedResult.size)
119+
assertEventAndExceptionsEqual(event1.withId(id1), orderedResult[0], onlyFieldsInExpected = true)
120+
assertEventAndExceptionsEqual(event2.withId(id2), orderedResult[1], onlyFieldsInExpected = true)
121+
}
122+
123+
@Test
124+
fun testIterateEventAndExceptions_NotFound() {
125+
recurringCalendar.iterateEventAndExceptions("${Events._SYNC_ID}=?", arrayOf("not-existent")) {
126+
fail("must not be called")
127+
}
128+
}
129+
109130
@Test
110131
fun testUpdateEventAndExceptions_NoRebuild() {
111132
// Create initial event
@@ -342,7 +363,7 @@ class AndroidRecurringCalendarTest {
342363
}
343364

344365

345-
// test helpers for dirty/deleted events and exceptions
366+
// test processing dirty/deleted events and exceptions
346367

347368
@Test
348369
fun testProcessDeletedExceptions() {
@@ -450,4 +471,34 @@ class AndroidRecurringCalendarTest {
450471
)
451472
}
452473

474+
475+
// helpers
476+
477+
private fun insertRecurring(syncId: String): Pair<Long, EventAndExceptions> {
478+
val now = 1754233504000 // Sun Aug 03 2025 15:05:04 GMT+0000
479+
val mainEvent = Entity(contentValuesOf(
480+
Events.CALENDAR_ID to calendar.id,
481+
Events._SYNC_ID to syncId,
482+
Events.DTSTART to now,
483+
Events.EVENT_TIMEZONE to TimeZones.GMT_ID,
484+
Events.DURATION to "PT1H",
485+
Events.TITLE to "Main Event",
486+
Events.RRULE to "FREQ=DAILY;COUNT=3"
487+
))
488+
val event = EventAndExceptions(
489+
main = mainEvent,
490+
exceptions = listOf(
491+
Entity(contentValuesOf(
492+
Events.CALENDAR_ID to calendar.id,
493+
Events.ORIGINAL_SYNC_ID to syncId,
494+
Events.DTSTART to now + 86400000,
495+
Events.DTEND to now + 86400000 + 2*3600000,
496+
Events.TITLE to "Exception"
497+
))
498+
)
499+
)
500+
val id = recurringCalendar.addEventAndExceptions(event)
501+
return id to event
502+
}
503+
453504
}

lib/src/main/kotlin/at/bitfire/synctools/storage/calendar/AndroidRecurringCalendar.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ class AndroidRecurringCalendar(
4545
/**
4646
* Inserts an event and all its exceptions. Input data is first cleaned up using [cleanUp].
4747
*
48+
* If you want to insert exceptions, [Events._SYNC_ID] must be set on the main
49+
* event and [Events.ORIGINAL_SYNC_ID] should be set to the same value for the
50+
* exception events. **It's not enough to just set [Events.ORIGINAL_ID] in the
51+
* exceptions**.
52+
*
4853
* @param eventAndExceptions event and exceptions to insert
4954
*
5055
* @return ID of the resulting main event

0 commit comments

Comments
 (0)