1 /*
2  * Copyright (C) 2018 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 
18 package com.android.settings.panel;
19 
20 import static com.google.common.truth.Truth.assertThat;
21 
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.Mockito.doReturn;
24 import static org.mockito.Mockito.spy;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.when;
27 
28 import android.app.settings.SettingsEnums;
29 import android.content.Context;
30 import android.net.Uri;
31 import android.os.Bundle;
32 import android.view.LayoutInflater;
33 import android.view.View;
34 import android.widget.Button;
35 import android.widget.LinearLayout;
36 import android.widget.ProgressBar;
37 import android.widget.TextView;
38 
39 import androidx.core.graphics.drawable.IconCompat;
40 
41 import com.android.settings.R;
42 import com.android.settings.testutils.FakeFeatureFactory;
43 
44 import org.junit.Before;
45 import org.junit.Ignore;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
48 import org.mockito.ArgumentCaptor;
49 import org.robolectric.Robolectric;
50 import org.robolectric.RobolectricTestRunner;
51 import org.robolectric.RuntimeEnvironment;
52 import org.robolectric.android.controller.ActivityController;
53 import org.robolectric.annotation.Config;
54 
55 import java.util.Objects;
56 
57 @Deprecated(forRemoval = true)
58 @Ignore("b/313576125")
59 @RunWith(RobolectricTestRunner.class)
60 @Config(shadows = {
61         com.android.settings.testutils.shadow.ShadowFragment.class,
62 })
63 public class PanelFragmentTest {
64 
65     private static final String TITLE = "title";
66     private static final String TITLE2 = "title2";
67     private static final String SUBTITLE = "subtitle";
68     private static final String SUBTITLE2 = "subtitle2";
69 
70     private Context mContext;
71     private PanelFragment mPanelFragment;
72     private FakeSettingsPanelActivity mActivity;
73     private FakeFeatureFactory mFakeFeatureFactory;
74     private PanelFeatureProvider mPanelFeatureProvider;
75     private FakePanelContent mFakePanelContent;
76     private ArgumentCaptor<PanelContentCallback> mPanelContentCbs = ArgumentCaptor.forClass(
77             PanelContentCallback.class);
78 
79     private final String FAKE_EXTRA = "fake_extra";
80 
81     @Before
setUp()82     public void setUp() {
83         mContext = RuntimeEnvironment.application;
84 
85         mPanelFeatureProvider = spy(new PanelFeatureProviderImpl());
86         mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
87         mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider;
88         mFakePanelContent = spy(new FakePanelContent());
89         doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any());
90     }
91 
initFakeActivity()92     private void initFakeActivity() {
93         mActivity = spy(Robolectric.buildActivity(FakeSettingsPanelActivity.class).setup().get());
94 
95         mPanelFragment =
96                 spy((PanelFragment)
97                         mActivity.getSupportFragmentManager().findFragmentById(R.id.main_content));
98         doReturn(mActivity).when(mPanelFragment).getActivity();
99 
100         final Bundle bundle = new Bundle();
101         bundle.putString(SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT, FAKE_EXTRA);
102         doReturn(bundle).when(mPanelFragment).getArguments();
103     }
104 
105     @Test
onCreateView_countdownLatch_setup()106     public void onCreateView_countdownLatch_setup() {
107         initFakeActivity();
108         mPanelFragment.onCreateView(LayoutInflater.from(mContext),
109                 new LinearLayout(mContext), null);
110         PanelSlicesLoaderCountdownLatch countdownLatch =
111                 mPanelFragment.mPanelSlicesLoaderCountdownLatch;
112         for (Uri sliecUri : mFakePanelContent.getSlices()) {
113             countdownLatch.markSliceLoaded(sliecUri);
114         }
115 
116         assertThat(countdownLatch.isPanelReadyToLoad()).isTrue();
117     }
118 
119     @Test
onCreate_logsOpenEvent()120     public void onCreate_logsOpenEvent() {
121         initFakeActivity();
122         verify(mFakeFeatureFactory.metricsFeatureProvider).action(
123                 0,
124                 SettingsEnums.PAGE_VISIBLE,
125                 mFakePanelContent.getMetricsCategory(),
126                 null,
127                 0);
128     }
129 
130     @Test
onDestroy_logCloseEvent()131     public void onDestroy_logCloseEvent() {
132         initFakeActivity();
133         mPanelFragment.onDestroyView();
134         verify(mFakeFeatureFactory.metricsFeatureProvider).action(
135                 0,
136                 SettingsEnums.PAGE_HIDE,
137                 mFakePanelContent.getMetricsCategory(),
138                 PanelLoggingContract.PanelClosedKeys.KEY_OTHERS,
139                 0);
140     }
141 
142     @Test
panelSeeMoreClick_logsCloseEvent()143     public void panelSeeMoreClick_logsCloseEvent() {
144         initFakeActivity();
145         final View.OnClickListener listener = mPanelFragment.getSeeMoreListener();
146         listener.onClick(null);
147         verify(mActivity).finish();
148 
149         mPanelFragment.onDestroyView();
150         verify(mFakeFeatureFactory.metricsFeatureProvider).action(
151                 0,
152                 SettingsEnums.PAGE_HIDE,
153                 mFakePanelContent.getMetricsCategory(),
154                 PanelLoggingContract.PanelClosedKeys.KEY_SEE_MORE,
155                 0
156         );
157     }
158 
159     @Test
panelDoneClick_logsCloseEvent()160     public void panelDoneClick_logsCloseEvent() {
161         initFakeActivity();
162         final View.OnClickListener listener = mPanelFragment.getCloseListener();
163         listener.onClick(null);
164         verify(mActivity).finish();
165 
166         mPanelFragment.onDestroyView();
167         verify(mFakeFeatureFactory.metricsFeatureProvider).action(
168                 0,
169                 SettingsEnums.PAGE_HIDE,
170                 mFakePanelContent.getMetricsCategory(),
171                 PanelLoggingContract.PanelClosedKeys.KEY_DONE,
172                 0
173         );
174     }
175 
176     @Test
supportIcon_displayIconHeaderLayout()177     public void supportIcon_displayIconHeaderLayout() {
178         final IconCompat icon = IconCompat.createWithResource(mContext, R.drawable.ic_android);
179         mFakePanelContent.setIcon(icon);
180         mFakePanelContent.setSubTitle(SUBTITLE);
181         final ActivityController<FakeSettingsPanelActivity> activityController =
182                 Robolectric.buildActivity(FakeSettingsPanelActivity.class);
183         activityController.setup();
184         final PanelFragment panelFragment = (PanelFragment)
185                 Objects.requireNonNull(activityController
186                         .get()
187                         .getSupportFragmentManager()
188                         .findFragmentById(R.id.main_content));
189         final View titleView = panelFragment.mLayoutView.findViewById(R.id.panel_title);
190         final LinearLayout panelHeader = panelFragment.mLayoutView.findViewById(R.id.panel_header);
191         final TextView headerTitle = panelFragment.mLayoutView.findViewById(R.id.header_title);
192         final TextView headerSubtitle = panelFragment.mLayoutView.findViewById(
193                 R.id.header_subtitle);
194         // Check visibility
195         assertThat(panelHeader.getVisibility()).isEqualTo(View.VISIBLE);
196         assertThat(titleView.getVisibility()).isEqualTo(View.GONE);
197         // Check content
198         assertThat(headerTitle.getText()).isEqualTo(FakePanelContent.TITLE);
199         assertThat(headerSubtitle.getText()).isEqualTo(SUBTITLE);
200     }
201 
202     @Test
notSupportIcon_displayDefaultHeaderLayout()203     public void notSupportIcon_displayDefaultHeaderLayout() {
204         final ActivityController<FakeSettingsPanelActivity> activityController =
205                 Robolectric.buildActivity(FakeSettingsPanelActivity.class);
206         activityController.setup();
207         final PanelFragment panelFragment = (PanelFragment)
208                 Objects.requireNonNull(activityController
209                         .get()
210                         .getSupportFragmentManager()
211                         .findFragmentById(R.id.main_content));
212 
213         final View titleView = panelFragment.mLayoutView.findViewById(R.id.panel_title);
214         final View panelHeader = panelFragment.mLayoutView.findViewById(R.id.panel_header);
215 
216         assertThat(panelHeader.getVisibility()).isEqualTo(View.GONE);
217         assertThat(titleView.getVisibility()).isEqualTo(View.VISIBLE);
218     }
219 
220     @Test
onHeaderChanged_updateHeader_verifyTitle()221     public void onHeaderChanged_updateHeader_verifyTitle() {
222         mFakePanelContent.setIcon(IconCompat.createWithResource(mContext, R.drawable.ic_android));
223         mFakePanelContent.setTitle(TITLE);
224         mFakePanelContent.setSubTitle(SUBTITLE);
225         final ActivityController<FakeSettingsPanelActivity> activityController =
226                 Robolectric.buildActivity(FakeSettingsPanelActivity.class);
227         activityController.setup();
228         final PanelFragment panelFragment = (PanelFragment)
229                 Objects.requireNonNull(activityController
230                         .get()
231                         .getSupportFragmentManager()
232                         .findFragmentById(R.id.main_content));
233         final TextView headerTitle = panelFragment.mLayoutView.findViewById(R.id.header_title);
234         final TextView headerSubtitle = panelFragment.mLayoutView.findViewById(
235                 R.id.header_subtitle);
236 
237         assertThat(headerTitle.getText()).isEqualTo(TITLE);
238         assertThat(headerSubtitle.getText()).isEqualTo(SUBTITLE);
239 
240         mFakePanelContent.setTitle(TITLE2);
241         mFakePanelContent.setSubTitle(SUBTITLE2);
242         verify(mFakePanelContent).registerCallback(mPanelContentCbs.capture());
243         final PanelContentCallback panelContentCallbacks = mPanelContentCbs.getValue();
244         panelContentCallbacks.onHeaderChanged();
245 
246         assertThat(headerTitle.getText()).isEqualTo(TITLE2);
247         assertThat(headerSubtitle.getText()).isEqualTo(SUBTITLE2);
248     }
249 
250     @Test
forceClose_verifyFinish()251     public void forceClose_verifyFinish() {
252         initFakeActivity();
253         verify(mFakePanelContent).registerCallback(mPanelContentCbs.capture());
254         final PanelContentCallback panelContentCallbacks = spy(mPanelContentCbs.getValue());
255         when(((PanelFragment.LocalPanelCallback) panelContentCallbacks).getFragmentActivity())
256                 .thenReturn(mActivity);
257 
258         panelContentCallbacks.forceClose();
259 
260         verify(mActivity).finish();
261     }
262 
263     @Test
onCustomizedButtonStateChanged_isCustomized_showCustomizedTitle()264     public void onCustomizedButtonStateChanged_isCustomized_showCustomizedTitle() {
265         final ActivityController<FakeSettingsPanelActivity> activityController =
266                 Robolectric.buildActivity(FakeSettingsPanelActivity.class);
267         activityController.setup();
268         final PanelFragment panelFragment = (PanelFragment)
269                 Objects.requireNonNull(activityController
270                         .get()
271                         .getSupportFragmentManager()
272                         .findFragmentById(R.id.main_content));
273 
274         final Button seeMoreButton = panelFragment.mLayoutView.findViewById(R.id.see_more);
275 
276         mFakePanelContent.setIsCustomizedButtonUsed(true);
277         mFakePanelContent.setCustomizedButtonTitle("test_title");
278         verify(mFakePanelContent).registerCallback(mPanelContentCbs.capture());
279         final PanelContentCallback panelContentCallbacks = mPanelContentCbs.getValue();
280         panelContentCallbacks.onCustomizedButtonStateChanged();
281 
282         assertThat(seeMoreButton.getVisibility()).isEqualTo(View.VISIBLE);
283         assertThat(seeMoreButton.getText()).isEqualTo("test_title");
284     }
285 
286     @Test
onProgressBarVisibleChanged_isProgressBarVisible_showProgressBar()287     public void onProgressBarVisibleChanged_isProgressBarVisible_showProgressBar() {
288         final ActivityController<FakeSettingsPanelActivity> activityController =
289                 Robolectric.buildActivity(FakeSettingsPanelActivity.class);
290         activityController.setup();
291         final PanelFragment panelFragment = (PanelFragment)
292                 Objects.requireNonNull(activityController
293                         .get()
294                         .getSupportFragmentManager()
295                         .findFragmentById(R.id.main_content));
296 
297         final ProgressBar progressBar = panelFragment.mLayoutView.findViewById(R.id.progress_bar);
298 
299         mFakePanelContent.setIsProgressBarVisible(true);
300         verify(mFakePanelContent).registerCallback(mPanelContentCbs.capture());
301         final PanelContentCallback panelContentCallbacks = mPanelContentCbs.getValue();
302         panelContentCallbacks.onProgressBarVisibleChanged();
303 
304         assertThat(progressBar.getVisibility()).isEqualTo(View.VISIBLE);
305     }
306 }