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

Commit 7a5aa655 authored by Anton Potapov's avatar Anton Potapov Committed by Android (Google) Code Review
Browse files

Merge "Add Volume Panel tests" into main

parents 821f8665 f7d71b07
Loading
Loading
Loading
Loading
+90 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.volume.panel.component.bottombar.ui.viewmodel

import android.content.Intent
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.activityStarter
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
import com.android.systemui.volume.panel.volumePanelViewModel
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit

@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class BottomBarViewModelTest : SysuiTestCase() {

    @JvmField @Rule var mockitoRule = MockitoJUnit.rule()

    @Captor private lateinit var intentCaptor: ArgumentCaptor<Intent>

    private val kosmos = testKosmos()

    private lateinit var underTest: BottomBarViewModel

    private fun initUnderTest() {
        underTest = with(kosmos) { BottomBarViewModel(activityStarter, volumePanelViewModel) }
    }

    @Test
    fun onDoneClicked_hidesPanel() {
        with(kosmos) {
            testScope.runTest {
                initUnderTest()
                underTest.onDoneClicked()
                runCurrent()

                val volumePanelState by collectLastValue(volumePanelViewModel.volumePanelState)
                assertThat(volumePanelState!!.isVisible).isFalse()
            }
        }
    }

    @Test
    fun onSettingsClicked_dismissesPanelAndNavigatesToSettings() {
        with(kosmos) {
            testScope.runTest {
                initUnderTest()
                underTest.onSettingsClicked()

                runCurrent()

                val volumePanelState by collectLastValue(volumePanelViewModel.volumePanelState)
                assertThat(volumePanelState!!.isVisible).isFalse()
                verify(activityStarter).startActivity(capture(intentCaptor), eq(true))
                assertThat(intentCaptor.value.action).isEqualTo(Settings.ACTION_SOUND_SETTINGS)
            }
        }
    }
}
+122 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.volume.panel.domain.interactor

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.volume.panel.availableCriteria
import com.android.systemui.volume.panel.criteriaByKey
import com.android.systemui.volume.panel.defaultCriteria
import com.android.systemui.volume.panel.domain.model.ComponentModel
import com.android.systemui.volume.panel.enabledComponents
import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey
import com.android.systemui.volume.panel.unavailableCriteria
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class ComponentsInteractorImplTest : SysuiTestCase() {

    private val kosmos = Kosmos()

    private lateinit var underTest: ComponentsInteractor

    private fun initUnderTest() {
        underTest =
            with(kosmos) {
                ComponentsInteractorImpl(
                    enabledComponents,
                    defaultCriteria,
                    testScope.backgroundScope,
                    criteriaByKey,
                )
            }
    }

    @Test
    fun componentsAvailability_checked() {
        with(kosmos) {
            testScope.runTest {
                enabledComponents =
                    setOf(
                        BOTTOM_BAR,
                        COMPONENT_1,
                        COMPONENT_2,
                    )
                criteriaByKey =
                    mapOf(
                        BOTTOM_BAR to availableCriteria,
                        COMPONENT_1 to unavailableCriteria,
                        COMPONENT_2 to availableCriteria,
                    )
                initUnderTest()

                val components by collectLastValue(underTest.components)

                assertThat(components)
                    .containsExactly(
                        ComponentModel(BOTTOM_BAR, true),
                        ComponentModel(COMPONENT_1, false),
                        ComponentModel(COMPONENT_2, true),
                    )
            }
        }
    }

    @Test
    fun noCriteria_fallbackToDefaultCriteria() {
        with(kosmos) {
            testScope.runTest {
                enabledComponents =
                    setOf(
                        BOTTOM_BAR,
                        COMPONENT_1,
                        COMPONENT_2,
                    )
                criteriaByKey =
                    mapOf(
                        BOTTOM_BAR to availableCriteria,
                        COMPONENT_2 to availableCriteria,
                    )
                defaultCriteria = unavailableCriteria
                initUnderTest()

                val components by collectLastValue(underTest.components)

                assertThat(components)
                    .containsExactly(
                        ComponentModel(BOTTOM_BAR, true),
                        ComponentModel(COMPONENT_1, false),
                        ComponentModel(COMPONENT_2, true),
                    )
            }
        }
    }

    private companion object {
        const val BOTTOM_BAR: VolumePanelComponentKey = "test_bottom_bar"
        const val COMPONENT_1: VolumePanelComponentKey = "test_component:1"
        const val COMPONENT_2: VolumePanelComponentKey = "test_component:2"
    }
}
+63 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.volume.panel.ui.composable

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.testKosmos
import com.android.systemui.volume.panel.componentByKey
import com.android.systemui.volume.panel.mockVolumePanelUiComponentProvider
import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey
import com.google.common.truth.Truth
import org.junit.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class ComponentsFactoryTest : SysuiTestCase() {

    private val kosmos = testKosmos()

    private lateinit var underTest: ComponentsFactory

    private fun initUnderTest() {
        underTest = ComponentsFactory(kosmos.componentByKey)
    }

    @Test
    fun existingComponent_created() {
        kosmos.componentByKey = mapOf(TEST_COMPONENT to kosmos.mockVolumePanelUiComponentProvider)
        initUnderTest()

        val component = underTest.createComponent(TEST_COMPONENT)

        Truth.assertThat(component).isNotNull()
    }

    @Test(expected = IllegalArgumentException::class)
    fun componentAbsence_throws() {
        kosmos.componentByKey = emptyMap()
        initUnderTest()

        underTest.createComponent(TEST_COMPONENT)
    }

    private companion object {
        const val TEST_COMPONENT: VolumePanelComponentKey = "test_component"
    }
}
+73 −2
Original line number Diff line number Diff line
@@ -16,7 +16,78 @@

