More logic added to ContactDetailsViewModel and some refactor of related components.
MAILAND-1875
This commit is contained in:
parent
cb9dc91e8b
commit
11a89b21f4
|
@ -186,7 +186,7 @@ internal class ContactDaoTest {
|
|||
//hack as encrypted data has equals not defined
|
||||
val actualFullContactDetailsSet = expectedFullContactDetails
|
||||
.map(FullContactDetails::contactId)
|
||||
.map(database::findFullContactDetailsById)
|
||||
.map(database::findFullContactDetailsByIdBlocking)
|
||||
.map { it?.apply { encryptedData = mutableListOf() } }
|
||||
.toSet()
|
||||
|
||||
|
@ -296,7 +296,7 @@ internal class ContactDaoTest {
|
|||
fun findContactEmailsByContactId() {
|
||||
val contactId = contactEmails[2].contactId!!
|
||||
val expected = contactEmails.filter { it.contactId == contactId }
|
||||
val actual = database.findContactEmailsByContactId(contactId)
|
||||
val actual = database.findContactEmailsByContactIdBlocking(contactId)
|
||||
Assert.assertEquals(expected, actual)
|
||||
assertDatabaseState()
|
||||
}
|
||||
|
@ -535,7 +535,7 @@ internal class ContactDaoTest {
|
|||
@Test
|
||||
fun findFullContactDetailsById() {
|
||||
val expected = fullContactDetails[1]
|
||||
val actual = database.findFullContactDetailsById(expected.contactId)
|
||||
val actual = database.findFullContactDetailsByIdBlocking(expected.contactId)
|
||||
Assert.assertThat(
|
||||
actual, `is`(FullContactsDetailsMatcher(expected))
|
||||
)
|
||||
|
@ -554,7 +554,7 @@ internal class ContactDaoTest {
|
|||
val deleted = fullContactDetails[1]
|
||||
val expected = fullContactDetails - deleted
|
||||
database.deleteFullContactsDetails(deleted)
|
||||
val found = database.findFullContactDetailsById(deleted.contactId)
|
||||
val found = database.findFullContactDetailsByIdBlocking(deleted.contactId)
|
||||
Assert.assertNull(found)
|
||||
assertDatabaseState(expectedFullContactDetails = expected)
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ class ExtractFullContactDetailsTask(
|
|||
|
||||
override fun doInBackground(vararg voids: Void): FullContactDetails? {
|
||||
return try {
|
||||
contactDao.findFullContactDetailsById(contactId)
|
||||
contactDao.findFullContactDetailsByIdBlocking(contactId)
|
||||
} catch (tooBigException: SQLiteBlobTooBigException) {
|
||||
Timber.i(tooBigException, "Data too big to be fetched")
|
||||
null
|
||||
|
|
|
@ -466,7 +466,7 @@ class EventHandler @AssistedInject constructor(
|
|||
}
|
||||
|
||||
val localFullContact = try {
|
||||
contactDao.findFullContactDetailsById(contactId)
|
||||
contactDao.findFullContactDetailsByIdBlocking(contactId)
|
||||
} catch (tooBigException: SQLiteBlobTooBigException) {
|
||||
Timber.i(tooBigException, "Data too big to be fetched")
|
||||
null
|
||||
|
|
|
@ -20,15 +20,18 @@
|
|||
package ch.protonmail.android.contacts.details
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import ch.protonmail.android.R
|
||||
import ch.protonmail.android.databinding.ActivityContactDetailsBinding
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ContactDetailsActivity : AppCompatActivity() {
|
||||
|
||||
private val viewModel by viewModels<ContactDetailsViewModel>()
|
||||
private val viewModel: ContactDetailsViewModel by viewModels()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -45,6 +48,14 @@ class ContactDetailsActivity : AppCompatActivity() {
|
|||
viewModel.getContactDetails(contactId)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (item.itemId == android.R.id.home) {
|
||||
onBackPressed()
|
||||
return true
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
super.onBackPressed()
|
||||
finish()
|
||||
|
|
|
@ -30,6 +30,9 @@ import ch.protonmail.android.worker.RemoveMembersFromContactGroupWorker
|
|||
import com.birbit.android.jobqueue.JobManager
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Observable
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.withContext
|
||||
import me.proton.core.util.kotlin.DispatcherProvider
|
||||
import me.proton.core.util.kotlin.toInt
|
||||
|
@ -50,11 +53,16 @@ open class ContactDetailsRepository @Inject constructor(
|
|||
.toObservable()
|
||||
}
|
||||
|
||||
fun getContactEmails(id: String): Observable<List<ContactEmail>> {
|
||||
@Deprecated("Use non rx version observeContactEmails")
|
||||
fun getContactEmailsBlocking(id: String): Observable<List<ContactEmail>> {
|
||||
return contactDao.findContactEmailsByContactIdObservable(id)
|
||||
.toObservable()
|
||||
}
|
||||
|
||||
suspend fun getContactEmails(contactId: String): List<ContactEmail> =
|
||||
contactDao.findContactEmailsByContactId(contactId)
|
||||
|
||||
@Deprecated("Use non rx version observeContactGroups")
|
||||
fun getContactGroups(): Observable<List<ContactLabel>> {
|
||||
return Observable.concatArrayDelayError(
|
||||
getContactGroupsFromDB(),
|
||||
|
@ -63,6 +71,16 @@ open class ContactDetailsRepository @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
fun observeContactGroups(): Flow<List<ContactLabel>> = observeContactGroupsFromDb()
|
||||
.onEach { fetchContactGroupsFromApi() }
|
||||
|
||||
private suspend fun fetchContactGroupsFromApi() {
|
||||
api.fetchContactGroupsList().also {
|
||||
contactDao.clearContactGroupsLabelsTable()
|
||||
contactDao.saveContactGroupsList(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getContactGroupsFromApi(): Observable<List<ContactLabel>> {
|
||||
return api.fetchContactGroupsAsObservable().doOnNext {
|
||||
contactDao.clearContactGroupsLabelsTableBlocking()
|
||||
|
@ -84,6 +102,12 @@ open class ContactDetailsRepository @Inject constructor(
|
|||
.toObservable()
|
||||
}
|
||||
|
||||
private fun observeContactGroupsFromDb() = contactDao.observeContactGroups()
|
||||
.map { labels ->
|
||||
labels.map { label -> label.contactEmailsCount = contactDao.countContactEmailsByLabelId(label.ID) }
|
||||
labels
|
||||
}
|
||||
|
||||
fun editContactGroup(contactLabel: ContactLabel): Completable {
|
||||
val contactLabelConverterFactory = ContactLabelFactory()
|
||||
val labelBody = contactLabelConverterFactory.createServerObjectFromDBObject(contactLabel)
|
||||
|
@ -107,7 +131,9 @@ open class ContactDetailsRepository @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun setMembersForContactGroup(contactGroupId: String, contactGroupName: String, membersList: List<String>): Completable {
|
||||
fun setMembersForContactGroup(
|
||||
contactGroupId: String, contactGroupName: String, membersList: List<String>
|
||||
): Completable {
|
||||
val labelContactsBody = LabelContactsBody(contactGroupId, membersList)
|
||||
return api.labelContacts(labelContactsBody)
|
||||
.doOnComplete {
|
||||
|
@ -119,7 +145,9 @@ open class ContactDetailsRepository @Inject constructor(
|
|||
}
|
||||
.doOnError { throwable ->
|
||||
if (throwable is IOException) {
|
||||
jobManager.addJobInBackground(SetMembersForContactGroupJob(contactGroupId, contactGroupName, membersList))
|
||||
jobManager.addJobInBackground(
|
||||
SetMembersForContactGroupJob(contactGroupId, contactGroupName, membersList)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -163,7 +191,7 @@ open class ContactDetailsRepository @Inject constructor(
|
|||
suspend fun updateAllContactEmails(contactId: String?, contactServerEmails: List<ContactEmail>) {
|
||||
withContext(dispatcherProvider.Io) {
|
||||
contactId?.let {
|
||||
val localContactEmails = contactDao.findContactEmailsByContactId(it)
|
||||
val localContactEmails = contactDao.findContactEmailsByContactIdBlocking(it)
|
||||
contactDao.deleteAllContactsEmails(localContactEmails)
|
||||
contactDao.saveAllContactsEmails(contactServerEmails)
|
||||
}
|
||||
|
@ -180,4 +208,7 @@ open class ContactDetailsRepository @Inject constructor(
|
|||
return@withContext contactDao.saveContactData(contactData)
|
||||
}
|
||||
|
||||
suspend fun getFullContactDetails(contactId: String): FullContactDetails? =
|
||||
contactDao.findFullContactDetailsById(contactId)
|
||||
|
||||
}
|
||||
|
|
|
@ -19,18 +19,25 @@
|
|||
|
||||
package ch.protonmail.android.contacts.details
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.work.WorkManager
|
||||
import ch.protonmail.android.usecase.fetch.FetchContactDetails
|
||||
import ch.protonmail.android.worker.DeleteContactWorker
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.launch
|
||||
import me.proton.core.user.domain.UserManager
|
||||
import me.proton.core.util.kotlin.DispatcherProvider
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ContactDetailsViewModel @Inject constructor(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
private val fetchContactDetails: FetchContactDetails
|
||||
private val dispatchers: DispatcherProvider,
|
||||
private val contactDetailsRepository: ContactDetailsRepository,
|
||||
private val fetchContactDetails: FetchContactDetails,
|
||||
private val userManager: UserManager,
|
||||
private val workManager: WorkManager
|
||||
) : ViewModel() {
|
||||
|
||||
fun getContactDetails(contactId: String) {
|
||||
|
@ -38,4 +45,43 @@ class ContactDetailsViewModel @Inject constructor(
|
|||
fetchContactDetails(contactId)
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteContact(contactId: String) = DeleteContactWorker.Enqueuer(workManager).enqueue(listOf(contactId))
|
||||
|
||||
fun observeContactGroups() = contactDetailsRepository.observeContactGroups()
|
||||
.flowOn(dispatchers.Io)
|
||||
|
||||
suspend fun observeContactEmails(contactId: String) = contactDetailsRepository.getContactEmails(contactId)
|
||||
|
||||
// private fun decryptAndFillVCard(contact: FullContactDetails?) {
|
||||
// var hasDecryptionError = false
|
||||
// val crypto: Crypto<*> = forUser(userManager, userManager.requireCurrentUserId())
|
||||
// var encData: List<ContactEncryptedData>? = ArrayList()
|
||||
// if (contact != null && contact.encryptedData != null) {
|
||||
// encData = contact.encryptedData
|
||||
// } else {
|
||||
// hasDecryptionError = true
|
||||
// }
|
||||
// for (contactEncryptedData in encData!!) {
|
||||
// if (contactEncryptedData.type == 0) {
|
||||
// mVCardType0 = contactEncryptedData.data
|
||||
// } else if (contactEncryptedData.type == 2) {
|
||||
// mVCardType2 = contactEncryptedData.data
|
||||
// mVCardType2Signature = contactEncryptedData.signature
|
||||
// } else if (contactEncryptedData.type == 3) {
|
||||
// try {
|
||||
// val tct = CipherText(contactEncryptedData.data)
|
||||
// val tdr = crypto.decrypt(tct)
|
||||
// mVCardType3 = tdr.decryptedData
|
||||
// } catch (e: Exception) {
|
||||
// hasDecryptionError = true
|
||||
// Logger.doLogException(e)
|
||||
// }
|
||||
// mVCardType3Signature = contactEncryptedData.signature
|
||||
// }
|
||||
// }
|
||||
// fillVCard(hasDecryptionError)
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@ open class ContactDetailsViewModelOld @Inject constructor(
|
|||
)
|
||||
}
|
||||
},
|
||||
contactDetailsRepository.getContactEmails(contactId).subscribeOn(ThreadSchedulers.io())
|
||||
contactDetailsRepository.getContactEmailsBlocking(contactId).subscribeOn(ThreadSchedulers.io())
|
||||
.doOnError {
|
||||
if (allContactEmails.isEmpty()) {
|
||||
_setupError.postValue(
|
||||
|
|
|
@ -101,7 +101,10 @@ interface ContactDao {
|
|||
fun findContactEmailByEmailLiveData(email: String): LiveData<ContactEmail>
|
||||
|
||||
@Query("SELECT * FROM $TABLE_CONTACT_EMAILS WHERE $COLUMN_CONTACT_EMAILS_CONTACT_ID = :contactId")
|
||||
fun findContactEmailsByContactId(contactId: String): List<ContactEmail>
|
||||
fun findContactEmailsByContactIdBlocking(contactId: String): List<ContactEmail>
|
||||
|
||||
@Query("SELECT * FROM $TABLE_CONTACT_EMAILS WHERE $COLUMN_CONTACT_EMAILS_CONTACT_ID = :contactId")
|
||||
suspend fun findContactEmailsByContactId(contactId: String): List<ContactEmail>
|
||||
|
||||
@Query("SELECT * FROM $TABLE_CONTACT_EMAILS WHERE $COLUMN_CONTACT_EMAILS_CONTACT_ID = :contactId")
|
||||
fun findContactEmailsByContactIdObservable(contactId: String): Flowable<List<ContactEmail>>
|
||||
|
@ -319,6 +322,9 @@ interface ContactDao {
|
|||
@Query("SELECT * FROM $TABLE_CONTACT_LABEL ORDER BY $COLUMN_LABEL_NAME")
|
||||
fun findContactGroupsObservable(): Flowable<List<ContactLabel>>
|
||||
|
||||
@Query("SELECT * FROM $TABLE_CONTACT_LABEL ORDER BY $COLUMN_LABEL_NAME")
|
||||
fun observeContactGroups(): Flow<List<ContactLabel>>
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT *
|
||||
|
@ -397,7 +403,10 @@ interface ContactDao {
|
|||
fun insertFullContactDetails(fullContactDetails: FullContactDetails)
|
||||
|
||||
@Query("SELECT * FROM $TABLE_FULL_CONTACT_DETAILS WHERE $COLUMN_CONTACT_ID = :id")
|
||||
fun findFullContactDetailsById(id: String): FullContactDetails?
|
||||
fun findFullContactDetailsByIdBlocking(id: String): FullContactDetails?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_FULL_CONTACT_DETAILS WHERE $COLUMN_CONTACT_ID = :id")
|
||||
suspend fun findFullContactDetailsById(id: String): FullContactDetails?
|
||||
|
||||
@Query("DELETE FROM $TABLE_FULL_CONTACT_DETAILS")
|
||||
fun clearFullContactDetailsCache()
|
||||
|
|
|
@ -311,7 +311,7 @@ class ConvertLocalContactsJob(
|
|||
val remoteContactId = response.contactId
|
||||
val previousContactData = contactDao.findContactDataByDbId(contactDataDbId)
|
||||
if (remoteContactId != "") {
|
||||
val contactEmails = contactDao.findContactEmailsByContactId(
|
||||
val contactEmails = contactDao.findContactEmailsByContactIdBlocking(
|
||||
previousContactData!!.contactId!!
|
||||
)
|
||||
previousContactData.contactId = remoteContactId
|
||||
|
|
|
@ -68,7 +68,7 @@ public class ResignContactJob extends ProtonMailEndlessJob {
|
|||
AppUtil.postEventOnUi(new ResignContactEvent(mSendPreference, ContactEvent.ERROR, mDestination));
|
||||
return;
|
||||
}
|
||||
FullContactDetails fullContactDetails = contactDao.findFullContactDetailsById(contactId);
|
||||
FullContactDetails fullContactDetails = contactDao.findFullContactDetailsByIdBlocking(contactId);
|
||||
|
||||
if (user == null || fullContactDetails == null) {
|
||||
AppUtil.postEventOnUi(new ResignContactEvent(mSendPreference, ContactEvent.ERROR, mDestination));
|
||||
|
@ -106,7 +106,7 @@ public class ResignContactJob extends ProtonMailEndlessJob {
|
|||
return;
|
||||
}
|
||||
|
||||
FullContactDetails fullContactDetails = contactDao.findFullContactDetailsById(
|
||||
FullContactDetails fullContactDetails = contactDao.findFullContactDetailsByIdBlocking(
|
||||
contactId);
|
||||
UserCrypto crypto = Crypto.forUser(getUserManager(), getUserManager().requireCurrentUserId());
|
||||
ContactEncryptedData signedCard = getCardByType(fullContactDetails.getEncryptedData(), ContactEncryption.SIGNED);
|
||||
|
|
|
@ -150,7 +150,7 @@ public class UpdateContactJob extends ProtonMailEndlessJob {
|
|||
mContactDao.saveContactData(contactData);
|
||||
}
|
||||
|
||||
List<ContactEmail> emails = mContactDao.findContactEmailsByContactId(mContactId);
|
||||
List<ContactEmail> emails = mContactDao.findContactEmailsByContactIdBlocking(mContactId);
|
||||
mContactDao.deleteAllContactsEmails(emails);
|
||||
|
||||
for (ContactEmail email : contactEmails) {
|
||||
|
@ -174,7 +174,7 @@ public class UpdateContactJob extends ProtonMailEndlessJob {
|
|||
}
|
||||
FullContactDetails contact = null;
|
||||
try {
|
||||
contact = mContactDao.findFullContactDetailsById(mContactId);
|
||||
contact = mContactDao.findFullContactDetailsByIdBlocking(mContactId);
|
||||
} catch (SQLiteBlobTooBigException tooBigException) {
|
||||
Timber.i(tooBigException,"Data too big to be fetched");
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ class DeleteContactWorker @AssistedInject constructor(
|
|||
contactData?.let { contact ->
|
||||
contactDatabase.runInTransaction {
|
||||
contact.contactId?.let {
|
||||
val contactEmails = contactDao.findContactEmailsByContactId(it)
|
||||
val contactEmails = contactDao.findContactEmailsByContactIdBlocking(it)
|
||||
contactDao.deleteAllContactsEmails(contactEmails)
|
||||
}
|
||||
contactDao.deleteContactData(contact)
|
||||
|
|
|
@ -98,11 +98,11 @@ class ContactDetailsRepositoryTest {
|
|||
ContactEmail("ID3", "martin@proton.com", "Martin"),
|
||||
ContactEmail("ID4", "kent@proton.com", "kent")
|
||||
)
|
||||
every { contactDao.findContactEmailsByContactId(contactId) } returns localContactEmails
|
||||
every { contactDao.findContactEmailsByContactIdBlocking(contactId) } returns localContactEmails
|
||||
|
||||
repository.updateAllContactEmails(contactId, serverEmails)
|
||||
|
||||
verify { contactDao.findContactEmailsByContactId(contactId) }
|
||||
verify { contactDao.findContactEmailsByContactIdBlocking(contactId) }
|
||||
verify { contactDao.deleteAllContactsEmails(localContactEmails) }
|
||||
coVerify { contactDao.saveAllContactsEmails(serverEmails) }
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ class FetchContactDetailsTest : ArchTest, CoroutinesTest {
|
|||
val fullContactsResponse = mockk<FullContactDetailsResponse> {
|
||||
every { contact } returns fullContactsFromNet
|
||||
}
|
||||
every { contactDao.findFullContactDetailsById(contactId) } returns fullContactsFromDb
|
||||
every { contactDao.findFullContactDetailsByIdBlocking(contactId) } returns fullContactsFromDb
|
||||
every { contactDao.insertFullContactDetails(any()) } returns Unit
|
||||
coEvery { api.fetchContactDetails(contactId) } returns fullContactsResponse
|
||||
val expectedDb = FetchContactDetailsResult.Data(
|
||||
|
@ -113,7 +113,7 @@ class FetchContactDetailsTest : ArchTest, CoroutinesTest {
|
|||
val fullContactsFromDb = mockk<FullContactDetails> {
|
||||
every { encryptedData } returns mutableListOf(contactEncryptedData)
|
||||
}
|
||||
every { contactDao.findFullContactDetailsById(contactId) } returns fullContactsFromDb
|
||||
every { contactDao.findFullContactDetailsByIdBlocking(contactId) } returns fullContactsFromDb
|
||||
val ioException = IOException("Cannot load contacts")
|
||||
coEvery { api.fetchContactDetails(contactId) } throws ioException
|
||||
val expected = FetchContactDetailsResult.Data(
|
||||
|
@ -152,7 +152,7 @@ class FetchContactDetailsTest : ArchTest, CoroutinesTest {
|
|||
val fullContactsResponse = mockk<FullContactDetailsResponse> {
|
||||
every { contact } returns fullContactsFromNet
|
||||
}
|
||||
every { contactDao.findFullContactDetailsById(contactId) } returns fullContactsFromDb
|
||||
every { contactDao.findFullContactDetailsByIdBlocking(contactId) } returns fullContactsFromDb
|
||||
every { contactDao.insertFullContactDetails(any()) } returns Unit
|
||||
coEvery { api.fetchContactDetails(contactId) } returns fullContactsResponse
|
||||
val expected = FetchContactDetailsResult.Data(
|
||||
|
@ -173,7 +173,7 @@ class FetchContactDetailsTest : ArchTest, CoroutinesTest {
|
|||
// given
|
||||
val contactId = "testContactId"
|
||||
val exception = Exception("An error!")
|
||||
every { contactDao.findFullContactDetailsById(contactId) } returns null
|
||||
every { contactDao.findFullContactDetailsByIdBlocking(contactId) } returns null
|
||||
coEvery { api.fetchContactDetails(contactId) } throws exception
|
||||
val expected = FetchContactDetailsResult.Error(exception)
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ class DeleteContactWorkerTest {
|
|||
val expected = ListenableWorker.Result.success()
|
||||
|
||||
every { contactDao.findContactDataById(contactId) } returns contactData
|
||||
every { contactDao.findContactEmailsByContactId(contactId) } returns listOf(contactEmail)
|
||||
every { contactDao.findContactEmailsByContactIdBlocking(contactId) } returns listOf(contactEmail)
|
||||
every { contactDao.deleteAllContactsEmails(any()) } returns mockk()
|
||||
every { contactDao.deleteContactData(any()) } returns mockk()
|
||||
every { parameters.inputData } returns
|
||||
|
@ -135,7 +135,7 @@ class DeleteContactWorkerTest {
|
|||
)
|
||||
|
||||
every { contactDao.findContactDataById(contactId) } returns contactData
|
||||
every { contactDao.findContactEmailsByContactId(contactId) } returns listOf(contactEmail)
|
||||
every { contactDao.findContactEmailsByContactIdBlocking(contactId) } returns listOf(contactEmail)
|
||||
every { contactDao.deleteAllContactsEmails(any()) } returns mockk()
|
||||
every { contactDao.deleteContactData(any()) } returns mockk()
|
||||
every { parameters.inputData } returns
|
||||
|
|
Loading…
Reference in New Issue