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 */ 16 17 package android.support.v4.widget; 18 19 import static android.support.test.espresso.Espresso.onView; 20 import static android.support.test.espresso.matcher.ViewMatchers.withId; 21 import static android.support.v4.widget.SwipeRefreshLayoutActions.setEnabled; 22 import static android.support.v4.widget.SwipeRefreshLayoutActions.setRefreshing; 23 import static android.support.v4.widget.SwipeRefreshLayoutActions.setSize; 24 25 import static org.junit.Assert.assertEquals; 26 import static org.junit.Assert.assertFalse; 27 import static org.junit.Assert.assertTrue; 28 import static org.mockito.Mockito.any; 29 import static org.mockito.Mockito.eq; 30 import static org.mockito.Mockito.mock; 31 import static org.mockito.Mockito.times; 32 import static org.mockito.Mockito.verify; 33 import static org.mockito.Mockito.when; 34 35 import android.support.coreui.test.R; 36 import android.support.test.espresso.action.ViewActions; 37 import android.support.test.filters.LargeTest; 38 import android.support.test.filters.MediumTest; 39 import android.support.test.filters.SmallTest; 40 import android.support.testutils.PollingCheck; 41 import android.support.v4.BaseInstrumentationTestCase; 42 import android.view.View; 43 44 import org.junit.Before; 45 import org.junit.Test; 46 47 import java.util.concurrent.CountDownLatch; 48 import java.util.concurrent.TimeUnit; 49 50 /** 51 * Tests SwipeRefreshLayout widget. 52 */ 53 public class SwipeRefreshLayoutTest 54 extends BaseInstrumentationTestCase<SwipeRefreshLayoutActivity> { 55 private static final long TIMEOUT = 1000; 56 private static final int INVALID_SIZE = 1000; 57 58 private SwipeRefreshLayout mSwipeRefresh; 59 60 public SwipeRefreshLayoutTest() { 61 super(SwipeRefreshLayoutActivity.class); 62 } 63 64 @Before 65 public void setUp() { 66 mSwipeRefresh = (SwipeRefreshLayout) mActivityTestRule.getActivity().findViewById( 67 R.id.swipe_refresh); 68 } 69 70 @Test 71 @MediumTest 72 public void testStartAndStopRefreshing() throws Throwable { 73 SwipeRefreshLayout.OnRefreshListener mockListener = 74 mock(SwipeRefreshLayout.OnRefreshListener.class); 75 mSwipeRefresh.setOnRefreshListener(mockListener); 76 77 assertFalse(mSwipeRefresh.isRefreshing()); 78 for (int i = 0; i < 5; i++) { 79 onView(withId(R.id.swipe_refresh)).perform(setRefreshing()); 80 assertTrue(mSwipeRefresh.isRefreshing()); 81 82 // onView(..).perform(..) does not work when views are animated. 83 // Therefore this is using a posted task to turn off refreshing. 84 mSwipeRefresh.getHandler().post(new Runnable() { 85 @Override 86 public void run() { 87 mSwipeRefresh.setRefreshing(false); 88 } 89 }); 90 91 PollingCheck.waitFor(TIMEOUT, new PollingCheck.PollingCheckCondition() { 92 @Override 93 public boolean canProceed() { 94 return !mSwipeRefresh.isRefreshing(); 95 } 96 }); 97 } 98 verify(mockListener, times(0)).onRefresh(); 99 } 100 101 @Test 102 @MediumTest 103 public void testSwipeDownToRefresh() throws Throwable { 104 assertFalse(mSwipeRefresh.isRefreshing()); 105 106 swipeToRefreshVerifyThenStopRefreshing(true); 107 } 108 109 @Test 110 @SmallTest 111 public void testSetSize() throws Throwable { 112 float density = mSwipeRefresh.getResources().getDisplayMetrics().density; 113 assertEquals((int) (SwipeRefreshLayout.CIRCLE_DIAMETER * density), 114 mSwipeRefresh.getProgressCircleDiameter()); 115 onView(withId(R.id.swipe_refresh)).perform(setSize(SwipeRefreshLayout.LARGE)); 116 assertEquals((int) (SwipeRefreshLayout.CIRCLE_DIAMETER_LARGE * density), 117 mSwipeRefresh.getProgressCircleDiameter()); 118 onView(withId(R.id.swipe_refresh)).perform(setSize(SwipeRefreshLayout.DEFAULT)); 119 assertEquals((int) (SwipeRefreshLayout.CIRCLE_DIAMETER * density), 120 mSwipeRefresh.getProgressCircleDiameter()); 121 onView(withId(R.id.swipe_refresh)).perform(setSize(SwipeRefreshLayout.DEFAULT)); 122 onView(withId(R.id.swipe_refresh)).perform(setSize(INVALID_SIZE)); 123 assertEquals((int) (SwipeRefreshLayout.CIRCLE_DIAMETER * density), 124 mSwipeRefresh.getProgressCircleDiameter()); 125 } 126 127 @Test 128 @SmallTest 129 public void testSetOnChildScrollUpCallback() throws Throwable { 130 SwipeRefreshLayout.OnChildScrollUpCallback mockCallback = 131 mock(SwipeRefreshLayout.OnChildScrollUpCallback.class); 132 when(mockCallback.canChildScrollUp(eq(mSwipeRefresh), any(View.class))) 133 .thenReturn(true) 134 .thenReturn(true) 135 .thenReturn(false) 136 .thenReturn(false); 137 mSwipeRefresh.setOnChildScrollUpCallback(mockCallback); 138 assertTrue(mSwipeRefresh.canChildScrollUp()); 139 assertTrue(mSwipeRefresh.canChildScrollUp()); 140 assertFalse(mSwipeRefresh.canChildScrollUp()); 141 assertFalse(mSwipeRefresh.canChildScrollUp()); 142 } 143 144 @Test 145 @LargeTest 146 public void testSwipeDownToRefreshInitiallyDisabled() throws Throwable { 147 mActivityTestRule.runOnUiThread(new Runnable() { 148 @Override 149 public void run() { 150 mActivityTestRule.getActivity().setContentView( 151 R.layout.swipe_refresh_layout_disabled_activity); 152 } 153 }); 154 mSwipeRefresh = (SwipeRefreshLayout) mActivityTestRule.getActivity().findViewById( 155 R.id.swipe_refresh); 156 157 assertFalse(mSwipeRefresh.isRefreshing()); 158 159 swipeToRefreshVerifyThenStopRefreshing(false); 160 161 onView(withId(R.id.swipe_refresh)).perform(setEnabled(true)); 162 163 swipeToRefreshVerifyThenStopRefreshing(true); 164 } 165 166 private void swipeToRefreshVerifyThenStopRefreshing(boolean expectRefreshing) throws Throwable { 167 final CountDownLatch latch = new CountDownLatch(1); 168 SwipeRefreshLayout.OnRefreshListener listener = new SwipeRefreshLayout.OnRefreshListener() { 169 @Override 170 public void onRefresh() { 171 latch.countDown(); 172 assertTrue(mSwipeRefresh.isRefreshing()); 173 mSwipeRefresh.setRefreshing(false); 174 } 175 }; 176 mSwipeRefresh.setOnRefreshListener(listener); 177 onView(withId(R.id.content)).perform(ViewActions.swipeDown()); 178 if (expectRefreshing) { 179 assertTrue("SwipeRefreshLayout never started refreshing", 180 latch.await(500, TimeUnit.MILLISECONDS)); 181 } else { 182 assertFalse("SwipeRefreshLayout unexpectedly started refreshing", 183 latch.await(500, TimeUnit.MILLISECONDS)); 184 } 185 } 186 } 187