package com.android.systemui.volume.panel.ui.viewmodel

class DefaultComponentsLayoutManagerTest {
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.testKosmos
import com.android.systemui.volume.panel.mockVolumePanelUiComponent
import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey
import com.android.systemui.volume.panel.ui.layout.ComponentsLayoutManager
import com.android.systemui.volume.panel.ui.layout.DefaultComponentsLayoutManager
import com.google.common.truth.Truth
import org.junit.Test
import org.junit.runner.RunWith

    // TODO(b/318080198) Write tests
@SmallTest
@RunWith(AndroidJUnit4::class)
class DefaultComponentsLayoutManagerTest : SysuiTestCase() {

    private val kosmos = testKosmos()
    private val underTest: ComponentsLayoutManager = DefaultComponentsLayoutManager()

    @Test
    fun bottomBar_isSet() {
        val bottomBarComponentState =
            ComponentState(BOTTOM_BAR, kosmos.mockVolumePanelUiComponent, false)
        val layout =
            underTest.layout(
                VolumePanelState(0, false),
                setOf(
                    bottomBarComponentState,
                    ComponentState(COMPONENT_1, kosmos.mockVolumePanelUiComponent, false),
                    ComponentState(COMPONENT_2, kosmos.mockVolumePanelUiComponent, false),
                )
            )

        Truth.assertThat(layout.bottomBarComponent).isEqualTo(bottomBarComponentState)
    }

    @Test
    fun componentsAreInOrder() {
        val bottomBarComponentState =
            ComponentState(BOTTOM_BAR, kosmos.mockVolumePanelUiComponent, false)
        val component1State = ComponentState(COMPONENT_1, kosmos.mockVolumePanelUiComponent, false)
        val component2State = ComponentState(COMPONENT_2, kosmos.mockVolumePanelUiComponent, false)
        val layout =
            underTest.layout(
                VolumePanelState(0, false),
                setOf(
                    bottomBarComponentState,
                    component1State,
                    component2State,
                )
            )

        Truth.assertThat(layout.contentComponents[0]).isEqualTo(component1State)
        Truth.assertThat(layout.contentComponents[1]).isEqualTo(component2State)
    }

    @Test(expected = IllegalStateException::class)
    fun bottomBarAbsence_throwsException() {
        val component1State = ComponentState(COMPONENT_1, kosmos.mockVolumePanelUiComponent, false)
        val component2State = ComponentState(COMPONENT_2, kosmos.mockVolumePanelUiComponent, false)
        underTest.layout(
            VolumePanelState(0, false),
            setOf(
                component1State,
                component2State,
            )
        )
    }

