summaryrefslogtreecommitdiff
path: root/android/app/src/test
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-07-13 18:26:46 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-07-16 02:43:18 +0000
commit3ccb4eb45ff0f2a0314c36dc530d5118b59a35fd (patch)
tree24e2f670b030433f67cf7e555d3d1a2055e944fd /android/app/src/test
parentca4c0ea6bcb791cd40d4684376ec2ac6f1a08c53 (diff)
feat(widget): show multi-day calendar events on every day they span
Multi-day events (Start and End on different calendar days) are pulled out of the normal grid/all-day pipeline and rendered as an all-day-style row on every day they touch (Today and/or Tomorrow), labeled starts/ends/plain per the day being rendered. Previously such an event either only appeared in the single hourly grid slot matching its start time (never again on later days) or, if genuinely flagged all-day, never had its End forwarded at all.
Diffstat (limited to 'android/app/src/test')
-rw-r--r--android/app/src/test/java/org/terst/doot/widget/ui/DootWidgetMultiDayTest.kt86
1 files changed, 86 insertions, 0 deletions
diff --git a/android/app/src/test/java/org/terst/doot/widget/ui/DootWidgetMultiDayTest.kt b/android/app/src/test/java/org/terst/doot/widget/ui/DootWidgetMultiDayTest.kt
new file mode 100644
index 0000000..2b6451f
--- /dev/null
+++ b/android/app/src/test/java/org/terst/doot/widget/ui/DootWidgetMultiDayTest.kt
@@ -0,0 +1,86 @@
+package org.terst.doot.widget.ui
+
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.terst.doot.widget.data.WidgetItem
+import java.time.LocalDate
+import java.time.ZoneId
+
+class DootWidgetMultiDayTest {
+ private val zone: ZoneId = ZoneId.of("UTC")
+
+ private fun event(start: String, end: String, isAllDay: Boolean = false): WidgetItem = WidgetItem(
+ id = "e1", title = "Event", source = "calendar", type = "event",
+ start = start, end = end, isAllDay = isAllDay
+ )
+
+ @Test
+ fun `isMultiDayEvent is false for a same-day timed event`() {
+ assertFalse(isMultiDayEvent(event("2026-07-13T10:00:00Z", "2026-07-13T11:00:00Z"), zone))
+ }
+
+ @Test
+ fun `isMultiDayEvent is true when start and end fall on different calendar days`() {
+ assertTrue(isMultiDayEvent(event("2026-07-13T17:35:00Z", "2026-07-30T22:30:00Z"), zone))
+ }
+
+ @Test
+ fun `isMultiDayEvent is true for a genuine all-day multi-day event`() {
+ assertTrue(isMultiDayEvent(event("2026-07-13T00:00:00Z", "2026-07-15T00:00:00Z", isAllDay = true), zone))
+ }
+
+ @Test
+ fun `isMultiDayEvent is false for non-event types`() {
+ val task = WidgetItem(
+ id = "t1", title = "Task", source = "doot", type = "task",
+ start = "2026-07-13T10:00:00Z", end = "2026-07-30T22:30:00Z"
+ )
+ assertFalse(isMultiDayEvent(task, zone))
+ }
+
+ @Test
+ fun `multiDayVariant returns STARTS on the event's start day`() {
+ val item = event("2026-07-13T17:35:00Z", "2026-07-30T22:30:00Z")
+ assertEquals(MultiDayVariant.STARTS, multiDayVariant(item, LocalDate.of(2026, 7, 13), zone))
+ }
+
+ @Test
+ fun `multiDayVariant returns ENDS on the event's end day`() {
+ val item = event("2026-07-13T17:35:00Z", "2026-07-30T22:30:00Z")
+ assertEquals(MultiDayVariant.ENDS, multiDayVariant(item, LocalDate.of(2026, 7, 30), zone))
+ }
+
+ @Test
+ fun `multiDayVariant returns SPANS on a day strictly between start and end`() {
+ val item = event("2026-07-13T17:35:00Z", "2026-07-30T22:30:00Z")
+ assertEquals(MultiDayVariant.SPANS, multiDayVariant(item, LocalDate.of(2026, 7, 20), zone))
+ }
+
+ @Test
+ fun `multiDayVariant returns NONE for a day outside the event's span`() {
+ val item = event("2026-07-13T17:35:00Z", "2026-07-30T22:30:00Z")
+ assertEquals(MultiDayVariant.NONE, multiDayVariant(item, LocalDate.of(2026, 8, 1), zone))
+ }
+
+ @Test
+ fun `isMultiDayEvent is false for a single-day all-day event (exclusive end-date)`() {
+ // Google Calendar's all-day End is EXCLUSIVE: a single-day all-day event on
+ // July 13 has start=Jul13 00:00, end=Jul14 00:00 (one day past its own day).
+ assertFalse(isMultiDayEvent(event("2026-07-13T00:00:00Z", "2026-07-14T00:00:00Z", isAllDay = true), zone))
+ }
+
+ @Test
+ fun `isMultiDayEvent is true for a 3-day all-day event`() {
+ // 3-day all-day event (Jul 13-15 inclusive) has end=Jul16 00:00 (exclusive).
+ assertTrue(isMultiDayEvent(event("2026-07-13T00:00:00Z", "2026-07-16T00:00:00Z", isAllDay = true), zone))
+ }
+
+ @Test
+ fun `multiDayVariant reports ENDS on the real last day of a multi-day all-day event, not the exclusive end date`() {
+ val item = event("2026-07-13T00:00:00Z", "2026-07-16T00:00:00Z", isAllDay = true)
+ assertEquals(MultiDayVariant.ENDS, multiDayVariant(item, LocalDate.of(2026, 7, 15), zone))
+ assertEquals(MultiDayVariant.NONE, multiDayVariant(item, LocalDate.of(2026, 7, 16), zone))
+ }
+}