diff --git a/lib/src/main/kotlin/at/bitfire/synctools/mapping/tasks/DmfsTaskBuilder.kt b/lib/src/main/kotlin/at/bitfire/synctools/mapping/tasks/DmfsTaskBuilder.kt index 5a059b3c..9e0b548d 100644 --- a/lib/src/main/kotlin/at/bitfire/synctools/mapping/tasks/DmfsTaskBuilder.kt +++ b/lib/src/main/kotlin/at/bitfire/synctools/mapping/tasks/DmfsTaskBuilder.kt @@ -6,10 +6,14 @@ package at.bitfire.synctools.mapping.tasks +import android.content.ContentValues +import android.content.Entity import at.bitfire.ical4android.ICalendar import at.bitfire.ical4android.Task import at.bitfire.ical4android.UnknownProperty import at.bitfire.synctools.icalendar.DatePropertyTzMapper.normalizedDate +import at.bitfire.synctools.mapping.tasks.builder.DmfsTaskFieldBuilder +import at.bitfire.synctools.mapping.tasks.builder.TitleBuilder import at.bitfire.synctools.storage.BatchOperation.CpoBuilder import at.bitfire.synctools.storage.tasks.DmfsTask.Companion.COLUMN_ETAG import at.bitfire.synctools.storage.tasks.DmfsTask.Companion.COLUMN_FLAGS @@ -60,6 +64,10 @@ class DmfsTaskBuilder( private val flags: Int, ) { + private val fieldBuilders: Array = arrayOf( + TitleBuilder() + ) + private val logger get() = Logger.getLogger(javaClass.name) @@ -84,10 +92,18 @@ class DmfsTaskBuilder( if (!update) builder .withValue(Tasks.LIST_ID, taskList.id) + // new builders + + val entity = Entity(ContentValues()) + for (fieldBuilder in fieldBuilders) + fieldBuilder.build(task, entity) + builder.withValues(entity.entityValues) + + // old builders + builder .withValue(Tasks._UID, task.uid) .withValue(Tasks._DIRTY, 0) .withValue(Tasks.SYNC_VERSION, task.sequence) - .withValue(Tasks.TITLE, task.summary) .withValue(Tasks.LOCATION, task.location) .withValue(Tasks.GEO, task.geoPosition?.let { "${it.longitude},${it.latitude}" }) .withValue(Tasks.DESCRIPTION, task.description) diff --git a/lib/src/main/kotlin/at/bitfire/synctools/mapping/tasks/builder/DmfsTaskFieldBuilder.kt b/lib/src/main/kotlin/at/bitfire/synctools/mapping/tasks/builder/DmfsTaskFieldBuilder.kt new file mode 100644 index 00000000..08a11100 --- /dev/null +++ b/lib/src/main/kotlin/at/bitfire/synctools/mapping/tasks/builder/DmfsTaskFieldBuilder.kt @@ -0,0 +1,26 @@ +/* + * This file is part of bitfireAT/synctools which is released under GPLv3. + * Copyright © All Contributors. See the LICENSE and AUTHOR files in the root directory for details. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package at.bitfire.synctools.mapping.tasks.builder + +import android.content.Entity +import at.bitfire.ical4android.Task + +interface DmfsTaskFieldBuilder { + + /** + * Maps a specific part of the given task into the provided [Entity]. + * + * Note: The result of the mapping is used to either create or update the task row in the + * content provider. For updates, explicit `null` values are required for fields that should + * be `null` (otherwise the value wouldn't be updated to `null` in case of a task update). + * + * @param from task to map + * @param to destination [Entity] where built values are stored (set `null` values, see note) + */ + fun build(from: Task, to: Entity) + +} diff --git a/lib/src/main/kotlin/at/bitfire/synctools/mapping/tasks/builder/TitleBuilder.kt b/lib/src/main/kotlin/at/bitfire/synctools/mapping/tasks/builder/TitleBuilder.kt new file mode 100644 index 00000000..5f3107f4 --- /dev/null +++ b/lib/src/main/kotlin/at/bitfire/synctools/mapping/tasks/builder/TitleBuilder.kt @@ -0,0 +1,20 @@ +/* + * This file is part of bitfireAT/synctools which is released under GPLv3. + * Copyright © All Contributors. See the LICENSE and AUTHOR files in the root directory for details. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package at.bitfire.synctools.mapping.tasks.builder + +import android.content.Entity +import at.bitfire.ical4android.Task +import at.bitfire.vcard4android.Utils.trimToNull +import org.dmfs.tasks.contract.TaskContract.Tasks + +class TitleBuilder : DmfsTaskFieldBuilder { + + override fun build(from: Task, to: Entity) { + to.entityValues.put(Tasks.TITLE, from.summary.trimToNull()) + } + +} diff --git a/lib/src/test/kotlin/at/bitfire/synctools/mapping/tasks/builder/TitleBuilderTest.kt b/lib/src/test/kotlin/at/bitfire/synctools/mapping/tasks/builder/TitleBuilderTest.kt new file mode 100644 index 00000000..f9e6e961 --- /dev/null +++ b/lib/src/test/kotlin/at/bitfire/synctools/mapping/tasks/builder/TitleBuilderTest.kt @@ -0,0 +1,57 @@ +/* + * This file is part of bitfireAT/synctools which is released under GPLv3. + * Copyright © All Contributors. See the LICENSE and AUTHOR files in the root directory for details. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package at.bitfire.synctools.mapping.tasks.builder + +import android.content.ContentValues +import android.content.Entity +import at.bitfire.ical4android.Task +import org.dmfs.tasks.contract.TaskContract.Tasks +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class TitleBuilderTest { + + private val builder = TitleBuilder() + + @Test + fun `No SUMMARY`() { + val result = Entity(ContentValues()) + builder.build( + from = Task(), + to = result + ) + assertTrue(result.entityValues.containsKey(Tasks.TITLE)) + assertNull(result.entityValues.get(Tasks.TITLE)) + } + + @Test + fun `SUMMARY is blank`() { + val result = Entity(ContentValues()) + builder.build( + from = Task(summary = ""), + to = result + ) + assertTrue(result.entityValues.containsKey(Tasks.TITLE)) + assertNull(result.entityValues.get(Tasks.TITLE)) + } + + @Test + fun `SUMMARY is text`() { + val result = Entity(ContentValues()) + builder.build( + from = Task(summary = "Task Summary"), + to = result + ) + assertEquals("Task Summary", result.entityValues.getAsString(Tasks.TITLE)) + } + +}