Add alarm tests

pull/1768/head
Alex Baker 2 years ago
parent 65e05b85b8
commit 00bc23c0dd

@ -0,0 +1,76 @@
package org.tasks.caldav.extensions
import at.bitfire.ical4android.util.TimeApiExtensions.toDuration
import net.fortuna.ical4j.model.ParameterList
import net.fortuna.ical4j.model.component.VAlarm
import net.fortuna.ical4j.model.parameter.Related
import net.fortuna.ical4j.model.property.Action
import net.fortuna.ical4j.model.property.Description
import net.fortuna.ical4j.model.property.Repeat
import net.fortuna.ical4j.model.property.Trigger
import org.tasks.caldav.iCalendar
import org.tasks.caldav.iCalendar.Companion.getDateTime
import org.tasks.data.Alarm
import java.time.Duration
import java.time.Instant
import java.time.temporal.TemporalAmount
fun List<Alarm>.toVAlarms(): List<VAlarm> = mapNotNull(Alarm::toVAlarm)
internal fun Alarm.toVAlarm(): VAlarm? {
val trigger = when (type) {
Alarm.TYPE_DATE_TIME ->
Trigger(getDateTime(time))
Alarm.TYPE_REL_START,
Alarm.TYPE_REL_END ->
Trigger(
ParameterList().apply {
add(if (type == Alarm.TYPE_REL_END) Related.END else Related.START)
},
Duration.ofMillis(time)
)
else ->
return null
}
return VAlarm().also {
with(it.properties) {
add(trigger)
add(Action.DISPLAY)
add(Description("Default Tasks.org description"))
if (repeat > 0) {
add(Repeat(repeat))
add(
net.fortuna.ical4j.model.property.Duration(
Duration.ofMillis(interval)
)
)
}
}
}
}
fun List<VAlarm>.toAlarms(): List<Alarm> = mapNotNull(VAlarm::toAlarm)
internal fun VAlarm.toAlarm(): Alarm? {
val (type, time) = when {
trigger.date != null ->
Pair(Alarm.TYPE_DATE_TIME, iCalendar.getLocal(trigger))
trigger.duration != null ->
Pair(
if (trigger.parameters.getParameter<Related>(Related.RELATED) == Related.END) {
Alarm.TYPE_REL_END
} else {
Alarm.TYPE_REL_START
},
trigger.duration.toMillis()
)
else ->
return null
}
return Alarm(0L, time, type, repeat?.count ?: 0, duration?.toMillis() ?: 0)
}
private fun net.fortuna.ical4j.model.property.Duration.toMillis() = duration.toMillis()
private fun TemporalAmount.toMillis() = toDuration(Instant.EPOCH).toSeconds() * 1_000

