PM-13019: Add special circumstance to navigate to the vault listing UI for TOTP code (#4033)

This commit is contained in:
David Perez
2024-10-07 10:04:58 -05:00
committed by GitHub
parent 8d578a9b57
commit c4467f0cba
10 changed files with 201 additions and 5 deletions

View File

@@ -50,6 +50,8 @@ import com.x8bit.bitwarden.ui.platform.feature.settings.appearance.model.AppThem
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
import com.x8bit.bitwarden.ui.platform.util.isMyVaultShortcut
import com.x8bit.bitwarden.ui.platform.util.isPasswordGeneratorShortcut
import com.x8bit.bitwarden.ui.vault.model.TotpData
import com.x8bit.bitwarden.ui.vault.util.getTotpDataOrNull
import io.mockk.coEvery
import io.mockk.every
import io.mockk.just
@@ -119,6 +121,7 @@ class MainViewModelTest : BaseViewModelTest() {
@BeforeEach
fun setup() {
mockkStatic(
Intent::getTotpDataOrNull,
Intent::getPasswordlessRequestDataIntentOrNull,
Intent::getAutofillSaveItemOrNull,
Intent::getAutofillSelectionDataOrNull,
@@ -134,6 +137,7 @@ class MainViewModelTest : BaseViewModelTest() {
@AfterEach
fun tearDown() {
unmockkStatic(
Intent::getTotpDataOrNull,
Intent::getPasswordlessRequestDataIntentOrNull,
Intent::getAutofillSaveItemOrNull,
Intent::getAutofillSelectionDataOrNull,
@@ -294,12 +298,35 @@ class MainViewModelTest : BaseViewModelTest() {
}
}
@Suppress("MaxLineLength")
@Test
fun `on ReceiveFirstIntent with TOTP data should set the special circumstance to AddTotpLoginItem`() {
val viewModel = createViewModel()
val mockIntent = mockk<Intent>()
val totpData = mockk<TotpData>()
every { mockIntent.getTotpDataOrNull() } returns totpData
every { mockIntent.getPasswordlessRequestDataIntentOrNull() } returns null
every { mockIntent.getAutofillSaveItemOrNull() } returns null
every { mockIntent.getAutofillSelectionDataOrNull() } returns null
every { mockIntent.getCompleteRegistrationDataIntentOrNull() } returns null
every { intentManager.getShareDataFromIntent(mockIntent) } returns null
every { mockIntent.isMyVaultShortcut } returns false
every { mockIntent.isPasswordGeneratorShortcut } returns false
viewModel.trySendAction(MainAction.ReceiveFirstIntent(intent = mockIntent))
assertEquals(
SpecialCircumstance.AddTotpLoginItem(data = totpData),
specialCircumstanceManager.specialCircumstance,
)
}
@Suppress("MaxLineLength")
@Test
fun `on ReceiveFirstIntent with share data should set the special circumstance to ShareNewSend`() {
val viewModel = createViewModel()
val mockIntent = mockk<Intent>()
val shareData = mockk<IntentManager.ShareData>()
every { mockIntent.getTotpDataOrNull() } returns null
every { mockIntent.getPasswordlessRequestDataIntentOrNull() } returns null
every { mockIntent.getAutofillSaveItemOrNull() } returns null
every { mockIntent.getAutofillSelectionDataOrNull() } returns null
@@ -328,6 +355,7 @@ class MainViewModelTest : BaseViewModelTest() {
val viewModel = createViewModel()
val mockIntent = mockk<Intent>()
val autofillSelectionData = mockk<AutofillSelectionData>()
every { mockIntent.getTotpDataOrNull() } returns null
every { mockIntent.getPasswordlessRequestDataIntentOrNull() } returns null
every { mockIntent.getAutofillSaveItemOrNull() } returns null
every { mockIntent.getCompleteRegistrationDataIntentOrNull() } returns null
@@ -359,6 +387,7 @@ class MainViewModelTest : BaseViewModelTest() {
every { verificationToken } returns "token"
}
val mockIntent = mockk<Intent> {
every { getTotpDataOrNull() } returns null
every { getPasswordlessRequestDataIntentOrNull() } returns null
every { getAutofillSaveItemOrNull() } returns null
every { getCompleteRegistrationDataIntentOrNull() } returns completeRegistrationData
@@ -394,6 +423,7 @@ class MainViewModelTest : BaseViewModelTest() {
every { verificationToken } returns "token"
}
val mockIntent = mockk<Intent> {
every { getTotpDataOrNull() } returns null
every { getPasswordlessRequestDataIntentOrNull() } returns null
every { getAutofillSaveItemOrNull() } returns null
every { getCompleteRegistrationDataIntentOrNull() } returns completeRegistrationData
@@ -431,6 +461,7 @@ class MainViewModelTest : BaseViewModelTest() {
every { verificationToken } returns token
}
val mockIntent = mockk<Intent> {
every { getTotpDataOrNull() } returns null
every { getPasswordlessRequestDataIntentOrNull() } returns null
every { getAutofillSaveItemOrNull() } returns null
every { getCompleteRegistrationDataIntentOrNull() } returns completeRegistrationData
@@ -470,6 +501,7 @@ class MainViewModelTest : BaseViewModelTest() {
every { verificationToken } returns token
}
val mockIntent = mockk<Intent> {
every { getTotpDataOrNull() } returns null
every { getPasswordlessRequestDataIntentOrNull() } returns null
every { getAutofillSaveItemOrNull() } returns null
every { getCompleteRegistrationDataIntentOrNull() } returns completeRegistrationData
@@ -511,6 +543,7 @@ class MainViewModelTest : BaseViewModelTest() {
every { verificationToken } returns token
}
val mockIntent = mockk<Intent> {
every { getTotpDataOrNull() } returns null
every { getPasswordlessRequestDataIntentOrNull() } returns null
every { getAutofillSaveItemOrNull() } returns null
every { getCompleteRegistrationDataIntentOrNull() } returns completeRegistrationData
@@ -548,6 +581,7 @@ class MainViewModelTest : BaseViewModelTest() {
val viewModel = createViewModel()
val mockIntent = mockk<Intent>()
val autofillSaveItem = mockk<AutofillSaveItem>()
every { mockIntent.getTotpDataOrNull() } returns null
every { mockIntent.getPasswordlessRequestDataIntentOrNull() } returns null
every { mockIntent.getAutofillSaveItemOrNull() } returns autofillSaveItem
every { mockIntent.getAutofillSelectionDataOrNull() } returns null
@@ -578,6 +612,7 @@ class MainViewModelTest : BaseViewModelTest() {
every {
mockIntent.getPasswordlessRequestDataIntentOrNull()
} returns passwordlessRequestData
every { mockIntent.getTotpDataOrNull() } returns null
every { mockIntent.getAutofillSaveItemOrNull() } returns null
every { mockIntent.getAutofillSelectionDataOrNull() } returns null
every { mockIntent.getCompleteRegistrationDataIntentOrNull() } returns null
@@ -663,6 +698,7 @@ class MainViewModelTest : BaseViewModelTest() {
origin = "mockOrigin",
)
val mockIntent = mockk<Intent> {
every { getTotpDataOrNull() } returns null
every { getFido2CredentialRequestOrNull() } returns fido2CredentialRequest
every { getPasswordlessRequestDataIntentOrNull() } returns null
every { getAutofillSelectionDataOrNull() } returns null
@@ -701,6 +737,7 @@ class MainViewModelTest : BaseViewModelTest() {
)
val mockIntent = mockk<Intent> {
every { getFido2CredentialRequestOrNull() } returns fido2CredentialRequest
every { getTotpDataOrNull() } returns null
every { getPasswordlessRequestDataIntentOrNull() } returns null
every { getAutofillSelectionDataOrNull() } returns null
every { getAutofillSaveItemOrNull() } returns null
@@ -773,6 +810,7 @@ class MainViewModelTest : BaseViewModelTest() {
val viewModel = createViewModel()
val mockIntent = mockk<Intent>()
val shareData = mockk<IntentManager.ShareData>()
every { mockIntent.getTotpDataOrNull() } returns null
every { mockIntent.getPasswordlessRequestDataIntentOrNull() } returns null
every { mockIntent.getAutofillSaveItemOrNull() } returns null
every { mockIntent.getAutofillSelectionDataOrNull() } returns null
@@ -795,12 +833,35 @@ class MainViewModelTest : BaseViewModelTest() {
)
}
@Suppress("MaxLineLength")
@Test
fun `on ReceiveNewIntent with TOTP data should set the special circumstance to AddTotpLoginItem`() {
val viewModel = createViewModel()
val mockIntent = mockk<Intent>()
val totpData = mockk<TotpData>()
every { mockIntent.getTotpDataOrNull() } returns totpData
every { mockIntent.getPasswordlessRequestDataIntentOrNull() } returns null
every { mockIntent.getAutofillSaveItemOrNull() } returns null
every { mockIntent.getAutofillSelectionDataOrNull() } returns null
every { mockIntent.getCompleteRegistrationDataIntentOrNull() } returns null
every { intentManager.getShareDataFromIntent(mockIntent) } returns null
every { mockIntent.isMyVaultShortcut } returns false
every { mockIntent.isPasswordGeneratorShortcut } returns false
viewModel.trySendAction(MainAction.ReceiveNewIntent(intent = mockIntent))
assertEquals(
SpecialCircumstance.AddTotpLoginItem(data = totpData),
specialCircumstanceManager.specialCircumstance,
)
}
@Suppress("MaxLineLength")
@Test
fun `on ReceiveNewIntent with autofill data should set the special circumstance to AutofillSelection`() {
val viewModel = createViewModel()
val mockIntent = mockk<Intent>()
val autofillSelectionData = mockk<AutofillSelectionData>()
every { mockIntent.getTotpDataOrNull() } returns null
every { mockIntent.getPasswordlessRequestDataIntentOrNull() } returns null
every { mockIntent.getAutofillSaveItemOrNull() } returns null
every { mockIntent.getCompleteRegistrationDataIntentOrNull() } returns null
@@ -829,6 +890,7 @@ class MainViewModelTest : BaseViewModelTest() {
val viewModel = createViewModel()
val mockIntent = mockk<Intent>()
val autofillSaveItem = mockk<AutofillSaveItem>()
every { mockIntent.getTotpDataOrNull() } returns null
every { mockIntent.getPasswordlessRequestDataIntentOrNull() } returns null
every { mockIntent.getAutofillSaveItemOrNull() } returns autofillSaveItem
every { mockIntent.getAutofillSelectionDataOrNull() } returns null
@@ -859,6 +921,7 @@ class MainViewModelTest : BaseViewModelTest() {
every {
mockIntent.getPasswordlessRequestDataIntentOrNull()
} returns passwordlessRequestData
every { mockIntent.getTotpDataOrNull() } returns null
every { mockIntent.getAutofillSaveItemOrNull() } returns null
every { mockIntent.getAutofillSelectionDataOrNull() } returns null
every { mockIntent.getCompleteRegistrationDataIntentOrNull() } returns null
@@ -885,6 +948,7 @@ class MainViewModelTest : BaseViewModelTest() {
fun `on ReceiveNewIntent with a Vault deeplink data should set the special circumstance to VaultShortcut`() {
val viewModel = createViewModel()
val mockIntent = mockk<Intent> {
every { getTotpDataOrNull() } returns null
every { getPasswordlessRequestDataIntentOrNull() } returns null
every { getAutofillSaveItemOrNull() } returns null
every { getAutofillSelectionDataOrNull() } returns null
@@ -910,6 +974,7 @@ class MainViewModelTest : BaseViewModelTest() {
fun `on ReceiveNewIntent with a password generator deeplink data should set the special circumstance to GeneratorShortcut`() {
val viewModel = createViewModel()
val mockIntent = mockk<Intent> {
every { getTotpDataOrNull() } returns null
every { getPasswordlessRequestDataIntentOrNull() } returns null
every { getAutofillSaveItemOrNull() } returns null
every { getAutofillSelectionDataOrNull() } returns null
@@ -1043,6 +1108,7 @@ private fun createMockFido2RegistrationIntent(
fido2CredentialRequest: Fido2CredentialRequest = createMockFido2CredentialRequest(number = 1),
): Intent = mockk<Intent> {
every { getFido2CredentialRequestOrNull() } returns fido2CredentialRequest
every { getTotpDataOrNull() } returns null
every { getPasswordlessRequestDataIntentOrNull() } returns null
every { getAutofillSelectionDataOrNull() } returns null
every { getAutofillSaveItemOrNull() } returns null
@@ -1056,6 +1122,7 @@ private fun createMockFido2AssertionIntent(
createMockFido2CredentialAssertionRequest(number = 1),
): Intent = mockk<Intent> {
every { getFido2AssertionRequestOrNull() } returns fido2CredentialAssertionRequest
every { getTotpDataOrNull() } returns null
every { getPasswordlessRequestDataIntentOrNull() } returns null
every { getAutofillSelectionDataOrNull() } returns null
every { getAutofillSaveItemOrNull() } returns null
@@ -1070,6 +1137,7 @@ private fun createMockFido2GetCredentialsIntent(
),
): Intent = mockk<Intent> {
every { getFido2GetCredentialsRequestOrNull() } returns fido2GetCredentialsRequest
every { getTotpDataOrNull() } returns null
every { getPasswordlessRequestDataIntentOrNull() } returns null
every { getAutofillSelectionDataOrNull() } returns null
every { getAutofillSaveItemOrNull() } returns null