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

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

Choose real or fake (for tests) SyncAdapter over DI (#1608)

* Choose real or fake (for tests) SyncAdapter over DI

* Minor changes

* Rename SyncAdapterServicesTest.kt to RealSyncAdapterTest.kt

* Group sync adapter / sync framework classes into new package

* Cache SyncAdapter in SyncAdapterServices

* Add documentation to SyncAdapter interface and rename RealSyncAdapterTest to SyncAdapterImplTest
parent 288583bf
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -10,7 +10,6 @@ import android.os.Build
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
@@ -36,9 +35,6 @@ class HiltTestRunner : AndroidJUnitRunner() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P)
            throw AssertionError("MockK requires Android P [https://mockk.io/ANDROID.html]")

        // disable sync adapters
        SyncAdapterService.syncActive.set(false)

        // set main dispatcher for tests (especially runTest)
        TestCoroutineDispatchersModule.initMainDispatcher()
    }
+20 −0
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.sync.FakeSyncAdapter
import at.bitfire.davdroid.sync.adapter.SyncAdapter
import at.bitfire.davdroid.sync.adapter.SyncAdapterImpl
import dagger.Binds
import dagger.Module
import dagger.hilt.components.SingletonComponent
import dagger.hilt.testing.TestInstallIn

@Module
@TestInstallIn(components = [SingletonComponent::class], replaces = [SyncAdapterImpl.RealSyncAdapterModule::class])
abstract class FakeSyncAdapterModule {
    @Binds
    abstract fun provide(impl: FakeSyncAdapter): SyncAdapter
}
 No newline at end of file
+1 −1
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@ import android.content.Context
import at.bitfire.davdroid.repository.DavCollectionRepository
import at.bitfire.davdroid.repository.DavServiceRepository
import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.sync.SyncFrameworkIntegration
import at.bitfire.davdroid.sync.adapter.SyncFrameworkIntegration
import at.bitfire.vcard4android.GroupMethod
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
+51 −0
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.sync

import android.accounts.Account
import android.content.AbstractThreadedSyncAdapter
import android.content.ContentProviderClient
import android.content.Context
import android.content.SyncResult
import android.os.Bundle
import android.os.IBinder
import at.bitfire.davdroid.sync.adapter.SyncAdapter
import dagger.hilt.android.qualifiers.ApplicationContext
import java.util.logging.Level
import java.util.logging.Logger
import javax.inject.Inject

class FakeSyncAdapter @Inject constructor(
    @ApplicationContext context: Context,
    private val logger: Logger
): AbstractThreadedSyncAdapter(context, true), SyncAdapter {

    init {
        logger.info("FakeSyncAdapter created")
    }

    override fun onPerformSync(account: Account, extras: Bundle, authority: String, provider: ContentProviderClient, syncResult: SyncResult) {
        logger.log(
            Level.INFO,
            "onPerformSync(account=$account, extras=$extras, authority=$authority, syncResult=$syncResult)",
            extras.keySet().map { key -> "extras[$key] = ${extras[key]}" }
        )

        // fake 5 sec sync
        try {
            Thread.sleep(5000)
        } catch (_: InterruptedException) {
            logger.info("onPerformSync($account) cancelled")
        }

        logger.info("onPerformSync($account) finished")
    }


    // SyncAdapter implementation and Hilt module

    override fun getBinder(): IBinder = syncAdapterBinder

}
 No newline at end of file
+7 −6
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ import androidx.work.WorkInfo
import androidx.work.WorkManager
import at.bitfire.davdroid.TestUtils
import at.bitfire.davdroid.sync.account.TestAccount
import at.bitfire.davdroid.sync.adapter.SyncAdapterImpl
import at.bitfire.davdroid.sync.worker.SyncWorkerManager
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.testing.BindValue
@@ -44,7 +45,7 @@ import javax.inject.Provider
import kotlin.coroutines.cancellation.CancellationException

@HiltAndroidTest
class SyncAdapterServicesTest {
class SyncAdapterImplTest {

    @get:Rule
    val hiltRule = HiltAndroidRule(this)
@@ -56,7 +57,7 @@ class SyncAdapterServicesTest {
    lateinit var context: Context

    @Inject
    lateinit var syncAdapterProvider: Provider<SyncAdapterService.SyncAdapter>
    lateinit var syncAdapterImplProvider: Provider<SyncAdapterImpl>

    @BindValue @MockK
    lateinit var syncWorkerManager: SyncWorkerManager
@@ -90,7 +91,7 @@ class SyncAdapterServicesTest {
    @Test
    fun testSyncAdapter_onPerformSync_cancellation() = runTest {
        val workManager = WorkManager.getInstance(context)
        val syncAdapter = syncAdapterProvider.get()
        val syncAdapter = syncAdapterImplProvider.get()

        mockkObject(workManager) {
            // don't actually create a worker
@@ -114,7 +115,7 @@ class SyncAdapterServicesTest {
    @Test
    fun testSyncAdapter_onPerformSync_returnsAfterTimeout() {
        val workManager = WorkManager.getInstance(context)
        val syncAdapter = syncAdapterProvider.get()
        val syncAdapter = syncAdapterImplProvider.get()

        mockkObject(workManager) {
            // don't actually create a worker
@@ -135,7 +136,7 @@ class SyncAdapterServicesTest {
    @Test
    fun testSyncAdapter_onPerformSync_runsInTime() {
        val workManager = WorkManager.getInstance(context)
        val syncAdapter = syncAdapterProvider.get()
        val syncAdapter = syncAdapterImplProvider.get()

        mockkObject(workManager) {
            // don't actually create a worker
Loading