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