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.wifi;
18 
19 import static android.net.ConnectivityManager.ACTION_PROMPT_LOST_VALIDATION;
20 import static android.net.ConnectivityManager.ACTION_PROMPT_PARTIAL_CONNECTIVITY;
21 import static android.net.ConnectivityManager.ACTION_PROMPT_UNVALIDATED;
22 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
23 
24 import static com.google.common.truth.Truth.assertThat;
25 
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.Mockito.eq;
28 import static org.mockito.Mockito.mock;
29 import static org.mockito.Mockito.never;
30 import static org.mockito.Mockito.spy;
31 import static org.mockito.Mockito.times;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
34 
35 import android.content.Context;
36 import android.content.DialogInterface;
37 import android.content.Intent;
38 import android.net.ConnectivityManager;
39 import android.net.Network;
40 import android.net.NetworkCapabilities;
41 import android.net.NetworkInfo;
42 import android.net.NetworkRequest;
43 import android.os.Bundle;
44 
45 import com.android.settings.R;
46 
47 import org.junit.Before;
48 import org.junit.Ignore;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 import org.mockito.ArgumentCaptor;
52 import org.mockito.Captor;
53 import org.mockito.Mock;
54 import org.mockito.MockitoAnnotations;
55 import org.robolectric.Robolectric;
56 import org.robolectric.RobolectricTestRunner;
57 import org.robolectric.RuntimeEnvironment;
58 
59 @Ignore("b/314867581")
60 @RunWith(RobolectricTestRunner.class)
61 public class WifiNoInternetDialogTest {
62 
63     private static final String FAKE_SSID = "fake_ssid";
64 
65     @Mock
66     private Network mNetwork;
67 
68     @Captor
69     private ArgumentCaptor<ConnectivityManager.NetworkCallback> mCallbackCaptor;
70 
71     @Mock
72     private ConnectivityManager mConnectivityManager;
73 
74     @Mock
75     private NetworkInfo mNetworkInfo;
76 
77     @Mock
78     private NetworkCapabilities mNetworkCapabilities;
79 
80     private WifiNoInternetDialog mActivity;
81 
82     @Before
setUp()83     public void setUp() {
84         MockitoAnnotations.initMocks(this);
85     }
86 
87     @Test
launchActivity_noIntentAction_shouldNotFatalException()88     public void launchActivity_noIntentAction_shouldNotFatalException() {
89         WifiNoInternetDialog wifiNoInternetDialog =
90                 Robolectric.setupActivity(WifiNoInternetDialog.class);
91     }
92 
93     @Test
setupPromptUnvalidated_shouldShowNoInternetAccessRemember()94     public void setupPromptUnvalidated_shouldShowNoInternetAccessRemember() {
95         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, mNetwork);
96         setupNetworkComponents();
97 
98         mActivity.onCreate(new Bundle());
99 
100         assertThat(mActivity.mAlwaysAllow.getText()).isEqualTo(
101                 mActivity.getString(R.string.no_internet_access_remember));
102     }
103 
104     @Test
setupPromptPartialConnectivity_shouldShowNoInternetAccessRemember()105     public void setupPromptPartialConnectivity_shouldShowNoInternetAccessRemember() {
106         setupActivityWithAction(ACTION_PROMPT_PARTIAL_CONNECTIVITY, mNetwork);
107         setupNetworkComponents();
108 
109         mActivity.onCreate(new Bundle());
110 
111         assertThat(mActivity.mAlwaysAllow.getText()).isEqualTo(
112                 mActivity.getString(R.string.no_internet_access_remember));
113     }
114 
115     @Test
setupPromptLostValidationAction_shouldShowLostInternetAccessPersist()116     public void setupPromptLostValidationAction_shouldShowLostInternetAccessPersist() {
117         setupActivityWithAction(ACTION_PROMPT_LOST_VALIDATION, mNetwork);
118         setupNetworkComponents();
119 
120         mActivity.onCreate(new Bundle());
121 
122         assertThat(mActivity.mAlwaysAllow.getText()).isEqualTo(
123                 mActivity.getString(R.string.lost_internet_access_persist));
124     }
125 
126     @Test
clickPositiveButton_whenPromptUnvalidated_shouldCallSetAcceptUnvalidated()127     public void clickPositiveButton_whenPromptUnvalidated_shouldCallSetAcceptUnvalidated() {
128         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, mNetwork);
129         setupNetworkComponents();
130         mActivity.onCreate(new Bundle());
131 
132         mActivity.onClick(null, DialogInterface.BUTTON_POSITIVE);
133 
134         verify(mConnectivityManager).setAcceptUnvalidated(any(Network.class), eq(true), eq(false));
135     }
136 
137     @Test
positiveButton_withPartialConnectivity_shouldCallSetAcceptPartialConnectivity()138     public void positiveButton_withPartialConnectivity_shouldCallSetAcceptPartialConnectivity() {
139         setupActivityWithAction(ACTION_PROMPT_PARTIAL_CONNECTIVITY, mNetwork);
140         setupNetworkComponents();
141         mActivity.onCreate(new Bundle());
142 
143         mActivity.onClick(null, DialogInterface.BUTTON_POSITIVE);
144 
145         verify(mConnectivityManager).setAcceptPartialConnectivity(any(Network.class), eq(true),
146                 eq(false));
147     }
148 
149     @Test
positiveButton_withLostValidation_shouldCallSetAvoidUnvalidated()150     public void positiveButton_withLostValidation_shouldCallSetAvoidUnvalidated() {
151         setupActivityWithAction(ACTION_PROMPT_LOST_VALIDATION, mNetwork);
152         setupNetworkComponents();
153         mActivity.onCreate(new Bundle());
154 
155         mActivity.onClick(null, DialogInterface.BUTTON_POSITIVE);
156 
157         verify(mConnectivityManager).setAvoidUnvalidated(any(Network.class));
158     }
159 
160     @Test
destroyWithNoClick_inPartialConnectivity_shouldCallSetAcceptPartialConnectivity()161     public void destroyWithNoClick_inPartialConnectivity_shouldCallSetAcceptPartialConnectivity() {
162         setupActivityWithAction(ACTION_PROMPT_PARTIAL_CONNECTIVITY, mNetwork);
163         setupNetworkComponents();
164         when(mActivity.isFinishing()).thenReturn(true);
165         mActivity.onCreate(new Bundle());
166 
167         mActivity.onDestroy();
168 
169         verify(mConnectivityManager).setAcceptPartialConnectivity(any(Network.class), eq(false),
170                 eq(false));
171     }
172 
173     @Test
destroyWithNoClick_whenUnvalidated_shouldCallSetAcceptUnvalidated()174     public void destroyWithNoClick_whenUnvalidated_shouldCallSetAcceptUnvalidated() {
175         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, mNetwork);
176         setupNetworkComponents();
177         when(mActivity.isFinishing()).thenReturn(true);
178         mActivity.onCreate(new Bundle());
179 
180         mActivity.onDestroy();
181 
182         verify(mConnectivityManager).setAcceptUnvalidated(any(Network.class), eq(false), eq(false));
183     }
184 
185     @Test
networkCallbackOnLost_shouldFinish()186     public void networkCallbackOnLost_shouldFinish() {
187         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, mNetwork);
188         setupNetworkComponents();
189         mActivity.onCreate(new Bundle());
190         verify(mConnectivityManager, times(1)).registerNetworkCallback(
191                 any(NetworkRequest.class), mCallbackCaptor.capture());
192 
193         mCallbackCaptor.getValue().onLost(mNetwork);
194 
195         verify(mActivity).finish();
196     }
197 
198     @Test
networkCallbackOnLost_shouldNotFinishIfNetworkIsNotTheSame()199     public void networkCallbackOnLost_shouldNotFinishIfNetworkIsNotTheSame() {
200         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, mNetwork);
201         setupNetworkComponents();
202         mActivity.onCreate(new Bundle());
203         verify(mConnectivityManager, times(1)).registerNetworkCallback(
204                 any(NetworkRequest.class), mCallbackCaptor.capture());
205 
206         Network unexpectedNetwork = mock(Network.class);
207         mCallbackCaptor.getValue().onLost(unexpectedNetwork);
208 
209         verify(mActivity, never()).finish();
210     }
211 
212     @Test
networkCallbackOnCapabilitiesChanged_shouldFinish()213     public void networkCallbackOnCapabilitiesChanged_shouldFinish() {
214         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, mNetwork);
215         setupNetworkComponents();
216         when(mNetworkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)).thenReturn(true);
217         mActivity.onCreate(new Bundle());
218         verify(mConnectivityManager, times(1)).registerNetworkCallback(
219                 any(NetworkRequest.class), mCallbackCaptor.capture());
220 
221         mCallbackCaptor.getValue().onCapabilitiesChanged(mNetwork, mNetworkCapabilities);
222 
223         verify(mActivity).finish();
224     }
225 
226     @Test
networkCallbackOnCapabilitiesChanged_shouldNotFinishIfNetworkIsNotTheSame()227     public void networkCallbackOnCapabilitiesChanged_shouldNotFinishIfNetworkIsNotTheSame() {
228         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, mNetwork);
229         setupNetworkComponents();
230         when(mNetworkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)).thenReturn(true);
231         mActivity.onCreate(new Bundle());
232         verify(mConnectivityManager, times(1)).registerNetworkCallback(
233                 any(NetworkRequest.class), mCallbackCaptor.capture());
234 
235         Network unexpectedNetwork = mock(Network.class);
236         mCallbackCaptor.getValue().onCapabilitiesChanged(unexpectedNetwork, mNetworkCapabilities);
237 
238         verify(mActivity, never()).finish();
239     }
240 
241     @Test
networkNotConnectedOrConnecting_shouldFinish()242     public void networkNotConnectedOrConnecting_shouldFinish() {
243         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, mNetwork);
244         setupNetworkComponents();
245         when(mNetworkInfo.isConnectedOrConnecting()).thenReturn(false);
246 
247         mActivity.onCreate(new Bundle());
248 
249         verify(mActivity).finish();
250     }
251 
252     @Test
withNullNetwork_shouldFinish()253     public void withNullNetwork_shouldFinish() {
254         setupActivityWithAction(ACTION_PROMPT_UNVALIDATED, null);
255         setupNetworkComponents();
256 
257         mActivity.onCreate(new Bundle());
258 
259         verify(mActivity).finish();
260     }
261 
setupNetworkComponents()262     private void setupNetworkComponents() {
263         when(mActivity.getSystemService(Context.CONNECTIVITY_SERVICE))
264                 .thenReturn(mConnectivityManager);
265         when(mNetworkInfo.isConnectedOrConnecting()).thenReturn(true);
266         when(mNetworkCapabilities.getSsid()).thenReturn(FAKE_SSID);
267         when(mConnectivityManager.getNetworkInfo(any()))
268                 .thenReturn(mNetworkInfo);
269         when(mConnectivityManager.getNetworkCapabilities(any()))
270                 .thenReturn(mNetworkCapabilities);
271     }
272 
setupActivityWithAction(String action, Network network)273     private void setupActivityWithAction(String action, Network network) {
274         final Intent intent = new Intent(action).setClassName(
275                 RuntimeEnvironment.application.getPackageName(),
276                 WifiNoInternetDialog.class.getName());
277         intent.putExtra(ConnectivityManager.EXTRA_NETWORK, network);
278         mActivity = spy(Robolectric.buildActivity(WifiNoInternetDialog.class, intent).get());
279     }
280 }