Loading packages/SystemUI/tests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt 0 → 100644 +164 −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.inputdevice.tutorial.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType import com.android.systemui.inputdevice.tutorial.data.repository.TutorialSchedulerRepository import com.android.systemui.inputdevice.tutorial.domain.interactor.TutorialSchedulerInteractor.TutorialType import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.touchpad.data.repository.FakeTouchpadRepository import com.google.common.truth.Truth.assertThat import kotlin.time.Duration.Companion.hours import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.cancel import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runTest import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) class TutorialSchedulerInteractorTest : SysuiTestCase() { private lateinit var underTest: TutorialSchedulerInteractor private val kosmos = Kosmos() private val testScope = kosmos.testScope private lateinit var dataStoreScope: CoroutineScope private val keyboardRepository = FakeKeyboardRepository() private val touchpadRepository = FakeTouchpadRepository() private lateinit var schedulerRepository: TutorialSchedulerRepository @Before fun setup() { dataStoreScope = CoroutineScope(Dispatchers.Unconfined) schedulerRepository = TutorialSchedulerRepository( context, dataStoreScope, dataStoreName = "TutorialSchedulerInteractorTest" ) underTest = TutorialSchedulerInteractor( testScope.backgroundScope, keyboardRepository, touchpadRepository, schedulerRepository ) underTest.start() } @After fun clear() { runBlocking { schedulerRepository.clearDataStore() } dataStoreScope.cancel() } @Test fun connectKeyboard_delayElapse_launchForKeyboard() = testScope.runTest { keyboardRepository.setIsAnyKeyboardConnected(true) advanceTimeBy(LAUNCH_DELAY) assertLaunch(TutorialType.KEYBOARD) } @Test fun connectBothDevices_delayElapse_launchForBoth() = testScope.runTest { keyboardRepository.setIsAnyKeyboardConnected(true) touchpadRepository.setIsAnyTouchpadConnected(true) advanceTimeBy(LAUNCH_DELAY) assertLaunch(TutorialType.BOTH) } @Test fun connectBothDevice_delayNotElapse_launchNothing() = testScope.runTest { keyboardRepository.setIsAnyKeyboardConnected(true) touchpadRepository.setIsAnyTouchpadConnected(true) advanceTimeBy(A_SHORT_PERIOD_OF_TIME) assertLaunch(TutorialType.NONE) } @Test fun nothingConnect_delayElapse_launchNothing() = testScope.runTest { keyboardRepository.setIsAnyKeyboardConnected(false) touchpadRepository.setIsAnyTouchpadConnected(false) advanceTimeBy(LAUNCH_DELAY) assertLaunch(TutorialType.NONE) } @Test fun connectKeyboard_thenTouchpad_delayElapse_launchForBoth() = testScope.runTest { keyboardRepository.setIsAnyKeyboardConnected(true) advanceTimeBy(A_SHORT_PERIOD_OF_TIME) touchpadRepository.setIsAnyTouchpadConnected(true) advanceTimeBy(REMAINING_TIME) assertLaunch(TutorialType.BOTH) } @Test fun connectKeyboard_thenTouchpad_removeKeyboard_delayElapse_launchNothing() = testScope.runTest { keyboardRepository.setIsAnyKeyboardConnected(true) advanceTimeBy(A_SHORT_PERIOD_OF_TIME) touchpadRepository.setIsAnyTouchpadConnected(true) keyboardRepository.setIsAnyKeyboardConnected(false) advanceTimeBy(REMAINING_TIME) assertLaunch(TutorialType.NONE) } // TODO: likely to be changed after we update TutorialSchedulerInteractor.launchTutorial private suspend fun assertLaunch(tutorialType: TutorialType) { when (tutorialType) { TutorialType.KEYBOARD -> { assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isTrue() assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isFalse() } TutorialType.TOUCHPAD -> { assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isFalse() assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isTrue() } TutorialType.BOTH -> { assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isTrue() assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isTrue() } TutorialType.NONE -> { assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isFalse() assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isFalse() } } } companion object { private val LAUNCH_DELAY = 72.hours private val A_SHORT_PERIOD_OF_TIME = 2.hours private val REMAINING_TIME = 70.hours } } packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/data/repository/FakeTouchpadRepository.kt 0 → 100644 +30 −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.touchpad.data.repository import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow class FakeTouchpadRepository : TouchpadRepository { private val _isAnyTouchpadConnected = MutableStateFlow(false) override val isAnyTouchpadConnected: Flow<Boolean> = _isAnyTouchpadConnected fun setIsAnyTouchpadConnected(connected: Boolean) { _isAnyTouchpadConnected.value = connected } } Loading
packages/SystemUI/tests/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractorTest.kt 0 → 100644 +164 −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.inputdevice.tutorial.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType import com.android.systemui.inputdevice.tutorial.data.repository.TutorialSchedulerRepository import com.android.systemui.inputdevice.tutorial.domain.interactor.TutorialSchedulerInteractor.TutorialType import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.touchpad.data.repository.FakeTouchpadRepository import com.google.common.truth.Truth.assertThat import kotlin.time.Duration.Companion.hours import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.cancel import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runTest import org.junit.After import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @RunWith(AndroidJUnit4::class) class TutorialSchedulerInteractorTest : SysuiTestCase() { private lateinit var underTest: TutorialSchedulerInteractor private val kosmos = Kosmos() private val testScope = kosmos.testScope private lateinit var dataStoreScope: CoroutineScope private val keyboardRepository = FakeKeyboardRepository() private val touchpadRepository = FakeTouchpadRepository() private lateinit var schedulerRepository: TutorialSchedulerRepository @Before fun setup() { dataStoreScope = CoroutineScope(Dispatchers.Unconfined) schedulerRepository = TutorialSchedulerRepository( context, dataStoreScope, dataStoreName = "TutorialSchedulerInteractorTest" ) underTest = TutorialSchedulerInteractor( testScope.backgroundScope, keyboardRepository, touchpadRepository, schedulerRepository ) underTest.start() } @After fun clear() { runBlocking { schedulerRepository.clearDataStore() } dataStoreScope.cancel() } @Test fun connectKeyboard_delayElapse_launchForKeyboard() = testScope.runTest { keyboardRepository.setIsAnyKeyboardConnected(true) advanceTimeBy(LAUNCH_DELAY) assertLaunch(TutorialType.KEYBOARD) } @Test fun connectBothDevices_delayElapse_launchForBoth() = testScope.runTest { keyboardRepository.setIsAnyKeyboardConnected(true) touchpadRepository.setIsAnyTouchpadConnected(true) advanceTimeBy(LAUNCH_DELAY) assertLaunch(TutorialType.BOTH) } @Test fun connectBothDevice_delayNotElapse_launchNothing() = testScope.runTest { keyboardRepository.setIsAnyKeyboardConnected(true) touchpadRepository.setIsAnyTouchpadConnected(true) advanceTimeBy(A_SHORT_PERIOD_OF_TIME) assertLaunch(TutorialType.NONE) } @Test fun nothingConnect_delayElapse_launchNothing() = testScope.runTest { keyboardRepository.setIsAnyKeyboardConnected(false) touchpadRepository.setIsAnyTouchpadConnected(false) advanceTimeBy(LAUNCH_DELAY) assertLaunch(TutorialType.NONE) } @Test fun connectKeyboard_thenTouchpad_delayElapse_launchForBoth() = testScope.runTest { keyboardRepository.setIsAnyKeyboardConnected(true) advanceTimeBy(A_SHORT_PERIOD_OF_TIME) touchpadRepository.setIsAnyTouchpadConnected(true) advanceTimeBy(REMAINING_TIME) assertLaunch(TutorialType.BOTH) } @Test fun connectKeyboard_thenTouchpad_removeKeyboard_delayElapse_launchNothing() = testScope.runTest { keyboardRepository.setIsAnyKeyboardConnected(true) advanceTimeBy(A_SHORT_PERIOD_OF_TIME) touchpadRepository.setIsAnyTouchpadConnected(true) keyboardRepository.setIsAnyKeyboardConnected(false) advanceTimeBy(REMAINING_TIME) assertLaunch(TutorialType.NONE) } // TODO: likely to be changed after we update TutorialSchedulerInteractor.launchTutorial private suspend fun assertLaunch(tutorialType: TutorialType) { when (tutorialType) { TutorialType.KEYBOARD -> { assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isTrue() assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isFalse() } TutorialType.TOUCHPAD -> { assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isFalse() assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isTrue() } TutorialType.BOTH -> { assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isTrue() assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isTrue() } TutorialType.NONE -> { assertThat(schedulerRepository.isLaunched(DeviceType.KEYBOARD)).isFalse() assertThat(schedulerRepository.isLaunched(DeviceType.TOUCHPAD)).isFalse() } } } companion object { private val LAUNCH_DELAY = 72.hours private val A_SHORT_PERIOD_OF_TIME = 2.hours private val REMAINING_TIME = 70.hours } }
packages/SystemUI/tests/utils/src/com/android/systemui/touchpad/data/repository/FakeTouchpadRepository.kt 0 → 100644 +30 −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.touchpad.data.repository import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow class FakeTouchpadRepository : TouchpadRepository { private val _isAnyTouchpadConnected = MutableStateFlow(false) override val isAnyTouchpadConnected: Flow<Boolean> = _isAnyTouchpadConnected fun setIsAnyTouchpadConnected(connected: Boolean) { _isAnyTouchpadConnected.value = connected } }