Skip to content

Commit

Permalink
Add shadowsocks unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Pururun committed Aug 26, 2024
1 parent 98eadaf commit 85f4ca0
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package net.mullvad.mullvadvpn.viewmodel

import app.cash.turbine.test
import arrow.core.right
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.test.runTest
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.common.test.assertLists
import net.mullvad.mullvadvpn.lib.model.Constraint
import net.mullvad.mullvadvpn.lib.model.Port
import net.mullvad.mullvadvpn.lib.model.PortRange
import net.mullvad.mullvadvpn.lib.model.Settings
import net.mullvad.mullvadvpn.repository.RelayListRepository
import net.mullvad.mullvadvpn.repository.SettingsRepository
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 ShadowsocksSettingsViewModelTest {

private val mockSettingsRepository: SettingsRepository = mockk()
private val mockRelayListRepository: RelayListRepository = mockk()

private val settingsFlow = MutableStateFlow<Settings?>(null)
private val portRangesFlow = MutableStateFlow<List<PortRange>>(emptyList())

private lateinit var viewModel: ShadowsocksSettingsViewModel

@BeforeEach
fun setUp() {
every { mockSettingsRepository.settingsUpdates } returns settingsFlow
every { mockRelayListRepository.shadowsocksPortRanges } returns portRangesFlow

viewModel =
ShadowsocksSettingsViewModel(
settingsRepository = mockSettingsRepository,
relayListRepository = mockRelayListRepository
)
}

@Test
fun `uiState should reflect latest port value from settings`() = runTest {
// Arrange
val mockSettings: Settings = mockk()
val port = Port(123)
every { mockSettings.obfuscationSettings.shadowsocks.port } returns Constraint.Only(port)

settingsFlow.update { mockSettings }

// Act, Assert
viewModel.uiState.test {
// Check result
val result = awaitItem().port
assertEquals(Constraint.Only(port), result)
}
}

@Test
fun `uiState should reflect latest port range value from relay list`() = runTest {
// Arrange
val mockPortRange: List<PortRange> = listOf(mockk())

portRangesFlow.update { mockPortRange }
settingsFlow.update { mockk(relaxed = true) }

// Act, Assert
viewModel.uiState.test {
// Check result
val result = awaitItem().validPortRanges
assertLists(mockPortRange, result)
}
}

@Test
fun `when onObfuscationPortSelected is called should call repository`() {
// Arrange
val port = Constraint.Only(Port(123))
coEvery { mockSettingsRepository.setCustomShadowsocksObfuscationPort(port) } returns
Unit.right()

// Act
viewModel.onObfuscationPortSelected(port)

// Assert
coVerify { mockSettingsRepository.setCustomShadowsocksObfuscationPort(port) }
}

@Test
fun `when reset custom port is called should reset custom port`() = runTest {
// Arrange
val mockSettings: Settings = mockk()
val port = Port(123) // Needs to be not in SHADOWSOCKS_PRESET_PORTS
every { mockSettings.obfuscationSettings.shadowsocks.port } returns Constraint.Only(port)
coEvery {
mockSettingsRepository.setCustomShadowsocksObfuscationPort(Constraint.Any)
} returns Unit.right()

settingsFlow.update { mockSettings }

// Act, Assert
viewModel.uiState.test {
val startState = awaitItem()
assertEquals(port, startState.customPort)

viewModel.resetCustomPort()

val updatedState = awaitItem()
assertEquals(null, updatedState.customPort)
coVerify { mockSettingsRepository.setCustomShadowsocksObfuscationPort(Constraint.Any) }
}
}
}
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.right
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
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.Port
import net.mullvad.mullvadvpn.lib.model.Settings
import net.mullvad.mullvadvpn.repository.SettingsRepository
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 Udp2TcpSettingsViewModelTest {

private val mockSettingsRepository: SettingsRepository = mockk()

private val settingsFlow = MutableStateFlow<Settings?>(null)

private lateinit var viewModel: Udp2TcpSettingsViewModel

@BeforeEach
fun setUp() {
every { mockSettingsRepository.settingsUpdates } returns settingsFlow

viewModel = Udp2TcpSettingsViewModel(repository = mockSettingsRepository)
}

@Test
fun `uiState should reflect latest value from settings`() = runTest {
// Arrange
val mockSettings: Settings = mockk()
val port = Port(123)
every { mockSettings.obfuscationSettings.udp2tcp.port } returns Constraint.Only(port)

settingsFlow.update { mockSettings }

// Act, Assert
viewModel.uiState.test {
// Check result
val result = awaitItem().port
assertEquals(Constraint.Only(port), result)
}
}

@Test
fun `when onObfuscationPortSelected is called should call repository`() {
// Arrange
val port = Constraint.Only(Port(123))
coEvery { mockSettingsRepository.setCustomUdp2TcpObfuscationPort(port) } returns
Unit.right()

// Act
viewModel.onObfuscationPortSelected(port)

// Assert
coVerify { mockSettingsRepository.setCustomUdp2TcpObfuscationPort(port) }
}
}

0 comments on commit 85f4ca0

Please sign in to comment.