Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d09238d4 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[Dual Shade] Fix ShadeHeaderViewModelTest for Dual Shade on by default." into main

parents 8139ebaf ef5647e5
Loading
Loading
Loading
Loading
+76 −92
Original line number Diff line number Diff line
@@ -10,11 +10,12 @@ import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.OverlayKey
import com.android.compose.animation.scene.SceneKey
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
@@ -30,58 +31,49 @@ import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.data.repository.fakePrivacyChipRepository
import com.android.systemui.shade.domain.interactor.disableDualShade
import com.android.systemui.shade.domain.interactor.enableDualShade
import com.android.systemui.shade.domain.interactor.shadeMode
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.shade.domain.interactor.enableSingleShade
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.fakeMobileIconsInteractor
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.argThat
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.flow.flowOf
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatcher
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations

@SmallTest
@RunWith(AndroidJUnit4::class)
@EnableSceneContainer
class ShadeHeaderViewModelTest : SysuiTestCase() {

    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
    private val testScope = kosmos.testScope
    private val mobileIconsInteractor by lazy { kosmos.fakeMobileIconsInteractor }
    private val sceneInteractor by lazy { kosmos.sceneInteractor }
    private val deviceEntryInteractor by lazy { kosmos.deviceEntryInteractor }
    private val underTest by lazy { kosmos.shadeHeaderViewModel }

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        underTest.activateIn(testScope)
        underTest.activateIn(kosmos.testScope)
    }

    @Test
    fun mobileSubIds_update() =
        testScope.runTest {
            mobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1)
        kosmos.runTest {
            fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1)

            assertThat(underTest.mobileSubIds).isEqualTo(listOf(1))
            assertThat(underTest.mobileSubIds).containsExactly(1)

            mobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
            fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)

            assertThat(underTest.mobileSubIds).isEqualTo(listOf(1, 2))
            assertThat(underTest.mobileSubIds).containsExactly(1, 2)
        }

    @Test
    fun onClockClicked_enableDesktopFeatureSetFalse_launchesClock() =
        testScope.runTest {
        kosmos.runTest {
            overrideResource(R.bool.config_enableDesktopFeatureSet, false)
            val activityStarter = kosmos.activityStarter

            underTest.onClockClicked()

@@ -94,9 +86,9 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onClockClicked_enableDesktopFeatureSetTrueAndSingleShade_launchesClock() =
        testScope.runTest {
        kosmos.runTest {
            overrideResource(R.bool.config_enableDesktopFeatureSet, true)
            val activityStarter = kosmos.activityStarter
            enableSingleShade()

            underTest.onClockClicked()

@@ -109,9 +101,10 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onClockClicked_enableDesktopFeatureSetTrueAndDualShade_openNotifShade() =
        testScope.runTest {
        kosmos.runTest {
            overrideResource(R.bool.config_enableDesktopFeatureSet, true)
            setupDualShadeState(scene = Scenes.Gone)
            enableDualShade()
            setDeviceEntered(true)
            val currentScene by collectLastValue(sceneInteractor.currentScene)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)

@@ -124,9 +117,11 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onClockClicked_enableDesktopFeatureSetTrueOnNotifShade_closesShade() =
        testScope.runTest {
        kosmos.runTest {
            overrideResource(R.bool.config_enableDesktopFeatureSet, true)
            setupDualShadeState(scene = Scenes.Gone, overlay = Overlays.NotificationsShade)
            enableDualShade()
            setDeviceEntered(true)
            setOverlay(Overlays.NotificationsShade)
            val currentScene by collectLastValue(sceneInteractor.currentScene)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)

@@ -138,9 +133,11 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onClockClicked_enableDesktopFeatureSetTrueOnQSShade_openNotifShade() =
        testScope.runTest {
        kosmos.runTest {
            overrideResource(R.bool.config_enableDesktopFeatureSet, true)
            setupDualShadeState(scene = Scenes.Gone, overlay = Overlays.QuickSettingsShade)
            enableDualShade()
            setDeviceEntered(true)
            setOverlay(Overlays.QuickSettingsShade)
            val currentScene by collectLastValue(sceneInteractor.currentScene)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)

@@ -153,8 +150,7 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onShadeCarrierGroupClicked_launchesNetworkSettings() =
        testScope.runTest {
            val activityStarter = kosmos.activityStarter
        kosmos.runTest {
            underTest.onShadeCarrierGroupClicked()

            verify(activityStarter)
@@ -166,8 +162,8 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onSystemIconChipClicked_locked_collapsesShadeToLockscreen() =
        testScope.runTest {
            kosmos.disableDualShade()
        kosmos.runTest {
            disableDualShade()
            setDeviceEntered(false)
            setScene(Scenes.Shade)

@@ -178,8 +174,10 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onSystemIconChipClicked_lockedOnQsShade_collapsesShadeToLockscreen() =
        testScope.runTest {
            setupDualShadeState(scene = Scenes.Lockscreen, overlay = Overlays.QuickSettingsShade)
        kosmos.runTest {
            enableDualShade()
            setDeviceEntered(false)
            setOverlay(Overlays.QuickSettingsShade)
            val currentScene by collectLastValue(sceneInteractor.currentScene)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)

@@ -191,8 +189,10 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onSystemIconChipClicked_lockedOnNotifShade_expandsQsShade() =
        testScope.runTest {
            setupDualShadeState(scene = Scenes.Lockscreen, overlay = Overlays.NotificationsShade)
        kosmos.runTest {
            enableDualShade()
            setDeviceEntered(false)
            setOverlay(Overlays.NotificationsShade)
            val currentScene by collectLastValue(sceneInteractor.currentScene)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)

@@ -205,8 +205,8 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onSystemIconChipClicked_unlocked_collapsesShadeToGone() =
        testScope.runTest {
            kosmos.disableDualShade()
        kosmos.runTest {
            disableDualShade()
            setDeviceEntered(true)
            setScene(Scenes.Shade)

@@ -217,8 +217,10 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onSystemIconChipClicked_unlockedOnQsShade_collapsesShadeToGone() =
        testScope.runTest {
            setupDualShadeState(scene = Scenes.Gone, overlay = Overlays.QuickSettingsShade)
        kosmos.runTest {
            enableDualShade()
            setDeviceEntered(true)
            setOverlay(Overlays.QuickSettingsShade)
            val currentScene by collectLastValue(sceneInteractor.currentScene)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)

@@ -230,8 +232,10 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onSystemIconChipClicked_unlockedOnNotifShade_expandsQsShade() =
        testScope.runTest {
            setupDualShadeState(scene = Scenes.Gone, overlay = Overlays.NotificationsShade)
        kosmos.runTest {
            enableDualShade()
            setDeviceEntered(true)
            setOverlay(Overlays.NotificationsShade)
            val currentScene by collectLastValue(sceneInteractor.currentScene)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)

@@ -244,9 +248,10 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onNotificationIconChipClicked_lockedOnNotifShade_collapsesShadeToLockscreen_opensClock() =
        testScope.runTest {
            setupDualShadeState(scene = Scenes.Lockscreen, overlay = Overlays.NotificationsShade)
            val activityStarter = kosmos.activityStarter
        kosmos.runTest {
            enableDualShade()
            setDeviceEntered(false)
            setOverlay(Overlays.NotificationsShade)
            val currentScene by collectLastValue(sceneInteractor.currentScene)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)

@@ -263,8 +268,10 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onNotificationIconChipClicked_lockedOnQsShade_expandsNotifShade() =
        testScope.runTest {
            setupDualShadeState(scene = Scenes.Lockscreen, overlay = Overlays.QuickSettingsShade)
        kosmos.runTest {
            enableDualShade()
            setDeviceEntered(false)
            setOverlay(Overlays.QuickSettingsShade)
            val currentScene by collectLastValue(sceneInteractor.currentScene)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)

@@ -277,9 +284,10 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onNotificationIconChipClicked_unlockedOnNotifShade_collapsesShadeToGone_opensClock() =
        testScope.runTest {
            setupDualShadeState(scene = Scenes.Gone, overlay = Overlays.NotificationsShade)
            val activityStarter = kosmos.activityStarter
        kosmos.runTest {
            enableDualShade()
            setDeviceEntered(true)
            setOverlay(Overlays.NotificationsShade)
            val currentScene by collectLastValue(sceneInteractor.currentScene)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)

@@ -296,8 +304,10 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {

    @Test
    fun onNotificationIconChipClicked_unlockedOnQsShade_expandsNotifShade() =
        testScope.runTest {
            setupDualShadeState(scene = Scenes.Gone, overlay = Overlays.QuickSettingsShade)
        kosmos.runTest {
            enableDualShade()
            setDeviceEntered(true)
            setOverlay(Overlays.QuickSettingsShade)
            val currentScene by collectLastValue(sceneInteractor.currentScene)
            val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)

@@ -380,57 +390,31 @@ class ShadeHeaderViewModelTest : SysuiTestCase() {
            )
    }

    private fun TestScope.setupDualShadeState(scene: SceneKey, overlay: OverlayKey? = null) {
        kosmos.enableDualShade()
        val shadeMode by collectLastValue(kosmos.shadeMode)
        val currentScene by collectLastValue(sceneInteractor.currentScene)
        val currentOverlays by collectLastValue(sceneInteractor.currentOverlays)
        if (scene == Scenes.Gone) {
            // Unlock the device, marking the device has been entered.
            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
                SuccessFingerprintAuthenticationStatus(0, true)
            )
    private fun Kosmos.setScene(key: SceneKey) {
        sceneInteractor.changeScene(key, "test")
        sceneInteractor.setTransitionState(flowOf(ObservableTransitionState.Idle(key)))
    }
        assertThat(shadeMode).isEqualTo(ShadeMode.Dual)

        sceneInteractor.changeScene(scene, "test")
        checkNotNull(currentOverlays).forEach { sceneInteractor.instantlyHideOverlay(it, "test") }
        overlay?.let { sceneInteractor.showOverlay(it, "test") }
    private fun Kosmos.setOverlay(key: OverlayKey) {
        sceneInteractor.showOverlay(key, "test")
        sceneInteractor.setTransitionState(
            MutableStateFlow<ObservableTransitionState>(
                ObservableTransitionState.Idle(scene, setOfNotNull(overlay))
            flowOf(
                ObservableTransitionState.Idle(
                    currentScene = sceneInteractor.currentScene.value,
                    currentOverlays = setOf(key),
                )
            )

        assertThat(currentScene).isEqualTo(scene)
        if (overlay == null) {
            assertThat(currentOverlays).isEmpty()
        } else {
            assertThat(currentOverlays).containsExactly(overlay)
        }
    }

    private fun setScene(key: SceneKey) {
        sceneInteractor.changeScene(key, "test")
        sceneInteractor.setTransitionState(
            MutableStateFlow<ObservableTransitionState>(ObservableTransitionState.Idle(key))
        )
    }

    private fun setDeviceEntered(isEntered: Boolean) {
    private fun Kosmos.setDeviceEntered(isEntered: Boolean) {
        if (isEntered) {
            // Unlock the device marking the device has entered.
            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
            fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
                SuccessFingerprintAuthenticationStatus(0, true)
            )
        }
        setScene(
            if (isEntered) {
                Scenes.Gone
            } else {
                Scenes.Lockscreen
            }
        )
        setScene(if (isEntered) Scenes.Gone else Scenes.Lockscreen)
        assertThat(deviceEntryInteractor.isDeviceEntered.value).isEqualTo(isEntered)
    }
}