Synctools: AndroidEvent companion object moved (#1572)

* Update synctools

* Refactor LocalCalendar to use Hilt

* Update synctools
This commit is contained in:
Ricki Hirner
2025-07-09 16:35:27 +02:00
committed by GitHub
parent 904c8ba29b
commit 4e2640ca01
6 changed files with 67 additions and 61 deletions

View File

@@ -18,56 +18,51 @@ import at.bitfire.ical4android.util.MiscUtils.asSyncAdapter
import at.bitfire.ical4android.util.MiscUtils.closeCompat
import at.bitfire.synctools.storage.calendar.AndroidCalendarProvider
import at.bitfire.synctools.test.InitCalendarProviderRule
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import net.fortuna.ical4j.model.property.DtStart
import net.fortuna.ical4j.model.property.RRule
import net.fortuna.ical4j.model.property.RecurrenceId
import net.fortuna.ical4j.model.property.Status
import org.junit.After
import org.junit.AfterClass
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.BeforeClass
import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TestRule
import javax.inject.Inject
@HiltAndroidTest
class LocalCalendarTest {
companion object {
@get:Rule
val hiltRule = HiltAndroidRule(this)
@JvmField
@ClassRule
val initCalendarProviderRule: TestRule = InitCalendarProviderRule.initialize()
@get:Rule
val initCalendarProviderRule: TestRule = InitCalendarProviderRule.initialize()
private lateinit var client: ContentProviderClient
@BeforeClass
@JvmStatic
fun setUpClass() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
client = context.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)!!
}
@AfterClass
@JvmStatic
fun tearDownClass() {
client.closeCompat()
}
}
@Inject
lateinit var localCalendarFactory: LocalCalendar.Factory
private val account = Account("LocalCalendarTest", ACCOUNT_TYPE_LOCAL)
private lateinit var client: ContentProviderClient
private lateinit var calendar: LocalCalendar
@Before
fun setUp() {
hiltRule.inject()
val context = InstrumentationRegistry.getInstrumentation().targetContext
client = context.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)!!
val provider = AndroidCalendarProvider(account, client)
calendar = LocalCalendar(provider.createAndGetCalendar(ContentValues()))
calendar = localCalendarFactory.create(provider.createAndGetCalendar(ContentValues()))
}
@After
fun tearDown() {
calendar.androidCalendar.delete()
client.closeCompat()
}

View File

@@ -4,6 +4,7 @@
package at.bitfire.davdroid.resource
import android.Manifest
import android.accounts.Account
import android.content.ContentProviderClient
import android.content.ContentUris
@@ -12,37 +13,57 @@ import android.provider.CalendarContract
import android.provider.CalendarContract.ACCOUNT_TYPE_LOCAL
import android.provider.CalendarContract.Events
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import at.bitfire.ical4android.AndroidEvent
import at.bitfire.ical4android.Event
import at.bitfire.ical4android.util.MiscUtils.closeCompat
import at.bitfire.synctools.storage.calendar.AndroidCalendarProvider
import at.techbee.jtx.JtxContract.asSyncAdapter
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import net.fortuna.ical4j.model.property.DtStart
import net.fortuna.ical4j.model.property.RRule
import net.fortuna.ical4j.model.property.RecurrenceId
import net.fortuna.ical4j.model.property.Status
import org.junit.After
import org.junit.AfterClass
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Rule
import org.junit.Test
import java.util.UUID
import javax.inject.Inject
@HiltAndroidTest
class LocalEventTest {
@get:Rule
val hiltRule = HiltAndroidRule(this)
@get:Rule
val permissionRule = GrantPermissionRule.grant(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR)
@Inject
lateinit var localCalendarFactory: LocalCalendar.Factory
private val account = Account("LocalCalendarTest", ACCOUNT_TYPE_LOCAL)
private lateinit var client: ContentProviderClient
private lateinit var calendar: LocalCalendar
@Before
fun setUp() {
hiltRule.inject()
val context = InstrumentationRegistry.getInstrumentation().targetContext
client = context.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)!!
val provider = AndroidCalendarProvider(account, client)
calendar = LocalCalendar(provider.createAndGetCalendar(ContentValues()))
calendar = localCalendarFactory.create(provider.createAndGetCalendar(ContentValues()))
}
@After
fun removeCalendar() {
fun tearDown() {
calendar.androidCalendar.delete()
client.closeCompat()
}
@@ -211,24 +232,4 @@ class LocalEventTest {
}
}
companion object {
private lateinit var client: ContentProviderClient
@BeforeClass
@JvmStatic
fun setUpClass() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
client = context.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)!!
}
@AfterClass
@JvmStatic
fun tearDownClass() {
client.closeCompat()
}
}
}

View File

