From 4c30a9a38cb6dc5610418e4670d2bcdb0fb8e045 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 22 Apr 2025 16:13:08 +0100 Subject: [PATCH 1/5] MS-862 Instructions button on the face Capture screen: UI --- .../res/color/feedback_instructions_text.xml | 5 +++++ .../drawable/feedback_instructions_outline.xml | 15 +++++++++++++++ .../res/layout-land/fragment_live_feedback.xml | 18 ++++++++++++++++++ .../fragment_live_feedback_auto_capture.xml | 18 ++++++++++++++++++ .../main/res/layout/fragment_live_feedback.xml | 18 ++++++++++++++++++ .../fragment_live_feedback_auto_capture.xml | 18 ++++++++++++++++++ .../resources/src/main/res/values/strings.xml | 1 + 7 files changed, 93 insertions(+) create mode 100644 face/capture/src/main/res/color/feedback_instructions_text.xml create mode 100644 face/capture/src/main/res/drawable/feedback_instructions_outline.xml diff --git a/face/capture/src/main/res/color/feedback_instructions_text.xml b/face/capture/src/main/res/color/feedback_instructions_text.xml new file mode 100644 index 0000000000..302c39c06c --- /dev/null +++ b/face/capture/src/main/res/color/feedback_instructions_text.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/face/capture/src/main/res/drawable/feedback_instructions_outline.xml b/face/capture/src/main/res/drawable/feedback_instructions_outline.xml new file mode 100644 index 0000000000..7ee0ad9dfc --- /dev/null +++ b/face/capture/src/main/res/drawable/feedback_instructions_outline.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/face/capture/src/main/res/layout-land/fragment_live_feedback.xml b/face/capture/src/main/res/layout-land/fragment_live_feedback.xml index 1f95b141c0..78bff808de 100644 --- a/face/capture/src/main/res/layout-land/fragment_live_feedback.xml +++ b/face/capture/src/main/res/layout-land/fragment_live_feedback.xml @@ -8,6 +8,24 @@ tools:background="#66000000" tools:ignore="ContentDescription"> + + + + + + diff --git a/face/capture/src/main/res/layout/fragment_live_feedback_auto_capture.xml b/face/capture/src/main/res/layout/fragment_live_feedback_auto_capture.xml index 179d0a180b..6f748f7d76 100644 --- a/face/capture/src/main/res/layout/fragment_live_feedback_auto_capture.xml +++ b/face/capture/src/main/res/layout/fragment_live_feedback_auto_capture.xml @@ -87,4 +87,22 @@ app:layout_constraintTop_toBottomOf="@id/capture_feedback_txt_explanation" tools:visibility="visible" /> + + diff --git a/infra/resources/src/main/res/values/strings.xml b/infra/resources/src/main/res/values/strings.xml index cf4981f5d7..3164eb6c24 100644 --- a/infra/resources/src/main/res/values/strings.xml +++ b/infra/resources/src/main/res/values/strings.xml @@ -172,6 +172,7 @@ Live Capture Preparation Start capture + Instructions Preparing to scan No face detected Make sure the face fills the circle From da36805bcd42b4bf180906d99f53c289d82da108 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 22 Apr 2025 16:13:50 +0100 Subject: [PATCH 2/5] MS-862 Instructions button on the face Capture screen: navigation --- .../screens/livefeedback/LiveFeedbackFragment.kt | 7 +++++++ .../LiveFeedbackAutoCaptureFragment.kt | 11 +++++++++-- .../navigation/graph_face_capture_auto_internal.xml | 5 +++++ .../res/navigation/graph_face_capture_internal.xml | 5 +++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedback/LiveFeedbackFragment.kt b/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedback/LiveFeedbackFragment.kt index 55691b6269..3b75d0684f 100644 --- a/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedback/LiveFeedbackFragment.kt +++ b/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedback/LiveFeedbackFragment.kt @@ -96,6 +96,13 @@ internal class LiveFeedbackFragment : Fragment(R.layout.fragment_live_feedback) vm.initCapture(mainVm.samplesToCapture, mainVm.attemptNumber) } } + + binding.captureInstructionsBtn.setOnClickListener { + findNavController().navigateSafely( + currentFragment = this, + directions = LiveFeedbackFragmentDirections.actionFaceLiveFeedbackFragmentToFacePreparationFragment(), + ) + } } /** Initialize CameraX, and prepare to bind the camera use cases */ diff --git a/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedbackautocapture/LiveFeedbackAutoCaptureFragment.kt b/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedbackautocapture/LiveFeedbackAutoCaptureFragment.kt index 4cefc2a5eb..4ed667846a 100644 --- a/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedbackautocapture/LiveFeedbackAutoCaptureFragment.kt +++ b/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedbackautocapture/LiveFeedbackAutoCaptureFragment.kt @@ -27,7 +27,7 @@ import com.simprints.core.domain.permission.PermissionStatus import com.simprints.core.tools.extentions.hasPermission import com.simprints.core.tools.extentions.permissionFromResult import com.simprints.face.capture.R -import com.simprints.face.capture.databinding.FragmentLiveFeedbackBinding +import com.simprints.face.capture.databinding.FragmentLiveFeedbackAutoCaptureBinding import com.simprints.face.capture.models.FaceDetection import com.simprints.face.capture.screens.FaceCaptureViewModel import com.simprints.face.capture.screens.livefeedback.CropToTargetOverlayAnalyzer @@ -56,7 +56,7 @@ internal class LiveFeedbackAutoCaptureFragment : Fragment(R.layout.fragment_live private val mainVm: FaceCaptureViewModel by activityViewModels() private val vm: LiveFeedbackAutoCaptureFragmentViewModel by viewModels() - private val binding by viewBinding(FragmentLiveFeedbackBinding::bind) + private val binding by viewBinding(FragmentLiveFeedbackAutoCaptureBinding::bind) private lateinit var screenSize: Size private lateinit var targetResolution: Size @@ -96,6 +96,13 @@ internal class LiveFeedbackAutoCaptureFragment : Fragment(R.layout.fragment_live vm.initCapture(mainVm.samplesToCapture, mainVm.attemptNumber) } } + + binding.captureInstructionsBtn.setOnClickListener { + findNavController().navigateSafely( + currentFragment = this, + directions = LiveFeedbackAutoCaptureFragmentDirections.actionFaceLiveFeedbackFragmentToFacePreparationFragment(), + ) + } } /** Initialize CameraX, and prepare to bind the camera use cases */ diff --git a/face/capture/src/main/res/navigation/graph_face_capture_auto_internal.xml b/face/capture/src/main/res/navigation/graph_face_capture_auto_internal.xml index e01cb708a7..129be9d9cd 100644 --- a/face/capture/src/main/res/navigation/graph_face_capture_auto_internal.xml +++ b/face/capture/src/main/res/navigation/graph_face_capture_auto_internal.xml @@ -27,6 +27,11 @@ app:destination="@id/faceConfirmationFragment" app:popUpTo="@+id/graph_face_capture_auto_internal" app:popUpToInclusive="true" /> + + Date: Tue, 22 Apr 2025 16:16:52 +0100 Subject: [PATCH 3/5] MS-862 Skipping the Preparation (Instructions) screen after the 1st time --- .../capture/screens/FaceCaptureViewModel.kt | 5 ++ .../FaceCaptureControllerFragment.kt | 12 ++++- ...ffPreparationInstructionsShowingUseCase.kt | 29 ++++++++++ .../screens/FaceCaptureViewModelTest.kt | 29 ++++++++++ ...eparationInstructionsShowingUseCaseTest.kt | 53 +++++++++++++++++++ 5 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 face/capture/src/main/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCase.kt create mode 100644 face/capture/src/test/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCaseTest.kt diff --git a/face/capture/src/main/java/com/simprints/face/capture/screens/FaceCaptureViewModel.kt b/face/capture/src/main/java/com/simprints/face/capture/screens/FaceCaptureViewModel.kt index 178a7b573f..3c12ff2f16 100644 --- a/face/capture/src/main/java/com/simprints/face/capture/screens/FaceCaptureViewModel.kt +++ b/face/capture/src/main/java/com/simprints/face/capture/screens/FaceCaptureViewModel.kt @@ -13,6 +13,7 @@ import com.simprints.core.tools.time.Timestamp import com.simprints.face.capture.FaceCaptureResult import com.simprints.face.capture.models.FaceDetection import com.simprints.face.capture.usecases.BitmapToByteArrayUseCase +import com.simprints.face.capture.usecases.GetAndTurnOffPreparationInstructionsShowingUseCase import com.simprints.face.capture.usecases.IsUsingAutoCaptureUseCase import com.simprints.face.capture.usecases.SaveFaceImageUseCase import com.simprints.face.capture.usecases.SimpleCaptureEventReporter @@ -51,6 +52,7 @@ internal class FaceCaptureViewModel @Inject constructor( private val resolveFaceBioSdk: ResolveFaceBioSdkUseCase, private val saveLicenseCheckEvent: SaveLicenseCheckEventUseCase, private val isUsingAutoCapture: IsUsingAutoCaptureUseCase, + private val getAndTurnOffPreparationInstructionsShowing: GetAndTurnOffPreparationInstructionsShowingUseCase, @DeviceID private val deviceID: String, ) : ViewModel() { // Updated in live feedback screen @@ -134,6 +136,9 @@ internal class FaceCaptureViewModel @Inject constructor( _isAutoCaptureEnabled.postValue(isUsingAutoCapture()) } + fun getAndTurnOffIfPreparationInstructionsShowing(): Boolean = + getAndTurnOffPreparationInstructionsShowing() + private suspend fun initialize( activity: Activity, license: License, diff --git a/face/capture/src/main/java/com/simprints/face/capture/screens/controller/FaceCaptureControllerFragment.kt b/face/capture/src/main/java/com/simprints/face/capture/screens/controller/FaceCaptureControllerFragment.kt index fffe77c9c1..1da4039f9c 100644 --- a/face/capture/src/main/java/com/simprints/face/capture/screens/controller/FaceCaptureControllerFragment.kt +++ b/face/capture/src/main/java/com/simprints/face/capture/screens/controller/FaceCaptureControllerFragment.kt @@ -119,13 +119,23 @@ internal class FaceCaptureControllerFragment : Fragment(R.layout.fragment_face_c viewModel.setupAutoCapture() viewModel.isAutoCaptureEnabled.observe(viewLifecycleOwner) { isAutoCaptureEnabled -> - internalNavController?.setGraph( + val graph = internalNavController?.navInflater?.inflate( if (isAutoCaptureEnabled) { R.navigation.graph_face_capture_auto_internal } else { R.navigation.graph_face_capture_internal }, ) + graph?.setStartDestination( + if (viewModel.getAndTurnOffIfPreparationInstructionsShowing()) { + R.id.facePreparationFragment + } else { + R.id.faceLiveFeedbackFragment + } + ) + graph?.let { + internalNavController?.setGraph(graph, null) + } } } diff --git a/face/capture/src/main/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCase.kt b/face/capture/src/main/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCase.kt new file mode 100644 index 0000000000..f3d71a5b7e --- /dev/null +++ b/face/capture/src/main/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCase.kt @@ -0,0 +1,29 @@ +package com.simprints.face.capture.usecases + +import androidx.annotation.VisibleForTesting +import com.simprints.infra.security.SecurityManager +import javax.inject.Inject +import javax.inject.Singleton +import androidx.core.content.edit + +@Singleton +class GetAndTurnOffPreparationInstructionsShowingUseCase @Inject constructor( + private val securityManager: SecurityManager, +) { + operator fun invoke(): Boolean { + val sharedPrefs = securityManager.buildEncryptedSharedPreferences(FILENAME_FOR_INSTRUCTIONS_SHOWING_SHARED_PREFS) + val areInstructionsShowing = sharedPrefs.getBoolean(INSTRUCTIONS_SHOWING_PREFERENCE_KEY, true) + if (areInstructionsShowing) { + sharedPrefs.edit { + putBoolean(INSTRUCTIONS_SHOWING_PREFERENCE_KEY, false) + } + } + return areInstructionsShowing + } + + companion object { + private const val FILENAME_FOR_INSTRUCTIONS_SHOWING_SHARED_PREFS = "INSTRUCTIONS_SHOWING" + @VisibleForTesting + const val INSTRUCTIONS_SHOWING_PREFERENCE_KEY = "preference_instructions_showing" + } +} diff --git a/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt b/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt index 65d011f544..107a5dacd9 100644 --- a/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt +++ b/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt @@ -5,6 +5,7 @@ import com.google.common.truth.Truth.assertThat import com.simprints.core.tools.time.Timestamp import com.simprints.face.capture.models.FaceDetection import com.simprints.face.capture.usecases.BitmapToByteArrayUseCase +import com.simprints.face.capture.usecases.GetAndTurnOffPreparationInstructionsShowingUseCase import com.simprints.face.capture.usecases.IsUsingAutoCaptureUseCase import com.simprints.face.capture.usecases.SaveFaceImageUseCase import com.simprints.face.capture.usecases.SimpleCaptureEventReporter @@ -72,6 +73,9 @@ class FaceCaptureViewModelTest { @MockK private lateinit var isUsingAutoCapture: IsUsingAutoCaptureUseCase + @MockK + private lateinit var getAndTurnOffPreparationInstructionsShowing: GetAndTurnOffPreparationInstructionsShowingUseCase + private lateinit var viewModel: FaceCaptureViewModel private val faceDetections = listOf( @@ -100,6 +104,7 @@ class FaceCaptureViewModelTest { }, saveLicenseCheckEvent, isUsingAutoCapture, + getAndTurnOffPreparationInstructionsShowing, "deviceId", ) } @@ -302,6 +307,30 @@ class FaceCaptureViewModelTest { assertThat(viewModel.isAutoCaptureEnabled.getOrAwaitValue()).isFalse() } + @Test + fun `preparation instructions screen should be set to showing according to its use case`() { + // Given + coEvery { getAndTurnOffPreparationInstructionsShowing() } returns true + + // When + val isShowing = viewModel.getAndTurnOffIfPreparationInstructionsShowing() + + // Then + assertThat(isShowing).isTrue() + } + + @Test + fun `preparation instructions screen should be set to not showing according to its use case`() { + // Given + coEvery { getAndTurnOffPreparationInstructionsShowing() } returns false + + // When + val isShowing = viewModel.getAndTurnOffIfPreparationInstructionsShowing() + + // Then + assertThat(isShowing).isFalse() + } + @Test fun `test initFaceBioSdk should return error when re-download fails`() { // Given diff --git a/face/capture/src/test/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCaseTest.kt b/face/capture/src/test/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCaseTest.kt new file mode 100644 index 0000000000..c40b762ccd --- /dev/null +++ b/face/capture/src/test/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCaseTest.kt @@ -0,0 +1,53 @@ +package com.simprints.face.capture.usecases + +import android.content.SharedPreferences +import com.simprints.face.capture.usecases.GetAndTurnOffPreparationInstructionsShowingUseCase.Companion.INSTRUCTIONS_SHOWING_PREFERENCE_KEY +import com.simprints.infra.security.SecurityManager +import io.mockk.* +import io.mockk.impl.annotations.MockK +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test + +class GetAndTurnOffPreparationInstructionsShowingUseCaseTest { + + @MockK + private lateinit var securityManager: SecurityManager + + @MockK + private lateinit var prefs: SharedPreferences + + private lateinit var getAndTurnOffPreparationInstructionsShowing: GetAndTurnOffPreparationInstructionsShowingUseCase + + @Before + fun setup() { + MockKAnnotations.init(this, relaxed = true) + every { securityManager.buildEncryptedSharedPreferences(any()) } returns prefs + + getAndTurnOffPreparationInstructionsShowing = GetAndTurnOffPreparationInstructionsShowingUseCase(securityManager) + } + + @Test + fun `should return true and write false to preferences when instructions are showing`() = runTest { + every { prefs.getBoolean(INSTRUCTIONS_SHOWING_PREFERENCE_KEY, any()) } returns true + val editor = mockk(relaxed = true) + every { prefs.edit() } returns editor + + val result = getAndTurnOffPreparationInstructionsShowing() + + assertTrue(result) + verify { editor.putBoolean(INSTRUCTIONS_SHOWING_PREFERENCE_KEY, false) } + } + + @Test + fun `should return false and not write to preferences when instructions are not showing`() = runTest { + every { prefs.getBoolean(INSTRUCTIONS_SHOWING_PREFERENCE_KEY, any()) } returns false + + val result = getAndTurnOffPreparationInstructionsShowing() + + assertFalse(result) + verify(exactly = 0) { prefs.edit() } + } +} From 81505b408ddb118b2fb337e1bf1e80cd004ec9b9 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 6 May 2025 16:19:28 +0100 Subject: [PATCH 4/5] MS-862 Simpler name for instructions screen showing use case --- .../face/capture/screens/FaceCaptureViewModel.kt | 8 ++++---- .../controller/FaceCaptureControllerFragment.kt | 2 +- ...ase.kt => ShouldShowInstructionsScreenUseCase.kt} | 2 +- .../face/capture/screens/FaceCaptureViewModelTest.kt | 10 +++++----- ...kt => ShouldShowInstructionsScreenUseCaseTest.kt} | 12 ++++++------ 5 files changed, 17 insertions(+), 17 deletions(-) rename face/capture/src/main/java/com/simprints/face/capture/usecases/{GetAndTurnOffPreparationInstructionsShowingUseCase.kt => ShouldShowInstructionsScreenUseCase.kt} (92%) rename face/capture/src/test/java/com/simprints/face/capture/usecases/{GetAndTurnOffPreparationInstructionsShowingUseCaseTest.kt => ShouldShowInstructionsScreenUseCaseTest.kt} (70%) diff --git a/face/capture/src/main/java/com/simprints/face/capture/screens/FaceCaptureViewModel.kt b/face/capture/src/main/java/com/simprints/face/capture/screens/FaceCaptureViewModel.kt index 3c12ff2f16..c0a2577e8f 100644 --- a/face/capture/src/main/java/com/simprints/face/capture/screens/FaceCaptureViewModel.kt +++ b/face/capture/src/main/java/com/simprints/face/capture/screens/FaceCaptureViewModel.kt @@ -13,7 +13,7 @@ import com.simprints.core.tools.time.Timestamp import com.simprints.face.capture.FaceCaptureResult import com.simprints.face.capture.models.FaceDetection import com.simprints.face.capture.usecases.BitmapToByteArrayUseCase -import com.simprints.face.capture.usecases.GetAndTurnOffPreparationInstructionsShowingUseCase +import com.simprints.face.capture.usecases.ShouldShowInstructionsScreenUseCase import com.simprints.face.capture.usecases.IsUsingAutoCaptureUseCase import com.simprints.face.capture.usecases.SaveFaceImageUseCase import com.simprints.face.capture.usecases.SimpleCaptureEventReporter @@ -52,7 +52,7 @@ internal class FaceCaptureViewModel @Inject constructor( private val resolveFaceBioSdk: ResolveFaceBioSdkUseCase, private val saveLicenseCheckEvent: SaveLicenseCheckEventUseCase, private val isUsingAutoCapture: IsUsingAutoCaptureUseCase, - private val getAndTurnOffPreparationInstructionsShowing: GetAndTurnOffPreparationInstructionsShowingUseCase, + private val shouldShowInstructionsScreen: ShouldShowInstructionsScreenUseCase, @DeviceID private val deviceID: String, ) : ViewModel() { // Updated in live feedback screen @@ -136,8 +136,8 @@ internal class FaceCaptureViewModel @Inject constructor( _isAutoCaptureEnabled.postValue(isUsingAutoCapture()) } - fun getAndTurnOffIfPreparationInstructionsShowing(): Boolean = - getAndTurnOffPreparationInstructionsShowing() + fun shouldShowInstructionsScreen(): Boolean = + shouldShowInstructionsScreen() private suspend fun initialize( activity: Activity, diff --git a/face/capture/src/main/java/com/simprints/face/capture/screens/controller/FaceCaptureControllerFragment.kt b/face/capture/src/main/java/com/simprints/face/capture/screens/controller/FaceCaptureControllerFragment.kt index 1da4039f9c..011f403c81 100644 --- a/face/capture/src/main/java/com/simprints/face/capture/screens/controller/FaceCaptureControllerFragment.kt +++ b/face/capture/src/main/java/com/simprints/face/capture/screens/controller/FaceCaptureControllerFragment.kt @@ -127,7 +127,7 @@ internal class FaceCaptureControllerFragment : Fragment(R.layout.fragment_face_c }, ) graph?.setStartDestination( - if (viewModel.getAndTurnOffIfPreparationInstructionsShowing()) { + if (viewModel.shouldShowInstructionsScreen()) { R.id.facePreparationFragment } else { R.id.faceLiveFeedbackFragment diff --git a/face/capture/src/main/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCase.kt b/face/capture/src/main/java/com/simprints/face/capture/usecases/ShouldShowInstructionsScreenUseCase.kt similarity index 92% rename from face/capture/src/main/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCase.kt rename to face/capture/src/main/java/com/simprints/face/capture/usecases/ShouldShowInstructionsScreenUseCase.kt index f3d71a5b7e..1e29419e62 100644 --- a/face/capture/src/main/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCase.kt +++ b/face/capture/src/main/java/com/simprints/face/capture/usecases/ShouldShowInstructionsScreenUseCase.kt @@ -7,7 +7,7 @@ import javax.inject.Singleton import androidx.core.content.edit @Singleton -class GetAndTurnOffPreparationInstructionsShowingUseCase @Inject constructor( +class ShouldShowInstructionsScreenUseCase @Inject constructor( private val securityManager: SecurityManager, ) { operator fun invoke(): Boolean { diff --git a/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt b/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt index 107a5dacd9..49bc605145 100644 --- a/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt +++ b/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt @@ -5,7 +5,7 @@ import com.google.common.truth.Truth.assertThat import com.simprints.core.tools.time.Timestamp import com.simprints.face.capture.models.FaceDetection import com.simprints.face.capture.usecases.BitmapToByteArrayUseCase -import com.simprints.face.capture.usecases.GetAndTurnOffPreparationInstructionsShowingUseCase +import com.simprints.face.capture.usecases.ShouldShowInstructionsScreenUseCase import com.simprints.face.capture.usecases.IsUsingAutoCaptureUseCase import com.simprints.face.capture.usecases.SaveFaceImageUseCase import com.simprints.face.capture.usecases.SimpleCaptureEventReporter @@ -74,7 +74,7 @@ class FaceCaptureViewModelTest { private lateinit var isUsingAutoCapture: IsUsingAutoCaptureUseCase @MockK - private lateinit var getAndTurnOffPreparationInstructionsShowing: GetAndTurnOffPreparationInstructionsShowingUseCase + private lateinit var shouldShowInstructionsScreen: ShouldShowInstructionsScreenUseCase private lateinit var viewModel: FaceCaptureViewModel @@ -104,7 +104,7 @@ class FaceCaptureViewModelTest { }, saveLicenseCheckEvent, isUsingAutoCapture, - getAndTurnOffPreparationInstructionsShowing, + shouldShowInstructionsScreen, "deviceId", ) } @@ -310,10 +310,10 @@ class FaceCaptureViewModelTest { @Test fun `preparation instructions screen should be set to showing according to its use case`() { // Given - coEvery { getAndTurnOffPreparationInstructionsShowing() } returns true + coEvery { shouldShowInstructionsScreen() } returns true // When - val isShowing = viewModel.getAndTurnOffIfPreparationInstructionsShowing() + val isShowing = viewModel.shouldShowInstructionsScreen() // Then assertThat(isShowing).isTrue() diff --git a/face/capture/src/test/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCaseTest.kt b/face/capture/src/test/java/com/simprints/face/capture/usecases/ShouldShowInstructionsScreenUseCaseTest.kt similarity index 70% rename from face/capture/src/test/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCaseTest.kt rename to face/capture/src/test/java/com/simprints/face/capture/usecases/ShouldShowInstructionsScreenUseCaseTest.kt index c40b762ccd..cbc932ec1b 100644 --- a/face/capture/src/test/java/com/simprints/face/capture/usecases/GetAndTurnOffPreparationInstructionsShowingUseCaseTest.kt +++ b/face/capture/src/test/java/com/simprints/face/capture/usecases/ShouldShowInstructionsScreenUseCaseTest.kt @@ -1,7 +1,7 @@ package com.simprints.face.capture.usecases import android.content.SharedPreferences -import com.simprints.face.capture.usecases.GetAndTurnOffPreparationInstructionsShowingUseCase.Companion.INSTRUCTIONS_SHOWING_PREFERENCE_KEY +import com.simprints.face.capture.usecases.ShouldShowInstructionsScreenUseCase.Companion.INSTRUCTIONS_SHOWING_PREFERENCE_KEY import com.simprints.infra.security.SecurityManager import io.mockk.* import io.mockk.impl.annotations.MockK @@ -11,7 +11,7 @@ import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test -class GetAndTurnOffPreparationInstructionsShowingUseCaseTest { +class ShouldShowInstructionsScreenUseCaseTest { @MockK private lateinit var securityManager: SecurityManager @@ -19,14 +19,14 @@ class GetAndTurnOffPreparationInstructionsShowingUseCaseTest { @MockK private lateinit var prefs: SharedPreferences - private lateinit var getAndTurnOffPreparationInstructionsShowing: GetAndTurnOffPreparationInstructionsShowingUseCase + private lateinit var shouldShowInstructionsScreen: ShouldShowInstructionsScreenUseCase @Before fun setup() { MockKAnnotations.init(this, relaxed = true) every { securityManager.buildEncryptedSharedPreferences(any()) } returns prefs - getAndTurnOffPreparationInstructionsShowing = GetAndTurnOffPreparationInstructionsShowingUseCase(securityManager) + shouldShowInstructionsScreen = ShouldShowInstructionsScreenUseCase(securityManager) } @Test @@ -35,7 +35,7 @@ class GetAndTurnOffPreparationInstructionsShowingUseCaseTest { val editor = mockk(relaxed = true) every { prefs.edit() } returns editor - val result = getAndTurnOffPreparationInstructionsShowing() + val result = shouldShowInstructionsScreen() assertTrue(result) verify { editor.putBoolean(INSTRUCTIONS_SHOWING_PREFERENCE_KEY, false) } @@ -45,7 +45,7 @@ class GetAndTurnOffPreparationInstructionsShowingUseCaseTest { fun `should return false and not write to preferences when instructions are not showing`() = runTest { every { prefs.getBoolean(INSTRUCTIONS_SHOWING_PREFERENCE_KEY, any()) } returns false - val result = getAndTurnOffPreparationInstructionsShowing() + val result = shouldShowInstructionsScreen() assertFalse(result) verify(exactly = 0) { prefs.edit() } From 38a0c315ea9c2fb7237bcff1913de55459d204e8 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 8 May 2025 12:23:50 +0100 Subject: [PATCH 5/5] MS-862 Redundant test cleanup for instructions screen showing --- .../face/capture/screens/FaceCaptureViewModel.kt | 4 ++-- .../face/capture/screens/FaceCaptureViewModelTest.kt | 12 ------------ 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/face/capture/src/main/java/com/simprints/face/capture/screens/FaceCaptureViewModel.kt b/face/capture/src/main/java/com/simprints/face/capture/screens/FaceCaptureViewModel.kt index c0a2577e8f..610574bd57 100644 --- a/face/capture/src/main/java/com/simprints/face/capture/screens/FaceCaptureViewModel.kt +++ b/face/capture/src/main/java/com/simprints/face/capture/screens/FaceCaptureViewModel.kt @@ -52,7 +52,7 @@ internal class FaceCaptureViewModel @Inject constructor( private val resolveFaceBioSdk: ResolveFaceBioSdkUseCase, private val saveLicenseCheckEvent: SaveLicenseCheckEventUseCase, private val isUsingAutoCapture: IsUsingAutoCaptureUseCase, - private val shouldShowInstructionsScreen: ShouldShowInstructionsScreenUseCase, + private val shouldShowInstructions: ShouldShowInstructionsScreenUseCase, @DeviceID private val deviceID: String, ) : ViewModel() { // Updated in live feedback screen @@ -137,7 +137,7 @@ internal class FaceCaptureViewModel @Inject constructor( } fun shouldShowInstructionsScreen(): Boolean = - shouldShowInstructionsScreen() + shouldShowInstructions() private suspend fun initialize( activity: Activity, diff --git a/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt b/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt index 49bc605145..8e6c15ab60 100644 --- a/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt +++ b/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt @@ -319,18 +319,6 @@ class FaceCaptureViewModelTest { assertThat(isShowing).isTrue() } - @Test - fun `preparation instructions screen should be set to not showing according to its use case`() { - // Given - coEvery { getAndTurnOffPreparationInstructionsShowing() } returns false - - // When - val isShowing = viewModel.getAndTurnOffIfPreparationInstructionsShowing() - - // Then - assertThat(isShowing).isFalse() - } - @Test fun `test initFaceBioSdk should return error when re-download fails`() { // Given