509 lines
17 KiB
Kotlin
509 lines
17 KiB
Kotlin
/*
|
|
* Copyright (c) 2022 Proton AG
|
|
*
|
|
* This file is part of Proton Mail.
|
|
*
|
|
* Proton Mail is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Proton Mail is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Proton Mail. If not, see https://www.gnu.org/licenses/.
|
|
*/
|
|
package ch.protonmail.android.api.models.room.contacts
|
|
|
|
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
|
import androidx.test.InstrumentationRegistry
|
|
import ch.protonmail.android.api.models.ContactEncryptedData
|
|
import ch.protonmail.android.api.models.MessageRecipient
|
|
import ch.protonmail.android.api.models.room.testValue
|
|
import ch.protonmail.android.core.Constants
|
|
import ch.protonmail.android.data.local.ContactDao
|
|
import ch.protonmail.android.data.local.ContactDatabase
|
|
import ch.protonmail.android.data.local.model.ContactData
|
|
import ch.protonmail.android.data.local.model.ContactEmail
|
|
import ch.protonmail.android.data.local.model.FullContactDetails
|
|
import kotlinx.coroutines.runBlocking
|
|
import org.hamcrest.Matchers.`is`
|
|
import org.junit.Assert
|
|
import org.junit.Rule
|
|
import org.junit.Test
|
|
import kotlin.test.BeforeTest
|
|
|
|
internal class ContactDaoTest {
|
|
|
|
private val context = InstrumentationRegistry.getTargetContext()
|
|
private var databaseFactory = ContactDatabase.buildInMemoryDatabase(context)
|
|
private var database = databaseFactory.getDao()
|
|
private val initiallyEmptyDatabase = databaseFactory.getDao()
|
|
|
|
@get:Rule
|
|
var instantTaskExecutorRule = InstantTaskExecutorRule()
|
|
|
|
private val contactData = listOf(
|
|
ContactData(contactId = "aa", name = "aaa").apply { dbId = 2 },
|
|
ContactData(contactId = "bb", name = "bbb").apply { dbId = 4 },
|
|
ContactData(contactId = "cc", name = "ccc").apply { dbId = 3 },
|
|
ContactData(contactId = "dd", name = "ddd").apply { dbId = 1 },
|
|
ContactData(contactId = "ee", name = "eee").apply { dbId = 7 }
|
|
)
|
|
|
|
|
|
private val contactEmails = listOf(
|
|
ContactEmail(
|
|
contactEmailId = "a",
|
|
email = "a@a.com",
|
|
contactId = "aa",
|
|
labelIds = listOf("aaa", "aaaa", "aaaaa"),
|
|
name = "ce1",
|
|
lastUsedTime = 111
|
|
),
|
|
ContactEmail(
|
|
contactEmailId = "b",
|
|
email = "b@b.com",
|
|
contactId = "bb",
|
|
labelIds = listOf("bbb", "bbbb", "bbbbb"),
|
|
name = "ce2",
|
|
lastUsedTime = 113
|
|
),
|
|
ContactEmail(
|
|
contactEmailId = "c",
|
|
email = "c@c.com",
|
|
contactId = "bb",
|
|
labelIds = listOf("ccc", "cccc", "ccccc"),
|
|
name = "ce3",
|
|
lastUsedTime = 115
|
|
),
|
|
ContactEmail(
|
|
contactEmailId = "d",
|
|
email = "b@b.com",
|
|
contactId = "dd",
|
|
labelIds = listOf("ddd", "dddd", "ddddd"),
|
|
name = "ce4",
|
|
lastUsedTime = 114
|
|
),
|
|
ContactEmail(
|
|
contactEmailId = "e",
|
|
email = "e@e.com",
|
|
contactId = "ee",
|
|
labelIds = listOf("eee", "eeee", "eeeee"),
|
|
name = "ce5",
|
|
lastUsedTime = 112
|
|
)
|
|
)
|
|
|
|
private val fullContactDetails = listOf(
|
|
FullContactDetails(
|
|
contactId = "a",
|
|
name = "aa",
|
|
uid = "aaa",
|
|
createTime = 1,
|
|
modifyTime = 1,
|
|
size = 5,
|
|
defaults = 3,
|
|
encryptedData = mutableListOf(
|
|
ContactEncryptedData("aaaa", "aaaaa", Constants.VCardType.SIGNED),
|
|
ContactEncryptedData("aaaaaa", "aaaaaaa", Constants.VCardType.SIGNED_ENCRYPTED)
|
|
)
|
|
),
|
|
FullContactDetails(
|
|
contactId = "b",
|
|
name = "bb",
|
|
uid = "bbb",
|
|
createTime = 5,
|
|
modifyTime = 7,
|
|
size = 12,
|
|
defaults = 2,
|
|
encryptedData = mutableListOf(
|
|
ContactEncryptedData("bbbb", "bbbbb", Constants.VCardType.SIGNED),
|
|
ContactEncryptedData("bbbbbb", "bbbbbbb", Constants.VCardType.SIGNED_ENCRYPTED)
|
|
)
|
|
),
|
|
FullContactDetails(
|
|
contactId = "c",
|
|
name = "cc",
|
|
uid = "ccc",
|
|
createTime = 12,
|
|
modifyTime = 1100,
|
|
size = 2,
|
|
defaults = 123,
|
|
encryptedData = mutableListOf(
|
|
ContactEncryptedData("cccc", "ccccc", Constants.VCardType.SIGNED),
|
|
ContactEncryptedData("cccccc", "ccccccc", Constants.VCardType.SIGNED_ENCRYPTED)
|
|
)
|
|
),
|
|
FullContactDetails(
|
|
contactId = "d",
|
|
name = "dd",
|
|
uid = "ddd",
|
|
createTime = 3,
|
|
modifyTime = 12,
|
|
size = 112,
|
|
defaults = 31,
|
|
encryptedData = mutableListOf(
|
|
ContactEncryptedData("dddd", "ddddd", Constants.VCardType.SIGNED),
|
|
ContactEncryptedData("dddddd", "ddddddd", Constants.VCardType.SIGNED_ENCRYPTED)
|
|
)
|
|
),
|
|
FullContactDetails(
|
|
contactId = "e",
|
|
name = "ee",
|
|
uid = "eee",
|
|
createTime = 1,
|
|
modifyTime = 131,
|
|
size = 12,
|
|
defaults = 321,
|
|
encryptedData = mutableListOf(
|
|
ContactEncryptedData("eeee", "eeeee", Constants.VCardType.SIGNED),
|
|
ContactEncryptedData("eeeeee", "eeeeeee", Constants.VCardType.SIGNED_ENCRYPTED)
|
|
)
|
|
),
|
|
FullContactDetails("f")
|
|
)
|
|
|
|
private fun ContactDao.populate() {
|
|
runBlocking {
|
|
saveAllContactsData(contactData)
|
|
saveAllContactsEmails(contactEmails)
|
|
}
|
|
fullContactDetails.forEach(this::insertFullContactDetailsBlocking)
|
|
}
|
|
|
|
private fun assertDatabaseState(
|
|
expectedContactData: Iterable<ContactData> = contactData,
|
|
expectedContactEmails: Iterable<ContactEmail> = contactEmails,
|
|
expectedFullContactDetails: Iterable<FullContactDetails> = fullContactDetails
|
|
) {
|
|
val expectedContactDataSet = expectedContactData.toSet()
|
|
val expectedContactEmailsSet = expectedContactEmails.toSet()
|
|
//hack as encrypted data has equals not defined
|
|
val expectedFullContactDetailsSet = expectedFullContactDetails
|
|
.map { it.apply { encryptedData = mutableListOf() } }.toSet()
|
|
|
|
val actualContactDataSet = database.findAllContactDataAsync().testValue!!.toSet()
|
|
val actualContactEmailsSet = database.findAllContactsEmailsAsync().testValue!!.toSet()
|
|
//hack as encrypted data has equals not defined
|
|
val actualFullContactDetailsSet = expectedFullContactDetails
|
|
.map(FullContactDetails::contactId)
|
|
.map(database::findFullContactDetailsByIdBlocking)
|
|
.map { it?.apply { encryptedData = mutableListOf() } }
|
|
.toSet()
|
|
|
|
Assert.assertEquals(expectedContactDataSet, actualContactDataSet)
|
|
Assert.assertEquals(expectedContactEmailsSet, actualContactEmailsSet)
|
|
Assert.assertEquals(expectedFullContactDetailsSet, actualFullContactDetailsSet)
|
|
}
|
|
|
|
@BeforeTest
|
|
fun setUp() {
|
|
database.populate()
|
|
}
|
|
|
|
@Test
|
|
fun findContactDataById() {
|
|
val expected = contactData[3]
|
|
val actual = database.findContactDataByIdBlocking(expected.contactId!!)
|
|
Assert.assertEquals(expected, actual)
|
|
assertDatabaseState()
|
|
}
|
|
|
|
@Test
|
|
fun findContactDataByDbId() {
|
|
val expected = contactData[3]
|
|
val actual = database.findContactDataByDbId(expected.dbId!!)
|
|
Assert.assertEquals(expected, actual)
|
|
assertDatabaseState()
|
|
}
|
|
|
|
@Test
|
|
fun findAllContactDataAsync() {
|
|
val expected = contactData
|
|
val actual = database.findAllContactDataAsync().testValue
|
|
Assert.assertEquals(expected, actual)
|
|
assertDatabaseState()
|
|
}
|
|
|
|
@Test
|
|
fun clearContactDataCache() {
|
|
database.clearContactDataCache()
|
|
assertDatabaseState(expectedContactData = emptyList())
|
|
}
|
|
|
|
@Test
|
|
fun saveContactData() {
|
|
val inserted = ContactData("z", "zz")
|
|
val expected = contactData + inserted
|
|
database.saveContactDataBlocking(inserted)
|
|
assertDatabaseState(expectedContactData = expected)
|
|
}
|
|
|
|
@Test
|
|
fun saveAllContactsData() {
|
|
runBlocking {
|
|
val inserted = listOf(
|
|
ContactData("y", "yy"), ContactData("z", "zz")
|
|
)
|
|
val expected = contactData + inserted
|
|
database.saveAllContactsData(inserted)
|
|
assertDatabaseState(expectedContactData = expected)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
fun saveAllContactsData1() {
|
|
val inserted = listOf(
|
|
ContactData("y", "yy"), ContactData("z", "zz")
|
|
)
|
|
val expected = contactData + inserted
|
|
database.saveAllContactsData(*inserted.toTypedArray())
|
|
assertDatabaseState(expectedContactData = expected)
|
|
}
|
|
|
|
@Test
|
|
fun deleteContactData() {
|
|
val deleted = contactData[3]
|
|
val expected = contactData - deleted
|
|
database.deleteContactData(deleted)
|
|
assertDatabaseState(expectedContactData = expected)
|
|
}
|
|
|
|
@Test
|
|
fun deleteContactsData() {
|
|
val deleted = listOf(contactData[3], contactData[1])
|
|
val expected = contactData - deleted
|
|
database.deleteContactsData(deleted)
|
|
assertDatabaseState(expectedContactData = expected)
|
|
}
|
|
|
|
@Test
|
|
fun findContactEmailById() = runBlocking{
|
|
val expected = contactEmails[2]
|
|
val actual = database.findContactEmailById(expected.contactEmailId!!)
|
|
Assert.assertEquals(expected, actual)
|
|
assertDatabaseState()
|
|
}
|
|
|
|
@Test
|
|
fun findContactEmailByEmail() {
|
|
val expected = contactEmails[2]
|
|
val actual = database.findContactEmailByEmailBlocking(expected.email)
|
|
Assert.assertEquals(expected, actual)
|
|
assertDatabaseState()
|
|
}
|
|
|
|
@Test
|
|
fun findContactEmailsByContactId() {
|
|
val contactId = contactEmails[2].contactId!!
|
|
val expected = contactEmails.filter { it.contactId == contactId }
|
|
val actual = database.findContactEmailsByContactIdBlocking(contactId)
|
|
Assert.assertEquals(expected, actual)
|
|
assertDatabaseState()
|
|
}
|
|
|
|
@Test
|
|
fun findAllContactsEmailsAsync() {
|
|
val expected = contactEmails.toSet()
|
|
val actual = database.findAllContactsEmailsAsync().testValue?.toSet()
|
|
Assert.assertEquals(expected, actual)
|
|
assertDatabaseState()
|
|
}
|
|
|
|
@Test
|
|
fun findAllMessageRecipients() {
|
|
// given
|
|
val expected = contactEmails
|
|
.sortedByDescending { it.lastUsedTime }
|
|
.map { contactEmail ->
|
|
MessageRecipient(contactData.find { it.contactId == contactEmail.contactId }?.name, contactEmail.email)
|
|
}.toSet()
|
|
|
|
// when
|
|
val actual = database.findAllMessageRecipients().blockingFirst().toSet()
|
|
|
|
// then
|
|
Assert.assertEquals(expected, actual)
|
|
assertDatabaseState()
|
|
}
|
|
|
|
@Test
|
|
fun clearByEmail() {
|
|
val deletedEmail = contactEmails[1].email
|
|
val expected = contactEmails.filterNot { it.email == deletedEmail }
|
|
database.clearByEmailBlocking(deletedEmail)
|
|
assertDatabaseState(expectedContactEmails = expected)
|
|
}
|
|
|
|
@Test
|
|
fun clearContactEmailsCache() {
|
|
val expected = emptyList<ContactEmail>()
|
|
database.clearContactEmailsCache()
|
|
assertDatabaseState(expectedContactEmails = expected)
|
|
}
|
|
|
|
@Test
|
|
fun deleteContactEmail() {
|
|
val deleted = listOf(contactEmails[3], contactEmails[1])
|
|
val expected = contactEmails - deleted
|
|
database.deleteContactEmail(*deleted.toTypedArray())
|
|
assertDatabaseState(expectedContactEmails = expected)
|
|
}
|
|
|
|
@Test
|
|
fun deleteAllContactsEmails() {
|
|
val deleted = listOf(contactEmails[3], contactEmails[1])
|
|
val expected = contactEmails - deleted
|
|
database.deleteAllContactsEmailsBlocking(deleted)
|
|
assertDatabaseState(expectedContactEmails = expected)
|
|
}
|
|
|
|
@Test
|
|
fun saveContactEmail() = runBlocking {
|
|
val inserted = ContactEmail(
|
|
"z",
|
|
"z@z.com",
|
|
contactId = "zzz",
|
|
labelIds = listOf("zzzz", "zzzzz", "zzzzzz"),
|
|
name = "ce1",
|
|
lastUsedTime = 116
|
|
)
|
|
val expected = contactEmails + inserted
|
|
database.saveContactEmail(inserted)
|
|
assertDatabaseState(expectedContactEmails = expected)
|
|
}
|
|
|
|
@Test
|
|
fun saveAllContactsEmails() {
|
|
val inserted = listOf(
|
|
ContactEmail(
|
|
"y",
|
|
"y@y.com",
|
|
contactId = "yyy",
|
|
labelIds = listOf("yyyy", "yyyyy", "yyyyyy"),
|
|
name = "ce1",
|
|
lastUsedTime = 118
|
|
),
|
|
ContactEmail(
|
|
"z",
|
|
"z@z.com",
|
|
contactId = "zzz",
|
|
labelIds = listOf("zzzz", "zzzzz", "zzzzzz"),
|
|
name = "ce2",
|
|
lastUsedTime = 116
|
|
)
|
|
)
|
|
val expected = contactEmails + inserted
|
|
database.saveAllContactsEmailsBlocking(inserted)
|
|
assertDatabaseState(expectedContactEmails = expected)
|
|
}
|
|
|
|
@Test
|
|
fun saveAllContactsEmails1() = runBlocking{
|
|
val inserted = listOf(
|
|
ContactEmail(
|
|
"y",
|
|
"y@y.com",
|
|
contactId = "yyy",
|
|
labelIds = listOf("yyyy", "yyyyy", "yyyyyy"),
|
|
name = "ce1",
|
|
lastUsedTime = 118
|
|
),
|
|
ContactEmail(
|
|
"z",
|
|
"z@z.com",
|
|
contactId = "zzz",
|
|
labelIds = listOf("zzzz", "zzzzz", "zzzzzz"),
|
|
name = "ce2",
|
|
lastUsedTime = 116
|
|
)
|
|
)
|
|
val expected = contactEmails + inserted
|
|
database.saveAllContactsEmails(inserted)
|
|
assertDatabaseState(expectedContactEmails = expected)
|
|
}
|
|
|
|
@Test
|
|
fun insertFullContactDetails() {
|
|
val inserted = FullContactDetails(
|
|
contactId = "z",
|
|
name = "zz",
|
|
uid = "zzz",
|
|
createTime = 1,
|
|
modifyTime = 131,
|
|
size = 12,
|
|
defaults = 321,
|
|
encryptedData = mutableListOf(
|
|
ContactEncryptedData("zzzz", "zzzzz", Constants.VCardType.SIGNED),
|
|
ContactEncryptedData("zzzzzz", "zzzzzzz", Constants.VCardType.SIGNED_ENCRYPTED)
|
|
)
|
|
)
|
|
val expected = fullContactDetails + inserted
|
|
database.insertFullContactDetailsBlocking(inserted)
|
|
assertDatabaseState(expectedFullContactDetails = expected)
|
|
}
|
|
|
|
@Test
|
|
fun findFullContactDetailsById() {
|
|
val expected = fullContactDetails[1]
|
|
val actual = database.findFullContactDetailsByIdBlocking(expected.contactId)
|
|
Assert.assertThat(
|
|
actual, `is`(FullContactsDetailsMatcher(expected))
|
|
)
|
|
assertDatabaseState()
|
|
}
|
|
|
|
@Test
|
|
fun clearFullContactDetailsCache() {
|
|
val expected = emptyList<FullContactDetails>()
|
|
database.clearFullContactDetailsCache()
|
|
assertDatabaseState(expectedFullContactDetails = expected)
|
|
}
|
|
|
|
@Test
|
|
fun deleteFullContactsDetails() {
|
|
val deleted = fullContactDetails[1]
|
|
val expected = fullContactDetails - deleted
|
|
database.deleteFullContactsDetails(deleted)
|
|
val found = database.findFullContactDetailsByIdBlocking(deleted.contactId)
|
|
Assert.assertNull(found)
|
|
assertDatabaseState(expectedFullContactDetails = expected)
|
|
}
|
|
|
|
@Test
|
|
fun testContactEmailsConverter() = runBlocking {
|
|
val email1 = ContactEmail(
|
|
"e1",
|
|
"1@1.1",
|
|
"a",
|
|
labelIds = listOf("la", "lc"),
|
|
lastUsedTime = 121
|
|
)
|
|
val email2 = ContactEmail(
|
|
"e2",
|
|
"2@2.2",
|
|
"b",
|
|
labelIds = listOf("la", "lc"),
|
|
lastUsedTime = 123
|
|
)
|
|
val email3 = ContactEmail(
|
|
"e3",
|
|
"3@3.3",
|
|
"c",
|
|
labelIds = listOf("la", "lc"),
|
|
lastUsedTime = 122
|
|
)
|
|
initiallyEmptyDatabase.saveAllContactsEmails(listOf(email1, email2, email3))
|
|
val emailFromDb = initiallyEmptyDatabase.findContactEmailById("e1")
|
|
Assert.assertNotNull(emailFromDb)
|
|
val listOfGroups = emailFromDb?.labelIds
|
|
Assert.assertNotNull(listOfGroups)
|
|
val expectedGroupId = "la"
|
|
Assert.assertEquals(expectedGroupId, listOfGroups?.get(0))
|
|
}
|
|
}
|