1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.customization.picker.mode.ui.viewmodel
18 
19 import com.android.customization.module.logging.TestThemesUserEventLogger
20 import com.android.customization.picker.mode.data.repository.DarkModeRepository
21 import com.android.customization.picker.mode.domain.interactor.DarkModeInteractor
22 import com.android.wallpaper.testing.FakePowerManager
23 import com.android.wallpaper.testing.FakeUiModeManager
24 import com.android.wallpaper.testing.collectLastValue
25 import com.google.common.truth.Truth.assertThat
26 import dagger.hilt.android.testing.HiltAndroidRule
27 import dagger.hilt.android.testing.HiltAndroidTest
28 import javax.inject.Inject
29 import kotlinx.coroutines.Dispatchers
30 import kotlinx.coroutines.ExperimentalCoroutinesApi
31 import kotlinx.coroutines.test.TestDispatcher
32 import kotlinx.coroutines.test.TestScope
33 import kotlinx.coroutines.test.runTest
34 import kotlinx.coroutines.test.setMain
35 import org.junit.Before
36 import org.junit.Rule
37 import org.junit.Test
38 import org.junit.runner.RunWith
39 import org.robolectric.RobolectricTestRunner
40 
41 @HiltAndroidTest
42 @OptIn(ExperimentalCoroutinesApi::class)
43 @RunWith(RobolectricTestRunner::class)
44 class DarkModeViewModelTest {
45     @get:Rule var hiltRule = HiltAndroidRule(this)
46 
47     @Inject lateinit var uiModeManager: FakeUiModeManager
48     @Inject lateinit var powerManager: FakePowerManager
49     @Inject lateinit var darkModeRepository: DarkModeRepository
50     @Inject lateinit var darkModeInteractor: DarkModeInteractor
51     @Inject lateinit var logger: TestThemesUserEventLogger
52     lateinit var darkModeViewModel: DarkModeViewModel
53 
54     @Inject lateinit var testDispatcher: TestDispatcher
55     @Inject lateinit var testScope: TestScope
56 
57     @Before
setUpnull58     fun setUp() {
59         hiltRule.inject()
60         Dispatchers.setMain(testDispatcher)
61 
62         darkModeViewModel = DarkModeViewModel(darkModeInteractor, logger)
63     }
64 
65     @Test
isEnabled_powerSaveModeOnnull66     fun isEnabled_powerSaveModeOn() {
67         testScope.runTest {
68             powerManager.setIsPowerSaveMode(true)
69             darkModeRepository.refreshIsPowerSaveModeActivated()
70 
71             val isEnabled = collectLastValue(darkModeViewModel.isEnabled)()
72 
73             assertThat(isEnabled).isFalse()
74         }
75     }
76 
77     @Test
isEnabled_powerSaveModeOffnull78     fun isEnabled_powerSaveModeOff() {
79         testScope.runTest {
80             powerManager.setIsPowerSaveMode(false)
81             darkModeRepository.refreshIsPowerSaveModeActivated()
82 
83             val isEnabled = collectLastValue(darkModeViewModel.isEnabled)()
84 
85             assertThat(isEnabled).isTrue()
86         }
87     }
88 
89     @Test
toggleDarkModenull90     fun toggleDarkMode() {
91         testScope.runTest {
92             uiModeManager.setNightModeActivated(false)
93             darkModeRepository.refreshIsDarkModeActivated()
94             val getOverridingIsDarkMode = collectLastValue(darkModeViewModel.overridingIsDarkMode)
95             val getPreviewingIsDarkMode = collectLastValue(darkModeViewModel.previewingIsDarkMode)
96             val getToggleDarkMode = collectLastValue(darkModeViewModel.toggleDarkMode)
97             assertThat(getPreviewingIsDarkMode()).isFalse()
98 
99             getToggleDarkMode()?.invoke()
100 
101             assertThat(getOverridingIsDarkMode()).isTrue()
102             assertThat(getPreviewingIsDarkMode()).isTrue()
103 
104             getToggleDarkMode()?.invoke()
105 
106             assertThat(getOverridingIsDarkMode()).isNull()
107             assertThat(getPreviewingIsDarkMode()).isFalse()
108         }
109     }
110 
111     @Test
onApply_shouldLogDarkThemenull112     fun onApply_shouldLogDarkTheme() {
113         testScope.runTest {
114             uiModeManager.setNightModeActivated(false)
115             darkModeRepository.refreshIsDarkModeActivated()
116             val getToggleDarkMode = collectLastValue(darkModeViewModel.toggleDarkMode)
117             val onApply = collectLastValue(darkModeViewModel.onApply)
118 
119             getToggleDarkMode()?.invoke()
120             onApply()?.invoke()
121 
122             assertThat(logger.useDarkTheme).isTrue()
123         }
124     }
125 
126     @Test
onApply_shouldApplyDarkThemenull127     fun onApply_shouldApplyDarkTheme() {
128         testScope.runTest {
129             uiModeManager.setNightModeActivated(false)
130             darkModeRepository.refreshIsDarkModeActivated()
131             val getToggleDarkMode = collectLastValue(darkModeViewModel.toggleDarkMode)
132             val onApply = collectLastValue(darkModeViewModel.onApply)
133 
134             getToggleDarkMode()?.invoke()
135             onApply()?.invoke()
136 
137             assertThat(uiModeManager.getIsNightModeActivated()).isTrue()
138         }
139     }
140 }
141