blob: 37ad8357aa95c692c7851cf6bd2327c725481c03 [file] [log] [blame]
/*
* Copyright (C) 2021 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.statusbar.notification.collection.notifcollection
import android.os.Handler
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender.OnEndLifetimeExtensionCallback
import com.android.systemui.util.mockito.withArgCaptor
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.any
import org.mockito.Mockito.anyLong
import org.mockito.Mockito.eq
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations.initMocks
import java.util.function.Consumer
import java.util.function.Predicate
@SmallTest
@RunWith(AndroidTestingRunner::class)
@RunWithLooper
class SelfTrackingLifetimeExtenderTest : SysuiTestCase() {
private lateinit var extender: TestableSelfTrackingLifetimeExtender
private lateinit var entry1: NotificationEntry
private lateinit var entry2: NotificationEntry
@Mock
private lateinit var callback: OnEndLifetimeExtensionCallback
@Mock
private lateinit var mainHandler: Handler
@Mock
private lateinit var shouldExtend: Predicate<NotificationEntry>
@Mock
private lateinit var onStarted: Consumer<NotificationEntry>
@Mock
private lateinit var onCanceled: Consumer<NotificationEntry>
@Before
fun setUp() {
initMocks(this)
extender = TestableSelfTrackingLifetimeExtender()
extender.setCallback(callback)
entry1 = NotificationEntryBuilder().setId(1).build()
entry2 = NotificationEntryBuilder().setId(2).build()
}
@Test
fun testName() {
assertThat(extender.name).isEqualTo("Testable")
}
@Test
fun testNoExtend() {
`when`(shouldExtend.test(entry1)).thenReturn(false)
assertThat(extender.shouldExtendLifetime(entry1, 0)).isFalse()
assertThat(extender.isExtending(entry1.key)).isFalse()
verify(onStarted, never()).accept(entry1)
verify(onCanceled, never()).accept(entry1)
}
@Test
fun testExtendThenCancelForRepost() {
`when`(shouldExtend.test(entry1)).thenReturn(true)
assertThat(extender.shouldExtendLifetime(entry1, 0)).isTrue()
verify(onStarted).accept(entry1)
verify(onCanceled, never()).accept(entry1)
assertThat(extender.isExtending(entry1.key)).isTrue()
extender.cancelLifetimeExtension(entry1)
verify(onCanceled).accept(entry1)
}
@Test
fun testExtendThenCancel_thenEndDoesNothing() {
testExtendThenCancelForRepost()
assertThat(extender.isExtending(entry1.key)).isFalse()
extender.endLifetimeExtension(entry1.key)
extender.endLifetimeExtensionAfterDelay(entry1.key, 1000)
verify(callback, never()).onEndLifetimeExtension(any(), any())
verify(mainHandler, never()).postDelayed(any(), anyLong())
}
@Test
fun testExtendThenEnd() {
`when`(shouldExtend.test(entry1)).thenReturn(true)
assertThat(extender.shouldExtendLifetime(entry1, 0)).isTrue()
verify(onStarted).accept(entry1)
assertThat(extender.isExtending(entry1.key)).isTrue()
extender.endLifetimeExtension(entry1.key)
verify(callback).onEndLifetimeExtension(extender, entry1)
verify(onCanceled, never()).accept(entry1)
}
@Test
fun testExtendThenEndAfterDelay() {
`when`(shouldExtend.test(entry1)).thenReturn(true)
assertThat(extender.shouldExtendLifetime(entry1, 0)).isTrue()
verify(onStarted).accept(entry1)
assertThat(extender.isExtending(entry1.key)).isTrue()
// Call the method and capture the posted runnable
extender.endLifetimeExtensionAfterDelay(entry1.key, 1234)
val runnable = withArgCaptor<Runnable> {
verify(mainHandler).postDelayed(capture(), eq(1234.toLong()))
}
assertThat(extender.isExtending(entry1.key)).isTrue()
verify(callback, never()).onEndLifetimeExtension(any(), any())
// now run the posted runnable and ensure it works as expected
runnable.run()
verify(callback).onEndLifetimeExtension(extender, entry1)
assertThat(extender.isExtending(entry1.key)).isFalse()
verify(onCanceled, never()).accept(entry1)
}
@Test
fun testExtendThenEndAll() {
`when`(shouldExtend.test(entry1)).thenReturn(true)
`when`(shouldExtend.test(entry2)).thenReturn(true)
assertThat(extender.shouldExtendLifetime(entry1, 0)).isTrue()
verify(onStarted).accept(entry1)
assertThat(extender.isExtending(entry1.key)).isTrue()
assertThat(extender.isExtending(entry2.key)).isFalse()
assertThat(extender.shouldExtendLifetime(entry2, 0)).isTrue()
verify(onStarted).accept(entry2)
assertThat(extender.isExtending(entry1.key)).isTrue()
assertThat(extender.isExtending(entry2.key)).isTrue()
extender.endAllLifetimeExtensions()
verify(callback).onEndLifetimeExtension(extender, entry1)
verify(callback).onEndLifetimeExtension(extender, entry2)
verify(onCanceled, never()).accept(entry1)
verify(onCanceled, never()).accept(entry2)
}
@Test
fun testExtendWithinEndCanReExtend() {
`when`(shouldExtend.test(entry1)).thenReturn(true)
assertThat(extender.shouldExtendLifetime(entry1, 0)).isTrue()
verify(onStarted, times(1)).accept(entry1)
`when`(callback.onEndLifetimeExtension(extender, entry1)).thenAnswer {
assertThat(extender.shouldExtendLifetime(entry1, 0)).isTrue()
}
extender.endLifetimeExtension(entry1.key)
verify(onStarted, times(2)).accept(entry1)
assertThat(extender.isExtending(entry1.key)).isTrue()
}
@Test
fun testExtendWithinEndCanNotReExtend() {
`when`(shouldExtend.test(entry1)).thenReturn(true, false)
assertThat(extender.shouldExtendLifetime(entry1, 0)).isTrue()
verify(onStarted, times(1)).accept(entry1)
`when`(callback.onEndLifetimeExtension(extender, entry1)).thenAnswer {
assertThat(extender.shouldExtendLifetime(entry1, 0)).isFalse()
}
extender.endLifetimeExtension(entry1.key)
verify(onStarted, times(1)).accept(entry1)
assertThat(extender.isExtending(entry1.key)).isFalse()
}
@Test
fun testExtendWithinEndAllCanReExtend() {
`when`(shouldExtend.test(entry1)).thenReturn(true)
assertThat(extender.shouldExtendLifetime(entry1, 0)).isTrue()
verify(onStarted, times(1)).accept(entry1)
`when`(callback.onEndLifetimeExtension(extender, entry1)).thenAnswer {
assertThat(extender.shouldExtendLifetime(entry1, 0)).isTrue()
}
extender.endAllLifetimeExtensions()
verify(onStarted, times(2)).accept(entry1)
assertThat(extender.isExtending(entry1.key)).isTrue()
}
@Test
fun testExtendWithinEndAllCanNotReExtend() {
`when`(shouldExtend.test(entry1)).thenReturn(true, false)
assertThat(extender.shouldExtendLifetime(entry1, 0)).isTrue()
verify(onStarted, times(1)).accept(entry1)
`when`(callback.onEndLifetimeExtension(extender, entry1)).thenAnswer {
assertThat(extender.shouldExtendLifetime(entry1, 0)).isFalse()
}
extender.endAllLifetimeExtensions()
verify(onStarted, times(1)).accept(entry1)
assertThat(extender.isExtending(entry1.key)).isFalse()
}
inner class TestableSelfTrackingLifetimeExtender(debug: Boolean = false) :
SelfTrackingLifetimeExtender("Test", "Testable", debug, mainHandler) {
override fun queryShouldExtendLifetime(entry: NotificationEntry) =
shouldExtend.test(entry)
override fun onStartedLifetimeExtension(entry: NotificationEntry) {
onStarted.accept(entry)
}
override fun onCanceledLifetimeExtension(entry: NotificationEntry) {
onCanceled.accept(entry)
}
}
}