diff options
| author | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2024-06-19 22:43:37 +0200 |
|---|---|---|
| committer | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2024-06-19 22:43:37 +0200 |
| commit | 52efdbe99507d6a5e60250d75d7049e2c3ade059 (patch) | |
| tree | 0bd3707a9c7ae4176e98efaa47f3681674743892 /android/app/src | |
| parent | b0335d5157e58a91f7d434aed3761e9dc81aba55 (diff) | |
| parent | 15d37677257bc2339b4a86eb6d90fbf6fe46696c (diff) | |
| download | mullvadvpn-52efdbe99507d6a5e60250d75d7049e2c3ade059.tar.xz mullvadvpn-52efdbe99507d6a5e60250d75d7049e2c3ade059.zip | |
Merge branch 'welcome-screen-does-not-display-disconnect-button-when-droid-884'
Diffstat (limited to 'android/app/src')
5 files changed, 96 insertions, 31 deletions
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreenTest.kt index 41c2c73d6a..cd5afa18fc 100644 --- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreenTest.kt +++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreenTest.kt @@ -14,6 +14,7 @@ import net.mullvad.mullvadvpn.compose.state.PaymentState import net.mullvad.mullvadvpn.compose.state.WelcomeUiState import net.mullvad.mullvadvpn.compose.test.PLAY_PAYMENT_INFO_ICON_TEST_TAG import net.mullvad.mullvadvpn.lib.model.AccountNumber +import net.mullvad.mullvadvpn.lib.model.TunnelState import net.mullvad.mullvadvpn.lib.payment.model.PaymentProduct import net.mullvad.mullvadvpn.lib.payment.model.PaymentStatus import net.mullvad.mullvadvpn.lib.payment.model.ProductId @@ -44,7 +45,8 @@ class WelcomeScreenTest { onAccountClick = {}, onPurchaseBillingProductClick = { _ -> }, navigateToDeviceInfoDialog = {}, - navigateToVerificationPendingDialog = {} + navigateToVerificationPendingDialog = {}, + onDisconnectClick = {} ) } @@ -66,7 +68,8 @@ class WelcomeScreenTest { onAccountClick = {}, onPurchaseBillingProductClick = { _ -> }, navigateToDeviceInfoDialog = {}, - navigateToVerificationPendingDialog = {} + navigateToVerificationPendingDialog = {}, + onDisconnectClick = {} ) } @@ -94,7 +97,8 @@ class WelcomeScreenTest { onAccountClick = {}, onPurchaseBillingProductClick = { _ -> }, navigateToDeviceInfoDialog = {}, - navigateToVerificationPendingDialog = {} + navigateToVerificationPendingDialog = {}, + onDisconnectClick = {} ) } @@ -116,7 +120,8 @@ class WelcomeScreenTest { onAccountClick = {}, onPurchaseBillingProductClick = { _ -> }, navigateToDeviceInfoDialog = {}, - navigateToVerificationPendingDialog = {} + navigateToVerificationPendingDialog = {}, + onDisconnectClick = {} ) } @@ -141,7 +146,8 @@ class WelcomeScreenTest { onAccountClick = {}, onPurchaseBillingProductClick = { _ -> }, navigateToDeviceInfoDialog = {}, - navigateToVerificationPendingDialog = {} + navigateToVerificationPendingDialog = {}, + onDisconnectClick = {} ) } @@ -165,7 +171,8 @@ class WelcomeScreenTest { onAccountClick = {}, onPurchaseBillingProductClick = { _ -> }, navigateToDeviceInfoDialog = {}, - navigateToVerificationPendingDialog = {} + navigateToVerificationPendingDialog = {}, + onDisconnectClick = {} ) } @@ -193,7 +200,8 @@ class WelcomeScreenTest { onAccountClick = {}, onPurchaseBillingProductClick = { _ -> }, navigateToDeviceInfoDialog = {}, - navigateToVerificationPendingDialog = {} + navigateToVerificationPendingDialog = {}, + onDisconnectClick = {} ) } @@ -222,7 +230,8 @@ class WelcomeScreenTest { onAccountClick = {}, onPurchaseBillingProductClick = { _ -> }, navigateToDeviceInfoDialog = {}, - navigateToVerificationPendingDialog = {} + navigateToVerificationPendingDialog = {}, + onDisconnectClick = {} ) } @@ -252,7 +261,8 @@ class WelcomeScreenTest { onAccountClick = {}, onPurchaseBillingProductClick = { _ -> }, navigateToVerificationPendingDialog = mockShowPendingInfo, - navigateToDeviceInfoDialog = {} + navigateToDeviceInfoDialog = {}, + onDisconnectClick = {} ) } @@ -284,7 +294,8 @@ class WelcomeScreenTest { onAccountClick = {}, onPurchaseBillingProductClick = { _ -> }, navigateToDeviceInfoDialog = {}, - navigateToVerificationPendingDialog = {} + navigateToVerificationPendingDialog = {}, + onDisconnectClick = {} ) } @@ -314,7 +325,8 @@ class WelcomeScreenTest { onAccountClick = {}, onPurchaseBillingProductClick = clickHandler, navigateToDeviceInfoDialog = {}, - navigateToVerificationPendingDialog = {} + navigateToVerificationPendingDialog = {}, + onDisconnectClick = {} ) } @@ -324,4 +336,32 @@ class WelcomeScreenTest { // Assert verify { clickHandler(ProductId("PRODUCT_ID")) } } + + @Test + fun testOnDisconnectClick() = + composeExtension.use { + // Arrange + val clickHandler: () -> Unit = mockk(relaxed = true) + val tunnelState: TunnelState = mockk(relaxed = true) + every { tunnelState.isSecured() } returns true + setContentWithTheme { + WelcomeScreen( + state = WelcomeUiState(tunnelState = tunnelState), + onSitePaymentClick = {}, + onRedeemVoucherClick = {}, + onSettingsClick = {}, + onAccountClick = {}, + onPurchaseBillingProductClick = {}, + navigateToDeviceInfoDialog = {}, + navigateToVerificationPendingDialog = {}, + onDisconnectClick = clickHandler + ) + } + + // Act + onNodeWithText("Disconnect").performClick() + + // Assert + verify { clickHandler() } + } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt index 22ab725e7f..58e5d4f8b3 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt @@ -48,7 +48,6 @@ import net.mullvad.mullvadvpn.compose.state.OutOfTimeUiState import net.mullvad.mullvadvpn.compose.test.OUT_OF_TIME_SCREEN_TITLE_TEST_TAG import net.mullvad.mullvadvpn.compose.transitions.HomeTransition import net.mullvad.mullvadvpn.compose.util.CollectSideEffectWithLifecycle -import net.mullvad.mullvadvpn.lib.model.ActionAfterDisconnect import net.mullvad.mullvadvpn.lib.model.ErrorState import net.mullvad.mullvadvpn.lib.model.ErrorStateCause import net.mullvad.mullvadvpn.lib.model.TunnelState @@ -268,7 +267,7 @@ private fun ButtonPanel( ) { Column { - if (state.tunnelState.showDisconnectButton()) { + if (state.tunnelState.isSecured()) { NegativeButton( onClick = onDisconnectClick, text = stringResource(id = R.string.disconnect), @@ -321,17 +320,6 @@ private fun ButtonPanel( } } -private fun TunnelState.showDisconnectButton(): Boolean = - when (this) { - is TunnelState.Disconnected -> false - is TunnelState.Connecting, - is TunnelState.Connected -> true - is TunnelState.Disconnecting -> { - this.actionAfterDisconnect != ActionAfterDisconnect.Nothing - } - is TunnelState.Error -> this.errorState.isBlocking - } - private fun TunnelState.enableSitePaymentButton(): Boolean = this is TunnelState.Disconnected private fun TunnelState.enableRedeemButton(): Boolean = diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreen.kt index 71594527fd..f233358bfc 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreen.kt @@ -35,6 +35,7 @@ import com.ramcosta.composedestinations.result.NavResult import com.ramcosta.composedestinations.result.ResultRecipient import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.compose.NavGraphs +import net.mullvad.mullvadvpn.compose.button.NegativeButton import net.mullvad.mullvadvpn.compose.button.RedeemVoucherButton import net.mullvad.mullvadvpn.compose.button.SitePaymentButton import net.mullvad.mullvadvpn.compose.component.CopyAnimatedIconButton @@ -89,7 +90,8 @@ private fun PreviewWelcomeScreen() { onAccountClick = {}, onPurchaseBillingProductClick = { _ -> }, navigateToDeviceInfoDialog = {}, - navigateToVerificationPendingDialog = {} + navigateToVerificationPendingDialog = {}, + onDisconnectClick = {} ) } } @@ -152,6 +154,7 @@ fun Welcome( onPurchaseBillingProductClick = { productId -> navigator.navigate(PaymentDestination(productId), onlyIfResumed = true) }, + onDisconnectClick = vm::onDisconnectClick, navigateToVerificationPendingDialog = dropUnlessResumed { navigator.navigate(VerificationPendingDialogDestination) } ) @@ -165,6 +168,7 @@ fun WelcomeScreen( onSettingsClick: () -> Unit, onAccountClick: () -> Unit, onPurchaseBillingProductClick: (productId: ProductId) -> Unit, + onDisconnectClick: () -> Unit, navigateToDeviceInfoDialog: () -> Unit, navigateToVerificationPendingDialog: () -> Unit ) { @@ -193,14 +197,16 @@ fun WelcomeScreen( Spacer(modifier = Modifier.weight(1f)) - // Payment button area - PaymentPanel( + // Button area + ButtonPanel( + showDisconnectButton = state.tunnelState.isSecured(), showSitePayment = state.showSitePayment, billingPaymentState = state.billingPaymentState, onSitePaymentClick = onSitePaymentClick, onRedeemVoucherClick = onRedeemVoucherClick, onPurchaseBillingProductClick = onPurchaseBillingProductClick, - onPaymentInfoClick = navigateToVerificationPendingDialog + onPaymentInfoClick = navigateToVerificationPendingDialog, + onDisconnectClick = onDisconnectClick ) } } @@ -326,16 +332,30 @@ fun DeviceNameRow(deviceName: String?, navigateToDeviceInfoDialog: () -> Unit) { } @Composable -private fun PaymentPanel( +private fun ButtonPanel( + showDisconnectButton: Boolean, showSitePayment: Boolean, billingPaymentState: PaymentState?, onSitePaymentClick: () -> Unit, onRedeemVoucherClick: () -> Unit, onPurchaseBillingProductClick: (productId: ProductId) -> Unit, - onPaymentInfoClick: () -> Unit + onPaymentInfoClick: () -> Unit, + onDisconnectClick: () -> Unit ) { Column(modifier = Modifier.fillMaxWidth().padding(top = Dimens.mediumPadding)) { Spacer(modifier = Modifier.padding(top = Dimens.screenVerticalMargin)) + if (showDisconnectButton) { + NegativeButton( + onClick = onDisconnectClick, + text = stringResource(id = R.string.disconnect), + modifier = + Modifier.padding( + start = Dimens.sideMargin, + end = Dimens.sideMargin, + bottom = Dimens.buttonSpacing + ) + ) + } billingPaymentState?.let { PlayPayment( billingPaymentState = billingPaymentState, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModel.kt index 9322ef9ce4..f987f16dc9 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModel.kt @@ -28,7 +28,7 @@ class WelcomeViewModel( private val accountRepository: AccountRepository, deviceRepository: DeviceRepository, private val paymentUseCase: PaymentUseCase, - connectionProxy: ConnectionProxy, + private val connectionProxy: ConnectionProxy, private val pollAccountExpiry: Boolean = true, private val isPlayBuild: Boolean ) : ViewModel() { @@ -78,6 +78,10 @@ class WelcomeViewModel( } } + fun onDisconnectClick() { + viewModelScope.launch { connectionProxy.disconnect() } + } + private fun verifyPurchases() { viewModelScope.launch { if (paymentUseCase.verifyPurchases().isSuccess()) { diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModelTest.kt index 4aaa000047..1c7a7d0e3b 100644 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModelTest.kt +++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModelTest.kt @@ -3,6 +3,7 @@ package net.mullvad.mullvadvpn.viewmodel import androidx.lifecycle.viewModelScope import app.cash.turbine.test import io.mockk.coEvery +import io.mockk.coVerify import io.mockk.every import io.mockk.mockk import io.mockk.mockkStatic @@ -213,6 +214,18 @@ class WelcomeViewModelTest { } } + @Test + fun `when on disconnect click is called should call connection proxy disconnect`() = runTest { + // Arrange + coEvery { mockConnectionProxy.disconnect() } returns true + + // Act + viewModel.onDisconnectClick() + + // Assert + coVerify { mockConnectionProxy.disconnect() } + } + companion object { private const val PURCHASE_RESULT_EXTENSIONS_CLASS = "net.mullvad.mullvadvpn.util.PurchaseResultExtensionsKt" |
