1 /*
2  * Copyright (C) 2021 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 
17 package com.android.managedprovisioning.preprovisioning;
18 
19 import static com.android.managedprovisioning.TestUtils.assertBundlesEqual;
20 import static com.android.managedprovisioning.preprovisioning.PreProvisioningViewModel.STATE_GETTING_PROVISIONING_MODE;
21 import static com.android.managedprovisioning.preprovisioning.PreProvisioningViewModel.STATE_PREPROVISIONING_INITIALIZED;
22 import static com.android.managedprovisioning.preprovisioning.PreProvisioningViewModel.STATE_PREPROVISIONING_INITIALIZING;
23 import static com.android.managedprovisioning.preprovisioning.PreProvisioningViewModel.STATE_PROVISIONING_FINALIZED;
24 import static com.android.managedprovisioning.preprovisioning.PreProvisioningViewModel.STATE_PROVISIONING_STARTED;
25 import static com.android.managedprovisioning.preprovisioning.PreProvisioningViewModel.STATE_ROLE_HOLDER_PROVISIONING;
26 import static com.android.managedprovisioning.preprovisioning.PreProvisioningViewModel.STATE_SHOWING_USER_CONSENT;
27 import static com.android.managedprovisioning.preprovisioning.PreProvisioningViewModel.STATE_UPDATING_ROLE_HOLDER;
28 
29 import static com.google.common.truth.Truth.assertThat;
30 
31 import static org.testng.Assert.assertThrows;
32 
33 import android.app.Instrumentation;
34 import android.content.Context;
35 import android.content.Intent;
36 import android.os.PersistableBundle;
37 
38 import androidx.test.InstrumentationRegistry;
39 import androidx.test.filters.SmallTest;
40 
41 import com.android.managedprovisioning.TestUtils;
42 import com.android.managedprovisioning.analytics.TimeLogger;
43 import com.android.managedprovisioning.common.IllegalProvisioningArgumentException;
44 import com.android.managedprovisioning.common.Utils;
45 import com.android.managedprovisioning.parser.MessageParser;
46 
47 import org.junit.Before;
48 import org.junit.Test;
49 
50 @SmallTest
51 public final class PreProvisioningViewModelTest {
52 
53     public static final String TEST_KEY = "testKey";
54     public static final String TEST_VALUE = "testValue";
55     private final Instrumentation mInstrumentation =
56             androidx.test.platform.app.InstrumentationRegistry.getInstrumentation();
57     private PreProvisioningViewModel mViewModel;
58     private TimeLogger mTimeLogger;
59     private EncryptionController mEncryptionController;
60     private final Context mContext = InstrumentationRegistry.getTargetContext();
61 
62     private static final PersistableBundle ROLE_HOLDER_STATE = createRoleHolderStateBundle();
63 
64     @Before
setUp()65     public void setUp()  {
66         mTimeLogger = new TimeLogger(mContext, /* category */ 0);
67         MessageParser messageParser = new MessageParser(mContext, new Utils());
68         mEncryptionController = TestUtils.createEncryptionController(mContext);
69         mViewModel = new PreProvisioningViewModel(
70                 mTimeLogger,
71                 messageParser,
72                 mEncryptionController, new PreProvisioningViewModel.DefaultConfig());
73     }
74 
75     @Test
getState_defaultsToInitializing()76     public void getState_defaultsToInitializing() {
77         assertThat(mViewModel.getState().getValue())
78                 .isEqualTo(STATE_PREPROVISIONING_INITIALIZING);
79     }
80 
81     @Test
onReturnFromProvisioning_stateIsProvisioningFinalized()82     public void onReturnFromProvisioning_stateIsProvisioningFinalized() {
83         mInstrumentation.runOnMainSync(
84                 () -> {
85                     mViewModel.onReturnFromProvisioning();
86 
87                     assertThat(mViewModel.getState().getValue())
88                             .isEqualTo(STATE_PROVISIONING_FINALIZED);
89                 });
90     }
91 
92     @Test
onAdminIntegratedFlowInitiated_stateIsGettingProvisioningMode()93     public void onAdminIntegratedFlowInitiated_stateIsGettingProvisioningMode() {
94         mInstrumentation.runOnMainSync(
95                 () -> {
96                     mViewModel.onAdminIntegratedFlowInitiated();
97                     assertThat(mViewModel.getState().getValue())
98                             .isEqualTo(STATE_GETTING_PROVISIONING_MODE);
99                 });
100     }
101 
102     @Test
onShowUserConsent_stateIsShowingUserConsent()103     public void onShowUserConsent_stateIsShowingUserConsent() {
104         mInstrumentation.runOnMainSync(
105                 () -> {
106                     mViewModel.onShowUserConsent();
107 
108                     assertThat(mViewModel.getState().getValue())
109                             .isEqualTo(STATE_SHOWING_USER_CONSENT);
110                 });
111     }
112 
113     @Test
onProvisioningStartedAfterUserConsent_stateIsProvisioningStarted()114     public void onProvisioningStartedAfterUserConsent_stateIsProvisioningStarted() {
115         mInstrumentation.runOnMainSync(
116                 () -> {
117                     mViewModel.onProvisioningStartedAfterUserConsent();
118 
119                     assertThat(mViewModel.getState().getValue())
120                             .isEqualTo(STATE_PROVISIONING_STARTED);
121                 });
122     }
123 
124     @Test
onProvisioningInitiated_stateIsProvisioningInitialized()125     public void onProvisioningInitiated_stateIsProvisioningInitialized() {
126         mInstrumentation.runOnMainSync(
127                 () -> {
128                     mViewModel.onPlatformProvisioningInitiated();
129 
130                     assertThat(mViewModel.getState().getValue())
131                             .isEqualTo(STATE_PREPROVISIONING_INITIALIZED);
132                 });
133     }
134 
135     @Test
getEncryptionController_valuesAreEqual()136     public void getEncryptionController_valuesAreEqual() {
137         assertThat(mViewModel.getEncryptionController())
138                 .isEqualTo(mEncryptionController);
139     }
140 
141     @Test
getTimeLogger_valuesAreEqual()142     public void getTimeLogger_valuesAreEqual() {
143         assertThat(mViewModel.getTimeLogger())
144                 .isEqualTo(mTimeLogger);
145     }
146 
147     @Test
loadParamsIfNecessary_invalidParams_throwsException()148     public void loadParamsIfNecessary_invalidParams_throwsException() {
149         Intent invalidIntent = new Intent();
150 
151         assertThrows(
152                 IllegalProvisioningArgumentException.class,
153                 () -> mViewModel.loadParamsIfNecessary(invalidIntent));
154     }
155 
156     @Test
canRetryRoleHolderUpdate_noTries_works()157     public void canRetryRoleHolderUpdate_noTries_works() {
158         mViewModel.incrementRoleHolderUpdateRetryCount();
159 
160         assertThat(mViewModel.canRetryRoleHolderUpdate()).isTrue();
161     }
162 
163     @Test
canRetryRoleHolderUpdate_threeTries_isFalse()164     public void canRetryRoleHolderUpdate_threeTries_isFalse() {
165         mViewModel.incrementRoleHolderUpdateRetryCount();
166         mViewModel.incrementRoleHolderUpdateRetryCount();
167         mViewModel.incrementRoleHolderUpdateRetryCount();
168 
169         assertThat(mViewModel.canRetryRoleHolderUpdate()).isFalse();
170     }
171 
172     @Test
canRetryRoleHolderUpdate_resetAfterMaxTries_isTrue()173     public void canRetryRoleHolderUpdate_resetAfterMaxTries_isTrue() {
174         mViewModel.incrementRoleHolderUpdateRetryCount();
175         mViewModel.incrementRoleHolderUpdateRetryCount();
176         mViewModel.incrementRoleHolderUpdateRetryCount();
177         mViewModel.resetRoleHolderUpdateRetryCount();
178 
179         assertThat(mViewModel.canRetryRoleHolderUpdate()).isTrue();
180     }
181 
182     @Test
canRetryRoleHolderUpdate_resetAndDoMaxRetries_isFalse()183     public void canRetryRoleHolderUpdate_resetAndDoMaxRetries_isFalse() {
184         mViewModel.incrementRoleHolderUpdateRetryCount();
185         mViewModel.incrementRoleHolderUpdateRetryCount();
186         mViewModel.incrementRoleHolderUpdateRetryCount();
187         mViewModel.resetRoleHolderUpdateRetryCount();
188         mViewModel.incrementRoleHolderUpdateRetryCount();
189         mViewModel.incrementRoleHolderUpdateRetryCount();
190         mViewModel.incrementRoleHolderUpdateRetryCount();
191 
192         assertThat(mViewModel.canRetryRoleHolderUpdate()).isFalse();
193     }
194 
195     @Test
onRoleHolderUpdateInitiated_works()196     public void onRoleHolderUpdateInitiated_works() {
197         mInstrumentation.runOnMainSync(
198                 () -> {
199                     mViewModel.onRoleHolderUpdateInitiated();
200 
201                     assertThat(mViewModel.getState().getValue())
202                             .isEqualTo(STATE_UPDATING_ROLE_HOLDER);
203                 });
204     }
205 
206     @Test
onRoleHolderProvisioningInitiated_works()207     public void onRoleHolderProvisioningInitiated_works() {
208         mInstrumentation.runOnMainSync(
209                 () -> {
210                     mViewModel.onRoleHolderProvisioningInitiated();
211 
212                     assertThat(mViewModel.getState().getValue())
213                             .isEqualTo(STATE_ROLE_HOLDER_PROVISIONING);
214                 });
215     }
216 
217     @Test
setRoleHolderState_works()218     public void setRoleHolderState_works() {
219         mViewModel.setRoleHolderState(ROLE_HOLDER_STATE);
220 
221         assertBundlesEqual(mViewModel.getRoleHolderState(), ROLE_HOLDER_STATE);
222     }
223 
224     @Test
getRoleHolderState_modifySetState_isImmutable()225     public void getRoleHolderState_modifySetState_isImmutable() {
226         PersistableBundle bundle = new PersistableBundle(ROLE_HOLDER_STATE);
227 
228         mViewModel.setRoleHolderState(bundle);
229         bundle.putString(TEST_KEY, TEST_VALUE);
230 
231         assertBundlesEqual(mViewModel.getRoleHolderState(), ROLE_HOLDER_STATE);
232     }
233 
234     @Test
getRoleHolderState_modifyGetState_isImmutable()235     public void getRoleHolderState_modifyGetState_isImmutable() {
236         PersistableBundle bundle = new PersistableBundle(ROLE_HOLDER_STATE);
237 
238         mViewModel.setRoleHolderState(bundle);
239         mViewModel.getRoleHolderState().putString(TEST_KEY, TEST_VALUE);
240 
241         assertBundlesEqual(mViewModel.getRoleHolderState(), ROLE_HOLDER_STATE);
242     }
243 
createRoleHolderStateBundle()244     private static PersistableBundle createRoleHolderStateBundle() {
245         PersistableBundle result = new PersistableBundle();
246         result.putString("key1", "value1");
247         result.putInt("key2", 2);
248         result.putBoolean("key3", true);
249         return result;
250     }
251 }
252