@@ -33,7 +33,6 @@ import at.bitfire.davdroid.di.IoDispatcher
import at.bitfire.davdroid.network.HttpClient
import at.bitfire.davdroid.servicedetection.RefreshCollectionsWorker
import at.bitfire.davdroid.util.DavUtils
import at.bitfire.ical4android.util.DateUtils
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.runInterruptible
@@ -42,6 +41,7 @@ import net.fortuna.ical4j.model.Component
import net.fortuna.ical4j.model.ComponentList
import net.fortuna.ical4j.model.Property
import net.fortuna.ical4j.model.PropertyList
import net.fortuna.ical4j.model.TimeZoneRegistryFactory
import net.fortuna.ical4j.model.component.VTimeZone
import net.fortuna.ical4j.model.property.Version
import okhttp3.HttpUrl
@@ -417,6 +417,9 @@ class DavCollectionRepository @Inject constructor(
return writer.toString()
}
private fun getVTimeZone(tzId: String): VTimeZone? = DateUtils.ical4jTimeZone(tzId)?.vTimeZone
private fun getVTimeZone(tzId: String): VTimeZone? {
val tzRegistry = TimeZoneRegistryFactory.getInstance().createRegistry()
return tzRegistry.getTimeZone(tzId)?.vTimeZone
}
}

View File

@@ -14,6 +14,9 @@ import at.bitfire.ical4android.util.MiscUtils.asSyncAdapter
import at.bitfire.synctools.storage.BatchOperation
import at.bitfire.synctools.storage.calendar.AndroidCalendar
import at.bitfire.synctools.storage.calendar.CalendarBatchOperation
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import java.util.LinkedList
import java.util.logging.Level
import java.util.logging.Logger
@@ -23,12 +26,15 @@ import java.util.logging.Logger
*
* [Calendars._SYNC_ID] corresponds to the database collection ID ([at.bitfire.davdroid.db.Collection.id]).
*/
class LocalCalendar(
val androidCalendar: AndroidCalendar
class LocalCalendar @AssistedInject constructor(
@Assisted val androidCalendar: AndroidCalendar,
private val logger: Logger
) : LocalCollection<LocalEvent> {
private val logger: Logger
get() = Logger.getLogger(javaClass.name)
@AssistedFactory
interface Factory {
fun create(androidCalendar: AndroidCalendar): LocalCalendar
}
override val dbCollectionId: Long?
@@ -198,15 +204,15 @@ class LocalCalendar(
"${Events.DIRTY} AND NOT ${Events.DELETED} AND ${Events.ORIGINAL_ID} IS NULL",
null
) { values ->
val eventID = values.getAsLong(Events._ID)
val eventId = values.getAsLong(Events._ID)
// get number of instances
val numEventInstances = AndroidEvent.numInstances(androidCalendar.client, androidCalendar.account, eventID)
val numEventInstances = androidCalendar.numInstances(eventId)
// delete event if there are no instances
if (numEventInstances == 0) {
logger.fine("Marking event #$eventID without instances as deleted")
AndroidEvent.markAsDeleted(androidCalendar.client, androidCalendar.account, eventID)
logger.fine("Marking event #$eventId without instances as deleted")
androidCalendar.updateEvent(eventId, contentValuesOf(Events.DELETED to 1))
}
}
}

View File

@@ -31,6 +31,7 @@ import javax.inject.Inject
class LocalCalendarStore @Inject constructor(
@ApplicationContext private val context: Context,
private val accountSettingsFactory: AccountSettings.Factory,
private val localCalendarFactory: LocalCalendar.Factory,
private val logger: Logger,
private val serviceRepository: DavServiceRepository
): LocalDataStore<LocalCalendar> {
@@ -71,13 +72,13 @@ class LocalCalendarStore @Inject constructor(
logger.log(Level.INFO, "Adding local calendar", values)
val provider = AndroidCalendarProvider(account, client)
return LocalCalendar(provider.createAndGetCalendar(values))
return localCalendarFactory.create(provider.createAndGetCalendar(values))
}
override fun getAll(account: Account, client: ContentProviderClient) =
AndroidCalendarProvider(account, client)
.findCalendars("${Calendars.SYNC_EVENTS}!=0", null)
.map { LocalCalendar(it) }
.map { localCalendarFactory.create(it) }
override fun update(client: ContentProviderClient, localCollection: LocalCalendar, fromCollection: Collection) {
val accountSettings = accountSettingsFactory.create(localCollection.androidCalendar.account)

View File

@@ -20,7 +20,7 @@ androidx-test-junit = "1.2.1"
androidx-work = "2.10.2"
bitfire-cert4android = "b67ba86d31"
bitfire-dav4jvm = "acbfbacbaf"
bitfire-synctools = "a365b91c04"
bitfire-synctools = "2bef0eee14"
compose-accompanist = "0.37.3"
compose-bom = "2025.06.01"
dnsjava = "3.6.3"