diff options
| -rw-r--r-- | packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt | 262 |
1 files changed, 65 insertions, 197 deletions
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt index 0b14be1eefbd..925b2e574962 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt @@ -42,14 +42,11 @@ import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import java.util.UUID import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope -import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.advanceTimeBy +import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest -import kotlinx.coroutines.yield -import org.junit.After import org.junit.Before import org.junit.Test import org.mockito.Mock @@ -68,7 +65,7 @@ class MobileIconsInteractorTest : SysuiTestCase() { set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, true) } - private val testDispatcher = UnconfinedTestDispatcher() + private val testDispatcher = StandardTestDispatcher() private val testScope = TestScope(testDispatcher) private val tableLogBuffer = @@ -113,17 +110,12 @@ class MobileIconsInteractorTest : SysuiTestCase() { ) } - @After fun tearDown() {} - @Test fun filteredSubscriptions_default() = testScope.runTest { - var latest: List<SubscriptionModel>? = null - val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.filteredSubscriptions) assertThat(latest).isEqualTo(listOf<SubscriptionModel>()) - - job.cancel() } // Based on the logic from the old pipeline, we'll never filter subs when there are more than 2 @@ -133,12 +125,9 @@ class MobileIconsInteractorTest : SysuiTestCase() { connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_3_OPP, SUB_4_OPP)) connectionsRepository.setActiveMobileDataSubscriptionId(SUB_4_ID) - var latest: List<SubscriptionModel>? = null - val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.filteredSubscriptions) assertThat(latest).isEqualTo(listOf(SUB_1, SUB_3_OPP, SUB_4_OPP)) - - job.cancel() } @Test @@ -146,12 +135,9 @@ class MobileIconsInteractorTest : SysuiTestCase() { testScope.runTest { connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_2)) - var latest: List<SubscriptionModel>? = null - val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.filteredSubscriptions) assertThat(latest).isEqualTo(listOf(SUB_1, SUB_2)) - - job.cancel() } @Test @@ -160,12 +146,9 @@ class MobileIconsInteractorTest : SysuiTestCase() { connectionsRepository.setSubscriptions(listOf(SUB_3_OPP, SUB_4_OPP)) connectionsRepository.setActiveMobileDataSubscriptionId(SUB_3_ID) - var latest: List<SubscriptionModel>? = null - val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.filteredSubscriptions) assertThat(latest).isEqualTo(listOf(SUB_3_OPP, SUB_4_OPP)) - - job.cancel() } @Test @@ -180,12 +163,9 @@ class MobileIconsInteractorTest : SysuiTestCase() { connectionsRepository.setSubscriptions(listOf(sub1, sub2)) connectionsRepository.setActiveMobileDataSubscriptionId(SUB_1_ID) - var latest: List<SubscriptionModel>? = null - val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.filteredSubscriptions) assertThat(latest).isEqualTo(listOf(sub1, sub2)) - - job.cancel() } @Test @@ -202,13 +182,10 @@ class MobileIconsInteractorTest : SysuiTestCase() { whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) .thenReturn(false) - var latest: List<SubscriptionModel>? = null - val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.filteredSubscriptions) // Filtered subscriptions should show the active one when the config is false assertThat(latest).isEqualTo(listOf(sub3)) - - job.cancel() } @Test @@ -225,13 +202,10 @@ class MobileIconsInteractorTest : SysuiTestCase() { whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) .thenReturn(false) - var latest: List<SubscriptionModel>? = null - val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.filteredSubscriptions) // Filtered subscriptions should show the active one when the config is false assertThat(latest).isEqualTo(listOf(sub4)) - - job.cancel() } @Test @@ -248,14 +222,11 @@ class MobileIconsInteractorTest : SysuiTestCase() { whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) .thenReturn(true) - var latest: List<SubscriptionModel>? = null - val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.filteredSubscriptions) // Filtered subscriptions should show the primary (non-opportunistic) if the config is // true assertThat(latest).isEqualTo(listOf(sub1)) - - job.cancel() } @Test @@ -272,14 +243,11 @@ class MobileIconsInteractorTest : SysuiTestCase() { whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) .thenReturn(true) - var latest: List<SubscriptionModel>? = null - val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.filteredSubscriptions) // Filtered subscriptions should show the primary (non-opportunistic) if the config is // true assertThat(latest).isEqualTo(listOf(sub1)) - - job.cancel() } @Test @@ -297,12 +265,9 @@ class MobileIconsInteractorTest : SysuiTestCase() { whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) .thenReturn(false) - var latest: List<SubscriptionModel>? = null - val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.filteredSubscriptions) assertThat(latest).isEqualTo(listOf(sub3)) - - job.cancel() } @Test @@ -320,12 +285,9 @@ class MobileIconsInteractorTest : SysuiTestCase() { whenever(carrierConfigTracker.alwaysShowPrimarySignalBarInOpportunisticNetworkDefault) .thenReturn(false) - var latest: List<SubscriptionModel>? = null - val job = underTest.filteredSubscriptions.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.filteredSubscriptions) assertThat(latest).isEqualTo(listOf(sub1)) - - job.cancel() } @Test @@ -449,310 +411,241 @@ class MobileIconsInteractorTest : SysuiTestCase() { fun activeDataConnection_turnedOn() = testScope.runTest { CONNECTION_1.setDataEnabled(true) - var latest: Boolean? = null - val job = - underTest.activeDataConnectionHasDataEnabled.onEach { latest = it }.launchIn(this) - assertThat(latest).isTrue() + val latest by collectLastValue(underTest.activeDataConnectionHasDataEnabled) - job.cancel() + assertThat(latest).isTrue() } @Test fun activeDataConnection_turnedOff() = testScope.runTest { CONNECTION_1.setDataEnabled(true) - var latest: Boolean? = null - val job = - underTest.activeDataConnectionHasDataEnabled.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.activeDataConnectionHasDataEnabled) CONNECTION_1.setDataEnabled(false) - yield() assertThat(latest).isFalse() - - job.cancel() } @Test fun activeDataConnection_invalidSubId() = testScope.runTest { - var latest: Boolean? = null - val job = - underTest.activeDataConnectionHasDataEnabled.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.activeDataConnectionHasDataEnabled) connectionsRepository.setActiveMobileDataSubscriptionId(INVALID_SUBSCRIPTION_ID) - yield() // An invalid active subId should tell us that data is off assertThat(latest).isFalse() - - job.cancel() } @Test fun failedConnection_default_validated_notFailed() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.isDefaultConnectionFailed.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.isDefaultConnectionFailed) connectionsRepository.mobileIsDefault.value = true connectionsRepository.defaultConnectionIsValidated.value = true - yield() assertThat(latest).isFalse() - - job.cancel() } @Test fun failedConnection_notDefault_notValidated_notFailed() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.isDefaultConnectionFailed.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.isDefaultConnectionFailed) connectionsRepository.mobileIsDefault.value = false connectionsRepository.defaultConnectionIsValidated.value = false - yield() assertThat(latest).isFalse() - - job.cancel() } @Test fun failedConnection_default_notValidated_failed() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.isDefaultConnectionFailed.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.isDefaultConnectionFailed) connectionsRepository.mobileIsDefault.value = true connectionsRepository.defaultConnectionIsValidated.value = false - yield() assertThat(latest).isTrue() - - job.cancel() } @Test fun failedConnection_carrierMergedDefault_notValidated_failed() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.isDefaultConnectionFailed.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.isDefaultConnectionFailed) connectionsRepository.hasCarrierMergedConnection.value = true connectionsRepository.defaultConnectionIsValidated.value = false - yield() assertThat(latest).isTrue() - - job.cancel() } /** Regression test for b/275076959. */ @Test fun failedConnection_dataSwitchInSameGroup_notFailed() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.isDefaultConnectionFailed.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.isDefaultConnectionFailed) connectionsRepository.mobileIsDefault.value = true connectionsRepository.defaultConnectionIsValidated.value = true + runCurrent() // WHEN there's a data change in the same subscription group connectionsRepository.activeSubChangedInGroupEvent.emit(Unit) connectionsRepository.defaultConnectionIsValidated.value = false + runCurrent() // THEN the default connection is *not* marked as failed because of forced validation assertThat(latest).isFalse() - - job.cancel() } @Test fun failedConnection_dataSwitchNotInSameGroup_isFailed() = testScope.runTest { - var latestConnectionFailed: Boolean? = null - val job = - underTest.isDefaultConnectionFailed - .onEach { latestConnectionFailed = it } - .launchIn(this) + val latest by collectLastValue(underTest.isDefaultConnectionFailed) + connectionsRepository.mobileIsDefault.value = true connectionsRepository.defaultConnectionIsValidated.value = true + runCurrent() // WHEN the connection is invalidated without a activeSubChangedInGroupEvent connectionsRepository.defaultConnectionIsValidated.value = false // THEN the connection is immediately marked as failed - assertThat(latestConnectionFailed).isTrue() - - job.cancel() + assertThat(latest).isTrue() } @Test fun alwaysShowDataRatIcon_configHasTrue() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.alwaysShowDataRatIcon.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.alwaysShowDataRatIcon) val config = MobileMappings.Config() config.alwaysShowDataRatIcon = true connectionsRepository.defaultDataSubRatConfig.value = config - yield() assertThat(latest).isTrue() - - job.cancel() } @Test fun alwaysShowDataRatIcon_configHasFalse() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.alwaysShowDataRatIcon.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.alwaysShowDataRatIcon) val config = MobileMappings.Config() config.alwaysShowDataRatIcon = false connectionsRepository.defaultDataSubRatConfig.value = config - yield() assertThat(latest).isFalse() - - job.cancel() } @Test fun alwaysUseCdmaLevel_configHasTrue() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.alwaysUseCdmaLevel.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.alwaysUseCdmaLevel) val config = MobileMappings.Config() config.alwaysShowCdmaRssi = true connectionsRepository.defaultDataSubRatConfig.value = config - yield() assertThat(latest).isTrue() - - job.cancel() } @Test fun alwaysUseCdmaLevel_configHasFalse() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.alwaysUseCdmaLevel.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.alwaysUseCdmaLevel) val config = MobileMappings.Config() config.alwaysShowCdmaRssi = false connectionsRepository.defaultDataSubRatConfig.value = config - yield() assertThat(latest).isFalse() - - job.cancel() } @Test fun isSingleCarrier_zeroSubscriptions_false() = testScope.runTest { - var latest: Boolean? = true - val job = underTest.isSingleCarrier.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.isSingleCarrier) connectionsRepository.setSubscriptions(emptyList()) - assertThat(latest).isFalse() - job.cancel() + assertThat(latest).isFalse() } @Test fun isSingleCarrier_oneSubscription_true() = testScope.runTest { - var latest: Boolean? = false - val job = underTest.isSingleCarrier.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.isSingleCarrier) connectionsRepository.setSubscriptions(listOf(SUB_1)) - assertThat(latest).isTrue() - job.cancel() + assertThat(latest).isTrue() } @Test fun isSingleCarrier_twoSubscriptions_false() = testScope.runTest { - var latest: Boolean? = true - val job = underTest.isSingleCarrier.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.isSingleCarrier) connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_2)) - assertThat(latest).isFalse() - job.cancel() + assertThat(latest).isFalse() } @Test fun isSingleCarrier_updates() = testScope.runTest { - var latest: Boolean? = false - val job = underTest.isSingleCarrier.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.isSingleCarrier) connectionsRepository.setSubscriptions(listOf(SUB_1)) assertThat(latest).isTrue() connectionsRepository.setSubscriptions(listOf(SUB_1, SUB_2)) assertThat(latest).isFalse() - - job.cancel() } @Test fun mobileIsDefault_mobileFalseAndCarrierMergedFalse_false() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.mobileIsDefault.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.mobileIsDefault) connectionsRepository.mobileIsDefault.value = false connectionsRepository.hasCarrierMergedConnection.value = false assertThat(latest).isFalse() - - job.cancel() } @Test fun mobileIsDefault_mobileTrueAndCarrierMergedFalse_true() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.mobileIsDefault.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.mobileIsDefault) connectionsRepository.mobileIsDefault.value = true connectionsRepository.hasCarrierMergedConnection.value = false assertThat(latest).isTrue() - - job.cancel() } /** Regression test for b/272586234. */ @Test fun mobileIsDefault_mobileFalseAndCarrierMergedTrue_true() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.mobileIsDefault.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.mobileIsDefault) connectionsRepository.mobileIsDefault.value = false connectionsRepository.hasCarrierMergedConnection.value = true assertThat(latest).isTrue() - - job.cancel() } @Test fun mobileIsDefault_updatesWhenRepoUpdates() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.mobileIsDefault.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.mobileIsDefault) connectionsRepository.mobileIsDefault.value = true assertThat(latest).isTrue() @@ -762,8 +655,6 @@ class MobileIconsInteractorTest : SysuiTestCase() { connectionsRepository.hasCarrierMergedConnection.value = true assertThat(latest).isTrue() - - job.cancel() } // The data switch tests are mostly testing the [forcingCellularValidation] flow, but that flow @@ -772,95 +663,79 @@ class MobileIconsInteractorTest : SysuiTestCase() { @Test fun dataSwitch_inSameGroup_validatedMatchesPreviousValue_expiresAfter2s() = testScope.runTest { - var latestConnectionFailed: Boolean? = null - val job = - underTest.isDefaultConnectionFailed - .onEach { latestConnectionFailed = it } - .launchIn(this) + val latest by collectLastValue(underTest.isDefaultConnectionFailed) connectionsRepository.mobileIsDefault.value = true connectionsRepository.defaultConnectionIsValidated.value = true + runCurrent() // Trigger a data change in the same subscription group that's not yet validated connectionsRepository.activeSubChangedInGroupEvent.emit(Unit) connectionsRepository.defaultConnectionIsValidated.value = false + runCurrent() // After 1s, the force validation bit is still present, so the connection is not marked // as failed advanceTimeBy(1000) - assertThat(latestConnectionFailed).isFalse() + assertThat(latest).isFalse() // After 2s, the force validation expires so the connection updates to failed advanceTimeBy(1001) - assertThat(latestConnectionFailed).isTrue() - - job.cancel() + assertThat(latest).isTrue() } @Test fun dataSwitch_inSameGroup_notValidated_immediatelyMarkedAsFailed() = testScope.runTest { - var latestConnectionFailed: Boolean? = null - val job = - underTest.isDefaultConnectionFailed - .onEach { latestConnectionFailed = it } - .launchIn(this) + val latest by collectLastValue(underTest.isDefaultConnectionFailed) connectionsRepository.mobileIsDefault.value = true connectionsRepository.defaultConnectionIsValidated.value = false + runCurrent() connectionsRepository.activeSubChangedInGroupEvent.emit(Unit) - assertThat(latestConnectionFailed).isTrue() - - job.cancel() + assertThat(latest).isTrue() } @Test fun dataSwitch_loseValidation_thenSwitchHappens_clearsForcedBit() = testScope.runTest { - var latestConnectionFailed: Boolean? = null - val job = - underTest.isDefaultConnectionFailed - .onEach { latestConnectionFailed = it } - .launchIn(this) + val latest by collectLastValue(underTest.isDefaultConnectionFailed) // GIVEN the network starts validated connectionsRepository.mobileIsDefault.value = true connectionsRepository.defaultConnectionIsValidated.value = true + runCurrent() // WHEN a data change happens in the same group connectionsRepository.activeSubChangedInGroupEvent.emit(Unit) // WHEN the validation bit is lost connectionsRepository.defaultConnectionIsValidated.value = false + runCurrent() // WHEN another data change happens in the same group connectionsRepository.activeSubChangedInGroupEvent.emit(Unit) // THEN the forced validation bit is still used... - assertThat(latestConnectionFailed).isFalse() + assertThat(latest).isFalse() advanceTimeBy(1000) - assertThat(latestConnectionFailed).isFalse() + assertThat(latest).isFalse() // ... but expires after 2s advanceTimeBy(1001) - assertThat(latestConnectionFailed).isTrue() - - job.cancel() + assertThat(latest).isTrue() } @Test fun dataSwitch_whileAlreadyForcingValidation_resetsClock() = testScope.runTest { - var latestConnectionFailed: Boolean? = null - val job = - underTest.isDefaultConnectionFailed - .onEach { latestConnectionFailed = it } - .launchIn(this) + val latest by collectLastValue(underTest.isDefaultConnectionFailed) connectionsRepository.mobileIsDefault.value = true connectionsRepository.defaultConnectionIsValidated.value = true + runCurrent() connectionsRepository.activeSubChangedInGroupEvent.emit(Unit) @@ -869,44 +744,37 @@ class MobileIconsInteractorTest : SysuiTestCase() { // WHEN another change in same group event happens connectionsRepository.activeSubChangedInGroupEvent.emit(Unit) connectionsRepository.defaultConnectionIsValidated.value = false + runCurrent() // THEN the forced validation remains for exactly 2 more seconds from now // 1.500s from second event advanceTimeBy(1500) - assertThat(latestConnectionFailed).isFalse() + assertThat(latest).isFalse() // 2.001s from the second event advanceTimeBy(501) - assertThat(latestConnectionFailed).isTrue() - - job.cancel() + assertThat(latest).isTrue() } @Test fun isForceHidden_repoHasMobileHidden_true() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.isForceHidden.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.isForceHidden) connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.MOBILE)) assertThat(latest).isTrue() - - job.cancel() } @Test fun isForceHidden_repoDoesNotHaveMobileHidden_false() = testScope.runTest { - var latest: Boolean? = null - val job = underTest.isForceHidden.onEach { latest = it }.launchIn(this) + val latest by collectLastValue(underTest.isForceHidden) connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.WIFI)) assertThat(latest).isFalse() - - job.cancel() } @Test |