diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreenTest.kt index 4844177b45ac..106d960d1fa2 100644 --- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreenTest.kt +++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreenTest.kt @@ -82,9 +82,13 @@ class SelectLocationScreenTest { uiState = SelectLocationUiState.ShowData( countries = - DUMMY_RELAY_COUNTRIES.apply { - this[0].expanded = true - this[0].cities[0].expanded = true + DUMMY_RELAY_COUNTRIES.let { + val cities = it[0].cities.toMutableList() + val city = cities.removeAt(0) + cities.add(0, city.copy(expanded = true)) + it.toMutableList()[0] = + it[0].copy(expanded = true, cities = cities.toList()) + it }, selectedRelay = DUMMY_RELAY_COUNTRIES[0].cities[0].relays[0] ), 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 78521592478f..18eebb8b85ad 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 @@ -100,7 +100,7 @@ fun ConnectionButton( @Preview @Composable -fun PreviewConnectionButton() { +private fun PreviewConnectionButton() { AppTheme { ConnectionButton( text = "Disconnect", diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/SwitchLocationButton.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/SwitchLocationButton.kt index e58e7e22025e..906afbb65ce6 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/SwitchLocationButton.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/SwitchLocationButton.kt @@ -22,7 +22,7 @@ import net.mullvad.mullvadvpn.lib.theme.Dimens @Preview @Composable -fun PreviewSwitchLocationButton() { +private fun PreviewSwitchLocationButton() { AppTheme { SpacedColumn { SwitchLocationButton(onClick = {}, text = "Switch Location", showChevron = false) 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 ab3e45c5c4e8..7021081963b8 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 @@ -33,7 +33,7 @@ import net.mullvad.mullvadvpn.lib.theme.Dimens @Preview @Composable -fun PreviewCustomPortCell() { +private fun PreviewCustomPortCell() { AppTheme { SpacedColumn(Modifier.background(MaterialTheme.colorScheme.background)) { CustomPortCell(title = "Title", isSelected = true, port = "444") diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt index fa896b2c9afe..742302ce91ae 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt @@ -15,7 +15,7 @@ import net.mullvad.talpid.tunnel.ErrorStateCause @Preview @Composable -fun PreviewConnectionStatusText() { +private fun PreviewConnectionStatusText() { AppTheme { SpacedColumn { ConnectionStatusText(TunnelState.Disconnected) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/List.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/List.kt index 7ff5b7f6cfab..66d9aea0fa35 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/List.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/List.kt @@ -32,7 +32,7 @@ import net.mullvad.mullvadvpn.lib.theme.typeface.listItemText @Preview @Composable -fun PreviewListItem() { +private fun PreviewListItem() { AppTheme { Column { ListItem(text = "No subtext No icon not loading", isLoading = false, onClick = {}) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/LocationInfo.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/LocationInfo.kt index 3f12457b8692..161bce9b7583 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/LocationInfo.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/LocationInfo.kt @@ -25,7 +25,7 @@ import net.mullvad.talpid.net.TransportProtocol @Preview @Composable -fun PreviewLocationInfo() { +private fun PreviewLocationInfo() { AppTheme { LocationInfo( onToggleTunnelInfo = {}, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/NotificationBanner.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/NotificationBanner.kt index 4e638d56b2e7..0f7fa7411719 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/NotificationBanner.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/NotificationBanner.kt @@ -40,7 +40,7 @@ import org.joda.time.DateTime @Preview @Composable -fun PreviewNotificationBanner() { +private fun PreviewNotificationBanner() { AppTheme { SpacedColumn(Modifier.background(color = MaterialTheme.colorScheme.background)) { val versionInfoNotification = diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scrollbar.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scrollbar.kt index 4af39cf4b5ae..35ddc585923f 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scrollbar.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/Scrollbar.kt @@ -287,7 +287,7 @@ private val FadeOutAnimationSpec = @Preview(widthDp = 400, heightDp = 400, showBackground = true) @Composable -internal fun ScrollbarPreview() { +private fun PreviewScrollbar() { val state = rememberScrollState() Column( modifier = Modifier.drawVerticalScrollbar(state).verticalScroll(state), @@ -300,7 +300,7 @@ internal fun ScrollbarPreview() { @Preview(widthDp = 400, heightDp = 400, showBackground = true) @Composable -internal fun LazyListScrollbarPreview() { +private fun PreviewLazyListScrollbar() { val state = rememberLazyListState() LazyColumn(modifier = Modifier.drawVerticalScrollbar(state), state = state) { items(50) { @@ -311,7 +311,7 @@ internal fun LazyListScrollbarPreview() { @Preview(widthDp = 400, showBackground = true) @Composable -internal fun HorizontalScrollbarPreview() { +private fun PreviewHorizontalScrollbar() { val state = rememberScrollState() Row(modifier = Modifier.drawHorizontalScrollbar(state).horizontalScroll(state)) { repeat(50) { @@ -325,7 +325,7 @@ internal fun HorizontalScrollbarPreview() { @Preview(widthDp = 400, showBackground = true) @Composable -internal fun LazyListHorizontalScrollbarPreview() { +private fun PreviewLazyListHorizontalScrollbar() { val state = rememberLazyListState() LazyRow(modifier = Modifier.drawHorizontalScrollbar(state), state = state) { items(50) { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CustomPortDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CustomPortDialog.kt index 3c36ca8f8885..e23af1356484 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CustomPortDialog.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/CustomPortDialog.kt @@ -30,7 +30,7 @@ import net.mullvad.mullvadvpn.util.isPortInValidRanges @Preview @Composable -fun PreviewCustomPortDialog() { +private fun PreviewCustomPortDialog() { AppTheme { CustomPortDialog( onSave = {}, 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 8ca98c410a9d..f2d5f9cd9552 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 @@ -55,7 +55,7 @@ private const val CONNECT_BUTTON_THROTTLE_MILLIS = 1000 @Preview @Composable -fun PreviewConnectScreen() { +private fun PreviewConnectScreen() { val state = ConnectUiState.INITIAL AppTheme { ConnectScreen( 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 2e72e1280147..37669a98512c 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 @@ -41,7 +41,7 @@ import net.mullvad.mullvadvpn.util.formatDate @Composable @Preview -fun PreviewDeviceListScreen() { +private fun PreviewDeviceListScreen() { AppTheme { DeviceListScreen( state = 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 c7f0c8416f96..22fa8a0469a8 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 @@ -32,7 +32,7 @@ import net.mullvad.mullvadvpn.lib.theme.AppTheme @Preview @Composable -fun PreivewDeviceRevokedScreen() { +private fun PreviewDeviceRevokedScreen() { AppTheme { DeviceRevokedScreen(state = DeviceRevokedUiState.SECURED) } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/PrivacyDisclaimerScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/PrivacyDisclaimerScreen.kt index 50ec92c45e5a..3de32531e898 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/PrivacyDisclaimerScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/PrivacyDisclaimerScreen.kt @@ -36,7 +36,7 @@ import net.mullvad.mullvadvpn.lib.theme.AppTheme @Preview @Composable -fun PreviewPrivacyDisclaimerScreen() { +private fun PreviewPrivacyDisclaimerScreen() { AppTheme { PrivacyDisclaimerScreen({}, {}) } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt index 3376ffe422e6..fec20ceb185c 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SelectLocationScreen.kt @@ -18,7 +18,6 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi @@ -54,7 +53,7 @@ import net.mullvad.mullvadvpn.relaylist.RelayItem @Preview @Composable -fun PreviewSelectLocationScreen() { +private fun PreviewSelectLocationScreen() { val state = SelectLocationUiState.ShowData( countries = listOf(RelayCountry("Country 1", "Code 1", false, emptyList())), 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 f5e512f8f699..ad9a7d3af26f 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 @@ -44,7 +44,7 @@ import net.mullvad.mullvadvpn.lib.theme.Dimens @Preview @Composable -fun PreviewSplitTunnelingScreen() { +private fun PreviewSplitTunnelingScreen() { AppTheme { SplitTunnelingScreen( uiState = diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/Relay.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/Relay.kt index f3c3a3cc7cc6..9bdb59168b1a 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/Relay.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/Relay.kt @@ -12,7 +12,5 @@ data class Relay( override val type = RelayItemType.Relay override val hasChildren = false - override var expanded - get() = false - set(_) {} + override val expanded = false } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayCity.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayCity.kt index d1a3332a78b6..e3693963f81f 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayCity.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayCity.kt @@ -6,7 +6,7 @@ data class RelayCity( override val name: String, override val code: String, override val location: GeographicLocationConstraint, - override var expanded: Boolean, + override val expanded: Boolean, val relays: List ) : RelayItem { override val type = RelayItemType.City diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayCountry.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayCountry.kt index d418fd3a4ae3..3ad1d5962fcc 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayCountry.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayCountry.kt @@ -5,7 +5,7 @@ import net.mullvad.mullvadvpn.model.GeographicLocationConstraint data class RelayCountry( override val name: String, override val code: String, - override var expanded: Boolean, + override val expanded: Boolean, val cities: List ) : RelayItem { override val type = RelayItemType.Country diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayItem.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayItem.kt index f4387e96471c..3d38d6b0685d 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayItem.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayItem.kt @@ -13,5 +13,5 @@ interface RelayItem { val locationName: String get() = name - var expanded: Boolean + val expanded: Boolean } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayListExtensions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayListExtensions.kt index 401f03d744d3..39618f96034e 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayListExtensions.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/relaylist/RelayListExtensions.kt @@ -122,8 +122,9 @@ fun List.filterOnSearchTerm( // Finally if the city has not already been added to the filtered list, add it, but // do not expand it yet. if (relayCity.name.contains(other = searchTerm, ignoreCase = true)) { - if (filteredCountries.containsKey(relayCountry.code)) { - filteredCountries[relayCountry.code]?.expanded = true + val value = filteredCountries[relayCountry.code] + if (value != null) { + filteredCountries[relayCountry.code] = value.copy(expanded = true) } else { filteredCountries[relayCountry.code] = relayCountry.copy(expanded = true, cities = cities) @@ -141,15 +142,23 @@ fun List.filterOnSearchTerm( // if so expand it, if not add it to the filtered list and expand it. // Finally add the relay to the list. if (relay.name.contains(other = searchTerm, ignoreCase = true)) { - if (filteredCountries.containsKey(relayCountry.code)) { - filteredCountries[relayCountry.code]?.expanded = true + val value = filteredCountries[relayCountry.code] + if (value != null) { + filteredCountries[relayCountry.code] = value.copy(expanded = true) } else { filteredCountries[relayCountry.code] = relayCountry.copy(expanded = true, cities = cities) } - val city = cities.find { it.code == relayCity.code } - city?.let { city.expanded = true } - ?: run { cities.add(relayCity.copy(expanded = true, relays = relays)) } + val cityIndex = cities.indexOfFirst { it.code == relayCity.code } + + // No city found + if (cityIndex < 0) { + cities.add(relayCity.copy(expanded = true, relays = relays)) + } else { + // Update found city as expanded + cities[cityIndex] = cities[cityIndex].copy(expanded = true) + } + relays.add(relay.copy()) } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModel.kt index 4099e524807d..a03de806b4b6 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AccountViewModel.kt @@ -38,7 +38,7 @@ class AccountViewModel( } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), AccountUiState.default()) - @Suppress("konsist.ensurePublicPropertiesUsePermittedNames") + @Suppress("konsist.ensure public properties use permitted names") val enterTransitionEndAction = _enterTransitionEndAction.asSharedFlow() fun onManageAccountClick() { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt index c554bd4daa48..98648e0015bb 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt @@ -37,10 +37,11 @@ class DeviceListViewModel( private val _loadingDevices = MutableStateFlow>(emptyList()) private val _toastMessages = MutableSharedFlow(extraBufferCapacity = 1) - @Suppress("konsist.ensurePublicPropertiesUsePermittedNames") + @Suppress("konsist.ensure public properties use permitted names") val toastMessages = _toastMessages.asSharedFlow() - @Suppress("konsist.ensurePublicPropertiesUsePermittedNames") var accountToken: String? = null + @Suppress("konsist.ensure public properties use permitted names") + var accountToken: String? = null private var cachedDeviceList: List? = null val uiState = diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModel.kt index 2ae361c96440..2507e9fb1903 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SelectLocationViewModel.kt @@ -66,9 +66,9 @@ class SelectLocationViewModel(private val serviceConnectionManager: ServiceConne SelectLocationUiState.Loading ) - @Suppress("konsist.ensurePublicPropertiesUsePermittedNames") + @Suppress("konsist.ensure public properties use permitted names") val uiCloseAction = _closeAction.asSharedFlow() - @Suppress("konsist.ensurePublicPropertiesUsePermittedNames") + @Suppress("konsist.ensure public properties use permitted names") val enterTransitionEndAction = _enterTransitionEndAction.asSharedFlow() fun selectRelay(relayItem: RelayItem?) { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SettingsViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SettingsViewModel.kt index 89adbe20befd..fb357dfe2a3a 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SettingsViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SettingsViewModel.kt @@ -45,7 +45,7 @@ class SettingsViewModel( SettingsUiState(appVersion = "", isLoggedIn = false, isUpdateAvailable = false) ) - @Suppress("konsist.ensurePublicPropertiesUsePermittedNames") + @Suppress("konsist.ensure public properties use permitted names") val enterTransitionEndAction = _enterTransitionEndAction.asSharedFlow() fun onTransitionAnimationEnd() { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt index 2c8e30f2b479..9c25fe824f75 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt @@ -51,7 +51,7 @@ class VpnSettingsViewModel( ) : ViewModel() { private val _toastMessages = MutableSharedFlow(extraBufferCapacity = 1) - @Suppress("konsist.ensurePublicPropertiesUsePermittedNames") + @Suppress("konsist.ensure public properties use permitted names") val toastMessages = _toastMessages.asSharedFlow() private val dialogState = diff --git a/android/buildSrc/src/main/kotlin/Dependencies.kt b/android/buildSrc/src/main/kotlin/Dependencies.kt index 80c33136835d..d23399c915f6 100644 --- a/android/buildSrc/src/main/kotlin/Dependencies.kt +++ b/android/buildSrc/src/main/kotlin/Dependencies.kt @@ -62,6 +62,9 @@ object Dependencies { const val uiTooling = "androidx.compose.ui:ui-tooling:${Versions.Compose.base}" const val uiToolingPreview = "androidx.compose.ui:ui-tooling-preview:${Versions.Compose.base}" + const val uiToolingAndroidPreview = + "androidx.compose.ui:ui-tooling-preview-android:${Versions.Compose.base}" + } object Koin { diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayConstraintsUpdate.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayConstraintsUpdate.kt index bd5bfb9605d1..991ae7dbdeef 100644 --- a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayConstraintsUpdate.kt +++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/model/RelayConstraintsUpdate.kt @@ -1,6 +1,6 @@ package net.mullvad.mullvadvpn.model data class RelayConstraintsUpdate( - var location: Constraint?, - var wireguardConstraints: WireguardConstraints? + val location: Constraint?, + val wireguardConstraints: WireguardConstraints? ) diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettingsUpdate.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettingsUpdate.kt index a7d4c0b03d0a..f8d27f115e37 100644 --- a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettingsUpdate.kt +++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/model/RelaySettingsUpdate.kt @@ -3,5 +3,5 @@ package net.mullvad.mullvadvpn.model sealed class RelaySettingsUpdate { object CustomTunnelEndpoint : RelaySettingsUpdate() - data class Normal(var constraints: RelayConstraintsUpdate) : RelaySettingsUpdate() + data class Normal(val constraints: RelayConstraintsUpdate) : RelaySettingsUpdate() } diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelState.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelState.kt index c3d58d2ca7e9..364c8861ceda 100644 --- a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelState.kt +++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/model/TunnelState.kt @@ -34,6 +34,27 @@ sealed class TunnelState : Parcelable { } } + override fun toString(): String = + when (this) { + is Disconnected -> DISCONNECTED + is Connecting -> CONNECTING + is Connected -> CONNECTED + is Disconnecting -> { + if (actionAfterDisconnect == ActionAfterDisconnect.Reconnect) { + RECONNECTING + } else { + DISCONNECTING + } + } + is Error -> { + if (errorState.isBlocking) { + BLOCKING + } else { + ERROR + } + } + } + companion object { const val DISCONNECTED = "disconnected" const val CONNECTING = "connecting" @@ -58,25 +79,4 @@ sealed class TunnelState : Parcelable { } } } - - override fun toString(): String = - when (this) { - is Disconnected -> DISCONNECTED - is Connecting -> CONNECTING - is Connected -> CONNECTED - is Disconnecting -> { - if (actionAfterDisconnect == ActionAfterDisconnect.Reconnect) { - RECONNECTING - } else { - DISCONNECTING - } - } - is Error -> { - if (errorState.isBlocking) { - BLOCKING - } else { - ERROR - } - } - } } diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt index 3f7149b282a4..cd05d5cc7139 100644 --- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt @@ -28,13 +28,6 @@ import net.mullvad.talpid.TalpidVpnService import org.koin.core.context.loadKoinModules class MullvadVpnService : TalpidVpnService() { - companion object { - private val TAG = "mullvad" - - init { - System.loadLibrary("mullvad_jni") - } - } private enum class PendingAction { Connect, @@ -273,4 +266,12 @@ class MullvadVpnService : TalpidVpnService() { startActivity(intent) } + + companion object { + private val TAG = "mullvad" + + init { + System.loadLibrary("mullvad_jni") + } + } } diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt index d6ba237f97e0..ba470a6b2428 100644 --- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt @@ -17,15 +17,6 @@ import net.mullvad.mullvadvpn.model.GetAccountDataResult import net.mullvad.talpid.util.EventNotifier class AccountCache(private val endpoint: ServiceEndpoint) { - companion object { - private sealed class Command { - object CreateAccount : Command() - - data class Login(val account: String) : Command() - - object Logout : Command() - } - } private val commandChannel = spawnActor() @@ -179,4 +170,14 @@ class AccountCache(private val endpoint: ServiceEndpoint) { private suspend fun fetchAccountData(accountToken: String): GetAccountDataResult { return daemon.await().getAccountData(accountToken) } + + companion object { + private sealed class Command { + object CreateAccount : Command() + + data class Login(val account: String) : Command() + + object Logout : Command() + } + } } diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AuthTokenCache.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AuthTokenCache.kt index 6506c0469d6c..08b0943c4d6f 100644 --- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AuthTokenCache.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AuthTokenCache.kt @@ -11,12 +11,6 @@ import net.mullvad.mullvadvpn.lib.ipc.Event import net.mullvad.mullvadvpn.lib.ipc.Request class AuthTokenCache(endpoint: ServiceEndpoint) { - companion object { - private enum class Command { - Fetch - } - } - private val daemon = endpoint.intermittentDaemon private val requestQueue = spawnActor() @@ -46,4 +40,10 @@ class AuthTokenCache(endpoint: ServiceEndpoint) { // Closed sender, so stop the actor } } + + companion object { + private enum class Command { + Fetch + } + } } diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/LocationInfoCache.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/LocationInfoCache.kt index e050421699b1..2d06cc109f73 100644 --- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/LocationInfoCache.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/LocationInfoCache.kt @@ -22,12 +22,6 @@ import net.mullvad.mullvadvpn.service.util.ExponentialBackoff import net.mullvad.talpid.tunnel.ActionAfterDisconnect class LocationInfoCache(private val endpoint: ServiceEndpoint) { - companion object { - private enum class RequestFetch { - ForRealLocation, - ForRelayLocation, - } - } private val fetchRetryDelays = ExponentialBackoff().apply { @@ -135,4 +129,11 @@ class LocationInfoCache(private val endpoint: ServiceEndpoint) { selectedRelayLocation = constraint?.value?.toGeographicLocationConstraint()?.location } + + companion object { + private enum class RequestFetch { + ForRealLocation, + ForRelayLocation, + } + } } diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt index 1abf64907c89..09f90a44d5da 100644 --- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt @@ -19,12 +19,6 @@ import net.mullvad.mullvadvpn.model.WireguardConstraints import net.mullvad.mullvadvpn.service.MullvadDaemon class RelayListListener(endpoint: ServiceEndpoint) { - companion object { - private enum class Command { - SetRelayLocation, - SetWireguardConstraints - } - } private val commandChannel = spawnActor() private val daemon = endpoint.intermittentDaemon @@ -105,4 +99,11 @@ class RelayListListener(endpoint: ServiceEndpoint) { daemon.await().updateRelaySettings(update) } + + companion object { + private enum class Command { + SetRelayLocation, + SetWireguardConstraints + } + } } diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt index e9aa8d432860..fe7ddb75e9cc 100644 --- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt @@ -27,13 +27,6 @@ class ServiceEndpoint( val connectivityListener: ConnectivityListener, context: Context ) { - companion object { - sealed class Command { - data class RegisterListener(val listener: Messenger) : Command() - - data class UnregisterListener(val listenerId: Int) : Command() - } - } private val listeners = mutableMapOf() private val commands: SendChannel = startRegistrator() @@ -165,4 +158,12 @@ class ServiceEndpoint( return listenerId } + + companion object { + sealed class Command { + data class RegisterListener(val listener: Messenger) : Command() + + data class UnregisterListener(val listenerId: Int) : Command() + } + } } diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/AccountExpiryNotification.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/AccountExpiryNotification.kt index b6085221f176..6ed6a5b72ec0 100644 --- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/AccountExpiryNotification.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/AccountExpiryNotification.kt @@ -28,11 +28,6 @@ class AccountExpiryNotification( val daemon: Intermittent, val accountCache: AccountCache ) { - companion object { - val NOTIFICATION_ID: Int = 2 - val REMAINING_TIME_FOR_REMINDERS = Duration.standardDays(2) - val TIME_BETWEEN_CHECKS: Long = 12 /* h */ * 60 /* min */ * 60 /* s */ * 1000 /* ms */ - } private val jobTracker = JobTracker() private val resources = context.resources @@ -143,4 +138,10 @@ class AccountExpiryNotification( private fun getRemainingText(pluralId: Int, quantity: Int): String { return resources.getQuantityString(pluralId, quantity, quantity) } + + companion object { + val NOTIFICATION_ID: Int = 2 + val REMAINING_TIME_FOR_REMINDERS = Duration.standardDays(2) + val TIME_BETWEEN_CHECKS: Long = 12 /* h */ * 60 /* min */ * 60 /* s */ * 1000 /* ms */ + } } diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt index a19358f95eba..97bddc860805 100644 --- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt @@ -18,10 +18,6 @@ import net.mullvad.talpid.tunnel.ActionAfterDisconnect import net.mullvad.talpid.tunnel.ErrorStateCause class TunnelStateNotification(val context: Context) { - companion object { - val NOTIFICATION_ID: Int = 1 - } - private val channel = NotificationChannel( context, @@ -149,4 +145,8 @@ class TunnelStateNotification(val context: Context) { return NotificationCompat.Action(action.icon, label, pendingIntent) } + + companion object { + val NOTIFICATION_ID: Int = 1 + } } diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotificationAction.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotificationAction.kt index c415940ea87c..c836c765f6bb 100644 --- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotificationAction.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotificationAction.kt @@ -12,28 +12,6 @@ enum class TunnelStateNotificationAction { Cancel, Dismiss; - companion object { - fun from(tunnelState: TunnelState) = - when (tunnelState) { - is TunnelState.Disconnected -> Connect - is TunnelState.Connecting -> Cancel - is TunnelState.Connected -> Disconnect - is TunnelState.Disconnecting -> { - when (tunnelState.actionAfterDisconnect) { - ActionAfterDisconnect.Reconnect -> Cancel - else -> Connect - } - } - is TunnelState.Error -> { - if (tunnelState.errorState.isBlocking) { - Disconnect - } else { - Dismiss - } - } - } - } - val text get() = when (this) { @@ -56,4 +34,26 @@ enum class TunnelStateNotificationAction { Connect -> R.drawable.icon_notification_connect else -> R.drawable.icon_notification_disconnect } + + companion object { + fun from(tunnelState: TunnelState) = + when (tunnelState) { + is TunnelState.Disconnected -> Connect + is TunnelState.Connecting -> Cancel + is TunnelState.Connected -> Disconnect + is TunnelState.Disconnecting -> { + when (tunnelState.actionAfterDisconnect) { + ActionAfterDisconnect.Reconnect -> Cancel + else -> Connect + } + } + is TunnelState.Error -> { + if (tunnelState.errorState.isBlocking) { + Disconnect + } else { + Dismiss + } + } + } + } } diff --git a/android/test/arch/build.gradle.kts b/android/test/arch/build.gradle.kts index 0a28fd2fab3c..dff039f0e2f8 100644 --- a/android/test/arch/build.gradle.kts +++ b/android/test/arch/build.gradle.kts @@ -7,18 +7,14 @@ android { namespace = "net.mullvad.mullvadvpn.test.arch" compileSdk = Versions.Android.compileSdkVersion - defaultConfig { - minSdk = Versions.Android.minSdkVersion - } + defaultConfig { minSdk = Versions.Android.minSdkVersion } compileOptions { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } - kotlinOptions { - jvmTarget = Versions.jvmTarget - } + kotlinOptions { jvmTarget = Versions.jvmTarget } lint { lintConfig = file("${rootProject.projectDir}/config/lint.xml") @@ -28,14 +24,11 @@ android { } androidComponents { - beforeVariants { variantBuilder -> - variantBuilder.apply { - enable = name != "release" - } - } + beforeVariants { variantBuilder -> variantBuilder.apply { enable = name != "release" } } } dependencies { + testImplementation(Dependencies.Compose.uiToolingAndroidPreview) testImplementation(Dependencies.AndroidX.appcompat) testImplementation(Dependencies.junit) testImplementation(Dependencies.konsist) diff --git a/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/ArchitectureTests.kt b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/ArchitectureTests.kt new file mode 100644 index 000000000000..2a7e1e205e34 --- /dev/null +++ b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/ArchitectureTests.kt @@ -0,0 +1,17 @@ +package net.mullvad.mullvadvpn.test.arch + +import com.lemonappdev.konsist.api.Konsist +import com.lemonappdev.konsist.api.architecture.KoArchitectureCreator.assertArchitecture +import com.lemonappdev.konsist.api.architecture.Layer +import org.junit.Test + +class ArchitectureTests { + + @Test + fun `ensure model layer depends on nothing`() = + Konsist.scopeFromProduction().assertArchitecture { + val model = Layer("Model", "net.mullvad.mullvadvpn.model..") + + model.dependsOnNothing() + } +} diff --git a/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/GeneralTests.kt b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/GeneralTests.kt new file mode 100644 index 000000000000..60842537c3af --- /dev/null +++ b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/GeneralTests.kt @@ -0,0 +1,24 @@ +package net.mullvad.mullvadvpn.test.arch + +import com.lemonappdev.konsist.api.Konsist +import com.lemonappdev.konsist.api.ext.list.properties +import com.lemonappdev.konsist.api.verify.assert +import com.lemonappdev.konsist.api.verify.assertNot +import org.junit.Test + +class GeneralTests { + @Test + fun `ensure package name must match file path`() = + Konsist.scopeFromProject().packages.assert { it.hasMatchingPath } + + @Test + fun `ensure no field should have 'm' prefix`() = + Konsist.scopeFromProject().classes().properties().assertNot { + val secondCharacterIsUppercase = it.name.getOrNull(1)?.isUpperCase() ?: false + it.name.startsWith('m') && secondCharacterIsUppercase + } + + @Test + fun `ensure no empty files allowed`() = + Konsist.scopeFromProject().files.assertNot { it.text.isEmpty() } +} diff --git a/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/KonsistTests.kt b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/KonsistTests.kt new file mode 100644 index 000000000000..f2954bdb687b --- /dev/null +++ b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/KonsistTests.kt @@ -0,0 +1,14 @@ +package net.mullvad.mullvadvpn.test.arch + +import com.lemonappdev.konsist.api.Konsist +import com.lemonappdev.konsist.api.ext.list.withAnnotationOf +import com.lemonappdev.konsist.api.verify.assert +import org.junit.Test + +class KonsistTests { + @Test + fun `ensure konsist tests have 'ensure ' prefix`() = + Konsist.scopeFromModule("test/arch").functions().withAnnotationOf(Test::class).assert { + it.hasNameStartingWith("ensure ") + } +} diff --git a/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/ViewModelTests.kt b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/ViewModelTests.kt index 8347c799d71f..0f23e52a4379 100644 --- a/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/ViewModelTests.kt +++ b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/ViewModelTests.kt @@ -12,26 +12,23 @@ import org.junit.Test class ViewModelTests { @Test - fun ensureViewModelsHaveViewModelSuffix() { + fun `ensure view models have view model suffix`() = allViewModels().assert { it.name.endsWith("ViewModel") } - } // The purpose of this check is to both keep the naming consistent and also to avoid exposing // properties that shouldn't be exposed. @Test - fun ensurePublicPropertiesUsePermittedNames() { + fun `ensure public properties use permitted names`() = allViewModels().properties(includeNested = false).withPublicOrDefaultModifier().assert { property -> property.name == "uiState" || property.name == "uiSideEffect" } - } @Test - fun ensurePublicFunctionsHaveNoReturnType() { + fun `ensure public functions have no return type`() = allViewModels().functions().withPublicOrDefaultModifier().assertNot { function -> function.hasReturnType() } - } private fun allViewModels() = Konsist.scopeFromProject().classes().withAllParentsOf(ViewModel::class) diff --git a/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/classes/ClassTests.kt b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/classes/ClassTests.kt new file mode 100644 index 000000000000..918139bf2458 --- /dev/null +++ b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/classes/ClassTests.kt @@ -0,0 +1,20 @@ +package net.mullvad.mullvadvpn.test.arch.classes + +import com.lemonappdev.konsist.api.Konsist +import com.lemonappdev.konsist.api.verify.assert +import org.junit.Test + +class ClassTests { + @Test + fun `ensure companion object is last declaration in the class`() = + Konsist.scopeFromProject().classes(includeNested = true).assert { + val companionObject = + it.objects(includeNested = false).lastOrNull { obj -> obj.hasCompanionModifier } + if (companionObject != null) { + it.declarations(includeNested = false, includeLocal = false).last() == + companionObject + } else { + true + } + } +} diff --git a/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/classes/DataClassTests.kt b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/classes/DataClassTests.kt new file mode 100644 index 000000000000..cc2f7262b128 --- /dev/null +++ b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/classes/DataClassTests.kt @@ -0,0 +1,17 @@ +package net.mullvad.mullvadvpn.test.arch.classes + +import com.lemonappdev.konsist.api.Konsist +import com.lemonappdev.konsist.api.ext.list.modifierprovider.withDataModifier +import com.lemonappdev.konsist.api.ext.list.properties +import com.lemonappdev.konsist.api.verify.assertNot +import org.junit.Test + +class DataClasses { + @Test + fun `ensure data classes only use immutable properties`() = + Konsist.scopeFromProject() + .classes(includeNested = true) + .withDataModifier() + .properties(includeNested = false, includeLocal = false) + .assertNot { it.hasVarModifier } +} diff --git a/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/compose/ComposePreviewTests.kt b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/compose/ComposePreviewTests.kt new file mode 100644 index 000000000000..5f8b1fef8026 --- /dev/null +++ b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/compose/ComposePreviewTests.kt @@ -0,0 +1,20 @@ +package net.mullvad.mullvadvpn.test.arch.compose + +import androidx.compose.ui.tooling.preview.Preview +import com.lemonappdev.konsist.api.Konsist +import com.lemonappdev.konsist.api.ext.list.withAllAnnotationsOf +import com.lemonappdev.konsist.api.verify.assert +import org.junit.Test + +class ComposePreviewTests { + @Test + fun `ensure all preview functions are private`() = + allPreviewFunctions().assert { it.hasPrivateModifier } + + @Test + fun `ensure all preview functions are prefixed with 'Preview'`() = + allPreviewFunctions().assert { it.name.startsWith("Preview") } + + private fun allPreviewFunctions() = + Konsist.scopeFromProduction("app").functions().withAllAnnotationsOf(Preview::class) +} diff --git a/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/compose/ComposeTests.kt b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/compose/ComposeTests.kt new file mode 100644 index 000000000000..025f10d11f25 --- /dev/null +++ b/android/test/arch/src/test/kotlin/net/mullvad/mullvadvpn/test/arch/compose/ComposeTests.kt @@ -0,0 +1,16 @@ +package net.mullvad.mullvadvpn.test.arch.compose + +import androidx.compose.runtime.Composable +import com.lemonappdev.konsist.api.Konsist +import com.lemonappdev.konsist.api.ext.list.withAllAnnotationsOf +import com.lemonappdev.konsist.api.verify.assert +import org.junit.Test + +class ComposeTests { + @Test + fun `ensure all app composables are in the compose package`() = + allAppComposeFunctions().assert { it.resideInPackage("net.mullvad.mullvadvpn.compose..") } + + private fun allAppComposeFunctions() = + Konsist.scopeFromProduction("app").functions().withAllAnnotationsOf(Composable::class) +} diff --git a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiDispatcher.kt b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiDispatcher.kt index 06f716403465..6a604bb09f53 100644 --- a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiDispatcher.kt +++ b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiDispatcher.kt @@ -8,7 +8,10 @@ import net.mullvad.mullvadvpn.test.mockapi.constant.DUMMY_ACCESS_TOKEN import net.mullvad.mullvadvpn.test.mockapi.constant.DUMMY_DEVICE_NAME import net.mullvad.mullvadvpn.test.mockapi.constant.DUMMY_ID import net.mullvad.mullvadvpn.test.mockapi.constant.LOG_TAG +import net.mullvad.mullvadvpn.test.mockapi.util.accessTokenJsonResponse +import net.mullvad.mullvadvpn.test.mockapi.util.accountInfoJson import net.mullvad.mullvadvpn.test.mockapi.util.currentUtcTimeWithOffsetZero +import net.mullvad.mullvadvpn.test.mockapi.util.deviceJson import okhttp3.mockwebserver.Dispatcher import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.RecordedRequest diff --git a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/util/JsonUtils.kt b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/util/JsonUtils.kt index 62320a07e6ff..2ccae9499e67 100644 --- a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/util/JsonUtils.kt +++ b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/util/JsonUtils.kt @@ -1,6 +1,5 @@ -package net.mullvad.mullvadvpn.test.mockapi +package net.mullvad.mullvadvpn.test.mockapi.util -import net.mullvad.mullvadvpn.test.mockapi.util.formatStrictlyAccordingToIso8601AndRfc3339 import org.joda.time.DateTime import org.json.JSONObject