summaryrefslogtreecommitdiffhomepage
path: root/android/app/src/test
diff options
context:
space:
mode:
authorJonatan Rhodin <jonatan.rhodin@mullvad.net>2025-09-01 10:42:49 +0200
committerJonatan Rhodin <jonatan.rhodin@mullvad.net>2025-09-03 15:52:43 +0200
commite266d72875224a0522d50e55f0555a38deb45ff3 (patch)
treed5d07d35aab1c90f094fba9d77b935ce23071b8b /android/app/src/test
parentf9693d2fe31c0c50027f69f5bd930d30dfa5c764 (diff)
downloadmullvadvpn-e266d72875224a0522d50e55f0555a38deb45ff3.tar.xz
mullvadvpn-e266d72875224a0522d50e55f0555a38deb45ff3.zip
Add UI support for QUIC setting
Diffstat (limited to 'android/app/src/test')
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/RecentsUseCaseTest.kt146
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListLocationsViewModelTest.kt4
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/location/SelectLocationListViewModelTest.kt2
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/location/SelectLocationViewModelTest.kt47
4 files changed, 143 insertions, 56 deletions
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/RecentsUseCaseTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/RecentsUseCaseTest.kt
index 9623fffc7c..09759116a4 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/RecentsUseCaseTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/RecentsUseCaseTest.kt
@@ -47,67 +47,65 @@ class RecentsUseCaseTest {
@Test
fun `given null settings when invoke then emit null`() = runTest {
+ // Arrange
settingsFlow.value = null
every { customListsRelayItemUseCase(any()) } returns flowOf(emptyList())
every { filteredRelayListUseCase(any()) } returns flowOf(emptyList())
- useCase().test { assertNull(awaitItem()) }
+ // Act, Assert
+ useCase(isMultihop = false).test { assertNull(awaitItem()) }
}
@Test
fun `given recents disabled when invoke then emit null`() = runTest {
+ // Arrange
settingsFlow.value = mockk<Settings> { every { recents } returns Recents.Disabled }
every { customListsRelayItemUseCase(any()) } returns flowOf(emptyList())
every { filteredRelayListUseCase(any()) } returns flowOf(emptyList())
- useCase().test { assertNull(awaitItem()) }
+ // Act, Assert
+ useCase(isMultihop = false).test { assertNull(awaitItem()) }
}
@Test
fun `given recents enabled but empty when invoke then emit empty list`() = runTest {
+ // Arrange
settingsFlow.value =
mockk<Settings> { every { recents } returns Recents.Enabled(emptyList()) }
every { customListsRelayItemUseCase(any()) } returns flowOf(emptyList())
every { filteredRelayListUseCase(any()) } returns flowOf(emptyList())
- useCase().test { assertEquals(emptyList(), awaitItem()) }
+ // Act, Assert
+ useCase(isMultihop = false).test { assertEquals(emptyList(), awaitItem()) }
}
@Test
- fun `given recents enabled when invoke then emit hops based on the relay item filters`() =
- runTest {
- val swedenId = GeoLocationId.Country("se")
- val stockholmId = GeoLocationId.City(swedenId, "sto")
- val sweden =
- RelayItem.Location.Country(
- id = swedenId,
- name = "Sweden",
- cities =
- listOf(
- RelayItem.Location.City(
- id = stockholmId,
- name = "Stockholm",
- relays = emptyList(),
- )
- ),
- )
-
- val norwayId = GeoLocationId.Country("no")
- val norway =
- RelayItem.Location.Country(id = norwayId, name = "Norway", cities = emptyList())
+ fun `given recent custom list with no children should not emit that recent`() = runTest {
+ // Arrange
+ val id = CustomListId("id")
+ val customList =
+ RelayItem.CustomList(
+ customList =
+ CustomList(
+ id = id,
+ name = CustomListName.fromString("name"),
+ locations = emptyList(),
+ ),
+ locations = emptyList(),
+ )
+ val recent = Recent.Singlehop(location = id)
+ settingsFlow.value =
+ mockk<Settings> { every { recents } returns Recents.Enabled(listOf(recent)) }
+ every { customListsRelayItemUseCase(any()) } returns flowOf(listOf(customList))
+ every { filteredRelayListUseCase(any()) } returns flowOf(emptyList())
- val entryCustomListId = CustomListId("custom")
- val customList =
- CustomList(
- id = entryCustomListId,
- name = CustomListName.fromString("Custom"),
- locations = listOf(swedenId, norwayId),
- )
- val entryCustomList =
- RelayItem.CustomList(customList = customList, locations = emptyList())
+ useCase(isMultihop = false).test { assertEquals(emptyList(), awaitItem()) }
+ }
- val singleHopRecent = Recent.Singlehop(stockholmId)
- val multiHopRecent = Recent.Multihop(entry = entryCustomListId, exit = norwayId)
+ @Test
+ fun `given recents enabled when invoke then emit hops based on the relay item filters`() =
+ runTest {
+ val singleHopRecent = Recent.Singlehop(STOCKHOLM_ID)
val filteredOutRecent =
Recent.Singlehop(
GeoLocationId.City(country = GeoLocationId.Country("xx"), code = "xx-xxx-xx")
@@ -116,30 +114,72 @@ class RecentsUseCaseTest {
settingsFlow.value =
mockk<Settings> {
every { recents } returns
- Recents.Enabled(listOf(singleHopRecent, multiHopRecent, filteredOutRecent))
+ Recents.Enabled(listOf(singleHopRecent, filteredOutRecent))
}
- every {
- customListsRelayItemUseCase(RelayListType.Multihop(MultihopRelayListType.ENTRY))
- } returns flowOf(listOf(entryCustomList))
- every {
- customListsRelayItemUseCase(RelayListType.Multihop(MultihopRelayListType.EXIT))
- } returns flowOf(emptyList())
- every {
- filteredRelayListUseCase(RelayListType.Multihop(MultihopRelayListType.ENTRY))
- } returns flowOf(listOf(sweden, norway))
- every {
- filteredRelayListUseCase(RelayListType.Multihop(MultihopRelayListType.EXIT))
- } returns flowOf(listOf(sweden, norway))
+ every { customListsRelayItemUseCase(RelayListType.Single) } returns flowOf(emptyList())
+ every { filteredRelayListUseCase(RelayListType.Single) } returns
+ flowOf(listOf(SWEDEN, NORWAY))
- useCase().test {
+ useCase(isMultihop = false).test {
val hops = awaitItem()
- val stockholmCity = sweden.cities.first()
-
- val expectedHops =
- listOf(Hop.Single(stockholmCity), Hop.Multi(entryCustomList, norway))
+ val expectedHops = listOf(Hop.Single(STOCKHOLM))
assertEquals(expectedHops, hops)
}
}
+
+ @Test
+ fun `given multihop true should filter out singlehop recents`() = runTest {
+ val singleHopRecent = Recent.Singlehop(STOCKHOLM_ID)
+ val multiHopRecent = Recent.Multihop(entry = CUSTOM_LIST_ID, exit = NORWAY_ID)
+
+ settingsFlow.value =
+ mockk<Settings> {
+ every { recents } returns Recents.Enabled(listOf(singleHopRecent, multiHopRecent))
+ }
+
+ every {
+ customListsRelayItemUseCase(RelayListType.Multihop(MultihopRelayListType.ENTRY))
+ } returns flowOf(listOf(CUSTOM_LIST_SWE_NO))
+ every {
+ customListsRelayItemUseCase(RelayListType.Multihop(MultihopRelayListType.EXIT))
+ } returns flowOf(emptyList())
+ every {
+ filteredRelayListUseCase(RelayListType.Multihop(MultihopRelayListType.ENTRY))
+ } returns flowOf(listOf(SWEDEN, NORWAY))
+ every {
+ filteredRelayListUseCase(RelayListType.Multihop(MultihopRelayListType.EXIT))
+ } returns flowOf(listOf(SWEDEN, NORWAY))
+
+ useCase(isMultihop = true).test {
+ val hops = awaitItem()
+
+ val expectedHops = listOf(Hop.Multi(CUSTOM_LIST_SWE_NO, NORWAY))
+ assertEquals(expectedHops, hops)
+ }
+ }
+
+ companion object {
+ private val SWEDEN_ID = GeoLocationId.Country("se")
+ private val STOCKHOLM_ID = GeoLocationId.City(SWEDEN_ID, "sto")
+ private val STOCKHOLM =
+ RelayItem.Location.City(id = STOCKHOLM_ID, name = "Stockholm", relays = emptyList())
+ private val SWEDEN =
+ RelayItem.Location.Country(id = SWEDEN_ID, name = "Sweden", cities = listOf(STOCKHOLM))
+ private val NORWAY_ID = GeoLocationId.Country("no")
+ private val NORWAY =
+ RelayItem.Location.Country(id = NORWAY_ID, name = "Norway", cities = emptyList())
+ private val CUSTOM_LIST_ID = CustomListId("custom")
+ private val CUSTOM_LIST_SWE_NO =
+ RelayItem.CustomList(
+ customList =
+ CustomList(
+ id = CUSTOM_LIST_ID,
+ name = CustomListName.fromString("Custom"),
+ locations = listOf(SWEDEN_ID, NORWAY_ID),
+ ),
+ locations = listOf(SWEDEN, NORWAY),
+ )
+ }
}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListLocationsViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListLocationsViewModelTest.kt
index a3257f04d9..fc6dcf79c0 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListLocationsViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/CustomListLocationsViewModelTest.kt
@@ -364,7 +364,7 @@ class CustomListLocationsViewModelTest {
provider = ProviderId("Provider"),
ownership = Ownership.MullvadOwned,
daita = false,
- quic = false,
+ quic = null,
)
),
)
@@ -382,7 +382,7 @@ class CustomListLocationsViewModelTest {
provider = ProviderId("Provider"),
ownership = Ownership.MullvadOwned,
daita = false,
- quic = false,
+ quic = null,
)
}
}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/location/SelectLocationListViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/location/SelectLocationListViewModelTest.kt
index 3f9bfe751a..8c01d592e5 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/location/SelectLocationListViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/location/SelectLocationListViewModelTest.kt
@@ -67,7 +67,7 @@ class SelectLocationListViewModelTest {
filteredCustomListRelayItems
every { mockCustomListRelayItemsUseCase() } returns customListRelayItems
every { mockSettingsRepository.settingsUpdates } returns settings
- every { recentsUseCase() } returns recentsRelayItems
+ every { recentsUseCase(any()) } returns recentsRelayItems
}
@Test
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/location/SelectLocationViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/location/SelectLocationViewModelTest.kt
index e50cfb48a2..b633e3402f 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/location/SelectLocationViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/location/SelectLocationViewModelTest.kt
@@ -21,6 +21,7 @@ import net.mullvad.mullvadvpn.compose.state.MultihopRelayListType
import net.mullvad.mullvadvpn.compose.state.RelayListType
import net.mullvad.mullvadvpn.compose.state.SelectLocationUiState
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.CustomList
import net.mullvad.mullvadvpn.lib.model.CustomListId
@@ -40,6 +41,7 @@ import net.mullvad.mullvadvpn.repository.SettingsRepository
import net.mullvad.mullvadvpn.repository.WireguardConstraintsRepository
import net.mullvad.mullvadvpn.usecase.FilterChip
import net.mullvad.mullvadvpn.usecase.FilterChipUseCase
+import net.mullvad.mullvadvpn.usecase.ModelOwnership
import net.mullvad.mullvadvpn.usecase.ModifyMultihopUseCase
import net.mullvad.mullvadvpn.usecase.MultihopChange
import net.mullvad.mullvadvpn.usecase.SelectHopUseCase
@@ -300,6 +302,51 @@ class SelectLocationViewModelTest {
}
}
+ @Test
+ fun `given entry blocked should not emit any filter if in entry list`() = runTest {
+ // Arrange
+ val mockSettings = mockk<Settings>(relaxed = true)
+ settings.value = mockSettings
+ every { mockSettings.tunnelOptions.wireguard.daitaSettings.enabled } returns true
+ every { mockSettings.tunnelOptions.wireguard.daitaSettings.directOnly } returns false
+ every {
+ mockSettings.relaySettings.relayConstraints.wireguardConstraints.isMultihopEnabled
+ } returns true
+ filterChips.value = listOf(FilterChip.Quic, FilterChip.Daita)
+
+ // Act, Assert
+ viewModel.uiState.test {
+ awaitItem() // Initial state
+ viewModel.selectRelayList(MultihopRelayListType.ENTRY)
+ val state = awaitItem()
+ assertIs<Lc.Content<SelectLocationUiState>>(state)
+ assert(state.value.filterChips.isEmpty())
+ }
+ }
+
+ @Test
+ fun `given entry blocked should emit filters if in exit list`() = runTest {
+ // Arrange
+ val mockSettings = mockk<Settings>(relaxed = true)
+ val expectedFilters = listOf(FilterChip.Ownership(ModelOwnership.MullvadOwned))
+ settings.value = mockSettings
+ filterChips.value = expectedFilters
+ every { mockSettings.tunnelOptions.wireguard.daitaSettings.enabled } returns true
+ every { mockSettings.tunnelOptions.wireguard.daitaSettings.directOnly } returns false
+ every {
+ mockSettings.relaySettings.relayConstraints.wireguardConstraints.isMultihopEnabled
+ } returns true
+
+ // Act, Assert
+ viewModel.uiState.test {
+ awaitItem() // Initial state
+ viewModel.selectRelayList(MultihopRelayListType.EXIT)
+ val state = awaitItem()
+ assertIs<Lc.Content<SelectLocationUiState>>(state)
+ assertLists(expectedFilters, state.value.filterChips)
+ }
+ }
+
companion object {
private const val RELAY_LIST_EXTENSIONS =
"net.mullvad.mullvadvpn.relaylist.RelayListExtensionsKt"