blob: 742fcf5e03c3104fb8928b0800e632fd07147c72 [file] [log] [blame]
/*
* Copyright (C) 2020 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.coordinator
import android.app.NotificationChannel
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
import com.android.systemui.statusbar.notification.collection.NotifPipeline
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
import com.android.systemui.statusbar.notification.collection.render.NodeController
import com.android.systemui.statusbar.notification.icon.ConversationIconManager
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_IMPORTANT_PERSON
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.withArgCaptor
import com.google.common.truth.Truth.assertThat
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import org.mockito.Mockito.`when` as whenever
@SmallTest
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
class ConversationCoordinatorTest : SysuiTestCase() {
// captured listeners and pluggables:
private lateinit var promoter: NotifPromoter
private lateinit var peopleSectioner: NotifSectioner
private lateinit var peopleComparator: NotifComparator
private lateinit var beforeRenderListListener: OnBeforeRenderListListener
@Mock private lateinit var pipeline: NotifPipeline
@Mock private lateinit var conversationIconManager: ConversationIconManager
@Mock private lateinit var peopleNotificationIdentifier: PeopleNotificationIdentifier
@Mock private lateinit var channel: NotificationChannel
@Mock private lateinit var headerController: NodeController
private lateinit var entry: NotificationEntry
private lateinit var entryA: NotificationEntry
private lateinit var entryB: NotificationEntry
private lateinit var coordinator: ConversationCoordinator
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
coordinator = ConversationCoordinator(
peopleNotificationIdentifier,
conversationIconManager,
headerController
)
whenever(channel.isImportantConversation).thenReturn(true)
coordinator.attach(pipeline)
// capture arguments:
promoter = withArgCaptor {
verify(pipeline).addPromoter(capture())
}
beforeRenderListListener = withArgCaptor {
verify(pipeline).addOnBeforeRenderListListener(capture())
}
peopleSectioner = coordinator.sectioner
peopleComparator = peopleSectioner.comparator!!
entry = NotificationEntryBuilder().setChannel(channel).build()
val section = NotifSection(peopleSectioner, 0)
entryA = NotificationEntryBuilder().setChannel(channel)
.setSection(section).setTag("A").build()
entryB = NotificationEntryBuilder().setChannel(channel)
.setSection(section).setTag("B").build()
}
@Test
fun testPromotesImportantConversations() {
// only promote important conversations
assertTrue(promoter.shouldPromoteToTopLevel(entry))
assertFalse(promoter.shouldPromoteToTopLevel(NotificationEntryBuilder().build()))
}
@Test
fun testPromotedImportantConversationsMakesSummaryUnimportant() {
val altChildA = NotificationEntryBuilder().setTag("A").build()
val altChildB = NotificationEntryBuilder().setTag("B").build()
val summary = NotificationEntryBuilder().setId(2).setChannel(channel).build()
val groupEntry = GroupEntryBuilder()
.setParent(GroupEntry.ROOT_ENTRY)
.setSummary(summary)
.setChildren(listOf(entry, altChildA, altChildB))
.build()
assertTrue(promoter.shouldPromoteToTopLevel(entry))
assertFalse(promoter.shouldPromoteToTopLevel(altChildA))
assertFalse(promoter.shouldPromoteToTopLevel(altChildB))
NotificationEntryBuilder.setNewParent(entry, GroupEntry.ROOT_ENTRY)
GroupEntryBuilder.getRawChildren(groupEntry).remove(entry)
beforeRenderListListener.onBeforeRenderList(listOf(entry, groupEntry))
verify(conversationIconManager).setUnimportantConversations(eq(listOf(summary.key)))
}
@Test
fun testInPeopleSection() {
whenever(peopleNotificationIdentifier.getPeopleNotificationType(entry))
.thenReturn(TYPE_PERSON)
// only put people notifications in this section
assertTrue(peopleSectioner.isInSection(entry))
assertFalse(peopleSectioner.isInSection(NotificationEntryBuilder().build()))
}
@Test
fun testComparatorPutsImportantPeopleFirst() {
whenever(peopleNotificationIdentifier.getPeopleNotificationType(entryA))
.thenReturn(TYPE_IMPORTANT_PERSON)
whenever(peopleNotificationIdentifier.getPeopleNotificationType(entryB))
.thenReturn(TYPE_PERSON)
// only put people notifications in this section
assertThat(peopleComparator.compare(entryA, entryB)).isEqualTo(-1)
}
@Test
fun testComparatorEquatesPeopleWithSameType() {
whenever(peopleNotificationIdentifier.getPeopleNotificationType(entryA))
.thenReturn(TYPE_PERSON)
whenever(peopleNotificationIdentifier.getPeopleNotificationType(entryB))
.thenReturn(TYPE_PERSON)
// only put people notifications in this section
assertThat(peopleComparator.compare(entryA, entryB)).isEqualTo(0)
}
}