1 /*
2  * Copyright (C) 2020 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.systemui.controls.controller
18 
19 import android.content.ComponentName
20 import android.os.Binder
21 import android.service.controls.Control
22 import android.service.controls.IControlsSubscription
23 import android.testing.AndroidTestingRunner
24 import androidx.test.filters.SmallTest
25 import com.android.systemui.SysuiTestCase
26 import com.android.systemui.util.concurrency.FakeExecutor
27 import com.android.systemui.util.time.FakeSystemClock
28 import org.junit.Before
29 import org.junit.Test
30 import org.junit.runner.RunWith
31 import org.mockito.Mock
32 import org.mockito.Mockito.never
33 import org.mockito.Mockito.`when`
34 import org.mockito.Mockito.times
35 import org.mockito.Mockito.verify
36 import org.mockito.MockitoAnnotations
37 
38 @SmallTest
39 @RunWith(AndroidTestingRunner::class)
40 class StatefulControlSubscriberTest : SysuiTestCase() {
41 
42     @Mock
43     private lateinit var controller: ControlsController
44 
45     @Mock
46     private lateinit var subscription: IControlsSubscription
47 
48     @Mock
49     private lateinit var provider: ControlsProviderLifecycleManager
50 
51     @Mock
52     private lateinit var control: Control
53 
54     private val executor = FakeExecutor(FakeSystemClock())
55     private val token = Binder()
56     private val badToken = Binder()
57 
58     private val TEST_COMPONENT = ComponentName("TEST_PKG", "TEST_CLS_1")
59 
60     private lateinit var scs: StatefulControlSubscriber
61 
62     private val REQUEST_LIMIT = 5L
63 
64     @Before
65     fun setUp() {
66         MockitoAnnotations.initMocks(this)
67 
68         `when`(provider.componentName).thenReturn(TEST_COMPONENT)
69         `when`(provider.token).thenReturn(token)
70         scs = StatefulControlSubscriber(controller, provider, executor, REQUEST_LIMIT)
71     }
72 
73     @Test
74     fun testOnSubscribe() {
75         scs.onSubscribe(token, subscription)
76 
77         executor.runAllReady()
78         verify(provider).startSubscription(subscription, REQUEST_LIMIT)
79     }
80 
81     @Test
82     fun testOnSubscribe_badToken() {
83         scs.onSubscribe(badToken, subscription)
84 
85         executor.runAllReady()
86         verify(provider, never()).startSubscription(subscription, REQUEST_LIMIT)
87     }
88 
89     @Test
90     fun testOnNext() {
91         scs.onSubscribe(token, subscription)
92         scs.onNext(token, control)
93 
94         executor.runAllReady()
95         verify(controller).refreshStatus(TEST_COMPONENT, control)
96     }
97 
98     @Test
99     fun testOnNext_multiple() {
100         scs.onSubscribe(token, subscription)
101         scs.onNext(token, control)
102         scs.onNext(token, control)
103         scs.onNext(token, control)
104 
105         executor.runAllReady()
106         verify(controller, times(3)).refreshStatus(TEST_COMPONENT, control)
107     }
108 
109     @Test
110     fun testOnNext_noRefreshBeforeSubscribe() {
111         scs.onNext(token, control)
112 
113         executor.runAllReady()
114         verify(controller, never()).refreshStatus(TEST_COMPONENT, control)
115     }
116 
117     @Test
118     fun testOnNext_noRefreshAfterCancel() {
119         scs.onSubscribe(token, subscription)
120         executor.runAllReady()
121 
122         scs.cancel()
123         scs.onNext(token, control)
124 
125         executor.runAllReady()
126         verify(controller, never()).refreshStatus(TEST_COMPONENT, control)
127     }
128 
129     @Test
130     fun testOnNext_noRefreshAfterError() {
131         scs.onSubscribe(token, subscription)
132         scs.onError(token, "Error")
133         scs.onNext(token, control)
134 
135         executor.runAllReady()
136         verify(controller, never()).refreshStatus(TEST_COMPONENT, control)
137     }
138 
139     @Test
140     fun testOnNext_noRefreshAfterComplete() {
141         scs.onSubscribe(token, subscription)
142         scs.onComplete(token)
143         scs.onNext(token, control)
144 
145         executor.runAllReady()
146         verify(controller, never()).refreshStatus(TEST_COMPONENT, control)
147     }
148 }
149