1 /*
2  * Copyright (C) 2023 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 @file:OptIn(ExperimentalCoroutinesApi::class, ExperimentalCoroutinesApi::class)
18 
19 package com.android.systemui.scene.domain.interactor
20 
21 import androidx.test.filters.SmallTest
22 import com.android.systemui.SysuiTestCase
23 import com.android.systemui.coroutines.collectLastValue
24 import com.android.systemui.scene.SceneTestUtils
25 import com.android.systemui.scene.shared.model.ObservableTransitionState
26 import com.android.systemui.scene.shared.model.SceneKey
27 import com.android.systemui.scene.shared.model.SceneModel
28 import com.google.common.truth.Truth.assertThat
29 import kotlinx.coroutines.ExperimentalCoroutinesApi
30 import kotlinx.coroutines.flow.MutableStateFlow
31 import kotlinx.coroutines.test.runTest
32 import org.junit.Test
33 import org.junit.runner.RunWith
34 import org.junit.runners.JUnit4
35 
36 @SmallTest
37 @RunWith(JUnit4::class)
38 class SceneInteractorTest : SysuiTestCase() {
39 
40     private val utils = SceneTestUtils(this)
41     private val testScope = utils.testScope
42     private val repository = utils.fakeSceneContainerRepository()
43     private val underTest = utils.sceneInteractor(repository = repository)
44 
45     @Test
46     fun allSceneKeys() {
47         assertThat(underTest.allSceneKeys()).isEqualTo(utils.fakeSceneKeys())
48     }
49 
50     @Test
51     fun changeScene() =
52         testScope.runTest {
53             val desiredScene by collectLastValue(underTest.desiredScene)
54             assertThat(desiredScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
55 
56             underTest.changeScene(SceneModel(SceneKey.Shade), "reason")
57             assertThat(desiredScene).isEqualTo(SceneModel(SceneKey.Shade))
58         }
59 
60     @Test
61     fun onSceneChanged() =
62         testScope.runTest {
63             val desiredScene by collectLastValue(underTest.desiredScene)
64             assertThat(desiredScene).isEqualTo(SceneModel(SceneKey.Lockscreen))
65 
66             underTest.onSceneChanged(SceneModel(SceneKey.Shade), "reason")
67             assertThat(desiredScene).isEqualTo(SceneModel(SceneKey.Shade))
68         }
69 
70     @Test
71     fun transitionState() =
72         testScope.runTest {
73             val underTest = utils.fakeSceneContainerRepository()
74             val transitionState =
75                 MutableStateFlow<ObservableTransitionState>(
76                     ObservableTransitionState.Idle(SceneKey.Lockscreen)
77                 )
78             underTest.setTransitionState(transitionState)
79             val reflectedTransitionState by collectLastValue(underTest.transitionState)
80             assertThat(reflectedTransitionState).isEqualTo(transitionState.value)
81 
82             val progress = MutableStateFlow(1f)
83             transitionState.value =
84                 ObservableTransitionState.Transition(
85                     fromScene = SceneKey.Lockscreen,
86                     toScene = SceneKey.Shade,
87                     progress = progress,
88                 )
89             assertThat(reflectedTransitionState).isEqualTo(transitionState.value)
90 
91             progress.value = 0.1f
92             assertThat(reflectedTransitionState).isEqualTo(transitionState.value)
93 
94             progress.value = 0.9f
95             assertThat(reflectedTransitionState).isEqualTo(transitionState.value)
96 
97             underTest.setTransitionState(null)
98             assertThat(reflectedTransitionState)
99                 .isEqualTo(
100                     ObservableTransitionState.Idle(utils.fakeSceneContainerConfig().initialSceneKey)
101                 )
102         }
103 
104     @Test
105     fun transitioningTo() =
106         testScope.runTest {
107             val transitionState =
108                 MutableStateFlow<ObservableTransitionState>(
109                     ObservableTransitionState.Idle(underTest.desiredScene.value.key)
110                 )
111             underTest.setTransitionState(transitionState)
112 
113             val transitionTo by collectLastValue(underTest.transitioningTo)
114             assertThat(transitionTo).isNull()
115 
116             underTest.changeScene(SceneModel(SceneKey.Shade), "reason")
117             assertThat(transitionTo).isNull()
118 
119             val progress = MutableStateFlow(0f)
120             transitionState.value =
121                 ObservableTransitionState.Transition(
122                     fromScene = underTest.desiredScene.value.key,
123                     toScene = SceneKey.Shade,
124                     progress = progress,
125                 )
126             assertThat(transitionTo).isEqualTo(SceneKey.Shade)
127 
128             progress.value = 0.5f
129             assertThat(transitionTo).isEqualTo(SceneKey.Shade)
130 
131             progress.value = 1f
132             assertThat(transitionTo).isEqualTo(SceneKey.Shade)
133 
134             transitionState.value = ObservableTransitionState.Idle(SceneKey.Shade)
135             assertThat(transitionTo).isNull()
136         }
137 
138     @Test
139     fun isVisible() =
140         testScope.runTest {
141             val isVisible by collectLastValue(underTest.isVisible)
142             assertThat(isVisible).isTrue()
143 
144             underTest.setVisible(false, "reason")
145             assertThat(isVisible).isFalse()
146 
147             underTest.setVisible(true, "reason")
148             assertThat(isVisible).isTrue()
149         }
150 }
151