summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
authorDavid Göransson <david.goransson@mullvad.net>2024-12-10 10:58:54 +0100
committerDavid Göransson <david.goransson@mullvad.net>2024-12-13 11:39:03 +0100
commit90174b2518dc15edcb1b1fe28392d6ad4fe34f89 (patch)
tree8ba79f4c7fde88f2996cb1cfdc24f76eb2254a48 /android
parentd1f2a58c6151527e6b29d3497728ff2913140291 (diff)
downloadmullvadvpn-90174b2518dc15edcb1b1fe28392d6ad4fe34f89.tar.xz
mullvadvpn-90174b2518dc15edcb1b1fe28392d6ad4fe34f89.zip
Remove bad default arguments
Diffstat (limited to 'android')
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/ChangelogDialogTest.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ChangelogDialogTest.kt)17
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialogTest.kt39
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/CustomPortDialogTest.kt83
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialogTest.kt38
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialogTest.kt57
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialogTest.kt39
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/MtuDialogTest.kt56
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/PaymentDialogTest.kt44
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialogTest.kt (renamed from android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/RedeemVoucherDialogTest.kt)86
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/ResetServerIPOverridesConfirmationDialogTest.kt31
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/SaveApiAccessMethodDialogTest.kt95
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/AccountScreenTest.kt234
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessListScreenTest.kt60
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessMethodDetailsScreenTest.kt177
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreenTest.kt593
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreenTest.kt175
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreenTest.kt55
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreenTest.kt23
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/EditApiAccessMethodScreenTest.kt292
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreenTest.kt120
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/FilterScreenTest.kt139
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreenTest.kt234
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ServerIpOverridesScreenTest.kt83
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreenTest.kt75
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ShadowsocksSettingsScreenTest.kt39
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreenTest.kt134
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/Udp2TcpSettingsScreenTest.kt27
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt390
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreenTest.kt259
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreenTest.kt98
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreenTest.kt149
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/CustomPortCell.kt20
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/DropdownMenuCell.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/ExpandableComposeCell.kt2
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/ObfuscationModeCell.kt2
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/RelayLocationCell.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/SplitTunnelingCell.kt8
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/SwitchComposeCell.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ChangelogDialog.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialog.kt13
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialog.kt8
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialog.kt8
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/NegativeConfirmationDialog.kt17
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialog.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/SaveApiAccessMethodDialog.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/payment/PaymentDialog.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AccountScreen.kt18
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessListScreen.kt10
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessMethodDetailsScreen.kt20
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AutoConnectAndLockdownModeScreen.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt39
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreen.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreen.kt10
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt18
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreen.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditApiAccessMethodScreen.kt40
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreen.kt10
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/FilterScreen.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ImportOverridesByTextScreen.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoginScreen.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MultihopScreen.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt18
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ReportProblemScreen.kt14
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt19
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ShadowsocksSettingsScreen.kt11
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt14
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/Udp2TcpSettingsScreen.kt10
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt69
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreen.kt52
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreen.kt58
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/util/Snackbar.kt8
74 files changed, 2370 insertions, 2196 deletions
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ChangelogDialogTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/ChangelogDialogTest.kt
index b8165f80fc..b811209d1c 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ChangelogDialogTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/ChangelogDialogTest.kt
@@ -1,12 +1,12 @@
-package net.mullvad.mullvadvpn.compose.screen
+package net.mullvad.mullvadvpn.compose.dialog
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
+import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.impl.annotations.MockK
import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
-import net.mullvad.mullvadvpn.compose.dialog.ChangelogDialog
import net.mullvad.mullvadvpn.compose.setContentWithTheme
import net.mullvad.mullvadvpn.viewmodel.AppInfoViewModel
import net.mullvad.mullvadvpn.viewmodel.ChangelogUiState
@@ -25,16 +25,19 @@ class ChangelogDialogTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initDialog(state: ChangelogUiState, onDismiss: () -> Unit = {}) {
+ setContentWithTheme { ChangelogDialog(state = state, onDismiss = onDismiss) }
+ }
+
@Test
fun testShowChangeLogWhenNeeded() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- ChangelogDialog(
+ initDialog(
+ state =
ChangelogUiState(changes = listOf(CHANGELOG_ITEM), version = CHANGELOG_VERSION),
- onDismiss = {},
- )
- }
+ onDismiss = {},
+ )
// Check changelog content showed within dialog
onNodeWithText(CHANGELOG_ITEM).assertExists()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialogTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialogTest.kt
index 915db82438..83dd0c3fdb 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialogTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialogTest.kt
@@ -5,6 +5,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
@@ -30,12 +31,28 @@ class CreateCustomListDialogTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initDialog(
+ state: CreateCustomListUiState = CreateCustomListUiState(),
+ createCustomList: (String) -> Unit = {},
+ onInputChanged: () -> Unit = {},
+ onDismiss: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ CreateCustomListDialog(
+ state = state,
+ createCustomList = createCustomList,
+ onInputChanged = onInputChanged,
+ onDismiss = onDismiss,
+ )
+ }
+ }
+
@Test
fun givenNoErrorShouldShowNoErrorMessage() =
composeExtension.use {
// Arrange
val state = CreateCustomListUiState(error = null)
- setContentWithTheme { CreateCustomListDialog(state = state) }
+ initDialog(state)
// Assert
onNodeWithText(NAME_EXIST_ERROR_TEXT).assertDoesNotExist()
@@ -50,7 +67,7 @@ class CreateCustomListDialogTest {
CreateCustomListUiState(
error = CreateWithLocationsError.Create(CustomListAlreadyExists)
)
- setContentWithTheme { CreateCustomListDialog(state = state) }
+ initDialog(state)
// Assert
onNodeWithText(NAME_EXIST_ERROR_TEXT).assertExists()
@@ -65,7 +82,7 @@ class CreateCustomListDialogTest {
CreateCustomListUiState(
error = CreateWithLocationsError.Create(UnknownCustomListError(Throwable()))
)
- setContentWithTheme { CreateCustomListDialog(state = state) }
+ initDialog(state)
// Assert
onNodeWithText(NAME_EXIST_ERROR_TEXT).assertDoesNotExist()
@@ -78,9 +95,7 @@ class CreateCustomListDialogTest {
// Arrange
val mockedOnDismiss: () -> Unit = mockk(relaxed = true)
val state = CreateCustomListUiState()
- setContentWithTheme {
- CreateCustomListDialog(state = state, onDismiss = mockedOnDismiss)
- }
+ initDialog(state, onDismiss = mockedOnDismiss)
// Act
onNodeWithText(CANCEL_BUTTON_TEXT).performClick()
@@ -95,9 +110,7 @@ class CreateCustomListDialogTest {
// Arrange
val mockedCreateCustomList: (String) -> Unit = mockk(relaxed = true)
val state = CreateCustomListUiState()
- setContentWithTheme {
- CreateCustomListDialog(state = state, createCustomList = mockedCreateCustomList)
- }
+ initDialog(state, createCustomList = mockedCreateCustomList)
// Act
onNodeWithText(CREATE_BUTTON_TEXT).performClick()
@@ -113,9 +126,7 @@ class CreateCustomListDialogTest {
val mockedCreateCustomList: (String) -> Unit = mockk(relaxed = true)
val inputText = "NEW LIST"
val state = CreateCustomListUiState()
- setContentWithTheme {
- CreateCustomListDialog(state = state, createCustomList = mockedCreateCustomList)
- }
+ initDialog(state, createCustomList = mockedCreateCustomList)
// Act
onNodeWithTag(CREATE_CUSTOM_LIST_DIALOG_INPUT_TEST_TAG).performTextInput(inputText)
@@ -132,9 +143,7 @@ class CreateCustomListDialogTest {
val mockedOnInputChanged: () -> Unit = mockk(relaxed = true)
val inputText = "NEW LIST"
val state = CreateCustomListUiState()
- setContentWithTheme {
- CreateCustomListDialog(state = state, onInputChanged = mockedOnInputChanged)
- }
+ initDialog(state, onInputChanged = mockedOnInputChanged)
// Act
onNodeWithTag(CREATE_CUSTOM_LIST_DIALOG_INPUT_TEST_TAG).performTextInput(inputText)
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/CustomPortDialogTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/CustomPortDialogTest.kt
index 7ca4d7f3d4..075c6cc360 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/CustomPortDialogTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/CustomPortDialogTest.kt
@@ -1,7 +1,5 @@
package net.mullvad.mullvadvpn.compose.dialog
-import android.annotation.SuppressLint
-import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -13,6 +11,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
@@ -36,30 +35,30 @@ class CustomPortDialogTest {
MockKAnnotations.init(this)
}
- @SuppressLint("ComposableNaming")
- @Composable
- private fun testWireguardCustomPortDialog(
+ private fun ComposeContext.initDialog(
title: String = "",
portInput: String = "",
isValidInput: Boolean = false,
- showResetToDefault: Boolean = false,
allowedPortRanges: List<PortRange> = emptyList(),
+ showResetToDefault: Boolean = false,
onInputChanged: (String) -> Unit = { _ -> },
onSavePort: (String) -> Unit = { _ -> },
onResetPort: () -> Unit = {},
onDismiss: () -> Unit = {},
) {
- CustomPortDialog(
- title = title,
- portInput = portInput,
- isValidInput = isValidInput,
- showResetToDefault = showResetToDefault,
- allowedPortRanges = allowedPortRanges,
- onInputChanged = onInputChanged,
- onSavePort = onSavePort,
- onDismiss = onDismiss,
- onResetPort = onResetPort,
- )
+ setContentWithTheme {
+ CustomPortDialog(
+ title = title,
+ portInput = portInput,
+ isValidInput = isValidInput,
+ allowedPortRanges = allowedPortRanges,
+ showResetToDefault = showResetToDefault,
+ onInputChanged = onInputChanged,
+ onSavePort = onSavePort,
+ onDismiss = onDismiss,
+ onResetPort = onResetPort,
+ )
+ }
}
@Test
@@ -71,7 +70,17 @@ class CustomPortDialogTest {
// Arrange
setContentWithTheme {
var input by remember { mutableStateOf("") }
- testWireguardCustomPortDialog(portInput = input, onInputChanged = { input = it })
+ CustomPortDialog(
+ title = "",
+ portInput = input,
+ isValidInput = false,
+ allowedPortRanges = emptyList(),
+ showResetToDefault = false,
+ onInputChanged = { input = it },
+ onSavePort = {},
+ onDismiss = {},
+ onResetPort = {},
+ )
}
// Act
@@ -86,7 +95,7 @@ class CustomPortDialogTest {
fun testEmptyInputResultsInSetPortButtonBeingDisabled() =
composeExtension.use {
// Arrange
- setContentWithTheme { testWireguardCustomPortDialog(isValidInput = false) }
+ initDialog(isValidInput = false)
// Assert
onNodeWithText("Set port").assertIsNotEnabled()
@@ -96,9 +105,7 @@ class CustomPortDialogTest {
fun testValidInputResultsInSetPortButtonBeingEnabled() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- testWireguardCustomPortDialog(portInput = VALID_CUSTOM_PORT, isValidInput = true)
- }
+ initDialog(portInput = VALID_CUSTOM_PORT, isValidInput = true)
// Assert
onNodeWithText("Set port").assertIsEnabled()
@@ -109,9 +116,7 @@ class CustomPortDialogTest {
fun testInvalidInputResultsInSetPortButtonBeingDisabled() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- testWireguardCustomPortDialog(portInput = INVALID_CUSTOM_PORT, isValidInput = false)
- }
+ initDialog(portInput = INVALID_CUSTOM_PORT, isValidInput = false)
// Assert
onNodeWithText("Set port").assertIsNotEnabled()
@@ -122,13 +127,11 @@ class CustomPortDialogTest {
composeExtension.use {
// Arrange
val mockedSubmitHandler: (String) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- testWireguardCustomPortDialog(
- portInput = VALID_CUSTOM_PORT,
- isValidInput = true,
- onSavePort = mockedSubmitHandler,
- )
- }
+ initDialog(
+ portInput = VALID_CUSTOM_PORT,
+ isValidInput = true,
+ onSavePort = mockedSubmitHandler,
+ )
// Act
onNodeWithText("Set port").assertIsEnabled().performClick()
@@ -142,14 +145,12 @@ class CustomPortDialogTest {
composeExtension.use {
// Arrange
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- testWireguardCustomPortDialog(
- portInput = VALID_CUSTOM_PORT,
- isValidInput = true,
- showResetToDefault = true,
- onResetPort = mockedClickHandler,
- )
- }
+ initDialog(
+ portInput = VALID_CUSTOM_PORT,
+ isValidInput = true,
+ showResetToDefault = true,
+ onResetPort = mockedClickHandler,
+ )
// Act
onNodeWithText("Remove custom port").performClick()
@@ -163,7 +164,7 @@ class CustomPortDialogTest {
composeExtension.use {
// Arrange
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme { testWireguardCustomPortDialog(onDismiss = mockedClickHandler) }
+ initDialog(onDismiss = mockedClickHandler)
// Assert
onNodeWithText("Cancel").performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialogTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialogTest.kt
index abe7abfbcf..6749e620a5 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialogTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialogTest.kt
@@ -3,6 +3,7 @@ package net.mullvad.mullvadvpn.compose.dialog
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
+import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
@@ -25,16 +26,23 @@ class DeleteCustomListConfirmationDialogTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initDialog(
+ state: DeleteCustomListUiState =
+ DeleteCustomListUiState(CustomListName.fromString("My Custom List"), null),
+ onDelete: () -> Unit = {},
+ onBack: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ DeleteCustomListConfirmationDialog(state = state, onDelete = onDelete, onBack = onBack)
+ }
+ }
+
@Test
fun givenNameShouldShowDeleteNameTitle() =
composeExtension.use {
// Arrange
val name = CustomListName.fromString("List should be deleted")
- setContentWithTheme {
- DeleteCustomListConfirmationDialog(
- state = DeleteCustomListUiState(name = name, deleteError = null)
- )
- }
+ initDialog(state = DeleteCustomListUiState(name = name, deleteError = null))
// Assert
onNodeWithText(DELETE_TITLE.format(name)).assertExists()
@@ -46,12 +54,10 @@ class DeleteCustomListConfirmationDialogTest {
// Arrange
val name = CustomListName.fromString("List should be deleted")
val mockedOnDelete: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- DeleteCustomListConfirmationDialog(
- state = DeleteCustomListUiState(name = name, deleteError = null),
- onDelete = mockedOnDelete,
- )
- }
+ initDialog(
+ state = DeleteCustomListUiState(name = name, deleteError = null),
+ onDelete = mockedOnDelete,
+ )
// Act
onNodeWithText(DELETE_BUTTON_TEXT).performClick()
@@ -66,12 +72,10 @@ class DeleteCustomListConfirmationDialogTest {
// Arrange
val name = CustomListName.fromString("List should be deleted")
val mockedOnBack: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- DeleteCustomListConfirmationDialog(
- state = DeleteCustomListUiState(name = name, deleteError = null),
- onBack = mockedOnBack,
- )
- }
+ initDialog(
+ state = DeleteCustomListUiState(name = name, deleteError = null),
+ onBack = mockedOnBack,
+ )
// Act
onNodeWithText(CANCEL_BUTTON_TEXT).performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialogTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialogTest.kt
index faafce1137..56bdc562fd 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialogTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialogTest.kt
@@ -1,10 +1,9 @@
package net.mullvad.mullvadvpn.compose.dialog
-import android.annotation.SuppressLint
-import androidx.compose.runtime.Composable
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.assertIsNotEnabled
import androidx.compose.ui.test.onNodeWithText
+import de.mannodermaus.junit5.compose.ComposeContext
import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
import net.mullvad.mullvadvpn.compose.setContentWithTheme
import net.mullvad.mullvadvpn.viewmodel.DnsDialogViewState
@@ -27,25 +26,29 @@ class DnsDialogTest {
index = null,
)
- @SuppressLint("ComposableNaming")
- @Composable
- private fun testDnsDialog(
+ private fun ComposeContext.initDialog(
state: DnsDialogViewState = defaultState,
onDnsInputChange: (String) -> Unit = { _ -> },
onSaveDnsClick: () -> Unit = {},
onRemoveDnsClick: (Int) -> Unit = {},
onDismiss: () -> Unit = {},
) {
- DnsDialog(state, onDnsInputChange, onSaveDnsClick, onRemoveDnsClick, onDismiss)
+ setContentWithTheme {
+ DnsDialog(
+ state = state,
+ onDnsInputChange = onDnsInputChange,
+ onSaveDnsClick = onSaveDnsClick,
+ onRemoveDnsClick = onRemoveDnsClick,
+ onDismiss = onDismiss,
+ )
+ }
}
@Test
fun testDnsDialogLanWarningShownWhenLanTrafficDisabledAndLocalAddressUsed() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- testDnsDialog(defaultState.copy(isAllowLanEnabled = false, isLocal = true))
- }
+ initDialog(defaultState.copy(isAllowLanEnabled = false, isLocal = true))
// Assert
onNodeWithText(LOCAL_DNS_SERVER_WARNING).assertExists()
@@ -55,9 +58,7 @@ class DnsDialogTest {
fun testDnsDialogLanWarningNotShownWhenLanTrafficEnabledAndLocalAddressUsed() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- testDnsDialog(defaultState.copy(isAllowLanEnabled = true, isLocal = true))
- }
+ initDialog(defaultState.copy(isAllowLanEnabled = true, isLocal = true))
// Assert
onNodeWithText(LOCAL_DNS_SERVER_WARNING).assertDoesNotExist()
@@ -67,9 +68,7 @@ class DnsDialogTest {
fun testDnsDialogLanWarningNotShownWhenLanTrafficEnabledAndNonLocalAddressUsed() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- testDnsDialog(defaultState.copy(isAllowLanEnabled = true, isLocal = false))
- }
+ initDialog(defaultState.copy(isAllowLanEnabled = true, isLocal = false))
// Assert
onNodeWithText(LOCAL_DNS_SERVER_WARNING).assertDoesNotExist()
@@ -79,9 +78,7 @@ class DnsDialogTest {
fun testDnsDialogLanWarningNotShownWhenLanTrafficDisabledAndNonLocalAddressUsed() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- testDnsDialog(defaultState.copy(isAllowLanEnabled = false, isLocal = false))
- }
+ initDialog(defaultState.copy(isAllowLanEnabled = false, isLocal = false))
// Assert
onNodeWithText(LOCAL_DNS_SERVER_WARNING).assertDoesNotExist()
@@ -91,14 +88,12 @@ class DnsDialogTest {
fun testDnsDialogSubmitButtonDisabledOnInvalidDnsAddress() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- testDnsDialog(
- defaultState.copy(
- input = invalidIpAddress,
- validationError = ValidationError.InvalidAddress,
- )
+ initDialog(
+ defaultState.copy(
+ input = invalidIpAddress,
+ validationError = ValidationError.InvalidAddress,
)
- }
+ )
// Assert
onNodeWithText("Submit").assertIsNotEnabled()
@@ -108,14 +103,12 @@ class DnsDialogTest {
fun testDnsDialogSubmitButtonDisabledOnDuplicateDnsAddress() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- testDnsDialog(
- defaultState.copy(
- input = "192.168.0.1",
- validationError = ValidationError.DuplicateAddress,
- )
+ initDialog(
+ defaultState.copy(
+ input = "192.168.0.1",
+ validationError = ValidationError.DuplicateAddress,
)
- }
+ )
// Assert
onNodeWithText("Submit").assertIsNotEnabled()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialogTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialogTest.kt
index d43a862037..a939b72ccf 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialogTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialogTest.kt
@@ -5,6 +5,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
@@ -31,12 +32,28 @@ class EditCustomListNameDialogTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initDialog(
+ state: EditCustomListNameUiState = EditCustomListNameUiState(),
+ updateName: (String) -> Unit = {},
+ onInputChanged: (String) -> Unit = {},
+ onDismiss: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ EditCustomListNameDialog(
+ state = state,
+ updateName = updateName,
+ onInputChanged = onInputChanged,
+ onDismiss = onDismiss,
+ )
+ }
+ }
+
@Test
fun givenNoErrorShouldShowNoErrorMessage() =
composeExtension.use {
// Arrange
val state = EditCustomListNameUiState(error = null)
- setContentWithTheme { EditCustomListNameDialog(state = state) }
+ initDialog(state = state)
// Assert
onNodeWithText(NAME_EXIST_ERROR_TEXT).assertDoesNotExist()
@@ -51,7 +68,7 @@ class EditCustomListNameDialogTest {
EditCustomListNameUiState(
error = RenameError(NameAlreadyExists(CustomListName.fromString("name")))
)
- setContentWithTheme { EditCustomListNameDialog(state = state) }
+ initDialog(state = state)
// Assert
onNodeWithText(NAME_EXIST_ERROR_TEXT).assertExists()
@@ -66,7 +83,7 @@ class EditCustomListNameDialogTest {
EditCustomListNameUiState(
error = RenameError(UnknownCustomListError(RuntimeException("")))
)
- setContentWithTheme { EditCustomListNameDialog(state = state) }
+ initDialog(state = state)
// Assert
onNodeWithText(NAME_EXIST_ERROR_TEXT).assertDoesNotExist()
@@ -79,9 +96,7 @@ class EditCustomListNameDialogTest {
// Arrange
val mockedOnDismiss: () -> Unit = mockk(relaxed = true)
val state = EditCustomListNameUiState()
- setContentWithTheme {
- EditCustomListNameDialog(state = state, onDismiss = mockedOnDismiss)
- }
+ initDialog(state = state, onDismiss = mockedOnDismiss)
// Act
onNodeWithText(CANCEL_BUTTON_TEXT).performClick()
@@ -96,9 +111,7 @@ class EditCustomListNameDialogTest {
// Arrange
val mockedUpdateName: (String) -> Unit = mockk(relaxed = true)
val state = EditCustomListNameUiState()
- setContentWithTheme {
- EditCustomListNameDialog(state = state, updateName = mockedUpdateName)
- }
+ initDialog(state = state, updateName = mockedUpdateName)
// Act
onNodeWithText(SAVE_BUTTON_TEXT).performClick()
@@ -114,9 +127,7 @@ class EditCustomListNameDialogTest {
val mockedUpdateName: (String) -> Unit = mockk(relaxed = true)
val inputText = "NEW NAME"
val state = EditCustomListNameUiState(name = inputText)
- setContentWithTheme {
- EditCustomListNameDialog(state = state, updateName = mockedUpdateName)
- }
+ initDialog(state, updateName = mockedUpdateName)
// Act
onNodeWithText(SAVE_BUTTON_TEXT).performClick()
@@ -132,9 +143,7 @@ class EditCustomListNameDialogTest {
val mockedOnInputChanged: (String) -> Unit = mockk(relaxed = true)
val inputText = "NEW NAME"
val state = EditCustomListNameUiState()
- setContentWithTheme {
- EditCustomListNameDialog(state = state, onInputChanged = mockedOnInputChanged)
- }
+ initDialog(state, onInputChanged = mockedOnInputChanged)
// Act
onNodeWithTag(EDIT_CUSTOM_LIST_DIALOG_INPUT_TEST_TAG).performTextInput(inputText)
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/MtuDialogTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/MtuDialogTest.kt
index 9d6b09fe2d..052c7846d9 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/MtuDialogTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/MtuDialogTest.kt
@@ -1,12 +1,11 @@
package net.mullvad.mullvadvpn.compose.dialog
-import android.annotation.SuppressLint
-import androidx.compose.runtime.Composable
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.assertIsEnabled
import androidx.compose.ui.test.assertIsNotEnabled
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
+import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
@@ -28,31 +27,32 @@ class MtuDialogTest {
MockKAnnotations.init(this)
}
- @SuppressLint("ComposableNaming")
- @Composable
- private fun testMtuDialog(
- mtuInput: String = "",
- isValidInput: Boolean = true,
- showResetButton: Boolean = true,
- onInputChanged: (String) -> Unit = { _ -> },
- onSaveMtu: (String) -> Unit = { _ -> },
+ private val defaultState =
+ MtuDialogUiState(mtuInput = "", isValidInput = true, showResetToDefault = true)
+
+ private fun ComposeContext.initDialog(
+ state: MtuDialogUiState = defaultState,
+ onInputChanged: (String) -> Unit = {},
+ onSaveMtu: (String) -> Unit = {},
onResetMtu: () -> Unit = {},
onDismiss: () -> Unit = {},
) {
- MtuDialog(
- MtuDialogUiState(mtuInput, isValidInput, showResetButton),
- onInputChanged = onInputChanged,
- onSaveMtu = onSaveMtu,
- onResetMtu = onResetMtu,
- onDismiss = onDismiss,
- )
+ setContentWithTheme {
+ MtuDialog(
+ state = state,
+ onInputChanged = onInputChanged,
+ onSaveMtu = onSaveMtu,
+ onResetMtu = onResetMtu,
+ onDismiss = onDismiss,
+ )
+ }
}
@Test
fun testMtuDialogWithDefaultValue() =
composeExtension.use {
// Arrange
- setContentWithTheme { testMtuDialog() }
+ initDialog()
// Assert
onNodeWithText(EMPTY_STRING).assertExists()
@@ -62,7 +62,7 @@ class MtuDialogTest {
fun testMtuDialogWithEditValue() =
composeExtension.use {
// Arrange
- setContentWithTheme { testMtuDialog(mtuInput = VALID_DUMMY_MTU_VALUE) }
+ initDialog(defaultState.copy(mtuInput = VALID_DUMMY_MTU_VALUE))
// Assert
onNodeWithText(VALID_DUMMY_MTU_VALUE).assertExists()
@@ -73,9 +73,10 @@ class MtuDialogTest {
composeExtension.use {
// Arrange
val mockedSubmitHandler: (String) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- testMtuDialog(VALID_DUMMY_MTU_VALUE, onSaveMtu = mockedSubmitHandler)
- }
+ initDialog(
+ defaultState.copy(mtuInput = VALID_DUMMY_MTU_VALUE),
+ onSaveMtu = mockedSubmitHandler,
+ )
// Act
onNodeWithText("Submit").assertIsEnabled().performClick()
@@ -88,7 +89,7 @@ class MtuDialogTest {
fun testMtuDialogSubmitButtonDisabledWhenInvalidInput() =
composeExtension.use {
// Arrange
- setContentWithTheme { testMtuDialog(INVALID_DUMMY_MTU_VALUE, false) }
+ initDialog(defaultState.copy(mtuInput = INVALID_DUMMY_MTU_VALUE, isValidInput = false))
// Assert
onNodeWithText("Submit").assertIsNotEnabled()
@@ -99,9 +100,10 @@ class MtuDialogTest {
composeExtension.use {
// Arrange
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- testMtuDialog(mtuInput = VALID_DUMMY_MTU_VALUE, onResetMtu = mockedClickHandler)
- }
+ initDialog(
+ defaultState.copy(mtuInput = VALID_DUMMY_MTU_VALUE),
+ onResetMtu = mockedClickHandler,
+ )
// Act
onNodeWithText("Reset to default").performClick()
@@ -115,7 +117,7 @@ class MtuDialogTest {
composeExtension.use {
// Arrange
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme { testMtuDialog(onDismiss = mockedClickHandler) }
+ initDialog(onDismiss = mockedClickHandler)
// Assert
onNodeWithText("Cancel").performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/PaymentDialogTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/PaymentDialogTest.kt
index 3a77a5620a..09a5e9dd72 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/PaymentDialogTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/PaymentDialogTest.kt
@@ -2,8 +2,10 @@ package net.mullvad.mullvadvpn.compose.dialog
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithText
+import de.mannodermaus.junit5.compose.ComposeContext
import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
import net.mullvad.mullvadvpn.compose.dialog.payment.PaymentDialog
+import net.mullvad.mullvadvpn.compose.dialog.payment.PaymentDialogData
import net.mullvad.mullvadvpn.compose.setContentWithTheme
import net.mullvad.mullvadvpn.lib.payment.model.ProductId
import net.mullvad.mullvadvpn.lib.payment.model.PurchaseResult
@@ -17,15 +19,25 @@ class PaymentDialogTest {
@RegisterExtension
val composeExtension = createEdgeToEdgeComposeExtension()
+ private fun ComposeContext.initDialog(
+ paymentDialogData: PaymentDialogData,
+ retryPurchase: (ProductId) -> Unit = {},
+ onCloseDialog: (isPaymentSuccessful: Boolean) -> Unit = {},
+ ) {
+ setContentWithTheme {
+ PaymentDialog(
+ paymentDialogData = paymentDialogData,
+ retryPurchase = retryPurchase,
+ onCloseDialog = onCloseDialog,
+ )
+ }
+ }
+
@Test
fun testShowPurchaseCompleteDialog() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- PaymentDialog(
- paymentDialogData = PurchaseResult.Completed.Success.toPaymentDialogData()!!
- )
- }
+ initDialog(paymentDialogData = PurchaseResult.Completed.Success.toPaymentDialogData()!!)
// Assert
onNodeWithText("Time was successfully added").assertExists()
@@ -35,12 +47,10 @@ class PaymentDialogTest {
fun testShowVerificationErrorDialog() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- PaymentDialog(
- paymentDialogData =
- PurchaseResult.Error.VerificationError(null).toPaymentDialogData()!!
- )
- }
+ initDialog(
+ paymentDialogData =
+ PurchaseResult.Error.VerificationError(null).toPaymentDialogData()!!
+ )
// Assert
onNodeWithText("Verifying purchase").assertExists()
@@ -50,13 +60,11 @@ class PaymentDialogTest {
fun testShowFetchProductsErrorDialog() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- PaymentDialog(
- paymentDialogData =
- PurchaseResult.Error.FetchProductsError(ProductId(""), null)
- .toPaymentDialogData()!!
- )
- }
+ initDialog(
+ paymentDialogData =
+ PurchaseResult.Error.FetchProductsError(ProductId(""), null)
+ .toPaymentDialogData()!!
+ )
// Assert
onNodeWithText("Google Play unavailable").assertExists()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/RedeemVoucherDialogTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialogTest.kt
index 10e7af7923..b87b43e3c6 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/RedeemVoucherDialogTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialogTest.kt
@@ -1,15 +1,15 @@
-package net.mullvad.mullvadvpn.compose.screen
+package net.mullvad.mullvadvpn.compose.dialog
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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.mockk
import io.mockk.mockkObject
import io.mockk.verify
import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
-import net.mullvad.mullvadvpn.compose.dialog.RedeemVoucherDialog
import net.mullvad.mullvadvpn.compose.setContentWithTheme
import net.mullvad.mullvadvpn.compose.state.VoucherDialogState
import net.mullvad.mullvadvpn.compose.state.VoucherDialogUiState
@@ -29,19 +29,28 @@ class RedeemVoucherDialogTest {
mockkObject(VoucherRegexHelper)
}
+ private fun ComposeContext.initDialog(
+ state: VoucherDialogUiState = VoucherDialogUiState.INITIAL,
+ onVoucherInputChange: (String) -> Unit = {},
+ onRedeem: (voucherCode: String) -> Unit = {},
+ onDismiss: (isTimeAdded: Boolean) -> Unit = {},
+ ) {
+ setContentWithTheme {
+ RedeemVoucherDialog(
+ state = state,
+ onVoucherInputChange = onVoucherInputChange,
+ onRedeem = onRedeem,
+ onDismiss = onDismiss,
+ )
+ }
+ }
+
@Test
fun testDismissDialog() =
composeExtension.use {
// Arrange
val mockedClickHandler: (Boolean) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- RedeemVoucherDialog(
- state = VoucherDialogUiState.INITIAL,
- onVoucherInputChange = {},
- onRedeem = {},
- onDismiss = mockedClickHandler,
- )
- }
+ initDialog(onDismiss = mockedClickHandler)
// Act
onNodeWithText(CANCEL_BUTTON_TEXT).performClick()
@@ -55,14 +64,10 @@ class RedeemVoucherDialogTest {
composeExtension.use {
// Arrange
val mockedClickHandler: (Boolean) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- RedeemVoucherDialog(
- state = VoucherDialogUiState(voucherState = VoucherDialogState.Success(0)),
- onVoucherInputChange = {},
- onRedeem = {},
- onDismiss = mockedClickHandler,
- )
- }
+ initDialog(
+ state = VoucherDialogUiState(voucherState = VoucherDialogState.Success(0)),
+ onDismiss = mockedClickHandler,
+ )
// Act
onNodeWithText(GOT_IT_BUTTON_TEXT).performClick()
@@ -76,14 +81,7 @@ class RedeemVoucherDialogTest {
composeExtension.use {
// Arrange
val mockedClickHandler: (String) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- RedeemVoucherDialog(
- state = VoucherDialogUiState(),
- onVoucherInputChange = mockedClickHandler,
- onRedeem = {},
- onDismiss = {},
- )
- }
+ initDialog(state = VoucherDialogUiState(), onVoucherInputChange = mockedClickHandler)
// Act
onNodeWithTag(VOUCHER_INPUT_TEST_TAG).performTextInput(DUMMY_VOUCHER)
@@ -96,14 +94,7 @@ class RedeemVoucherDialogTest {
fun testVerifyingState() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- RedeemVoucherDialog(
- state = VoucherDialogUiState(voucherState = VoucherDialogState.Verifying),
- onVoucherInputChange = {},
- onRedeem = {},
- onDismiss = {},
- )
- }
+ initDialog(state = VoucherDialogUiState(voucherState = VoucherDialogState.Verifying))
// Assert
onNodeWithText("Verifying voucher…").assertExists()
@@ -113,14 +104,7 @@ class RedeemVoucherDialogTest {
fun testSuccessState() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- RedeemVoucherDialog(
- state = VoucherDialogUiState(voucherState = VoucherDialogState.Success(0)),
- onVoucherInputChange = {},
- onRedeem = {},
- onDismiss = {},
- )
- }
+ initDialog(state = VoucherDialogUiState(voucherState = VoucherDialogState.Success(0)))
// Assert
onNodeWithText("Voucher was successfully redeemed.").assertExists()
@@ -130,18 +114,12 @@ class RedeemVoucherDialogTest {
fun testErrorState() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- RedeemVoucherDialog(
- state =
- VoucherDialogUiState(
- voucherState =
- VoucherDialogState.Error(RedeemVoucherError.InvalidVoucher)
- ),
- onVoucherInputChange = {},
- onRedeem = {},
- onDismiss = {},
- )
- }
+ initDialog(
+ state =
+ VoucherDialogUiState(
+ voucherState = VoucherDialogState.Error(RedeemVoucherError.InvalidVoucher)
+ )
+ )
// Assert
onNodeWithText(VOUCHER_CODE_INVALID_ERROR_MESSAGE).assertExists()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/ResetServerIPOverridesConfirmationDialogTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/ResetServerIPOverridesConfirmationDialogTest.kt
index 107c03f1d6..818cec27f3 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/ResetServerIPOverridesConfirmationDialogTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/ResetServerIPOverridesConfirmationDialogTest.kt
@@ -3,6 +3,7 @@ package net.mullvad.mullvadvpn.compose.dialog
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
+import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
@@ -25,18 +26,25 @@ class ResetServerIPOverridesConfirmationDialogTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initDialog(
+ onClearAllOverrides: () -> Unit = {},
+ onNavigateBack: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ ResetServerIpOverridesConfirmationDialog(
+ onClearAllOverrides = onClearAllOverrides,
+ onNavigateBack = onNavigateBack,
+ )
+ }
+ }
+
@Test
- fun ensure_cancel_click_works() =
+ fun ensureCancelClickWorks() =
composeExtension.use {
val clickHandler: () -> Unit = mockk(relaxed = true)
// Arrange
- setContentWithTheme {
- ResetServerIpOverridesConfirmationDialog(
- onNavigateBack = clickHandler,
- onClearAllOverrides = {},
- )
- }
+ initDialog(onNavigateBack = clickHandler)
// Act
onNodeWithTag(RESET_SERVER_IP_OVERRIDE_CANCEL_TEST_TAG).performClick()
@@ -46,17 +54,12 @@ class ResetServerIPOverridesConfirmationDialogTest {
}
@Test
- fun ensure_reset_click_works() =
+ fun ensureResetClickWorks() =
composeExtension.use {
val clickHandler: () -> Unit = mockk(relaxed = true)
// Arrange
- setContentWithTheme {
- ResetServerIpOverridesConfirmationDialog(
- onNavigateBack = {},
- onClearAllOverrides = clickHandler,
- )
- }
+ initDialog(onClearAllOverrides = clickHandler)
// Act
onNodeWithTag(RESET_SERVER_IP_OVERRIDE_RESET_TEST_TAG).performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/SaveApiAccessMethodDialogTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/SaveApiAccessMethodDialogTest.kt
index afd6d0e15d..a9ad169b01 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/SaveApiAccessMethodDialogTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/dialog/SaveApiAccessMethodDialogTest.kt
@@ -4,6 +4,7 @@ import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.assertIsNotEnabled
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
+import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.mockk
import io.mockk.verify
import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
@@ -20,19 +21,27 @@ import org.junit.jupiter.api.extension.RegisterExtension
class SaveApiAccessMethodDialogTest {
@JvmField @RegisterExtension val composeExtension = createEdgeToEdgeComposeExtension()
+ private fun ComposeContext.initDialog(
+ state: SaveApiAccessMethodUiState = SaveApiAccessMethodUiState(),
+ onCancel: () -> Unit = {},
+ onSave: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ SaveApiAccessMethodDialog(state = state, onCancel = onCancel, onSave = onSave)
+ }
+ }
+
@Test
fun whenTestingInProgressShouldShowSpinnerWithCancelButton() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- SaveApiAccessMethodDialog(
- state =
- SaveApiAccessMethodUiState(
- testingState = TestApiAccessMethodState.Testing,
- isSaving = false,
- )
- )
- }
+ initDialog(
+ state =
+ SaveApiAccessMethodUiState(
+ testingState = TestApiAccessMethodState.Testing,
+ isSaving = false,
+ )
+ )
// Assert
onNodeWithTag(SAVE_API_ACCESS_METHOD_LOADING_SPINNER_TEST_TAG).assertExists()
@@ -43,15 +52,13 @@ class SaveApiAccessMethodDialogTest {
fun whenTestingFailedShouldShowSaveAndCancelButton() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- SaveApiAccessMethodDialog(
- state =
- SaveApiAccessMethodUiState(
- testingState = TestApiAccessMethodState.Result.Failure,
- isSaving = false,
- )
- )
- }
+ initDialog(
+ state =
+ SaveApiAccessMethodUiState(
+ testingState = TestApiAccessMethodState.Result.Failure,
+ isSaving = false,
+ )
+ )
// Assert
onNodeWithTag(SAVE_API_ACCESS_METHOD_SAVE_BUTTON_TEST_TAG).assertExists()
@@ -62,15 +69,13 @@ class SaveApiAccessMethodDialogTest {
fun whenTestingSuccessfulAndSavingShouldShowDisabledCancelButton() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- SaveApiAccessMethodDialog(
- state =
- SaveApiAccessMethodUiState(
- testingState = TestApiAccessMethodState.Result.Successful,
- isSaving = true,
- )
- )
- }
+ initDialog(
+ state =
+ SaveApiAccessMethodUiState(
+ testingState = TestApiAccessMethodState.Result.Successful,
+ isSaving = true,
+ )
+ )
// Assert
onNodeWithTag(SAVE_API_ACCESS_METHOD_CANCEL_BUTTON_TEST_TAG).assertExists()
@@ -82,16 +87,14 @@ class SaveApiAccessMethodDialogTest {
composeExtension.use {
// Arrange
val onCancelClick: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- SaveApiAccessMethodDialog(
- state =
- SaveApiAccessMethodUiState(
- testingState = TestApiAccessMethodState.Testing,
- isSaving = false,
- ),
- onCancel = onCancelClick,
- )
- }
+ initDialog(
+ state =
+ SaveApiAccessMethodUiState(
+ testingState = TestApiAccessMethodState.Testing,
+ isSaving = false,
+ ),
+ onCancel = onCancelClick,
+ )
// Act
onNodeWithTag(SAVE_API_ACCESS_METHOD_CANCEL_BUTTON_TEST_TAG).performClick()
@@ -105,16 +108,14 @@ class SaveApiAccessMethodDialogTest {
composeExtension.use {
// Arrange
val onSaveClick: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- SaveApiAccessMethodDialog(
- state =
- SaveApiAccessMethodUiState(
- testingState = TestApiAccessMethodState.Result.Failure,
- isSaving = false,
- ),
- onSave = onSaveClick,
- )
- }
+ initDialog(
+ state =
+ SaveApiAccessMethodUiState(
+ testingState = TestApiAccessMethodState.Result.Failure,
+ isSaving = false,
+ ),
+ onSave = onSaveClick,
+ )
// Act
onNodeWithTag(SAVE_API_ACCESS_METHOD_SAVE_BUTTON_TEST_TAG).performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/AccountScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/AccountScreenTest.kt
index dba40b40dd..88b783df83 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/AccountScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/AccountScreenTest.kt
@@ -5,6 +5,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.mockk
@@ -33,23 +34,47 @@ class AccountScreenTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initScreen(
+ state: AccountUiState = AccountUiState.default(),
+ onCopyAccountNumber: (String) -> Unit = {},
+ onRedeemVoucherClick: () -> Unit = {},
+ onManageAccountClick: () -> Unit = {},
+ onLogoutClick: () -> Unit = {},
+ onPurchaseBillingProductClick: (productId: ProductId) -> Unit = {},
+ navigateToDeviceInfo: () -> Unit = {},
+ navigateToVerificationPendingDialog: () -> Unit = {},
+ onBackClick: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ AccountScreen(
+ state = state,
+ onCopyAccountNumber = onCopyAccountNumber,
+ onRedeemVoucherClick = onRedeemVoucherClick,
+ onManageAccountClick = onManageAccountClick,
+ onLogoutClick = onLogoutClick,
+ onPurchaseBillingProductClick = onPurchaseBillingProductClick,
+ navigateToDeviceInfo = navigateToDeviceInfo,
+ navigateToVerificationPendingDialog = navigateToVerificationPendingDialog,
+ onBackClick = onBackClick,
+ )
+ }
+ }
+
@Test
fun testDefaultState() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- AccountScreen(
- state =
- AccountUiState(
- deviceName = DUMMY_DEVICE_NAME,
- accountNumber = DUMMY_ACCOUNT_NUMBER,
- accountExpiry = null,
- showSitePayment = false,
- showLogoutLoading = false,
- showManageAccountLoading = false,
- )
- )
- }
+ initScreen(
+ state =
+ AccountUiState(
+ deviceName = DUMMY_DEVICE_NAME,
+ accountNumber = DUMMY_ACCOUNT_NUMBER,
+ accountExpiry = null,
+ showSitePayment = false,
+ showLogoutLoading = false,
+ showManageAccountLoading = false,
+ )
+ )
// Assert
onNodeWithText("Redeem voucher").assertExists()
@@ -61,20 +86,18 @@ class AccountScreenTest {
composeExtension.use {
// Arrange
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- AccountScreen(
- state =
- AccountUiState(
- deviceName = DUMMY_DEVICE_NAME,
- accountNumber = DUMMY_ACCOUNT_NUMBER,
- accountExpiry = null,
- showSitePayment = true,
- showLogoutLoading = false,
- showManageAccountLoading = false,
- ),
- onManageAccountClick = mockedClickHandler,
- )
- }
+ initScreen(
+ state =
+ AccountUiState(
+ deviceName = DUMMY_DEVICE_NAME,
+ accountNumber = DUMMY_ACCOUNT_NUMBER,
+ accountExpiry = null,
+ showSitePayment = true,
+ showLogoutLoading = false,
+ showManageAccountLoading = false,
+ ),
+ onManageAccountClick = mockedClickHandler,
+ )
// Act
onNodeWithText("Manage account").performClick()
@@ -88,20 +111,18 @@ class AccountScreenTest {
composeExtension.use {
// Arrange
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- AccountScreen(
- state =
- AccountUiState(
- deviceName = DUMMY_DEVICE_NAME,
- accountNumber = DUMMY_ACCOUNT_NUMBER,
- accountExpiry = null,
- showSitePayment = false,
- showLogoutLoading = false,
- showManageAccountLoading = false,
- ),
- onRedeemVoucherClick = mockedClickHandler,
- )
- }
+ initScreen(
+ state =
+ AccountUiState(
+ deviceName = DUMMY_DEVICE_NAME,
+ accountNumber = DUMMY_ACCOUNT_NUMBER,
+ accountExpiry = null,
+ showSitePayment = false,
+ showLogoutLoading = false,
+ showManageAccountLoading = false,
+ ),
+ onRedeemVoucherClick = mockedClickHandler,
+ )
// Act
onNodeWithText("Redeem voucher").performClick()
@@ -115,20 +136,18 @@ class AccountScreenTest {
composeExtension.use {
// Arrange
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- AccountScreen(
- state =
- AccountUiState(
- deviceName = DUMMY_DEVICE_NAME,
- accountNumber = DUMMY_ACCOUNT_NUMBER,
- accountExpiry = null,
- showSitePayment = false,
- showLogoutLoading = false,
- showManageAccountLoading = false,
- ),
- onLogoutClick = mockedClickHandler,
- )
- }
+ initScreen(
+ state =
+ AccountUiState(
+ deviceName = DUMMY_DEVICE_NAME,
+ accountNumber = DUMMY_ACCOUNT_NUMBER,
+ accountExpiry = null,
+ showSitePayment = false,
+ showLogoutLoading = false,
+ showManageAccountLoading = false,
+ ),
+ onLogoutClick = mockedClickHandler,
+ )
// Act
onNodeWithText("Log out").performClick()
@@ -141,13 +160,10 @@ class AccountScreenTest {
fun testShowBillingErrorPaymentButton() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- AccountScreen(
- state =
- AccountUiState.default()
- .copy(billingPaymentState = PaymentState.Error.Billing)
- )
- }
+ initScreen(
+ state =
+ AccountUiState.default().copy(billingPaymentState = PaymentState.Error.Billing)
+ )
// Assert
onNodeWithText("Add 30 days time").assertExists()
@@ -160,16 +176,14 @@ class AccountScreenTest {
val mockPaymentProduct: PaymentProduct = mockk()
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.status } returns null
- setContentWithTheme {
- AccountScreen(
- state =
- AccountUiState.default()
- .copy(
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
- )
- )
- }
+ initScreen(
+ state =
+ AccountUiState.default()
+ .copy(
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
+ )
+ )
// Assert
onNodeWithText("Add 30 days time ($10)").assertExists()
@@ -182,16 +196,14 @@ class AccountScreenTest {
val mockPaymentProduct: PaymentProduct = mockk()
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.status } returns PaymentStatus.PENDING
- setContentWithTheme {
- AccountScreen(
- state =
- AccountUiState.default()
- .copy(
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
- )
- )
- }
+ initScreen(
+ state =
+ AccountUiState.default()
+ .copy(
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
+ )
+ )
// Assert
onNodeWithText("Google Play payment pending").assertExists()
@@ -205,17 +217,15 @@ class AccountScreenTest {
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.status } returns PaymentStatus.PENDING
val mockNavigateToVerificationPending: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- AccountScreen(
- state =
- AccountUiState.default()
- .copy(
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
- ),
- navigateToVerificationPendingDialog = mockNavigateToVerificationPending,
- )
- }
+ initScreen(
+ state =
+ AccountUiState.default()
+ .copy(
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
+ ),
+ navigateToVerificationPendingDialog = mockNavigateToVerificationPending,
+ )
// Act
onNodeWithTag(PLAY_PAYMENT_INFO_ICON_TEST_TAG).performClick()
@@ -231,16 +241,14 @@ class AccountScreenTest {
val mockPaymentProduct: PaymentProduct = mockk()
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.status } returns PaymentStatus.VERIFICATION_IN_PROGRESS
- setContentWithTheme {
- AccountScreen(
- state =
- AccountUiState.default()
- .copy(
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
- )
- )
- }
+ initScreen(
+ state =
+ AccountUiState.default()
+ .copy(
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
+ )
+ )
// Assert
onNodeWithText("Verifying purchase").assertExists()
@@ -255,17 +263,15 @@ class AccountScreenTest {
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.productId } returns ProductId("PRODUCT_ID")
every { mockPaymentProduct.status } returns null
- setContentWithTheme {
- AccountScreen(
- state =
- AccountUiState.default()
- .copy(
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
- ),
- onPurchaseBillingProductClick = clickHandler,
- )
- }
+ initScreen(
+ state =
+ AccountUiState.default()
+ .copy(
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
+ ),
+ onPurchaseBillingProductClick = clickHandler,
+ )
// Act
onNodeWithText("Add 30 days time ($10)").performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessListScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessListScreenTest.kt
index e08d46d9d3..e0f24bcc5e 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessListScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessListScreenTest.kt
@@ -4,6 +4,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.mockk
import io.mockk.verify
import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
@@ -19,17 +20,32 @@ import org.junit.jupiter.api.extension.RegisterExtension
class ApiAccessListScreenTest {
@JvmField @RegisterExtension val composeExtension = createEdgeToEdgeComposeExtension()
+ private fun ComposeContext.initScreen(
+ state: ApiAccessListUiState = ApiAccessListUiState(),
+ onAddMethodClick: () -> Unit = {},
+ onApiAccessMethodClick: (apiAccessMethodSetting: ApiAccessMethodSetting) -> Unit = {},
+ onApiAccessInfoClick: () -> Unit = {},
+ onBackClick: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ ApiAccessListScreen(
+ state = state,
+ onAddMethodClick = onAddMethodClick,
+ onApiAccessMethodClick = onApiAccessMethodClick,
+ onApiAccessInfoClick = onApiAccessInfoClick,
+ onBackClick = onBackClick,
+ )
+ }
+ }
+
@Test
fun shouldShowCurrentApiAccessName() =
composeExtension.use {
// Arrange
val currentApiAccessMethod = DIRECT_ACCESS_METHOD
- setContentWithTheme {
- ApiAccessListScreen(
- state =
- ApiAccessListUiState(currentApiAccessMethodSetting = currentApiAccessMethod)
- )
- }
+ initScreen(
+ state = ApiAccessListUiState(currentApiAccessMethodSetting = currentApiAccessMethod)
+ )
// Assert
onNodeWithText("Current: ${currentApiAccessMethod.name}")
@@ -40,11 +56,9 @@ class ApiAccessListScreenTest {
composeExtension.use {
// Arrange
val apiAccessMethod = DIRECT_ACCESS_METHOD
- setContentWithTheme {
- ApiAccessListScreen(
- state = ApiAccessListUiState(apiAccessMethodSettings = listOf(apiAccessMethod))
- )
- }
+ initScreen(
+ state = ApiAccessListUiState(apiAccessMethodSettings = listOf(apiAccessMethod))
+ )
// Assert
onNodeWithText(apiAccessMethod.name.value)
@@ -56,12 +70,7 @@ class ApiAccessListScreenTest {
composeExtension.use {
// Arrange
val onAddMethodClick: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ApiAccessListScreen(
- state = ApiAccessListUiState(),
- onAddMethodClick = onAddMethodClick,
- )
- }
+ initScreen(state = ApiAccessListUiState(), onAddMethodClick = onAddMethodClick)
// Act
onNodeWithText("Add").performClick()
@@ -75,12 +84,7 @@ class ApiAccessListScreenTest {
composeExtension.use {
// Arrange
val onApiAccessInfoClick: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ApiAccessListScreen(
- state = ApiAccessListUiState(),
- onApiAccessInfoClick = onApiAccessInfoClick,
- )
- }
+ initScreen(state = ApiAccessListUiState(), onApiAccessInfoClick = onApiAccessInfoClick)
// Act
onNodeWithTag(API_ACCESS_LIST_INFO_TEST_TAG).performClick()
@@ -95,12 +99,10 @@ class ApiAccessListScreenTest {
// Arrange
val apiAccessMethod = DIRECT_ACCESS_METHOD
val onApiAccessMethodClick: (ApiAccessMethodSetting) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ApiAccessListScreen(
- state = ApiAccessListUiState(apiAccessMethodSettings = listOf(apiAccessMethod)),
- onApiAccessMethodClick = onApiAccessMethodClick,
- )
- }
+ initScreen(
+ state = ApiAccessListUiState(apiAccessMethodSettings = listOf(apiAccessMethod)),
+ onApiAccessMethodClick = onApiAccessMethodClick,
+ )
// Act
onNodeWithText(apiAccessMethod.name.value).performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessMethodDetailsScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessMethodDetailsScreenTest.kt
index 93f3fb0343..14dfdfbfd7 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessMethodDetailsScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessMethodDetailsScreenTest.kt
@@ -4,6 +4,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.mockk
import io.mockk.verify
import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
@@ -23,22 +24,44 @@ import org.junit.jupiter.api.extension.RegisterExtension
class ApiAccessMethodDetailsScreenTest {
@JvmField @RegisterExtension val composeExtension = createEdgeToEdgeComposeExtension()
+ private fun ComposeContext.initScreen(
+ state: ApiAccessMethodDetailsUiState,
+ onEditMethodClicked: () -> Unit = {},
+ onEnableClicked: (Boolean) -> Unit = {},
+ onTestMethodClicked: () -> Unit = {},
+ onUseMethodClicked: () -> Unit = {},
+ onDeleteApiAccessMethodClicked: (ApiAccessMethodId) -> Unit = {},
+ onNavigateToEncryptedDnsInfoDialog: () -> Unit = {},
+ onBackClicked: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ ApiAccessMethodDetailsScreen(
+ state = state,
+ onEditMethodClicked = onEditMethodClicked,
+ onEnableClicked = onEnableClicked,
+ onTestMethodClicked = onTestMethodClicked,
+ onUseMethodClicked = onUseMethodClicked,
+ onDeleteApiAccessMethodClicked = onDeleteApiAccessMethodClicked,
+ onNavigateToEncryptedDnsInfoDialog = onNavigateToEncryptedDnsInfoDialog,
+ onBackClicked = onBackClicked,
+ )
+ }
+ }
+
@Test
fun whenApiAccessMethodIsNotEditableShouldNotShowDeleteAndEdit() =
composeExtension.use {
// Arrange
val apiAccessMethod = DIRECT_ACCESS_METHOD
- setContentWithTheme {
- ApiAccessMethodDetailsScreen(
- state =
- ApiAccessMethodDetailsUiState.Content(
- apiAccessMethodSetting = apiAccessMethod,
- isDisableable = true,
- isCurrentMethod = true,
- isTestingAccessMethod = false,
- )
- )
- }
+ initScreen(
+ state =
+ ApiAccessMethodDetailsUiState.Content(
+ apiAccessMethodSetting = apiAccessMethod,
+ isDisableable = true,
+ isCurrentMethod = true,
+ isTestingAccessMethod = false,
+ )
+ )
// Assert
onNodeWithTag(API_ACCESS_DETAILS_TOP_BAR_DROPDOWN_BUTTON_TEST_TAG).assertDoesNotExist()
@@ -51,18 +74,16 @@ class ApiAccessMethodDetailsScreenTest {
// Arrange
val onEnableClicked: (Boolean) -> Unit = mockk(relaxed = true)
val apiAccessMethod = DIRECT_ACCESS_METHOD
- setContentWithTheme {
- ApiAccessMethodDetailsScreen(
- state =
- ApiAccessMethodDetailsUiState.Content(
- apiAccessMethodSetting = apiAccessMethod,
- isDisableable = false,
- isCurrentMethod = true,
- isTestingAccessMethod = false,
- ),
- onEnableClicked = onEnableClicked,
- )
- }
+ initScreen(
+ state =
+ ApiAccessMethodDetailsUiState.Content(
+ apiAccessMethodSetting = apiAccessMethod,
+ isDisableable = false,
+ isCurrentMethod = true,
+ isTestingAccessMethod = false,
+ ),
+ onEnableClicked = onEnableClicked,
+ )
// Act
onNodeWithText("Enable method").performClick()
@@ -78,18 +99,16 @@ class ApiAccessMethodDetailsScreenTest {
// Arrange
val onDeleteApiAccessMethodClicked: (ApiAccessMethodId) -> Unit = mockk(relaxed = true)
val apiAccessMethod = CUSTOM_ACCESS_METHOD
- setContentWithTheme {
- ApiAccessMethodDetailsScreen(
- state =
- ApiAccessMethodDetailsUiState.Content(
- apiAccessMethodSetting = apiAccessMethod,
- isDisableable = false,
- isCurrentMethod = true,
- isTestingAccessMethod = false,
- ),
- onDeleteApiAccessMethodClicked = onDeleteApiAccessMethodClicked,
- )
- }
+ initScreen(
+ state =
+ ApiAccessMethodDetailsUiState.Content(
+ apiAccessMethodSetting = apiAccessMethod,
+ isDisableable = false,
+ isCurrentMethod = true,
+ isTestingAccessMethod = false,
+ ),
+ onDeleteApiAccessMethodClicked = onDeleteApiAccessMethodClicked,
+ )
// Act
onNodeWithTag(API_ACCESS_DETAILS_TOP_BAR_DROPDOWN_BUTTON_TEST_TAG).performClick()
@@ -105,18 +124,16 @@ class ApiAccessMethodDetailsScreenTest {
// Arrange
val onEditMethodClicked: () -> Unit = mockk(relaxed = true)
val apiAccessMethod = CUSTOM_ACCESS_METHOD
- setContentWithTheme {
- ApiAccessMethodDetailsScreen(
- state =
- ApiAccessMethodDetailsUiState.Content(
- apiAccessMethodSetting = apiAccessMethod,
- isDisableable = false,
- isCurrentMethod = true,
- isTestingAccessMethod = false,
- ),
- onEditMethodClicked = onEditMethodClicked,
- )
- }
+ initScreen(
+ state =
+ ApiAccessMethodDetailsUiState.Content(
+ apiAccessMethodSetting = apiAccessMethod,
+ isDisableable = false,
+ isCurrentMethod = true,
+ isTestingAccessMethod = false,
+ ),
+ onEditMethodClicked = onEditMethodClicked,
+ )
// Act
onNodeWithTag(API_ACCESS_DETAILS_EDIT_BUTTON).performClick()
@@ -131,18 +148,16 @@ class ApiAccessMethodDetailsScreenTest {
// Arrange
val onEnableClicked: (Boolean) -> Unit = mockk(relaxed = true)
val apiAccessMethod = DIRECT_ACCESS_METHOD
- setContentWithTheme {
- ApiAccessMethodDetailsScreen(
- state =
- ApiAccessMethodDetailsUiState.Content(
- apiAccessMethodSetting = apiAccessMethod,
- isDisableable = true,
- isCurrentMethod = true,
- isTestingAccessMethod = false,
- ),
- onEnableClicked = onEnableClicked,
- )
- }
+ initScreen(
+ state =
+ ApiAccessMethodDetailsUiState.Content(
+ apiAccessMethodSetting = apiAccessMethod,
+ isDisableable = true,
+ isCurrentMethod = true,
+ isTestingAccessMethod = false,
+ ),
+ onEnableClicked = onEnableClicked,
+ )
// Act
onNodeWithText("Enable method").performClick()
@@ -157,18 +172,16 @@ class ApiAccessMethodDetailsScreenTest {
// Arrange
val onTestMethodClicked: () -> Unit = mockk(relaxed = true)
val apiAccessMethod = DIRECT_ACCESS_METHOD
- setContentWithTheme {
- ApiAccessMethodDetailsScreen(
- state =
- ApiAccessMethodDetailsUiState.Content(
- apiAccessMethodSetting = apiAccessMethod,
- isDisableable = true,
- isCurrentMethod = true,
- isTestingAccessMethod = false,
- ),
- onTestMethodClicked = onTestMethodClicked,
- )
- }
+ initScreen(
+ state =
+ ApiAccessMethodDetailsUiState.Content(
+ apiAccessMethodSetting = apiAccessMethod,
+ isDisableable = true,
+ isCurrentMethod = true,
+ isTestingAccessMethod = false,
+ ),
+ onTestMethodClicked = onTestMethodClicked,
+ )
// Act
onNodeWithTag(API_ACCESS_TEST_METHOD_BUTTON).performClick()
@@ -183,18 +196,16 @@ class ApiAccessMethodDetailsScreenTest {
// Arrange
val onUseMethodClicked: () -> Unit = mockk(relaxed = true)
val apiAccessMethod = DIRECT_ACCESS_METHOD
- setContentWithTheme {
- ApiAccessMethodDetailsScreen(
- state =
- ApiAccessMethodDetailsUiState.Content(
- apiAccessMethodSetting = apiAccessMethod,
- isDisableable = true,
- isCurrentMethod = false,
- isTestingAccessMethod = false,
- ),
- onUseMethodClicked = onUseMethodClicked,
- )
- }
+ initScreen(
+ state =
+ ApiAccessMethodDetailsUiState.Content(
+ apiAccessMethodSetting = apiAccessMethod,
+ isDisableable = true,
+ isCurrentMethod = false,
+ isTestingAccessMethod = false,
+ ),
+ onUseMethodClicked = onUseMethodClicked,
+ )
// Act
onNodeWithTag(API_ACCESS_USE_METHOD_BUTTON).performClick()
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 9087fe2f6c..be998a3728 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
@@ -4,6 +4,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.mockk
@@ -52,11 +53,41 @@ class ConnectScreenTest {
unmockkAll()
}
+ private fun ComposeContext.initScreen(
+ state: ConnectUiState = ConnectUiState.INITIAL,
+ onDisconnectClick: () -> Unit = {},
+ onReconnectClick: () -> Unit = {},
+ onConnectClick: () -> Unit = {},
+ onCancelClick: () -> Unit = {},
+ onSwitchLocationClick: () -> Unit = {},
+ onOpenAppListing: () -> Unit = {},
+ onManageAccountClick: () -> Unit = {},
+ onSettingsClick: () -> Unit = {},
+ onAccountClick: () -> Unit = {},
+ onDismissNewDeviceClick: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ ConnectScreen(
+ state = state,
+ onDisconnectClick = onDisconnectClick,
+ onReconnectClick = onReconnectClick,
+ onConnectClick = onConnectClick,
+ onCancelClick = onCancelClick,
+ onSwitchLocationClick = onSwitchLocationClick,
+ onOpenAppListing = onOpenAppListing,
+ onManageAccountClick = onManageAccountClick,
+ onSettingsClick = onSettingsClick,
+ onAccountClick = onAccountClick,
+ onDismissNewDeviceClick = onDismissNewDeviceClick,
+ )
+ }
+ }
+
@Test
fun testDefaultState() {
composeExtension.use {
// Arrange
- setContentWithTheme { ConnectScreen(state = ConnectUiState.INITIAL) }
+ initScreen()
// Assert
onNodeWithText("DISCONNECTED").assertExists()
@@ -68,21 +99,19 @@ class ConnectScreenTest {
fun testConnectingState() {
composeExtension.use {
// Arrange
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = null,
- tunnelState = TunnelState.Connecting(null, null, emptyList()),
- showLocation = false,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = InAppNotification.TunnelStateBlocked,
- isPlayBuild = false,
- )
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = null,
+ tunnelState = TunnelState.Connecting(null, null, emptyList()),
+ showLocation = false,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = InAppNotification.TunnelStateBlocked,
+ isPlayBuild = false,
+ )
+ )
// Assert
onNodeWithTag(CIRCULAR_PROGRESS_INDICATOR).assertExists()
@@ -98,22 +127,19 @@ class ConnectScreenTest {
composeExtension.use {
// Arrange
val mockTunnelEndpoint: TunnelEndpoint = mockk(relaxed = true)
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = null,
- tunnelState =
- TunnelState.Connected(mockTunnelEndpoint, null, emptyList()),
- showLocation = false,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = null,
- isPlayBuild = false,
- )
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = null,
+ tunnelState = TunnelState.Connected(mockTunnelEndpoint, null, emptyList()),
+ showLocation = false,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = null,
+ isPlayBuild = false,
+ )
+ )
// Assert
onNodeWithText("CONNECTED").assertExists()
@@ -127,21 +153,19 @@ class ConnectScreenTest {
composeExtension.use {
// Arrange
val mockLocationName = "Home"
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = mockLocationName,
- tunnelState = TunnelState.Disconnecting(ActionAfterDisconnect.Nothing),
- showLocation = true,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = null,
- isPlayBuild = false,
- )
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = mockLocationName,
+ tunnelState = TunnelState.Disconnecting(ActionAfterDisconnect.Nothing),
+ showLocation = true,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = null,
+ isPlayBuild = false,
+ )
+ )
// Assert
onNodeWithText("DISCONNECTED").assertExists()
@@ -155,21 +179,19 @@ class ConnectScreenTest {
composeExtension.use {
// Arrange
val mockLocationName = "Home"
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = mockLocationName,
- tunnelState = TunnelState.Disconnected(),
- showLocation = true,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = null,
- isPlayBuild = false,
- )
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = mockLocationName,
+ tunnelState = TunnelState.Disconnected(),
+ showLocation = true,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = null,
+ isPlayBuild = false,
+ )
+ )
// Assert
onNodeWithText("DISCONNECTED").assertExists()
@@ -183,27 +205,23 @@ class ConnectScreenTest {
composeExtension.use {
// Arrange
val mockLocationName = "Home"
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = mockLocationName,
- tunnelState =
- TunnelState.Error(
- ErrorState(ErrorStateCause.StartTunnelError, true)
- ),
- showLocation = true,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification =
- InAppNotification.TunnelStateError(
- ErrorState(ErrorStateCause.StartTunnelError, true)
- ),
- isPlayBuild = false,
- )
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = mockLocationName,
+ tunnelState =
+ TunnelState.Error(ErrorState(ErrorStateCause.StartTunnelError, true)),
+ showLocation = true,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification =
+ InAppNotification.TunnelStateError(
+ ErrorState(ErrorStateCause.StartTunnelError, true)
+ ),
+ isPlayBuild = false,
+ )
+ )
// Assert
onNodeWithText("BLOCKED CONNECTION").assertExists()
@@ -218,27 +236,23 @@ class ConnectScreenTest {
composeExtension.use {
// Arrange
val mockLocationName = "Home"
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = mockLocationName,
- tunnelState =
- TunnelState.Error(
- ErrorState(ErrorStateCause.StartTunnelError, false)
- ),
- showLocation = true,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification =
- InAppNotification.TunnelStateError(
- ErrorState(ErrorStateCause.StartTunnelError, false)
- ),
- isPlayBuild = false,
- )
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = mockLocationName,
+ tunnelState =
+ TunnelState.Error(ErrorState(ErrorStateCause.StartTunnelError, false)),
+ showLocation = true,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification =
+ InAppNotification.TunnelStateError(
+ ErrorState(ErrorStateCause.StartTunnelError, false)
+ ),
+ isPlayBuild = false,
+ )
+ )
// Assert
onNodeWithText("FAILED TO CONNECT").assertExists()
@@ -253,22 +267,19 @@ class ConnectScreenTest {
fun testReconnectingState() {
composeExtension.use {
// Arrange
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = null,
- tunnelState =
- TunnelState.Disconnecting(ActionAfterDisconnect.Reconnect),
- showLocation = false,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = InAppNotification.TunnelStateBlocked,
- isPlayBuild = false,
- )
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = null,
+ tunnelState = TunnelState.Disconnecting(ActionAfterDisconnect.Reconnect),
+ showLocation = false,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = InAppNotification.TunnelStateBlocked,
+ isPlayBuild = false,
+ )
+ )
// Assert
onNodeWithTag(CIRCULAR_PROGRESS_INDICATOR).assertExists()
@@ -284,21 +295,19 @@ class ConnectScreenTest {
composeExtension.use {
// Arrange
val mockLocationName = "Home"
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = mockLocationName,
- tunnelState = TunnelState.Disconnecting(ActionAfterDisconnect.Block),
- showLocation = true,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = InAppNotification.TunnelStateBlocked,
- isPlayBuild = false,
- )
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = mockLocationName,
+ tunnelState = TunnelState.Disconnecting(ActionAfterDisconnect.Block),
+ showLocation = true,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = InAppNotification.TunnelStateBlocked,
+ isPlayBuild = false,
+ )
+ )
// Assert
onNodeWithText("CONNECTED").assertExists()
@@ -314,22 +323,20 @@ class ConnectScreenTest {
// Arrange
val mockLocationName = "Home"
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = mockLocationName,
- tunnelState = TunnelState.Disconnected(),
- showLocation = false,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = null,
- isPlayBuild = false,
- ),
- onSwitchLocationClick = mockedClickHandler,
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = mockLocationName,
+ tunnelState = TunnelState.Disconnected(),
+ showLocation = false,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = null,
+ isPlayBuild = false,
+ ),
+ onSwitchLocationClick = mockedClickHandler,
+ )
// Act
onNodeWithTag(SELECT_LOCATION_BUTTON_TEST_TAG).performClick()
@@ -345,23 +352,20 @@ class ConnectScreenTest {
// Arrange
val mockTunnelEndpoint: TunnelEndpoint = mockk(relaxed = true)
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = null,
- tunnelState =
- TunnelState.Connected(mockTunnelEndpoint, null, emptyList()),
- showLocation = false,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = null,
- isPlayBuild = false,
- ),
- onDisconnectClick = mockedClickHandler,
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = null,
+ tunnelState = TunnelState.Connected(mockTunnelEndpoint, null, emptyList()),
+ showLocation = false,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = null,
+ isPlayBuild = false,
+ ),
+ onDisconnectClick = mockedClickHandler,
+ )
// Act
onNodeWithTag(CONNECT_BUTTON_TEST_TAG).performClick()
@@ -377,23 +381,20 @@ class ConnectScreenTest {
// Arrange
val mockTunnelEndpoint: TunnelEndpoint = mockk(relaxed = true)
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = null,
- tunnelState =
- TunnelState.Connected(mockTunnelEndpoint, null, emptyList()),
- showLocation = false,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = null,
- isPlayBuild = false,
- ),
- onReconnectClick = mockedClickHandler,
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = null,
+ tunnelState = TunnelState.Connected(mockTunnelEndpoint, null, emptyList()),
+ showLocation = false,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = null,
+ isPlayBuild = false,
+ ),
+ onReconnectClick = mockedClickHandler,
+ )
// Act
onNodeWithTag(RECONNECT_BUTTON_TEST_TAG).performClick()
@@ -408,22 +409,20 @@ class ConnectScreenTest {
composeExtension.use {
// Arrange
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = null,
- tunnelState = TunnelState.Disconnected(),
- showLocation = false,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = null,
- isPlayBuild = false,
- ),
- onConnectClick = mockedClickHandler,
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = null,
+ tunnelState = TunnelState.Disconnected(),
+ showLocation = false,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = null,
+ isPlayBuild = false,
+ ),
+ onConnectClick = mockedClickHandler,
+ )
// Act
onNodeWithTag(CONNECT_BUTTON_TEST_TAG).performClick()
@@ -438,22 +437,20 @@ class ConnectScreenTest {
composeExtension.use {
// Arrange
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = null,
- tunnelState = TunnelState.Connecting(null, null, emptyList()),
- showLocation = false,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = null,
- isPlayBuild = false,
- ),
- onCancelClick = mockedClickHandler,
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = null,
+ tunnelState = TunnelState.Connecting(null, null, emptyList()),
+ showLocation = false,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = null,
+ isPlayBuild = false,
+ ),
+ onCancelClick = mockedClickHandler,
+ )
// Act
onNodeWithTag(CONNECT_BUTTON_TEST_TAG).performClick()
@@ -490,26 +487,20 @@ class ConnectScreenTest {
val outIpv6 = "ipv6address"
every { mockLocation.ipv6?.hostAddress } returns outIpv6
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = mockLocation,
- selectedRelayItemTitle = null,
- tunnelState =
- TunnelState.Connected(
- mockTunnelEndpoint,
- mockLocation,
- emptyList(),
- ),
- showLocation = false,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = null,
- isPlayBuild = false,
- )
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = mockLocation,
+ selectedRelayItemTitle = null,
+ tunnelState =
+ TunnelState.Connected(mockTunnelEndpoint, mockLocation, emptyList()),
+ showLocation = false,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = null,
+ isPlayBuild = false,
+ )
+ )
// Act
onNodeWithTag(CONNECT_CARD_HEADER_TEST_TAG).performClick()
@@ -532,21 +523,19 @@ class ConnectScreenTest {
composeExtension.use {
// Arrange
val versionInfo = VersionInfo(currentVersion = "1.0", isSupported = false)
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = null,
- tunnelState = TunnelState.Connecting(null, null, emptyList()),
- showLocation = false,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = InAppNotification.UnsupportedVersion(versionInfo),
- isPlayBuild = false,
- )
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = null,
+ tunnelState = TunnelState.Connecting(null, null, emptyList()),
+ showLocation = false,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = InAppNotification.UnsupportedVersion(versionInfo),
+ isPlayBuild = false,
+ )
+ )
// Assert
onNodeWithText("UNSUPPORTED VERSION").assertExists()
@@ -562,24 +551,20 @@ class ConnectScreenTest {
composeExtension.use {
// Arrange
val expiryDate = DateTime(2020, 11, 11, 10, 10)
- setContentWithTheme {
- ConnectScreen(
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = null,
- tunnelState = TunnelState.Connecting(null, null, emptyList()),
- showLocation = false,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification =
- InAppNotification.AccountExpiry(
- Duration(DateTime.now(), expiryDate)
- ),
- isPlayBuild = false,
- )
- )
- }
+ initScreen(
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = null,
+ tunnelState = TunnelState.Connecting(null, null, emptyList()),
+ showLocation = false,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification =
+ InAppNotification.AccountExpiry(Duration(DateTime.now(), expiryDate)),
+ isPlayBuild = false,
+ )
+ )
// Assert
onNodeWithText("ACCOUNT CREDIT EXPIRES SOON").assertExists()
@@ -593,22 +578,20 @@ class ConnectScreenTest {
// Arrange
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
val versionInfo = VersionInfo(isSupported = false, currentVersion = "")
- setContentWithTheme {
- ConnectScreen(
- onOpenAppListing = mockedClickHandler,
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = null,
- tunnelState = TunnelState.Connecting(null, null, emptyList()),
- showLocation = false,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification = InAppNotification.UnsupportedVersion(versionInfo),
- isPlayBuild = false,
- ),
- )
- }
+ initScreen(
+ onOpenAppListing = mockedClickHandler,
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = null,
+ tunnelState = TunnelState.Connecting(null, null, emptyList()),
+ showLocation = false,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification = InAppNotification.UnsupportedVersion(versionInfo),
+ isPlayBuild = false,
+ ),
+ )
// Act
onNodeWithTag(NOTIFICATION_BANNER_ACTION).performClick()
@@ -624,25 +607,21 @@ class ConnectScreenTest {
// Arrange
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
val expiryDate = DateTime(2020, 11, 11, 10, 10)
- setContentWithTheme {
- ConnectScreen(
- onManageAccountClick = mockedClickHandler,
- state =
- ConnectUiState(
- location = null,
- selectedRelayItemTitle = null,
- tunnelState = TunnelState.Connecting(null, null, emptyList()),
- showLocation = false,
- deviceName = "",
- daysLeftUntilExpiry = null,
- inAppNotification =
- InAppNotification.AccountExpiry(
- Duration(DateTime.now(), expiryDate)
- ),
- isPlayBuild = false,
- ),
- )
- }
+ initScreen(
+ onManageAccountClick = mockedClickHandler,
+ state =
+ ConnectUiState(
+ location = null,
+ selectedRelayItemTitle = null,
+ tunnelState = TunnelState.Connecting(null, null, emptyList()),
+ showLocation = false,
+ deviceName = "",
+ daysLeftUntilExpiry = null,
+ inAppNotification =
+ InAppNotification.AccountExpiry(Duration(DateTime.now(), expiryDate)),
+ isPlayBuild = false,
+ ),
+ )
// Act
onNodeWithTag(NOTIFICATION_BANNER_ACTION).performClick()
@@ -657,9 +636,7 @@ class ConnectScreenTest {
composeExtension.use {
// Arrange
val onAccountClickMockk: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ConnectScreen(state = ConnectUiState.INITIAL, onAccountClick = onAccountClickMockk)
- }
+ initScreen(state = ConnectUiState.INITIAL, onAccountClick = onAccountClickMockk)
// Assert
onNodeWithTag(TOP_BAR_ACCOUNT_BUTTON).performClick()
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 484bb132d6..dee081ba03 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
@@ -5,6 +5,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
@@ -29,15 +30,32 @@ class CustomListLocationsScreenTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initScreen(
+ state: CustomListLocationsUiState,
+ onSearchTermInput: (String) -> Unit = {},
+ onSaveClick: () -> Unit = {},
+ onRelaySelectionClick: (RelayItem.Location, selected: Boolean) -> Unit = { _, _ -> },
+ onExpand: (RelayItem.Location, selected: Boolean) -> Unit = { _, _ -> },
+ onBackClick: () -> Unit = {},
+ ) {
+
+ setContentWithTheme {
+ CustomListLocationsScreen(
+ state = state,
+ onSearchTermInput = onSearchTermInput,
+ onSaveClick = onSaveClick,
+ onRelaySelectionClick = onRelaySelectionClick,
+ onExpand = onExpand,
+ onBackClick = onBackClick,
+ )
+ }
+ }
+
@Test
fun givenLoadingStateShouldShowLoadingSpinner() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- CustomListLocationsScreen(
- state = CustomListLocationsUiState.Loading(newList = false)
- )
- }
+ initScreen(state = CustomListLocationsUiState.Loading(newList = false))
// Assert
onNodeWithTag(CIRCULAR_PROGRESS_INDICATOR).assertExists()
@@ -48,11 +66,7 @@ class CustomListLocationsScreenTest {
composeExtension.use {
// Arrange
val newList = true
- setContentWithTheme {
- CustomListLocationsScreen(
- state = CustomListLocationsUiState.Loading(newList = newList)
- )
- }
+ initScreen(state = CustomListLocationsUiState.Loading(newList = newList))
// Assert
onNodeWithText(ADD_LOCATIONS_TEXT).assertExists()
@@ -63,11 +77,7 @@ class CustomListLocationsScreenTest {
composeExtension.use {
// Arrange
val newList = false
- setContentWithTheme {
- CustomListLocationsScreen(
- state = CustomListLocationsUiState.Loading(newList = newList)
- )
- }
+ initScreen(state = CustomListLocationsUiState.Loading(newList = newList))
// Assert
onNodeWithText(EDIT_LOCATIONS_TEXT).assertExists()
@@ -77,19 +87,17 @@ class CustomListLocationsScreenTest {
fun givenListOfAvailableLocationsShouldShowThem() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- CustomListLocationsScreen(
- state =
- CustomListLocationsUiState.Content.Data(
- locations =
- listOf(
- RelayLocationListItem(DUMMY_RELAY_COUNTRIES[0], checked = true),
- RelayLocationListItem(DUMMY_RELAY_COUNTRIES[1], checked = false),
- ),
- searchTerm = "",
- )
- )
- }
+ initScreen(
+ state =
+ CustomListLocationsUiState.Content.Data(
+ locations =
+ listOf(
+ RelayLocationListItem(DUMMY_RELAY_COUNTRIES[0], checked = true),
+ RelayLocationListItem(DUMMY_RELAY_COUNTRIES[1], checked = false),
+ ),
+ searchTerm = "",
+ )
+ )
// Assert
onNodeWithText("Relay Country 1").assertExists()
@@ -102,17 +110,14 @@ class CustomListLocationsScreenTest {
// Arrange
val selectedCountry = DUMMY_RELAY_COUNTRIES[0]
val mockedOnRelaySelectionClicked: (RelayItem, Boolean) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- CustomListLocationsScreen(
- state =
- CustomListLocationsUiState.Content.Data(
- newList = false,
- locations =
- listOf(RelayLocationListItem(selectedCountry, checked = true)),
- ),
- onRelaySelectionClick = mockedOnRelaySelectionClicked,
- )
- }
+ initScreen(
+ state =
+ CustomListLocationsUiState.Content.Data(
+ newList = false,
+ locations = listOf(RelayLocationListItem(selectedCountry, checked = true)),
+ ),
+ onRelaySelectionClick = mockedOnRelaySelectionClicked,
+ )
// Act
onNodeWithText(selectedCountry.name).performClick()
@@ -126,16 +131,14 @@ class CustomListLocationsScreenTest {
composeExtension.use {
// Arrange
val mockedSearchTermInput: (String) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- CustomListLocationsScreen(
- state =
- CustomListLocationsUiState.Content.Data(
- newList = false,
- locations = emptyList(),
- ),
- onSearchTermInput = mockedSearchTermInput,
- )
- }
+ initScreen(
+ state =
+ CustomListLocationsUiState.Content.Data(
+ newList = false,
+ locations = emptyList(),
+ ),
+ onSearchTermInput = mockedSearchTermInput,
+ )
val mockSearchString = "SEARCH"
// Act
@@ -151,16 +154,14 @@ class CustomListLocationsScreenTest {
// Arrange
val mockedSearchTermInput: (String) -> Unit = mockk(relaxed = true)
val mockSearchString = "SEARCH"
- setContentWithTheme {
- CustomListLocationsScreen(
- state =
- CustomListLocationsUiState.Content.Empty(
- newList = false,
- searchTerm = mockSearchString,
- ),
- onSearchTermInput = mockedSearchTermInput,
- )
- }
+ initScreen(
+ state =
+ CustomListLocationsUiState.Content.Empty(
+ newList = false,
+ searchTerm = mockSearchString,
+ ),
+ onSearchTermInput = mockedSearchTermInput,
+ )
// Assert
onNodeWithText(EMPTY_SEARCH.format(mockSearchString)).assertExists()
@@ -171,15 +172,13 @@ class CustomListLocationsScreenTest {
composeExtension.use {
// Arrange
val emptySearchString = ""
- setContentWithTheme {
- CustomListLocationsScreen(
- state =
- CustomListLocationsUiState.Content.Empty(
- newList = false,
- searchTerm = emptySearchString,
- )
- )
- }
+ initScreen(
+ state =
+ CustomListLocationsUiState.Content.Empty(
+ newList = false,
+ searchTerm = emptySearchString,
+ )
+ )
// Assert
onNodeWithText(NO_LOCATIONS_FOUND_TEXT).assertExists()
@@ -190,17 +189,15 @@ class CustomListLocationsScreenTest {
composeExtension.use {
// Arrange
val mockOnSaveClick: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- CustomListLocationsScreen(
- state =
- CustomListLocationsUiState.Content.Data(
- newList = false,
- locations = emptyList(),
- saveEnabled = true,
- ),
- onSaveClick = mockOnSaveClick,
- )
- }
+ initScreen(
+ state =
+ CustomListLocationsUiState.Content.Data(
+ newList = false,
+ locations = emptyList(),
+ saveEnabled = true,
+ ),
+ onSaveClick = mockOnSaveClick,
+ )
// Act
onNodeWithTag(SAVE_BUTTON_TEST_TAG).performClick()
@@ -214,17 +211,15 @@ class CustomListLocationsScreenTest {
composeExtension.use {
// Arrange
val mockOnSaveClick: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- CustomListLocationsScreen(
- state =
- CustomListLocationsUiState.Content.Data(
- newList = false,
- locations = emptyList(),
- saveEnabled = false,
- ),
- onSaveClick = mockOnSaveClick,
- )
- }
+ initScreen(
+ state =
+ CustomListLocationsUiState.Content.Data(
+ newList = false,
+ locations = emptyList(),
+ saveEnabled = false,
+ ),
+ onSaveClick = mockOnSaveClick,
+ )
// Act
onNodeWithTag(SAVE_BUTTON_TEST_TAG).performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreenTest.kt
index 47e88bb52f..f319ce92b3 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreenTest.kt
@@ -1,10 +1,10 @@
package net.mullvad.mullvadvpn.compose.screen
-import androidx.compose.material3.SnackbarHostState
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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
@@ -28,16 +28,28 @@ class CustomListsScreenTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initScreen(
+ state: CustomListsUiState = CustomListsUiState.Loading,
+ addCustomList: () -> Unit = {},
+ openCustomList: (CustomList) -> Unit = {},
+ onBackClick: () -> Unit = {},
+ ) {
+
+ setContentWithTheme {
+ CustomListsScreen(
+ state = state,
+ addCustomList = addCustomList,
+ openCustomList = openCustomList,
+ onBackClick = onBackClick,
+ )
+ }
+ }
+
@Test
fun givenLoadingStateShouldShowLoadingSpinner() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- CustomListsScreen(
- state = CustomListsUiState.Loading,
- snackbarHostState = SnackbarHostState(),
- )
- }
+ initScreen(state = CustomListsUiState.Loading)
// Assert
onNodeWithTag(CIRCULAR_PROGRESS_INDICATOR).assertExists()
@@ -48,12 +60,7 @@ class CustomListsScreenTest {
composeExtension.use {
// Arrange
val customLists = DUMMY_CUSTOM_LISTS
- setContentWithTheme {
- CustomListsScreen(
- state = CustomListsUiState.Content(customLists = customLists),
- snackbarHostState = SnackbarHostState(),
- )
- }
+ initScreen(state = CustomListsUiState.Content(customLists = customLists))
// Assert
onNodeWithText(customLists[0].name.value).assertExists()
@@ -66,13 +73,10 @@ class CustomListsScreenTest {
// Arrange
val customLists = DUMMY_CUSTOM_LISTS
val mockedAddCustomList: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- CustomListsScreen(
- state = CustomListsUiState.Content(customLists = customLists),
- snackbarHostState = SnackbarHostState(),
- addCustomList = mockedAddCustomList,
- )
- }
+ initScreen(
+ state = CustomListsUiState.Content(customLists = customLists),
+ addCustomList = mockedAddCustomList,
+ )
// Act
onNodeWithTag(NEW_LIST_BUTTON_TEST_TAG).performClick()
@@ -88,13 +92,10 @@ class CustomListsScreenTest {
val customLists = DUMMY_CUSTOM_LISTS
val clickedList = DUMMY_CUSTOM_LISTS[0]
val mockedOpenCustomList: (CustomList) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- CustomListsScreen(
- state = CustomListsUiState.Content(customLists = customLists),
- snackbarHostState = SnackbarHostState(),
- openCustomList = mockedOpenCustomList,
- )
- }
+ initScreen(
+ state = CustomListsUiState.Content(customLists = customLists),
+ openCustomList = mockedOpenCustomList,
+ )
// Act
onNodeWithText(clickedList.name.value).performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreenTest.kt
index cd1c03a59e..879d76ddd4 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreenTest.kt
@@ -3,6 +3,7 @@ package net.mullvad.mullvadvpn.compose.screen
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
+import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
@@ -22,6 +23,20 @@ class DeviceRevokedScreenTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initScreen(
+ state: DeviceRevokedUiState,
+ onSettingsClicked: () -> Unit = {},
+ onGoToLoginClicked: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ DeviceRevokedScreen(
+ state = state,
+ onSettingsClicked = onSettingsClicked,
+ onGoToLoginClicked = onGoToLoginClicked,
+ )
+ }
+ }
+
@Test
fun testUnblockWarningShowingWhenSecured() =
composeExtension.use {
@@ -29,7 +44,7 @@ class DeviceRevokedScreenTest {
val state = DeviceRevokedUiState.SECURED
// Act
- setContentWithTheme { DeviceRevokedScreen(state) }
+ initScreen(state)
// Assert
onNodeWithText(UNBLOCK_WARNING).assertExists()
@@ -42,7 +57,7 @@ class DeviceRevokedScreenTest {
val state = DeviceRevokedUiState.UNSECURED
// Act
- setContentWithTheme { DeviceRevokedScreen(state) }
+ initScreen(state)
// Assert
onNodeWithText(UNBLOCK_WARNING).assertDoesNotExist()
@@ -54,9 +69,7 @@ class DeviceRevokedScreenTest {
// Arrange
val state = DeviceRevokedUiState.UNSECURED
val mockOnGoToLoginClicked: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- DeviceRevokedScreen(state = state, onGoToLoginClicked = mockOnGoToLoginClicked)
- }
+ initScreen(state = state, onGoToLoginClicked = mockOnGoToLoginClicked)
// Act
onNodeWithText(GO_TO_LOGIN_BUTTON_TEXT).performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/EditApiAccessMethodScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/EditApiAccessMethodScreenTest.kt
index d737f5459f..1c763219ea 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/EditApiAccessMethodScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/EditApiAccessMethodScreenTest.kt
@@ -5,6 +5,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.mockk
import io.mockk.verify
import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
@@ -13,6 +14,7 @@ import net.mullvad.mullvadvpn.compose.state.ApiAccessMethodTypes
import net.mullvad.mullvadvpn.compose.state.EditApiAccessFormData
import net.mullvad.mullvadvpn.compose.state.EditApiAccessMethodUiState
import net.mullvad.mullvadvpn.compose.test.EDIT_API_ACCESS_NAME_INPUT
+import net.mullvad.mullvadvpn.lib.model.Cipher
import net.mullvad.mullvadvpn.lib.model.InvalidDataError
import net.mullvad.mullvadvpn.lib.model.ParsePortError
import org.junit.jupiter.api.Test
@@ -22,21 +24,51 @@ import org.junit.jupiter.api.extension.RegisterExtension
class EditApiAccessMethodScreenTest {
@JvmField @RegisterExtension val composeExtension = createEdgeToEdgeComposeExtension()
+ private fun ComposeContext.initScreen(
+ state: EditApiAccessMethodUiState,
+ onNameChanged: (String) -> Unit = {},
+ onTypeSelected: (ApiAccessMethodTypes) -> Unit = {},
+ onIpChanged: (String) -> Unit = {},
+ onPortChanged: (String) -> Unit = {},
+ onPasswordChanged: (String) -> Unit = {},
+ onCipherChange: (Cipher) -> Unit = {},
+ onToggleAuthenticationEnabled: (Boolean) -> Unit = {},
+ onUsernameChanged: (String) -> Unit = {},
+ onTestMethod: () -> Unit = {},
+ onAddMethod: () -> Unit = {},
+ onNavigateBack: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ EditApiAccessMethodScreen(
+ state = state,
+ onNameChanged = onNameChanged,
+ onTypeSelected = onTypeSelected,
+ onIpChanged = onIpChanged,
+ onPortChanged = onPortChanged,
+ onPasswordChanged = onPasswordChanged,
+ onCipherChange = onCipherChange,
+ onToggleAuthenticationEnabled = onToggleAuthenticationEnabled,
+ onUsernameChanged = onUsernameChanged,
+ onTestMethod = onTestMethod,
+ onAddMethod = onAddMethod,
+ onNavigateBack = onNavigateBack,
+ )
+ }
+ }
+
@Test
fun whenInEditModeAddButtonShouldSaySave() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- EditApiAccessMethodScreen(
- state =
- EditApiAccessMethodUiState.Content(
- editMode = true,
- formData = EditApiAccessFormData.empty(),
- hasChanges = false,
- isTestingApiAccessMethod = false,
- )
- )
- }
+ initScreen(
+ state =
+ EditApiAccessMethodUiState.Content(
+ editMode = true,
+ formData = EditApiAccessFormData.empty(),
+ hasChanges = false,
+ isTestingApiAccessMethod = false,
+ )
+ )
// Assert
onNodeWithText("Save").assertExists()
@@ -46,17 +78,15 @@ class EditApiAccessMethodScreenTest {
fun whenNotInEditModeAddButtonShouldSayAdd() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- EditApiAccessMethodScreen(
- state =
- EditApiAccessMethodUiState.Content(
- editMode = false,
- formData = EditApiAccessFormData.empty(),
- hasChanges = false,
- isTestingApiAccessMethod = false,
- )
- )
- }
+ initScreen(
+ state =
+ EditApiAccessMethodUiState.Content(
+ editMode = false,
+ formData = EditApiAccessFormData.empty(),
+ hasChanges = false,
+ isTestingApiAccessMethod = false,
+ )
+ )
// Assert
onNodeWithText("Add").assertExists()
@@ -66,25 +96,23 @@ class EditApiAccessMethodScreenTest {
fun whenNameInputHasErrorShouldShowError() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- EditApiAccessMethodScreen(
- state =
- EditApiAccessMethodUiState.Content(
- editMode = false,
- formData =
- EditApiAccessFormData(
- name = "",
- nameError = InvalidDataError.NameError.Required,
- serverIp = "",
- username = "",
- password = "",
- port = "",
- ),
- hasChanges = false,
- isTestingApiAccessMethod = false,
- )
- )
- }
+ initScreen(
+ state =
+ EditApiAccessMethodUiState.Content(
+ editMode = false,
+ formData =
+ EditApiAccessFormData(
+ name = "",
+ nameError = InvalidDataError.NameError.Required,
+ serverIp = "",
+ username = "",
+ password = "",
+ port = "",
+ ),
+ hasChanges = false,
+ isTestingApiAccessMethod = false,
+ )
+ )
// Assert
onNodeWithText("This field is required").assertExists()
@@ -94,25 +122,23 @@ class EditApiAccessMethodScreenTest {
fun whenServerInputIsNotIpAddressShouldShowError() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- EditApiAccessMethodScreen(
- state =
- EditApiAccessMethodUiState.Content(
- editMode = false,
- formData =
- EditApiAccessFormData(
- name = "",
- serverIp = "123",
- serverIpError = InvalidDataError.ServerIpError.Invalid,
- username = "",
- password = "",
- port = "",
- ),
- hasChanges = false,
- isTestingApiAccessMethod = false,
- )
- )
- }
+ initScreen(
+ state =
+ EditApiAccessMethodUiState.Content(
+ editMode = false,
+ formData =
+ EditApiAccessFormData(
+ name = "",
+ serverIp = "123",
+ serverIpError = InvalidDataError.ServerIpError.Invalid,
+ username = "",
+ password = "",
+ port = "",
+ ),
+ hasChanges = false,
+ isTestingApiAccessMethod = false,
+ )
+ )
// Assert
onNodeWithText("Please enter a valid IPv4 or IPv6 address").assertExists()
@@ -122,28 +148,26 @@ class EditApiAccessMethodScreenTest {
fun whenPortInputIsNotWithinRangeShouldShowError() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- EditApiAccessMethodScreen(
- state =
- EditApiAccessMethodUiState.Content(
- editMode = false,
- formData =
- EditApiAccessFormData(
- name = "",
- serverIp = "",
- username = "",
- password = "",
- port = "1111111111",
- portError =
- InvalidDataError.PortError.Invalid(
- ParsePortError.OutOfRange(1111111111)
- ),
- ),
- hasChanges = false,
- isTestingApiAccessMethod = false,
- )
- )
- }
+ initScreen(
+ state =
+ EditApiAccessMethodUiState.Content(
+ editMode = false,
+ formData =
+ EditApiAccessFormData(
+ name = "",
+ serverIp = "",
+ username = "",
+ password = "",
+ port = "1111111111",
+ portError =
+ InvalidDataError.PortError.Invalid(
+ ParsePortError.OutOfRange(1111111111)
+ ),
+ ),
+ hasChanges = false,
+ isTestingApiAccessMethod = false,
+ )
+ )
// Assert
onNodeWithText("Please enter a valid remote server port").assertExists()
@@ -155,18 +179,16 @@ class EditApiAccessMethodScreenTest {
// Arrange
val onNameChanged: (String) -> Unit = mockk(relaxed = true)
val mockInput = "Name"
- setContentWithTheme {
- EditApiAccessMethodScreen(
- state =
- EditApiAccessMethodUiState.Content(
- editMode = false,
- formData = EditApiAccessFormData.empty(),
- hasChanges = false,
- isTestingApiAccessMethod = false,
- ),
- onNameChanged = onNameChanged,
- )
- }
+ initScreen(
+ state =
+ EditApiAccessMethodUiState.Content(
+ editMode = false,
+ formData = EditApiAccessFormData.empty(),
+ hasChanges = false,
+ isTestingApiAccessMethod = false,
+ ),
+ onNameChanged = onNameChanged,
+ )
// Act
onNodeWithTag(EDIT_API_ACCESS_NAME_INPUT).performTextInput(mockInput)
@@ -179,26 +201,24 @@ class EditApiAccessMethodScreenTest {
fun whenSocks5IsSelectedAndAuthenticationIsEnabledShouldShowUsernameAndPassword() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- EditApiAccessMethodScreen(
- state =
- EditApiAccessMethodUiState.Content(
- editMode = false,
- formData =
- EditApiAccessFormData(
- name = "",
- serverIp = "",
- username = "",
- password = "",
- port = "",
- enableAuthentication = true,
- apiAccessMethodTypes = ApiAccessMethodTypes.SOCKS5_REMOTE,
- ),
- hasChanges = false,
- isTestingApiAccessMethod = false,
- )
- )
- }
+ initScreen(
+ state =
+ EditApiAccessMethodUiState.Content(
+ editMode = false,
+ formData =
+ EditApiAccessFormData(
+ name = "",
+ serverIp = "",
+ username = "",
+ password = "",
+ port = "",
+ enableAuthentication = true,
+ apiAccessMethodTypes = ApiAccessMethodTypes.SOCKS5_REMOTE,
+ ),
+ hasChanges = false,
+ isTestingApiAccessMethod = false,
+ )
+ )
// Assert
onNodeWithText("Username").assertExists()
@@ -210,18 +230,16 @@ class EditApiAccessMethodScreenTest {
composeExtension.use {
// Arrange
val onTestMethod: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- EditApiAccessMethodScreen(
- state =
- EditApiAccessMethodUiState.Content(
- editMode = false,
- formData = EditApiAccessFormData.empty(),
- hasChanges = false,
- isTestingApiAccessMethod = false,
- ),
- onTestMethod = onTestMethod,
- )
- }
+ initScreen(
+ state =
+ EditApiAccessMethodUiState.Content(
+ editMode = false,
+ formData = EditApiAccessFormData.empty(),
+ hasChanges = false,
+ isTestingApiAccessMethod = false,
+ ),
+ onTestMethod = onTestMethod,
+ )
// Act
onNodeWithText("Test method").performClick()
@@ -235,18 +253,16 @@ class EditApiAccessMethodScreenTest {
composeExtension.use {
// Arrange
val onAddMethod: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- EditApiAccessMethodScreen(
- state =
- EditApiAccessMethodUiState.Content(
- editMode = false,
- formData = EditApiAccessFormData.empty(),
- hasChanges = false,
- isTestingApiAccessMethod = false,
- ),
- onAddMethod = onAddMethod,
- )
- }
+ initScreen(
+ state =
+ EditApiAccessMethodUiState.Content(
+ editMode = false,
+ formData = EditApiAccessFormData.empty(),
+ hasChanges = false,
+ isTestingApiAccessMethod = false,
+ ),
+ onAddMethod = onAddMethod,
+ )
// Act
onNodeWithText("Add").performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreenTest.kt
index 1207f2417b..f3a4e3b2af 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreenTest.kt
@@ -4,6 +4,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
@@ -29,11 +30,29 @@ class EditCustomListScreenTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initScreen(
+ state: EditCustomListUiState = EditCustomListUiState.Loading,
+ onDeleteList: (id: CustomListId, name: CustomListName) -> Unit = { _, _ -> },
+ onNameClicked: (id: CustomListId, name: CustomListName) -> Unit = { _, _ -> },
+ onLocationsClicked: (CustomListId) -> Unit = {},
+ onBackClick: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ EditCustomListScreen(
+ state = state,
+ onDeleteList = onDeleteList,
+ onNameClicked = onNameClicked,
+ onLocationsClicked = onLocationsClicked,
+ onBackClick = onBackClick,
+ )
+ }
+ }
+
@Test
fun givenLoadingStateShouldShowLoadingSpinner() =
composeExtension.use {
// Arrange
- setContentWithTheme { EditCustomListScreen(state = EditCustomListUiState.Loading) }
+ initScreen()
// Assert
onNodeWithTag(CIRCULAR_PROGRESS_INDICATOR).assertExists()
@@ -43,7 +62,7 @@ class EditCustomListScreenTest {
fun givenNotFoundStateShouldShowNotFound() =
composeExtension.use {
// Arrange
- setContentWithTheme { EditCustomListScreen(state = EditCustomListUiState.NotFound) }
+ initScreen(state = EditCustomListUiState.NotFound)
// Assert
onNodeWithText(NOT_FOUND_TEXT).assertExists()
@@ -54,16 +73,15 @@ class EditCustomListScreenTest {
composeExtension.use {
// Arrange
val customList = DUMMY_CUSTOM_LISTS[0]
- setContentWithTheme {
- EditCustomListScreen(
- state =
- EditCustomListUiState.Content(
- id = customList.id,
- name = customList.name,
- locations = customList.locations,
- )
- )
- }
+
+ initScreen(
+ state =
+ EditCustomListUiState.Content(
+ id = customList.id,
+ name = customList.name,
+ locations = customList.locations,
+ )
+ )
// Assert
onNodeWithText(customList.name.value)
@@ -74,16 +92,14 @@ class EditCustomListScreenTest {
composeExtension.use {
// Arrange
val customList = DUMMY_CUSTOM_LISTS[0]
- setContentWithTheme {
- EditCustomListScreen(
- state =
- EditCustomListUiState.Content(
- id = customList.id,
- name = customList.name,
- locations = customList.locations,
- )
- )
- }
+ initScreen(
+ state =
+ EditCustomListUiState.Content(
+ id = customList.id,
+ name = customList.name,
+ locations = customList.locations,
+ )
+ )
// Assert
onNodeWithText(LOCATIONS_TEXT.format(customList.locations.size))
@@ -95,17 +111,15 @@ class EditCustomListScreenTest {
// Arrange
val mockedOnDelete: (CustomListId, CustomListName) -> Unit = mockk(relaxed = true)
val customList = DUMMY_CUSTOM_LISTS[0]
- setContentWithTheme {
- EditCustomListScreen(
- state =
- EditCustomListUiState.Content(
- id = customList.id,
- name = customList.name,
- locations = customList.locations,
- ),
- onDeleteList = mockedOnDelete,
- )
- }
+ initScreen(
+ state =
+ EditCustomListUiState.Content(
+ id = customList.id,
+ name = customList.name,
+ locations = customList.locations,
+ ),
+ onDeleteList = mockedOnDelete,
+ )
// Act
onNodeWithTag(TOP_BAR_DROPDOWN_BUTTON_TEST_TAG).performClick()
@@ -121,17 +135,15 @@ class EditCustomListScreenTest {
// Arrange
val mockedOnNameClicked: (CustomListId, CustomListName) -> Unit = mockk(relaxed = true)
val customList = DUMMY_CUSTOM_LISTS[0]
- setContentWithTheme {
- EditCustomListScreen(
- state =
- EditCustomListUiState.Content(
- id = customList.id,
- name = customList.name,
- locations = customList.locations,
- ),
- onNameClicked = mockedOnNameClicked,
- )
- }
+ initScreen(
+ state =
+ EditCustomListUiState.Content(
+ id = customList.id,
+ name = customList.name,
+ locations = customList.locations,
+ ),
+ onNameClicked = mockedOnNameClicked,
+ )
// Act
onNodeWithText(customList.name.value).performClick()
@@ -146,17 +158,15 @@ class EditCustomListScreenTest {
// Arrange
val mockedOnLocationsClicked: (CustomListId) -> Unit = mockk(relaxed = true)
val customList = DUMMY_CUSTOM_LISTS[0]
- setContentWithTheme {
- EditCustomListScreen(
- state =
- EditCustomListUiState.Content(
- id = customList.id,
- name = customList.name,
- locations = customList.locations,
- ),
- onLocationsClicked = mockedOnLocationsClicked,
- )
- }
+ initScreen(
+ state =
+ EditCustomListUiState.Content(
+ id = customList.id,
+ name = customList.name,
+ locations = customList.locations,
+ ),
+ onLocationsClicked = mockedOnLocationsClicked,
+ )
// Act
onNodeWithText(LOCATIONS_TEXT.format(customList.locations.size)).performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/FilterScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/FilterScreenTest.kt
index 7ca3d6941e..2f16b27c23 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/FilterScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/FilterScreenTest.kt
@@ -3,6 +3,7 @@ package net.mullvad.mullvadvpn.compose.screen
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
+import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
@@ -23,20 +24,37 @@ class FilterScreenTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initScreen(
+ state: RelayFilterUiState = RelayFilterUiState(),
+ onBackClick: () -> Unit = {},
+ onApplyClick: () -> Unit = {},
+ onSelectedOwnership: (ownership: Ownership?) -> Unit = {},
+ onAllProviderCheckChange: (isChecked: Boolean) -> Unit = {},
+ onSelectedProvider: (checked: Boolean, provider: Provider) -> Unit = { _, _ -> },
+ ) {
+ setContentWithTheme {
+ FilterScreen(
+ state = state,
+ onBackClick = onBackClick,
+ onApplyClick = onApplyClick,
+ onSelectedOwnership = onSelectedOwnership,
+ onAllProviderCheckChange = onAllProviderCheckChange,
+ onSelectedProvider = onSelectedProvider,
+ )
+ }
+ }
+
@Test
fun testDefaultState() =
composeExtension.use {
- setContentWithTheme {
- FilterScreen(
- state =
- RelayFilterUiState(
- allProviders = DUMMY_RELAY_ALL_PROVIDERS,
- selectedOwnership = null,
- selectedProviders = DUMMY_SELECTED_PROVIDERS,
- ),
- onSelectedProvider = { _, _ -> },
- )
- }
+ initScreen(
+ state =
+ RelayFilterUiState(
+ allProviders = DUMMY_RELAY_ALL_PROVIDERS,
+ selectedOwnership = null,
+ selectedProviders = DUMMY_SELECTED_PROVIDERS,
+ )
+ )
onNodeWithText("Ownership").assertExists()
onNodeWithText("Providers").assertExists()
}
@@ -44,17 +62,14 @@ class FilterScreenTest {
@Test
fun testIsAnyCellShowing() =
composeExtension.use {
- setContentWithTheme {
- FilterScreen(
- state =
- RelayFilterUiState(
- allProviders = DUMMY_RELAY_ALL_PROVIDERS,
- selectedOwnership = null,
- selectedProviders = DUMMY_SELECTED_PROVIDERS,
- ),
- onSelectedProvider = { _, _ -> },
- )
- }
+ initScreen(
+ state =
+ RelayFilterUiState(
+ allProviders = DUMMY_RELAY_ALL_PROVIDERS,
+ selectedOwnership = null,
+ selectedProviders = DUMMY_SELECTED_PROVIDERS,
+ )
+ )
onNodeWithText("Ownership").performClick()
onNodeWithText("Any").assertExists()
}
@@ -62,17 +77,14 @@ class FilterScreenTest {
@Test
fun testIsMullvadCellShowing() =
composeExtension.use {
- setContentWithTheme {
- FilterScreen(
- state =
- RelayFilterUiState(
- allProviders = DUMMY_RELAY_ALL_PROVIDERS,
- selectedOwnership = Ownership.MullvadOwned,
- selectedProviders = DUMMY_SELECTED_PROVIDERS,
- ),
- onSelectedProvider = { _, _ -> },
- )
- }
+ initScreen(
+ state =
+ RelayFilterUiState(
+ allProviders = DUMMY_RELAY_ALL_PROVIDERS,
+ selectedOwnership = Ownership.MullvadOwned,
+ selectedProviders = DUMMY_SELECTED_PROVIDERS,
+ )
+ )
onNodeWithText("Ownership").performClick()
onNodeWithText("Mullvad owned only").assertExists()
}
@@ -80,17 +92,14 @@ class FilterScreenTest {
@Test
fun testIsRentedCellShowing() =
composeExtension.use {
- setContentWithTheme {
- FilterScreen(
- state =
- RelayFilterUiState(
- allProviders = DUMMY_RELAY_ALL_PROVIDERS,
- selectedOwnership = Ownership.Rented,
- selectedProviders = DUMMY_SELECTED_PROVIDERS,
- ),
- onSelectedProvider = { _, _ -> },
- )
- }
+ initScreen(
+ state =
+ RelayFilterUiState(
+ allProviders = DUMMY_RELAY_ALL_PROVIDERS,
+ selectedOwnership = Ownership.Rented,
+ selectedProviders = DUMMY_SELECTED_PROVIDERS,
+ )
+ )
onNodeWithText("Ownership").performClick()
onNodeWithText("Rented only").assertExists()
}
@@ -98,17 +107,14 @@ class FilterScreenTest {
@Test
fun testShowProviders() =
composeExtension.use {
- setContentWithTheme {
- FilterScreen(
- state =
- RelayFilterUiState(
- allProviders = DUMMY_RELAY_ALL_PROVIDERS,
- selectedOwnership = null,
- selectedProviders = DUMMY_SELECTED_PROVIDERS,
- ),
- onSelectedProvider = { _, _ -> },
- )
- }
+ initScreen(
+ state =
+ RelayFilterUiState(
+ allProviders = DUMMY_RELAY_ALL_PROVIDERS,
+ selectedOwnership = null,
+ selectedProviders = DUMMY_SELECTED_PROVIDERS,
+ )
+ )
onNodeWithText("Providers").performClick()
onNodeWithText("Creanova").assertExists()
@@ -119,19 +125,16 @@ class FilterScreenTest {
fun testApplyButtonClick() =
composeExtension.use {
val mockClickListener: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- FilterScreen(
- state =
- RelayFilterUiState(
- allProviders = listOf(),
- selectedOwnership = null,
- selectedProviders =
- listOf(Provider(ProviderId("31173"), Ownership.MullvadOwned)),
- ),
- onSelectedProvider = { _, _ -> },
- onApplyClick = mockClickListener,
- )
- }
+ initScreen(
+ state =
+ RelayFilterUiState(
+ allProviders = listOf(),
+ selectedOwnership = null,
+ selectedProviders =
+ listOf(Provider(ProviderId("31173"), Ownership.MullvadOwned)),
+ ),
+ onApplyClick = mockClickListener,
+ )
onNodeWithText("Apply").performClick()
verify { mockClickListener() }
}
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreenTest.kt
index 4294577836..ce683cc7fd 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreenTest.kt
@@ -1,9 +1,11 @@
package net.mullvad.mullvadvpn.compose.screen
import androidx.compose.ui.test.ExperimentalTestApi
+import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
+import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.mockk
@@ -31,20 +33,36 @@ class OutOfTimeScreenTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initScreen(
+ state: OutOfTimeUiState = OutOfTimeUiState(),
+ onDisconnectClick: () -> Unit = {},
+ onSitePaymentClick: () -> Unit = {},
+ onRedeemVoucherClick: () -> Unit = {},
+ onSettingsClick: () -> Unit = {},
+ onAccountClick: () -> Unit = {},
+ onPurchaseBillingProductClick: (ProductId) -> Unit = {},
+ navigateToVerificationPendingDialog: () -> Unit = {},
+ ) {
+
+ setContentWithTheme {
+ OutOfTimeScreen(
+ state = state,
+ onDisconnectClick = onDisconnectClick,
+ onSitePaymentClick = onSitePaymentClick,
+ onRedeemVoucherClick = onRedeemVoucherClick,
+ onSettingsClick = onSettingsClick,
+ onAccountClick = onAccountClick,
+ onPurchaseBillingProductClick = onPurchaseBillingProductClick,
+ navigateToVerificationPendingDialog = navigateToVerificationPendingDialog,
+ )
+ }
+ }
+
@Test
fun testDisableSitePayment() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- OutOfTimeScreen(
- state = OutOfTimeUiState(deviceName = ""),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onDisconnectClick = {},
- )
- }
+ initScreen(state = OutOfTimeUiState(deviceName = ""))
// Assert
onNodeWithText(
@@ -58,20 +76,18 @@ class OutOfTimeScreenTest {
@Test
fun testOpenAccountView() =
composeExtension.use {
+ val mockClickListener: () -> Unit = mockk(relaxed = true)
+
// Arrange
- setContentWithTheme {
- OutOfTimeScreen(
- state = OutOfTimeUiState(deviceName = "", showSitePayment = true),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onDisconnectClick = {},
- )
- }
+ initScreen(
+ state = OutOfTimeUiState(deviceName = "", showSitePayment = true),
+ onAccountClick = mockClickListener,
+ )
+
+ onNodeWithContentDescription(label = "Account").performClick()
// Assert
- onNodeWithText("Congrats!").assertDoesNotExist()
+ verify(exactly = 1) { mockClickListener.invoke() }
}
@Test
@@ -79,16 +95,10 @@ class OutOfTimeScreenTest {
composeExtension.use {
// Arrange
val mockClickListener: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- OutOfTimeScreen(
- state = OutOfTimeUiState(deviceName = "", showSitePayment = true),
- onSitePaymentClick = mockClickListener,
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onDisconnectClick = {},
- )
- }
+ initScreen(
+ state = OutOfTimeUiState(deviceName = "", showSitePayment = true),
+ onSitePaymentClick = mockClickListener,
+ )
// Act
onNodeWithText("Buy credit").performClick()
@@ -102,16 +112,10 @@ class OutOfTimeScreenTest {
composeExtension.use {
// Arrange
val mockClickListener: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- OutOfTimeScreen(
- state = OutOfTimeUiState(deviceName = "", showSitePayment = true),
- onSitePaymentClick = {},
- onRedeemVoucherClick = mockClickListener,
- onSettingsClick = {},
- onAccountClick = {},
- onDisconnectClick = {},
- )
- }
+ initScreen(
+ state = OutOfTimeUiState(deviceName = "", showSitePayment = true),
+ onRedeemVoucherClick = mockClickListener,
+ )
// Act
onNodeWithText("Redeem voucher").performClick()
@@ -125,21 +129,15 @@ class OutOfTimeScreenTest {
composeExtension.use {
// Arrange
val mockClickListener: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- OutOfTimeScreen(
- state =
- OutOfTimeUiState(
- tunnelState = TunnelState.Connecting(null, null, emptyList()),
- deviceName = "",
- showSitePayment = true,
- ),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onDisconnectClick = mockClickListener,
- )
- }
+ initScreen(
+ state =
+ OutOfTimeUiState(
+ tunnelState = TunnelState.Connecting(null, null, emptyList()),
+ deviceName = "",
+ showSitePayment = true,
+ ),
+ onDisconnectClick = mockClickListener,
+ )
// Act
onNodeWithText("Disconnect").performClick()
@@ -152,20 +150,13 @@ class OutOfTimeScreenTest {
fun testShowBillingErrorPaymentButton() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- OutOfTimeScreen(
- state =
- OutOfTimeUiState(
- showSitePayment = true,
- billingPaymentState = PaymentState.Error.Billing,
- ),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = { _ -> },
- )
- }
+ initScreen(
+ state =
+ OutOfTimeUiState(
+ showSitePayment = true,
+ billingPaymentState = PaymentState.Error.Billing,
+ )
+ )
// Assert
onNodeWithText("Add 30 days time").assertExists()
@@ -178,21 +169,14 @@ class OutOfTimeScreenTest {
val mockPaymentProduct: PaymentProduct = mockk()
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.status } returns null
- setContentWithTheme {
- OutOfTimeScreen(
- state =
- OutOfTimeUiState(
- showSitePayment = true,
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct)),
- ),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = { _ -> },
- )
- }
+ initScreen(
+ state =
+ OutOfTimeUiState(
+ showSitePayment = true,
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct)),
+ )
+ )
// Assert
onNodeWithText("Add 30 days time ($10)").assertExists()
@@ -205,16 +189,14 @@ class OutOfTimeScreenTest {
val mockPaymentProduct: PaymentProduct = mockk()
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.status } returns PaymentStatus.PENDING
- setContentWithTheme {
- OutOfTimeScreen(
- state =
- OutOfTimeUiState(
- showSitePayment = true,
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct)),
- )
- )
- }
+ initScreen(
+ state =
+ OutOfTimeUiState(
+ showSitePayment = true,
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct)),
+ )
+ )
// Assert
onNodeWithText("Google Play payment pending").assertExists()
@@ -228,17 +210,15 @@ class OutOfTimeScreenTest {
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.status } returns PaymentStatus.PENDING
val mockNavigateToVerificationPending: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- OutOfTimeScreen(
- state =
- OutOfTimeUiState(
- showSitePayment = true,
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct)),
- ),
- navigateToVerificationPendingDialog = mockNavigateToVerificationPending,
- )
- }
+ initScreen(
+ state =
+ OutOfTimeUiState(
+ showSitePayment = true,
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct)),
+ ),
+ navigateToVerificationPendingDialog = mockNavigateToVerificationPending,
+ )
// Act
onNodeWithTag(PLAY_PAYMENT_INFO_ICON_TEST_TAG).performClick()
@@ -255,16 +235,14 @@ class OutOfTimeScreenTest {
val mockPaymentProduct: PaymentProduct = mockk()
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.status } returns PaymentStatus.VERIFICATION_IN_PROGRESS
- setContentWithTheme {
- OutOfTimeScreen(
- state =
- OutOfTimeUiState(
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct)),
- showSitePayment = true,
- )
- )
- }
+ initScreen(
+ state =
+ OutOfTimeUiState(
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct)),
+ showSitePayment = true,
+ )
+ )
// Assert
onNodeWithText("Verifying purchase").assertExists()
@@ -279,21 +257,15 @@ class OutOfTimeScreenTest {
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.productId } returns ProductId("PRODUCT_ID")
every { mockPaymentProduct.status } returns null
- setContentWithTheme {
- OutOfTimeScreen(
- state =
- OutOfTimeUiState(
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct)),
- showSitePayment = true,
- ),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = clickHandler,
- )
- }
+ initScreen(
+ state =
+ OutOfTimeUiState(
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct)),
+ showSitePayment = true,
+ ),
+ onPurchaseBillingProductClick = clickHandler,
+ )
// Act
onNodeWithText("Add 30 days time ($10)").performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ServerIpOverridesScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ServerIpOverridesScreenTest.kt
index 8d33d848f1..0b11616184 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ServerIpOverridesScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ServerIpOverridesScreenTest.kt
@@ -1,10 +1,10 @@
package net.mullvad.mullvadvpn.compose.screen
-import androidx.compose.runtime.Composable
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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
@@ -30,9 +30,7 @@ class ServerIpOverridesScreenTest {
MockKAnnotations.init(this)
}
- @Suppress("TestFunctionName")
- @Composable
- private fun ScreenWithDefault(
+ private fun ComposeContext.initScreen(
state: ServerIpOverridesUiState,
onBackClick: () -> Unit = {},
onInfoClick: () -> Unit = {},
@@ -40,43 +38,43 @@ class ServerIpOverridesScreenTest {
onImportByFile: () -> Unit = {},
onImportByText: () -> Unit = {},
) {
- ServerIpOverridesScreen(
- state = state,
- onBackClick = onBackClick,
- onInfoClick = onInfoClick,
- onResetOverridesClick = onResetOverridesClick,
- onImportByFile = onImportByFile,
- onImportByText = onImportByText,
- )
+ setContentWithTheme {
+ ServerIpOverridesScreen(
+ state = state,
+ onBackClick = onBackClick,
+ onInfoClick = onInfoClick,
+ onResetOverridesClick = onResetOverridesClick,
+ onImportByFile = onImportByFile,
+ onImportByText = onImportByText,
+ )
+ }
}
@Test
- fun ensure_overrides_inactive_is_displayed() =
+ fun ensureOverridesInactiveIsDisplayed() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- ScreenWithDefault(state = ServerIpOverridesUiState.Loaded(false))
- }
+ initScreen(state = ServerIpOverridesUiState.Loaded(false))
// Assert
onNodeWithText("Overrides inactive").assertExists()
}
@Test
- fun ensure_overrides_active_is_displayed() =
+ fun ensureOverridesActiveIsDisplayed() =
composeExtension.use {
// Arrange
- setContentWithTheme { ScreenWithDefault(state = ServerIpOverridesUiState.Loaded(true)) }
+ initScreen(state = ServerIpOverridesUiState.Loaded(true))
// Assert
onNodeWithText("Overrides active").assertExists()
}
@Test
- fun ensure_overrides_active_shows_warning_on_import() =
+ fun ensureOverridesActiveShowsWarningOnImport() =
composeExtension.use {
// Arrange
- setContentWithTheme { ScreenWithDefault(state = ServerIpOverridesUiState.Loaded(true)) }
+ initScreen(state = ServerIpOverridesUiState.Loaded(true))
// Act
onNodeWithTag(testTag = SERVER_IP_OVERRIDE_IMPORT_TEST_TAG).performClick()
@@ -89,16 +87,11 @@ class ServerIpOverridesScreenTest {
}
@Test
- fun ensure_info_click_works() =
+ fun ensureInfoClickWorks() =
composeExtension.use {
// Arrange
val clickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ScreenWithDefault(
- state = ServerIpOverridesUiState.Loaded(false),
- onInfoClick = clickHandler,
- )
- }
+ initScreen(state = ServerIpOverridesUiState.Loaded(false), onInfoClick = clickHandler)
// Act
onNodeWithTag(SERVER_IP_OVERRIDE_INFO_TEST_TAG).performClick()
@@ -108,16 +101,14 @@ class ServerIpOverridesScreenTest {
}
@Test
- fun ensure_reset_click_works() =
+ fun ensureResetClickWorks() =
composeExtension.use {
// Arrange
val clickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ScreenWithDefault(
- state = ServerIpOverridesUiState.Loaded(true),
- onResetOverridesClick = clickHandler,
- )
- }
+ initScreen(
+ state = ServerIpOverridesUiState.Loaded(true),
+ onResetOverridesClick = clickHandler,
+ )
// Act
onNodeWithTag(SERVER_IP_OVERRIDE_MORE_VERT_TEST_TAG).performClick()
@@ -128,16 +119,14 @@ class ServerIpOverridesScreenTest {
}
@Test
- fun ensure_import_by_file_works() =
+ fun ensureImportByFileWorks() =
composeExtension.use {
// Arrange
val clickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ScreenWithDefault(
- state = ServerIpOverridesUiState.Loaded(false),
- onImportByFile = clickHandler,
- )
- }
+ initScreen(
+ state = ServerIpOverridesUiState.Loaded(false),
+ onImportByFile = clickHandler,
+ )
// Act
onNodeWithTag(SERVER_IP_OVERRIDE_IMPORT_TEST_TAG).performClick()
@@ -148,16 +137,14 @@ class ServerIpOverridesScreenTest {
}
@Test
- fun ensure_import_by_text() =
+ fun ensureImportByText() =
composeExtension.use {
// Arrange
val clickHandler: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ScreenWithDefault(
- state = ServerIpOverridesUiState.Loaded(false),
- onImportByText = clickHandler,
- )
- }
+ initScreen(
+ state = ServerIpOverridesUiState.Loaded(false),
+ onImportByText = clickHandler,
+ )
// Act
onNodeWithTag(SERVER_IP_OVERRIDE_IMPORT_TEST_TAG).performClick()
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 464fa1181a..b343c44c95 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
@@ -3,6 +3,7 @@ package net.mullvad.mullvadvpn.compose.screen
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithText
+import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
import net.mullvad.mullvadvpn.compose.setContentWithTheme
@@ -20,24 +21,48 @@ class SettingsScreenTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initScreen(
+ state: SettingsUiState,
+ onVpnSettingCellClick: () -> Unit = {},
+ onSplitTunnelingCellClick: () -> Unit = {},
+ onAppInfoClick: () -> Unit = {},
+ onReportProblemCellClick: () -> Unit = {},
+ onApiAccessClick: () -> Unit = {},
+ onMultihopClick: () -> Unit = {},
+ onDaitaClick: () -> Unit = {},
+ onBackClick: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ SettingsScreen(
+ state = state,
+ onVpnSettingCellClick = onVpnSettingCellClick,
+ onSplitTunnelingCellClick = onSplitTunnelingCellClick,
+ onAppInfoClick = onAppInfoClick,
+ onReportProblemCellClick = onReportProblemCellClick,
+ onApiAccessClick = onApiAccessClick,
+ onMultihopClick = onMultihopClick,
+ onDaitaClick = onDaitaClick,
+ onBackClick = onBackClick,
+ )
+ }
+ }
+
@Test
@OptIn(ExperimentalMaterial3Api::class)
fun testLoggedInState() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- SettingsScreen(
- state =
- SettingsUiState(
- appVersion = "",
- isLoggedIn = true,
- isSupportedVersion = true,
- isPlayBuild = false,
- multihopEnabled = false,
- isDaitaEnabled = false,
- )
- )
- }
+ initScreen(
+ state =
+ SettingsUiState(
+ appVersion = "",
+ isLoggedIn = true,
+ isSupportedVersion = true,
+ isPlayBuild = false,
+ multihopEnabled = false,
+ isDaitaEnabled = false,
+ )
+ )
// Assert
onNodeWithText("VPN settings").assertExists()
onNodeWithText("Split tunneling").assertExists()
@@ -50,19 +75,17 @@ class SettingsScreenTest {
fun testLoggedOutState() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- SettingsScreen(
- state =
- SettingsUiState(
- appVersion = "",
- isLoggedIn = false,
- isSupportedVersion = true,
- isPlayBuild = false,
- multihopEnabled = false,
- isDaitaEnabled = false,
- )
- )
- }
+ initScreen(
+ state =
+ SettingsUiState(
+ appVersion = "",
+ isLoggedIn = false,
+ isSupportedVersion = true,
+ isPlayBuild = false,
+ multihopEnabled = false,
+ isDaitaEnabled = false,
+ )
+ )
// Assert
onNodeWithText("VPN settings").assertDoesNotExist()
onNodeWithText("Split tunneling").assertDoesNotExist()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ShadowsocksSettingsScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ShadowsocksSettingsScreenTest.kt
index 23d94f58c6..1340e96c58 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ShadowsocksSettingsScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/ShadowsocksSettingsScreenTest.kt
@@ -4,6 +4,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.mockk
import io.mockk.verify
import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
@@ -19,13 +20,27 @@ import org.junit.jupiter.api.extension.RegisterExtension
class ShadowsocksSettingsScreenTest {
@JvmField @RegisterExtension val composeExtension = createEdgeToEdgeComposeExtension()
+ private fun ComposeContext.initScreen(
+ state: ShadowsocksSettingsState = ShadowsocksSettingsState(),
+ navigateToCustomPortDialog: () -> Unit = {},
+ onObfuscationPortSelected: (Constraint<Port>) -> Unit = {},
+ onBackClick: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ ShadowsocksSettingsScreen(
+ state = state,
+ navigateToCustomPortDialog = navigateToCustomPortDialog,
+ onObfuscationPortSelected = onObfuscationPortSelected,
+ onBackClick = onBackClick,
+ )
+ }
+ }
+
@Test
fun testShowShadowsocksCustomPort() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- ShadowsocksSettingsScreen(state = ShadowsocksSettingsState(customPort = Port(4000)))
- }
+ initScreen(state = ShadowsocksSettingsState(customPort = Port(4000)))
// Assert
onNodeWithText("4000").assertExists()
@@ -36,16 +51,14 @@ class ShadowsocksSettingsScreenTest {
composeExtension.use {
// Arrange
val onObfuscationPortSelected: (Constraint<Port>) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- ShadowsocksSettingsScreen(
- state =
- ShadowsocksSettingsState(
- port = Constraint.Only(Port(4000)),
- customPort = Port(4000),
- ),
- onObfuscationPortSelected = onObfuscationPortSelected,
- )
- }
+ initScreen(
+ state =
+ ShadowsocksSettingsState(
+ port = Constraint.Only(Port(4000)),
+ customPort = Port(4000),
+ ),
+ onObfuscationPortSelected = onObfuscationPortSelected,
+ )
// Act
onNodeWithTag(testTag = SHADOWSOCKS_CUSTOM_PORT_TEXT_TEST_TAG).performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreenTest.kt
index 500349c861..8215ccde69 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreenTest.kt
@@ -1,8 +1,10 @@
package net.mullvad.mullvadvpn.compose.screen
+import android.graphics.Bitmap
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
+import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.unmockkAll
@@ -30,13 +32,33 @@ class SplitTunnelingScreenTest {
unmockkAll()
}
+ private fun ComposeContext.initScreen(
+ state: SplitTunnelingUiState,
+ onEnableSplitTunneling: (Boolean) -> Unit = {},
+ onShowSystemAppsClick: (show: Boolean) -> Unit = {},
+ onExcludeAppClick: (packageName: String) -> Unit = {},
+ onIncludeAppClick: (packageName: String) -> Unit = {},
+ onBackClick: () -> Unit = {},
+ onResolveIcon: (String) -> Bitmap? = { null },
+ ) {
+ setContentWithTheme {
+ SplitTunnelingScreen(
+ state = state,
+ onEnableSplitTunneling = onEnableSplitTunneling,
+ onShowSystemAppsClick = onShowSystemAppsClick,
+ onExcludeAppClick = onExcludeAppClick,
+ onIncludeAppClick = onIncludeAppClick,
+ onBackClick = onBackClick,
+ onResolveIcon = onResolveIcon,
+ )
+ }
+ }
+
@Test
fun testLoadingState() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- SplitTunnelingScreen(state = SplitTunnelingUiState.Loading(enabled = true))
- }
+ initScreen(state = SplitTunnelingUiState.Loading(enabled = true))
// Assert
onNodeWithText(TITLE).assertExists()
@@ -62,17 +84,15 @@ class SplitTunnelingScreenTest {
iconRes = 0,
name = INCLUDED_APP_NAME,
)
- setContentWithTheme {
- SplitTunnelingScreen(
- state =
- SplitTunnelingUiState.ShowAppList(
- enabled = true,
- excludedApps = listOf(excludedApp),
- includedApps = listOf(includedApp),
- showSystemApps = false,
- )
- )
- }
+ initScreen(
+ state =
+ SplitTunnelingUiState.ShowAppList(
+ enabled = true,
+ excludedApps = listOf(excludedApp),
+ includedApps = listOf(includedApp),
+ showSystemApps = false,
+ )
+ )
// Assert
onNodeWithText(TITLE).assertExists()
@@ -94,17 +114,15 @@ class SplitTunnelingScreenTest {
iconRes = 0,
name = INCLUDED_APP_NAME,
)
- setContentWithTheme {
- SplitTunnelingScreen(
- state =
- SplitTunnelingUiState.ShowAppList(
- enabled = true,
- excludedApps = emptyList(),
- includedApps = listOf(includedApp),
- showSystemApps = false,
- )
- )
- }
+ initScreen(
+ state =
+ SplitTunnelingUiState.ShowAppList(
+ enabled = true,
+ excludedApps = emptyList(),
+ includedApps = listOf(includedApp),
+ showSystemApps = false,
+ )
+ )
// Assert
onNodeWithText(TITLE).assertExists()
@@ -133,18 +151,16 @@ class SplitTunnelingScreenTest {
name = INCLUDED_APP_NAME,
)
val mockedClickHandler: (String) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- SplitTunnelingScreen(
- state =
- SplitTunnelingUiState.ShowAppList(
- enabled = true,
- excludedApps = listOf(excludedApp),
- includedApps = listOf(includedApp),
- showSystemApps = false,
- ),
- onExcludeAppClick = mockedClickHandler,
- )
- }
+ initScreen(
+ state =
+ SplitTunnelingUiState.ShowAppList(
+ enabled = true,
+ excludedApps = listOf(excludedApp),
+ includedApps = listOf(includedApp),
+ showSystemApps = false,
+ ),
+ onExcludeAppClick = mockedClickHandler,
+ )
// Act
onNodeWithText(INCLUDED_APP_NAME).performClick()
@@ -170,18 +186,16 @@ class SplitTunnelingScreenTest {
name = INCLUDED_APP_NAME,
)
val mockedClickHandler: (String) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- SplitTunnelingScreen(
- state =
- SplitTunnelingUiState.ShowAppList(
- enabled = true,
- excludedApps = listOf(excludedApp),
- includedApps = listOf(includedApp),
- showSystemApps = false,
- ),
- onIncludeAppClick = mockedClickHandler,
- )
- }
+ initScreen(
+ state =
+ SplitTunnelingUiState.ShowAppList(
+ enabled = true,
+ excludedApps = listOf(excludedApp),
+ includedApps = listOf(includedApp),
+ showSystemApps = false,
+ ),
+ onIncludeAppClick = mockedClickHandler,
+ )
// Act
onNodeWithText(EXCLUDED_APP_NAME).performClick()
@@ -207,18 +221,16 @@ class SplitTunnelingScreenTest {
name = INCLUDED_APP_NAME,
)
val mockedClickHandler: (Boolean) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- SplitTunnelingScreen(
- state =
- SplitTunnelingUiState.ShowAppList(
- enabled = true,
- excludedApps = listOf(excludedApp),
- includedApps = listOf(includedApp),
- showSystemApps = false,
- ),
- onShowSystemAppsClick = mockedClickHandler,
- )
- }
+ initScreen(
+ state =
+ SplitTunnelingUiState.ShowAppList(
+ enabled = true,
+ excludedApps = listOf(excludedApp),
+ includedApps = listOf(includedApp),
+ showSystemApps = false,
+ ),
+ onShowSystemAppsClick = mockedClickHandler,
+ )
// Act
onNodeWithText(SHOW_SYSTEM_APPS).performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/Udp2TcpSettingsScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/Udp2TcpSettingsScreenTest.kt
index 77b9965b26..1c16ff0bd1 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/Udp2TcpSettingsScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/Udp2TcpSettingsScreenTest.kt
@@ -2,6 +2,7 @@ package net.mullvad.mullvadvpn.compose.screen
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.performClick
+import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.coVerify
import io.mockk.mockk
import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
@@ -18,17 +19,31 @@ import org.junit.jupiter.api.extension.RegisterExtension
class Udp2TcpSettingsScreenTest {
@JvmField @RegisterExtension val composeExtension = createEdgeToEdgeComposeExtension()
+ private fun ComposeContext.initScreen(
+ state: Udp2TcpSettingsState = Udp2TcpSettingsState(),
+ onObfuscationPortSelected: (Constraint<Port>) -> Unit = {},
+ navigateUdp2TcpInfo: () -> Unit = {},
+ onBackClick: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ Udp2TcpSettingsScreen(
+ state = state,
+ onObfuscationPortSelected = onObfuscationPortSelected,
+ navigateUdp2TcpInfo = navigateUdp2TcpInfo,
+ onBackClick = onBackClick,
+ )
+ }
+ }
+
@Test
fun testSelectTcpOverUdpPortOption() =
composeExtension.use {
// Arrange
val onObfuscationPortSelected: (Constraint<Port>) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- Udp2TcpSettingsScreen(
- state = Udp2TcpSettingsState(port = Constraint.Any),
- onObfuscationPortSelected = onObfuscationPortSelected,
- )
- }
+ initScreen(
+ state = Udp2TcpSettingsState(port = Constraint.Any),
+ onObfuscationPortSelected = onObfuscationPortSelected,
+ )
// Act
onNodeWithTagAndText(
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt
index 19802571f6..43c5559a38 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt
@@ -7,6 +7,7 @@ import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollToNode
+import de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.verify
@@ -23,6 +24,7 @@ import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_WIREGUARD_OBFUSCATION_TITLE
import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_WIREGUARD_PORT_ITEM_X_TEST_TAG
import net.mullvad.mullvadvpn.lib.model.Constraint
import net.mullvad.mullvadvpn.lib.model.Mtu
+import net.mullvad.mullvadvpn.lib.model.ObfuscationMode
import net.mullvad.mullvadvpn.lib.model.Port
import net.mullvad.mullvadvpn.lib.model.PortRange
import net.mullvad.mullvadvpn.lib.model.QuantumResistantState
@@ -41,11 +43,75 @@ class VpnSettingsScreenTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initScreen(
+ state: VpnSettingsUiState = VpnSettingsUiState.createDefault(),
+ navigateToContentBlockersInfo: () -> Unit = {},
+ navigateToAutoConnectScreen: () -> Unit = {},
+ navigateToCustomDnsInfo: () -> Unit = {},
+ navigateToMalwareInfo: () -> Unit = {},
+ navigateToObfuscationInfo: () -> Unit = {},
+ navigateToQuantumResistanceInfo: () -> Unit = {},
+ navigateToWireguardPortInfo: (availablePortRanges: List<PortRange>) -> Unit = {},
+ navigateToLocalNetworkSharingInfo: () -> Unit = {},
+ navigateToWireguardPortDialog: () -> Unit = {},
+ navigateToServerIpOverrides: () -> Unit = {},
+ onToggleBlockTrackers: (Boolean) -> Unit = {},
+ onToggleBlockAds: (Boolean) -> Unit = {},
+ onToggleBlockMalware: (Boolean) -> Unit = {},
+ onToggleLocalNetworkSharing: (Boolean) -> Unit = {},
+ onToggleBlockAdultContent: (Boolean) -> Unit = {},
+ onToggleBlockGambling: (Boolean) -> Unit = {},
+ onToggleBlockSocialMedia: (Boolean) -> Unit = {},
+ navigateToMtuDialog: (mtu: Mtu?) -> Unit = {},
+ navigateToDns: (index: Int?, address: String?) -> Unit = { _, _ -> },
+ onToggleDnsClick: (Boolean) -> Unit = {},
+ onBackClick: () -> Unit = {},
+ onSelectObfuscationMode: (obfuscationMode: ObfuscationMode) -> Unit = {},
+ onSelectQuantumResistanceSetting: (quantumResistant: QuantumResistantState) -> Unit = {},
+ onWireguardPortSelected: (port: Constraint<Port>) -> Unit = {},
+ navigateToShadowSocksSettings: () -> Unit = {},
+ navigateToUdp2TcpSettings: () -> Unit = {},
+ onToggleAutoStartAndConnectOnBoot: (Boolean) -> Unit = {},
+ ) {
+ setContentWithTheme {
+ VpnSettingsScreen(
+ state = state,
+ navigateToContentBlockersInfo = navigateToContentBlockersInfo,
+ navigateToAutoConnectScreen = navigateToAutoConnectScreen,
+ navigateToCustomDnsInfo = navigateToCustomDnsInfo,
+ navigateToMalwareInfo = navigateToMalwareInfo,
+ navigateToObfuscationInfo = navigateToObfuscationInfo,
+ navigateToQuantumResistanceInfo = navigateToQuantumResistanceInfo,
+ navigateToWireguardPortInfo = navigateToWireguardPortInfo,
+ navigateToLocalNetworkSharingInfo = navigateToLocalNetworkSharingInfo,
+ navigateToWireguardPortDialog = navigateToWireguardPortDialog,
+ navigateToServerIpOverrides = navigateToServerIpOverrides,
+ onToggleBlockTrackers = onToggleBlockTrackers,
+ onToggleBlockAds = onToggleBlockAds,
+ onToggleBlockMalware = onToggleBlockMalware,
+ onToggleLocalNetworkSharing = onToggleLocalNetworkSharing,
+ onToggleBlockAdultContent = onToggleBlockAdultContent,
+ onToggleBlockGambling = onToggleBlockGambling,
+ onToggleBlockSocialMedia = onToggleBlockSocialMedia,
+ navigateToMtuDialog = navigateToMtuDialog,
+ navigateToDns = navigateToDns,
+ onToggleDnsClick = onToggleDnsClick,
+ onBackClick = onBackClick,
+ onSelectObfuscationMode = onSelectObfuscationMode,
+ onSelectQuantumResistanceSetting = onSelectQuantumResistanceSetting,
+ onWireguardPortSelected = onWireguardPortSelected,
+ navigateToShadowSocksSettings = navigateToShadowSocksSettings,
+ navigateToUdp2TcpSettings = navigateToUdp2TcpSettings,
+ onToggleAutoStartAndConnectOnBoot = onToggleAutoStartAndConnectOnBoot,
+ )
+ }
+ }
+
@Test
fun testDefaultState() =
composeExtension.use {
// Arrange
- setContentWithTheme { VpnSettingsScreen(state = VpnSettingsUiState.createDefault()) }
+ initScreen(state = VpnSettingsUiState.createDefault())
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
.performScrollToNode(hasTestTag(LAZY_LIST_LAST_ITEM_TEST_TAG))
@@ -61,14 +127,12 @@ class VpnSettingsScreenTest {
fun testMtuCustomValue() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- mtu = Mtu.fromString(VALID_DUMMY_MTU_VALUE).getOrNull()!!
- )
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(
+ mtu = Mtu.fromString(VALID_DUMMY_MTU_VALUE).getOrNull()!!
+ )
+ )
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
.performScrollToNode(hasTestTag(LAZY_LIST_LAST_ITEM_TEST_TAG))
@@ -81,20 +145,18 @@ class VpnSettingsScreenTest {
fun testCustomDnsAddressesAndAddButtonVisibleWhenCustomDnsEnabled() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- isCustomDnsEnabled = true,
- customDnsItems =
- listOf(
- CustomDnsItem(address = DUMMY_DNS_ADDRESS, false),
- CustomDnsItem(address = DUMMY_DNS_ADDRESS_2, false),
- CustomDnsItem(address = DUMMY_DNS_ADDRESS_3, false),
- ),
- )
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(
+ isCustomDnsEnabled = true,
+ customDnsItems =
+ listOf(
+ CustomDnsItem(address = DUMMY_DNS_ADDRESS, false),
+ CustomDnsItem(address = DUMMY_DNS_ADDRESS_2, false),
+ CustomDnsItem(address = DUMMY_DNS_ADDRESS_3, false),
+ ),
+ )
+ )
// Assert
onNodeWithText(DUMMY_DNS_ADDRESS).assertExists()
@@ -107,16 +169,13 @@ class VpnSettingsScreenTest {
fun testCustomDnsAddressesAndAddButtonNotVisibleWhenCustomDnsDisabled() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- isCustomDnsEnabled = false,
- customDnsItems =
- listOf(CustomDnsItem(address = DUMMY_DNS_ADDRESS, false)),
- )
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(
+ isCustomDnsEnabled = false,
+ customDnsItems = listOf(CustomDnsItem(address = DUMMY_DNS_ADDRESS, false)),
+ )
+ )
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
.performScrollToNode(hasTestTag(LAZY_LIST_LAST_ITEM_TEST_TAG))
// Assert
@@ -128,17 +187,15 @@ class VpnSettingsScreenTest {
fun testLanWarningNotShownWhenLanTrafficEnabledAndLocalAddressIsUsed() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- isCustomDnsEnabled = true,
- isLocalNetworkSharingEnabled = true,
- customDnsItems =
- listOf(CustomDnsItem(address = DUMMY_DNS_ADDRESS, isLocal = true)),
- )
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(
+ isCustomDnsEnabled = true,
+ isLocalNetworkSharingEnabled = true,
+ customDnsItems =
+ listOf(CustomDnsItem(address = DUMMY_DNS_ADDRESS, isLocal = true)),
+ )
+ )
// Assert
onNodeWithContentDescription(LOCAL_DNS_SERVER_WARNING).assertDoesNotExist()
@@ -148,16 +205,14 @@ class VpnSettingsScreenTest {
fun testLanWarningNotShowedWhenLanTrafficDisabledAndLocalAddressIsNotUsed() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- isCustomDnsEnabled = true,
- customDnsItems =
- listOf(CustomDnsItem(address = DUMMY_DNS_ADDRESS, isLocal = false)),
- )
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(
+ isCustomDnsEnabled = true,
+ customDnsItems =
+ listOf(CustomDnsItem(address = DUMMY_DNS_ADDRESS, isLocal = false)),
+ )
+ )
// Assert
onNodeWithContentDescription(LOCAL_DNS_SERVER_WARNING).assertDoesNotExist()
@@ -167,16 +222,14 @@ class VpnSettingsScreenTest {
fun testLanWarningNotShowedWhenLanTrafficEnabledAndLocalAddressIsNotUsed() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- isCustomDnsEnabled = true,
- customDnsItems =
- listOf(CustomDnsItem(address = DUMMY_DNS_ADDRESS, isLocal = false)),
- )
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(
+ isCustomDnsEnabled = true,
+ customDnsItems =
+ listOf(CustomDnsItem(address = DUMMY_DNS_ADDRESS, isLocal = false)),
+ )
+ )
// Assert
onNodeWithContentDescription(LOCAL_DNS_SERVER_WARNING).assertDoesNotExist()
@@ -186,16 +239,14 @@ class VpnSettingsScreenTest {
fun testLanWarningShowedWhenAllowLanEnabledAndLocalDnsAddressIsUsed() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- isCustomDnsEnabled = true,
- customDnsItems =
- listOf(CustomDnsItem(address = DUMMY_DNS_ADDRESS, isLocal = true)),
- )
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(
+ isCustomDnsEnabled = true,
+ customDnsItems =
+ listOf(CustomDnsItem(address = DUMMY_DNS_ADDRESS, isLocal = true)),
+ )
+ )
// Assert
onNodeWithContentDescription(LOCAL_DNS_SERVER_WARNING).assertExists()
@@ -205,14 +256,10 @@ class VpnSettingsScreenTest {
fun testShowSelectedTunnelQuantumOption() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- quantumResistant = QuantumResistantState.On
- )
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(quantumResistant = QuantumResistantState.On)
+ )
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
.performScrollToNode(hasTestTag(LAZY_LIST_QUANTUM_ITEM_OFF_TEST_TAG))
@@ -227,15 +274,11 @@ class VpnSettingsScreenTest {
// Arrange
val mockSelectQuantumResistantSettingListener: (QuantumResistantState) -> Unit =
mockk(relaxed = true)
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- quantumResistant = QuantumResistantState.Auto
- ),
- onSelectQuantumResistanceSetting = mockSelectQuantumResistantSettingListener,
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(quantumResistant = QuantumResistantState.Auto),
+ onSelectQuantumResistanceSetting = mockSelectQuantumResistantSettingListener,
+ )
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
.performScrollToNode(hasTestTag(LAZY_LIST_QUANTUM_ITEM_OFF_TEST_TAG))
@@ -251,14 +294,12 @@ class VpnSettingsScreenTest {
fun testShowWireguardPortOptions() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- selectedWireguardPort = Constraint.Only(Port(53))
- )
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(
+ selectedWireguardPort = Constraint.Only(Port(53))
+ )
+ )
// Act
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
@@ -280,15 +321,13 @@ class VpnSettingsScreenTest {
// Arrange
val mockSelectWireguardPortSelectionListener: (Constraint<Port>) -> Unit =
mockk(relaxed = true)
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- selectedWireguardPort = Constraint.Only(Port(53))
- ),
- onWireguardPortSelected = mockSelectWireguardPortSelectionListener,
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(
+ selectedWireguardPort = Constraint.Only(Port(53))
+ ),
+ onWireguardPortSelected = mockSelectWireguardPortSelectionListener,
+ )
// Act
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
@@ -311,11 +350,7 @@ class VpnSettingsScreenTest {
fun testShowWireguardCustomPort() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state = VpnSettingsUiState.createDefault(customWireguardPort = Port(4000))
- )
- }
+ initScreen(state = VpnSettingsUiState.createDefault(customWireguardPort = Port(4000)))
// Act
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
@@ -330,16 +365,14 @@ class VpnSettingsScreenTest {
composeExtension.use {
// Arrange
val onWireguardPortSelected: (Constraint<Port>) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- selectedWireguardPort = Constraint.Only(Port(4000)),
- customWireguardPort = Port(4000),
- ),
- onWireguardPortSelected = onWireguardPortSelected,
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(
+ selectedWireguardPort = Constraint.Only(Port(4000)),
+ customWireguardPort = Port(4000),
+ ),
+ onWireguardPortSelected = onWireguardPortSelected,
+ )
// Act
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
@@ -357,12 +390,10 @@ class VpnSettingsScreenTest {
composeExtension.use {
// Arrange
val mockedClickHandler: (Mtu?) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- VpnSettingsScreen(
- state = VpnSettingsUiState.createDefault(),
- navigateToMtuDialog = mockedClickHandler,
- )
- }
+ initScreen(
+ state = VpnSettingsUiState.createDefault(),
+ navigateToMtuDialog = mockedClickHandler,
+ )
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
.performScrollToNode(hasTestTag(LAZY_LIST_LAST_ITEM_TEST_TAG))
@@ -379,12 +410,10 @@ class VpnSettingsScreenTest {
composeExtension.use {
// Arrange
val mockedClickHandler: (Int?, String?) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- VpnSettingsScreen(
- state = VpnSettingsUiState.createDefault(isCustomDnsEnabled = true),
- navigateToDns = mockedClickHandler,
- )
- }
+ initScreen(
+ state = VpnSettingsUiState.createDefault(isCustomDnsEnabled = true),
+ navigateToDns = mockedClickHandler,
+ )
// Act
onNodeWithText("Add a server").performClick()
@@ -399,12 +428,10 @@ class VpnSettingsScreenTest {
val mockedNavigateToObfuscationInfo: () -> Unit = mockk(relaxed = true)
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state = VpnSettingsUiState.createDefault(),
- navigateToObfuscationInfo = mockedNavigateToObfuscationInfo,
- )
- }
+ initScreen(
+ state = VpnSettingsUiState.createDefault(),
+ navigateToObfuscationInfo = mockedNavigateToObfuscationInfo,
+ )
// Act
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
@@ -421,15 +448,12 @@ class VpnSettingsScreenTest {
val mockedShowTunnelQuantumInfoClick: () -> Unit = mockk(relaxed = true)
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state = VpnSettingsUiState.createDefault(),
- navigateToQuantumResistanceInfo = mockedShowTunnelQuantumInfoClick,
- )
- }
+ initScreen(
+ state = VpnSettingsUiState.createDefault(),
+ navigateToQuantumResistanceInfo = mockedShowTunnelQuantumInfoClick,
+ )
// Act
-
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
.performScrollToNode(hasTestTag(LAZY_LIST_QUANTUM_ITEM_ON_TEST_TAG))
onNodeWithText("Quantum-resistant tunnel").performClick()
@@ -444,12 +468,10 @@ class VpnSettingsScreenTest {
val mockedClickHandler: (List<PortRange>) -> Unit = mockk(relaxed = true)
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state = VpnSettingsUiState.createDefault(),
- navigateToWireguardPortInfo = mockedClickHandler,
- )
- }
+ initScreen(
+ state = VpnSettingsUiState.createDefault(),
+ navigateToWireguardPortInfo = mockedClickHandler,
+ )
onNodeWithText("WireGuard port").performClick()
@@ -462,12 +484,10 @@ class VpnSettingsScreenTest {
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state = VpnSettingsUiState.createDefault(),
- navigateToWireguardPortDialog = mockedClickHandler,
- )
- }
+ initScreen(
+ state = VpnSettingsUiState.createDefault(),
+ navigateToWireguardPortDialog = mockedClickHandler,
+ )
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
.performScrollToNode(hasTestTag(LAZY_LIST_WIREGUARD_CUSTOM_PORT_NUMBER_TEST_TAG))
@@ -482,12 +502,10 @@ class VpnSettingsScreenTest {
composeExtension.use {
// Arrange
val mockOnShowCustomPortDialog: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- VpnSettingsScreen(
- state = VpnSettingsUiState.createDefault(),
- navigateToWireguardPortDialog = mockOnShowCustomPortDialog,
- )
- }
+ initScreen(
+ state = VpnSettingsUiState.createDefault(),
+ navigateToWireguardPortDialog = mockOnShowCustomPortDialog,
+ )
// Act
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
@@ -503,15 +521,13 @@ class VpnSettingsScreenTest {
composeExtension.use {
// Arrange
val mockOnShowCustomPortDialog: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- selectedWireguardPort = Constraint.Only(Port(4000))
- ),
- navigateToWireguardPortDialog = mockOnShowCustomPortDialog,
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(
+ selectedWireguardPort = Constraint.Only(Port(4000))
+ ),
+ navigateToWireguardPortDialog = mockOnShowCustomPortDialog,
+ )
// Act
onNodeWithTag(LAZY_LIST_VPN_SETTINGS_TEST_TAG)
@@ -526,11 +542,7 @@ class VpnSettingsScreenTest {
fun ensureConnectOnStartIsShownWhenSystemVpnSettingsAvailableIsFalse() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- VpnSettingsScreen(
- state = VpnSettingsUiState.createDefault(systemVpnSettingsAvailable = false)
- )
- }
+ initScreen(state = VpnSettingsUiState.createDefault(systemVpnSettingsAvailable = false))
// Assert
onNodeWithText("Connect on device start-up").assertExists()
@@ -541,16 +553,14 @@ class VpnSettingsScreenTest {
composeExtension.use {
// Arrange
val mockOnToggleAutoStartAndConnectOnBoot: (Boolean) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- VpnSettingsScreen(
- state =
- VpnSettingsUiState.createDefault(
- systemVpnSettingsAvailable = false,
- autoStartAndConnectOnBoot = false,
- ),
- onToggleAutoStartAndConnectOnBoot = mockOnToggleAutoStartAndConnectOnBoot,
- )
- }
+ initScreen(
+ state =
+ VpnSettingsUiState.createDefault(
+ systemVpnSettingsAvailable = false,
+ autoStartAndConnectOnBoot = false,
+ ),
+ onToggleAutoStartAndConnectOnBoot = mockOnToggleAutoStartAndConnectOnBoot,
+ )
// Act
onNodeWithText("Connect on device start-up").performClick()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreenTest.kt
index a9f1658308..8e9cc3fdf8 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/WelcomeScreenTest.kt
@@ -4,6 +4,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.mockk
@@ -32,23 +33,37 @@ class WelcomeScreenTest {
MockKAnnotations.init(this)
}
+ private fun ComposeContext.initScreen(
+ state: WelcomeUiState = WelcomeUiState(),
+ onSitePaymentClick: () -> Unit = {},
+ onRedeemVoucherClick: () -> Unit = {},
+ onSettingsClick: () -> Unit = {},
+ onAccountClick: () -> Unit = {},
+ onPurchaseBillingProductClick: (productId: ProductId) -> Unit = {},
+ onDisconnectClick: () -> Unit = {},
+ navigateToDeviceInfoDialog: () -> Unit = {},
+ navigateToVerificationPendingDialog: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ WelcomeScreen(
+ state = state,
+ onSitePaymentClick = onSitePaymentClick,
+ onRedeemVoucherClick = onRedeemVoucherClick,
+ onSettingsClick = onSettingsClick,
+ onAccountClick = onAccountClick,
+ onPurchaseBillingProductClick = onPurchaseBillingProductClick,
+ navigateToDeviceInfoDialog = navigateToDeviceInfoDialog,
+ navigateToVerificationPendingDialog = navigateToVerificationPendingDialog,
+ onDisconnectClick = onDisconnectClick,
+ )
+ }
+ }
+
@Test
fun testDefaultState() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- WelcomeScreen(
- state = WelcomeUiState(),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = { _ -> },
- navigateToDeviceInfoDialog = {},
- navigateToVerificationPendingDialog = {},
- onDisconnectClick = {},
- )
- }
+ initScreen()
// Assert
onNodeWithText("Congrats!").assertExists()
@@ -59,19 +74,7 @@ class WelcomeScreenTest {
fun testDisableSitePayment() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- WelcomeScreen(
- state = WelcomeUiState(),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = { _ -> },
- navigateToDeviceInfoDialog = {},
- navigateToVerificationPendingDialog = {},
- onDisconnectClick = {},
- )
- }
+ initScreen()
// Assert
onNodeWithText(
@@ -88,19 +91,7 @@ class WelcomeScreenTest {
// Arrange
val rawAccountNumber = AccountNumber("1111222233334444")
val expectedAccountNumber = "1111 2222 3333 4444"
- setContentWithTheme {
- WelcomeScreen(
- state = WelcomeUiState(accountNumber = rawAccountNumber),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = { _ -> },
- navigateToDeviceInfoDialog = {},
- navigateToVerificationPendingDialog = {},
- onDisconnectClick = {},
- )
- }
+ initScreen(state = WelcomeUiState(accountNumber = rawAccountNumber))
// Assert
onNodeWithText(expectedAccountNumber).assertExists()
@@ -111,19 +102,10 @@ class WelcomeScreenTest {
composeExtension.use {
// Arrange
val mockClickListener: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- WelcomeScreen(
- state = WelcomeUiState(showSitePayment = true),
- onSitePaymentClick = mockClickListener,
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = { _ -> },
- navigateToDeviceInfoDialog = {},
- navigateToVerificationPendingDialog = {},
- onDisconnectClick = {},
- )
- }
+ initScreen(
+ state = WelcomeUiState(showSitePayment = true),
+ onSitePaymentClick = mockClickListener,
+ )
// Act
onNodeWithText("Buy credit").performClick()
@@ -137,19 +119,7 @@ class WelcomeScreenTest {
composeExtension.use {
// Arrange
val mockClickListener: () -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- WelcomeScreen(
- state = WelcomeUiState(),
- onSitePaymentClick = {},
- onRedeemVoucherClick = mockClickListener,
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = { _ -> },
- navigateToDeviceInfoDialog = {},
- navigateToVerificationPendingDialog = {},
- onDisconnectClick = {},
- )
- }
+ initScreen(state = WelcomeUiState(), onRedeemVoucherClick = mockClickListener)
// Act
onNodeWithText("Redeem voucher").performClick()
@@ -162,19 +132,9 @@ class WelcomeScreenTest {
fun testShowBillingErrorPaymentButton() =
composeExtension.use {
// Arrange
- setContentWithTheme {
- WelcomeScreen(
- state = WelcomeUiState().copy(billingPaymentState = PaymentState.Error.Billing),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = { _ -> },
- navigateToDeviceInfoDialog = {},
- navigateToVerificationPendingDialog = {},
- onDisconnectClick = {},
- )
- }
+ initScreen(
+ state = WelcomeUiState().copy(billingPaymentState = PaymentState.Error.Billing)
+ )
// Assert
onNodeWithText("Add 30 days time").assertExists()
@@ -187,23 +147,13 @@ class WelcomeScreenTest {
val mockPaymentProduct: PaymentProduct = mockk()
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.status } returns null
- setContentWithTheme {
- WelcomeScreen(
- state =
- WelcomeUiState(
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
- ),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = { _ -> },
- navigateToDeviceInfoDialog = {},
- navigateToVerificationPendingDialog = {},
- onDisconnectClick = {},
- )
- }
+ initScreen(
+ state =
+ WelcomeUiState(
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
+ )
+ )
// Assert
onNodeWithText("Add 30 days time ($10)").assertExists()
@@ -216,24 +166,13 @@ class WelcomeScreenTest {
val mockPaymentProduct: PaymentProduct = mockk()
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.status } returns PaymentStatus.PENDING
- setContentWithTheme {
- WelcomeScreen(
- state =
- WelcomeUiState()
- .copy(
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
- ),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = { _ -> },
- navigateToDeviceInfoDialog = {},
- navigateToVerificationPendingDialog = {},
- onDisconnectClick = {},
- )
- }
+ initScreen(
+ state =
+ WelcomeUiState(
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
+ )
+ )
// Assert
onNodeWithText("Google Play payment pending").assertExists()
@@ -247,24 +186,14 @@ class WelcomeScreenTest {
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.status } returns PaymentStatus.PENDING
val mockShowPendingInfo = mockk<() -> Unit>(relaxed = true)
- setContentWithTheme {
- WelcomeScreen(
- state =
- WelcomeUiState()
- .copy(
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
- ),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = { _ -> },
- navigateToVerificationPendingDialog = mockShowPendingInfo,
- navigateToDeviceInfoDialog = {},
- onDisconnectClick = {},
- )
- }
+ initScreen(
+ state =
+ WelcomeUiState(
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
+ ),
+ navigateToVerificationPendingDialog = mockShowPendingInfo,
+ )
// Act
onNodeWithTag(PLAY_PAYMENT_INFO_ICON_TEST_TAG).performClick()
@@ -280,24 +209,14 @@ class WelcomeScreenTest {
val mockPaymentProduct: PaymentProduct = mockk()
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.status } returns PaymentStatus.VERIFICATION_IN_PROGRESS
- setContentWithTheme {
- WelcomeScreen(
- state =
- WelcomeUiState()
- .copy(
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
- ),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = { _ -> },
- navigateToDeviceInfoDialog = {},
- navigateToVerificationPendingDialog = {},
- onDisconnectClick = {},
- )
- }
+
+ initScreen(
+ state =
+ WelcomeUiState(
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
+ )
+ )
// Assert
onNodeWithText("Verifying purchase").assertExists()
@@ -312,23 +231,14 @@ class WelcomeScreenTest {
every { mockPaymentProduct.price } returns ProductPrice("$10")
every { mockPaymentProduct.productId } returns ProductId("PRODUCT_ID")
every { mockPaymentProduct.status } returns null
- setContentWithTheme {
- WelcomeScreen(
- state =
- WelcomeUiState(
- billingPaymentState =
- PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
- ),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = clickHandler,
- navigateToDeviceInfoDialog = {},
- navigateToVerificationPendingDialog = {},
- onDisconnectClick = {},
- )
- }
+ initScreen(
+ state =
+ WelcomeUiState(
+ billingPaymentState =
+ PaymentState.PaymentAvailable(listOf(mockPaymentProduct))
+ ),
+ onPurchaseBillingProductClick = clickHandler,
+ )
// Act
onNodeWithText("Add 30 days time ($10)").performClick()
@@ -344,19 +254,10 @@ class WelcomeScreenTest {
val clickHandler: () -> Unit = mockk(relaxed = true)
val tunnelState: TunnelState = mockk(relaxed = true)
every { tunnelState.isSecured() } returns true
- setContentWithTheme {
- WelcomeScreen(
- state = WelcomeUiState(tunnelState = tunnelState),
- onSitePaymentClick = {},
- onRedeemVoucherClick = {},
- onSettingsClick = {},
- onAccountClick = {},
- onPurchaseBillingProductClick = {},
- navigateToDeviceInfoDialog = {},
- navigateToVerificationPendingDialog = {},
- onDisconnectClick = clickHandler,
- )
- }
+ initScreen(
+ state = WelcomeUiState(tunnelState = tunnelState),
+ onDisconnectClick = clickHandler,
+ )
// Act
onNodeWithText("Disconnect").performClick()
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
index 5901599df9..8e87c03e13 100644
--- 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
@@ -4,6 +4,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.unmockkAll
@@ -14,6 +15,9 @@ 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 net.mullvad.mullvadvpn.lib.model.CustomListId
+import net.mullvad.mullvadvpn.lib.model.RelayItem
+import net.mullvad.mullvadvpn.lib.model.RelayItemId
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@@ -33,18 +37,57 @@ class SearchLocationScreenTest {
unmockkAll()
}
+ private fun ComposeContext.initScreen(
+ state: SearchLocationUiState,
+ onSelectRelay: (RelayItem) -> Unit = {},
+ onToggleExpand: (RelayItemId, CustomListId?, Boolean) -> Unit = { _, _, _ -> },
+ onSearchInputChanged: (String) -> Unit = {},
+ onCreateCustomList: (location: RelayItem.Location?) -> Unit = {},
+ onEditCustomLists: () -> Unit = {},
+ onAddLocationToList:
+ (location: RelayItem.Location, customList: RelayItem.CustomList) -> Unit =
+ { _, _ ->
+ },
+ onRemoveLocationFromList:
+ (location: RelayItem.Location, customListId: CustomListId) -> Unit =
+ { _, _ ->
+ },
+ onEditCustomListName: (RelayItem.CustomList) -> Unit = {},
+ onEditLocationsCustomList: (RelayItem.CustomList) -> Unit = {},
+ onDeleteCustomList: (RelayItem.CustomList) -> Unit = {},
+ onRemoveOwnershipFilter: () -> Unit = {},
+ onRemoveProviderFilter: () -> Unit = {},
+ onGoBack: () -> Unit = {},
+ ) {
+ setContentWithTheme {
+ SearchLocationScreen(
+ state = state,
+ onSelectRelay = onSelectRelay,
+ onToggleExpand = onToggleExpand,
+ onSearchInputChanged = onSearchInputChanged,
+ onCreateCustomList = onCreateCustomList,
+ onEditCustomLists = onEditCustomLists,
+ onAddLocationToList = onAddLocationToList,
+ onRemoveLocationFromList = onRemoveLocationFromList,
+ onEditCustomListName = onEditCustomListName,
+ onEditLocationsCustomList = onEditLocationsCustomList,
+ onDeleteCustomList = onDeleteCustomList,
+ onRemoveOwnershipFilter = onRemoveOwnershipFilter,
+ onRemoveProviderFilter = onRemoveProviderFilter,
+ onGoBack = onGoBack,
+ )
+ }
+ }
+
@Test
fun testSearchInput() =
composeExtension.use {
// Arrange
val mockedSearchTermInput: (String) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- SearchLocationScreen(
- state =
- SearchLocationUiState.NoQuery(searchTerm = "", filterChips = emptyList()),
- onSearchInputChanged = mockedSearchTermInput,
- )
- }
+ initScreen(
+ state = SearchLocationUiState.NoQuery(searchTerm = "", filterChips = emptyList()),
+ onSearchInputChanged = mockedSearchTermInput,
+ )
val mockSearchString = "SEARCH"
// Act
@@ -59,18 +102,15 @@ class SearchLocationScreenTest {
composeExtension.use {
// Arrange
val mockSearchString = "SEARCH"
- setContentWithTheme {
- SearchLocationScreen(
- state =
- SearchLocationUiState.Content(
- searchTerm = mockSearchString,
- filterChips = emptyList(),
- relayListItems =
- listOf(RelayListItem.LocationsEmptyText(mockSearchString)),
- customLists = emptyList(),
- )
- )
- }
+ initScreen(
+ 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")
@@ -82,17 +122,15 @@ class SearchLocationScreenTest {
composeExtension.use {
// Arrange
val mockSearchString = "SEARCH"
- setContentWithTheme {
- SearchLocationScreen(
- state =
- SearchLocationUiState.Content(
- searchTerm = mockSearchString,
- filterChips = emptyList(),
- relayListItems = emptyList(),
- customLists = DUMMY_RELAY_ITEM_CUSTOM_LISTS,
- )
- )
- }
+ initScreen(
+ state =
+ SearchLocationUiState.Content(
+ searchTerm = mockSearchString,
+ filterChips = emptyList(),
+ relayListItems = emptyList(),
+ customLists = DUMMY_RELAY_ITEM_CUSTOM_LISTS,
+ )
+ )
// Assert
onNodeWithText(CUSTOM_LISTS_EMPTY_TEXT).assertDoesNotExist()
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreenTest.kt
index cf3380e97a..d0dbb9155d 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreenTest.kt
@@ -4,6 +4,7 @@ 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 de.mannodermaus.junit5.compose.ComposeContext
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.mockk
@@ -20,6 +21,7 @@ import net.mullvad.mullvadvpn.compose.state.SelectLocationListUiState
import net.mullvad.mullvadvpn.compose.state.SelectLocationUiState
import net.mullvad.mullvadvpn.compose.test.SELECT_LOCATION_CUSTOM_LIST_BOTTOM_SHEET_TEST_TAG
import net.mullvad.mullvadvpn.compose.test.SELECT_LOCATION_LOCATION_BOTTOM_SHEET_TEST_TAG
+import net.mullvad.mullvadvpn.lib.model.CustomListId
import net.mullvad.mullvadvpn.lib.model.RelayItem
import net.mullvad.mullvadvpn.performLongClick
import net.mullvad.mullvadvpn.viewmodel.location.SelectLocationListViewModel
@@ -49,6 +51,53 @@ class SelectLocationScreenTest {
unmockkAll()
}
+ private fun ComposeContext.initScreen(
+ state: SelectLocationUiState = SelectLocationUiState.Loading,
+ onSelectRelay: (item: RelayItem) -> Unit = {},
+ onSearchClick: (RelayListType) -> Unit = {},
+ onBackClick: () -> Unit = {},
+ onFilterClick: () -> Unit = {},
+ onCreateCustomList: (location: RelayItem.Location?) -> Unit = {},
+ onEditCustomLists: () -> Unit = {},
+ removeOwnershipFilter: () -> Unit = {},
+ removeProviderFilter: () -> Unit = {},
+ onAddLocationToList:
+ (location: RelayItem.Location, customList: RelayItem.CustomList) -> Unit =
+ { _, _ ->
+ },
+ onRemoveLocationFromList:
+ (location: RelayItem.Location, customListId: CustomListId) -> Unit =
+ { _, _ ->
+ },
+ onEditCustomListName: (RelayItem.CustomList) -> Unit = {},
+ onEditLocationsCustomList: (RelayItem.CustomList) -> Unit = {},
+ onDeleteCustomList: (RelayItem.CustomList) -> Unit = {},
+ onSelectRelayList: (RelayListType) -> Unit = {},
+ openDaitaSettings: () -> Unit = {},
+ ) {
+
+ setContentWithTheme {
+ SelectLocationScreen(
+ state = state,
+ onSelectRelay = onSelectRelay,
+ onSearchClick = onSearchClick,
+ onBackClick = onBackClick,
+ onFilterClick = onFilterClick,
+ onCreateCustomList = onCreateCustomList,
+ onEditCustomLists = onEditCustomLists,
+ removeOwnershipFilter = removeOwnershipFilter,
+ removeProviderFilter = removeProviderFilter,
+ onAddLocationToList = onAddLocationToList,
+ onRemoveLocationFromList = onRemoveLocationFromList,
+ onEditCustomListName = onEditCustomListName,
+ onEditLocationsCustomList = onEditLocationsCustomList,
+ onDeleteCustomList = onDeleteCustomList,
+ onSelectRelayList = onSelectRelayList,
+ openDaitaSettings = openDaitaSettings,
+ )
+ }
+ }
+
@Test
fun testShowRelayListState() =
composeExtension.use {
@@ -61,17 +110,15 @@ class SelectLocationScreenTest {
customLists = emptyList(),
)
)
- setContentWithTheme {
- SelectLocationScreen(
- state =
- SelectLocationUiState.Data(
- // searchTerm = "",
- filterChips = emptyList(),
- multihopEnabled = false,
- relayListType = RelayListType.EXIT,
- )
- )
- }
+ initScreen(
+ state =
+ SelectLocationUiState.Data(
+ // searchTerm = "",
+ filterChips = emptyList(),
+ multihopEnabled = false,
+ relayListType = RelayListType.EXIT,
+ )
+ )
// Assert
onNodeWithText("Relay Country 1").assertExists()
@@ -93,16 +140,14 @@ class SelectLocationScreenTest {
customLists = emptyList(),
)
)
- setContentWithTheme {
- SelectLocationScreen(
- state =
- SelectLocationUiState.Data(
- filterChips = emptyList(),
- multihopEnabled = false,
- relayListType = RelayListType.EXIT,
- )
- )
- }
+ initScreen(
+ state =
+ SelectLocationUiState.Data(
+ filterChips = emptyList(),
+ multihopEnabled = false,
+ relayListType = RelayListType.EXIT,
+ )
+ )
// Assert
onNodeWithText(CUSTOM_LISTS_EMPTY_TEXT).assertExists()
@@ -121,17 +166,15 @@ class SelectLocationScreenTest {
)
)
val mockedOnSelectRelay: (RelayItem) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- SelectLocationScreen(
- state =
- SelectLocationUiState.Data(
- filterChips = emptyList(),
- multihopEnabled = false,
- relayListType = RelayListType.EXIT,
- ),
- onSelectRelay = mockedOnSelectRelay,
- )
- }
+ initScreen(
+ state =
+ SelectLocationUiState.Data(
+ filterChips = emptyList(),
+ multihopEnabled = false,
+ relayListType = RelayListType.EXIT,
+ ),
+ onSelectRelay = mockedOnSelectRelay,
+ )
// Act
onNodeWithText(customList.name).performClick()
@@ -153,18 +196,16 @@ class SelectLocationScreenTest {
)
)
val mockedOnSelectRelay: (RelayItem) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- SelectLocationScreen(
- state =
- SelectLocationUiState.Data(
- // searchTerm = "",
- filterChips = emptyList(),
- multihopEnabled = false,
- relayListType = RelayListType.EXIT,
- ),
- onSelectRelay = mockedOnSelectRelay,
- )
- }
+ initScreen(
+ state =
+ SelectLocationUiState.Data(
+ // searchTerm = "",
+ filterChips = emptyList(),
+ multihopEnabled = false,
+ relayListType = RelayListType.EXIT,
+ ),
+ onSelectRelay = mockedOnSelectRelay,
+ )
// Act
onNodeWithText(customList.name).performLongClick()
@@ -186,17 +227,15 @@ class SelectLocationScreenTest {
)
)
val mockedOnSelectRelay: (RelayItem) -> Unit = mockk(relaxed = true)
- setContentWithTheme {
- SelectLocationScreen(
- state =
- SelectLocationUiState.Data(
- filterChips = emptyList(),
- multihopEnabled = false,
- relayListType = RelayListType.EXIT,
- ),
- onSelectRelay = mockedOnSelectRelay,
- )
- }
+ initScreen(
+ state =
+ SelectLocationUiState.Data(
+ filterChips = emptyList(),
+ multihopEnabled = false,
+ relayListType = RelayListType.EXIT,
+ ),
+ onSelectRelay = mockedOnSelectRelay,
+ )
// Act
onNodeWithText(relayItem.name).performLongClick()
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt
index 47690247dc..8c336e5544 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt
@@ -31,9 +31,9 @@ private fun PreviewConnectionButton(
fun ConnectionButton(
modifier: Modifier = Modifier,
state: TunnelState,
- disconnectClick: () -> Unit = {},
- cancelClick: () -> Unit = {},
- connectClick: () -> Unit = {},
+ disconnectClick: () -> Unit,
+ cancelClick: () -> Unit,
+ connectClick: () -> Unit,
) {
val containerColor =
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/CustomPortCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/CustomPortCell.kt
index 321a86700f..0ea351e8b1 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/CustomPortCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/CustomPortCell.kt
@@ -40,8 +40,20 @@ import net.mullvad.mullvadvpn.lib.theme.color.selected
private fun PreviewCustomPortCell() {
AppTheme {
SpacedColumn(Modifier.background(MaterialTheme.colorScheme.surface)) {
- CustomPortCell(title = "Title", isSelected = true, port = Port(444))
- CustomPortCell(title = "Title", isSelected = false, port = null)
+ CustomPortCell(
+ title = "Title",
+ isSelected = true,
+ port = Port(444),
+ onPortCellClicked = {},
+ onMainCellClicked = {},
+ )
+ CustomPortCell(
+ title = "Title",
+ isSelected = false,
+ port = null,
+ onPortCellClicked = {},
+ onMainCellClicked = {},
+ )
}
}
}
@@ -53,8 +65,8 @@ fun CustomPortCell(
port: Port?,
mainTestTag: String = "",
numberTestTag: String = "",
- onMainCellClicked: () -> Unit = {},
- onPortCellClicked: () -> Unit = {},
+ onMainCellClicked: () -> Unit,
+ onPortCellClicked: () -> Unit,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/DropdownMenuCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/DropdownMenuCell.kt
index 5560a69754..70b04822ee 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/DropdownMenuCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/DropdownMenuCell.kt
@@ -18,14 +18,14 @@ import net.mullvad.mullvadvpn.lib.theme.Dimens
@Preview
@Composable
private fun PreviewThreeDotCell() {
- AppTheme { ThreeDotCell(text = "Three dots") }
+ AppTheme { ThreeDotCell(text = "Three dots", onClickDots = {}) }
}
@Composable
fun ThreeDotCell(
text: String,
modifier: Modifier = Modifier,
- onClickDots: () -> Unit = {},
+ onClickDots: () -> Unit,
textStyle: TextStyle = MaterialTheme.typography.titleMedium,
textColor: Color = MaterialTheme.colorScheme.onPrimary,
background: Color = MaterialTheme.colorScheme.primary,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/ExpandableComposeCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/ExpandableComposeCell.kt
index 81a5bd0ea5..a1ca433322 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/ExpandableComposeCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/ExpandableComposeCell.kt
@@ -53,7 +53,7 @@ fun ExpandableComposeCell(
testTag: String = "",
textColor: Color = MaterialTheme.colorScheme.onPrimary,
background: Color = MaterialTheme.colorScheme.primary,
- onCellClicked: (Boolean) -> Unit = {},
+ onCellClicked: (Boolean) -> Unit,
onInfoClicked: (() -> Unit)? = null,
) {
val titleModifier = Modifier.alpha(if (isEnabled) AlphaVisible else AlphaInactive)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/ObfuscationModeCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/ObfuscationModeCell.kt
index 5191eba331..90b5da8891 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/ObfuscationModeCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/ObfuscationModeCell.kt
@@ -57,7 +57,7 @@ fun ObfuscationModeCell(
port: Constraint<Port>,
isSelected: Boolean,
onSelected: (ObfuscationMode) -> Unit,
- onNavigate: () -> Unit = {},
+ onNavigate: () -> Unit,
testTag: String? = null,
) {
Row(
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/RelayLocationCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/RelayLocationCell.kt
index eb729701bc..14d9c20ebe 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/RelayLocationCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/RelayLocationCell.kt
@@ -75,9 +75,9 @@ fun StatusRelayItemCell(
isSelected: Boolean,
state: RelayListItemState?,
modifier: Modifier = Modifier,
- onClick: () -> Unit = {},
+ onClick: () -> Unit,
onLongClick: (() -> Unit)? = null,
- onToggleExpand: ((Boolean) -> Unit) = {},
+ onToggleExpand: ((Boolean) -> Unit),
isExpanded: Boolean = false,
depth: Int = 0,
activeColor: Color = MaterialTheme.colorScheme.selected,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/SplitTunnelingCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/SplitTunnelingCell.kt
index 05bbcb1b5a..15a83776d4 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/SplitTunnelingCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/SplitTunnelingCell.kt
@@ -48,12 +48,16 @@ private fun PreviewTunnelingCell() {
packageName = "",
isSelected = false,
enabled = true,
+ onCellClicked = {},
+ onResolveIcon = { null },
)
SplitTunnelingCell(
title = "Mullvad VPN",
packageName = "",
isSelected = true,
enabled = true,
+ onCellClicked = {},
+ onResolveIcon = { null },
)
}
}
@@ -67,8 +71,8 @@ fun SplitTunnelingCell(
enabled: Boolean,
modifier: Modifier = Modifier,
backgroundColor: Color = MaterialTheme.colorScheme.surfaceContainerHigh,
- onResolveIcon: (String) -> Bitmap? = { null },
- onCellClicked: () -> Unit = {},
+ onResolveIcon: (String) -> Bitmap?,
+ onCellClicked: () -> Unit,
) {
var icon by remember(packageName) { mutableStateOf<ImageBitmap?>(null) }
LaunchedEffect(packageName) {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/SwitchComposeCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/SwitchComposeCell.kt
index 3f05995738..61b9a828a5 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/SwitchComposeCell.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/SwitchComposeCell.kt
@@ -64,7 +64,7 @@ fun NormalSwitchComposeCell(
isEnabled: Boolean = true,
background: Color = MaterialTheme.colorScheme.surfaceContainerLow,
onBackground: Color = MaterialTheme.colorScheme.onSurface,
- onCellClicked: (Boolean) -> Unit = {},
+ onCellClicked: (Boolean) -> Unit,
onInfoClicked: (() -> Unit)? = null,
) {
SwitchComposeCell(
@@ -95,7 +95,7 @@ fun HeaderSwitchComposeCell(
isEnabled: Boolean = true,
background: Color = MaterialTheme.colorScheme.primary,
onBackground: Color = MaterialTheme.colorScheme.onPrimary,
- onCellClicked: (Boolean) -> Unit = {},
+ onCellClicked: (Boolean) -> Unit,
onInfoClicked: (() -> Unit)? = null,
) {
SwitchComposeCell(
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ChangelogDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ChangelogDialog.kt
index 67a6aac2fe..e5afe6d9bc 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ChangelogDialog.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/ChangelogDialog.kt
@@ -39,12 +39,12 @@ fun Changelog(navController: NavController) {
}
@Composable
-fun ChangelogDialog(changeLog: ChangelogUiState, onDismiss: () -> Unit) {
+fun ChangelogDialog(state: ChangelogUiState, onDismiss: () -> Unit) {
AlertDialog(
onDismissRequest = onDismiss,
title = {
Text(
- text = changeLog.version,
+ text = state.version,
style = MaterialTheme.typography.headlineLarge,
color = MaterialTheme.colorScheme.onSurface,
textAlign = TextAlign.Center,
@@ -64,7 +64,7 @@ fun ChangelogDialog(changeLog: ChangelogUiState, onDismiss: () -> Unit) {
modifier = Modifier.fillMaxWidth(),
)
- changeLog.changes.forEach { changeItem -> ChangeListItem(text = changeItem) }
+ state.changes.forEach { changeItem -> ChangeListItem(text = changeItem) }
}
},
confirmButton = {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialog.kt
index fc9109cf4d..b93c08321c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialog.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CreateCustomListDialog.kt
@@ -33,7 +33,7 @@ import org.koin.androidx.compose.koinViewModel
@Preview
@Composable
private fun PreviewCreateCustomListDialog() {
- AppTheme { CreateCustomListDialog(state = CreateCustomListUiState()) }
+ AppTheme { CreateCustomListDialog(state = CreateCustomListUiState(), {}, {}, {}) }
}
@Preview
@@ -44,7 +44,10 @@ private fun PreviewCreateCustomListDialogError() {
state =
CreateCustomListUiState(
error = CreateWithLocationsError.Create(CustomListAlreadyExists)
- )
+ ),
+ {},
+ {},
+ {},
)
}
}
@@ -92,9 +95,9 @@ fun CreateCustomList(
@Composable
fun CreateCustomListDialog(
state: CreateCustomListUiState,
- createCustomList: (String) -> Unit = {},
- onInputChanged: () -> Unit = {},
- onDismiss: () -> Unit = {},
+ createCustomList: (String) -> Unit,
+ onInputChanged: () -> Unit,
+ onDismiss: () -> Unit,
) {
val name = rememberSaveable { mutableStateOf("") }
val isValidName = name.value.isNotBlank()
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialog.kt
index 3153aeb37c..1dffa3bfc9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialog.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeleteCustomListConfirmationDialog.kt
@@ -26,7 +26,9 @@ import org.koin.androidx.compose.koinViewModel
private fun PreviewRemoveDeviceConfirmationDialog() {
AppTheme {
DeleteCustomListConfirmationDialog(
- state = DeleteCustomListUiState(CustomListName.fromString("My Custom List"), null)
+ state = DeleteCustomListUiState(CustomListName.fromString("My Custom List"), null),
+ {},
+ {},
)
}
}
@@ -59,8 +61,8 @@ fun DeleteCustomList(navigator: ResultBackNavigator<CustomListActionResultData.S
@Composable
fun DeleteCustomListConfirmationDialog(
state: DeleteCustomListUiState,
- onDelete: () -> Unit = {},
- onBack: () -> Unit = {},
+ onDelete: () -> Unit,
+ onBack: () -> Unit,
) {
NegativeConfirmationDialog(
onConfirm = onDelete,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialog.kt
index 57205175e5..20560fe9e8 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialog.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/EditCustomListNameDialog.kt
@@ -32,7 +32,7 @@ import org.koin.androidx.compose.koinViewModel
@Preview
@Composable
private fun PreviewEditCustomListNameDialog() {
- AppTheme { EditCustomListNameDialog(EditCustomListNameUiState()) }
+ AppTheme { EditCustomListNameDialog(EditCustomListNameUiState(), {}, {}, {}) }
}
data class EditCustomListNameNavArgs(
@@ -69,9 +69,9 @@ fun EditCustomListName(
@Composable
fun EditCustomListNameDialog(
state: EditCustomListNameUiState,
- updateName: (String) -> Unit = {},
- onInputChanged: (String) -> Unit = {},
- onDismiss: () -> Unit = {},
+ updateName: (String) -> Unit,
+ onInputChanged: (String) -> Unit,
+ onDismiss: () -> Unit,
) {
InputDialog(
title = stringResource(id = R.string.update_list_name),
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/NegativeConfirmationDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/NegativeConfirmationDialog.kt
index 4720fd9fb7..dab6142c89 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/NegativeConfirmationDialog.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/NegativeConfirmationDialog.kt
@@ -30,7 +30,12 @@ import net.mullvad.mullvadvpn.lib.theme.Dimens
@Composable
private fun PreviewDeleteConfirmationDialog() {
AppTheme {
- NegativeConfirmationDialog(message = "Do you want to delete Cookie?", errorMessage = null)
+ NegativeConfirmationDialog(
+ message = "Do you want to delete Cookie?",
+ errorMessage = null,
+ onConfirm = {},
+ onBack = {},
+ )
}
}
@@ -41,6 +46,8 @@ private fun PreviewDeleteConfirmationDialogError() {
NegativeConfirmationDialog(
message = "Do you want to delete Cookie?",
errorMessage = "An error occured",
+ onConfirm = {},
+ onBack = {},
)
}
}
@@ -52,8 +59,8 @@ fun NegativeConfirmationDialog(
errorMessage: String? = null,
confirmationText: String = stringResource(id = R.string.delete),
cancelText: String = stringResource(id = R.string.cancel),
- onConfirm: () -> Unit = {},
- onBack: () -> Unit = {},
+ onConfirm: () -> Unit,
+ onBack: () -> Unit,
) {
NegativeConfirmationDialog(
message = AnnotatedString(message),
@@ -73,8 +80,8 @@ fun NegativeConfirmationDialog(
errorMessage: String? = null,
confirmationText: String = stringResource(id = R.string.delete),
cancelText: String = stringResource(id = R.string.cancel),
- onConfirm: () -> Unit = {},
- onBack: () -> Unit = {},
+ onConfirm: () -> Unit,
+ onBack: () -> Unit,
) {
AlertDialog(
onDismissRequest = onBack,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialog.kt
index 04f3c05a11..5f8968beec 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialog.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialog.kt
@@ -121,7 +121,7 @@ fun RedeemVoucher(resultBackNavigator: ResultBackNavigator<Boolean>) {
@Composable
fun RedeemVoucherDialog(
state: VoucherDialogUiState,
- onVoucherInputChange: (String) -> Unit = {},
+ onVoucherInputChange: (String) -> Unit,
onRedeem: (voucherCode: String) -> Unit,
onDismiss: (isTimeAdded: Boolean) -> Unit,
) {
@@ -230,7 +230,7 @@ private fun RedeemSuccessBody(message: String) {
@Composable
private fun EnterVoucherBody(
state: VoucherDialogUiState,
- onVoucherInputChange: (String) -> Unit = {},
+ onVoucherInputChange: (String) -> Unit,
onRedeem: (voucherCode: String) -> Unit,
) {
CustomTextField(
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/SaveApiAccessMethodDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/SaveApiAccessMethodDialog.kt
index 6182f0eb81..f351c95c0e 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/SaveApiAccessMethodDialog.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/SaveApiAccessMethodDialog.kt
@@ -42,7 +42,7 @@ private fun PreviewSaveApiAccessMethodDialog(
@PreviewParameter(SaveApiAccessMethodUiStatePreviewParameterProvider::class)
state: SaveApiAccessMethodUiState
) {
- AppTheme { SaveApiAccessMethodDialog(state = state) }
+ AppTheme { SaveApiAccessMethodDialog(state = state, {}, {}) }
}
data class SaveApiAccessMethodNavArgs(
@@ -79,8 +79,8 @@ fun SaveApiAccessMethod(backNavigator: ResultBackNavigator<Boolean>) {
@Composable
fun SaveApiAccessMethodDialog(
state: SaveApiAccessMethodUiState,
- onCancel: () -> Unit = {},
- onSave: () -> Unit = {},
+ onCancel: () -> Unit,
+ onSave: () -> Unit,
) {
AlertDialog(
icon = {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/payment/PaymentDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/payment/PaymentDialog.kt
index 1001490339..72fdd752e9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/payment/PaymentDialog.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/payment/PaymentDialog.kt
@@ -147,8 +147,8 @@ fun Payment(productId: ProductId, resultBackNavigator: ResultBackNavigator<Boole
@Composable
fun PaymentDialog(
paymentDialogData: PaymentDialogData,
- retryPurchase: (ProductId) -> Unit = {},
- onCloseDialog: (isPaymentSuccessful: Boolean) -> Unit = {},
+ retryPurchase: (ProductId) -> Unit,
+ onCloseDialog: (isPaymentSuccessful: Boolean) -> Unit,
) {
val clickResolver: (action: PaymentDialogAction) -> Unit = {
when (it) {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AccountScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AccountScreen.kt
index 3e95235d23..ddfb535faf 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AccountScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AccountScreen.kt
@@ -72,7 +72,7 @@ import org.koin.androidx.compose.koinViewModel
private fun PreviewAccountScreen(
@PreviewParameter(AccountUiStatePreviewParameterProvider::class) state: AccountUiState
) {
- AppTheme { AccountScreen(state = state) }
+ AppTheme { AccountScreen(state = state, SnackbarHostState(), {}, {}, {}, {}, {}, {}, {}, {}) }
}
@OptIn(ExperimentalMaterial3Api::class)
@@ -138,14 +138,14 @@ fun Account(
fun AccountScreen(
state: AccountUiState,
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
- onCopyAccountNumber: (String) -> Unit = {},
- onRedeemVoucherClick: () -> Unit = {},
- onManageAccountClick: () -> Unit = {},
- onLogoutClick: () -> Unit = {},
- onPurchaseBillingProductClick: (productId: ProductId) -> Unit = { _ -> },
- navigateToDeviceInfo: () -> Unit = {},
- navigateToVerificationPendingDialog: () -> Unit = {},
- onBackClick: () -> Unit = {},
+ onCopyAccountNumber: (String) -> Unit,
+ onRedeemVoucherClick: () -> Unit,
+ onManageAccountClick: () -> Unit,
+ onLogoutClick: () -> Unit,
+ onPurchaseBillingProductClick: (productId: ProductId) -> Unit,
+ navigateToDeviceInfo: () -> Unit,
+ navigateToVerificationPendingDialog: () -> Unit,
+ onBackClick: () -> Unit,
) {
// This will enable SECURE_FLAG while this screen is visible to preview screenshot
SecureScreenWhileInView()
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessListScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessListScreen.kt
index c1fc183cfa..fb5f03015c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessListScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessListScreen.kt
@@ -51,7 +51,7 @@ private fun PreviewApiAccessList(
@PreviewParameter(ApiAccessListUiStatePreviewParameterProvider::class)
state: ApiAccessListUiState
) {
- AppTheme { ApiAccessListScreen(state = state) }
+ AppTheme { ApiAccessListScreen(state = state, {}, { _ -> }, {}, {}) }
}
@Destination<RootGraph>(style = SlideInFromRightTransition::class)
@@ -78,10 +78,10 @@ fun ApiAccessList(navigator: DestinationsNavigator) {
@Composable
fun ApiAccessListScreen(
state: ApiAccessListUiState,
- onAddMethodClick: () -> Unit = {},
- onApiAccessMethodClick: (apiAccessMethodSetting: ApiAccessMethodSetting) -> Unit = {},
- onApiAccessInfoClick: () -> Unit = {},
- onBackClick: () -> Unit = {},
+ onAddMethodClick: () -> Unit,
+ onApiAccessMethodClick: (apiAccessMethodSetting: ApiAccessMethodSetting) -> Unit,
+ onApiAccessInfoClick: () -> Unit,
+ onBackClick: () -> Unit,
) {
ScaffoldWithMediumTopBar(
appBarTitle = stringResource(id = R.string.settings_api_access),
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessMethodDetailsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessMethodDetailsScreen.kt
index 35c4c8a444..b4f10d691b 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessMethodDetailsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ApiAccessMethodDetailsScreen.kt
@@ -77,7 +77,9 @@ private fun PreviewApiAccessMethodDetailsScreen(
@PreviewParameter(ApiAccessMethodDetailsUiStatePreviewParameterProvider::class)
state: ApiAccessMethodDetailsUiState
) {
- AppTheme { ApiAccessMethodDetailsScreen(state = state) }
+ AppTheme {
+ ApiAccessMethodDetailsScreen(state = state, SnackbarHostState(), {}, {}, {}, {}, {}, {}, {})
+ }
}
data class ApiAccessMethodDetailsNavArgs(val accessMethodId: ApiAccessMethodId)
@@ -187,14 +189,14 @@ fun ApiAccessMethodDetails(
@Composable
fun ApiAccessMethodDetailsScreen(
state: ApiAccessMethodDetailsUiState,
- snackbarHostState: SnackbarHostState = SnackbarHostState(),
- onEditMethodClicked: () -> Unit = {},
- onEnableClicked: (Boolean) -> Unit = {},
- onTestMethodClicked: () -> Unit = {},
- onUseMethodClicked: () -> Unit = {},
- onDeleteApiAccessMethodClicked: (ApiAccessMethodId) -> Unit = {},
- onNavigateToEncryptedDnsInfoDialog: () -> Unit = {},
- onBackClicked: () -> Unit = {},
+ snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
+ onEditMethodClicked: () -> Unit,
+ onEnableClicked: (Boolean) -> Unit,
+ onTestMethodClicked: () -> Unit,
+ onUseMethodClicked: () -> Unit,
+ onDeleteApiAccessMethodClicked: (ApiAccessMethodId) -> Unit,
+ onNavigateToEncryptedDnsInfoDialog: () -> Unit,
+ onBackClicked: () -> Unit,
) {
ScaffoldWithMediumTopBar(
appBarTitle = state.name(),
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AutoConnectAndLockdownModeScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AutoConnectAndLockdownModeScreen.kt
index cafb9ef11d..3d2949fc9c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AutoConnectAndLockdownModeScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AutoConnectAndLockdownModeScreen.kt
@@ -67,7 +67,7 @@ import net.mullvad.mullvadvpn.util.appendHideNavOnPlayBuild
@Preview
@Composable
private fun PreviewAutoConnectAndLockdownModeScreen() {
- AppTheme { AutoConnectAndLockdownModeScreen() }
+ AppTheme { AutoConnectAndLockdownModeScreen({}) }
}
@Destination<RootGraph>(style = SlideInFromRightTransition::class)
@@ -77,7 +77,7 @@ fun AutoConnectAndLockdownMode(navigator: DestinationsNavigator) {
}
@Composable
-fun AutoConnectAndLockdownModeScreen(onBackClick: () -> Unit = {}) {
+fun AutoConnectAndLockdownModeScreen(onBackClick: () -> Unit) {
val context = LocalContext.current
ScaffoldWithLargeTopBarAndButton(
appBarTitle = stringResource(id = R.string.auto_connect_and_lockdown_mode),
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt
index b143e72f25..30af30fec5 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt
@@ -125,7 +125,22 @@ private const val TALL_SCREEN_INDICATOR_BIAS = 0.3f
private fun PreviewAccountScreen(
@PreviewParameter(ConnectUiStatePreviewParameterProvider::class) state: ConnectUiState
) {
- AppTheme { ConnectScreen(state = state) }
+ AppTheme {
+ ConnectScreen(
+ state = state,
+ snackbarHostState = SnackbarHostState(),
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ )
+ }
}
@Destination<RootGraph>(style = HomeTransition::class)
@@ -228,17 +243,17 @@ fun Connect(
@Composable
fun ConnectScreen(
state: ConnectUiState,
- snackbarHostState: SnackbarHostState = SnackbarHostState(),
- onDisconnectClick: () -> Unit = {},
- onReconnectClick: () -> Unit = {},
- onConnectClick: () -> Unit = {},
- onCancelClick: () -> Unit = {},
- onSwitchLocationClick: () -> Unit = {},
- onOpenAppListing: () -> Unit = {},
- onManageAccountClick: () -> Unit = {},
- onSettingsClick: () -> Unit = {},
- onAccountClick: () -> Unit = {},
- onDismissNewDeviceClick: () -> Unit = {},
+ snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
+ onDisconnectClick: () -> Unit,
+ onReconnectClick: () -> Unit,
+ onConnectClick: () -> Unit,
+ onCancelClick: () -> Unit,
+ onSwitchLocationClick: () -> Unit,
+ onOpenAppListing: () -> Unit,
+ onManageAccountClick: () -> Unit,
+ onSettingsClick: () -> Unit,
+ onAccountClick: () -> Unit,
+ onDismissNewDeviceClick: () -> Unit,
) {
ScaffoldWithTopBarAndDeviceName(
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreen.kt
index 8fcf650bf4..16234326d2 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListLocationsScreen.kt
@@ -63,7 +63,7 @@ private fun PreviewCustomListLocationScreen(
@PreviewParameter(CustomListLocationUiStatePreviewParameterProvider::class)
state: CustomListLocationsUiState
) {
- AppTheme { CustomListLocationsScreen(state = state) }
+ AppTheme { CustomListLocationsScreen(state = state, {}, {}, { _, _ -> }, { _, _ -> }, {}) }
}
data class CustomListLocationsNavArgs(val customListId: CustomListId, val newList: Boolean)
@@ -119,11 +119,11 @@ fun CustomListLocations(
@Composable
fun CustomListLocationsScreen(
state: CustomListLocationsUiState,
- onSearchTermInput: (String) -> Unit = {},
- onSaveClick: () -> Unit = {},
- onRelaySelectionClick: (RelayItem.Location, selected: Boolean) -> Unit = { _, _ -> },
- onExpand: (RelayItem.Location, selected: Boolean) -> Unit = { _, _ -> },
- onBackClick: () -> Unit = {},
+ onSearchTermInput: (String) -> Unit,
+ onSaveClick: () -> Unit,
+ onRelaySelectionClick: (RelayItem.Location, selected: Boolean) -> Unit,
+ onExpand: (RelayItem.Location, selected: Boolean) -> Unit,
+ onBackClick: () -> Unit,
) {
ScaffoldWithSmallTopBar(
appBarTitle =
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreen.kt
index 08ec0ee503..0d2a47e026 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/CustomListsScreen.kt
@@ -60,7 +60,7 @@ import org.koin.androidx.compose.koinViewModel
private fun PreviewAccountScreen(
@PreviewParameter(CustomListsUiStatePreviewParameterProvider::class) state: CustomListsUiState
) {
- AppTheme { CustomListsScreen(state = state, SnackbarHostState()) }
+ AppTheme { CustomListsScreen(state = state, SnackbarHostState(), {}, { _ -> }, {}) }
}
@Composable
@@ -112,10 +112,10 @@ fun CustomLists(
@Composable
fun CustomListsScreen(
state: CustomListsUiState,
- snackbarHostState: SnackbarHostState,
- addCustomList: () -> Unit = {},
- openCustomList: (CustomList) -> Unit = {},
- onBackClick: () -> Unit = {},
+ snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
+ addCustomList: () -> Unit,
+ openCustomList: (CustomList) -> Unit,
+ onBackClick: () -> Unit,
) {
ScaffoldWithMediumTopBar(
appBarTitle = stringResource(id = R.string.edit_custom_lists),
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt
index a6a2a279dc..70e0d1622a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DaitaScreen.kt
@@ -50,7 +50,15 @@ import org.koin.androidx.compose.koinViewModel
@Preview
@Composable
private fun PreviewDaitaScreen() {
- AppTheme { DaitaScreen(state = DaitaUiState(daitaEnabled = false, directOnly = false)) }
+ AppTheme {
+ DaitaScreen(
+ state = DaitaUiState(daitaEnabled = false, directOnly = false),
+ { _ -> },
+ { _ -> },
+ {},
+ {},
+ )
+ }
}
@Destination<RootGraph>(style = SlideInFromRightTransition::class)
@@ -87,10 +95,10 @@ fun Daita(
@Composable
fun DaitaScreen(
state: DaitaUiState,
- onDaitaEnabled: (enable: Boolean) -> Unit = {},
- onDirectOnlyClick: (enable: Boolean) -> Unit = {},
- onDirectOnlyInfoClick: () -> Unit = {},
- onBackClick: () -> Unit = {},
+ onDaitaEnabled: (enable: Boolean) -> Unit,
+ onDirectOnlyClick: (enable: Boolean) -> Unit,
+ onDirectOnlyInfoClick: () -> Unit,
+ onBackClick: () -> Unit,
) {
ScaffoldWithMediumTopBar(
appBarTitle = stringResource(id = R.string.daita),
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt
index beb83a9b2e..34ac8d98b7 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt
@@ -74,7 +74,7 @@ import org.koin.androidx.compose.koinViewModel
private fun PreviewDeviceListScreenContent(
@PreviewParameter(DeviceListUiStatePreviewParameterProvider::class) state: DeviceListUiState
) {
- AppTheme { DeviceListScreen(state = state) }
+ AppTheme { DeviceListScreen(state = state, SnackbarHostState(), {}, {}, {}, {}, {}) }
}
data class DeviceListNavArgs(val accountNumber: AccountNumber)
@@ -139,11 +139,11 @@ fun DeviceList(
fun DeviceListScreen(
state: DeviceListUiState,
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
- onBackClick: () -> Unit = {},
- onContinueWithLogin: () -> Unit = {},
- onSettingsClicked: () -> Unit = {},
- onTryAgainClicked: () -> Unit = {},
- navigateToRemoveDeviceConfirmationDialog: (device: Device) -> Unit = {},
+ onBackClick: () -> Unit,
+ onContinueWithLogin: () -> Unit,
+ onSettingsClicked: () -> Unit,
+ onTryAgainClicked: () -> Unit,
+ navigateToRemoveDeviceConfirmationDialog: (device: Device) -> Unit,
) {
ScaffoldWithTopBar(
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreen.kt
index 39f8f2fd84..d0a334d561 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceRevokedScreen.kt
@@ -46,7 +46,7 @@ private fun PreviewDeviceRevokedScreen(
@PreviewParameter(DeviceRevokedUiStatePreviewParameterProvider::class)
state: DeviceRevokedUiState
) {
- AppTheme { DeviceRevokedScreen(state = state) }
+ AppTheme { DeviceRevokedScreen(state = state, {}, {}) }
}
@Destination<RootGraph>
@@ -76,8 +76,8 @@ fun DeviceRevoked(navigator: DestinationsNavigator) {
@Composable
fun DeviceRevokedScreen(
state: DeviceRevokedUiState,
- onSettingsClicked: () -> Unit = {},
- onGoToLoginClicked: () -> Unit = {},
+ onSettingsClicked: () -> Unit,
+ onGoToLoginClicked: () -> Unit,
) {
val topColor =
if (state == DeviceRevokedUiState.SECURED) {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditApiAccessMethodScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditApiAccessMethodScreen.kt
index 6596f7c343..768c43d588 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditApiAccessMethodScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditApiAccessMethodScreen.kt
@@ -79,7 +79,23 @@ private fun PreviewEditApiAccessMethodScreen(
@PreviewParameter(EditApiAccessMethodUiStatePreviewParameterProvider::class)
state: EditApiAccessMethodUiState
) {
- AppTheme { EditApiAccessMethodScreen(state = state) }
+ AppTheme {
+ EditApiAccessMethodScreen(
+ state = state,
+ SnackbarHostState(),
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ )
+ }
}
data class EditApiAccessMethodNavArgs(val accessMethodId: ApiAccessMethodId?)
@@ -192,17 +208,17 @@ fun EditApiAccessMethod(
fun EditApiAccessMethodScreen(
state: EditApiAccessMethodUiState,
snackbarHostState: SnackbarHostState = SnackbarHostState(),
- onNameChanged: (String) -> Unit = {},
- onTypeSelected: (ApiAccessMethodTypes) -> Unit = {},
- onIpChanged: (String) -> Unit = {},
- onPortChanged: (String) -> Unit = {},
- onPasswordChanged: (String) -> Unit = {},
- onCipherChange: (Cipher) -> Unit = {},
- onToggleAuthenticationEnabled: (Boolean) -> Unit = {},
- onUsernameChanged: (String) -> Unit = {},
- onTestMethod: () -> Unit = {},
- onAddMethod: () -> Unit = {},
- onNavigateBack: () -> Unit = {},
+ onNameChanged: (String) -> Unit,
+ onTypeSelected: (ApiAccessMethodTypes) -> Unit,
+ onIpChanged: (String) -> Unit,
+ onPortChanged: (String) -> Unit,
+ onPasswordChanged: (String) -> Unit,
+ onCipherChange: (Cipher) -> Unit,
+ onToggleAuthenticationEnabled: (Boolean) -> Unit,
+ onUsernameChanged: (String) -> Unit,
+ onTestMethod: () -> Unit,
+ onAddMethod: () -> Unit,
+ onNavigateBack: () -> Unit,
) {
ScaffoldWithSmallTopBar(
snackbarHostState = snackbarHostState,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreen.kt
index 30f5491c73..513bc636d4 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/EditCustomListScreen.kt
@@ -62,7 +62,7 @@ private fun PreviewEditCustomListScreen(
@PreviewParameter(EditCustomListUiStatePreviewParameterProvider::class)
state: EditCustomListUiState
) {
- AppTheme { EditCustomListScreen(state = state) }
+ AppTheme { EditCustomListScreen(state = state, { _, _ -> }, { _, _ -> }, {}, {}) }
}
data class EditCustomListNavArgs(val customListId: CustomListId)
@@ -116,10 +116,10 @@ fun EditCustomList(
@Composable
fun EditCustomListScreen(
state: EditCustomListUiState,
- onDeleteList: (id: CustomListId, name: CustomListName) -> Unit = { _, _ -> },
- onNameClicked: (id: CustomListId, name: CustomListName) -> Unit = { _, _ -> },
- onLocationsClicked: (CustomListId) -> Unit = {},
- onBackClick: () -> Unit = {},
+ onDeleteList: (id: CustomListId, name: CustomListName) -> Unit,
+ onNameClicked: (id: CustomListId, name: CustomListName) -> Unit,
+ onLocationsClicked: (CustomListId) -> Unit,
+ onBackClick: () -> Unit,
) {
ScaffoldWithMediumTopBar(
appBarTitle = stringResource(id = R.string.edit_list),
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/FilterScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/FilterScreen.kt
index 9b3142b161..60788bffd5 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/FilterScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/FilterScreen.kt
@@ -64,6 +64,8 @@ private fun PreviewFilterScreen(
onSelectedOwnership = {},
onSelectedProvider = { _, _ -> },
onAllProviderCheckChange = {},
+ onBackClick = {},
+ onApplyClick = {},
)
}
}
@@ -92,11 +94,11 @@ fun Filter(navigator: DestinationsNavigator) {
@Composable
fun FilterScreen(
state: RelayFilterUiState,
- onBackClick: () -> Unit = {},
- onApplyClick: () -> Unit = {},
- onSelectedOwnership: (ownership: Ownership?) -> Unit = {},
- onAllProviderCheckChange: (isChecked: Boolean) -> Unit = {},
- onSelectedProvider: (checked: Boolean, provider: Provider) -> Unit = { _, _ -> },
+ onBackClick: () -> Unit,
+ onApplyClick: () -> Unit,
+ onSelectedOwnership: (ownership: Ownership?) -> Unit,
+ onAllProviderCheckChange: (isChecked: Boolean) -> Unit,
+ onSelectedProvider: (checked: Boolean, provider: Provider) -> Unit,
) {
var providerExpanded by rememberSaveable { mutableStateOf(false) }
var ownershipExpanded by rememberSaveable { mutableStateOf(false) }
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ImportOverridesByTextScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ImportOverridesByTextScreen.kt
index 3abcc5842d..228cfff16f 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ImportOverridesByTextScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ImportOverridesByTextScreen.kt
@@ -29,11 +29,12 @@ import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.compose.component.MullvadSmallTopBar
import net.mullvad.mullvadvpn.compose.textfield.mullvadWhiteTextFieldColors
import net.mullvad.mullvadvpn.compose.transitions.DefaultTransition
+import net.mullvad.mullvadvpn.lib.theme.AppTheme
@Preview
@Composable
private fun PreviewImportOverridesByText() {
- ImportOverridesByTextScreen({}, {})
+ AppTheme { ImportOverridesByTextScreen({}, {}) }
}
@Destination<RootGraph>(style = DefaultTransition::class)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoginScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoginScreen.kt
index ba799d55c1..fef29516c5 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoginScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/LoginScreen.kt
@@ -95,7 +95,7 @@ import org.koin.androidx.compose.koinViewModel
private fun PreviewLoginScreen(
@PreviewParameter(LoginUiStatePreviewParameterProvider::class) state: LoginUiState
) {
- AppTheme { LoginScreen(state = state) }
+ AppTheme { LoginScreen(state = state, SnackbarHostState(), {}, {}, {}, {}, {}) }
}
private const val TOP_SPACER_WEIGHT = 1f
@@ -172,11 +172,11 @@ fun Login(
private fun LoginScreen(
state: LoginUiState,
snackbarHostState: SnackbarHostState = SnackbarHostState(),
- onLoginClick: (String) -> Unit = {},
- onCreateAccountClick: () -> Unit = {},
- onDeleteHistoryClick: () -> Unit = {},
- onAccountNumberChange: (String) -> Unit = {},
- onSettingsClick: () -> Unit = {},
+ onLoginClick: (String) -> Unit,
+ onCreateAccountClick: () -> Unit,
+ onDeleteHistoryClick: () -> Unit,
+ onAccountNumberChange: (String) -> Unit,
+ onSettingsClick: () -> Unit,
) {
ScaffoldWithTopBar(
snackbarHostState = snackbarHostState,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MultihopScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MultihopScreen.kt
index 5491fc624c..0c7be2aadc 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MultihopScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MultihopScreen.kt
@@ -33,7 +33,7 @@ import org.koin.androidx.compose.koinViewModel
@Preview
@Composable
private fun PreviewMultihopScreen() {
- AppTheme { MultihopScreen(state = MultihopUiState(false)) }
+ AppTheme { MultihopScreen(state = MultihopUiState(false), {}, {}) }
}
@Destination<RootGraph>(style = SlideInFromRightTransition::class)
@@ -51,8 +51,8 @@ fun Multihop(navigator: DestinationsNavigator) {
@Composable
fun MultihopScreen(
state: MultihopUiState,
- onMultihopClick: (enable: Boolean) -> Unit = {},
- onBackClick: () -> Unit = {},
+ onMultihopClick: (enable: Boolean) -> Unit,
+ onBackClick: () -> Unit,
) {
ScaffoldWithMediumTopBar(
appBarTitle = stringResource(id = R.string.multihop),
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt
index 10fc9cd3af..95056dba4a 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt
@@ -69,7 +69,7 @@ import org.koin.androidx.compose.koinViewModel
private fun PreviewOutOfTimeScreen(
@PreviewParameter(OutOfTimeScreenPreviewParameterProvider::class) state: OutOfTimeUiState
) {
- AppTheme { OutOfTimeScreen(state = state) }
+ AppTheme { OutOfTimeScreen(state = state, SnackbarHostState(), {}, {}, {}, {}, {}, {}, {}) }
}
@Destination<RootGraph>(style = HomeTransition::class)
@@ -137,14 +137,14 @@ fun OutOfTime(
@Composable
fun OutOfTimeScreen(
state: OutOfTimeUiState,
- snackbarHostState: SnackbarHostState = SnackbarHostState(),
- onDisconnectClick: () -> Unit = {},
- onSitePaymentClick: () -> Unit = {},
- onRedeemVoucherClick: () -> Unit = {},
- onSettingsClick: () -> Unit = {},
- onAccountClick: () -> Unit = {},
- onPurchaseBillingProductClick: (ProductId) -> Unit = { _ -> },
- navigateToVerificationPendingDialog: () -> Unit = {},
+ snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
+ onDisconnectClick: () -> Unit,
+ onSitePaymentClick: () -> Unit,
+ onRedeemVoucherClick: () -> Unit,
+ onSettingsClick: () -> Unit,
+ onAccountClick: () -> Unit,
+ onPurchaseBillingProductClick: (ProductId) -> Unit,
+ navigateToVerificationPendingDialog: () -> Unit,
) {
val scrollState = rememberScrollState()
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ReportProblemScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ReportProblemScreen.kt
index 2e5688da81..a3338d2e24 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ReportProblemScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ReportProblemScreen.kt
@@ -72,7 +72,7 @@ private fun PreviewReportProblemScreen(
@PreviewParameter(ReportProblemUiStatePreviewParameterProvider::class)
state: ReportProblemUiState
) {
- AppTheme { ReportProblemScreen(state = state) }
+ AppTheme { ReportProblemScreen(state = state, {}, {}, {}, {}, {}, {}) }
}
@Destination<RootGraph>(style = SlideInFromRightTransition::class)
@@ -115,12 +115,12 @@ fun ReportProblem(
@Composable
private fun ReportProblemScreen(
state: ReportProblemUiState,
- onSendReport: () -> Unit = {},
- onClearSendResult: () -> Unit = {},
- onNavigateToViewLogs: () -> Unit = {},
- onEmailChanged: (String) -> Unit = {},
- onDescriptionChanged: (String) -> Unit = {},
- onBackClick: () -> Unit = {},
+ onSendReport: () -> Unit,
+ onClearSendResult: () -> Unit,
+ onNavigateToViewLogs: () -> Unit,
+ onEmailChanged: (String) -> Unit,
+ onDescriptionChanged: (String) -> Unit,
+ onBackClick: () -> Unit,
) {
ScaffoldWithMediumTopBar(
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt
index 15754990f2..6bef82fd9e 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt
@@ -57,7 +57,7 @@ import org.koin.androidx.compose.koinViewModel
private fun PreviewSettingsScreen(
@PreviewParameter(SettingsUiStatePreviewParameterProvider::class) state: SettingsUiState
) {
- AppTheme { SettingsScreen(state = state) }
+ AppTheme { SettingsScreen(state = state, {}, {}, {}, {}, {}, {}, {}, {}) }
}
@OptIn(ExperimentalMaterial3Api::class)
@@ -81,18 +81,17 @@ fun Settings(navigator: DestinationsNavigator) {
)
}
-@ExperimentalMaterial3Api
@Composable
fun SettingsScreen(
state: SettingsUiState,
- onVpnSettingCellClick: () -> Unit = {},
- onSplitTunnelingCellClick: () -> Unit = {},
- onAppInfoClick: () -> Unit = {},
- onReportProblemCellClick: () -> Unit = {},
- onApiAccessClick: () -> Unit = {},
- onMultihopClick: () -> Unit = {},
- onDaitaClick: () -> Unit = {},
- onBackClick: () -> Unit = {},
+ onVpnSettingCellClick: () -> Unit,
+ onSplitTunnelingCellClick: () -> Unit,
+ onAppInfoClick: () -> Unit,
+ onReportProblemCellClick: () -> Unit,
+ onApiAccessClick: () -> Unit,
+ onMultihopClick: () -> Unit,
+ onDaitaClick: () -> Unit,
+ onBackClick: () -> Unit,
) {
ScaffoldWithMediumTopBar(
appBarTitle = stringResource(id = R.string.settings),
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ShadowsocksSettingsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ShadowsocksSettingsScreen.kt
index 0ea4b7fbb0..05a99a1c49 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ShadowsocksSettingsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ShadowsocksSettingsScreen.kt
@@ -39,7 +39,10 @@ import org.koin.androidx.compose.koinViewModel
private fun PreviewShadowsocksSettingsScreen() {
AppTheme {
ShadowsocksSettingsScreen(
- state = ShadowsocksSettingsState(port = Constraint.Any, validPortRanges = emptyList())
+ state = ShadowsocksSettingsState(port = Constraint.Any, validPortRanges = emptyList()),
+ {},
+ {},
+ {},
)
}
}
@@ -82,9 +85,9 @@ fun ShadowsocksSettings(
@Composable
fun ShadowsocksSettingsScreen(
state: ShadowsocksSettingsState,
- navigateToCustomPortDialog: () -> Unit = {},
- onObfuscationPortSelected: (Constraint<Port>) -> Unit = {},
- onBackClick: () -> Unit = {},
+ navigateToCustomPortDialog: () -> Unit,
+ onObfuscationPortSelected: (Constraint<Port>) -> Unit,
+ onBackClick: () -> Unit,
) {
ScaffoldWithMediumTopBar(
appBarTitle = stringResource(id = R.string.shadowsocks),
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt
index 0dddd926fc..5061655003 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplitTunnelingScreen.kt
@@ -59,7 +59,7 @@ private fun PreviewSplitTunnelingScreen(
@PreviewParameter(SplitTunnelingUiStatePreviewParameterProvider::class)
state: SplitTunnelingUiState
) {
- AppTheme { SplitTunnelingScreen(state = state) }
+ AppTheme { SplitTunnelingScreen(state = state, {}, {}, {}, {}, {}, { null }) }
}
@Destination<RootGraph>(style = SlideInFromRightTransition::class)
@@ -86,12 +86,12 @@ fun SplitTunneling(navigator: DestinationsNavigator) {
@Composable
fun SplitTunnelingScreen(
state: SplitTunnelingUiState,
- onEnableSplitTunneling: (Boolean) -> Unit = {},
- onShowSystemAppsClick: (show: Boolean) -> Unit = {},
- onExcludeAppClick: (packageName: String) -> Unit = {},
- onIncludeAppClick: (packageName: String) -> Unit = {},
- onBackClick: () -> Unit = {},
- onResolveIcon: (String) -> Bitmap? = { null },
+ onEnableSplitTunneling: (Boolean) -> Unit,
+ onShowSystemAppsClick: (show: Boolean) -> Unit,
+ onExcludeAppClick: (packageName: String) -> Unit,
+ onIncludeAppClick: (packageName: String) -> Unit,
+ onBackClick: () -> Unit,
+ onResolveIcon: (String) -> Bitmap?,
) {
val focusManager = LocalFocusManager.current
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/Udp2TcpSettingsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/Udp2TcpSettingsScreen.kt
index 436d8c9020..079311f123 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/Udp2TcpSettingsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/Udp2TcpSettingsScreen.kt
@@ -31,7 +31,9 @@ import org.koin.androidx.compose.koinViewModel
@Preview
@Composable
private fun PreviewUdp2TcpSettingsScreen() {
- AppTheme { Udp2TcpSettingsScreen(state = Udp2TcpSettingsState(port = Constraint.Any)) }
+ AppTheme {
+ Udp2TcpSettingsScreen(state = Udp2TcpSettingsState(port = Constraint.Any), {}, {}, {})
+ }
}
@Destination<RootGraph>(style = SlideInFromRightTransition::class)
@@ -51,9 +53,9 @@ fun Udp2TcpSettings(navigator: DestinationsNavigator) {
@Composable
fun Udp2TcpSettingsScreen(
state: Udp2TcpSettingsState,
- onObfuscationPortSelected: (Constraint<Port>) -> Unit = {},
- navigateUdp2TcpInfo: () -> Unit = {},
- onBackClick: () -> Unit = {},
+ onObfuscationPortSelected: (Constraint<Port>) -> Unit,
+ navigateUdp2TcpInfo: () -> Unit,
+ onBackClick: () -> Unit,
) {
ScaffoldWithMediumTopBar(
appBarTitle = stringResource(id = R.string.upd_over_tcp),
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt
index 7b227f9a9f..621fb42885 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ViewLogsScreen.kt
@@ -63,7 +63,7 @@ import org.koin.androidx.compose.koinViewModel
private fun PreviewViewLogsScreen(
@PreviewParameter(ViewLogsUiStatePreviewParameterProvider::class) state: ViewLogsUiState
) {
- AppTheme { ViewLogsScreen(state = state) }
+ AppTheme { ViewLogsScreen(state = state, {}) }
}
@Destination<RootGraph>(style = SlideInFromRightTransition::class)
@@ -75,7 +75,7 @@ fun ViewLogs(navigator: DestinationsNavigator) {
}
@Composable
-fun ViewLogsScreen(state: ViewLogsUiState, onBackClick: () -> Unit = {}) {
+fun ViewLogsScreen(state: ViewLogsUiState, onBackClick: () -> Unit) {
val snackbarHostState = remember { SnackbarHostState() }
val clipboardHandle = createCopyToClipboardHandle(snackbarHostState = snackbarHostState)
Scaffold(
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
index 6489b53e79..c44972e781 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
@@ -129,6 +129,19 @@ private fun PreviewVpnSettings(
onSelectObfuscationMode = {},
onSelectQuantumResistanceSetting = {},
onWireguardPortSelected = {},
+ navigateToShadowSocksSettings = {},
+ navigateToUdp2TcpSettings = {},
+ onToggleAutoStartAndConnectOnBoot = { _ -> },
+ navigateToMalwareInfo = {},
+ navigateToContentBlockersInfo = {},
+ navigateToAutoConnectScreen = {},
+ navigateToCustomDnsInfo = {},
+ navigateToObfuscationInfo = {},
+ navigateToQuantumResistanceInfo = {},
+ navigateToWireguardPortInfo = {},
+ navigateToLocalNetworkSharingInfo = {},
+ navigateToWireguardPortDialog = {},
+ navigateToServerIpOverrides = {},
)
}
}
@@ -255,39 +268,39 @@ fun VpnSettings(
)
}
-@Suppress("LongMethod")
+@Suppress("LongMethod", "LongParameterList")
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun VpnSettingsScreen(
state: VpnSettingsUiState,
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
- navigateToContentBlockersInfo: () -> Unit = {},
- navigateToAutoConnectScreen: () -> Unit = {},
- navigateToCustomDnsInfo: () -> Unit = {},
- navigateToMalwareInfo: () -> Unit = {},
- navigateToObfuscationInfo: () -> Unit = {},
- navigateToQuantumResistanceInfo: () -> Unit = {},
- navigateToWireguardPortInfo: (availablePortRanges: List<PortRange>) -> Unit = {},
- navigateToLocalNetworkSharingInfo: () -> Unit = {},
- navigateToWireguardPortDialog: () -> Unit = {},
- navigateToServerIpOverrides: () -> Unit = {},
- onToggleBlockTrackers: (Boolean) -> Unit = {},
- onToggleBlockAds: (Boolean) -> Unit = {},
- onToggleBlockMalware: (Boolean) -> Unit = {},
- onToggleLocalNetworkSharing: (Boolean) -> Unit = {},
- onToggleBlockAdultContent: (Boolean) -> Unit = {},
- onToggleBlockGambling: (Boolean) -> Unit = {},
- onToggleBlockSocialMedia: (Boolean) -> Unit = {},
- navigateToMtuDialog: (mtu: Mtu?) -> Unit = {},
- navigateToDns: (index: Int?, address: String?) -> Unit = { _, _ -> },
- onToggleDnsClick: (Boolean) -> Unit = {},
- onBackClick: () -> Unit = {},
- onSelectObfuscationMode: (obfuscationMode: ObfuscationMode) -> Unit = {},
- onSelectQuantumResistanceSetting: (quantumResistant: QuantumResistantState) -> Unit = {},
- onWireguardPortSelected: (port: Constraint<Port>) -> Unit = {},
- navigateToShadowSocksSettings: () -> Unit = {},
- navigateToUdp2TcpSettings: () -> Unit = {},
- onToggleAutoStartAndConnectOnBoot: (Boolean) -> Unit = {},
+ navigateToContentBlockersInfo: () -> Unit,
+ navigateToAutoConnectScreen: () -> Unit,
+ navigateToCustomDnsInfo: () -> Unit,
+ navigateToMalwareInfo: () -> Unit,
+ navigateToObfuscationInfo: () -> Unit,
+ navigateToQuantumResistanceInfo: () -> Unit,
+ navigateToWireguardPortInfo: (availablePortRanges: List<PortRange>) -> Unit,
+ navigateToLocalNetworkSharingInfo: () -> Unit,
+ navigateToWireguardPortDialog: () -> Unit,
+ navigateToServerIpOverrides: () -> Unit,
+ onToggleBlockTrackers: (Boolean) -> Unit,
+ onToggleBlockAds: (Boolean) -> Unit,
+ onToggleBlockMalware: (Boolean) -> Unit,
+ onToggleLocalNetworkSharing: (Boolean) -> Unit,
+ onToggleBlockAdultContent: (Boolean) -> Unit,
+ onToggleBlockGambling: (Boolean) -> Unit,
+ onToggleBlockSocialMedia: (Boolean) -> Unit,
+ navigateToMtuDialog: (mtu: Mtu?) -> Unit,
+ navigateToDns: (index: Int?, address: String?) -> Unit,
+ onToggleDnsClick: (Boolean) -> Unit,
+ onBackClick: () -> Unit,
+ onSelectObfuscationMode: (obfuscationMode: ObfuscationMode) -> Unit,
+ onSelectQuantumResistanceSetting: (quantumResistant: QuantumResistantState) -> Unit,
+ onWireguardPortSelected: (port: Constraint<Port>) -> Unit,
+ navigateToShadowSocksSettings: () -> Unit,
+ navigateToUdp2TcpSettings: () -> Unit,
+ onToggleAutoStartAndConnectOnBoot: (Boolean) -> Unit,
) {
var expandContentBlockersState by rememberSaveable { mutableStateOf(false) }
val biggerPadding = 54.dp
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreen.kt
index fc810e6882..737baa6f0c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SearchLocationScreen.kt
@@ -80,7 +80,25 @@ private fun PreviewSearchLocationScreen(
@PreviewParameter(SearchLocationsUiStatePreviewParameterProvider::class)
state: SearchLocationUiState
) {
- AppTheme { SearchLocationScreen(state = state) }
+ AppTheme {
+ SearchLocationScreen(
+ state = state,
+ SnackbarHostState(),
+ {},
+ { _, _, _ -> },
+ {},
+ {},
+ {},
+ { _, _ -> },
+ { _, _ -> },
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ )
+ }
}
data class SearchLocationNavArgs(val relayListType: RelayListType)
@@ -198,24 +216,20 @@ fun SearchLocation(
@Composable
fun SearchLocationScreen(
state: SearchLocationUiState,
- snackbarHostState: SnackbarHostState = SnackbarHostState(),
- onSelectRelay: (RelayItem) -> Unit = {},
- onToggleExpand: (RelayItemId, CustomListId?, Boolean) -> Unit = { _, _, _ -> },
- onSearchInputChanged: (String) -> Unit = {},
- onCreateCustomList: (location: RelayItem.Location?) -> Unit = {},
- onEditCustomLists: () -> Unit = {},
- onAddLocationToList: (location: RelayItem.Location, customList: RelayItem.CustomList) -> Unit =
- { _, _ ->
- },
- onRemoveLocationFromList: (location: RelayItem.Location, customListId: CustomListId) -> Unit =
- { _, _ ->
- },
- onEditCustomListName: (RelayItem.CustomList) -> Unit = {},
- onEditLocationsCustomList: (RelayItem.CustomList) -> Unit = {},
- onDeleteCustomList: (RelayItem.CustomList) -> Unit = {},
- onRemoveOwnershipFilter: () -> Unit = {},
- onRemoveProviderFilter: () -> Unit = {},
- onGoBack: () -> Unit = {},
+ snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
+ onSelectRelay: (RelayItem) -> Unit,
+ onToggleExpand: (RelayItemId, CustomListId?, Boolean) -> Unit,
+ onSearchInputChanged: (String) -> Unit,
+ onCreateCustomList: (location: RelayItem.Location?) -> Unit,
+ onEditCustomLists: () -> Unit,
+ onAddLocationToList: (location: RelayItem.Location, customList: RelayItem.CustomList) -> Unit,
+ onRemoveLocationFromList: (location: RelayItem.Location, customListId: CustomListId) -> Unit,
+ onEditCustomListName: (RelayItem.CustomList) -> Unit,
+ onEditLocationsCustomList: (RelayItem.CustomList) -> Unit,
+ onDeleteCustomList: (RelayItem.CustomList) -> Unit,
+ onRemoveOwnershipFilter: () -> Unit,
+ onRemoveProviderFilter: () -> Unit,
+ onGoBack: () -> Unit,
) {
val backgroundColor = MaterialTheme.colorScheme.surface
val onBackgroundColor = MaterialTheme.colorScheme.onSurface
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreen.kt
index 079c1e175b..cac37053ad 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/location/SelectLocationScreen.kt
@@ -83,7 +83,27 @@ private fun PreviewSelectLocationScreen(
@PreviewParameter(SelectLocationsUiStatePreviewParameterProvider::class)
state: SelectLocationUiState
) {
- AppTheme { SelectLocationScreen(state = state) }
+ AppTheme {
+ SelectLocationScreen(
+ state = state,
+ SnackbarHostState(),
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ { _, _ -> },
+ { _, _ -> },
+ {},
+ {},
+ {},
+ {},
+ {},
+ )
+ }
}
@SuppressLint("CheckResult")
@@ -202,30 +222,26 @@ fun SelectLocation(
)
}
-@Suppress("LongMethod")
+@Suppress("LongMethod", "LongParameterList")
@Composable
fun SelectLocationScreen(
state: SelectLocationUiState,
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
- onSelectRelay: (item: RelayItem) -> Unit = {},
- onSearchClick: (RelayListType) -> Unit = {},
- onBackClick: () -> Unit = {},
- onFilterClick: () -> Unit = {},
- onCreateCustomList: (location: RelayItem.Location?) -> Unit = {},
- onEditCustomLists: () -> Unit = {},
- removeOwnershipFilter: () -> Unit = {},
- removeProviderFilter: () -> Unit = {},
- onAddLocationToList: (location: RelayItem.Location, customList: RelayItem.CustomList) -> Unit =
- { _, _ ->
- },
- onRemoveLocationFromList: (location: RelayItem.Location, customListId: CustomListId) -> Unit =
- { _, _ ->
- },
- onEditCustomListName: (RelayItem.CustomList) -> Unit = {},
- onEditLocationsCustomList: (RelayItem.CustomList) -> Unit = {},
- onDeleteCustomList: (RelayItem.CustomList) -> Unit = {},
- onSelectRelayList: (RelayListType) -> Unit = {},
- openDaitaSettings: () -> Unit = {},
+ onSelectRelay: (item: RelayItem) -> Unit,
+ onSearchClick: (RelayListType) -> Unit,
+ onBackClick: () -> Unit,
+ onFilterClick: () -> Unit,
+ onCreateCustomList: (location: RelayItem.Location?) -> Unit,
+ onEditCustomLists: () -> Unit,
+ removeOwnershipFilter: () -> Unit,
+ removeProviderFilter: () -> Unit,
+ onAddLocationToList: (location: RelayItem.Location, customList: RelayItem.CustomList) -> Unit,
+ onRemoveLocationFromList: (location: RelayItem.Location, customListId: CustomListId) -> Unit,
+ onEditCustomListName: (RelayItem.CustomList) -> Unit,
+ onEditLocationsCustomList: (RelayItem.CustomList) -> Unit,
+ onDeleteCustomList: (RelayItem.CustomList) -> Unit,
+ onSelectRelayList: (RelayListType) -> Unit,
+ openDaitaSettings: () -> Unit,
) {
val backgroundColor = MaterialTheme.colorScheme.surface
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/util/Snackbar.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/util/Snackbar.kt
index 88ec729d46..f67c1e7320 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/util/Snackbar.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/util/Snackbar.kt
@@ -8,15 +8,15 @@ import androidx.compose.material3.SnackbarResult
suspend fun SnackbarHostState.showSnackbarImmediately(
message: String,
actionLabel: String? = null,
- onAction: (() -> Unit) = {},
+ onAction: (() -> Unit)? = null,
withDismissAction: Boolean = false,
- onDismiss: (() -> Unit) = {},
+ onDismiss: (() -> Unit)? = null,
duration: SnackbarDuration =
if (actionLabel == null) SnackbarDuration.Short else SnackbarDuration.Indefinite,
) {
currentSnackbarData?.dismiss()
when (showSnackbar(message, actionLabel, withDismissAction, duration)) {
- SnackbarResult.ActionPerformed -> onAction()
- SnackbarResult.Dismissed -> onDismiss()
+ SnackbarResult.ActionPerformed -> onAction?.invoke()
+ SnackbarResult.Dismissed -> onDismiss?.invoke()
}
}