diff options
| author | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2025-09-01 10:42:49 +0200 |
|---|---|---|
| committer | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2025-09-03 15:52:43 +0200 |
| commit | e266d72875224a0522d50e55f0555a38deb45ff3 (patch) | |
| tree | d5d07d35aab1c90f094fba9d77b935ce23071b8b /android/app/src/test | |
| parent | f9693d2fe31c0c50027f69f5bd930d30dfa5c764 (diff) | |
| download | mullvadvpn-e266d72875224a0522d50e55f0555a38deb45ff3.tar.xz mullvadvpn-e266d72875224a0522d50e55f0555a38deb45ff3.zip | |
Add UI support for QUIC setting
Diffstat (limited to 'android/app/src/test')
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" |
