Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ package at.bitfire.synctools.mapping.jtx
import android.content.ContentValues
import android.content.Entity
import at.bitfire.synctools.icalendar.AssociatedComponents
import at.bitfire.synctools.mapping.jtx.builder.CategoriesBuilder
import at.bitfire.synctools.mapping.jtx.builder.CollectionIdBuilder
import at.bitfire.synctools.mapping.jtx.builder.CommentsBuilder
import at.bitfire.synctools.mapping.jtx.builder.DescriptionBuilder
import at.bitfire.synctools.mapping.jtx.builder.JtxEntityBuilder
import at.bitfire.synctools.mapping.jtx.builder.RecurrenceFieldsBuilder
import at.bitfire.synctools.mapping.jtx.builder.RemindersBuilder
import at.bitfire.synctools.mapping.jtx.builder.ResourcesBuilder
import at.bitfire.synctools.mapping.jtx.builder.SyncPropertiesBuilder
import at.bitfire.synctools.mapping.jtx.builder.TimeFieldsBuilder
import at.bitfire.synctools.storage.jtx.JtxObjectAndExceptions
Expand All @@ -39,7 +42,10 @@ class JtxObjectBuilder(
DescriptionBuilder(),
RecurrenceFieldsBuilder(),
TimeFieldsBuilder(),
RemindersBuilder()
RemindersBuilder(),
CategoriesBuilder(),
CommentsBuilder(),
ResourcesBuilder()
)

