Rename the AutofillTotpCopyActivity (#5713)

This commit is contained in:
David Perez
2025-08-15 18:24:05 +00:00
committed by GitHub
parent 584bdb6277
commit 3cf325becf
10 changed files with 106 additions and 116 deletions
+2 -2
View File
@@ -115,11 +115,11 @@
android:theme="@android:style/Theme.NoDisplay" />
<activity
android:name=".AutofillTotpCopyActivity"
android:name=".AutofillCallbackActivity"
android:exported="true"
android:launchMode="singleTop"
android:noHistory="true"
android:theme="@style/AutofillTotpCopyTheme" />
android:theme="@style/AutofillCallbackTheme" />
<activity
android:name=".AuthCallbackActivity"
@@ -15,18 +15,18 @@ import kotlinx.coroutines.flow.onEach
import javax.inject.Inject
/**
* An activity for copying a TOTP code to the clipboard. This is done when an autofill item is
* selected and it requires TOTP authentication. Due to the constraints of the autofill framework,
* we also have to re-fulfill the autofill for the views that are being filled.
* An activity that is launched to complete Autofill. This is done when an autofill item is selected
* and is associated with a valid cipher. Due to the constraints of the autofill framework, we also
* have to re-fulfill the autofill for the views that are being filled.
*/
@OmitFromCoverage
@AndroidEntryPoint
class AutofillTotpCopyActivity : AppCompatActivity() {
class AutofillCallbackActivity : AppCompatActivity() {
@Inject
lateinit var autofillCompletionManager: AutofillCompletionManager
private val autofillTotpCopyViewModel: AutofillTotpCopyViewModel by viewModels()
private val viewModel: AutofillCallbackViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
intent = intent.validate()
@@ -34,11 +34,7 @@ class AutofillTotpCopyActivity : AppCompatActivity() {
observeViewModelEvents()
autofillTotpCopyViewModel.trySendAction(
AutofillTotpCopyAction.IntentReceived(
intent = intent,
),
)
viewModel.trySendAction(AutofillCallbackAction.IntentReceived(intent = intent))
}
override fun onNewIntent(intent: Intent) {
@@ -50,17 +46,12 @@ class AutofillTotpCopyActivity : AppCompatActivity() {
}
private fun observeViewModelEvents() {
autofillTotpCopyViewModel
viewModel
.eventFlow
.onEach { event ->
when (event) {
is AutofillTotpCopyEvent.CompleteAutofill -> {
handleCompleteAutofill(event)
}
is AutofillTotpCopyEvent.FinishActivity -> {
finishActivity()
}
is AutofillCallbackEvent.CompleteAutofill -> handleCompleteAutofill(event)
is AutofillCallbackEvent.FinishActivity -> finishActivity()
}
}
.launchIn(lifecycleScope)
@@ -69,7 +60,7 @@ class AutofillTotpCopyActivity : AppCompatActivity() {
/**
* Complete autofill with the provided data.
*/
private fun handleCompleteAutofill(event: AutofillTotpCopyEvent.CompleteAutofill) {
private fun handleCompleteAutofill(event: AutofillCallbackEvent.CompleteAutofill) {
autofillCompletionManager.completeAutofill(
activity = this,
cipherView = event.cipherView,
@@ -5,7 +5,7 @@ import androidx.lifecycle.viewModelScope
import com.bitwarden.ui.platform.base.BaseViewModel
import com.bitwarden.vault.CipherView
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.autofill.util.getTotpCopyIntentOrNull
import com.x8bit.bitwarden.data.autofill.util.getAutofillCallbackIntentOrNull
import com.x8bit.bitwarden.data.platform.util.launchWithTimeout
import com.x8bit.bitwarden.data.vault.manager.model.GetCipherResult
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
@@ -22,23 +22,23 @@ import javax.inject.Inject
private const val CIPHER_WAIT_TIMEOUT_MILLIS: Long = 500
/**
* A view model that handles logic for the [AutofillTotpCopyActivity].
* A view model that handles logic for the [AutofillCallbackActivity].
*/
@HiltViewModel
class AutofillTotpCopyViewModel @Inject constructor(
class AutofillCallbackViewModel @Inject constructor(
private val authRepository: AuthRepository,
private val vaultRepository: VaultRepository,
) : BaseViewModel<Unit, AutofillTotpCopyEvent, AutofillTotpCopyAction>(Unit) {
) : BaseViewModel<Unit, AutofillCallbackEvent, AutofillCallbackAction>(Unit) {
private val activeUserId: String? get() = authRepository.activeUserId
override fun handleAction(action: AutofillTotpCopyAction): Unit = when (action) {
is AutofillTotpCopyAction.IntentReceived -> handleIntentReceived(action)
override fun handleAction(action: AutofillCallbackAction): Unit = when (action) {
is AutofillCallbackAction.IntentReceived -> handleIntentReceived(action)
}
/**
* Process the received intent and alert the activity of what to do next.
*/
private fun handleIntentReceived(action: AutofillTotpCopyAction.IntentReceived) {
private fun handleIntentReceived(action: AutofillCallbackAction.IntentReceived) {
viewModelScope
.launchWithTimeout(
timeoutBlock = {
@@ -50,7 +50,7 @@ class AutofillTotpCopyViewModel @Inject constructor(
// Extract TOTP copy data from the intent.
val cipherId = action
.intent
.getTotpCopyIntentOrNull()
.getAutofillCallbackIntentOrNull()
?.cipherId
if (cipherId == null) {
@@ -78,7 +78,7 @@ class AutofillTotpCopyViewModel @Inject constructor(
is GetCipherResult.Success -> {
Timber.d("Autofill -- Cipher found")
sendEvent(AutofillTotpCopyEvent.CompleteAutofill(result.cipherView))
sendEvent(AutofillCallbackEvent.CompleteAutofill(result.cipherView))
}
}
}
@@ -88,7 +88,7 @@ class AutofillTotpCopyViewModel @Inject constructor(
* Send an event to the activity that signals it to finish.
*/
private fun finishActivity() {
sendEvent(AutofillTotpCopyEvent.FinishActivity)
sendEvent(AutofillCallbackEvent.FinishActivity)
}
private suspend fun isVaultLocked(): Boolean {
@@ -105,30 +105,30 @@ class AutofillTotpCopyViewModel @Inject constructor(
}
/**
* Represents actions that can be sent to the [AutofillTotpCopyViewModel].
* Represents actions that can be sent to the [AutofillCallbackViewModel].
*/
sealed class AutofillTotpCopyAction {
sealed class AutofillCallbackAction {
/**
* An [intent] has been received and is ready to be processed.
*/
data class IntentReceived(
val intent: Intent,
) : AutofillTotpCopyAction()
) : AutofillCallbackAction()
}
/**
* Represents events emitted by the [AutofillTotpCopyViewModel].
* Represents events emitted by the [AutofillCallbackViewModel].
*/
sealed class AutofillTotpCopyEvent {
sealed class AutofillCallbackEvent {
/**
* Complete autofill with the provided [cipherView].
*/
data class CompleteAutofill(
val cipherView: CipherView,
) : AutofillTotpCopyEvent()
) : AutofillCallbackEvent()
/**
* Finish the activity.
*/
data object FinishActivity : AutofillTotpCopyEvent()
data object FinishActivity : AutofillCallbackEvent()
}
@@ -8,7 +8,7 @@ import com.x8bit.bitwarden.data.autofill.model.FilledData
import com.x8bit.bitwarden.data.autofill.model.FilledPartition
import com.x8bit.bitwarden.data.autofill.util.buildDataset
import com.x8bit.bitwarden.data.autofill.util.buildVaultItemDataset
import com.x8bit.bitwarden.data.autofill.util.createTotpCopyIntentSender
import com.x8bit.bitwarden.data.autofill.util.createAutofillCallbackIntentSender
import com.x8bit.bitwarden.data.autofill.util.fillableAutofillIds
import timber.log.Timber
@@ -65,8 +65,8 @@ class FillResponseBuilderImpl : FillResponseBuilder {
}
/**
* Convert this [FilledPartition] and [autofillAppInfo] into an [IntentSender] if totp is enabled
* and there the [FilledPartition.autofillCipher] has a valid cipher id.
* Convert this [FilledPartition] and [autofillAppInfo] into an [IntentSender] if the
* [FilledPartition.autofillCipher] has a valid cipher id.
*/
private fun FilledPartition.toAuthIntentSenderOrNull(
autofillAppInfo: AutofillAppInfo,
@@ -74,8 +74,7 @@ private fun FilledPartition.toAuthIntentSenderOrNull(
autofillCipher
.cipherId
?.let { cipherId ->
// We always do this even if there is no TOTP code because we want to log the events
createTotpCopyIntentSender(
createAutofillCallbackIntentSender(
cipherId = cipherId,
context = autofillAppInfo.context,
)
@@ -0,0 +1,14 @@
package com.x8bit.bitwarden.data.autofill.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
/**
* Represents data for the autofill flow via authentication intents.
*
* @property cipherId The ID of the cipher associated with this Autofill instance.
*/
@Parcelize
data class AutofillCallbackData(
val cipherId: String,
) : Parcelable
@@ -1,14 +0,0 @@
package com.x8bit.bitwarden.data.autofill.model
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
/**
* Represents data for a TOTP copying during the autofill flow via authentication intents.
*
* @property cipherId The cipher for which we are copying a TOTP to the clipboard.
*/
@Parcelize
data class AutofillTotpCopyData(
val cipherId: String,
) : Parcelable
@@ -13,17 +13,17 @@ import android.view.autofill.AutofillManager
import androidx.core.os.bundleOf
import com.bitwarden.annotation.OmitFromCoverage
import com.bitwarden.ui.platform.util.getSafeParcelableExtra
import com.x8bit.bitwarden.AutofillTotpCopyActivity
import com.x8bit.bitwarden.AutofillCallbackActivity
import com.x8bit.bitwarden.MainActivity
import com.x8bit.bitwarden.data.autofill.model.AutofillAppInfo
import com.x8bit.bitwarden.data.autofill.model.AutofillCallbackData
import com.x8bit.bitwarden.data.autofill.model.AutofillSaveItem
import com.x8bit.bitwarden.data.autofill.model.AutofillSelectionData
import com.x8bit.bitwarden.data.autofill.model.AutofillTotpCopyData
import kotlin.random.Random
private const val AUTOFILL_SAVE_ITEM_DATA_KEY = "autofill-save-item-data"
private const val AUTOFILL_SELECTION_DATA_KEY = "autofill-selection-data"
private const val AUTOFILL_TOTP_COPY_DATA_KEY = "autofill-totp-copy-data"
private const val AUTOFILL_CALLBACK_DATA_KEY = "autofill-callback-data"
private const val AUTOFILL_BUNDLE_KEY = "autofill-bundle-key"
/**
@@ -54,21 +54,21 @@ fun createAutofillSelectionIntent(
}
/**
* Creates an [IntentSender] built with the data required for performing a TOTP copying during
* the autofill flow.
* Creates an [IntentSender] built with the data required for performing an Autofill callback
* during the autofill flow.
*/
fun createTotpCopyIntentSender(
fun createAutofillCallbackIntentSender(
cipherId: String,
context: Context,
): IntentSender {
val intent = Intent(
context,
AutofillTotpCopyActivity::class.java,
AutofillCallbackActivity::class.java,
)
.putExtra(
AUTOFILL_BUNDLE_KEY,
bundleOf(
AUTOFILL_TOTP_COPY_DATA_KEY to AutofillTotpCopyData(cipherId = cipherId),
AUTOFILL_CALLBACK_DATA_KEY to AutofillCallbackData(cipherId = cipherId),
),
)
return PendingIntent
@@ -142,12 +142,12 @@ fun Intent.getAutofillSelectionDataOrNull(): AutofillSelectionData? =
?.getSafeParcelableExtra(AUTOFILL_SELECTION_DATA_KEY)
/**
* Checks if the given [Intent] contains data for TOTP copying. The [AutofillTotpCopyData] will be
* Checks if the given [Intent] contains Autofill callback data. The [AutofillCallbackData] will be
* returned when present.
*/
fun Intent.getTotpCopyIntentOrNull(): AutofillTotpCopyData? =
fun Intent.getAutofillCallbackIntentOrNull(): AutofillCallbackData? =
getBundleExtra(AUTOFILL_BUNDLE_KEY)
?.getSafeParcelableExtra(AUTOFILL_TOTP_COPY_DATA_KEY)
?.getSafeParcelableExtra(AUTOFILL_CALLBACK_DATA_KEY)
/**
* Checks if the given [Activity] was created for Autofill. This is useful to avoid locking the
+2 -2
View File
@@ -18,8 +18,8 @@
<item name="windowSplashScreenBackground">@color/ic_launcher_background</item>
</style>
<!-- A translucent theme for the autofill TOTP copy activity -->
<style name="AutofillTotpCopyTheme" parent="Theme.AppCompat.NoActionBar">
<!-- A translucent theme for the autofill callback activity -->
<style name="AutofillCallbackTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
@@ -5,8 +5,8 @@ import app.cash.turbine.test
import com.bitwarden.ui.platform.base.BaseViewModelTest
import com.bitwarden.vault.CipherView
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.autofill.model.AutofillTotpCopyData
import com.x8bit.bitwarden.data.autofill.util.getTotpCopyIntentOrNull
import com.x8bit.bitwarden.data.autofill.model.AutofillCallbackData
import com.x8bit.bitwarden.data.autofill.util.getAutofillCallbackIntentOrNull
import com.x8bit.bitwarden.data.vault.manager.model.GetCipherResult
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
import com.x8bit.bitwarden.data.vault.repository.model.VaultUnlockData
@@ -24,8 +24,8 @@ import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
class AutofillTotpCopyViewModelTest : BaseViewModelTest() {
private lateinit var autofillTotpCopyViewModel: AutofillTotpCopyViewModel
class AutofillCallbackViewModelTest : BaseViewModelTest() {
private lateinit var autofillCallbackViewModel: AutofillCallbackViewModel
private val mutableVaultUnlockDataStateFlow: MutableStateFlow<List<VaultUnlockData>> =
MutableStateFlow(emptyList())
@@ -41,9 +41,9 @@ class AutofillTotpCopyViewModelTest : BaseViewModelTest() {
@BeforeEach
fun setup() {
mockkStatic(Intent::getTotpCopyIntentOrNull)
mockkStatic(Intent::getAutofillCallbackIntentOrNull)
autofillTotpCopyViewModel = AutofillTotpCopyViewModel(
autofillCallbackViewModel = AutofillCallbackViewModel(
authRepository = authRepository,
vaultRepository = vaultRepository,
)
@@ -51,7 +51,7 @@ class AutofillTotpCopyViewModelTest : BaseViewModelTest() {
@AfterEach
fun teardown() {
unmockkStatic(Intent::getTotpCopyIntentOrNull)
unmockkStatic(Intent::getAutofillCallbackIntentOrNull)
}
@Suppress("MaxLineLength")
@@ -62,20 +62,20 @@ class AutofillTotpCopyViewModelTest : BaseViewModelTest() {
val cipherView: CipherView = mockk {
every { id } returns CIPHER_ID
}
val totpCopyData = AutofillTotpCopyData(
val totpCopyData = AutofillCallbackData(
cipherId = CIPHER_ID,
)
val action = AutofillTotpCopyAction.IntentReceived(
val action = AutofillCallbackAction.IntentReceived(
intent = intent,
)
val expectedEvent = AutofillTotpCopyEvent.CompleteAutofill(
val expectedEvent = AutofillCallbackEvent.CompleteAutofill(
cipherView = cipherView,
)
val vaultUnlockData = VaultUnlockData(
userId = ACTIVE_USER_ID,
status = VaultUnlockData.Status.UNLOCKED,
)
every { intent.getTotpCopyIntentOrNull() } returns totpCopyData
every { intent.getAutofillCallbackIntentOrNull() } returns totpCopyData
every { authRepository.activeUserId } returns ACTIVE_USER_ID
every { vaultRepository.isVaultUnlocked(userId = ACTIVE_USER_ID) } returns true
coEvery {
@@ -84,10 +84,10 @@ class AutofillTotpCopyViewModelTest : BaseViewModelTest() {
mutableVaultUnlockDataStateFlow.value = listOf(vaultUnlockData)
// Test
autofillTotpCopyViewModel.trySendAction(action)
autofillCallbackViewModel.trySendAction(action)
// Verify
autofillTotpCopyViewModel.eventFlow.test {
autofillCallbackViewModel.eventFlow.test {
assertEquals(expectedEvent, awaitItem())
expectNoEvents()
}
@@ -96,17 +96,17 @@ class AutofillTotpCopyViewModelTest : BaseViewModelTest() {
@Test
fun `on IntentReceived should emit FinishActivity when cipherID is not`() = runTest {
// Setup
val action = AutofillTotpCopyAction.IntentReceived(
val action = AutofillCallbackAction.IntentReceived(
intent = intent,
)
val expectedEvent = AutofillTotpCopyEvent.FinishActivity
every { intent.getTotpCopyIntentOrNull() } returns null
val expectedEvent = AutofillCallbackEvent.FinishActivity
every { intent.getAutofillCallbackIntentOrNull() } returns null
// Test
autofillTotpCopyViewModel.trySendAction(action)
autofillCallbackViewModel.trySendAction(action)
// Verify
autofillTotpCopyViewModel.eventFlow.test {
autofillCallbackViewModel.eventFlow.test {
assertEquals(expectedEvent, awaitItem())
expectNoEvents()
}
@@ -117,21 +117,21 @@ class AutofillTotpCopyViewModelTest : BaseViewModelTest() {
fun `on IntentReceived should emit FinishActivity when cipherID is extracted and no active user`() =
runTest {
// Setup
val totpCopyData = AutofillTotpCopyData(
val totpCopyData = AutofillCallbackData(
cipherId = CIPHER_ID,
)
val action = AutofillTotpCopyAction.IntentReceived(
val action = AutofillCallbackAction.IntentReceived(
intent = intent,
)
val expectedEvent = AutofillTotpCopyEvent.FinishActivity
every { intent.getTotpCopyIntentOrNull() } returns totpCopyData
val expectedEvent = AutofillCallbackEvent.FinishActivity
every { intent.getAutofillCallbackIntentOrNull() } returns totpCopyData
every { authRepository.activeUserId } returns null
// Test
autofillTotpCopyViewModel.trySendAction(action)
autofillCallbackViewModel.trySendAction(action)
// Verify
autofillTotpCopyViewModel.eventFlow.test {
autofillCallbackViewModel.eventFlow.test {
assertEquals(expectedEvent, awaitItem())
expectNoEvents()
}
@@ -142,22 +142,22 @@ class AutofillTotpCopyViewModelTest : BaseViewModelTest() {
fun `on IntentReceived should emit FinishActivity when cipherID is extracted and vault locked`() =
runTest {
// Setup
val totpCopyData = AutofillTotpCopyData(
val totpCopyData = AutofillCallbackData(
cipherId = CIPHER_ID,
)
val action = AutofillTotpCopyAction.IntentReceived(
val action = AutofillCallbackAction.IntentReceived(
intent = intent,
)
val expectedEvent = AutofillTotpCopyEvent.FinishActivity
every { intent.getTotpCopyIntentOrNull() } returns totpCopyData
val expectedEvent = AutofillCallbackEvent.FinishActivity
every { intent.getAutofillCallbackIntentOrNull() } returns totpCopyData
every { authRepository.activeUserId } returns ACTIVE_USER_ID
every { vaultRepository.isVaultUnlocked(userId = ACTIVE_USER_ID) } returns false
// Test
autofillTotpCopyViewModel.trySendAction(action)
autofillCallbackViewModel.trySendAction(action)
// Verify
autofillTotpCopyViewModel.eventFlow.test {
autofillCallbackViewModel.eventFlow.test {
assertEquals(expectedEvent, awaitItem())
expectNoEvents()
}
@@ -171,18 +171,18 @@ class AutofillTotpCopyViewModelTest : BaseViewModelTest() {
val cipherView: CipherView = mockk {
every { id } returns "NEW CIPHER ID"
}
val totpCopyData = AutofillTotpCopyData(
val totpCopyData = AutofillCallbackData(
cipherId = CIPHER_ID,
)
val action = AutofillTotpCopyAction.IntentReceived(
val action = AutofillCallbackAction.IntentReceived(
intent = intent,
)
val expectedEvent = AutofillTotpCopyEvent.FinishActivity
val expectedEvent = AutofillCallbackEvent.FinishActivity
val vaultUnlockData = VaultUnlockData(
userId = ACTIVE_USER_ID,
status = VaultUnlockData.Status.UNLOCKED,
)
every { intent.getTotpCopyIntentOrNull() } returns totpCopyData
every { intent.getAutofillCallbackIntentOrNull() } returns totpCopyData
every { authRepository.activeUserId } returns ACTIVE_USER_ID
every { vaultRepository.isVaultUnlocked(userId = ACTIVE_USER_ID) } returns true
coEvery {
@@ -191,10 +191,10 @@ class AutofillTotpCopyViewModelTest : BaseViewModelTest() {
mutableVaultUnlockDataStateFlow.value = listOf(vaultUnlockData)
// Test
autofillTotpCopyViewModel.trySendAction(action)
autofillCallbackViewModel.trySendAction(action)
// Verify
autofillTotpCopyViewModel.eventFlow.test {
autofillCallbackViewModel.eventFlow.test {
assertEquals(expectedEvent, awaitItem())
expectNoEvents()
}
@@ -203,28 +203,28 @@ class AutofillTotpCopyViewModelTest : BaseViewModelTest() {
@Test
fun `on IntentReceived should emit FinishActivity when timeout is elapsed`() = runTest {
// Setup
val totpCopyData = AutofillTotpCopyData(
val totpCopyData = AutofillCallbackData(
cipherId = CIPHER_ID,
)
val action = AutofillTotpCopyAction.IntentReceived(
val action = AutofillCallbackAction.IntentReceived(
intent = intent,
)
val expectedEvent = AutofillTotpCopyEvent.FinishActivity
val expectedEvent = AutofillCallbackEvent.FinishActivity
val vaultUnlockData = VaultUnlockData(
userId = ACTIVE_USER_ID,
status = VaultUnlockData.Status.UNLOCKED,
)
every { intent.getTotpCopyIntentOrNull() } returns totpCopyData
every { intent.getAutofillCallbackIntentOrNull() } returns totpCopyData
every { authRepository.activeUserId } returns ACTIVE_USER_ID
every { vaultRepository.isVaultUnlocked(userId = ACTIVE_USER_ID) } returns true
coEvery { vaultRepository.getCipher(cipherId = CIPHER_ID) } just awaits
mutableVaultUnlockDataStateFlow.value = listOf(vaultUnlockData)
// Test
autofillTotpCopyViewModel.trySendAction(action)
autofillCallbackViewModel.trySendAction(action)
// Verify
autofillTotpCopyViewModel.eventFlow.test {
autofillCallbackViewModel.eventFlow.test {
assertEquals(expectedEvent, awaitItem())
expectNoEvents()
}
@@ -15,7 +15,7 @@ import com.x8bit.bitwarden.data.autofill.model.FilledData
import com.x8bit.bitwarden.data.autofill.model.FilledPartition
import com.x8bit.bitwarden.data.autofill.util.buildDataset
import com.x8bit.bitwarden.data.autofill.util.buildVaultItemDataset
import com.x8bit.bitwarden.data.autofill.util.createTotpCopyIntentSender
import com.x8bit.bitwarden.data.autofill.util.createAutofillCallbackIntentSender
import com.x8bit.bitwarden.data.util.mockBuilder
import io.mockk.every
import io.mockk.mockk
@@ -65,12 +65,12 @@ class FillResponseBuilderTest {
@BeforeEach
fun setup() {
mockkConstructor(FillResponse.Builder::class)
mockkStatic(::createTotpCopyIntentSender)
mockkStatic(::createAutofillCallbackIntentSender)
mockkStatic(FilledData::buildVaultItemDataset)
mockkStatic(FilledPartition::buildDataset)
every { anyConstructed<FillResponse.Builder>().build() } returns fillResponse
every {
createTotpCopyIntentSender(
createAutofillCallbackIntentSender(
cipherId = CIPHER_ID,
context = context,
)
@@ -82,7 +82,7 @@ class FillResponseBuilderTest {
@AfterEach
fun teardown() {
unmockkConstructor(FillResponse.Builder::class)
unmockkStatic(::createTotpCopyIntentSender)
unmockkStatic(::createAutofillCallbackIntentSender)
unmockkStatic(FilledData::buildVaultItemDataset)
unmockkStatic(FilledPartition::buildDataset)
}