summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
authorJonatan Rhodin <jonatan.rhodin@mullvad.net>2024-11-24 23:23:40 +0100
committerJonatan Rhodin <jonatan.rhodin@mullvad.net>2024-11-27 08:50:54 +0100
commit90a0aaa1ddf207aae70492472f27cff32e771866 (patch)
treef9e2fa3cc77e98cef2943d8db72e23ca8b7a0462 /android
parent2153daeb14d1baafaad62c6af591eaebe9351128 (diff)
downloadmullvadvpn-90a0aaa1ddf207aae70492472f27cff32e771866.tar.xz
mullvadvpn-90a0aaa1ddf207aae70492472f27cff32e771866.zip
Update and add screen tests
Diffstat (limited to 'android')
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt1
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreenTest.kt7
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreenTest.kt2
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreenTest.kt105
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreenTest.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreenTest.kt)183
5 files changed, 182 insertions, 116 deletions
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt
index 1c33420863..487e739025 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt
@@ -474,6 +474,7 @@ class ConnectScreenTest {
val inPort = 99
val inProtocol = TransportProtocol.Udp
every { mockLocation.hostname } returns mockHostName
+ every { mockLocation.entryHostname } returns null
// In
every { mockTunnelEndpoint.obfuscation } returns null
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreenTest.kt
index 444bbd2c5b..484bb132d6 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreenTest.kt
@@ -163,9 +163,7 @@ class CustomListLocationsScreenTest {
}
// Assert
- onNodeWithText(EMPTY_SEARCH_FIRST_ROW.format(mockSearchString), substring = true)
- .assertExists()
- onNodeWithText(EMPTY_SEARCH_SECOND_ROW, substring = true).assertExists()
+ onNodeWithText(EMPTY_SEARCH.format(mockSearchString)).assertExists()
}
@Test
@@ -239,8 +237,7 @@ class CustomListLocationsScreenTest {
const val ADD_LOCATIONS_TEXT = "Add locations"
const val EDIT_LOCATIONS_TEXT = "Edit locations"
const val SEARCH_PLACEHOLDER = "Search for..."
- const val EMPTY_SEARCH_FIRST_ROW = "No result for %s."
- const val EMPTY_SEARCH_SECOND_ROW = "Try a different search"
+ const val EMPTY_SEARCH = "No result for \"%s\", please try a different search"
const val NO_LOCATIONS_FOUND_TEXT = "No locations found"
}
}
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreenTest.kt
index 2509c7be8d..e691909a40 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreenTest.kt
@@ -33,6 +33,7 @@ class SettingsScreenTest {
isLoggedIn = true,
isSupportedVersion = true,
isPlayBuild = false,
+ multihopEnabled = false,
)
)
}
@@ -56,6 +57,7 @@ class SettingsScreenTest {
isLoggedIn = false,
isSupportedVersion = true,
isPlayBuild = false,
+ multihopEnabled = false,
)
)
}
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreenTest.kt
new file mode 100644
index 0000000000..5901599df9
--- /dev/null
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreenTest.kt
@@ -0,0 +1,105 @@
+package net.mullvad.mullvadvpn.compose.screen.location
+
+import androidx.compose.ui.test.ExperimentalTestApi
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.performTextInput
+import io.mockk.MockKAnnotations
+import io.mockk.mockk
+import io.mockk.unmockkAll
+import io.mockk.verify
+import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
+import net.mullvad.mullvadvpn.compose.data.DUMMY_RELAY_ITEM_CUSTOM_LISTS
+import net.mullvad.mullvadvpn.compose.setContentWithTheme
+import net.mullvad.mullvadvpn.compose.state.RelayListItem
+import net.mullvad.mullvadvpn.compose.state.SearchLocationUiState
+import net.mullvad.mullvadvpn.compose.test.SELECT_LOCATION_CUSTOM_LIST_HEADER_TEST_TAG
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.extension.RegisterExtension
+
+@OptIn(ExperimentalTestApi::class)
+class SearchLocationScreenTest {
+ @JvmField @RegisterExtension val composeExtension = createEdgeToEdgeComposeExtension()
+
+ @BeforeEach
+ fun setup() {
+ MockKAnnotations.init(this)
+ }
+
+ @AfterEach
+ fun teardown() {
+ unmockkAll()
+ }
+
+ @Test
+ fun testSearchInput() =
+ composeExtension.use {
+ // Arrange
+ val mockedSearchTermInput: (String) -> Unit = mockk(relaxed = true)
+ setContentWithTheme {
+ SearchLocationScreen(
+ state =
+ SearchLocationUiState.NoQuery(searchTerm = "", filterChips = emptyList()),
+ onSearchInputChanged = mockedSearchTermInput,
+ )
+ }
+ val mockSearchString = "SEARCH"
+
+ // Act
+ onNodeWithText("Search for...").performTextInput(mockSearchString)
+
+ // Assert
+ verify { mockedSearchTermInput.invoke(mockSearchString) }
+ }
+
+ @Test
+ fun testSearchTermNotFound() =
+ composeExtension.use {
+ // Arrange
+ val mockSearchString = "SEARCH"
+ setContentWithTheme {
+ SearchLocationScreen(
+ state =
+ SearchLocationUiState.Content(
+ searchTerm = mockSearchString,
+ filterChips = emptyList(),
+ relayListItems =
+ listOf(RelayListItem.LocationsEmptyText(mockSearchString)),
+ customLists = emptyList(),
+ )
+ )
+ }
+
+ // Assert
+ onNodeWithText("No result for \"$mockSearchString\", please try a different search")
+ .assertExists()
+ }
+
+ @Test
+ fun givenNoCustomListsAndSearchIsActiveShouldNotShowCustomListHeader() =
+ composeExtension.use {
+ // Arrange
+ val mockSearchString = "SEARCH"
+ setContentWithTheme {
+ SearchLocationScreen(
+ state =
+ SearchLocationUiState.Content(
+ searchTerm = mockSearchString,
+ filterChips = emptyList(),
+ relayListItems = emptyList(),
+ customLists = DUMMY_RELAY_ITEM_CUSTOM_LISTS,
+ )
+ )
+ }
+
+ // Assert
+ onNodeWithText(CUSTOM_LISTS_EMPTY_TEXT).assertDoesNotExist()
+ onNodeWithTag(SELECT_LOCATION_CUSTOM_LIST_HEADER_TEST_TAG).assertDoesNotExist()
+ }
+
+ companion object {
+ private const val CUSTOM_LISTS_EMPTY_TEXT = "To create a custom list press the \"︙\""
+ }
+}
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreenTest.kt
index 31097725db..a154344f26 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreenTest.kt
@@ -1,63 +1,74 @@
-package net.mullvad.mullvadvpn.compose.screen
+package net.mullvad.mullvadvpn.compose.screen.location
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
-import androidx.compose.ui.test.performTextInput
import io.mockk.MockKAnnotations
+import io.mockk.every
import io.mockk.mockk
+import io.mockk.unmockkAll
import io.mockk.verify
+import kotlinx.coroutines.flow.MutableStateFlow
import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
import net.mullvad.mullvadvpn.compose.data.DUMMY_RELAY_COUNTRIES
import net.mullvad.mullvadvpn.compose.data.DUMMY_RELAY_ITEM_CUSTOM_LISTS
import net.mullvad.mullvadvpn.compose.setContentWithTheme
import net.mullvad.mullvadvpn.compose.state.RelayListItem
+import net.mullvad.mullvadvpn.compose.state.RelayListType
+import net.mullvad.mullvadvpn.compose.state.SelectLocationListUiState
import net.mullvad.mullvadvpn.compose.state.SelectLocationUiState
-import net.mullvad.mullvadvpn.compose.test.CIRCULAR_PROGRESS_INDICATOR
import net.mullvad.mullvadvpn.compose.test.SELECT_LOCATION_CUSTOM_LIST_BOTTOM_SHEET_TEST_TAG
-import net.mullvad.mullvadvpn.compose.test.SELECT_LOCATION_CUSTOM_LIST_HEADER_TEST_TAG
import net.mullvad.mullvadvpn.compose.test.SELECT_LOCATION_LOCATION_BOTTOM_SHEET_TEST_TAG
import net.mullvad.mullvadvpn.lib.model.RelayItem
import net.mullvad.mullvadvpn.performLongClick
+import net.mullvad.mullvadvpn.viewmodel.location.SelectLocationListViewModel
+import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.RegisterExtension
+import org.koin.core.context.loadKoinModules
+import org.koin.core.module.dsl.viewModel
+import org.koin.dsl.module
@OptIn(ExperimentalTestApi::class)
class SelectLocationScreenTest {
@JvmField @RegisterExtension val composeExtension = createEdgeToEdgeComposeExtension()
+ private val listViewModel: SelectLocationListViewModel = mockk(relaxed = true)
+
@BeforeEach
fun setup() {
MockKAnnotations.init(this)
+ loadKoinModules(module { viewModel { listViewModel } })
+ every { listViewModel.uiState } returns MutableStateFlow(SelectLocationListUiState.Loading)
}
- @Test
- fun testDefaultState() =
- composeExtension.use {
- // Arrange
- setContentWithTheme { SelectLocationScreen(state = SelectLocationUiState.Loading) }
-
- // Assert
- onNodeWithTag(CIRCULAR_PROGRESS_INDICATOR).assertExists()
- }
+ @AfterEach
+ fun teardown() {
+ unmockkAll()
+ }
@Test
fun testShowRelayListState() =
composeExtension.use {
// Arrange
+ every { listViewModel.uiState } returns
+ MutableStateFlow(
+ SelectLocationListUiState.Content(
+ relayListItems =
+ DUMMY_RELAY_COUNTRIES.map { RelayListItem.GeoLocationItem(item = it) },
+ customLists = emptyList(),
+ )
+ )
setContentWithTheme {
SelectLocationScreen(
state =
- SelectLocationUiState.Content(
- searchTerm = "",
+ SelectLocationUiState(
+ // searchTerm = "",
filterChips = emptyList(),
- relayListItems =
- DUMMY_RELAY_COUNTRIES.map {
- RelayListItem.GeoLocationItem(item = it)
- },
- customLists = emptyList(),
+ multihopEnabled = false,
+ relayListType = RelayListType.EXIT,
)
)
}
@@ -72,97 +83,29 @@ class SelectLocationScreenTest {
}
@Test
- fun testSearchInput() =
- composeExtension.use {
- // Arrange
- val mockedSearchTermInput: (String) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- SelectLocationScreen(
- state =
- SelectLocationUiState.Content(
- searchTerm = "",
- filterChips = emptyList(),
- relayListItems = emptyList(),
- customLists = emptyList(),
- ),
- onSearchTermInput = mockedSearchTermInput,
- )
- }
- val mockSearchString = "SEARCH"
-
- // Act
- onNodeWithText("Search for...").performTextInput(mockSearchString)
-
- // Assert
- verify { mockedSearchTermInput.invoke(mockSearchString) }
- }
-
- @Test
- fun testSearchTermNotFound() =
- composeExtension.use {
- // Arrange
- val mockedSearchTermInput: (String) -> Unit = mockk(relaxed = true)
- val mockSearchString = "SEARCH"
- setContentWithTheme {
- SelectLocationScreen(
- state =
- SelectLocationUiState.Content(
- searchTerm = mockSearchString,
- filterChips = emptyList(),
- relayListItems =
- listOf(RelayListItem.LocationsEmptyText(mockSearchString)),
- customLists = emptyList(),
- ),
- onSearchTermInput = mockedSearchTermInput,
- )
- }
-
- // Assert
- onNodeWithText("No result for $mockSearchString.", substring = true).assertExists()
- onNodeWithText("Try a different search", substring = true).assertExists()
- }
-
- @Test
fun customListFooterShouldShowEmptyTextWhenNoCustomList() =
composeExtension.use {
// Arrange
- val mockSearchString = ""
- setContentWithTheme {
- SelectLocationScreen(
- state =
- SelectLocationUiState.Content(
- searchTerm = mockSearchString,
- filterChips = emptyList(),
- relayListItems = listOf(RelayListItem.CustomListFooter(false)),
- customLists = emptyList(),
- )
+ every { listViewModel.uiState } returns
+ MutableStateFlow(
+ SelectLocationListUiState.Content(
+ relayListItems = listOf(RelayListItem.CustomListFooter(false)),
+ customLists = emptyList(),
+ )
)
- }
-
- // Assert
- onNodeWithText(CUSTOM_LISTS_EMPTY_TEXT).assertExists()
- }
-
- @Test
- fun givenNoCustomListsAndSearchIsActiveShouldNotShowCustomListHeader() =
- composeExtension.use {
- // Arrange
- val mockSearchString = "SEARCH"
setContentWithTheme {
SelectLocationScreen(
state =
- SelectLocationUiState.Content(
- searchTerm = mockSearchString,
+ SelectLocationUiState(
filterChips = emptyList(),
- relayListItems = emptyList(),
- customLists = DUMMY_RELAY_ITEM_CUSTOM_LISTS,
+ multihopEnabled = false,
+ relayListType = RelayListType.EXIT,
)
)
}
// Assert
- onNodeWithText(CUSTOM_LISTS_EMPTY_TEXT).assertDoesNotExist()
- onNodeWithTag(SELECT_LOCATION_CUSTOM_LIST_HEADER_TEST_TAG).assertDoesNotExist()
+ onNodeWithText(CUSTOM_LISTS_EMPTY_TEXT).assertExists()
}
@Test
@@ -170,15 +113,21 @@ class SelectLocationScreenTest {
composeExtension.use {
// Arrange
val customList = DUMMY_RELAY_ITEM_CUSTOM_LISTS[0]
+ every { listViewModel.uiState } returns
+ MutableStateFlow(
+ SelectLocationListUiState.Content(
+ relayListItems = listOf(RelayListItem.CustomListItem(customList)),
+ customLists = DUMMY_RELAY_ITEM_CUSTOM_LISTS,
+ )
+ )
val mockedOnSelectRelay: (RelayItem) -> Unit = mockk(relaxed = true)
setContentWithTheme {
SelectLocationScreen(
state =
- SelectLocationUiState.Content(
- searchTerm = "",
+ SelectLocationUiState(
filterChips = emptyList(),
- relayListItems = listOf(RelayListItem.CustomListItem(customList)),
- customLists = DUMMY_RELAY_ITEM_CUSTOM_LISTS,
+ multihopEnabled = false,
+ relayListType = RelayListType.EXIT,
),
onSelectRelay = mockedOnSelectRelay,
)
@@ -196,16 +145,22 @@ class SelectLocationScreenTest {
composeExtension.use {
// Arrange
val customList = DUMMY_RELAY_ITEM_CUSTOM_LISTS[0]
+ every { listViewModel.uiState } returns
+ MutableStateFlow(
+ SelectLocationListUiState.Content(
+ relayListItems = listOf(RelayListItem.CustomListItem(item = customList)),
+ customLists = DUMMY_RELAY_ITEM_CUSTOM_LISTS,
+ )
+ )
val mockedOnSelectRelay: (RelayItem) -> Unit = mockk(relaxed = true)
setContentWithTheme {
SelectLocationScreen(
state =
- SelectLocationUiState.Content(
- searchTerm = "",
+ SelectLocationUiState(
+ // searchTerm = "",
filterChips = emptyList(),
- relayListItems =
- listOf(RelayListItem.CustomListItem(item = customList)),
- customLists = DUMMY_RELAY_ITEM_CUSTOM_LISTS,
+ multihopEnabled = false,
+ relayListType = RelayListType.EXIT,
),
onSelectRelay = mockedOnSelectRelay,
)
@@ -223,15 +178,21 @@ class SelectLocationScreenTest {
composeExtension.use {
// Arrange
val relayItem = DUMMY_RELAY_COUNTRIES[0]
+ every { listViewModel.uiState } returns
+ MutableStateFlow(
+ SelectLocationListUiState.Content(
+ relayListItems = listOf(RelayListItem.GeoLocationItem(relayItem)),
+ customLists = emptyList(),
+ )
+ )
val mockedOnSelectRelay: (RelayItem) -> Unit = mockk(relaxed = true)
setContentWithTheme {
SelectLocationScreen(
state =
- SelectLocationUiState.Content(
- searchTerm = "",
+ SelectLocationUiState(
filterChips = emptyList(),
- relayListItems = listOf(RelayListItem.GeoLocationItem(relayItem)),
- customLists = emptyList(),
+ multihopEnabled = false,
+ relayListType = RelayListType.EXIT,
),
onSelectRelay = mockedOnSelectRelay,
)