Skip to content

Commit

Permalink
Tests, set default sync interval when tasks app is installed, notify …
Browse files Browse the repository at this point in the history
…on missing tasks app permission during sync
  • Loading branch information
rfc2822 committed Dec 25, 2024
1 parent e7c3abd commit 2729055
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/

package at.bitfire.davdroid.settings.migration

import android.accounts.Account
import android.content.Context
import android.util.Log
import androidx.hilt.work.HiltWorkerFactory
import androidx.work.Configuration
import androidx.work.WorkManager
import androidx.work.testing.WorkManagerTestInitHelper
import at.bitfire.davdroid.R
import at.bitfire.davdroid.sync.AutomaticSyncManager
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import io.mockk.MockKAnnotations
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.MockK
import io.mockk.impl.annotations.SpyK
import io.mockk.mockk
import io.mockk.mockkObject
import io.mockk.unmockkAll
import io.mockk.verify
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import javax.inject.Inject

@HiltAndroidTest
class AccountSettingsMigration19Test {

@Inject @ApplicationContext
@SpyK
lateinit var context: Context

@MockK(relaxed = true)
lateinit var automaticSyncManager: AutomaticSyncManager

@InjectMockKs
lateinit var migration: AccountSettingsMigration19

@Inject
lateinit var workerFactory: HiltWorkerFactory

@get:Rule
val hiltRule = HiltAndroidRule(this)


@Before
fun setUp() {
hiltRule.inject()

// Initialize WorkManager for instrumentation tests.
val config = Configuration.Builder()
.setMinimumLoggingLevel(Log.DEBUG)
.setWorkerFactory(workerFactory)
.build()
WorkManagerTestInitHelper.initializeTestWorkManager(context, config)

MockKAnnotations.init(this)
}

@After
fun tearDown() {
unmockkAll()
}


@Test
fun testMigrate_CancelsOldWorkersAndUpdatesAutomaticSync() {
val workManager = WorkManager.getInstance(context)
mockkObject(workManager)

val account = Account("Some", "Test")
migration.migrate(account, mockk())

val addressBookAuthority = context.getString(R.string.address_books_authority)
verify {
workManager.cancelUniqueWork("periodic-sync $addressBookAuthority Test/Some")
workManager.cancelUniqueWork("periodic-sync com.android.calendar Test/Some")
workManager.cancelUniqueWork("periodic-sync at.techbee.jtx.provider Test/Some")
workManager.cancelUniqueWork("periodic-sync org.dmfs.tasks Test/Some")
workManager.cancelUniqueWork("periodic-sync org.tasks.opentasks Test/Some")

automaticSyncManager.updateAutomaticSync(account)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ class AutomaticSyncManager @Inject constructor(
} else
for (authority in dataType.possibleAuthorities(context))
syncFramework.disableSyncOnContentChange(account, authority)

// FIXME check permission, if applicable (was: check tasks permission)
}

/**
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/kotlin/at/bitfire/davdroid/sync/Syncer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import at.bitfire.davdroid.repository.DavServiceRepository
import at.bitfire.davdroid.resource.LocalCollection
import at.bitfire.davdroid.resource.LocalDataStore
import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.ui.NotificationRegistry
import dagger.hilt.android.qualifiers.ApplicationContext
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
Expand Down Expand Up @@ -74,6 +75,9 @@ abstract class Syncer<StoreType: LocalDataStore<CollectionType>, CollectionType:
@Inject
lateinit var logger: Logger

@Inject
lateinit var notificationRegistry: NotificationRegistry

@Inject
lateinit var serviceRepository: DavServiceRepository

Expand Down Expand Up @@ -252,6 +256,7 @@ abstract class Syncer<StoreType: LocalDataStore<CollectionType>, CollectionType:
context.contentResolver.acquireContentProviderClient(authority)
} catch (e: SecurityException) {
logger.log(Level.WARNING, "Missing permissions for authority $authority", e)
notificationRegistry.notifyPermissions()
null
}.use { provider ->
if (provider == null) {
Expand Down
21 changes: 18 additions & 3 deletions app/src/main/kotlin/at/bitfire/davdroid/sync/TasksAppManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import android.net.Uri
import androidx.core.app.NotificationCompat
import at.bitfire.davdroid.R
import at.bitfire.davdroid.repository.AccountRepository
import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.settings.Settings
import at.bitfire.davdroid.settings.SettingsManager
import at.bitfire.davdroid.ui.NotificationRegistry
Expand All @@ -31,6 +32,7 @@ import javax.inject.Inject
class TasksAppManager @Inject constructor(
@ApplicationContext private val context: Context,
private val accountRepository: Lazy<AccountRepository>,
private val accountSettingsFactory: AccountSettings.Factory,
private val automaticSyncManager: AutomaticSyncManager,
private val logger: Logger,
private val notificationRegistry: Lazy<NotificationRegistry>,
Expand Down Expand Up @@ -73,11 +75,24 @@ class TasksAppManager @Inject constructor(
fun selectProvider(selectedProvider: ProviderName?) {
logger.info("Selecting tasks app: $selectedProvider")

settingsManager.putString(Settings.SELECTED_TASKS_PROVIDER, selectedProvider?.authority)
val authority = selectedProvider?.authority
settingsManager.putString(Settings.SELECTED_TASKS_PROVIDER, authority)

// check all accounts and update task sync
for (account in accountRepository.get().getAll())
automaticSyncManager.updateAutomaticSync(account, SyncDataType.TASKS)
for (account in accountRepository.get().getAll()) {
if (authority != null) {
val accountSettings = accountSettingsFactory.create(account)
val syncInterval = accountSettings.getSyncInterval(authority)
if (syncInterval != null && syncInterval != AccountSettings.SYNC_INTERVAL_MANUALLY)
// we already have a sync interval, only update automatic sync
automaticSyncManager.updateAutomaticSync(account, SyncDataType.TASKS)
else {
// no sync interval yet, set it to default
val syncInterval = settingsManager.getLong(Settings.DEFAULT_SYNC_INTERVAL)
accountSettings.setSyncInterval(authority, syncInterval)
}
}
}
}


Expand Down

0 comments on commit 2729055

Please sign in to comment.