@@ -11,6 +11,7 @@ import io.mockk.mockkStatic
11
11
import io.mockk.unmockkAll
12
12
import kotlin.test.assertEquals
13
13
import kotlin.test.assertIs
14
+ import kotlin.test.assertTrue
14
15
import kotlinx.coroutines.cancel
15
16
import kotlinx.coroutines.flow.MutableStateFlow
16
17
import kotlinx.coroutines.test.runTest
@@ -64,8 +65,9 @@ class SelectLocationViewModelTest {
64
65
private val selectedProviders = MutableStateFlow <Constraint <Providers >>(Constraint .Any )
65
66
private val selectedRelayItemFlow = MutableStateFlow <Constraint <RelayItemId >>(Constraint .Any )
66
67
private val filteredRelayList = MutableStateFlow <List <RelayItem .Location .Country >>(emptyList())
67
- private val filteredCustomRelayListItems = MutableStateFlow <List <RelayItem .CustomList >>(emptyList())
68
- private val customListsRelayItem = MutableStateFlow <List <RelayItem .CustomList >>(emptyList())
68
+ private val filteredCustomRelayListItems =
69
+ MutableStateFlow <List <RelayItem .CustomList >>(emptyList())
70
+ private val customListsRelayItem = MutableStateFlow <List <RelayItem .CustomList >>(emptyList())
69
71
70
72
@BeforeEach
71
73
fun setup () {
@@ -78,7 +80,6 @@ class SelectLocationViewModelTest {
78
80
every { mockFilteredCustomListRelayItemsUseCase() } returns filteredCustomRelayListItems
79
81
every { mockCustomListsRelayItemUseCase() } returns customListsRelayItem
80
82
81
-
82
83
mockkStatic(RELAY_LIST_EXTENSIONS )
83
84
mockkStatic(RELAY_ITEM_EXTENSIONS )
84
85
mockkStatic(CUSTOM_LIST_EXTENSIONS )
@@ -107,51 +108,50 @@ class SelectLocationViewModelTest {
107
108
}
108
109
109
110
@Test
110
- fun `given relayListWithSelection emits update uiState should contain new update` () = runTest {
111
+ fun `given filteredRelayList emits update uiState should contain new update` () = runTest {
111
112
// Arrange
112
- val mockCountries = listOf<RelayItem .Location .Country >(mockk(), mockk())
113
- val selectedItem: RelayItemId = mockk()
114
- filteredRelayList.value = mockCountries
115
- selectedRelayItemFlow.value = Constraint .Only (selectedItem)
113
+ filteredRelayList.value = testCountries
114
+ val selectedId = testCountries.first().id
115
+ selectedRelayItemFlow.value = Constraint .Only (selectedId)
116
116
117
117
// Act, Assert
118
118
viewModel.uiState.test {
119
- val loading = awaitItem()
120
- assertIs<SelectLocationUiState .Loading >(loading)
121
119
val actualState = awaitItem()
122
120
assertIs<SelectLocationUiState .Content >(actualState)
123
- assertLists(mockCountries, actualState.relayListItems.filter { it is RelayListItem .GeoLocationItem })
124
- // assertEquals(selectedItem, actualState.selectedItem)
121
+ assertLists(
122
+ testCountries.map { it.id },
123
+ actualState.relayListItems.mapNotNull { it.relayItemId() }
124
+ )
125
+ assertTrue(
126
+ actualState.relayListItems
127
+ .filterIsInstance<RelayListItem .SelectableItem >()
128
+ .first { it.relayItemId() == selectedId }
129
+ .isSelected
130
+ )
125
131
}
126
132
}
127
133
128
- fun RelayListItem.relayItemId () = when (this ) {
129
- is RelayListItem .CustomListFooter -> null
130
- RelayListItem .CustomListHeader -> null
131
- RelayListItem .LocationHeader -> null
132
- is RelayListItem .LocationsEmptyText -> null
133
- is RelayListItem .CustomListEntryItem -> item.id
134
- is RelayListItem .CustomListItem -> item.id
135
- is RelayListItem .GeoLocationItem -> item.id
136
- }
137
-
138
134
@Test
139
- fun `given relayListWithSelection emits update with no selections selectedItem should be null` () =
140
- runTest {
141
- // Arrange
142
- val mockCountries = listOf<RelayItem .Location .Country >(mockk(), mockk())
143
- val selectedItem: RelayItemId ? = null
144
- filteredRelayList.value = mockCountries
145
- selectedRelayItemFlow.value = Constraint .Any
146
-
147
- // Act, Assert
148
- viewModel.uiState.test {
149
- val actualState = awaitItem()
150
- assertIs<SelectLocationUiState .Content >(actualState)
151
- // assertLists(mockCountries, actualState.countries)
152
- // assertEquals(selectedItem, actualState.selectedItem)
153
- }
135
+ fun `given relay is selected all relay items should not be selected` () = runTest {
136
+ // Arrange
137
+ filteredRelayList.value = testCountries
138
+ selectedRelayItemFlow.value = Constraint .Any
139
+
140
+ // Act, Assert
141
+ viewModel.uiState.test {
142
+ val actualState = awaitItem()
143
+ assertIs<SelectLocationUiState .Content >(actualState)
144
+ assertLists(
145
+ testCountries.map { it.id },
146
+ actualState.relayListItems.mapNotNull { it.relayItemId() }
147
+ )
148
+ assertTrue(
149
+ actualState.relayListItems.filterIsInstance<RelayListItem .SelectableItem >().all {
150
+ ! it.isSelected
151
+ }
152
+ )
154
153
}
154
+ }
155
155
156
156
@Test
157
157
fun `on selectRelay call uiSideEffect should emit CloseScreen and connect` () = runTest {
@@ -296,12 +296,29 @@ class SelectLocationViewModelTest {
296
296
}
297
297
}
298
298
299
+ fun RelayListItem.relayItemId () =
300
+ when (this ) {
301
+ is RelayListItem .CustomListFooter -> null
302
+ RelayListItem .CustomListHeader -> null
303
+ RelayListItem .LocationHeader -> null
304
+ is RelayListItem .LocationsEmptyText -> null
305
+ is RelayListItem .CustomListEntryItem -> item.id
306
+ is RelayListItem .CustomListItem -> item.id
307
+ is RelayListItem .GeoLocationItem -> item.id
308
+ }
309
+
299
310
companion object {
300
311
private const val RELAY_LIST_EXTENSIONS =
301
312
" net.mullvad.mullvadvpn.relaylist.RelayListExtensionsKt"
302
313
private const val RELAY_ITEM_EXTENSIONS =
303
314
" net.mullvad.mullvadvpn.relaylist.RelayItemExtensionsKt"
304
315
private const val CUSTOM_LIST_EXTENSIONS =
305
316
" net.mullvad.mullvadvpn.relaylist.CustomListExtensionsKt"
317
+
318
+ private val testCountries =
319
+ listOf<RelayItem .Location .Country >(
320
+ RelayItem .Location .Country (id = GeoLocationId .Country (" se" ), " Sweden" , emptyList()),
321
+ RelayItem .Location .Country (id = GeoLocationId .Country (" no" ), " Norway" , emptyList())
322
+ )
306
323
}
307
324
}
0 commit comments