From 028feeac21597ed8a9aab469e4b9137e6d5fc7db Mon Sep 17 00:00:00 2001 From: alexandr Date: Wed, 19 Jun 2024 15:43:48 +0300 Subject: [PATCH 1/9] [MS-491] Adding the limit to the amount of the 'No finger detected' scans. Capture state is refactored to have common classes that represent the scan process under a single parent class --- .../resources/CaptureStateResources.kt | 32 ++--- .../capture/resources/FingerStateResources.kt | 28 ++--- .../screen/FingerprintCaptureFragment.kt | 2 +- .../screen/FingerprintCaptureViewModel.kt | 83 ++++++++----- .../fingerprint/capture/state/CaptureState.kt | 113 +++++++++++++----- .../usecase/AddCaptureEventsUseCase.kt | 8 +- .../capture/usecase/SaveImageUseCase.kt | 2 +- .../views/fingerviewpager/FingerFragment.kt | 8 +- .../store/models/FingerprintConfiguration.kt | 4 +- 9 files changed, 177 insertions(+), 103 deletions(-) diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/resources/CaptureStateResources.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/resources/CaptureStateResources.kt index c995358d35..c4d3eb3dd4 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/resources/CaptureStateResources.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/resources/CaptureStateResources.kt @@ -10,12 +10,12 @@ import com.simprints.infra.uibase.annotations.ExcludedFromGeneratedTestCoverageR @StringRes internal fun CaptureState.buttonTextId(isAskingRescan: Boolean): Int = when (this) { is CaptureState.NotCollected -> R.string.fingerprint_capture_scan - is CaptureState.Scanning -> R.string.fingerprint_capture_cancel_button - is CaptureState.TransferringImage -> R.string.fingerprint_capture_please_wait + is CaptureState.ScanProcess.Scanning -> R.string.fingerprint_capture_cancel_button + is CaptureState.ScanProcess.TransferringImage -> R.string.fingerprint_capture_please_wait is CaptureState.Skipped, - is CaptureState.NotDetected -> R.string.fingerprint_capture_rescan + is CaptureState.ScanProcess.NotDetected -> R.string.fingerprint_capture_rescan - is CaptureState.Collected -> if (scanResult.isGoodScan()) { + is CaptureState.ScanProcess.Collected -> if (scanResult.isGoodScan()) { if (isAskingRescan) { R.string.fingerprint_capture_rescan_question } else { @@ -30,13 +30,13 @@ internal fun CaptureState.buttonTextId(isAskingRescan: Boolean): Int = when (thi @ColorRes internal fun CaptureState.buttonBackgroundColour(): Int = when (this) { is CaptureState.NotCollected -> R.color.simprints_grey - is CaptureState.Scanning, - is CaptureState.TransferringImage -> R.color.simprints_blue + is CaptureState.ScanProcess.Scanning, + is CaptureState.ScanProcess.TransferringImage -> R.color.simprints_blue is CaptureState.Skipped, - is CaptureState.NotDetected -> R.color.simprints_red + is CaptureState.ScanProcess.NotDetected -> R.color.simprints_red - is CaptureState.Collected -> if (scanResult.isGoodScan()) { + is CaptureState.ScanProcess.Collected -> if (scanResult.isGoodScan()) { R.color.simprints_green } else { R.color.simprints_red @@ -47,16 +47,16 @@ internal fun CaptureState.buttonBackgroundColour(): Int = when (this) { @StringRes internal fun CaptureState.resultTextId(): Int = when (this) { is CaptureState.NotCollected -> R.string.fingerprint_capture_empty - is CaptureState.Scanning -> R.string.fingerprint_capture_empty - is CaptureState.TransferringImage -> if (scanResult.isGoodScan()) { + is CaptureState.ScanProcess.Scanning -> R.string.fingerprint_capture_empty + is CaptureState.ScanProcess.TransferringImage -> if (scanResult.isGoodScan()) { R.string.fingerprint_capture_good_scan_message } else { R.string.fingerprint_capture_poor_scan_message } is CaptureState.Skipped -> R.string.fingerprint_capture_finger_skipped_message - is CaptureState.NotDetected -> R.string.fingerprint_capture_no_finger_detected_message - is CaptureState.Collected -> if (scanResult.isGoodScan()) { + is CaptureState.ScanProcess.NotDetected -> R.string.fingerprint_capture_no_finger_detected_message + is CaptureState.ScanProcess.Collected -> if (scanResult.isGoodScan()) { R.string.fingerprint_capture_good_scan_message } else { R.string.fingerprint_capture_poor_scan_message @@ -67,18 +67,18 @@ internal fun CaptureState.resultTextId(): Int = when (this) { @ColorRes internal fun CaptureState.resultTextColour(): Int = when (this) { is CaptureState.NotCollected, - is CaptureState.Scanning -> android.R.color.white + is CaptureState.ScanProcess.Scanning -> android.R.color.white - is CaptureState.TransferringImage -> if (scanResult.isGoodScan()) { + is CaptureState.ScanProcess.TransferringImage -> if (scanResult.isGoodScan()) { R.color.simprints_green } else { R.color.simprints_red } is CaptureState.Skipped, - is CaptureState.NotDetected -> R.color.simprints_red + is CaptureState.ScanProcess.NotDetected -> R.color.simprints_red - is CaptureState.Collected -> if (scanResult.isGoodScan()) { + is CaptureState.ScanProcess.Collected -> if (scanResult.isGoodScan()) { R.color.simprints_green } else { R.color.simprints_red diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/resources/FingerStateResources.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/resources/FingerStateResources.kt index faf8c25318..89c1b3f4ce 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/resources/FingerStateResources.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/resources/FingerStateResources.kt @@ -18,14 +18,14 @@ internal fun FingerState.indicatorDrawableId(selected: Boolean): Int = @DrawableRes internal fun FingerState.indicatorSelectedDrawableId(): Int = when (this.currentCapture()) { is CaptureState.NotCollected, - is CaptureState.Scanning, - is CaptureState.TransferringImage -> R.drawable.blank_selected + is CaptureState.ScanProcess.Scanning, + is CaptureState.ScanProcess.TransferringImage -> R.drawable.blank_selected is CaptureState.Skipped, - is CaptureState.NotDetected -> R.drawable.alert_selected + is CaptureState.ScanProcess.NotDetected -> R.drawable.alert_selected - is CaptureState.Collected -> when { - captures.all { it is CaptureState.Collected && it.scanResult.isGoodScan() } -> R.drawable.ok_selected + is CaptureState.ScanProcess.Collected -> when { + captures.all { it is CaptureState.ScanProcess.Collected && it.scanResult.isGoodScan() } -> R.drawable.ok_selected captures.any { it is CaptureState.NotCollected } -> R.drawable.blank_selected else -> R.drawable.alert_selected } @@ -35,14 +35,14 @@ internal fun FingerState.indicatorSelectedDrawableId(): Int = when (this.current @DrawableRes internal fun FingerState.indicatorDeselectedDrawableId(): Int = when (this.currentCapture()) { is CaptureState.NotCollected, - is CaptureState.Scanning, - is CaptureState.TransferringImage -> R.drawable.blank_deselected + is CaptureState.ScanProcess.Scanning, + is CaptureState.ScanProcess.TransferringImage -> R.drawable.blank_deselected is CaptureState.Skipped, - is CaptureState.NotDetected -> R.drawable.alert_deselected + is CaptureState.ScanProcess.NotDetected -> R.drawable.alert_deselected - is CaptureState.Collected -> when { - captures.all { it is CaptureState.Collected && it.scanResult.isGoodScan() } -> R.drawable.ok_deselected + is CaptureState.ScanProcess.Collected -> when { + captures.all { it is CaptureState.ScanProcess.Collected && it.scanResult.isGoodScan() } -> R.drawable.ok_deselected captures.any { it is CaptureState.NotCollected } -> R.drawable.blank_deselected else -> R.drawable.alert_deselected } @@ -62,11 +62,11 @@ internal fun FingerState.captureNumberTextId(): Int = IDR.string.fingerprint_cap @StringRes internal fun FingerState.directionTextId(isLastFinger: Boolean): Int = when (val currentCapture = this.currentCapture()) { is CaptureState.NotCollected -> if (currentCaptureIndex == 0) IDR.string.fingerprint_capture_please_scan else IDR.string.fingerprint_capture_please_scan_again - is CaptureState.Scanning -> IDR.string.fingerprint_capture_scanning - is CaptureState.TransferringImage -> IDR.string.fingerprint_capture_transfering_data + is CaptureState.ScanProcess.Scanning -> IDR.string.fingerprint_capture_scanning + is CaptureState.ScanProcess.TransferringImage -> IDR.string.fingerprint_capture_transfering_data is CaptureState.Skipped -> IDR.string.fingerprint_capture_good_scan_direction - is CaptureState.NotDetected -> IDR.string.fingerprint_capture_poor_scan_direction - is CaptureState.Collected -> if (currentCapture.scanResult.isGoodScan()) { + is CaptureState.ScanProcess.NotDetected -> IDR.string.fingerprint_capture_poor_scan_direction + is CaptureState.ScanProcess.Collected -> if (currentCapture.scanResult.isGoodScan()) { if (isLastFinger || currentCaptureIndex + 1 < captures.size) IDR.string.fingerprint_capture_empty else IDR.string.fingerprint_capture_good_scan_direction } else { IDR.string.fingerprint_capture_poor_scan_direction diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureFragment.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureFragment.kt index d0a9882b9d..db89e6666a 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureFragment.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureFragment.kt @@ -250,7 +250,7 @@ internal class FingerprintCaptureFragment : Fragment(R.layout.fragment_fingerpri val dialogItems = state.fingerStates.map { ConfirmFingerprintsDialog.Item( it.id, - it.captures.count { capture -> capture is CaptureState.Collected && capture.scanResult.isGoodScan() }, + it.captures.count { capture -> capture is CaptureState.ScanProcess.Collected && capture.scanResult.isGoodScan() }, it.captures.size ) } diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModel.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModel.kt index 939ea1aa6d..8e259d7b08 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModel.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModel.kt @@ -57,7 +57,6 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -import java.util.UUID import javax.inject.Inject import kotlin.math.min @@ -206,14 +205,14 @@ internal class FingerprintCaptureViewModel @Inject constructor( } when (it.currentCaptureState()) { - is CaptureState.Scanning, - is CaptureState.TransferringImage, + is CaptureState.ScanProcess.Scanning, + is CaptureState.ScanProcess.TransferringImage, -> pauseLiveFeedback() CaptureState.NotCollected, CaptureState.Skipped, - is CaptureState.NotDetected, - is CaptureState.Collected, + is CaptureState.ScanProcess.NotDetected, + is CaptureState.ScanProcess.Collected, -> { if (it.isShowingConfirmDialog) stopLiveFeedback() else startLiveFeedback(scannerManager.scanner) @@ -271,11 +270,11 @@ internal class FingerprintCaptureViewModel @Inject constructor( * */ fun progressBarTimeout() = bioSdkWrapper.scanningTimeoutMs + - if (isImageTransferRequired()) bioSdkWrapper.imageTransferTimeoutMs else 0 + if (isImageTransferRequired()) bioSdkWrapper.imageTransferTimeoutMs else 0 private fun isImageTransferRequired(): Boolean = bioSdkConfiguration.vero2?.imageSavingStrategy?.isImageTransferRequired() ?: false && - scannerManager.scanner.isImageTransferSupported() + scannerManager.scanner.isImageTransferSupported() fun updateSelectedFinger(index: Int) { viewModelScope.launch { @@ -306,7 +305,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( fun handleScanButtonPressed() { val state = state val fingerState = this.state.currentCaptureState() - if (fingerState is CaptureState.Collected && fingerState.scanResult.isGoodScan() && state.isAskingRescan.not()) { + if (fingerState is CaptureState.ScanProcess.Collected && fingerState.scanResult.isGoodScan() && state.isAskingRescan.not()) { updateState { it.copy(isAskingRescan = true) } } else { updateState { it.copy(isAskingRescan = false) } @@ -317,16 +316,16 @@ internal class FingerprintCaptureViewModel @Inject constructor( } private fun isBusyForScanning(): Boolean = with(state) { - currentCaptureState() is CaptureState.TransferringImage || isShowingConfirmDialog || isShowingSplashScreen + currentCaptureState() is CaptureState.ScanProcess.TransferringImage || isShowingConfirmDialog || isShowingSplashScreen } private fun toggleScanning() { when (state.currentCaptureState()) { - is CaptureState.Scanning -> cancelScanning() - is CaptureState.TransferringImage -> { /* do nothing */ + is CaptureState.ScanProcess.Scanning -> cancelScanning() + is CaptureState.ScanProcess.TransferringImage -> { /* do nothing */ } - is CaptureState.NotCollected, is CaptureState.Skipped, is CaptureState.NotDetected, is CaptureState.Collected -> startScanning() + is CaptureState.NotCollected, is CaptureState.Skipped, is CaptureState.ScanProcess.NotDetected, is CaptureState.ScanProcess.Collected -> startScanning() } } @@ -349,7 +348,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( bioSdkWrapper.scanningTimeoutMs.toInt(), qualityThreshold(), // is this is the last bad scan, we allow low quality extraction - tooManyBadScans(state.currentCaptureState(), plusBadScan = true) + isTooManyBadScans(state.currentCaptureState(), plusBadScan = true) ) handleCaptureSuccess(capturedFingerprint) @@ -382,7 +381,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( private fun shouldProceedToImageTransfer(quality: Int): Boolean { val isGoodScan = quality >= qualityThreshold() - val isTooManyBadScans = tooManyBadScans(state.currentCaptureState(), plusBadScan = true) + val isTooManyBadScans = isTooManyBadScans(state.currentCaptureState(), plusBadScan = true) val shouldUploadImage = when (bioSdkConfiguration.vero2?.imageSavingStrategy) { NEVER, null -> false @@ -436,7 +435,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( lastCaptureStartedAt, fingerState, qualityThreshold(), - tooManyBadScans(captureState, plusBadScan = false) + isTooManyBadScans(captureState, plusBadScan = false) ) } captureEventIds[CaptureId(fingerState.id, fingerState.currentCaptureIndex)] = payloadId @@ -445,7 +444,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( private fun saveCurrentImageIfEager() { if (bioSdkConfiguration.vero2?.imageSavingStrategy?.isEager() == true) { with(state.currentFingerState()) { - (currentCapture() as? CaptureState.Collected)?.let { capture -> + (currentCapture() as? CaptureState.ScanProcess.Collected)?.let { capture -> runBlocking { saveImageIfExists(CaptureId(id, currentCaptureIndex), capture) } @@ -472,7 +471,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( if (isScanningEndStateAchieved()) { Simber.tag(FINGER_CAPTURE.name).i("Confirm fingerprints dialog shown") updateState { it.copy(isShowingConfirmDialog = true) } - } else if (currentCaptureState().let { it is CaptureState.Collected && it.scanResult.isGoodScan() }) { + } else if (currentCaptureState().let { it is CaptureState.ScanProcess.Collected && it.scanResult.isGoodScan() }) { nudgeToNextFinger() } else { if (haveNotExceedMaximumNumberOfFingersToAutoAdd()) { @@ -533,6 +532,9 @@ internal class FingerprintCaptureViewModel @Inject constructor( _vibrate.send() updateCaptureState(CaptureState::toNotDetected) addCaptureAndBiometricEventsInSession() + if(isNumberOfNoFingerDetectedReached(state.currentCaptureState())){ + handleCaptureFinished() + } } fun handleMissingFingerButtonPressed() { @@ -551,12 +553,26 @@ internal class FingerprintCaptureViewModel @Inject constructor( private fun CollectFingerprintsState.everyActiveFingerHasSatisfiedTerminalCondition(): Boolean = fingerStates.all { captureHasSatisfiedTerminalCondition(it.currentCapture()) } - private fun tooManyBadScans(fingerState: CaptureState, plusBadScan: Boolean): Boolean = + private fun isTooManyBadScans(fingerState: CaptureState, plusBadScan: Boolean): Boolean { + val isNumberOfBadScansReached = isNumberOfBadScansReached(fingerState, plusBadScan) + val isNumberOfNoFingerDetectedReached = isNumberOfNoFingerDetectedReached(fingerState) + return isNumberOfBadScansReached || isNumberOfNoFingerDetectedReached + } + + private fun isNumberOfNoFingerDetectedReached(fingerState: CaptureState): Boolean { + val noFingerDetectedThreshold = configuration.secugenSimMatcher?.noFingerDetectedThreshold + ?: return false + + val currentNumberOfNoFingerDetectedScans = when (fingerState) { + is CaptureState.ScanProcess -> fingerState.numberOfNoFingerDetectedScans + else -> 0 + } + return noFingerDetectedThreshold > 0 && currentNumberOfNoFingerDetectedScans >= noFingerDetectedThreshold + } + + private fun isNumberOfBadScansReached(fingerState: CaptureState, plusBadScan: Boolean) = when (fingerState) { - is CaptureState.Scanning -> fingerState.numberOfBadScans - is CaptureState.TransferringImage -> fingerState.numberOfBadScans - is CaptureState.NotDetected -> fingerState.numberOfBadScans - is CaptureState.Collected -> fingerState.numberOfBadScans + is CaptureState.ScanProcess -> fingerState.numberOfBadScans else -> 0 } >= numberOfBadScansRequiredToAutoAddNewFinger - if (plusBadScan) 1 else 0 @@ -566,7 +582,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( private fun CollectFingerprintsState.weHaveTheMinimumNumberOfGoodScans(): Boolean = fingerStates.filter { val currentCapture = it.currentCapture() - currentCapture is CaptureState.Collected && currentCapture.scanResult.isGoodScan() + currentCapture is CaptureState.ScanProcess.Collected && currentCapture.scanResult.isGoodScan() }.size >= min(targetNumberOfGoodScans, numberOfOriginalFingers()) private fun CollectFingerprintsState.weHaveTheMinimumNumberOfAnyQualityScans() = @@ -576,10 +592,14 @@ internal class FingerprintCaptureViewModel @Inject constructor( private fun numberOfOriginalFingers() = originalFingerprintsToCapture.toSet().size - private fun captureHasSatisfiedTerminalCondition(captureState: CaptureState) = - captureState is CaptureState.Collected && (tooManyBadScans( + private fun captureHasSatisfiedTerminalCondition(captureState: CaptureState): Boolean { + val isCollected = captureState is CaptureState.ScanProcess.Collected && (isTooManyBadScans( captureState, plusBadScan = false - ) || captureState.scanResult.isGoodScan()) || captureState is CaptureState.Skipped + ) || captureState.scanResult.isGoodScan()) + val isSkipped = captureState is CaptureState.Skipped + val isNotDetected = isNumberOfNoFingerDetectedReached(captureState) + return isCollected || isSkipped || isNotDetected + } private fun fingerHasSatisfiedTerminalCondition(fingerState: FingerState) = fingerState.captures.all { captureHasSatisfiedTerminalCondition(it) } @@ -587,7 +607,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( fun handleConfirmFingerprintsAndContinue() { val collectedFingers = state.fingerStates.flatMap { it.captures.mapIndexedNotNull { index, capture -> - if (capture is CaptureState.Collected) Pair( + if (capture is CaptureState.ScanProcess.Collected) Pair( CaptureId(it.id, index), capture ) else null @@ -605,7 +625,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( } } - private fun saveImages(collectedFingers: List>) { + private fun saveImages(collectedFingers: List>) { runBlocking { collectedFingers.map { (id, collectedFinger) -> saveImageIfExists(id, collectedFinger) @@ -613,7 +633,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( } } - private fun proceedToFinish(collectedFingers: List>) { + private fun proceedToFinish(collectedFingers: List>) { val resultItems = collectedFingers.map { (captureId, collectedFinger) -> FingerprintCaptureResult.Item( identifier = captureId.finger, @@ -630,7 +650,10 @@ internal class FingerprintCaptureViewModel @Inject constructor( _finishWithFingerprints.send(FingerprintCaptureResult(resultItems)) } - private suspend fun saveImageIfExists(id: CaptureId, collectedFinger: CaptureState.Collected) { + private suspend fun saveImageIfExists( + id: CaptureId, + collectedFinger: CaptureState.ScanProcess.Collected + ) { val captureEventId = captureEventIds[id] val imageRef = saveImage( vero2Configuration = bioSdkConfiguration.vero2!!, diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/state/CaptureState.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/state/CaptureState.kt index 0a36e293ea..73398df63c 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/state/CaptureState.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/state/CaptureState.kt @@ -4,55 +4,104 @@ internal sealed class CaptureState { data object NotCollected : CaptureState() data object Skipped : CaptureState() - data class Scanning(val numberOfBadScans: Int = 0) : CaptureState() - data class TransferringImage(val scanResult: ScanResult, val numberOfBadScans: Int = 0) : CaptureState() - data class NotDetected(val numberOfBadScans: Int = 0) : CaptureState() - data class Collected(val scanResult: ScanResult, val numberOfBadScans: Int = 0) : CaptureState() + sealed class ScanProcess : CaptureState() { + abstract val numberOfBadScans: Int + abstract val numberOfNoFingerDetectedScans: Int - fun isCommunicating(): Boolean = this is Scanning || this is TransferringImage + data class Scanning( + override val numberOfBadScans: Int, + override val numberOfNoFingerDetectedScans: Int + ) : ScanProcess() + + data class TransferringImage( + override val numberOfBadScans: Int, + override val numberOfNoFingerDetectedScans: Int, + val scanResult: ScanResult, + ) : ScanProcess() + + data class NotDetected( + override val numberOfBadScans: Int, + override val numberOfNoFingerDetectedScans: Int + ) : ScanProcess() + + data class Collected( + override val numberOfBadScans: Int, + override val numberOfNoFingerDetectedScans: Int, + val scanResult: ScanResult + ) : ScanProcess() + + } + + fun isCommunicating(): Boolean = + this is ScanProcess.Scanning || this is ScanProcess.TransferringImage fun toNotCollected() = NotCollected fun toSkipped() = Skipped - fun toScanning(): Scanning = when (this) { - is Scanning -> Scanning(numberOfBadScans) - is TransferringImage -> Scanning(numberOfBadScans) - is NotDetected -> Scanning(numberOfBadScans) - is Collected -> Scanning(numberOfBadScans) - else -> Scanning() + fun toScanning(): ScanProcess.Scanning = when (this) { + is ScanProcess -> ScanProcess.Scanning( + numberOfBadScans = numberOfBadScans, + numberOfNoFingerDetectedScans = numberOfNoFingerDetectedScans + ) + + else -> ScanProcess.Scanning( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0 + ) } - fun toTransferringImage(scanResult: ScanResult): TransferringImage = when (this) { - is TransferringImage -> TransferringImage(scanResult, numberOfBadScans) - is Scanning -> TransferringImage(scanResult, numberOfBadScans) - is NotDetected -> TransferringImage(scanResult, numberOfBadScans) - is Collected -> TransferringImage(scanResult, numberOfBadScans) - else -> TransferringImage(scanResult) + fun toTransferringImage(scanResult: ScanResult): ScanProcess.TransferringImage = when (this) { + is ScanProcess -> ScanProcess.TransferringImage( + numberOfBadScans = numberOfBadScans, + numberOfNoFingerDetectedScans = numberOfNoFingerDetectedScans, + scanResult = scanResult + ) + + else -> ScanProcess.TransferringImage( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, + scanResult = scanResult + ) } - fun toNotDetected(): NotDetected = when (this) { - is NotDetected -> NotDetected(numberOfBadScans) - is Scanning -> NotDetected(numberOfBadScans) - is TransferringImage -> NotDetected(numberOfBadScans) - is Collected -> NotDetected(numberOfBadScans) - else -> NotDetected() + fun toNotDetected(): ScanProcess.NotDetected = when (this) { + is ScanProcess -> ScanProcess.NotDetected( + numberOfBadScans = numberOfBadScans, + numberOfNoFingerDetectedScans = numberOfNoFingerDetectedScans + 1 + ) + + else -> ScanProcess.NotDetected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0 + ) } - fun toCollected(scanResult: ScanResult): Collected = when (this) { - is Scanning -> Collected(scanResult, numberOfBadScans + incIfBadScan(scanResult)) - is TransferringImage -> Collected(scanResult, numberOfBadScans + incIfBadScan(scanResult)) - is NotDetected -> Collected(scanResult, numberOfBadScans + incIfBadScan(scanResult)) - is Collected -> Collected(scanResult, numberOfBadScans + incIfBadScan(scanResult)) - else -> Collected(scanResult, incIfBadScan(scanResult)) + fun toCollected(scanResult: ScanResult): ScanProcess.Collected = when (this) { + is ScanProcess -> ScanProcess.Collected( + numberOfBadScans = numberOfBadScans + incIfBadScan(scanResult), + numberOfNoFingerDetectedScans = numberOfNoFingerDetectedScans, + scanResult = scanResult + ) + + else -> ScanProcess.Collected( + numberOfBadScans = incIfBadScan(scanResult), + numberOfNoFingerDetectedScans = 0, + scanResult, + ) } private fun incIfBadScan(scanResult: ScanResult) = if (scanResult.isGoodScan()) 0 else 1 - fun toCollected(imageBytes: ByteArray): Collected = when (this) { - is TransferringImage -> toCollected(scanResult.copy(image = imageBytes)) - is Collected -> Collected(scanResult.copy(image = imageBytes), numberOfBadScans) + fun toCollected(imageBytes: ByteArray): ScanProcess.Collected = when (this) { + is ScanProcess.TransferringImage -> toCollected(scanResult.copy(image = imageBytes)) + is ScanProcess.Collected -> ScanProcess.Collected( + numberOfBadScans = numberOfBadScans, + numberOfNoFingerDetectedScans = numberOfNoFingerDetectedScans, + scanResult = scanResult.copy(image = imageBytes) + ) + else -> throw IllegalStateException("Illegal attempt to move to collected state without scan result") } } diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/AddCaptureEventsUseCase.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/AddCaptureEventsUseCase.kt index 7563c2c5e9..6b92773ae5 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/AddCaptureEventsUseCase.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/AddCaptureEventsUseCase.kt @@ -40,7 +40,7 @@ internal class AddCaptureEventsUseCase @Inject constructor( ) val fingerprintCaptureBiometricsEvent = - if (captureState is CaptureState.Collected && (captureEvent.payload.result == Result.GOOD_SCAN || tooManyBadScans)) + if (captureState is CaptureState.ScanProcess.Collected && (captureEvent.payload.result == Result.GOOD_SCAN || tooManyBadScans)) FingerprintCaptureBiometricsEvent( createdAt = lastCaptureStartedAt, fingerprint = mapCaptureToBiometricFingerprint( @@ -61,8 +61,8 @@ internal class AddCaptureEventsUseCase @Inject constructor( private fun mapCaptureStateToResult(captureState: CaptureState) = when (captureState) { is CaptureState.Skipped -> Result.SKIPPED - is CaptureState.NotDetected -> Result.NO_FINGER_DETECTED - is CaptureState.Collected -> if (captureState.scanResult.isGoodScan()) { + is CaptureState.ScanProcess.NotDetected -> Result.NO_FINGER_DETECTED + is CaptureState.ScanProcess.Collected -> if (captureState.scanResult.isGoodScan()) { Result.GOOD_SCAN } else { Result.BAD_QUALITY @@ -73,7 +73,7 @@ internal class AddCaptureEventsUseCase @Inject constructor( private fun mapCaptureStateToFingerprint(captureState: CaptureState, fingerState: FingerState) = captureState - .let { it as? CaptureState.Collected } + .let { it as? CaptureState.ScanProcess.Collected } ?.scanResult ?.let { FingerprintCapturePayload.Fingerprint( diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/SaveImageUseCase.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/SaveImageUseCase.kt index ec4b2b0f0e..7fe343cc71 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/SaveImageUseCase.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/SaveImageUseCase.kt @@ -22,7 +22,7 @@ internal class SaveImageUseCase @Inject constructor( vero2Configuration: Vero2Configuration, finger: IFingerIdentifier, captureEventId: String?, - collectedFinger: CaptureState.Collected, + collectedFinger: CaptureState.ScanProcess.Collected, ) = if (collectedFinger.scanResult.image != null && captureEventId != null) { saveImage( imageBytes = collectedFinger.scanResult.image, diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/fingerviewpager/FingerFragment.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/fingerviewpager/FingerFragment.kt index 3a2b1d602c..3df643acf5 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/fingerviewpager/FingerFragment.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/fingerviewpager/FingerFragment.kt @@ -141,12 +141,12 @@ internal class FingerFragment : Fragment(R.layout.fragment_finger) { ) } - is CaptureState.Scanning -> startTimeoutBar() - is CaptureState.TransferringImage -> { + is CaptureState.ScanProcess.Scanning -> startTimeoutBar() + is CaptureState.ScanProcess.TransferringImage -> { //Do nothing } - is CaptureState.NotDetected -> { + is CaptureState.ScanProcess.NotDetected -> { handleCancelled() progressBar.progressDrawable = ContextCompat.getDrawable( requireContext(), @@ -154,7 +154,7 @@ internal class FingerFragment : Fragment(R.layout.fragment_finger) { ) } - is CaptureState.Collected -> if (fingerState.scanResult.isGoodScan()) { + is CaptureState.ScanProcess.Collected -> if (fingerState.scanResult.isGoodScan()) { handleCancelled() progressBar.progressDrawable = ContextCompat.getDrawable( requireContext(), diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/models/FingerprintConfiguration.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/models/FingerprintConfiguration.kt index 5aad9da4df..ad02874acd 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/models/FingerprintConfiguration.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/models/FingerprintConfiguration.kt @@ -13,7 +13,9 @@ data class FingerprintConfiguration( val decisionPolicy: DecisionPolicy, val comparisonStrategyForVerification: FingerComparisonStrategy, val vero1: Vero1Configuration? = null, - val vero2: Vero2Configuration? = null + val vero2: Vero2Configuration? = null, + // [MS-491] Allowed amount of 'No Finger Detected' scans before proceeding further + val noFingerDetectedThreshold: Int? = null ) enum class VeroGeneration { From 1558e88c0c103d9c64eb3124c0ac66172eab9c05 Mon Sep 17 00:00:00 2001 From: alexandr Date: Mon, 22 Jul 2024 15:43:23 +0300 Subject: [PATCH 2/9] [MS-491] Moving the calculatuon of the 'No Finger Detected' limit into the use-case file --- .../screen/FingerprintCaptureViewModel.kt | 21 +++++---------- .../IsNoFingerDetectedLimitReachedUseCase.kt | 26 +++++++++++++++++++ .../store/local/ConfigLocalDataSourceImpl.kt | 1 + .../migrations/models/OldProjectConfig.kt | 1 + .../local/models/FingerprintConfiguration.kt | 16 ++++++++---- .../store/models/FingerprintConfiguration.kt | 6 +++-- .../config/store/models/MaxCaptureAttempts.kt | 5 ++++ .../models/ApiFingerprintConfiguration.kt | 15 ++++++----- .../remote/models/ApiMaxCaptureAttempts.kt | 13 ++++++++++ .../src/main/proto/project_config.proto | 4 +++ 10 files changed, 79 insertions(+), 29 deletions(-) create mode 100644 fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCase.kt create mode 100644 infra/config-store/src/main/java/com/simprints/infra/config/store/models/MaxCaptureAttempts.kt create mode 100644 infra/config-store/src/main/java/com/simprints/infra/config/store/remote/models/ApiMaxCaptureAttempts.kt diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModel.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModel.kt index 8e259d7b08..b054cbcba4 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModel.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModel.kt @@ -27,6 +27,7 @@ import com.simprints.fingerprint.capture.state.ScanResult import com.simprints.fingerprint.capture.usecase.AddCaptureEventsUseCase import com.simprints.fingerprint.capture.usecase.GetNextFingerToAddUseCase import com.simprints.fingerprint.capture.usecase.GetStartStateUseCase +import com.simprints.fingerprint.capture.usecase.IsNoFingerDetectedLimitReachedUseCase import com.simprints.fingerprint.capture.usecase.SaveImageUseCase import com.simprints.fingerprint.infra.basebiosdk.exceptions.BioSdkException import com.simprints.fingerprint.infra.biosdk.BioSdkWrapper @@ -70,6 +71,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( private val getNextFingerToAdd: GetNextFingerToAddUseCase, private val getStartState: GetStartStateUseCase, private val addCaptureEvents: AddCaptureEventsUseCase, + private val isNoFingerDetectedLimitReachedUseCase: IsNoFingerDetectedLimitReachedUseCase, @ExternalScope private val externalScope: CoroutineScope, ) : ViewModel() { @@ -532,7 +534,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( _vibrate.send() updateCaptureState(CaptureState::toNotDetected) addCaptureAndBiometricEventsInSession() - if(isNumberOfNoFingerDetectedReached(state.currentCaptureState())){ + if (isNoFingerDetectedLimitReachedUseCase(state.currentCaptureState(), configuration)) { handleCaptureFinished() } } @@ -555,21 +557,11 @@ internal class FingerprintCaptureViewModel @Inject constructor( private fun isTooManyBadScans(fingerState: CaptureState, plusBadScan: Boolean): Boolean { val isNumberOfBadScansReached = isNumberOfBadScansReached(fingerState, plusBadScan) - val isNumberOfNoFingerDetectedReached = isNumberOfNoFingerDetectedReached(fingerState) + val isNumberOfNoFingerDetectedReached = + isNoFingerDetectedLimitReachedUseCase(fingerState, configuration) return isNumberOfBadScansReached || isNumberOfNoFingerDetectedReached } - private fun isNumberOfNoFingerDetectedReached(fingerState: CaptureState): Boolean { - val noFingerDetectedThreshold = configuration.secugenSimMatcher?.noFingerDetectedThreshold - ?: return false - - val currentNumberOfNoFingerDetectedScans = when (fingerState) { - is CaptureState.ScanProcess -> fingerState.numberOfNoFingerDetectedScans - else -> 0 - } - return noFingerDetectedThreshold > 0 && currentNumberOfNoFingerDetectedScans >= noFingerDetectedThreshold - } - private fun isNumberOfBadScansReached(fingerState: CaptureState, plusBadScan: Boolean) = when (fingerState) { is CaptureState.ScanProcess -> fingerState.numberOfBadScans @@ -597,7 +589,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( captureState, plusBadScan = false ) || captureState.scanResult.isGoodScan()) val isSkipped = captureState is CaptureState.Skipped - val isNotDetected = isNumberOfNoFingerDetectedReached(captureState) + val isNotDetected = isNoFingerDetectedLimitReachedUseCase(captureState, configuration) return isCollected || isSkipped || isNotDetected } @@ -726,7 +718,6 @@ internal class FingerprintCaptureViewModel @Inject constructor( const val targetNumberOfGoodScans = 2 const val maximumTotalNumberOfFingersForAutoAdding = 4 const val numberOfBadScansRequiredToAutoAddNewFinger = 3 - const val AUTO_SWIPE_DELAY: Long = 500 const val TRY_DIFFERENT_FINGER_SPLASH_DELAY: Long = 2000 diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCase.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCase.kt new file mode 100644 index 0000000000..66570c0dff --- /dev/null +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCase.kt @@ -0,0 +1,26 @@ +package com.simprints.fingerprint.capture.usecase + +import com.simprints.fingerprint.capture.state.CaptureState +import com.simprints.infra.config.store.models.FingerprintConfiguration +import javax.inject.Inject + +internal class IsNoFingerDetectedLimitReachedUseCase @Inject constructor() { + operator fun invoke( + fingerState: CaptureState, + configuration: FingerprintConfiguration + + ): Boolean = when (fingerState) { + is CaptureState.ScanProcess -> { + val noFingerDetectedThreshold = + configuration.secugenSimMatcher?.maxCaptureAttempts?.noFingerDetected?.takeIf { it > 1 } + ?: MAXIMUM_LIMIT_OF_NO_FINGER_DETECTED_SCANS + fingerState.numberOfNoFingerDetectedScans >= noFingerDetectedThreshold + } + + else -> false + } + + companion object { + const val MAXIMUM_LIMIT_OF_NO_FINGER_DETECTED_SCANS = 40 // current maximum value in Vulcan + } +} \ No newline at end of file diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/local/ConfigLocalDataSourceImpl.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/ConfigLocalDataSourceImpl.kt index cd3ff29918..47a8f03ef1 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/local/ConfigLocalDataSourceImpl.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/ConfigLocalDataSourceImpl.kt @@ -155,6 +155,7 @@ internal class ConfigLocalDataSourceImpl @Inject constructor( comparisonStrategyForVerification = FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = Vero1Configuration(60), vero2 = null, + maxCaptureAttempts = null ), nec = null, ), diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/local/migrations/models/OldProjectConfig.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/migrations/models/OldProjectConfig.kt index 40b8590f4f..1a7c1f3545 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/local/migrations/models/OldProjectConfig.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/migrations/models/OldProjectConfig.kt @@ -124,6 +124,7 @@ internal data class OldProjectConfig( ?: FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = Vero1Configuration(fingerprintQualityThreshold.toInt()), vero2 = vero2Configuration(), + maxCaptureAttempts = null ), nec = null, ) diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/FingerprintConfiguration.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/FingerprintConfiguration.kt index df4cbda510..35dadb1eb8 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/FingerprintConfiguration.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/FingerprintConfiguration.kt @@ -2,6 +2,7 @@ package com.simprints.infra.config.store.local.models import com.simprints.infra.config.store.exceptions.InvalidProtobufEnumException import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.infra.config.store.models.MaxCaptureAttempts internal fun FingerprintConfiguration.toProto(): ProtoFingerprintConfiguration = ProtoFingerprintConfiguration.newBuilder() @@ -59,6 +60,7 @@ internal fun ProtoFingerprintConfiguration.toDomainOld() = FingerprintConfigurat comparisonStrategyForVerification = comparisonStrategyForVerification.toDomain(), vero1 = vero1.toDomain(), vero2 = vero2.toDomain(), + maxCaptureAttempts = null ), nec = null, displayHandIcons = displayHandIcons, @@ -82,13 +84,17 @@ internal fun ProtoFingerprintConfiguration.ProtoBioSdk.toDomain() = when (this) internal fun ProtoFingerprintConfiguration.ProtoFingerprintSdkConfiguration.toDomain() = FingerprintConfiguration.FingerprintSdkConfiguration( - fingersToCaptureList.map { it.toDomain() }, - decisionPolicy.toDomain(), - comparisonStrategyForVerification.toDomain(), - if (hasVero1()) vero1.toDomain() else null, - if (hasVero2()) vero2.toDomain() else null, + fingersToCapture = fingersToCaptureList.map { it.toDomain() }, + decisionPolicy = decisionPolicy.toDomain(), + comparisonStrategyForVerification = comparisonStrategyForVerification.toDomain(), + vero1 = if (hasVero1()) vero1.toDomain() else null, + vero2 = if (hasVero2()) vero2.toDomain() else null, + maxCaptureAttempts = maxCaptureAttempts.toDomain() ) +internal fun ProtoFingerprintConfiguration.ProtoMaxCaptureAttempts.toDomain() = MaxCaptureAttempts( + noFingerDetected = noFingerDetected +) internal fun ProtoFingerprintConfiguration.VeroGeneration.toDomain() = when (this) { ProtoFingerprintConfiguration.VeroGeneration.VERO_1 -> FingerprintConfiguration.VeroGeneration.VERO_1 diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/models/FingerprintConfiguration.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/models/FingerprintConfiguration.kt index ad02874acd..70fe78d935 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/models/FingerprintConfiguration.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/models/FingerprintConfiguration.kt @@ -14,8 +14,10 @@ data class FingerprintConfiguration( val comparisonStrategyForVerification: FingerComparisonStrategy, val vero1: Vero1Configuration? = null, val vero2: Vero2Configuration? = null, - // [MS-491] Allowed amount of 'No Finger Detected' scans before proceeding further - val noFingerDetectedThreshold: Int? = null + /** + * Allowed amount of 'No Finger Detected' scans before proceeding further + */ + val maxCaptureAttempts: MaxCaptureAttempts? ) enum class VeroGeneration { diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/models/MaxCaptureAttempts.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/models/MaxCaptureAttempts.kt new file mode 100644 index 0000000000..535aa5b08e --- /dev/null +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/models/MaxCaptureAttempts.kt @@ -0,0 +1,5 @@ +package com.simprints.infra.config.store.models + +data class MaxCaptureAttempts( + val noFingerDetected: Int +) \ No newline at end of file diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/remote/models/ApiFingerprintConfiguration.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/remote/models/ApiFingerprintConfiguration.kt index 1f95f3f66f..881a9cb46f 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/remote/models/ApiFingerprintConfiguration.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/remote/models/ApiFingerprintConfiguration.kt @@ -27,15 +27,16 @@ internal data class ApiFingerprintConfiguration( val decisionPolicy: ApiDecisionPolicy, val comparisonStrategyForVerification: FingerComparisonStrategy, val vero1: ApiVero1Configuration? = null, - val vero2: ApiVero2Configuration? = null + val vero2: ApiVero2Configuration? = null, + val maxCaptureAttempts: ApiMaxCaptureAttempts? = null ) { fun toDomain() = FingerprintConfiguration.FingerprintSdkConfiguration( - fingersToCapture.map { it.toDomain() }, - decisionPolicy.toDomain(), - comparisonStrategyForVerification.toDomain(), - vero1?.toDomain(), - vero2?.toDomain() - + fingersToCapture = fingersToCapture.map { it.toDomain() }, + decisionPolicy = decisionPolicy.toDomain(), + comparisonStrategyForVerification = comparisonStrategyForVerification.toDomain(), + vero1 = vero1?.toDomain(), + vero2 = vero2?.toDomain(), + maxCaptureAttempts = maxCaptureAttempts?.toDomain() ) } diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/remote/models/ApiMaxCaptureAttempts.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/remote/models/ApiMaxCaptureAttempts.kt new file mode 100644 index 0000000000..eb34f9b578 --- /dev/null +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/remote/models/ApiMaxCaptureAttempts.kt @@ -0,0 +1,13 @@ +package com.simprints.infra.config.store.remote.models + +import androidx.annotation.Keep +import com.simprints.infra.config.store.models.MaxCaptureAttempts + +@Keep +internal data class ApiMaxCaptureAttempts( + val noFingerDetected: Int +) { + fun toDomain(): MaxCaptureAttempts = MaxCaptureAttempts( + noFingerDetected = noFingerDetected + ) +} diff --git a/infra/config-store/src/main/proto/project_config.proto b/infra/config-store/src/main/proto/project_config.proto index 0c7f3f5ddf..e39652e789 100644 --- a/infra/config-store/src/main/proto/project_config.proto +++ b/infra/config-store/src/main/proto/project_config.proto @@ -76,7 +76,11 @@ message ProtoFingerprintConfiguration { FingerComparisonStrategy comparison_strategy_for_verification = 3; optional ProtoVero2Configuration vero_2 = 4; optional ProtoVero1Configuration vero_1 = 5; + ProtoMaxCaptureAttempts max_capture_attempts = 6; + } + message ProtoMaxCaptureAttempts { + int32 no_finger_detected = 1; } } message ProtoVero1Configuration { From dd499421d6245f9f2c6df93311f14a50596561d1 Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 12 Sep 2024 17:13:58 +0300 Subject: [PATCH 3/9] =?UTF-8?q?[MS-491]=20Saving=20maxCaptureAttempts=20in?= =?UTF-8?q?=20proto=20config=CB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/store/local/models/FingerprintConfiguration.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/FingerprintConfiguration.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/FingerprintConfiguration.kt index 35dadb1eb8..f8b79a7ceb 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/FingerprintConfiguration.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/FingerprintConfiguration.kt @@ -1,6 +1,7 @@ package com.simprints.infra.config.store.local.models import com.simprints.infra.config.store.exceptions.InvalidProtobufEnumException +import com.simprints.infra.config.store.local.models.ProtoFingerprintConfiguration.ProtoMaxCaptureAttempts import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.MaxCaptureAttempts @@ -23,6 +24,7 @@ internal fun FingerprintConfiguration.FingerprintSdkConfiguration.toProto() = .also { if (vero1 != null) it.vero1 = vero1.toProto() if (vero2 != null) it.vero2 = vero2.toProto() + if (maxCaptureAttempts != null) it.maxCaptureAttempts = maxCaptureAttempts.toProto() } .build() @@ -41,6 +43,8 @@ internal fun FingerprintConfiguration.FingerComparisonStrategy.toProto() = when FingerprintConfiguration.FingerComparisonStrategy.CROSS_FINGER_USING_MEAN_OF_MAX -> ProtoFingerprintConfiguration.FingerComparisonStrategy.CROSS_FINGER_USING_MEAN_OF_MAX } +internal fun MaxCaptureAttempts.toProto() = ProtoMaxCaptureAttempts.newBuilder().setNoFingerDetected(noFingerDetected).build() + internal fun ProtoFingerprintConfiguration.toDomain() = // if has nec or sim matcher then it's a new config From 5c6af17e95852836c38e9211b0b1d48986d46ffb Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 16 Sep 2024 13:11:39 +0300 Subject: [PATCH 4/9] [MS-491] Adding test cases for the IsNoFingerDetectedLimitReachedUseCaseTest --- ...NoFingerDetectedLimitReachedUseCaseTest.kt | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCaseTest.kt diff --git a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCaseTest.kt b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCaseTest.kt new file mode 100644 index 0000000000..cc41e52ffb --- /dev/null +++ b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCaseTest.kt @@ -0,0 +1,92 @@ +package com.simprints.fingerprint.capture.usecase + +import com.google.common.truth.Truth.assertThat +import com.simprints.fingerprint.capture.state.CaptureState +import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.infra.config.store.models.FingerprintConfiguration.FingerprintSdkConfiguration +import com.simprints.infra.config.store.models.MaxCaptureAttempts +import io.mockk.every +import io.mockk.mockk +import org.junit.Test + + +internal class IsNoFingerDetectedLimitReachedUseCaseTest { + private val isNoFingerDetectedLimitReachedUseCase = IsNoFingerDetectedLimitReachedUseCase() + + @Test + fun `when capture state is not ScanProcess, then returns false`() { + val fingerStateNotCollected = mockk() + val fingerStateSkipped = mockk() + val configuration = mockk() + + listOf(fingerStateNotCollected, fingerStateSkipped).forEach { fingerState -> + assertThat( + isNoFingerDetectedLimitReachedUseCase( + fingerState = fingerState, + configuration = configuration + ) + ).isFalse() + } + } + + @Test + fun `when max capture attempts is null, then inclusive MAXIMUM_LIMIT_OF_NO_FINGER_DETECTED_SCANS is used`() { + val fingerState = mockk { + every { numberOfNoFingerDetectedScans } returns IsNoFingerDetectedLimitReachedUseCase.MAXIMUM_LIMIT_OF_NO_FINGER_DETECTED_SCANS + } + val configuration = mockk { + every { secugenSimMatcher } returns null + } + assertThat( + isNoFingerDetectedLimitReachedUseCase( + fingerState = fingerState, + configuration = configuration + ) + ).isTrue() + } + + @Test + fun `when number of no finger detected scans is greater than no finger detected threshold, then true is returned`() { + val noFingerDetectedThreshold = 3 + val noFingerDetectedScans = noFingerDetectedThreshold + val fingerState = mockk { + every { numberOfNoFingerDetectedScans } returns noFingerDetectedScans + } + val configuration = mockk { + every { secugenSimMatcher } returns mockk { + every { maxCaptureAttempts } returns mockk { + every { noFingerDetected } returns noFingerDetectedThreshold + } + } + } + assertThat( + isNoFingerDetectedLimitReachedUseCase( + fingerState = fingerState, + configuration = configuration + ) + ).isTrue() + } + + @Test + fun `when threshold number of no finger detected scans is lower than 2, then MAXIMUM_LIMIT_OF_NO_FINGER_DETECTED_SCANS is used`() { + val noFingerDetectedThreshold = + IsNoFingerDetectedLimitReachedUseCase.MAXIMUM_LIMIT_OF_NO_FINGER_DETECTED_SCANS + val noFingerDetectedScans = noFingerDetectedThreshold - 1 + val fingerState = mockk { + every { numberOfNoFingerDetectedScans } returns noFingerDetectedScans + } + val configuration = mockk { + every { secugenSimMatcher } returns mockk { + every { maxCaptureAttempts } returns mockk { + every { noFingerDetected } returns 1 + } + } + } + assertThat( + isNoFingerDetectedLimitReachedUseCase( + fingerState = fingerState, + configuration = configuration + ) + ).isFalse() + } +} From c0d41ac6d2aacc28b00c0a4672e81f34737439d8 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 16 Sep 2024 13:11:49 +0300 Subject: [PATCH 5/9] [MS-491] Fixing existing test cases --- .../screen/FingerprintCaptureViewModelTest.kt | 222 +++++++++++------- .../usecase/AddCaptureEventsUseCaseTest.kt | 18 +- .../capture/usecase/SaveImageUseCaseTest.kt | 7 +- 3 files changed, 157 insertions(+), 90 deletions(-) diff --git a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModelTest.kt b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModelTest.kt index 773a407964..e9e6bf993d 100644 --- a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModelTest.kt +++ b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModelTest.kt @@ -19,6 +19,7 @@ import com.simprints.fingerprint.capture.state.ScanResult import com.simprints.fingerprint.capture.usecase.AddCaptureEventsUseCase import com.simprints.fingerprint.capture.usecase.GetNextFingerToAddUseCase import com.simprints.fingerprint.capture.usecase.GetStartStateUseCase +import com.simprints.fingerprint.capture.usecase.IsNoFingerDetectedLimitReachedUseCase import com.simprints.fingerprint.capture.usecase.SaveImageUseCase import com.simprints.fingerprint.infra.basebiosdk.exceptions.BioSdkException import com.simprints.fingerprint.infra.biosdk.BioSdkWrapper @@ -99,6 +100,7 @@ class FingerprintCaptureViewModelTest { private val getStartStateUseCase = GetStartStateUseCase() private val getNextFingerToAddUseCase = GetNextFingerToAddUseCase() + private val isNoFingerDetectedLimitReachedUseCase = IsNoFingerDetectedLimitReachedUseCase() private lateinit var vm: FingerprintCaptureViewModel @@ -129,15 +131,16 @@ class FingerprintCaptureViewModelTest { every { bioSdkWrapper.imageTransferTimeoutMs } returns 1000 vm = FingerprintCaptureViewModel( - scannerManager, - configManager, - timeHelper, - resolveBioSdkWrapperUseCase, - saveImageUseCase, - getNextFingerToAddUseCase, - getStartStateUseCase, - addCaptureEventsUseCase, - CoroutineScope(testCoroutineRule.testCoroutineDispatcher), + scannerManager = scannerManager, + configManager = configManager, + timeHelper = timeHelper, + resolveBioSdkWrapperUseCase = resolveBioSdkWrapperUseCase, + saveImage = saveImageUseCase, + getNextFingerToAdd = getNextFingerToAddUseCase, + getStartState = getStartStateUseCase, + addCaptureEvents = addCaptureEventsUseCase, + isNoFingerDetectedLimitReachedUseCase = isNoFingerDetectedLimitReachedUseCase, + externalScope = CoroutineScope(testCoroutineRule.testCoroutineDispatcher), ) } @@ -182,7 +185,7 @@ class FingerprintCaptureViewModelTest { vm.handleOnViewCreated(TWO_FINGERS_IDS) vm.handleScanButtonPressed() - assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo(CaptureState.Scanning()) + assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo(CaptureState.ScanProcess.Scanning(0, 0)) } @Test @@ -213,8 +216,10 @@ class FingerprintCaptureViewModelTest { vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.TransferringImage( - ScanResult( + CaptureState.ScanProcess.TransferringImage( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult( GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, null, 60 ) ) @@ -232,8 +237,10 @@ class FingerprintCaptureViewModelTest { vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.Collected( - ScanResult( + CaptureState.ScanProcess.Collected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult( GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, null, 60 ) ) @@ -258,8 +265,10 @@ class FingerprintCaptureViewModelTest { vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.Collected( - ScanResult(GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60) + CaptureState.ScanProcess.Collected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult(GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60) ) ) vm.vibrate.assertEventReceived() @@ -280,10 +289,12 @@ class FingerprintCaptureViewModelTest { vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.Collected( - ScanResult( + CaptureState.ScanProcess.Collected( + numberOfBadScans = 1, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult( BAD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, null, 60 - ), 1 + ) ) ) vm.vibrate.assertEventReceived() @@ -301,10 +312,12 @@ class FingerprintCaptureViewModelTest { vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.Collected( - ScanResult( + CaptureState.ScanProcess.Collected( + numberOfBadScans = 1, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult( BAD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, null, 60 - ), 1 + ) ) ) vm.vibrate.assertEventReceived() @@ -321,7 +334,12 @@ class FingerprintCaptureViewModelTest { vm.handleOnViewCreated(TWO_FINGERS_IDS) vm.handleScanButtonPressed() - assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo(CaptureState.NotDetected()) + assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( + CaptureState.ScanProcess.NotDetected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 1, + ) + ) vm.vibrate.assertEventReceived() coVerify { addCaptureEventsUseCase.invoke(any(), any(), any(), any()) } } @@ -367,26 +385,32 @@ class FingerprintCaptureViewModelTest { vm.handleOnViewCreated(TWO_FINGERS_IDS) vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.Collected( - ScanResult( + CaptureState.ScanProcess.Collected( + numberOfBadScans = 1, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult( BAD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, null, 60 - ), 1 + ) ) ) vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.Collected( - ScanResult( + CaptureState.ScanProcess.Collected( + numberOfBadScans = 2, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult( BAD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, null, 60 - ), 2 + ) ) ) vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.Collected( - ScanResult( + CaptureState.ScanProcess.Collected( + numberOfBadScans = 3, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult( BAD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60 - ), 3 + ) ) ) @@ -422,12 +446,13 @@ class FingerprintCaptureViewModelTest { fingerStates = FOUR_FINGERS_IDS.map { FingerState( it, listOf( - CaptureState.Collected( - ScanResult(BAD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), - numberOfBadScans = 3 + CaptureState.ScanProcess.Collected( + numberOfBadScans = 3, + numberOfNoFingerDetectedScans = 0, + ScanResult(BAD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), + ) ) ) - ) }, currentFingerIndex = 3, isAskingRescan = false, @@ -471,13 +496,15 @@ class FingerprintCaptureViewModelTest { fingerStates = TWO_FINGERS_IDS.map { FingerState( it, listOf( - CaptureState.Collected( - ScanResult( - GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60 + CaptureState.ScanProcess.Collected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult( + GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60 + ) ) ) ) - ) }, currentFingerIndex = 1, isAskingRescan = false, @@ -521,13 +548,15 @@ class FingerprintCaptureViewModelTest { fingerStates = TWO_FINGERS_IDS.map { FingerState( it, listOf( - CaptureState.Collected( - ScanResult( - GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, null, 60 + CaptureState.ScanProcess.Collected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult( + GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, null, 60 + ) ) ) ) - ) }, currentFingerIndex = 1, isAskingRescan = false, @@ -573,8 +602,10 @@ class FingerprintCaptureViewModelTest { vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.isAskingRescan).isFalse() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.Collected( - ScanResult( + CaptureState.ScanProcess.Collected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult( DIFFERENT_GOOD_QUALITY, DIFFERENT_TEMPLATE, TEMPLATE_FORMAT, null, 60 ) ) @@ -700,9 +731,10 @@ class FingerprintCaptureViewModelTest { FingerState( FOUR_FINGERS_IDS[0], listOf( - CaptureState.Collected( - ScanResult(GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), - numberOfBadScans = 2 + CaptureState.ScanProcess.Collected( + numberOfBadScans = 2, + numberOfNoFingerDetectedScans = 1, + scanResult = ScanResult(GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), ) ) ), @@ -710,18 +742,20 @@ class FingerprintCaptureViewModelTest { FingerState( FOUR_FINGERS_IDS[2], listOf( - CaptureState.Collected( - ScanResult(BAD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), - numberOfBadScans = 3 + CaptureState.ScanProcess.Collected( + numberOfBadScans = 3, + numberOfNoFingerDetectedScans = 1, + scanResult = ScanResult(BAD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), ) ) ), FingerState( FOUR_FINGERS_IDS[3], listOf( - CaptureState.Collected( - ScanResult(GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), - numberOfBadScans = 0 + CaptureState.ScanProcess.Collected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 1, + scanResult = ScanResult(GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), ) ) ) @@ -808,9 +842,10 @@ class FingerprintCaptureViewModelTest { FingerState( FOUR_FINGERS_IDS[0], listOf( - CaptureState.Collected( - ScanResult(GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), - numberOfBadScans = 2 + CaptureState.ScanProcess.Collected( + numberOfBadScans = 2, + numberOfNoFingerDetectedScans = 1, + scanResult = ScanResult(GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), ) ) ), @@ -818,18 +853,20 @@ class FingerprintCaptureViewModelTest { FingerState( FOUR_FINGERS_IDS[2], listOf( - CaptureState.Collected( - ScanResult(BAD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), - numberOfBadScans = 3 + CaptureState.ScanProcess.Collected( + numberOfBadScans = 3, + numberOfNoFingerDetectedScans = 1, + scanResult = ScanResult(BAD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), ) ) ), FingerState( FOUR_FINGERS_IDS[3], listOf( - CaptureState.Collected( - ScanResult(GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), - numberOfBadScans = 0 + CaptureState.ScanProcess.Collected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 1, + scanResult = ScanResult(GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), ) ) ) @@ -905,27 +942,30 @@ class FingerprintCaptureViewModelTest { FingerState( FOUR_FINGERS_IDS[0], listOf( - CaptureState.Collected( + CaptureState.ScanProcess.Collected( + numberOfBadScans = 3, + numberOfNoFingerDetectedScans = 0, ScanResult(BAD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, null, 60), - numberOfBadScans = 3 ) ) ), FingerState( FOUR_FINGERS_IDS[1], listOf( - CaptureState.Collected( + CaptureState.ScanProcess.Collected( + numberOfBadScans = 1, + numberOfNoFingerDetectedScans = 0, ScanResult(GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), - numberOfBadScans = 1 ) ) ), FingerState( FOUR_FINGERS_IDS[2], listOf( - CaptureState.Collected( + CaptureState.ScanProcess.Collected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, ScanResult(GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, IMAGE, 60), - numberOfBadScans = 0 ) ) ) @@ -966,7 +1006,8 @@ class FingerprintCaptureViewModelTest { vm.handleOnViewCreated(TWO_FINGERS_IDS) vm.handleScanButtonPressed() - assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo(CaptureState.Scanning()) + assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo(CaptureState.ScanProcess.Scanning(numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0,)) vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo(CaptureState.NotCollected) } @@ -982,15 +1023,23 @@ class FingerprintCaptureViewModelTest { vm.handleOnViewCreated(TWO_FINGERS_IDS) vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.TransferringImage( - ScanResult( - GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, null, 60 + CaptureState.ScanProcess.TransferringImage( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult( + qualityScore = GOOD_QUALITY, + template = TEMPLATE, + templateFormat = TEMPLATE_FORMAT, + image = null, + qualityThreshold = 60 ) ) ) vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.TransferringImage( + CaptureState.ScanProcess.TransferringImage( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, ScanResult( GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, null, 60 ) @@ -1039,7 +1088,7 @@ class FingerprintCaptureViewModelTest { vm.handleOnViewCreated(TWO_FINGERS_IDS) vm.handleScanButtonPressed() - assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo(CaptureState.Scanning()) + assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo(CaptureState.ScanProcess.Scanning(0, 0)) vm.handleOnBackPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo(CaptureState.NotCollected) } @@ -1066,7 +1115,9 @@ class FingerprintCaptureViewModelTest { vm.handleOnViewCreated(TWO_FINGERS_IDS) vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.TransferringImage( + CaptureState.ScanProcess.TransferringImage( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, ScanResult( GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, null, 60 ) @@ -1087,9 +1138,15 @@ class FingerprintCaptureViewModelTest { vm.handleScanButtonPressed() vm.handleOnBackPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.Collected( - ScanResult( - GOOD_QUALITY, TEMPLATE, TEMPLATE_FORMAT, null, 60 + CaptureState.ScanProcess.Collected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult( + qualityScore = GOOD_QUALITY, + template = TEMPLATE, + templateFormat = TEMPLATE_FORMAT, + image = null, + qualityThreshold = 60 ) ) ) @@ -1306,7 +1363,10 @@ class FingerprintCaptureViewModelTest { vm.handleScanButtonPressed() assertThat(vm.stateLiveData.value?.currentCaptureState()).isEqualTo( - CaptureState.NotDetected(3) + /* expected = */ CaptureState.ScanProcess.NotDetected( + numberOfBadScans = 3, + numberOfNoFingerDetectedScans = 1 + ) ) coVerify(exactly = 4) { addCaptureEventsUseCase.invoke(any(), any(), any(), any()) } diff --git a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/AddCaptureEventsUseCaseTest.kt b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/AddCaptureEventsUseCaseTest.kt index 136b1d3116..2c39d4d6e0 100644 --- a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/AddCaptureEventsUseCaseTest.kt +++ b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/AddCaptureEventsUseCaseTest.kt @@ -58,8 +58,10 @@ internal class AddCaptureEventsUseCaseTest { useCase.invoke( Timestamp(1L), FingerState( - IFingerIdentifier.LEFT_THUMB, listOf(CaptureState.Collected( - ScanResult(0, byteArrayOf(), "", null, 10))) + IFingerIdentifier.LEFT_THUMB, listOf(CaptureState.ScanProcess.Collected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult(0, byteArrayOf(), "", null, 10))) ), 10, false @@ -74,8 +76,10 @@ internal class AddCaptureEventsUseCaseTest { useCase.invoke( Timestamp(1L), FingerState( - IFingerIdentifier.LEFT_THUMB, listOf(CaptureState.Collected( - ScanResult(100, byteArrayOf(), "", null, 10))) + IFingerIdentifier.LEFT_THUMB, listOf(CaptureState.ScanProcess.Collected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult(100, byteArrayOf(), "", null, 10))) ), 10, false @@ -93,8 +97,10 @@ internal class AddCaptureEventsUseCaseTest { useCase.invoke( Timestamp(1L), FingerState( - IFingerIdentifier.LEFT_THUMB, listOf(CaptureState.Collected( - ScanResult(0, byteArrayOf(), "", null, 10))) + IFingerIdentifier.LEFT_THUMB, listOf(CaptureState.ScanProcess.Collected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult(0, byteArrayOf(), "", null, 10))) ), 10, true diff --git a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/SaveImageUseCaseTest.kt b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/SaveImageUseCaseTest.kt index 9ce4139714..91eb6c1075 100644 --- a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/SaveImageUseCaseTest.kt +++ b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/SaveImageUseCaseTest.kt @@ -134,14 +134,15 @@ class SaveImageUseCaseTest { coVerify { imageRepo.storeImageSecurely(any(), "projectId", any(), any()) } } - private fun createCollectedStub(image: ByteArray?) = CaptureState.Collected( - ScanResult( + private fun createCollectedStub(image: ByteArray?) = CaptureState.ScanProcess.Collected( + numberOfBadScans = 0, + numberOfNoFingerDetectedScans = 0, + scanResult = ScanResult( 0, byteArrayOf(), "format", image, 10, ), - 0 ) } From b2d10008db4f552ed54e508e59cd717186b9664a Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 16 Sep 2024 15:18:37 +0300 Subject: [PATCH 6/9] =?UTF-8?q?[MS-491]=20Fixing=20existing=20mapper=20tes?= =?UTF-8?q?ts=CB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/FingerprintConfigurationTest.kt | 2 + .../models/ApiFingerprintConfigurationTest.kt | 56 +++++++++++-------- .../infra/config/store/testtools/Models.kt | 19 ++++--- 3 files changed, 46 insertions(+), 31 deletions(-) diff --git a/infra/config-store/src/test/java/com/simprints/infra/config/store/models/FingerprintConfigurationTest.kt b/infra/config-store/src/test/java/com/simprints/infra/config/store/models/FingerprintConfigurationTest.kt index a905024d50..84d83df7aa 100644 --- a/infra/config-store/src/test/java/com/simprints/infra/config/store/models/FingerprintConfigurationTest.kt +++ b/infra/config-store/src/test/java/com/simprints/infra/config/store/models/FingerprintConfigurationTest.kt @@ -18,6 +18,7 @@ class FingerprintConfigurationTest { comparisonStrategyForVerification = FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = Vero1Configuration(60), vero2 = null, + maxCaptureAttempts = MaxCaptureAttempts(noFingerDetected = 17) ), nec = null, ) @@ -39,6 +40,7 @@ class FingerprintConfigurationTest { comparisonStrategyForVerification = FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = Vero1Configuration(60), vero2 = null, + maxCaptureAttempts = MaxCaptureAttempts(noFingerDetected = 17) ), ) Truth.assertThat(fingerprintConfiguration.getSdkConfiguration(FingerprintConfiguration.BioSdk.NEC)) diff --git a/infra/config-store/src/test/java/com/simprints/infra/config/store/remote/models/ApiFingerprintConfigurationTest.kt b/infra/config-store/src/test/java/com/simprints/infra/config/store/remote/models/ApiFingerprintConfigurationTest.kt index 480f749c81..d6148c0a6d 100644 --- a/infra/config-store/src/test/java/com/simprints/infra/config/store/remote/models/ApiFingerprintConfigurationTest.kt +++ b/infra/config-store/src/test/java/com/simprints/infra/config/store/remote/models/ApiFingerprintConfigurationTest.kt @@ -4,9 +4,11 @@ import com.google.common.truth.Truth.assertThat import com.simprints.infra.config.store.models.AgeGroup import com.simprints.infra.config.store.models.Finger import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.infra.config.store.models.MaxCaptureAttempts import com.simprints.infra.config.store.models.Vero1Configuration import com.simprints.infra.config.store.testtools.apiDecisionPolicy import com.simprints.infra.config.store.testtools.apiFingerprintConfiguration +import com.simprints.infra.config.store.testtools.apiMaxCaptureAttempts import com.simprints.infra.config.store.testtools.decisionPolicy import com.simprints.infra.config.store.testtools.fingerprintConfiguration import org.junit.Test @@ -40,12 +42,13 @@ class ApiFingerprintConfigurationTest { listOf(ApiFingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER), true, ApiFingerprintConfiguration.ApiFingerprintSdkConfiguration( - listOf(ApiFingerprintConfiguration.Finger.LEFT_3RD_FINGER), - apiDecisionPolicy, - ApiFingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, - null, - apiFingerprintConfiguration.secugenSimMatcher?.vero2, - apiFingerprintConfiguration.secugenSimMatcher?.allowedAgeRange!!, + fingersToCapture = listOf(ApiFingerprintConfiguration.Finger.LEFT_3RD_FINGER), + decisionPolicy = apiDecisionPolicy, + comparisonStrategyForVerification = ApiFingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, + vero1 = null, + vero2 = apiFingerprintConfiguration.secugenSimMatcher?.vero2, + allowedAgeRange = apiFingerprintConfiguration.secugenSimMatcher?.allowedAgeRange!!, + maxCaptureAttempts = apiMaxCaptureAttempts ), null, ) @@ -54,12 +57,14 @@ class ApiFingerprintConfigurationTest { listOf(FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER), true, FingerprintConfiguration.FingerprintSdkConfiguration( - listOf(Finger.LEFT_3RD_FINGER), - decisionPolicy, - FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, - null, - fingerprintConfiguration.secugenSimMatcher?.vero2, - fingerprintConfiguration.secugenSimMatcher?.allowedAgeRange!!, + fingersToCapture = listOf(Finger.LEFT_3RD_FINGER), + decisionPolicy = decisionPolicy, + comparisonStrategyForVerification = FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, + vero1 = null, + vero2 = fingerprintConfiguration.secugenSimMatcher?.vero2, + allowedAgeRange = fingerprintConfiguration.secugenSimMatcher?.allowedAgeRange!!, + verificationMatchThreshold = null, + maxCaptureAttempts = MaxCaptureAttempts(noFingerDetected = 17) ), null, ) @@ -75,12 +80,13 @@ class ApiFingerprintConfigurationTest { true, null, ApiFingerprintConfiguration.ApiFingerprintSdkConfiguration( - listOf(ApiFingerprintConfiguration.Finger.LEFT_3RD_FINGER), - apiDecisionPolicy, - ApiFingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, - ApiVero1Configuration(10), - null, - apiFingerprintConfiguration.secugenSimMatcher?.allowedAgeRange!! + fingersToCapture = listOf(ApiFingerprintConfiguration.Finger.LEFT_3RD_FINGER), + decisionPolicy = apiDecisionPolicy, + comparisonStrategyForVerification = ApiFingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, + vero1 = ApiVero1Configuration(10), + vero2 = null, + allowedAgeRange = apiFingerprintConfiguration.secugenSimMatcher?.allowedAgeRange!!, + maxCaptureAttempts = apiMaxCaptureAttempts ), ) @@ -90,12 +96,14 @@ class ApiFingerprintConfigurationTest { true, null, FingerprintConfiguration.FingerprintSdkConfiguration( - listOf(Finger.LEFT_3RD_FINGER), - decisionPolicy, - FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, - Vero1Configuration(10), - null, - fingerprintConfiguration.secugenSimMatcher?.allowedAgeRange!! + fingersToCapture = listOf(Finger.LEFT_3RD_FINGER), + decisionPolicy = decisionPolicy, + comparisonStrategyForVerification = FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, + vero1 = Vero1Configuration(10), + vero2 = null, + allowedAgeRange = fingerprintConfiguration.secugenSimMatcher?.allowedAgeRange!!, + verificationMatchThreshold = null, + maxCaptureAttempts = MaxCaptureAttempts(noFingerDetected = 17) ), ) diff --git a/infra/config-store/src/test/java/com/simprints/infra/config/store/testtools/Models.kt b/infra/config-store/src/test/java/com/simprints/infra/config/store/testtools/Models.kt index 2358d504f2..1c9ffb3edb 100644 --- a/infra/config-store/src/test/java/com/simprints/infra/config/store/testtools/Models.kt +++ b/infra/config-store/src/test/java/com/simprints/infra/config/store/testtools/Models.kt @@ -9,6 +9,7 @@ import com.simprints.infra.config.store.local.models.ProtoDownSynchronizationCon import com.simprints.infra.config.store.local.models.ProtoFaceConfiguration import com.simprints.infra.config.store.local.models.ProtoFinger import com.simprints.infra.config.store.local.models.ProtoFingerprintConfiguration +import com.simprints.infra.config.store.local.models.ProtoFingerprintConfiguration.ProtoMaxCaptureAttempts import com.simprints.infra.config.store.local.models.ProtoGeneralConfiguration import com.simprints.infra.config.store.local.models.ProtoIdentificationConfiguration import com.simprints.infra.config.store.local.models.ProtoProject @@ -105,6 +106,7 @@ internal val protoConsentConfiguration = ProtoConsentConfiguration.newBuilder() .build() internal val apiAllowedAgeRange = ApiAllowedAgeRange(2, 10) +internal val apiMaxCaptureAttempts = ApiMaxCaptureAttempts(noFingerDetected = 17) internal val allowedAgeRange = AgeGroup(2, 10) internal val protoAllowedAgeRange = ProtoAllowedAgeRange.newBuilder().setStartInclusive(2).setEndExclusive(10).build() @@ -186,13 +188,14 @@ internal val apiFingerprintConfiguration = ApiFingerprintConfiguration( allowedSDKs = listOf(ApiFingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER), displayHandIcons = true, secugenSimMatcher = ApiFingerprintConfiguration.ApiFingerprintSdkConfiguration( - listOf(ApiFingerprintConfiguration.Finger.LEFT_3RD_FINGER), - apiDecisionPolicy, - ApiFingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, - ApiVero1Configuration(10), - apiVero2Configuration, - apiAllowedAgeRange, - 42.0f, + fingersToCapture = listOf(ApiFingerprintConfiguration.Finger.LEFT_3RD_FINGER), + decisionPolicy = apiDecisionPolicy, + comparisonStrategyForVerification = ApiFingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, + vero1 = ApiVero1Configuration(10), + vero2 = apiVero2Configuration, + allowedAgeRange = apiAllowedAgeRange, + verificationMatchThreshold = 42.0f, + maxCaptureAttempts = apiMaxCaptureAttempts ), nec = null, ) @@ -209,6 +212,7 @@ internal val fingerprintConfiguration = FingerprintConfiguration( vero2 = vero2Configuration, allowedAgeRange = allowedAgeRange, verificationMatchThreshold = 42.0f, + maxCaptureAttempts = MaxCaptureAttempts(noFingerDetected = 17) ), nec = null, ) @@ -226,6 +230,7 @@ internal val protoFingerprintConfiguration = ProtoFingerprintConfiguration.newBu .setVero2(protoVero2Configuration) .setAllowedAgeRange(protoAllowedAgeRange) .setVerificationMatchThreshold(42.0f) + .setMaxCaptureAttempts(ProtoMaxCaptureAttempts.newBuilder().setNoFingerDetected(17)) .build() ) .build() From 931258d351990bd543a340d5027d6ca957deca83 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 16 Sep 2024 15:33:28 +0300 Subject: [PATCH 7/9] =?UTF-8?q?[MS-491]=20Fixing=20existing=20mapper=20tes?= =?UTF-8?q?ts=CB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/simprints/infra/sync/config/testtools/Models.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/infra/sync/src/test/java/com/simprints/infra/sync/config/testtools/Models.kt b/infra/sync/src/test/java/com/simprints/infra/sync/config/testtools/Models.kt index e0934123da..7ff0cc1756 100644 --- a/infra/sync/src/test/java/com/simprints/infra/sync/config/testtools/Models.kt +++ b/infra/sync/src/test/java/com/simprints/infra/sync/config/testtools/Models.kt @@ -1,6 +1,7 @@ package com.simprints.infra.sync.config.testtools import com.simprints.core.domain.tokenization.asTokenizableEncrypted +import com.simprints.infra.config.store.models.AgeGroup import com.simprints.infra.config.store.models.ConsentConfiguration import com.simprints.infra.config.store.models.DecisionPolicy import com.simprints.infra.config.store.models.DownSynchronizationConfiguration @@ -9,6 +10,7 @@ import com.simprints.infra.config.store.models.Finger import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.store.models.IdentificationConfiguration +import com.simprints.infra.config.store.models.MaxCaptureAttempts import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.ProjectState @@ -58,6 +60,10 @@ internal val fingerprintConfiguration = FingerprintConfiguration( FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = Vero1Configuration(10), vero2 = vero2Configuration, + allowedAgeRange = AgeGroup(0, null), + verificationMatchThreshold = 42.0f, + maxCaptureAttempts = MaxCaptureAttempts(noFingerDetected = 17) + ), nec = null, ) From 6feab1fc2a94082653ec69f2b9b3d9b27d95ed4d Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 19 Sep 2024 13:17:06 +0300 Subject: [PATCH 8/9] =?UTF-8?q?[MS-491]=20IsNoFingerDetectedLimitReachedUs?= =?UTF-8?q?eCase=20now=20accepts=20the=20specific=20FingerprintSdkConfigur?= =?UTF-8?q?ation=20(SimMatcher=20or=20NEC)=20so=20that=20'maxCaptureAttemp?= =?UTF-8?q?ts'=20is=20taken=20from=20the=20currently=20used=20SDK=CB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../screen/FingerprintCaptureViewModel.kt | 6 ++-- .../IsNoFingerDetectedLimitReachedUseCase.kt | 7 ++--- ...NoFingerDetectedLimitReachedUseCaseTest.kt | 29 ++++++++----------- 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModel.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModel.kt index 3a00ffc097..2a3e665fe9 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModel.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModel.kt @@ -537,7 +537,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( _vibrate.send() updateCaptureState(CaptureState::toNotDetected) addCaptureAndBiometricEventsInSession() - if (isNoFingerDetectedLimitReachedUseCase(state.currentCaptureState(), configuration)) { + if (isNoFingerDetectedLimitReachedUseCase(state.currentCaptureState(), bioSdkConfiguration)) { handleCaptureFinished() } } @@ -561,7 +561,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( private fun isTooManyBadScans(fingerState: CaptureState, plusBadScan: Boolean): Boolean { val isNumberOfBadScansReached = isNumberOfBadScansReached(fingerState, plusBadScan) val isNumberOfNoFingerDetectedReached = - isNoFingerDetectedLimitReachedUseCase(fingerState, configuration) + isNoFingerDetectedLimitReachedUseCase(fingerState, bioSdkConfiguration) return isNumberOfBadScansReached || isNumberOfNoFingerDetectedReached } @@ -592,7 +592,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( captureState, plusBadScan = false ) || captureState.scanResult.isGoodScan()) val isSkipped = captureState is CaptureState.Skipped - val isNotDetected = isNoFingerDetectedLimitReachedUseCase(captureState, configuration) + val isNotDetected = isNoFingerDetectedLimitReachedUseCase(captureState, bioSdkConfiguration) return isCollected || isSkipped || isNotDetected } diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCase.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCase.kt index 66570c0dff..fb446b01a8 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCase.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCase.kt @@ -7,12 +7,11 @@ import javax.inject.Inject internal class IsNoFingerDetectedLimitReachedUseCase @Inject constructor() { operator fun invoke( fingerState: CaptureState, - configuration: FingerprintConfiguration - + sdkConfiguration: FingerprintConfiguration.FingerprintSdkConfiguration ): Boolean = when (fingerState) { is CaptureState.ScanProcess -> { val noFingerDetectedThreshold = - configuration.secugenSimMatcher?.maxCaptureAttempts?.noFingerDetected?.takeIf { it > 1 } + sdkConfiguration.maxCaptureAttempts?.noFingerDetected?.takeIf { it > 1 } ?: MAXIMUM_LIMIT_OF_NO_FINGER_DETECTED_SCANS fingerState.numberOfNoFingerDetectedScans >= noFingerDetectedThreshold } @@ -23,4 +22,4 @@ internal class IsNoFingerDetectedLimitReachedUseCase @Inject constructor() { companion object { const val MAXIMUM_LIMIT_OF_NO_FINGER_DETECTED_SCANS = 40 // current maximum value in Vulcan } -} \ No newline at end of file +} diff --git a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCaseTest.kt b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCaseTest.kt index cc41e52ffb..6c1ad5d42a 100644 --- a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCaseTest.kt +++ b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/IsNoFingerDetectedLimitReachedUseCaseTest.kt @@ -2,7 +2,6 @@ package com.simprints.fingerprint.capture.usecase import com.google.common.truth.Truth.assertThat import com.simprints.fingerprint.capture.state.CaptureState -import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.FingerprintConfiguration.FingerprintSdkConfiguration import com.simprints.infra.config.store.models.MaxCaptureAttempts import io.mockk.every @@ -12,18 +11,18 @@ import org.junit.Test internal class IsNoFingerDetectedLimitReachedUseCaseTest { private val isNoFingerDetectedLimitReachedUseCase = IsNoFingerDetectedLimitReachedUseCase() - + @Test fun `when capture state is not ScanProcess, then returns false`() { val fingerStateNotCollected = mockk() val fingerStateSkipped = mockk() - val configuration = mockk() + val sdkConfiguration = mockk() listOf(fingerStateNotCollected, fingerStateSkipped).forEach { fingerState -> assertThat( isNoFingerDetectedLimitReachedUseCase( fingerState = fingerState, - configuration = configuration + sdkConfiguration = sdkConfiguration ) ).isFalse() } @@ -34,13 +33,13 @@ internal class IsNoFingerDetectedLimitReachedUseCaseTest { val fingerState = mockk { every { numberOfNoFingerDetectedScans } returns IsNoFingerDetectedLimitReachedUseCase.MAXIMUM_LIMIT_OF_NO_FINGER_DETECTED_SCANS } - val configuration = mockk { - every { secugenSimMatcher } returns null + val sdkConfiguration = mockk { + every { maxCaptureAttempts } returns null } assertThat( isNoFingerDetectedLimitReachedUseCase( fingerState = fingerState, - configuration = configuration + sdkConfiguration = sdkConfiguration ) ).isTrue() } @@ -52,17 +51,15 @@ internal class IsNoFingerDetectedLimitReachedUseCaseTest { val fingerState = mockk { every { numberOfNoFingerDetectedScans } returns noFingerDetectedScans } - val configuration = mockk { - every { secugenSimMatcher } returns mockk { - every { maxCaptureAttempts } returns mockk { - every { noFingerDetected } returns noFingerDetectedThreshold - } + val sdkConfiguration = mockk { + every { maxCaptureAttempts } returns mockk { + every { noFingerDetected } returns noFingerDetectedThreshold } } assertThat( isNoFingerDetectedLimitReachedUseCase( fingerState = fingerState, - configuration = configuration + sdkConfiguration = sdkConfiguration ) ).isTrue() } @@ -75,17 +72,15 @@ internal class IsNoFingerDetectedLimitReachedUseCaseTest { val fingerState = mockk { every { numberOfNoFingerDetectedScans } returns noFingerDetectedScans } - val configuration = mockk { - every { secugenSimMatcher } returns mockk { + val sdkConfiguration = mockk { every { maxCaptureAttempts } returns mockk { every { noFingerDetected } returns 1 } - } } assertThat( isNoFingerDetectedLimitReachedUseCase( fingerState = fingerState, - configuration = configuration + sdkConfiguration = sdkConfiguration ) ).isFalse() } From bc6cc377c87751df798555580c769dc0c0722d41 Mon Sep 17 00:00:00 2001 From: alex Date: Thu, 19 Sep 2024 15:08:36 +0300 Subject: [PATCH 9/9] =?UTF-8?q?[MS-491]=20Fixing=20tests=CB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../capture/screen/FingerprintCaptureViewModelTest.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModelTest.kt b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModelTest.kt index 007dcedebd..740e7a6585 100644 --- a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModelTest.kt +++ b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/screen/FingerprintCaptureViewModelTest.kt @@ -99,9 +99,12 @@ class FingerprintCaptureViewModelTest { @MockK private lateinit var addCaptureEventsUseCase: AddCaptureEventsUseCase + @MockK + private lateinit var isNoFingerDetectedLimitReachedUseCase: IsNoFingerDetectedLimitReachedUseCase + private val getStartStateUseCase = GetStartStateUseCase() private val getNextFingerToAddUseCase = GetNextFingerToAddUseCase() - private val isNoFingerDetectedLimitReachedUseCase = IsNoFingerDetectedLimitReachedUseCase() + private lateinit var vm: FingerprintCaptureViewModel @@ -120,6 +123,7 @@ class FingerprintCaptureViewModelTest { } coEvery { addCaptureEventsUseCase.invoke(any(), any(), any(), any()) } returns "payloadId" + coEvery { isNoFingerDetectedLimitReachedUseCase.invoke(any(), any()) } returns false every { scanner.isLiveFeedbackAvailable() } returns false every { scanner.isImageTransferSupported() } returns true