1 /*
2  * Copyright (C) 2020 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.network;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.Mockito.spy;
22 import static org.mockito.Mockito.when;
23 
24 import android.content.Context;
25 import android.os.Looper;
26 import android.telephony.SubscriptionManager;
27 
28 import androidx.preference.PreferenceCategory;
29 import androidx.preference.PreferenceManager;
30 import androidx.preference.PreferenceScreen;
31 import androidx.test.core.app.ApplicationProvider;
32 import androidx.test.ext.junit.runners.AndroidJUnit4;
33 
34 import com.android.settings.wifi.WifiConnectionPreferenceController;
35 import com.android.settingslib.core.lifecycle.Lifecycle;
36 
37 import org.junit.Assert;
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 import org.mockito.Mock;
42 import org.mockito.MockitoAnnotations;
43 
44 @RunWith(AndroidJUnit4.class)
45 public class MultiNetworkHeaderControllerTest {
46     private static final String KEY_HEADER = "multi_network_header";
47     private static final int EXPANDED_CHILDREN_COUNT = 5;
48 
49     @Mock
50     private PreferenceCategory mPreferenceCategory;
51     @Mock
52     private WifiConnectionPreferenceController mWifiController;
53     @Mock
54     private SubscriptionsPreferenceController mSubscriptionsController;
55     @Mock
56     private SubscriptionManager mSubscriptionManager;
57     @Mock
58     private Lifecycle mLifecycle;
59 
60     private Context mContext;
61     private PreferenceManager mPreferenceManager;
62     private PreferenceScreen mPreferenceScreen;
63     private MultiNetworkHeaderController mHeaderController;
64 
65     @Before
setUp()66     public void setUp() {
67         MockitoAnnotations.initMocks(this);
68         mContext = spy(ApplicationProvider.getApplicationContext());
69         when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
70 
71         mHeaderController = new MultiNetworkHeaderController(mContext, KEY_HEADER) {
72             @Override
73             WifiConnectionPreferenceController createWifiController(Lifecycle lifecycle) {
74                 return mWifiController;
75             }
76 
77             @Override
78             SubscriptionsPreferenceController createSubscriptionsController(Lifecycle lifecycle) {
79                 return mSubscriptionsController;
80             }
81         };
82 
83         if (Looper.myLooper() == null) {
84             Looper.prepare();
85         }
86         mPreferenceManager = new PreferenceManager(mContext);
87         mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
88         mPreferenceScreen.setInitialExpandedChildrenCount(EXPANDED_CHILDREN_COUNT);
89         when(mPreferenceCategory.getKey()).thenReturn(KEY_HEADER);
90         when(mPreferenceCategory.getPreferenceCount()).thenReturn(3);
91         mPreferenceScreen.addPreference(mPreferenceCategory);
92     }
93 
94     @Test
isAvailable_beforeInitIsCalled_notAvailable()95     public void isAvailable_beforeInitIsCalled_notAvailable() {
96         assertThat(mHeaderController.isAvailable()).isFalse();
97     }
98 
99     // When calling displayPreference, the header itself should only be visible if the
100     // subscriptions controller says it is available. This is a helper for test cases of this logic.
displayPreferenceTest(boolean wifiAvailable, boolean subscriptionsAvailable, boolean setVisibleExpectedValue)101     private void displayPreferenceTest(boolean wifiAvailable, boolean subscriptionsAvailable,
102             boolean setVisibleExpectedValue) {
103         when(mWifiController.isAvailable()).thenReturn(wifiAvailable);
104         when(mSubscriptionsController.isAvailable()).thenReturn(subscriptionsAvailable);
105 
106         mHeaderController.init(mLifecycle);
107         mHeaderController.displayPreference(mPreferenceScreen);
108         Assert.assertEquals(mPreferenceCategory.isVisible(), setVisibleExpectedValue);
109     }
110 
111     @Test
displayPreference_bothNotAvailable_categoryIsNotVisible()112     public void displayPreference_bothNotAvailable_categoryIsNotVisible() {
113         displayPreferenceTest(false, false, false);
114     }
115 
116     @Test
displayPreference_wifiAvailableButNotSubscriptions_categoryIsNotVisible()117     public void displayPreference_wifiAvailableButNotSubscriptions_categoryIsNotVisible() {
118         displayPreferenceTest(true, false, false);
119     }
120 
121     @Test
displayPreference_subscriptionsAvailableButNotWifi_categoryIsVisible()122     public void displayPreference_subscriptionsAvailableButNotWifi_categoryIsVisible() {
123         displayPreferenceTest(false, true, true);
124     }
125 
126     @Test
displayPreference_bothAvailable_categoryIsVisible()127     public void displayPreference_bothAvailable_categoryIsVisible() {
128         displayPreferenceTest(true, true, true);
129     }
130 
131     @Test
onChildUpdated_subscriptionsBecameAvailable_categoryIsVisible()132     public void onChildUpdated_subscriptionsBecameAvailable_categoryIsVisible() {
133         when(mSubscriptionsController.isAvailable()).thenReturn(false);
134         mHeaderController.init(mLifecycle);
135         mHeaderController.displayPreference(mPreferenceScreen);
136 
137         when(mSubscriptionsController.isAvailable()).thenReturn(true);
138         mHeaderController.onChildrenUpdated();
139 
140         Assert.assertTrue(mPreferenceCategory.isVisible());
141         assertThat(mPreferenceScreen.getInitialExpandedChildrenCount()).isEqualTo(
142                 EXPANDED_CHILDREN_COUNT + mPreferenceCategory.getPreferenceCount());
143     }
144 
145     @Test
onChildUpdated_subscriptionsBecameUnavailable_categoryIsNotVisible()146     public void onChildUpdated_subscriptionsBecameUnavailable_categoryIsNotVisible() {
147         when(mSubscriptionsController.isAvailable()).thenReturn(true);
148         mHeaderController.init(mLifecycle);
149         mHeaderController.displayPreference(mPreferenceScreen);
150 
151         when(mSubscriptionsController.isAvailable()).thenReturn(false);
152         mHeaderController.onChildrenUpdated();
153 
154         Assert.assertFalse(mPreferenceCategory.isVisible());
155         assertThat(mPreferenceScreen.getInitialExpandedChildrenCount()).isEqualTo(
156                 EXPANDED_CHILDREN_COUNT);
157     }
158 
159     @Test
onChildUpdated_noExpandedChildCountAndAvailable_doesNotSetExpandedCount()160     public void onChildUpdated_noExpandedChildCountAndAvailable_doesNotSetExpandedCount() {
161         mPreferenceScreen.setInitialExpandedChildrenCount(Integer.MAX_VALUE);
162 
163         when(mSubscriptionsController.isAvailable()).thenReturn(false);
164         mHeaderController.init(mLifecycle);
165         mHeaderController.displayPreference(mPreferenceScreen);
166 
167         when(mSubscriptionsController.isAvailable()).thenReturn(true);
168         mHeaderController.onChildrenUpdated();
169 
170         // Check that setInitialExpandedChildrenCount was never called.
171         Assert.assertEquals(mPreferenceScreen.getInitialExpandedChildrenCount(), Integer.MAX_VALUE);
172     }
173 }
174