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