Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 0ccd9d5e authored by Ricki Hirner's avatar Ricki Hirner Committed by GitHub
Browse files

Update synctools for events as `Entity` and `EventAndExceptions` (#1605)

* [WIP] Refactor LocalResource interface and implementations to use immutable properties and add deleteLocal method

* Use `Optional` for `fileName` in `clearDirty` methods, update syncManagers

* Update synctools

* Refactor LocalCalendar to use AndroidRecurringCalendar for event operations

* Use AndroidCalendar.findEvent

* Update SyncManager to process fileName, eTag, scheduleTag and flags

* SyncManager: make ETag and Schedule-Tag processing more understandable

* Make upload handling more clear

* Update synctools
parent 438f9671
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import org.junit.Rule
import org.junit.Test
import java.io.FileNotFoundException
import java.util.LinkedList
import java.util.Optional
import javax.inject.Inject

@HiltAndroidTest
@@ -98,7 +99,7 @@ class LocalAddressBookTest {
            val id = ContentUris.parseId(uri)

            // make sure it's not dirty
            localGroup.clearDirty(null, null, null)
            localGroup.clearDirty(Optional.empty(), null, null)
            assertFalse("Group is dirty before moving", isGroupDirty(addressBook, id))

            // rename address book
@@ -127,7 +128,7 @@ class LocalAddressBookTest {
     */
    fun isContactDirty(adddressBook: LocalAddressBook, id: Long): Boolean {
        val uri = ContentUris.withAppendedId(adddressBook.rawContactsSyncUri(), id)
        provider!!.query(uri, arrayOf(ContactsContract.RawContacts.DIRTY), null, null, null)?.use { cursor ->
        provider.query(uri, arrayOf(ContactsContract.RawContacts.DIRTY), null, null, null)?.use { cursor ->
            if (cursor.moveToFirst())
                return cursor.getInt(0) != 0
        }
@@ -143,7 +144,7 @@ class LocalAddressBookTest {
     */
    fun isGroupDirty(adddressBook: LocalAddressBook, id: Long): Boolean {
        val uri = ContentUris.withAppendedId(adddressBook.groupsSyncUri(), id)
        provider!!.query(uri, arrayOf(ContactsContract.Groups.DIRTY), null, null, null)?.use { cursor ->
        provider.query(uri, arrayOf(ContactsContract.Groups.DIRTY), null, null, null)?.use { cursor ->
            if (cursor.moveToFirst())
                return cursor.getInt(0) != 0
        }
+16 −7
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@ import android.provider.CalendarContract.ACCOUNT_TYPE_LOCAL
import android.provider.CalendarContract.Events
import androidx.test.platform.app.InstrumentationRegistry
import at.bitfire.ical4android.Event
import at.bitfire.ical4android.LegacyAndroidCalendar
import at.bitfire.ical4android.util.MiscUtils.asSyncAdapter
import at.bitfire.ical4android.util.MiscUtils.closeCompat
import at.bitfire.synctools.storage.calendar.AndroidCalendarProvider
@@ -92,10 +91,15 @@ class LocalCalendarTest {
                status = Status.VEVENT_CANCELLED
            })
        }
        val legacyCalendar = LegacyAndroidCalendar(calendar.androidCalendar)
        legacyCalendar.add(event = event, syncId = "filename.ics", flags = LocalResource.FLAG_REMOTELY_PRESENT)
        calendar.add(
            event = event,
            fileName = "filename.ics",
            eTag = null,
            scheduleTag = null,
            flags = LocalResource.FLAG_REMOTELY_PRESENT
        )
        val localEvent = calendar.findByName("filename.ics")!!
        val eventId = localEvent.id!!
        val eventId = localEvent.id

        // set event as dirty
        client.update(ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId), ContentValues(1).apply {
@@ -123,10 +127,15 @@ class LocalCalendarTest {
            summary = "Event with 3 instances"
            rRules.add(RRule("FREQ=DAILY;COUNT=3"))
        }
        val legacyCalendar = LegacyAndroidCalendar(calendar.androidCalendar)
        legacyCalendar.add(event = event, syncId = "filename.ics", flags = LocalResource.FLAG_REMOTELY_PRESENT)
        calendar.add(
            event = event,
            fileName = "filename.ics",
            eTag = null,
            scheduleTag = null,
            flags = LocalResource.FLAG_REMOTELY_PRESENT
        )
        val localEvent = calendar.findByName("filename.ics")!!
        val eventId = localEvent.id!!
        val eventId = localEvent.id

        // set event as dirty
        client.update(ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId), ContentValues(1).apply {
+35 −11
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@ import android.provider.CalendarContract.Events
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import at.bitfire.ical4android.Event
import at.bitfire.ical4android.LegacyAndroidCalendar
import at.bitfire.ical4android.util.MiscUtils.closeCompat
import at.bitfire.synctools.storage.calendar.AndroidCalendarProvider
import at.techbee.jtx.JtxContract.asSyncAdapter
@@ -75,8 +74,13 @@ class LocalEventTest {
            summary = "Event without uid"
        }

        val legacyCalendar = LegacyAndroidCalendar(calendar.androidCalendar)
        legacyCalendar.add(event = event, syncId = "filename.ics", flags = LocalResource.FLAG_REMOTELY_PRESENT)
        calendar.add(
            event = event,
            fileName = "filename.ics",
            eTag = null,
            scheduleTag = null,
            flags = LocalResource.FLAG_REMOTELY_PRESENT
        )
        val localEvent = calendar.findByName("filename.ics")!!

        // prepare for upload - this should generate a new random uuid, returned as filename
@@ -104,8 +108,13 @@ class LocalEventTest {
            summary = "Event with normal uid"
            uid = "some-event@hostname.tld"     // old UID format, UUID would be new format
        }
        val legacyCalendar = LegacyAndroidCalendar(calendar.androidCalendar)
        legacyCalendar.add(event = event, syncId = "filename.ics", flags = LocalResource.FLAG_REMOTELY_PRESENT)
        calendar.add(
            event = event,
            fileName = "filename.ics",
            eTag = null,
            scheduleTag = null,
            flags = LocalResource.FLAG_REMOTELY_PRESENT
        )
        val localEvent = calendar.findByName("filename.ics")!!

        // prepare for upload - this should use the UID for the file name
@@ -132,8 +141,13 @@ class LocalEventTest {
            summary = "Event with funny uid"
            uid = "https://www.example.com/events/asdfewfe-cxyb-ewrws-sadfrwerxyvser-asdfxye-"
        }
        val legacyCalendar = LegacyAndroidCalendar(calendar.androidCalendar)
        legacyCalendar.add(event = event, syncId = "filename.ics", flags = LocalResource.FLAG_REMOTELY_PRESENT)
        calendar.add(
            event = event,
            fileName = "filename.ics",
            eTag = null,
            scheduleTag = null,
            flags = LocalResource.FLAG_REMOTELY_PRESENT
        )
        val localEvent = calendar.findByName("filename.ics")!!

        // prepare for upload - this should generate a new random uuid, returned as filename
@@ -185,8 +199,13 @@ class LocalEventTest {
                status = Status.VEVENT_CANCELLED
            })
        }
        val legacyCalendar = LegacyAndroidCalendar(calendar.androidCalendar)
        legacyCalendar.add(event = event, syncId = "filename.ics", flags = LocalResource.FLAG_REMOTELY_PRESENT)
        calendar.add(
            event = event,
            fileName = "filename.ics",
            eTag = null,
            scheduleTag = null,
            flags = LocalResource.FLAG_REMOTELY_PRESENT
        )
        val localEvent = calendar.findByName("filename.ics")!!
        val eventId = localEvent.id!!

@@ -215,8 +234,13 @@ class LocalEventTest {
            summary = "Event with 3 instances"
            rRules.add(RRule("FREQ=DAILY;COUNT=3"))
        }
        val legacyCalendar = LegacyAndroidCalendar(calendar.androidCalendar)
        legacyCalendar.add(event = event, syncId = "filename.ics", flags = LocalResource.FLAG_REMOTELY_PRESENT)
        calendar.add(
            event = event,
            fileName = "filename.ics",
            eTag = null,
            scheduleTag = null,
            flags = LocalResource.FLAG_REMOTELY_PRESENT
        )
        val localEvent = calendar.findByName("filename.ics")!!
        val eventId = localEvent.id!!

+3 −2
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import org.junit.BeforeClass
import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
import java.util.Optional
import javax.inject.Inject

@HiltAndroidTest
@@ -164,7 +165,7 @@ class LocalGroupTest {
                }
            )

            group.clearDirty(null, null)
            group.clearDirty(Optional.empty(), null)

            // check cached group membership
            ab.provider!!.query(
@@ -200,7 +201,7 @@ class LocalGroupTest {
                }
            )

            group.clearDirty(null, null)
            group.clearDirty(Optional.empty(), null)

            // cached group membership should be gone
            ab.provider!!.query(
+6 −5
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
package at.bitfire.davdroid.sync

import at.bitfire.davdroid.resource.LocalResource
import java.util.Optional

class LocalTestResource: LocalResource<Any> {

@@ -19,10 +20,10 @@ class LocalTestResource: LocalResource<Any> {

    override fun prepareForUpload() = "generated-file.txt"

    override fun clearDirty(fileName: String?, eTag: String?, scheduleTag: String?) {
    override fun clearDirty(fileName: Optional<String>, eTag: String?, scheduleTag: String?) {
        dirty = false
        if (fileName != null)
            this.fileName = fileName
        if (fileName.isPresent)
            this.fileName = fileName.get()
        this.eTag = eTag
        this.scheduleTag = scheduleTag
    }
@@ -31,8 +32,8 @@ class LocalTestResource: LocalResource<Any> {
        this.flags = flags
    }

    override fun update(data: Any) = throw NotImplementedError()
    override fun delete() = throw NotImplementedError()
    override fun update(data: Any, fileName: String?, eTag: String?, scheduleTag: String?, flags: Int) = throw NotImplementedError()
    override fun deleteLocal() = throw NotImplementedError()
    override fun resetDeleted() = throw NotImplementedError()

}
 No newline at end of file
Loading