@ -36,6 +36,8 @@ import org.tasks.Strings.isNullOrEmpty
import org.tasks.caldav.GeoUtils.equalish
import org.tasks.caldav.GeoUtils.toGeo
import org.tasks.caldav.GeoUtils.toLikeString
import org.tasks.caldav.extensions.toAlarms
import org.tasks.caldav.extensions.toVAlarms
import org.tasks.data.Alarm
import org.tasks.data.Alarm.Companion.TYPE_DATE_TIME
import org.tasks.data.Alarm.Companion.TYPE_REL_END
@ -170,41 +172,7 @@ class iCalendar @Inject constructor(
remoteModel.geoPosition = localGeo
}
remoteModel.alarms.removeAll(remoteModel.alarms.filtered)
remoteModel.alarms.addAll(
alarmDao
.getAlarms(task.id)
.mapNotNull {
val trigger = when (it.type) {
TYPE_DATE_TIME ->
Trigger(getDateTime(it.time))
TYPE_REL_START,
TYPE_REL_END ->
Trigger(
ParameterList().apply {
add(if (it.type == TYPE_REL_END) END else START)
},
Duration.ofMillis(it.time)
)
else -> return@mapNotNull null
}
VAlarm().apply {
with(properties) {
add(trigger)
add(Action.DISPLAY)
add(Description("Default Tasks.org description"))
if (it.repeat > 0) {
add(Repeat(it.repeat))
add(
net.fortuna.ical4j.model.property.Duration(
Duration.ofMillis(it.interval)
)
)
}
}
}
}
)
remoteModel.alarms.addAll(alarmDao.getAlarms(task.id).toVAlarms())
}
suspend fun fromVtodo(
@ -281,7 +249,7 @@ class iCalendar @Inject constructor(
}
}
private fun getLocal(property: DateProperty): Long =
internal fun getLocal(property: DateProperty): Long =
org.tasks.time.DateTime.from(property.date)?.toLocal()?.millis ?: 0
fun fromVtodo(vtodo: String): Task? {
@ -465,35 +433,13 @@ class iCalendar @Inject constructor(
.filterNot { it.trigger.dateTime == IGNORE_ALARM }
val Task.reminders: List<Alarm>
get() = alarms.filtered.mapNotNull {
val (type, time) = when {
it.trigger.date != null ->
Pair(TYPE_DATE_TIME, getLocal(it.trigger))
it.trigger.duration != null ->
Pair(
if (it.trigger.parameters.getParameter<Related>(RELATED) == END) {
TYPE_REL_END
} else {
TYPE_REL_START
},
it.trigger.duration.toMillis()
)
else -> return@mapNotNull null
}
Alarm(0L, time, type, it.repeat?.count ?: 0, it.duration?.toMillis() ?: 0)
}
get() = alarms.filtered.toAlarms()
private fun getDateTime(timestamp: Long): DateTime {
internal fun getDateTime(timestamp: Long): DateTime {
val tz = ical4jTimeZone(TimeZone.getDefault().id)
val dateTime = DateTime(if (tz != null) timestamp else org.tasks.time.DateTime(timestamp).toUTC().millis)
dateTime.timeZone = tz
return dateTime
}
private fun net.fortuna.ical4j.model.property.Duration.toMillis() =
duration.toMillis()
private fun TemporalAmount.toMillis(): Long =
toDuration(Instant.EPOCH).toSeconds() * 1_000
}
}

@ -0,0 +1,110 @@
package org.tasks.caldav.extensions
import org.junit.Assert.assertEquals
import org.junit.Test
import org.tasks.data.Alarm
import org.tasks.data.Alarm.Companion.TYPE_DATE_TIME
import org.tasks.data.Alarm.Companion.TYPE_REL_END
import org.tasks.data.Alarm.Companion.TYPE_REL_START
import org.tasks.time.DateTime
import org.tasks.time.DateTime.UTC
import java.util.concurrent.TimeUnit.HOURS
import java.util.concurrent.TimeUnit.MINUTES
class VAlarmTests {
@Test
fun dateTimeToVAlarm() {
assertEquals(
"BEGIN:VALARM\r\nTRIGGER;VALUE=DATE-TIME:20220121T190000Z\r\nACTION:DISPLAY\r\nDESCRIPTION:Default Tasks.org description\r\nEND:VALARM\r\n",
Alarm(
0,
DateTime(2022, 1, 21, 19, 0, 0, 0, UTC).millis,
TYPE_DATE_TIME,
0,
0
).toVAlarm().toString()
)
}
@Test
fun dateTimeFromAlarm() {
val alarm = Alarm(
0,
DateTime(2022, 1, 21, 19, 0, 0, 0, UTC).millis,
TYPE_DATE_TIME,
0,
0
)
assertEquals(alarm, alarm.toVAlarm()?.toAlarm())
}
@Test
fun beforeStartToVAlarm() {
assertEquals(
"BEGIN:VALARM\r\nTRIGGER;RELATED=START:-PT1H15M\r\nACTION:DISPLAY\r\nDESCRIPTION:Default Tasks.org description\r\nEND:VALARM\r\n",
Alarm(0, -MINUTES.toMillis(75), TYPE_REL_START, 0, 0).toVAlarm().toString()
)
}
@Test
fun beforeStartFromAlarm() {
val alarm = Alarm(0, -MINUTES.toMillis(75), TYPE_REL_START, 0, 0)
assertEquals(alarm, alarm.toVAlarm()?.toAlarm())
}
@Test
fun afterStartToVAlarm() {
assertEquals(
"BEGIN:VALARM\r\nTRIGGER;RELATED=START:PT1H15M\r\nACTION:DISPLAY\r\nDESCRIPTION:Default Tasks.org description\r\nEND:VALARM\r\n",
Alarm(0, MINUTES.toMillis(75), TYPE_REL_START, 0, 0).toVAlarm().toString()
)
}
@Test
fun afterStartFromAlarm() {
val alarm = Alarm(0, MINUTES.toMillis(75), TYPE_REL_START, 0, 0)
assertEquals(alarm, alarm.toVAlarm()?.toAlarm())
}
@Test
fun beforeEndToVAlarm() {
assertEquals(
"BEGIN:VALARM\r\nTRIGGER;RELATED=END:-PT1H15M\r\nACTION:DISPLAY\r\nDESCRIPTION:Default Tasks.org description\r\nEND:VALARM\r\n",
Alarm(0, -MINUTES.toMillis(75), TYPE_REL_END, 0, 0).toVAlarm().toString()
)
}
@Test
fun beforeEndFromAlarm() {
val alarm = Alarm(0, -MINUTES.toMillis(75), TYPE_REL_END, 0, 0)
assertEquals(alarm, alarm.toVAlarm()?.toAlarm())
}
@Test
fun afterEndToVAlarm() {
assertEquals(
"BEGIN:VALARM\r\nTRIGGER;RELATED=END:PT1H15M\r\nACTION:DISPLAY\r\nDESCRIPTION:Default Tasks.org description\r\nEND:VALARM\r\n",
Alarm(0, MINUTES.toMillis(75), TYPE_REL_END, 0, 0).toVAlarm().toString()
)
}
@Test
fun afterEndFromAlarm() {
val alarm = Alarm(0, MINUTES.toMillis(75), TYPE_REL_END, 0, 0)
assertEquals(alarm, alarm.toVAlarm()?.toAlarm())
}
@Test
fun repeatingAlarm() {
assertEquals(
"BEGIN:VALARM\r\nTRIGGER;RELATED=START:P1DT8H\r\nACTION:DISPLAY\r\nDESCRIPTION:Default Tasks.org description\r\nREPEAT:15\r\nDURATION:PT15M\r\nEND:VALARM\r\n",
Alarm(0, HOURS.toMillis(32), TYPE_REL_START, 15, MINUTES.toMillis(15)).toVAlarm().toString()
)
}
@Test
fun repeatingFromAlarm() {
val alarm = Alarm(0, HOURS.toMillis(32), TYPE_REL_START, 15, MINUTES.toMillis(15))
assertEquals(alarm, alarm.toVAlarm()?.toAlarm())
}
}
Loading…
Cancel
Save