1/* 2 * Copyright (C) 2015 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 17package android.support.v7.app; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertNotNull; 21import static org.junit.Assert.assertNull; 22import static org.junit.Assert.assertTrue; 23import static org.mockito.Matchers.any; 24import static org.mockito.Mockito.mock; 25import static org.mockito.Mockito.never; 26import static org.mockito.Mockito.reset; 27import static org.mockito.Mockito.verify; 28import static org.mockito.Mockito.verifyNoMoreInteractions; 29import static org.mockito.Mockito.when; 30 31import android.os.Build; 32import android.support.test.annotation.UiThreadTest; 33import android.support.v7.appcompat.test.R; 34import android.support.v7.custom.FitWindowsContentLayout; 35import android.support.v7.testutils.BaseTestActivity; 36import android.support.v7.testutils.TestUtils; 37import android.support.v7.view.ActionMode; 38import android.test.suitebuilder.annotation.SmallTest; 39import android.view.Menu; 40import android.view.View; 41import android.view.WindowInsets; 42 43import org.junit.Test; 44 45import java.util.concurrent.atomic.AtomicBoolean; 46 47public abstract class BaseBasicsTestCase<A extends BaseTestActivity> 48 extends BaseInstrumentationTestCase<A> { 49 50 protected BaseBasicsTestCase(Class<A> activityClass) { 51 super(activityClass); 52 } 53 54 @Test 55 @SmallTest 56 public void testActionBarExists() { 57 assertNotNull("ActionBar is not null", getActivity().getSupportActionBar()); 58 } 59 60 @Test 61 @SmallTest 62 public void testDefaultActionBarTitle() { 63 assertEquals(getActivity().getTitle(), getActivity().getSupportActionBar().getTitle()); 64 } 65 66 @Test 67 @SmallTest 68 public void testSetActionBarTitle() throws Throwable { 69 final String newTitle = "hello"; 70 runTestOnUiThread(new Runnable() { 71 @Override 72 public void run() { 73 getActivity().setTitle(newTitle); 74 assertEquals("New title is set to ActionBar", 75 newTitle, getActivity().getSupportActionBar().getTitle()); 76 } 77 }); 78 } 79 80 @Test 81 @SmallTest 82 public void testMenuInvalidationAfterDestroy() throws Throwable { 83 final A activity = getActivity(); 84 // Reset to make sure that we don't have a menu currently 85 activity.reset(); 86 assertNull(activity.getMenu()); 87 88 // Now destroy the Activity 89 activity.finish(); 90 TestUtils.waitForActivityDestroyed(activity); 91 92 // Now dispatch a menu invalidation and wait for an idle sync 93 activity.supportInvalidateOptionsMenu(); 94 getInstrumentation().waitForIdleSync(); 95 96 // Make sure that we don't have a menu given to use after being destroyed 97 assertNull(activity.getMenu()); 98 } 99 100 @Test 101 @SmallTest 102 public void testFitSystemWindowsReachesContent() { 103 final FitWindowsContentLayout content = 104 (FitWindowsContentLayout) getActivity().findViewById(R.id.test_content); 105 assertNotNull(content); 106 assertTrue(content.getFitsSystemWindowsCalled()); 107 } 108 109 @Test 110 @SmallTest 111 public void testOnApplyWindowInsetsReachesContent() { 112 if (Build.VERSION.SDK_INT < 21) { 113 // OnApplyWindowInsetsListener is only available on API 21+ 114 return; 115 } 116 117 final View content = getActivity().findViewById(R.id.test_content); 118 assertNotNull(content); 119 120 final AtomicBoolean applyWindowInsetsCalled = new AtomicBoolean(); 121 content.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { 122 @Override 123 public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) { 124 applyWindowInsetsCalled.set(true); 125 return windowInsets; 126 } 127 }); 128 assertTrue(applyWindowInsetsCalled.get()); 129 } 130 131 @Test 132 @SmallTest 133 @UiThreadTest 134 public void testSupportActionModeCallbacks() { 135 final A activity = getActivity(); 136 137 // Create a mock action mode callback which returns true from onCreateActionMode 138 final ActionMode.Callback callback = mock(ActionMode.Callback.class); 139 when(callback.onCreateActionMode(any(ActionMode.class), any(Menu.class))).thenReturn(true); 140 141 // Start an action mode 142 final ActionMode actionMode = activity.startSupportActionMode(callback); 143 assertNotNull(actionMode); 144 145 // Now verify that onCreateActionMode and onPrepareActionMode are called once 146 verify(callback).onCreateActionMode(any(ActionMode.class), any(Menu.class)); 147 verify(callback).onPrepareActionMode(any(ActionMode.class), any(Menu.class)); 148 149 // Now finish and verify that onDestroyActionMode is called once, and there are no more 150 // interactions 151 actionMode.finish(); 152 verify(callback).onDestroyActionMode(any(ActionMode.class)); 153 verifyNoMoreInteractions(callback); 154 } 155 156 @Test 157 @SmallTest 158 @UiThreadTest 159 public void testSupportActionModeCallbacksInvalidate() { 160 final A activity = getActivity(); 161 162 // Create a mock action mode callback which returns true from onCreateActionMode 163 final ActionMode.Callback callback = mock(ActionMode.Callback.class); 164 when(callback.onCreateActionMode(any(ActionMode.class), any(Menu.class))).thenReturn(true); 165 166 // Start an action mode 167 final ActionMode actionMode = activity.startSupportActionMode(callback); 168 // Assert that one was created 169 assertNotNull(actionMode); 170 // Reset the mock so that any callback counts from the create are reset 171 reset(callback); 172 173 // Now invalidate the action mode 174 actionMode.invalidate(); 175 176 // Now verify that onCreateActionMode is not called, and onPrepareActionMode is called once 177 verify(callback, never()).onCreateActionMode(any(ActionMode.class), any(Menu.class)); 178 verify(callback).onPrepareActionMode(any(ActionMode.class), any(Menu.class)); 179 } 180 181 @Test 182 @SmallTest 183 @UiThreadTest 184 public void testSupportActionModeCallbacksWithFalseOnCreate() { 185 final A activity = getActivity(); 186 187 // Create a mock action mode callback which returns true from onCreateActionMode 188 final ActionMode.Callback callback = mock(ActionMode.Callback.class); 189 when(callback.onCreateActionMode(any(ActionMode.class), any(Menu.class))).thenReturn(false); 190 191 // Start an action mode 192 final ActionMode actionMode = activity.startSupportActionMode(callback); 193 194 // Now verify that onCreateActionMode is called once 195 verify(callback).onCreateActionMode(any(ActionMode.class), any(Menu.class)); 196 197 // Now verify that onPrepareActionMode is not called (since onCreateActionMode 198 // returns false) 199 verify(callback, never()).onPrepareActionMode(any(ActionMode.class), any(Menu.class)); 200 201 // Assert that an action mode was not created 202 assertNull(actionMode); 203 } 204 205 protected void testSupportActionModeAppCompatCallbacks(final boolean fromWindow) { 206 final A activity = getActivity(); 207 208 // Create a mock action mode callback which returns true from onCreateActionMode 209 final ActionMode.Callback amCallback = mock(ActionMode.Callback.class); 210 when(amCallback.onCreateActionMode(any(ActionMode.class), any(Menu.class))) 211 .thenReturn(true); 212 213 // Create a mock AppCompatCallback, which returns null from 214 // onWindowStartingSupportActionMode, and set it on the Activity 215 final AppCompatCallback apCallback = mock(AppCompatCallback.class); 216 when(apCallback.onWindowStartingSupportActionMode(any(ActionMode.Callback.class))) 217 .thenReturn(null); 218 activity.setAppCompatCallback(apCallback); 219 220 // Start an action mode with the action mode callback 221 final ActionMode actionMode = activity.startSupportActionMode(amCallback); 222 223 if (fromWindow) { 224 // Verify that the callback's onWindowStartingSupportActionMode was called 225 verify(apCallback).onWindowStartingSupportActionMode(any(ActionMode.Callback.class)); 226 } 227 228 // Now assert that an action mode was created 229 assertNotNull(actionMode); 230 231 // Now verify that onSupportActionModeStarted is called once 232 verify(apCallback).onSupportActionModeStarted(any(ActionMode.class)); 233 234 // Now finish and verify that onDestroyActionMode is called once 235 actionMode.finish(); 236 verify(apCallback).onSupportActionModeFinished(any(ActionMode.class)); 237 } 238} 239