Skip to content

Commit

Permalink
Add and update unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Pururun committed Nov 26, 2024
1 parent 7280044 commit ba00662
Show file tree
Hide file tree
Showing 8 changed files with 691 additions and 181 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package net.mullvad.mullvadvpn.usecase

import app.cash.turbine.test
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
import net.mullvad.mullvadvpn.compose.state.RelayListType
import net.mullvad.mullvadvpn.lib.common.test.assertLists
import net.mullvad.mullvadvpn.lib.model.Constraint
import net.mullvad.mullvadvpn.lib.model.Ownership
import net.mullvad.mullvadvpn.lib.model.Provider
import net.mullvad.mullvadvpn.lib.model.ProviderId
import net.mullvad.mullvadvpn.lib.model.Providers
import net.mullvad.mullvadvpn.lib.model.Settings
import net.mullvad.mullvadvpn.lib.model.WireguardConstraints
import net.mullvad.mullvadvpn.repository.RelayListFilterRepository
import net.mullvad.mullvadvpn.repository.SettingsRepository
import net.mullvad.mullvadvpn.repository.WireguardConstraintsRepository
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class FilterChipUseCaseTest {

private val mockRelayListFilterRepository: RelayListFilterRepository = mockk()
private val mockAvailableProvidersUseCase: AvailableProvidersUseCase = mockk()
private val mockSettingRepository: SettingsRepository = mockk()
private val mockWireguardConstraintsRepository: WireguardConstraintsRepository = mockk()

private val selectedOwnership = MutableStateFlow<Constraint<Ownership>>(Constraint.Any)
private val selectedProviders = MutableStateFlow<Constraint<Providers>>(Constraint.Any)
private val availableProviders = MutableStateFlow<List<Provider>>(emptyList())
private val settings = MutableStateFlow<Settings>(mockk(relaxed = true))
private val wireguardConstraints = MutableStateFlow<WireguardConstraints>(mockk(relaxed = true))

private lateinit var filterChipUseCase: FilterChipUseCase

@BeforeEach
fun setUp() {
every { mockRelayListFilterRepository.selectedOwnership } returns selectedOwnership
every { mockRelayListFilterRepository.selectedProviders } returns selectedProviders
every { mockAvailableProvidersUseCase() } returns availableProviders
every { mockSettingRepository.settingsUpdates } returns settings
every { mockWireguardConstraintsRepository.wireguardConstraints } returns
wireguardConstraints

filterChipUseCase =
FilterChipUseCase(
relayListFilterRepository = mockRelayListFilterRepository,
availableProvidersUseCase = mockAvailableProvidersUseCase,
settingsRepository = mockSettingRepository,
wireguardConstraintsRepository = mockWireguardConstraintsRepository,
)
}

@Test
fun `when no filters are applied should return empty list`() = runTest {
filterChipUseCase(RelayListType.EXIT).test { assertLists(emptyList(), awaitItem()) }
}

@Test
fun `when ownership filter is applied should return correct ownership`() = runTest {
// Arrange
val expectedOwnership = Ownership.MullvadOwned
selectedOwnership.value = Constraint.Only(expectedOwnership)

filterChipUseCase(RelayListType.EXIT).test {
assertLists(listOf(FilterChip.Ownership(expectedOwnership)), awaitItem())
}
}

@Test
fun `when provider filter is applied should return correct number of providers`() = runTest {
// Arrange
val expectedProviders = Providers(providers = setOf(ProviderId("1"), ProviderId("2")))
selectedProviders.value = Constraint.Only(expectedProviders)
availableProviders.value =
listOf(
Provider(ProviderId("1"), Ownership.MullvadOwned),
Provider(ProviderId("2"), Ownership.Rented),
)

filterChipUseCase(RelayListType.EXIT).test {
assertLists(listOf(FilterChip.Provider(2)), awaitItem())
}
}

@Test
fun `when provider and ownership filter is applied should return correct filter chips`() =
runTest {
// Arrange
val expectedProviders = Providers(providers = setOf(ProviderId("1")))
val expectedOwnership = Ownership.MullvadOwned
selectedProviders.value = Constraint.Only(expectedProviders)
selectedOwnership.value = Constraint.Only(expectedOwnership)
availableProviders.value =
listOf(
Provider(ProviderId("1"), Ownership.MullvadOwned),
Provider(ProviderId("2"), Ownership.Rented),
)

filterChipUseCase(RelayListType.EXIT).test {
assertLists(
listOf(FilterChip.Ownership(expectedOwnership), FilterChip.Provider(1)),
awaitItem(),
)
}
}

@Test
fun `when Daita is enabled and multihop is disabled should return Daita filter chip`() =
runTest {
// Arrange
settings.value = mockk(relaxed = true) { every { isDaitaEnabled() } returns true }
wireguardConstraints.value =
mockk(relaxed = true) { every { isMultihopEnabled } returns false }

filterChipUseCase(RelayListType.EXIT).test {
assertLists(listOf(FilterChip.Daita), awaitItem())
}
}

@Test
fun `when Daita is enabled and multihop is enabled and relay list type is entry should return Daita filter chip`() =
runTest {
// Arrange
settings.value = mockk(relaxed = true) { every { isDaitaEnabled() } returns true }
wireguardConstraints.value =
mockk(relaxed = true) { every { isMultihopEnabled } returns true }

filterChipUseCase(RelayListType.ENTRY).test {
assertLists(listOf(FilterChip.Daita), awaitItem())
}
}

@Test
fun `when Daita is enabled and multihop is enabled and relay list type is exit should return no filter`() =
runTest {
// Arrange
settings.value = mockk(relaxed = true) { every { isDaitaEnabled() } returns true }
wireguardConstraints.value =
mockk(relaxed = true) { every { isMultihopEnabled } returns true }

filterChipUseCase(RelayListType.EXIT).test { assertLists(emptyList(), awaitItem()) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package net.mullvad.mullvadvpn.usecase

import app.cash.turbine.test
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
import net.mullvad.mullvadvpn.lib.model.Constraint
import net.mullvad.mullvadvpn.lib.model.GeoLocationId
import net.mullvad.mullvadvpn.lib.model.RelayItemId
import net.mullvad.mullvadvpn.lib.model.RelayItemSelection
import net.mullvad.mullvadvpn.lib.model.WireguardConstraints
import net.mullvad.mullvadvpn.repository.RelayListRepository
import net.mullvad.mullvadvpn.repository.WireguardConstraintsRepository
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class SelectedLocationUseCaseTest {
private val mockRelayListRepository: RelayListRepository = mockk()
private val mockWireguardConstraintsRepository: WireguardConstraintsRepository = mockk()

private val selectedLocation = MutableStateFlow<Constraint<RelayItemId>>(Constraint.Any)
private val wireguardConstraints = MutableStateFlow<WireguardConstraints>(mockk(relaxed = true))

private lateinit var selectLocationUseCase: SelectedLocationUseCase

@BeforeEach
fun setup() {
every { mockRelayListRepository.selectedLocation } returns selectedLocation
every { mockWireguardConstraintsRepository.wireguardConstraints } returns
wireguardConstraints

selectLocationUseCase =
SelectedLocationUseCase(
relayListRepository = mockRelayListRepository,
wireguardConstraintsRepository = mockWireguardConstraintsRepository,
)
}

@Test
fun `when wireguard constraints is multihop enabled should return Multiple`() = runTest {
// Arrange
val entryLocation: Constraint<RelayItemId> = Constraint.Only(GeoLocationId.Country("se"))
val exitLocation = Constraint.Only(GeoLocationId.Country("us"))
wireguardConstraints.value =
WireguardConstraints(
isMultihopEnabled = true,
entryLocation = entryLocation,
port = Constraint.Any,
)
selectedLocation.value = exitLocation

// Act, Assert
selectLocationUseCase().test {
assertEquals(RelayItemSelection.Multiple(entryLocation, exitLocation), awaitItem())
}
}

@Test
fun `when wireguard constraints is multihop disabled should return Single`() = runTest {
// Arrange
val exitLocation = Constraint.Only(GeoLocationId.Country("us"))
selectedLocation.value = exitLocation

// Act, Assert
selectLocationUseCase().test {
assertEquals(RelayItemSelection.Single(exitLocation), awaitItem())
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package net.mullvad.mullvadvpn.viewmodel

import app.cash.turbine.test
import arrow.core.Either
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.model.Constraint
import net.mullvad.mullvadvpn.lib.model.WireguardConstraints
import net.mullvad.mullvadvpn.repository.WireguardConstraintsRepository
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith

@ExtendWith(TestCoroutineRule::class)
class MultihopViewModelTest {

private val mockWireguardConstraintsRepository: WireguardConstraintsRepository = mockk()

private val wireguardConstraints = MutableStateFlow<WireguardConstraints>(mockk(relaxed = true))

private lateinit var multihopViewModel: MultihopViewModel

@BeforeEach
fun setUp() {
every { mockWireguardConstraintsRepository.wireguardConstraints } returns
wireguardConstraints

multihopViewModel =
MultihopViewModel(wireguardConstraintsRepository = mockWireguardConstraintsRepository)
}

@Test
fun `default state should be multihop disabled`() {
assertEquals(false, multihopViewModel.uiState.value.enable)
}

@Test
fun `when multihop enabled is true state should return multihop enabled true`() = runTest {
// Arrange
wireguardConstraints.value =
WireguardConstraints(
isMultihopEnabled = true,
entryLocation = Constraint.Any,
port = Constraint.Any,
)

// Act, Assert
multihopViewModel.uiState.test { assertEquals(MultihopUiState(true), awaitItem()) }
}

@Test
fun `when set multihop is called should call repository set multihop`() = runTest {
// Arrange
coEvery { mockWireguardConstraintsRepository.setMultihop(any()) } returns Either.Right(Unit)

// Act
multihopViewModel.setMultihop(true)

// Assert
coVerify { mockWireguardConstraintsRepository.setMultihop(true) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.model.Constraint
import net.mullvad.mullvadvpn.lib.model.DeviceState
import net.mullvad.mullvadvpn.lib.model.WireguardConstraints
import net.mullvad.mullvadvpn.lib.shared.DeviceRepository
import net.mullvad.mullvadvpn.repository.WireguardConstraintsRepository
import net.mullvad.mullvadvpn.ui.VersionInfo
import net.mullvad.mullvadvpn.ui.serviceconnection.AppVersionInfoRepository
import org.junit.jupiter.api.AfterEach
Expand All @@ -24,9 +27,11 @@ class SettingsViewModelTest {

private val mockDeviceRepository: DeviceRepository = mockk()
private val mockAppVersionInfoRepository: AppVersionInfoRepository = mockk()
private val mockWireguardConstraintsRepository: WireguardConstraintsRepository = mockk()

private val versionInfo =
MutableStateFlow(VersionInfo(currentVersion = "", isSupported = false))
private val wireguardConstraints = MutableStateFlow<WireguardConstraints>(mockk(relaxed = true))

private lateinit var viewModel: SettingsViewModel

Expand All @@ -36,11 +41,14 @@ class SettingsViewModelTest {

every { mockDeviceRepository.deviceState } returns deviceState
every { mockAppVersionInfoRepository.versionInfo } returns versionInfo
every { mockWireguardConstraintsRepository.wireguardConstraints } returns
wireguardConstraints

viewModel =
SettingsViewModel(
deviceRepository = mockDeviceRepository,
appVersionInfoRepository = mockAppVersionInfoRepository,
wireguardConstraintsRepository = mockWireguardConstraintsRepository,
isPlayBuild = false,
)
}
Expand Down Expand Up @@ -84,4 +92,22 @@ class SettingsViewModelTest {
assertEquals(false, result.isSupportedVersion)
}
}

@Test
fun `when WireguardConstraintsRepository return multihop enabled uiState should return multihop enabled true`() =
runTest {
// Arrange
wireguardConstraints.value =
WireguardConstraints(
isMultihopEnabled = true,
entryLocation = Constraint.Any,
port = Constraint.Any,
)

// Act, Assert
viewModel.uiState.test {
val result = awaitItem()
assertEquals(true, result.multihopEnabled)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ class VpnSettingsViewModelTest {
val wireguardConstraints =
WireguardConstraints(
port = wireguardPort,
useMultihop = false,
isMultihopEnabled = false,
entryLocation = Constraint.Any,
)
coEvery { mockWireguardConstraintsRepository.setWireguardPort(any()) } returns
Expand Down
Loading

0 comments on commit ba00662

Please sign in to comment.