GuidedStepFragmentTest.java revision 42e7d6fafcde7bfe261dd7d8d75ee53ca0cd6790
1/* 2 * Copyright (C) 2016 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 */ 16package android.support.v17.leanback.app; 17 18import static org.junit.Assert.assertEquals; 19import static org.junit.Assert.assertFalse; 20import static org.junit.Assert.assertTrue; 21import static org.mockito.Mockito.any; 22import static org.mockito.Mockito.doAnswer; 23import static org.mockito.Mockito.times; 24import static org.mockito.Mockito.verify; 25 26import android.os.Bundle; 27import android.support.test.filters.MediumTest; 28import android.support.test.runner.AndroidJUnit4; 29import android.support.v17.leanback.testutils.PollingCheck; 30import android.support.v17.leanback.widget.GuidedAction; 31import android.view.KeyEvent; 32import android.view.LayoutInflater; 33import android.view.View; 34import android.view.ViewGroup; 35 36import org.junit.Test; 37import org.junit.runner.RunWith; 38import org.mockito.ArgumentCaptor; 39import org.mockito.invocation.InvocationOnMock; 40import org.mockito.stubbing.Answer; 41 42import java.util.ArrayList; 43import java.util.List; 44 45/** 46 * @hide from javadoc 47 */ 48@MediumTest 49@RunWith(AndroidJUnit4.class) 50public class GuidedStepFragmentTest extends GuidedStepFragmentTestBase { 51 52 @Test 53 public void nextAndBack() throws Throwable { 54 GuidedStepTestFragment.Provider first = mockProvider("first"); 55 doAnswer(new Answer<Void>() { 56 public Void answer(InvocationOnMock invocation) { 57 List actions = (List) invocation.getArguments()[0]; 58 actions.add(new GuidedAction.Builder().id(1000).title("OK").build()); 59 return null; 60 } 61 }).when(first).onCreateActions(any(List.class), any(Bundle.class)); 62 doAnswer(new Answer<Void>() { 63 public Void answer(InvocationOnMock invocation) { 64 GuidedAction action = (GuidedAction) invocation.getArguments()[0]; 65 GuidedStepTestFragment.Provider obj = (GuidedStepTestFragment.Provider) 66 invocation.getMock(); 67 if (action.getId() == 1000) { 68 GuidedStepFragment.add(obj.getFragmentManager(), 69 new GuidedStepTestFragment("second")); 70 } 71 return null; 72 } 73 }).when(first).onGuidedActionClicked(any(GuidedAction.class)); 74 75 GuidedStepTestFragment.Provider second = mockProvider("second"); 76 77 GuidedStepFragmentTestActivity activity = launchTestActivity("first"); 78 verify(first, times(1)).onCreate(any(Bundle.class)); 79 verify(first, times(1)).onCreateGuidance(any(Bundle.class)); 80 verify(first, times(1)).onCreateActions(any(List.class), any(Bundle.class)); 81 verify(first, times(1)).onCreateButtonActions(any(List.class), any(Bundle.class)); 82 verify(first, times(1)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 83 any(Bundle.class), any(View.class)); 84 verify(first, times(1)).onViewStateRestored(any(Bundle.class)); 85 verify(first, times(1)).onStart(); 86 verify(first, times(1)).onResume(); 87 88 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 89 verify(first, times(1)).onGuidedActionClicked(any(GuidedAction.class)); 90 91 PollingCheck.waitFor(new EnterTransitionFinish(second)); 92 verify(first, times(1)).onPause(); 93 verify(first, times(1)).onStop(); 94 verify(first, times(1)).onDestroyView(); 95 verify(second, times(1)).onCreate(any(Bundle.class)); 96 verify(second, times(1)).onCreateGuidance(any(Bundle.class)); 97 verify(second, times(1)).onCreateActions(any(List.class), any(Bundle.class)); 98 verify(second, times(1)).onCreateButtonActions(any(List.class), any(Bundle.class)); 99 verify(second, times(1)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 100 any(Bundle.class), any(View.class)); 101 verify(second, times(1)).onViewStateRestored(any(Bundle.class)); 102 verify(second, times(1)).onStart(); 103 verify(second, times(1)).onResume(); 104 105 sendKey(KeyEvent.KEYCODE_BACK); 106 107 PollingCheck.waitFor(new EnterTransitionFinish(first)); 108 verify(second, times(1)).onPause(); 109 verify(second, times(1)).onStop(); 110 verify(second, times(1)).onDestroyView(); 111 verify(second, times(1)).onDestroy(); 112 verify(first, times(1)).onCreateActions(any(List.class), any(Bundle.class)); 113 verify(first, times(2)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 114 any(Bundle.class), any(View.class)); 115 verify(first, times(2)).onViewStateRestored(any(Bundle.class)); 116 verify(first, times(2)).onStart(); 117 verify(first, times(2)).onResume(); 118 119 sendKey(KeyEvent.KEYCODE_BACK); 120 PollingCheck.waitFor(new PollingCheck.ActivityDestroy(activity)); 121 verify(first, times(1)).onDestroy(); 122 assertTrue(activity.isDestroyed()); 123 } 124 125 @Test 126 public void restoreFragments() throws Throwable { 127 GuidedStepTestFragment.Provider first = mockProvider("first"); 128 doAnswer(new Answer<Void>() { 129 public Void answer(InvocationOnMock invocation) { 130 List actions = (List) invocation.getArguments()[0]; 131 actions.add(new GuidedAction.Builder().id(1000).title("OK").build()); 132 actions.add(new GuidedAction.Builder().id(1001).editable(true).title("text") 133 .build()); 134 actions.add(new GuidedAction.Builder().id(1002).editable(true).title("text") 135 .autoSaveRestoreEnabled(false).build()); 136 return null; 137 } 138 }).when(first).onCreateActions(any(List.class), any(Bundle.class)); 139 doAnswer(new Answer<Void>() { 140 public Void answer(InvocationOnMock invocation) { 141 GuidedAction action = (GuidedAction) invocation.getArguments()[0]; 142 GuidedStepTestFragment.Provider obj = (GuidedStepTestFragment.Provider) 143 invocation.getMock(); 144 if (action.getId() == 1000) { 145 GuidedStepFragment.add(obj.getFragmentManager(), 146 new GuidedStepTestFragment("second")); 147 } 148 return null; 149 } 150 }).when(first).onGuidedActionClicked(any(GuidedAction.class)); 151 152 GuidedStepTestFragment.Provider second = mockProvider("second"); 153 154 final GuidedStepFragmentTestActivity activity = launchTestActivity("first"); 155 first.getFragment().findActionById(1001).setTitle("modified text"); 156 first.getFragment().findActionById(1002).setTitle("modified text"); 157 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 158 PollingCheck.waitFor(new EnterTransitionFinish(second)); 159 160 activityTestRule.runOnUiThread(new Runnable() { 161 @Override 162 public void run() { 163 activity.recreate(); 164 } 165 }); 166 PollingCheck.waitFor(new EnterTransitionFinish(second)); 167 verify(first, times(2)).onCreate(any(Bundle.class)); 168 verify(first, times(1)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 169 any(Bundle.class), any(View.class)); 170 verify(first, times(2)).onCreateActions(any(List.class), any(Bundle.class)); 171 verify(first, times(1)).onDestroy(); 172 verify(second, times(2)).onCreate(any(Bundle.class)); 173 verify(second, times(2)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 174 any(Bundle.class), any(View.class)); 175 verify(second, times(1)).onDestroy(); 176 assertEquals("modified text", first.getFragment().findActionById(1001).getTitle()); 177 assertEquals("text", first.getFragment().findActionById(1002).getTitle()); 178 179 sendKey(KeyEvent.KEYCODE_BACK); 180 PollingCheck.waitFor(new EnterTransitionFinish(first)); 181 verify(second, times(2)).onPause(); 182 verify(second, times(2)).onStop(); 183 verify(second, times(2)).onDestroyView(); 184 verify(second, times(2)).onDestroy(); 185 verify(first, times(2)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 186 any(Bundle.class), any(View.class)); 187 } 188 189 190 @Test 191 public void finishGuidedStepFragment_finishes_activity() throws Throwable { 192 GuidedStepTestFragment.Provider first = mockProvider("first"); 193 doAnswer(new Answer<Void>() { 194 public Void answer(InvocationOnMock invocation) { 195 List actions = (List) invocation.getArguments()[0]; 196 actions.add(new GuidedAction.Builder().id(1001).title("Finish activity").build()); 197 return null; 198 } 199 }).when(first).onCreateActions(any(List.class), any(Bundle.class)); 200 doAnswer(new Answer<Void>() { 201 public Void answer(InvocationOnMock invocation) { 202 GuidedAction action = (GuidedAction) invocation.getArguments()[0]; 203 GuidedStepTestFragment.Provider obj = (GuidedStepTestFragment.Provider) 204 invocation.getMock(); 205 if (action.getId() == 1001) { 206 obj.getFragment().finishGuidedStepFragments(); 207 } 208 return null; 209 } 210 }).when(first).onGuidedActionClicked(any(GuidedAction.class)); 211 212 final GuidedStepFragmentTestActivity activity = launchTestActivity("first"); 213 214 View viewFinish = first.getFragment().getActionItemView(0); 215 assertTrue(viewFinish.hasFocus()); 216 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 217 PollingCheck.waitFor(new PollingCheck.ActivityDestroy(activity)); 218 verify(first, times(1)).onDestroy(); 219 } 220 221 @Test 222 public void finishGuidedStepFragment_finishes_fragments() throws Throwable { 223 GuidedStepTestFragment.Provider first = mockProvider("first"); 224 doAnswer(new Answer<Void>() { 225 public Void answer(InvocationOnMock invocation) { 226 List actions = (List) invocation.getArguments()[0]; 227 actions.add(new GuidedAction.Builder().id(1001).title("Finish fragments").build()); 228 return null; 229 } 230 }).when(first).onCreateActions(any(List.class), any(Bundle.class)); 231 doAnswer(new Answer<Void>() { 232 public Void answer(InvocationOnMock invocation) { 233 GuidedAction action = (GuidedAction) invocation.getArguments()[0]; 234 GuidedStepTestFragment.Provider obj = (GuidedStepTestFragment.Provider) 235 invocation.getMock(); 236 if (action.getId() == 1001) { 237 obj.getFragment().finishGuidedStepFragments(); 238 } 239 return null; 240 } 241 }).when(first).onGuidedActionClicked(any(GuidedAction.class)); 242 243 final GuidedStepFragmentTestActivity activity = launchTestActivity("first", 244 false /*asRoot*/); 245 246 View viewFinish = first.getFragment().getActionItemView(0); 247 assertTrue(viewFinish.hasFocus()); 248 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 249 250 // fragment should be destroyed, activity should not destroyed 251 waitOnDestroy(first, 1); 252 assertFalse(activity.isDestroyed()); 253 } 254 255 @Test 256 public void subActions() throws Throwable { 257 final boolean[] expandSubActionInOnCreateView = new boolean[] {false}; 258 GuidedStepTestFragment.Provider first = mockProvider("first"); 259 doAnswer(new Answer<Void>() { 260 public Void answer(InvocationOnMock invocation) { 261 GuidedStepTestFragment.Provider obj = (GuidedStepTestFragment.Provider) 262 invocation.getMock(); 263 if (expandSubActionInOnCreateView[0]) { 264 obj.getFragment().expandAction(obj.getFragment().findActionById(1000), false); 265 } 266 return null; 267 } 268 }).when(first).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 269 any(Bundle.class), any(View.class)); 270 doAnswer(new Answer<Void>() { 271 public Void answer(InvocationOnMock invocation) { 272 List actions = (List) invocation.getArguments()[0]; 273 List<GuidedAction> subActions = new ArrayList<GuidedAction>(); 274 subActions.add(new GuidedAction.Builder().id(2000).title("item1").build()); 275 subActions.add(new GuidedAction.Builder().id(2001).title("item2").build()); 276 actions.add(new GuidedAction.Builder().id(1000).subActions(subActions) 277 .title("list").build()); 278 return null; 279 } 280 }).when(first).onCreateActions(any(List.class), any(Bundle.class)); 281 doAnswer(new Answer<Boolean>() { 282 public Boolean answer(InvocationOnMock invocation) { 283 GuidedStepTestFragment.Provider obj = (GuidedStepTestFragment.Provider) 284 invocation.getMock(); 285 GuidedAction action = (GuidedAction) invocation.getArguments()[0]; 286 if (action.getId() == 2000) { 287 return true; 288 } else if (action.getId() == 2001) { 289 GuidedStepFragment.add(obj.getFragmentManager(), 290 new GuidedStepTestFragment("second")); 291 return false; 292 } 293 return false; 294 } 295 }).when(first).onSubGuidedActionClicked(any(GuidedAction.class)); 296 297 GuidedStepTestFragment.Provider second = mockProvider("second"); 298 299 final GuidedStepFragmentTestActivity activity = launchTestActivity("first"); 300 301 // after clicked, it sub actions list should expand 302 View viewForList = first.getFragment().getActionItemView(0); 303 assertTrue(viewForList.hasFocus()); 304 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 305 PollingCheck.waitFor(new ExpandTransitionFinish(first)); 306 assertFalse(viewForList.hasFocus()); 307 308 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 309 ArgumentCaptor<GuidedAction> actionCapture = ArgumentCaptor.forClass(GuidedAction.class); 310 verify(first, times(1)).onSubGuidedActionClicked(actionCapture.capture()); 311 assertEquals(2000, actionCapture.getValue().getId()); 312 // after clicked a sub action, it sub actions list should close 313 PollingCheck.waitFor(new ExpandTransitionFinish(first)); 314 assertTrue(viewForList.hasFocus()); 315 316 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 317 PollingCheck.waitFor(new ExpandTransitionFinish(first)); 318 319 assertFalse(viewForList.hasFocus()); 320 sendKey(KeyEvent.KEYCODE_DPAD_DOWN); 321 sendKey(KeyEvent.KEYCODE_DPAD_CENTER); 322 ArgumentCaptor<GuidedAction> actionCapture2 = ArgumentCaptor.forClass(GuidedAction.class); 323 verify(first, times(2)).onSubGuidedActionClicked(actionCapture2.capture()); 324 assertEquals(2001, actionCapture2.getValue().getId()); 325 326 PollingCheck.waitFor(new EnterTransitionFinish(second)); 327 verify(second, times(1)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 328 any(Bundle.class), any(View.class)); 329 330 // test expand sub action when return to first fragment 331 expandSubActionInOnCreateView[0] = true; 332 sendKey(KeyEvent.KEYCODE_BACK); 333 PollingCheck.waitFor(new EnterTransitionFinish(first)); 334 verify(first, times(2)).onCreateView(any(LayoutInflater.class), any(ViewGroup.class), 335 any(Bundle.class), any(View.class)); 336 assertTrue(first.getFragment().isExpanded()); 337 338 sendKey(KeyEvent.KEYCODE_BACK); 339 PollingCheck.waitFor(new ExpandTransitionFinish(first)); 340 assertFalse(first.getFragment().isExpanded()); 341 342 sendKey(KeyEvent.KEYCODE_BACK); 343 PollingCheck.waitFor(new PollingCheck.ActivityDestroy(activity)); 344 verify(first, times(1)).onDestroy(); 345 } 346} 347