    private companion object {
        const val BOTTOM_BAR: VolumePanelComponentKey = "bottom_bar"
        const val COMPONENT_1: VolumePanelComponentKey = "test_component:1"
        const val COMPONENT_2: VolumePanelComponentKey = "test_component:2"
    }
}
+115 −2
Original line number Diff line number Diff line
@@ -16,7 +16,120 @@

package com.android.systemui.volume.panel.ui.viewmodel

class VolumePanelViewModelTest {
import android.content.res.Configuration
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.statusbar.policy.fakeConfigurationController
import com.android.systemui.testKosmos
import com.android.systemui.volume.panel.componentByKey
import com.android.systemui.volume.panel.componentsLayoutManager
import com.android.systemui.volume.panel.criteriaByKey
import com.android.systemui.volume.panel.dagger.factory.KosmosVolumePanelComponentFactory
import com.android.systemui.volume.panel.mockVolumePanelUiComponentProvider
import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey
import com.android.systemui.volume.panel.ui.layout.FakeComponentsLayoutManager
import com.android.systemui.volume.panel.unavailableCriteria
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith

    // TODO(b/318080198) Write tests
@SmallTest
@RunWith(AndroidJUnit4::class)
@OptIn(ExperimentalCoroutinesApi::class)
class VolumePanelViewModelTest : SysuiTestCase() {

    private val kosmos =
        testKosmos().apply {
            componentsLayoutManager = FakeComponentsLayoutManager { it.key == BOTTOM_BAR }
        }

    private val testableResources = context.orCreateTestableResources

    private lateinit var underTest: VolumePanelViewModel

    private fun initUnderTest() {
        underTest =
            VolumePanelViewModel(
                testableResources.resources,
                KosmosVolumePanelComponentFactory(kosmos),
                kosmos.fakeConfigurationController,
            )
    }

    @Test
    fun dismissingPanel_changesVisibility() {
        with(kosmos) {
            testScope.runTest {
                initUnderTest()
                assertThat(underTest.volumePanelState.value.isVisible).isTrue()

                underTest.dismissPanel()
                runCurrent()

                assertThat(underTest.volumePanelState.value.isVisible).isFalse()
            }
        }
    }

    @Test
    fun orientationChanges_panelOrientationChanges() {
        with(kosmos) {
            testScope.runTest {
                initUnderTest()
                val volumePanelState by collectLastValue(underTest.volumePanelState)
                testableResources.overrideConfiguration(
                    Configuration().apply { orientation = Configuration.ORIENTATION_PORTRAIT }
                )
                assertThat(volumePanelState!!.orientation)
                    .isEqualTo(Configuration.ORIENTATION_PORTRAIT)

                fakeConfigurationController.onConfigurationChanged(
                    Configuration().apply { orientation = Configuration.ORIENTATION_LANDSCAPE }
                )
                runCurrent()

                assertThat(volumePanelState!!.orientation)
                    .isEqualTo(Configuration.ORIENTATION_LANDSCAPE)
            }
        }
    }

    @Test
    fun components_areReturned() {
        with(kosmos) {
            testScope.runTest {
                componentByKey =
                    mapOf(
                        COMPONENT_1 to mockVolumePanelUiComponentProvider,
                        COMPONENT_2 to mockVolumePanelUiComponentProvider,
                        BOTTOM_BAR to mockVolumePanelUiComponentProvider,
                    )
                criteriaByKey = mapOf(COMPONENT_2 to unavailableCriteria)
                initUnderTest()

                val componentsLayout by collectLastValue(underTest.componentsLayout)
                runCurrent()

                assertThat(componentsLayout!!.contentComponents).hasSize(2)
                assertThat(componentsLayout!!.contentComponents[0].key).isEqualTo(COMPONENT_1)
                assertThat(componentsLayout!!.contentComponents[0].isVisible).isTrue()
                assertThat(componentsLayout!!.contentComponents[1].key).isEqualTo(COMPONENT_2)
                assertThat(componentsLayout!!.contentComponents[1].isVisible).isFalse()
                assertThat(componentsLayout!!.bottomBarComponent.key).isEqualTo(BOTTOM_BAR)
                assertThat(componentsLayout!!.bottomBarComponent.isVisible).isTrue()
            }
        }
    }

    private companion object {
        const val BOTTOM_BAR: VolumePanelComponentKey = "test_bottom_bar"
        const val COMPONENT_1: VolumePanelComponentKey = "test_component:1"
        const val COMPONENT_2: VolumePanelComponentKey = "test_component:2"
    }
}
Loading