[PM-37804] feat: Confirm before leaving the app to Stripe checkout (#6958)

This commit is contained in:
Patrick Honkonen
2026-05-20 18:28:05 -04:00
committed by GitHub
parent c6746fb369
commit 8f72c10f8e
3 changed files with 81 additions and 7 deletions

View File

@@ -269,6 +269,7 @@ private fun FreeCloudContent(
handlers: PlanHandlers,
modifier: Modifier = Modifier,
) {
var shouldShowUpgradeDialog by rememberSaveable { mutableStateOf(false) }
Column(
modifier = modifier
.fillMaxSize()
@@ -285,7 +286,7 @@ private fun FreeCloudContent(
BitwardenFilledButton(
label = stringResource(id = BitwardenString.upgrade_now),
onClick = handlers.onUpgradeNowClick,
onClick = { shouldShowUpgradeDialog = true },
icon = rememberVectorPainter(id = BitwardenDrawable.ic_external_link),
modifier = Modifier
.standardHorizontalMargin()
@@ -296,7 +297,10 @@ private fun FreeCloudContent(
Spacer(modifier = Modifier.height(12.dp))
Text(
text = stringResource(id = BitwardenString.stripe_checkout_footer),
text = stringResource(
id = BitwardenString
.youll_go_to_stripes_secure_checkout_to_complete_your_purchase,
),
style = BitwardenTheme.typography.bodyMedium,
color = BitwardenTheme.colorScheme.text.secondary,
textAlign = TextAlign.Center,
@@ -309,6 +313,24 @@ private fun FreeCloudContent(
Spacer(modifier = Modifier.height(16.dp))
Spacer(modifier = Modifier.navigationBarsPadding())
}
if (shouldShowUpgradeDialog) {
BitwardenTwoButtonDialog(
title = stringResource(id = BitwardenString.continue_to_stripe),
message = stringResource(
id = BitwardenString
.youll_go_to_stripes_secure_checkout_to_complete_your_purchase,
),
confirmButtonText = stringResource(id = BitwardenString.continue_text),
dismissButtonText = stringResource(id = BitwardenString.cancel),
onConfirmClick = {
shouldShowUpgradeDialog = false
handlers.onUpgradeNowClick()
},
onDismissClick = { shouldShowUpgradeDialog = false },
onDismissRequest = { shouldShowUpgradeDialog = false },
)
}
}
@Suppress("MaxLineLength")

View File

@@ -136,14 +136,66 @@ class PlanScreenTest : BitwardenComposeTest() {
}
@Test
fun `upgrade now button click should send UpgradeNowClick action`() {
fun `upgrade now button click should show continue to Stripe confirmation dialog`() {
composeTestRule
.onAllNodesWithText("Continue to Stripe?")
.filterToOne(hasAnyAncestor(isDialog()))
.assertDoesNotExist()
composeTestRule
.onNodeWithTag("UpgradeNowButton")
.performScrollTo()
.performClick()
verify {
viewModel.trySendAction(PlanAction.UpgradeNowClick)
}
composeTestRule
.onAllNodesWithText("Continue to Stripe?")
.filterToOne(hasAnyAncestor(isDialog()))
.assertExists()
composeTestRule
.onAllNodesWithText(
"Youll go to Stripes secure checkout to complete your purchase.",
)
.filterToOne(hasAnyAncestor(isDialog()))
.assertExists()
verify(exactly = 0) { viewModel.trySendAction(PlanAction.UpgradeNowClick) }
}
@Test
fun `upgrade now dialog continue click should send UpgradeNowClick action and dismiss`() {
composeTestRule
.onNodeWithTag("UpgradeNowButton")
.performScrollTo()
.performClick()
composeTestRule
.onAllNodesWithText("Continue")
.filterToOne(hasAnyAncestor(isDialog()))
.performClick()
verify { viewModel.trySendAction(PlanAction.UpgradeNowClick) }
composeTestRule
.onAllNodesWithText("Continue to Stripe?")
.filterToOne(hasAnyAncestor(isDialog()))
.assertDoesNotExist()
}
@Test
fun `upgrade now dialog cancel click should dismiss without sending action`() {
composeTestRule
.onNodeWithTag("UpgradeNowButton")
.performScrollTo()
.performClick()
composeTestRule
.onAllNodesWithText("Cancel")
.filterToOne(hasAnyAncestor(isDialog()))
.performClick()
verify(exactly = 0) { viewModel.trySendAction(PlanAction.UpgradeNowClick) }
composeTestRule
.onAllNodesWithText("Continue to Stripe?")
.filterToOne(hasAnyAncestor(isDialog()))
.assertDoesNotExist()
}
@Test

View File

@@ -1278,7 +1278,7 @@ Do you want to switch to this account?</string>
<string name="secure_file_storage">Secure file storage</string>
<string name="breach_monitoring">Breach monitoring</string>
<string name="upgrade_now">Upgrade now</string>
<string name="stripe_checkout_footer">Youll go to Stripes secure checkout to complete your purchase.</string>
<string name="youll_go_to_stripes_secure_checkout_to_complete_your_purchase">Youll go to Stripes secure checkout to complete your purchase.</string>
<string name="opening_checkout">Opening checkout…</string>
<string name="secure_checkout_didnt_load">Secure checkout didnt load</string>
<string name="trouble_opening_payment_page">We had trouble opening the payment page, so try again.</string>