summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJonatan Rhodin <jonatan.rhodin@mullvad.net>2024-06-19 22:43:37 +0200
committerJonatan Rhodin <jonatan.rhodin@mullvad.net>2024-06-19 22:43:37 +0200
commit52efdbe99507d6a5e60250d75d7049e2c3ade059 (patch)
tree0bd3707a9c7ae4176e98efaa47f3681674743892
parentb0335d5157e58a91f7d434aed3761e9dc81aba55 (diff)
parent15d37677257bc2339b4a86eb6d90fbf6fe46696c (diff)
downloadmullvadvpn-52efdbe99507d6a5e60250d75d7049e2c3ade059.tar.xz
mullvadvpn-52efdbe99507d6a5e60250d75d7049e2c3ade059.zip
Merge branch 'welcome-screen-does-not-display-disconnect-button-when-droid-884'
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreenTest.kt62
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt14
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreen.kt32
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModel.kt6
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModelTest.kt13
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"