summaryrefslogtreecommitdiffhomepage
path: root/android/app/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'android/app/src/test')
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/AccountExpiryNotificationProviderTest.kt213
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/data/Extensions.kt12
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/AccountExpiryInAppNotificationUseCaseTest.kt11
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/OutOfTimeUseCaseTest.kt25
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModelTest.kt5
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModelTest.kt5
6 files changed, 31 insertions, 240 deletions
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/AccountExpiryNotificationProviderTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/AccountExpiryNotificationProviderTest.kt
deleted file mode 100644
index 9a3672515d..0000000000
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/AccountExpiryNotificationProviderTest.kt
+++ /dev/null
@@ -1,213 +0,0 @@
-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 java.time.Duration
-import java.time.ZonedDateTime
-import kotlin.test.assertEquals
-import kotlin.test.assertTrue
-import kotlin.time.Duration.Companion.minutes
-import kotlin.time.Duration.Companion.seconds
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.test.advanceTimeBy
-import kotlinx.coroutines.test.runTest
-import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
-import net.mullvad.mullvadvpn.lib.model.AccountData
-import net.mullvad.mullvadvpn.lib.model.DeviceState
-import net.mullvad.mullvadvpn.lib.model.Notification
-import net.mullvad.mullvadvpn.lib.model.NotificationChannelId
-import net.mullvad.mullvadvpn.lib.model.NotificationUpdate
-import net.mullvad.mullvadvpn.lib.model.NotificationUpdate.Cancel
-import net.mullvad.mullvadvpn.lib.model.NotificationUpdate.Notify
-import net.mullvad.mullvadvpn.lib.shared.AccountRepository
-import net.mullvad.mullvadvpn.lib.shared.DeviceRepository
-import net.mullvad.mullvadvpn.service.notifications.accountexpiry.ACCOUNT_EXPIRY_CLOSE_TO_EXPIRY_THRESHOLD
-import net.mullvad.mullvadvpn.service.notifications.accountexpiry.AccountExpiryNotificationProvider
-import org.junit.jupiter.api.AfterEach
-import org.junit.jupiter.api.BeforeEach
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.extension.ExtendWith
-
-@ExperimentalCoroutinesApi
-@ExtendWith(TestCoroutineRule::class)
-class AccountExpiryNotificationProviderTest {
-
- private lateinit var provider: AccountExpiryNotificationProvider
-
- private val accountData = MutableStateFlow<AccountData?>(null)
- private val deviceState = MutableStateFlow<DeviceState?>(null)
- private val isNewDevice = MutableStateFlow(true)
-
- @BeforeEach
- fun setup() {
- MockKAnnotations.init(this)
-
- val accountRepository = mockk<AccountRepository>(relaxed = true)
- every { accountRepository.accountData } returns accountData
- every { accountRepository.isNewAccount } returns isNewDevice
-
- val deviceRepository = mockk<DeviceRepository>(relaxed = true)
- every { deviceRepository.deviceState } returns deviceState
-
- provider =
- AccountExpiryNotificationProvider(
- channelId = NotificationChannelId("channelId"),
- accountRepository = accountRepository,
- deviceRepository = deviceRepository,
- )
-
- deviceState.value = DeviceState.LoggedIn(mockk(relaxed = true), mockk(relaxed = true))
- isNewDevice.value = false
- }
-
- @AfterEach
- fun teardown() {
- unmockkAll()
- }
-
- @Test
- fun `should not emit notification in initial state`() = runTest {
- accountData.value = null
- deviceState.value = null
- isNewDevice.value = true
- provider.notifications.test { expectNoEvents() }
- }
-
- @Test
- fun `should emit notification if expiry time is shorter than expiry warning threshold`() =
- runTest {
- setExpiry(
- ZonedDateTime.now().plus(ACCOUNT_EXPIRY_CLOSE_TO_EXPIRY_THRESHOLD).minusDays(1)
- )
- provider.notifications.test {
- assertTrue(awaitItem() is Notify)
- expectNoEvents()
- }
- }
-
- @Test
- fun `should emit cancel notification if user account is new`() = runTest {
- isNewDevice.value = true
- setExpiry(ZonedDateTime.now().plus(ACCOUNT_EXPIRY_CLOSE_TO_EXPIRY_THRESHOLD).minusDays(1))
- provider.notifications.test {
- assertTrue(awaitItem() is Cancel)
- expectNoEvents()
- }
- }
-
- @Test
- fun `should emit cancel notification if user account is logged out`() = runTest {
- setIsLoggedIn(false)
- setExpiry(ZonedDateTime.now().plus(ACCOUNT_EXPIRY_CLOSE_TO_EXPIRY_THRESHOLD).minusDays(1))
- provider.notifications.test {
- assertTrue(awaitItem() is Cancel)
- expectNoEvents()
-
- setIsLoggedIn(true)
- assertTrue(awaitItem() is Notify)
- expectNoEvents()
-
- setIsLoggedIn(false)
- assertTrue(awaitItem() is Cancel)
- expectNoEvents()
- }
- }
-
- @Test
- fun `should emit zero duration notification when remaining time runs out`() = runTest {
- setExpiry(ZonedDateTime.now().plus(Duration.ofSeconds(60)))
- provider.notifications.test {
- assertTrue(awaitItem() is Notify)
- expectNoEvents()
-
- advanceTimeBy(59.seconds)
- expectNoEvents()
-
- advanceTimeBy(2.seconds)
- val item = getAccountExpiry(awaitItem())
- assertEquals(item.durationUntilExpiry, Duration.ZERO)
- expectNoEvents()
- }
- }
-
- @Test
- fun `should emit notification when update interval is passed`() = runTest {
- setExpiry(
- ZonedDateTime.now()
- .plus(ACCOUNT_EXPIRY_CLOSE_TO_EXPIRY_THRESHOLD)
- .minusDays(1)
- .plusHours(1)
- )
- provider.notifications.test {
- assertTrue(awaitItem() is Notify)
- expectNoEvents()
-
- advanceTimeBy(59.minutes)
- expectNoEvents()
-
- advanceTimeBy(1.minutes + 1.seconds)
- assertTrue(awaitItem() is Notify)
- expectNoEvents()
- }
- }
-
- @Test
- fun `should cancel existing notification if more time is added to account`() = runTest {
- setExpiry(ZonedDateTime.now().plus(ACCOUNT_EXPIRY_CLOSE_TO_EXPIRY_THRESHOLD).minusDays(1))
- provider.notifications.test {
- assertTrue(awaitItem() is Notify)
- expectNoEvents()
-
- setExpiry(
- ZonedDateTime.now().plus(ACCOUNT_EXPIRY_CLOSE_TO_EXPIRY_THRESHOLD).plusDays(1)
- )
- assertTrue(awaitItem() is Cancel)
- expectNoEvents()
- }
- }
-
- @Test
- fun `should not cancel existing notification if too little time is added`() = runTest {
- setExpiry(ZonedDateTime.now().plus(ACCOUNT_EXPIRY_CLOSE_TO_EXPIRY_THRESHOLD).minusDays(1))
- provider.notifications.test {
- assertTrue(awaitItem() is Notify)
- expectNoEvents()
-
- setExpiry(
- ZonedDateTime.now().plus(ACCOUNT_EXPIRY_CLOSE_TO_EXPIRY_THRESHOLD).minusHours(1)
- )
- assertTrue(awaitItem() is Notify)
- expectNoEvents()
- }
- }
-
- private fun getAccountExpiry(
- awaitItem: NotificationUpdate<Notification.AccountExpiry>
- ): Notification.AccountExpiry =
- when (awaitItem) {
- is Cancel -> error("expected AccountExpiry, was Cancel")
- is Notify -> awaitItem.value
- }
-
- private fun setExpiry(expiryDateTime: ZonedDateTime): ZonedDateTime {
- val expiry = AccountData(mockk(relaxed = true), expiryDateTime)
- accountData.value = expiry
- return expiryDateTime
- }
-
- private fun setIsLoggedIn(isLoggedIn: Boolean) {
- deviceState.value =
- if (isLoggedIn) {
- DeviceState.LoggedIn(
- accountNumber = mockk(relaxed = true),
- device = mockk(relaxed = true),
- )
- } else {
- DeviceState.LoggedOut
- }
- }
-}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/data/Extensions.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/data/Extensions.kt
new file mode 100644
index 0000000000..eb7a98ed8b
--- /dev/null
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/data/Extensions.kt
@@ -0,0 +1,12 @@
+package net.mullvad.mullvadvpn.data
+
+import io.mockk.mockk
+import java.time.ZonedDateTime
+import net.mullvad.mullvadvpn.lib.model.AccountData
+
+fun AccountData.Companion.mock(expiry: ZonedDateTime): AccountData =
+ AccountData(
+ id = mockk(relaxed = true),
+ accountNumber = mockk(relaxed = true),
+ expiryDate = expiry,
+ )
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/AccountExpiryInAppNotificationUseCaseTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/AccountExpiryInAppNotificationUseCaseTest.kt
index df7d561f84..0557cc5786 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/AccountExpiryInAppNotificationUseCaseTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/AccountExpiryInAppNotificationUseCaseTest.kt
@@ -15,12 +15,13 @@ import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runTest
+import net.mullvad.mullvadvpn.data.mock
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.model.AccountData
import net.mullvad.mullvadvpn.lib.model.InAppNotification
import net.mullvad.mullvadvpn.lib.shared.AccountRepository
import net.mullvad.mullvadvpn.service.notifications.accountexpiry.ACCOUNT_EXPIRY_CLOSE_TO_EXPIRY_THRESHOLD
-import net.mullvad.mullvadvpn.service.notifications.accountexpiry.ACCOUNT_EXPIRY_IN_APP_NOTIFICATION_UPDATE_INTERVAL
+import net.mullvad.mullvadvpn.service.notifications.accountexpiry.ACCOUNT_EXPIRY_NOTIFICATION_UPDATE_INTERVAL
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@@ -103,7 +104,7 @@ class AccountExpiryInAppNotificationUseCaseTest {
// Set expiry to to be in the final update interval.
val inLastUpdate =
ZonedDateTime.now()
- .plus(ACCOUNT_EXPIRY_IN_APP_NOTIFICATION_UPDATE_INTERVAL)
+ .plus(ACCOUNT_EXPIRY_NOTIFICATION_UPDATE_INTERVAL)
.minusSeconds(1)
val expiry = setExpiry(inLastUpdate)
@@ -113,9 +114,9 @@ class AccountExpiryInAppNotificationUseCaseTest {
expectNoEvents()
// Advance past the delay before the while loop:
- advanceTimeBy(ACCOUNT_EXPIRY_IN_APP_NOTIFICATION_UPDATE_INTERVAL.toMillis())
+ advanceTimeBy(ACCOUNT_EXPIRY_NOTIFICATION_UPDATE_INTERVAL.toMillis())
// Advance past the delay after the while loop:
- advanceTimeBy(ACCOUNT_EXPIRY_IN_APP_NOTIFICATION_UPDATE_INTERVAL.toMillis())
+ advanceTimeBy(ACCOUNT_EXPIRY_NOTIFICATION_UPDATE_INTERVAL.toMillis())
assertEquals(Duration.ZERO, getExpiryNotificationDuration(expectMostRecentItem()))
expectNoEvents()
@@ -128,7 +129,7 @@ class AccountExpiryInAppNotificationUseCaseTest {
}
private fun setExpiry(expiryDateTime: ZonedDateTime): ZonedDateTime {
- val expiry = AccountData(mockk(relaxed = true), expiryDateTime)
+ val expiry = AccountData.mock(expiryDateTime)
accountExpiry.value = expiry
return expiryDateTime
}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/OutOfTimeUseCaseTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/OutOfTimeUseCaseTest.kt
index 4fd3ba08d1..0fd1563169 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/OutOfTimeUseCaseTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/OutOfTimeUseCaseTest.kt
@@ -20,6 +20,7 @@ import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
+import net.mullvad.mullvadvpn.data.mock
import net.mullvad.mullvadvpn.lib.model.AccountData
import net.mullvad.mullvadvpn.lib.model.AuthFailedError
import net.mullvad.mullvadvpn.lib.model.ErrorState
@@ -90,8 +91,7 @@ class OutOfTimeUseCaseTest {
fun `tunnel is connected should emit false`() =
scope.runTest {
// Arrange
- val expiredAccountExpiry =
- AccountData(mockk(relaxed = true), ZonedDateTime.now().plusDays(1))
+ val expiredAccountExpiry = AccountData.mock(ZonedDateTime.now().plusDays(1))
val tunnelStateChanges =
listOf(
TunnelState.Disconnected(),
@@ -119,8 +119,7 @@ class OutOfTimeUseCaseTest {
fun `account expiry that has expired should emit true`() =
scope.runTest {
// Arrange
- val expiredAccountExpiry =
- AccountData(mockk(relaxed = true), ZonedDateTime.now().minusDays(1))
+ val expiredAccountExpiry = AccountData.mock(ZonedDateTime.now().minusDays(1))
// Act, Assert
outOfTimeUseCase.isOutOfTime.test {
assertEquals(null, awaitItem())
@@ -133,8 +132,7 @@ class OutOfTimeUseCaseTest {
fun `account expiry that has not expired should emit false`() =
scope.runTest {
// Arrange
- val notExpiredAccountExpiry =
- AccountData(mockk(relaxed = true), ZonedDateTime.now().plusDays(1))
+ val notExpiredAccountExpiry = AccountData.mock(ZonedDateTime.now().plusDays(1))
// Act, Assert
outOfTimeUseCase.isOutOfTime.test {
@@ -148,8 +146,7 @@ class OutOfTimeUseCaseTest {
fun `account that expires without new expiry event should emit true`() =
scope.runTest {
// Arrange
- val expiredAccountExpiry =
- AccountData(mockk(relaxed = true), ZonedDateTime.now().plusSeconds(100))
+ val expiredAccountExpiry = AccountData.mock(ZonedDateTime.now().plusSeconds(100))
// Act, Assert
outOfTimeUseCase.isOutOfTime.test {
// Initial event
@@ -172,10 +169,8 @@ class OutOfTimeUseCaseTest {
fun `account that is about to expire but is refilled should emit false`() =
scope.runTest {
// Arrange
- val initialAccountExpiry =
- AccountData(mockk(relaxed = true), ZonedDateTime.now().plusSeconds(100))
- val updatedExpiry =
- AccountData(mockk(relaxed = true), initialAccountExpiry.expiryDate.plusDays(30))
+ val initialAccountExpiry = AccountData.mock(ZonedDateTime.now().plusSeconds(100))
+ val updatedExpiry = AccountData.mock(initialAccountExpiry.expiryDate.plusDays(30))
// Act, Assert
outOfTimeUseCase.isOutOfTime.test {
@@ -202,10 +197,8 @@ class OutOfTimeUseCaseTest {
fun `expired account that is refilled should emit false`() =
scope.runTest {
// Arrange
- val initialAccountExpiry =
- AccountData(mockk(relaxed = true), ZonedDateTime.now().plusSeconds(100))
- val updatedExpiry =
- AccountData(mockk(relaxed = true), initialAccountExpiry.expiryDate.plusDays(30))
+ val initialAccountExpiry = AccountData.mock(ZonedDateTime.now().plusSeconds(100))
+ val updatedExpiry = AccountData.mock(initialAccountExpiry.expiryDate.plusDays(30))
// Act, Assert
outOfTimeUseCase.isOutOfTime.test {
// Initial event
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 a2be07e0a6..eeb848dc14 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.compose.state.LoginState.Idle
import net.mullvad.mullvadvpn.compose.state.LoginState.Loading
import net.mullvad.mullvadvpn.compose.state.LoginState.Success
import net.mullvad.mullvadvpn.compose.state.LoginUiState
+import net.mullvad.mullvadvpn.data.mock
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.model.AccountData
import net.mullvad.mullvadvpn.lib.model.AccountNumber
@@ -133,9 +134,7 @@ class LoginViewModelTest {
val sideEffects = loginViewModel.uiSideEffect.testIn(backgroundScope)
coEvery { mockedAccountRepository.login(any()) } returns Unit.right()
coEvery { mockedAccountRepository.accountData } returns
- MutableStateFlow(
- AccountData(mockk(relaxed = true), ZonedDateTime.now().plusDays(3))
- )
+ MutableStateFlow(AccountData.mock(ZonedDateTime.now().plusDays(3)))
// Act, Assert
uiStates.skipDefaultItem()
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 a96d59361a..f753a2e613 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
@@ -15,6 +15,7 @@ import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
import net.mullvad.mullvadvpn.compose.state.WelcomeUiState
+import net.mullvad.mullvadvpn.data.mock
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.model.AccountData
import net.mullvad.mullvadvpn.lib.model.AccountNumber
@@ -149,9 +150,7 @@ class WelcomeViewModelTest {
@Test
fun `when user has added time then uiSideEffect should emit OpenConnectScreen`() = runTest {
// Arrange
- accountExpiryStateFlow.emit(
- AccountData(mockk(relaxed = true), ZonedDateTime.now().plusDays(1))
- )
+ accountExpiryStateFlow.emit(AccountData.mock(ZonedDateTime.now().plusDays(1)))
// Act, Assert
viewModel.uiSideEffect.test {