summaryrefslogtreecommitdiff
path: root/tests/src/com/android/dialer/onboard/OnboardingControllerTest.java
blob: d6348553f2b90152aa9120eabf30d0085ef7a6db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.dialer.onboard;

import android.app.Activity;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.Suppress;

@SmallTest
public class OnboardingControllerTest extends AndroidTestCase {
    private MockOnboardUi mOnboardUi;
    private OnboardingController mController;

    public class MockOnboardUi implements OnboardingController.OnboardingUi {
        public int currentScreen = -1;
        public boolean completedOnboardingFlow = false;

        @Override
        public void showScreen(int screenId) {
            currentScreen = screenId;
        }

        @Override
        public void completeOnboardingFlow() {
            completedOnboardingFlow = true;
        }
    }

    public class MockScreen extends OnboardingController.OnboardingScreen {
        boolean shouldShowScreen;
        boolean canSkipScreen;

        public MockScreen(boolean shouldShowScreen, boolean canSkipScreen) {
            this.shouldShowScreen = shouldShowScreen;
            this.canSkipScreen = canSkipScreen;
        }

        @Override
        public boolean shouldShowScreen() {
            return shouldShowScreen;
        }

        @Override
        public boolean canSkipScreen() {
            return canSkipScreen;
        }

        @Override
        public void onNextClicked(Activity activity) {
        }
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mOnboardUi = new MockOnboardUi();
        mController = new OnboardingController(mOnboardUi);
    }

    @Suppress
    public void testNoScreensToDisplay_OnboardingFlowImmediatelyCompleted() {
        mController.showNextScreen();
        assertEquals(-1, mOnboardUi.currentScreen);
        assertTrue(mOnboardUi.completedOnboardingFlow);
    }

    @Suppress
    public void testSkipAllScreens_OnboardingFlowImmediatelyCompleted() {
        mController.addScreen(new MockScreen(false /* shouldShowScreen */,
                true /* canSkipScreen */));
        mController.addScreen(new MockScreen(false /* shouldShowScreen */,
                true /* canSkipScreen */));
        mController.addScreen(new MockScreen(false /* shouldShowScreen */,
                true /* canSkipScreen */));
        mController.showNextScreen();
        assertEquals(-1, mOnboardUi.currentScreen);
        assertTrue(mOnboardUi.completedOnboardingFlow);
    }

    @Suppress
    public void testFirstScreenNotNeeded_ShowsSecondScreen() {
        mController.addScreen(new MockScreen(false /* shouldShowScreen */,
                false /* canSkipScreen */));
        mController.addScreen(new MockScreen(true /* shouldShowScreen */,
                false /* canSkipScreen */));
        mController.showNextScreen();
        assertEquals(1, mOnboardUi.currentScreen);
    }

    @Suppress
    public void testScreenRequired() {
        final MockScreen mockScreen =
                new MockScreen(true /* shouldShowScreen */, false /* canSkipScreen */);
        mController.addScreen(mockScreen);

        mController.showNextScreen();
        assertEquals(0, mOnboardUi.currentScreen);
        assertFalse(mOnboardUi.completedOnboardingFlow);

        // User tried to skip an unskippable screen
        mController.onScreenResult(0, false);
        assertEquals(0, mOnboardUi.currentScreen);
        assertFalse(mOnboardUi.completedOnboardingFlow);

        // User said yes, but the underlying requirements have not been fulfilled yet, so don't
        // show the next screen. Should be very rare in practice.
        mController.onScreenResult(0, true);
        assertEquals(0, mOnboardUi.currentScreen);
        assertFalse(mOnboardUi.completedOnboardingFlow);

        // Requirement has been fulfiled.
        mockScreen.shouldShowScreen = false;
        mController.onScreenResult(0, true);
        assertTrue(mOnboardUi.completedOnboardingFlow);
    }

    /**
     * Verifies the use case where completing the first screen will provide the necessary conditions
     * to skip the second screen as well.
     *
     * For example, setting the default dialer in the first screen will automatically grant
     * permissions such that the second permissions screen is no longer needed.
     */
    @Suppress
    public void testFirstScreenCompleted_SkipsSecondScreen() {
        final MockScreen mockScreen1 =
                new MockScreen(true /* shouldShowScreen */, true /* canSkipScreen */);
        final MockScreen mockScreen2 =
                new MockScreen(true /* shouldShowScreen */, false /* canSkipScreen */);
        mController.addScreen(mockScreen1);
        mController.addScreen(mockScreen2);

        mController.showNextScreen();
        assertEquals(0, mOnboardUi.currentScreen);
        assertFalse(mOnboardUi.completedOnboardingFlow);

        // Screen 1 succeeded, screen 2 is no longer necessary
        mockScreen2.shouldShowScreen = false;
        mController.onScreenResult(0, true);
        assertEquals(0, mOnboardUi.currentScreen);
        assertTrue(mOnboardUi.completedOnboardingFlow);
    }

    /**
     * Verifies the use case where skipping the first screen will proceed to show the second screen
     * since the necessary conditions to skip the second screen have not been met.
     */
    @Suppress
    public void testFirstScreenSkipped_ShowsSecondScreen() {
        final MockScreen mockScreen1 =
                new MockScreen(true /* shouldShowScreen */, true /* canSkipScreen */);
        final MockScreen mockScreen2 =
                new MockScreen(true /* shouldShowScreen */, false /* canSkipScreen */);
        mController.addScreen(mockScreen1);
        mController.addScreen(mockScreen2);

        mController.showNextScreen();
        assertEquals(0, mOnboardUi.currentScreen);
        assertFalse(mOnboardUi.completedOnboardingFlow);

        // Screen 1 skipped
        mController.onScreenResult(0, false);
        assertEquals(1, mOnboardUi.currentScreen);
        assertFalse(mOnboardUi.completedOnboardingFlow);

        // Repeatedly trying to skip screen 2 will not work since it is marked as unskippable.
        mController.onScreenResult(1, false);
        assertEquals(1, mOnboardUi.currentScreen);
        assertFalse(mOnboardUi.completedOnboardingFlow);
    }
}