1841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang/*
2841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang * Copyright (C) 2017 The Android Open Source Project
3841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang *
4841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang * Licensed under the Apache License, Version 2.0 (the "License");
5841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang * you may not use this file except in compliance with the License.
6841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang * You may obtain a copy of the License at
7841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang *
8841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang *      http://www.apache.org/licenses/LICENSE-2.0
9841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang *
10841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang * Unless required by applicable law or agreed to in writing, software
11841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang * distributed under the License is distributed on an "AS IS" BASIS,
12841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang * See the License for the specific language governing permissions and
14841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang * limitations under the License.
15841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang */
16841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
17841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangpackage com.android.settings.widget;
18841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
19841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
20e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhangimport static com.google.common.truth.Truth.assertThat;
21e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhangimport static org.mockito.Matchers.any;
22e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhangimport static org.mockito.Mockito.times;
23e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhangimport static org.mockito.Mockito.verify;
24e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhangimport static org.mockito.Mockito.when;
25e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang
26841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport android.app.ActionBar;
27841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport android.app.Activity;
28841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport android.support.v7.widget.RecyclerView;
29e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhangimport android.view.View;
30841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
31841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport com.android.settings.TestConfig;
32e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhangimport com.android.settings.testutils.SettingsRobolectricTestRunner;
33841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport com.android.settingslib.core.lifecycle.Lifecycle;
34841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport com.android.settingslib.core.lifecycle.LifecycleObserver;
35841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
36841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport org.junit.Before;
37841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport org.junit.Test;
38841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport org.junit.runner.RunWith;
39841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport org.mockito.Mock;
40841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport org.mockito.MockitoAnnotations;
41e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhangimport org.robolectric.RuntimeEnvironment;
42841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport org.robolectric.annotation.Config;
43841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport org.robolectric.util.ReflectionHelpers;
44841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
45841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangimport java.util.List;
46841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
47841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang@RunWith(SettingsRobolectricTestRunner.class)
48841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
49841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhangpublic class ActionBarShadowControllerTest {
50841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
51841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    @Mock
52841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    private RecyclerView mRecyclerView;
53841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    @Mock
54841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    private Activity mActivity;
55841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    @Mock
56841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    private ActionBar mActionBar;
57841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    private Lifecycle mLifecycle;
58e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang    private View mView;
59841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
60841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    @Before
61841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    public void setUp() {
62841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang        MockitoAnnotations.initMocks(this);
63841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang        when(mActivity.getActionBar()).thenReturn(mActionBar);
64e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang        mView = new View(RuntimeEnvironment.application);
65841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang        mLifecycle = new Lifecycle();
66841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    }
67841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
68841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    @Test
69841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    public void attachToRecyclerView_shouldAddScrollWatcherAndUpdateActionBar() {
70841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang        when(mRecyclerView.canScrollVertically(-1)).thenReturn(false);
71841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
72841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang        ActionBarShadowController.attachToRecyclerView(mActivity, mLifecycle, mRecyclerView);
73841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
74e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang        verify(mActionBar).setElevation(ActionBarShadowController.ELEVATION_LOW);
75841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    }
76841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
77e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang    @Test
78e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang    public void attachToRecyclerView_customViewAsActionBar_shouldUpdateElevationOnScroll() {
79e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang        // Setup
80e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang        mView.setElevation(50);
81e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang        when(mRecyclerView.canScrollVertically(-1)).thenReturn(false);
82e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang        final ActionBarShadowController controller =
83e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang                ActionBarShadowController.attachToRecyclerView(mView, mLifecycle, mRecyclerView);
84e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang        assertThat(mView.getElevation()).isEqualTo(ActionBarShadowController.ELEVATION_LOW);
85e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang
86e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang        // Scroll
87e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang        when(mRecyclerView.canScrollVertically(-1)).thenReturn(true);
88e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang        controller.mScrollChangeWatcher.onScrolled(mRecyclerView, 10 /* dx */, 10 /* dy */);
89e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang        assertThat(mView.getElevation()).isEqualTo(ActionBarShadowController.ELEVATION_HIGH);
90e651ddf9e6c00a62338ef8c7114b5e5e9cd307ecFan Zhang    }
91841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
92841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    @Test
93841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    public void attachToRecyclerView_lifecycleChange_shouldAttachDetach() {
94841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang        ActionBarShadowController.attachToRecyclerView(mActivity, mLifecycle, mRecyclerView);
95841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
96841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang        List<LifecycleObserver> observers = ReflectionHelpers.getField(mLifecycle, "mObservers");
97841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang        assertThat(observers).hasSize(1);
98841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang        verify(mRecyclerView).addOnScrollListener(any());
99841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
100841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang        mLifecycle.onStop();
101841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang        verify(mRecyclerView).removeOnScrollListener(any());
102841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
103841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang        mLifecycle.onStart();
104841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang        verify(mRecyclerView, times(2)).addOnScrollListener(any());
105841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang    }
106841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang
107d53a3128e8107569636da407d7cb75e458e22779Doris Ling    @Test
108d53a3128e8107569636da407d7cb75e458e22779Doris Ling    public void onScrolled_nullAnchorViewAndActivity_shouldNotCrash() {
109d53a3128e8107569636da407d7cb75e458e22779Doris Ling        final Activity activity = null;
110d53a3128e8107569636da407d7cb75e458e22779Doris Ling        final ActionBarShadowController controller =
111d53a3128e8107569636da407d7cb75e458e22779Doris Ling                ActionBarShadowController.attachToRecyclerView(activity, mLifecycle, mRecyclerView);
112d53a3128e8107569636da407d7cb75e458e22779Doris Ling
113d53a3128e8107569636da407d7cb75e458e22779Doris Ling        // Scroll
114d53a3128e8107569636da407d7cb75e458e22779Doris Ling        controller.mScrollChangeWatcher.onScrolled(mRecyclerView, 10 /* dx */, 10 /* dy */);
115d53a3128e8107569636da407d7cb75e458e22779Doris Ling        // no crash
116d53a3128e8107569636da407d7cb75e458e22779Doris Ling    }
117d53a3128e8107569636da407d7cb75e458e22779Doris Ling
118841d1d5aabc33024b2e03276085b0d1dbdb92b23Fan Zhang}
119