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

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

AndroidCalendar refactoring (#1560)

* [WIP] Refactor calendar sync manager to use synctools library

* [WIP] Update synctools

* [WIP] Tests

* Remove test logger module and update calendar color methods

* Fix migrations

* Update libs.versions.toml
parent b62c7eff
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -11,7 +11,11 @@ import android.os.Bundle
import androidx.test.runner.AndroidJUnitRunner
import at.bitfire.davdroid.di.TestCoroutineDispatchersModule
import at.bitfire.davdroid.sync.SyncAdapterService
import at.bitfire.davdroid.test.BuildConfig
import at.bitfire.synctools.log.LogcatHandler
import dagger.hilt.android.testing.HiltTestApplication
import java.util.logging.Level
import java.util.logging.Logger

@Suppress("unused")
class HiltTestRunner : AndroidJUnitRunner() {
@@ -22,6 +26,12 @@ class HiltTestRunner : AndroidJUnitRunner() {
    override fun onCreate(arguments: Bundle?) {
        super.onCreate(arguments)

        // set root logger to adb Logcat
        val rootLogger = Logger.getLogger("")
        rootLogger.level = Level.ALL
        rootLogger.handlers.forEach { rootLogger.removeHandler(it) }
        rootLogger.addHandler(LogcatHandler(BuildConfig.APPLICATION_ID))

        // MockK requirements
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P)
            throw AssertionError("MockK requires Android P [https://mockk.io/ANDROID.html]")
+0 −33
Original line number Diff line number Diff line
/*
 * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
 */

package at.bitfire.davdroid.di

import at.bitfire.davdroid.log.LogcatHandler
import dagger.Module
import dagger.Provides
import dagger.hilt.components.SingletonComponent
import dagger.hilt.testing.TestInstallIn
import java.util.logging.Level
import java.util.logging.Logger
import javax.inject.Singleton

/**
 * Module that provides verbose logging for tests.
 */
@TestInstallIn(
    components = [SingletonComponent::class],
    replaces = [LoggerModule::class]
)
@Module
class TestLoggerModule {

    @Provides
    @Singleton
    fun logger(): Logger = Logger.getGlobal().apply {
        level = Level.ALL
        addHandler(LogcatHandler())
    }

}
 No newline at end of file
+11 −11
Original line number Diff line number Diff line
@@ -12,11 +12,11 @@ import android.provider.CalendarContract
import android.provider.CalendarContract.ACCOUNT_TYPE_LOCAL
import android.provider.CalendarContract.Events
import androidx.test.platform.app.InstrumentationRegistry
import at.bitfire.ical4android.AndroidCalendar
import at.bitfire.ical4android.AndroidEvent
import at.bitfire.ical4android.Event
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 net.fortuna.ical4j.model.property.DtStart
import net.fortuna.ical4j.model.property.RRule
@@ -37,21 +37,21 @@ class LocalCalendarTest {

        @JvmField
        @ClassRule
        val initCalendarProviderRule: TestRule = InitCalendarProviderRule.getInstance()
        val initCalendarProviderRule: TestRule = InitCalendarProviderRule.initialize()

        private lateinit var provider: ContentProviderClient
        private lateinit var client: ContentProviderClient

        @BeforeClass
        @JvmStatic
        fun setUpClass() {
            val context = InstrumentationRegistry.getInstrumentation().targetContext
            provider = context.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)!!
            client = context.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)!!
        }

        @AfterClass
        @JvmStatic
        fun tearDownClass() {
            provider.closeCompat()
            client.closeCompat()
        }

    }
@@ -61,8 +61,8 @@ class LocalCalendarTest {

    @Before
    fun setUp() {
        val uri = AndroidCalendar.create(account, provider, ContentValues())
        calendar = LocalCalendar(AndroidCalendar.findByID(account, provider, ContentUris.parseId(uri)))
        val provider = AndroidCalendarProvider(account, client)
        calendar = LocalCalendar(provider.createAndGetCalendar(ContentValues()))
    }

    @After
@@ -102,7 +102,7 @@ class LocalCalendarTest {
        val eventId = localEvent.id!!

        // set event as dirty
        provider.update(ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId), ContentValues(1).apply {
        client.update(ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId), ContentValues(1).apply {
            put(Events.DIRTY, 1)
        }, null, null)

@@ -110,7 +110,7 @@ class LocalCalendarTest {
        calendar.deleteDirtyEventsWithoutInstances()

        // verify that event is now marked as deleted
        provider.query(
        client.query(
            ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId),
            arrayOf(Events.DELETED), null, null, null
        )!!.use { cursor ->
@@ -132,7 +132,7 @@ class LocalCalendarTest {
        val eventId = localEvent.id!!

        // set event as dirty
        provider.update(ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId), ContentValues(1).apply {
        client.update(ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId), ContentValues(1).apply {
            put(Events.DIRTY, 1)
        }, null, null)

@@ -140,7 +140,7 @@ class LocalCalendarTest {
        calendar.deleteDirtyEventsWithoutInstances()

        // verify that event is not marked as deleted
        provider.query(
        client.query(
            ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId),
            arrayOf(Events.DELETED), null, null, null
        )!!.use { cursor ->
+13 −13
Original line number Diff line number Diff line
@@ -12,10 +12,10 @@ import android.provider.CalendarContract
import android.provider.CalendarContract.ACCOUNT_TYPE_LOCAL
import android.provider.CalendarContract.Events
import androidx.test.platform.app.InstrumentationRegistry
import at.bitfire.ical4android.AndroidCalendar
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 net.fortuna.ical4j.model.property.DtStart
import net.fortuna.ical4j.model.property.RRule
@@ -36,8 +36,8 @@ class LocalEventTest {

    @Before
    fun setUp() {
        val uri = AndroidCalendar.create(account, provider, ContentValues())
        calendar = LocalCalendar(AndroidCalendar.findByID(account, provider, ContentUris.parseId(uri)))
        val provider = AndroidCalendarProvider(account, client)
        calendar = LocalCalendar(provider.createAndGetCalendar(ContentValues()))
    }

    @After
@@ -64,7 +64,7 @@ class LocalEventTest {
        UUID.fromString(fileName)

        // UID in calendar storage should be the same as file name
        provider.query(
        client.query(
            ContentUris.withAppendedId(Events.CONTENT_URI, localEvent.id!!).asSyncAdapter(account),
            arrayOf(Events.UID_2445), null, null, null
        )!!.use { cursor ->
@@ -91,7 +91,7 @@ class LocalEventTest {
        assertEquals(event.uid, fileName)

        // UID in calendar storage should still be set, too
        provider.query(
        client.query(
            ContentUris.withAppendedId(Events.CONTENT_URI, localEvent.id!!).asSyncAdapter(account),
            arrayOf(Events.UID_2445), null, null, null
        )!!.use { cursor ->
@@ -119,7 +119,7 @@ class LocalEventTest {
        UUID.fromString(fileName)

        // UID in calendar storage shouldn't have been changed
        provider.query(
        client.query(
            ContentUris.withAppendedId(Events.CONTENT_URI, localEvent.id!!).asSyncAdapter(account),
            arrayOf(Events.UID_2445), null, null, null
        )!!.use { cursor ->
@@ -165,7 +165,7 @@ class LocalEventTest {
        val eventId = localEvent.id!!

        // set event as dirty
        provider.update(ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId), ContentValues(1).apply {
        client.update(ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId), ContentValues(1).apply {
            put(Events.DIRTY, 1)
        }, null, null)

@@ -173,7 +173,7 @@ class LocalEventTest {
        calendar.deleteDirtyEventsWithoutInstances()

        // verify that event is now marked as deleted
        provider.query(
        client.query(
            ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId),
            arrayOf(Events.DELETED), null, null, null
        )!!.use { cursor ->
@@ -194,7 +194,7 @@ class LocalEventTest {
        val eventId = localEvent.id!!

        // set event as dirty
        provider.update(ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId), ContentValues(1).apply {
        client.update(ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId), ContentValues(1).apply {
            put(Events.DIRTY, 1)
        }, null, null)

@@ -202,7 +202,7 @@ class LocalEventTest {
        calendar.deleteDirtyEventsWithoutInstances()

        // verify that event is not marked as deleted
        provider.query(
        client.query(
            ContentUris.withAppendedId(Events.CONTENT_URI.asSyncAdapter(account), eventId),
            arrayOf(Events.DELETED), null, null, null
        )!!.use { cursor ->
@@ -214,19 +214,19 @@ class LocalEventTest {

    companion object {

        private lateinit var provider: ContentProviderClient
        private lateinit var client: ContentProviderClient

        @BeforeClass
        @JvmStatic
        fun setUpClass() {
            val context = InstrumentationRegistry.getInstrumentation().targetContext
            provider = context.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)!!
            client = context.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)!!
        }

        @AfterClass
        @JvmStatic
        fun tearDownClass() {
            provider.closeCompat()
            client.closeCompat()
        }

    }
+4 −4
Original line number Diff line number Diff line
@@ -127,16 +127,16 @@ class AccountSettingsMigration20Test {
                    Calendars.NAME to url,
                    Calendars.SYNC_EVENTS to 1
                )
            )!!
            )!!.asSyncAdapter(account)
            try {
                migration.migrateCalendars(account, calDavServiceId = 1)
                migration.migrateCalendars(account, 1)

                provider.query(uri.asSyncAdapter(account), arrayOf(Calendars._SYNC_ID), null, null, null)!!.use { cursor ->
                provider.query(uri, arrayOf(Calendars._SYNC_ID), null, null, null)!!.use { cursor ->
                    cursor.moveToNext()
                    assertEquals(collectionId, cursor.getLongOrNull(0))
                }
            } finally {
                provider.delete(uri.asSyncAdapter(account), null, null)
                provider.delete(uri, null, null)
            }
        }
    }
Loading