summaryrefslogtreecommitdiffhomepage
path: root/android/app/src/test
diff options
context:
space:
mode:
authorDavid Göransson <david.goransson90@gmail.com>2023-12-14 16:40:25 +0100
committerAlbin <albin@mullvad.net>2023-12-14 16:54:21 +0100
commit435d437f344d484270c1ce55d9f65985287bfac8 (patch)
treea53801b0a90b04944938c1db9436cbe357208fe9 /android/app/src/test
parentf33b1f76eac937b579ef589cc047da8f3421f630 (diff)
downloadmullvadvpn-435d437f344d484270c1ce55d9f65985287bfac8.tar.xz
mullvadvpn-435d437f344d484270c1ce55d9f65985287bfac8.zip
Migrate to Compose Destinations
Diffstat (limited to 'android/app/src/test')
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModelTest.kt26
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModelTest.kt66
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModelTest.kt14
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt4
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModelTest.kt89
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/PaymentViewModelTest.kt70
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ReportProblemViewModelTest.kt192
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModelTest.kt4
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt27
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModelTest.kt129
10 files changed, 375 insertions, 246 deletions
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModelTest.kt
index c02e755951..282d1d3a27 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModelTest.kt
@@ -11,10 +11,8 @@ import io.mockk.unmockkAll
import io.mockk.verify
import kotlin.test.assertEquals
import kotlin.test.assertIs
-import kotlin.test.assertNull
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
-import net.mullvad.mullvadvpn.compose.dialog.payment.PaymentDialogData
import net.mullvad.mullvadvpn.compose.state.PaymentState
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.common.test.assertLists
@@ -32,7 +30,6 @@ import net.mullvad.mullvadvpn.ui.serviceconnection.AuthTokenCache
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager
import net.mullvad.mullvadvpn.ui.serviceconnection.authTokenCache
import net.mullvad.mullvadvpn.usecase.PaymentUseCase
-import net.mullvad.mullvadvpn.util.toPaymentDialogData
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -161,29 +158,6 @@ class AccountViewModelTest {
}
@Test
- fun testBillingUserCancelled() = runTest {
- // Arrange
- val result = PurchaseResult.Completed.Cancelled
- purchaseResult.value = result
- every { result.toPaymentDialogData() } returns null
-
- // Act, Assert
- viewModel.uiState.test { assertNull(awaitItem().paymentDialogData) }
- }
-
- @Test
- fun testBillingPurchaseSuccess() = runTest {
- // Arrange
- val result = PurchaseResult.Completed.Success
- val expectedData: PaymentDialogData = mockk()
- purchaseResult.value = result
- every { result.toPaymentDialogData() } returns expectedData
-
- // Act, Assert
- viewModel.uiState.test { assertEquals(expectedData, awaitItem().paymentDialogData) }
- }
-
- @Test
fun testStartBillingPayment() {
// Arrange
val mockProductId = ProductId("MOCK")
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModelTest.kt
index e223a12539..3350178ca3 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ChangelogViewModelTest.kt
@@ -8,15 +8,17 @@ import io.mockk.impl.annotations.MockK
import io.mockk.just
import io.mockk.mockkStatic
import io.mockk.unmockkAll
-import io.mockk.verify
-import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
import kotlinx.coroutines.test.runTest
+import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.repository.ChangelogRepository
import org.junit.After
import org.junit.Before
+import org.junit.Rule
import org.junit.Test
class ChangelogViewModelTest {
+ @get:Rule val testCoroutineRule = TestCoroutineRule()
@MockK private lateinit var mockedChangelogRepository: ChangelogRepository
@@ -28,7 +30,6 @@ class ChangelogViewModelTest {
mockkStatic(EVENT_NOTIFIER_EXTENSION_CLASS)
every { mockedChangelogRepository.setVersionCodeOfMostRecentChangelogShowed(any()) } just
Runs
- viewModel = ChangelogViewModel(mockedChangelogRepository, 1, false)
}
@After
@@ -37,54 +38,41 @@ class ChangelogViewModelTest {
}
@Test
- fun testInitialState() = runTest {
- // Arrange, Act, Assert
- viewModel.uiState.test { assertEquals(ChangelogDialogUiState.Hide, awaitItem()) }
+ fun testUpToDateVersionCodeShouldNotEmitChangelog() = runTest {
+ // Arrange
+ every { mockedChangelogRepository.getVersionCodeOfMostRecentChangelogShowed() } returns
+ buildVersionCode
+ viewModel = ChangelogViewModel(mockedChangelogRepository, buildVersionCode, false)
+
+ // If we have the most up to date version code, we should not show the changelog dialog
+ viewModel.uiSideEffect.test { expectNoEvents() }
}
@Test
- fun testShowAndDismissChangelogDialog() = runTest {
- viewModel.uiState.test {
- // Arrange
- val fakeList = listOf("test")
- every { mockedChangelogRepository.getVersionCodeOfMostRecentChangelogShowed() } returns
- -1
- every { mockedChangelogRepository.getLastVersionChanges() } returns fakeList
-
- // Assert initial ui state
- assertEquals(ChangelogDialogUiState.Hide, awaitItem())
+ fun testNotUpToDateVersionCodeShouldEmitChangelog() = runTest {
+ // Arrange
+ every { mockedChangelogRepository.getVersionCodeOfMostRecentChangelogShowed() } returns -1
+ every { mockedChangelogRepository.getLastVersionChanges() } returns listOf("bla", "bla")
- // Refresh and verify that the dialog should be shown
- viewModel.refreshChangelogDialogUiState()
- assertEquals(ChangelogDialogUiState.Show(fakeList), awaitItem())
-
- // Dismiss dialog and verify that the dialog should be hidden
- viewModel.dismissChangelogDialog()
- assertEquals(ChangelogDialogUiState.Hide, awaitItem())
- verify { mockedChangelogRepository.setVersionCodeOfMostRecentChangelogShowed(1) }
- }
+ viewModel = ChangelogViewModel(mockedChangelogRepository, buildVersionCode, false)
+ // Given a new version with a change log we should return it
+ viewModel.uiSideEffect.test { assertNotNull(awaitItem()) }
}
@Test
- fun testShowCaseChangelogWithEmptyListDialog() = runTest {
- viewModel.uiState.test {
- // Arrange
- val fakeEmptyList = emptyList<String>()
- every { mockedChangelogRepository.getVersionCodeOfMostRecentChangelogShowed() } returns
- -1
- every { mockedChangelogRepository.getLastVersionChanges() } returns fakeEmptyList
-
- // Assert initial ui state
- assertEquals(ChangelogDialogUiState.Hide, awaitItem())
+ fun testEmptyChangelogShouldNotEmitChangelog() = runTest {
+ // Arrange
+ every { mockedChangelogRepository.getVersionCodeOfMostRecentChangelogShowed() } returns -1
+ every { mockedChangelogRepository.getLastVersionChanges() } returns emptyList()
- // Refresh and verify that the Ui state remain same due list being empty
- viewModel.refreshChangelogDialogUiState()
- expectNoEvents()
- }
+ viewModel = ChangelogViewModel(mockedChangelogRepository, buildVersionCode, false)
+ // Given a new version with a change log we should not return it
+ viewModel.uiSideEffect.test { expectNoEvents() }
}
companion object {
private const val EVENT_NOTIFIER_EXTENSION_CLASS =
"net.mullvad.talpid.util.EventNotifierExtensionsKt"
+ private const val buildVersionCode = 10
}
}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModelTest.kt
index 345a57df80..35898df4ab 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModelTest.kt
@@ -39,11 +39,11 @@ import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState
import net.mullvad.mullvadvpn.ui.serviceconnection.authTokenCache
import net.mullvad.mullvadvpn.ui.serviceconnection.connectionProxy
+import net.mullvad.mullvadvpn.usecase.OutOfTimeUseCase
import net.mullvad.mullvadvpn.usecase.PaymentUseCase
import net.mullvad.mullvadvpn.usecase.RelayListUseCase
import net.mullvad.mullvadvpn.util.appVersionCallbackFlow
import net.mullvad.talpid.tunnel.ErrorState
-import net.mullvad.talpid.tunnel.ErrorStateCause
import net.mullvad.talpid.util.EventNotifier
import org.junit.After
import org.junit.Before
@@ -103,6 +103,10 @@ class ConnectViewModelTest {
// Flows
private val selectedRelayFlow = MutableStateFlow<RelayItem?>(null)
+ // Out Of Time Use Case
+ private val outOfTimeUseCase: OutOfTimeUseCase = mockk()
+ private val outOfTimeViewFlow = MutableStateFlow(false)
+
@Before
fun setup() {
mockkStatic(CACHE_EXTENSION_CLASS)
@@ -136,6 +140,7 @@ class ConnectViewModelTest {
// Flows
every { mockRelayListUseCase.selectedRelayItem() } returns selectedRelayFlow
+ every { outOfTimeUseCase.isOutOfTime() } returns outOfTimeViewFlow
viewModel =
ConnectViewModel(
serviceConnectionManager = mockServiceConnectionManager,
@@ -144,6 +149,7 @@ class ConnectViewModelTest {
inAppNotificationController = mockInAppNotificationController,
relayListUseCase = mockRelayListUseCase,
newDeviceNotificationUseCase = mockk(),
+ outOfTimeUseCase = outOfTimeUseCase,
paymentUseCase = mockPaymentUseCase
)
}
@@ -342,8 +348,6 @@ class ConnectViewModelTest {
fun testOutOfTimeUiSideEffect() =
runTest(testCoroutineRule.testDispatcher) {
// Arrange
- val errorStateCause = ErrorStateCause.AuthFailed("[EXPIRED_ACCOUNT]")
- val tunnelRealStateTestItem = TunnelState.Error(ErrorState(errorStateCause, true))
val deferred = async { viewModel.uiSideEffect.first() }
// Act
@@ -352,12 +356,12 @@ class ConnectViewModelTest {
serviceConnectionState.value =
ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
locationSlot.captured.invoke(mockLocation)
- eventNotifierTunnelRealState.notify(tunnelRealStateTestItem)
+ outOfTimeViewFlow.value = true
awaitItem()
}
// Assert
- assertIs<ConnectViewModel.UiSideEffect.OpenOutOfTimeView>(deferred.await())
+ assertIs<ConnectViewModel.UiSideEffect.OutOfTime>(deferred.await())
}
companion object {
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt
index 7eb35404d0..c402a3103e 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt
@@ -20,6 +20,7 @@ import net.mullvad.mullvadvpn.compose.state.LoginState.Success
import net.mullvad.mullvadvpn.compose.state.LoginUiState
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.model.AccountCreationResult
+import net.mullvad.mullvadvpn.model.AccountExpiry
import net.mullvad.mullvadvpn.model.AccountHistory
import net.mullvad.mullvadvpn.model.AccountToken
import net.mullvad.mullvadvpn.model.DeviceListEvent
@@ -28,6 +29,7 @@ import net.mullvad.mullvadvpn.repository.AccountRepository
import net.mullvad.mullvadvpn.repository.DeviceRepository
import net.mullvad.mullvadvpn.usecase.ConnectivityUseCase
import net.mullvad.mullvadvpn.usecase.NewDeviceNotificationUseCase
+import org.joda.time.DateTime
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
@@ -113,6 +115,8 @@ class LoginViewModelTest {
val uiStates = loginViewModel.uiState.testIn(backgroundScope)
val sideEffects = loginViewModel.uiSideEffect.testIn(backgroundScope)
coEvery { mockedAccountRepository.login(any()) } returns LoginResult.Ok
+ coEvery { mockedAccountRepository.accountExpiryState } returns
+ MutableStateFlow(AccountExpiry.Available(DateTime.now().plusDays(3)))
// Act, Assert
uiStates.skipDefaultItem()
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModelTest.kt
index dad51eab59..0232f12e89 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModelTest.kt
@@ -1,6 +1,5 @@
package net.mullvad.mullvadvpn.viewmodel
-import android.app.Activity
import androidx.lifecycle.viewModelScope
import app.cash.turbine.test
import io.mockk.coEvery
@@ -12,18 +11,15 @@ import io.mockk.unmockkAll
import io.mockk.verify
import kotlin.test.assertEquals
import kotlin.test.assertIs
-import kotlin.test.assertNull
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
-import net.mullvad.mullvadvpn.compose.dialog.payment.PaymentDialogData
import net.mullvad.mullvadvpn.compose.state.OutOfTimeUiState
import net.mullvad.mullvadvpn.compose.state.PaymentState
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.common.test.assertLists
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.PurchaseResult
import net.mullvad.mullvadvpn.model.AccountExpiry
import net.mullvad.mullvadvpn.model.DeviceState
@@ -37,8 +33,8 @@ import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState
import net.mullvad.mullvadvpn.ui.serviceconnection.authTokenCache
import net.mullvad.mullvadvpn.ui.serviceconnection.connectionProxy
+import net.mullvad.mullvadvpn.usecase.OutOfTimeUseCase
import net.mullvad.mullvadvpn.usecase.PaymentUseCase
-import net.mullvad.mullvadvpn.util.toPaymentDialogData
import net.mullvad.talpid.util.EventNotifier
import org.joda.time.DateTime
import org.joda.time.ReadableInstant
@@ -50,12 +46,13 @@ import org.junit.Test
class OutOfTimeViewModelTest {
@get:Rule val testCoroutineRule = TestCoroutineRule()
- private val serviceConnectionState =
+ private val serviceConnectionStateFlow =
MutableStateFlow<ServiceConnectionState>(ServiceConnectionState.Disconnected)
- private val accountExpiryState = MutableStateFlow<AccountExpiry>(AccountExpiry.Missing)
- private val deviceState = MutableStateFlow<DeviceState>(DeviceState.Initial)
- private val paymentAvailability = MutableStateFlow<PaymentAvailability?>(null)
- private val purchaseResult = MutableStateFlow<PurchaseResult?>(null)
+ private val accountExpiryStateFlow = MutableStateFlow<AccountExpiry>(AccountExpiry.Missing)
+ private val deviceStateFlow = MutableStateFlow<DeviceState>(DeviceState.Initial)
+ private val paymentAvailabilityFlow = MutableStateFlow<PaymentAvailability?>(null)
+ private val purchaseResultFlow = MutableStateFlow<PurchaseResult?>(null)
+ private val outOfTimeFlow = MutableStateFlow(true)
// Service connections
private val mockServiceConnectionContainer: ServiceConnectionContainer = mockk()
@@ -68,6 +65,7 @@ class OutOfTimeViewModelTest {
private val mockDeviceRepository: DeviceRepository = mockk()
private val mockServiceConnectionManager: ServiceConnectionManager = mockk()
private val mockPaymentUseCase: PaymentUseCase = mockk(relaxed = true)
+ private val mockOutOfTimeUseCase: OutOfTimeUseCase = mockk(relaxed = true)
private lateinit var viewModel: OutOfTimeViewModel
@@ -76,19 +74,21 @@ class OutOfTimeViewModelTest {
mockkStatic(SERVICE_CONNECTION_MANAGER_EXTENSIONS)
mockkStatic(PURCHASE_RESULT_EXTENSIONS_CLASS)
- every { mockServiceConnectionManager.connectionState } returns serviceConnectionState
+ every { mockServiceConnectionManager.connectionState } returns serviceConnectionStateFlow
every { mockServiceConnectionContainer.connectionProxy } returns mockConnectionProxy
every { mockConnectionProxy.onStateChange } returns eventNotifierTunnelRealState
- every { mockAccountRepository.accountExpiryState } returns accountExpiryState
+ every { mockAccountRepository.accountExpiryState } returns accountExpiryStateFlow
- every { mockDeviceRepository.deviceState } returns deviceState
+ every { mockDeviceRepository.deviceState } returns deviceStateFlow
- coEvery { mockPaymentUseCase.purchaseResult } returns purchaseResult
+ coEvery { mockPaymentUseCase.purchaseResult } returns purchaseResultFlow
- coEvery { mockPaymentUseCase.paymentAvailability } returns paymentAvailability
+ coEvery { mockPaymentUseCase.paymentAvailability } returns paymentAvailabilityFlow
+
+ coEvery { mockOutOfTimeUseCase.isOutOfTime() } returns outOfTimeFlow
viewModel =
OutOfTimeViewModel(
@@ -96,6 +96,7 @@ class OutOfTimeViewModelTest {
serviceConnectionManager = mockServiceConnectionManager,
deviceRepository = mockDeviceRepository,
paymentUseCase = mockPaymentUseCase,
+ outOfTimeUseCase = mockOutOfTimeUseCase,
pollAccountExpiry = false
)
}
@@ -134,7 +135,7 @@ class OutOfTimeViewModelTest {
viewModel.uiState.test {
assertEquals(OutOfTimeUiState(deviceName = ""), awaitItem())
eventNotifierTunnelRealState.notify(tunnelRealStateTestItem)
- serviceConnectionState.value =
+ serviceConnectionStateFlow.value =
ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
val result = awaitItem()
assertEquals(tunnelRealStateTestItem, result.tunnelState)
@@ -150,7 +151,7 @@ class OutOfTimeViewModelTest {
// Act, Assert
viewModel.uiSideEffect.test {
- accountExpiryState.value = AccountExpiry.Available(mockExpiryDate)
+ outOfTimeFlow.value = false
val action = awaitItem()
assertIs<OutOfTimeViewModel.UiSideEffect.OpenConnectScreen>(action)
}
@@ -174,8 +175,8 @@ class OutOfTimeViewModelTest {
fun testBillingProductsUnavailableState() = runTest {
// Arrange
val productsUnavailable = PaymentAvailability.ProductsUnavailable
- paymentAvailability.value = productsUnavailable
- serviceConnectionState.value =
+ paymentAvailabilityFlow.value = productsUnavailable
+ serviceConnectionStateFlow.value =
ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
// Act, Assert
@@ -189,8 +190,8 @@ class OutOfTimeViewModelTest {
fun testBillingProductsGenericErrorState() = runTest {
// Arrange
val paymentAvailabilityError = PaymentAvailability.Error.Other(mockk())
- paymentAvailability.value = paymentAvailabilityError
- serviceConnectionState.value =
+ paymentAvailabilityFlow.value = paymentAvailabilityError
+ serviceConnectionStateFlow.value =
ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
// Act, Assert
@@ -204,8 +205,8 @@ class OutOfTimeViewModelTest {
fun testBillingProductsBillingErrorState() = runTest {
// Arrange
val paymentAvailabilityError = PaymentAvailability.Error.BillingUnavailable
- paymentAvailability.value = paymentAvailabilityError
- serviceConnectionState.value =
+ paymentAvailabilityFlow.value = paymentAvailabilityError
+ serviceConnectionStateFlow.value =
ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
// Act, Assert
@@ -221,8 +222,8 @@ class OutOfTimeViewModelTest {
val mockProduct: PaymentProduct = mockk()
val expectedProductList = listOf(mockProduct)
val productsAvailable = PaymentAvailability.ProductsAvailable(listOf(mockProduct))
- paymentAvailability.value = productsAvailable
- serviceConnectionState.value =
+ paymentAvailabilityFlow.value = productsAvailable
+ serviceConnectionStateFlow.value =
ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
// Act, Assert
@@ -234,44 +235,6 @@ class OutOfTimeViewModelTest {
}
@Test
- fun testBillingUserCancelled() = runTest {
- // Arrange
- val result = PurchaseResult.Completed.Cancelled
- purchaseResult.value = result
- every { result.toPaymentDialogData() } returns null
-
- // Act, Assert
- viewModel.uiState.test { assertNull(awaitItem().paymentDialogData) }
- }
-
- @Test
- fun testBillingPurchaseSuccess() = runTest {
- // Arrange
- val result = PurchaseResult.Completed.Success
- val expectedData: PaymentDialogData = mockk()
- purchaseResult.value = result
- serviceConnectionState.value =
- ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
- every { result.toPaymentDialogData() } returns expectedData
-
- // Act, Assert
- viewModel.uiState.test { assertEquals(expectedData, awaitItem().paymentDialogData) }
- }
-
- @Test
- fun testStartBillingPayment() {
- // Arrange
- val mockProductId = ProductId("MOCK")
- val mockActivityProvider = mockk<() -> Activity>()
-
- // Act
- viewModel.startBillingPayment(mockProductId, mockActivityProvider)
-
- // Assert
- coVerify { mockPaymentUseCase.purchaseProduct(mockProductId, mockActivityProvider) }
- }
-
- @Test
fun testOnClosePurchaseResultDialogSuccessful() {
// Arrange
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/PaymentViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/PaymentViewModelTest.kt
new file mode 100644
index 0000000000..665e23c3d4
--- /dev/null
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/PaymentViewModelTest.kt
@@ -0,0 +1,70 @@
+package net.mullvad.mullvadvpn.viewmodel
+
+import app.cash.turbine.test
+import io.mockk.coEvery
+import io.mockk.mockk
+import io.mockk.unmockkAll
+import kotlin.test.assertEquals
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.runTest
+import net.mullvad.mullvadvpn.compose.dialog.payment.PaymentDialogData
+import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
+import net.mullvad.mullvadvpn.lib.payment.model.PurchaseResult
+import net.mullvad.mullvadvpn.usecase.PaymentUseCase
+import net.mullvad.mullvadvpn.util.toPaymentDialogData
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+class PaymentViewModelTest {
+ @get:Rule val testCoroutineRule = TestCoroutineRule()
+
+ private val mockPaymentUseCase: PaymentUseCase = mockk(relaxed = true)
+
+ private val purchaseResult = MutableStateFlow<PurchaseResult?>(null)
+
+ private lateinit var viewModel: PaymentViewModel
+
+ @Before
+ fun setUp() {
+ coEvery { mockPaymentUseCase.purchaseResult } returns purchaseResult
+
+ viewModel = PaymentViewModel(paymentUseCase = mockPaymentUseCase)
+ }
+
+ @After
+ fun tearDown() {
+ unmockkAll()
+ }
+
+ @Test
+ fun testBillingUserCancelled() = runTest {
+ // Arrange
+ val result = PurchaseResult.Completed.Cancelled
+ purchaseResult.value = result
+
+ // Act, Assert
+ viewModel.uiState.test {
+ assertEquals(PaymentDialogData(), awaitItem().paymentDialogData)
+ purchaseResult.value = result
+ }
+
+ viewModel.uiSideEffect.test {
+ assertEquals(PaymentUiSideEffect.PaymentCancelled, awaitItem())
+ }
+ }
+
+ @Test
+ fun testBillingPurchaseSuccess() = runTest {
+ // Arrange
+ val result = PurchaseResult.Completed.Success
+
+ // Act, Assert
+ viewModel.uiState.test {
+ awaitItem()
+ purchaseResult.value = result
+ assertEquals(result.toPaymentDialogData(), awaitItem().paymentDialogData)
+ }
+ }
+}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ReportProblemViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ReportProblemViewModelTest.kt
new file mode 100644
index 0000000000..5726c6249c
--- /dev/null
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ReportProblemViewModelTest.kt
@@ -0,0 +1,192 @@
+package net.mullvad.mullvadvpn.viewmodel
+
+import androidx.lifecycle.viewModelScope
+import app.cash.turbine.test
+import io.mockk.MockKAnnotations
+import io.mockk.coEvery
+import io.mockk.impl.annotations.MockK
+import io.mockk.verify
+import kotlin.test.assertEquals
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.runTest
+import net.mullvad.mullvadvpn.dataproxy.MullvadProblemReport
+import net.mullvad.mullvadvpn.dataproxy.SendProblemReportResult
+import net.mullvad.mullvadvpn.dataproxy.UserReport
+import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
+import net.mullvad.mullvadvpn.repository.ProblemReportRepository
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+class ReportProblemViewModelTest {
+ @get:Rule val testCoroutineRule = TestCoroutineRule()
+
+ @MockK private lateinit var mockMullvadProblemReport: MullvadProblemReport
+
+ @MockK(relaxed = true) private lateinit var mockProblemReportRepository: ProblemReportRepository
+
+ private val problemReportFlow = MutableStateFlow(UserReport("", ""))
+
+ private lateinit var viewModel: ReportProblemViewModel
+
+ @Before
+ fun setUp() {
+ MockKAnnotations.init(this)
+ coEvery { mockMullvadProblemReport.collectLogs() } returns true
+ coEvery { mockProblemReportRepository.problemReport } returns problemReportFlow
+ viewModel = ReportProblemViewModel(mockMullvadProblemReport, mockProblemReportRepository)
+ }
+
+ @After
+ fun tearDown() {
+ viewModel.viewModelScope.coroutineContext.cancel()
+ }
+
+ @Test
+ fun sendReportFailedToCollectLogs() = runTest {
+ // Arrange
+ coEvery { mockMullvadProblemReport.sendReport(any()) } returns
+ SendProblemReportResult.Error.CollectLog
+ val email = "my@email.com"
+
+ // Act, Assert
+ viewModel.uiState.test {
+ assertEquals(null, awaitItem().sendingState)
+ viewModel.sendReport(email, "My description")
+ assertEquals(SendingReportUiState.Sending, awaitItem().sendingState)
+ assertEquals(
+ SendingReportUiState.Error(SendProblemReportResult.Error.CollectLog),
+ awaitItem().sendingState
+ )
+ }
+ }
+
+ @Test
+ fun sendReportFailedToSendReport() = runTest {
+ // Arrange
+ coEvery { mockMullvadProblemReport.sendReport(any()) } returns
+ SendProblemReportResult.Error.SendReport
+ val email = "my@email.com"
+
+ // Act, Assert
+ viewModel.uiState.test {
+ assertEquals(null, awaitItem().sendingState)
+ viewModel.sendReport(email, "My description")
+ assertEquals(SendingReportUiState.Sending, awaitItem().sendingState)
+ assertEquals(
+ SendingReportUiState.Error(SendProblemReportResult.Error.SendReport),
+ awaitItem().sendingState
+ )
+ }
+ }
+
+ @Test
+ fun sendReportWithoutEmailSuccessfully() = runTest {
+ // Arrange
+ coEvery { mockMullvadProblemReport.sendReport(any()) } returns
+ SendProblemReportResult.Success
+ val email = ""
+ val description = "My description"
+
+ coEvery { mockProblemReportRepository.setDescription(any()) } answers
+ {
+ problemReportFlow.value = problemReportFlow.value.copy(description = arg(0))
+ }
+
+ // Act, Assert
+ viewModel.uiState.test {
+ assertEquals(ReportProblemUiState(), awaitItem())
+ viewModel.updateDescription(description)
+ assertEquals(ReportProblemUiState(description = description), awaitItem())
+
+ viewModel.sendReport(email, description, true)
+ assertEquals(
+ ReportProblemUiState(SendingReportUiState.Sending, email, description),
+ awaitItem()
+ )
+ assertEquals(
+ ReportProblemUiState(
+ SendingReportUiState.Success(null),
+ "",
+ "",
+ ),
+ awaitItem()
+ )
+ }
+ }
+
+ @Test
+ fun sendReportSuccessfully() = runTest {
+ // Arrange
+ coEvery { mockMullvadProblemReport.collectLogs() } returns true
+ coEvery { mockMullvadProblemReport.sendReport(any()) } returns
+ SendProblemReportResult.Success
+ val email = "my@email.com"
+ val description = "My description"
+
+ // This might look a bit weird, and is not optimal. An alternative would be to use the real
+ // ProblemReportRepository, but that would complicate the other tests. This is a compromise.
+ coEvery { mockProblemReportRepository.setEmail(any()) } answers
+ {
+ problemReportFlow.value = problemReportFlow.value.copy(email = arg(0))
+ }
+ coEvery { mockProblemReportRepository.setDescription(any()) } answers
+ {
+ problemReportFlow.value = problemReportFlow.value.copy(description = arg(0))
+ }
+
+ // Act, Assert
+ viewModel.uiState.test {
+ assertEquals(awaitItem(), ReportProblemUiState(null, "", ""))
+ viewModel.updateEmail(email)
+ awaitItem()
+ viewModel.updateDescription(description)
+ awaitItem()
+
+ viewModel.sendReport(email, description)
+
+ assertEquals(
+ ReportProblemUiState(
+ SendingReportUiState.Sending,
+ email,
+ description,
+ ),
+ awaitItem()
+ )
+ assertEquals(
+ ReportProblemUiState(
+ SendingReportUiState.Success(email),
+ "",
+ "",
+ ),
+ awaitItem()
+ )
+ }
+ }
+
+ @Test
+ fun testUpdateEmail() = runTest {
+ // Arrange
+ val email = "my@email.com"
+
+ // Act
+ viewModel.updateEmail(email)
+
+ // Assert
+ verify { mockProblemReportRepository.setEmail(email) }
+ }
+
+ @Test
+ fun testUpdateDescription() = runTest {
+ // Arrange
+ val description = "My description"
+
+ // Act
+ viewModel.updateDescription(description)
+
+ // Assert
+ verify { mockProblemReportRepository.setDescription(description) }
+ }
+}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModelTest.kt
index 74d7d80c19..5ad1af1182 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModelTest.kt
@@ -120,10 +120,10 @@ class SelectLocationViewModelTest {
every { mockRelayListUseCase.updateSelectedRelayLocation(mockLocation) } returns Unit
// Act, Assert
- viewModel.uiCloseAction.test {
+ viewModel.uiSideEffect.test {
viewModel.selectRelay(mockRelayItem)
// Await an empty item
- assertEquals(Unit, awaitItem())
+ assertEquals(SelectLocationSideEffect.CloseScreen, awaitItem())
verify {
connectionProxyMock.connect()
mockRelayListUseCase.updateSelectedRelayLocation(mockLocation)
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt
index f8736eb823..0ac13777cd 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt
@@ -9,15 +9,11 @@ import io.mockk.unmockkAll
import io.mockk.verify
import kotlin.test.assertEquals
import kotlin.test.assertIs
-import kotlin.test.assertTrue
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
-import net.mullvad.mullvadvpn.compose.state.VpnSettingsDialog
-import net.mullvad.mullvadvpn.compose.state.VpnSettingsUiState
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
-import net.mullvad.mullvadvpn.lib.common.test.assertLists
import net.mullvad.mullvadvpn.model.Constraint
import net.mullvad.mullvadvpn.model.Port
import net.mullvad.mullvadvpn.model.PortRange
@@ -31,7 +27,6 @@ import net.mullvad.mullvadvpn.model.WireguardTunnelOptions
import net.mullvad.mullvadvpn.repository.SettingsRepository
import net.mullvad.mullvadvpn.usecase.PortRangeUseCase
import net.mullvad.mullvadvpn.usecase.RelayListUseCase
-import org.apache.commons.validator.routines.InetAddressValidator
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -41,7 +36,6 @@ class VpnSettingsViewModelTest {
@get:Rule val testCoroutineRule = TestCoroutineRule()
private val mockSettingsRepository: SettingsRepository = mockk()
- private val mockInetAddressValidator: InetAddressValidator = mockk()
private val mockResources: Resources = mockk()
private val mockPortRangeUseCase: PortRangeUseCase = mockk()
private val mockRelayListUseCase: RelayListUseCase = mockk()
@@ -59,7 +53,6 @@ class VpnSettingsViewModelTest {
viewModel =
VpnSettingsViewModel(
repository = mockSettingsRepository,
- inetAddressValidator = mockInetAddressValidator,
resources = mockResources,
portRangeUseCase = mockPortRangeUseCase,
relayListUseCase = mockRelayListUseCase,
@@ -133,6 +126,7 @@ class VpnSettingsViewModelTest {
viewModel.uiState.test {
assertIs<Constraint.Any<Port>>(awaitItem().selectedWireguardPort)
mockSettingsUpdate.value = mockSettings
+ assertEquals(expectedPort, awaitItem().customWireguardPort)
assertEquals(expectedPort, awaitItem().selectedWireguardPort)
}
}
@@ -152,23 +146,4 @@ class VpnSettingsViewModelTest {
mockRelayListUseCase.updateSelectedWireguardConstraints(wireguardConstraints)
}
}
-
- @Test
- fun test_update_port_range_state() = runTest {
- // Arrange
- val expectedPortRange = listOf<PortRange>(mockk(), mockk())
- val mockSettings: Settings = mockk(relaxed = true)
-
- every { mockSettings.relaySettings } returns mockk<RelaySettings.Normal>(relaxed = true)
- portRangeFlow.value = expectedPortRange
-
- // Act, Assert
- viewModel.uiState.test {
- assertIs<VpnSettingsUiState>(awaitItem())
- viewModel.onWireguardPortInfoClicked()
- val state = awaitItem()
- assertTrue { state.dialog is VpnSettingsDialog.WireguardPortInfo }
- assertLists(expectedPortRange, state.availablePortRanges)
- }
- }
}
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 e958df9337..433a9f5709 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
@@ -1,28 +1,23 @@
package net.mullvad.mullvadvpn.viewmodel
-import android.app.Activity
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
import io.mockk.unmockkAll
import kotlin.test.assertEquals
import kotlin.test.assertIs
-import kotlin.test.assertNull
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
-import net.mullvad.mullvadvpn.compose.dialog.payment.PaymentDialogData
import net.mullvad.mullvadvpn.compose.state.PaymentState
import net.mullvad.mullvadvpn.compose.state.WelcomeUiState
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.common.test.assertLists
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.PurchaseResult
import net.mullvad.mullvadvpn.model.AccountAndDevice
import net.mullvad.mullvadvpn.model.AccountExpiry
@@ -37,8 +32,8 @@ import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionContainer
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState
import net.mullvad.mullvadvpn.ui.serviceconnection.authTokenCache
+import net.mullvad.mullvadvpn.usecase.OutOfTimeUseCase
import net.mullvad.mullvadvpn.usecase.PaymentUseCase
-import net.mullvad.mullvadvpn.util.toPaymentDialogData
import net.mullvad.talpid.util.EventNotifier
import org.joda.time.DateTime
import org.joda.time.ReadableInstant
@@ -50,12 +45,13 @@ import org.junit.Test
class WelcomeViewModelTest {
@get:Rule val testCoroutineRule = TestCoroutineRule()
- private val serviceConnectionState =
+ private val serviceConnectionStateFlow =
MutableStateFlow<ServiceConnectionState>(ServiceConnectionState.Disconnected)
- private val deviceState = MutableStateFlow<DeviceState>(DeviceState.Initial)
- private val accountExpiryState = MutableStateFlow<AccountExpiry>(AccountExpiry.Missing)
- private val purchaseResult = MutableStateFlow<PurchaseResult?>(null)
- private val paymentAvailability = MutableStateFlow<PaymentAvailability?>(null)
+ private val deviceStateFlow = MutableStateFlow<DeviceState>(DeviceState.Initial)
+ private val accountExpiryStateFlow = MutableStateFlow<AccountExpiry>(AccountExpiry.Missing)
+ private val purchaseResultFlow = MutableStateFlow<PurchaseResult?>(null)
+ private val paymentAvailabilityFlow = MutableStateFlow<PaymentAvailability?>(null)
+ private val outOfTimeFlow = MutableStateFlow(true)
// Service connections
private val mockServiceConnectionContainer: ServiceConnectionContainer = mockk()
@@ -68,6 +64,7 @@ class WelcomeViewModelTest {
private val mockDeviceRepository: DeviceRepository = mockk()
private val mockServiceConnectionManager: ServiceConnectionManager = mockk()
private val mockPaymentUseCase: PaymentUseCase = mockk(relaxed = true)
+ private val mockOutOfTimeUseCase: OutOfTimeUseCase = mockk(relaxed = true)
private lateinit var viewModel: WelcomeViewModel
@@ -76,19 +73,21 @@ class WelcomeViewModelTest {
mockkStatic(SERVICE_CONNECTION_MANAGER_EXTENSIONS)
mockkStatic(PURCHASE_RESULT_EXTENSIONS_CLASS)
- every { mockDeviceRepository.deviceState } returns deviceState
+ every { mockDeviceRepository.deviceState } returns deviceStateFlow
- every { mockServiceConnectionManager.connectionState } returns serviceConnectionState
+ every { mockServiceConnectionManager.connectionState } returns serviceConnectionStateFlow
every { mockServiceConnectionContainer.connectionProxy } returns mockConnectionProxy
every { mockConnectionProxy.onUiStateChange } returns eventNotifierTunnelUiState
- every { mockAccountRepository.accountExpiryState } returns accountExpiryState
+ every { mockAccountRepository.accountExpiryState } returns accountExpiryStateFlow
- coEvery { mockPaymentUseCase.purchaseResult } returns purchaseResult
+ coEvery { mockPaymentUseCase.purchaseResult } returns purchaseResultFlow
- coEvery { mockPaymentUseCase.paymentAvailability } returns paymentAvailability
+ coEvery { mockPaymentUseCase.paymentAvailability } returns paymentAvailabilityFlow
+
+ coEvery { mockOutOfTimeUseCase.isOutOfTime() } returns outOfTimeFlow
viewModel =
WelcomeViewModel(
@@ -96,6 +95,7 @@ class WelcomeViewModelTest {
deviceRepository = mockDeviceRepository,
serviceConnectionManager = mockServiceConnectionManager,
paymentUseCase = mockPaymentUseCase,
+ outOfTimeUseCase = mockOutOfTimeUseCase,
pollAccountExpiry = false
)
}
@@ -134,7 +134,7 @@ class WelcomeViewModelTest {
viewModel.uiState.test {
assertEquals(WelcomeUiState(), awaitItem())
eventNotifierTunnelUiState.notify(tunnelUiStateTestItem)
- serviceConnectionState.value =
+ serviceConnectionStateFlow.value =
ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
val result = awaitItem()
assertEquals(tunnelUiStateTestItem, result.tunnelState)
@@ -142,27 +142,26 @@ class WelcomeViewModelTest {
}
@Test
- fun testUpdateAccountNumber() =
- runTest(testCoroutineRule.testDispatcher) {
- // Arrange
- val expectedAccountNumber = "4444555566667777"
- val device: Device = mockk()
- every { device.displayName() } returns ""
+ fun testUpdateAccountNumber() = runTest {
+ // Arrange
+ val expectedAccountNumber = "4444555566667777"
+ val device: Device = mockk()
+ every { device.displayName() } returns ""
- // Act, Assert
- viewModel.uiState.test {
- assertEquals(WelcomeUiState(), awaitItem())
- serviceConnectionState.value =
- ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
- deviceState.value =
- DeviceState.LoggedIn(
- accountAndDevice =
- AccountAndDevice(account_token = expectedAccountNumber, device = device)
- )
- val result = awaitItem()
- assertEquals(expectedAccountNumber, result.accountNumber)
- }
+ // Act, Assert
+ viewModel.uiState.test {
+ assertEquals(WelcomeUiState(), awaitItem())
+ paymentAvailabilityFlow.value = null
+ deviceStateFlow.value =
+ DeviceState.LoggedIn(
+ accountAndDevice =
+ AccountAndDevice(account_token = expectedAccountNumber, device = device)
+ )
+ serviceConnectionStateFlow.value =
+ ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
+ assertEquals(expectedAccountNumber, awaitItem().accountNumber)
}
+ }
@Test
fun testOpenConnectScreen() =
@@ -173,7 +172,7 @@ class WelcomeViewModelTest {
// Act, Assert
viewModel.uiSideEffect.test {
- accountExpiryState.value = AccountExpiry.Available(mockExpiryDate)
+ outOfTimeFlow.value = false
val action = awaitItem()
assertIs<WelcomeViewModel.UiSideEffect.OpenConnectScreen>(action)
}
@@ -188,8 +187,8 @@ class WelcomeViewModelTest {
viewModel.uiState.test {
// Default item
awaitItem()
- paymentAvailability.tryEmit(productsUnavailable)
- serviceConnectionState.value =
+ paymentAvailabilityFlow.tryEmit(productsUnavailable)
+ serviceConnectionStateFlow.value =
ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
val result = awaitItem().billingPaymentState
assertIs<PaymentState.NoPayment>(result)
@@ -200,8 +199,8 @@ class WelcomeViewModelTest {
fun testBillingProductsGenericErrorState() = runTest {
// Arrange
val paymentOtherError = PaymentAvailability.Error.Other(mockk())
- paymentAvailability.tryEmit(paymentOtherError)
- serviceConnectionState.value =
+ paymentAvailabilityFlow.tryEmit(paymentOtherError)
+ serviceConnectionStateFlow.value =
ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
// Act, Assert
@@ -215,8 +214,8 @@ class WelcomeViewModelTest {
fun testBillingProductsBillingErrorState() = runTest {
// Arrange
val paymentBillingError = PaymentAvailability.Error.BillingUnavailable
- paymentAvailability.value = paymentBillingError
- serviceConnectionState.value =
+ paymentAvailabilityFlow.value = paymentBillingError
+ serviceConnectionStateFlow.value =
ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
// Act, Assert
@@ -232,8 +231,8 @@ class WelcomeViewModelTest {
val mockProduct: PaymentProduct = mockk()
val expectedProductList = listOf(mockProduct)
val productsAvailable = PaymentAvailability.ProductsAvailable(listOf(mockProduct))
- paymentAvailability.value = productsAvailable
- serviceConnectionState.value =
+ paymentAvailabilityFlow.value = productsAvailable
+ serviceConnectionStateFlow.value =
ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
// Act, Assert
@@ -244,46 +243,6 @@ class WelcomeViewModelTest {
}
}
- @Test
- fun testBillingUserCancelled() = runTest {
- // Arrange
- val result = PurchaseResult.Completed.Cancelled
- purchaseResult.value = result
- serviceConnectionState.value =
- ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
- every { result.toPaymentDialogData() } returns null
-
- // Act, Assert
- viewModel.uiState.test { assertNull(awaitItem().paymentDialogData) }
- }
-
- @Test
- fun testBillingPurchaseSuccess() = runTest {
- // Arrange
- val result = PurchaseResult.Completed.Success
- val expectedData: PaymentDialogData = mockk()
- purchaseResult.value = result
- serviceConnectionState.value =
- ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
- every { result.toPaymentDialogData() } returns expectedData
-
- // Act, Assert
- viewModel.uiState.test { assertEquals(expectedData, awaitItem().paymentDialogData) }
- }
-
- @Test
- fun testStartBillingPayment() {
- // Arrange
- val mockProductId = ProductId("MOCK")
- val mockActivityProvider = mockk<() -> Activity>()
-
- // Act
- viewModel.startBillingPayment(mockProductId, mockActivityProvider)
-
- // Assert
- coVerify { mockPaymentUseCase.purchaseProduct(mockProductId, mockActivityProvider) }
- }
-
companion object {
private const val SERVICE_CONNECTION_MANAGER_EXTENSIONS =
"net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManagerExtensionsKt"