mirror of
https://github.com/bitwarden/android.git
synced 2026-08-29 10:17:56 -05:00
Rename the AutofillTotpCopyActivity (#5713)
This commit is contained in:
@@ -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"
|
||||
|
||||
+10
-19
@@ -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,
|
||||
+17
-17
@@ -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()
|
||||
}
|
||||
+4
-5
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
+42
-42
@@ -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()
|
||||
}
|
||||
+4
-4
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user