Loading tests/robotests/src/com/android/settings/biometrics2/OWNERS 0 → 100644 +1 −0 Original line number Diff line number Diff line include /src/com/android/settings/biometrics/OWNERS tests/robotests/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModelTest.java 0 → 100644 +179 −0 Original line number Diff line number Diff line /* * 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.FingerprintManager.ENROLL_ENROLL; import static android.hardware.fingerprint.FingerprintManager.ENROLL_FIND_SENSOR; import static android.hardware.fingerprint.FingerprintManager.EnrollReason; import static android.hardware.fingerprint.FingerprintManager.EnrollmentCallback; import static com.android.settings.biometrics2.ui.model.EnrollmentProgress.INITIAL_STEPS; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.only; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Application; import android.content.res.Resources; import android.os.CancellationSignal; import com.android.settings.R; import com.android.settings.biometrics.fingerprint.FingerprintUpdater; import com.android.settings.biometrics2.ui.model.EnrollmentProgress; 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; import org.robolectric.RobolectricTestRunner; @RunWith(RobolectricTestRunner.class) public class FingerprintEnrollProgressViewModelTest { @Rule public final MockitoRule mockito = MockitoJUnit.rule(); @Rule public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule(); @Mock private Application mApplication; @Mock private Resources mResources; @Mock private FingerprintUpdater mFingerprintUpdater; private FingerprintEnrollProgressViewModel mViewModel; @Before public void setUp() { when(mApplication.getResources()).thenReturn(mResources); when(mResources.getBoolean(R.bool.enrollment_message_display_controller_flag)) .thenReturn(false); mViewModel = new FingerprintEnrollProgressViewModel(mApplication, mFingerprintUpdater); } @Test public void testStartEnrollment() { @EnrollReason final int enrollReason = ENROLL_FIND_SENSOR; final int userId = 334; final byte[] token = new byte[] { 1, 2, 3 }; mViewModel.setToken(token); mViewModel.setUserId(userId); // Start enrollment final boolean ret = mViewModel.startEnrollment(enrollReason); assertThat(ret).isTrue(); verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class), eq(userId), any(EnrollmentCallback.class), eq(enrollReason)); } @Test public void testStartEnrollmentFailBecauseOfNoToken() { // Start enrollment final boolean ret = mViewModel.startEnrollment(ENROLL_FIND_SENSOR); assertThat(ret).isFalse(); verify(mFingerprintUpdater, never()).enroll(any(byte[].class), any(CancellationSignal.class), anyInt(), any(EnrollmentCallback.class), anyInt()); } @Test public void testCancelEnrollment() { @EnrollReason final int enrollReason = ENROLL_ENROLL; final int userId = 334; final byte[] token = new byte[] { 1, 2, 3 }; mViewModel.setToken(token); mViewModel.setUserId(userId); final TestWrapper<CancellationSignal> signalWrapper = new TestWrapper<>(); doAnswer(invocation -> { signalWrapper.mValue = invocation.getArgument(1); return null; }).when(mFingerprintUpdater).enroll(any(byte[].class), any(CancellationSignal.class), eq(userId), any(EnrollmentCallback.class), anyInt()); // Start enrollment final boolean ret = mViewModel.startEnrollment(enrollReason); assertThat(ret).isTrue(); assertThat(signalWrapper.mValue).isNotNull(); // Cancel enrollment mViewModel.cancelEnrollment(); assertThat(signalWrapper.mValue.isCanceled()).isTrue(); } @Test public void testProgressUpdate() { @EnrollReason final int enrollReason = ENROLL_ENROLL; final int userId = 334; final byte[] token = new byte[] { 1, 2, 3 }; mViewModel.setToken(token); mViewModel.setUserId(userId); final TestWrapper<EnrollmentCallback> callbackWrapper = new TestWrapper<>(); doAnswer(invocation -> { callbackWrapper.mValue = invocation.getArgument(3); return null; }).when(mFingerprintUpdater).enroll(any(byte[].class), any(CancellationSignal.class), eq(userId), any(EnrollmentCallback.class), anyInt()); // Start enrollment final boolean ret = mViewModel.startEnrollment(enrollReason); assertThat(ret).isTrue(); assertThat(callbackWrapper.mValue).isNotNull(); // Update first progress callbackWrapper.mValue.onEnrollmentProgress(25); EnrollmentProgress progress = mViewModel.getProgressLiveData().getValue(); assertThat(progress).isNotNull(); assertThat(progress.getSteps()).isEqualTo(25); // TODO(b/260957933) verify getRemaining() when it is really used //assertThat(progress.getRemaining()).isEqualTo(25); // Update second progress callbackWrapper.mValue.onEnrollmentProgress(20); progress = mViewModel.getProgressLiveData().getValue(); assertThat(progress).isNotNull(); assertThat(progress.getSteps()).isEqualTo(25); // TODO(b/260957933) verify getRemaining() when it is really used //assertThat(progress.getRemaining()).isEqualTo(20); // Clear progress mViewModel.clearProgressLiveData(); progress = mViewModel.getProgressLiveData().getValue(); assertThat(progress).isNotNull(); assertThat(progress.getSteps()).isEqualTo(INITIAL_STEPS); // TODO(b/260957933) verify getRemaining() when it is really used //assertThat(progress.getRemaining()).isEqualTo(INITIAL_REMAINING); } // TODO(b/260957933): FingerprintEnrollProgressViewModel::getErrorLiveData() and // FingerprintEnrollProgressViewModel::getHelpLiveData() doesn't built into apk because no one // uses it. We shall test it when new FingerprintEnrollEnrolling has used these 2 methods. private static class TestWrapper<T> { T mValue; } } tests/robotests/src/com/android/settings/testutils/InstantTaskExecutorRule.java 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * 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.testutils; import androidx.arch.core.executor.ArchTaskExecutor; import androidx.arch.core.executor.TaskExecutor; import org.junit.rules.TestWatcher; import org.junit.runner.Description; /** * A JUnit Test Rule that swaps the background executor used by the Architecture Components with a * different one which executes each task synchronously. * * We can't refer it in prebuilt androidX library. * Copied it from androidx/arch/core/executor/testing/InstantTaskExecutorRule.java */ public class InstantTaskExecutorRule extends TestWatcher { @Override protected void starting(Description description) { super.starting(description); ArchTaskExecutor.getInstance().setDelegate(new TaskExecutor() { @Override public void executeOnDiskIO(Runnable runnable) { runnable.run(); } @Override public void postToMainThread(Runnable runnable) { runnable.run(); } @Override public boolean isMainThread() { return true; } }); } @Override protected void finished(Description description) { super.finished(description); ArchTaskExecutor.getInstance().setDelegate(null); } } Loading
tests/robotests/src/com/android/settings/biometrics2/OWNERS 0 → 100644 +1 −0 Original line number Diff line number Diff line include /src/com/android/settings/biometrics/OWNERS
tests/robotests/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollProgressViewModelTest.java 0 → 100644 +179 −0 Original line number Diff line number Diff line /* * 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.FingerprintManager.ENROLL_ENROLL; import static android.hardware.fingerprint.FingerprintManager.ENROLL_FIND_SENSOR; import static android.hardware.fingerprint.FingerprintManager.EnrollReason; import static android.hardware.fingerprint.FingerprintManager.EnrollmentCallback; import static com.android.settings.biometrics2.ui.model.EnrollmentProgress.INITIAL_STEPS; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.only; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Application; import android.content.res.Resources; import android.os.CancellationSignal; import com.android.settings.R; import com.android.settings.biometrics.fingerprint.FingerprintUpdater; import com.android.settings.biometrics2.ui.model.EnrollmentProgress; 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; import org.robolectric.RobolectricTestRunner; @RunWith(RobolectricTestRunner.class) public class FingerprintEnrollProgressViewModelTest { @Rule public final MockitoRule mockito = MockitoJUnit.rule(); @Rule public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule(); @Mock private Application mApplication; @Mock private Resources mResources; @Mock private FingerprintUpdater mFingerprintUpdater; private FingerprintEnrollProgressViewModel mViewModel; @Before public void setUp() { when(mApplication.getResources()).thenReturn(mResources); when(mResources.getBoolean(R.bool.enrollment_message_display_controller_flag)) .thenReturn(false); mViewModel = new FingerprintEnrollProgressViewModel(mApplication, mFingerprintUpdater); } @Test public void testStartEnrollment() { @EnrollReason final int enrollReason = ENROLL_FIND_SENSOR; final int userId = 334; final byte[] token = new byte[] { 1, 2, 3 }; mViewModel.setToken(token); mViewModel.setUserId(userId); // Start enrollment final boolean ret = mViewModel.startEnrollment(enrollReason); assertThat(ret).isTrue(); verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class), eq(userId), any(EnrollmentCallback.class), eq(enrollReason)); } @Test public void testStartEnrollmentFailBecauseOfNoToken() { // Start enrollment final boolean ret = mViewModel.startEnrollment(ENROLL_FIND_SENSOR); assertThat(ret).isFalse(); verify(mFingerprintUpdater, never()).enroll(any(byte[].class), any(CancellationSignal.class), anyInt(), any(EnrollmentCallback.class), anyInt()); } @Test public void testCancelEnrollment() { @EnrollReason final int enrollReason = ENROLL_ENROLL; final int userId = 334; final byte[] token = new byte[] { 1, 2, 3 }; mViewModel.setToken(token); mViewModel.setUserId(userId); final TestWrapper<CancellationSignal> signalWrapper = new TestWrapper<>(); doAnswer(invocation -> { signalWrapper.mValue = invocation.getArgument(1); return null; }).when(mFingerprintUpdater).enroll(any(byte[].class), any(CancellationSignal.class), eq(userId), any(EnrollmentCallback.class), anyInt()); // Start enrollment final boolean ret = mViewModel.startEnrollment(enrollReason); assertThat(ret).isTrue(); assertThat(signalWrapper.mValue).isNotNull(); // Cancel enrollment mViewModel.cancelEnrollment(); assertThat(signalWrapper.mValue.isCanceled()).isTrue(); } @Test public void testProgressUpdate() { @EnrollReason final int enrollReason = ENROLL_ENROLL; final int userId = 334; final byte[] token = new byte[] { 1, 2, 3 }; mViewModel.setToken(token); mViewModel.setUserId(userId); final TestWrapper<EnrollmentCallback> callbackWrapper = new TestWrapper<>(); doAnswer(invocation -> { callbackWrapper.mValue = invocation.getArgument(3); return null; }).when(mFingerprintUpdater).enroll(any(byte[].class), any(CancellationSignal.class), eq(userId), any(EnrollmentCallback.class), anyInt()); // Start enrollment final boolean ret = mViewModel.startEnrollment(enrollReason); assertThat(ret).isTrue(); assertThat(callbackWrapper.mValue).isNotNull(); // Update first progress callbackWrapper.mValue.onEnrollmentProgress(25); EnrollmentProgress progress = mViewModel.getProgressLiveData().getValue(); assertThat(progress).isNotNull(); assertThat(progress.getSteps()).isEqualTo(25); // TODO(b/260957933) verify getRemaining() when it is really used //assertThat(progress.getRemaining()).isEqualTo(25); // Update second progress callbackWrapper.mValue.onEnrollmentProgress(20); progress = mViewModel.getProgressLiveData().getValue(); assertThat(progress).isNotNull(); assertThat(progress.getSteps()).isEqualTo(25); // TODO(b/260957933) verify getRemaining() when it is really used //assertThat(progress.getRemaining()).isEqualTo(20); // Clear progress mViewModel.clearProgressLiveData(); progress = mViewModel.getProgressLiveData().getValue(); assertThat(progress).isNotNull(); assertThat(progress.getSteps()).isEqualTo(INITIAL_STEPS); // TODO(b/260957933) verify getRemaining() when it is really used //assertThat(progress.getRemaining()).isEqualTo(INITIAL_REMAINING); } // TODO(b/260957933): FingerprintEnrollProgressViewModel::getErrorLiveData() and // FingerprintEnrollProgressViewModel::getHelpLiveData() doesn't built into apk because no one // uses it. We shall test it when new FingerprintEnrollEnrolling has used these 2 methods. private static class TestWrapper<T> { T mValue; } }
tests/robotests/src/com/android/settings/testutils/InstantTaskExecutorRule.java 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * 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.testutils; import androidx.arch.core.executor.ArchTaskExecutor; import androidx.arch.core.executor.TaskExecutor; import org.junit.rules.TestWatcher; import org.junit.runner.Description; /** * A JUnit Test Rule that swaps the background executor used by the Architecture Components with a * different one which executes each task synchronously. * * We can't refer it in prebuilt androidX library. * Copied it from androidx/arch/core/executor/testing/InstantTaskExecutorRule.java */ public class InstantTaskExecutorRule extends TestWatcher { @Override protected void starting(Description description) { super.starting(description); ArchTaskExecutor.getInstance().setDelegate(new TaskExecutor() { @Override public void executeOnDiskIO(Runnable runnable) { runnable.run(); } @Override public void postToMainThread(Runnable runnable) { runnable.run(); } @Override public boolean isMainThread() { return true; } }); } @Override protected void finished(Description description) { super.finished(description); ArchTaskExecutor.getInstance().setDelegate(null); } }