1/* 2 * Copyright 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 17package androidx.swiperefreshlayout.widget; 18 19import static android.support.test.espresso.Espresso.onView; 20import static android.support.test.espresso.matcher.ViewMatchers.withId; 21 22import static org.junit.Assert.assertEquals; 23import static org.junit.Assert.assertFalse; 24import static org.junit.Assert.assertTrue; 25import static org.mockito.Mockito.any; 26import static org.mockito.Mockito.eq; 27import static org.mockito.Mockito.mock; 28import static org.mockito.Mockito.times; 29import static org.mockito.Mockito.verify; 30import static org.mockito.Mockito.when; 31 32import android.support.test.espresso.action.ViewActions; 33import android.support.test.filters.LargeTest; 34import android.support.test.filters.MediumTest; 35import android.support.test.filters.SmallTest; 36import android.support.test.rule.ActivityTestRule; 37import android.support.test.runner.AndroidJUnit4; 38import android.view.View; 39 40import androidx.swiperefreshlayout.test.R; 41import androidx.testutils.PollingCheck; 42 43import org.junit.Before; 44import org.junit.Rule; 45import org.junit.Test; 46import org.junit.runner.RunWith; 47 48import java.util.concurrent.CountDownLatch; 49import java.util.concurrent.TimeUnit; 50 51/** 52 * Tests SwipeRefreshLayout widget. 53 */ 54@RunWith(AndroidJUnit4.class) 55public class SwipeRefreshLayoutTest { 56 @Rule 57 public final ActivityTestRule<SwipeRefreshLayoutActivity> mActivityTestRule = 58 new ActivityTestRule<>(SwipeRefreshLayoutActivity.class); 59 60 private static final long TIMEOUT = 1000; 61 private static final int INVALID_SIZE = 1000; 62 63 private SwipeRefreshLayout mSwipeRefresh; 64 65 @Before 66 public void setUp() { 67 mSwipeRefresh = mActivityTestRule.getActivity().findViewById(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(SwipeRefreshLayoutActions.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(SwipeRefreshLayoutActions.setSize(SwipeRefreshLayout.LARGE)); 116 assertEquals((int) (SwipeRefreshLayout.CIRCLE_DIAMETER_LARGE * density), 117 mSwipeRefresh.getProgressCircleDiameter()); 118 onView(withId(R.id.swipe_refresh)).perform(SwipeRefreshLayoutActions.setSize(SwipeRefreshLayout.DEFAULT)); 119 assertEquals((int) (SwipeRefreshLayout.CIRCLE_DIAMETER * density), 120 mSwipeRefresh.getProgressCircleDiameter()); 121 onView(withId(R.id.swipe_refresh)).perform(SwipeRefreshLayoutActions.setSize(SwipeRefreshLayout.DEFAULT)); 122 onView(withId(R.id.swipe_refresh)).perform(SwipeRefreshLayoutActions.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(SwipeRefreshLayoutActions.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