diff --git a/app/src/androidTest/kotlin/at/bitfire/davdroid/resource/LocalTestAddressBook.kt b/app/src/androidTest/kotlin/at/bitfire/davdroid/resource/LocalTestAddressBook.kt index a1a3c31d2..0c501b898 100644 --- a/app/src/androidTest/kotlin/at/bitfire/davdroid/resource/LocalTestAddressBook.kt +++ b/app/src/androidTest/kotlin/at/bitfire/davdroid/resource/LocalTestAddressBook.kt @@ -119,6 +119,11 @@ class LocalTestAddressBook @AssistedInject constructor( val counter = AtomicInteger() + /** + * Creates a [at.bitfire.davdroid.resource.LocalTestAddressBook]. + * + * Make sure to delete it with [at.bitfire.davdroid.resource.LocalTestAddressBook.remove] or [removeAll] after use. + */ fun create(context: Context, account: Account, provider: ContentProviderClient, groupMethod: GroupMethod = GroupMethod.GROUP_VCARDS): LocalTestAddressBook { // create new address book account val addressBookAccount = Account("Test Address Book ${counter.incrementAndGet()}", context.getString(R.string.account_type_address_book)) @@ -131,6 +136,12 @@ class LocalTestAddressBook @AssistedInject constructor( return factory.create(account, addressBookAccount, provider, groupMethod) } + fun removeAll(context: Context) { + val accountManager = AccountManager.get(context) + for (account in accountManager.getAccountsByType(context.getString(R.string.account_type_address_book))) + accountManager.removeAccountExplicitly(account) + } + } } \ No newline at end of file diff --git a/app/src/androidTest/kotlin/at/bitfire/davdroid/resource/contactrow/CachedGroupMembershipHandlerTest.kt b/app/src/androidTest/kotlin/at/bitfire/davdroid/resource/contactrow/CachedGroupMembershipHandlerTest.kt index 236e066b4..95dbf9e9e 100644 --- a/app/src/androidTest/kotlin/at/bitfire/davdroid/resource/contactrow/CachedGroupMembershipHandlerTest.kt +++ b/app/src/androidTest/kotlin/at/bitfire/davdroid/resource/contactrow/CachedGroupMembershipHandlerTest.kt @@ -74,14 +74,17 @@ class CachedGroupMembershipHandlerTest { @Test fun testMembership() { val addressBook = LocalTestAddressBook.create(context, account, provider, GroupMethod.GROUP_VCARDS) - - val contact = Contact() - val localContact = LocalContact(addressBook, contact, null, null, 0) - CachedGroupMembershipHandler(localContact).handle(ContentValues().apply { - put(CachedGroupMembership.GROUP_ID, 123456) - put(CachedGroupMembership.RAW_CONTACT_ID, 789) - }, contact) - assertArrayEquals(arrayOf(123456L), localContact.cachedGroupMemberships.toArray()) + try { + val contact = Contact() + val localContact = LocalContact(addressBook, contact, null, null, 0) + CachedGroupMembershipHandler(localContact).handle(ContentValues().apply { + put(CachedGroupMembership.GROUP_ID, 123456) + put(CachedGroupMembership.RAW_CONTACT_ID, 789) + }, contact) + assertArrayEquals(arrayOf(123456L), localContact.cachedGroupMemberships.toArray()) + } finally { + addressBook.remove() + } } } \ No newline at end of file diff --git a/app/src/androidTest/kotlin/at/bitfire/davdroid/resource/contactrow/GroupMembershipBuilderTest.kt b/app/src/androidTest/kotlin/at/bitfire/davdroid/resource/contactrow/GroupMembershipBuilderTest.kt index 2499e8ec7..72c2c564f 100644 --- a/app/src/androidTest/kotlin/at/bitfire/davdroid/resource/contactrow/GroupMembershipBuilderTest.kt +++ b/app/src/androidTest/kotlin/at/bitfire/davdroid/resource/contactrow/GroupMembershipBuilderTest.kt @@ -52,10 +52,14 @@ class GroupMembershipBuilderTest { categories += "TEST GROUP" } val addressBookGroupsAsCategories = LocalTestAddressBook.create(context, account, provider, GroupMethod.CATEGORIES) - GroupMembershipBuilder(Uri.EMPTY, null, contact, addressBookGroupsAsCategories, false).build().also { result -> - assertEquals(1, result.size) - assertEquals(GroupMembership.CONTENT_ITEM_TYPE, result[0].values[GroupMembership.MIMETYPE]) - assertEquals(addressBookGroupsAsCategories.findOrCreateGroup("TEST GROUP"), result[0].values[GroupMembership.GROUP_ROW_ID]) + try { + GroupMembershipBuilder(Uri.EMPTY, null, contact, addressBookGroupsAsCategories, false).build().also { result -> + assertEquals(1, result.size) + assertEquals(GroupMembership.CONTENT_ITEM_TYPE, result[0].values[GroupMembership.MIMETYPE]) + assertEquals(addressBookGroupsAsCategories.findOrCreateGroup("TEST GROUP"), result[0].values[GroupMembership.GROUP_ROW_ID]) + } + } finally { + addressBookGroupsAsCategories.remove() } } @@ -65,9 +69,13 @@ class GroupMembershipBuilderTest { categories += "TEST GROUP" } val addressBookGroupsAsVCards = LocalTestAddressBook.create(context, account, provider, GroupMethod.GROUP_VCARDS) - GroupMembershipBuilder(Uri.EMPTY, null, contact, addressBookGroupsAsVCards, false).build().also { result -> - // group membership is constructed during post-processing - assertEquals(0, result.size) + try { + GroupMembershipBuilder(Uri.EMPTY, null, contact, addressBookGroupsAsVCards, false).build().also { result -> + // group membership is constructed during post-processing + assertEquals(0, result.size) + } + } finally { + addressBookGroupsAsVCards.remove() } } diff --git a/app/src/androidTest/kotlin/at/bitfire/davdroid/sync/account/AccountsCleanupWorkerTest.kt b/app/src/androidTest/kotlin/at/bitfire/davdroid/sync/account/AccountsCleanupWorkerTest.kt index 590914c4d..bdd80ff68 100644 --- a/app/src/androidTest/kotlin/at/bitfire/davdroid/sync/account/AccountsCleanupWorkerTest.kt +++ b/app/src/androidTest/kotlin/at/bitfire/davdroid/sync/account/AccountsCleanupWorkerTest.kt @@ -11,12 +11,11 @@ import at.bitfire.davdroid.TestUtils import at.bitfire.davdroid.db.AppDatabase import at.bitfire.davdroid.db.Service import at.bitfire.davdroid.resource.LocalAddressBook +import at.bitfire.davdroid.resource.LocalTestAddressBook import at.bitfire.davdroid.settings.SettingsManager import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest -import io.mockk.every -import io.mockk.mockkObject import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull @@ -36,8 +35,7 @@ class AccountsCleanupWorkerTest { @Inject lateinit var accountsCleanupWorkerFactory: AccountsCleanupWorker.Factory - @Inject - @ApplicationContext + @Inject @ApplicationContext lateinit var context: Context @Inject @@ -59,15 +57,14 @@ class AccountsCleanupWorkerTest { hiltRule.inject() TestUtils.setUpWorkManager(context, workerFactory) - service = createTestService(Service.TYPE_CARDDAV) - - // Prepare test account accountManager = AccountManager.get(context) + service = createTestService() + addressBookAccountType = context.getString(R.string.account_type_address_book) - addressBookAccount = Account( - "Fancy address book account", - addressBookAccountType - ) + addressBookAccount = Account("Fancy address book account", addressBookAccountType) + + // Make sure there are no address books + LocalTestAddressBook.removeAll(context) } @After @@ -95,27 +92,24 @@ class AccountsCleanupWorkerTest { @Test fun testCleanUpServices_oneAccount() { - val account = Account("test", "test") - val accountManager = AccountManager.get(context) - mockkObject(accountManager) - every { accountManager.getAccountsByType(context.getString(R.string.account_type)) } returns arrayOf(account) - - // Insert services, one that reference the existing account and one that references an invalid account - db.serviceDao().insertOrReplace(Service(id = 1, accountName = account.name, type = Service.TYPE_CALDAV, principal = null)) - assertNotNull(db.serviceDao().get(1)) + TestAccount.provide { existingAccount -> + // Insert services, one that reference the existing account and one that references an invalid account + db.serviceDao().insertOrReplace(Service(id = 1, accountName = existingAccount.name, type = Service.TYPE_CALDAV, principal = null)) + assertNotNull(db.serviceDao().get(1)) - db.serviceDao().insertOrReplace(Service(id = 2, accountName = "not existing", type = Service.TYPE_CARDDAV, principal = null)) - assertNotNull(db.serviceDao().get(2)) + db.serviceDao().insertOrReplace(Service(id = 2, accountName = "not existing", type = Service.TYPE_CARDDAV, principal = null)) + assertNotNull(db.serviceDao().get(2)) - // Create worker and run the method - val worker = TestListenableWorkerBuilder(context) - .setWorkerFactory(workerFactory) - .build() - worker.cleanUpServices() + // Create worker and run the method + val worker = TestListenableWorkerBuilder(context) + .setWorkerFactory(workerFactory) + .build() + worker.cleanUpServices() - // Verify that one service is deleted and the other one is kept - assertNotNull(db.serviceDao().get(1)) - assertNull(db.serviceDao().get(2)) + // Verify that one service is deleted and the other one is kept + assertNotNull(db.serviceDao().get(1)) + assertNull(db.serviceDao().get(2)) + } } @@ -123,9 +117,7 @@ class AccountsCleanupWorkerTest { fun testCleanUpAddressBooks_deletesAddressBookWithoutAccount() { // Create address book account without corresponding account assertTrue(accountManager.addAccountExplicitly(addressBookAccount, null, null)) - - val addressBookAccounts = accountManager.getAccountsByType(addressBookAccountType) - assertEquals(addressBookAccount, addressBookAccounts.firstOrNull()) + assertEquals(listOf(addressBookAccount), accountManager.getAccountsByType(addressBookAccountType).toList()) // Create worker and run the method val worker = TestListenableWorkerBuilder(context) @@ -139,16 +131,14 @@ class AccountsCleanupWorkerTest { @Test fun testCleanUpAddressBooks_keepsAddressBookWithAccount() { - TestAccount.provide { account -> + TestAccount.provide { existingAccount -> // Create address book account _with_ corresponding account and verify val userData = Bundle(2).apply { - putString(LocalAddressBook.USER_DATA_ACCOUNT_NAME, account.name) - putString(LocalAddressBook.USER_DATA_ACCOUNT_TYPE, account.type) + putString(LocalAddressBook.USER_DATA_ACCOUNT_NAME, existingAccount.name) + putString(LocalAddressBook.USER_DATA_ACCOUNT_TYPE, existingAccount.type) } assertTrue(accountManager.addAccountExplicitly(addressBookAccount, null, userData)) - - val addressBookAccounts = accountManager.getAccountsByType(addressBookAccountType) - assertEquals(addressBookAccount, addressBookAccounts.firstOrNull()) + assertEquals(listOf(addressBookAccount), accountManager.getAccountsByType(addressBookAccountType).toList()) // Create worker and run the method val worker = TestListenableWorkerBuilder(context) @@ -157,15 +147,15 @@ class AccountsCleanupWorkerTest { worker.cleanUpAddressBooks() // Verify account was _not_ deleted - assertEquals(addressBookAccount, addressBookAccounts.firstOrNull()) + assertEquals(listOf(addressBookAccount), accountManager.getAccountsByType(addressBookAccountType).toList()) } } // helpers - private fun createTestService(serviceType: String): Service { - val service = Service(id=0, accountName="test", type=serviceType, principal = null) + private fun createTestService(): Service { + val service = Service(id=0, accountName="test", type=Service.TYPE_CARDDAV, principal = null) val serviceId = db.serviceDao().insertOrReplace(service) return db.serviceDao().get(serviceId)!! } diff --git a/app/src/androidTest/kotlin/at/bitfire/davdroid/sync/account/SystemAccountUtilsTest.kt b/app/src/androidTest/kotlin/at/bitfire/davdroid/sync/account/SystemAccountUtilsTest.kt index c3ef133e1..b05b36d27 100644 --- a/app/src/androidTest/kotlin/at/bitfire/davdroid/sync/account/SystemAccountUtilsTest.kt +++ b/app/src/androidTest/kotlin/at/bitfire/davdroid/sync/account/SystemAccountUtilsTest.kt @@ -32,11 +32,6 @@ class SystemAccountUtilsTest { @Inject lateinit var settingsManager: SettingsManager - val account = Account( - "AccountUtilsTest", - context.getString(R.string.account_type) - ) - @Before fun setUp() { hiltRule.inject() @@ -49,6 +44,7 @@ class SystemAccountUtilsTest { userData.putString("int", "1") userData.putString("string", "abc/\"-") + val account = Account("AccountUtilsTest", context.getString(R.string.account_type)) val manager = AccountManager.get(context) try { assertTrue(SystemAccountUtils.createAccount(context, account, userData)) diff --git a/app/src/main/res/xml/sync_calendars.xml b/app/src/main/res/xml/sync_calendars.xml index 7b01f2054..d047b5d56 100644 --- a/app/src/main/res/xml/sync_calendars.xml +++ b/app/src/main/res/xml/sync_calendars.xml @@ -1,6 +1,6 @@ \ No newline at end of file + android:supportsUploading="true" + android:allowParallelSyncs="true" /> \ No newline at end of file diff --git a/app/src/main/res/xml/sync_contacts.xml b/app/src/main/res/xml/sync_contacts.xml index 87b67ec1c..23a5173a1 100644 --- a/app/src/main/res/xml/sync_contacts.xml +++ b/app/src/main/res/xml/sync_contacts.xml @@ -1,6 +1,6 @@ \ No newline at end of file + android:supportsUploading="true" + android:allowParallelSyncs="true" /> \ No newline at end of file diff --git a/app/src/main/res/xml/sync_notes.xml b/app/src/main/res/xml/sync_notes.xml index 1db9a29d0..d571b982f 100644 --- a/app/src/main/res/xml/sync_notes.xml +++ b/app/src/main/res/xml/sync_notes.xml @@ -1,6 +1,6 @@ \ No newline at end of file + android:supportsUploading="true" + android:allowParallelSyncs="true" /> \ No newline at end of file diff --git a/app/src/main/res/xml/sync_opentasks.xml b/app/src/main/res/xml/sync_opentasks.xml index dfa5c7984..6e82cdf2c 100644 --- a/app/src/main/res/xml/sync_opentasks.xml +++ b/app/src/main/res/xml/sync_opentasks.xml @@ -1,6 +1,6 @@ \ No newline at end of file + android:supportsUploading="true" + android:allowParallelSyncs="true" /> \ No newline at end of file diff --git a/app/src/main/res/xml/sync_tasks_org.xml b/app/src/main/res/xml/sync_tasks_org.xml index ecd712be5..f93254975 100644 --- a/app/src/main/res/xml/sync_tasks_org.xml +++ b/app/src/main/res/xml/sync_tasks_org.xml @@ -1,6 +1,6 @@ \ No newline at end of file + android:supportsUploading="true" + android:allowParallelSyncs="true" /> \ No newline at end of file