diff options
Diffstat (limited to 'tests/src/com/android/customization/picker')
7 files changed, 715 insertions, 0 deletions
diff --git a/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt b/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt new file mode 100644 index 00000000..2ef4e974 --- /dev/null +++ b/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt @@ -0,0 +1,89 @@ +/* + * 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.customization.picker.clock.data.repository + +import android.graphics.Color +import androidx.annotation.ColorInt +import androidx.annotation.IntRange +import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository.Companion.fakeClocks +import com.android.customization.picker.clock.shared.ClockSize +import com.android.customization.picker.clock.shared.model.ClockMetadataModel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.combine + +/** By default [FakeClockPickerRepository] uses [fakeClocks]. */ +open class FakeClockPickerRepository(clocks: List<ClockMetadataModel> = fakeClocks) : + ClockPickerRepository { + override val allClocks: Flow<List<ClockMetadataModel>> = MutableStateFlow(clocks).asStateFlow() + + private val selectedClockId = MutableStateFlow(fakeClocks[0].clockId) + @ColorInt private val selectedColorId = MutableStateFlow<String?>(null) + private val colorTone = MutableStateFlow(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS) + @ColorInt private val seedColor = MutableStateFlow<Int?>(null) + override val selectedClock: Flow<ClockMetadataModel> = + combine( + selectedClockId, + selectedColorId, + colorTone, + seedColor, + ) { selectedClockId, selectedColor, colorTone, seedColor -> + val selectedClock = fakeClocks.find { clock -> clock.clockId == selectedClockId } + checkNotNull(selectedClock) + ClockMetadataModel( + selectedClock.clockId, + selectedClock.name, + selectedColor, + colorTone, + seedColor, + ) + } + + private val _selectedClockSize = MutableStateFlow(ClockSize.SMALL) + override val selectedClockSize: Flow<ClockSize> = _selectedClockSize.asStateFlow() + + override fun setSelectedClock(clockId: String) { + selectedClockId.value = clockId + } + + override fun setClockColor( + selectedColorId: String?, + @IntRange(from = 0, to = 100) colorToneProgress: Int, + @ColorInt seedColor: Int?, + ) { + this.selectedColorId.value = selectedColorId + this.colorTone.value = colorToneProgress + this.seedColor.value = seedColor + } + + override suspend fun setClockSize(size: ClockSize) { + _selectedClockSize.value = size + } + + companion object { + val fakeClocks = + listOf( + ClockMetadataModel("clock0", "clock0", null, 50, null), + ClockMetadataModel("clock1", "clock1", null, 50, null), + ClockMetadataModel("clock2", "clock2", null, 50, null), + ClockMetadataModel("clock3", "clock3", null, 50, null), + ) + const val CLOCK_COLOR_ID = "RED" + const val CLOCK_COLOR_TONE_PROGRESS = 87 + const val SEED_COLOR = Color.RED + } +} diff --git a/tests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt b/tests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt new file mode 100644 index 00000000..cd41d7d0 --- /dev/null +++ b/tests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt @@ -0,0 +1,73 @@ +package com.android.customization.picker.clock.domain.interactor + +import androidx.test.filters.SmallTest +import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository +import com.android.customization.picker.clock.shared.ClockSize +import com.android.wallpaper.testing.collectLastValue +import com.google.common.truth.Truth +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(JUnit4::class) +class ClockPickerInteractorTest { + + private lateinit var underTest: ClockPickerInteractor + + @Before + fun setUp() { + val testDispatcher = StandardTestDispatcher() + Dispatchers.setMain(testDispatcher) + underTest = ClockPickerInteractor(FakeClockPickerRepository()) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun setSelectedClock() = runTest { + val observedSelectedClockId = collectLastValue(underTest.selectedClockId) + underTest.setSelectedClock(FakeClockPickerRepository.fakeClocks[1].clockId) + Truth.assertThat(observedSelectedClockId()) + .isEqualTo(FakeClockPickerRepository.fakeClocks[1].clockId) + } + + @Test + fun setClockSize() = runTest { + val observedClockSize = collectLastValue(underTest.selectedClockSize) + underTest.setClockSize(ClockSize.DYNAMIC) + Truth.assertThat(observedClockSize()).isEqualTo(ClockSize.DYNAMIC) + + underTest.setClockSize(ClockSize.SMALL) + Truth.assertThat(observedClockSize()).isEqualTo(ClockSize.SMALL) + } + + @Test + fun setColor() = runTest { + val observedSelectedColor = collectLastValue(underTest.selectedColorId) + val observedColorToneProgress = collectLastValue(underTest.colorToneProgress) + val observedSeedColor = collectLastValue(underTest.seedColor) + underTest.setClockColor( + FakeClockPickerRepository.CLOCK_COLOR_ID, + FakeClockPickerRepository.CLOCK_COLOR_TONE_PROGRESS, + FakeClockPickerRepository.SEED_COLOR, + ) + Truth.assertThat(observedSelectedColor()) + .isEqualTo(FakeClockPickerRepository.CLOCK_COLOR_ID) + Truth.assertThat(observedColorToneProgress()) + .isEqualTo(FakeClockPickerRepository.CLOCK_COLOR_TONE_PROGRESS) + Truth.assertThat(observedSeedColor()).isEqualTo(FakeClockPickerRepository.SEED_COLOR) + } +} diff --git a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt new file mode 100644 index 00000000..63f77bd6 --- /dev/null +++ b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt @@ -0,0 +1,120 @@ +/* + * 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.customization.picker.clock.ui.viewmodel + +import androidx.test.filters.SmallTest +import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository +import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor +import com.android.customization.picker.clock.shared.model.ClockMetadataModel +import com.android.wallpaper.testing.collectLastValue +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.advanceTimeBy +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(JUnit4::class) +class ClockCarouselViewModelTest { + private val repositoryWithMultipleClocks by lazy { FakeClockPickerRepository() } + private val repositoryWithSingleClock by lazy { + FakeClockPickerRepository( + listOf( + ClockMetadataModel( + "clock0", + "clock0", + null, + ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS, + null, + ), + ) + ) + } + private lateinit var underTest: ClockCarouselViewModel + + @Before + fun setUp() { + val testDispatcher = StandardTestDispatcher() + Dispatchers.setMain(testDispatcher) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun setSelectedClock() = runTest { + underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithMultipleClocks)) + val observedSelectedIndex = collectLastValue(underTest.selectedIndex) + advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS) + underTest.setSelectedClock(FakeClockPickerRepository.fakeClocks[2].clockId) + assertThat(observedSelectedIndex()).isEqualTo(2) + } + + @Test + fun setShouldShowCarousel() = runTest { + underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithMultipleClocks)) + val observedIsCarouselVisible = collectLastValue(underTest.isCarouselVisible) + advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS) + underTest.showClockCarousel(false) + assertThat(observedIsCarouselVisible()).isFalse() + underTest.showClockCarousel(true) + assertThat(observedIsCarouselVisible()).isTrue() + } + + @Test + fun shouldNotShowCarouselWhenSingleClock() = runTest { + underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithSingleClock)) + val observedIsCarouselVisible = collectLastValue(underTest.isCarouselVisible) + advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS) + underTest.showClockCarousel(false) + assertThat(observedIsCarouselVisible()).isFalse() + underTest.showClockCarousel(true) + assertThat(observedIsCarouselVisible()).isFalse() + } + + @Test + fun setShouldShowSingleClock() = runTest { + underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithSingleClock)) + val observedIsSingleClockViewVisible = collectLastValue(underTest.isSingleClockViewVisible) + advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS) + underTest.showClockCarousel(false) + assertThat(observedIsSingleClockViewVisible()).isFalse() + underTest.showClockCarousel(true) + assertThat(observedIsSingleClockViewVisible()).isTrue() + } + + @Test + fun shouldNotShowSingleClockWhenMultipleClocks() = runTest { + underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithMultipleClocks)) + val observedIsSingleClockViewVisible = collectLastValue(underTest.isSingleClockViewVisible) + advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS) + underTest.showClockCarousel(false) + assertThat(observedIsSingleClockViewVisible()).isFalse() + underTest.showClockCarousel(true) + assertThat(observedIsSingleClockViewVisible()).isFalse() + } +} diff --git a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSectionViewModelTest.kt b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSectionViewModelTest.kt new file mode 100644 index 00000000..61976ad6 --- /dev/null +++ b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSectionViewModelTest.kt @@ -0,0 +1,82 @@ +/* + * 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.customization.picker.clock.ui.viewmodel + +import androidx.test.filters.SmallTest +import androidx.test.platform.app.InstrumentationRegistry +import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository +import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor +import com.android.customization.picker.clock.shared.ClockSize +import com.android.customization.picker.clock.shared.model.ClockMetadataModel +import com.android.wallpaper.testing.collectLastValue +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(JUnit4::class) +class ClockSectionViewModelTest { + + private lateinit var clockColorMap: Map<String, ClockColorViewModel> + private lateinit var interactor: ClockPickerInteractor + private lateinit var underTest: ClockSectionViewModel + + @Before + fun setUp() { + val testDispatcher = StandardTestDispatcher() + Dispatchers.setMain(testDispatcher) + val context = InstrumentationRegistry.getInstrumentation().targetContext + clockColorMap = ClockColorViewModel.getPresetColorMap(context.resources) + interactor = ClockPickerInteractor(FakeClockPickerRepository()) + underTest = + ClockSectionViewModel( + context, + interactor, + ) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun setSelectedClock() = runTest { + val colorRed = clockColorMap.values.first() + val observedSelectedClockColorAndSizeText = + collectLastValue(underTest.selectedClockColorAndSizeText) + interactor.setClockColor( + colorRed.colorId, + ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS, + ClockSettingsViewModel.blendColorWithTone( + colorRed.color, + colorRed.getColorTone(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS), + ) + ) + interactor.setClockSize(ClockSize.DYNAMIC) + assertThat(observedSelectedClockColorAndSizeText()).isEqualTo("Red, dynamic") + } +} diff --git a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModelTest.kt b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModelTest.kt new file mode 100644 index 00000000..d53288d0 --- /dev/null +++ b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModelTest.kt @@ -0,0 +1,156 @@ +package com.android.customization.picker.clock.ui.viewmodel + +import android.content.Context +import androidx.test.filters.SmallTest +import androidx.test.platform.app.InstrumentationRegistry +import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository +import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor +import com.android.customization.picker.clock.shared.ClockSize +import com.android.customization.picker.clock.shared.model.ClockMetadataModel +import com.android.customization.picker.color.data.repository.FakeColorPickerRepository +import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor +import com.android.customization.picker.color.domain.interactor.ColorPickerSnapshotRestorer +import com.android.wallpaper.testing.FakeSnapshotStore +import com.android.wallpaper.testing.collectLastValue +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.advanceTimeBy +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(JUnit4::class) +class ClockSettingsViewModelTest { + + private lateinit var context: Context + private lateinit var colorPickerInteractor: ColorPickerInteractor + private lateinit var underTest: ClockSettingsViewModel + private lateinit var colorMap: Map<String, ClockColorViewModel> + + @Before + fun setUp() { + val testDispatcher = StandardTestDispatcher() + Dispatchers.setMain(testDispatcher) + context = InstrumentationRegistry.getInstrumentation().targetContext + colorPickerInteractor = + ColorPickerInteractor( + repository = FakeColorPickerRepository(context = context), + snapshotRestorer = { + ColorPickerSnapshotRestorer(interactor = colorPickerInteractor).apply { + runBlocking { setUpSnapshotRestorer(store = FakeSnapshotStore()) } + } + }, + ) + underTest = + ClockSettingsViewModel.Factory( + context = context, + clockPickerInteractor = ClockPickerInteractor(FakeClockPickerRepository()), + colorPickerInteractor = colorPickerInteractor, + ) + .create(ClockSettingsViewModel::class.java) + colorMap = ClockColorViewModel.getPresetColorMap(context.resources) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun clickOnColorSettingsTab() = runTest { + val tabs = collectLastValue(underTest.tabs) + assertThat(tabs()?.get(0)?.name).isEqualTo("Color") + assertThat(tabs()?.get(0)?.isSelected).isTrue() + assertThat(tabs()?.get(1)?.name).isEqualTo("Size") + assertThat(tabs()?.get(1)?.isSelected).isFalse() + + tabs()?.get(1)?.onClicked?.invoke() + assertThat(tabs()?.get(0)?.isSelected).isFalse() + assertThat(tabs()?.get(1)?.isSelected).isTrue() + } + + @Test + fun setSelectedColor() = runTest { + val observedClockColorOptions = collectLastValue(underTest.colorOptions) + val observedSelectedColorOptionPosition = + collectLastValue(underTest.selectedColorOptionPosition) + val observedSliderProgress = collectLastValue(underTest.sliderProgress) + val observedSeedColor = collectLastValue(underTest.seedColor) + // Advance COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from colorOptions + advanceTimeBy(ClockSettingsViewModel.COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS) + assertThat(observedClockColorOptions()!![0].isSelected).isTrue() + assertThat(observedClockColorOptions()!![0].onClick).isNull() + assertThat(observedSelectedColorOptionPosition()).isEqualTo(0) + + observedClockColorOptions()!![1].onClick?.invoke() + // Advance COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from colorOptions + advanceTimeBy(ClockSettingsViewModel.COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS) + assertThat(observedClockColorOptions()!![1].isSelected).isTrue() + assertThat(observedClockColorOptions()!![1].onClick).isNull() + assertThat(observedSelectedColorOptionPosition()).isEqualTo(1) + assertThat(observedSliderProgress()) + .isEqualTo(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS) + val expectedSelectedColorModel = colorMap.values.first() // RED + assertThat(observedSeedColor()) + .isEqualTo( + ClockSettingsViewModel.blendColorWithTone( + expectedSelectedColorModel.color, + expectedSelectedColorModel.getColorTone( + ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS + ), + ) + ) + } + + @Test + fun setColorTone() = runTest { + val observedClockColorOptions = collectLastValue(underTest.colorOptions) + val observedIsSliderEnabled = collectLastValue(underTest.isSliderEnabled) + val observedSliderProgress = collectLastValue(underTest.sliderProgress) + val observedSeedColor = collectLastValue(underTest.seedColor) + // Advance COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from colorOptions + advanceTimeBy(ClockSettingsViewModel.COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS) + assertThat(observedClockColorOptions()!![0].isSelected).isTrue() + assertThat(observedIsSliderEnabled()).isFalse() + + observedClockColorOptions()!![1].onClick?.invoke() + + // Advance COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from colorOptions + advanceTimeBy(ClockSettingsViewModel.COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS) + assertThat(observedIsSliderEnabled()).isTrue() + val targetProgress1 = 99 + underTest.onSliderProgressChanged(targetProgress1) + assertThat(observedSliderProgress()).isEqualTo(targetProgress1) + val targetProgress2 = 55 + underTest.onSliderProgressStop(targetProgress2) + assertThat(observedSliderProgress()).isEqualTo(targetProgress2) + val expectedSelectedColorModel = colorMap.values.first() // RED + assertThat(observedSeedColor()) + .isEqualTo( + ClockSettingsViewModel.blendColorWithTone( + expectedSelectedColorModel.color, + expectedSelectedColorModel.getColorTone(targetProgress2), + ) + ) + } + + @Test + fun setClockSize() = runTest { + val observedClockSize = collectLastValue(underTest.selectedClockSize) + underTest.setClockSize(ClockSize.DYNAMIC) + assertThat(observedClockSize()).isEqualTo(ClockSize.DYNAMIC) + + underTest.setClockSize(ClockSize.SMALL) + assertThat(observedClockSize()).isEqualTo(ClockSize.SMALL) + } +} diff --git a/tests/src/com/android/customization/picker/notifications/data/repository/NotificationsRepositoryTest.kt b/tests/src/com/android/customization/picker/notifications/data/repository/NotificationsRepositoryTest.kt new file mode 100644 index 00000000..be799db3 --- /dev/null +++ b/tests/src/com/android/customization/picker/notifications/data/repository/NotificationsRepositoryTest.kt @@ -0,0 +1,94 @@ +/* + * 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.customization.picker.notifications.data.repository + +import android.provider.Settings +import androidx.test.filters.SmallTest +import com.android.customization.picker.notifications.shared.model.NotificationSettingsModel +import com.android.wallpaper.testing.FakeSecureSettingsRepository +import com.android.wallpaper.testing.collectLastValue +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(JUnit4::class) +class NotificationsRepositoryTest { + + private lateinit var underTest: NotificationsRepository + + private lateinit var testScope: TestScope + private lateinit var secureSettingsRepository: FakeSecureSettingsRepository + + @Before + fun setUp() { + val testDispatcher = StandardTestDispatcher() + testScope = TestScope(testDispatcher) + secureSettingsRepository = FakeSecureSettingsRepository() + + underTest = + NotificationsRepository( + scope = testScope.backgroundScope, + backgroundDispatcher = testDispatcher, + secureSettingsRepository = secureSettingsRepository, + ) + } + + @Test + fun settings() = + testScope.runTest { + val settings = collectLastValue(underTest.settings) + + secureSettingsRepository.set( + name = Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, + value = 1, + ) + assertThat(settings()) + .isEqualTo(NotificationSettingsModel(isShowNotificationsOnLockScreenEnabled = true)) + + secureSettingsRepository.set( + name = Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, + value = 0, + ) + assertThat(settings()) + .isEqualTo( + NotificationSettingsModel(isShowNotificationsOnLockScreenEnabled = false) + ) + } + + @Test + fun setSettings() = + testScope.runTest { + val settings = collectLastValue(underTest.settings) + + val model1 = NotificationSettingsModel(isShowNotificationsOnLockScreenEnabled = true) + underTest.setSettings(model1) + assertThat(settings()).isEqualTo(model1) + + val model2 = NotificationSettingsModel(isShowNotificationsOnLockScreenEnabled = false) + underTest.setSettings(model2) + assertThat(settings()).isEqualTo(model2) + } +} diff --git a/tests/src/com/android/customization/picker/notifications/ui/viewmodel/NotificationSectionViewModelTest.kt b/tests/src/com/android/customization/picker/notifications/ui/viewmodel/NotificationSectionViewModelTest.kt new file mode 100644 index 00000000..64426094 --- /dev/null +++ b/tests/src/com/android/customization/picker/notifications/ui/viewmodel/NotificationSectionViewModelTest.kt @@ -0,0 +1,101 @@ +/* + * 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.customization.picker.notifications.ui.viewmodel + +import androidx.test.filters.SmallTest +import com.android.customization.picker.notifications.data.repository.NotificationsRepository +import com.android.customization.picker.notifications.domain.interactor.NotificationsInteractor +import com.android.customization.picker.notifications.domain.interactor.NotificationsSnapshotRestorer +import com.android.wallpaper.testing.FakeSecureSettingsRepository +import com.android.wallpaper.testing.FakeSnapshotStore +import com.android.wallpaper.testing.collectLastValue +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(JUnit4::class) +class NotificationSectionViewModelTest { + + private lateinit var underTest: NotificationSectionViewModel + + private lateinit var testScope: TestScope + private lateinit var interactor: NotificationsInteractor + + @Before + fun setUp() { + val testDispatcher = UnconfinedTestDispatcher() + Dispatchers.setMain(testDispatcher) + testScope = TestScope(testDispatcher) + interactor = + NotificationsInteractor( + repository = + NotificationsRepository( + scope = testScope.backgroundScope, + backgroundDispatcher = testDispatcher, + secureSettingsRepository = FakeSecureSettingsRepository(), + ), + snapshotRestorer = { + NotificationsSnapshotRestorer( + interactor = interactor, + ) + .apply { runBlocking { setUpSnapshotRestorer(FakeSnapshotStore()) } } + }, + ) + + underTest = + NotificationSectionViewModel( + interactor = interactor, + ) + } + + @After + fun tearDown() { + Dispatchers.resetMain() + } + + @Test + fun `toggles back and forth`() = + testScope.runTest { + val subtitleStringResId = collectLastValue(underTest.subtitleStringResourceId) + val isSwitchOn = collectLastValue(underTest.isSwitchOn) + + val initialSubtitleStringRes = subtitleStringResId() + val initialIsSwitchOn = isSwitchOn() + + underTest.onClicked() + assertThat(subtitleStringResId()).isNotEqualTo(initialSubtitleStringRes) + assertThat(isSwitchOn()).isNotEqualTo(initialIsSwitchOn) + + underTest.onClicked() + assertThat(subtitleStringResId()).isEqualTo(initialSubtitleStringRes) + assertThat(isSwitchOn()).isEqualTo(initialIsSwitchOn) + } +} |
