1 // CHECKSTYLE:OFF Generated code 2 /* This file is auto-generated from GuidedStepSupportFragmentTest.java. DO NOT MODIFY. */ 3 4 /* 5 * Copyright (C) 2016 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 package androidx.leanback.app; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertFalse; 23 import static org.junit.Assert.assertTrue; 24 import static org.mockito.ArgumentMatchers.nullable; 25 import static org.mockito.Mockito.any; 26 import static org.mockito.Mockito.doAnswer; 27 import static org.mockito.Mockito.timeout; 28 import static org.mockito.Mockito.times; 29 import static org.mockito.Mockito.verify; 30 31 import android.os.Bundle; 32 import android.support.test.InstrumentationRegistry; 33 import android.support.test.filters.LargeTest; 34 import android.support.test.runner.AndroidJUnit4; 35 import android.view.KeyEvent; 36 import android.view.LayoutInflater; 37 import android.view.View; 38 import android.view.ViewGroup; 39 40 import androidx.leanback.testutils.PollingCheck; 41 import androidx.leanback.widget.GuidedAction; 42 import androidx.leanback.widget.GuidedActionsStylist; 43 import androidx.leanback.widget.VerticalGridView; 44 import androidx.recyclerview.widget.DefaultItemAnimator; 45 import androidx.recyclerview.widget.RecyclerView; 46 47 import org.junit.Test; 48 import org.junit.runner.RunWith; 49 import org.mockito.ArgumentCaptor; 50 import org.mockito.invocation.InvocationOnMock; 51 import org.mockito.stubbing.Answer; 52 53 import java.util.ArrayList; 54 import java.util.List; 55 56 @LargeTest 57 @RunWith(AndroidJUnit4.class) 58 public class GuidedStepFragmentTest extends GuidedStepFragmentTestBase { 59 60 private static final int ON_DESTROY_TIMEOUT = 5000; 61 62 @Test 63 public void nextAndBack() throws Throwable { 64 final String firstFragmentName = generateMethodTestName("first"); 65 final String secondFragmentName = generateMethodTestName("second"); 66 GuidedStepTestFragment.Provider first = mockProvider(firstFragmentName); 67 doAnswer(new Answer<Void>() { 68 @Override 69 public Void answer(InvocationOnMock invocation) { 70 List actions = (List) invocation.getArguments()[0]; 71 actions.add(new GuidedAction.Builder().id(1000).title("OK").build()); 72 return null; 73 } 74 }).when(first).onCreateActions(any(List.class), nullable(Bundle.class)); 75 doAnswer(new Answer<Void>() { 76 @Override 77 public Void answer(InvocationOnMock invocation) { 78 GuidedAction action = (GuidedAction) invocation.getArguments()[0]; 79 GuidedStepTestFragment.Provider obj = (GuidedStepTestFragment.Provider) 80 invocation.getMock(); 81 if (action.getId() == 1000) { 82 GuidedStepFragment.add(obj.getFragmentManager(), 83 new GuidedStepTestFragment(secondFragmentName)); 84 } 85 return null; 86 } 87 }).when(first).onGuidedActionClicked(any(GuidedAction.class)); 88 89 GuidedStepTestFragment.Provider second = mockProvider(secondFragmentName); 90 91 GuidedStepFragmentTestActivity activity = launchTestActivity(firstFragmentName); 92 verify(first, times(1)).onCreate(nullable(Bundle.class)); 93 verify(first, times(1)).onCreateGuidance(nullable(Bundle.class)); 94 verify(first, times(1)).onCreateActions(any(List.class), nullable(Bundle.class)); 95 verify(first, times(1)).onCreateButtonActions(any(List.class), nullable(Bundle.class)); 96 verify(first, times(1)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 97 nullable(Bundle.class), any(View.class)); 98 verify(first, times(1)).onViewStateRestored(nullable(Bundle.class)); 99 verify(first, times(1)).onStart(); 100 verify(first, times(1)).onResume(); 101 102 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 103 verify(first, times(1)).onGuidedActionClicked(any(GuidedAction.class)); 104 105 PollingCheck.waitFor(new EnterTransitionFinish(second)); 106 verify(first, times(1)).onPause(); 107 verify(first, times(1)).onStop(); 108 verify(first, times(1)).onDestroyView(); 109 verify(second, times(1)).onCreate(nullable(Bundle.class)); 110 verify(second, times(1)).onCreateGuidance(nullable(Bundle.class)); 111 verify(second, times(1)).onCreateActions(any(List.class), nullable(Bundle.class)); 112 verify(second, times(1)).onCreateButtonActions(any(List.class), nullable(Bundle.class)); 113 verify(second, times(1)).onCreateView(any(LayoutInflater.class), nullable(ViewGroup.class), 114 nullable(Bundle.class), any(View.class)); 115 verify(second, times(1)).onViewStateRestored(nullable(Bundle.class)); 116 verify(second, times(1)).onStart(); 117 verify(second, times(1)).onResume(); 118 119 sendKey(KeyEvent.KEYCODE_BACK); 120 121 PollingCheck.waitFor(new EnterTransitionFinish(first)); 122 verify(second, times(1)).onPause(); 123 verify(second, times(1)).onStop(); 124 verify(second, times(1)).onDestroyView(); 125 verify(second, times(1)).onDestroy(); 126 verify(first, times(1)).onCreateActions(any(List.class), nullable(Bundle.class)); 127 verify(first, times(2)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 128 nullable(Bundle.class), any(View.class)); 129 verify(first, times(2)).onViewStateRestored(nullable(Bundle.class)); 130 verify(first, times(2)).onStart(); 131 verify(first, times(2)).onResume(); 132 133 sendKey(KeyEvent.KEYCODE_BACK); 134 PollingCheck.waitFor(new PollingCheck.ActivityDestroy(activity)); 135 verify(first, timeout(ON_DESTROY_TIMEOUT).times(1)).onDestroy(); 136 assertTrue(activity.isDestroyed()); 137 } 138 139 @Test 140 public void restoreFragments() throws Throwable { 141 final String firstFragmentName = generateMethodTestName("first"); 142 final String secondFragmentName = generateMethodTestName("second"); 143 GuidedStepTestFragment.Provider first = mockProvider(firstFragmentName); 144 doAnswer(new Answer<Void>() { 145 @Override 146 public Void answer(InvocationOnMock invocation) { 147 List actions = (List) invocation.getArguments()[0]; 148 actions.add(new GuidedAction.Builder().id(1000).title("OK").build()); 149 actions.add(new GuidedAction.Builder().id(1001).editable(true).title("text") 150 .build()); 151 actions.add(new GuidedAction.Builder().id(1002).editable(true).title("text") 152 .autoSaveRestoreEnabled(false).build()); 153 return null; 154 } 155 }).when(first).onCreateActions(any(List.class), nullable(Bundle.class)); 156 doAnswer(new Answer<Void>() { 157 @Override 158 public Void answer(InvocationOnMock invocation) { 159 GuidedAction action = (GuidedAction) invocation.getArguments()[0]; 160 GuidedStepTestFragment.Provider obj = (GuidedStepTestFragment.Provider) 161 invocation.getMock(); 162 if (action.getId() == 1000) { 163 GuidedStepFragment.add(obj.getFragmentManager(), 164 new GuidedStepTestFragment(secondFragmentName)); 165 } 166 return null; 167 } 168 }).when(first).onGuidedActionClicked(any(GuidedAction.class)); 169 170 GuidedStepTestFragment.Provider second = mockProvider(secondFragmentName); 171 172 final GuidedStepFragmentTestActivity activity = launchTestActivity(firstFragmentName); 173 first.getFragment().findActionById(1001).setTitle("modified text"); 174 first.getFragment().findActionById(1002).setTitle("modified text"); 175 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 176 PollingCheck.waitFor(new EnterTransitionFinish(second)); 177 178 activityTestRule.runOnUiThread(new Runnable() { 179 @Override 180 public void run() { 181 activity.recreate(); 182 } 183 }); 184 PollingCheck.waitFor(new EnterTransitionFinish(second)); 185 verify(first, times(1)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 186 nullable(Bundle.class), any(View.class)); 187 verify(first, times(1)).onDestroy(); 188 verify(second, times(2)).onCreate(nullable(Bundle.class)); 189 verify(second, times(2)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 190 nullable(Bundle.class), any(View.class)); 191 verify(second, times(1)).onDestroy(); 192 193 sendKey(KeyEvent.KEYCODE_BACK); 194 PollingCheck.waitFor(new EnterTransitionFinish(first)); 195 verify(second, times(2)).onPause(); 196 verify(second, times(2)).onStop(); 197 verify(second, times(2)).onDestroyView(); 198 verify(second, times(2)).onDestroy(); 199 assertEquals("modified text", first.getFragment().findActionById(1001).getTitle()); 200 assertEquals("text", first.getFragment().findActionById(1002).getTitle()); 201 verify(first, times(2)).onCreate(nullable(Bundle.class)); 202 verify(first, times(2)).onCreateActions(any(List.class), nullable(Bundle.class)); 203 verify(first, times(2)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 204 nullable(Bundle.class), any(View.class)); 205 } 206 207 208 @Test 209 public void finishGuidedStepFragment_finishes_activity() throws Throwable { 210 final String firstFragmentName = generateMethodTestName("first"); 211 GuidedStepTestFragment.Provider first = mockProvider(firstFragmentName); 212 doAnswer(new Answer<Void>() { 213 @Override 214 public Void answer(InvocationOnMock invocation) { 215 List actions = (List) invocation.getArguments()[0]; 216 actions.add(new GuidedAction.Builder().id(1001).title("Finish activity").build()); 217 return null; 218 } 219 }).when(first).onCreateActions(any(List.class), nullable(Bundle.class)); 220 doAnswer(new Answer<Void>() { 221 @Override 222 public Void answer(InvocationOnMock invocation) { 223 GuidedAction action = (GuidedAction) invocation.getArguments()[0]; 224 GuidedStepTestFragment.Provider obj = (GuidedStepTestFragment.Provider) 225 invocation.getMock(); 226 if (action.getId() == 1001) { 227 obj.getFragment().finishGuidedStepFragments(); 228 } 229 return null; 230 } 231 }).when(first).onGuidedActionClicked(any(GuidedAction.class)); 232 233 final GuidedStepFragmentTestActivity activity = launchTestActivity(firstFragmentName); 234 235 View viewFinish = first.getFragment().getActionItemView(0); 236 assertTrue(viewFinish.hasFocus()); 237 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 238 PollingCheck.waitFor(new PollingCheck.ActivityDestroy(activity)); 239 verify(first, timeout(ON_DESTROY_TIMEOUT).times(1)).onDestroy(); 240 } 241 242 @Test 243 public void finishGuidedStepFragment_finishes_fragments() throws Throwable { 244 final String firstFragmentName = generateMethodTestName("first"); 245 GuidedStepTestFragment.Provider first = mockProvider(firstFragmentName); 246 doAnswer(new Answer<Void>() { 247 @Override 248 public Void answer(InvocationOnMock invocation) { 249 List actions = (List) invocation.getArguments()[0]; 250 actions.add(new GuidedAction.Builder().id(1001).title("Finish fragments").build()); 251 return null; 252 } 253 }).when(first).onCreateActions(any(List.class), nullable(Bundle.class)); 254 doAnswer(new Answer<Void>() { 255 @Override 256 public Void answer(InvocationOnMock invocation) { 257 GuidedAction action = (GuidedAction) invocation.getArguments()[0]; 258 GuidedStepTestFragment.Provider obj = (GuidedStepTestFragment.Provider) 259 invocation.getMock(); 260 if (action.getId() == 1001) { 261 obj.getFragment().finishGuidedStepFragments(); 262 } 263 return null; 264 } 265 }).when(first).onGuidedActionClicked(any(GuidedAction.class)); 266 267 final GuidedStepFragmentTestActivity activity = launchTestActivity(firstFragmentName, 268 false /*asRoot*/); 269 270 View viewFinish = first.getFragment().getActionItemView(0); 271 assertTrue(viewFinish.hasFocus()); 272 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 273 274 // fragment should be destroyed, activity should not destroyed 275 waitOnDestroy(first, 1); 276 assertFalse(activity.isDestroyed()); 277 } 278 279 @Test 280 public void subActions() throws Throwable { 281 final String firstFragmentName = generateMethodTestName("first"); 282 final String secondFragmentName = generateMethodTestName("second"); 283 final boolean[] expandSubActionInOnCreateView = new boolean[] {false}; 284 GuidedStepTestFragment.Provider first = mockProvider(firstFragmentName); 285 doAnswer(new Answer<Void>() { 286 @Override 287 public Void answer(InvocationOnMock invocation) { 288 GuidedStepTestFragment.Provider obj = (GuidedStepTestFragment.Provider) 289 invocation.getMock(); 290 if (expandSubActionInOnCreateView[0]) { 291 obj.getFragment().expandAction(obj.getFragment().findActionById(1000), false); 292 } 293 return null; 294 } 295 }).when(first).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 296 nullable(Bundle.class), any(View.class)); 297 doAnswer(new Answer<Void>() { 298 @Override 299 public Void answer(InvocationOnMock invocation) { 300 List actions = (List) invocation.getArguments()[0]; 301 List<GuidedAction> subActions = new ArrayList<GuidedAction>(); 302 subActions.add(new GuidedAction.Builder().id(2000).title("item1").build()); 303 subActions.add(new GuidedAction.Builder().id(2001).title("item2").build()); 304 actions.add(new GuidedAction.Builder().id(1000).subActions(subActions) 305 .title("list").build()); 306 return null; 307 } 308 }).when(first).onCreateActions(any(List.class), nullable(Bundle.class)); 309 doAnswer(new Answer<Boolean>() { 310 @Override 311 public Boolean answer(InvocationOnMock invocation) { 312 GuidedStepTestFragment.Provider obj = (GuidedStepTestFragment.Provider) 313 invocation.getMock(); 314 GuidedAction action = (GuidedAction) invocation.getArguments()[0]; 315 if (action.getId() == 2000) { 316 return true; 317 } else if (action.getId() == 2001) { 318 GuidedStepFragment.add(obj.getFragmentManager(), 319 new GuidedStepTestFragment(secondFragmentName)); 320 return false; 321 } 322 return false; 323 } 324 }).when(first).onSubGuidedActionClicked(any(GuidedAction.class)); 325 326 GuidedStepTestFragment.Provider second = mockProvider(secondFragmentName); 327 328 final GuidedStepFragmentTestActivity activity = launchTestActivity(firstFragmentName); 329 330 // after clicked, it sub actions list should expand 331 View viewForList = first.getFragment().getActionItemView(0); 332 assertTrue(viewForList.hasFocus()); 333 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 334 PollingCheck.waitFor(new ExpandTransitionFinish(first)); 335 assertFalse(viewForList.hasFocus()); 336 337 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 338 ArgumentCaptor<GuidedAction> actionCapture = ArgumentCaptor.forClass(GuidedAction.class); 339 verify(first, times(1)).onSubGuidedActionClicked(actionCapture.capture()); 340 assertEquals(2000, actionCapture.getValue().getId()); 341 // after clicked a sub action, it sub actions list should close 342 PollingCheck.waitFor(new ExpandTransitionFinish(first)); 343 assertTrue(viewForList.hasFocus()); 344 345 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 346 PollingCheck.waitFor(new ExpandTransitionFinish(first)); 347 348 assertFalse(viewForList.hasFocus()); 349 sendKey(KeyEvent.KEYCODE_DPAD_DOWN); 350 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 351 ArgumentCaptor<GuidedAction> actionCapture2 = ArgumentCaptor.forClass(GuidedAction.class); 352 verify(first, times(2)).onSubGuidedActionClicked(actionCapture2.capture()); 353 assertEquals(2001, actionCapture2.getValue().getId()); 354 355 PollingCheck.waitFor(new EnterTransitionFinish(second)); 356 verify(second, times(1)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 357 nullable(Bundle.class), any(View.class)); 358 359 // test expand sub action when return to first fragment 360 expandSubActionInOnCreateView[0] = true; 361 sendKey(KeyEvent.KEYCODE_BACK); 362 PollingCheck.waitFor(new EnterTransitionFinish(first)); 363 verify(first, times(2)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 364 nullable(Bundle.class), any(View.class)); 365 assertTrue(first.getFragment().isExpanded()); 366 367 sendKey(KeyEvent.KEYCODE_BACK); 368 PollingCheck.waitFor(new ExpandTransitionFinish(first)); 369 assertFalse(first.getFragment().isExpanded()); 370 371 sendKey(KeyEvent.KEYCODE_BACK); 372 PollingCheck.waitFor(new PollingCheck.ActivityDestroy(activity)); 373 verify(first, timeout(ON_DESTROY_TIMEOUT).times(1)).onDestroy(); 374 } 375 376 @Test 377 public void setActionsWhenSubActionsExpanded() throws Throwable { 378 final String firstFragmentName = generateMethodTestName("first"); 379 GuidedStepTestFragment.Provider first = mockProvider(firstFragmentName); 380 doAnswer(new Answer<Void>() { 381 @Override 382 public Void answer(InvocationOnMock invocation) { 383 List actions = (List) invocation.getArguments()[0]; 384 List<GuidedAction> subActions = new ArrayList<GuidedAction>(); 385 subActions.add(new GuidedAction.Builder().id(2000).title("item1").build()); 386 actions.add(new GuidedAction.Builder().id(1000).subActions(subActions) 387 .title("list").build()); 388 return null; 389 } 390 }).when(first).onCreateActions(any(List.class), nullable(Bundle.class)); 391 doAnswer(new Answer<Boolean>() { 392 @Override 393 public Boolean answer(InvocationOnMock invocation) { 394 GuidedStepTestFragment.Provider obj = (GuidedStepTestFragment.Provider) 395 invocation.getMock(); 396 GuidedAction action = (GuidedAction) invocation.getArguments()[0]; 397 if (action.getId() == 2000) { 398 List<GuidedAction> newActions = new ArrayList<GuidedAction>(); 399 newActions.add(new GuidedAction.Builder().id(1001).title("item2").build()); 400 obj.getFragment().setActions(newActions); 401 return false; 402 } 403 return false; 404 } 405 }).when(first).onSubGuidedActionClicked(any(GuidedAction.class)); 406 407 final GuidedStepFragmentTestActivity activity = launchTestActivity(firstFragmentName); 408 409 // after clicked, it sub actions list should expand 410 View firstView = first.getFragment().getActionItemView(0); 411 assertTrue(firstView.hasFocus()); 412 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 413 PollingCheck.waitFor(new ExpandTransitionFinish(first)); 414 assertFalse(firstView.hasFocus()); 415 416 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 417 ArgumentCaptor<GuidedAction> actionCapture = ArgumentCaptor.forClass(GuidedAction.class); 418 verify(first, times(1)).onSubGuidedActionClicked(actionCapture.capture()); 419 // after clicked a sub action, whole action list is replaced. 420 PollingCheck.waitFor(new ExpandTransitionFinish(first)); 421 assertFalse(first.getFragment().isExpanded()); 422 View newFirstView = first.getFragment().getActionItemView(0); 423 assertTrue(newFirstView.hasFocus()); 424 assertTrue(newFirstView.getVisibility() == View.VISIBLE); 425 GuidedActionsStylist.ViewHolder vh = (GuidedActionsStylist.ViewHolder) first.getFragment() 426 .getGuidedActionsStylist().getActionsGridView().getChildViewHolder(newFirstView); 427 assertEquals(1001, vh.getAction().getId()); 428 429 } 430 431 @Test 432 public void buttonActionsRtl() throws Throwable { 433 final String firstFragmentName = generateMethodTestName("first"); 434 GuidedStepTestFragment.Provider first = mockProvider(firstFragmentName); 435 doAnswer(new Answer<Void>() { 436 @Override 437 public Void answer(InvocationOnMock invocation) { 438 List actions = (List) invocation.getArguments()[0]; 439 actions.add(new GuidedAction.Builder().id(1000).title("action").build()); 440 return null; 441 } 442 }).when(first).onCreateActions(any(List.class), nullable(Bundle.class)); 443 doAnswer(new Answer<Void>() { 444 @Override 445 public Void answer(InvocationOnMock invocation) { 446 List actions = (List) invocation.getArguments()[0]; 447 actions.add(new GuidedAction.Builder().id(1001).title("button action").build()); 448 return null; 449 } 450 }).when(first).onCreateButtonActions(any(List.class), nullable(Bundle.class)); 451 452 final GuidedStepFragmentTestActivity activity = launchTestActivity(firstFragmentName, 453 true, View.LAYOUT_DIRECTION_RTL); 454 455 assertEquals(View.LAYOUT_DIRECTION_RTL, first.getFragment().getView().getLayoutDirection()); 456 View firstView = first.getFragment().getActionItemView(0); 457 assertTrue(firstView.hasFocus()); 458 } 459 460 @Test 461 public void recyclerViewDiffTest() throws Throwable { 462 final String firstFragmentName = generateMethodTestName("first"); 463 final GuidedStepTestFragment.Provider first = mockProvider(firstFragmentName); 464 doAnswer(new Answer<Void>() { 465 @Override 466 public Void answer(InvocationOnMock invocation) { 467 List actions = (List) invocation.getArguments()[0]; 468 actions.add(new GuidedAction.Builder().id(1000).title("action1").build()); 469 actions.add(new GuidedAction.Builder().id(1001).title("action2").build()); 470 return null; 471 } 472 }).when(first).onCreateActions(any(List.class), nullable(Bundle.class)); 473 474 launchTestActivity(firstFragmentName, true); 475 476 final ArrayList<RecyclerView.ViewHolder> changeList = new ArrayList(); 477 VerticalGridView rv = first.getFragment().mActionsStylist.getActionsGridView(); 478 rv.setItemAnimator(new DefaultItemAnimator() { 479 @Override 480 public void onChangeStarting(RecyclerView.ViewHolder item, boolean oldItem) { 481 if (!oldItem) { 482 changeList.add(item); 483 } 484 super.onChangeStarting(item, oldItem); 485 } 486 }); 487 488 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { 489 @Override 490 public void run() { 491 List actions = new ArrayList(); 492 actions.add(new GuidedAction.Builder().id(1001).title("action2x").build()); 493 actions.add(new GuidedAction.Builder().id(1000).title("action1x").build()); 494 first.getFragment().setActions(actions); 495 } 496 }); 497 498 // should causes two change animation. 499 PollingCheck.waitFor(new PollingCheck.PollingCheckCondition() { 500 @Override 501 public boolean canProceed() { 502 return changeList.size() == 2; 503 } 504 }); 505 } 506 } 507