Skip to content

Commit

Permalink
Implement multihop
Browse files Browse the repository at this point in the history
  • Loading branch information
Pururun committed Nov 13, 2024
1 parent e3c573d commit ca6f944
Show file tree
Hide file tree
Showing 92 changed files with 4,363 additions and 1,977 deletions.
2 changes: 2 additions & 0 deletions android/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Line wrap the file at 100 chars. Th
### Added
- Add a new access method: Encrypted DNS Proxy. Encrypted DNS proxy is a way to reach the API via
proxies. The access method is enabled by default.
- Add multihop which allows the routing of traffic through an entry and exit server, making it
harder to trace.

### Changed
- Animation has been changed to look better with predictive back.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ class ConnectScreenTest {
val inPort = 99
val inProtocol = TransportProtocol.Udp
every { mockLocation.hostname } returns mockHostName
every { mockLocation.entryHostname } returns null

// In
every { mockTunnelEndpoint.obfuscation } returns null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,7 @@ class CustomListLocationsScreenTest {
}

// Assert
onNodeWithText(EMPTY_SEARCH_FIRST_ROW.format(mockSearchString), substring = true)
.assertExists()
onNodeWithText(EMPTY_SEARCH_SECOND_ROW, substring = true).assertExists()
onNodeWithText(EMPTY_SEARCH.format(mockSearchString)).assertExists()
}

@Test
Expand Down Expand Up @@ -239,8 +237,7 @@ class CustomListLocationsScreenTest {
const val ADD_LOCATIONS_TEXT = "Add locations"
const val EDIT_LOCATIONS_TEXT = "Edit locations"
const val SEARCH_PLACEHOLDER = "Search for..."
const val EMPTY_SEARCH_FIRST_ROW = "No result for %s."
const val EMPTY_SEARCH_SECOND_ROW = "Try a different search"
const val EMPTY_SEARCH = "No result for \"%s\", please try a different search"
const val NO_LOCATIONS_FOUND_TEXT = "No locations found"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class SettingsScreenTest {
isLoggedIn = true,
isSupportedVersion = true,
isPlayBuild = false,
multihopEnabled = false,
)
)
}
Expand All @@ -56,6 +57,7 @@ class SettingsScreenTest {
isLoggedIn = false,
isSupportedVersion = true,
isPlayBuild = false,
multihopEnabled = false,
)
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package net.mullvad.mullvadvpn.compose.screen.location

import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performTextInput
import io.mockk.MockKAnnotations
import io.mockk.mockk
import io.mockk.unmockkAll
import io.mockk.verify
import net.mullvad.mullvadvpn.compose.createEdgeToEdgeComposeExtension
import net.mullvad.mullvadvpn.compose.data.DUMMY_RELAY_ITEM_CUSTOM_LISTS
import net.mullvad.mullvadvpn.compose.setContentWithTheme
import net.mullvad.mullvadvpn.compose.state.RelayListItem
import net.mullvad.mullvadvpn.compose.state.SearchLocationUiState
import net.mullvad.mullvadvpn.compose.test.SELECT_LOCATION_CUSTOM_LIST_HEADER_TEST_TAG
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.RegisterExtension

@OptIn(ExperimentalTestApi::class)
class SearchLocationScreenTest {
@JvmField @RegisterExtension val composeExtension = createEdgeToEdgeComposeExtension()

@BeforeEach
fun setup() {
MockKAnnotations.init(this)
}

@AfterEach
fun teardown() {
unmockkAll()
}

@Test
fun testSearchInput() =
composeExtension.use {
// Arrange
val mockedSearchTermInput: (String) -> Unit = mockk(relaxed = true)
setContentWithTheme {
SearchLocationScreen(
state =
SearchLocationUiState.NoQuery(searchTerm = "", filterChips = emptyList()),
onSearchInputChanged = mockedSearchTermInput,
)
}
val mockSearchString = "SEARCH"

// Act
onNodeWithText("Search for...").performTextInput(mockSearchString)

// Assert
verify { mockedSearchTermInput.invoke(mockSearchString) }
}

@Test
fun testSearchTermNotFound() =
composeExtension.use {
// Arrange
val mockSearchString = "SEARCH"
setContentWithTheme {
SearchLocationScreen(
state =
SearchLocationUiState.Content(
searchTerm = mockSearchString,
filterChips = emptyList(),
relayListItems =
listOf(RelayListItem.LocationsEmptyText(mockSearchString)),
customLists = emptyList(),
)
)
}

// Assert
onNodeWithText("No result for \"$mockSearchString\", please try a different search")
.assertExists()
}

@Test
fun givenNoCustomListsAndSearchIsActiveShouldNotShowCustomListHeader() =
composeExtension.use {
// Arrange
val mockSearchString = "SEARCH"
setContentWithTheme {
SearchLocationScreen(
state =
SearchLocationUiState.Content(
searchTerm = mockSearchString,
filterChips = emptyList(),
relayListItems = emptyList(),
customLists = DUMMY_RELAY_ITEM_CUSTOM_LISTS,
)
)
}

// Assert
onNodeWithText(CUSTOM_LISTS_EMPTY_TEXT).assertDoesNotExist()
onNodeWithTag(SELECT_LOCATION_CUSTOM_LIST_HEADER_TEST_TAG).assertDoesNotExist()
}

companion object {
private const val CUSTOM_LISTS_EMPTY_TEXT = "To create a custom list press the \"\""
}
}
Loading

0 comments on commit ca6f944

Please sign in to comment.