summaryrefslogtreecommitdiffhomepage
path: root/android/app/src/test
diff options
context:
space:
mode:
authorDavid Göransson <david.goransson90@gmail.com>2023-10-13 12:21:10 +0200
committerDavid Göransson <david.goransson90@gmail.com>2023-10-23 11:28:23 +0200
commit02b7b4313323fcb1bb10f72ccb956177d44ecf16 (patch)
tree0c66180f1b208a00ecb9885d0d9f4372d578660e /android/app/src/test
parentc085b31acdc002076106a30f7cd1dcdcd43daf05 (diff)
downloadmullvadvpn-02b7b4313323fcb1bb10f72ccb956177d44ecf16.tar.xz
mullvadvpn-02b7b4313323fcb1bb10f72ccb956177d44ecf16.zip
Add tests
Diffstat (limited to 'android/app/src/test')
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/InAppNotificationControllerTest.kt102
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/AccountExpiryNotificationUseCaseTest.kt75
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/NewDeviceUseNotificationCaseTest.kt81
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/TunnelStateNotificationUseCaseTest.kt94
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/VersionNotificationUseCaseTest.kt114
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModelTest.kt91
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt4
7 files changed, 485 insertions, 76 deletions
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/InAppNotificationControllerTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/InAppNotificationControllerTest.kt
new file mode 100644
index 0000000000..30b54cea11
--- /dev/null
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/InAppNotificationControllerTest.kt
@@ -0,0 +1,102 @@
+package net.mullvad.mullvadvpn
+
+import app.cash.turbine.test
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.unmockkAll
+import kotlin.test.assertEquals
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.runTest
+import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
+import net.mullvad.mullvadvpn.repository.InAppNotification
+import net.mullvad.mullvadvpn.repository.InAppNotificationController
+import net.mullvad.mullvadvpn.usecase.AccountExpiryNotificationUseCase
+import net.mullvad.mullvadvpn.usecase.NewDeviceNotificationUseCase
+import net.mullvad.mullvadvpn.usecase.TunnelStateNotificationUseCase
+import net.mullvad.mullvadvpn.usecase.VersionNotificationUseCase
+import net.mullvad.talpid.tunnel.ErrorState
+import org.joda.time.DateTime
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+class InAppNotificationControllerTest {
+ @get:Rule val testCoroutineRule = TestCoroutineRule()
+
+ private lateinit var inAppNotificationController: InAppNotificationController
+ private val accountExpiryNotifications = MutableStateFlow(emptyList<InAppNotification>())
+ private val newDeviceNotifications = MutableStateFlow(emptyList<InAppNotification.NewDevice>())
+ private val versionNotifications = MutableStateFlow(emptyList<InAppNotification>())
+ private val tunnelStateNotifications = MutableStateFlow(emptyList<InAppNotification>())
+
+ private lateinit var job: Job
+
+ @Before
+ fun setup() {
+ MockKAnnotations.init(this)
+
+ val accountExpiryNotificationUseCase: AccountExpiryNotificationUseCase = mockk()
+ val newDeviceNotificationUseCase: NewDeviceNotificationUseCase = mockk()
+ val versionNotificationUseCase: VersionNotificationUseCase = mockk()
+ val tunnelStateNotificationUseCase: TunnelStateNotificationUseCase = mockk()
+ every { accountExpiryNotificationUseCase.notifications() } returns
+ accountExpiryNotifications
+ every { newDeviceNotificationUseCase.notifications() } returns newDeviceNotifications
+ every { versionNotificationUseCase.notifications() } returns versionNotifications
+ every { tunnelStateNotificationUseCase.notifications() } returns tunnelStateNotifications
+ job = Job()
+
+ inAppNotificationController =
+ InAppNotificationController(
+ accountExpiryNotificationUseCase,
+ newDeviceNotificationUseCase,
+ versionNotificationUseCase,
+ tunnelStateNotificationUseCase,
+ CoroutineScope(job + testCoroutineRule.testDispatcher)
+ )
+ }
+
+ @After
+ fun teardown() {
+ job.cancel()
+ unmockkAll()
+ }
+
+ @Test
+ fun `ensure all notifications have the right priority`() = runTest {
+ val newDevice = InAppNotification.NewDevice("")
+ newDeviceNotifications.value = listOf(newDevice)
+
+ val errorState: ErrorState = mockk()
+ val tunnelStateBlocked = InAppNotification.TunnelStateBlocked
+ val tunnelStateError = InAppNotification.TunnelStateError(errorState)
+ tunnelStateNotifications.value = listOf(tunnelStateBlocked, tunnelStateError)
+
+ val unsupportedVersion = InAppNotification.UnsupportedVersion(mockk())
+ val updateAvailable = InAppNotification.UpdateAvailable(mockk())
+ versionNotifications.value = listOf(unsupportedVersion, updateAvailable)
+
+ val accountExpiry = InAppNotification.AccountExpiry(DateTime.now())
+ accountExpiryNotifications.value = listOf(accountExpiry)
+
+ inAppNotificationController.notifications.test {
+ val notifications = awaitItem()
+
+ assertEquals(
+ listOf(
+ tunnelStateError,
+ tunnelStateBlocked,
+ unsupportedVersion,
+ accountExpiry,
+ newDevice,
+ updateAvailable,
+ ),
+ notifications
+ )
+ }
+ }
+}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/AccountExpiryNotificationUseCaseTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/AccountExpiryNotificationUseCaseTest.kt
new file mode 100644
index 0000000000..5341708d3b
--- /dev/null
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/AccountExpiryNotificationUseCaseTest.kt
@@ -0,0 +1,75 @@
+package net.mullvad.mullvadvpn.usecase
+
+import app.cash.turbine.test
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.unmockkAll
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.runTest
+import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
+import net.mullvad.mullvadvpn.model.AccountExpiry
+import net.mullvad.mullvadvpn.repository.AccountRepository
+import net.mullvad.mullvadvpn.repository.InAppNotification
+import org.joda.time.DateTime
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+class AccountExpiryNotificationUseCaseTest {
+ @get:Rule val testCoroutineRule = TestCoroutineRule()
+
+ private val accountExpiry = MutableStateFlow<AccountExpiry>(AccountExpiry.Missing)
+ private lateinit var accountExpiryNotificationUseCase: AccountExpiryNotificationUseCase
+
+ @Before
+ fun setup() {
+ MockKAnnotations.init(this)
+
+ val accountRepository = mockk<AccountRepository>()
+ every { accountRepository.accountExpiryState } returns accountExpiry
+
+ accountExpiryNotificationUseCase = AccountExpiryNotificationUseCase(accountRepository)
+ }
+
+ @After
+ fun teardown() {
+ unmockkAll()
+ }
+
+ @Test
+ fun `ensure notifications are empty by default`() = runTest {
+ // Arrange, Act, Assert
+ accountExpiryNotificationUseCase.notifications().test {
+ assertTrue { awaitItem().isEmpty() }
+ }
+ }
+
+ @Test
+ fun `ensure account expiry within 3 days generates notification`() = runTest {
+ // Arrange, Act, Assert
+ accountExpiryNotificationUseCase.notifications().test {
+ assertTrue { awaitItem().isEmpty() }
+ val closeToExpiry = AccountExpiry.Available(DateTime.now().plusDays(2))
+ accountExpiry.value = closeToExpiry
+
+ assertEquals(
+ listOf(InAppNotification.AccountExpiry(closeToExpiry.expiryDateTime)),
+ awaitItem()
+ )
+ }
+ }
+
+ @Test
+ fun `ensure an expire of 4 days in the future does not produce a notification`() = runTest {
+ // Arrange, Act, Assert
+ accountExpiryNotificationUseCase.notifications().test {
+ assertTrue { awaitItem().isEmpty() }
+ accountExpiry.value = AccountExpiry.Available(DateTime.now().plusDays(4))
+ expectNoEvents()
+ }
+ }
+}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/NewDeviceUseNotificationCaseTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/NewDeviceUseNotificationCaseTest.kt
new file mode 100644
index 0000000000..bd375d729a
--- /dev/null
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/NewDeviceUseNotificationCaseTest.kt
@@ -0,0 +1,81 @@
+package net.mullvad.mullvadvpn.usecase
+
+import app.cash.turbine.test
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.unmockkAll
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.runTest
+import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
+import net.mullvad.mullvadvpn.model.AccountAndDevice
+import net.mullvad.mullvadvpn.model.Device
+import net.mullvad.mullvadvpn.model.DeviceState
+import net.mullvad.mullvadvpn.repository.DeviceRepository
+import net.mullvad.mullvadvpn.repository.InAppNotification
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+class NewDeviceUseNotificationCaseTest {
+ @get:Rule val testCoroutineRule = TestCoroutineRule()
+
+ private val deviceName = "Frank Zebra"
+ private val deviceState =
+ MutableStateFlow<DeviceState>(
+ DeviceState.LoggedIn(
+ accountAndDevice = AccountAndDevice("", Device("", deviceName, byteArrayOf(), ""))
+ )
+ )
+ private lateinit var newDeviceNotificationUseCase: NewDeviceNotificationUseCase
+
+ @Before
+ fun setup() {
+ MockKAnnotations.init(this)
+
+ val mockDeviceRepository: DeviceRepository = mockk()
+ every { mockDeviceRepository.deviceState } returns deviceState
+ newDeviceNotificationUseCase =
+ NewDeviceNotificationUseCase(deviceRepository = mockDeviceRepository)
+ }
+
+ @After
+ fun teardown() {
+ unmockkAll()
+ }
+
+ @Test
+ fun `ensure empty by default`() = runTest {
+ // Arrange, Act, Assert
+ newDeviceNotificationUseCase.notifications().test { assertTrue { awaitItem().isEmpty() } }
+ }
+
+ @Test
+ fun `ensure NewDevice notification is created and contains device name`() = runTest {
+ newDeviceNotificationUseCase.notifications().test {
+ // Arrange, Act
+ awaitItem()
+ newDeviceNotificationUseCase.newDeviceCreated()
+
+ // Assert
+ assertEquals(awaitItem(), listOf(InAppNotification.NewDevice(deviceName)))
+ }
+ }
+
+ @Test
+ fun `ensure NewDevice notification is cleared`() = runTest {
+ newDeviceNotificationUseCase.notifications().test {
+ // Arrange, Act
+ awaitItem()
+ newDeviceNotificationUseCase.newDeviceCreated()
+ awaitItem()
+ newDeviceNotificationUseCase.clearNewDeviceCreatedNotification()
+
+ // Assert
+ assertEquals(awaitItem(), emptyList())
+ }
+ }
+}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/TunnelStateNotificationUseCaseTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/TunnelStateNotificationUseCaseTest.kt
new file mode 100644
index 0000000000..1b89c92be7
--- /dev/null
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/TunnelStateNotificationUseCaseTest.kt
@@ -0,0 +1,94 @@
+package net.mullvad.mullvadvpn.usecase
+
+import app.cash.turbine.test
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.unmockkAll
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.runTest
+import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
+import net.mullvad.mullvadvpn.model.TunnelState
+import net.mullvad.mullvadvpn.repository.InAppNotification
+import net.mullvad.mullvadvpn.ui.serviceconnection.ConnectionProxy
+import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionContainer
+import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager
+import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState
+import net.mullvad.talpid.tunnel.ActionAfterDisconnect
+import net.mullvad.talpid.tunnel.ErrorState
+import net.mullvad.talpid.util.EventNotifier
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+class TunnelStateNotificationUseCaseTest {
+ @get:Rule val testCoroutineRule = TestCoroutineRule()
+
+ private val mockServiceConnectionManager: ServiceConnectionManager = mockk()
+ private val mockServiceConnectionContainer: ServiceConnectionContainer = mockk()
+ private val mockConnectionProxy: ConnectionProxy = mockk()
+
+ private val serviceConnectionState =
+ MutableStateFlow<ServiceConnectionState>(ServiceConnectionState.Disconnected)
+ private lateinit var tunnelStateNotificationUseCase: TunnelStateNotificationUseCase
+
+ private val eventNotifierTunnelUiState = EventNotifier<TunnelState>(TunnelState.Disconnected)
+
+ @Before
+ fun setup() {
+ MockKAnnotations.init(this)
+ every { mockConnectionProxy.onUiStateChange } returns eventNotifierTunnelUiState
+
+ every { mockServiceConnectionManager.connectionState } returns serviceConnectionState
+ every { mockServiceConnectionContainer.connectionProxy } returns mockConnectionProxy
+
+ tunnelStateNotificationUseCase =
+ TunnelStateNotificationUseCase(serviceConnectionManager = mockServiceConnectionManager)
+ }
+
+ @After
+ fun teardown() {
+ unmockkAll()
+ }
+
+ @Test
+ fun `ensure notifications are empty by default`() = runTest {
+ // Arrange, Act, Assert
+ tunnelStateNotificationUseCase.notifications().test { assertTrue { awaitItem().isEmpty() } }
+ }
+
+ @Test
+ fun `ensure TunnelState with error will produce TunnelStateError notification`() = runTest {
+ tunnelStateNotificationUseCase.notifications().test {
+ // Arrange, Act
+ assertEquals(emptyList(), awaitItem())
+ serviceConnectionState.value =
+ ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
+ val errorState: ErrorState = mockk()
+ eventNotifierTunnelUiState.notify(TunnelState.Error(errorState))
+
+ // Assert
+ assertEquals(listOf(InAppNotification.TunnelStateError(errorState)), awaitItem())
+ }
+ }
+
+ @Test
+ fun `ensure disconnecting TunnelState with blocking will produce TunnelStateBlocked notification`() =
+ runTest {
+ tunnelStateNotificationUseCase.notifications().test {
+ // Arrange, Act
+ assertEquals(emptyList(), awaitItem())
+ serviceConnectionState.value =
+ ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
+ eventNotifierTunnelUiState.notify(
+ TunnelState.Disconnecting(ActionAfterDisconnect.Block)
+ )
+
+ // Assert
+ assertEquals(listOf(InAppNotification.TunnelStateBlocked), awaitItem())
+ }
+ }
+}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/VersionNotificationUseCaseTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/VersionNotificationUseCaseTest.kt
new file mode 100644
index 0000000000..5aba70c938
--- /dev/null
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/VersionNotificationUseCaseTest.kt
@@ -0,0 +1,114 @@
+package net.mullvad.mullvadvpn.usecase
+
+import app.cash.turbine.test
+import io.mockk.MockKAnnotations
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.mockkStatic
+import io.mockk.unmockkAll
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.runTest
+import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
+import net.mullvad.mullvadvpn.repository.InAppNotification
+import net.mullvad.mullvadvpn.ui.VersionInfo
+import net.mullvad.mullvadvpn.ui.serviceconnection.AppVersionInfoCache
+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.util.appVersionCallbackFlow
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+class VersionNotificationUseCaseTest {
+ @get:Rule val testCoroutineRule = TestCoroutineRule()
+
+ private val mockServiceConnectionManager: ServiceConnectionManager = mockk()
+ private lateinit var mockAppVersionInfoCache: AppVersionInfoCache
+ private val mockServiceConnectionContainer: ServiceConnectionContainer = mockk()
+
+ private val serviceConnectionState =
+ MutableStateFlow<ServiceConnectionState>(ServiceConnectionState.Disconnected)
+ private val versionInfo =
+ MutableStateFlow(
+ VersionInfo(
+ currentVersion = null,
+ upgradeVersion = null,
+ isOutdated = false,
+ isSupported = true
+ )
+ )
+ private lateinit var versionNotificationUseCase: VersionNotificationUseCase
+
+ @Before
+ fun setup() {
+ MockKAnnotations.init(this)
+ mockkStatic(CACHE_EXTENSION_CLASS)
+ mockAppVersionInfoCache =
+ mockk<AppVersionInfoCache>().apply {
+ every { appVersionCallbackFlow() } returns versionInfo
+ }
+
+ every { mockServiceConnectionManager.connectionState } returns serviceConnectionState
+ every { mockServiceConnectionContainer.appVersionInfoCache } returns mockAppVersionInfoCache
+ every { mockAppVersionInfoCache.onUpdate = any() } answers {}
+
+ versionNotificationUseCase =
+ VersionNotificationUseCase(
+ serviceConnectionManager = mockServiceConnectionManager,
+ isVersionInfoNotificationEnabled = true
+ )
+ }
+
+ @After
+ fun teardown() {
+ unmockkAll()
+ }
+
+ @Test
+ fun `ensure notifications are empty by default`() = runTest {
+ // Arrange, Act, Assert
+ versionNotificationUseCase.notifications().test { assertTrue { awaitItem().isEmpty() } }
+ }
+
+ @Test
+ fun `ensure UpdateAvailable notification is created`() = runTest {
+ versionNotificationUseCase.notifications().test {
+ // Arrange, Act
+ val upgradeVersionInfo =
+ VersionInfo("1.0", "1.1", isOutdated = true, isSupported = true)
+ serviceConnectionState.value =
+ ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
+ awaitItem()
+ versionInfo.value = upgradeVersionInfo
+
+ // Assert
+ assertEquals(awaitItem(), listOf(InAppNotification.UpdateAvailable(upgradeVersionInfo)))
+ }
+ }
+
+ @Test
+ fun `ensure UnsupportedVersion notification is created`() = runTest {
+ versionNotificationUseCase.notifications().test {
+ // Arrange, Act
+ val upgradeVersionInfo = VersionInfo("1.0", "", isOutdated = false, isSupported = false)
+ serviceConnectionState.value =
+ ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
+ awaitItem()
+ versionInfo.value = upgradeVersionInfo
+
+ // Assert
+ assertEquals(
+ awaitItem(),
+ listOf(InAppNotification.UnsupportedVersion(upgradeVersionInfo))
+ )
+ }
+ }
+
+ companion object {
+ private const val CACHE_EXTENSION_CLASS = "net.mullvad.mullvadvpn.util.CacheExtensionsKt"
+ }
+}
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 bddaee353e..5839e575c1 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
@@ -11,12 +11,12 @@ import io.mockk.unmockkAll
import io.mockk.verify
import kotlin.test.assertEquals
import kotlin.test.assertIs
+import kotlin.test.assertTrue
import kotlinx.coroutines.async
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runTest
-import net.mullvad.mullvadvpn.compose.state.ConnectNotificationState
import net.mullvad.mullvadvpn.compose.state.ConnectUiState
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.model.AccountExpiry
@@ -27,6 +27,8 @@ import net.mullvad.mullvadvpn.relaylist.RelayCountry
import net.mullvad.mullvadvpn.relaylist.RelayItem
import net.mullvad.mullvadvpn.repository.AccountRepository
import net.mullvad.mullvadvpn.repository.DeviceRepository
+import net.mullvad.mullvadvpn.repository.InAppNotification
+import net.mullvad.mullvadvpn.repository.InAppNotificationController
import net.mullvad.mullvadvpn.ui.VersionInfo
import net.mullvad.mullvadvpn.ui.serviceconnection.AppVersionInfoCache
import net.mullvad.mullvadvpn.ui.serviceconnection.AuthTokenCache
@@ -42,8 +44,6 @@ 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.joda.time.DateTime
-import org.joda.time.ReadableInstant
import org.junit.After
import org.junit.Before
import org.junit.Rule
@@ -68,6 +68,7 @@ class ConnectViewModelTest {
)
private val accountExpiryState = MutableStateFlow<AccountExpiry>(AccountExpiry.Missing)
private val deviceState = MutableStateFlow<DeviceState>(DeviceState.Initial)
+ private val notifications = MutableStateFlow<List<InAppNotification>>(emptyList())
// Service connections
private val mockServiceConnectionContainer: ServiceConnectionContainer = mockk()
@@ -83,6 +84,9 @@ class ConnectViewModelTest {
// Device Repository
private val mockDeviceRepository: DeviceRepository = mockk()
+ // In App Notifications
+ private val mockInAppNotificationController: InAppNotificationController = mockk()
+
// Captures
private val locationSlot = slot<((GeoIpLocation?) -> Unit)>()
private val relaySlot = slot<(List<RelayCountry>, RelayItem?) -> Unit>()
@@ -111,6 +115,8 @@ class ConnectViewModelTest {
every { mockDeviceRepository.deviceState } returns deviceState
+ every { mockInAppNotificationController.notifications } returns notifications
+
every { mockConnectionProxy.onUiStateChange } returns eventNotifierTunnelUiState
every { mockConnectionProxy.onStateChange } returns eventNotifierTunnelRealState
@@ -126,7 +132,8 @@ class ConnectViewModelTest {
serviceConnectionManager = mockServiceConnectionManager,
accountRepository = mockAccountRepository,
deviceRepository = mockDeviceRepository,
- isVersionInfoNotificationEnabled = true
+ inAppNotificationController = mockInAppNotificationController,
+ newDeviceNotificationUseCase = mockk()
)
}
@@ -144,8 +151,6 @@ class ConnectViewModelTest {
@Test
fun testTunnelInfoExpandedUpdate() =
runTest(testCoroutineRule.testDispatcher) {
- val expectedResult = true
-
viewModel.uiState.test {
assertEquals(ConnectUiState.INITIAL, awaitItem())
serviceConnectionState.value =
@@ -154,7 +159,7 @@ class ConnectViewModelTest {
relaySlot.captured.invoke(mockk(), mockk())
viewModel.toggleTunnelInfoExpansion()
val result = awaitItem()
- assertEquals(expectedResult, result.isTunnelInfoExpanded)
+ assertTrue(result.isTunnelInfoExpanded)
}
}
@@ -288,34 +293,14 @@ class ConnectViewModelTest {
}
@Test
- fun testBlockingNotificationState() =
- runTest(testCoroutineRule.testDispatcher) {
- // Arrange
- val expectedConnectNotificationState =
- ConnectNotificationState.ShowTunnelStateNotificationBlocked
- val tunnelUiState = TunnelState.Connecting(null, null)
-
- // Act, Assert
- viewModel.uiState.test {
- assertEquals(ConnectUiState.INITIAL, awaitItem())
- serviceConnectionState.value =
- ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
- locationSlot.captured.invoke(mockLocation)
- relaySlot.captured.invoke(mockk(), mockk())
- eventNotifierTunnelUiState.notify(tunnelUiState)
- val result = awaitItem()
- assertEquals(expectedConnectNotificationState, result.connectNotificationState)
- }
- }
-
- @Test
fun testErrorNotificationState() =
runTest(testCoroutineRule.testDispatcher) {
// Arrange
val mockErrorState: ErrorState = mockk()
val expectedConnectNotificationState =
- ConnectNotificationState.ShowTunnelStateNotificationError(mockErrorState)
+ InAppNotification.TunnelStateError(mockErrorState)
val tunnelUiState = TunnelState.Error(mockErrorState)
+ notifications.value = listOf(expectedConnectNotificationState)
// Act, Assert
viewModel.uiState.test {
@@ -326,53 +311,7 @@ class ConnectViewModelTest {
relaySlot.captured.invoke(mockk(), mockk())
eventNotifierTunnelUiState.notify(tunnelUiState)
val result = awaitItem()
- assertEquals(expectedConnectNotificationState, result.connectNotificationState)
- }
- }
-
- @Test
- fun testVersionInfoNotificationState() =
- runTest(testCoroutineRule.testDispatcher) {
- // Arrange
- val mockVersionInfo: VersionInfo = mockk()
- val expectedConnectNotificationState =
- ConnectNotificationState.ShowVersionInfoNotification(mockVersionInfo)
- every { mockVersionInfo.isOutdated } returns true
-
- // Act, Assert
- viewModel.uiState.test {
- assertEquals(ConnectUiState.INITIAL, awaitItem())
- serviceConnectionState.value =
- ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
- locationSlot.captured.invoke(mockLocation)
- relaySlot.captured.invoke(mockk(), mockk())
- versionInfo.value = mockVersionInfo
- val result = awaitItem()
- assertEquals(expectedConnectNotificationState, result.connectNotificationState)
- }
- }
-
- @Test
- fun testAccountExpiryNotificationState() =
- runTest(testCoroutineRule.testDispatcher) {
- // Arrange
- val mockDateTime: DateTime = mockk()
- val expectedConnectNotificationState =
- ConnectNotificationState.ShowAccountExpiryNotification(mockDateTime)
- every { mockDateTime.isBefore(any<ReadableInstant>()) } returns true
- every { mockDateTime.toInstant().millis } returns 0
-
- // Act, Assert
- viewModel.uiState.test {
- assertEquals(ConnectUiState.INITIAL, awaitItem())
- serviceConnectionState.value =
- ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
- locationSlot.captured.invoke(mockLocation)
- relaySlot.captured.invoke(mockk(), mockk())
- accountExpiryState.value = AccountExpiry.Available(mockDateTime)
-
- val result = awaitItem()
- assertEquals(expectedConnectNotificationState, result.connectNotificationState)
+ assertEquals(expectedConnectNotificationState, result.inAppNotification)
}
}
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 744989a922..2ada5bf767 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
@@ -24,6 +24,7 @@ import net.mullvad.mullvadvpn.model.DeviceListEvent
import net.mullvad.mullvadvpn.model.LoginResult
import net.mullvad.mullvadvpn.repository.AccountRepository
import net.mullvad.mullvadvpn.repository.DeviceRepository
+import net.mullvad.mullvadvpn.usecase.NewDeviceNotificationUseCase
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
@@ -34,6 +35,7 @@ class LoginViewModelTest {
@MockK private lateinit var mockedAccountRepository: AccountRepository
@MockK private lateinit var mockedDeviceRepository: DeviceRepository
+ @MockK private lateinit var mockedNewDeviceNotificationUseCase: NewDeviceNotificationUseCase
private lateinit var loginViewModel: LoginViewModel
private val accountHistoryTestEvents = MutableStateFlow<AccountHistory>(AccountHistory.Missing)
@@ -44,11 +46,13 @@ class LoginViewModelTest {
MockKAnnotations.init(this, relaxUnitFun = true)
every { mockedAccountRepository.accountHistory } returns accountHistoryTestEvents
+ every { mockedNewDeviceNotificationUseCase.newDeviceCreated() } returns Unit
loginViewModel =
LoginViewModel(
mockedAccountRepository,
mockedDeviceRepository,
+ mockedNewDeviceNotificationUseCase,
UnconfinedTestDispatcher()
)
}