From 71d61f3202cafce05efeb616b905f8f05771cc5c Mon Sep 17 00:00:00 2001 From: Caitlin Shkuratov Date: Tue, 27 Sep 2022 21:05:16 +0000 Subject: [PATCH] [SB Refactor] Convert the WifiViewModel.wifiIcon tests to a parameterized test file to make all the possibilities clearer. Bug: 238425913 Test: WifiViewModelIconParameterizedTest Change-Id: I5250e903a1b99c2a1ea29b39c3cf3b3e8a5abcfc --- .../wifi/ui/viewmodel/HomeWifiViewModel.kt | 2 +- .../ui/viewmodel/KeyguardWifiViewModel.kt | 2 +- .../viewmodel/LocationBasedWifiViewModel.kt | 2 +- .../wifi/ui/viewmodel/QsWifiViewModel.kt | 2 +- .../wifi/ui/viewmodel/WifiViewModel.kt | 2 +- .../WifiViewModelIconParameterizedTest.kt | 326 ++++++++++++++++ .../wifi/ui/viewmodel/WifiViewModelTest.kt | 361 ------------------ 7 files changed, 331 insertions(+), 366 deletions(-) create mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/HomeWifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/HomeWifiViewModel.kt index 871b395d09964..40f948f9ee6ca 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/HomeWifiViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/HomeWifiViewModel.kt @@ -28,7 +28,7 @@ import kotlinx.coroutines.flow.StateFlow */ class HomeWifiViewModel( statusBarPipelineFlags: StatusBarPipelineFlags, - wifiIcon: StateFlow, + wifiIcon: StateFlow, isActivityInViewVisible: Flow, isActivityOutViewVisible: Flow, isActivityContainerVisible: Flow, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/KeyguardWifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/KeyguardWifiViewModel.kt index be1f3f2194bc5..9642ac42972eb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/KeyguardWifiViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/KeyguardWifiViewModel.kt @@ -25,7 +25,7 @@ import kotlinx.coroutines.flow.StateFlow /** A view model for the wifi icon shown on keyguard (lockscreen). */ class KeyguardWifiViewModel( statusBarPipelineFlags: StatusBarPipelineFlags, - wifiIcon: StateFlow, + wifiIcon: StateFlow, isActivityInViewVisible: Flow, isActivityOutViewVisible: Flow, isActivityContainerVisible: Flow, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt index 7243acfbd56d9..e23f8c7e97e07 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/LocationBasedWifiViewModel.kt @@ -34,7 +34,7 @@ abstract class LocationBasedWifiViewModel( debugTint: Int, /** The wifi icon that should be displayed. Null if we shouldn't display any icon. */ - val wifiIcon: StateFlow, + val wifiIcon: StateFlow, /** True if the activity in view should be visible. */ val isActivityInViewVisible: Flow, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/QsWifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/QsWifiViewModel.kt index d640d33eb316e..0ddf90e218726 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/QsWifiViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/QsWifiViewModel.kt @@ -25,7 +25,7 @@ import kotlinx.coroutines.flow.StateFlow /** A view model for the wifi icon shown in quick settings (when the shade is pulled down). */ class QsWifiViewModel( statusBarPipelineFlags: StatusBarPipelineFlags, - wifiIcon: StateFlow, + wifiIcon: StateFlow, isActivityInViewVisible: Flow, isActivityOutViewVisible: Flow, isActivityContainerVisible: Flow, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt index 295bdfb758d84..ebbd77b72014e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt @@ -121,7 +121,7 @@ constructor( } /** The wifi icon that should be displayed. Null if we shouldn't display any icon. */ - private val wifiIcon: StateFlow = + private val wifiIcon: StateFlow = combine( interactor.isEnabled, interactor.isForceHidden, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt new file mode 100644 index 0000000000000..929e5294de3dc --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelIconParameterizedTest.kt @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel + +import android.content.Context +import androidx.annotation.DrawableRes +import androidx.test.filters.SmallTest +import com.android.settingslib.AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH +import com.android.settingslib.AccessibilityContentDescriptions.WIFI_NO_CONNECTION +import com.android.systemui.SysuiTestCase +import com.android.systemui.common.shared.model.ContentDescription +import com.android.systemui.statusbar.connectivity.WifiIcons +import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_FULL_ICONS +import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_NO_INTERNET_ICONS +import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags +import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants +import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger +import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot +import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository +import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel +import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository +import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor +import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants +import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel.Companion.NO_INTERNET +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.yield +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.junit.runners.Parameterized.Parameters +import org.mockito.Mock +import org.mockito.Mockito.`when` as whenever +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(Parameterized::class) +internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase) : + SysuiTestCase() { + + private lateinit var underTest: WifiViewModel + + @Mock private lateinit var statusBarPipelineFlags: StatusBarPipelineFlags + @Mock private lateinit var logger: ConnectivityPipelineLogger + @Mock private lateinit var connectivityConstants: ConnectivityConstants + @Mock private lateinit var wifiConstants: WifiConstants + private lateinit var connectivityRepository: FakeConnectivityRepository + private lateinit var wifiRepository: FakeWifiRepository + private lateinit var interactor: WifiInteractor + private lateinit var scope: CoroutineScope + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + connectivityRepository = FakeConnectivityRepository() + wifiRepository = FakeWifiRepository() + wifiRepository.setIsWifiEnabled(true) + interactor = WifiInteractor(connectivityRepository, wifiRepository) + scope = CoroutineScope(IMMEDIATE) + } + + @After + fun tearDown() { + scope.cancel() + } + + @Test + fun wifiIcon() = + runBlocking(IMMEDIATE) { + wifiRepository.setIsWifiEnabled(testCase.enabled) + connectivityRepository.setForceHiddenIcons( + if (testCase.forceHidden) { + setOf(ConnectivitySlot.WIFI) + } else { + setOf() + } + ) + whenever(wifiConstants.alwaysShowIconIfEnabled) + .thenReturn(testCase.alwaysShowIconWhenEnabled) + whenever(connectivityConstants.hasDataCapabilities) + .thenReturn(testCase.hasDataCapabilities) + underTest = + WifiViewModel( + connectivityConstants, + context, + logger, + interactor, + scope, + statusBarPipelineFlags, + wifiConstants, + ) + + val iconFlow = underTest.home.wifiIcon + val job = iconFlow.launchIn(this) + + // WHEN we set a certain network + wifiRepository.setWifiNetwork(testCase.network) + yield() + + // THEN we get the expected icon + assertThat(iconFlow.value?.res).isEqualTo(testCase.expected?.iconResource) + val expectedContentDescription = + if (testCase.expected == null) { + null + } else { + testCase.expected.contentDescription.invoke(context) + } + assertThat(iconFlow.value?.contentDescription?.getAsString()) + .isEqualTo(expectedContentDescription) + + job.cancel() + } + + private fun ContentDescription.getAsString(): String? { + return when (this) { + is ContentDescription.Loaded -> this.description + is ContentDescription.Resource -> context.getString(this.res) + } + } + + internal data class Expected( + /** The resource that should be used for the icon. */ + @DrawableRes val iconResource: Int, + + /** A function that, given a context, calculates the correct content description string. */ + val contentDescription: (Context) -> String, + ) + + // Note: We use default values for the boolean parameters to reflect a "typical configuration" + // for wifi. This allows each TestCase to only define the parameter values that are critical + // for the test function. + internal data class TestCase( + val enabled: Boolean = true, + val forceHidden: Boolean = false, + val alwaysShowIconWhenEnabled: Boolean = false, + val hasDataCapabilities: Boolean = true, + val network: WifiNetworkModel, + + /** The expected output. Null if we expect the output to be null. */ + val expected: Expected? + ) + + companion object { + @Parameters(name = "{0}") + @JvmStatic + fun data(): Collection = + listOf( + // Enabled = false => no networks shown + TestCase( + enabled = false, + network = WifiNetworkModel.CarrierMerged, + expected = null, + ), + TestCase( + enabled = false, + network = WifiNetworkModel.Inactive, + expected = null, + ), + TestCase( + enabled = false, + network = WifiNetworkModel.Active(NETWORK_ID, isValidated = false, level = 1), + expected = null, + ), + TestCase( + enabled = false, + network = WifiNetworkModel.Active(NETWORK_ID, isValidated = true, level = 3), + expected = null, + ), + + // forceHidden = true => no networks shown + TestCase( + forceHidden = true, + network = WifiNetworkModel.CarrierMerged, + expected = null, + ), + TestCase( + forceHidden = true, + network = WifiNetworkModel.Inactive, + expected = null, + ), + TestCase( + enabled = false, + network = WifiNetworkModel.Active(NETWORK_ID, isValidated = false, level = 2), + expected = null, + ), + TestCase( + forceHidden = true, + network = WifiNetworkModel.Active(NETWORK_ID, isValidated = true, level = 1), + expected = null, + ), + + // alwaysShowIconWhenEnabled = true => all Inactive and Active networks shown + TestCase( + alwaysShowIconWhenEnabled = true, + network = WifiNetworkModel.Inactive, + expected = + Expected( + iconResource = WifiIcons.WIFI_NO_NETWORK, + contentDescription = { context -> + "${context.getString(WIFI_NO_CONNECTION)}," + + context.getString(NO_INTERNET) + } + ), + ), + TestCase( + alwaysShowIconWhenEnabled = true, + network = WifiNetworkModel.Active(NETWORK_ID, isValidated = false, level = 4), + expected = + Expected( + iconResource = WIFI_NO_INTERNET_ICONS[4], + contentDescription = { context -> + "${context.getString(WIFI_CONNECTION_STRENGTH[4])}," + + context.getString(NO_INTERNET) + } + ), + ), + TestCase( + alwaysShowIconWhenEnabled = true, + network = WifiNetworkModel.Active(NETWORK_ID, isValidated = true, level = 2), + expected = + Expected( + iconResource = WIFI_FULL_ICONS[2], + contentDescription = { context -> + context.getString(WIFI_CONNECTION_STRENGTH[2]) + } + ), + ), + + // hasDataCapabilities = false => all Inactive and Active networks shown + TestCase( + hasDataCapabilities = false, + network = WifiNetworkModel.Inactive, + expected = + Expected( + iconResource = WifiIcons.WIFI_NO_NETWORK, + contentDescription = { context -> + "${context.getString(WIFI_NO_CONNECTION)}," + + context.getString(NO_INTERNET) + } + ), + ), + TestCase( + hasDataCapabilities = false, + network = WifiNetworkModel.Active(NETWORK_ID, isValidated = false, level = 2), + expected = + Expected( + iconResource = WIFI_NO_INTERNET_ICONS[2], + contentDescription = { context -> + "${context.getString(WIFI_CONNECTION_STRENGTH[2])}," + + context.getString(NO_INTERNET) + } + ), + ), + TestCase( + hasDataCapabilities = false, + network = WifiNetworkModel.Active(NETWORK_ID, isValidated = true, level = 0), + expected = + Expected( + iconResource = WIFI_FULL_ICONS[0], + contentDescription = { context -> + context.getString(WIFI_CONNECTION_STRENGTH[0]) + } + ), + ), + + // network = CarrierMerged => not shown + TestCase( + network = WifiNetworkModel.CarrierMerged, + expected = null, + ), + + // network = Inactive => not shown + TestCase( + network = WifiNetworkModel.Inactive, + expected = null, + ), + + // network = Active & validated = false => not shown + TestCase( + network = WifiNetworkModel.Active(NETWORK_ID, isValidated = false, level = 3), + expected = null, + ), + + // network = Active & validated = true => shown + TestCase( + network = WifiNetworkModel.Active(NETWORK_ID, isValidated = true, level = 4), + expected = + Expected( + iconResource = WIFI_FULL_ICONS[4], + contentDescription = { context -> + context.getString(WIFI_CONNECTION_STRENGTH[4]) + } + ), + ), + + // network has null level => not shown + TestCase( + network = WifiNetworkModel.Active(NETWORK_ID, isValidated = true, level = null), + expected = null, + ), + ) + } +} + +private val IMMEDIATE = Dispatchers.Main.immediate +private const val NETWORK_ID = 789 diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt index 74ea21c11447f..3169eef83f07b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt @@ -17,25 +17,17 @@ package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel import androidx.test.filters.SmallTest -import com.android.settingslib.AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH -import com.android.settingslib.AccessibilityContentDescriptions.WIFI_NO_CONNECTION import com.android.systemui.SysuiTestCase -import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon -import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_FULL_ICONS -import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_NO_INTERNET_ICONS -import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_NO_NETWORK import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger -import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiActivityModel -import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel.Companion.NO_INTERNET import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -89,352 +81,6 @@ class WifiViewModelTest : SysuiTestCase() { // same data for icon, activity, etc. flows. So, most of these tests will test just one of the // instances. There are also some tests that verify all 3 instances received the same data. - // TODO(b/238425913): We should probably parameterize the wifiIcon tests since there's so many - // different possibilities. - - @Test - fun wifiIcon_notEnabled_outputsNull() = runBlocking(IMMEDIATE) { - wifiRepository.setIsWifiEnabled(false) - - // Start as non-null so we can verify we got the update - var latest: Icon? = Icon.Resource(0, null) - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - wifiRepository.setWifiNetwork(WifiNetworkModel.Active(NETWORK_ID, level = 2)) - yield() - - assertThat(latest).isNull() - - job.cancel() - } - - @Test - fun wifiIcon_forceHidden_outputsNull() = runBlocking(IMMEDIATE) { - connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.WIFI)) - - // Start as non-null so we can verify we got the update - var latest: Icon? = Icon.Resource(0, null) - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - wifiRepository.setWifiNetwork(WifiNetworkModel.Active(NETWORK_ID, level = 2)) - yield() - - assertThat(latest).isNull() - - job.cancel() - } - - @Test - fun wifiIcon_notForceHidden_outputsVisible() = runBlocking(IMMEDIATE) { - connectivityRepository.setForceHiddenIcons(setOf()) - - var latest: Icon? = null - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - wifiRepository.setWifiNetwork( - WifiNetworkModel.Active(NETWORK_ID, isValidated = true, level = 2) - ) - yield() - - assertThat(latest).isInstanceOf(Icon.Resource::class.java) - - job.cancel() - } - - @Test - fun wifiIcon_inactiveNetwork_alwaysShowFalse_outputsNull() = runBlocking(IMMEDIATE) { - whenever(wifiConstants.alwaysShowIconIfEnabled).thenReturn(false) - whenever(connectivityConstants.hasDataCapabilities).thenReturn(true) - createAndSetViewModel() - - // Start as non-null so we can verify we got the update - var latest: Icon? = Icon.Resource(0, null) - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive) - yield() - - assertThat(latest).isNull() - - job.cancel() - } - - @Test - fun wifiIcon_inactiveNetwork_alwaysShowTrue_outputsNoNetworkIcon() = runBlocking(IMMEDIATE) { - whenever(wifiConstants.alwaysShowIconIfEnabled).thenReturn(true) - createAndSetViewModel() - - var latest: Icon? = null - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive) - yield() - - assertThat(latest).isInstanceOf(Icon.Resource::class.java) - val icon = latest as Icon.Resource - assertThat(icon.res).isEqualTo(WIFI_NO_NETWORK) - assertThat(icon.contentDescription?.getAsString()) - .contains(context.getString(WIFI_NO_CONNECTION)) - assertThat(icon.contentDescription?.getAsString()) - .contains(context.getString(NO_INTERNET)) - - job.cancel() - } - - @Test - fun wifiIcon_inactiveNetwork_hasDataCaps_outputsNull() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.hasDataCapabilities).thenReturn(true) - createAndSetViewModel() - - // Start as non-null so we can verify we got the update - var latest: Icon? = Icon.Resource(0, null) - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive) - yield() - - assertThat(latest).isNull() - - job.cancel() - } - - @Test - fun wifiIcon_inactiveNetwork_noDataCaps_outputsNoNetworkIcon() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.hasDataCapabilities).thenReturn(false) - createAndSetViewModel() - - var latest: Icon? = null - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive) - yield() - - assertThat(latest).isInstanceOf(Icon.Resource::class.java) - val icon = latest as Icon.Resource - assertThat(icon.res).isEqualTo(WIFI_NO_NETWORK) - assertThat(icon.contentDescription?.getAsString()) - .contains(context.getString(WIFI_NO_CONNECTION)) - assertThat(icon.contentDescription?.getAsString()) - .contains(context.getString(NO_INTERNET)) - - job.cancel() - } - - @Test - fun wifiIcon_carrierMergedNetwork_outputsNull() = runBlocking(IMMEDIATE) { - // Even when we should always show the icon - whenever(wifiConstants.alwaysShowIconIfEnabled).thenReturn(true) - createAndSetViewModel() - - var latest: Icon? = Icon.Resource(0, null) - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - // WHEN we have a carrier merged network - wifiRepository.setWifiNetwork(WifiNetworkModel.CarrierMerged) - yield() - - // THEN we override the alwaysShow boolean and still don't show the icon - assertThat(latest).isNull() - - job.cancel() - } - - @Test - fun wifiIcon_isActiveNullLevel_outputsNull() = runBlocking(IMMEDIATE) { - // Even when we should always show the icon - whenever(wifiConstants.alwaysShowIconIfEnabled).thenReturn(true) - createAndSetViewModel() - - var latest: Icon? = Icon.Resource(0, null) - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - // WHEN we have a null level - wifiRepository.setWifiNetwork(WifiNetworkModel.Active(NETWORK_ID, level = null)) - yield() - - // THEN we override the alwaysShow boolean and still don't show the icon - assertThat(latest).isNull() - - job.cancel() - } - - @Test - fun wifiIcon_isActiveAndValidated_level1_outputsFull1Icon() = runBlocking(IMMEDIATE) { - var latest: Icon? = null - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - val level = 1 - wifiRepository.setWifiNetwork( - WifiNetworkModel.Active( - NETWORK_ID, - isValidated = true, - level, - ) - ) - yield() - - assertThat(latest).isInstanceOf(Icon.Resource::class.java) - val icon = latest as Icon.Resource - assertThat(icon.res).isEqualTo(WIFI_FULL_ICONS[level]) - assertThat(icon.contentDescription?.getAsString()) - .contains(context.getString(WIFI_CONNECTION_STRENGTH[level])) - assertThat(icon.contentDescription?.getAsString()) - .doesNotContain(context.getString(NO_INTERNET)) - - job.cancel() - } - - @Test - fun wifiIcon_isActiveAndNotValidated_alwaysShowFalse_outputsNull() = runBlocking(IMMEDIATE) { - whenever(wifiConstants.alwaysShowIconIfEnabled).thenReturn(false) - whenever(connectivityConstants.hasDataCapabilities).thenReturn(true) - createAndSetViewModel() - - var latest: Icon? = Icon.Resource(0, null) - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - wifiRepository.setWifiNetwork( - WifiNetworkModel.Active(NETWORK_ID, isValidated = false, level = 4,) - ) - yield() - - assertThat(latest).isNull() - - job.cancel() - } - - @Test - fun wifiIcon_isActiveAndNotValidated_alwaysShowTrue_outputsIcon() = runBlocking(IMMEDIATE) { - whenever(wifiConstants.alwaysShowIconIfEnabled).thenReturn(true) - createAndSetViewModel() - - var latest: Icon? = null - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - val level = 4 - wifiRepository.setWifiNetwork( - WifiNetworkModel.Active( - NETWORK_ID, - isValidated = false, - level, - ) - ) - yield() - - assertThat(latest).isInstanceOf(Icon.Resource::class.java) - val icon = latest as Icon.Resource - assertThat(icon.res).isEqualTo(WIFI_NO_INTERNET_ICONS[level]) - assertThat(icon.contentDescription?.getAsString()) - .contains(context.getString(WIFI_CONNECTION_STRENGTH[level])) - assertThat(icon.contentDescription?.getAsString()) - .contains(context.getString(NO_INTERNET)) - - job.cancel() - } - - @Test - fun wifiIcon_isActiveAndNotValidated_hasDataCaps_outputsNull() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.hasDataCapabilities).thenReturn(true) - createAndSetViewModel() - - var latest: Icon? = Icon.Resource(0, null) - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - wifiRepository.setWifiNetwork( - WifiNetworkModel.Active(NETWORK_ID, isValidated = false, level = 4,) - ) - yield() - - assertThat(latest).isNull() - - job.cancel() - } - - @Test - fun wifiIcon_isActiveAndNotValidated_noDataCaps_outputsIcon() = runBlocking(IMMEDIATE) { - whenever(connectivityConstants.hasDataCapabilities).thenReturn(false) - createAndSetViewModel() - - var latest: Icon? = null - val job = underTest - .home - .wifiIcon - .onEach { latest = it } - .launchIn(this) - - val level = 4 - wifiRepository.setWifiNetwork( - WifiNetworkModel.Active( - NETWORK_ID, - isValidated = false, - level, - ) - ) - yield() - - assertThat(latest).isInstanceOf(Icon.Resource::class.java) - val icon = latest as Icon.Resource - assertThat(icon.res).isEqualTo(WIFI_NO_INTERNET_ICONS[level]) - assertThat(icon.contentDescription?.getAsString()) - .contains(context.getString(WIFI_CONNECTION_STRENGTH[level])) - assertThat(icon.contentDescription?.getAsString()) - .contains(context.getString(NO_INTERNET)) - - job.cancel() - } - @Test fun wifiIcon_allLocationViewModelsReceiveSameData() = runBlocking(IMMEDIATE) { var latestHome: Icon? = null @@ -829,13 +475,6 @@ class WifiViewModelTest : SysuiTestCase() { ) } - private fun ContentDescription.getAsString(): String? { - return when (this) { - is ContentDescription.Loaded -> this.description - is ContentDescription.Resource -> context.getString(this.res) - } - } - companion object { private const val NETWORK_ID = 2 private val ACTIVE_VALID_WIFI_NETWORK = WifiNetworkModel.Active(NETWORK_ID, ssid = "AB")