diff options
| author | David Göransson <david.goransson@mullvad.net> | 2025-07-09 16:14:17 +0200 |
|---|---|---|
| committer | David Göransson <david.goransson@mullvad.net> | 2025-07-09 16:14:17 +0200 |
| commit | 4d90ff4fd81b0692945df0c67e0e8074716c14f3 (patch) | |
| tree | dc54697af312d65ff246d0fc3c07d5a44fd524af /android | |
| parent | ab2cf79c4b36e7ecf0485e57c89b50738b4fc482 (diff) | |
| parent | b1020e692b5cb4dfefb77a75c34d4f6af569d41e (diff) | |
| download | mullvadvpn-4d90ff4fd81b0692945df0c67e0e8074716c14f3.tar.xz mullvadvpn-4d90ff4fd81b0692945df0c67e0e8074716c14f3.zip | |
Merge branch 'billing-tests-are-flaky-droid-2075'
Diffstat (limited to 'android')
5 files changed, 67 insertions, 27 deletions
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/component/AddTimeBottomSheetTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/component/AddTimeBottomSheetTest.kt index 095c15dafc..893ac23825 100644 --- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/component/AddTimeBottomSheetTest.kt +++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/component/AddTimeBottomSheetTest.kt @@ -78,7 +78,7 @@ class AddTimeBottomSheetTest { state = AddTimeUiState( purchaseState = null, - billingPaymentState = null, + billingPaymentState = PaymentState.NoPayment, showSitePayment = true, tunnelStateBlocked = false, ) @@ -102,7 +102,7 @@ class AddTimeBottomSheetTest { state = AddTimeUiState( purchaseState = null, - billingPaymentState = null, + billingPaymentState = PaymentState.NoPayment, tunnelStateBlocked = false, showSitePayment = true, ) @@ -271,12 +271,21 @@ class AddTimeBottomSheetTest { fun testShowPurchaseCompleteDialog() = composeExtension.use { // Arrange + val productId = ProductId(ProductIds.ThreeMonths) initBottomSheet( state = AddTimeUiState( - purchaseState = - PurchaseState.Success(ProductId(ProductIds.ThreeMonths)), - billingPaymentState = null, + purchaseState = PurchaseState.Success(productId), + billingPaymentState = + PaymentState.PaymentAvailable( + listOf( + PaymentProduct( + productId = productId, + price = ProductPrice("$30"), + status = null, + ) + ) + ), tunnelStateBlocked = false, showSitePayment = false, ) @@ -292,10 +301,20 @@ class AddTimeBottomSheetTest { fun testShowVerificationErrorDialog() = composeExtension.use { // Arrange + val productId = ProductId(ProductIds.ThreeMonths) initBottomSheet( AddTimeUiState( purchaseState = PurchaseState.VerifyingPurchase, - billingPaymentState = null, + billingPaymentState = + PaymentState.PaymentAvailable( + listOf( + PaymentProduct( + productId = productId, + price = ProductPrice("$30"), + status = null, + ) + ) + ), tunnelStateBlocked = false, showSitePayment = false, ) @@ -310,11 +329,22 @@ class AddTimeBottomSheetTest { fun testShowFetchProductsErrorDialog() = composeExtension.use { // Arrange + + val productId = ProductId(ProductIds.ThreeMonths) initBottomSheet( state = AddTimeUiState( - purchaseState = PurchaseState.Error.OtherError(ProductId("ProductId")), - billingPaymentState = null, + purchaseState = PurchaseState.Error.OtherError(productId), + billingPaymentState = + PaymentState.PaymentAvailable( + listOf( + PaymentProduct( + productId = productId, + price = ProductPrice("$30"), + status = null, + ) + ) + ), tunnelStateBlocked = false, showSitePayment = false, ) @@ -336,7 +366,7 @@ class AddTimeBottomSheetTest { state = AddTimeUiState( purchaseState = null, - billingPaymentState = null, + billingPaymentState = PaymentState.NoPayment, tunnelStateBlocked = false, showSitePayment = false, ) @@ -355,7 +385,7 @@ class AddTimeBottomSheetTest { state = AddTimeUiState( purchaseState = null, - billingPaymentState = null, + billingPaymentState = PaymentState.NoPayment, tunnelStateBlocked = true, showSitePayment = true, ) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/AddMoreTimeUiStatePreviewParameterProvider.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/AddMoreTimeUiStatePreviewParameterProvider.kt index 1a2f5a7024..24160aa40c 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/AddMoreTimeUiStatePreviewParameterProvider.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/AddMoreTimeUiStatePreviewParameterProvider.kt @@ -17,14 +17,14 @@ class AddMoreTimeUiStatePreviewParameterProvider : Lc.Loading(Unit), AddTimeUiState( purchaseState = null, - billingPaymentState = null, + billingPaymentState = PaymentState.Loading, showSitePayment = true, tunnelStateBlocked = false, ) .toLc(), AddTimeUiState( purchaseState = null, - billingPaymentState = null, + billingPaymentState = PaymentState.NoPayment, showSitePayment = true, tunnelStateBlocked = false, ) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/AddTimeUiState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/AddTimeUiState.kt index a9b4d3c09c..94340e8e45 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/AddTimeUiState.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/AddTimeUiState.kt @@ -4,7 +4,7 @@ import net.mullvad.mullvadvpn.lib.payment.model.ProductId data class AddTimeUiState( val purchaseState: PurchaseState?, - val billingPaymentState: PaymentState?, + val billingPaymentState: PaymentState, val showSitePayment: Boolean, val tunnelStateBlocked: Boolean, ) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AddTimeViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AddTimeViewModel.kt index 141e854b81..36e6864a80 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AddTimeViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AddTimeViewModel.kt @@ -8,6 +8,7 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch @@ -35,14 +36,14 @@ class AddTimeViewModel( val uiState: StateFlow<Lc<Unit, AddTimeUiState>> = combine( - paymentUseCase.paymentAvailability, + paymentUseCase.paymentAvailability.filterNotNull(), paymentUseCase.purchaseResult, connectionProxy.tunnelState, ) { paymentAvailability, purchaseResult, tunnelState -> Lc.Content( AddTimeUiState( purchaseState = purchaseResult?.toPurchaseState(), - billingPaymentState = paymentAvailability?.toPaymentState(), + billingPaymentState = paymentAvailability.toPaymentState(), tunnelStateBlocked = tunnelState.isBlocked(), showSitePayment = !isPlayBuild, ) diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/AddTimeViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/AddTimeViewModelTest.kt index 1b9c4a9ef3..f9497bd159 100644 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/AddTimeViewModelTest.kt +++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/AddTimeViewModelTest.kt @@ -21,6 +21,7 @@ import net.mullvad.mullvadvpn.lib.model.TunnelState import net.mullvad.mullvadvpn.lib.payment.model.PaymentAvailability import net.mullvad.mullvadvpn.lib.payment.model.PaymentProduct import net.mullvad.mullvadvpn.lib.payment.model.ProductId +import net.mullvad.mullvadvpn.lib.payment.model.ProductPrice import net.mullvad.mullvadvpn.lib.payment.model.PurchaseResult import net.mullvad.mullvadvpn.lib.payment.model.VerificationResult import net.mullvad.mullvadvpn.lib.shared.AccountRepository @@ -78,12 +79,14 @@ class AddTimeViewModelTest { @Test fun `when paymentAvailability emits ErrorOther uiState should be null`() = runTest { - // Arrange - paymentAvailability.emit(PaymentAvailability.Error.Other(mockk())) // Act, Assert viewModel.uiState.test { awaitItem() // Default state + + // Emit an error with a mock exception + paymentAvailability.emit(PaymentAvailability.Error.Other(mockk())) + val result = awaitItem() assertIs<Lc.Content<AddTimeUiState>>(result) assertIs<PaymentState.Error.Generic>(result.value.billingPaymentState) @@ -122,7 +125,7 @@ class AddTimeViewModelTest { } @Test - fun `startBillingPayment should invoke purchaseProduct on PaymentUseCase`() { + fun `startBillingPayment should invoke purchaseProduct on PaymentUseCase`() = runTest { // Arrange val mockProductId = ProductId("MOCK") val mockActivityProvider = mockk<() -> Activity>() @@ -149,7 +152,7 @@ class AddTimeViewModelTest { } @Test - fun `purchaseState error should invoke queryPaymentAvailability on PaymentUseCase`() { + fun `purchaseState error should invoke queryPaymentAvailability on PaymentUseCase`() = runTest { // Arrange val purchaseResultData = PurchaseResult.Error.VerificationError(Throwable()) @@ -161,25 +164,31 @@ class AddTimeViewModelTest { } @Test - fun `resetPurchaseResult with success should invoke resetPurchaseResult on PaymentUseCase`() { - // Arrange + fun `resetPurchaseResult with success should invoke resetPurchaseResult on PaymentUseCase`() = + runTest { + // Arrange - // Act - viewModel.resetPurchaseResult() + // Act + viewModel.resetPurchaseResult() - // Assert - coVerify { mockPaymentUseCase.resetPurchaseResult() } - } + // Assert + coVerify { mockPaymentUseCase.resetPurchaseResult() } + } @Test fun `purchaseResult emitting Success should result in success dialog state`() = runTest { // Arrange - val result = PurchaseState.Success(ProductId("one_month")) + val productId = ProductId("one_month") + val paymentProduct = + PaymentProduct(productId = productId, price = ProductPrice("€5.00"), status = null) + val result = PurchaseState.Success(productId) val purchaseResultData = PurchaseResult.Completed.Success(ProductId("one_month")) // Act, Assert viewModel.uiState.test { awaitItem() // Default state + paymentAvailability.emit(PaymentAvailability.ProductsAvailable(listOf(paymentProduct))) + awaitItem() purchaseResult.emit(purchaseResultData) val item = awaitItem() assertIs<Lc.Content<AddTimeUiState>>(item) |
