Add test code for Fix the height of NotificationContentView when there's no actions but bubble button

Added function `NotificationContentView.shouldShowBubbleButton(NotificationEntry entry)` to make unit test possible. Added tests in the converted Kotlin version of NotificationContentViewTest.

Bug: 244522899
Test: `atest NotificationContentViewTest`
Change-Id: I8c34db53386dac95d52874ed250d8420ab9a1676
This commit is contained in:
Yining Liu
2022-10-20 16:26:09 +00:00
parent 3650a601e7
commit 900fa741b5
2 changed files with 179 additions and 10 deletions

View File

@@ -1374,13 +1374,8 @@ public class NotificationContentView extends FrameLayout implements Notification
if (bubbleButton == null || actionContainer == null) {
return;
}
boolean isPersonWithShortcut =
mPeopleIdentifier.getPeopleNotificationType(entry)
>= PeopleNotificationIdentifier.TYPE_FULL_PERSON;
boolean showButton = BubblesManager.areBubblesEnabled(mContext, entry.getSbn().getUser())
&& isPersonWithShortcut
&& entry.getBubbleMetadata() != null;
if (showButton) {
if (shouldShowBubbleButton(entry)) {
// explicitly resolve drawable resource using SystemUI's theme
Drawable d = mContext.getDrawable(entry.isBubble()
? R.drawable.bubble_ic_stop_bubble
@@ -1410,6 +1405,16 @@ public class NotificationContentView extends FrameLayout implements Notification
}
}
@VisibleForTesting
boolean shouldShowBubbleButton(NotificationEntry entry) {
boolean isPersonWithShortcut =
mPeopleIdentifier.getPeopleNotificationType(entry)
>= PeopleNotificationIdentifier.TYPE_FULL_PERSON;
return BubblesManager.areBubblesEnabled(mContext, entry.getSbn().getUser())
&& isPersonWithShortcut
&& entry.getBubbleMetadata() != null;
}
private void applySnoozeAction(View layout) {
if (layout == null || mContainingNotification == null) {
return;

View File

@@ -16,9 +16,15 @@
package com.android.systemui.statusbar.notification.row
import android.content.res.Resources
import android.os.UserHandle
import android.service.notification.StatusBarNotification
import android.testing.AndroidTestingRunner
import android.view.NotificationHeaderView
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.test.filters.SmallTest
import com.android.internal.R
import com.android.internal.widget.NotificationActionListLayout
@@ -26,31 +32,45 @@ import com.android.internal.widget.NotificationExpandButton
import com.android.systemui.SysuiTestCase
import com.android.systemui.media.dialog.MediaOutputDialogFactory
import com.android.systemui.statusbar.notification.FeedbackIcon
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import junit.framework.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
import org.mockito.Mock
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations.initMocks
@SmallTest
@RunWith(AndroidTestingRunner::class)
class NotificationContentViewTest : SysuiTestCase() {
private lateinit var view: NotificationContentView
@Mock private lateinit var mPeopleNotificationIdentifier: PeopleNotificationIdentifier
private val notificationContentMargin =
mContext.resources.getDimensionPixelSize(R.dimen.notification_content_margin)
@Before
fun setup() {
initMocks(this)
mDependency.injectMockDependency(MediaOutputDialogFactory::class.java)
view = NotificationContentView(mContext, /* attrs= */ null)
view = spy(NotificationContentView(mContext, /* attrs= */ null))
val row = ExpandableNotificationRow(mContext, /* attrs= */ null)
val spyRow = Mockito.spy(row)
row.entry = createMockNotificationEntry(false)
val spyRow = spy(row)
doReturn(10).whenever(spyRow).intrinsicHeight
with(view) {
initialize(mPeopleNotificationIdentifier, mock(), mock(), mock())
setContainingNotification(spyRow)
setHeights(/* smallHeight= */ 10, /* headsUpMaxHeight= */ 20, /* maxHeight= */ 30)
contractedChild = createViewWithHeight(10)
@@ -183,4 +203,148 @@ class NotificationContentViewTest : SysuiTestCase() {
View.IMPORTANT_FOR_ACCESSIBILITY_AUTO
verify(mockHeadsUpActions).importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_AUTO
}
@Test
fun setExpandedChild_notShowBubbleButton_marginTargetBottomMarginShouldNotChange() {
// Given: bottom margin of actionListMarginTarget is notificationContentMargin
// Bubble button should not be shown for the given NotificationEntry
val mockNotificationEntry = createMockNotificationEntry(/* showButton= */ false)
val mockContainingNotification = createMockContainingNotification(mockNotificationEntry)
val actionListMarginTarget =
spy(createLinearLayoutWithBottomMargin(notificationContentMargin))
val mockExpandedChild = createMockExpandedChild(mockNotificationEntry)
whenever(
mockExpandedChild.findViewById<LinearLayout>(
R.id.notification_action_list_margin_target
)
)
.thenReturn(actionListMarginTarget)
view.setContainingNotification(mockContainingNotification)
// When: call NotificationContentView.setExpandedChild() to set the expandedChild
view.expandedChild = mockExpandedChild
// Then: bottom margin of actionListMarginTarget should not change,
// still be notificationContentMargin
assertEquals(notificationContentMargin, getMarginBottom(actionListMarginTarget))
}
@Test
fun setExpandedChild_showBubbleButton_marginTargetBottomMarginShouldChangeToZero() {
// Given: bottom margin of actionListMarginTarget is notificationContentMargin
// Bubble button should be shown for the given NotificationEntry
val mockNotificationEntry = createMockNotificationEntry(/* showButton= */ true)
val mockContainingNotification = createMockContainingNotification(mockNotificationEntry)
val actionListMarginTarget =
spy(createLinearLayoutWithBottomMargin(notificationContentMargin))
val mockExpandedChild = createMockExpandedChild(mockNotificationEntry)
whenever(
mockExpandedChild.findViewById<LinearLayout>(
R.id.notification_action_list_margin_target
)
)
.thenReturn(actionListMarginTarget)
view.setContainingNotification(mockContainingNotification)
// When: call NotificationContentView.setExpandedChild() to set the expandedChild
view.expandedChild = mockExpandedChild
// Then: bottom margin of actionListMarginTarget should be set to 0
assertEquals(0, getMarginBottom(actionListMarginTarget))
}
@Test
fun onNotificationUpdated_notShowBubbleButton_marginTargetBottomMarginShouldNotChange() {
// Given: bottom margin of actionListMarginTarget is notificationContentMargin
val mockNotificationEntry = createMockNotificationEntry(/* showButton= */ false)
val mockContainingNotification = createMockContainingNotification(mockNotificationEntry)
val actionListMarginTarget =
spy(createLinearLayoutWithBottomMargin(notificationContentMargin))
val mockExpandedChild = createMockExpandedChild(mockNotificationEntry)
whenever(
mockExpandedChild.findViewById<LinearLayout>(
R.id.notification_action_list_margin_target
)
)
.thenReturn(actionListMarginTarget)
view.setContainingNotification(mockContainingNotification)
view.expandedChild = mockExpandedChild
assertEquals(notificationContentMargin, getMarginBottom(actionListMarginTarget))
// When: call NotificationContentView.onNotificationUpdated() to update the
// NotificationEntry, which should not show bubble button
view.onNotificationUpdated(createMockNotificationEntry(/* showButton= */ false))
// Then: bottom margin of actionListMarginTarget should not change, still be 20
assertEquals(notificationContentMargin, getMarginBottom(actionListMarginTarget))
}
@Test
fun onNotificationUpdated_showBubbleButton_marginTargetBottomMarginShouldChangeToZero() {
// Given: bottom margin of actionListMarginTarget is notificationContentMargin
val mockNotificationEntry = createMockNotificationEntry(/* showButton= */ false)
val mockContainingNotification = createMockContainingNotification(mockNotificationEntry)
val actionListMarginTarget =
spy(createLinearLayoutWithBottomMargin(notificationContentMargin))
val mockExpandedChild = createMockExpandedChild(mockNotificationEntry)
whenever(
mockExpandedChild.findViewById<LinearLayout>(
R.id.notification_action_list_margin_target
)
)
.thenReturn(actionListMarginTarget)
view.setContainingNotification(mockContainingNotification)
view.expandedChild = mockExpandedChild
assertEquals(notificationContentMargin, getMarginBottom(actionListMarginTarget))
// When: call NotificationContentView.onNotificationUpdated() to update the
// NotificationEntry, which should show bubble button
view.onNotificationUpdated(createMockNotificationEntry(true))
// Then: bottom margin of actionListMarginTarget should not change, still be 20
assertEquals(0, getMarginBottom(actionListMarginTarget))
}
private fun createMockContainingNotification(notificationEntry: NotificationEntry) =
mock<ExpandableNotificationRow>().apply {
whenever(this.entry).thenReturn(notificationEntry)
whenever(this.context).thenReturn(mContext)
whenever(this.bubbleClickListener).thenReturn(View.OnClickListener {})
}
private fun createMockNotificationEntry(showButton: Boolean) =
mock<NotificationEntry>().apply {
whenever(mPeopleNotificationIdentifier.getPeopleNotificationType(this))
.thenReturn(PeopleNotificationIdentifier.TYPE_FULL_PERSON)
whenever(this.bubbleMetadata).thenReturn(mock())
val sbnMock: StatusBarNotification = mock()
val userMock: UserHandle = mock()
whenever(this.sbn).thenReturn(sbnMock)
whenever(sbnMock.user).thenReturn(userMock)
doReturn(showButton).whenever(view).shouldShowBubbleButton(this)
}
private fun createLinearLayoutWithBottomMargin(bottomMargin: Int): LinearLayout {
val outerLayout = LinearLayout(mContext)
val innerLayout = LinearLayout(mContext)
outerLayout.addView(innerLayout)
val mlp = innerLayout.layoutParams as ViewGroup.MarginLayoutParams
mlp.setMargins(0, 0, 0, bottomMargin)
return innerLayout
}
private fun createMockExpandedChild(notificationEntry: NotificationEntry) =
mock<ExpandableNotificationRow>().apply {
whenever(this.findViewById<ImageView>(R.id.bubble_button)).thenReturn(mock())
whenever(this.findViewById<View>(R.id.actions_container)).thenReturn(mock())
whenever(this.entry).thenReturn(notificationEntry)
whenever(this.context).thenReturn(mContext)
val resourcesMock: Resources = mock()
whenever(resourcesMock.configuration).thenReturn(mock())
whenever(this.resources).thenReturn(resourcesMock)
}
private fun getMarginBottom(layout: LinearLayout): Int =
(layout.layoutParams as ViewGroup.MarginLayoutParams).bottomMargin
}