1a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy/*
2a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy * Copyright (C) 2018 The Android Open Source Project
3a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy *
4a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy * except in compliance with the License. You may obtain a copy of the License at
6a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy *
7a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy *      http://www.apache.org/licenses/LICENSE-2.0
8a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy *
9a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy * Unless required by applicable law or agreed to in writing, software distributed under the
10a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy * KIND, either express or implied. See the License for the specific language governing
12a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy * permissions and limitations under the License.
13a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy */
14a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
15a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guypackage com.android.systemui.statusbar;
16a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
178cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guyimport static junit.framework.Assert.assertFalse;
188cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guyimport static junit.framework.Assert.assertTrue;
19a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport static org.mockito.ArgumentMatchers.argThat;
20a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport static org.mockito.ArgumentMatchers.eq;
21a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport static org.mockito.ArgumentMatchers.isNull;
22a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport static org.mockito.Mockito.mock;
23a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport static org.mockito.Mockito.verify;
24a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport static org.mockito.Mockito.when;
25a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
26a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport android.app.Notification;
27a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport android.os.RemoteException;
28a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport android.service.notification.StatusBarNotification;
29a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport android.support.test.filters.SmallTest;
30a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport android.testing.AndroidTestingRunner;
31a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport android.testing.TestableLooper;
32a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
33a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport com.android.internal.statusbar.IStatusBarService;
34a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport com.android.systemui.R;
35a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport com.android.systemui.SysuiTestCase;
36a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
37a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport org.junit.Before;
38a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport org.junit.Test;
39a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport org.junit.runner.RunWith;
40a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport org.mockito.Mock;
41a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guyimport org.mockito.MockitoAnnotations;
42a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
43a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy@RunWith(AndroidTestingRunner.class)
44a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy@TestableLooper.RunWithLooper
45a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy@SmallTest
46a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guypublic class SmartReplyControllerTest extends SysuiTestCase {
47a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    private static final String TEST_NOTIFICATION_KEY = "akey";
48a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    private static final String TEST_CHOICE_TEXT = "A Reply";
49a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    private static final int TEST_CHOICE_INDEX = 2;
50a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    private static final int TEST_CHOICE_COUNT = 4;
51a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
52a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    private Notification mNotification;
53a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    private NotificationData.Entry mEntry;
54a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
55a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    @Mock
56a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    private NotificationEntryManager mNotificationEntryManager;
57a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    @Mock
58a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    private IStatusBarService mIStatusBarService;
59a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
60a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    @Before
61a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    public void setUp() {
62a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        MockitoAnnotations.initMocks(this);
63a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
64a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        mDependency.injectTestDependency(NotificationEntryManager.class,
65a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy                mNotificationEntryManager);
66a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        mDependency.injectTestDependency(IStatusBarService.class, mIStatusBarService);
67a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
68a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        mNotification = new Notification.Builder(mContext, "")
69a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy                .setSmallIcon(R.drawable.ic_person)
70a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy                .setContentTitle("Title")
71a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy                .setContentText("Text").build();
72a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        StatusBarNotification sbn = mock(StatusBarNotification.class);
73a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        when(sbn.getNotification()).thenReturn(mNotification);
74a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        when(sbn.getKey()).thenReturn(TEST_NOTIFICATION_KEY);
75a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        mEntry = new NotificationData.Entry(sbn);
76a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    }
77a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
78a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    @Test
798cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy    public void testSendSmartReply_updatesRemoteInput() {
80a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        StatusBarNotification sbn = mock(StatusBarNotification.class);
81a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        when(sbn.getKey()).thenReturn(TEST_NOTIFICATION_KEY);
82a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        when(mNotificationEntryManager.rebuildNotificationWithRemoteInput(
83a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy                argThat(entry -> entry.notification.getKey().equals(TEST_NOTIFICATION_KEY)),
84a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy                eq(TEST_CHOICE_TEXT), eq(true))).thenReturn(sbn);
85a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
86a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        SmartReplyController controller = new SmartReplyController();
87a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        controller.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT);
88a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
89a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        // Sending smart reply should make calls to NotificationEntryManager
90a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        // to update the notification with reply and spinner.
91a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        verify(mNotificationEntryManager).rebuildNotificationWithRemoteInput(
92a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy                argThat(entry -> entry.notification.getKey().equals(TEST_NOTIFICATION_KEY)),
93a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy                eq(TEST_CHOICE_TEXT), eq(true));
94a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        verify(mNotificationEntryManager).updateNotification(
95a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy                argThat(sbn2 -> sbn2.getKey().equals(TEST_NOTIFICATION_KEY)), isNull());
96a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    }
97a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
98a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    @Test
99a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    public void testSendSmartReply_logsToStatusBar() throws RemoteException {
100a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        StatusBarNotification sbn = mock(StatusBarNotification.class);
101a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        when(sbn.getKey()).thenReturn(TEST_NOTIFICATION_KEY);
102a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        when(mNotificationEntryManager.rebuildNotificationWithRemoteInput(
103a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy                argThat(entry -> entry.notification.getKey().equals(TEST_NOTIFICATION_KEY)),
104a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy                eq(TEST_CHOICE_TEXT), eq(true))).thenReturn(sbn);
105a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
106a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        SmartReplyController controller = new SmartReplyController();
107a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        controller.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT);
108a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
109a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        // Check we log the result to the status bar service.
110a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        verify(mIStatusBarService).onNotificationSmartReplySent(TEST_NOTIFICATION_KEY,
111a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy                TEST_CHOICE_INDEX);
112a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    }
113a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
114a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    @Test
115a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    public void testShowSmartReply_logsToStatusBar() throws RemoteException {
116a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        SmartReplyController controller = new SmartReplyController();
117a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        controller.smartRepliesAdded(mEntry, TEST_CHOICE_COUNT);
118a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy
119a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        // Check we log the result to the status bar service.
120a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy        verify(mIStatusBarService).onNotificationSmartRepliesAdded(TEST_NOTIFICATION_KEY,
121a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy                TEST_CHOICE_COUNT);
122a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy    }
1238cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy
1248cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy    @Test
1258cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy    public void testSendSmartReply_reportsSending() {
1268cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy        SmartReplyController controller = new SmartReplyController();
1278cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy        controller.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT);
1288cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy
1298cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy        assertTrue(controller.isSendingSmartReply(TEST_NOTIFICATION_KEY));
1308cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy    }
1318cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy
1328cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy    @Test
1338cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy    public void testSendingSmartReply_afterRemove_shouldReturnFalse() {
1348cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy        SmartReplyController controller = new SmartReplyController();
1358cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy        controller.isSendingSmartReply(TEST_NOTIFICATION_KEY);
1368cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy        controller.stopSending(mEntry);
1378cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy
1388cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy        assertFalse(controller.isSendingSmartReply(TEST_NOTIFICATION_KEY));
1398cc15d2ebf3cb2e5caaefb984e547b4b3c1249d0Kenny Guy    }
140a0f6de8ab2d78445fe0259ef0f5f00e25a3f7d19Kenny Guy}
141