1/*
2 * Copyright (C) 2017 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
17package com.android.settings.wifi;
18
19import static android.provider.Settings.Global.USE_OPEN_WIFI_PACKAGE;
20import static com.android.settings.wifi.UseOpenWifiPreferenceController.REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY;
21import static com.google.common.truth.Truth.assertThat;
22import static org.mockito.Matchers.eq;
23import static org.mockito.Mockito.mock;
24import static org.mockito.Mockito.verify;
25import static org.mockito.Mockito.when;
26
27import android.annotation.NonNull;
28import android.app.Activity;
29import android.app.Fragment;
30import android.content.ComponentName;
31import android.content.Context;
32import android.content.Intent;
33import android.net.NetworkScoreManager;
34import android.net.NetworkScorerAppData;
35import android.provider.Settings;
36import android.support.v14.preference.SwitchPreference;
37import android.support.v7.preference.Preference;
38
39import com.android.settings.R;
40import com.android.settings.TestConfig;
41import com.android.settings.network.NetworkScoreManagerWrapper;
42import com.android.settings.testutils.SettingsRobolectricTestRunner;
43import com.android.settingslib.core.lifecycle.Lifecycle;
44
45import com.google.common.collect.Lists;
46import org.junit.Before;
47import org.junit.Test;
48import org.junit.runner.RunWith;
49import org.mockito.ArgumentCaptor;
50import org.mockito.Captor;
51import org.mockito.Mock;
52import org.mockito.MockitoAnnotations;
53import org.robolectric.RuntimeEnvironment;
54import org.robolectric.annotation.Config;
55
56import java.util.ArrayList;
57import java.util.List;
58
59@RunWith(SettingsRobolectricTestRunner.class)
60@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
61public class UseOpenWifiPreferenceControllerTest {
62    private static ComponentName ENABLE_ACTIVITY_COMPONENT =
63            new ComponentName("package", "activityClass");
64    private static NetworkScorerAppData APP_DATA =
65            new NetworkScorerAppData(0, null, null, ENABLE_ACTIVITY_COMPONENT, null);
66    private static NetworkScorerAppData APP_DATA_NO_ACTIVITY =
67            new NetworkScorerAppData(0, null, null, null, null);
68
69    @Mock private Lifecycle mLifecycle;
70    @Mock private Fragment mFragment;
71    @Mock private NetworkScoreManagerWrapper mNetworkScoreManagerWrapper;
72    @Captor private ArgumentCaptor<Intent> mIntentCaptor;
73    private Context mContext;
74    private UseOpenWifiPreferenceController mController;
75
76    @Before
77    public void setUp() {
78        MockitoAnnotations.initMocks(this);
79
80        mContext = RuntimeEnvironment.application;
81    }
82
83    private void createController() {
84        mController = new UseOpenWifiPreferenceController(
85                mContext, mFragment, mNetworkScoreManagerWrapper, mLifecycle);
86    }
87
88    /**
89     * Sets the scorers.
90     * @param scorers list of scorers returned by {@link NetworkScoreManager#getAllValidScorers()}.
91     *                First scorer in the list is the active scorer.
92     */
93    private void setupScorers(@NonNull List<NetworkScorerAppData> scorers) {
94        when(mNetworkScoreManagerWrapper.getActiveScorerPackage()).thenReturn(
95                ENABLE_ACTIVITY_COMPONENT.getPackageName());
96        when(mNetworkScoreManagerWrapper.getAllValidScorers()).thenReturn(scorers);
97        when(mNetworkScoreManagerWrapper.getActiveScorer()).thenReturn(scorers.get(0));
98    }
99
100    @Test
101    public void testIsAvailable_returnsFalseWhenNoScorerSet() {
102        createController();
103
104        assertThat(mController.isAvailable()).isFalse();
105    }
106
107    @Test
108    public void testIsAvailable_returnsFalseWhenScorersNotSupported() {
109        setupScorers(Lists.newArrayList(APP_DATA_NO_ACTIVITY));
110        createController();
111
112        assertThat(mController.isAvailable()).isFalse();
113    }
114
115    @Test
116    public void testIsAvailable_returnsTrueIfActiveScorerSupported() {
117        setupScorers(Lists.newArrayList(APP_DATA, APP_DATA_NO_ACTIVITY));
118        createController();
119
120        assertThat(mController.isAvailable()).isTrue();
121    }
122
123    @Test
124    public void testIsAvailable_returnsTrueIfNonActiveScorerSupported() {
125        setupScorers(Lists.newArrayList(APP_DATA_NO_ACTIVITY, APP_DATA));
126        when(mNetworkScoreManagerWrapper.getActiveScorer()).thenReturn(APP_DATA_NO_ACTIVITY);
127        createController();
128
129        assertThat(mController.isAvailable()).isTrue();
130    }
131
132    @Test
133    public void onPreferenceChange_nonMatchingKey_shouldDoNothing() {
134        createController();
135
136        final SwitchPreference pref = new SwitchPreference(mContext);
137
138        assertThat(mController.onPreferenceChange(pref, null)).isFalse();
139    }
140
141    @Test
142    public void onPreferenceChange_notAvailable_shouldDoNothing() {
143        createController();
144
145        final Preference pref = new Preference(mContext);
146        pref.setKey(mController.getPreferenceKey());
147
148        assertThat(mController.onPreferenceChange(pref, null)).isFalse();
149    }
150
151    @Test
152    public void onPreferenceChange_matchingKeyAndAvailable_enableShouldStartEnableActivity() {
153        setupScorers(Lists.newArrayList(APP_DATA, APP_DATA_NO_ACTIVITY));
154        createController();
155
156        final SwitchPreference pref = new SwitchPreference(mContext);
157        pref.setKey(mController.getPreferenceKey());
158
159        assertThat(mController.onPreferenceChange(pref, null)).isFalse();
160        verify(mFragment).startActivityForResult(mIntentCaptor.capture(),
161                eq(REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY));
162        Intent activityIntent = mIntentCaptor.getValue();
163        assertThat(activityIntent.getComponent()).isEqualTo(ENABLE_ACTIVITY_COMPONENT);
164        assertThat(activityIntent.getAction()).isEqualTo(NetworkScoreManager.ACTION_CUSTOM_ENABLE);
165    }
166
167    @Test
168    public void onPreferenceChange_matchingKeyAndAvailable_disableShouldUpdateSetting() {
169        setupScorers(Lists.newArrayList(APP_DATA, APP_DATA_NO_ACTIVITY));
170        Settings.Global.putString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE,
171                ENABLE_ACTIVITY_COMPONENT.getPackageName());
172
173        createController();
174
175        final SwitchPreference pref = new SwitchPreference(mContext);
176        pref.setKey(mController.getPreferenceKey());
177
178        assertThat(mController.onPreferenceChange(pref, null)).isTrue();
179        assertThat(Settings.Global.getString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE))
180                .isEqualTo("");
181    }
182
183    @Test
184    public void onActivityResult_nonmatchingRequestCode_shouldDoNothing() {
185        setupScorers(Lists.newArrayList(APP_DATA, APP_DATA_NO_ACTIVITY));
186        createController();
187
188        assertThat(mController.onActivityResult(234 /* requestCode */ , Activity.RESULT_OK))
189                .isEqualTo(false);
190        assertThat(Settings.Global.getString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE))
191                .isNull();
192    }
193
194    @Test
195    public void onActivityResult_matchingRequestCode_nonOkResult_shouldDoNothing() {
196        setupScorers(Lists.newArrayList(APP_DATA, APP_DATA_NO_ACTIVITY));
197        createController();
198
199        assertThat(mController
200                .onActivityResult(REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY, Activity.RESULT_CANCELED))
201                .isEqualTo(true);
202        assertThat(Settings.Global.getString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE))
203                .isNull();
204    }
205
206    @Test
207    public void onActivityResult_matchingRequestCode_okResult_updatesSetting() {
208        setupScorers(Lists.newArrayList(APP_DATA, APP_DATA_NO_ACTIVITY));
209        createController();
210
211        assertThat(mController
212                .onActivityResult(REQUEST_CODE_OPEN_WIFI_AUTOMATICALLY, Activity.RESULT_OK))
213                .isEqualTo(true);
214        assertThat(Settings.Global.getString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE))
215                .isEqualTo(ENABLE_ACTIVITY_COMPONENT.getPackageName());
216    }
217
218    @Test
219    public void updateState_noEnableActivity_preferenceDisabled_summaryChanged() {
220        setupScorers(Lists.newArrayList(APP_DATA_NO_ACTIVITY));
221        createController();
222
223        final SwitchPreference preference = mock(SwitchPreference.class);
224        Settings.Global.putString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE,
225                ENABLE_ACTIVITY_COMPONENT.getPackageName());
226
227        mController.updateState(preference);
228
229        verify(preference).setChecked(false);
230        verify(preference).setSummary(
231                R.string.use_open_wifi_automatically_summary_scorer_unsupported_disabled);
232    }
233
234    @Test
235    public void updateState_noScorer_preferenceDisabled_summaryChanged() {
236        when(mNetworkScoreManagerWrapper.getAllValidScorers()).thenReturn(new ArrayList<>());
237        createController();
238
239        final SwitchPreference preference = mock(SwitchPreference.class);
240        Settings.Global.putString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE,
241                ENABLE_ACTIVITY_COMPONENT.getPackageName());
242
243        mController.updateState(preference);
244
245        verify(preference).setChecked(false);
246        verify(preference).setSummary(
247                R.string.use_open_wifi_automatically_summary_scoring_disabled);
248    }
249
250    @Test
251    public void updateState_enableActivityExists_preferenceEnabled() {
252        setupScorers(Lists.newArrayList(APP_DATA, APP_DATA_NO_ACTIVITY));
253        createController();
254
255        final SwitchPreference preference = mock(SwitchPreference.class);
256        Settings.Global.putString(mContext.getContentResolver(), USE_OPEN_WIFI_PACKAGE,
257                ENABLE_ACTIVITY_COMPONENT.getPackageName());
258
259        mController.updateState(preference);
260
261        verify(preference).setChecked(true);
262        verify(preference).setSummary(R.string.use_open_wifi_automatically_summary);
263    }
264}
265