Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add accounts to DB #1205

Draft
wants to merge 8 commits into
base: main-ose
Choose a base branch
from
711 changes: 711 additions & 0 deletions app/schemas/at.bitfire.davdroid.db.AppDatabase/17.json

Large diffs are not rendered by default.

723 changes: 723 additions & 0 deletions app/schemas/at.bitfire.davdroid.db.AppDatabase/18.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import org.junit.Assert.assertNull
import org.junit.Test

@HiltAndroidTest
class AutoMigration16Test: DatabaseMigrationTest(toVersion = 16) {
class AutoMigration16Test: DatabaseMigrationTest(fromVersion = 15, toVersion = 16) {

@Test
fun testMigrate_WithTimeZone() = testMigration(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ import org.junit.Rule
import javax.inject.Inject

/**
* Helper for testing the database migration from [toVersion] - 1 to [toVersion].
* Helper for testing the database migration from [fromVersion] to [toVersion].
*
* @param fromVersion The source version to migrate from (usually `toVersion - 1`).
* @param toVersion The target version to migrate to.
*/
abstract class DatabaseMigrationTest(
private val fromVersion: Int,
private val toVersion: Int
) {

Expand All @@ -42,14 +44,14 @@ abstract class DatabaseMigrationTest(


/**
* Used for testing the migration process from [toVersion]-1 to [toVersion].
* Used for testing the migration process from [fromVersion] to [toVersion].
*
* @param prepare Callback to prepare the database. Will be run with database schema in version [toVersion] - 1.
* @param validate Callback to validate the migration result. Will be run with database schema in version [toVersion].
* @param prepare Callback to prepare the database. Will be run with database schema in version [fromVersion].
* @param verify Callback to verify the migration result. Will be run with database schema in version [toVersion].
*/
protected fun testMigration(
prepare: (SupportSQLiteDatabase) -> Unit,
validate: (SupportSQLiteDatabase) -> Unit
verify: (SupportSQLiteDatabase) -> Unit
) {
val helper = MigrationTestHelper(
InstrumentationRegistry.getInstrumentation(),
Expand All @@ -60,7 +62,7 @@ abstract class DatabaseMigrationTest(

// Prepare the database with the initial version.
val dbName = "test"
helper.createDatabase(dbName, version = toVersion - 1).apply {
helper.createDatabase(dbName, version = fromVersion).apply {
prepare(this)
close()
}
Expand All @@ -73,7 +75,7 @@ abstract class DatabaseMigrationTest(
migrations = manualMigrations.toTypedArray()
)

validate(db)
verify(db)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/

package at.bitfire.davdroid.db.migration

import at.bitfire.davdroid.db.Service
import dagger.hilt.android.testing.HiltAndroidTest
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

@Suppress("ClassName")
@HiltAndroidTest
class Migration17_18Test: DatabaseMigrationTest(fromVersion = 16, toVersion = 18) {

@Test
fun testMigrate_WithServices() = testMigration(
prepare = { db ->
db.execSQL(
"INSERT INTO service (accountName, type) VALUES (?, ?)",
arrayOf("test1", Service.Companion.TYPE_CALDAV)
)
db.execSQL(
"INSERT INTO service (accountName, type) VALUES (?, ?)",
arrayOf("test1", Service.Companion.TYPE_CARDDAV)
)

db.execSQL(
"INSERT INTO service (accountName, type) VALUES (?, ?)",
arrayOf("test2", Service.Companion.TYPE_CALDAV)
)

db.execSQL(
"INSERT INTO service (accountName, type) VALUES (?, ?)",
arrayOf("test3", Service.Companion.TYPE_CARDDAV)
)
}
) { db ->
db.query("SELECT name FROM account ORDER BY name").use { cursor ->
assertTrue(cursor.moveToFirst())
assertEquals("test1", cursor.getString(0))

assertTrue(cursor.moveToNext())
assertEquals("test2", cursor.getString(0))

assertTrue(cursor.moveToNext())
assertEquals("test3", cursor.getString(0))

assertFalse(cursor.moveToNext())
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/

package at.bitfire.davdroid.repository

import android.content.Context
import at.bitfire.davdroid.db.AppDatabase
import at.bitfire.davdroid.sync.account.TestAccount
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import javax.inject.Inject
import at.bitfire.davdroid.db.Account as DbAccount

@HiltAndroidTest
class AccountRepositoryTest {

@Inject
lateinit var accountRepository: AccountRepository

@Inject @ApplicationContext
lateinit var context: Context

@Inject
lateinit var db: AppDatabase

@get:Rule
val hiltRule = HiltAndroidRule(this)

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


@Test
fun testRemoveOrphanedInDb() {
TestAccount.provide { systemAccount ->
val dao = db.accountDao()
dao.insertOrIgnore(DbAccount(id = 1, name = systemAccount.name))
dao.insertOrIgnore(DbAccount(id = 2, name = "no-corresponding-system-account"))

accountRepository.removeOrphanedInDb()

// now the account without a corresponding system account should be removed
assertEquals(listOf(DbAccount(id = 1, name = systemAccount.name)), db.accountDao().getAll())
}
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package at.bitfire.davdroid.repository

import android.accounts.Account
import android.content.Context
import at.bitfire.davdroid.db.AppDatabase
import at.bitfire.davdroid.db.Collection
import at.bitfire.davdroid.db.Service
import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.sync.account.TestAccount
import dagger.Lazy
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.testing.HiltAndroidRule
Expand All @@ -18,13 +20,17 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import javax.inject.Inject
import at.bitfire.davdroid.db.Account as DbAccount

@HiltAndroidTest
class DavCollectionRepositoryTest {

@get:Rule
var hiltRule = HiltAndroidRule(this)

@Inject
lateinit var accountRepository: AccountRepository

@Inject
lateinit var accountSettingsFactory: AccountSettings.Factory

Expand All @@ -38,33 +44,40 @@ class DavCollectionRepositoryTest {
@Inject
lateinit var serviceRepository: DavServiceRepository

var service: Service? = null
lateinit var account: Account
var serviceId: Long = 0L

@Before
fun setUp() {
hiltRule.inject()
service = createTestService(Service.TYPE_CARDDAV)!!

account = TestAccount.create()
db.accountDao().insertOrIgnore(DbAccount(name = account.name))

val service = Service(id=0, accountName=account.name, type= Service.TYPE_CALDAV, principal = null)
serviceId = serviceRepository.insertOrReplace(service)
}

@After
fun cleanUp() {
db.close()
fun tearDown() {
serviceRepository.deleteAll()
TestAccount.remove(account)
}


@Test
fun testOnChangeListener_setForceReadOnly() = runBlocking {
val collectionId = db.collectionDao().insertOrUpdateByUrl(
Collection(
serviceId = service!!.id,
serviceId = serviceId,
type = Collection.TYPE_ADDRESSBOOK,
url = "https://example.com".toHttpUrl(),
forceReadOnly = false,
)
)
val testObserver = mockk<DavCollectionRepository.OnChangeListener>(relaxed = true)
val collectionRepository = DavCollectionRepository(
accountRepository,
accountSettingsFactory,
context,
db,
Expand All @@ -87,13 +100,4 @@ class DavCollectionRepositoryTest {
}
}


// Test helpers and dependencies

private fun createTestService(serviceType: String) : Service? {
val service = Service(id=0, accountName="test", type=serviceType, principal = null)
val serviceId = serviceRepository.insertOrReplace(service)
return serviceRepository.get(serviceId)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,61 @@

package at.bitfire.davdroid.repository

import android.accounts.Account
import at.bitfire.davdroid.db.AppDatabase
import at.bitfire.davdroid.db.HomeSet
import at.bitfire.davdroid.db.Service
import at.bitfire.davdroid.sync.account.TestAccount
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import okhttp3.HttpUrl.Companion.toHttpUrl
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import javax.inject.Inject
import at.bitfire.davdroid.db.Account as DbAccount

@HiltAndroidTest
class DavHomeSetRepositoryTest {

@get:Rule
var hiltRule = HiltAndroidRule(this)

@Inject
lateinit var db: AppDatabase

@Inject
lateinit var repository: DavHomeSetRepository

@Inject
lateinit var serviceRepository: DavServiceRepository

lateinit var account: Account
var serviceId: Long = 0L


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

account = TestAccount.create()
db.accountDao().insertOrIgnore(DbAccount(name = account.name))

val service = Service(id=0, accountName=account.name, type= Service.TYPE_CALDAV, principal = null)
serviceId = serviceRepository.insertOrReplace(service)
}

@After
fun tearDown() {
TestAccount.remove(account)
}


@Test
fun testInsertOrUpdate() {
// should insert new row or update (upsert) existing row - without changing its key!
val serviceId = createTestService()

val entry1 = HomeSet(id=0, serviceId=serviceId, personal=true, url="https://example.com/1".toHttpUrl())
val insertId1 = repository.insertOrUpdateByUrl(entry1)
assertEquals(1L, insertId1)
Expand All @@ -57,8 +78,6 @@ class DavHomeSetRepositoryTest {
@Test
fun testDelete() {
// should delete row with given primary key (id)
val serviceId = createTestService()

val entry1 = HomeSet(id=1, serviceId=serviceId, personal=true, url= "https://example.com/1".toHttpUrl())

val insertId1 = repository.insertOrUpdateByUrl(entry1)
Expand All @@ -69,10 +88,4 @@ class DavHomeSetRepositoryTest {
assertEquals(null, repository.getById(1L))
}


private fun createTestService() : Long {
val service = Service(id=0, accountName="test", type= Service.TYPE_CALDAV, principal = null)
return serviceRepository.insertOrReplace(service)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import android.content.ContentUris
import android.content.Context
import android.provider.ContactsContract
import at.bitfire.davdroid.R
import at.bitfire.davdroid.repository.AccountRepository
import at.bitfire.davdroid.repository.DavCollectionRepository
import at.bitfire.davdroid.repository.DavServiceRepository
import at.bitfire.davdroid.settings.AccountSettings
Expand All @@ -34,6 +35,7 @@ class LocalTestAddressBook @AssistedInject constructor(
@Assisted("addressBook") addressBookAccount: Account,
@Assisted provider: ContentProviderClient,
@Assisted override val groupMethod: GroupMethod,
accountRepository: AccountRepository,
accountSettingsFactory: AccountSettings.Factory,
collectionRepository: DavCollectionRepository,
@ApplicationContext private val context: Context,
Expand All @@ -44,6 +46,7 @@ class LocalTestAddressBook @AssistedInject constructor(
account = account,
_addressBookAccount = addressBookAccount,
provider = provider,
accountRepository = accountRepository,
accountSettingsFactory = accountSettingsFactory,
collectionRepository = collectionRepository,
context = context,
Expand Down
Loading
Loading