diff options
| author | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2023-05-19 08:16:51 +0200 |
|---|---|---|
| committer | Albin <albin@mullvad.net> | 2023-05-23 16:27:32 +0200 |
| commit | 6d8b81e305489bafed9e84a7c297e4f71ac3e9dc (patch) | |
| tree | 20ff409083afbee7e3b23c366d6094fd6f589358 /android/app/src | |
| parent | 3470c85de0a361ee340b510bc779318c5ac95860 (diff) | |
| download | mullvadvpn-6d8b81e305489bafed9e84a7c297e4f71ac3e9dc.tar.xz mullvadvpn-6d8b81e305489bafed9e84a7c297e4f71ac3e9dc.zip | |
Remove scopes in koin and use global scope everywhere
Diffstat (limited to 'android/app/src')
12 files changed, 91 insertions, 151 deletions
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 087c4b72a7..e7fa052d5f 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 @@ -11,28 +11,21 @@ import io.mockk.verify import net.mullvad.mullvadvpn.applist.AppData import net.mullvad.mullvadvpn.applist.ApplicationsIconManager import net.mullvad.mullvadvpn.compose.state.SplitTunnelingUiState -import net.mullvad.mullvadvpn.di.APPS_SCOPE import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test import org.koin.core.context.loadKoinModules import org.koin.core.context.unloadKoinModules -import org.koin.core.qualifier.named -import org.koin.core.scope.Scope import org.koin.dsl.module -import org.koin.java.KoinJavaComponent.getKoin class SplitTunnelingScreenTest { @get:Rule val composeTestRule = createComposeRule() - private lateinit var scope: Scope private val testModule = module { - scope(named(APPS_SCOPE)) { - scoped { - mockk<ApplicationsIconManager>().apply { - every { getAppIcon(any()) } returns mockk(relaxed = true) - } + single { + mockk<ApplicationsIconManager>().apply { + every { getAppIcon(any()) } returns mockk(relaxed = true) } } } @@ -41,12 +34,10 @@ class SplitTunnelingScreenTest { fun setup() { MockKAnnotations.init(this) loadKoinModules(testModule) - scope = getKoin().getOrCreateScope(APPS_SCOPE, named(APPS_SCOPE)) } @After fun tearDown() { - scope.close() unloadKoinModules(testModule) unmockkAll() } @@ -76,7 +67,7 @@ class SplitTunnelingScreenTest { composeTestRule.setContent { SplitTunnelingScreen( uiState = - SplitTunnelingUiState.Data( + SplitTunnelingUiState.ShowAppList( excludedApps = listOf(excludedApp), includedApps = listOf(includedApp), showSystemApps = false @@ -104,7 +95,7 @@ class SplitTunnelingScreenTest { composeTestRule.setContent { SplitTunnelingScreen( uiState = - SplitTunnelingUiState.Data( + SplitTunnelingUiState.ShowAppList( excludedApps = emptyList(), includedApps = listOf(includedApp), showSystemApps = false @@ -135,7 +126,7 @@ class SplitTunnelingScreenTest { composeTestRule.setContent { SplitTunnelingScreen( uiState = - SplitTunnelingUiState.Data( + SplitTunnelingUiState.ShowAppList( excludedApps = listOf(excludedApp), includedApps = listOf(includedApp), showSystemApps = false @@ -162,7 +153,7 @@ class SplitTunnelingScreenTest { composeTestRule.setContent { SplitTunnelingScreen( uiState = - SplitTunnelingUiState.Data( + SplitTunnelingUiState.ShowAppList( excludedApps = listOf(excludedApp), includedApps = listOf(includedApp), showSystemApps = false @@ -189,7 +180,7 @@ class SplitTunnelingScreenTest { composeTestRule.setContent { SplitTunnelingScreen( uiState = - SplitTunnelingUiState.Data( + SplitTunnelingUiState.ShowAppList( excludedApps = listOf(excludedApp), includedApps = listOf(includedApp), showSystemApps = false 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 8c5a295308..5fc222bf0a 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 @@ -98,7 +98,7 @@ fun SplitTunnelingScreen( title = stringResource(id = R.string.split_tunneling), progress = progress, modifier = scaffoldModifier, - backTitle = stringResource(id = R.string.settings_vpn) + backTitle = stringResource(id = R.string.settings) ) }, ) { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt index 26703d98ec..f0fcc4fa65 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt @@ -45,16 +45,12 @@ val uiModule = module { single<PackageManager> { androidContext().packageManager } single<String>(named(SELF_PACKAGE_NAME)) { androidContext().packageName } - scope(named(APPS_SCOPE)) { - viewModel { SplitTunnelingViewModel(get(), get(), Dispatchers.Default) } - scoped { ApplicationsIconManager(get()) } onClose { it?.dispose() } - scoped { ApplicationsProvider(get(), get(named(SELF_PACKAGE_NAME))) } - } + viewModel { SplitTunnelingViewModel(get(), get(), Dispatchers.Default) } + single { ApplicationsIconManager(get()) } onClose { it?.dispose() } + single { ApplicationsProvider(get(), get(named(SELF_PACKAGE_NAME))) } - scope(named(SERVICE_CONNECTION_SCOPE)) { - scoped<SplitTunneling> { (messenger: Messenger, dispatcher: EventDispatcher) -> - SplitTunneling(messenger, dispatcher) - } + single { (messenger: Messenger, dispatcher: EventDispatcher) -> + SplitTunneling(messenger, dispatcher) } single { ServiceConnectionManager(androidContext()) } @@ -97,7 +93,5 @@ val uiModule = module { } } -const val APPS_SCOPE = "APPS_SCOPE" -const val SERVICE_CONNECTION_SCOPE = "SERVICE_CONNECTION_SCOPE" const val SELF_PACKAGE_NAME = "SELF_PACKAGE_NAME" const val APP_PREFERENCES_NAME = "net.mullvad.mullvadvpn.app_preferences" diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragment.kt index 910588e580..9a920d7324 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/SplitTunnelingFragment.kt @@ -9,24 +9,11 @@ import androidx.compose.ui.platform.ComposeView import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.compose.screen.SplitTunnelingScreen import net.mullvad.mullvadvpn.compose.theme.AppTheme -import net.mullvad.mullvadvpn.di.APPS_SCOPE -import net.mullvad.mullvadvpn.di.SERVICE_CONNECTION_SCOPE import net.mullvad.mullvadvpn.viewmodel.SplitTunnelingViewModel -import org.koin.android.ext.android.getKoin -import org.koin.androidx.viewmodel.ViewModelOwner -import org.koin.androidx.viewmodel.scope.viewModel -import org.koin.core.qualifier.named -import org.koin.core.scope.Scope +import org.koin.androidx.viewmodel.ext.android.viewModel class SplitTunnelingFragment : BaseFragment() { - private val scope: Scope = - getKoin().getOrCreateScope(APPS_SCOPE, named(APPS_SCOPE)).also { appsScope -> - getKoin().getScopeOrNull(SERVICE_CONNECTION_SCOPE)?.let { serviceConnectionScope -> - appsScope.linkTo(serviceConnectionScope) - } - } - private val viewModel by - scope.viewModel<SplitTunnelingViewModel>(owner = { ViewModelOwner.from(this, this) }) + private val viewModel: SplitTunnelingViewModel by viewModel() override fun onCreateView( inflater: LayoutInflater, @@ -48,9 +35,4 @@ class SplitTunnelingFragment : BaseFragment() { } } } - - override fun onDestroy() { - scope.close() - super.onDestroy() - } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt index a58db46ff7..7f895618fb 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionContainer.kt @@ -4,15 +4,12 @@ import android.os.Looper import android.os.Messenger import android.os.RemoteException import android.util.Log -import net.mullvad.mullvadvpn.di.SERVICE_CONNECTION_SCOPE import net.mullvad.mullvadvpn.ipc.DispatchingHandler import net.mullvad.mullvadvpn.ipc.Event import net.mullvad.mullvadvpn.ipc.Request import org.koin.core.component.KoinApiExtension -import org.koin.core.parameter.parametersOf -import org.koin.core.qualifier.named -import org.koin.core.scope.KoinScopeComponent -import org.koin.core.scope.get +import org.koin.core.component.KoinComponent +import org.koin.core.component.get // Container of classes that communicate with the service through an active connection // @@ -23,13 +20,10 @@ class ServiceConnectionContainer( val connection: Messenger, onServiceReady: (ServiceConnectionContainer) -> Unit, onVpnPermissionRequest: () -> Unit -) : KoinScopeComponent { +) : KoinComponent { private val dispatcher = DispatchingHandler(Looper.getMainLooper()) { message -> Event.fromMessage(message) } - override val scope = - getKoin().getOrCreateScope(SERVICE_CONNECTION_SCOPE, named(SERVICE_CONNECTION_SCOPE), this) - val accountDataSource = ServiceConnectionAccountDataSource(connection, dispatcher) val authTokenCache = AuthTokenCache(connection, dispatcher) val connectionProxy = ConnectionProxy(connection, dispatcher) @@ -37,8 +31,7 @@ class ServiceConnectionContainer( val locationInfoCache = LocationInfoCache(dispatcher) val settingsListener = SettingsListener(connection, dispatcher) - // NOTE: `org.koin.core.scope.get` must be used here rather than `org.koin.core.component.get`. - val splitTunneling = get<SplitTunneling>(parameters = { parametersOf(connection, dispatcher) }) + val splitTunneling = SplitTunneling(connection, dispatcher) val voucherRedeemer = VoucherRedeemer(connection, dispatcher) val vpnPermission = VpnPermission(connection, dispatcher) @@ -61,7 +54,6 @@ class ServiceConnectionContainer( fun onDestroy() { unregisterListener() - closeScope() dispatcher.onDestroy() diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt index 1de160ffe8..f7be833792 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManagerExtensions.kt @@ -22,3 +22,6 @@ fun ServiceConnectionManager.relayListListener() = fun ServiceConnectionManager.settingsListener() = this.connectionState.value.readyContainer()?.settingsListener + +fun ServiceConnectionManager.splitTunneling() = + this.connectionState.value.readyContainer()?.splitTunneling diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ApplicationImageView.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ApplicationImageView.kt index 8c840357e0..519fefb180 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ApplicationImageView.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/ApplicationImageView.kt @@ -15,25 +15,23 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.applist.ApplicationsIconManager -import net.mullvad.mullvadvpn.di.APPS_SCOPE -import org.koin.core.scope.inject -import org.koin.core.scope.KoinScopeComponent -import org.koin.core.scope.Scope +import org.koin.core.component.KoinApiExtension +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject +@OptIn(KoinApiExtension::class) class ApplicationImageView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = R.attr.applicationListItemViewStyle, -) : AppCompatImageView(context, attrs, defStyleAttr), KoinScopeComponent { +) : AppCompatImageView(context, attrs, defStyleAttr), KoinComponent { private val viewScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) private val iconManager: ApplicationsIconManager by inject() private var updateImageJob: Job? = null - override val scope: Scope = getKoin().getScope(APPS_SCOPE) - var packageName: String = "" set(value) { field = value diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModel.kt index 38803cfc21..a1376eabb4 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModel.kt @@ -5,36 +5,60 @@ import androidx.lifecycle.viewModelScope import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.applist.AppData import net.mullvad.mullvadvpn.applist.ApplicationsProvider import net.mullvad.mullvadvpn.compose.state.SplitTunnelingUiState +import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionContainer +import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager +import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState import net.mullvad.mullvadvpn.ui.serviceconnection.SplitTunneling +import net.mullvad.mullvadvpn.ui.serviceconnection.splitTunneling class SplitTunnelingViewModel( private val appsProvider: ApplicationsProvider, - private val splitTunneling: SplitTunneling, + private val serviceConnectionManager: ServiceConnectionManager, private val dispatcher: CoroutineDispatcher ) : ViewModel() { private val allApps = MutableStateFlow<List<AppData>?>(null) private val showSystemApps = MutableStateFlow(false) + private val _shared: SharedFlow<ServiceConnectionContainer> = + serviceConnectionManager.connectionState + .flatMapLatest { state -> + if (state is ServiceConnectionState.ConnectedReady) { + flowOf(state.container) + } else { + emptyFlow() + } + } + .shareIn(viewModelScope, SharingStarted.WhileSubscribed()) + private val vmState = - combine(splitTunneling.excludedAppsCallbackFlow(), allApps, showSystemApps) { - excludedApps, - allApps, - showSystemApps -> - SplitTunnelingViewModelState( - excludedApps = excludedApps, - allApps = allApps, - showSystemApps = showSystemApps - ) + _shared + .flatMapLatest { serviceConnection -> + combine( + serviceConnection.splitTunneling.excludedAppsCallbackFlow(), + allApps, + showSystemApps + ) { excludedApps, allApps, showSystemApps -> + SplitTunnelingViewModelState( + excludedApps = excludedApps, + allApps = allApps, + showSystemApps = showSystemApps + ) + } } .stateIn( viewModelScope, @@ -53,22 +77,28 @@ class SplitTunnelingViewModel( init { viewModelScope.launch(dispatcher) { - if (!splitTunneling.enabled) splitTunneling.enabled = true + if (serviceConnectionManager.splitTunneling()?.enabled == false) { + serviceConnectionManager.splitTunneling()?.enabled = true + } fetchApps() } } override fun onCleared() { - splitTunneling.persist() + serviceConnectionManager.splitTunneling()?.persist() super.onCleared() } - + fun onIncludeAppClick(packageName: String) { - viewModelScope.launch(dispatcher) { splitTunneling.includeApp(packageName) } + viewModelScope.launch(dispatcher) { + serviceConnectionManager.splitTunneling()?.includeApp(packageName) + } } fun onExcludeAppClick(packageName: String) { - viewModelScope.launch(dispatcher) { splitTunneling.excludeApp(packageName) } + viewModelScope.launch(dispatcher) { + serviceConnectionManager.splitTunneling()?.excludeApp(packageName) + } } fun onShowSystemAppsClicked(show: Boolean) { diff --git a/android/app/src/main/res/values/dimensions.xml b/android/app/src/main/res/values/dimensions.xml index 76fa24032d..d6bab1dade 100644 --- a/android/app/src/main/res/values/dimensions.xml +++ b/android/app/src/main/res/values/dimensions.xml @@ -39,7 +39,6 @@ <dimen name="half_vertical_space">10dp</dimen> <dimen name="button_separation">18dp</dimen> <dimen name="screen_vertical_margin">22dp</dimen> - <dimen name="app_list_item_icon_size">35dp</dimen> <dimen name="progress_size">60dp</dimen> <dimen name="icon_size">24dp</dimen> <dimen name="widget_padding">16dp</dimen> diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index 9a808e9c3b..dab9229592 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -56,10 +56,6 @@ <item name="android:textColor">@color/white</item> <item name="android:textSize">@dimen/text_medium_plus</item> </style> - <style name="TextAppearance.Mullvad.Title2"> - <item name="android:textColor">@color/white</item> - <item name="android:textSize">@dimen/text_medium</item> - </style> <style name="TextAppearance.Mullvad.Small"> <item name="android:textColor">@color/white60</item> <item name="android:textSize">@dimen/text_small</item> @@ -90,17 +86,6 @@ <item name="android:clickable">false</item> <item name="android:focusable">false</item> </style> - <style name="TextAppearance.Mullvad.CollapsingToolbar"> - <item name="android:textColor">@color/white</item> - </style> - <style name="TextAppearance.Mullvad.CollapsingToolbar.Expanded"> - <item name="android:textSize">30sp</item> - <item name="android:textStyle">bold</item> - </style> - <style name="TextAppearance.Mullvad.CollapsingToolbar.Collapsed"> - <item name="android:textSize">20sp</item> - <item name="android:textStyle">bold</item> - </style> <!-- Switch Style --> <style name="AppTheme.Switch"> <item name="android:layout_width">@dimen/switch_width</item> diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/di/UiModuleTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/di/UiModuleTest.kt deleted file mode 100644 index 01b1807d42..0000000000 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/di/UiModuleTest.kt +++ /dev/null @@ -1,45 +0,0 @@ -package net.mullvad.mullvadvpn.di - -import android.os.Messenger -import io.mockk.mockk -import io.mockk.unmockkAll -import kotlin.test.assertEquals -import net.mullvad.mullvadvpn.ipc.Event -import net.mullvad.mullvadvpn.ipc.MessageDispatcher -import net.mullvad.mullvadvpn.ui.serviceconnection.SplitTunneling -import org.junit.After -import org.junit.Rule -import org.junit.Test -import org.koin.core.parameter.parametersOf -import org.koin.core.qualifier.named -import org.koin.core.scope.Scope -import org.koin.test.KoinTest -import org.koin.test.KoinTestRule - -class UiModuleTest : KoinTest { - - @get:Rule val koinTestRule = KoinTestRule.create { modules(uiModule) } - - @After - fun tearDown() { - unmockkAll() - } - - @Test - fun test_scope_linking() { - val appsScope: Scope = getKoin().createScope(APPS_SCOPE, named(APPS_SCOPE)) - val serviceConnectionScope = - getKoin().createScope(SERVICE_CONNECTION_SCOPE, named(SERVICE_CONNECTION_SCOPE)) - - appsScope.linkTo(serviceConnectionScope) - - val mockedMessenger = mockk<Messenger>() - val mockedEventMessageHandler = mockk<MessageDispatcher<Event>>(relaxed = true) - val serviceConnectionSplitTunneling = - serviceConnectionScope.get<SplitTunneling>( - parameters = { parametersOf(mockedMessenger, mockedEventMessageHandler) } - ) - - assertEquals(appsScope.get<SplitTunneling>(), serviceConnectionSplitTunneling) - } -} diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModelTest.kt index bc31165ebe..2b5a7f261c 100644 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModelTest.kt +++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SplitTunnelingViewModelTest.kt @@ -14,11 +14,15 @@ import io.mockk.verifyAll import java.util.concurrent.TimeUnit import kotlin.test.assertEquals import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.runTest import net.mullvad.mullvadvpn.TestCoroutineRule import net.mullvad.mullvadvpn.applist.AppData import net.mullvad.mullvadvpn.applist.ApplicationsProvider import net.mullvad.mullvadvpn.compose.state.SplitTunnelingUiState +import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionContainer +import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager +import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState import net.mullvad.mullvadvpn.ui.serviceconnection.SplitTunneling import org.junit.After import org.junit.Before @@ -32,6 +36,8 @@ class SplitTunnelingViewModelTest { @get:Rule val timeout = Timeout(3000L, TimeUnit.MILLISECONDS) private val mockedApplicationsProvider = mockk<ApplicationsProvider>() private val mockedSplitTunneling = mockk<SplitTunneling>() + private val mockedServiceConnectionManager = mockk<ServiceConnectionManager>() + private val mockedServiceConnectionContainer = mockk<ServiceConnectionContainer>() private lateinit var testSubject: SplitTunnelingViewModel @Before @@ -67,7 +73,7 @@ class SplitTunnelingViewModelTest { } initTestSubject(emptyList()) val expectedState = - SplitTunnelingUiState.Data( + SplitTunnelingUiState.ShowAppList( excludedApps = emptyList(), includedApps = emptyList(), showSystemApps = false @@ -88,7 +94,7 @@ class SplitTunnelingViewModelTest { initTestSubject(listOf(appExcluded, appNotExcluded)) val expectedState = - SplitTunnelingUiState.Data( + SplitTunnelingUiState.ShowAppList( excludedApps = listOf(appExcluded), includedApps = listOf(appNotExcluded), showSystemApps = false @@ -119,13 +125,13 @@ class SplitTunnelingViewModelTest { initTestSubject(listOf(app)) val expectedStateBeforeAction = - SplitTunnelingUiState.Data( + SplitTunnelingUiState.ShowAppList( excludedApps = listOf(app), includedApps = emptyList(), showSystemApps = false ) val expectedStateAfterAction = - SplitTunnelingUiState.Data( + SplitTunnelingUiState.ShowAppList( excludedApps = emptyList(), includedApps = listOf(app), showSystemApps = false @@ -160,14 +166,14 @@ class SplitTunnelingViewModelTest { initTestSubject(listOf(app)) val expectedStateBeforeAction = - SplitTunnelingUiState.Data( + SplitTunnelingUiState.ShowAppList( excludedApps = emptyList(), includedApps = listOf(app), showSystemApps = false ) val expectedStateAfterAction = - SplitTunnelingUiState.Data( + SplitTunnelingUiState.ShowAppList( excludedApps = listOf(app), includedApps = emptyList(), showSystemApps = false @@ -189,10 +195,15 @@ class SplitTunnelingViewModelTest { private fun initTestSubject(appList: List<AppData>) { every { mockedApplicationsProvider.getAppsList() } returns appList + every { mockedServiceConnectionManager.connectionState } returns + MutableStateFlow( + ServiceConnectionState.ConnectedReady(mockedServiceConnectionContainer) + ) + every { mockedServiceConnectionContainer.splitTunneling } returns mockedSplitTunneling testSubject = SplitTunnelingViewModel( mockedApplicationsProvider, - mockedSplitTunneling, + mockedServiceConnectionManager, testCoroutineRule.testDispatcher ) } |
