10ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam/* 20ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam * Copyright (C) 2017 The Android Open Source Project 30ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam * 40ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam * Licensed under the Apache License, Version 2.0 (the "License"); 50ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam * you may not use this file except in compliance with the License. 60ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam * You may obtain a copy of the License at 70ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam * 80ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam * http://www.apache.org/licenses/LICENSE-2.0 90ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam * 100ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam * Unless required by applicable law or agreed to in writing, software 110ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam * distributed under the License is distributed on an "AS IS" BASIS, 120ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam * See the License for the specific language governing permissions and 140ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam * limitations under the License. 150ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam */ 160ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 170ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lampackage com.android.setupwizardlib.template; 180ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 190ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport static org.mockito.Matchers.anyInt; 200ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport static org.mockito.Matchers.eq; 210ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport static org.mockito.Mockito.doNothing; 220ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport static org.mockito.Mockito.doReturn; 230ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport static org.mockito.Mockito.spy; 240ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport static org.mockito.Mockito.verify; 250ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport static org.robolectric.RuntimeEnvironment.application; 260ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 270ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport android.content.Context; 280ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport android.view.View; 290ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport android.view.ViewGroup; 300ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport android.widget.AbsListView.OnScrollListener; 310ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport android.widget.BaseAdapter; 320ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport android.widget.ListView; 330ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 340ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport com.android.setupwizardlib.robolectric.SuwLibRobolectricTestRunner; 350ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 360ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport org.junit.Before; 370ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport org.junit.Test; 380ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport org.junit.runner.RunWith; 390ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport org.mockito.ArgumentCaptor; 400ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport org.mockito.Mock; 410ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport org.mockito.MockitoAnnotations; 420ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lamimport org.robolectric.annotation.Config; 430ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 4466815fe66392bcbb12e2fc93bbf326a5c2d8782fMaurice Lam@Config(sdk = { Config.OLDEST_SDK, Config.NEWEST_SDK }) 450ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam@RunWith(SuwLibRobolectricTestRunner.class) 460ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lampublic class ListViewScrollHandlingDelegateTest { 470ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 480ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam @Mock 490ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam private RequireScrollMixin mRequireScrollMixin; 500ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 510ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam private ListView mListView; 520ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam private ListViewScrollHandlingDelegate mDelegate; 530ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam private ArgumentCaptor<OnScrollListener> mListenerCaptor; 540ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 550ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam @Before 560ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam public void setUp() throws Exception { 570ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam MockitoAnnotations.initMocks(this); 580ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 590ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam mListView = spy(new TestListView(application)); 600ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam mDelegate = new ListViewScrollHandlingDelegate(mRequireScrollMixin, mListView); 610ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 620ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam mListenerCaptor = ArgumentCaptor.forClass(OnScrollListener.class); 630ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam doNothing().when(mListView).setOnScrollListener(mListenerCaptor.capture()); 640ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 650ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam mListView.layout(0, 0, 50, 50); 660ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam } 670ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 680ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam @Test 690ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam public void testRequireScroll() throws Throwable { 700ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam mDelegate.startListening(); 710ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 720ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam verify(mRequireScrollMixin).notifyScrollabilityChange(true); 730ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam } 740ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 750ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam @Test 760ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam public void testScrolledToBottom() throws Throwable { 770ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam mDelegate.startListening(); 780ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 790ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam verify(mRequireScrollMixin).notifyScrollabilityChange(true); 800ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 810ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam doReturn(20).when(mListView).getLastVisiblePosition(); 820ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam mListenerCaptor.getValue().onScroll(mListView, 2, 20, 20); 830ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 840ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam verify(mRequireScrollMixin).notifyScrollabilityChange(false); 850ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam } 860ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 870ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam @Test 880ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam public void testPageScrollDown() throws Throwable { 890ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam mDelegate.pageScrollDown(); 900ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam verify(mListView).smoothScrollBy(eq(50), anyInt()); 910ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam } 920ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 930ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam private static class TestListView extends ListView { 940ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 950ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam TestListView(Context context) { 960ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam super(context); 970ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam setAdapter(new BaseAdapter() { 980ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam @Override 990ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam public int getCount() { 1000ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam return 20; 1010ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam } 1020ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 1030ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam @Override 1040ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam public Object getItem(int position) { 1050ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam return null; 1060ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam } 1070ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 1080ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam @Override 1090ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam public long getItemId(int position) { 1100ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam return position; 1110ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam } 1120ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam 1130ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam @Override 1140ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam public View getView(int position, View convertView, ViewGroup parent) { 1150ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam return new View(parent.getContext()); 1160ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam } 1170ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam }); 1180ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam } 1190ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam } 1200ceb8d53e39ebb5bc103863787afb39ec5c41ad8Maurice Lam} 121