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