Merge "[BiometricsV2] Refactor EnrollIntroViewModel" into main
This commit is contained in:
committed by
Android (Google) Code Review
commit
317bfca133
@@ -1,328 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.settings.biometrics2.ui.viewmodel;
|
||||
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
|
||||
|
||||
import static com.android.settings.biometrics2.ui.model.FingerprintEnrollable.FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX;
|
||||
import static com.android.settings.biometrics2.ui.model.FingerprintEnrollable.FINGERPRINT_ENROLLABLE_OK;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_CONTINUE_ENROLL;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_DONE_AND_FINISH;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_SKIP_OR_CANCEL;
|
||||
import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newAllFalseRequest;
|
||||
import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwDeferredRequest;
|
||||
import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwPortalRequest;
|
||||
import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwRequest;
|
||||
import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwSuggestedActionFlowRequest;
|
||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.newFingerprintRepository;
|
||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupFingerprintEnrolledFingerprints;
|
||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupSuwMaxFingerprintsEnrollable;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.biometrics2.data.repository.FingerprintRepository;
|
||||
import com.android.settings.biometrics2.ui.model.EnrollmentRequest;
|
||||
import com.android.settings.biometrics2.ui.model.FingerprintEnrollIntroStatus;
|
||||
import com.android.settings.testutils.InstantTaskExecutorRule;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class FingerprintEnrollIntroViewModelTest {
|
||||
|
||||
private static final int TEST_USER_ID = 33;
|
||||
|
||||
@Rule public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Rule public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
|
||||
|
||||
@Mock private Resources mResources;
|
||||
@Mock private FingerprintManager mFingerprintManager;
|
||||
|
||||
private Application mApplication;
|
||||
|
||||
private FingerprintEnrollIntroViewModel newFingerprintEnrollIntroViewModel(
|
||||
@NonNull FingerprintRepository fingerprintRepository,
|
||||
@NonNull EnrollmentRequest enrollmentRequest) {
|
||||
final FingerprintEnrollIntroViewModel viewModel =
|
||||
new FingerprintEnrollIntroViewModel(mApplication, fingerprintRepository,
|
||||
enrollmentRequest, TEST_USER_ID);
|
||||
// MediatorLiveData won't update itself unless observed
|
||||
viewModel.getPageStatusLiveData().observeForever(event -> {});
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mApplication = ApplicationProvider.getApplicationContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPageStatusLiveDataDefaultValue() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newAllFalseRequest(mApplication));
|
||||
final FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.hasScrollToBottom()).isFalse();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPageStatusLiveDataRefreshWhenRefetch() {
|
||||
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
|
||||
TYPE_UDFPS_OPTICAL, 1);
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
repository,
|
||||
newAllFalseRequest(mApplication));
|
||||
FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.hasScrollToBottom()).isFalse();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_OK);
|
||||
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, TEST_USER_ID, 1);
|
||||
|
||||
// Refetch PageStatusLiveData
|
||||
status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.hasScrollToBottom()).isFalse();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearActionLiveData() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newAllFalseRequest(mApplication));
|
||||
|
||||
final MutableLiveData<Integer> actionLiveData =
|
||||
(MutableLiveData<Integer>) viewModel.getActionLiveData();
|
||||
actionLiveData.postValue(1);
|
||||
assertThat(actionLiveData.getValue()).isEqualTo(1);
|
||||
|
||||
viewModel.clearActionLiveData();
|
||||
|
||||
assertThat(actionLiveData.getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetEnrollmentRequest() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newAllFalseRequest(mApplication));
|
||||
|
||||
assertThat(viewModel.getRequest()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusOk_isSuw() {
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, TEST_USER_ID, 0);
|
||||
setupSuwMaxFingerprintsEnrollable(mApplication, mResources, 1);
|
||||
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newIsSuwRequest(mApplication));
|
||||
final FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusReachMax_isSuw() {
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, TEST_USER_ID, 1);
|
||||
setupSuwMaxFingerprintsEnrollable(mApplication, mResources, 1);
|
||||
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newIsSuwRequest(mApplication));
|
||||
final FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusOk_isNotSuw() {
|
||||
testOnStartToUpdateEnrollableStatusOk(newAllFalseRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusReachMax_isNotSuw() {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(newAllFalseRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusOk_isSuwDeferred() {
|
||||
testOnStartToUpdateEnrollableStatusOk(newIsSuwDeferredRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusReachMax_isSuwDeferred() {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(newIsSuwDeferredRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusOk_isSuwPortal() {
|
||||
testOnStartToUpdateEnrollableStatusOk(newIsSuwPortalRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusReachMax_isSuwPortal() {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(newIsSuwPortalRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusOk_isSuwSuggestedActionFlow() {
|
||||
testOnStartToUpdateEnrollableStatusOk(newIsSuwSuggestedActionFlowRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusReachMax_isSuwSuggestedActionFlow() {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(
|
||||
newIsSuwSuggestedActionFlowRequest(mApplication));
|
||||
}
|
||||
|
||||
private void testOnStartToUpdateEnrollableStatusOk(@NonNull EnrollmentRequest request) {
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, TEST_USER_ID, 0);
|
||||
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
request);
|
||||
FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_OK);
|
||||
}
|
||||
|
||||
private void testOnStartToUpdateEnrollableStatusReachMax(@NonNull EnrollmentRequest request) {
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, TEST_USER_ID, 5);
|
||||
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
request);
|
||||
FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsParentalConsentRequired() {
|
||||
// We shall not mock FingerprintRepository, but
|
||||
// FingerprintRepository.isParentalConsentRequired() calls static method inside, we can't
|
||||
// mock static method
|
||||
final FingerprintRepository fingerprintRepository = mock(FingerprintRepository.class);
|
||||
final FingerprintEnrollIntroViewModel viewModel = new FingerprintEnrollIntroViewModel(
|
||||
mApplication, fingerprintRepository, newAllFalseRequest(mApplication),
|
||||
TEST_USER_ID);
|
||||
|
||||
when(fingerprintRepository.isParentalConsentRequired(mApplication)).thenReturn(true);
|
||||
assertThat(viewModel.isParentalConsentRequired()).isEqualTo(true);
|
||||
|
||||
when(fingerprintRepository.isParentalConsentRequired(mApplication)).thenReturn(false);
|
||||
assertThat(viewModel.isParentalConsentRequired()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsBiometricUnlockDisabledByAdmin() {
|
||||
// We shall not mock FingerprintRepository, but
|
||||
// FingerprintRepository.isDisabledByAdmin() calls static method inside, we can't mock
|
||||
// static method
|
||||
final FingerprintRepository fingerprintRepository = mock(FingerprintRepository.class);
|
||||
final FingerprintEnrollIntroViewModel viewModel = new FingerprintEnrollIntroViewModel(
|
||||
mApplication, fingerprintRepository, newAllFalseRequest(mApplication),
|
||||
TEST_USER_ID);
|
||||
|
||||
when(fingerprintRepository.isDisabledByAdmin(mApplication, TEST_USER_ID)).thenReturn(true);
|
||||
assertThat(viewModel.isBiometricUnlockDisabledByAdmin()).isEqualTo(true);
|
||||
|
||||
when(fingerprintRepository.isDisabledByAdmin(mApplication, TEST_USER_ID)).thenReturn(false);
|
||||
assertThat(viewModel.isBiometricUnlockDisabledByAdmin()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetHasScrolledToBottom() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newAllFalseRequest(mApplication));
|
||||
|
||||
viewModel.setHasScrolledToBottom(true);
|
||||
FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.hasScrollToBottom()).isEqualTo(true);
|
||||
|
||||
viewModel.setHasScrolledToBottom(false);
|
||||
status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.hasScrollToBottom()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnNextButtonClick_enrollNext() {
|
||||
// Set latest status to FINGERPRINT_ENROLLABLE_OK
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, TEST_USER_ID, 0);
|
||||
setupSuwMaxFingerprintsEnrollable(mApplication, mResources, 1);
|
||||
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newIsSuwRequest(mApplication));
|
||||
FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_OK);
|
||||
|
||||
// Perform click on `next`
|
||||
viewModel.onNextButtonClick();
|
||||
|
||||
assertThat(viewModel.getActionLiveData().getValue())
|
||||
.isEqualTo(FINGERPRINT_ENROLL_INTRO_ACTION_CONTINUE_ENROLL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnNextButtonClick_doneAndFinish() {
|
||||
// Set latest status to FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, TEST_USER_ID, 1);
|
||||
setupSuwMaxFingerprintsEnrollable(mApplication, mResources, 1);
|
||||
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newIsSuwRequest(mApplication));
|
||||
FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX);
|
||||
|
||||
// Perform click on `next`
|
||||
viewModel.onNextButtonClick();
|
||||
|
||||
assertThat(viewModel.getActionLiveData().getValue())
|
||||
.isEqualTo(FINGERPRINT_ENROLL_INTRO_ACTION_DONE_AND_FINISH);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnSkipOrCancelButtonClick() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newAllFalseRequest(mApplication));
|
||||
|
||||
viewModel.onSkipOrCancelButtonClick();
|
||||
|
||||
assertThat(viewModel.getActionLiveData().getValue())
|
||||
.isEqualTo(FINGERPRINT_ENROLL_INTRO_ACTION_SKIP_OR_CANCEL);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.settings.biometrics2.ui.viewmodel
|
||||
|
||||
import android.app.Application
|
||||
import android.content.res.Resources
|
||||
import android.hardware.fingerprint.FingerprintManager
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.biometrics2.data.repository.FingerprintRepository
|
||||
import com.android.settings.biometrics2.ui.model.EnrollmentRequest
|
||||
import com.android.settings.biometrics2.ui.model.FingerprintEnrollIntroStatus
|
||||
import com.android.settings.biometrics2.ui.model.FingerprintEnrollable.FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX
|
||||
import com.android.settings.biometrics2.ui.model.FingerprintEnrollable.FINGERPRINT_ENROLLABLE_OK
|
||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroAction.CONTINUE_ENROLL
|
||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroAction.DONE_AND_FINISH
|
||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroAction.SKIP_OR_CANCEL
|
||||
import com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newAllFalseRequest
|
||||
import com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwDeferredRequest
|
||||
import com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwPortalRequest
|
||||
import com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwRequest
|
||||
import com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwSuggestedActionFlowRequest
|
||||
import com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.newFingerprintRepository
|
||||
import com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupFingerprintEnrolledFingerprints
|
||||
import com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupSuwMaxFingerprintsEnrollable
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class FingerprintEnrollIntroViewModelTest {
|
||||
|
||||
@get:Rule val mockito = MockitoJUnit.rule()
|
||||
|
||||
@Mock private lateinit var resources: Resources
|
||||
@Mock private lateinit var fingerprintManager: FingerprintManager
|
||||
|
||||
private var application: Application = ApplicationProvider.getApplicationContext()
|
||||
|
||||
private fun newFingerprintEnrollIntroViewModel(
|
||||
fingerprintRepository: FingerprintRepository,
|
||||
enrollmentRequest: EnrollmentRequest
|
||||
) = FingerprintEnrollIntroViewModel(
|
||||
application,
|
||||
fingerprintRepository,
|
||||
enrollmentRequest,
|
||||
TEST_USER_ID
|
||||
)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
application = ApplicationProvider.getApplicationContext()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testPageStatusFlowDefaultAndUpdate() = runTest {
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 1),
|
||||
newAllFalseRequest(application)
|
||||
)
|
||||
|
||||
val statusList = listOfPageStatusFlow(viewModel)
|
||||
|
||||
runCurrent()
|
||||
|
||||
// assert default values
|
||||
assertThat(statusList.size).isEqualTo(1)
|
||||
assertThat(statusList[0].hasScrollToBottom()).isFalse()
|
||||
assertThat(statusList[0].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_OK)
|
||||
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 1)
|
||||
viewModel.updateEnrollableStatus(backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
// assert new updated value
|
||||
assertThat(statusList.size).isEqualTo(2)
|
||||
assertThat(statusList[1].hasScrollToBottom()).isFalse()
|
||||
assertThat(statusList[1].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
fun testOnStartToUpdateEnrollableStatusOk_isSuw() = runTest {
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 0)
|
||||
setupSuwMaxFingerprintsEnrollable(application, resources, 1)
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newIsSuwRequest(application)
|
||||
)
|
||||
|
||||
val statusList = listOfPageStatusFlow(viewModel)
|
||||
|
||||
runCurrent()
|
||||
|
||||
assertThat(statusList.size).isEqualTo(1)
|
||||
assertThat(statusList[0].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_OK)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusReachMax_isSuw() = runTest {
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 1)
|
||||
setupSuwMaxFingerprintsEnrollable(application, resources, 1)
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newIsSuwRequest(application)
|
||||
)
|
||||
|
||||
val statusList = listOfPageStatusFlow(viewModel)
|
||||
|
||||
runCurrent()
|
||||
|
||||
assertThat(statusList.size).isEqualTo(1)
|
||||
assertThat(statusList[0].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusOk_isNotSuw() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusOk(newAllFalseRequest(application))
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusReachMax_isNotSuw() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(newAllFalseRequest(application))
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusOk_isSuwDeferred() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusOk(newIsSuwDeferredRequest(application))
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusReachMax_isSuwDeferred() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(newIsSuwDeferredRequest(application))
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusOk_isSuwPortal() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusOk(newIsSuwPortalRequest(application))
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusReachMax_isSuwPortal() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(newIsSuwPortalRequest(application))
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusOk_isSuwSuggestedActionFlow() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusOk(newIsSuwSuggestedActionFlowRequest(application))
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusReachMax_isSuwSuggestedActionFlow() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(
|
||||
newIsSuwSuggestedActionFlowRequest(application)
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private fun TestScope.testOnStartToUpdateEnrollableStatusOk(request: EnrollmentRequest) {
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 0)
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
request
|
||||
)
|
||||
|
||||
val statusList = listOfPageStatusFlow(viewModel)
|
||||
|
||||
runCurrent()
|
||||
|
||||
assertThat(statusList.size).isEqualTo(1)
|
||||
assertThat(statusList[0].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_OK)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private fun TestScope.testOnStartToUpdateEnrollableStatusReachMax(request: EnrollmentRequest) {
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 5)
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
request
|
||||
)
|
||||
|
||||
val statusList = listOfPageStatusFlow(viewModel)
|
||||
|
||||
runCurrent()
|
||||
|
||||
assertThat(statusList.size).isEqualTo(1)
|
||||
assertThat(statusList[0].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsParentalConsentRequired() {
|
||||
// We shall not mock FingerprintRepository, but
|
||||
// FingerprintRepository.isParentalConsentRequired() calls static method inside, we can't
|
||||
// mock static method
|
||||
val fingerprintRepository = Mockito.mock(
|
||||
FingerprintRepository::class.java
|
||||
)
|
||||
val viewModel = FingerprintEnrollIntroViewModel(
|
||||
application,
|
||||
fingerprintRepository,
|
||||
newAllFalseRequest(application),
|
||||
TEST_USER_ID
|
||||
)
|
||||
Mockito.`when`(
|
||||
fingerprintRepository.isParentalConsentRequired(application)
|
||||
).thenReturn(true)
|
||||
assertThat(viewModel.isParentalConsentRequired).isEqualTo(true)
|
||||
Mockito.`when`(
|
||||
fingerprintRepository.isParentalConsentRequired(application)
|
||||
).thenReturn(false)
|
||||
assertThat(viewModel.isParentalConsentRequired).isEqualTo(false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsBiometricUnlockDisabledByAdmin() {
|
||||
// We shall not mock FingerprintRepository, but
|
||||
// FingerprintRepository.isDisabledByAdmin() calls static method inside, we can't mock
|
||||
// static method
|
||||
val fingerprintRepository = Mockito.mock(FingerprintRepository::class.java)
|
||||
val viewModel = FingerprintEnrollIntroViewModel(
|
||||
application,
|
||||
fingerprintRepository,
|
||||
newAllFalseRequest(application),
|
||||
TEST_USER_ID
|
||||
)
|
||||
Mockito.`when`(
|
||||
fingerprintRepository.isDisabledByAdmin(application, TEST_USER_ID)
|
||||
).thenReturn(true)
|
||||
assertThat(viewModel.isBiometricUnlockDisabledByAdmin).isEqualTo(true)
|
||||
Mockito.`when`(
|
||||
fingerprintRepository.isDisabledByAdmin(application, TEST_USER_ID)
|
||||
).thenReturn(false)
|
||||
assertThat(viewModel.isBiometricUnlockDisabledByAdmin).isEqualTo(false)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testSetHasScrolledToBottom() = runTest {
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newAllFalseRequest(application)
|
||||
)
|
||||
|
||||
val pageStatusList = listOfPageStatusFlow(viewModel)
|
||||
|
||||
viewModel.setHasScrolledToBottom(true, backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
assertThat(pageStatusList[pageStatusList.size-1].hasScrollToBottom()).isEqualTo(true)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testOnNextButtonClick_enrollNext() = runTest {
|
||||
// Set latest status to FINGERPRINT_ENROLLABLE_OK
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 0)
|
||||
setupSuwMaxFingerprintsEnrollable(application, resources, 1)
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newIsSuwRequest(application)
|
||||
)
|
||||
|
||||
val actions = listOfActionFlow(viewModel)
|
||||
|
||||
// Perform click on `next`
|
||||
viewModel.onNextButtonClick(backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
assertThat(actions.size).isEqualTo(1)
|
||||
assertThat(actions[0]).isEqualTo(CONTINUE_ENROLL)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testOnNextButtonClick_doneAndFinish() = runTest {
|
||||
// Set latest status to FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 1)
|
||||
setupSuwMaxFingerprintsEnrollable(application, resources, 1)
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newIsSuwRequest(application)
|
||||
)
|
||||
|
||||
val statusList = listOfPageStatusFlow(viewModel)
|
||||
val actionList = listOfActionFlow(viewModel)
|
||||
|
||||
runCurrent()
|
||||
|
||||
assertThat(statusList.size).isEqualTo(1)
|
||||
assertThat(statusList[0].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX)
|
||||
|
||||
val actions = listOfActionFlow(viewModel)
|
||||
|
||||
// Perform click on `next`
|
||||
viewModel.onNextButtonClick(backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
assertThat(actionList.size).isEqualTo(1)
|
||||
assertThat(actionList[0]).isEqualTo(DONE_AND_FINISH)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun testOnSkipOrCancelButtonClick() = runTest {
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newAllFalseRequest(application)
|
||||
)
|
||||
|
||||
val actions = listOfActionFlow(viewModel)
|
||||
|
||||
viewModel.onSkipOrCancelButtonClick(backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
assertThat(actions.size).isEqualTo(1)
|
||||
assertThat(actions[0]).isEqualTo(SKIP_OR_CANCEL)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private fun TestScope.listOfActionFlow(
|
||||
viewModel: FingerprintEnrollIntroViewModel
|
||||
): List<FingerprintEnrollIntroAction> =
|
||||
mutableListOf<FingerprintEnrollIntroAction>().also {
|
||||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
|
||||
viewModel.actionFlow.toList(it)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private fun TestScope.listOfPageStatusFlow(
|
||||
viewModel: FingerprintEnrollIntroViewModel
|
||||
): List<FingerprintEnrollIntroStatus> =
|
||||
mutableListOf<FingerprintEnrollIntroStatus>().also {
|
||||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
|
||||
viewModel.pageStatusFlow.toList(it)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TEST_USER_ID = 33
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user