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