1 /*
2  * Copyright (C) 2019 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.settings.notification;
18 
19 import static org.junit.Assert.assertFalse;
20 import static org.junit.Assert.assertTrue;
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.ArgumentMatchers.anyBoolean;
23 import static org.mockito.ArgumentMatchers.anyString;
24 import static org.mockito.ArgumentMatchers.eq;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.never;
27 import static org.mockito.Mockito.spy;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
31 
32 import android.content.ComponentName;
33 import android.content.Context;
34 import android.os.UserManager;
35 import android.provider.Settings;
36 
37 import androidx.fragment.app.FragmentManager;
38 import androidx.fragment.app.FragmentTransaction;
39 import androidx.test.core.app.ApplicationProvider;
40 
41 import com.android.settings.testutils.shadow.ShadowSecureSettings;
42 
43 import org.junit.Before;
44 import org.junit.Test;
45 import org.junit.runner.RunWith;
46 import org.mockito.Answers;
47 import org.mockito.Mock;
48 import org.mockito.MockitoAnnotations;
49 import org.robolectric.RobolectricTestRunner;
50 import org.robolectric.annotation.Config;
51 import org.robolectric.shadows.ShadowApplication;
52 
53 
54 @RunWith(RobolectricTestRunner.class)
55 public class NotificationAssistantPreferenceControllerTest {
56 
57     private static final String KEY = "TEST_KEY";
58     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
59     private Context mContext;
60     @Mock
61     private ConfigureNotificationSettings mFragment;
62     @Mock
63     private FragmentManager mFragmentManager;
64     @Mock
65     private FragmentTransaction mFragmentTransaction;
66     @Mock
67     private NotificationBackend mBackend;
68     @Mock
69     private UserManager mUserManager;
70     private NotificationAssistantPreferenceController mPreferenceController;
71     ComponentName mNASComponent = new ComponentName("a", "b");
72 
73     @Before
setUp()74     public void setUp() {
75         MockitoAnnotations.initMocks(this);
76         mContext = spy(ApplicationProvider.getApplicationContext());
77         ShadowApplication.getInstance().setSystemService(Context.USER_SERVICE, mUserManager);
78         doReturn(mContext).when(mFragment).getContext();
79         when(mFragment.getFragmentManager()).thenReturn(mFragmentManager);
80         when(mFragmentManager.beginTransaction()).thenReturn(mFragmentTransaction);
81         when(mBackend.getDefaultNotificationAssistant()).thenReturn(mNASComponent);
82         mPreferenceController = new NotificationAssistantPreferenceController(mContext);
83         mPreferenceController.setBackend(mBackend);
84         mPreferenceController.setFragment(mFragment);
85         when(mUserManager.getProfileIds(eq(0), anyBoolean())).thenReturn(new int[] {0, 10});
86         when(mUserManager.getProfileIds(eq(20), anyBoolean())).thenReturn(new int[] {20});
87     }
88 
89     @Test
testIsChecked()90     public void testIsChecked() throws Exception {
91         when(mBackend.getAllowedNotificationAssistant()).thenReturn(mNASComponent);
92         assertTrue(mPreferenceController.isChecked());
93 
94         when(mBackend.getAllowedNotificationAssistant()).thenReturn(null);
95         assertFalse(mPreferenceController.isChecked());
96     }
97 
98     @Test
testSetChecked()99     public void testSetChecked() throws Exception {
100         // Verify a dialog is shown when the switch is to be enabled.
101         assertFalse(mPreferenceController.setChecked(true));
102         verify(mFragmentTransaction).add(
103                 any(NotificationAssistantDialogFragment.class), anyString());
104         verify(mBackend, times(0)).setNotificationAssistantGranted(any());
105 
106         // Verify no dialog is shown and NAS set to null when disabled
107         assertTrue(mPreferenceController.setChecked(false));
108         verify(mBackend, times(1)).setNotificationAssistantGranted(null);
109     }
110 
111     @Test
112     @Config(shadows = ShadowSecureSettings.class)
testMigrationFromSetting_userEnable_multiProfile()113     public void testMigrationFromSetting_userEnable_multiProfile() throws Exception {
114         Settings.Secure.putIntForUser(mContext.getContentResolver(),
115                 Settings.Secure.NAS_SETTINGS_UPDATED, 0, 0);
116         Settings.Secure.putIntForUser(mContext.getContentResolver(),
117                 Settings.Secure.NAS_SETTINGS_UPDATED, 0, 10);
118 
119         //Test user enable for the first time
120         mPreferenceController.setNotificationAssistantGranted(mNASComponent);
121         verify(mBackend, times(1))
122                 .setNASMigrationDoneAndResetDefault(eq(0), eq(true));
123         verify(mBackend, never())
124                 .setNASMigrationDoneAndResetDefault(eq(10), anyBoolean());
125     }
126 
127     @Test
128     @Config(shadows = ShadowSecureSettings.class)
testMigrationFromSetting_userEnable_multiUser()129     public void testMigrationFromSetting_userEnable_multiUser() throws Exception {
130         Settings.Secure.putIntForUser(mContext.getContentResolver(),
131                 Settings.Secure.NAS_SETTINGS_UPDATED, 0, 0);
132         Settings.Secure.putIntForUser(mContext.getContentResolver(),
133                 Settings.Secure.NAS_SETTINGS_UPDATED, 0, 20);
134 
135         //Test user 0 enable for the first time
136         mPreferenceController.setNotificationAssistantGranted(mNASComponent);
137         verify(mBackend, times(1))
138                 .setNASMigrationDoneAndResetDefault(eq(0), eq(true));
139         verify(mBackend, never())
140                 .setNASMigrationDoneAndResetDefault(eq(20), anyBoolean());
141     }
142 
143     @Test
144     @Config(shadows = ShadowSecureSettings.class)
testMigrationFromSetting_userDisable_multiProfile()145     public void testMigrationFromSetting_userDisable_multiProfile() throws Exception {
146         Settings.Secure.putIntForUser(mContext.getContentResolver(),
147                 Settings.Secure.NAS_SETTINGS_UPDATED, 0, 0);
148         Settings.Secure.putIntForUser(mContext.getContentResolver(),
149                 Settings.Secure.NAS_SETTINGS_UPDATED, 0, 10);
150 
151         //Test user disable for the first time
152         mPreferenceController.setChecked(false);
153         verify(mBackend, times(1))
154                 .setNASMigrationDoneAndResetDefault(eq(0), eq(false));
155         verify(mBackend, never())
156                 .setNASMigrationDoneAndResetDefault(eq(10), anyBoolean());
157     }
158 
159 }
160