fun build(component: AssociatedComponents<CalendarComponent>): JtxObjectAndExceptions {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.jtx.builder

import android.content.Entity
import androidx.core.content.contentValuesOf
import at.techbee.jtx.JtxContract
import net.fortuna.ical4j.model.Property
import net.fortuna.ical4j.model.component.CalendarComponent
import net.fortuna.ical4j.model.property.Categories

class CategoriesBuilder : JtxEntityBuilder {
override fun build(from: CalendarComponent, main: CalendarComponent, to: Entity) {
for (categories in from.getProperties<Categories>(Property.CATEGORIES)) {
for (category in categories.categories.texts) {
to.addSubValue(
JtxContract.JtxCategory.CONTENT_URI,
contentValuesOf(
JtxContract.JtxCategory.TEXT to category,

// Note: Currently not supported
JtxContract.JtxCategory.ID to 0L,
JtxContract.JtxCategory.LANGUAGE to null,
JtxContract.JtxCategory.OTHER to null
)
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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.jtx.builder

import android.content.Entity
import androidx.core.content.contentValuesOf
import at.techbee.jtx.JtxContract
import net.fortuna.ical4j.model.Parameter
import net.fortuna.ical4j.model.Property
import net.fortuna.ical4j.model.component.CalendarComponent
import net.fortuna.ical4j.model.parameter.AltRep
import net.fortuna.ical4j.model.parameter.Language
import net.fortuna.ical4j.model.property.Comment
import kotlin.jvm.optionals.getOrNull

class CommentsBuilder : JtxEntityBuilder {
override fun build(from: CalendarComponent, main: CalendarComponent, to: Entity) {
for (comment in from.getProperties<Comment>(Property.COMMENT)) {
val text = comment.value
val language = comment.getParameter<Language>(Parameter.LANGUAGE).getOrNull()?.value
val altRep = comment.getParameter<AltRep>(Parameter.ALTREP).getOrNull()?.value

val otherParameters = comment.parameterList.removeAll(
Parameter.LANGUAGE,
Parameter.ALTREP
)
val others = JtxContract.getJsonStringFromXParameters(otherParameters)

to.addSubValue(
JtxContract.JtxComment.CONTENT_URI,
contentValuesOf(
JtxContract.JtxComment.TEXT to text,
JtxContract.JtxComment.ALTREP to altRep,
JtxContract.JtxComment.LANGUAGE to language,
JtxContract.JtxComment.OTHER to others,
JtxContract.JtxComment.ID to 0L
)
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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.jtx.builder

import android.content.Entity
import androidx.core.content.contentValuesOf
import at.techbee.jtx.JtxContract
import net.fortuna.ical4j.model.Property
import net.fortuna.ical4j.model.component.CalendarComponent
import net.fortuna.ical4j.model.component.VJournal
import net.fortuna.ical4j.model.property.Resources

class ResourcesBuilder : JtxEntityBuilder {
override fun build(from: CalendarComponent, main: CalendarComponent, to: Entity) {
if (from is VJournal) {
// VJOURNAL doesn't support the RESOURCES property
return
}

for (resources in from.getProperties<Resources>(Property.RESOURCES)) {
for (resource in resources.resources.texts) {
to.addSubValue(
JtxContract.JtxResource.CONTENT_URI,
contentValuesOf(
JtxContract.JtxResource.TEXT to resource,

// Note: Currently not supported
JtxContract.JtxResource.ID to 0L,
JtxContract.JtxResource.LANGUAGE to null,
JtxContract.JtxResource.OTHER to null
)
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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.jtx.builder

import android.content.ContentValues
import android.content.Entity
import at.bitfire.synctools.icalendar.plusAssign
import at.techbee.jtx.JtxContract
import net.fortuna.ical4j.model.TextList
import net.fortuna.ical4j.model.component.VJournal
import net.fortuna.ical4j.model.property.Categories
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner

@RunWith(RobolectricTestRunner::class)
class CategoriesBuilderTest {

private val builder = CategoriesBuilder()

@Test
fun happyPath() {
val output = Entity(ContentValues())
val journal = VJournal().apply {
this += Categories(TextList("one", "two"))
}

builder.build(from = journal, main = journal, output)

assertEquals(2, output.subValues.size)
val first = output.subValues[0]
assertEquals(JtxContract.JtxCategory.CONTENT_URI, first.uri)
assertEquals("one", first.values.getAsString(JtxContract.JtxCategory.TEXT))
val second = output.subValues[1]
assertEquals(JtxContract.JtxCategory.CONTENT_URI, second.uri)
assertEquals("two", second.values.getAsString(JtxContract.JtxCategory.TEXT))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* 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.jtx.builder

import android.content.ContentValues
import android.content.Entity
import androidx.core.content.contentValuesOf
import at.bitfire.synctools.icalendar.plusAssign
import at.bitfire.synctools.test.assertContentValuesEqual
import at.techbee.jtx.JtxContract
import net.fortuna.ical4j.model.ParameterList
import net.fortuna.ical4j.model.component.VJournal
import net.fortuna.ical4j.model.component.VToDo
import net.fortuna.ical4j.model.parameter.AltRep
import net.fortuna.ical4j.model.parameter.Language
import net.fortuna.ical4j.model.parameter.XParameter
import net.fortuna.ical4j.model.property.Comment
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import java.net.URI

@RunWith(RobolectricTestRunner::class)
class CommentsBuilderTest {
private val builder = CommentsBuilder()

@Test
fun `no comment`() {
val output = Entity(ContentValues())
val journal = VJournal()

builder.build(from = journal, main = journal, output)

assertEquals(0, output.subValues.size)
}

@Test
fun `single comment`() {
val output = Entity(ContentValues())
val task = VToDo().apply {
this += Comment(
ParameterList(
listOf(
Language("en"),
AltRep(URI.create("https://domain.example/comment.txt")),
XParameter("X-PARAM", "x-value")
)
),
"comment"
)
}

builder.build(from = task, main = task, output)

assertEquals(1, output.subValues.size)
val subValue = output.subValues.first()
assertEquals(JtxContract.JtxComment.CONTENT_URI, subValue.uri)
assertContentValuesEqual(
expected = contentValuesOf(
JtxContract.JtxComment.TEXT to "comment",
JtxContract.JtxComment.ALTREP to "https://domain.example/comment.txt",
JtxContract.JtxComment.LANGUAGE to "en",
JtxContract.JtxComment.OTHER to """{"X-PARAM":"x-value"}""",
JtxContract.JtxComment.ID to 0L
),
actual = subValue.values
)
}

@Test
fun `multiple comments`() {
val output = Entity(ContentValues())
val task = VToDo().apply {
this += Comment("one")
this += Comment("two")
}

builder.build(from = task, main = task, output)

assertEquals(2, output.subValues.size)
val first = output.subValues[0]
assertEquals(JtxContract.JtxComment.CONTENT_URI, first.uri)
assertEquals("one", first.values.getAsString(JtxContract.JtxComment.TEXT))
val second = output.subValues[1]
assertEquals(JtxContract.JtxComment.CONTENT_URI, second.uri)
assertEquals("two", second.values.getAsString(JtxContract.JtxComment.TEXT))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* 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.jtx.builder

import android.content.ContentValues
import android.content.Entity
import androidx.core.content.contentValuesOf
import at.bitfire.synctools.icalendar.plusAssign
import at.bitfire.synctools.test.assertContentValuesEqual
import at.techbee.jtx.JtxContract
import net.fortuna.ical4j.model.component.VJournal
import net.fortuna.ical4j.model.component.VToDo
import net.fortuna.ical4j.model.property.Resources
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner

@RunWith(RobolectricTestRunner::class)
class ResourcesBuilderTest {

private val builder = ResourcesBuilder()

@Test
fun `VTODO without resources`() {
val output = Entity(ContentValues())
val journal = VToDo()

builder.build(from = journal, main = journal, output)

assertEquals(0, output.subValues.size)
}

@Test
fun `VTODO with single resource`() {
val output = Entity(ContentValues())
val journal = VToDo().apply {
this += Resources("resource")
}

builder.build(from = journal, main = journal, output)

assertEquals(1, output.subValues.size)
val subValue = output.subValues.first()
assertEquals(JtxContract.JtxResource.CONTENT_URI, subValue.uri)
assertContentValuesEqual(
expected = contentValuesOf(
JtxContract.JtxResource.TEXT to "resource",
JtxContract.JtxResource.ID to 0L,
JtxContract.JtxResource.LANGUAGE to null,
JtxContract.JtxResource.OTHER to null
),
actual = subValue.values
)
}

@Test
fun `VTODO with multiple resources`() {
val output = Entity(ContentValues())
val journal = VToDo().apply {
this += Resources(listOf("one", "two"))
this += Resources("three")
}

builder.build(from = journal, main = journal, output)

assertEquals(3, output.subValues.size)
val first = output.subValues[0]
assertEquals(JtxContract.JtxResource.CONTENT_URI, first.uri)
assertEquals("one", first.values.getAsString(JtxContract.JtxResource.TEXT))
val second = output.subValues[1]
assertEquals(JtxContract.JtxResource.CONTENT_URI, second.uri)
assertEquals("two", second.values.getAsString(JtxContract.JtxResource.TEXT))
val third = output.subValues[2]
assertEquals(JtxContract.JtxResource.CONTENT_URI, third.uri)
assertEquals("three", third.values.getAsString(JtxContract.JtxResource.TEXT))
}

@Test
fun `VJOURNAL should ignore RESOURCES properties`() {
val output = Entity(ContentValues())
val journal = VJournal().apply {
this += Resources(listOf("one", "two"))
}

builder.build(from = journal, main = journal, output)

assertEquals(0, output.subValues.size)
}
}
Loading