diff --git a/face/capture/src/main/java/com/simprints/face/capture/FaceCaptureResult.kt b/face/capture/src/main/java/com/simprints/face/capture/FaceCaptureResult.kt deleted file mode 100644 index d12839ee2c..0000000000 --- a/face/capture/src/main/java/com/simprints/face/capture/FaceCaptureResult.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.simprints.face.capture - -import androidx.annotation.Keep -import com.simprints.core.ExcludedFromGeneratedTestCoverageReports -import com.simprints.core.domain.step.StepResult -import com.simprints.infra.images.model.SecuredImageRef - -@Keep -data class FaceCaptureResult( - val referenceId: String, - val results: List, -) : StepResult { - @Keep - data class Item( - val captureEventId: String?, - val index: Int, - val sample: Sample?, - ) : StepResult - - @Keep - data class Sample( - val faceId: String, - val template: ByteArray, - val imageRef: SecuredImageRef?, - val format: String, - ) : StepResult { - @ExcludedFromGeneratedTestCoverageReports("Generated code") - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as Sample - - if (faceId != other.faceId) return false - if (!template.contentEquals(other.template)) return false - if (imageRef != other.imageRef) return false - if (format != other.format) return false - - return true - } - - @ExcludedFromGeneratedTestCoverageReports("Generated code") - override fun hashCode(): Int { - var result = faceId.hashCode() - result = 31 * result + template.contentHashCode() - result = 31 * result + (imageRef?.hashCode() ?: 0) - result = 31 * result + format.hashCode() - return result - } - } -} 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 2b25f11709..fb676fee61 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 @@ -6,14 +6,15 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.simprints.core.DeviceID +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureIdentity +import com.simprints.core.domain.sample.CaptureSample import com.simprints.core.livedata.LiveDataEvent import com.simprints.core.livedata.LiveDataEventWithContent import com.simprints.core.livedata.send 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.IsUsingAutoCaptureUseCase import com.simprints.face.capture.usecases.SaveFaceSampleUseCase import com.simprints.face.capture.usecases.ShouldShowInstructionsScreenUseCase import com.simprints.face.capture.usecases.SimpleCaptureEventReporter @@ -78,9 +79,9 @@ internal class FaceCaptureViewModel @Inject constructor( get() = _unexpectedErrorEvent private val _unexpectedErrorEvent = MutableLiveData() - val finishFlowEvent: LiveData> + val finishFlowEvent: LiveData> get() = _finishFlowEvent - private val _finishFlowEvent = MutableLiveData>() + private val _finishFlowEvent = MutableLiveData>() val invalidLicense: LiveData get() = _invalidLicense @@ -179,21 +180,17 @@ internal class FaceCaptureViewModel @Inject constructor( } val items = faceDetections.mapIndexed { index, detection -> - FaceCaptureResult.Item( + CaptureSample( captureEventId = detection.id, - index = index, - sample = FaceCaptureResult.Sample( - faceId = detection.id, - template = detection.face?.template ?: ByteArray(0), - imageRef = detection.securedImageRef, - format = detection.face?.format ?: "", - ), + template = detection.face?.template ?: ByteArray(0), + format = detection.face?.format ?: "", + modality = Modality.FACE, ) } val referenceId = UUID.randomUUID().toString() - eventReporter.addBiometricReferenceCreationEvents(referenceId, items.mapNotNull { it.captureEventId }) + eventReporter.addBiometricReferenceCreationEvents(referenceId, items.map { it.captureEventId }) - _finishFlowEvent.send(FaceCaptureResult(referenceId, items)) + _finishFlowEvent.send(CaptureIdentity(referenceId, Modality.FACE, items)) } } diff --git a/face/capture/src/main/java/com/simprints/face/capture/usecases/SaveFaceSampleUseCase.kt b/face/capture/src/main/java/com/simprints/face/capture/usecases/SaveFaceSampleUseCase.kt index f6ea99b859..144a1fe928 100644 --- a/face/capture/src/main/java/com/simprints/face/capture/usecases/SaveFaceSampleUseCase.kt +++ b/face/capture/src/main/java/com/simprints/face/capture/usecases/SaveFaceSampleUseCase.kt @@ -1,6 +1,6 @@ package com.simprints.face.capture.usecases -import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.core.domain.common.Modality import com.simprints.infra.events.session.SessionEventRepository import com.simprints.infra.images.ImageRepository import com.simprints.infra.images.model.SecuredImageRef @@ -23,7 +23,7 @@ internal class SaveFaceSampleUseCase @Inject constructor( return coreImageRepository.storeSample( projectId = sessionScope.projectId, sessionId = sessionScope.id, - modality = GeneralConfiguration.Modality.FACE, + modality = Modality.FACE, sampleId = captureEventId, fileExtension = "jpg", sampleBytes = imageBytes, diff --git a/face/infra/base-bio-sdk/src/main/java/com/simprints/face/infra/basebiosdk/matching/FaceMatcher.kt b/face/infra/base-bio-sdk/src/main/java/com/simprints/face/infra/basebiosdk/matching/FaceMatcher.kt index 80daab7261..78892c5adf 100644 --- a/face/infra/base-bio-sdk/src/main/java/com/simprints/face/infra/basebiosdk/matching/FaceMatcher.kt +++ b/face/infra/base-bio-sdk/src/main/java/com/simprints/face/infra/basebiosdk/matching/FaceMatcher.kt @@ -1,7 +1,10 @@ package com.simprints.face.infra.basebiosdk.matching +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity + abstract class FaceMatcher( - open val probeSamples: List + open val probeSamples: List, ) : AutoCloseable { /** * Get highest comparison score for matching candidate template against samples @@ -9,5 +12,5 @@ abstract class FaceMatcher( * @param candidate * @return the highest comparison score */ - abstract suspend fun getHighestComparisonScoreForCandidate(candidate: FaceIdentity): Float + abstract suspend fun getHighestComparisonScoreForCandidate(candidate: Identity): Float } diff --git a/face/infra/base-bio-sdk/src/main/java/com/simprints/face/infra/basebiosdk/matching/FaceSample.kt b/face/infra/base-bio-sdk/src/main/java/com/simprints/face/infra/basebiosdk/matching/FaceSample.kt deleted file mode 100644 index abf92709bb..0000000000 --- a/face/infra/base-bio-sdk/src/main/java/com/simprints/face/infra/basebiosdk/matching/FaceSample.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.simprints.face.infra.basebiosdk.matching - -import android.os.Parcelable -import kotlinx.parcelize.Parcelize - -@Parcelize -data class FaceSample( - val faceId: String, - val template: ByteArray, -) : Parcelable diff --git a/face/infra/bio-sdk-resolver/src/debug/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt b/face/infra/bio-sdk-resolver/src/debug/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt index d20c47607c..fe4be76ae8 100644 --- a/face/infra/bio-sdk-resolver/src/debug/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt +++ b/face/infra/bio-sdk-resolver/src/debug/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt @@ -1,8 +1,8 @@ package com.simprints.face.infra.biosdkresolver import com.simprints.biometrics.simface.SimFace +import com.simprints.core.domain.sample.CaptureSample import com.simprints.face.infra.basebiosdk.matching.FaceMatcher -import com.simprints.face.infra.basebiosdk.matching.FaceSample import com.simprints.face.infra.simface.detection.SimFaceDetector import com.simprints.face.infra.simface.initialization.SimFaceInitializer import com.simprints.face.infra.simface.matching.SimFaceMatcher @@ -21,5 +21,5 @@ class SimFaceBioSdk @Inject constructor( override fun matcherName(): String = "SIM_FACE" - override fun createMatcher(probeSamples: List): FaceMatcher = SimFaceMatcher(simFace, probeSamples) + override fun createMatcher(probeSamples: List): FaceMatcher = SimFaceMatcher(simFace, probeSamples) } diff --git a/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/FaceBioSDK.kt b/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/FaceBioSDK.kt index 130ff8eb25..a11b2bc478 100644 --- a/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/FaceBioSDK.kt +++ b/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/FaceBioSDK.kt @@ -1,9 +1,9 @@ package com.simprints.face.infra.biosdkresolver +import com.simprints.core.domain.sample.CaptureSample import com.simprints.face.infra.basebiosdk.detection.FaceDetector import com.simprints.face.infra.basebiosdk.initialization.FaceBioSdkInitializer import com.simprints.face.infra.basebiosdk.matching.FaceMatcher -import com.simprints.face.infra.basebiosdk.matching.FaceSample interface FaceBioSDK { val initializer: FaceBioSdkInitializer @@ -15,5 +15,5 @@ interface FaceBioSDK { fun matcherName(): String - fun createMatcher(probeSamples: List): FaceMatcher + fun createMatcher(probeSamples: List): FaceMatcher } diff --git a/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/RocV1BioSdk.kt b/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/RocV1BioSdk.kt index 16ed495d4e..4b5de11830 100644 --- a/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/RocV1BioSdk.kt +++ b/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/RocV1BioSdk.kt @@ -1,7 +1,7 @@ package com.simprints.face.infra.biosdkresolver +import com.simprints.core.domain.sample.CaptureSample import com.simprints.face.infra.basebiosdk.matching.FaceMatcher -import com.simprints.face.infra.basebiosdk.matching.FaceSample import com.simprints.face.infra.rocv1.detection.RocV1Detector import com.simprints.face.infra.rocv1.detection.RocV1Detector.Companion.RANK_ONE_TEMPLATE_FORMAT_1_23 import com.simprints.face.infra.rocv1.initialization.RocV1Initializer @@ -20,5 +20,5 @@ class RocV1BioSdk @Inject constructor( override fun matcherName(): String = "RANK_ONE" - override fun createMatcher(probeSamples: List): FaceMatcher = RocV1Matcher(probeSamples) + override fun createMatcher(probeSamples: List): FaceMatcher = RocV1Matcher(probeSamples) } diff --git a/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/RocV3BioSdk.kt b/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/RocV3BioSdk.kt index 474370ef96..f3b000b023 100644 --- a/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/RocV3BioSdk.kt +++ b/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/RocV3BioSdk.kt @@ -1,7 +1,7 @@ package com.simprints.face.infra.biosdkresolver +import com.simprints.core.domain.sample.CaptureSample import com.simprints.face.infra.basebiosdk.matching.FaceMatcher -import com.simprints.face.infra.basebiosdk.matching.FaceSample import com.simprints.face.infra.rocv3.detection.RocV3Detector import com.simprints.face.infra.rocv3.detection.RocV3Detector.Companion.RANK_ONE_TEMPLATE_FORMAT_3_1 import com.simprints.face.infra.rocv3.initialization.RocV3Initializer @@ -20,5 +20,5 @@ class RocV3BioSdk @Inject constructor( override fun matcherName(): String = "RANK_ONE" - override fun createMatcher(probeSamples: List): FaceMatcher = RocV3Matcher(probeSamples) + override fun createMatcher(probeSamples: List): FaceMatcher = RocV3Matcher(probeSamples) } diff --git a/face/infra/bio-sdk-resolver/src/release/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt b/face/infra/bio-sdk-resolver/src/release/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt index e084d9fb8c..bdec404d40 100644 --- a/face/infra/bio-sdk-resolver/src/release/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt +++ b/face/infra/bio-sdk-resolver/src/release/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt @@ -1,10 +1,10 @@ package com.simprints.face.infra.biosdkresolver import com.simprints.core.ExcludedFromGeneratedTestCoverageReports +import com.simprints.core.domain.sample.CaptureSample import com.simprints.face.infra.basebiosdk.detection.FaceDetector import com.simprints.face.infra.basebiosdk.initialization.FaceBioSdkInitializer import com.simprints.face.infra.basebiosdk.matching.FaceMatcher -import com.simprints.face.infra.basebiosdk.matching.FaceSample import javax.inject.Inject import javax.inject.Singleton @@ -26,5 +26,5 @@ class SimFaceBioSdk @Inject constructor() : FaceBioSDK { override fun matcherName(): String = TODO() - override fun createMatcher(probeSamples: List): FaceMatcher = TODO() + override fun createMatcher(probeSamples: List): FaceMatcher = TODO() } diff --git a/face/infra/bio-sdk-resolver/src/staging/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt b/face/infra/bio-sdk-resolver/src/staging/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt index e084d9fb8c..bdec404d40 100644 --- a/face/infra/bio-sdk-resolver/src/staging/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt +++ b/face/infra/bio-sdk-resolver/src/staging/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt @@ -1,10 +1,10 @@ package com.simprints.face.infra.biosdkresolver import com.simprints.core.ExcludedFromGeneratedTestCoverageReports +import com.simprints.core.domain.sample.CaptureSample import com.simprints.face.infra.basebiosdk.detection.FaceDetector import com.simprints.face.infra.basebiosdk.initialization.FaceBioSdkInitializer import com.simprints.face.infra.basebiosdk.matching.FaceMatcher -import com.simprints.face.infra.basebiosdk.matching.FaceSample import javax.inject.Inject import javax.inject.Singleton @@ -26,5 +26,5 @@ class SimFaceBioSdk @Inject constructor() : FaceBioSDK { override fun matcherName(): String = TODO() - override fun createMatcher(probeSamples: List): FaceMatcher = TODO() + override fun createMatcher(probeSamples: List): FaceMatcher = TODO() } diff --git a/face/infra/bio-sdk-resolver/src/test/java/com/simprints/face/infra/biosdkresolver/SimFaceSdkTest.kt b/face/infra/bio-sdk-resolver/src/test/java/com/simprints/face/infra/biosdkresolver/SimFaceSdkTest.kt index 63c7f9d422..2c4cb3022f 100644 --- a/face/infra/bio-sdk-resolver/src/test/java/com/simprints/face/infra/biosdkresolver/SimFaceSdkTest.kt +++ b/face/infra/bio-sdk-resolver/src/test/java/com/simprints/face/infra/biosdkresolver/SimFaceSdkTest.kt @@ -1,6 +1,9 @@ package com.simprints.face.infra.biosdkresolver import com.google.common.truth.* +import com.simprints.biometrics.simface.SimFace +import com.simprints.face.infra.simface.detection.SimFaceDetector +import com.simprints.face.infra.simface.initialization.SimFaceInitializer import io.mockk.* import org.junit.Test @@ -9,7 +12,11 @@ class SimFaceSdkTest { @Test fun createMatcher() { - bioSdk = SimFaceBioSdk(mockk(), mockk(), mockk(relaxed = true)) + bioSdk = SimFaceBioSdk( + initializer = mockk(), + detector = mockk(), + simFace = mockk(relaxed = true), + ) val matcher = bioSdk.createMatcher(emptyList()) diff --git a/face/infra/roc-v1/src/main/java/com/simprints/face/infra/rocv1/matching/RocV1Matcher.kt b/face/infra/roc-v1/src/main/java/com/simprints/face/infra/rocv1/matching/RocV1Matcher.kt index 5e8a3bfc38..5979018813 100644 --- a/face/infra/roc-v1/src/main/java/com/simprints/face/infra/rocv1/matching/RocV1Matcher.kt +++ b/face/infra/roc-v1/src/main/java/com/simprints/face/infra/rocv1/matching/RocV1Matcher.kt @@ -1,9 +1,9 @@ package com.simprints.face.infra.rocv1.matching import com.simprints.core.ExcludedFromGeneratedTestCoverageReports -import com.simprints.face.infra.basebiosdk.matching.FaceIdentity +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity import com.simprints.face.infra.basebiosdk.matching.FaceMatcher -import com.simprints.face.infra.basebiosdk.matching.FaceSample import io.rankone.rocsdk.embedded.SWIGTYPE_p_unsigned_char import io.rankone.rocsdk.embedded.roc import io.rankone.rocsdk.embedded.rocConstants.ROC_FAST_FV_SIZE @@ -12,9 +12,8 @@ import io.rankone.rocsdk.embedded.rocConstants.ROC_FAST_FV_SIZE reason = "This function uses roc class that has native functions and can't be mocked", ) class RocV1Matcher( - override val probeSamples: List + override val probeSamples: List, ) : FaceMatcher(probeSamples) { - var probeTemplates: List = probeSamples.mapIndexed { i, probe -> val probeTemplate: SWIGTYPE_p_unsigned_char = roc.new_uint8_t_array(ROC_FAST_FV_SIZE.toInt()) @@ -22,16 +21,16 @@ class RocV1Matcher( probeTemplate } - override suspend fun getHighestComparisonScoreForCandidate(candidate: FaceIdentity): Float = - probeTemplates.flatMap { probeTemplate -> - candidate.faces.map { face -> + override suspend fun getHighestComparisonScoreForCandidate(candidate: Identity): Float = probeTemplates + .flatMap { probeTemplate -> + candidate.samples.map { face -> getSimilarityScoreForCandidate(probeTemplate, face.template) } }.max() private fun getSimilarityScoreForCandidate( probeTemplate: SWIGTYPE_p_unsigned_char, - candidateTemplate: ByteArray + candidateTemplate: ByteArray, ): Float { val matchTemplate = roc.new_uint8_t_array(ROC_FAST_FV_SIZE.toInt()) roc.memmove(roc.roc_cast(matchTemplate), candidateTemplate) diff --git a/face/infra/roc-v3/src/main/java/com/simprints/face/infra/rocv3/matching/RocV3Matcher.kt b/face/infra/roc-v3/src/main/java/com/simprints/face/infra/rocv3/matching/RocV3Matcher.kt index db2c4c52da..9bdbaec3b6 100644 --- a/face/infra/roc-v3/src/main/java/com/simprints/face/infra/rocv3/matching/RocV3Matcher.kt +++ b/face/infra/roc-v3/src/main/java/com/simprints/face/infra/rocv3/matching/RocV3Matcher.kt @@ -4,17 +4,16 @@ import ai.roc.rocsdk.embedded.SWIGTYPE_p_unsigned_char import ai.roc.rocsdk.embedded.roc import ai.roc.rocsdk.embedded.rocConstants.ROC_FACE_FAST_FV_SIZE import com.simprints.core.ExcludedFromGeneratedTestCoverageReports -import com.simprints.face.infra.basebiosdk.matching.FaceIdentity +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity import com.simprints.face.infra.basebiosdk.matching.FaceMatcher -import com.simprints.face.infra.basebiosdk.matching.FaceSample @ExcludedFromGeneratedTestCoverageReports( reason = "This function uses roc class that has native functions and can't be mocked", ) class RocV3Matcher( - override val probeSamples: List + override val probeSamples: List, ) : FaceMatcher(probeSamples) { - var probeTemplates: List = probeSamples.mapIndexed { i, probe -> val probeTemplate: SWIGTYPE_p_unsigned_char = roc.new_uint8_t_array(ROC_FACE_FAST_FV_SIZE.toInt()) @@ -22,9 +21,9 @@ class RocV3Matcher( probeTemplate } - override suspend fun getHighestComparisonScoreForCandidate(candidate: FaceIdentity): Float = - probeTemplates.flatMap { probeTemplate -> - candidate.faces.map { face -> + override suspend fun getHighestComparisonScoreForCandidate(candidate: Identity): Float = probeTemplates + .flatMap { probeTemplate -> + candidate.samples.map { face -> getSimilarityScoreForCandidate(probeTemplate, face.template) } }.max() diff --git a/face/infra/simface/src/main/java/com/simprints/face/infra/simface/matching/SimFaceMatcher.kt b/face/infra/simface/src/main/java/com/simprints/face/infra/simface/matching/SimFaceMatcher.kt index 7717000528..8e7a4db345 100644 --- a/face/infra/simface/src/main/java/com/simprints/face/infra/simface/matching/SimFaceMatcher.kt +++ b/face/infra/simface/src/main/java/com/simprints/face/infra/simface/matching/SimFaceMatcher.kt @@ -1,19 +1,19 @@ package com.simprints.face.infra.simface.matching import com.simprints.biometrics.simface.SimFace -import com.simprints.face.infra.basebiosdk.matching.FaceIdentity +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity import com.simprints.face.infra.basebiosdk.matching.FaceMatcher -import com.simprints.face.infra.basebiosdk.matching.FaceSample class SimFaceMatcher( private val simFace: SimFace, - override val probeSamples: List, + override val probeSamples: List, ) : FaceMatcher(probeSamples) { private val probeTemplates = probeSamples.map { it.template } - override suspend fun getHighestComparisonScoreForCandidate(candidate: FaceIdentity): Float = probeTemplates + override suspend fun getHighestComparisonScoreForCandidate(candidate: Identity): Float = probeTemplates .flatMap { probeTemplate -> - candidate.faces.map { face -> + candidate.samples.map { face -> val baseScore = simFace.verificationScore(probeTemplate, face.template) // TODO: remove the adjustment after we find out why the returned range is biased towards [0.5;1] (baseScore - 0.5).coerceAtLeast(0.0).toFloat() * 200f diff --git a/face/infra/simface/src/test/java/com/simprints/face/infra/simface/matching/SimFaceMatcherTest.kt b/face/infra/simface/src/test/java/com/simprints/face/infra/simface/matching/SimFaceMatcherTest.kt index 651777ba24..22409cce7c 100644 --- a/face/infra/simface/src/test/java/com/simprints/face/infra/simface/matching/SimFaceMatcherTest.kt +++ b/face/infra/simface/src/test/java/com/simprints/face/infra/simface/matching/SimFaceMatcherTest.kt @@ -2,10 +2,11 @@ package com.simprints.face.infra.simface.matching import com.google.common.truth.Truth.* import com.simprints.biometrics.simface.SimFace -import com.simprints.face.infra.basebiosdk.matching.FaceIdentity -import com.simprints.face.infra.basebiosdk.matching.FaceSample -import io.mockk.every -import io.mockk.mockk +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.Sample +import io.mockk.* import kotlinx.coroutines.test.runTest import org.junit.Test @@ -43,12 +44,26 @@ class SimFaceMatcherTest { } val matcher = SimFaceMatcher( simFace = simFace, - probeSamples = listOf(FaceSample(faceId = "id", template = byteArrayOf(1))), + probeSamples = listOf( + CaptureSample( + captureEventId = "id", + modality = Modality.FACE, + format = "ROC", + template = byteArrayOf(1), + ), + ), ) val result = matcher.getHighestComparisonScoreForCandidate( - candidate = FaceIdentity( + candidate = Identity( subjectId = "id", - faces = listOf(FaceSample(faceId = "id", template = byteArrayOf(1))), + samples = listOf( + Sample( + referenceId = "id", + modality = Modality.FACE, + template = byteArrayOf(1), + format = "ROC", + ), + ), ), ) assertThat(result - expectedScore).isLessThan(0.0001f) @@ -62,12 +77,26 @@ class SimFaceMatcherTest { } val matcher = SimFaceMatcher( simFace = simFace, - probeSamples = listOf(FaceSample(faceId = "id", template = byteArrayOf(1))), + probeSamples = listOf( + CaptureSample( + captureEventId = "id", + modality = Modality.FACE, + format = "ROC", + template = byteArrayOf(1), + ), + ), ) val result = matcher.getHighestComparisonScoreForCandidate( - candidate = FaceIdentity( + candidate = Identity( subjectId = "id", - faces = listOf(FaceSample(faceId = "id", template = byteArrayOf(1))), + samples = listOf( + Sample( + referenceId = "id", + modality = Modality.FACE, + template = byteArrayOf(1), + format = "ROC", + ), + ), ), ) assertThat(result - 80f).isLessThan(0.0001f) diff --git a/feature/consent/src/main/java/com/simprints/feature/consent/screens/consent/helpers/GeneralConsentTextHelper.kt b/feature/consent/src/main/java/com/simprints/feature/consent/screens/consent/helpers/GeneralConsentTextHelper.kt index c8e234d80e..5612ea8eec 100644 --- a/feature/consent/src/main/java/com/simprints/feature/consent/screens/consent/helpers/GeneralConsentTextHelper.kt +++ b/feature/consent/src/main/java/com/simprints/feature/consent/screens/consent/helpers/GeneralConsentTextHelper.kt @@ -1,9 +1,9 @@ package com.simprints.feature.consent.screens.consent.helpers import android.content.Context +import com.simprints.core.domain.common.Modality import com.simprints.feature.consent.ConsentType import com.simprints.infra.config.store.models.ConsentConfiguration -import com.simprints.infra.config.store.models.GeneralConfiguration.Modality import com.simprints.infra.resources.R internal data class GeneralConsentTextHelper( diff --git a/feature/consent/src/main/java/com/simprints/feature/consent/screens/consent/helpers/ParentalConsentTextHelper.kt b/feature/consent/src/main/java/com/simprints/feature/consent/screens/consent/helpers/ParentalConsentTextHelper.kt index 66ae44a2f7..f683edb65e 100644 --- a/feature/consent/src/main/java/com/simprints/feature/consent/screens/consent/helpers/ParentalConsentTextHelper.kt +++ b/feature/consent/src/main/java/com/simprints/feature/consent/screens/consent/helpers/ParentalConsentTextHelper.kt @@ -1,9 +1,9 @@ package com.simprints.feature.consent.screens.consent.helpers import android.content.Context +import com.simprints.core.domain.common.Modality import com.simprints.feature.consent.ConsentType import com.simprints.infra.config.store.models.ConsentConfiguration -import com.simprints.infra.config.store.models.GeneralConfiguration.Modality import com.simprints.infra.resources.R internal data class ParentalConsentTextHelper( diff --git a/feature/consent/src/test/java/com/simprints/feature/consent/screens/consent/ConsentViewModelTest.kt b/feature/consent/src/test/java/com/simprints/feature/consent/screens/consent/ConsentViewModelTest.kt index e89ee16ae8..aacb2a8c07 100644 --- a/feature/consent/src/test/java/com/simprints/feature/consent/screens/consent/ConsentViewModelTest.kt +++ b/feature/consent/src/test/java/com/simprints/feature/consent/screens/consent/ConsentViewModelTest.kt @@ -2,25 +2,20 @@ package com.simprints.feature.consent.screens.consent import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp import com.simprints.feature.consent.ConsentResult import com.simprints.feature.consent.ConsentType import com.simprints.feature.exitform.ExitFormResult -import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.event.domain.models.ConsentEvent import com.simprints.infra.events.session.SessionEventRepository import com.simprints.testtools.common.coroutines.TestCoroutineRule import com.simprints.testtools.common.livedata.getOrAwaitValue -import io.mockk.MockKAnnotations -import io.mockk.coEvery -import io.mockk.coVerify -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK -import io.mockk.mockk -import io.mockk.slot import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.test.runTest import org.junit.Before @@ -46,7 +41,7 @@ class ConsentViewModelTest { @MockK private lateinit var eventRepository: SessionEventRepository - private val defaultModalityList = listOf(GeneralConfiguration.Modality.FACE) + private val defaultModalityList = listOf(Modality.FACE) private lateinit var vm: ConsentViewModel diff --git a/feature/consent/src/test/java/com/simprints/feature/consent/screens/consent/helpers/GeneralConsentTextHelperTest.kt b/feature/consent/src/test/java/com/simprints/feature/consent/screens/consent/helpers/GeneralConsentTextHelperTest.kt index cda8dba7b1..c9a9a236ad 100644 --- a/feature/consent/src/test/java/com/simprints/feature/consent/screens/consent/helpers/GeneralConsentTextHelperTest.kt +++ b/feature/consent/src/test/java/com/simprints/feature/consent/screens/consent/helpers/GeneralConsentTextHelperTest.kt @@ -1,12 +1,12 @@ package com.simprints.feature.consent.screens.consent.helpers import android.content.Context -import androidx.test.core.app.ApplicationProvider -import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.core.app.* +import androidx.test.ext.junit.runners.* import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.feature.consent.ConsentType import com.simprints.infra.config.store.models.ConsentConfiguration -import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.resources.R import org.junit.Test import org.junit.runner.RunWith @@ -38,7 +38,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.ENROL, false, ).assembleText(context) @@ -62,7 +62,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT, GeneralConfiguration.Modality.FACE), + listOf(Modality.FINGERPRINT, Modality.FACE), ConsentType.ENROL, false, ).assembleText(context) @@ -86,7 +86,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FACE), + listOf(Modality.FACE), ConsentType.ENROL, false, ).assembleText(context) @@ -110,7 +110,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT, GeneralConfiguration.Modality.FACE), + listOf(Modality.FINGERPRINT, Modality.FACE), ConsentType.ENROL, false, ).assembleText(context) @@ -134,7 +134,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.VERIFY, false, ).assembleText(context) @@ -158,7 +158,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -182,7 +182,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT, GeneralConfiguration.Modality.FACE), + listOf(Modality.FINGERPRINT, Modality.FACE), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -206,7 +206,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -231,7 +231,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FACE), + listOf(Modality.FACE), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -256,7 +256,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT, GeneralConfiguration.Modality.FACE), + listOf(Modality.FINGERPRINT, Modality.FACE), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -281,7 +281,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -305,7 +305,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -328,7 +328,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -351,7 +351,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -374,7 +374,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -397,7 +397,7 @@ class GeneralConsentTextHelperTest { confirmation = true, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -421,7 +421,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -444,7 +444,7 @@ class GeneralConsentTextHelperTest { confirmation = true, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -464,7 +464,7 @@ class GeneralConsentTextHelperTest { confirmation = true, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -484,7 +484,7 @@ class GeneralConsentTextHelperTest { confirmation = true, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -504,7 +504,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.ENROL, isMultiFactorIdEnabled = true, ).assembleText(context) @@ -530,7 +530,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, isMultiFactorIdEnabled = true, ).assembleText(context) @@ -551,7 +551,7 @@ class GeneralConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, isMultiFactorIdEnabled = true, ).assembleText(context) diff --git a/feature/consent/src/test/java/com/simprints/feature/consent/screens/consent/helpers/ParentalConsentTextHelperTest.kt b/feature/consent/src/test/java/com/simprints/feature/consent/screens/consent/helpers/ParentalConsentTextHelperTest.kt index 542eae823a..15b7dcad65 100644 --- a/feature/consent/src/test/java/com/simprints/feature/consent/screens/consent/helpers/ParentalConsentTextHelperTest.kt +++ b/feature/consent/src/test/java/com/simprints/feature/consent/screens/consent/helpers/ParentalConsentTextHelperTest.kt @@ -1,12 +1,12 @@ package com.simprints.feature.consent.screens.consent.helpers import android.content.Context -import androidx.test.core.app.ApplicationProvider -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.google.common.truth.Truth.assertThat +import androidx.test.core.app.* +import androidx.test.ext.junit.runners.* +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.feature.consent.ConsentType import com.simprints.infra.config.store.models.ConsentConfiguration -import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.resources.R import org.junit.Test import org.junit.runner.RunWith @@ -38,7 +38,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.ENROL, false, ).assembleText(context) @@ -62,7 +62,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT, GeneralConfiguration.Modality.FACE), + listOf(Modality.FINGERPRINT, Modality.FACE), ConsentType.ENROL, false, ).assembleText(context) @@ -86,7 +86,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FACE), + listOf(Modality.FACE), ConsentType.ENROL, false, ).assembleText(context) @@ -110,7 +110,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT, GeneralConfiguration.Modality.FACE), + listOf(Modality.FINGERPRINT, Modality.FACE), ConsentType.ENROL, false, ).assembleText(context) @@ -134,7 +134,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.VERIFY, false, ).assembleText(context) @@ -158,7 +158,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -182,7 +182,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT, GeneralConfiguration.Modality.FACE), + listOf(Modality.FINGERPRINT, Modality.FACE), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -206,7 +206,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -231,7 +231,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FACE), + listOf(Modality.FACE), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -256,7 +256,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT, GeneralConfiguration.Modality.FACE), + listOf(Modality.FINGERPRINT, Modality.FACE), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -281,7 +281,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -305,7 +305,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -328,7 +328,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -351,7 +351,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -374,7 +374,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -397,7 +397,7 @@ class ParentalConsentTextHelperTest { confirmation = true, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -421,7 +421,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -444,7 +444,7 @@ class ParentalConsentTextHelperTest { confirmation = true, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -464,7 +464,7 @@ class ParentalConsentTextHelperTest { confirmation = true, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -484,7 +484,7 @@ class ParentalConsentTextHelperTest { confirmation = true, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, false, ).assembleText(context) @@ -504,7 +504,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.ENROL, isMultiFactorIdEnabled = true, ).assembleText(context) @@ -524,7 +524,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, isMultiFactorIdEnabled = true, ).assembleText(context) @@ -544,7 +544,7 @@ class ParentalConsentTextHelperTest { confirmation = false, ), ), - listOf(GeneralConfiguration.Modality.FINGERPRINT), + listOf(Modality.FINGERPRINT), ConsentType.IDENTIFY, isMultiFactorIdEnabled = true, ).assembleText(context) diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/SettingsFragment.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/SettingsFragment.kt index ca6e074c1d..8692b0a00b 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/SettingsFragment.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/SettingsFragment.kt @@ -13,14 +13,13 @@ import androidx.navigation.fragment.findNavController import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.simprints.core.domain.common.Modality import com.simprints.core.livedata.LiveDataEventObserver import com.simprints.core.livedata.LiveDataEventWithContentObserver import com.simprints.feature.dashboard.DashboardActivity import com.simprints.feature.dashboard.R import com.simprints.feature.dashboard.databinding.FragmentSettingsBinding import com.simprints.feature.dashboard.settings.password.SettingsPasswordDialogFragment -import com.simprints.infra.config.store.models.GeneralConfiguration -import com.simprints.infra.config.store.models.GeneralConfiguration.Modality.FINGERPRINT import com.simprints.infra.uibase.navigation.navigateSafely import com.simprints.infra.uibase.view.applySystemBarInsets import com.simprints.infra.uibase.viewbinding.viewBinding @@ -92,8 +91,8 @@ internal class SettingsFragment : PreferenceFragmentCompat() { bindClickListeners() } - private fun enableFingerprintSettings(modalities: List) { - getFingerSelectionPreference()?.isVisible = modalities.contains(FINGERPRINT) + private fun enableFingerprintSettings(modalities: List) { + getFingerSelectionPreference()?.isVisible = modalities.contains(Modality.FINGERPRINT) } private fun bindClickListeners() { diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/about/AboutFragment.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/about/AboutFragment.kt index fc105b5a4b..3a51564da5 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/about/AboutFragment.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/about/AboutFragment.kt @@ -13,12 +13,12 @@ import androidx.preference.PreferenceFragmentCompat import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.simprints.core.DeviceID import com.simprints.core.PackageVersionName +import com.simprints.core.domain.common.Modality import com.simprints.core.livedata.LiveDataEventObserver import com.simprints.core.livedata.LiveDataEventWithContentObserver import com.simprints.feature.dashboard.R import com.simprints.feature.dashboard.databinding.FragmentSettingsAboutBinding import com.simprints.feature.dashboard.settings.password.SettingsPasswordDialogFragment -import com.simprints.infra.config.store.models.GeneralConfiguration.Modality.FINGERPRINT import com.simprints.infra.uibase.navigation.navigateSafely import com.simprints.infra.uibase.system.Clipboard import com.simprints.infra.uibase.view.applySystemBarInsets @@ -86,7 +86,7 @@ internal class AboutFragment : PreferenceFragmentCompat() { "${it.sync.lowerCaseCapitalized()} Sync - ${it.search.lowerCaseCapitalized()} Search" } viewModel.modalities.observe(viewLifecycleOwner) { - getScannerVersionPreference()?.isVisible = it.contains(FINGERPRINT) + getScannerVersionPreference()?.isVisible = it.contains(Modality.FINGERPRINT) } viewModel.recentUserActivity.observe(viewLifecycleOwner) { getScannerVersionPreference()?.summary = it.lastScannerVersion diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/about/AboutViewModel.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/about/AboutViewModel.kt index 9e2ae9e96f..0e9e80087c 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/about/AboutViewModel.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/about/AboutViewModel.kt @@ -4,12 +4,12 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.simprints.core.domain.common.Modality import com.simprints.core.livedata.LiveDataEvent import com.simprints.core.livedata.LiveDataEventWithContent import com.simprints.core.livedata.send import com.simprints.feature.dashboard.logout.usecase.LogoutUseCase import com.simprints.feature.troubleshooting.AutoResettingClickCounter -import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.store.models.SettingsPasswordConfig import com.simprints.infra.config.store.models.canSyncDataToSimprints import com.simprints.infra.config.sync.ConfigManager @@ -32,9 +32,9 @@ internal class AboutViewModel @Inject constructor( get() = _syncAndSearchConfig private val _syncAndSearchConfig = MutableLiveData() - val modalities: LiveData> + val modalities: LiveData> get() = _modalities - private val _modalities = MutableLiveData>() + private val _modalities = MutableLiveData>() val recentUserActivity: LiveData get() = _recentUserActivity @@ -85,7 +85,9 @@ internal class AboutViewModel @Inject constructor( private fun load() = viewModelScope.launch { val configuration = configManager.getProjectConfiguration() val syncAndSearchConfig = SyncAndSearchConfig( - configuration.synchronization.down.simprints?.partitionType?.name ?: "CommCare", + configuration.synchronization.down.simprints + ?.partitionType + ?.name ?: "CommCare", configuration.identification.poolType.name, ) _syncAndSearchConfig.postValue(syncAndSearchConfig) diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionItemAdapter.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionItemAdapter.kt index d9168d78f2..b06511e5b0 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionItemAdapter.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionItemAdapter.kt @@ -4,9 +4,9 @@ import android.content.Context import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.feature.dashboard.databinding.HeaderSdkNameBinding import com.simprints.feature.dashboard.databinding.ItemFingerSelectionBinding -import com.simprints.infra.config.store.models.Finger import com.simprints.infra.resources.R as IDR internal class FingerSelectionItemAdapter( @@ -89,17 +89,18 @@ internal class FingerSelectionItemAdapter( } } -fun Finger.toString(context: Context) = context.getString( +fun SampleIdentifier.toString(context: Context) = context.getString( when (this) { - Finger.LEFT_THUMB -> IDR.string.fingerprint_capture_finger_l_1 - Finger.LEFT_INDEX_FINGER -> IDR.string.fingerprint_capture_finger_l_2 - Finger.LEFT_3RD_FINGER -> IDR.string.fingerprint_capture_finger_l_3 - Finger.LEFT_4TH_FINGER -> IDR.string.fingerprint_capture_finger_l_4 - Finger.LEFT_5TH_FINGER -> IDR.string.fingerprint_capture_finger_l_5 - Finger.RIGHT_THUMB -> IDR.string.fingerprint_capture_finger_r_1 - Finger.RIGHT_INDEX_FINGER -> IDR.string.fingerprint_capture_finger_r_2 - Finger.RIGHT_3RD_FINGER -> IDR.string.fingerprint_capture_finger_r_3 - Finger.RIGHT_4TH_FINGER -> IDR.string.fingerprint_capture_finger_r_4 - Finger.RIGHT_5TH_FINGER -> IDR.string.fingerprint_capture_finger_r_5 + SampleIdentifier.LEFT_THUMB -> IDR.string.fingerprint_capture_finger_l_1 + SampleIdentifier.LEFT_INDEX_FINGER -> IDR.string.fingerprint_capture_finger_l_2 + SampleIdentifier.LEFT_3RD_FINGER -> IDR.string.fingerprint_capture_finger_l_3 + SampleIdentifier.LEFT_4TH_FINGER -> IDR.string.fingerprint_capture_finger_l_4 + SampleIdentifier.LEFT_5TH_FINGER -> IDR.string.fingerprint_capture_finger_l_5 + SampleIdentifier.RIGHT_THUMB -> IDR.string.fingerprint_capture_finger_r_1 + SampleIdentifier.RIGHT_INDEX_FINGER -> IDR.string.fingerprint_capture_finger_r_2 + SampleIdentifier.RIGHT_3RD_FINGER -> IDR.string.fingerprint_capture_finger_r_3 + SampleIdentifier.RIGHT_4TH_FINGER -> IDR.string.fingerprint_capture_finger_r_4 + SampleIdentifier.RIGHT_5TH_FINGER -> IDR.string.fingerprint_capture_finger_r_5 + SampleIdentifier.NONE -> throw IllegalArgumentException("Incorrect sample identifier") }, ) diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionViewModel.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionViewModel.kt index b5715a69c8..9c643942f5 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionViewModel.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionViewModel.kt @@ -4,7 +4,7 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.simprints.infra.config.store.models.Finger +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.infra.config.sync.ConfigManager import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch @@ -31,7 +31,7 @@ internal class FingerSelectionViewModel @Inject constructor( } } - private fun List.toFingerSelectionItems(): List { + private fun List.toFingerSelectionItems(): List { val result = mutableListOf() this.forEach { finger -> val alreadyExistingFingerSelection = result.firstOrNull { fingerSelectionItem -> @@ -54,6 +54,6 @@ data class FingerSelectionSection( ) data class FingerSelectionItem( - var finger: Finger, + var finger: SampleIdentifier, var quantity: Int, ) diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/SettingsFragmentTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/SettingsFragmentTest.kt index af02aed87a..8168afdb4e 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/SettingsFragmentTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/SettingsFragmentTest.kt @@ -2,15 +2,14 @@ package com.simprints.feature.dashboard.settings import androidx.lifecycle.Observer import androidx.recyclerview.widget.RecyclerView -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.assertion.ViewAssertions.doesNotExist -import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.contrib.RecyclerViewActions -import androidx.test.espresso.matcher.PreferenceMatchers.* +import androidx.test.espresso.Espresso.* +import androidx.test.espresso.action.ViewActions.* +import androidx.test.espresso.assertion.ViewAssertions.* +import androidx.test.espresso.contrib.* import androidx.test.espresso.matcher.ViewMatchers.* -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.google.common.truth.Truth.assertThat +import androidx.test.ext.junit.runners.* +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.feature.dashboard.R import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.testtools.hilt.launchFragmentInHiltContainer @@ -19,8 +18,7 @@ import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltTestApplication -import io.mockk.every -import io.mockk.mockk +import io.mockk.* import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -60,7 +58,7 @@ class SettingsFragmentTest { @Test fun `should display the toolbar`() { - mockModalities(listOf(GeneralConfiguration.Modality.FINGERPRINT)) + mockModalities(listOf(Modality.FINGERPRINT)) launchFragmentInHiltContainer() @@ -69,7 +67,7 @@ class SettingsFragmentTest { @Test fun `should hide the fingerprint preference if the modalities doesn't contain Fingerprint`() { - mockModalities(listOf(GeneralConfiguration.Modality.FACE)) + mockModalities(listOf(Modality.FACE)) launchFragmentInHiltContainer() @@ -78,7 +76,7 @@ class SettingsFragmentTest { @Test fun `should display the fingerprint preference if the modalities contains Fingerprint`() { - mockModalities(listOf(GeneralConfiguration.Modality.FINGERPRINT)) + mockModalities(listOf(Modality.FINGERPRINT)) launchFragmentInHiltContainer() @@ -87,7 +85,7 @@ class SettingsFragmentTest { @Test fun `should redirect to the sync info fragment when clicking on the sync info preference`() { - mockModalities(listOf(GeneralConfiguration.Modality.FINGERPRINT)) + mockModalities(listOf(Modality.FINGERPRINT)) val navController = testNavController(R.navigation.graph_dashboard, R.id.settingsFragment) @@ -99,7 +97,7 @@ class SettingsFragmentTest { @Test fun `should redirect to the finger selection fragment when clicking on the finger selection preference`() { - mockModalities(listOf(GeneralConfiguration.Modality.FINGERPRINT)) + mockModalities(listOf(Modality.FINGERPRINT)) val navController = testNavController(R.navigation.graph_dashboard, R.id.settingsFragment) @@ -111,7 +109,7 @@ class SettingsFragmentTest { @Test fun `should redirect to the about fragment when clicking on the about preference`() { - mockModalities(listOf(GeneralConfiguration.Modality.FACE)) + mockModalities(listOf(Modality.FACE)) val navController = testNavController(R.navigation.graph_dashboard, R.id.settingsFragment) @@ -128,14 +126,14 @@ class SettingsFragmentTest { @Test fun `should add the selected language as the summary of the language preference`() { - mockModalities(listOf(GeneralConfiguration.Modality.FACE)) + mockModalities(listOf(Modality.FACE)) launchFragmentInHiltContainer() onView(withText("English")).check(matches(isDisplayed())) } - private fun mockModalities(modalities: List) { + private fun mockModalities(modalities: List) { every { configuration.modalities } returns modalities } } diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/SettingsViewModelTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/SettingsViewModelTest.kt index 785a944088..f3b7782781 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/SettingsViewModelTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/SettingsViewModelTest.kt @@ -3,6 +3,7 @@ package com.simprints.feature.dashboard.settings import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.google.common.truth.Truth.assertThat import com.jraska.livedata.test +import com.simprints.core.domain.common.Modality import com.simprints.infra.config.store.models.DeviceConfiguration import com.simprints.infra.config.store.models.ExperimentalProjectConfiguration import com.simprints.infra.config.store.models.GeneralConfiguration @@ -28,8 +29,8 @@ class SettingsViewModelTest { val testCoroutineRule = TestCoroutineRule() private val generalConfiguration = GeneralConfiguration( - modalities = listOf(GeneralConfiguration.Modality.FINGERPRINT), - matchingModalities = listOf(GeneralConfiguration.Modality.FINGERPRINT), + modalities = listOf(Modality.FINGERPRINT), + matchingModalities = listOf(Modality.FINGERPRINT), languageOptions = listOf("en", "fr"), defaultLanguage = "fr", collectLocation = true, @@ -83,7 +84,7 @@ class SettingsViewModelTest { listOf( ExperimentalProjectConfiguration(experimentalConfig1), ExperimentalProjectConfiguration(experimentalConfig2), - ) + ), ) } diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/about/AboutFragmentTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/about/AboutFragmentTest.kt index ccfa32a492..41697d77f0 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/about/AboutFragmentTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/about/AboutFragmentTest.kt @@ -2,22 +2,19 @@ package com.simprints.feature.dashboard.settings.about import androidx.annotation.IdRes import androidx.lifecycle.Observer -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.action.ViewActions.replaceText -import androidx.test.espresso.assertion.ViewAssertions.doesNotExist -import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.matcher.PreferenceMatchers.* -import androidx.test.espresso.matcher.RootMatchers.isDialog +import androidx.test.espresso.Espresso.* +import androidx.test.espresso.action.ViewActions.* +import androidx.test.espresso.assertion.ViewAssertions.* +import androidx.test.espresso.matcher.RootMatchers.* import androidx.test.espresso.matcher.ViewMatchers.* -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.google.common.truth.Truth +import androidx.test.ext.junit.runners.* +import com.google.common.truth.* import com.simprints.core.DeviceID import com.simprints.core.PackageVersionName +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.livedata.LiveDataEventWithContent import com.simprints.feature.dashboard.R -import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.store.models.SettingsPasswordConfig import com.simprints.infra.recent.user.activity.domain.RecentUserActivity import com.simprints.testtools.hilt.launchFragmentInHiltContainer @@ -26,9 +23,7 @@ import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltTestApplication -import io.mockk.every -import io.mockk.mockk -import io.mockk.verify +import io.mockk.* import org.junit.Before import org.junit.Rule import org.junit.Test @@ -84,7 +79,7 @@ class AboutFragmentTest { @Test fun `should hide the fingerprint preference if the modalities doesn't contain Fingerprint`() { - mockModalities(listOf(GeneralConfiguration.Modality.FACE)) + mockModalities(listOf(Modality.FACE)) launchFragmentInHiltContainer() @@ -94,7 +89,7 @@ class AboutFragmentTest { @Test fun `should display the fingerprint preference if the modalities contains Fingerprint`() { - mockModalities(listOf(GeneralConfiguration.Modality.FINGERPRINT)) + mockModalities(listOf(Modality.FINGERPRINT)) launchFragmentInHiltContainer() @@ -104,7 +99,7 @@ class AboutFragmentTest { @Test fun `should display the toolbar`() { - mockModalities(listOf(GeneralConfiguration.Modality.FINGERPRINT)) + mockModalities(listOf(Modality.FINGERPRINT)) launchFragmentInHiltContainer() @@ -113,7 +108,7 @@ class AboutFragmentTest { @Test fun `should init the preferences correctly`() { - mockModalities(listOf(GeneralConfiguration.Modality.FACE)) + mockModalities(listOf(Modality.FACE)) launchFragmentInHiltContainer() @@ -125,7 +120,7 @@ class AboutFragmentTest { @Test fun `should process logout when no password and clicking on logout`() { mockSettingsPassword(SettingsPasswordConfig.NotSet) - mockModalities(listOf(GeneralConfiguration.Modality.FACE)) + mockModalities(listOf(Modality.FACE)) val navController = testNavController(R.navigation.graph_dashboard, R.id.aboutFragment) launchFragmentInHiltContainer(navController = navController) @@ -159,7 +154,7 @@ class AboutFragmentTest { @IdRes targetDestinationId: Int, ) { mockSettingsPassword(SettingsPasswordConfig.NotSet) - mockModalities(listOf(GeneralConfiguration.Modality.FACE)) + mockModalities(listOf(Modality.FACE)) mockLogoutDestination(destination) val navController = testNavController(R.navigation.graph_dashboard, R.id.aboutFragment) @@ -170,7 +165,7 @@ class AboutFragmentTest { @Test fun `should not logout when no password and refusing on the alert dialog`() { mockSettingsPassword(SettingsPasswordConfig.NotSet) - mockModalities(listOf(GeneralConfiguration.Modality.FACE)) + mockModalities(listOf(Modality.FACE)) val navController = testNavController(R.navigation.graph_dashboard, R.id.aboutFragment) launchFragmentInHiltContainer(navController = navController) @@ -187,7 +182,7 @@ class AboutFragmentTest { @Test fun `should prompt password input when has password and clicking on logout`() { mockSettingsPassword(SettingsPasswordConfig.Locked("1234")) - mockModalities(listOf(GeneralConfiguration.Modality.FACE)) + mockModalities(listOf(Modality.FACE)) val navController = testNavController(R.navigation.graph_dashboard, R.id.aboutFragment) launchFragmentInHiltContainer(navController = navController) @@ -203,7 +198,7 @@ class AboutFragmentTest { @Test fun `should not log out when prompted password and it was incorrect`() { mockSettingsPassword(SettingsPasswordConfig.Locked("1234")) - mockModalities(listOf(GeneralConfiguration.Modality.FACE)) + mockModalities(listOf(Modality.FACE)) val navController = testNavController(R.navigation.graph_dashboard, R.id.aboutFragment) launchFragmentInHiltContainer(navController = navController) @@ -217,10 +212,10 @@ class AboutFragmentTest { verify(exactly = 0) { viewModel.processLogoutRequest() } } - private fun mockModalities(modalities: List) { + private fun mockModalities(modalities: List) { every { viewModel.modalities } returns mockk { every { observe(any(), any()) } answers { - secondArg>>().onChanged(modalities) + secondArg>>().onChanged(modalities) } } } diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/about/AboutViewModelTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/about/AboutViewModelTest.kt index e0143c30d1..c0c01b8caf 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/about/AboutViewModelTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/about/AboutViewModelTest.kt @@ -3,6 +3,7 @@ package com.simprints.feature.dashboard.settings.about import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.google.common.truth.Truth.assertThat import com.jraska.livedata.test +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.feature.dashboard.logout.usecase.LogoutUseCase import com.simprints.infra.config.store.models.DownSynchronizationConfiguration @@ -30,7 +31,7 @@ import org.junit.Test class AboutViewModelTest { companion object { - private val MODALITIES = listOf(GeneralConfiguration.Modality.FINGERPRINT) + private val MODALITIES = listOf(Modality.FINGERPRINT) private val POOL_TYPE = IdentificationConfiguration.PoolType.MODULE private val PARTITION_TYPE = DownSynchronizationConfiguration.PartitionType.PROJECT } diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionFragmentTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionFragmentTest.kt index 9e0525ef9a..8c16f1aa92 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionFragmentTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionFragmentTest.kt @@ -6,8 +6,8 @@ import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.* import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.feature.dashboard.R -import com.simprints.infra.config.store.models.Finger import com.simprints.testtools.hilt.launchFragmentInHiltContainer import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule @@ -43,9 +43,9 @@ class FingerSelectionFragmentTest { FingerSelectionSection( sdkName = SIM_MATCHER_NAME, items = listOf( - FingerSelectionItem(Finger.LEFT_THUMB, 1), - FingerSelectionItem(Finger.RIGHT_THUMB, 2), - FingerSelectionItem(Finger.LEFT_INDEX_FINGER, 3), + FingerSelectionItem(SampleIdentifier.LEFT_THUMB, 1), + FingerSelectionItem(SampleIdentifier.RIGHT_THUMB, 2), + FingerSelectionItem(SampleIdentifier.LEFT_INDEX_FINGER, 3), ), ), ), diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionViewModelTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionViewModelTest.kt index a3dac93906..8afc217e58 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionViewModelTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/fingerselection/FingerSelectionViewModelTest.kt @@ -1,23 +1,12 @@ package com.simprints.feature.dashboard.settings.fingerselection import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import com.google.common.truth.Truth.assertThat -import com.simprints.infra.config.store.models.Finger.LEFT_3RD_FINGER -import com.simprints.infra.config.store.models.Finger.LEFT_4TH_FINGER -import com.simprints.infra.config.store.models.Finger.LEFT_5TH_FINGER -import com.simprints.infra.config.store.models.Finger.LEFT_INDEX_FINGER -import com.simprints.infra.config.store.models.Finger.LEFT_THUMB -import com.simprints.infra.config.store.models.Finger.RIGHT_3RD_FINGER -import com.simprints.infra.config.store.models.Finger.RIGHT_4TH_FINGER -import com.simprints.infra.config.store.models.Finger.RIGHT_5TH_FINGER -import com.simprints.infra.config.store.models.Finger.RIGHT_INDEX_FINGER -import com.simprints.infra.config.store.models.Finger.RIGHT_THUMB +import com.google.common.truth.Truth.* +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.sync.ConfigManager import com.simprints.testtools.common.coroutines.TestCoroutineRule -import io.mockk.coEvery -import io.mockk.every -import io.mockk.mockk +import io.mockk.* import org.junit.Rule import org.junit.Test @@ -37,10 +26,10 @@ class FingerSelectionViewModelTest { @Test fun start_loadsSingleSdkFingerStatesCorrectly() { every { fingerprintConfiguration.secugenSimMatcher?.fingersToCapture } returns listOf( - LEFT_THUMB, - LEFT_THUMB, - RIGHT_THUMB, - RIGHT_THUMB, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.RIGHT_THUMB, + SampleIdentifier.RIGHT_THUMB, ) every { fingerprintConfiguration.nec } returns null @@ -53,8 +42,8 @@ class FingerSelectionViewModelTest { assertThat(fingerSelections?.first()?.items) .containsExactlyElementsIn( listOf( - FingerSelectionItem(LEFT_THUMB, 2), - FingerSelectionItem(RIGHT_THUMB, 2), + FingerSelectionItem(SampleIdentifier.LEFT_THUMB, 2), + FingerSelectionItem(SampleIdentifier.RIGHT_THUMB, 2), ), ).inOrder() } @@ -62,18 +51,18 @@ class FingerSelectionViewModelTest { @Test fun start_loadsTwoSdksFingerStatesCorrectly() { every { fingerprintConfiguration.secugenSimMatcher?.fingersToCapture } returns listOf( - LEFT_THUMB, - RIGHT_THUMB, - RIGHT_THUMB, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.RIGHT_THUMB, + SampleIdentifier.RIGHT_THUMB, ) every { fingerprintConfiguration.nec?.fingersToCapture } returns listOf( - LEFT_INDEX_FINGER, - LEFT_INDEX_FINGER, - LEFT_INDEX_FINGER, - RIGHT_INDEX_FINGER, - RIGHT_INDEX_FINGER, - RIGHT_INDEX_FINGER, - RIGHT_INDEX_FINGER, + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.RIGHT_INDEX_FINGER, + SampleIdentifier.RIGHT_INDEX_FINGER, + SampleIdentifier.RIGHT_INDEX_FINGER, + SampleIdentifier.RIGHT_INDEX_FINGER, ) viewModel.start() @@ -85,8 +74,8 @@ class FingerSelectionViewModelTest { assertThat(fingerSelections?.first()?.items) .containsExactlyElementsIn( listOf( - FingerSelectionItem(LEFT_THUMB, 1), - FingerSelectionItem(RIGHT_THUMB, 2), + FingerSelectionItem(SampleIdentifier.LEFT_THUMB, 1), + FingerSelectionItem(SampleIdentifier.RIGHT_THUMB, 2), ), ).inOrder() assertThat(fingerSelections?.get(1)?.sdkName).isEqualTo("NEC") @@ -94,8 +83,8 @@ class FingerSelectionViewModelTest { assertThat(fingerSelections?.get(1)?.items) .containsExactlyElementsIn( listOf( - FingerSelectionItem(LEFT_INDEX_FINGER, 3), - FingerSelectionItem(RIGHT_INDEX_FINGER, 4), + FingerSelectionItem(SampleIdentifier.LEFT_INDEX_FINGER, 3), + FingerSelectionItem(SampleIdentifier.RIGHT_INDEX_FINGER, 4), ), ).inOrder() } @@ -103,36 +92,36 @@ class FingerSelectionViewModelTest { @Test fun scatteredFingers_areAggregated() { every { fingerprintConfiguration.secugenSimMatcher?.fingersToCapture } returns listOf( - LEFT_THUMB, - RIGHT_THUMB, - RIGHT_INDEX_FINGER, - LEFT_3RD_FINGER, - LEFT_3RD_FINGER, - LEFT_4TH_FINGER, - LEFT_INDEX_FINGER, - RIGHT_5TH_FINGER, - LEFT_5TH_FINGER, - LEFT_3RD_FINGER, - LEFT_4TH_FINGER, - RIGHT_5TH_FINGER, - RIGHT_5TH_FINGER, - LEFT_5TH_FINGER, - RIGHT_4TH_FINGER, - LEFT_4TH_FINGER, - RIGHT_3RD_FINGER, - RIGHT_4TH_FINGER, - RIGHT_5TH_FINGER, - LEFT_5TH_FINGER, - RIGHT_INDEX_FINGER, - RIGHT_4TH_FINGER, - LEFT_4TH_FINGER, - LEFT_5TH_FINGER, - RIGHT_3RD_FINGER, - LEFT_5TH_FINGER, - RIGHT_4TH_FINGER, - RIGHT_5TH_FINGER, - LEFT_INDEX_FINGER, - RIGHT_3RD_FINGER, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.RIGHT_THUMB, + SampleIdentifier.RIGHT_INDEX_FINGER, + SampleIdentifier.LEFT_3RD_FINGER, + SampleIdentifier.LEFT_3RD_FINGER, + SampleIdentifier.LEFT_4TH_FINGER, + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.RIGHT_5TH_FINGER, + SampleIdentifier.LEFT_5TH_FINGER, + SampleIdentifier.LEFT_3RD_FINGER, + SampleIdentifier.LEFT_4TH_FINGER, + SampleIdentifier.RIGHT_5TH_FINGER, + SampleIdentifier.RIGHT_5TH_FINGER, + SampleIdentifier.LEFT_5TH_FINGER, + SampleIdentifier.RIGHT_4TH_FINGER, + SampleIdentifier.LEFT_4TH_FINGER, + SampleIdentifier.RIGHT_3RD_FINGER, + SampleIdentifier.RIGHT_4TH_FINGER, + SampleIdentifier.RIGHT_5TH_FINGER, + SampleIdentifier.LEFT_5TH_FINGER, + SampleIdentifier.RIGHT_INDEX_FINGER, + SampleIdentifier.RIGHT_4TH_FINGER, + SampleIdentifier.LEFT_4TH_FINGER, + SampleIdentifier.LEFT_5TH_FINGER, + SampleIdentifier.RIGHT_3RD_FINGER, + SampleIdentifier.LEFT_5TH_FINGER, + SampleIdentifier.RIGHT_4TH_FINGER, + SampleIdentifier.RIGHT_5TH_FINGER, + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.RIGHT_3RD_FINGER, ) every { fingerprintConfiguration.nec } returns null @@ -145,16 +134,16 @@ class FingerSelectionViewModelTest { assertThat(fingerSelections?.first()?.items) .containsExactlyElementsIn( listOf( - FingerSelectionItem(LEFT_THUMB, 1), - FingerSelectionItem(RIGHT_THUMB, 1), - FingerSelectionItem(RIGHT_INDEX_FINGER, 2), - FingerSelectionItem(LEFT_3RD_FINGER, 3), - FingerSelectionItem(LEFT_4TH_FINGER, 4), - FingerSelectionItem(LEFT_INDEX_FINGER, 2), - FingerSelectionItem(RIGHT_5TH_FINGER, 5), - FingerSelectionItem(LEFT_5TH_FINGER, 5), - FingerSelectionItem(RIGHT_4TH_FINGER, 4), - FingerSelectionItem(RIGHT_3RD_FINGER, 3), + FingerSelectionItem(SampleIdentifier.LEFT_THUMB, 1), + FingerSelectionItem(SampleIdentifier.RIGHT_THUMB, 1), + FingerSelectionItem(SampleIdentifier.RIGHT_INDEX_FINGER, 2), + FingerSelectionItem(SampleIdentifier.LEFT_3RD_FINGER, 3), + FingerSelectionItem(SampleIdentifier.LEFT_4TH_FINGER, 4), + FingerSelectionItem(SampleIdentifier.LEFT_INDEX_FINGER, 2), + FingerSelectionItem(SampleIdentifier.RIGHT_5TH_FINGER, 5), + FingerSelectionItem(SampleIdentifier.LEFT_5TH_FINGER, 5), + FingerSelectionItem(SampleIdentifier.RIGHT_4TH_FINGER, 4), + FingerSelectionItem(SampleIdentifier.RIGHT_3RD_FINGER, 3), ), ).inOrder() } diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/SyncInfoViewModelTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/SyncInfoViewModelTest.kt index 1098b55c23..d50572d491 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/SyncInfoViewModelTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/SyncInfoViewModelTest.kt @@ -4,6 +4,7 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.lifecycle.MutableLiveData import androidx.lifecycle.asFlow import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp @@ -746,7 +747,7 @@ class SyncInfoViewModelTest { fun `should trigger initial sync when in pre-logout mode and module selection required`() = runTest { val mockProjectConfigRequiringModules = mockk { every { general } returns mockk { - every { modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { modalities } returns listOf(Modality.FINGERPRINT) } } val mockEmptyDeviceConfig = mockk { @@ -768,7 +769,7 @@ class SyncInfoViewModelTest { fun `should not trigger initial sync when not in pre-logout mode and module selection required`() = runTest { val mockProjectConfigRequiringModules = mockk { every { general } returns mockk { - every { modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { modalities } returns listOf(Modality.FINGERPRINT) } } val mockEmptyDeviceConfig = mockk { diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/repository/ModuleRepositoryImplTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/repository/ModuleRepositoryImplTest.kt index 3d422bc64c..32423c5e8b 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/repository/ModuleRepositoryImplTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/repository/ModuleRepositoryImplTest.kt @@ -1,6 +1,7 @@ package com.simprints.feature.dashboard.settings.syncinfo.moduleselection.repository import com.google.common.truth.Truth.assertThat +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.infra.config.store.models.DeviceConfiguration @@ -42,7 +43,7 @@ class ModuleRepositoryImplTest { fun setUp() { MockKAnnotations.init(this, relaxed = true) - every { projectConfiguration.general.modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { projectConfiguration.general.modalities } returns listOf(Modality.FINGERPRINT) every { projectConfiguration.synchronization.down } returns downSynchronizationConfiguration coEvery { configManager.getProjectConfiguration() } returns projectConfiguration diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/usecase/ObserveSyncInfoUseCaseTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/usecase/ObserveSyncInfoUseCaseTest.kt index fa63f700d7..2d8de4f833 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/usecase/ObserveSyncInfoUseCaseTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/usecase/ObserveSyncInfoUseCaseTest.kt @@ -3,7 +3,8 @@ package com.simprints.feature.dashboard.settings.syncinfo.usecase import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.lifecycle.MutableLiveData import androidx.lifecycle.asFlow -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.lifecycle.AppForegroundStateTracker import com.simprints.core.tools.time.Ticker @@ -37,13 +38,7 @@ import com.simprints.infra.network.ConnectivityTracker import com.simprints.infra.sync.ImageSyncStatus import com.simprints.infra.sync.SyncOrchestrator import com.simprints.testtools.common.coroutines.TestCoroutineRule -import io.mockk.MockKAnnotations -import io.mockk.coEvery -import io.mockk.coVerify -import io.mockk.every -import io.mockk.mockk -import io.mockk.mockkStatic -import io.mockk.verify +import io.mockk.* import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOf @@ -395,7 +390,7 @@ class ObserveSyncInfoUseCaseTest { fun `should emit SyncInfo with correct syncInfoSectionModules data`() = runTest { val mockProjectConfigWithModules = mockk { every { general } returns mockk { - every { modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { modalities } returns listOf(Modality.FINGERPRINT) } every { synchronization } returns createMockSynchronizationConfiguration() } @@ -643,7 +638,7 @@ class ObserveSyncInfoUseCaseTest { fun `should emit SyncInfo with correct module counts when modules selected`() = runTest { val mockProjectConfigWithModules = mockk { every { general } returns mockk { - every { modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { modalities } returns listOf(Modality.FINGERPRINT) } every { synchronization } returns createMockSynchronizationConfiguration() } @@ -949,7 +944,7 @@ class ObserveSyncInfoUseCaseTest { val mockConfigWithModules = mockk { every { general } returns mockk { - every { modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { modalities } returns listOf(Modality.FINGERPRINT) } every { synchronization } returns createMockSynchronizationConfiguration() } @@ -1323,7 +1318,7 @@ class ObserveSyncInfoUseCaseTest { fun `should show correct visibility states for module selection instructions`() = runTest { val mockProjectConfigRequiringModules = mockk { every { general } returns mockk { - every { modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { modalities } returns listOf(Modality.FINGERPRINT) } every { synchronization } returns createMockSynchronizationConfiguration() } @@ -1431,7 +1426,7 @@ class ObserveSyncInfoUseCaseTest { val tokenizedModule = TokenizableString.Tokenized("encrypted_module_name") val mockProjectConfigWithModules = mockk { every { general } returns mockk { - every { modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { modalities } returns listOf(Modality.FINGERPRINT) } every { synchronization } returns createMockSynchronizationConfiguration() } @@ -1462,7 +1457,7 @@ class ObserveSyncInfoUseCaseTest { val rawModule = TokenizableString.Raw("raw_module_name") val mockProjectConfigWithModules = mockk { every { general } returns mockk { - every { modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { modalities } returns listOf(Modality.FINGERPRINT) } every { synchronization } returns createMockSynchronizationConfiguration() } diff --git a/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/EnrolLastBiometricParams.kt b/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/EnrolLastBiometricParams.kt index 57040125ff..17f4d9bb17 100644 --- a/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/EnrolLastBiometricParams.kt +++ b/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/EnrolLastBiometricParams.kt @@ -2,12 +2,12 @@ package com.simprints.feature.enrollast import androidx.annotation.Keep import com.simprints.core.ExcludedFromGeneratedTestCoverageReports +import com.simprints.core.domain.common.ModalitySdkType +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.core.domain.step.StepParams import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.feature.externalcredential.screens.search.model.ScannedCredential -import com.simprints.infra.config.store.models.FaceConfiguration -import com.simprints.infra.config.store.models.Finger -import com.simprints.infra.config.store.models.FingerprintConfiguration @Keep @ExcludedFromGeneratedTestCoverageReports("Data class") @@ -26,86 +26,14 @@ sealed class EnrolLastBiometricStepResult : StepParams { ) : EnrolLastBiometricStepResult() @Keep - data class FingerprintMatchResult( - val results: List, - val sdk: FingerprintConfiguration.BioSdk, - ) : EnrolLastBiometricStepResult() - - @Keep - data class FaceMatchResult( - val results: List, - val sdk: FaceConfiguration.BioSdk, - ) : EnrolLastBiometricStepResult() - - @Keep - data class FingerprintCaptureResult( + data class CaptureResult( val referenceId: String, - val results: List, + val results: List, ) : EnrolLastBiometricStepResult() @Keep - data class FaceCaptureResult( - val referenceId: String, - val results: List, + data class MatchResult( + val results: List, + val sdk: ModalitySdkType, ) : EnrolLastBiometricStepResult() } - -@Keep -data class MatchResult( - val subjectId: String, - val confidenceScore: Float, -) : StepParams - -@Keep -data class FingerTemplateCaptureResult( - val finger: Finger, - val template: ByteArray, - val templateQualityScore: Int, - val format: String, -) : StepParams { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as FingerTemplateCaptureResult - - if (finger != other.finger) return false - if (!template.contentEquals(other.template)) return false - if (templateQualityScore != other.templateQualityScore) return false - if (format != other.format) return false - - return true - } - - override fun hashCode(): Int { - var result = finger.hashCode() - result = 31 * result + template.contentHashCode() - result = 31 * result + templateQualityScore - result = 31 * result + format.hashCode() - return result - } -} - -@Keep -data class FaceTemplateCaptureResult( - val template: ByteArray, - val format: String, -) : StepParams { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as FaceTemplateCaptureResult - - if (!template.contentEquals(other.template)) return false - if (format != other.format) return false - - return true - } - - override fun hashCode(): Int { - var result = template.contentHashCode() - result = 31 * result + format.hashCode() - return result - } -} diff --git a/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/EnrolLastBiometricFragment.kt b/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/EnrolLastBiometricFragment.kt index b95dc0bafa..c9b7f96eed 100644 --- a/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/EnrolLastBiometricFragment.kt +++ b/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/EnrolLastBiometricFragment.kt @@ -7,6 +7,7 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import com.google.android.material.bottomsheet.BottomSheetDialog +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredential import com.simprints.core.domain.response.AppErrorReason import com.simprints.core.livedata.LiveDataEventWithContentObserver @@ -25,7 +26,6 @@ import com.simprints.feature.enrollast.screen.EnrolLastState.ErrorType.GENERAL_E import com.simprints.feature.enrollast.screen.EnrolLastState.ErrorType.NO_MATCH_RESULTS import com.simprints.feature.enrollast.screen.model.CredentialDialogItem import com.simprints.feature.externalcredential.view.ScannedCredentialDialog -import com.simprints.infra.config.store.models.GeneralConfiguration.Modality import com.simprints.infra.events.event.domain.models.AlertScreenEvent import com.simprints.infra.logging.LoggingConstants.CrashReportTag.ORCHESTRATION import com.simprints.infra.logging.Simber diff --git a/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/EnrolLastState.kt b/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/EnrolLastState.kt index 2f5a2f7d27..80b2541427 100644 --- a/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/EnrolLastState.kt +++ b/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/EnrolLastState.kt @@ -1,8 +1,8 @@ package com.simprints.feature.enrollast.screen import com.simprints.core.ExcludedFromGeneratedTestCoverageReports +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredential -import com.simprints.infra.config.store.models.GeneralConfiguration @ExcludedFromGeneratedTestCoverageReports("Data class") internal sealed class EnrolLastState { @@ -15,7 +15,7 @@ internal sealed class EnrolLastState { @ExcludedFromGeneratedTestCoverageReports("Data class") data class Failed( val errorType: ErrorType, - val modalities: List, + val modalities: List, ) : EnrolLastState() @ExcludedFromGeneratedTestCoverageReports("Data class") diff --git a/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/usecase/BuildSubjectUseCase.kt b/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/usecase/BuildSubjectUseCase.kt index 6341a5a27d..da9cbc03d8 100644 --- a/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/usecase/BuildSubjectUseCase.kt +++ b/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/usecase/BuildSubjectUseCase.kt @@ -1,16 +1,13 @@ package com.simprints.feature.enrollast.screen.usecase -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Sample import com.simprints.core.tools.time.TimeHelper import com.simprints.feature.enrollast.EnrolLastBiometricParams import com.simprints.feature.enrollast.EnrolLastBiometricStepResult -import com.simprints.feature.enrollast.FaceTemplateCaptureResult -import com.simprints.feature.enrollast.FingerTemplateCaptureResult import com.simprints.feature.externalcredential.screens.search.model.ScannedCredential import com.simprints.feature.externalcredential.screens.search.model.toExternalCredential -import com.simprints.infra.config.store.models.Finger import com.simprints.infra.enrolment.records.repository.domain.models.Subject import com.simprints.infra.eventsync.sync.common.SubjectFactory import java.util.Date @@ -31,18 +28,19 @@ internal class BuildSubjectUseCase @Inject constructor( } else { emptyList() } + val captureResult = params.steps + .filterIsInstance() + .flatMap { result -> result.results.map { toSample(result.referenceId, it) } } + .groupBy { it.modality } + return subjectFactory.buildSubject( subjectId = subjectId, projectId = params.projectId, attendantId = params.userId, moduleId = params.moduleId, createdAt = Date(timeHelper.now().ms), - fingerprintSamples = getFingerprintCaptureResult(params.steps) - ?.let { result -> result.results.map { fingerprintSample(result.referenceId, it) } } - .orEmpty(), - faceSamples = getFaceCaptureResult(params.steps) - ?.let { result -> result.results.map { faceSample(result.referenceId, it) } } - .orEmpty(), + fingerprintSamples = captureResult[Modality.FINGERPRINT].orEmpty(), + faceSamples = captureResult[Modality.FACE].orEmpty(), externalCredentials = externalCredentials, ) } @@ -52,39 +50,14 @@ internal class BuildSubjectUseCase @Inject constructor( subjectId: String, ) = credential?.toExternalCredential(subjectId) - private fun getFingerprintCaptureResult(steps: List) = steps - .filterIsInstance() - .firstOrNull() - - private fun getFaceCaptureResult(steps: List) = steps - .filterIsInstance() - .firstOrNull() - - private fun fingerprintSample( + private fun toSample( referenceId: String, - result: FingerTemplateCaptureResult, - ) = FingerprintSample( - fromDomainToModuleApi(result.finger), - result.template, - result.format, - referenceId, + result: CaptureSample, + ) = Sample( + identifier = result.identifier, + template = result.template, + format = result.format, + referenceId = referenceId, + modality = result.modality, ) - - private fun fromDomainToModuleApi(finger: Finger) = when (finger) { - Finger.RIGHT_5TH_FINGER -> IFingerIdentifier.RIGHT_5TH_FINGER - Finger.RIGHT_4TH_FINGER -> IFingerIdentifier.RIGHT_4TH_FINGER - Finger.RIGHT_3RD_FINGER -> IFingerIdentifier.RIGHT_3RD_FINGER - Finger.RIGHT_INDEX_FINGER -> IFingerIdentifier.RIGHT_INDEX_FINGER - Finger.RIGHT_THUMB -> IFingerIdentifier.RIGHT_THUMB - Finger.LEFT_THUMB -> IFingerIdentifier.LEFT_THUMB - Finger.LEFT_INDEX_FINGER -> IFingerIdentifier.LEFT_INDEX_FINGER - Finger.LEFT_3RD_FINGER -> IFingerIdentifier.LEFT_3RD_FINGER - Finger.LEFT_4TH_FINGER -> IFingerIdentifier.LEFT_4TH_FINGER - Finger.LEFT_5TH_FINGER -> IFingerIdentifier.LEFT_5TH_FINGER - } - - private fun faceSample( - referenceId: String, - result: FaceTemplateCaptureResult, - ) = FaceSample(result.template, result.format, referenceId) } diff --git a/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/usecase/CheckForDuplicateEnrolmentsUseCase.kt b/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/usecase/CheckForDuplicateEnrolmentsUseCase.kt index 0529524d61..818b85987d 100644 --- a/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/usecase/CheckForDuplicateEnrolmentsUseCase.kt +++ b/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/usecase/CheckForDuplicateEnrolmentsUseCase.kt @@ -2,6 +2,8 @@ package com.simprints.feature.enrollast.screen.usecase import com.simprints.feature.enrollast.EnrolLastBiometricStepResult import com.simprints.feature.enrollast.screen.EnrolLastState +import com.simprints.infra.config.store.models.FaceConfiguration +import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.logging.LoggingConstants.CrashReportTag.ENROLMENT import com.simprints.infra.logging.Simber @@ -37,17 +39,17 @@ internal class CheckForDuplicateEnrolmentsUseCase @Inject constructor() { } private fun getFingerprintMatchResult(steps: List) = steps - .filterIsInstance() - .lastOrNull() + .filterIsInstance() + .lastOrNull { it.sdk is FingerprintConfiguration.BioSdk } private fun getFaceMatchResult(steps: List) = steps - .filterIsInstance() - .lastOrNull() + .filterIsInstance() + .lastOrNull { it.sdk is FaceConfiguration.BioSdk } private fun isAnyResponseWithHighConfidence( configuration: ProjectConfiguration, - fingerprintResponse: EnrolLastBiometricStepResult.FingerprintMatchResult?, - faceResponse: EnrolLastBiometricStepResult.FaceMatchResult?, + fingerprintResponse: EnrolLastBiometricStepResult.MatchResult?, + faceResponse: EnrolLastBiometricStepResult.MatchResult?, ): Boolean { val fingerprintThreshold = fingerprintResponse?.let { configuration.fingerprint @@ -65,8 +67,8 @@ internal class CheckForDuplicateEnrolmentsUseCase @Inject constructor() { ?.toFloat() } ?: Float.MAX_VALUE - return fingerprintResponse?.results?.any { it.confidenceScore >= fingerprintThreshold } == true || - faceResponse?.results?.any { it.confidenceScore >= faceThreshold } == true + return fingerprintResponse?.results?.any { it.confidence >= fingerprintThreshold } == true || + faceResponse?.results?.any { it.confidence >= faceThreshold } == true } private class MissingMatchResultException : IllegalStateException("No match response in duplicate check.") diff --git a/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/EnrolLastBiometricParamsTest.kt b/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/EnrolLastBiometricParamsTest.kt deleted file mode 100644 index e382ab8f22..0000000000 --- a/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/EnrolLastBiometricParamsTest.kt +++ /dev/null @@ -1,147 +0,0 @@ -package com.simprints.feature.enrollast - -import com.google.common.truth.Truth.assertThat -import com.simprints.infra.config.store.models.Finger -import org.junit.Test - -class EnrolLastBiometricParamsTest { - private val isoTemplateFormat = "ISO_19794_2" - - @Test - fun testFingerTemplateCaptureResultEquals() { - val result = FingerTemplateCaptureResult( - finger = Finger.LEFT_THUMB, - template = byteArrayOf(3, 4), - templateQualityScore = 42, - format = isoTemplateFormat, - ) - - assertThat(result).isEqualTo( - FingerTemplateCaptureResult( - finger = Finger.LEFT_THUMB, - template = byteArrayOf(3, 4), - templateQualityScore = 42, - format = isoTemplateFormat, - ), - ) - assertThat(result).isNotEqualTo( - FingerTemplateCaptureResult( - finger = Finger.RIGHT_3RD_FINGER, - template = byteArrayOf(3, 4), - templateQualityScore = 42, - format = isoTemplateFormat, - ), - ) - assertThat(result).isNotEqualTo( - FingerTemplateCaptureResult( - finger = Finger.RIGHT_3RD_FINGER, - template = byteArrayOf(3, 4, 5), - templateQualityScore = 42, - format = isoTemplateFormat, - ), - ) - assertThat(result).isNotEqualTo( - FingerTemplateCaptureResult( - finger = Finger.RIGHT_3RD_FINGER, - template = byteArrayOf(3, 4), - templateQualityScore = 41, - format = isoTemplateFormat, - ), - ) - assertThat(result).isNotEqualTo( - FingerTemplateCaptureResult( - finger = Finger.RIGHT_3RD_FINGER, - template = byteArrayOf(3, 4, 5, 6), - templateQualityScore = 42, - format = "NEC_1", - ), - ) - } - - @Test - fun testFingerTemplateCaptureResultHashCode() { - assertThat( - FingerTemplateCaptureResult( - finger = Finger.LEFT_THUMB, - template = byteArrayOf(3, 4), - templateQualityScore = 42, - format = isoTemplateFormat, - ).hashCode(), - ).isEqualTo( - FingerTemplateCaptureResult( - finger = Finger.LEFT_THUMB, - template = byteArrayOf(3, 4), - templateQualityScore = 42, - format = isoTemplateFormat, - ).hashCode(), - ) - assertThat( - FingerTemplateCaptureResult( - finger = Finger.LEFT_THUMB, - template = byteArrayOf(3, 4), - templateQualityScore = 42, - format = isoTemplateFormat, - ).hashCode(), - ).isNotEqualTo( - FingerTemplateCaptureResult( - finger = Finger.RIGHT_3RD_FINGER, - template = byteArrayOf(3, 4, 5, 6), - templateQualityScore = 42, - format = isoTemplateFormat, - ).hashCode(), - ) - } - - @Test - fun testFaceTemplateCaptureResultEquals() { - val result = FaceTemplateCaptureResult( - template = byteArrayOf(3, 4), - format = "format 1", - ) - - assertThat(result).isEqualTo( - FaceTemplateCaptureResult( - template = byteArrayOf(3, 4), - format = "format 1", - ), - ) - assertThat(result).isNotEqualTo( - FaceTemplateCaptureResult( - template = byteArrayOf(3, 4, 5), - format = "format 1", - ), - ) - assertThat(result).isNotEqualTo( - FaceTemplateCaptureResult( - template = byteArrayOf(3, 4), - format = "format 2", - ), - ) - } - - @Test - fun testFaceTemplateCaptureResultHashCode() { - assertThat( - FaceTemplateCaptureResult( - template = byteArrayOf(3, 4), - format = "format 1", - ).hashCode(), - ).isEqualTo( - FaceTemplateCaptureResult( - template = byteArrayOf(3, 4), - format = "format 1", - ).hashCode(), - ) - assertThat( - FaceTemplateCaptureResult( - template = byteArrayOf(3, 4), - format = "format 1", - ).hashCode(), - ).isNotEqualTo( - FaceTemplateCaptureResult( - template = byteArrayOf(3, 4), - format = "format 2", - ).hashCode(), - ) - } -} diff --git a/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/screen/usecase/BuildSubjectUseCaseTest.kt b/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/screen/usecase/BuildSubjectUseCaseTest.kt index 89f970bc80..5f624dadef 100644 --- a/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/screen/usecase/BuildSubjectUseCaseTest.kt +++ b/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/screen/usecase/BuildSubjectUseCaseTest.kt @@ -1,26 +1,21 @@ package com.simprints.feature.enrollast.screen.usecase -import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.externalcredential.ExternalCredential +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredentialType -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp import com.simprints.feature.enrollast.EnrolLastBiometricParams import com.simprints.feature.enrollast.EnrolLastBiometricStepResult -import com.simprints.feature.enrollast.FaceTemplateCaptureResult -import com.simprints.feature.enrollast.FingerTemplateCaptureResult import com.simprints.feature.externalcredential.screens.search.model.ScannedCredential -import com.simprints.feature.externalcredential.screens.search.model.toExternalCredential -import com.simprints.infra.config.store.models.Finger import com.simprints.infra.eventsync.sync.common.SubjectFactory import com.simprints.testtools.unit.EncodingUtilsImplForTests -import io.mockk.MockKAnnotations -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK -import io.mockk.mockk import org.junit.Before import org.junit.Test @@ -60,8 +55,8 @@ class BuildSubjectUseCaseTest { createParams( steps = listOf( EnrolLastBiometricStepResult.EnrolLastBiometricsResult(null), - EnrolLastBiometricStepResult.FingerprintMatchResult(emptyList(), mockk()), - EnrolLastBiometricStepResult.FaceMatchResult(emptyList(), mockk()), + EnrolLastBiometricStepResult.MatchResult(emptyList(), mockk()), + EnrolLastBiometricStepResult.MatchResult(emptyList(), mockk()), ), scannedCredential = scannedCredential, ), @@ -77,14 +72,14 @@ class BuildSubjectUseCaseTest { val result = useCase( createParams( steps = listOf( - EnrolLastBiometricStepResult.FingerprintMatchResult(emptyList(), mockk()), - EnrolLastBiometricStepResult.FingerprintCaptureResult( + EnrolLastBiometricStepResult.MatchResult(emptyList(), mockk()), + EnrolLastBiometricStepResult.CaptureResult( REFERENCE_ID, - listOf(mockFingerprintResults(Finger.RIGHT_THUMB)), + listOf(mockFingerprintResults(SampleIdentifier.RIGHT_THUMB)), ), - EnrolLastBiometricStepResult.FingerprintCaptureResult( + EnrolLastBiometricStepResult.CaptureResult( REFERENCE_ID, - listOf(mockFingerprintResults(Finger.LEFT_THUMB)), + listOf(mockFingerprintResults(SampleIdentifier.LEFT_THUMB)), ), ), scannedCredential = scannedCredential, @@ -93,27 +88,27 @@ class BuildSubjectUseCaseTest { ) assertThat(result.fingerprintSamples).isNotEmpty() - assertThat(result.fingerprintSamples.first().fingerIdentifier).isEqualTo(IFingerIdentifier.RIGHT_THUMB) + assertThat(result.fingerprintSamples.first().identifier).isEqualTo(SampleIdentifier.RIGHT_THUMB) } @Test fun `maps all provided fingerprint capture samples`() { val result = useCase( createParams( - listOf( - element = EnrolLastBiometricStepResult.FingerprintCaptureResult( + steps = listOf( + EnrolLastBiometricStepResult.CaptureResult( REFERENCE_ID, listOf( - mockFingerprintResults(Finger.RIGHT_5TH_FINGER), - mockFingerprintResults(Finger.RIGHT_4TH_FINGER), - mockFingerprintResults(Finger.RIGHT_3RD_FINGER), - mockFingerprintResults(Finger.RIGHT_INDEX_FINGER), - mockFingerprintResults(Finger.RIGHT_THUMB), - mockFingerprintResults(Finger.LEFT_THUMB), - mockFingerprintResults(Finger.LEFT_INDEX_FINGER), - mockFingerprintResults(Finger.LEFT_3RD_FINGER), - mockFingerprintResults(Finger.LEFT_4TH_FINGER), - mockFingerprintResults(Finger.LEFT_5TH_FINGER), + mockFingerprintResults(SampleIdentifier.RIGHT_5TH_FINGER), + mockFingerprintResults(SampleIdentifier.RIGHT_4TH_FINGER), + mockFingerprintResults(SampleIdentifier.RIGHT_3RD_FINGER), + mockFingerprintResults(SampleIdentifier.RIGHT_INDEX_FINGER), + mockFingerprintResults(SampleIdentifier.RIGHT_THUMB), + mockFingerprintResults(SampleIdentifier.LEFT_THUMB), + mockFingerprintResults(SampleIdentifier.LEFT_INDEX_FINGER), + mockFingerprintResults(SampleIdentifier.LEFT_3RD_FINGER), + mockFingerprintResults(SampleIdentifier.LEFT_4TH_FINGER), + mockFingerprintResults(SampleIdentifier.LEFT_5TH_FINGER), ), ), ), @@ -131,9 +126,9 @@ class BuildSubjectUseCaseTest { val result = useCase( params = createParams( listOf( - EnrolLastBiometricStepResult.FaceMatchResult(emptyList(), mockk()), - EnrolLastBiometricStepResult.FaceCaptureResult(REFERENCE_ID, mockFaceResultsList("first")), - EnrolLastBiometricStepResult.FaceCaptureResult(REFERENCE_ID, mockFaceResultsList("second")), + EnrolLastBiometricStepResult.MatchResult(emptyList(), mockk()), + EnrolLastBiometricStepResult.CaptureResult(REFERENCE_ID, listOf(mockFaceResults("first"))), + EnrolLastBiometricStepResult.CaptureResult(REFERENCE_ID, listOf(mockFaceResults("second"))), ), scannedCredential = scannedCredential, ), @@ -185,9 +180,20 @@ class BuildSubjectUseCaseTest { scannedCredential = scannedCredential, ) - private fun mockFingerprintResults(finger: Finger) = FingerTemplateCaptureResult(finger, byteArrayOf(), 1, "ISO_19794_2") + private fun mockFingerprintResults(finger: SampleIdentifier) = CaptureSample( + captureEventId = "eventId", + identifier = finger, + template = byteArrayOf(), + format = "ISO_19794_2", + modality = Modality.FINGERPRINT, + ) - private fun mockFaceResultsList(format: String) = listOf(FaceTemplateCaptureResult(byteArrayOf(), format)) + private fun mockFaceResults(format: String) = CaptureSample( + captureEventId = "eventId", + template = byteArrayOf(), + format = format, + modality = Modality.FACE, + ) companion object { private const val REFERENCE_ID = "referenceId" diff --git a/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/screen/usecase/CheckDuplicateEnrolmentsErrorsUseCaseTest.kt b/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/screen/usecase/CheckDuplicateEnrolmentsErrorsUseCaseTest.kt index e442d02b81..8f49fb9676 100644 --- a/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/screen/usecase/CheckDuplicateEnrolmentsErrorsUseCaseTest.kt +++ b/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/screen/usecase/CheckDuplicateEnrolmentsErrorsUseCaseTest.kt @@ -1,10 +1,12 @@ package com.simprints.feature.enrollast.screen.usecase import com.google.common.truth.Truth.* +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.feature.enrollast.EnrolLastBiometricStepResult -import com.simprints.feature.enrollast.MatchResult import com.simprints.feature.enrollast.screen.EnrolLastState import com.simprints.infra.config.store.models.DecisionPolicy +import com.simprints.infra.config.store.models.FaceConfiguration +import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.ProjectConfiguration import io.mockk.* import org.junit.Before @@ -33,9 +35,9 @@ class CheckDuplicateEnrolmentsErrorsUseCaseTest { val result = useCase( projectConfig = mockProjectConfig(), steps = listOf( - EnrolLastBiometricStepResult.FingerprintMatchResult( + EnrolLastBiometricStepResult.MatchResult( listOf(matchResult(LOW_CONFIDENCE)), - mockk(), + FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, ), ), ) @@ -48,9 +50,9 @@ class CheckDuplicateEnrolmentsErrorsUseCaseTest { val result = useCase( projectConfig = mockProjectConfig(), steps = listOf( - EnrolLastBiometricStepResult.FaceMatchResult( + EnrolLastBiometricStepResult.MatchResult( listOf(matchResult(LOW_CONFIDENCE)), - mockk(), + FaceConfiguration.BioSdk.RANK_ONE, ), ), ) @@ -63,9 +65,9 @@ class CheckDuplicateEnrolmentsErrorsUseCaseTest { val result = useCase( projectConfig = mockProjectConfig(highConfidence = null), steps = listOf( - EnrolLastBiometricStepResult.FingerprintMatchResult( + EnrolLastBiometricStepResult.MatchResult( listOf(matchResult(HIGH_CONFIDENCE)), - mockk(), + FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, ), ), ) @@ -78,9 +80,9 @@ class CheckDuplicateEnrolmentsErrorsUseCaseTest { val result = useCase( projectConfig = mockProjectConfig(highConfidence = null), steps = listOf( - EnrolLastBiometricStepResult.FaceMatchResult( + EnrolLastBiometricStepResult.MatchResult( listOf(matchResult(HIGH_CONFIDENCE)), - mockk(), + FaceConfiguration.BioSdk.RANK_ONE, ), ), ) @@ -103,9 +105,9 @@ class CheckDuplicateEnrolmentsErrorsUseCaseTest { val result = useCase( projectConfig = mockProjectConfig(), steps = listOf( - EnrolLastBiometricStepResult.FingerprintMatchResult( + EnrolLastBiometricStepResult.MatchResult( listOf(matchResult(HIGH_CONFIDENCE)), - mockk(), + FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, ), ), ) @@ -118,9 +120,9 @@ class CheckDuplicateEnrolmentsErrorsUseCaseTest { val result = useCase( projectConfig = mockProjectConfig(), steps = listOf( - EnrolLastBiometricStepResult.FaceMatchResult( + EnrolLastBiometricStepResult.MatchResult( listOf(matchResult(HIGH_CONFIDENCE)), - mockk(), + FaceConfiguration.BioSdk.RANK_ONE, ), ), ) @@ -140,7 +142,7 @@ class CheckDuplicateEnrolmentsErrorsUseCaseTest { every { face?.getSdkConfiguration(any())?.decisionPolicy } returns highConfidence?.let { DecisionPolicy(0, 0, it) } } - private fun matchResult(confidence: Float) = MatchResult("subjectId", confidence) + private fun matchResult(confidence: Float) = MatchComparisonResult("subjectId", confidence) companion object { private const val LOW_CONFIDENCE = 50f diff --git a/feature/exit-form/src/main/java/com/simprints/feature/exitform/screen/ExitFormViewModel.kt b/feature/exit-form/src/main/java/com/simprints/feature/exitform/screen/ExitFormViewModel.kt index 2d96f4901b..94ce833378 100644 --- a/feature/exit-form/src/main/java/com/simprints/feature/exitform/screen/ExitFormViewModel.kt +++ b/feature/exit-form/src/main/java/com/simprints/feature/exitform/screen/ExitFormViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.simprints.core.SessionCoroutineScope +import com.simprints.core.domain.common.Modality import com.simprints.core.livedata.LiveDataEvent import com.simprints.core.livedata.LiveDataEventWithContent import com.simprints.core.livedata.send @@ -75,7 +76,7 @@ internal class ExitFormViewModel @Inject constructor( fun start() { viewModelScope.launch { val projectConfig = configManager.getProjectConfiguration() - if (projectConfig.general.modalities.contains(GeneralConfiguration.Modality.FINGERPRINT)) { + if (projectConfig.general.modalities.contains(Modality.FINGERPRINT)) { val options = DEFAULT_OPTIONS.toMutableSet() options.remove(ExitFormOption.AppNotWorking) options.add(ExitFormOption.ScannerNotWorking) diff --git a/feature/exit-form/src/test/java/com/simprints/feature/exitform/screen/ExitFormViewModelTest.kt b/feature/exit-form/src/test/java/com/simprints/feature/exitform/screen/ExitFormViewModelTest.kt index 10287ee4c0..03660f037e 100644 --- a/feature/exit-form/src/test/java/com/simprints/feature/exitform/screen/ExitFormViewModelTest.kt +++ b/feature/exit-form/src/test/java/com/simprints/feature/exitform/screen/ExitFormViewModelTest.kt @@ -1,21 +1,17 @@ package com.simprints.feature.exitform.screen import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* import com.jraska.livedata.test +import com.simprints.core.domain.common.Modality import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp import com.simprints.feature.exitform.ExitFormOption -import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.session.SessionEventRepository import com.simprints.testtools.common.coroutines.TestCoroutineRule -import io.mockk.MockKAnnotations -import io.mockk.coEvery -import io.mockk.coVerify -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK -import io.mockk.mockk import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.test.runTest import org.junit.Before @@ -57,7 +53,7 @@ internal class ExitFormViewModelTest { @Test fun `show default options when configuration doesn't contain fingerprint`() = runTest { coEvery { configManager.getProjectConfiguration() } returns mockk { - every { general.modalities } returns listOf(GeneralConfiguration.Modality.FACE) + every { general.modalities } returns listOf(Modality.FACE) } exitFormViewModel.start() @@ -68,7 +64,7 @@ internal class ExitFormViewModelTest { @Test fun `show scanner options when configuration contains fingerprint`() = runTest { coEvery { configManager.getProjectConfiguration() } returns mockk { - every { general.modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { general.modalities } returns listOf(Modality.FINGERPRINT) } exitFormViewModel.start() diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/ExternalCredentialContract.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/ExternalCredentialContract.kt index 2aeb320d87..f153415cf6 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/ExternalCredentialContract.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/ExternalCredentialContract.kt @@ -2,9 +2,9 @@ package com.simprints.feature.externalcredential import com.simprints.core.ExcludedFromGeneratedTestCoverageReports import com.simprints.core.domain.common.FlowType +import com.simprints.core.domain.sample.CaptureSample import com.simprints.feature.externalcredential.model.ExternalCredentialParams import com.simprints.infra.config.store.models.AgeGroup -import com.simprints.infra.matching.MatchParams @ExcludedFromGeneratedTestCoverageReports("Navigation class") object ExternalCredentialContract { @@ -15,8 +15,8 @@ object ExternalCredentialContract { flowType: FlowType, ageGroup: AgeGroup?, probeReferenceId: String? = null, - faceSamples: List = emptyList(), - fingerprintSamples: List = emptyList(), + faceSamples: List = emptyList(), + fingerprintSamples: List = emptyList(), ) = ExternalCredentialParams( subjectId = subjectId, flowType = flowType, diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/CredentialMatch.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/CredentialMatch.kt index 3fd619dac9..7fadc7c165 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/CredentialMatch.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/CredentialMatch.kt @@ -2,17 +2,17 @@ package com.simprints.feature.externalcredential.model import androidx.annotation.Keep import com.simprints.core.ExcludedFromGeneratedTestCoverageReports +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.core.domain.step.StepResult import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.infra.config.store.models.FaceConfiguration import com.simprints.infra.config.store.models.FingerprintConfiguration -import com.simprints.infra.matching.MatchResultItem @Keep @ExcludedFromGeneratedTestCoverageReports("Data class") data class CredentialMatch( val credential: TokenizableString.Tokenized, - val matchResult: MatchResultItem, + val matchResult: MatchComparisonResult, val verificationThreshold: Float, val faceBioSdk: FaceConfiguration.BioSdk?, val fingerprintBioSdk: FingerprintConfiguration.BioSdk?, diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/ExternalCredentialParams.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/ExternalCredentialParams.kt index 54060a72c9..461fc5f77c 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/ExternalCredentialParams.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/model/ExternalCredentialParams.kt @@ -3,9 +3,9 @@ package com.simprints.feature.externalcredential.model import androidx.annotation.Keep import com.simprints.core.ExcludedFromGeneratedTestCoverageReports import com.simprints.core.domain.common.FlowType +import com.simprints.core.domain.sample.CaptureSample import com.simprints.core.domain.step.StepParams import com.simprints.infra.config.store.models.AgeGroup -import com.simprints.infra.matching.MatchParams @Keep @ExcludedFromGeneratedTestCoverageReports("Data class") @@ -14,6 +14,6 @@ data class ExternalCredentialParams( val flowType: FlowType, val ageGroup: AgeGroup?, val probeReferenceId: String?, - val faceSamples: List, - val fingerprintSamples: List, + val faceSamples: List, + val fingerprintSamples: List, ) : StepParams diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/search/usecase/CreateMatchParamsUseCase.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/search/usecase/CreateMatchParamsUseCase.kt index 241cbe01a8..b7ee13f92b 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/search/usecase/CreateMatchParamsUseCase.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/search/usecase/CreateMatchParamsUseCase.kt @@ -1,8 +1,9 @@ package com.simprints.feature.externalcredential.screens.search.usecase import com.simprints.core.domain.common.FlowType +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureSample import com.simprints.infra.config.store.models.AgeGroup -import com.simprints.infra.config.store.models.GeneralConfiguration.Modality import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.determineFaceSDKs import com.simprints.infra.config.store.models.determineFingerprintSDKs @@ -17,27 +18,39 @@ internal class CreateMatchParamsUseCase @Inject constructor() { flowType: FlowType, probeReferenceId: String?, projectConfiguration: ProjectConfiguration, - faceSamples: List, - fingerprintSamples: List, + faceSamples: List, + fingerprintSamples: List, ageGroup: AgeGroup?, ): List = projectConfiguration.general.matchingModalities .map { modality -> - val template = MatchParams( - probeReferenceId = probeReferenceId.orEmpty(), - flowType = flowType, - queryForCandidates = SubjectQuery(subjectId = candidateSubjectId), - biometricDataSource = BiometricDataSource.Simprints, // [MS-1167] No CoSync in initial MF-ID implementation - ) when (modality) { Modality.FACE -> projectConfiguration .determineFaceSDKs(ageGroup) - .map { template.copy(faceSDK = it, probeFaceSamples = faceSamples) } + .map { + MatchParams( + probeReferenceId = probeReferenceId.orEmpty(), + flowType = flowType, + queryForCandidates = SubjectQuery(subjectId = candidateSubjectId), + bioSdk = it, + probeFaceSamples = faceSamples, + biometricDataSource = BiometricDataSource.Simprints, // [MS-1167] No CoSync in initial MF-ID implementation + ) + } Modality.FINGERPRINT -> projectConfiguration .determineFingerprintSDKs(ageGroup) - .map { template.copy(fingerprintSDK = it, probeFingerprintSamples = fingerprintSamples) } + .map { + MatchParams( + probeReferenceId = probeReferenceId.orEmpty(), + flowType = flowType, + queryForCandidates = SubjectQuery(subjectId = candidateSubjectId), + bioSdk = it, + probeFingerprintSamples = fingerprintSamples, + biometricDataSource = BiometricDataSource.Simprints, // [MS-1167] No CoSync in initial MF-ID implementation + ) + } } }.flatten() } diff --git a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/search/usecase/MatchCandidatesUseCase.kt b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/search/usecase/MatchCandidatesUseCase.kt index b63d6e6d79..b8e74dec63 100644 --- a/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/search/usecase/MatchCandidatesUseCase.kt +++ b/feature/external-credential/src/main/java/com/simprints/feature/externalcredential/screens/search/usecase/MatchCandidatesUseCase.kt @@ -3,6 +3,8 @@ package com.simprints.feature.externalcredential.screens.search.usecase import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.feature.externalcredential.model.CredentialMatch import com.simprints.feature.externalcredential.model.ExternalCredentialParams +import com.simprints.infra.config.store.models.FaceConfiguration +import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.enrolment.records.repository.domain.models.Subject @@ -37,17 +39,17 @@ internal class MatchCandidatesUseCase @Inject constructor( .mapNotNull { matchParams -> when { matchParams.probeFaceSamples.isNotEmpty() -> { - val faceSdk = matchParams.faceSDK ?: return@mapNotNull null + val faceSdk = matchParams.bioSdk projectConfig.face?.getSdkConfiguration(faceSdk)?.verificationMatchThreshold?.let { matchThreshold -> (faceMatcher(matchParams, project).last() as? MatcherState.Success) - ?.matchResultItems + ?.comparisonResults .orEmpty() .map { result -> CredentialMatch( credential = credential, matchResult = result, verificationThreshold = matchThreshold, - faceBioSdk = faceSdk, + faceBioSdk = faceSdk as FaceConfiguration.BioSdk, fingerprintBioSdk = null, ) } @@ -55,10 +57,10 @@ internal class MatchCandidatesUseCase @Inject constructor( } else -> { - val fingerprintSdk = matchParams.fingerprintSDK ?: return@mapNotNull null + val fingerprintSdk = matchParams.bioSdk projectConfig.fingerprint?.getSdkConfiguration(fingerprintSdk)?.verificationMatchThreshold?.let { matchThreshold -> (fingerprintMatcher(matchParams, project).last() as? MatcherState.Success) - ?.matchResultItems + ?.comparisonResults .orEmpty() .map { result -> CredentialMatch( @@ -66,7 +68,7 @@ internal class MatchCandidatesUseCase @Inject constructor( matchResult = result, verificationThreshold = matchThreshold, faceBioSdk = null, - fingerprintBioSdk = fingerprintSdk, + fingerprintBioSdk = fingerprintSdk as FingerprintConfiguration.BioSdk, ) } } diff --git a/feature/external-credential/src/test/java/com/simprints/feature/externalcredential/screens/search/usecase/CreateMatchParamsUseCaseTest.kt b/feature/external-credential/src/test/java/com/simprints/feature/externalcredential/screens/search/usecase/CreateMatchParamsUseCaseTest.kt index c3c7da0ce5..da65fb27a8 100644 --- a/feature/external-credential/src/test/java/com/simprints/feature/externalcredential/screens/search/usecase/CreateMatchParamsUseCaseTest.kt +++ b/feature/external-credential/src/test/java/com/simprints/feature/externalcredential/screens/search/usecase/CreateMatchParamsUseCaseTest.kt @@ -2,6 +2,8 @@ package com.simprints.feature.externalcredential.screens.search.usecase import com.google.common.truth.Truth.* import com.simprints.core.domain.common.FlowType +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureSample import com.simprints.infra.config.store.models.AgeGroup import com.simprints.infra.config.store.models.FaceConfiguration import com.simprints.infra.config.store.models.FingerprintConfiguration @@ -10,7 +12,6 @@ import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.determineFaceSDKs import com.simprints.infra.config.store.models.determineFingerprintSDKs import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource -import com.simprints.infra.matching.MatchParams import io.mockk.* import io.mockk.impl.annotations.MockK import org.junit.Before @@ -25,10 +26,10 @@ internal class CreateMatchParamsUseCaseTest { private val ageGroup = AgeGroup(25, 30) @MockK - private lateinit var faceSample: MatchParams.FaceSample + private lateinit var faceSample: CaptureSample @MockK - private lateinit var fingerprintSample: MatchParams.FingerprintSample + private lateinit var fingerprintSample: CaptureSample @MockK private lateinit var generalConfiguration: GeneralConfiguration @@ -44,13 +45,13 @@ internal class CreateMatchParamsUseCaseTest { } @Test - fun ` creates correct MatchParams for face modality`() { + fun `creates correct MatchParams for face modality`() { every { projectConfiguration.determineFaceSDKs(ageGroup) } returns listOf( FaceConfiguration.BioSdk.RANK_ONE, FaceConfiguration.BioSdk.SIM_FACE, ) every { projectConfiguration.determineFingerprintSDKs(ageGroup) } returns emptyList() - every { generalConfiguration.matchingModalities } returns listOf(GeneralConfiguration.Modality.FACE) + every { generalConfiguration.matchingModalities } returns listOf(Modality.FACE) val result = useCase( candidateSubjectId = subjectId, @@ -69,20 +70,20 @@ internal class CreateMatchParamsUseCaseTest { assertThat(matchParams.queryForCandidates.subjectId).isEqualTo(subjectId) assertThat(matchParams.biometricDataSource).isEqualTo(BiometricDataSource.Simprints) assertThat(matchParams.probeFaceSamples).containsExactly(faceSample) - assertThat(matchParams.faceSDK).isNotNull() + assertThat(matchParams.bioSdk).isNotNull() } - assertThat(result[0].faceSDK).isEqualTo(FaceConfiguration.BioSdk.RANK_ONE) - assertThat(result[1].faceSDK).isEqualTo(FaceConfiguration.BioSdk.SIM_FACE) + assertThat(result[0].bioSdk).isEqualTo(FaceConfiguration.BioSdk.RANK_ONE) + assertThat(result[1].bioSdk).isEqualTo(FaceConfiguration.BioSdk.SIM_FACE) } @Test - fun ` creates correct MatchParams for fingerprint modality`() { + fun `creates correct MatchParams for fingerprint modality`() { every { projectConfiguration.determineFaceSDKs(ageGroup) } returns emptyList() every { projectConfiguration.determineFingerprintSDKs(ageGroup) } returns listOf( FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, FingerprintConfiguration.BioSdk.NEC, ) - every { generalConfiguration.matchingModalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { generalConfiguration.matchingModalities } returns listOf(Modality.FINGERPRINT) val result = useCase( candidateSubjectId = subjectId, @@ -101,17 +102,17 @@ internal class CreateMatchParamsUseCaseTest { assertThat(matchParams.queryForCandidates.subjectId).isEqualTo(subjectId) assertThat(matchParams.biometricDataSource).isEqualTo(BiometricDataSource.Simprints) assertThat(matchParams.probeFingerprintSamples).containsExactly(fingerprintSample) - assertThat(matchParams.fingerprintSDK).isNotNull() + assertThat(matchParams.bioSdk).isNotNull() } - assertThat(result[0].fingerprintSDK).isEqualTo(FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER) - assertThat(result[1].fingerprintSDK).isEqualTo(FingerprintConfiguration.BioSdk.NEC) + assertThat(result[0].bioSdk).isEqualTo(FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER) + assertThat(result[1].bioSdk).isEqualTo(FingerprintConfiguration.BioSdk.NEC) } @Test - fun ` creates correct MatchParams for multiple`() { + fun `creates correct MatchParams for multiple`() { every { generalConfiguration.matchingModalities } returns listOf( - GeneralConfiguration.Modality.FACE, - GeneralConfiguration.Modality.FINGERPRINT, + Modality.FACE, + Modality.FINGERPRINT, ) every { projectConfiguration.determineFaceSDKs(ageGroup) } returns listOf( FaceConfiguration.BioSdk.RANK_ONE, @@ -132,24 +133,24 @@ internal class CreateMatchParamsUseCaseTest { assertThat(result).hasSize(2) - val faceMatch = result.find { it.faceSDK != null } + val faceMatch = result.find { it.bioSdk is FaceConfiguration.BioSdk } assertThat(faceMatch).isNotNull() - assertThat(faceMatch?.faceSDK).isEqualTo(FaceConfiguration.BioSdk.RANK_ONE) + assertThat(faceMatch?.bioSdk).isEqualTo(FaceConfiguration.BioSdk.RANK_ONE) assertThat(faceMatch?.probeFaceSamples).containsExactly(faceSample) - val fingerprintMatch = result.find { it.fingerprintSDK != null } + val fingerprintMatch = result.find { it.bioSdk is FingerprintConfiguration.BioSdk } assertThat(fingerprintMatch).isNotNull() - assertThat(fingerprintMatch?.fingerprintSDK).isEqualTo(FingerprintConfiguration.BioSdk.NEC) + assertThat(fingerprintMatch?.bioSdk).isEqualTo(FingerprintConfiguration.BioSdk.NEC) assertThat(fingerprintMatch?.probeFingerprintSamples).containsExactly(fingerprintSample) } @Test - fun ` handles null ageGroup`() { + fun `handles null ageGroup`() { every { projectConfiguration.determineFaceSDKs(null) } returns listOf( FaceConfiguration.BioSdk.RANK_ONE, ) every { projectConfiguration.determineFingerprintSDKs(null) } returns emptyList() - every { generalConfiguration.matchingModalities } returns listOf(GeneralConfiguration.Modality.FACE) + every { generalConfiguration.matchingModalities } returns listOf(Modality.FACE) val result = useCase( candidateSubjectId = subjectId, @@ -165,7 +166,7 @@ internal class CreateMatchParamsUseCaseTest { } @Test - fun ` returns empty list when no SDKs available`() { + fun `returns empty list when no SDKs available`() { every { projectConfiguration.determineFaceSDKs(ageGroup) } returns emptyList() every { projectConfiguration.determineFingerprintSDKs(ageGroup) } returns emptyList() @@ -183,13 +184,13 @@ internal class CreateMatchParamsUseCaseTest { } @Test - fun ` creates multiple MatchParams for multiple face SDKs`() { + fun `creates multiple MatchParams for multiple face SDKs`() { every { projectConfiguration.determineFaceSDKs(ageGroup) } returns listOf( FaceConfiguration.BioSdk.RANK_ONE, FaceConfiguration.BioSdk.SIM_FACE, ) every { projectConfiguration.determineFingerprintSDKs(ageGroup) } returns emptyList() - every { generalConfiguration.matchingModalities } returns listOf(GeneralConfiguration.Modality.FACE) + every { generalConfiguration.matchingModalities } returns listOf(Modality.FACE) val faceSamples = listOf(faceSample, mockk(relaxed = true)) diff --git a/feature/external-credential/src/test/java/com/simprints/feature/externalcredential/screens/search/usecase/MatchCandidatesUseCaseTest.kt b/feature/external-credential/src/test/java/com/simprints/feature/externalcredential/screens/search/usecase/MatchCandidatesUseCaseTest.kt index b7e07b2fe1..1069e4826d 100644 --- a/feature/external-credential/src/test/java/com/simprints/feature/externalcredential/screens/search/usecase/MatchCandidatesUseCaseTest.kt +++ b/feature/external-credential/src/test/java/com/simprints/feature/externalcredential/screens/search/usecase/MatchCandidatesUseCaseTest.kt @@ -2,6 +2,8 @@ package com.simprints.feature.externalcredential.screens.search.usecase import com.google.common.truth.Truth.* import com.simprints.core.domain.common.FlowType +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.feature.externalcredential.model.ExternalCredentialParams import com.simprints.infra.config.store.models.AgeGroup @@ -11,7 +13,6 @@ import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.enrolment.records.repository.domain.models.Subject import com.simprints.infra.matching.MatchParams -import com.simprints.infra.matching.MatchResultItem import com.simprints.infra.matching.usecase.FaceMatcherUseCase import com.simprints.infra.matching.usecase.FingerprintMatcherUseCase import com.simprints.infra.matching.usecase.MatcherUseCase.MatcherState @@ -59,16 +60,16 @@ internal class MatchCandidatesUseCaseTest { private lateinit var fingerprintSdkConfig: FingerprintConfiguration.FingerprintSdkConfiguration @MockK - private lateinit var matchResultItem: MatchResultItem + private lateinit var matchResultItem: MatchComparisonResult @MockK private lateinit var matchParams: MatchParams @MockK - private lateinit var faceSample: MatchParams.FaceSample + private lateinit var faceSample: CaptureSample @MockK - private lateinit var fingerprintSample: MatchParams.FingerprintSample + private lateinit var fingerprintSample: CaptureSample @MockK private lateinit var ageGroup: AgeGroup @@ -97,8 +98,6 @@ internal class MatchCandidatesUseCaseTest { every { externalCredentialParams.fingerprintSamples } returns listOf(fingerprintSample) every { externalCredentialParams.ageGroup } returns ageGroup - every { matchParams.faceSDK } returns FaceConfiguration.BioSdk.RANK_ONE - every { matchParams.fingerprintSDK } returns FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER coEvery { createMatchParamsUseCase( candidateSubjectId = any(), @@ -116,21 +115,21 @@ internal class MatchCandidatesUseCaseTest { every { faceSdkConfig.verificationMatchThreshold } returns verificationMatchThreshold every { fingerprintConfig.getSdkConfiguration(FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER) } returns fingerprintSdkConfig every { fingerprintSdkConfig.verificationMatchThreshold } returns verificationMatchThreshold - every { matcherSuccess.matchResultItems } returns listOf(matchResultItem) + every { matcherSuccess.comparisonResults } returns listOf(matchResultItem) coEvery { faceMatcher(matchParams, project) } returns flowOf(matcherSuccess) coEvery { fingerprintMatcher(matchParams, project) } returns flowOf(matcherSuccess) } private fun initMatchParams(isFace: Boolean) { - val (faceSamples, fingerprintSamples) = if (isFace) { - listOf(faceSample) to emptyList() + if (isFace) { + every { matchParams.probeFingerprintSamples } returns emptyList() + every { matchParams.probeFaceSamples } returns listOf(faceSample) + every { matchParams.bioSdk } returns FaceConfiguration.BioSdk.RANK_ONE } else { - emptyList() to listOf(fingerprintSample) + every { matchParams.probeFingerprintSamples } returns listOf(fingerprintSample) + every { matchParams.probeFaceSamples } returns emptyList() + every { matchParams.bioSdk } returns FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER } - every { matchParams.probeFaceSamples } returns faceSamples - every { matchParams.faceSDK } returns FaceConfiguration.BioSdk.RANK_ONE - every { matchParams.probeFingerprintSamples } returns fingerprintSamples - every { matchParams.fingerprintSDK } returns FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER } @Test @@ -184,38 +183,6 @@ internal class MatchCandidatesUseCaseTest { assertThat(result).isEmpty() } - @Test - fun `returns empty list when face SDK is null`() = runTest { - initMatchParams(isFace = true) - every { matchParams.faceSDK } returns null - - val result = useCase.invoke( - candidates = listOf(subject), - credential = credential, - externalCredentialParams = externalCredentialParams, - project = project, - projectConfig = projectConfig, - ) - - assertThat(result).isEmpty() - } - - @Test - fun `returns empty list when fingerprint SDK is null`() = runTest { - initMatchParams(isFace = false) - every { matchParams.fingerprintSDK } returns null - - val result = useCase.invoke( - candidates = listOf(subject), - credential = credential, - externalCredentialParams = externalCredentialParams, - project = project, - projectConfig = projectConfig, - ) - - assertThat(result).isEmpty() - } - @Test fun `returns empty list when face SDK configuration is null`() = runTest { initMatchParams(isFace = true) diff --git a/feature/matcher/src/main/java/com/simprints/matcher/MatchContract.kt b/feature/matcher/src/main/java/com/simprints/matcher/MatchContract.kt index 79efa31499..9606843f82 100644 --- a/feature/matcher/src/main/java/com/simprints/matcher/MatchContract.kt +++ b/feature/matcher/src/main/java/com/simprints/matcher/MatchContract.kt @@ -1,8 +1,8 @@ package com.simprints.matcher import com.simprints.core.domain.common.FlowType -import com.simprints.infra.config.store.models.FaceConfiguration -import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.core.domain.common.ModalitySdkType +import com.simprints.core.domain.sample.CaptureSample import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery import com.simprints.infra.matching.MatchParams @@ -12,21 +12,19 @@ object MatchContract { fun getParams( referenceId: String = "", - fingerprintSamples: List = emptyList(), - faceSamples: List = emptyList(), - fingerprintSDK: FingerprintConfiguration.BioSdk? = null, - faceSDK: FaceConfiguration.BioSdk? = null, + fingerprintSamples: List = emptyList(), + faceSamples: List = emptyList(), + bioSdk: ModalitySdkType, flowType: FlowType, subjectQuery: SubjectQuery, biometricDataSource: BiometricDataSource, ) = MatchParams( - referenceId, - faceSamples, - faceSDK, - fingerprintSamples, - fingerprintSDK, - flowType, - subjectQuery, - biometricDataSource, + probeReferenceId = referenceId, + bioSdk = bioSdk, + probeFaceSamples = faceSamples, + probeFingerprintSamples = fingerprintSamples, + flowType = flowType, + queryForCandidates = subjectQuery, + biometricDataSource = biometricDataSource, ) } diff --git a/feature/matcher/src/main/java/com/simprints/matcher/screen/MatchViewModel.kt b/feature/matcher/src/main/java/com/simprints/matcher/screen/MatchViewModel.kt index fa86d5a068..b90b151d8d 100644 --- a/feature/matcher/src/main/java/com/simprints/matcher/screen/MatchViewModel.kt +++ b/feature/matcher/src/main/java/com/simprints/matcher/screen/MatchViewModel.kt @@ -4,16 +4,17 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.core.livedata.LiveDataEventWithContent import com.simprints.core.livedata.send import com.simprints.core.tools.time.TimeHelper import com.simprints.infra.authstore.AuthStore import com.simprints.infra.config.store.models.DecisionPolicy +import com.simprints.infra.config.store.models.FaceConfiguration +import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.sync.ConfigManager -import com.simprints.infra.matching.FaceMatchResult -import com.simprints.infra.matching.FingerprintMatchResult import com.simprints.infra.matching.MatchParams -import com.simprints.infra.matching.MatchResultItem +import com.simprints.infra.matching.MatchResult import com.simprints.infra.matching.usecase.FaceMatcherUseCase import com.simprints.infra.matching.usecase.FingerprintMatcherUseCase import com.simprints.infra.matching.usecase.MatcherUseCase @@ -21,7 +22,6 @@ import com.simprints.infra.matching.usecase.SaveMatchEventUseCase import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import java.io.Serializable import javax.inject.Inject @HiltViewModel @@ -45,9 +45,9 @@ internal class MatchViewModel @Inject constructor( get() = _matchState private val _matchState = MutableLiveData(MatchState.NotStarted) - val matchResponse: LiveData> + val matchResponse: LiveData> get() = _matchResponse - private val _matchResponse = MutableLiveData>() + private val _matchResponse = MutableLiveData>() fun setupMatch(params: MatchParams) = viewModelScope.launch { if (isMatcherRunning) return@launch @@ -86,21 +86,16 @@ internal class MatchViewModel @Inject constructor( params, matcherState.totalCandidates, matcherState.matcherName, - matcherState.matchResultItems, + matcherState.comparisonResults, matcherState.matchBatches, ) - setMatchState(matcherState.totalCandidates, matcherState.matchResultItems, decisionPolicy) + setMatchState(matcherState.totalCandidates, matcherState.comparisonResults, decisionPolicy) // wait a bit for the user to see the results delay(MATCHING_END_WAIT_TIME_MS) - _matchResponse.send( - when { - isFaceMatch -> FaceMatchResult(matcherState.matchResultItems, params.faceSDK!!) - else -> FingerprintMatchResult(matcherState.matchResultItems, params.fingerprintSDK!!) - }, - ) + _matchResponse.send(MatchResult(matcherState.comparisonResults, params.bioSdk)) } } } @@ -108,11 +103,9 @@ internal class MatchViewModel @Inject constructor( private suspend fun getDecisionPolicy(params: MatchParams): DecisionPolicy { val config = configManager.getProjectConfiguration() - val faceSDK = params.faceSDK - val fingerprintSDK = params.fingerprintSDK - val policy = when { - faceSDK != null -> config.face?.getSdkConfiguration(faceSDK)?.decisionPolicy - fingerprintSDK != null -> config.fingerprint?.getSdkConfiguration(fingerprintSDK)?.decisionPolicy + val policy = when (params.bioSdk) { + is FaceConfiguration.BioSdk -> config.face?.getSdkConfiguration(params.bioSdk)?.decisionPolicy + is FingerprintConfiguration.BioSdk -> config.fingerprint?.getSdkConfiguration(params.bioSdk)?.decisionPolicy else -> null } return policy ?: fallbackDecisionPolicy() @@ -120,7 +113,7 @@ internal class MatchViewModel @Inject constructor( private fun setMatchState( candidatesMatched: Int, - results: List, + results: List, decisionPolicy: DecisionPolicy, ) { val veryGoodMatches = results.count { decisionPolicy.high <= it.confidence } diff --git a/feature/matcher/src/test/java/com/simprints/matcher/screen/MatchViewModelTest.kt b/feature/matcher/src/test/java/com/simprints/matcher/screen/MatchViewModelTest.kt index 67e2573625..0d7304ab2c 100644 --- a/feature/matcher/src/test/java/com/simprints/matcher/screen/MatchViewModelTest.kt +++ b/feature/matcher/src/test/java/com/simprints/matcher/screen/MatchViewModelTest.kt @@ -4,7 +4,10 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.google.common.truth.Truth.* import com.jraska.livedata.test import com.simprints.core.domain.common.FlowType -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.MatchComparisonResult +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp import com.simprints.infra.authstore.AuthStore @@ -13,10 +16,9 @@ import com.simprints.infra.config.store.models.FaceConfiguration import com.simprints.infra.config.store.models.FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource -import com.simprints.infra.matching.FaceMatchResult -import com.simprints.infra.matching.FingerprintMatchResult import com.simprints.infra.matching.MatchBatchInfo import com.simprints.infra.matching.MatchParams +import com.simprints.infra.matching.MatchResult import com.simprints.infra.matching.usecase.FaceMatcherUseCase import com.simprints.infra.matching.usecase.FingerprintMatcherUseCase import com.simprints.infra.matching.usecase.MatcherUseCase @@ -85,7 +87,7 @@ internal class MatchViewModelTest { @Test fun `when setup is called, then view model becomes initialized`() = runTest { val responseItems = listOf( - FaceMatchResult.Item("1", 90f), + MatchComparisonResult("1", 90f), ) coEvery { faceMatcherUseCase.invoke(any(), any()) } returns flow { @@ -93,7 +95,7 @@ internal class MatchViewModelTest { emit(MatcherUseCase.MatcherState.CandidateLoaded) emit( MatcherUseCase.MatcherState.Success( - matchResultItems = responseItems, + comparisonResults = responseItems, totalCandidates = responseItems.size, matcherName = "MatcherName", matchBatches = emptyList(), @@ -109,7 +111,7 @@ internal class MatchViewModelTest { MatchParams( probeReferenceId = "referenceId", probeFaceSamples = listOf(getFaceSample()), - faceSDK = FaceConfiguration.BioSdk.RANK_ONE, + bioSdk = FaceConfiguration.BioSdk.RANK_ONE, flowType = FlowType.ENROL, queryForCandidates = mockk {}, biometricDataSource = BiometricDataSource.Simprints, @@ -137,13 +139,13 @@ internal class MatchViewModelTest { } returns DecisionPolicy(20, 35, 50) val responseItems = listOf( - FaceMatchResult.Item("1", 90f), - FaceMatchResult.Item("1", 80f), - FaceMatchResult.Item("1", 55f), - FaceMatchResult.Item("1", 40f), - FaceMatchResult.Item("1", 36f), - FaceMatchResult.Item("1", 20f), - FaceMatchResult.Item("1", 10f), + MatchComparisonResult("1", 90f), + MatchComparisonResult("1", 80f), + MatchComparisonResult("1", 55f), + MatchComparisonResult("1", 40f), + MatchComparisonResult("1", 36f), + MatchComparisonResult("1", 20f), + MatchComparisonResult("1", 10f), ) val batches = listOf( MatchBatchInfo( @@ -167,7 +169,7 @@ internal class MatchViewModelTest { emit(MatcherUseCase.MatcherState.CandidateLoaded) emit( MatcherUseCase.MatcherState.Success( - matchResultItems = responseItems, + comparisonResults = responseItems, totalCandidates = responseItems.size, matcherName = MATCHER_NAME, matchBatches = batches, @@ -181,7 +183,7 @@ internal class MatchViewModelTest { MatchParams( probeReferenceId = "referenceId", probeFaceSamples = listOf(getFaceSample()), - faceSDK = FaceConfiguration.BioSdk.RANK_ONE, + bioSdk = FaceConfiguration.BioSdk.RANK_ONE, flowType = FlowType.ENROL, queryForCandidates = mockk {}, biometricDataSource = BiometricDataSource.Simprints, @@ -199,7 +201,7 @@ internal class MatchViewModelTest { ), ) assertThat(viewModel.matchResponse.getOrAwaitValue().peekContent()).isEqualTo( - FaceMatchResult(responseItems, FaceConfiguration.BioSdk.RANK_ONE), + MatchResult(responseItems, FaceConfiguration.BioSdk.RANK_ONE), ) verify { @@ -226,13 +228,13 @@ internal class MatchViewModelTest { } returns DecisionPolicy(200, 350, 500) val responseItems = listOf( - FingerprintMatchResult.Item("1", 900f), - FingerprintMatchResult.Item("1", 800f), - FingerprintMatchResult.Item("1", 550f), - FingerprintMatchResult.Item("1", 400f), - FingerprintMatchResult.Item("1", 360f), - FingerprintMatchResult.Item("1", 200f), - FingerprintMatchResult.Item("1", 100f), + MatchComparisonResult("1", 900f), + MatchComparisonResult("1", 800f), + MatchComparisonResult("1", 550f), + MatchComparisonResult("1", 400f), + MatchComparisonResult("1", 360f), + MatchComparisonResult("1", 200f), + MatchComparisonResult("1", 100f), ) val batches = listOf( MatchBatchInfo( @@ -256,7 +258,7 @@ internal class MatchViewModelTest { emit(MatcherUseCase.MatcherState.CandidateLoaded) emit( MatcherUseCase.MatcherState.Success( - matchResultItems = responseItems, + comparisonResults = responseItems, totalCandidates = responseItems.size, matcherName = MATCHER_NAME, matchBatches = batches, @@ -272,7 +274,7 @@ internal class MatchViewModelTest { MatchParams( probeReferenceId = "referenceId", probeFingerprintSamples = listOf(getFingerprintSample()), - fingerprintSDK = SECUGEN_SIM_MATCHER, + bioSdk = SECUGEN_SIM_MATCHER, flowType = FlowType.ENROL, queryForCandidates = mockk {}, biometricDataSource = BiometricDataSource.Simprints, @@ -290,7 +292,7 @@ internal class MatchViewModelTest { ), ) assertThat(viewModel.matchResponse.getOrAwaitValue().peekContent()).isEqualTo( - FingerprintMatchResult(responseItems, SECUGEN_SIM_MATCHER), + MatchResult(responseItems, SECUGEN_SIM_MATCHER), ) verify { @@ -317,14 +319,14 @@ internal class MatchViewModelTest { } returns null val responseItems = listOf( - FaceMatchResult.Item("1", 90f), - FaceMatchResult.Item("1", 10f), + MatchComparisonResult("1", 90f), + MatchComparisonResult("1", 10f), ) coEvery { faceMatcherUseCase.invoke(any(), any()) } returns flow { emit(MatcherUseCase.MatcherState.LoadingStarted(responseItems.size)) emit( MatcherUseCase.MatcherState.Success( - matchResultItems = responseItems, + comparisonResults = responseItems, totalCandidates = responseItems.size, matcherName = MATCHER_NAME, matchBatches = emptyList(), @@ -337,7 +339,7 @@ internal class MatchViewModelTest { MatchParams( probeReferenceId = "referenceId", probeFaceSamples = listOf(getFaceSample()), - faceSDK = FaceConfiguration.BioSdk.RANK_ONE, + bioSdk = FaceConfiguration.BioSdk.RANK_ONE, flowType = FlowType.ENROL, queryForCandidates = mockk {}, biometricDataSource = BiometricDataSource.Simprints, @@ -363,7 +365,7 @@ internal class MatchViewModelTest { emit(MatcherUseCase.MatcherState.CandidateLoaded) emit( MatcherUseCase.MatcherState.Success( - matchResultItems = listOf(FaceMatchResult.Item("1", 90f)), + comparisonResults = listOf(MatchComparisonResult("1", 90f)), totalCandidates = 1, matcherName = MATCHER_NAME, matchBatches = emptyList(), @@ -376,7 +378,7 @@ internal class MatchViewModelTest { val matchParams = MatchParams( probeReferenceId = "referenceId", probeFaceSamples = listOf(getFaceSample()), - faceSDK = FaceConfiguration.BioSdk.RANK_ONE, + bioSdk = FaceConfiguration.BioSdk.RANK_ONE, flowType = FlowType.ENROL, queryForCandidates = mockk {}, biometricDataSource = BiometricDataSource.Simprints, @@ -387,17 +389,26 @@ internal class MatchViewModelTest { viewModel.setupMatch(matchParams) advanceUntilIdle() - coVerify(exactly = 1) { faceMatcherUseCase.invoke(any(), any()) } + coVerify(exactly = 1) { + faceMatcherUseCase.invoke(any(), any()) + } // Checking that no new states were emitted. History = (NotStarted, LoadingCandidates LoadingCandidates, Finished) assertThat(states.valueHistory()).hasSize(4) } - private fun getFaceSample(): MatchParams.FaceSample = MatchParams.FaceSample(UUID.randomUUID().toString(), Random.nextBytes(20)) + private fun getFaceSample(): CaptureSample = CaptureSample( + captureEventId = UUID.randomUUID().toString(), + modality = Modality.FACE, + template = Random.nextBytes(20), + format = "format", + ) - private fun getFingerprintSample(): MatchParams.FingerprintSample = MatchParams.FingerprintSample( - IFingerIdentifier.LEFT_3RD_FINGER, - "format", - Random.nextBytes(20), + private fun getFingerprintSample(): CaptureSample = CaptureSample( + captureEventId = UUID.randomUUID().toString(), + modality = Modality.FINGERPRINT, + template = Random.nextBytes(20), + format = "format", + identifier = SampleIdentifier.LEFT_3RD_FINGER, ) companion object { diff --git a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/OrchestratorViewModel.kt b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/OrchestratorViewModel.kt index 9bbd9ca7f7..cf9380d8e7 100644 --- a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/OrchestratorViewModel.kt +++ b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/OrchestratorViewModel.kt @@ -7,7 +7,9 @@ import androidx.lifecycle.viewModelScope import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.databind.module.SimpleModule import com.simprints.core.domain.common.FlowType +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.response.AppErrorReason +import com.simprints.core.domain.sample.CaptureIdentity import com.simprints.core.domain.step.StepResult import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.domain.tokenization.serialization.TokenizationClassNameDeserializer @@ -16,7 +18,6 @@ import com.simprints.core.livedata.LiveDataEventWithContent import com.simprints.core.livedata.send import com.simprints.core.tools.json.JsonHelper import com.simprints.face.capture.FaceCaptureParams -import com.simprints.face.capture.FaceCaptureResult import com.simprints.feature.enrollast.EnrolLastBiometricContract import com.simprints.feature.enrollast.EnrolLastBiometricParams import com.simprints.feature.externalcredential.ExternalCredentialSearchResult @@ -37,12 +38,9 @@ import com.simprints.feature.orchestrator.usecases.steps.BuildStepsUseCase import com.simprints.feature.selectagegroup.SelectSubjectAgeGroupResult import com.simprints.feature.setup.LocationStore import com.simprints.fingerprint.capture.FingerprintCaptureParams -import com.simprints.fingerprint.capture.FingerprintCaptureResult -import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.logging.LoggingConstants.CrashReportTag.ORCHESTRATION import com.simprints.infra.logging.Simber -import com.simprints.infra.matching.MatchParams import com.simprints.infra.orchestration.data.ActionRequest import com.simprints.infra.orchestration.data.responses.AppErrorResponse import com.simprints.infra.orchestration.data.responses.AppResponse @@ -68,7 +66,7 @@ internal class OrchestratorViewModel @Inject constructor( // [MS-1127] MF-ID: during enrolment, the same 'subjectId' needs to be used during the entire workflow private val enrolmentSubjectId = UUID.randomUUID().toString() - private var modalities = emptySet() + private var modalities = emptySet() private var steps = emptyList() private var actionRequest: ActionRequest? = null @@ -258,55 +256,43 @@ internal class OrchestratorViewModel @Inject constructor( currentStep: Step, result: Serializable, ) { - if (currentStep.id == StepId.FACE_CAPTURE && result is FaceCaptureResult) { + if (currentStep.id == StepId.FACE_CAPTURE && result is CaptureIdentity) { val captureParams = currentStep.params?.let { it as? FaceCaptureParams } val matchingStep = steps.firstOrNull { step -> if (step.id != StepId.FACE_MATCHER) { false } else { - val stepSdk = step.params?.let { it as? MatchStepStubPayload }?.faceSDK + val stepSdk = step.params?.let { it as? MatchStepStubPayload }?.bioSdk stepSdk == captureParams?.faceSDK } } if (matchingStep != null) { - val faceSamples = result.results - .mapNotNull { it.sample } - .map { MatchParams.FaceSample(it.faceId, it.template) } val newPayload = matchingStep.params ?.let { it as? MatchStepStubPayload } - ?.toFaceStepArgs(result.referenceId, faceSamples) + ?.toFaceStepArgs(result.referenceId, result.samples) if (newPayload != null) { matchingStep.params = newPayload } } } - if (currentStep.id == StepId.FINGERPRINT_CAPTURE && result is FingerprintCaptureResult) { + if (currentStep.id == StepId.FINGERPRINT_CAPTURE && result is CaptureIdentity) { val captureParams = currentStep.params?.let { it as? FingerprintCaptureParams } // Find the matching step for the same fingerprint SDK as there may be multiple match steps val matchingStep = steps.firstOrNull { step -> if (step.id != StepId.FINGERPRINT_MATCHER) { false } else { - val stepSdk = step.params?.let { it as? MatchStepStubPayload }?.fingerprintSDK + val stepSdk = step.params?.let { it as? MatchStepStubPayload }?.bioSdk stepSdk == captureParams?.fingerprintSDK } } if (matchingStep != null) { - val fingerprintSamples = result.results - .mapNotNull { it.sample } - .map { - MatchParams.FingerprintSample( - fingerId = it.fingerIdentifier, - format = it.format, - template = it.template, - ) - } val newPayload = matchingStep.params ?.let { it as? MatchStepStubPayload } - ?.toFingerprintStepArgs(result.referenceId, fingerprintSamples) + ?.toFingerprintStepArgs(result.referenceId, result.samples) if (newPayload != null) { matchingStep.params = newPayload @@ -326,29 +312,17 @@ internal class OrchestratorViewModel @Inject constructor( val step = steps.firstOrNull { it.id == StepId.EXTERNAL_CREDENTIAL } ?: return val params = step.params as? ExternalCredentialParams ?: return val updatedParams = when { - currentStep.id == StepId.FACE_CAPTURE && result is FaceCaptureResult -> { - val faceSamples = result.results - .mapNotNull { it.sample } - .map { MatchParams.FaceSample(it.faceId, it.template) } + currentStep.id == StepId.FACE_CAPTURE && result is CaptureIdentity -> { params.copy( probeReferenceId = result.referenceId, - faceSamples = faceSamples, + faceSamples = result.samples, ) } - currentStep.id == StepId.FINGERPRINT_CAPTURE && result is FingerprintCaptureResult -> { - val fingerprintSamples = result.results - .mapNotNull { it.sample } - .map { - MatchParams.FingerprintSample( - fingerId = it.fingerIdentifier, - format = it.format, - template = it.template, - ) - } + currentStep.id == StepId.FINGERPRINT_CAPTURE && result is CaptureIdentity -> { params.copy( probeReferenceId = result.referenceId, - fingerprintSamples = fingerprintSamples, + fingerprintSamples = result.samples, ) } diff --git a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/steps/MatchStepStubPayload.kt b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/steps/MatchStepStubPayload.kt index 176570381b..dd98bd3d24 100644 --- a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/steps/MatchStepStubPayload.kt +++ b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/steps/MatchStepStubPayload.kt @@ -1,9 +1,9 @@ package com.simprints.feature.orchestrator.steps import com.simprints.core.domain.common.FlowType +import com.simprints.core.domain.common.ModalitySdkType +import com.simprints.core.domain.sample.CaptureSample import com.simprints.core.domain.step.StepParams -import com.simprints.infra.config.store.models.FaceConfiguration -import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery import com.simprints.infra.matching.MatchParams @@ -19,16 +19,15 @@ internal data class MatchStepStubPayload( val flowType: FlowType, val subjectQuery: SubjectQuery, val biometricDataSource: BiometricDataSource, - val fingerprintSDK: FingerprintConfiguration.BioSdk?, - val faceSDK: FaceConfiguration.BioSdk?, + val bioSdk: ModalitySdkType, ) : StepParams { fun toFaceStepArgs( referenceId: String, - samples: List, + samples: List, ) = MatchContract.getParams( referenceId = referenceId, faceSamples = samples, - faceSDK = faceSDK, + bioSdk = bioSdk, flowType = flowType, subjectQuery = subjectQuery, biometricDataSource = biometricDataSource, @@ -36,11 +35,11 @@ internal data class MatchStepStubPayload( fun toFingerprintStepArgs( referenceId: String, - samples: List, + samples: List, ) = MatchContract.getParams( referenceId = referenceId, fingerprintSamples = samples, - fingerprintSDK = fingerprintSDK, + bioSdk = bioSdk, flowType = flowType, subjectQuery = subjectQuery, biometricDataSource = biometricDataSource, @@ -53,8 +52,7 @@ internal data class MatchStepStubPayload( flowType: FlowType, subjectQuery: SubjectQuery, biometricDataSource: BiometricDataSource, - fingerprintSDK: FingerprintConfiguration.BioSdk? = null, - faceSDK: FaceConfiguration.BioSdk? = null, - ) = MatchStepStubPayload(flowType, subjectQuery, biometricDataSource, fingerprintSDK, faceSDK) + bioSdk: ModalitySdkType, + ) = MatchStepStubPayload(flowType, subjectQuery, biometricDataSource, bioSdk) } } diff --git a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/steps/Step.kt b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/steps/Step.kt index 2360d0b4e3..696f6e20cb 100644 --- a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/steps/Step.kt +++ b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/steps/Step.kt @@ -4,19 +4,18 @@ import androidx.annotation.IdRes import androidx.annotation.Keep import com.fasterxml.jackson.annotation.JsonSubTypes import com.fasterxml.jackson.annotation.JsonTypeInfo +import com.simprints.core.domain.sample.CaptureIdentity +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.core.domain.step.StepParams import com.simprints.core.domain.step.StepResult import com.simprints.face.capture.FaceCaptureParams -import com.simprints.face.capture.FaceCaptureResult import com.simprints.feature.alert.AlertResult import com.simprints.feature.consent.ConsentParams import com.simprints.feature.consent.ConsentResult import com.simprints.feature.enrollast.EnrolLastBiometricParams import com.simprints.feature.enrollast.EnrolLastBiometricResult import com.simprints.feature.enrollast.EnrolLastBiometricStepResult -import com.simprints.feature.enrollast.FaceTemplateCaptureResult -import com.simprints.feature.enrollast.FingerTemplateCaptureResult -import com.simprints.feature.enrollast.MatchResult import com.simprints.feature.exitform.ExitFormResult import com.simprints.feature.externalcredential.ExternalCredentialSearchResult import com.simprints.feature.externalcredential.model.ExternalCredentialParams @@ -31,14 +30,14 @@ import com.simprints.feature.setup.SetupResult import com.simprints.feature.validatepool.ValidateSubjectPoolFragmentParams import com.simprints.feature.validatepool.ValidateSubjectPoolResult import com.simprints.fingerprint.capture.FingerprintCaptureParams -import com.simprints.fingerprint.capture.FingerprintCaptureResult import com.simprints.fingerprint.connect.FingerprintConnectParams import com.simprints.fingerprint.connect.FingerprintConnectResult +import com.simprints.infra.config.store.models.FaceConfiguration +import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery -import com.simprints.infra.matching.FaceMatchResult -import com.simprints.infra.matching.FingerprintMatchResult import com.simprints.infra.matching.MatchParams +import com.simprints.infra.matching.MatchResult import java.io.Serializable @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "resultType") @@ -47,25 +46,7 @@ import java.io.Serializable JsonSubTypes.Type(value = SetupResult::class, name = "SetupResult"), JsonSubTypes.Type(value = ConsentResult::class, name = "ConsentResult"), JsonSubTypes.Type(value = FingerprintConnectResult::class, name = "FingerprintConnectResult"), - JsonSubTypes.Type(value = FingerprintCaptureResult::class, name = "FingerprintCaptureResult"), - JsonSubTypes.Type( - value = FingerprintCaptureResult.Item::class, - name = "FingerprintCaptureResult.Item", - ), - JsonSubTypes.Type( - value = FingerprintCaptureResult.Sample::class, - name = "FingerprintCaptureResult.Sample", - ), - JsonSubTypes.Type(value = FingerprintMatchResult::class, name = "FingerprintMatchResult"), - JsonSubTypes.Type( - value = FingerprintMatchResult.Item::class, - name = "FingerprintMatchResult.Item", - ), - JsonSubTypes.Type(value = FaceCaptureResult::class, name = "FaceCaptureResult"), - JsonSubTypes.Type(value = FaceCaptureResult.Item::class, name = "FaceCaptureResult.Item"), - JsonSubTypes.Type(value = FaceCaptureResult.Sample::class, name = "FaceCaptureResult.Sample"), - JsonSubTypes.Type(value = FaceMatchResult::class, name = "FaceMatchResult"), - JsonSubTypes.Type(value = FaceMatchResult.Item::class, name = "FaceMatchResult.Item"), + JsonSubTypes.Type(value = MatchResult::class, name = "MatchResult"), JsonSubTypes.Type(value = EnrolLastBiometricResult::class, name = "EnrolLastBiometricResult"), JsonSubTypes.Type(value = FetchSubjectResult::class, name = "FetchSubjectResult"), JsonSubTypes.Type(value = SelectSubjectResult::class, name = "SelectSubjectResult"), @@ -74,6 +55,10 @@ import java.io.Serializable JsonSubTypes.Type(value = ValidateSubjectPoolResult::class, name = "ValidateSubjectPoolResult"), JsonSubTypes.Type(value = SelectSubjectAgeGroupResult::class, name = "SelectSubjectAgeGroupResult"), JsonSubTypes.Type(value = ExternalCredentialSearchResult::class, name = "ExternalCredentialSearchResult"), + // Common data types + JsonSubTypes.Type(value = CaptureIdentity::class, name = "CaptureIdentity"), + JsonSubTypes.Type(value = CaptureSample::class, name = "CaptureSample"), + JsonSubTypes.Type(value = MatchComparisonResult::class, name = "MatchComparisonResult"), ) abstract class StepResultMixin : StepResult @@ -90,8 +75,6 @@ abstract class StepResultMixin : StepResult // Match params are updated after capture steps JsonSubTypes.Type(value = MatchStepStubPayload::class, name = "MatchStepStubPayload"), JsonSubTypes.Type(value = MatchParams::class, name = "MatchParams"), - JsonSubTypes.Type(value = MatchParams.FaceSample::class, name = "MatchParams.FaceSample"), - JsonSubTypes.Type(value = MatchParams.FingerprintSample::class, name = "MatchParams.FingerprintSample"), // Below are subclasses of enrol-last step that takes results of other steps as parameters JsonSubTypes.Type(value = EnrolLastBiometricParams::class, name = "EnrolLastBiometricParams"), JsonSubTypes.Type(value = EnrolLastBiometricStepResult::class, name = "EnrolLastBiometricStepResult"), @@ -100,29 +83,23 @@ abstract class StepResultMixin : StepResult name = "EnrolLastBiometricStepResult.EnrolLastBiometricsResult", ), JsonSubTypes.Type( - value = EnrolLastBiometricStepResult.FingerprintMatchResult::class, - name = "EnrolLastBiometricStepResult.FingerprintMatchResult", - ), - JsonSubTypes.Type( - value = EnrolLastBiometricStepResult.FaceMatchResult::class, - name = "EnrolLastBiometricStepResult.FaceMatchResult", - ), - JsonSubTypes.Type( - value = EnrolLastBiometricStepResult.FingerprintCaptureResult::class, - name = "EnrolLastBiometricStepResult.FingerprintCaptureResult", + value = EnrolLastBiometricStepResult.MatchResult::class, + name = "EnrolLastBiometricStepResult.MatchResult", ), JsonSubTypes.Type( - value = EnrolLastBiometricStepResult.FaceCaptureResult::class, - name = "EnrolLastBiometricStepResult.FaceCaptureResult", + value = EnrolLastBiometricStepResult.CaptureResult::class, + name = "EnrolLastBiometricStepResult.CaptureResult", ), JsonSubTypes.Type(value = ExternalCredentialParams::class, name = "ExternalCredentialParams"), JsonSubTypes.Type(value = ExternalCredentialSearchResult::class, name = "ExternalCredentialSearchResult"), JsonSubTypes.Type(value = MatchResult::class, name = "MatchResult"), - JsonSubTypes.Type(value = FingerTemplateCaptureResult::class, name = "FingerTemplateCaptureResult"), - JsonSubTypes.Type(value = FaceTemplateCaptureResult::class, name = "FaceTemplateCaptureResult"), // Additional types that are used in top-level params + JsonSubTypes.Type(value = CaptureSample::class, name = "CaptureSample"), + JsonSubTypes.Type(value = MatchComparisonResult::class, name = "MatchComparisonResult"), JsonSubTypes.Type(value = BiometricDataSource::class, name = "BiometricDataSource"), JsonSubTypes.Type(value = SubjectQuery::class, name = "SubjectQuery"), + JsonSubTypes.Type(value = FingerprintConfiguration.BioSdk::class, name = "FingerprintConfiguration.BioSdk"), + JsonSubTypes.Type(value = FaceConfiguration.BioSdk::class, name = "FaceConfiguration.BioSdk"), ) abstract class StepParamsMixin : StepParams diff --git a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/MapStepsForLastBiometricEnrolUseCase.kt b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/MapStepsForLastBiometricEnrolUseCase.kt index 251a2183e2..986164d220 100644 --- a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/MapStepsForLastBiometricEnrolUseCase.kt +++ b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/MapStepsForLastBiometricEnrolUseCase.kt @@ -1,15 +1,10 @@ package com.simprints.feature.orchestrator.usecases -import com.simprints.face.capture.FaceCaptureResult +import com.simprints.core.domain.sample.CaptureIdentity +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.feature.enrollast.EnrolLastBiometricResult import com.simprints.feature.enrollast.EnrolLastBiometricStepResult -import com.simprints.feature.enrollast.FaceTemplateCaptureResult -import com.simprints.feature.enrollast.FingerTemplateCaptureResult -import com.simprints.feature.enrollast.MatchResult -import com.simprints.fingerprint.capture.FingerprintCaptureResult -import com.simprints.infra.config.store.models.fromModuleApiToDomain -import com.simprints.infra.matching.FaceMatchResult -import com.simprints.infra.matching.FingerprintMatchResult +import com.simprints.infra.matching.MatchResult import java.io.Serializable import javax.inject.Inject @@ -21,30 +16,13 @@ internal class MapStepsForLastBiometricEnrolUseCase @Inject constructor() { result.newSubjectId, ) - is FingerprintCaptureResult -> EnrolLastBiometricStepResult.FingerprintCaptureResult( + is CaptureIdentity -> EnrolLastBiometricStepResult.CaptureResult( result.referenceId, - result.results.mapNotNull { it.sample }.map { - FingerTemplateCaptureResult( - it.fingerIdentifier.fromModuleApiToDomain(), - it.template, - it.templateQualityScore, - it.format, - ) - }, + result.samples, ) - is FingerprintMatchResult -> EnrolLastBiometricStepResult.FingerprintMatchResult( - result.results.map { MatchResult(it.subjectId, it.confidence) }, - result.sdk, - ) - - is FaceCaptureResult -> EnrolLastBiometricStepResult.FaceCaptureResult( - result.referenceId, - result.results.mapNotNull { it.sample }.map { FaceTemplateCaptureResult(it.template, it.format) }, - ) - - is FaceMatchResult -> EnrolLastBiometricStepResult.FaceMatchResult( - result.results.map { MatchResult(it.subjectId, it.confidence) }, + is MatchResult -> EnrolLastBiometricStepResult.MatchResult( + result.results.map { MatchComparisonResult(it.subjectId, it.confidence) }, result.sdk, ) diff --git a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/CreateEnrolResponseUseCase.kt b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/CreateEnrolResponseUseCase.kt index e1da2e0a66..3a74335b54 100644 --- a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/CreateEnrolResponseUseCase.kt +++ b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/CreateEnrolResponseUseCase.kt @@ -1,10 +1,10 @@ package com.simprints.feature.orchestrator.usecases.response +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.response.AppErrorReason -import com.simprints.face.capture.FaceCaptureResult +import com.simprints.core.domain.sample.CaptureIdentity import com.simprints.feature.externalcredential.ExternalCredentialSearchResult import com.simprints.feature.externalcredential.screens.search.model.toExternalCredential -import com.simprints.fingerprint.capture.FingerprintCaptureResult import com.simprints.infra.config.store.models.Project import com.simprints.infra.eventsync.sync.common.SubjectFactory import com.simprints.infra.logging.LoggingConstants.CrashReportTag.ORCHESTRATION @@ -26,9 +26,9 @@ internal class CreateEnrolResponseUseCase @Inject constructor( project: Project, enrolmentSubjectId: String, ): AppResponse { - val fingerprintCapture = results.filterIsInstance(FingerprintCaptureResult::class.java).lastOrNull() - val faceCapture = results.filterIsInstance(FaceCaptureResult::class.java).lastOrNull() - val credentialResult = results.filterIsInstance(ExternalCredentialSearchResult::class.java).lastOrNull() + val fingerprintCapture = results.filterIsInstance().lastOrNull { it.modality == Modality.FINGERPRINT } + val faceCapture = results.filterIsInstance().lastOrNull { it.modality == Modality.FACE } + val credentialResult = results.filterIsInstance().lastOrNull() val externalCredential = credentialResult?.scannedCredential?.toExternalCredential(enrolmentSubjectId) return try { diff --git a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/CreateIdentifyResponseUseCase.kt b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/CreateIdentifyResponseUseCase.kt index 8e80443f5b..2b99a2ed93 100644 --- a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/CreateIdentifyResponseUseCase.kt +++ b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/CreateIdentifyResponseUseCase.kt @@ -1,21 +1,18 @@ package com.simprints.feature.orchestrator.usecases.response -import com.simprints.core.domain.response.AppMatchConfidence +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.feature.externalcredential.ExternalCredentialSearchResult import com.simprints.infra.config.store.models.DecisionPolicy +import com.simprints.infra.config.store.models.FaceConfiguration +import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.events.session.SessionEventRepository -import com.simprints.infra.matching.FaceMatchResult -import com.simprints.infra.matching.FingerprintMatchResult -import com.simprints.infra.matching.MatchResultItem +import com.simprints.infra.matching.MatchResult import com.simprints.infra.orchestration.data.responses.AppIdentifyResponse import com.simprints.infra.orchestration.data.responses.AppMatchResult import com.simprints.infra.orchestration.data.responses.AppResponse import java.io.Serializable import javax.inject.Inject -import kotlin.collections.ifEmpty -import kotlin.collections.map -import kotlin.collections.take internal class CreateIdentifyResponseUseCase @Inject constructor( private val eventRepository: SessionEventRepository, @@ -51,38 +48,66 @@ internal class CreateIdentifyResponseUseCase @Inject constructor( private fun getFingerprintResults( results: List, projectConfiguration: ProjectConfiguration, - ) = results.filterIsInstance().lastOrNull()?.let { fingerprintMatchResult -> - projectConfiguration.fingerprint - ?.getSdkConfiguration(fingerprintMatchResult.sdk) - ?.decisionPolicy - ?.let { fingerprintDecisionPolicy -> - fingerprintMatchResult.results.mapToMatchResults( - decisionPolicy = fingerprintDecisionPolicy, - projectConfiguration = projectConfiguration, - isCredentialMatch = false, - verificationMatchThreshold = null, - ) - } - } ?: emptyList() + ) = results + .filterIsInstance() + .lastOrNull { it.sdk is FingerprintConfiguration.BioSdk } + ?.let { fingerprintMatchResult -> + projectConfiguration.fingerprint + ?.getSdkConfiguration(fingerprintMatchResult.sdk) + ?.decisionPolicy + ?.let { fingerprintDecisionPolicy -> + val matches = fingerprintMatchResult.results + val goodResults = matches + .filter { it.confidence >= fingerprintDecisionPolicy.low } + .sortedByDescending { it.confidence } + // Attempt to include only high confidence matches + goodResults + .filter { it.confidence >= fingerprintDecisionPolicy.high } + .ifEmpty { goodResults } + .take(projectConfiguration.identification.maxNbOfReturnedCandidates) + .map { + AppMatchResult( + guid = it.subjectId, + confidenceScore = it.confidence, + decisionPolicy = fingerprintDecisionPolicy, + isCredentialMatch = false, + ) + } + } + } ?: emptyList() private fun getFaceMatchResults( results: List, projectConfiguration: ProjectConfiguration, - ) = results.filterIsInstance().lastOrNull()?.let { faceMatchResult -> - projectConfiguration.face - ?.getSdkConfiguration(faceMatchResult.sdk) - ?.decisionPolicy - ?.let { faceDecisionPolicy -> - faceMatchResult.results.mapToMatchResults( - decisionPolicy = faceDecisionPolicy, - projectConfiguration = projectConfiguration, - isCredentialMatch = false, - verificationMatchThreshold = null, - ) - } - } ?: emptyList() + ) = results + .filterIsInstance() + .lastOrNull { it.sdk is FaceConfiguration.BioSdk } + ?.let { faceMatchResult -> + projectConfiguration.face + ?.getSdkConfiguration(faceMatchResult.sdk) + ?.decisionPolicy + ?.let { faceDecisionPolicy -> + val matches = faceMatchResult.results + val goodResults = matches + .filter { it.confidence >= faceDecisionPolicy.low } + .sortedByDescending { it.confidence } + // Attempt to include only high confidence matches + goodResults + .filter { it.confidence >= faceDecisionPolicy.high } + .ifEmpty { goodResults } + .take(projectConfiguration.identification.maxNbOfReturnedCandidates) + .map { + AppMatchResult( + guid = it.subjectId, + confidenceScore = it.confidence, + decisionPolicy = faceDecisionPolicy, + isCredentialMatch = false, + ) + } + } + } ?: emptyList() - private fun List.mapToMatchResults( + private fun List.mapToMatchResults( decisionPolicy: DecisionPolicy, verificationMatchThreshold: Float?, projectConfiguration: ProjectConfiguration, @@ -123,8 +148,8 @@ internal class CreateIdentifyResponseUseCase @Inject constructor( .firstOrNull() ?.let { credentialSearchResult -> val credentialMatchItems = credentialSearchResult.matchResults.map { it.matchResult } - val faceMatchItems = credentialMatchItems.filterIsInstance() - val fingerMatchItems = credentialMatchItems.filterIsInstance() + val faceMatchItems = credentialSearchResult.matchResults.filter { it.faceBioSdk != null }.map { it.matchResult } + val fingerMatchItems = credentialSearchResult.matchResults.filter { it.fingerprintBioSdk != null }.map { it.matchResult } val (decisionPolicy, verificationMatchThreshold) = if (isFace) { credentialSearchResult.matchResults.find { it.faceBioSdk != null }?.faceBioSdk?.let { sdk -> val config = projectConfiguration.face?.getSdkConfiguration(sdk) diff --git a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/CreateVerifyResponseUseCase.kt b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/CreateVerifyResponseUseCase.kt index bb75ce096d..4999a30667 100644 --- a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/CreateVerifyResponseUseCase.kt +++ b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/CreateVerifyResponseUseCase.kt @@ -1,11 +1,12 @@ package com.simprints.feature.orchestrator.usecases.response import com.simprints.core.domain.response.AppErrorReason +import com.simprints.infra.config.store.models.FaceConfiguration +import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.logging.LoggingConstants.CrashReportTag.FINGER_MATCHING import com.simprints.infra.logging.Simber -import com.simprints.infra.matching.FaceMatchResult -import com.simprints.infra.matching.FingerprintMatchResult +import com.simprints.infra.matching.MatchResult import com.simprints.infra.orchestration.data.responses.AppErrorResponse import com.simprints.infra.orchestration.data.responses.AppMatchResult import com.simprints.infra.orchestration.data.responses.AppResponse @@ -31,8 +32,8 @@ internal class CreateVerifyResponseUseCase @Inject constructor() { projectConfiguration: ProjectConfiguration, results: List, ) = results - .filterIsInstance() - .lastOrNull() + .filterIsInstance() + .lastOrNull { it.sdk is FingerprintConfiguration.BioSdk } ?.let { fingerprintMatchResult -> projectConfiguration.fingerprint ?.getSdkConfiguration(fingerprintMatchResult.sdk) @@ -55,8 +56,8 @@ internal class CreateVerifyResponseUseCase @Inject constructor() { projectConfiguration: ProjectConfiguration, results: List, ) = results - .filterIsInstance() - .lastOrNull() + .filterIsInstance() + .lastOrNull { it.sdk is FaceConfiguration.BioSdk } ?.let { faceMatchResult -> projectConfiguration.face ?.getSdkConfiguration(faceMatchResult.sdk) diff --git a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/IsNewEnrolmentUseCase.kt b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/IsNewEnrolmentUseCase.kt index a1e6809439..c23bad1e6c 100644 --- a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/IsNewEnrolmentUseCase.kt +++ b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/response/IsNewEnrolmentUseCase.kt @@ -1,9 +1,10 @@ package com.simprints.feature.orchestrator.usecases.response import com.simprints.feature.externalcredential.ExternalCredentialSearchResult +import com.simprints.infra.config.store.models.FaceConfiguration +import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.ProjectConfiguration -import com.simprints.infra.matching.FaceMatchResult -import com.simprints.infra.matching.FingerprintMatchResult +import com.simprints.infra.matching.MatchResult import java.io.Serializable import javax.inject.Inject @@ -31,8 +32,8 @@ internal class IsNewEnrolmentUseCase @Inject constructor() { return true } - val faceResult = results.lastOrNull { it is FaceMatchResult } as? FaceMatchResult - val fingerprintResult = results.lastOrNull { it is FingerprintMatchResult } as? FingerprintMatchResult + val faceResult = results.lastOrNull { it is MatchResult && it.sdk is FaceConfiguration.BioSdk } as? MatchResult + val fingerprintResult = results.lastOrNull { it is MatchResult && it.sdk is FingerprintConfiguration.BioSdk } as? MatchResult val isNewFaceEnrolment = isNewEnrolmentFaceResult(projectConfiguration, faceResult) val isNewFingerprintEnrolment = isValidEnrolmentFingerprintResult(projectConfiguration, fingerprintResult) @@ -43,7 +44,7 @@ internal class IsNewEnrolmentUseCase @Inject constructor() { // Missing results and configuration are ignored as "valid" to allow creating new records. private fun isValidEnrolmentFingerprintResult( projectConfiguration: ProjectConfiguration, - fingerprintResult: FingerprintMatchResult?, + fingerprintResult: MatchResult?, ): Boolean = fingerprintResult?.let { projectConfiguration.fingerprint ?.getSdkConfiguration(fingerprintResult.sdk) @@ -56,7 +57,7 @@ internal class IsNewEnrolmentUseCase @Inject constructor() { // Missing results and configuration are ignored as "valid" to allow creating new records. private fun isNewEnrolmentFaceResult( projectConfiguration: ProjectConfiguration, - faceResult: FaceMatchResult?, + faceResult: MatchResult?, ): Boolean = faceResult?.let { projectConfiguration.face ?.getSdkConfiguration(faceResult.sdk) diff --git a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/steps/BuildStepsUseCase.kt b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/steps/BuildStepsUseCase.kt index c0ae456e02..0cfe44d2cd 100644 --- a/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/steps/BuildStepsUseCase.kt +++ b/feature/orchestrator/src/main/java/com/simprints/feature/orchestrator/usecases/steps/BuildStepsUseCase.kt @@ -1,6 +1,7 @@ package com.simprints.feature.orchestrator.usecases.steps import com.simprints.core.domain.common.FlowType +import com.simprints.core.domain.common.Modality import com.simprints.face.capture.FaceCaptureContract import com.simprints.feature.consent.ConsentContract import com.simprints.feature.consent.ConsentType @@ -21,13 +22,11 @@ import com.simprints.feature.setup.SetupContract import com.simprints.feature.validatepool.ValidateSubjectPoolContract import com.simprints.fingerprint.capture.FingerprintCaptureContract import com.simprints.infra.config.store.models.AgeGroup -import com.simprints.infra.config.store.models.GeneralConfiguration.Modality import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.allowedAgeRanges import com.simprints.infra.config.store.models.determineFaceSDKs import com.simprints.infra.config.store.models.determineFingerprintSDKs import com.simprints.infra.config.store.models.experimental -import com.simprints.infra.config.store.models.fromDomainToModuleApi import com.simprints.infra.config.store.models.isAgeRestricted import com.simprints.infra.config.store.models.sortedUniqueAgeGroups import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource @@ -410,7 +409,6 @@ internal class BuildStepsUseCase @Inject constructor( val fingersToCollect = sdkConfiguration ?.fingersToCapture .orEmpty() - .map { finger -> finger.fromDomainToModuleApi() } Step( id = StepId.FINGERPRINT_CAPTURE, @@ -474,7 +472,7 @@ internal class BuildStepsUseCase @Inject constructor( flowType = flowType, subjectQuery = subjectQuery, biometricDataSource = biometricDataSource, - fingerprintSDK = bioSDK, + bioSdk = bioSDK, ), ) } @@ -491,7 +489,7 @@ internal class BuildStepsUseCase @Inject constructor( flowType = flowType, subjectQuery = subjectQuery, biometricDataSource = biometricDataSource, - faceSDK = bioSDK, + bioSdk = bioSDK, ), ) } diff --git a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/OrchestratorViewModelTest.kt b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/OrchestratorViewModelTest.kt index 493a4c12d9..2cc7e2c078 100644 --- a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/OrchestratorViewModelTest.kt +++ b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/OrchestratorViewModelTest.kt @@ -1,15 +1,17 @@ package com.simprints.feature.orchestrator import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.google.common.truth.Truth.assertThat +import androidx.test.ext.junit.runners.* +import com.google.common.truth.Truth.* import com.jraska.livedata.test import com.simprints.core.domain.common.FlowType -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.response.AppErrorReason +import com.simprints.core.domain.sample.CaptureIdentity +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.step.StepParams import com.simprints.core.domain.tokenization.TokenizableString -import com.simprints.face.capture.FaceCaptureResult import com.simprints.feature.consent.ConsentResult import com.simprints.feature.enrollast.EnrolLastBiometricParams import com.simprints.feature.enrollast.EnrolLastBiometricStepResult @@ -32,27 +34,20 @@ import com.simprints.feature.selectagegroup.SelectSubjectAgeGroupResult import com.simprints.feature.setup.LocationStore import com.simprints.feature.setup.SetupResult import com.simprints.fingerprint.capture.FingerprintCaptureContract -import com.simprints.fingerprint.capture.FingerprintCaptureResult import com.simprints.infra.config.store.models.AgeGroup +import com.simprints.infra.config.store.models.FaceConfiguration import com.simprints.infra.config.store.models.FingerprintConfiguration.BioSdk.NEC import com.simprints.infra.config.store.models.FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER -import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery +import com.simprints.infra.events.sampledata.SampleDefaults.GUID1 +import com.simprints.infra.events.sampledata.SampleDefaults.GUID2 import com.simprints.infra.matching.MatchParams import com.simprints.infra.orchestration.data.responses.AppErrorResponse import com.simprints.testtools.common.coroutines.TestCoroutineRule -import io.mockk.MockKAnnotations -import io.mockk.clearMocks -import io.mockk.coEvery -import io.mockk.coJustRun -import io.mockk.coVerify -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK -import io.mockk.justRun -import io.mockk.mockk -import io.mockk.verify import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Rule @@ -202,6 +197,7 @@ internal class OrchestratorViewModelTest { FlowType.VERIFY, SubjectQuery(), BiometricDataSource.Simprints, + FaceConfiguration.BioSdk.RANK_ONE, ), ), ) @@ -226,13 +222,14 @@ internal class OrchestratorViewModelTest { FlowType.VERIFY, SubjectQuery(), BiometricDataSource.Simprints, + FaceConfiguration.BioSdk.RANK_ONE, ), ), ) coEvery { mapRefusalOrErrorResult(any(), any()) } returns null viewModel.handleAction(mockk()) - viewModel.handleResult(FaceCaptureResult("", emptyList())) + viewModel.handleResult(CaptureIdentity("", Modality.FACE, emptyList())) viewModel.currentStep.test().value().peekContent()?.let { step -> assertThat(step.id).isEqualTo(StepId.FACE_MATCHER) @@ -249,13 +246,14 @@ internal class OrchestratorViewModelTest { FlowType.VERIFY, SubjectQuery(), BiometricDataSource.Simprints, + FaceConfiguration.BioSdk.RANK_ONE, ), ), ) coEvery { mapRefusalOrErrorResult(any(), any()) } returns null viewModel.handleAction(mockk()) - viewModel.handleResult(FingerprintCaptureResult("", emptyList())) + viewModel.handleResult(CaptureIdentity("", Modality.FINGERPRINT, emptyList())) viewModel.currentStep.test().value().peekContent()?.let { step -> assertThat(step.id).isEqualTo(StepId.FINGERPRINT_MATCHER) @@ -279,7 +277,7 @@ internal class OrchestratorViewModelTest { flowType = FlowType.VERIFY, subjectQuery = SubjectQuery(), biometricDataSource = BiometricDataSource.Simprints, - fingerprintSDK = SECUGEN_SIM_MATCHER, + bioSdk = SECUGEN_SIM_MATCHER, ), ), createMockStep( @@ -296,39 +294,35 @@ internal class OrchestratorViewModelTest { flowType = FlowType.VERIFY, subjectQuery = SubjectQuery(), biometricDataSource = BiometricDataSource.Simprints, - fingerprintSDK = NEC, + bioSdk = NEC, ), ), ) coEvery { mapRefusalOrErrorResult(any(), any()) } returns null val format = "SimMatcher" - val sample1 = FingerprintCaptureResult.Sample( - IFingerIdentifier.LEFT_INDEX_FINGER, - ByteArray(0), - 0, - null, - format, - ) - val sample2 = FingerprintCaptureResult.Sample( - IFingerIdentifier.LEFT_THUMB, - ByteArray(0), - 0, - null, - format, + val sample1 = CaptureSample( + captureEventId = GUID1, + modality = Modality.FINGERPRINT, + identifier = SampleIdentifier.LEFT_INDEX_FINGER, + template = ByteArray(0), + format = format, ) - val captureResults: List = listOf( - FingerprintCaptureResult.Item(null, IFingerIdentifier.LEFT_INDEX_FINGER, sample1), - FingerprintCaptureResult.Item(null, IFingerIdentifier.LEFT_THUMB, sample2), + val sample2 = CaptureSample( + captureEventId = GUID2, + modality = Modality.FINGERPRINT, + identifier = SampleIdentifier.LEFT_THUMB, + template = ByteArray(0), + format = format, ) viewModel.handleAction(mockk()) - viewModel.handleResult(FingerprintCaptureResult("", captureResults)) + viewModel.handleResult(CaptureIdentity("", Modality.FINGERPRINT, listOf(sample1, sample2))) viewModel.currentStep.test().value().peekContent()?.let { step -> assertThat(step.id).isEqualTo(StepId.FINGERPRINT_MATCHER) val params = step.params?.let { it as? MatchParams } assertThat(params).isNotNull() - assertThat(params?.fingerprintSDK).isEqualTo(SECUGEN_SIM_MATCHER) + assertThat(params?.bioSdk).isEqualTo(SECUGEN_SIM_MATCHER) assertThat(params?.probeFingerprintSamples?.size).isEqualTo(2) assertThat(params?.probeFingerprintSamples?.get(0)?.format).isEqualTo(format) assertThat(params?.probeFingerprintSamples?.get(1)?.format).isEqualTo(format) @@ -370,7 +364,7 @@ internal class OrchestratorViewModelTest { @Test fun `Restores modalities if empty`() = runTest { - val projectModalities = listOf( + val projectModalities = listOf( mockk(), mockk(), ) @@ -389,7 +383,7 @@ internal class OrchestratorViewModelTest { @Test fun `Does not restore modalities if not empty`() = runTest { - val projectModalities = listOf( + val projectModalities = listOf( mockk(), mockk(), ) @@ -428,7 +422,7 @@ internal class OrchestratorViewModelTest { ) viewModel.handleAction(mockk()) - viewModel.handleResult(FingerprintCaptureResult("", emptyList())) + viewModel.handleResult(CaptureIdentity("", Modality.FINGERPRINT, emptyList())) viewModel.currentStep.test().value().peekContent()?.let { step -> assertThat(step.params?.let { it as? EnrolLastBiometricParams }?.steps).containsExactly(mockEnrolLastStep) @@ -438,30 +432,27 @@ internal class OrchestratorViewModelTest { @Test fun `Updates external credential step payload with fingerprint samples when receiving fingerprint capture result`() = runTest { val fingerprintReferenceId = "fingerprintReferenceId" - val fingerId1 = IFingerIdentifier.LEFT_INDEX_FINGER - val fingerId2 = IFingerIdentifier.RIGHT_THUMB + val fingerId1 = SampleIdentifier.LEFT_INDEX_FINGER + val fingerId2 = SampleIdentifier.RIGHT_THUMB val template1 = ByteArray(10) val template2 = ByteArray(20) val format1 = "format1" val format2 = "format2" - val fingerprintSample1 = mockk { - every { fingerIdentifier } returns fingerId1 - every { template } returns template1 - every { format } returns format1 - } - val fingerprintSample2 = mockk { - every { fingerIdentifier } returns fingerId2 - every { template } returns template2 - every { format } returns format2 - } - - val fingerprintItem1 = mockk { - every { sample } returns fingerprintSample1 - } - val fingerprintItem2 = mockk { - every { sample } returns fingerprintSample2 - } + val fingerprintSample1 = CaptureSample( + captureEventId = GUID1, + modality = Modality.FINGERPRINT, + identifier = fingerId1, + template = template1, + format = format1, + ) + val fingerprintSample2 = CaptureSample( + captureEventId = GUID2, + modality = Modality.FINGERPRINT, + identifier = fingerId2, + template = template2, + format = format2, + ) val externalCredentialParams = mockk(relaxed = true) { every { copy(probeReferenceId = any(), fingerprintSamples = any()) } returns this @@ -475,15 +466,12 @@ internal class OrchestratorViewModelTest { viewModel.handleAction(mockk()) viewModel.handleResult( - FingerprintCaptureResult( - fingerprintReferenceId, - listOf(fingerprintItem1, fingerprintItem2), - ), + CaptureIdentity(fingerprintReferenceId, Modality.FINGERPRINT, listOf(fingerprintSample1, fingerprintSample2)), ) val expectedFingerprintSamples = listOf( - MatchParams.FingerprintSample(fingerId1, format1, template1), - MatchParams.FingerprintSample(fingerId2, format2, template2), + CaptureSample(GUID1, Modality.FINGERPRINT, format1, template1, fingerId1), + CaptureSample(GUID2, Modality.FINGERPRINT, format2, template2, fingerId2), ) verify { diff --git a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/cache/OrchestratorCacheIntegrationTest.kt b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/cache/OrchestratorCacheIntegrationTest.kt index e450f188d0..9345de2281 100644 --- a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/cache/OrchestratorCacheIntegrationTest.kt +++ b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/cache/OrchestratorCacheIntegrationTest.kt @@ -4,25 +4,25 @@ import android.content.SharedPreferences import androidx.test.ext.junit.runners.* import com.google.common.truth.Truth.* import com.simprints.core.domain.common.FlowType +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredentialType -import com.simprints.core.domain.fingerprint.IFingerIdentifier import com.simprints.core.domain.response.AppErrorReason +import com.simprints.core.domain.sample.CaptureIdentity +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.MatchComparisonResult +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.core.tools.json.JsonHelper import com.simprints.core.tools.time.Timestamp import com.simprints.face.capture.FaceCaptureParams -import com.simprints.face.capture.FaceCaptureResult import com.simprints.feature.alert.AlertResult import com.simprints.feature.consent.ConsentParams import com.simprints.feature.consent.ConsentResult import com.simprints.feature.consent.ConsentType import com.simprints.feature.enrollast.EnrolLastBiometricParams import com.simprints.feature.enrollast.EnrolLastBiometricStepResult -import com.simprints.feature.enrollast.FaceTemplateCaptureResult -import com.simprints.feature.enrollast.FingerTemplateCaptureResult -import com.simprints.feature.enrollast.MatchResult import com.simprints.feature.exitform.ExitFormOption import com.simprints.feature.exitform.ExitFormResult import com.simprints.feature.externalcredential.ExternalCredentialSearchResult @@ -45,19 +45,14 @@ import com.simprints.feature.setup.SetupResult import com.simprints.feature.validatepool.ValidateSubjectPoolFragmentParams import com.simprints.feature.validatepool.ValidateSubjectPoolResult import com.simprints.fingerprint.capture.FingerprintCaptureParams -import com.simprints.fingerprint.capture.FingerprintCaptureResult import com.simprints.infra.config.store.models.AgeGroup import com.simprints.infra.config.store.models.FaceConfiguration -import com.simprints.infra.config.store.models.Finger import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery import com.simprints.infra.events.sampledata.SampleDefaults.GUID1 -import com.simprints.infra.images.model.Path -import com.simprints.infra.images.model.SecuredImageRef -import com.simprints.infra.matching.FaceMatchResult -import com.simprints.infra.matching.FingerprintMatchResult import com.simprints.infra.matching.MatchParams +import com.simprints.infra.matching.MatchResult import com.simprints.infra.security.SecurityManager import io.mockk.* import io.mockk.impl.annotations.MockK @@ -130,29 +125,24 @@ class OrchestratorCacheIntegrationTest { userId = TokenizableString.Raw("value"), moduleId = TokenizableString.Raw("value"), steps = listOf( - EnrolLastBiometricStepResult.FingerprintCaptureResult( + EnrolLastBiometricStepResult.CaptureResult( "referenceId", listOf( - FingerTemplateCaptureResult( - Finger.LEFT_4TH_FINGER, - byteArrayOf(1, 2, 3), - 10, - "NEC", + CaptureSample( + captureEventId = GUID1, + identifier = SampleIdentifier.LEFT_THUMB, + template = byteArrayOf(1, 2, 3), + modality = Modality.FINGERPRINT, + format = "format", ), ), ), - EnrolLastBiometricStepResult.FingerprintMatchResult( - listOf(MatchResult("subjectId", 0.5f)), + EnrolLastBiometricStepResult.MatchResult( + listOf(MatchComparisonResult("subjectId", 0.5f)), FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, ), - EnrolLastBiometricStepResult.FaceCaptureResult( - "referenceId", - listOf( - FaceTemplateCaptureResult(byteArrayOf(1, 2, 3), "RankOne"), - ), - ), - EnrolLastBiometricStepResult.FaceMatchResult( - listOf(MatchResult("subjectId", 0.5f)), + EnrolLastBiometricStepResult.MatchResult( + listOf(MatchComparisonResult("subjectId", 0.5f)), FaceConfiguration.BioSdk.RANK_ONE, ), EnrolLastBiometricStepResult.EnrolLastBiometricsResult("subjectId"), @@ -196,16 +186,21 @@ class OrchestratorCacheIntegrationTest { ageGroup = AgeGroup(1, 2), probeReferenceId = "referenceId", faceSamples = listOf( - MatchParams.FaceSample( - faceId = "faceId", + CaptureSample( + captureEventId = GUID1, + identifier = SampleIdentifier.LEFT_THUMB, template = byteArrayOf(1, 2, 3), + modality = Modality.FACE, + format = "format", ), ), fingerprintSamples = listOf( - MatchParams.FingerprintSample( - fingerId = IFingerIdentifier.LEFT_4TH_FINGER, - format = "NEC", + CaptureSample( + captureEventId = GUID1, + identifier = SampleIdentifier.LEFT_THUMB, template = byteArrayOf(1, 2, 3), + modality = Modality.FINGERPRINT, + format = "format", ), ), ), @@ -226,7 +221,7 @@ class OrchestratorCacheIntegrationTest { matchResults = listOf( CredentialMatch( credential = "credential".asTokenizableEncrypted(), - matchResult = FaceMatchResult.Item("subjectId", 0.5f), + matchResult = MatchComparisonResult("subjectId", 0.5f), verificationThreshold = 55f, faceBioSdk = FaceConfiguration.BioSdk.RANK_ONE, fingerprintBioSdk = FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, @@ -254,23 +249,20 @@ class OrchestratorCacheIntegrationTest { destinationId = 4, params = FingerprintCaptureParams( flowType = FlowType.ENROL, - fingerprintsToCapture = listOf(IFingerIdentifier.LEFT_4TH_FINGER), + fingerprintsToCapture = listOf(SampleIdentifier.LEFT_4TH_FINGER), fingerprintSDK = FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, ), status = StepStatus.COMPLETED, - result = FingerprintCaptureResult( + result = CaptureIdentity( "", - results = listOf( - FingerprintCaptureResult.Item( + modality = Modality.FINGERPRINT, + samples = listOf( + CaptureSample( captureEventId = GUID1, - identifier = IFingerIdentifier.LEFT_THUMB, - sample = FingerprintCaptureResult.Sample( - fingerIdentifier = IFingerIdentifier.LEFT_4TH_FINGER, - template = byteArrayOf(1, 2, 3), - templateQualityScore = 10, - imageRef = SecuredImageRef(Path("file/path")), - format = "NEC", - ), + identifier = SampleIdentifier.LEFT_THUMB, + template = byteArrayOf(1, 2, 3), + modality = Modality.FINGERPRINT, + format = "format", ), ), ), @@ -284,17 +276,20 @@ class OrchestratorCacheIntegrationTest { flowType = FlowType.IDENTIFY, queryForCandidates = SubjectQuery(), biometricDataSource = BiometricDataSource.CommCare("name"), + bioSdk = FingerprintConfiguration.BioSdk.NEC, probeFingerprintSamples = listOf( - MatchParams.FingerprintSample( - fingerId = IFingerIdentifier.LEFT_4TH_FINGER, - format = "NEC", + CaptureSample( + captureEventId = GUID1, + identifier = SampleIdentifier.LEFT_THUMB, template = byteArrayOf(1, 2, 3), + modality = Modality.FINGERPRINT, + format = "format", ), ), ), status = StepStatus.COMPLETED, - result = FingerprintMatchResult( - listOf(FingerprintMatchResult.Item("subjectId", 0.5f)), + result = MatchResult( + listOf(MatchComparisonResult("subjectId", 0.5f)), FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, ), ), @@ -318,18 +313,16 @@ class OrchestratorCacheIntegrationTest { destinationId = 6, params = FaceCaptureParams(3, FaceConfiguration.BioSdk.RANK_ONE), status = StepStatus.COMPLETED, - result = FaceCaptureResult( + result = CaptureIdentity( "", - results = listOf( - FaceCaptureResult.Item( - captureEventId = "event", - index = 0, - sample = FaceCaptureResult.Sample( - faceId = "faceId", - template = byteArrayOf(1, 2, 3), - imageRef = SecuredImageRef(Path("file/path")), - format = "ROC", - ), + modality = Modality.FACE, + samples = listOf( + CaptureSample( + captureEventId = GUID1, + identifier = SampleIdentifier.LEFT_THUMB, + template = byteArrayOf(1, 2, 3), + modality = Modality.FACE, + format = "ROC", ), ), ), @@ -343,16 +336,20 @@ class OrchestratorCacheIntegrationTest { flowType = FlowType.IDENTIFY, queryForCandidates = SubjectQuery(), biometricDataSource = BiometricDataSource.Simprints, + bioSdk = FaceConfiguration.BioSdk.RANK_ONE, probeFaceSamples = listOf( - MatchParams.FaceSample( - faceId = "faceId", + CaptureSample( + captureEventId = GUID1, + identifier = SampleIdentifier.LEFT_THUMB, template = byteArrayOf(1, 2, 3), + modality = Modality.FACE, + format = "format", ), ), ), status = StepStatus.COMPLETED, - result = FaceMatchResult( - listOf(FaceMatchResult.Item("subjectId", 0.5f)), + result = MatchResult( + listOf(MatchComparisonResult("subjectId", 0.5f)), FaceConfiguration.BioSdk.RANK_ONE, ), ), diff --git a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/MapRefusalOrErrorResultUseCaseTest.kt b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/MapRefusalOrErrorResultUseCaseTest.kt index 2559681523..ba81d3826c 100644 --- a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/MapRefusalOrErrorResultUseCaseTest.kt +++ b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/MapRefusalOrErrorResultUseCaseTest.kt @@ -1,7 +1,8 @@ package com.simprints.feature.orchestrator.usecases -import com.google.common.truth.Truth.assertThat -import com.simprints.face.capture.FaceCaptureResult +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureIdentity import com.simprints.feature.alert.AlertResult import com.simprints.feature.exitform.ExitFormOption import com.simprints.feature.exitform.ExitFormResult @@ -16,11 +17,8 @@ import com.simprints.infra.events.session.SessionEventRepository import com.simprints.infra.orchestration.data.responses.AppErrorResponse import com.simprints.infra.orchestration.data.responses.AppIdentifyResponse import com.simprints.infra.orchestration.data.responses.AppRefusalResponse -import io.mockk.MockKAnnotations -import io.mockk.coEvery -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK -import io.mockk.mockk import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -64,7 +62,7 @@ class MapRefusalOrErrorResultUseCaseTest { listOf( FetchSubjectResult(found = true), SetupResult(isSuccess = true), - FaceCaptureResult("", emptyList()), + CaptureIdentity("", modality = Modality.FACE, emptyList()), ).forEach { result -> assertThat(useCase(result, mockk())).isNull() } } diff --git a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/MapStepsForLastBiometricEnrolUseCaseTest.kt b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/MapStepsForLastBiometricEnrolUseCaseTest.kt index 10e95ec261..0e0a2fb096 100644 --- a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/MapStepsForLastBiometricEnrolUseCaseTest.kt +++ b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/MapStepsForLastBiometricEnrolUseCaseTest.kt @@ -1,19 +1,16 @@ package com.simprints.feature.orchestrator.usecases -import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.fingerprint.IFingerIdentifier -import com.simprints.face.capture.FaceCaptureResult +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureIdentity +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.feature.enrollast.EnrolLastBiometricResult import com.simprints.feature.enrollast.EnrolLastBiometricStepResult -import com.simprints.feature.enrollast.FaceTemplateCaptureResult -import com.simprints.feature.enrollast.FingerTemplateCaptureResult -import com.simprints.fingerprint.capture.FingerprintCaptureResult import com.simprints.infra.config.store.models.FaceConfiguration -import com.simprints.infra.config.store.models.Finger import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.events.sampledata.SampleDefaults.GUID1 -import com.simprints.infra.matching.FaceMatchResult -import com.simprints.infra.matching.FingerprintMatchResult +import com.simprints.infra.matching.MatchResult import org.junit.Before import org.junit.Test @@ -40,30 +37,26 @@ internal class MapStepsForLastBiometricEnrolUseCaseTest { fun `maps FaceMatchResult correctly`() { val result = useCase( listOf( - FaceMatchResult(emptyList(), FaceConfiguration.BioSdk.RANK_ONE), + MatchResult(emptyList(), FaceConfiguration.BioSdk.RANK_ONE), ), ) - assertThat(result.first()).isEqualTo(EnrolLastBiometricStepResult.FaceMatchResult(emptyList(), FaceConfiguration.BioSdk.RANK_ONE)) + assertThat(result.first()).isEqualTo(EnrolLastBiometricStepResult.MatchResult(emptyList(), FaceConfiguration.BioSdk.RANK_ONE)) } @Test - fun `maps FaceCaptureResult correctly`() { + fun `maps face CaptureIdentity correctly`() { val result = useCase( listOf( - FaceCaptureResult( + CaptureIdentity( "referenceId", - results = listOf( - FaceCaptureResult.Item(captureEventId = null, index = 0, sample = null), - FaceCaptureResult.Item( + modality = Modality.FACE, + samples = listOf( + CaptureSample( captureEventId = GUID1, - index = 0, - sample = FaceCaptureResult.Sample( - faceId = "faceId", - template = byteArrayOf(), - imageRef = null, - format = "format", - ), + modality = Modality.FACE, + format = "format", + template = byteArrayOf(), ), ), ), @@ -71,12 +64,14 @@ internal class MapStepsForLastBiometricEnrolUseCaseTest { ) assertThat(result.first()).isEqualTo( - EnrolLastBiometricStepResult.FaceCaptureResult( + EnrolLastBiometricStepResult.CaptureResult( referenceId = "referenceId", results = listOf( - element = FaceTemplateCaptureResult( + CaptureSample( + captureEventId = "captureId", template = byteArrayOf(), format = "format", + modality = Modality.FACE, ), ), ), @@ -87,33 +82,29 @@ internal class MapStepsForLastBiometricEnrolUseCaseTest { fun `maps FingerprintMatchResult correctly`() { val result = useCase( listOf( - FingerprintMatchResult(emptyList(), FingerprintConfiguration.BioSdk.NEC), + MatchResult(emptyList(), FingerprintConfiguration.BioSdk.NEC), ), ) assertThat( result.first(), - ).isEqualTo(EnrolLastBiometricStepResult.FingerprintMatchResult(emptyList(), FingerprintConfiguration.BioSdk.NEC)) + ).isEqualTo(EnrolLastBiometricStepResult.MatchResult(emptyList(), FingerprintConfiguration.BioSdk.NEC)) } @Test - fun `maps FingerprintCaptureResult correctly`() { + fun `maps fingerprint CaptureIdentity correctly`() { val result = useCase( listOf( - FingerprintCaptureResult( + CaptureIdentity( "referenceId", - results = listOf( - FingerprintCaptureResult.Item(null, IFingerIdentifier.LEFT_THUMB, null), - FingerprintCaptureResult.Item( - identifier = IFingerIdentifier.RIGHT_THUMB, + modality = Modality.FINGERPRINT, + samples = listOf( + CaptureSample( captureEventId = GUID1, - sample = FingerprintCaptureResult.Sample( - fingerIdentifier = IFingerIdentifier.RIGHT_THUMB, - template = byteArrayOf(), - templateQualityScore = 0, - imageRef = null, - format = "format", - ), + modality = Modality.FINGERPRINT, + format = "format", + template = byteArrayOf(), + identifier = SampleIdentifier.RIGHT_THUMB, ), ), ), @@ -121,14 +112,15 @@ internal class MapStepsForLastBiometricEnrolUseCaseTest { ) assertThat(result.first()).isEqualTo( - EnrolLastBiometricStepResult.FingerprintCaptureResult( + EnrolLastBiometricStepResult.CaptureResult( referenceId = "referenceId", results = listOf( - FingerTemplateCaptureResult( + CaptureSample( + captureEventId = "captureId", template = byteArrayOf(), - templateQualityScore = 0, format = "format", - finger = Finger.RIGHT_THUMB, + identifier = SampleIdentifier.RIGHT_THUMB, + modality = Modality.FINGERPRINT, ), ), ), diff --git a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/CreateEnrolResponseUseCaseTest.kt b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/CreateEnrolResponseUseCaseTest.kt index df5c2419a2..58d5b3c622 100644 --- a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/CreateEnrolResponseUseCaseTest.kt +++ b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/CreateEnrolResponseUseCaseTest.kt @@ -1,27 +1,21 @@ package com.simprints.feature.orchestrator.usecases.response -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredentialType +import com.simprints.core.domain.sample.CaptureIdentity import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.domain.tokenization.asTokenizableRaw -import com.simprints.face.capture.FaceCaptureResult import com.simprints.feature.externalcredential.ExternalCredentialSearchResult import com.simprints.feature.externalcredential.screens.search.model.ScannedCredential import com.simprints.feature.orchestrator.exceptions.MissingCaptureException -import com.simprints.fingerprint.capture.FingerprintCaptureResult import com.simprints.infra.config.store.models.Project -import com.simprints.infra.config.store.models.TokenKeyType -import com.simprints.infra.config.store.tokenization.TokenizationProcessor import com.simprints.infra.eventsync.sync.common.SubjectFactory import com.simprints.infra.orchestration.data.ActionRequest import com.simprints.infra.orchestration.data.responses.AppEnrolResponse import com.simprints.infra.orchestration.data.responses.AppErrorResponse -import io.mockk.MockKAnnotations -import io.mockk.coJustRun -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK -import io.mockk.mockk -import io.mockk.verify import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -75,8 +69,8 @@ internal class CreateEnrolResponseUseCaseTest { useCase( request = action, results = listOf( - FingerprintCaptureResult("", emptyList()), - FaceCaptureResult("", emptyList()), + CaptureIdentity("", Modality.FINGERPRINT, emptyList()), + CaptureIdentity("", Modality.FACE, emptyList()), mockk(), ), project = project, @@ -129,7 +123,7 @@ internal class CreateEnrolResponseUseCaseTest { useCase( request = action, results = listOf( - FingerprintCaptureResult("", emptyList()), + CaptureIdentity("", Modality.FINGERPRINT, emptyList()), credentialSearchResult, ), project = project, diff --git a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/CreateIdentifyResponseUseCaseTest.kt b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/CreateIdentifyResponseUseCaseTest.kt index 22d51a8680..d542ad7bb5 100644 --- a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/CreateIdentifyResponseUseCaseTest.kt +++ b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/CreateIdentifyResponseUseCaseTest.kt @@ -1,20 +1,17 @@ package com.simprints.feature.orchestrator.usecases.response -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.feature.externalcredential.ExternalCredentialSearchResult import com.simprints.feature.externalcredential.model.CredentialMatch import com.simprints.infra.config.store.models.DecisionPolicy import com.simprints.infra.config.store.models.FaceConfiguration import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.events.session.SessionEventRepository -import com.simprints.infra.matching.FaceMatchResult -import com.simprints.infra.matching.FingerprintMatchResult +import com.simprints.infra.matching.MatchResult import com.simprints.infra.orchestration.data.responses.AppIdentifyResponse -import io.mockk.MockKAnnotations -import io.mockk.coEvery -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK -import io.mockk.mockk import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -210,7 +207,7 @@ class CreateIdentifyResponseUseCaseTest { val faceMatches = listOf( mockk { every { verificationThreshold } returns 0.0f - every { matchResult } returns FaceMatchResult.Item( + every { matchResult } returns MatchComparisonResult( subjectId = faceSmallConfidence, confidence = smallConfidence, ) @@ -218,7 +215,7 @@ class CreateIdentifyResponseUseCaseTest { every { fingerprintBioSdk } returns null }, mockk { - every { matchResult } returns FaceMatchResult.Item( + every { matchResult } returns MatchComparisonResult( subjectId = faceBigConfidence, confidence = bigConfidence, ) @@ -229,7 +226,7 @@ class CreateIdentifyResponseUseCaseTest { val fingerprintMatches = listOf( mockk { - every { matchResult } returns FingerprintMatchResult.Item( + every { matchResult } returns MatchComparisonResult( subjectId = "fingerprintSubjectId", confidence = 90f, ) @@ -273,7 +270,7 @@ class CreateIdentifyResponseUseCaseTest { val fingerprintMatches = listOf( mockk { every { verificationThreshold } returns 0.0f - every { matchResult } returns FingerprintMatchResult.Item( + every { matchResult } returns MatchComparisonResult( subjectId = fingerprintSmallConfidence, confidence = smallConfidence, ) @@ -281,7 +278,7 @@ class CreateIdentifyResponseUseCaseTest { every { fingerprintBioSdk } returns FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER }, mockk { - every { matchResult } returns FingerprintMatchResult.Item( + every { matchResult } returns MatchComparisonResult( subjectId = fingerprintBigConfidence, confidence = bigConfidence, ) @@ -292,7 +289,7 @@ class CreateIdentifyResponseUseCaseTest { val faceMatches = listOf( mockk { - every { matchResult } returns FaceMatchResult.Item( + every { matchResult } returns MatchComparisonResult( subjectId = "faceSubjectId", confidence = 90f, ) @@ -337,7 +334,7 @@ class CreateIdentifyResponseUseCaseTest { val credentialFaceMatches = listOf( mockk { - every { matchResult } returns FaceMatchResult.Item( + every { matchResult } returns MatchComparisonResult( subjectId = sharedGuid, confidence = credentialConfidence, ) @@ -358,10 +355,8 @@ class CreateIdentifyResponseUseCaseTest { mockk { every { matchResults } returns credentialFaceMatches }, - FaceMatchResult( - listOf( - FaceMatchResult.Item(subjectId = sharedGuid, confidence = faceConfidence), - ), + MatchResult( + listOf(MatchComparisonResult(subjectId = sharedGuid, confidence = faceConfidence)), FaceConfiguration.BioSdk.RANK_ONE, ), ), @@ -381,7 +376,7 @@ class CreateIdentifyResponseUseCaseTest { val credentialFingerprintMatches = listOf( mockk { every { verificationThreshold } returns 0.0f - every { matchResult } returns FingerprintMatchResult.Item( + every { matchResult } returns MatchComparisonResult( subjectId = sharedGuid, confidence = credentialConfidence, ) @@ -409,10 +404,8 @@ class CreateIdentifyResponseUseCaseTest { mockk { every { matchResults } returns credentialFingerprintMatches }, - FingerprintMatchResult( - listOf( - FingerprintMatchResult.Item(subjectId = sharedGuid, confidence = fingerprintConfidence), - ), + MatchResult( + listOf(MatchComparisonResult(subjectId = sharedGuid, confidence = fingerprintConfidence)), FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, ), ), @@ -423,13 +416,13 @@ class CreateIdentifyResponseUseCaseTest { assertThat(result.identifications.first().confidenceScore).isEqualTo(credentialConfidence.toInt()) } - private fun createFaceMatchResult(vararg confidences: Float): Serializable = FaceMatchResult( - confidences.mapIndexed { i, confidence -> FaceMatchResult.Item(subjectId = "$i", confidence = confidence) }, + private fun createFaceMatchResult(vararg confidences: Float): Serializable = MatchResult( + confidences.mapIndexed { i, confidence -> MatchComparisonResult(subjectId = "$i", confidence = confidence) }, FaceConfiguration.BioSdk.RANK_ONE, ) - private fun createFingerprintMatchResult(vararg confidences: Float): Serializable = FingerprintMatchResult( - confidences.mapIndexed { i, confidence -> FingerprintMatchResult.Item(subjectId = "$i", confidence = confidence) }, + private fun createFingerprintMatchResult(vararg confidences: Float): Serializable = MatchResult( + confidences.mapIndexed { i, confidence -> MatchComparisonResult(subjectId = "$i", confidence = confidence) }, FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, ) } diff --git a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/CreateVerifyResponseUseCaseTest.kt b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/CreateVerifyResponseUseCaseTest.kt index b83cb332f7..6510596a3b 100644 --- a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/CreateVerifyResponseUseCaseTest.kt +++ b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/CreateVerifyResponseUseCaseTest.kt @@ -1,11 +1,13 @@ package com.simprints.feature.orchestrator.usecases.response import com.google.common.truth.Truth.* +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.infra.config.store.models.DecisionPolicy +import com.simprints.infra.config.store.models.FaceConfiguration +import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.infra.matching.MatchResult import com.simprints.infra.orchestration.data.responses.AppErrorResponse import com.simprints.infra.orchestration.data.responses.AppVerifyResponse -import com.simprints.infra.matching.FaceMatchResult -import com.simprints.infra.matching.FingerprintMatchResult import io.mockk.* import org.junit.Before import org.junit.Test @@ -245,13 +247,13 @@ class CreateVerifyResponseUseCaseTest { assertThat((result as AppVerifyResponse).matchResult.verificationSuccess).isEqualTo(false) } - private fun createFingerprintMatchResult(vararg confidences: Float): Serializable = FingerprintMatchResult( - confidences.map { FingerprintMatchResult.Item(subjectId = "1", confidence = it) }, - mockk(), + private fun createFingerprintMatchResult(vararg confidences: Float): Serializable = MatchResult( + confidences.map { MatchComparisonResult(subjectId = "1", confidence = it) }, + FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, ) - private fun createFaceMatchResult(vararg confidences: Float): Serializable = FaceMatchResult( - confidences.map { FaceMatchResult.Item(subjectId = "1", confidence = it) }, - mockk(), + private fun createFaceMatchResult(vararg confidences: Float): Serializable = MatchResult( + confidences.map { MatchComparisonResult(subjectId = "1", confidence = it) }, + FaceConfiguration.BioSdk.RANK_ONE, ) } diff --git a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/IsNewEnrolmentUseCaseTest.kt b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/IsNewEnrolmentUseCaseTest.kt index 721293030c..0333ee7924 100644 --- a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/IsNewEnrolmentUseCaseTest.kt +++ b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/response/IsNewEnrolmentUseCaseTest.kt @@ -1,13 +1,14 @@ package com.simprints.feature.orchestrator.usecases.response import com.google.common.truth.Truth.* +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.feature.externalcredential.ExternalCredentialSearchResult import com.simprints.feature.externalcredential.model.CredentialMatch import com.simprints.infra.config.store.models.DecisionPolicy import com.simprints.infra.config.store.models.FaceConfiguration +import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.ProjectConfiguration -import com.simprints.infra.matching.FaceMatchResult -import com.simprints.infra.matching.FingerprintMatchResult +import com.simprints.infra.matching.MatchResult import io.mockk.* import io.mockk.impl.annotations.MockK import org.junit.Before @@ -50,7 +51,12 @@ internal class IsNewEnrolmentUseCaseTest { assertThat( useCase( projectConfiguration, - listOf(FingerprintMatchResult(listOf(FingerprintMatchResult.Item("", LOWER_THAN_MEDIUM_SCORE)), mockk())), + listOf( + MatchResult( + listOf(MatchComparisonResult("", LOWER_THAN_MEDIUM_SCORE)), + FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, + ), + ), ), ).isTrue() } @@ -62,7 +68,12 @@ internal class IsNewEnrolmentUseCaseTest { assertThat( useCase( projectConfiguration, - listOf(FingerprintMatchResult(listOf(FingerprintMatchResult.Item("", HIGHER_THAN_MEDIUM_SCORE)), mockk())), + listOf( + MatchResult( + listOf(MatchComparisonResult("", HIGHER_THAN_MEDIUM_SCORE)), + FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, + ), + ), ), ).isFalse() } @@ -74,7 +85,7 @@ internal class IsNewEnrolmentUseCaseTest { assertThat( useCase( projectConfiguration, - listOf(FaceMatchResult(listOf(FaceMatchResult.Item("", LOWER_THAN_MEDIUM_SCORE)), FaceConfiguration.BioSdk.RANK_ONE)), + listOf(MatchResult(listOf(MatchComparisonResult("", LOWER_THAN_MEDIUM_SCORE)), FaceConfiguration.BioSdk.RANK_ONE)), ), ).isTrue() } @@ -86,7 +97,7 @@ internal class IsNewEnrolmentUseCaseTest { assertThat( useCase( projectConfiguration, - listOf(FaceMatchResult(listOf(FaceMatchResult.Item("", HIGHER_THAN_MEDIUM_SCORE)), FaceConfiguration.BioSdk.RANK_ONE)), + listOf(MatchResult(listOf(MatchComparisonResult("", HIGHER_THAN_MEDIUM_SCORE)), FaceConfiguration.BioSdk.RANK_ONE)), ), ).isFalse() } @@ -99,11 +110,11 @@ internal class IsNewEnrolmentUseCaseTest { useCase( projectConfiguration, listOf( - FingerprintMatchResult( - listOf(FingerprintMatchResult.Item("", LOWER_THAN_MEDIUM_SCORE)), - mockk(), + MatchResult( + listOf(MatchComparisonResult("", LOWER_THAN_MEDIUM_SCORE)), + FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, ), - FaceMatchResult(listOf(FaceMatchResult.Item("", LOWER_THAN_MEDIUM_SCORE)), FaceConfiguration.BioSdk.RANK_ONE), + MatchResult(listOf(MatchComparisonResult("", LOWER_THAN_MEDIUM_SCORE)), FaceConfiguration.BioSdk.RANK_ONE), ), ), ).isTrue() @@ -117,11 +128,11 @@ internal class IsNewEnrolmentUseCaseTest { useCase( projectConfiguration, listOf( - FingerprintMatchResult( - listOf(FingerprintMatchResult.Item("", LOWER_THAN_MEDIUM_SCORE)), - mockk(), + MatchResult( + listOf(MatchComparisonResult("", LOWER_THAN_MEDIUM_SCORE)), + FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, ), - FaceMatchResult(listOf(FaceMatchResult.Item("", HIGHER_THAN_MEDIUM_SCORE)), FaceConfiguration.BioSdk.RANK_ONE), + MatchResult(listOf(MatchComparisonResult("", HIGHER_THAN_MEDIUM_SCORE)), FaceConfiguration.BioSdk.RANK_ONE), ), ), ).isFalse() @@ -135,11 +146,11 @@ internal class IsNewEnrolmentUseCaseTest { useCase( projectConfiguration, listOf( - FingerprintMatchResult( - listOf(FingerprintMatchResult.Item("", HIGHER_THAN_MEDIUM_SCORE)), - mockk(), + MatchResult( + listOf(MatchComparisonResult("", HIGHER_THAN_MEDIUM_SCORE)), + FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER, ), - FaceMatchResult(listOf(FaceMatchResult.Item("", LOWER_THAN_MEDIUM_SCORE)), FaceConfiguration.BioSdk.RANK_ONE), + MatchResult(listOf(MatchComparisonResult("", LOWER_THAN_MEDIUM_SCORE)), FaceConfiguration.BioSdk.RANK_ONE), ), ), ).isFalse() diff --git a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/steps/BuildStepsUseCaseTest.kt b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/steps/BuildStepsUseCaseTest.kt index 348e7c7c64..0d51ba0e9e 100644 --- a/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/steps/BuildStepsUseCaseTest.kt +++ b/feature/orchestrator/src/test/java/com/simprints/feature/orchestrator/usecases/steps/BuildStepsUseCaseTest.kt @@ -1,8 +1,10 @@ package com.simprints.feature.orchestrator.usecases.steps -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredentialType import com.simprints.feature.externalcredential.screens.search.model.ScannedCredential +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.feature.orchestrator.cache.OrchestratorCache import com.simprints.feature.orchestrator.exceptions.SubjectAgeNotSupportedException import com.simprints.feature.orchestrator.steps.Step @@ -11,19 +13,14 @@ import com.simprints.feature.orchestrator.usecases.MapStepsForLastBiometricEnrol import com.simprints.feature.selectsubject.SelectSubjectParams import com.simprints.infra.config.store.models.AgeGroup import com.simprints.infra.config.store.models.FaceConfiguration -import com.simprints.infra.config.store.models.Finger import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.FingerprintConfiguration.BioSdk.NEC import com.simprints.infra.config.store.models.FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER -import com.simprints.infra.config.store.models.GeneralConfiguration.Modality import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.experimental import com.simprints.infra.orchestration.data.ActionRequest -import io.mockk.MockKAnnotations -import io.mockk.coEvery -import io.mockk.every -import io.mockk.impl.annotations.RelaxedMockK -import io.mockk.mockk +import io.mockk.* +import io.mockk.impl.annotations.* import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals @@ -78,16 +75,16 @@ class BuildStepsUseCaseTest { ) every { secugenSimMatcher.fingersToCapture } returns listOf( - Finger.LEFT_THUMB, - Finger.RIGHT_THUMB, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.RIGHT_THUMB, ) every { secugenSimMatcher.allowedAgeRange } returns AgeGroup(0, null) every { projectConfiguration.fingerprint?.secugenSimMatcher } returns secugenSimMatcher every { projectConfiguration.fingerprint?.getSdkConfiguration(SECUGEN_SIM_MATCHER) } returns secugenSimMatcher every { nec.fingersToCapture } returns listOf( - Finger.LEFT_INDEX_FINGER, - Finger.RIGHT_INDEX_FINGER, + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.RIGHT_INDEX_FINGER, ) every { nec.allowedAgeRange } returns AgeGroup(0, null) every { projectConfiguration.fingerprint?.nec } returns nec diff --git a/feature/setup/src/main/java/com/simprints/feature/setup/screen/SetupViewModel.kt b/feature/setup/src/main/java/com/simprints/feature/setup/screen/SetupViewModel.kt index bbf8b2ba74..7761d9ef10 100644 --- a/feature/setup/src/main/java/com/simprints/feature/setup/screen/SetupViewModel.kt +++ b/feature/setup/src/main/java/com/simprints/feature/setup/screen/SetupViewModel.kt @@ -6,11 +6,11 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.simprints.core.DeviceID +import com.simprints.core.domain.common.Modality import com.simprints.feature.setup.LocationStore import com.simprints.infra.authstore.AuthStore import com.simprints.infra.config.store.models.FaceConfiguration import com.simprints.infra.config.store.models.FingerprintConfiguration -import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.isCommCareEventDownSyncAllowed import com.simprints.infra.config.sync.ConfigManager @@ -154,11 +154,11 @@ internal class SetupViewModel @Inject constructor( private val ProjectConfiguration.requiredLicenses: List> get() = general.modalities.mapNotNull { when { - it == GeneralConfiguration.Modality.FACE && shouldIncludeRankOne() -> { + it == Modality.FACE && shouldIncludeRankOne() -> { Vendor.RankOne to LicenseVersion(face?.rankOne?.version.orEmpty()) } - it == GeneralConfiguration.Modality.FINGERPRINT && shouldIncludeNec() -> { + it == Modality.FINGERPRINT && shouldIncludeNec() -> { Vendor.Nec to LicenseVersion(fingerprint?.nec?.version.orEmpty()) } diff --git a/feature/setup/src/test/java/com/simprints/feature/setup/screen/SetupViewModelTest.kt b/feature/setup/src/test/java/com/simprints/feature/setup/screen/SetupViewModelTest.kt index ea9328b776..8369182d06 100644 --- a/feature/setup/src/test/java/com/simprints/feature/setup/screen/SetupViewModelTest.kt +++ b/feature/setup/src/test/java/com/simprints/feature/setup/screen/SetupViewModelTest.kt @@ -2,11 +2,11 @@ package com.simprints.feature.setup.screen import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.jraska.livedata.test +import com.simprints.core.domain.common.Modality import com.simprints.feature.setup.LocationStore import com.simprints.infra.authstore.AuthStore import com.simprints.infra.config.store.models.FaceConfiguration import com.simprints.infra.config.store.models.FingerprintConfiguration -import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.license.LicenseRepository @@ -170,8 +170,8 @@ class SetupViewModelTest { coEvery { configManager.getProjectConfiguration() } returns mockk { every { general } returns mockk { every { modalities } returns listOf( - GeneralConfiguration.Modality.FINGERPRINT, - GeneralConfiguration.Modality.FACE, + Modality.FINGERPRINT, + Modality.FACE, ) } every { fingerprint } returns mockk { @@ -201,8 +201,8 @@ class SetupViewModelTest { coEvery { configManager.getProjectConfiguration() } returns mockk { every { general } returns mockk { every { modalities } returns listOf( - GeneralConfiguration.Modality.FINGERPRINT, - GeneralConfiguration.Modality.FACE, + Modality.FINGERPRINT, + Modality.FACE, ) every { fingerprint } returns mockk { every { allowedSDKs } returns listOf(FingerprintConfiguration.BioSdk.NEC) @@ -232,8 +232,8 @@ class SetupViewModelTest { coEvery { configManager.getProjectConfiguration() } returns mockk { every { general } returns mockk { every { modalities } returns listOf( - GeneralConfiguration.Modality.FINGERPRINT, - GeneralConfiguration.Modality.FACE, + Modality.FINGERPRINT, + Modality.FACE, ) every { fingerprint } returns mockk { every { allowedSDKs } returns listOf(FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER) @@ -257,8 +257,8 @@ class SetupViewModelTest { coEvery { configManager.getProjectConfiguration() } returns mockk { every { general } returns mockk { every { modalities } returns listOf( - GeneralConfiguration.Modality.FINGERPRINT, - GeneralConfiguration.Modality.FACE, + Modality.FINGERPRINT, + Modality.FACE, ) } every { fingerprint } returns mockk { diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/FingerprintCaptureContract.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/FingerprintCaptureContract.kt index 5f74639a5d..e9ef9f00d7 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/FingerprintCaptureContract.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/FingerprintCaptureContract.kt @@ -1,7 +1,7 @@ package com.simprints.fingerprint.capture import com.simprints.core.domain.common.FlowType -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.infra.config.store.models.FingerprintConfiguration object FingerprintCaptureContract { @@ -9,7 +9,7 @@ object FingerprintCaptureContract { fun getParams( flowType: FlowType, - fingers: List, + fingers: List, fingerprintSDK: FingerprintConfiguration.BioSdk, ) = FingerprintCaptureParams(flowType, fingers, fingerprintSDK) } diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/FingerprintCaptureParams.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/FingerprintCaptureParams.kt index 75c487a2bf..84f9f6e6e4 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/FingerprintCaptureParams.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/FingerprintCaptureParams.kt @@ -2,13 +2,13 @@ package com.simprints.fingerprint.capture import androidx.annotation.Keep import com.simprints.core.domain.common.FlowType -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.step.StepParams import com.simprints.infra.config.store.models.FingerprintConfiguration @Keep data class FingerprintCaptureParams( val flowType: FlowType, - val fingerprintsToCapture: List, + val fingerprintsToCapture: List, val fingerprintSDK: FingerprintConfiguration.BioSdk, ) : StepParams diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/FingerprintCaptureResult.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/FingerprintCaptureResult.kt deleted file mode 100644 index a8c8b916ef..0000000000 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/FingerprintCaptureResult.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.simprints.fingerprint.capture - -import androidx.annotation.Keep -import com.simprints.core.ExcludedFromGeneratedTestCoverageReports -import com.simprints.core.domain.fingerprint.IFingerIdentifier -import com.simprints.core.domain.step.StepResult -import com.simprints.infra.images.model.SecuredImageRef - -@Keep -data class FingerprintCaptureResult( - val referenceId: String, - var results: List, -) : StepResult { - @Keep - data class Item( - val captureEventId: String?, - val identifier: IFingerIdentifier, - val sample: Sample?, - ) : StepResult - - @Keep - data class Sample( - val fingerIdentifier: IFingerIdentifier, - val template: ByteArray, - val templateQualityScore: Int, - val imageRef: SecuredImageRef?, - val format: String, - ) : StepResult { - @ExcludedFromGeneratedTestCoverageReports("Generated code") - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as Sample - - if (templateQualityScore != other.templateQualityScore) return false - if (fingerIdentifier != other.fingerIdentifier) return false - if (!template.contentEquals(other.template)) return false - if (imageRef != other.imageRef) return false - if (format != other.format) return false - - return true - } - - @ExcludedFromGeneratedTestCoverageReports("Generated code") - override fun hashCode(): Int { - var result = templateQualityScore - result = 31 * result + fingerIdentifier.hashCode() - result = 31 * result + template.contentHashCode() - result = 31 * result + (imageRef?.hashCode() ?: 0) - result = 31 * result + format.hashCode() - return result - } - } -} diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/models/CaptureId.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/models/CaptureId.kt index 781ba08372..c692dc0eb0 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/models/CaptureId.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/models/CaptureId.kt @@ -1,8 +1,8 @@ package com.simprints.fingerprint.capture.models -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier internal data class CaptureId( - val finger: IFingerIdentifier, + val finger: SampleIdentifier, val captureIndex: Int, ) diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/resources/FingerIdentifierResources.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/resources/FingerIdentifierResources.kt index a5acb1799c..ea989b61a1 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/resources/FingerIdentifierResources.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/resources/FingerIdentifierResources.kt @@ -2,37 +2,39 @@ package com.simprints.fingerprint.capture.resources import androidx.annotation.DrawableRes import androidx.annotation.StringRes -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.fingerprint.capture.R import com.simprints.infra.uibase.annotations.ExcludedFromGeneratedTestCoverageReports import com.simprints.infra.resources.R as IDR @ExcludedFromGeneratedTestCoverageReports("UI code") @DrawableRes -internal fun IFingerIdentifier.fingerDrawable(): Int = when (this) { - IFingerIdentifier.RIGHT_5TH_FINGER -> R.drawable.hand_bb_r5_c4 - IFingerIdentifier.RIGHT_4TH_FINGER -> R.drawable.hand_bb_r4_c4 - IFingerIdentifier.RIGHT_3RD_FINGER -> R.drawable.hand_bb_r3_c4 - IFingerIdentifier.RIGHT_INDEX_FINGER -> R.drawable.hand_bb_r2_c4 - IFingerIdentifier.RIGHT_THUMB -> R.drawable.hand_bb_r1_c4 - IFingerIdentifier.LEFT_THUMB -> R.drawable.hand_bb_l1_c4 - IFingerIdentifier.LEFT_INDEX_FINGER -> R.drawable.hand_bb_l2_c4 - IFingerIdentifier.LEFT_3RD_FINGER -> R.drawable.hand_bb_l3_c4 - IFingerIdentifier.LEFT_4TH_FINGER -> R.drawable.hand_bb_l4_c4 - IFingerIdentifier.LEFT_5TH_FINGER -> R.drawable.hand_bb_l5_c4 +internal fun SampleIdentifier.fingerDrawable(): Int = when (this) { + SampleIdentifier.RIGHT_5TH_FINGER -> R.drawable.hand_bb_r5_c4 + SampleIdentifier.RIGHT_4TH_FINGER -> R.drawable.hand_bb_r4_c4 + SampleIdentifier.RIGHT_3RD_FINGER -> R.drawable.hand_bb_r3_c4 + SampleIdentifier.RIGHT_INDEX_FINGER -> R.drawable.hand_bb_r2_c4 + SampleIdentifier.RIGHT_THUMB -> R.drawable.hand_bb_r1_c4 + SampleIdentifier.LEFT_THUMB -> R.drawable.hand_bb_l1_c4 + SampleIdentifier.LEFT_INDEX_FINGER -> R.drawable.hand_bb_l2_c4 + SampleIdentifier.LEFT_3RD_FINGER -> R.drawable.hand_bb_l3_c4 + SampleIdentifier.LEFT_4TH_FINGER -> R.drawable.hand_bb_l4_c4 + SampleIdentifier.LEFT_5TH_FINGER -> R.drawable.hand_bb_l5_c4 + SampleIdentifier.NONE -> throw IllegalArgumentException("Must be a finger sample identifier") } @ExcludedFromGeneratedTestCoverageReports("UI code") @StringRes -internal fun IFingerIdentifier.nameTextId(): Int = when (this) { - IFingerIdentifier.RIGHT_5TH_FINGER -> IDR.string.fingerprint_capture_finger_r_5 - IFingerIdentifier.RIGHT_4TH_FINGER -> IDR.string.fingerprint_capture_finger_r_4 - IFingerIdentifier.RIGHT_3RD_FINGER -> IDR.string.fingerprint_capture_finger_r_3 - IFingerIdentifier.RIGHT_INDEX_FINGER -> IDR.string.fingerprint_capture_finger_r_2 - IFingerIdentifier.RIGHT_THUMB -> IDR.string.fingerprint_capture_finger_r_1 - IFingerIdentifier.LEFT_THUMB -> IDR.string.fingerprint_capture_finger_l_1 - IFingerIdentifier.LEFT_INDEX_FINGER -> IDR.string.fingerprint_capture_finger_l_2 - IFingerIdentifier.LEFT_3RD_FINGER -> IDR.string.fingerprint_capture_finger_l_3 - IFingerIdentifier.LEFT_4TH_FINGER -> IDR.string.fingerprint_capture_finger_l_4 - IFingerIdentifier.LEFT_5TH_FINGER -> IDR.string.fingerprint_capture_finger_l_5 +internal fun SampleIdentifier.nameTextId(): Int = when (this) { + SampleIdentifier.RIGHT_5TH_FINGER -> IDR.string.fingerprint_capture_finger_r_5 + SampleIdentifier.RIGHT_4TH_FINGER -> IDR.string.fingerprint_capture_finger_r_4 + SampleIdentifier.RIGHT_3RD_FINGER -> IDR.string.fingerprint_capture_finger_r_3 + SampleIdentifier.RIGHT_INDEX_FINGER -> IDR.string.fingerprint_capture_finger_r_2 + SampleIdentifier.RIGHT_THUMB -> IDR.string.fingerprint_capture_finger_r_1 + SampleIdentifier.LEFT_THUMB -> IDR.string.fingerprint_capture_finger_l_1 + SampleIdentifier.LEFT_INDEX_FINGER -> IDR.string.fingerprint_capture_finger_l_2 + SampleIdentifier.LEFT_3RD_FINGER -> IDR.string.fingerprint_capture_finger_l_3 + SampleIdentifier.LEFT_4TH_FINGER -> IDR.string.fingerprint_capture_finger_l_4 + SampleIdentifier.LEFT_5TH_FINGER -> IDR.string.fingerprint_capture_finger_l_5 + SampleIdentifier.NONE -> throw IllegalArgumentException("Must be a finger sample identifier") } 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 069dd719ae..6dfd9df73e 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 @@ -6,14 +6,16 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.simprints.core.ExternalScope -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureIdentity +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.livedata.LiveDataEvent import com.simprints.core.livedata.LiveDataEventWithContent import com.simprints.core.livedata.send import com.simprints.core.tools.extentions.updateOnIndex import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp -import com.simprints.fingerprint.capture.FingerprintCaptureResult import com.simprints.fingerprint.capture.extensions.isEager import com.simprints.fingerprint.capture.extensions.isImageTransferRequired import com.simprints.fingerprint.capture.extensions.toInt @@ -50,8 +52,6 @@ import com.simprints.infra.config.store.models.Vero2Configuration.ImageSavingStr import com.simprints.infra.config.store.models.Vero2Configuration.ImageSavingStrategy.ONLY_USED_IN_REFERENCE import com.simprints.infra.config.store.models.Vero2Configuration.LedsMode.LIVE_QUALITY_FEEDBACK import com.simprints.infra.config.sync.ConfigManager -import com.simprints.infra.images.model.Path -import com.simprints.infra.images.model.SecuredImageRef import com.simprints.infra.logging.LoggingConstants.CrashReportTag.FINGER_CAPTURE import com.simprints.infra.logging.Simber import dagger.hilt.android.lifecycle.HiltViewModel @@ -135,14 +135,13 @@ internal class FingerprintCaptureViewModel @Inject constructor( get() = _invalidLicense private val _invalidLicense = MutableLiveData() - val finishWithFingerprints: LiveData> + val finishWithFingerprints: LiveData> get() = _finishWithFingerprints private val _finishWithFingerprints = - MutableLiveData>() + MutableLiveData>() - private lateinit var originalFingerprintsToCapture: List + private lateinit var originalFingerprintsToCapture: List private val captureEventIds: MutableMap = mutableMapOf() - private val imageRefs: MutableMap = mutableMapOf() private var lastCaptureStartedAt: Timestamp = Timestamp(0L) private var hasStarted: Boolean = false @@ -167,7 +166,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( } private fun start( - fingerprintsToCapture: List, + fingerprintsToCapture: List, fingerprintSdk: FingerprintConfiguration.BioSdk, ) { if (!hasStarted) { @@ -274,7 +273,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( } } - private fun setStartingState(fingerprintsToCapture: List) { + private fun setStartingState(fingerprintsToCapture: List) { val initialState = CollectFingerprintsState.EMPTY.copy( fingerStates = getStartState(fingerprintsToCapture), ) @@ -659,23 +658,21 @@ internal class FingerprintCaptureViewModel @Inject constructor( private fun proceedToFinish(collectedFingers: List>) { Simber.i("Finishing fingerprint capture", tag = FINGER_CAPTURE) - val resultItems = collectedFingers.map { (captureId, collectedFinger) -> - FingerprintCaptureResult.Item( - identifier = captureId.finger, - captureEventId = captureEventIds[captureId], - sample = FingerprintCaptureResult.Sample( - fingerIdentifier = captureId.finger, - template = collectedFinger.scanResult.template, - templateQualityScore = collectedFinger.scanResult.qualityScore, - imageRef = imageRefs[captureId]?.let { SecuredImageRef(Path(it.relativePath.parts)) }, + val resultItems = collectedFingers.mapNotNull { (captureId, collectedFinger) -> + captureEventIds[captureId]?.let { captureEventId -> + CaptureSample( + captureEventId = captureEventId, + identifier = captureId.finger, + modality = Modality.FINGERPRINT, format = collectedFinger.scanResult.templateFormat, - ), - ) + template = collectedFinger.scanResult.template, + ) + } } val biometricReferenceId = UUID.randomUUID().toString() - addBiometricReferenceCreationEvents(biometricReferenceId, resultItems.mapNotNull { it.captureEventId }) + addBiometricReferenceCreationEvents(biometricReferenceId, resultItems.map { it.captureEventId }) - _finishWithFingerprints.send(FingerprintCaptureResult(biometricReferenceId, resultItems)) + _finishWithFingerprints.send(CaptureIdentity(biometricReferenceId, Modality.FINGERPRINT, resultItems)) } private suspend fun saveImageIfExists( @@ -683,13 +680,12 @@ internal class FingerprintCaptureViewModel @Inject constructor( collectedFinger: CaptureState.ScanProcess.Collected, ) { val captureEventId = captureEventIds[id] - val imageRef = saveImage( + saveImage( vero2Configuration = bioSdkConfiguration.vero2!!, finger = id.finger, captureEventId = captureEventId, collectedFinger = collectedFinger, ) - imageRefs[id] = imageRef } fun handleRestart() { @@ -699,7 +695,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( } fun handleOnViewCreated( - fingerprintsToCapture: List, + fingerprintsToCapture: List, fingerprintSdk: FingerprintConfiguration.BioSdk, ) { updateState { diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/state/FingerState.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/state/FingerState.kt index ce6884f0bf..bbaa99da4f 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/state/FingerState.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/state/FingerState.kt @@ -1,9 +1,9 @@ package com.simprints.fingerprint.capture.state -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier internal data class FingerState( - val id: IFingerIdentifier, + val id: SampleIdentifier, val captures: List, val currentCaptureIndex: Int = 0, ) { diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/GetNextFingerToAddUseCase.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/GetNextFingerToAddUseCase.kt index 40ff4c6f66..a06d25152c 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/GetNextFingerToAddUseCase.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/GetNextFingerToAddUseCase.kt @@ -1,24 +1,24 @@ package com.simprints.fingerprint.capture.usecase -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import javax.inject.Inject internal class GetNextFingerToAddUseCase @Inject constructor() { - operator fun invoke(existingFingers: List): IFingerIdentifier? = + operator fun invoke(existingFingers: List): SampleIdentifier? = DEFAULT_PRIORITY.minus(existingFingers.toSet()).firstOrNull() companion object { private val DEFAULT_PRIORITY = listOf( - IFingerIdentifier.LEFT_THUMB, - IFingerIdentifier.LEFT_INDEX_FINGER, - IFingerIdentifier.RIGHT_THUMB, - IFingerIdentifier.RIGHT_INDEX_FINGER, - IFingerIdentifier.LEFT_3RD_FINGER, - IFingerIdentifier.RIGHT_3RD_FINGER, - IFingerIdentifier.LEFT_4TH_FINGER, - IFingerIdentifier.RIGHT_4TH_FINGER, - IFingerIdentifier.LEFT_5TH_FINGER, - IFingerIdentifier.RIGHT_5TH_FINGER, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.RIGHT_THUMB, + SampleIdentifier.RIGHT_INDEX_FINGER, + SampleIdentifier.LEFT_3RD_FINGER, + SampleIdentifier.RIGHT_3RD_FINGER, + SampleIdentifier.LEFT_4TH_FINGER, + SampleIdentifier.RIGHT_4TH_FINGER, + SampleIdentifier.LEFT_5TH_FINGER, + SampleIdentifier.RIGHT_5TH_FINGER, ) } } diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/GetStartStateUseCase.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/GetStartStateUseCase.kt index 4e9664658e..f445419720 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/GetStartStateUseCase.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/GetStartStateUseCase.kt @@ -1,12 +1,12 @@ package com.simprints.fingerprint.capture.usecase -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.fingerprint.capture.state.CaptureState import com.simprints.fingerprint.capture.state.FingerState import javax.inject.Inject internal class GetStartStateUseCase @Inject constructor() { - operator fun invoke(fingerprintsToCapture: List) = fingerprintsToCapture + operator fun invoke(fingerprintsToCapture: List) = fingerprintsToCapture .groupingBy { it } .eachCount() .map { (id, quantity) -> FingerState(id, List(quantity) { CaptureState.NotCollected }) } diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/SaveFingerprintSampleUseCase.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/SaveFingerprintSampleUseCase.kt index 293aa215b5..792d2ca4b4 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/SaveFingerprintSampleUseCase.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/usecase/SaveFingerprintSampleUseCase.kt @@ -1,11 +1,11 @@ package com.simprints.fingerprint.capture.usecase -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.fingerprint.capture.extensions.deduceFileExtension import com.simprints.fingerprint.capture.extensions.toInt import com.simprints.fingerprint.capture.state.CaptureState import com.simprints.fingerprint.infra.scanner.v2.scanner.ScannerInfo -import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.store.models.Vero2Configuration import com.simprints.infra.events.session.SessionEventRepository import com.simprints.infra.images.ImageRepository @@ -21,7 +21,7 @@ internal class SaveFingerprintSampleUseCase @Inject constructor( ) { suspend operator fun invoke( vero2Configuration: Vero2Configuration, - finger: IFingerIdentifier, + finger: SampleIdentifier, captureEventId: String?, collectedFinger: CaptureState.ScanProcess.Collected, ) = if (collectedFinger.scanResult.image != null && captureEventId != null) { @@ -45,7 +45,7 @@ internal class SaveFingerprintSampleUseCase @Inject constructor( imageBytes: ByteArray, captureEventId: String, fileExtension: String, - finger: IFingerIdentifier, + finger: SampleIdentifier, dpi: Int, scannerId: String?, un20SerialNumber: String?, @@ -59,7 +59,7 @@ internal class SaveFingerprintSampleUseCase @Inject constructor( return coreImageRepository.storeSample( projectId = currentSession.projectId, sessionId = currentSession.id, - modality = GeneralConfiguration.Modality.FINGERPRINT, + modality = Modality.FINGERPRINT, sampleId = captureEventId, fileExtension = fileExtension, sampleBytes = imageBytes, diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/confirmfingerprints/ConfirmFingerprintsDialog.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/confirmfingerprints/ConfirmFingerprintsDialog.kt index a8f64ce3d4..6921c8b5fc 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/confirmfingerprints/ConfirmFingerprintsDialog.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/confirmfingerprints/ConfirmFingerprintsDialog.kt @@ -5,7 +5,7 @@ import android.content.Context import androidx.appcompat.app.AlertDialog import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.simprints.core.ExcludedFromGeneratedTestCoverageReports -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.fingerprint.capture.resources.nameTextId import com.simprints.infra.resources.R as IDR @@ -38,7 +38,7 @@ internal class ConfirmFingerprintsDialog( }.toString() data class Item( - val finger: IFingerIdentifier, + val finger: SampleIdentifier, val numberOfSuccessfulScans: Int, val numberOfScans: Int, ) 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 bda823e77d..bfe89e809b 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 @@ -8,7 +8,7 @@ import androidx.core.content.ContextCompat import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.fingerprint.capture.R import com.simprints.fingerprint.capture.databinding.FragmentFingerBinding import com.simprints.fingerprint.capture.resources.directionTextColour @@ -30,7 +30,7 @@ internal class FingerFragment : Fragment(R.layout.fragment_finger) { private val binding by viewBinding(FragmentFingerBinding::bind) private val vm: FingerprintCaptureViewModel by viewModels(ownerProducer = { requireParentFragment() }) - private lateinit var fingerId: IFingerIdentifier + private lateinit var fingerId: SampleIdentifier private lateinit var timeoutBars: List @@ -40,7 +40,7 @@ internal class FingerFragment : Fragment(R.layout.fragment_finger) { ) { super.onViewCreated(view, savedInstanceState) - fingerId = IFingerIdentifier.entries.toTypedArray()[ + fingerId = SampleIdentifier.entries.toTypedArray()[ arguments?.getInt(FINGER_ID_BUNDLE_KEY) ?: throw IllegalArgumentException(), ] @@ -151,7 +151,7 @@ internal class FingerFragment : Fragment(R.layout.fragment_finger) { private const val PROGRESS_BAR_MARGIN = 4 - fun newInstance(fingerId: IFingerIdentifier) = FingerFragment().also { + fun newInstance(fingerId: SampleIdentifier) = FingerFragment().also { it.arguments = Bundle().apply { putInt(FINGER_ID_BUNDLE_KEY, fingerId.ordinal) } } } diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/fingerviewpager/FingerPageAdapter.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/fingerviewpager/FingerPageAdapter.kt index f374362a56..0c534e9b12 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/fingerviewpager/FingerPageAdapter.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/fingerviewpager/FingerPageAdapter.kt @@ -2,13 +2,13 @@ package com.simprints.fingerprint.capture.views.fingerviewpager import androidx.fragment.app.Fragment import androidx.viewpager2.adapter.FragmentStateAdapter -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.infra.uibase.annotations.ExcludedFromGeneratedTestCoverageReports @ExcludedFromGeneratedTestCoverageReports("UI code") internal class FingerPageAdapter( parent: Fragment, - private val activeFingers: MutableList, + private val activeFingers: MutableList, ) : FragmentStateAdapter(parent) { override fun createFragment(position: Int): Fragment = FingerFragment.newInstance(activeFingers[position]) @@ -18,7 +18,7 @@ internal class FingerPageAdapter( override fun getItemId(position: Int): Long = activeFingers[position].toItemId() - private fun IFingerIdentifier.toItemId(): Long = this.ordinal.toLong() + private fun SampleIdentifier.toItemId(): Long = this.ordinal.toLong() - private fun Long.itemIdToFingerIdentifier(): IFingerIdentifier = IFingerIdentifier.values()[this.toInt()] + private fun Long.itemIdToFingerIdentifier(): SampleIdentifier = SampleIdentifier.values()[this.toInt()] } diff --git a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/fingerviewpager/FingerViewPagerManager.kt b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/fingerviewpager/FingerViewPagerManager.kt index 495d637693..a4d3e01be6 100644 --- a/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/fingerviewpager/FingerViewPagerManager.kt +++ b/fingerprint/capture/src/main/java/com/simprints/fingerprint/capture/views/fingerviewpager/FingerViewPagerManager.kt @@ -7,14 +7,14 @@ import android.widget.LinearLayout import androidx.core.view.children import androidx.fragment.app.Fragment import androidx.viewpager2.widget.ViewPager2 -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.fingerprint.capture.resources.indicatorDrawableId import com.simprints.fingerprint.capture.state.FingerState import com.simprints.infra.uibase.annotations.ExcludedFromGeneratedTestCoverageReports @ExcludedFromGeneratedTestCoverageReports("UI code") internal class FingerViewPagerManager( - private val activeFingers: MutableList, + private val activeFingers: MutableList, private val parentFragment: Fragment, private val viewPager: ViewPager2, private val indicatorLayout: LinearLayout, 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 7cc121f2e6..aa95b1f67f 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 @@ -1,8 +1,8 @@ package com.simprints.fingerprint.capture.screen import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.google.common.truth.Truth.* +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.tools.time.TimeHelper import com.simprints.fingerprint.capture.screen.FingerprintCaptureViewModelTest.MockAcquireImageResult.OK import com.simprints.fingerprint.capture.screen.FingerprintCaptureViewModelTest.MockCaptureFingerprintResponse.BAD_SCAN @@ -46,16 +46,9 @@ import com.simprints.testtools.common.coroutines.TestCoroutineRule import com.simprints.testtools.common.livedata.assertEventNotReceived import com.simprints.testtools.common.livedata.assertEventReceived import com.simprints.testtools.common.livedata.assertEventReceivedWithContentAssertions -import io.mockk.MockKAnnotations -import io.mockk.coEvery -import io.mockk.coJustRun -import io.mockk.coVerify -import io.mockk.every +import io.mockk.* +import io.mockk.impl.annotations.* import io.mockk.impl.annotations.MockK -import io.mockk.impl.annotations.RelaxedMockK -import io.mockk.mockk -import io.mockk.unmockkAll -import io.mockk.verify import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay @@ -522,13 +515,12 @@ class FingerprintCaptureViewModelTest { coVerify { addBiometricReferenceCreatedEvents.invoke(any(), any()) } vm.finishWithFingerprints.assertEventReceivedWithContentAssertions { actualFingerprints -> - assertThat(actualFingerprints?.results).hasSize(FOUR_FINGERS_IDS.size) - assertThat(actualFingerprints?.results?.map { it.identifier }).containsExactlyElementsIn( + assertThat(actualFingerprints?.samples).hasSize(FOUR_FINGERS_IDS.size) + assertThat(actualFingerprints?.samples?.map { it.identifier }).containsExactlyElementsIn( FOUR_FINGERS_IDS, ) - actualFingerprints?.results?.forEach { - assertThat(it.sample?.template).isEqualTo(TEMPLATE) - assertThat(it.sample?.imageRef).isNotNull() + actualFingerprints?.samples?.forEach { + assertThat(it.template).isEqualTo(TEMPLATE) } } } @@ -581,13 +573,12 @@ class FingerprintCaptureViewModelTest { coVerify { addBiometricReferenceCreatedEvents.invoke(any(), any()) } vm.finishWithFingerprints.assertEventReceivedWithContentAssertions { actualFingerprints -> - assertThat(actualFingerprints?.results).hasSize(TWO_FINGERS_IDS.size) - assertThat(actualFingerprints?.results?.map { it.identifier }).containsExactlyElementsIn( + assertThat(actualFingerprints?.samples).hasSize(TWO_FINGERS_IDS.size) + assertThat(actualFingerprints?.samples?.map { it.identifier }).containsExactlyElementsIn( TWO_FINGERS_IDS, ) - actualFingerprints?.results?.forEach { - assertThat(it.sample?.template).isEqualTo(TEMPLATE) - assertThat(it.sample?.imageRef).isNotNull() + actualFingerprints?.samples?.forEach { + assertThat(it.template).isEqualTo(TEMPLATE) } } } @@ -638,13 +629,12 @@ class FingerprintCaptureViewModelTest { coVerify { addBiometricReferenceCreatedEvents.invoke(any(), any()) } vm.finishWithFingerprints.assertEventReceivedWithContentAssertions { actualFingerprints -> - assertThat(actualFingerprints?.results).hasSize(TWO_FINGERS_IDS.size) - assertThat(actualFingerprints?.results?.map { it.identifier }).containsExactlyElementsIn( + assertThat(actualFingerprints?.samples).hasSize(TWO_FINGERS_IDS.size) + assertThat(actualFingerprints?.samples?.map { it.identifier }).containsExactlyElementsIn( TWO_FINGERS_IDS, ) - actualFingerprints?.results?.forEach { - assertThat(it.sample?.template).isEqualTo(TEMPLATE) - assertThat(it.sample?.imageRef).isNull() + actualFingerprints?.samples?.forEach { + assertThat(it.template).isEqualTo(TEMPLATE) } } } @@ -852,15 +842,14 @@ class FingerprintCaptureViewModelTest { coVerify(exactly = 3) { saveFingerprintSampleUseCase.invoke(any(), any(), any(), any()) } vm.finishWithFingerprints.assertEventReceivedWithContentAssertions { actualFingerprints -> - assertThat(actualFingerprints?.results).hasSize(3) - assertThat(actualFingerprints?.results?.map { it.identifier }).containsExactly( - IFingerIdentifier.LEFT_THUMB, - IFingerIdentifier.RIGHT_THUMB, - IFingerIdentifier.RIGHT_INDEX_FINGER, + assertThat(actualFingerprints?.samples).hasSize(3) + assertThat(actualFingerprints?.samples?.map { it.identifier }).containsExactly( + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.RIGHT_THUMB, + SampleIdentifier.RIGHT_INDEX_FINGER, ) - actualFingerprints?.results?.forEach { - assertThat(it.sample?.template).isEqualTo(TEMPLATE) - assertThat(it.sample?.imageRef).isNotNull() + actualFingerprints?.samples?.forEach { + assertThat(it.template).isEqualTo(TEMPLATE) } } } @@ -965,15 +954,14 @@ class FingerprintCaptureViewModelTest { vm.handleConfirmFingerprintsAndContinue() vm.finishWithFingerprints.assertEventReceivedWithContentAssertions { actualFingerprints -> - assertThat(actualFingerprints?.results).hasSize(3) - assertThat(actualFingerprints?.results?.map { it.identifier }).containsExactly( - IFingerIdentifier.LEFT_THUMB, - IFingerIdentifier.RIGHT_THUMB, - IFingerIdentifier.RIGHT_INDEX_FINGER, + assertThat(actualFingerprints?.samples).hasSize(3) + assertThat(actualFingerprints?.samples?.map { it.identifier }).containsExactly( + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.RIGHT_THUMB, + SampleIdentifier.RIGHT_INDEX_FINGER, ) - actualFingerprints?.results?.forEach { - assertThat(it.sample?.template).isEqualTo(TEMPLATE) - assertThat(it.sample?.imageRef).isNotNull() + actualFingerprints?.samples?.forEach { + assertThat(it.template).isEqualTo(TEMPLATE) } } } @@ -1060,15 +1048,14 @@ class FingerprintCaptureViewModelTest { coVerify(exactly = 3) { saveFingerprintSampleUseCase.invoke(any(), any(), any(), any()) } vm.finishWithFingerprints.assertEventReceivedWithContentAssertions { actualFingerprints -> - assertThat(actualFingerprints?.results).hasSize(3) - assertThat(actualFingerprints?.results?.map { it.identifier }).containsExactly( - IFingerIdentifier.LEFT_THUMB, - IFingerIdentifier.LEFT_INDEX_FINGER, - IFingerIdentifier.RIGHT_THUMB, + assertThat(actualFingerprints?.samples).hasSize(3) + assertThat(actualFingerprints?.samples?.map { it.identifier }).containsExactly( + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.RIGHT_THUMB, ) - actualFingerprints?.results?.forEach { - assertThat(it.sample?.template).isEqualTo(TEMPLATE) - assertThat(it.sample?.imageRef).isNotNull() + actualFingerprints?.samples?.forEach { + assertThat(it.template).isEqualTo(TEMPLATE) } } } @@ -1563,14 +1550,14 @@ class FingerprintCaptureViewModelTest { companion object { val TWO_FINGERS_IDS = listOf( - IFingerIdentifier.LEFT_THUMB, - IFingerIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_INDEX_FINGER, ) val FOUR_FINGERS_IDS = listOf( - IFingerIdentifier.LEFT_THUMB, - IFingerIdentifier.LEFT_INDEX_FINGER, - IFingerIdentifier.RIGHT_THUMB, - IFingerIdentifier.RIGHT_INDEX_FINGER, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.RIGHT_THUMB, + SampleIdentifier.RIGHT_INDEX_FINGER, ) const val GOOD_QUALITY = 80 @@ -1578,8 +1565,8 @@ class FingerprintCaptureViewModelTest { const val DIFFERENT_GOOD_QUALITY = 80 const val BAD_QUALITY = 20 - val TEMPLATE = FingerprintGenerator.generateRandomFingerprint().template - val DIFFERENT_TEMPLATE = FingerprintGenerator.generateRandomFingerprint().template + val TEMPLATE = FingerprintGenerator.generateRandomFingerprintTemplate() + val DIFFERENT_TEMPLATE = FingerprintGenerator.generateRandomFingerprintTemplate() val IMAGE = byteArrayOf(0x05, 0x06, 0x07, 0x08) 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 f4841e69ac..fa1a5e40d5 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 @@ -1,6 +1,6 @@ package com.simprints.fingerprint.capture.usecase -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp import com.simprints.core.tools.utils.EncodingUtils @@ -43,7 +43,7 @@ internal class AddCaptureEventsUseCaseTest { fun `Saves only capture event when not collected state`() = runTest { useCase.invoke( Timestamp(1L), - FingerState(IFingerIdentifier.LEFT_THUMB, listOf(CaptureState.NotCollected)), + FingerState(SampleIdentifier.LEFT_THUMB, listOf(CaptureState.NotCollected)), 10, false, ) @@ -57,7 +57,7 @@ internal class AddCaptureEventsUseCaseTest { useCase.invoke( Timestamp(1L), FingerState( - IFingerIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_THUMB, listOf( CaptureState.ScanProcess.Collected( numberOfBadScans = 0, @@ -79,7 +79,7 @@ internal class AddCaptureEventsUseCaseTest { useCase.invoke( Timestamp(1L), FingerState( - IFingerIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_THUMB, listOf( CaptureState.ScanProcess.Collected( numberOfBadScans = 0, @@ -103,7 +103,7 @@ internal class AddCaptureEventsUseCaseTest { useCase.invoke( Timestamp(1L), FingerState( - IFingerIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_THUMB, listOf( CaptureState.ScanProcess.Collected( numberOfBadScans = 0, diff --git a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/GetNextFingerToAddUseCaseTest.kt b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/GetNextFingerToAddUseCaseTest.kt index 4d8bc92c48..da264b64d7 100644 --- a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/GetNextFingerToAddUseCaseTest.kt +++ b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/GetNextFingerToAddUseCaseTest.kt @@ -1,7 +1,7 @@ package com.simprints.fingerprint.capture.usecase import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import org.junit.Test class GetNextFingerToAddUseCaseTest { @@ -9,7 +9,7 @@ class GetNextFingerToAddUseCaseTest { @Test fun `Returns left thumb as first in priority`() { - assertThat(useCase(listOf())).isEqualTo(IFingerIdentifier.LEFT_THUMB) + assertThat(useCase(listOf())).isEqualTo(SampleIdentifier.LEFT_THUMB) } @Test @@ -17,10 +17,10 @@ class GetNextFingerToAddUseCaseTest { assertThat( useCase( listOf( - IFingerIdentifier.LEFT_THUMB, - IFingerIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_INDEX_FINGER, ), ), - ).isEqualTo(IFingerIdentifier.RIGHT_THUMB) + ).isEqualTo(SampleIdentifier.RIGHT_THUMB) } } diff --git a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/GetStartStateUseCaseTest.kt b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/GetStartStateUseCaseTest.kt index 3844102e33..428783f073 100644 --- a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/GetStartStateUseCaseTest.kt +++ b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/GetStartStateUseCaseTest.kt @@ -1,7 +1,7 @@ package com.simprints.fingerprint.capture.usecase import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.fingerprint.capture.state.CaptureState import com.simprints.fingerprint.capture.state.FingerState import org.junit.Test @@ -14,16 +14,16 @@ internal class GetStartStateUseCaseTest { assertThat( getStartStateUseCase( listOf( - IFingerIdentifier.LEFT_THUMB, - IFingerIdentifier.RIGHT_5TH_FINGER, - IFingerIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.RIGHT_5TH_FINGER, + SampleIdentifier.LEFT_INDEX_FINGER, ), ), ).containsExactlyElementsIn( listOf( - FingerState(IFingerIdentifier.LEFT_THUMB, listOf(CaptureState.NotCollected)), - FingerState(IFingerIdentifier.RIGHT_5TH_FINGER, listOf(CaptureState.NotCollected)), - FingerState(IFingerIdentifier.LEFT_INDEX_FINGER, listOf(CaptureState.NotCollected)), + FingerState(SampleIdentifier.LEFT_THUMB, listOf(CaptureState.NotCollected)), + FingerState(SampleIdentifier.RIGHT_5TH_FINGER, listOf(CaptureState.NotCollected)), + FingerState(SampleIdentifier.LEFT_INDEX_FINGER, listOf(CaptureState.NotCollected)), ), ) } @@ -33,22 +33,22 @@ internal class GetStartStateUseCaseTest { assertThat( getStartStateUseCase( listOf( - IFingerIdentifier.LEFT_THUMB, - IFingerIdentifier.LEFT_THUMB, - IFingerIdentifier.LEFT_THUMB, - IFingerIdentifier.RIGHT_5TH_FINGER, - IFingerIdentifier.LEFT_INDEX_FINGER, - IFingerIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.RIGHT_5TH_FINGER, + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.LEFT_INDEX_FINGER, ), ), ).containsExactlyElementsIn( listOf( FingerState( - IFingerIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_THUMB, listOf(CaptureState.NotCollected, CaptureState.NotCollected, CaptureState.NotCollected), ), - FingerState(IFingerIdentifier.RIGHT_5TH_FINGER, listOf(CaptureState.NotCollected)), - FingerState(IFingerIdentifier.LEFT_INDEX_FINGER, listOf(CaptureState.NotCollected, CaptureState.NotCollected)), + FingerState(SampleIdentifier.RIGHT_5TH_FINGER, listOf(CaptureState.NotCollected)), + FingerState(SampleIdentifier.LEFT_INDEX_FINGER, listOf(CaptureState.NotCollected, CaptureState.NotCollected)), ), ) } @@ -58,22 +58,22 @@ internal class GetStartStateUseCaseTest { assertThat( getStartStateUseCase( listOf( - IFingerIdentifier.LEFT_THUMB, - IFingerIdentifier.RIGHT_5TH_FINGER, - IFingerIdentifier.LEFT_INDEX_FINGER, - IFingerIdentifier.LEFT_THUMB, - IFingerIdentifier.LEFT_INDEX_FINGER, - IFingerIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.RIGHT_5TH_FINGER, + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.LEFT_THUMB, ), ), ).containsExactlyElementsIn( listOf( FingerState( - IFingerIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_THUMB, listOf(CaptureState.NotCollected, CaptureState.NotCollected, CaptureState.NotCollected), ), - FingerState(IFingerIdentifier.RIGHT_5TH_FINGER, listOf(CaptureState.NotCollected)), - FingerState(IFingerIdentifier.LEFT_INDEX_FINGER, listOf(CaptureState.NotCollected, CaptureState.NotCollected)), + FingerState(SampleIdentifier.RIGHT_5TH_FINGER, listOf(CaptureState.NotCollected)), + FingerState(SampleIdentifier.LEFT_INDEX_FINGER, listOf(CaptureState.NotCollected, CaptureState.NotCollected)), ), ) } diff --git a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/SaveFingerprintSampleUseCaseTest.kt b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/SaveFingerprintSampleUseCaseTest.kt index 711955473b..eb1153e29d 100644 --- a/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/SaveFingerprintSampleUseCaseTest.kt +++ b/fingerprint/capture/src/test/java/com/simprints/fingerprint/capture/usecase/SaveFingerprintSampleUseCaseTest.kt @@ -1,22 +1,18 @@ package com.simprints.fingerprint.capture.usecase -import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.fingerprint.capture.state.CaptureState import com.simprints.fingerprint.capture.state.ScanResult import com.simprints.fingerprint.infra.scanner.v2.scanner.ScannerInfo -import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.store.models.Vero2Configuration import com.simprints.infra.events.session.SessionEventRepository import com.simprints.infra.images.ImageRepository import com.simprints.infra.images.model.Path import com.simprints.infra.images.model.SecuredImageRef -import io.mockk.MockKAnnotations -import io.mockk.coEvery -import io.mockk.coVerify -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK -import io.mockk.mockk import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -48,7 +44,7 @@ class SaveFingerprintSampleUseCaseTest { fun `Returns null if no scan image`() = runTest { val result = useCase.invoke( vero2Configuration, - IFingerIdentifier.LEFT_3RD_FINGER, + SampleIdentifier.LEFT_3RD_FINGER, "captureEventId", createCollectedStub(null), ) @@ -59,7 +55,7 @@ class SaveFingerprintSampleUseCaseTest { fun `Returns null if no capture event id`() = runTest { val result = useCase.invoke( vero2Configuration, - IFingerIdentifier.LEFT_3RD_FINGER, + SampleIdentifier.LEFT_3RD_FINGER, null, createCollectedStub(byteArrayOf()), ) @@ -71,7 +67,7 @@ class SaveFingerprintSampleUseCaseTest { val scannerId = "scannerId" val un20SerialNumber = "un20SerialNumber" val expectedMetadata = mapOf( - "finger" to IFingerIdentifier.LEFT_3RD_FINGER.name, + "finger" to SampleIdentifier.LEFT_3RD_FINGER.name, "dpi" to "1300", "scannerID" to scannerId, "un20SerialNumber" to un20SerialNumber, @@ -98,7 +94,7 @@ class SaveFingerprintSampleUseCaseTest { assertThat( useCase.invoke( vero2Configuration, - IFingerIdentifier.LEFT_3RD_FINGER, + SampleIdentifier.LEFT_3RD_FINGER, "captureEventId", createCollectedStub(byteArrayOf()), ), @@ -114,7 +110,7 @@ class SaveFingerprintSampleUseCaseTest { assertThat( useCase.invoke( vero2Configuration, - IFingerIdentifier.LEFT_3RD_FINGER, + SampleIdentifier.LEFT_3RD_FINGER, "captureEventId", createCollectedStub(byteArrayOf()), ), @@ -128,13 +124,13 @@ class SaveFingerprintSampleUseCaseTest { every { id } returns "sessionId" } coEvery { - imageRepo.storeSample(any(), any(), GeneralConfiguration.Modality.FINGERPRINT, any(), any(), any(), any()) + imageRepo.storeSample(any(), any(), Modality.FINGERPRINT, any(), any(), any(), any()) } returns null assertThat( useCase.invoke( vero2Configuration, - IFingerIdentifier.LEFT_3RD_FINGER, + SampleIdentifier.LEFT_3RD_FINGER, "captureEventId", createCollectedStub(byteArrayOf()), ), diff --git a/fingerprint/capture/src/test/java/com/simprints/fingerprint/testtools/FingerprintGenerator.kt b/fingerprint/capture/src/test/java/com/simprints/fingerprint/testtools/FingerprintGenerator.kt index 3640a971d9..04dc8aab8a 100644 --- a/fingerprint/capture/src/test/java/com/simprints/fingerprint/testtools/FingerprintGenerator.kt +++ b/fingerprint/capture/src/test/java/com/simprints/fingerprint/testtools/FingerprintGenerator.kt @@ -1,7 +1,5 @@ package com.simprints.fingerprint.testtools -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.Fingerprint import java.nio.ByteBuffer import java.nio.ByteOrder import java.util.Random @@ -35,35 +33,20 @@ object FingerprintGenerator { private const val QUALITY_SHIFT = 5 // SHORT private val RANDOM_GENERATOR = Random() - private val FINGER_IDENTIFIERS = FingerIdentifier.values() /** - * @return A random valid [Fingerprint] with a random [FingerIdentifier] + * @return A random valid fingerprint template */ - fun generateRandomFingerprint(): Fingerprint { - val fingerNo = RANDOM_GENERATOR.nextInt(FINGER_IDENTIFIERS.size) - val fingerId = FINGER_IDENTIFIERS[fingerNo] - return generateRandomFingerprint(fingerId) - } - - /** - * @param fingerId Finger identifier of the fingerprint - * @return A random valid [Fingerprint] with specified [FingerIdentifier] - */ - private fun generateRandomFingerprint(fingerId: FingerIdentifier): Fingerprint { + fun generateRandomFingerprintTemplate(): ByteArray { val qualityScore = RANDOM_GENERATOR.nextInt(101).toByte() - return generateRandomFingerprint(fingerId, qualityScore) + return generateRandomFingerprintTemplate(qualityScore) } /** - * @param fingerId Finger identifier of the fingerprint * @param qualityScore Quality score of the fingerprint - * @return A random valid [Fingerprint] with specified [FingerIdentifier] + * @return A random valid fingerprint template */ - private fun generateRandomFingerprint( - fingerId: FingerIdentifier, - qualityScore: Byte, - ): Fingerprint { + private fun generateRandomFingerprintTemplate(qualityScore: Byte): ByteArray { val nbMinutiae = RANDOM_GENERATOR.nextInt(128).toByte() val length = HEADER_SIZE + nbMinutiae * MINUTIAE_SIZE @@ -95,8 +78,9 @@ object FingerprintGenerator { } bb.position(0) + val templateBytes = ByteArray(bb.remaining()) bb.get(templateBytes) - return Fingerprint(fingerId, templateBytes, format = "ISO_19794_2") + return templateBytes } } diff --git a/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/FingerprintBioSdk.kt b/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/FingerprintBioSdk.kt index aeba28d837..56226b4bf2 100644 --- a/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/FingerprintBioSdk.kt +++ b/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/FingerprintBioSdk.kt @@ -1,10 +1,11 @@ package com.simprints.fingerprint.infra.basebiosdk +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity import com.simprints.fingerprint.infra.basebiosdk.acquisition.FingerprintImageProvider import com.simprints.fingerprint.infra.basebiosdk.acquisition.FingerprintTemplateProvider import com.simprints.fingerprint.infra.basebiosdk.initialization.SdkInitializer import com.simprints.fingerprint.infra.basebiosdk.matching.FingerprintMatcher -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity class FingerprintBioSdk( private val sdkInitializer: SdkInitializer, @@ -24,8 +25,8 @@ class FingerprintBioSdk, + probe: List, + candidates: List, matchingSettings: MatcherSettings?, ) = fingerprintMatcher.match(probe, candidates, matchingSettings) diff --git a/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/FingerprintMatcher.kt b/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/FingerprintMatcher.kt index 902807f442..87bc9b697a 100644 --- a/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/FingerprintMatcher.kt +++ b/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/FingerprintMatcher.kt @@ -1,20 +1,21 @@ package com.simprints.fingerprint.infra.basebiosdk.matching -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.MatchResult +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.MatchComparisonResult interface FingerprintMatcher { /** * Matches a [probe] against the given flow of [candidates] - * producing a flow of [MatchResult]. + * producing a flow of [MatchComparisonResult]. * * @throws IllegalArgumentException if the TemplateFormats of the supplied [probe] */ suspend fun match( - probe: FingerprintIdentity, - candidates: List, + probe: List, + candidates: List, settings: MatcherSettings?, - ): List + ): List val supportedTemplateFormat: String val matcherName: String diff --git a/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/domain/FingerIdentifier.kt b/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/domain/FingerIdentifier.kt deleted file mode 100644 index c91e8517b9..0000000000 --- a/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/domain/FingerIdentifier.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.simprints.fingerprint.infra.basebiosdk.matching.domain - -enum class FingerIdentifier { - RIGHT_5TH_FINGER, - RIGHT_4TH_FINGER, - RIGHT_3RD_FINGER, - RIGHT_INDEX_FINGER, - RIGHT_THUMB, - LEFT_THUMB, - LEFT_INDEX_FINGER, - LEFT_3RD_FINGER, - LEFT_4TH_FINGER, - LEFT_5TH_FINGER, -} diff --git a/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/domain/Fingerprint.kt b/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/domain/Fingerprint.kt deleted file mode 100644 index a64865f1d6..0000000000 --- a/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/domain/Fingerprint.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.simprints.fingerprint.infra.basebiosdk.matching.domain - -class Fingerprint( - val fingerId: FingerIdentifier, - val template: ByteArray, - val format: String, -) diff --git a/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/domain/FingerprintIdentity.kt b/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/domain/FingerprintIdentity.kt deleted file mode 100644 index 8f55090ed1..0000000000 --- a/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/domain/FingerprintIdentity.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.simprints.fingerprint.infra.basebiosdk.matching.domain - -class FingerprintIdentity( - val subjectId: String, - val fingerprints: List, -) diff --git a/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/domain/MatchResult.kt b/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/domain/MatchResult.kt deleted file mode 100644 index fb128e8924..0000000000 --- a/fingerprint/infra/base-bio-sdk/src/main/java/com/simprints/fingerprint/infra/basebiosdk/matching/domain/MatchResult.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.simprints.fingerprint.infra.basebiosdk.matching.domain - -class MatchResult( - val id: String, - val score: Float, -) diff --git a/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/BioSdkWrapper.kt b/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/BioSdkWrapper.kt index bb436fc1c3..1b044d0d22 100644 --- a/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/BioSdkWrapper.kt +++ b/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/BioSdkWrapper.kt @@ -1,7 +1,8 @@ package com.simprints.fingerprint.infra.biosdk -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.MatchResult +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.fingerprint.infra.scanner.domain.fingerprint.AcquireFingerprintImageResponse import com.simprints.fingerprint.infra.scanner.domain.fingerprint.AcquireFingerprintTemplateResponse @@ -25,10 +26,10 @@ interface BioSdkWrapper { suspend fun initialize() suspend fun match( - probe: FingerprintIdentity, - candidates: List, + probe: List, + candidates: List, isCrossFingerMatchingEnabled: Boolean, - ): List + ): List suspend fun acquireFingerprintTemplate( capturingResolution: Int?, diff --git a/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/NECBioSdkWrapper.kt b/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/NECBioSdkWrapper.kt index b66a414896..08f8f643a6 100644 --- a/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/NECBioSdkWrapper.kt +++ b/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/NECBioSdkWrapper.kt @@ -1,10 +1,11 @@ package com.simprints.fingerprint.infra.biosdk +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.fingerprint.infra.basebiosdk.FingerprintBioSdk import com.simprints.fingerprint.infra.basebiosdk.acquisition.domain.TemplateResponse import com.simprints.fingerprint.infra.basebiosdk.acquisition.domain.toDomain -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.MatchResult import com.simprints.fingerprint.infra.necsdkimpl.acquisition.template.FingerprintTemplateAcquisitionSettings import com.simprints.fingerprint.infra.necsdkimpl.acquisition.template.FingerprintTemplateMetadata import com.simprints.fingerprint.infra.necsdkimpl.matching.NecMatchingSettings @@ -34,10 +35,10 @@ class NECBioSdkWrapper @Inject constructor( override suspend fun initialize() = bioSdk.initialize() override suspend fun match( - probe: FingerprintIdentity, - candidates: List, + probe: List, + candidates: List, isCrossFingerMatchingEnabled: Boolean, - ): List = bioSdk.match(probe, candidates, NecMatchingSettings(isCrossFingerMatchingEnabled)) + ): List = bioSdk.match(probe, candidates, NecMatchingSettings(isCrossFingerMatchingEnabled)) override suspend fun acquireFingerprintTemplate( capturingResolution: Int?, diff --git a/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/SimprintsBioSdkWrapper.kt b/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/SimprintsBioSdkWrapper.kt index 6b9a4cc625..da205a1177 100644 --- a/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/SimprintsBioSdkWrapper.kt +++ b/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/SimprintsBioSdkWrapper.kt @@ -1,9 +1,10 @@ package com.simprints.fingerprint.infra.biosdk +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity import com.simprints.fingerprint.infra.basebiosdk.FingerprintBioSdk import com.simprints.fingerprint.infra.basebiosdk.acquisition.domain.TemplateResponse import com.simprints.fingerprint.infra.basebiosdk.acquisition.domain.toDomain -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity import com.simprints.fingerprint.infra.biosdkimpl.acquisition.template.FingerprintTemplateAcquisitionSettings import com.simprints.fingerprint.infra.biosdkimpl.acquisition.template.FingerprintTemplateMetadata import com.simprints.fingerprint.infra.biosdkimpl.matching.SimAfisMatcherSettings @@ -35,8 +36,8 @@ class SimprintsBioSdkWrapper @Inject constructor( } override suspend fun match( - probe: FingerprintIdentity, - candidates: List, + probe: List, + candidates: List, isCrossFingerMatchingEnabled: Boolean, ) = bioSdk.match(probe, candidates, SimAfisMatcherSettings(isCrossFingerMatchingEnabled)) diff --git a/fingerprint/infra/bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdk/NECBioSdkWrapperTest.kt b/fingerprint/infra/bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdk/NECBioSdkWrapperTest.kt index 567971e522..cda1652cbe 100644 --- a/fingerprint/infra/bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdk/NECBioSdkWrapperTest.kt +++ b/fingerprint/infra/bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdk/NECBioSdkWrapperTest.kt @@ -1,20 +1,17 @@ package com.simprints.fingerprint.infra.biosdk -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity import com.simprints.fingerprint.infra.basebiosdk.FingerprintBioSdk import com.simprints.fingerprint.infra.basebiosdk.acquisition.domain.ImageResponse import com.simprints.fingerprint.infra.basebiosdk.acquisition.domain.TemplateResponse -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity import com.simprints.fingerprint.infra.necsdkimpl.acquisition.template.FingerprintTemplateAcquisitionSettings import com.simprints.fingerprint.infra.necsdkimpl.acquisition.template.FingerprintTemplateMetadata import com.simprints.fingerprint.infra.necsdkimpl.matching.NecMatchingSettings import com.simprints.testtools.common.syntax.assertThrows -import io.mockk.MockKAnnotations -import io.mockk.coEvery -import io.mockk.coVerify -import io.mockk.impl.annotations.RelaxedMockK -import io.mockk.mockk -import io.mockk.slot +import io.mockk.* +import io.mockk.impl.annotations.* import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -72,8 +69,8 @@ class NECBioSdkWrapperTest { @Test fun `calls match on bio sdk`() = runTest { // Given - val probe = mockk() - val candidates = listOf(mockk()) + val probe = listOf(mockk()) + val candidates = listOf(mockk()) val isCrossFingerMatchingEnabled = true val settings = NecMatchingSettings(isCrossFingerMatchingEnabled) // When diff --git a/fingerprint/infra/bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdk/SimprintsBioSdkWrapperTest.kt b/fingerprint/infra/bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdk/SimprintsBioSdkWrapperTest.kt index 9a171a03e0..586167658b 100644 --- a/fingerprint/infra/bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdk/SimprintsBioSdkWrapperTest.kt +++ b/fingerprint/infra/bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdk/SimprintsBioSdkWrapperTest.kt @@ -1,20 +1,17 @@ package com.simprints.fingerprint.infra.biosdk -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity import com.simprints.fingerprint.infra.basebiosdk.FingerprintBioSdk import com.simprints.fingerprint.infra.basebiosdk.acquisition.domain.ImageResponse import com.simprints.fingerprint.infra.basebiosdk.acquisition.domain.TemplateResponse -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity import com.simprints.fingerprint.infra.biosdkimpl.acquisition.template.FingerprintTemplateAcquisitionSettings import com.simprints.fingerprint.infra.biosdkimpl.acquisition.template.FingerprintTemplateMetadata import com.simprints.fingerprint.infra.biosdkimpl.matching.SimAfisMatcherSettings import com.simprints.testtools.common.syntax.assertThrows -import io.mockk.MockKAnnotations -import io.mockk.coEvery -import io.mockk.coVerify +import io.mockk.* import io.mockk.impl.annotations.MockK -import io.mockk.mockk -import io.mockk.slot import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -66,8 +63,8 @@ class SimprintsBioSdkWrapperTest { @Test fun `Calls match on bio sdk`() = runTest { // Given - val probe = mockk() - val candidates = listOf(mockk()) + val probe = listOf(mockk()) + val candidates = listOf(mockk()) val isCrossFingerMatchingEnabled = true val settings = SimAfisMatcherSettings(isCrossFingerMatchingEnabled) // When diff --git a/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/matching/FingerprintMatcherImpl.kt b/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/matching/FingerprintMatcherImpl.kt index 823ce3d01d..5680a0f02a 100644 --- a/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/matching/FingerprintMatcherImpl.kt +++ b/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/matching/FingerprintMatcherImpl.kt @@ -1,11 +1,12 @@ package com.simprints.fingerprint.infra.necsdkimpl.matching +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.MatchComparisonResult +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.fingerprint.infra.basebiosdk.exceptions.BioSdkException import com.simprints.fingerprint.infra.basebiosdk.matching.FingerprintMatcher -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.Fingerprint -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.MatchResult import com.simprints.fingerprint.infra.necsdkimpl.acquisition.template.NEC_TEMPLATE_FORMAT import com.simprints.necwrapper.nec.NEC import com.simprints.necwrapper.nec.models.NECTemplate @@ -18,10 +19,10 @@ internal class FingerprintMatcherImpl @Inject constructor( override val matcherName: String = "NEC" override suspend fun match( - probe: FingerprintIdentity, - candidates: List, + probe: List, + candidates: List, settings: NecMatchingSettings?, - ): List { + ): List { // if probe template format is not supported by NEC matcher, return empty list if (probe.templateFormatNotSupportedByNecMatcher()) { return emptyList() @@ -34,8 +35,8 @@ internal class FingerprintMatcherImpl @Inject constructor( } private fun sameFingerMatching( - probe: FingerprintIdentity, - candidates: List, + probe: List, + candidates: List, ) = candidates.map { sameFingerMatching(probe, it) } @@ -51,22 +52,22 @@ internal class FingerprintMatcherImpl @Inject constructor( * @return MatchResult */ private fun sameFingerMatching( - probe: FingerprintIdentity, - candidate: FingerprintIdentity, - ): MatchResult { + probe: List, + candidate: Identity, + ): MatchComparisonResult { var fingers = 0 // the number of fingers used in matching - val total = probe.fingerprints.sumOf { fingerprint -> - candidate.templateForFinger(fingerprint.fingerId)?.let { candidateTemplate -> + val total = probe.sumOf { fingerprint -> + candidate.templateForFinger(fingerprint.identifier)?.let { candidateTemplate -> fingers++ verify(fingerprint, candidateTemplate) } ?: 0.toDouble() } - return MatchResult(candidate.subjectId, getOverallScore(total, fingers)) + return MatchComparisonResult(candidate.subjectId, getOverallScore(total, fingers)) } private fun verify( - probe: Fingerprint, - candidate: Fingerprint, + probe: CaptureSample, + candidate: Sample, ) = try { nec .match( @@ -78,29 +79,31 @@ internal class FingerprintMatcherImpl @Inject constructor( } private fun crossFingerMatching( - probe: FingerprintIdentity, - candidates: List, + probe: List, + candidates: List, ) = candidates.map { crossFingerMatching(probe, it) } private fun crossFingerMatching( - probe: FingerprintIdentity, - candidate: FingerprintIdentity, - ): MatchResult { + probe: List, + candidate: Identity, + ): MatchComparisonResult { // Number of fingers used in matching - val fingers = probe.fingerprints.size + val fingers = probe.size // Sum of maximum matching score for each finger - val total = probe.fingerprints.sumOf { probeTemplate -> - candidate.fingerprints.maxOf { candidateTemplate -> + val total = probe.sumOf { probeTemplate -> + candidate.samples.maxOf { candidateTemplate -> verify(probeTemplate, candidateTemplate) } } // Matching score = total/number of fingers - return MatchResult(candidate.subjectId, getOverallScore(total, fingers)) + return MatchComparisonResult(candidate.subjectId, getOverallScore(total, fingers)) } - private fun FingerprintIdentity.templateForFinger(fingerId: FingerIdentifier) = fingerprints.find { it.fingerId == fingerId } + private fun Identity.templateForFinger(fingerId: SampleIdentifier) = samples.find { it.identifier == fingerId } - private fun Fingerprint.toNecTemplate() = NECTemplate(template, 0) // Quality score not used + private fun CaptureSample.toNecTemplate() = NECTemplate(template, 0) // Quality score not used + + private fun Sample.toNecTemplate() = NECTemplate(template, 0) // Quality score not used private fun getOverallScore( total: Double, @@ -112,4 +115,4 @@ internal class FingerprintMatcherImpl @Inject constructor( } } -private fun FingerprintIdentity.templateFormatNotSupportedByNecMatcher(): Boolean = fingerprints.any { it.format != NEC_TEMPLATE_FORMAT } +private fun List.templateFormatNotSupportedByNecMatcher(): Boolean = any { it.format != NEC_TEMPLATE_FORMAT } diff --git a/fingerprint/infra/nec-bio-sdk/src/test/java/com/simprints/fingerprint/infra/necsdkimpl/matching/FingerprintMatcherImplTest.kt b/fingerprint/infra/nec-bio-sdk/src/test/java/com/simprints/fingerprint/infra/necsdkimpl/matching/FingerprintMatcherImplTest.kt index 0f4e648aea..4f79c54341 100644 --- a/fingerprint/infra/nec-bio-sdk/src/test/java/com/simprints/fingerprint/infra/necsdkimpl/matching/FingerprintMatcherImplTest.kt +++ b/fingerprint/infra/nec-bio-sdk/src/test/java/com/simprints/fingerprint/infra/necsdkimpl/matching/FingerprintMatcherImplTest.kt @@ -1,14 +1,15 @@ package com.simprints.fingerprint.infra.necsdkimpl.matching -import com.google.common.truth.Truth +import com.google.common.truth.* +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.fingerprint.infra.basebiosdk.exceptions.BioSdkException -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.Fingerprint -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity import com.simprints.fingerprint.infra.necsdkimpl.acquisition.template.NEC_TEMPLATE_FORMAT import com.simprints.necwrapper.nec.NEC -import io.mockk.MockKAnnotations -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK import kotlinx.coroutines.test.runTest import org.junit.Before @@ -30,73 +31,56 @@ class FingerprintMatcherImplTest { fun `test match FingerprintIdentities with the same fingerprint IDs`() = runTest { // Given every { nec.match(any(), any(), any()) } returns 3 - val probe = - generatePersonIdentity(FingerIdentifier.LEFT_THUMB, FingerIdentifier.RIGHT_THUMB) - val candidates = - listOf( - generatePersonIdentity(FingerIdentifier.LEFT_THUMB, FingerIdentifier.RIGHT_THUMB), - generatePersonIdentity(FingerIdentifier.LEFT_THUMB, FingerIdentifier.RIGHT_THUMB), - generatePersonIdentity(FingerIdentifier.LEFT_THUMB, FingerIdentifier.RIGHT_THUMB), - ) + val probe = generateProbe(SampleIdentifier.LEFT_THUMB, SampleIdentifier.RIGHT_THUMB) + val candidates = listOf( + generateIdentity(SampleIdentifier.LEFT_THUMB, SampleIdentifier.RIGHT_THUMB), + generateIdentity(SampleIdentifier.LEFT_THUMB, SampleIdentifier.RIGHT_THUMB), + generateIdentity(SampleIdentifier.LEFT_THUMB, SampleIdentifier.RIGHT_THUMB), + ) // When val result = matcher.match(probe, candidates, NecMatchingSettings(false)) // Then Truth.assertThat(result.size).isEqualTo(3) - Truth.assertThat(result[0].score).isEqualTo(3) + Truth.assertThat(result[0].confidence).isEqualTo(3) } @Test fun `test match FingerprintIdentities with different fingerprint IDs`() = runTest { // Given every { nec.match(any(), any(), any()) } returns 3 - val probe = - generatePersonIdentity( - FingerIdentifier.LEFT_INDEX_FINGER, - FingerIdentifier.RIGHT_INDEX_FINGER, - ) - val candidate = - generatePersonIdentity(FingerIdentifier.LEFT_THUMB, FingerIdentifier.RIGHT_THUMB) + val probe = generateProbe(SampleIdentifier.LEFT_INDEX_FINGER, SampleIdentifier.RIGHT_INDEX_FINGER) + val candidate = generateIdentity(SampleIdentifier.LEFT_THUMB, SampleIdentifier.RIGHT_THUMB) // When val result = matcher.match(probe, listOf(candidate), NecMatchingSettings(false)) // Then Truth.assertThat(result.size).isEqualTo(1) - Truth.assertThat(result[0].score).isEqualTo(0) + Truth.assertThat(result[0].confidence).isEqualTo(0) } @Test fun `test match FingerprintIdentities with different fingerprint IDs and crossFingerComparison`() = runTest { // Given every { nec.match(any(), any(), any()) } returns 3 - val probe = - generatePersonIdentity( - FingerIdentifier.LEFT_INDEX_FINGER, - FingerIdentifier.RIGHT_INDEX_FINGER, - ) - val candidate = - generatePersonIdentity(FingerIdentifier.LEFT_THUMB, FingerIdentifier.RIGHT_THUMB) + val probe = generateProbe(SampleIdentifier.LEFT_INDEX_FINGER, SampleIdentifier.RIGHT_INDEX_FINGER) + val candidate = generateIdentity(SampleIdentifier.LEFT_THUMB, SampleIdentifier.RIGHT_THUMB) // When val result = matcher.match(probe, listOf(candidate), NecMatchingSettings(true)) // Then Truth.assertThat(result.size).isEqualTo(1) - Truth.assertThat(result[0].score).isEqualTo(3) + Truth.assertThat(result[0].confidence).isEqualTo(3) } @Test fun `test match FingerprintIdentities with only one equal fingerprint IDs`() = runTest { // Given every { nec.match(any(), any(), any()) } returns 3 - val probe = - generatePersonIdentity( - FingerIdentifier.LEFT_INDEX_FINGER, - FingerIdentifier.RIGHT_INDEX_FINGER, - ) - val candidate = - generatePersonIdentity(FingerIdentifier.LEFT_INDEX_FINGER, FingerIdentifier.RIGHT_THUMB) + val probe = generateProbe(SampleIdentifier.LEFT_INDEX_FINGER, SampleIdentifier.RIGHT_INDEX_FINGER) + val candidate = generateIdentity(SampleIdentifier.LEFT_INDEX_FINGER, SampleIdentifier.RIGHT_THUMB) // When val result = matcher.match(probe, listOf(candidate), NecMatchingSettings(false)) // Then Truth.assertThat(result.size).isEqualTo(1) - Truth.assertThat(result[0].score).isEqualTo(3) + Truth.assertThat(result[0].confidence).isEqualTo(3) } @Test(expected = BioSdkException.TemplateMatchingException::class) @@ -105,13 +89,11 @@ class FingerprintMatcherImplTest { every { nec.match(any(), any(), any()) } throws NEC.AttemptedToRunBeforeInitializedException() - val probe = - generatePersonIdentity( - FingerIdentifier.LEFT_INDEX_FINGER, - FingerIdentifier.RIGHT_INDEX_FINGER, - ) - val candidate = - generatePersonIdentity(FingerIdentifier.LEFT_INDEX_FINGER, FingerIdentifier.RIGHT_THUMB) + val probe = generateProbe( + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.RIGHT_INDEX_FINGER, + ) + val candidate = generateIdentity(SampleIdentifier.LEFT_INDEX_FINGER, SampleIdentifier.RIGHT_THUMB) // When matcher.match(probe, listOf(candidate), NecMatchingSettings(false)) } @@ -120,26 +102,45 @@ class FingerprintMatcherImplTest { fun `test match FingerprintIdentities probe with different template format`() = runTest { // Given val probe = - generatePersonIdentity( - FingerIdentifier.LEFT_INDEX_FINGER, - FingerIdentifier.RIGHT_INDEX_FINGER, + generateProbe( + SampleIdentifier.LEFT_INDEX_FINGER, + SampleIdentifier.RIGHT_INDEX_FINGER, format = "Unsupported", ) val candidate = - generatePersonIdentity(FingerIdentifier.LEFT_THUMB, FingerIdentifier.RIGHT_THUMB) + generateIdentity(SampleIdentifier.LEFT_THUMB, SampleIdentifier.RIGHT_THUMB) // When val result = matcher.match(probe, listOf(candidate), NecMatchingSettings(false)) // Then Truth.assertThat(result.size).isEqualTo(0) } - private fun generatePersonIdentity( - vararg fingers: FingerIdentifier, + private fun generateProbe( + vararg fingers: SampleIdentifier, format: String = NEC_TEMPLATE_FORMAT, - ) = FingerprintIdentity( - "ID", - fingers.map { - Fingerprint(it, ByteArray(0), format) + ) = fingers.map { + CaptureSample( + captureEventId = it.name, + identifier = it, + modality = Modality.FINGERPRINT, + format = format, + template = ByteArray(0), + ) + } + + private fun generateIdentity( + vararg fingers: SampleIdentifier, + format: String = NEC_TEMPLATE_FORMAT, + ) = Identity( + subjectId = "id", + samples = fingers.map { + Sample( + referenceId = it.name, + identifier = it, + modality = Modality.FINGERPRINT, + format = format, + template = ByteArray(0), + ) }, ) } diff --git a/fingerprint/infra/simprints-bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdkimpl/matching/FingerprintMatcherImpl.kt b/fingerprint/infra/simprints-bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdkimpl/matching/FingerprintMatcherImpl.kt index d14498e19d..67ee2a925b 100644 --- a/fingerprint/infra/simprints-bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdkimpl/matching/FingerprintMatcherImpl.kt +++ b/fingerprint/infra/simprints-bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdkimpl/matching/FingerprintMatcherImpl.kt @@ -1,8 +1,9 @@ package com.simprints.fingerprint.infra.biosdkimpl.matching +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.fingerprint.infra.basebiosdk.matching.FingerprintMatcher -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.MatchResult import com.simprints.fingerprint.infra.biosdkimpl.matching.SimAfisMatcher.Companion.SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT import javax.inject.Inject @@ -13,8 +14,8 @@ internal class FingerprintMatcherImpl @Inject constructor( override val matcherName: String = "SIM_AFIS" override suspend fun match( - probe: FingerprintIdentity, - candidates: List, + probe: List, + candidates: List, settings: SimAfisMatcherSettings?, - ): List = simAfisMatcher.match(probe, candidates, settings?.crossFingerComparison ?: false) + ): List = simAfisMatcher.match(probe, candidates, settings?.crossFingerComparison ?: false) } diff --git a/fingerprint/infra/simprints-bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdkimpl/matching/SimAfisMatcher.kt b/fingerprint/infra/simprints-bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdkimpl/matching/SimAfisMatcher.kt index bd067642ed..50264ac57e 100644 --- a/fingerprint/infra/simprints-bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdkimpl/matching/SimAfisMatcher.kt +++ b/fingerprint/infra/simprints-bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdkimpl/matching/SimAfisMatcher.kt @@ -1,20 +1,11 @@ package com.simprints.fingerprint.infra.biosdkimpl.matching import com.simprints.core.ExcludedFromGeneratedTestCoverageReports -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier.LEFT_3RD_FINGER -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier.LEFT_4TH_FINGER -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier.LEFT_5TH_FINGER -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier.LEFT_INDEX_FINGER -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier.LEFT_THUMB -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier.RIGHT_3RD_FINGER -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier.RIGHT_4TH_FINGER -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier.RIGHT_5TH_FINGER -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier.RIGHT_INDEX_FINGER -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier.RIGHT_THUMB -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.Fingerprint -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.MatchResult +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.MatchComparisonResult +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.fingerprint.infra.simafiswrapper.JNILibAfisInterface import com.simprints.fingerprint.infra.simafiswrapper.models.SimAfisFingerIdentifier import com.simprints.fingerprint.infra.simafiswrapper.models.SimAfisFingerprint @@ -35,10 +26,10 @@ internal class SimAfisMatcher @Inject constructor( private val jniLibAfis: JNILibAfisInterface, ) { fun match( - probe: FingerprintIdentity, - candidates: List, + probe: List, + candidates: List, crossFingerComparison: Boolean, - ): List { + ): List { // if probe template format is not supported by SimAfisMatcher, return empty list if (probe.templateFormatNotSupportedBySimAfisMatcher()) { return emptyList() @@ -51,9 +42,9 @@ internal class SimAfisMatcher @Inject constructor( } private fun match( - probe: FingerprintIdentity, - candidates: List, - ): List { + probe: List, + candidates: List, + ): List { val simAfisCandidates = candidates.map { it.toSimAfisPerson() } println("Matching ${simAfisCandidates.size} candidates using all ${jniLibAfis.getNbCores()} cores") @@ -65,32 +56,37 @@ internal class SimAfisMatcher @Inject constructor( ) return results.zip(simAfisCandidates).map { (score, candidate) -> - MatchResult(candidate.guid, score) + MatchComparisonResult(candidate.guid, score) } } - private fun FingerprintIdentity.toSimAfisPerson(): SimAfisPerson = - SimAfisPerson(subjectId, fingerprints.map { it.toSimAfisFingerprint() }) + private fun Identity.toSimAfisPerson(): SimAfisPerson = SimAfisPerson(subjectId, samples.map { it.toSimAfisFingerprint() }) - private fun Fingerprint.toSimAfisFingerprint(): SimAfisFingerprint = SimAfisFingerprint(fingerId.toSimAfisFingerIdentifier(), template) + private fun Sample.toSimAfisFingerprint(): SimAfisFingerprint = SimAfisFingerprint(identifier.toSimAfisFingerIdentifier(), template) + + private fun List.toSimAfisPerson(): SimAfisPerson = SimAfisPerson("", map { it.toSimAfisFingerprint() }) + + private fun CaptureSample.toSimAfisFingerprint(): SimAfisFingerprint = + SimAfisFingerprint(identifier.toSimAfisFingerIdentifier(), template) @ExcludedFromGeneratedTestCoverageReports(reason = "This is just a mapping function") - private fun FingerIdentifier.toSimAfisFingerIdentifier(): SimAfisFingerIdentifier = when (this) { - RIGHT_5TH_FINGER -> SimAfisFingerIdentifier.RIGHT_5TH_FINGER - RIGHT_4TH_FINGER -> SimAfisFingerIdentifier.RIGHT_4TH_FINGER - RIGHT_3RD_FINGER -> SimAfisFingerIdentifier.RIGHT_3RD_FINGER - RIGHT_INDEX_FINGER -> SimAfisFingerIdentifier.RIGHT_INDEX_FINGER - RIGHT_THUMB -> SimAfisFingerIdentifier.RIGHT_THUMB - LEFT_THUMB -> SimAfisFingerIdentifier.LEFT_THUMB - LEFT_INDEX_FINGER -> SimAfisFingerIdentifier.LEFT_INDEX_FINGER - LEFT_3RD_FINGER -> SimAfisFingerIdentifier.LEFT_3RD_FINGER - LEFT_4TH_FINGER -> SimAfisFingerIdentifier.LEFT_4TH_FINGER - LEFT_5TH_FINGER -> SimAfisFingerIdentifier.LEFT_5TH_FINGER + private fun SampleIdentifier.toSimAfisFingerIdentifier(): SimAfisFingerIdentifier = when (this) { + SampleIdentifier.RIGHT_5TH_FINGER -> SimAfisFingerIdentifier.RIGHT_5TH_FINGER + SampleIdentifier.RIGHT_4TH_FINGER -> SimAfisFingerIdentifier.RIGHT_4TH_FINGER + SampleIdentifier.RIGHT_3RD_FINGER -> SimAfisFingerIdentifier.RIGHT_3RD_FINGER + SampleIdentifier.RIGHT_INDEX_FINGER -> SimAfisFingerIdentifier.RIGHT_INDEX_FINGER + SampleIdentifier.RIGHT_THUMB -> SimAfisFingerIdentifier.RIGHT_THUMB + SampleIdentifier.LEFT_THUMB -> SimAfisFingerIdentifier.LEFT_THUMB + SampleIdentifier.LEFT_INDEX_FINGER -> SimAfisFingerIdentifier.LEFT_INDEX_FINGER + SampleIdentifier.LEFT_3RD_FINGER -> SimAfisFingerIdentifier.LEFT_3RD_FINGER + SampleIdentifier.LEFT_4TH_FINGER -> SimAfisFingerIdentifier.LEFT_4TH_FINGER + SampleIdentifier.LEFT_5TH_FINGER -> SimAfisFingerIdentifier.LEFT_5TH_FINGER + SampleIdentifier.NONE -> throw IllegalArgumentException("Must be a finger sample identifier") } private fun crossFingerMatch( - probe: FingerprintIdentity, - candidates: List, + probe: List, + candidates: List, ) = candidates.map { crossFingerMatching(probe, it, jniLibAfis) } /** @@ -102,10 +98,10 @@ internal class SimAfisMatcher @Inject constructor( * @return MatchResult */ private fun crossFingerMatching( - probe: FingerprintIdentity, - candidate: FingerprintIdentity, + probe: List, + candidate: Identity, jniLibAfis: JNILibAfisInterface, - ): MatchResult { + ): MatchComparisonResult { // Number of fingers used in matching val fingers = probe.fingerprintsTemplates.size // Sum of maximum matching score for each finger @@ -120,7 +116,7 @@ internal class SimAfisMatcher @Inject constructor( }.toDouble() } // Matching score = total/number of fingers - return MatchResult(candidate.subjectId, getOverallScore(total, fingers)) + return MatchComparisonResult(candidate.subjectId, getOverallScore(total, fingers)) } private fun getOverallScore( @@ -137,10 +133,13 @@ internal class SimAfisMatcher @Inject constructor( } } -val FingerprintIdentity.fingerprintsTemplates - get() = fingerprints.map { it.template.toByteBuffer() } +val List.fingerprintsTemplates + get() = map { it.template.toByteBuffer() } + +val Identity.fingerprintsTemplates + get() = samples.map { it.template.toByteBuffer() } private fun ByteArray.toByteBuffer(): ByteBuffer = ByteBuffer.allocateDirect(size).put(this) -fun FingerprintIdentity.templateFormatNotSupportedBySimAfisMatcher(): Boolean = - fingerprints.any { it.format != SimAfisMatcher.SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT } +fun List.templateFormatNotSupportedBySimAfisMatcher(): Boolean = + any { it.format != SimAfisMatcher.SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT } diff --git a/fingerprint/infra/simprints-bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdkimpl/matching/FingerprintMatcherImplTest.kt b/fingerprint/infra/simprints-bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdkimpl/matching/FingerprintMatcherImplTest.kt index 8ec84b7040..6513abc896 100644 --- a/fingerprint/infra/simprints-bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdkimpl/matching/FingerprintMatcherImplTest.kt +++ b/fingerprint/infra/simprints-bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdkimpl/matching/FingerprintMatcherImplTest.kt @@ -1,10 +1,10 @@ package com.simprints.fingerprint.infra.biosdkimpl.matching -import com.google.common.truth.Truth -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.MatchResult -import io.mockk.every -import io.mockk.mockk +import com.google.common.truth.* +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.MatchComparisonResult +import io.mockk.* import kotlinx.coroutines.test.runTest import org.junit.Test @@ -15,11 +15,11 @@ class FingerprintMatcherImplTest { fun match() = runTest { // Given val matcher = FingerprintMatcherImpl(simAfisMatcher) - val probe: FingerprintIdentity = mockk() - val candidates: List = mockk() + val probe = listOf(mockk()) + val candidates: List = mockk() val simAfisMatcherSettings = SimAfisMatcherSettings() simAfisMatcherSettings.crossFingerComparison = false - val matchResult: List = mockk() + val matchResult: List = mockk() every { simAfisMatcher.match(probe, candidates, false) } returns matchResult diff --git a/fingerprint/infra/simprints-bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdkimpl/matching/SimAfisMatcherTest.kt b/fingerprint/infra/simprints-bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdkimpl/matching/SimAfisMatcherTest.kt index 011d0a440b..6469c01377 100644 --- a/fingerprint/infra/simprints-bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdkimpl/matching/SimAfisMatcherTest.kt +++ b/fingerprint/infra/simprints-bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdkimpl/matching/SimAfisMatcherTest.kt @@ -1,16 +1,15 @@ package com.simprints.fingerprint.infra.biosdkimpl.matching -import com.google.common.truth.Truth.assertThat -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.Fingerprint -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier +import com.simprints.fingerprint.infra.scanner.v2.tools.primitives.byteArrayOf import com.simprints.fingerprint.infra.simafiswrapper.JNILibAfisInterface -import io.mockk.MockKAnnotations -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK -import io.mockk.mockk -import io.mockk.mockkStatic -import io.mockk.verify import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -32,66 +31,129 @@ class SimAfisMatcherTest { @Test fun `test same finger match`() = runTest { every { jniLibAfis.identify(any(), any(), 1) } returns floatArrayOf(1F) - val candidate = FingerprintIdentity( + + val probes = listOf( + CaptureSample( + captureEventId = "referenceId", + identifier = SampleIdentifier.RIGHT_THUMB, + template = IsoFingerprintTemplateGenerator.generate(1), + format = SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT, + modality = Modality.FINGERPRINT, + ), + ) + val candidate = Identity( "candidate", listOf( - Fingerprint( - FingerIdentifier.RIGHT_THUMB, - IsoFingerprintTemplateGenerator.generate(1), - SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT, + Sample( + referenceId = "referenceId", + identifier = SampleIdentifier.RIGHT_THUMB, + template = IsoFingerprintTemplateGenerator.generate(1), + format = SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT, + modality = Modality.FINGERPRINT, ), ), ) // When - val result = simAfisMatcher.match(candidate, listOf(candidate), false).last() + val result = simAfisMatcher.match(probes, listOf(candidate), false).last() // Then verify { jniLibAfis.identify(any(), any(), any()) } - assertThat(result.score).isEqualTo(1) + assertThat(result.confidence).isEqualTo(1) } @Test fun `test matching probe with other template format ignore candidate`() = runTest { every { jniLibAfis.identify(any(), any(), 1) } returns floatArrayOf(1F) - val candidate = FingerprintIdentity( + val probes = listOf( + CaptureSample( + captureEventId = "referenceId", + identifier = SampleIdentifier.RIGHT_3RD_FINGER, + template = IsoFingerprintTemplateGenerator.generate(1), + format = "NEC_1", + modality = Modality.FINGERPRINT, + ), + ) + val candidate = Identity( "candidate", listOf( - Fingerprint( - FingerIdentifier.RIGHT_3RD_FINGER, - IsoFingerprintTemplateGenerator.generate(1), - "NEC_1", + Sample( + referenceId = "referenceId", + identifier = SampleIdentifier.RIGHT_3RD_FINGER, + template = IsoFingerprintTemplateGenerator.generate(1), + format = "NEC_1", + modality = Modality.FINGERPRINT, ), ), ) // When - val result = simAfisMatcher.match(candidate, listOf(candidate), false) + val result = simAfisMatcher.match(probes, listOf(candidate), false) // Then assertThat(result).isEmpty() } @Test fun `test cross finger match`() = runTest { - mockkStatic("com.simprints.fingerprint.infra.biosdkimpl.matching.SimAfisMatcherKt") - val template1 = mockk() - val template2 = mockk() - val template3 = mockk() + val template1 = byteArrayOf(1) + val template2 = byteArrayOf(2) + val template3 = byteArrayOf(3) - val probe = mockk { - every { templateFormatNotSupportedBySimAfisMatcher() } returns false - every { fingerprintsTemplates } returns listOf(template1, template2) - } - val candidate1 = mockk { - every { subjectId } returns "candidate1" - every { templateFormatNotSupportedBySimAfisMatcher() } returns false - every { fingerprintsTemplates } returns listOf(template2, template1) - } - val candidate2 = mockk { - every { subjectId } returns "candidate2" - every { templateFormatNotSupportedBySimAfisMatcher() } returns false - every { fingerprintsTemplates } returns listOf(template3, template1) - } + val probe = listOf( + CaptureSample( + captureEventId = "referenceId", + identifier = SampleIdentifier.RIGHT_THUMB, + template = template1, + format = SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT, + modality = Modality.FINGERPRINT, + ), + CaptureSample( + captureEventId = "referenceId", + identifier = SampleIdentifier.LEFT_THUMB, + template = template2, + format = SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT, + modality = Modality.FINGERPRINT, + ), + ) + + val candidate1 = Identity( + subjectId = "candidate1", + samples = listOf( + Sample( + referenceId = "referenceId", + identifier = SampleIdentifier.LEFT_4TH_FINGER, + template = template2, + format = SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT, + modality = Modality.FINGERPRINT, + ), + Sample( + referenceId = "referenceId", + identifier = SampleIdentifier.LEFT_5TH_FINGER, + template = template1, + format = SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT, + modality = Modality.FINGERPRINT, + ), + ), + ) + val candidate2 = Identity( + subjectId = "candidate2", + samples = listOf( + Sample( + referenceId = "referenceId", + identifier = SampleIdentifier.RIGHT_3RD_FINGER, + template = template3, + format = SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT, + modality = Modality.FINGERPRINT, + ), + Sample( + referenceId = "referenceId", + identifier = SampleIdentifier.RIGHT_5TH_FINGER, + template = template1, + format = SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT, + modality = Modality.FINGERPRINT, + ), + ), + ) every { jniLibAfis.verify(any(), any()) } answers { - if (firstArg() === secondArg()) 1F else 0F + if (firstArg().get(0) == secondArg().get(0)) 1F else 0F } // When val matchingResult = simAfisMatcher.match( @@ -99,8 +161,8 @@ class SimAfisMatcherTest { listOf(candidate1, candidate2), true, ) - val maxScore = matchingResult.maxOf { it.score } - val minScore = matchingResult.minOf { it.score } + val maxScore = matchingResult.maxOf { it.confidence } + val minScore = matchingResult.minOf { it.confidence } // Then verify(exactly = 8) { jniLibAfis.verify(any(), any()) } assertThat(maxScore).isEqualTo(1) @@ -111,27 +173,32 @@ class SimAfisMatcherTest { fun `test crossFingerMatching zero fingers success`() { // Given every { jniLibAfis.verify(any(), any()) } returns 1F - val probe = FingerprintIdentity("probe", listOf()) - val candidate = FingerprintIdentity( + val probes = listOf() + val candidate = Identity( "candidate", listOf( - Fingerprint( - FingerIdentifier.LEFT_THUMB, - IsoFingerprintTemplateGenerator.generate(1), - SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT, + Sample( + referenceId = "referenceId", + identifier = SampleIdentifier.LEFT_THUMB, + template = IsoFingerprintTemplateGenerator.generate(1), + format = SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT, + modality = Modality.FINGERPRINT, ), - Fingerprint( - FingerIdentifier.LEFT_3RD_FINGER, - IsoFingerprintTemplateGenerator.generate(1), - SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT, + Sample( + referenceId = "referenceId", + identifier = SampleIdentifier.LEFT_3RD_FINGER, + template = IsoFingerprintTemplateGenerator.generate(1), + format = SIMAFIS_MATCHER_SUPPORTED_TEMPLATE_FORMAT, + modality = Modality.FINGERPRINT, ), ), ) + // When - val result = simAfisMatcher.match(probe, listOf(candidate), true) + val result = simAfisMatcher.match(probes, listOf(candidate), true) // Then verify(exactly = 0) { jniLibAfis.verify(any(), any()) } - assertThat(result[0].score).isEqualTo(0) + assertThat(result[0].confidence).isEqualTo(0) } companion object { 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 c8ebca0873..9c64dc6380 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 @@ -1,6 +1,8 @@ package com.simprints.infra.config.store.local import androidx.datastore.core.DataStore +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.tools.utils.LanguageHelper import com.simprints.infra.config.store.AbsolutePath @@ -14,7 +16,6 @@ import com.simprints.infra.config.store.models.DecisionPolicy import com.simprints.infra.config.store.models.DeviceConfiguration import com.simprints.infra.config.store.models.DownSynchronizationConfiguration import com.simprints.infra.config.store.models.DownSynchronizationConfiguration.Companion.DEFAULT_DOWN_SYNC_MAX_AGE -import com.simprints.infra.config.store.models.Finger import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.Frequency import com.simprints.infra.config.store.models.GeneralConfiguration @@ -75,17 +76,15 @@ internal class ConfigLocalDataSourceImpl @Inject constructor( override suspend fun getProjectConfiguration(): ProjectConfiguration = configDataStore.data.first().toDomain() - override fun observeProjectConfiguration(): Flow = - configDataStore.data.map(ProtoProjectConfiguration::toDomain) + override fun observeProjectConfiguration(): Flow = configDataStore.data.map(ProtoProjectConfiguration::toDomain) override suspend fun clearProjectConfiguration() { configDataStore.updateData { it.toBuilder().clear().build() } } - override suspend fun getDeviceConfiguration(): DeviceConfiguration = - deviceConfigDataStore.data.first().toDomain().apply { - selectedModules = selectedModules.mapToTokenizedModuleIds() - } + override suspend fun getDeviceConfiguration(): DeviceConfiguration = deviceConfigDataStore.data.first().toDomain().apply { + selectedModules = selectedModules.mapToTokenizedModuleIds() + } override fun observeDeviceConfiguration(): Flow = deviceConfigDataStore.data.map(ProtoDeviceConfiguration::toDomain).map { config -> @@ -171,8 +170,8 @@ internal class ConfigLocalDataSourceImpl @Inject constructor( projectId = "", updatedAt = "", general = GeneralConfiguration( - modalities = listOf(GeneralConfiguration.Modality.FINGERPRINT), - matchingModalities = listOf(GeneralConfiguration.Modality.FINGERPRINT), + modalities = listOf(Modality.FINGERPRINT), + matchingModalities = listOf(Modality.FINGERPRINT), languageOptions = listOf(), defaultLanguage = "en", collectLocation = true, @@ -186,8 +185,8 @@ internal class ConfigLocalDataSourceImpl @Inject constructor( allowedSDKs = listOf(FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER), secugenSimMatcher = FingerprintConfiguration.FingerprintSdkConfiguration( fingersToCapture = listOf( - Finger.LEFT_THUMB, - Finger.LEFT_INDEX_FINGER, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_INDEX_FINGER, ), decisionPolicy = DecisionPolicy( 0, 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 f167ff0c7e..3b4fa1bb21 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 @@ -2,13 +2,14 @@ package com.simprints.infra.config.store.local.migrations.models import androidx.annotation.Keep import com.fasterxml.jackson.annotation.JsonProperty +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.core.tools.json.JsonHelper import com.simprints.infra.config.store.models.ConsentConfiguration import com.simprints.infra.config.store.models.DecisionPolicy import com.simprints.infra.config.store.models.DownSynchronizationConfiguration import com.simprints.infra.config.store.models.FaceConfiguration -import com.simprints.infra.config.store.models.Finger import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.Frequency import com.simprints.infra.config.store.models.GeneralConfiguration @@ -83,11 +84,7 @@ internal data class OldProjectConfig( val modalities = modality .split(",") .map { if (it == "FINGER") "FINGERPRINT" else it } - .map { - GeneralConfiguration.Modality.valueOf( - it, - ) - } + .map { Modality.valueOf(it) } return GeneralConfiguration( modalities = modalities, matchingModalities = modalities, @@ -138,10 +135,10 @@ internal data class OldProjectConfig( secugenSimMatcher = FingerprintConfiguration.FingerprintSdkConfiguration( fingersToCapture = fingerprintsToCollect ?.split(",") - ?.map { Finger.valueOf(it) } + ?.map { SampleIdentifier.valueOf(it) } ?: listOf( - Finger.LEFT_THUMB, - Finger.LEFT_INDEX_FINGER, + SampleIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_INDEX_FINGER, ), decisionPolicy = fingerprintConfidenceThresholds?.let { parseDecisionPolicy(it) } ?: DecisionPolicy(0, 0, 700), diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/Finger.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/Finger.kt index ac1c24d005..ba7f9311aa 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/Finger.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/Finger.kt @@ -1,31 +1,31 @@ package com.simprints.infra.config.store.local.models -import com.simprints.infra.config.store.exceptions.InvalidProtobufEnumException -import com.simprints.infra.config.store.models.Finger +import com.simprints.core.domain.sample.SampleIdentifier -internal fun Finger.toProto(): ProtoFinger = when (this) { - Finger.LEFT_THUMB -> ProtoFinger.LEFT_THUMB - Finger.LEFT_INDEX_FINGER -> ProtoFinger.LEFT_INDEX_FINGER - Finger.LEFT_3RD_FINGER -> ProtoFinger.LEFT_3RD_FINGER - Finger.LEFT_4TH_FINGER -> ProtoFinger.LEFT_4TH_FINGER - Finger.LEFT_5TH_FINGER -> ProtoFinger.LEFT_5TH_FINGER - Finger.RIGHT_THUMB -> ProtoFinger.RIGHT_THUMB - Finger.RIGHT_INDEX_FINGER -> ProtoFinger.RIGHT_INDEX_FINGER - Finger.RIGHT_3RD_FINGER -> ProtoFinger.RIGHT_3RD_FINGER - Finger.RIGHT_4TH_FINGER -> ProtoFinger.RIGHT_4TH_FINGER - Finger.RIGHT_5TH_FINGER -> ProtoFinger.RIGHT_5TH_FINGER +internal fun SampleIdentifier.toProtoFinger(): ProtoFinger = when (this) { + SampleIdentifier.LEFT_THUMB -> ProtoFinger.LEFT_THUMB + SampleIdentifier.LEFT_INDEX_FINGER -> ProtoFinger.LEFT_INDEX_FINGER + SampleIdentifier.LEFT_3RD_FINGER -> ProtoFinger.LEFT_3RD_FINGER + SampleIdentifier.LEFT_4TH_FINGER -> ProtoFinger.LEFT_4TH_FINGER + SampleIdentifier.LEFT_5TH_FINGER -> ProtoFinger.LEFT_5TH_FINGER + SampleIdentifier.RIGHT_THUMB -> ProtoFinger.RIGHT_THUMB + SampleIdentifier.RIGHT_INDEX_FINGER -> ProtoFinger.RIGHT_INDEX_FINGER + SampleIdentifier.RIGHT_3RD_FINGER -> ProtoFinger.RIGHT_3RD_FINGER + SampleIdentifier.RIGHT_4TH_FINGER -> ProtoFinger.RIGHT_4TH_FINGER + SampleIdentifier.RIGHT_5TH_FINGER -> ProtoFinger.RIGHT_5TH_FINGER + else -> ProtoFinger.UNRECOGNIZED } -internal fun ProtoFinger.toDomain(): Finger = when (this) { - ProtoFinger.LEFT_THUMB -> Finger.LEFT_THUMB - ProtoFinger.LEFT_INDEX_FINGER -> Finger.LEFT_INDEX_FINGER - ProtoFinger.LEFT_3RD_FINGER -> Finger.LEFT_3RD_FINGER - ProtoFinger.LEFT_4TH_FINGER -> Finger.LEFT_4TH_FINGER - ProtoFinger.LEFT_5TH_FINGER -> Finger.LEFT_5TH_FINGER - ProtoFinger.RIGHT_THUMB -> Finger.RIGHT_THUMB - ProtoFinger.RIGHT_INDEX_FINGER -> Finger.RIGHT_INDEX_FINGER - ProtoFinger.RIGHT_3RD_FINGER -> Finger.RIGHT_3RD_FINGER - ProtoFinger.RIGHT_4TH_FINGER -> Finger.RIGHT_4TH_FINGER - ProtoFinger.RIGHT_5TH_FINGER -> Finger.RIGHT_5TH_FINGER - ProtoFinger.UNRECOGNIZED -> throw InvalidProtobufEnumException("invalid Finger $name") +internal fun ProtoFinger.toDomain(): SampleIdentifier = when (this) { + ProtoFinger.UNRECOGNIZED -> SampleIdentifier.NONE + ProtoFinger.LEFT_THUMB -> SampleIdentifier.LEFT_THUMB + ProtoFinger.LEFT_INDEX_FINGER -> SampleIdentifier.LEFT_INDEX_FINGER + ProtoFinger.LEFT_3RD_FINGER -> SampleIdentifier.LEFT_3RD_FINGER + ProtoFinger.LEFT_4TH_FINGER -> SampleIdentifier.LEFT_4TH_FINGER + ProtoFinger.LEFT_5TH_FINGER -> SampleIdentifier.LEFT_5TH_FINGER + ProtoFinger.RIGHT_THUMB -> SampleIdentifier.RIGHT_THUMB + ProtoFinger.RIGHT_INDEX_FINGER -> SampleIdentifier.RIGHT_INDEX_FINGER + ProtoFinger.RIGHT_3RD_FINGER -> SampleIdentifier.RIGHT_3RD_FINGER + ProtoFinger.RIGHT_4TH_FINGER -> SampleIdentifier.RIGHT_4TH_FINGER + ProtoFinger.RIGHT_5TH_FINGER -> SampleIdentifier.RIGHT_5TH_FINGER } 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 58af439c66..b6abb13e81 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 @@ -18,7 +18,7 @@ internal fun FingerprintConfiguration.toProto(): ProtoFingerprintConfiguration = internal fun FingerprintConfiguration.FingerprintSdkConfiguration.toProto() = ProtoFingerprintConfiguration.ProtoFingerprintSdkConfiguration .newBuilder() - .addAllFingersToCapture(fingersToCapture.map { it.toProto() }) + .addAllFingersToCapture(fingersToCapture.map { it.toProtoFinger() }) .setDecisionPolicy(decisionPolicy.toProto()) .setComparisonStrategyForVerification(comparisonStrategyForVerification.toProto()) .setAllowedAgeRange(allowedAgeRange.toProto()) @@ -41,7 +41,8 @@ internal fun FingerprintConfiguration.BioSdk.toProto() = when (this) { internal fun FingerprintConfiguration.FingerComparisonStrategy.toProto() = when (this) { FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER -> ProtoFingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER - FingerprintConfiguration.FingerComparisonStrategy.CROSS_FINGER_USING_MEAN_OF_MAX -> ProtoFingerprintConfiguration.FingerComparisonStrategy.CROSS_FINGER_USING_MEAN_OF_MAX + 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() diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/GeneralConfiguration.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/GeneralConfiguration.kt index 2fb132a6e0..3c40d3aae2 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/GeneralConfiguration.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/models/GeneralConfiguration.kt @@ -1,5 +1,6 @@ package com.simprints.infra.config.store.local.models +import com.simprints.core.domain.common.Modality import com.simprints.infra.config.store.exceptions.InvalidProtobufEnumException import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.store.models.SettingsPasswordConfig @@ -15,9 +16,9 @@ internal fun GeneralConfiguration.toProto(): ProtoGeneralConfiguration = ProtoGe .setSettingsPassword(settingsPassword.toProto()) .build() -internal fun GeneralConfiguration.Modality.toProto(): ProtoGeneralConfiguration.Modality = when (this) { - GeneralConfiguration.Modality.FACE -> ProtoGeneralConfiguration.Modality.FACE - GeneralConfiguration.Modality.FINGERPRINT -> ProtoGeneralConfiguration.Modality.FINGERPRINT +internal fun Modality.toProto(): ProtoGeneralConfiguration.Modality = when (this) { + Modality.FACE -> ProtoGeneralConfiguration.Modality.FACE + Modality.FINGERPRINT -> ProtoGeneralConfiguration.Modality.FINGERPRINT } internal fun ProtoGeneralConfiguration.toDomain(): GeneralConfiguration = GeneralConfiguration( @@ -30,9 +31,9 @@ internal fun ProtoGeneralConfiguration.toDomain(): GeneralConfiguration = Genera SettingsPasswordConfig.toDomain(settingsPassword), ) -internal fun ProtoGeneralConfiguration.Modality.toDomain(): GeneralConfiguration.Modality = when (this) { - ProtoGeneralConfiguration.Modality.FACE -> GeneralConfiguration.Modality.FACE - ProtoGeneralConfiguration.Modality.FINGERPRINT -> GeneralConfiguration.Modality.FINGERPRINT +internal fun ProtoGeneralConfiguration.Modality.toDomain(): Modality = when (this) { + ProtoGeneralConfiguration.Modality.FACE -> Modality.FACE + ProtoGeneralConfiguration.Modality.FINGERPRINT -> Modality.FINGERPRINT ProtoGeneralConfiguration.Modality.UNRECOGNIZED -> throw InvalidProtobufEnumException("invalid modality $name") } diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/models/FaceConfiguration.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/models/FaceConfiguration.kt index f6061ea06c..43d2bbc7a7 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/models/FaceConfiguration.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/models/FaceConfiguration.kt @@ -1,5 +1,7 @@ package com.simprints.infra.config.store.models +import com.simprints.core.domain.common.ModalitySdkType + data class FaceConfiguration( val allowedSDKs: List, val rankOne: FaceSdkConfiguration?, @@ -15,12 +17,13 @@ data class FaceConfiguration( val verificationMatchThreshold: Float? = null, ) - fun getSdkConfiguration(sdk: BioSdk): FaceSdkConfiguration? = when (sdk) { + fun getSdkConfiguration(sdk: ModalitySdkType): FaceSdkConfiguration? = when (sdk) { BioSdk.RANK_ONE -> rankOne BioSdk.SIM_FACE -> simFace + else -> null } - enum class BioSdk { + enum class BioSdk : ModalitySdkType { RANK_ONE, SIM_FACE, } diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/models/Finger.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/models/Finger.kt deleted file mode 100644 index c430303153..0000000000 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/models/Finger.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.simprints.infra.config.store.models - -import com.simprints.core.domain.fingerprint.IFingerIdentifier - -enum class Finger { - LEFT_THUMB, - LEFT_INDEX_FINGER, - LEFT_3RD_FINGER, - LEFT_4TH_FINGER, - LEFT_5TH_FINGER, - RIGHT_THUMB, - RIGHT_INDEX_FINGER, - RIGHT_3RD_FINGER, - RIGHT_4TH_FINGER, - RIGHT_5TH_FINGER, -} - -fun Finger.fromDomainToModuleApi() = when (this) { - Finger.RIGHT_5TH_FINGER -> IFingerIdentifier.RIGHT_5TH_FINGER - Finger.RIGHT_4TH_FINGER -> IFingerIdentifier.RIGHT_4TH_FINGER - Finger.RIGHT_3RD_FINGER -> IFingerIdentifier.RIGHT_3RD_FINGER - Finger.RIGHT_INDEX_FINGER -> IFingerIdentifier.RIGHT_INDEX_FINGER - Finger.RIGHT_THUMB -> IFingerIdentifier.RIGHT_THUMB - Finger.LEFT_THUMB -> IFingerIdentifier.LEFT_THUMB - Finger.LEFT_INDEX_FINGER -> IFingerIdentifier.LEFT_INDEX_FINGER - Finger.LEFT_3RD_FINGER -> IFingerIdentifier.LEFT_3RD_FINGER - Finger.LEFT_4TH_FINGER -> IFingerIdentifier.LEFT_4TH_FINGER - Finger.LEFT_5TH_FINGER -> IFingerIdentifier.LEFT_5TH_FINGER -} - -fun IFingerIdentifier.fromModuleApiToDomain(): Finger = when (this) { - IFingerIdentifier.RIGHT_5TH_FINGER -> Finger.RIGHT_5TH_FINGER - IFingerIdentifier.RIGHT_4TH_FINGER -> Finger.RIGHT_4TH_FINGER - IFingerIdentifier.RIGHT_3RD_FINGER -> Finger.RIGHT_3RD_FINGER - IFingerIdentifier.RIGHT_INDEX_FINGER -> Finger.RIGHT_INDEX_FINGER - IFingerIdentifier.RIGHT_THUMB -> Finger.RIGHT_THUMB - IFingerIdentifier.LEFT_THUMB -> Finger.LEFT_THUMB - IFingerIdentifier.LEFT_INDEX_FINGER -> Finger.LEFT_INDEX_FINGER - IFingerIdentifier.LEFT_3RD_FINGER -> Finger.LEFT_3RD_FINGER - IFingerIdentifier.LEFT_4TH_FINGER -> Finger.LEFT_4TH_FINGER - IFingerIdentifier.LEFT_5TH_FINGER -> Finger.LEFT_5TH_FINGER -} 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 9694009f0f..aa8bfb4b78 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 @@ -1,5 +1,8 @@ package com.simprints.infra.config.store.models +import com.simprints.core.domain.common.ModalitySdkType +import com.simprints.core.domain.sample.SampleIdentifier + data class FingerprintConfiguration( val allowedScanners: List, val allowedSDKs: List, @@ -8,7 +11,7 @@ data class FingerprintConfiguration( val nec: FingerprintSdkConfiguration?, ) { data class FingerprintSdkConfiguration( - val fingersToCapture: List, + val fingersToCapture: List, val decisionPolicy: DecisionPolicy, val comparisonStrategyForVerification: FingerComparisonStrategy, val vero1: Vero1Configuration? = null, @@ -27,7 +30,7 @@ data class FingerprintConfiguration( VERO_2, } - enum class BioSdk { + enum class BioSdk : ModalitySdkType { SECUGEN_SIM_MATCHER, NEC, } @@ -37,8 +40,9 @@ data class FingerprintConfiguration( CROSS_FINGER_USING_MEAN_OF_MAX, } - fun getSdkConfiguration(sdk: BioSdk): FingerprintSdkConfiguration? = when (sdk) { + fun getSdkConfiguration(sdk: ModalitySdkType): FingerprintSdkConfiguration? = when (sdk) { BioSdk.SECUGEN_SIM_MATCHER -> secugenSimMatcher BioSdk.NEC -> nec + else -> null } } diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/models/GeneralConfiguration.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/models/GeneralConfiguration.kt index 27919d4a3c..4769bb9090 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/models/GeneralConfiguration.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/models/GeneralConfiguration.kt @@ -1,6 +1,6 @@ package com.simprints.infra.config.store.models -import com.simprints.core.domain.modality.Modes +import com.simprints.core.domain.common.Modality data class GeneralConfiguration( val modalities: List, @@ -10,15 +10,4 @@ data class GeneralConfiguration( val collectLocation: Boolean, val duplicateBiometricEnrolmentCheck: Boolean, val settingsPassword: SettingsPasswordConfig, -) { - enum class Modality { - FACE, - FINGERPRINT, - ; - - fun toMode(): Modes = when (this) { - FACE -> Modes.FACE - FINGERPRINT -> Modes.FINGERPRINT - } - } -} +) 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 b8800cd80e..211b44f911 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 @@ -1,9 +1,9 @@ package com.simprints.infra.config.store.remote.models import androidx.annotation.Keep +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.infra.config.store.models.AgeGroup import com.simprints.infra.config.store.models.FingerprintConfiguration -import com.simprints.infra.config.store.models.Finger as DomainFingerprint @Keep internal data class ApiFingerprintConfiguration( @@ -23,7 +23,7 @@ internal data class ApiFingerprintConfiguration( @Keep data class ApiFingerprintSdkConfiguration( - val fingersToCapture: List, + val fingersToCapture: List, val decisionPolicy: ApiDecisionPolicy, val comparisonStrategyForVerification: FingerComparisonStrategy, val vero1: ApiVero1Configuration? = null, @@ -45,7 +45,7 @@ internal data class ApiFingerprintConfiguration( } @Keep - enum class Finger { + enum class ApiFinger { LEFT_THUMB, LEFT_INDEX_FINGER, LEFT_3RD_FINGER, @@ -59,16 +59,16 @@ internal data class ApiFingerprintConfiguration( ; fun toDomain() = when (this) { - LEFT_THUMB -> DomainFingerprint.LEFT_THUMB - LEFT_INDEX_FINGER -> DomainFingerprint.LEFT_INDEX_FINGER - LEFT_3RD_FINGER -> DomainFingerprint.LEFT_3RD_FINGER - LEFT_4TH_FINGER -> DomainFingerprint.LEFT_4TH_FINGER - LEFT_5TH_FINGER -> DomainFingerprint.LEFT_5TH_FINGER - RIGHT_THUMB -> DomainFingerprint.RIGHT_THUMB - RIGHT_INDEX_FINGER -> DomainFingerprint.RIGHT_INDEX_FINGER - RIGHT_3RD_FINGER -> DomainFingerprint.RIGHT_3RD_FINGER - RIGHT_4TH_FINGER -> DomainFingerprint.RIGHT_4TH_FINGER - RIGHT_5TH_FINGER -> DomainFingerprint.RIGHT_5TH_FINGER + LEFT_THUMB -> SampleIdentifier.LEFT_THUMB + LEFT_INDEX_FINGER -> SampleIdentifier.LEFT_INDEX_FINGER + LEFT_3RD_FINGER -> SampleIdentifier.LEFT_3RD_FINGER + LEFT_4TH_FINGER -> SampleIdentifier.LEFT_4TH_FINGER + LEFT_5TH_FINGER -> SampleIdentifier.LEFT_5TH_FINGER + RIGHT_THUMB -> SampleIdentifier.RIGHT_THUMB + RIGHT_INDEX_FINGER -> SampleIdentifier.RIGHT_INDEX_FINGER + RIGHT_3RD_FINGER -> SampleIdentifier.RIGHT_3RD_FINGER + RIGHT_4TH_FINGER -> SampleIdentifier.RIGHT_4TH_FINGER + RIGHT_5TH_FINGER -> SampleIdentifier.RIGHT_5TH_FINGER } } diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/remote/models/ApiGeneralConfiguration.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/remote/models/ApiGeneralConfiguration.kt index 224639ee75..13b68792a4 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/remote/models/ApiGeneralConfiguration.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/remote/models/ApiGeneralConfiguration.kt @@ -1,13 +1,14 @@ package com.simprints.infra.config.store.remote.models import androidx.annotation.Keep +import com.simprints.core.domain.common.Modality import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.store.models.SettingsPasswordConfig @Keep internal data class ApiGeneralConfiguration( - val modalities: List, - val matchingModalities: List, + val modalities: List, + val matchingModalities: List, val languageOptions: List, val defaultLanguage: String, val collectLocation: Boolean, @@ -27,14 +28,14 @@ internal data class ApiGeneralConfiguration( ) @Keep - enum class Modality { + enum class ApiModality { FACE, FINGERPRINT, ; - fun toDomain(): GeneralConfiguration.Modality = when (this) { - FACE -> GeneralConfiguration.Modality.FACE - FINGERPRINT -> GeneralConfiguration.Modality.FINGERPRINT + fun toDomain(): Modality = when (this) { + FACE -> Modality.FACE + FINGERPRINT -> Modality.FINGERPRINT } } } diff --git a/infra/config-store/src/test/java/com/simprints/infra/config/store/local/models/FingerprintConfigurationTest.kt b/infra/config-store/src/test/java/com/simprints/infra/config/store/local/models/FingerprintConfigurationTest.kt index b4c691fbd0..5503ed0def 100644 --- a/infra/config-store/src/test/java/com/simprints/infra/config/store/local/models/FingerprintConfigurationTest.kt +++ b/infra/config-store/src/test/java/com/simprints/infra/config/store/local/models/FingerprintConfigurationTest.kt @@ -1,8 +1,8 @@ package com.simprints.infra.config.store.local.models -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* +import com.simprints.core.domain.sample.SampleIdentifier 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.testtools.fingerprintConfiguration import com.simprints.infra.config.store.testtools.protoFingerprintConfiguration @@ -44,21 +44,21 @@ class FingerprintConfigurationTest { @Test fun `should map correctly the Finger enums`() { val mapping = mapOf( - ProtoFinger.LEFT_THUMB to Finger.LEFT_THUMB, - ProtoFinger.LEFT_INDEX_FINGER to Finger.LEFT_INDEX_FINGER, - ProtoFinger.LEFT_3RD_FINGER to Finger.LEFT_3RD_FINGER, - ProtoFinger.LEFT_4TH_FINGER to Finger.LEFT_4TH_FINGER, - ProtoFinger.LEFT_5TH_FINGER to Finger.LEFT_5TH_FINGER, - ProtoFinger.RIGHT_THUMB to Finger.RIGHT_THUMB, - ProtoFinger.RIGHT_INDEX_FINGER to Finger.RIGHT_INDEX_FINGER, - ProtoFinger.RIGHT_3RD_FINGER to Finger.RIGHT_3RD_FINGER, - ProtoFinger.RIGHT_4TH_FINGER to Finger.RIGHT_4TH_FINGER, - ProtoFinger.RIGHT_5TH_FINGER to Finger.RIGHT_5TH_FINGER, + ProtoFinger.LEFT_THUMB to SampleIdentifier.LEFT_THUMB, + ProtoFinger.LEFT_INDEX_FINGER to SampleIdentifier.LEFT_INDEX_FINGER, + ProtoFinger.LEFT_3RD_FINGER to SampleIdentifier.LEFT_3RD_FINGER, + ProtoFinger.LEFT_4TH_FINGER to SampleIdentifier.LEFT_4TH_FINGER, + ProtoFinger.LEFT_5TH_FINGER to SampleIdentifier.LEFT_5TH_FINGER, + ProtoFinger.RIGHT_THUMB to SampleIdentifier.RIGHT_THUMB, + ProtoFinger.RIGHT_INDEX_FINGER to SampleIdentifier.RIGHT_INDEX_FINGER, + ProtoFinger.RIGHT_3RD_FINGER to SampleIdentifier.RIGHT_3RD_FINGER, + ProtoFinger.RIGHT_4TH_FINGER to SampleIdentifier.RIGHT_4TH_FINGER, + ProtoFinger.RIGHT_5TH_FINGER to SampleIdentifier.RIGHT_5TH_FINGER, ) mapping.forEach { assertThat(it.key.toDomain()).isEqualTo(it.value) - assertThat(it.value.toProto()).isEqualTo(it.key) + assertThat(it.value.toProtoFinger()).isEqualTo(it.key) } } diff --git a/infra/config-store/src/test/java/com/simprints/infra/config/store/local/models/GeneralConfigurationTest.kt b/infra/config-store/src/test/java/com/simprints/infra/config/store/local/models/GeneralConfigurationTest.kt index 193da4b01e..0184d7af21 100644 --- a/infra/config-store/src/test/java/com/simprints/infra/config/store/local/models/GeneralConfigurationTest.kt +++ b/infra/config-store/src/test/java/com/simprints/infra/config/store/local/models/GeneralConfigurationTest.kt @@ -1,7 +1,7 @@ package com.simprints.infra.config.store.local.models -import com.google.common.truth.Truth.assertThat -import com.simprints.infra.config.store.models.GeneralConfiguration +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.infra.config.store.models.SettingsPasswordConfig import com.simprints.infra.config.store.testtools.generalConfiguration import com.simprints.infra.config.store.testtools.protoGeneralConfiguration @@ -18,8 +18,8 @@ class GeneralConfigurationTest { @Test fun `should map correctly the Modality enums`() { val mapping = mapOf( - ProtoGeneralConfiguration.Modality.FACE to GeneralConfiguration.Modality.FACE, - ProtoGeneralConfiguration.Modality.FINGERPRINT to GeneralConfiguration.Modality.FINGERPRINT, + ProtoGeneralConfiguration.Modality.FACE to Modality.FACE, + ProtoGeneralConfiguration.Modality.FINGERPRINT to Modality.FINGERPRINT, ) mapping.forEach { diff --git a/infra/config-store/src/test/java/com/simprints/infra/config/store/models/FingerExtTest.kt b/infra/config-store/src/test/java/com/simprints/infra/config/store/models/FingerExtTest.kt deleted file mode 100644 index 2a13acacc4..0000000000 --- a/infra/config-store/src/test/java/com/simprints/infra/config/store/models/FingerExtTest.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.simprints.infra.config.store.models - -import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.fingerprint.IFingerIdentifier -import org.junit.Test - -class FingerExtTest { - @Test - fun `should map correctly the Finger enums`() { - val mapping = mapOf( - IFingerIdentifier.LEFT_THUMB to Finger.LEFT_THUMB, - IFingerIdentifier.LEFT_INDEX_FINGER to Finger.LEFT_INDEX_FINGER, - IFingerIdentifier.LEFT_3RD_FINGER to Finger.LEFT_3RD_FINGER, - IFingerIdentifier.LEFT_4TH_FINGER to Finger.LEFT_4TH_FINGER, - IFingerIdentifier.LEFT_5TH_FINGER to Finger.LEFT_5TH_FINGER, - IFingerIdentifier.RIGHT_THUMB to Finger.RIGHT_THUMB, - IFingerIdentifier.RIGHT_INDEX_FINGER to Finger.RIGHT_INDEX_FINGER, - IFingerIdentifier.RIGHT_3RD_FINGER to Finger.RIGHT_3RD_FINGER, - IFingerIdentifier.RIGHT_4TH_FINGER to Finger.RIGHT_4TH_FINGER, - IFingerIdentifier.RIGHT_5TH_FINGER to Finger.RIGHT_5TH_FINGER, - ) - - mapping.forEach { - assertThat(it.key.fromModuleApiToDomain()).isEqualTo(it.value) - assertThat(it.value.fromDomainToModuleApi()).isEqualTo(it.key) - } - } -} 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 46e3e3e5bc..0a3eef1a55 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 @@ -1,6 +1,7 @@ package com.simprints.infra.config.store.models import com.google.common.truth.* +import com.simprints.core.domain.sample.SampleIdentifier import org.junit.Test class FingerprintConfigurationTest { @@ -11,7 +12,7 @@ class FingerprintConfigurationTest { allowedSDKs = listOf(FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER), displayHandIcons = true, secugenSimMatcher = FingerprintConfiguration.FingerprintSdkConfiguration( - fingersToCapture = listOf(Finger.LEFT_THUMB), + fingersToCapture = listOf(SampleIdentifier.LEFT_THUMB), decisionPolicy = DecisionPolicy(20, 50, 100), comparisonStrategyForVerification = FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = Vero1Configuration(60), @@ -33,7 +34,7 @@ class FingerprintConfigurationTest { displayHandIcons = true, secugenSimMatcher = null, nec = FingerprintConfiguration.FingerprintSdkConfiguration( - fingersToCapture = listOf(Finger.LEFT_THUMB), + fingersToCapture = listOf(SampleIdentifier.LEFT_THUMB), decisionPolicy = DecisionPolicy(20, 50, 100), comparisonStrategyForVerification = FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = Vero1Configuration(60), 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 953f57b48e..b6078af2cf 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 @@ -1,8 +1,8 @@ package com.simprints.infra.config.store.remote.models -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* +import com.simprints.core.domain.sample.SampleIdentifier 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 @@ -41,7 +41,7 @@ class ApiFingerprintConfigurationTest { listOf(ApiFingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER), true, ApiFingerprintConfiguration.ApiFingerprintSdkConfiguration( - fingersToCapture = listOf(ApiFingerprintConfiguration.Finger.LEFT_3RD_FINGER), + fingersToCapture = listOf(ApiFingerprintConfiguration.ApiFinger.LEFT_3RD_FINGER), decisionPolicy = apiDecisionPolicy, comparisonStrategyForVerification = ApiFingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = null, @@ -56,7 +56,7 @@ class ApiFingerprintConfigurationTest { listOf(FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER), true, FingerprintConfiguration.FingerprintSdkConfiguration( - fingersToCapture = listOf(Finger.LEFT_3RD_FINGER), + fingersToCapture = listOf(SampleIdentifier.LEFT_3RD_FINGER), decisionPolicy = decisionPolicy, comparisonStrategyForVerification = FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = null, @@ -79,7 +79,7 @@ class ApiFingerprintConfigurationTest { true, null, ApiFingerprintConfiguration.ApiFingerprintSdkConfiguration( - fingersToCapture = listOf(ApiFingerprintConfiguration.Finger.LEFT_3RD_FINGER), + fingersToCapture = listOf(ApiFingerprintConfiguration.ApiFinger.LEFT_3RD_FINGER), decisionPolicy = apiDecisionPolicy, comparisonStrategyForVerification = ApiFingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = ApiVero1Configuration(10), @@ -94,7 +94,7 @@ class ApiFingerprintConfigurationTest { true, null, FingerprintConfiguration.FingerprintSdkConfiguration( - fingersToCapture = listOf(Finger.LEFT_3RD_FINGER), + fingersToCapture = listOf(SampleIdentifier.LEFT_3RD_FINGER), decisionPolicy = decisionPolicy, comparisonStrategyForVerification = FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = Vero1Configuration(10), @@ -111,16 +111,16 @@ class ApiFingerprintConfigurationTest { @Test fun `should map correctly the Finger enums`() { val mapping = mapOf( - ApiFingerprintConfiguration.Finger.LEFT_THUMB to Finger.LEFT_THUMB, - ApiFingerprintConfiguration.Finger.LEFT_INDEX_FINGER to Finger.LEFT_INDEX_FINGER, - ApiFingerprintConfiguration.Finger.LEFT_3RD_FINGER to Finger.LEFT_3RD_FINGER, - ApiFingerprintConfiguration.Finger.LEFT_4TH_FINGER to Finger.LEFT_4TH_FINGER, - ApiFingerprintConfiguration.Finger.LEFT_5TH_FINGER to Finger.LEFT_5TH_FINGER, - ApiFingerprintConfiguration.Finger.RIGHT_THUMB to Finger.RIGHT_THUMB, - ApiFingerprintConfiguration.Finger.RIGHT_INDEX_FINGER to Finger.RIGHT_INDEX_FINGER, - ApiFingerprintConfiguration.Finger.RIGHT_3RD_FINGER to Finger.RIGHT_3RD_FINGER, - ApiFingerprintConfiguration.Finger.RIGHT_4TH_FINGER to Finger.RIGHT_4TH_FINGER, - ApiFingerprintConfiguration.Finger.RIGHT_5TH_FINGER to Finger.RIGHT_5TH_FINGER, + ApiFingerprintConfiguration.ApiFinger.LEFT_THUMB to SampleIdentifier.LEFT_THUMB, + ApiFingerprintConfiguration.ApiFinger.LEFT_INDEX_FINGER to SampleIdentifier.LEFT_INDEX_FINGER, + ApiFingerprintConfiguration.ApiFinger.LEFT_3RD_FINGER to SampleIdentifier.LEFT_3RD_FINGER, + ApiFingerprintConfiguration.ApiFinger.LEFT_4TH_FINGER to SampleIdentifier.LEFT_4TH_FINGER, + ApiFingerprintConfiguration.ApiFinger.LEFT_5TH_FINGER to SampleIdentifier.LEFT_5TH_FINGER, + ApiFingerprintConfiguration.ApiFinger.RIGHT_THUMB to SampleIdentifier.RIGHT_THUMB, + ApiFingerprintConfiguration.ApiFinger.RIGHT_INDEX_FINGER to SampleIdentifier.RIGHT_INDEX_FINGER, + ApiFingerprintConfiguration.ApiFinger.RIGHT_3RD_FINGER to SampleIdentifier.RIGHT_3RD_FINGER, + ApiFingerprintConfiguration.ApiFinger.RIGHT_4TH_FINGER to SampleIdentifier.RIGHT_4TH_FINGER, + ApiFingerprintConfiguration.ApiFinger.RIGHT_5TH_FINGER to SampleIdentifier.RIGHT_5TH_FINGER, ) mapping.forEach { diff --git a/infra/config-store/src/test/java/com/simprints/infra/config/store/remote/models/ApiGeneralConfigurationTest.kt b/infra/config-store/src/test/java/com/simprints/infra/config/store/remote/models/ApiGeneralConfigurationTest.kt index 59647cc8d9..ff74dc42bf 100644 --- a/infra/config-store/src/test/java/com/simprints/infra/config/store/remote/models/ApiGeneralConfigurationTest.kt +++ b/infra/config-store/src/test/java/com/simprints/infra/config/store/remote/models/ApiGeneralConfigurationTest.kt @@ -1,7 +1,7 @@ package com.simprints.infra.config.store.remote.models import com.google.common.truth.Truth.assertThat -import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.core.domain.common.Modality import com.simprints.infra.config.store.models.SettingsPasswordConfig import com.simprints.infra.config.store.testtools.apiGeneralConfiguration import com.simprints.infra.config.store.testtools.generalConfiguration @@ -16,8 +16,8 @@ class ApiGeneralConfigurationTest { @Test fun `should map correctly the Modality enums`() { val mapping = mapOf( - ApiGeneralConfiguration.Modality.FACE to GeneralConfiguration.Modality.FACE, - ApiGeneralConfiguration.Modality.FINGERPRINT to GeneralConfiguration.Modality.FINGERPRINT, + ApiGeneralConfiguration.ApiModality.FACE to Modality.FACE, + ApiGeneralConfiguration.ApiModality.FINGERPRINT to Modality.FINGERPRINT, ) mapping.forEach { 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 5c9634289f..0bad324692 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 @@ -1,6 +1,8 @@ package com.simprints.infra.config.store.testtools +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredentialType +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.infra.config.store.local.models.ProtoAllowedAgeRange import com.simprints.infra.config.store.local.models.ProtoConsentConfiguration @@ -32,7 +34,6 @@ import com.simprints.infra.config.store.models.DeviceState import com.simprints.infra.config.store.models.DownSynchronizationConfiguration import com.simprints.infra.config.store.models.FaceConfiguration import com.simprints.infra.config.store.models.FaceConfiguration.FaceSdkConfiguration -import com.simprints.infra.config.store.models.Finger import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.Frequency import com.simprints.infra.config.store.models.GeneralConfiguration @@ -255,7 +256,7 @@ internal val apiFingerprintConfiguration = ApiFingerprintConfiguration( allowedSDKs = listOf(ApiFingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER), displayHandIcons = true, secugenSimMatcher = ApiFingerprintConfiguration.ApiFingerprintSdkConfiguration( - fingersToCapture = listOf(ApiFingerprintConfiguration.Finger.LEFT_3RD_FINGER), + fingersToCapture = listOf(ApiFingerprintConfiguration.ApiFinger.LEFT_3RD_FINGER), decisionPolicy = apiDecisionPolicy, comparisonStrategyForVerification = ApiFingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = ApiVero1Configuration(10), @@ -268,7 +269,7 @@ internal val apiFingerprintConfiguration = ApiFingerprintConfiguration( ) internal val fingerprintSdkConfiguration = FingerprintConfiguration.FingerprintSdkConfiguration( - fingersToCapture = listOf(Finger.LEFT_3RD_FINGER), + fingersToCapture = listOf(SampleIdentifier.LEFT_3RD_FINGER), decisionPolicy = decisionPolicy, comparisonStrategyForVerification = FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = Vero1Configuration(qualityThreshold = 10), @@ -306,8 +307,8 @@ internal val protoFingerprintConfiguration = ProtoFingerprintConfiguration ).build() internal val apiGeneralConfiguration = ApiGeneralConfiguration( - listOf(ApiGeneralConfiguration.Modality.FACE), - listOf(ApiGeneralConfiguration.Modality.FACE), + listOf(ApiGeneralConfiguration.ApiModality.FACE), + listOf(ApiGeneralConfiguration.ApiModality.FACE), listOf("en"), "en", collectLocation = true, @@ -316,8 +317,8 @@ internal val apiGeneralConfiguration = ApiGeneralConfiguration( ) internal val generalConfiguration = GeneralConfiguration( - listOf(GeneralConfiguration.Modality.FACE), - listOf(GeneralConfiguration.Modality.FACE), + listOf(Modality.FACE), + listOf(Modality.FACE), listOf("en"), "en", collectLocation = true, @@ -418,7 +419,7 @@ internal val synchronizationConfiguration = SynchronizationConfiguration( internal val allowedExternalCredential = ExternalCredentialType.NHISCard internal val multiFactorIdConfiguration = MultiFactorIdConfiguration( - allowedExternalCredentials = listOf(allowedExternalCredential) + allowedExternalCredentials = listOf(allowedExternalCredential), ) internal val protoMultiFactorIdConfiguration = ProtoMultiFactorIdConfiguration @@ -474,7 +475,7 @@ internal val protoSynchronizationConfiguration = ProtoSynchronizationConfigurati internal val apiAllowedExternalCredential = ApiExternalCredentialType.NHIS_CARD internal val apiMultiFactorIdConfiguration = ApiMultiFactorIdConfiguration( - allowedExternalCredentials = listOf(apiAllowedExternalCredential) + allowedExternalCredentials = listOf(apiAllowedExternalCredential), ) internal val customKeyMap: Map? = mapOf( @@ -510,7 +511,7 @@ internal val projectConfiguration = ProjectConfiguration( identification = identificationConfiguration, synchronization = synchronizationConfiguration, multifactorId = multiFactorIdConfiguration, - custom = customKeyMap + custom = customKeyMap, ) internal val protoProjectConfiguration = ProtoProjectConfiguration diff --git a/infra/core/src/main/java/com/simprints/core/domain/modality/Modes.kt b/infra/core/src/main/java/com/simprints/core/domain/common/Modality.kt similarity index 52% rename from infra/core/src/main/java/com/simprints/core/domain/modality/Modes.kt rename to infra/core/src/main/java/com/simprints/core/domain/common/Modality.kt index 49e2064626..cb82cba57b 100644 --- a/infra/core/src/main/java/com/simprints/core/domain/modality/Modes.kt +++ b/infra/core/src/main/java/com/simprints/core/domain/common/Modality.kt @@ -1,9 +1,9 @@ -package com.simprints.core.domain.modality +package com.simprints.core.domain.common import androidx.annotation.Keep @Keep -enum class Modes { +enum class Modality { FINGERPRINT, FACE, } diff --git a/infra/core/src/main/java/com/simprints/core/domain/common/ModalitySdkType.kt b/infra/core/src/main/java/com/simprints/core/domain/common/ModalitySdkType.kt new file mode 100644 index 0000000000..586f81f234 --- /dev/null +++ b/infra/core/src/main/java/com/simprints/core/domain/common/ModalitySdkType.kt @@ -0,0 +1,8 @@ +package com.simprints.core.domain.common + +import com.simprints.core.domain.step.StepParams + +/** + * Marker interface for for enums that list SDK types in each modality. + */ +interface ModalitySdkType : StepParams diff --git a/infra/core/src/main/java/com/simprints/core/domain/face/FaceSample.kt b/infra/core/src/main/java/com/simprints/core/domain/face/FaceSample.kt deleted file mode 100644 index 57b44fd5f9..0000000000 --- a/infra/core/src/main/java/com/simprints/core/domain/face/FaceSample.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.simprints.core.domain.face - -import android.os.Parcelable -import com.simprints.core.ExcludedFromGeneratedTestCoverageReports -import kotlinx.parcelize.Parcelize -import java.util.UUID - -@Parcelize -@ExcludedFromGeneratedTestCoverageReports("Data class with generated code") -data class FaceSample( - val template: ByteArray, - val format: String, - val referenceId: String, - val id: String = UUID.randomUUID().toString(), -) : Parcelable { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as FaceSample - - return template.contentEquals(other.template) - } - - override fun hashCode(): Int = template.contentHashCode() -} diff --git a/infra/core/src/main/java/com/simprints/core/domain/sample/CaptureIdentity.kt b/infra/core/src/main/java/com/simprints/core/domain/sample/CaptureIdentity.kt new file mode 100644 index 0000000000..cc6ef358f8 --- /dev/null +++ b/infra/core/src/main/java/com/simprints/core/domain/sample/CaptureIdentity.kt @@ -0,0 +1,12 @@ +package com.simprints.core.domain.sample + +import androidx.annotation.Keep +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.step.StepResult + +@Keep +data class CaptureIdentity( + val referenceId: String, + val modality: Modality, + var samples: List, +) : StepResult diff --git a/infra/core/src/main/java/com/simprints/core/domain/sample/CaptureSample.kt b/infra/core/src/main/java/com/simprints/core/domain/sample/CaptureSample.kt new file mode 100644 index 0000000000..28b5d533ff --- /dev/null +++ b/infra/core/src/main/java/com/simprints/core/domain/sample/CaptureSample.kt @@ -0,0 +1,40 @@ +package com.simprints.core.domain.sample + +import android.os.Parcelable +import com.simprints.core.ExcludedFromGeneratedTestCoverageReports +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.SampleIdentifier +import com.simprints.core.domain.step.StepParams +import com.simprints.core.domain.step.StepResult +import kotlinx.parcelize.Parcelize +import java.util.UUID + +@Parcelize +@ExcludedFromGeneratedTestCoverageReports("Data class with generated code") +data class CaptureSample( + val captureEventId: String, + val modality: Modality, + val format: String, + val template: ByteArray, + val identifier: SampleIdentifier = SampleIdentifier.NONE, +) : StepResult, + StepParams, + Parcelable { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as CaptureSample + + if (identifier != other.identifier) return false + if (!template.contentEquals(other.template)) return false + + return true + } + + override fun hashCode(): Int { + var result = identifier.hashCode() + result = 31 * result + template.contentHashCode() + return result + } +} diff --git a/face/infra/base-bio-sdk/src/main/java/com/simprints/face/infra/basebiosdk/matching/FaceIdentity.kt b/infra/core/src/main/java/com/simprints/core/domain/sample/Identity.kt similarity index 51% rename from face/infra/base-bio-sdk/src/main/java/com/simprints/face/infra/basebiosdk/matching/FaceIdentity.kt rename to infra/core/src/main/java/com/simprints/core/domain/sample/Identity.kt index 62d5542b49..5bc5af9e5f 100644 --- a/face/infra/base-bio-sdk/src/main/java/com/simprints/face/infra/basebiosdk/matching/FaceIdentity.kt +++ b/infra/core/src/main/java/com/simprints/core/domain/sample/Identity.kt @@ -1,10 +1,10 @@ -package com.simprints.face.infra.basebiosdk.matching +package com.simprints.core.domain.sample import android.os.Parcelable import kotlinx.parcelize.Parcelize @Parcelize -data class FaceIdentity( +class Identity( val subjectId: String, - val faces: List, + val samples: List, ) : Parcelable diff --git a/infra/core/src/main/java/com/simprints/core/domain/sample/MatchComparisonResult.kt b/infra/core/src/main/java/com/simprints/core/domain/sample/MatchComparisonResult.kt new file mode 100644 index 0000000000..17964472a7 --- /dev/null +++ b/infra/core/src/main/java/com/simprints/core/domain/sample/MatchComparisonResult.kt @@ -0,0 +1,16 @@ +package com.simprints.core.domain.sample + +import android.os.Parcelable +import androidx.annotation.Keep +import com.simprints.core.domain.step.StepParams +import com.simprints.core.domain.step.StepResult +import kotlinx.parcelize.Parcelize + +@Keep +@Parcelize +data class MatchComparisonResult( + val subjectId: String, + val confidence: Float, +) : StepParams, + StepResult, + Parcelable diff --git a/infra/core/src/main/java/com/simprints/core/domain/fingerprint/FingerprintSample.kt b/infra/core/src/main/java/com/simprints/core/domain/sample/Sample.kt similarity index 66% rename from infra/core/src/main/java/com/simprints/core/domain/fingerprint/FingerprintSample.kt rename to infra/core/src/main/java/com/simprints/core/domain/sample/Sample.kt index 308fc83935..b6f54799dd 100644 --- a/infra/core/src/main/java/com/simprints/core/domain/fingerprint/FingerprintSample.kt +++ b/infra/core/src/main/java/com/simprints/core/domain/sample/Sample.kt @@ -1,33 +1,36 @@ -package com.simprints.core.domain.fingerprint +package com.simprints.core.domain.sample import android.os.Parcelable import com.simprints.core.ExcludedFromGeneratedTestCoverageReports +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.SampleIdentifier import kotlinx.parcelize.Parcelize import java.util.UUID @Parcelize @ExcludedFromGeneratedTestCoverageReports("Data class with generated code") -data class FingerprintSample( - val fingerIdentifier: IFingerIdentifier, - val template: ByteArray, - val format: String, - val referenceId: String, +data class Sample( val id: String = UUID.randomUUID().toString(), + val identifier: SampleIdentifier = SampleIdentifier.NONE, + val modality: Modality, + val referenceId: String, + val format: String, + val template: ByteArray, ) : Parcelable { override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false - other as FingerprintSample + other as Sample - if (fingerIdentifier != other.fingerIdentifier) return false + if (identifier != other.identifier) return false if (!template.contentEquals(other.template)) return false return true } override fun hashCode(): Int { - var result = fingerIdentifier.hashCode() + var result = identifier.hashCode() result = 31 * result + template.contentHashCode() return result } diff --git a/infra/core/src/main/java/com/simprints/core/domain/fingerprint/IFingerIdentifier.kt b/infra/core/src/main/java/com/simprints/core/domain/sample/SampleIdentifier.kt similarity index 75% rename from infra/core/src/main/java/com/simprints/core/domain/fingerprint/IFingerIdentifier.kt rename to infra/core/src/main/java/com/simprints/core/domain/sample/SampleIdentifier.kt index 13b51e432d..2082a60101 100644 --- a/infra/core/src/main/java/com/simprints/core/domain/fingerprint/IFingerIdentifier.kt +++ b/infra/core/src/main/java/com/simprints/core/domain/sample/SampleIdentifier.kt @@ -1,11 +1,14 @@ -package com.simprints.core.domain.fingerprint +package com.simprints.core.domain.sample import androidx.annotation.Keep import com.simprints.core.ExcludedFromGeneratedTestCoverageReports @Keep @ExcludedFromGeneratedTestCoverageReports("Enum") -enum class IFingerIdentifier { +enum class SampleIdentifier { + NONE, + + // Fingerprint specific identifiers RIGHT_5TH_FINGER, RIGHT_4TH_FINGER, RIGHT_3RD_FINGER, diff --git a/infra/enrolment-records/repository/src/androidTest/kotlin/com/simprints/infra/enrolment/records/repository/local/RealmEnrolmentRecordLocalDataSourceIntegrationTest.kt b/infra/enrolment-records/repository/src/androidTest/kotlin/com/simprints/infra/enrolment/records/repository/local/RealmEnrolmentRecordLocalDataSourceIntegrationTest.kt index f11482bfff..02a39ae6ff 100644 --- a/infra/enrolment-records/repository/src/androidTest/kotlin/com/simprints/infra/enrolment/records/repository/local/RealmEnrolmentRecordLocalDataSourceIntegrationTest.kt +++ b/infra/enrolment-records/repository/src/androidTest/kotlin/com/simprints/infra/enrolment/records/repository/local/RealmEnrolmentRecordLocalDataSourceIntegrationTest.kt @@ -2,11 +2,12 @@ package com.simprints.infra.enrolment.records.repository.local import androidx.test.core.app.* import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredential import com.simprints.core.domain.externalcredential.ExternalCredentialType -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.core.tools.time.TimeHelper @@ -18,8 +19,6 @@ import com.simprints.infra.enrolment.records.realm.store.RealmWrapper import com.simprints.infra.enrolment.records.realm.store.RealmWrapperImpl import com.simprints.infra.enrolment.records.realm.store.config.RealmConfig import com.simprints.infra.enrolment.records.realm.store.models.DbSubject -import com.simprints.infra.enrolment.records.repository.domain.models.FaceIdentity -import com.simprints.infra.enrolment.records.repository.domain.models.FingerprintIdentity import com.simprints.infra.enrolment.records.repository.domain.models.IdentityBatch import com.simprints.infra.enrolment.records.repository.domain.models.Subject import com.simprints.infra.enrolment.records.repository.domain.models.SubjectAction @@ -237,10 +236,11 @@ class RealmEnrolmentRecordLocalDataSourceIntegrationTest { val subjectId = UUID.randomUUID().toString() val originalSubject = createTestSubject(subjectId) originalSubject.faceSamples = listOf( - FaceSample( + Sample( template = byteArrayOf(), format = "ISO", referenceId = "ref1", + modality = Modality.FACE, ), ) originalSubject.externalCredentials = listOf( @@ -256,18 +256,20 @@ class RealmEnrolmentRecordLocalDataSourceIntegrationTest { val updateAction = SubjectAction.Update( subjectId, faceSamplesToAdd = listOf( - FaceSample( + Sample( template = byteArrayOf(1, 2, 3), format = "ISO", referenceId = "ref2", + modality = Modality.FACE, ), ), fingerprintSamplesToAdd = listOf( - FingerprintSample( + Sample( template = byteArrayOf(4, 5, 6), format = "ISO", referenceId = "ref3", - fingerIdentifier = IFingerIdentifier.LEFT_THUMB, + identifier = SampleIdentifier.LEFT_THUMB, + modality = Modality.FINGERPRINT, ), ), referenceIdsToRemove = listOf("ref1"), @@ -312,7 +314,12 @@ class RealmEnrolmentRecordLocalDataSourceIntegrationTest { val subjects = (1..10).map { i -> createTestSubject(subjectId = UUID.randomUUID().toString()).apply { faceSamples = listOf( - FaceSample(template = byteArrayOf(i.toByte()), format = "ISO", referenceId = "ref$i"), + Sample( + template = byteArrayOf(i.toByte()), + format = "ISO", + referenceId = "ref$i", + modality = Modality.FACE, + ), ) } } @@ -335,7 +342,7 @@ class RealmEnrolmentRecordLocalDataSourceIntegrationTest { onCandidateLoaded = { loadedCandidates.add(Unit) }, ) - val results = mutableListOf>() + val results = mutableListOf>() for (batch in channel) { results.add(batch) } @@ -355,11 +362,12 @@ class RealmEnrolmentRecordLocalDataSourceIntegrationTest { val subjects = (1..10).map { i -> createTestSubject(subjectId = UUID.randomUUID().toString()).apply { fingerprintSamples = listOf( - FingerprintSample( + Sample( template = byteArrayOf(i.toByte()), format = "ISO", referenceId = "ref$i", - fingerIdentifier = IFingerIdentifier.LEFT_THUMB, + identifier = SampleIdentifier.LEFT_THUMB, + modality = Modality.FINGERPRINT, ), ) } @@ -383,7 +391,7 @@ class RealmEnrolmentRecordLocalDataSourceIntegrationTest { onCandidateLoaded = { loadedCandidates.add(Unit) }, ) - val results = mutableListOf>() + val results = mutableListOf>() for (batch in channel) { results.add(batch) } diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/IdentityDataSource.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/IdentityDataSource.kt index 0fe763ad9f..0828fa9ea6 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/IdentityDataSource.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/IdentityDataSource.kt @@ -1,9 +1,8 @@ package com.simprints.infra.enrolment.records.repository +import com.simprints.core.domain.sample.Identity import com.simprints.infra.config.store.models.Project import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource -import com.simprints.infra.enrolment.records.repository.domain.models.FaceIdentity -import com.simprints.infra.enrolment.records.repository.domain.models.FingerprintIdentity import com.simprints.infra.enrolment.records.repository.domain.models.IdentityBatch import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery import kotlinx.coroutines.CoroutineScope @@ -22,7 +21,7 @@ interface IdentityDataSource { project: Project, scope: CoroutineScope, onCandidateLoaded: suspend () -> Unit, - ): ReceiveChannel> + ): ReceiveChannel> suspend fun loadFaceIdentities( query: SubjectQuery, @@ -31,7 +30,7 @@ interface IdentityDataSource { project: Project, scope: CoroutineScope, onCandidateLoaded: suspend () -> Unit, - ): ReceiveChannel> + ): ReceiveChannel> /** * Loads identities concurrently using the provided dispatcher and parallelism level. diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/commcare/CommCareIdentityDataSource.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/commcare/CommCareIdentityDataSource.kt index 9684437207..11cc9fd2f7 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/commcare/CommCareIdentityDataSource.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/commcare/CommCareIdentityDataSource.kt @@ -8,8 +8,9 @@ import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.databind.module.SimpleModule import com.simprints.core.AvailableProcessors import com.simprints.core.DispatcherBG -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.Sample import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.domain.tokenization.serialization.TokenizationClassNameDeserializer import com.simprints.core.domain.tokenization.serialization.TokenizationClassNameSerializer @@ -21,8 +22,6 @@ import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.store.models.TokenKeyType import com.simprints.infra.enrolment.records.repository.IdentityDataSource import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource -import com.simprints.infra.enrolment.records.repository.domain.models.FaceIdentity -import com.simprints.infra.enrolment.records.repository.domain.models.FingerprintIdentity import com.simprints.infra.enrolment.records.repository.domain.models.IdentityBatch import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery import com.simprints.infra.enrolment.records.repository.usecases.CompareImplicitTokenizedStringsUseCase @@ -66,25 +65,25 @@ internal class CommCareIdentityDataSource @Inject constructor( dataSource: BiometricDataSource, project: Project, onCandidateLoaded: suspend () -> Unit, - ): List = - loadEnrolmentRecordCreationEvents(range, dataSource.callerPackageName(), query, project, onCandidateLoaded) - .filter { erce -> - erce.payload.biometricReferences.any { it is FingerprintReference && it.format == query.fingerprintSampleFormat } - }.map { - FingerprintIdentity( - it.payload.subjectId, - it.payload.biometricReferences.filterIsInstance().flatMap { fingerprintReference -> - fingerprintReference.templates.map { fingerprintTemplate -> - FingerprintSample( - fingerIdentifier = fingerprintTemplate.finger, - template = encoder.base64ToBytes(fingerprintTemplate.template), - format = fingerprintReference.format, - referenceId = fingerprintReference.id, - ) - } - }, - ) - } + ): List = loadEnrolmentRecordCreationEvents(range, dataSource.callerPackageName(), query, project, onCandidateLoaded) + .filter { erce -> + erce.payload.biometricReferences.any { it is FingerprintReference && it.format == query.fingerprintSampleFormat } + }.map { + Identity( + it.payload.subjectId, + it.payload.biometricReferences.filterIsInstance().flatMap { fingerprintReference -> + fingerprintReference.templates.map { fingerprintTemplate -> + Sample( + identifier = fingerprintTemplate.finger, + template = encoder.base64ToBytes(fingerprintTemplate.template), + format = fingerprintReference.format, + referenceId = fingerprintReference.id, + modality = Modality.FINGERPRINT, + ) + } + }, + ) + } private suspend fun loadEnrolmentRecordCreationEvents( range: IntRange, @@ -133,18 +132,19 @@ internal class CommCareIdentityDataSource @Inject constructor( dataSource: BiometricDataSource, project: Project, onCandidateLoaded: suspend () -> Unit, - ): List = loadEnrolmentRecordCreationEvents(range, dataSource.callerPackageName(), query, project, onCandidateLoaded) + ): List = loadEnrolmentRecordCreationEvents(range, dataSource.callerPackageName(), query, project, onCandidateLoaded) .filter { erce -> erce.payload.biometricReferences.any { it is FaceReference && it.format == query.faceSampleFormat } }.map { - FaceIdentity( + Identity( it.payload.subjectId, it.payload.biometricReferences.filterIsInstance().flatMap { faceReference -> faceReference.templates.map { faceTemplate -> - FaceSample( + Sample( template = encoder.base64ToBytes(faceTemplate.template), format = faceReference.format, referenceId = faceReference.id, + modality = Modality.FACE, ) } }, @@ -276,7 +276,7 @@ internal class CommCareIdentityDataSource @Inject constructor( project: Project, scope: CoroutineScope, onCandidateLoaded: suspend () -> Unit, - ): ReceiveChannel> = loadIdentitiesConcurrently( + ): ReceiveChannel> = loadIdentitiesConcurrently( ranges = ranges, scope = scope, ) { range -> @@ -299,7 +299,7 @@ internal class CommCareIdentityDataSource @Inject constructor( project: Project, scope: CoroutineScope, onCandidateLoaded: suspend () -> Unit, - ): ReceiveChannel> = loadIdentitiesConcurrently( + ): ReceiveChannel> = loadIdentitiesConcurrently( ranges = ranges, scope = scope, ) { range -> diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/FaceIdentity.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/FaceIdentity.kt deleted file mode 100644 index 32881787b5..0000000000 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/FaceIdentity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.simprints.infra.enrolment.records.repository.domain.models - -import android.os.Parcelable -import com.simprints.core.domain.face.FaceSample -import kotlinx.parcelize.Parcelize - -@Parcelize -class FaceIdentity( - val subjectId: String, - val faces: List, -) : Parcelable diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/FingerIdentifier.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/FingerIdentifier.kt deleted file mode 100644 index 50ed8caf34..0000000000 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/FingerIdentifier.kt +++ /dev/null @@ -1,47 +0,0 @@ -package com.simprints.infra.enrolment.records.repository.domain.models - -import androidx.annotation.Keep -import com.simprints.core.domain.fingerprint.IFingerIdentifier - -// **IMPORTANT**: Do NOT change the order of this enum as it is used in the database by index. -// Changing the order of the entries in this enum will lead to data corruption or mismatches -// when retrieving or storing data in the database. Always append new entries at the end. -@Keep -enum class FingerIdentifier { - RIGHT_5TH_FINGER, - RIGHT_4TH_FINGER, - RIGHT_3RD_FINGER, - RIGHT_INDEX_FINGER, - RIGHT_THUMB, - LEFT_THUMB, - LEFT_INDEX_FINGER, - LEFT_3RD_FINGER, - LEFT_4TH_FINGER, - LEFT_5TH_FINGER, -} - -fun FingerIdentifier.fromDomainToModuleApi() = when (this) { - FingerIdentifier.RIGHT_5TH_FINGER -> IFingerIdentifier.RIGHT_5TH_FINGER - FingerIdentifier.RIGHT_4TH_FINGER -> IFingerIdentifier.RIGHT_4TH_FINGER - FingerIdentifier.RIGHT_3RD_FINGER -> IFingerIdentifier.RIGHT_3RD_FINGER - FingerIdentifier.RIGHT_INDEX_FINGER -> IFingerIdentifier.RIGHT_INDEX_FINGER - FingerIdentifier.RIGHT_THUMB -> IFingerIdentifier.RIGHT_THUMB - FingerIdentifier.LEFT_THUMB -> IFingerIdentifier.LEFT_THUMB - FingerIdentifier.LEFT_INDEX_FINGER -> IFingerIdentifier.LEFT_INDEX_FINGER - FingerIdentifier.LEFT_3RD_FINGER -> IFingerIdentifier.LEFT_3RD_FINGER - FingerIdentifier.LEFT_4TH_FINGER -> IFingerIdentifier.LEFT_4TH_FINGER - FingerIdentifier.LEFT_5TH_FINGER -> IFingerIdentifier.LEFT_5TH_FINGER -} - -fun IFingerIdentifier.fromModuleApiToDomain() = when (this) { - IFingerIdentifier.RIGHT_5TH_FINGER -> FingerIdentifier.RIGHT_5TH_FINGER - IFingerIdentifier.RIGHT_4TH_FINGER -> FingerIdentifier.RIGHT_4TH_FINGER - IFingerIdentifier.RIGHT_3RD_FINGER -> FingerIdentifier.RIGHT_3RD_FINGER - IFingerIdentifier.RIGHT_INDEX_FINGER -> FingerIdentifier.RIGHT_INDEX_FINGER - IFingerIdentifier.RIGHT_THUMB -> FingerIdentifier.RIGHT_THUMB - IFingerIdentifier.LEFT_THUMB -> FingerIdentifier.LEFT_THUMB - IFingerIdentifier.LEFT_INDEX_FINGER -> FingerIdentifier.LEFT_INDEX_FINGER - IFingerIdentifier.LEFT_3RD_FINGER -> FingerIdentifier.LEFT_3RD_FINGER - IFingerIdentifier.LEFT_4TH_FINGER -> FingerIdentifier.LEFT_4TH_FINGER - IFingerIdentifier.LEFT_5TH_FINGER -> FingerIdentifier.LEFT_5TH_FINGER -} diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/FingerprintIdentity.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/FingerprintIdentity.kt deleted file mode 100644 index 968bc90d23..0000000000 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/FingerprintIdentity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.simprints.infra.enrolment.records.repository.domain.models - -import android.os.Parcelable -import com.simprints.core.domain.fingerprint.FingerprintSample -import kotlinx.parcelize.Parcelize - -@Parcelize -class FingerprintIdentity( - val subjectId: String, - val fingerprints: List, -) : Parcelable diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/Subject.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/Subject.kt index 3cc6060579..befdef7283 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/Subject.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/Subject.kt @@ -2,8 +2,7 @@ package com.simprints.infra.enrolment.records.repository.domain.models import android.os.Parcelable import com.simprints.core.domain.externalcredential.ExternalCredential -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample +import com.simprints.core.domain.sample.Sample import com.simprints.core.domain.tokenization.TokenizableString import kotlinx.parcelize.Parcelize import java.util.Date @@ -16,7 +15,7 @@ data class Subject( val moduleId: TokenizableString, val createdAt: Date? = null, val updatedAt: Date? = null, - var fingerprintSamples: List = emptyList(), - var faceSamples: List = emptyList(), + var fingerprintSamples: List = emptyList(), + var faceSamples: List = emptyList(), var externalCredentials: List = emptyList(), ) : Parcelable diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/SubjectAction.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/SubjectAction.kt index e222562f1c..1ec3d43782 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/SubjectAction.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/domain/models/SubjectAction.kt @@ -2,8 +2,7 @@ package com.simprints.infra.enrolment.records.repository.domain.models import androidx.annotation.Keep import com.simprints.core.domain.externalcredential.ExternalCredential -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample +import com.simprints.core.domain.sample.Sample @Keep sealed class SubjectAction { @@ -13,8 +12,8 @@ sealed class SubjectAction { data class Update( val subjectId: String, - val faceSamplesToAdd: List, - val fingerprintSamplesToAdd: List, + val faceSamplesToAdd: List, + val fingerprintSamplesToAdd: List, val referenceIdsToRemove: List, val externalCredentialsToAdd: List, val externalCredentialIdsToRemove: List, diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/RealmEnrolmentRecordLocalDataSource.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/RealmEnrolmentRecordLocalDataSource.kt index bc51a673d5..d5340e2935 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/RealmEnrolmentRecordLocalDataSource.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/RealmEnrolmentRecordLocalDataSource.kt @@ -1,6 +1,7 @@ package com.simprints.infra.enrolment.records.repository.local import com.simprints.core.DispatcherIO +import com.simprints.core.domain.sample.Identity import com.simprints.core.tools.time.TimeHelper import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.store.models.TokenKeyType @@ -8,14 +9,14 @@ import com.simprints.infra.config.store.tokenization.TokenizationProcessor import com.simprints.infra.enrolment.records.realm.store.RealmWrapper import com.simprints.infra.enrolment.records.realm.store.models.DbSubject import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource -import com.simprints.infra.enrolment.records.repository.domain.models.FaceIdentity -import com.simprints.infra.enrolment.records.repository.domain.models.FingerprintIdentity import com.simprints.infra.enrolment.records.repository.domain.models.IdentityBatch import com.simprints.infra.enrolment.records.repository.domain.models.Subject import com.simprints.infra.enrolment.records.repository.domain.models.SubjectAction import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery import com.simprints.infra.enrolment.records.repository.local.models.toDomain import com.simprints.infra.enrolment.records.repository.local.models.toRealmDb +import com.simprints.infra.enrolment.records.repository.local.models.toRealmFaceDb +import com.simprints.infra.enrolment.records.repository.local.models.toRealmFingerprintDb import com.simprints.infra.logging.LoggingConstants.CrashReportTag.REALM_DB import com.simprints.infra.logging.Simber import io.realm.kotlin.MutableRealm @@ -74,8 +75,8 @@ internal class RealmEnrolmentRecordLocalDataSource @Inject constructor( project: Project, scope: CoroutineScope, onCandidateLoaded: suspend () -> Unit, - ): ReceiveChannel> { - val channel = Channel>(CHANNEL_CAPACITY) + ): ReceiveChannel> { + val channel = Channel>(CHANNEL_CAPACITY) scope.launch(dispatcherIO) { ranges.forEach { range -> val startTime = timeHelper.now() @@ -83,9 +84,9 @@ internal class RealmEnrolmentRecordLocalDataSource @Inject constructor( query = query, range = range, mapper = { dbSubject -> - FaceIdentity( + Identity( subjectId = dbSubject.subjectId.toString(), - faces = dbSubject.faceSamples + samples = dbSubject.faceSamples .filter { it.format == query.faceSampleFormat } .map { it.toDomain() }, ) @@ -107,8 +108,8 @@ internal class RealmEnrolmentRecordLocalDataSource @Inject constructor( project: Project, scope: CoroutineScope, onCandidateLoaded: suspend () -> Unit, - ): ReceiveChannel> { - val channel = Channel>(CHANNEL_CAPACITY) + ): ReceiveChannel> { + val channel = Channel>(CHANNEL_CAPACITY) scope.launch(dispatcherIO) { ranges.forEach { range -> val startTime = timeHelper.now() @@ -116,9 +117,9 @@ internal class RealmEnrolmentRecordLocalDataSource @Inject constructor( query = query, range = range, mapper = { dbSubject -> - FingerprintIdentity( + Identity( subjectId = dbSubject.subjectId.toString(), - fingerprints = dbSubject.fingerprintSamples + samples = dbSubject.fingerprintSamples .filter { it.format == query.fingerprintSampleFormat } .map { it.toDomain() }, ) @@ -245,10 +246,10 @@ internal class RealmEnrolmentRecordLocalDataSource @Inject constructor( // Append new samples to the list of samples that remain after removing dbSubject.faceSamples = ( - faceSamplesMap[false].orEmpty() + action.faceSamplesToAdd.map { it.toRealmDb() } + faceSamplesMap[false].orEmpty() + action.faceSamplesToAdd.map { it.toRealmFaceDb() } ).toRealmList() dbSubject.fingerprintSamples = ( - fingerprintSamplesMap[false].orEmpty() + action.fingerprintSamplesToAdd.map { it.toRealmDb() } + fingerprintSamplesMap[false].orEmpty() + action.fingerprintSamplesToAdd.map { it.toRealmFingerprintDb() } ).toRealmList() dbSubject.externalCredentials = allExternalCredentials.toRealmList() diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/RoomEnrolmentRecordLocalDataSource.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/RoomEnrolmentRecordLocalDataSource.kt index a6a056309e..292586d900 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/RoomEnrolmentRecordLocalDataSource.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/RoomEnrolmentRecordLocalDataSource.kt @@ -2,19 +2,19 @@ package com.simprints.infra.enrolment.records.repository.local import androidx.room.withTransaction import com.simprints.core.DispatcherIO -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.tools.time.TimeHelper import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.store.models.TokenKeyType import com.simprints.infra.config.store.tokenization.TokenizationProcessor import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource -import com.simprints.infra.enrolment.records.repository.domain.models.FaceIdentity -import com.simprints.infra.enrolment.records.repository.domain.models.FingerprintIdentity import com.simprints.infra.enrolment.records.repository.domain.models.IdentityBatch import com.simprints.infra.enrolment.records.repository.domain.models.SubjectAction import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery +import com.simprints.infra.enrolment.records.repository.local.models.DbSampleIdentifier import com.simprints.infra.enrolment.records.repository.local.models.toDomain import com.simprints.infra.enrolment.records.repository.local.models.toRoomDb import com.simprints.infra.enrolment.records.room.store.BuildConfig.DB_ENCRYPTION @@ -91,19 +91,20 @@ internal class RoomEnrolmentRecordLocalDataSource @Inject constructor( project: Project, scope: CoroutineScope, onCandidateLoaded: suspend () -> Unit, - ): ReceiveChannel> = loadBiometricIdentitiesPaged( + ): ReceiveChannel> = loadBiometricIdentitiesPaged( query = query, ranges = ranges, format = requireNotNull(query.faceSampleFormat) { "faceSampleFormat required" }, createIdentity = { subjectId, templates -> - FaceIdentity( + Identity( subjectId = subjectId, - faces = templates.map { sample -> - FaceSample( + samples = templates.map { sample -> + Sample( template = sample.templateData, id = sample.uuid, format = sample.format, referenceId = sample.referenceId, + modality = Modality.FACE, ) }, ) @@ -122,20 +123,23 @@ internal class RoomEnrolmentRecordLocalDataSource @Inject constructor( project: Project, scope: CoroutineScope, onCandidateLoaded: suspend () -> Unit, - ): ReceiveChannel> = loadBiometricIdentitiesPaged( + ): ReceiveChannel> = loadBiometricIdentitiesPaged( query = query, ranges = ranges, format = requireNotNull(query.fingerprintSampleFormat) { "fingerprintSampleFormat required" }, createIdentity = { subjectId, templates -> - FingerprintIdentity( + Identity( subjectId = subjectId, - fingerprints = templates.map { sample -> - FingerprintSample( - fingerIdentifier = IFingerIdentifier.entries[sample.identifier!!], + samples = templates.map { sample -> + Sample( + identifier = sample.identifier + ?.let { DbSampleIdentifier.fromId(it)?.toDomain() } + ?: SampleIdentifier.NONE, template = sample.templateData, id = sample.uuid, format = sample.format, referenceId = sample.referenceId, + modality = Modality.FINGERPRINT, ) }, ) @@ -171,7 +175,7 @@ internal class RoomEnrolmentRecordLocalDataSource @Inject constructor( onCandidateLoaded = onCandidateLoaded, ) afterSubjectId = identities.lastOrNull()?.let { - (it as? FaceIdentity)?.subjectId ?: (it as? FingerprintIdentity)?.subjectId + (it as? Identity)?.subjectId ?: (it as? Identity)?.subjectId } lastOffset = range.last + 1 val endTime = timeHelper.now() diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/DbSampleIdentifier.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/DbSampleIdentifier.kt new file mode 100644 index 0000000000..d6ab99e37a --- /dev/null +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/DbSampleIdentifier.kt @@ -0,0 +1,51 @@ +package com.simprints.infra.enrolment.records.repository.local.models + +import com.simprints.core.domain.sample.SampleIdentifier + +enum class DbSampleIdentifier( + val id: Int, +) { + RIGHT_5TH_FINGER(0), + RIGHT_4TH_FINGER(1), + RIGHT_3RD_FINGER(2), + RIGHT_INDEX_FINGER(3), + RIGHT_THUMB(4), + LEFT_THUMB(5), + LEFT_INDEX_FINGER(6), + LEFT_3RD_FINGER(7), + LEFT_4TH_FINGER(8), + LEFT_5TH_FINGER(9), + ; + + companion object Companion { + fun fromId(id: Int) = DbSampleIdentifier.entries.firstOrNull { it.id == id } + } +} + +internal fun DbSampleIdentifier?.toDomain() = when (this) { + null -> SampleIdentifier.NONE + DbSampleIdentifier.RIGHT_5TH_FINGER -> SampleIdentifier.RIGHT_5TH_FINGER + DbSampleIdentifier.RIGHT_4TH_FINGER -> SampleIdentifier.RIGHT_4TH_FINGER + DbSampleIdentifier.RIGHT_3RD_FINGER -> SampleIdentifier.RIGHT_3RD_FINGER + DbSampleIdentifier.RIGHT_INDEX_FINGER -> SampleIdentifier.RIGHT_INDEX_FINGER + DbSampleIdentifier.RIGHT_THUMB -> SampleIdentifier.RIGHT_THUMB + DbSampleIdentifier.LEFT_THUMB -> SampleIdentifier.LEFT_THUMB + DbSampleIdentifier.LEFT_INDEX_FINGER -> SampleIdentifier.LEFT_INDEX_FINGER + DbSampleIdentifier.LEFT_3RD_FINGER -> SampleIdentifier.LEFT_3RD_FINGER + DbSampleIdentifier.LEFT_4TH_FINGER -> SampleIdentifier.LEFT_4TH_FINGER + DbSampleIdentifier.LEFT_5TH_FINGER -> SampleIdentifier.LEFT_5TH_FINGER +} + +internal fun SampleIdentifier.fromDomain() = when (this) { + SampleIdentifier.NONE -> null + SampleIdentifier.RIGHT_5TH_FINGER -> DbSampleIdentifier.RIGHT_5TH_FINGER + SampleIdentifier.RIGHT_4TH_FINGER -> DbSampleIdentifier.RIGHT_4TH_FINGER + SampleIdentifier.RIGHT_3RD_FINGER -> DbSampleIdentifier.RIGHT_3RD_FINGER + SampleIdentifier.RIGHT_INDEX_FINGER -> DbSampleIdentifier.RIGHT_INDEX_FINGER + SampleIdentifier.RIGHT_THUMB -> DbSampleIdentifier.RIGHT_THUMB + SampleIdentifier.LEFT_THUMB -> DbSampleIdentifier.LEFT_THUMB + SampleIdentifier.LEFT_INDEX_FINGER -> DbSampleIdentifier.LEFT_INDEX_FINGER + SampleIdentifier.LEFT_3RD_FINGER -> DbSampleIdentifier.LEFT_3RD_FINGER + SampleIdentifier.LEFT_4TH_FINGER -> DbSampleIdentifier.LEFT_4TH_FINGER + SampleIdentifier.LEFT_5TH_FINGER -> DbSampleIdentifier.LEFT_5TH_FINGER +} diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/IFingerIdentifier.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/IFingerIdentifier.kt deleted file mode 100644 index 5f7beec9d2..0000000000 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/IFingerIdentifier.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.simprints.infra.enrolment.records.repository.local.models -import com.simprints.core.domain.fingerprint.IFingerIdentifier as CoreFingerIdentifier - -enum class IFingerIdentifier( - val id: Int, -) { - RIGHT_5TH_FINGER(0), - RIGHT_4TH_FINGER(1), - RIGHT_3RD_FINGER(2), - RIGHT_INDEX_FINGER(3), - RIGHT_THUMB(4), - LEFT_THUMB(5), - LEFT_INDEX_FINGER(6), - LEFT_3RD_FINGER(7), - LEFT_4TH_FINGER(8), - LEFT_5TH_FINGER(9), - ; - - companion object { - fun fromId(id: Int) = IFingerIdentifier.entries - .firstOrNull { it.id == id } - ?: throw IllegalArgumentException("Invalid id: $id") - } -} - -internal fun IFingerIdentifier.toDomain() = when (this) { - IFingerIdentifier.RIGHT_5TH_FINGER -> CoreFingerIdentifier.RIGHT_5TH_FINGER - IFingerIdentifier.RIGHT_4TH_FINGER -> CoreFingerIdentifier.RIGHT_4TH_FINGER - IFingerIdentifier.RIGHT_3RD_FINGER -> CoreFingerIdentifier.RIGHT_3RD_FINGER - IFingerIdentifier.RIGHT_INDEX_FINGER -> CoreFingerIdentifier.RIGHT_INDEX_FINGER - IFingerIdentifier.RIGHT_THUMB -> CoreFingerIdentifier.RIGHT_THUMB - IFingerIdentifier.LEFT_THUMB -> CoreFingerIdentifier.LEFT_THUMB - IFingerIdentifier.LEFT_INDEX_FINGER -> CoreFingerIdentifier.LEFT_INDEX_FINGER - IFingerIdentifier.LEFT_3RD_FINGER -> CoreFingerIdentifier.LEFT_3RD_FINGER - IFingerIdentifier.LEFT_4TH_FINGER -> CoreFingerIdentifier.LEFT_4TH_FINGER - IFingerIdentifier.LEFT_5TH_FINGER -> CoreFingerIdentifier.LEFT_5TH_FINGER -} - -internal fun CoreFingerIdentifier.fromDomain() = when (this) { - CoreFingerIdentifier.RIGHT_5TH_FINGER -> IFingerIdentifier.RIGHT_5TH_FINGER - CoreFingerIdentifier.RIGHT_4TH_FINGER -> IFingerIdentifier.RIGHT_4TH_FINGER - CoreFingerIdentifier.RIGHT_3RD_FINGER -> IFingerIdentifier.RIGHT_3RD_FINGER - CoreFingerIdentifier.RIGHT_INDEX_FINGER -> IFingerIdentifier.RIGHT_INDEX_FINGER - CoreFingerIdentifier.RIGHT_THUMB -> IFingerIdentifier.RIGHT_THUMB - CoreFingerIdentifier.LEFT_THUMB -> IFingerIdentifier.LEFT_THUMB - CoreFingerIdentifier.LEFT_INDEX_FINGER -> IFingerIdentifier.LEFT_INDEX_FINGER - CoreFingerIdentifier.LEFT_3RD_FINGER -> IFingerIdentifier.LEFT_3RD_FINGER - CoreFingerIdentifier.LEFT_4TH_FINGER -> IFingerIdentifier.LEFT_4TH_FINGER - CoreFingerIdentifier.LEFT_5TH_FINGER -> IFingerIdentifier.LEFT_5TH_FINGER -} diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RealmFaceSampleConverter.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RealmFaceSampleConverter.kt index 1cab7429a8..0120134b66 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RealmFaceSampleConverter.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RealmFaceSampleConverter.kt @@ -1,16 +1,18 @@ package com.simprints.infra.enrolment.records.repository.local.models -import com.simprints.core.domain.face.FaceSample +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.Sample import com.simprints.infra.enrolment.records.realm.store.models.DbFaceSample as RealmFaceSample -internal fun RealmFaceSample.toDomain(): FaceSample = FaceSample( +internal fun RealmFaceSample.toDomain(): Sample = Sample( id = id, template = template, format = format, referenceId = referenceId, + modality = Modality.FACE, ) -internal fun FaceSample.toRealmDb(): RealmFaceSample = RealmFaceSample().also { sample -> +internal fun Sample.toRealmFaceDb(): RealmFaceSample = RealmFaceSample().also { sample -> sample.id = id sample.referenceId = referenceId sample.template = template diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RealmFingerprintSampleConverter.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RealmFingerprintSampleConverter.kt index 6b2be097ba..a3e1317978 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RealmFingerprintSampleConverter.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RealmFingerprintSampleConverter.kt @@ -1,20 +1,22 @@ package com.simprints.infra.enrolment.records.repository.local.models -import com.simprints.core.domain.fingerprint.FingerprintSample +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.Sample import com.simprints.infra.enrolment.records.realm.store.models.DbFingerprintSample as RealmFingerprintSample -internal fun RealmFingerprintSample.toDomain(): FingerprintSample = FingerprintSample( +internal fun RealmFingerprintSample.toDomain(): Sample = Sample( id = id, - fingerIdentifier = IFingerIdentifier.fromId(fingerIdentifier).toDomain(), + identifier = DbSampleIdentifier.fromId(fingerIdentifier).toDomain(), template = template, format = format, referenceId = referenceId, + modality = Modality.FINGERPRINT, ) -internal fun FingerprintSample.toRealmDb(): RealmFingerprintSample = RealmFingerprintSample().also { sample -> +internal fun Sample.toRealmFingerprintDb(): RealmFingerprintSample = RealmFingerprintSample().also { sample -> sample.id = id sample.referenceId = referenceId - sample.fingerIdentifier = fingerIdentifier.fromDomain().id + sample.fingerIdentifier = identifier.fromDomain()?.id ?: -1 sample.template = template sample.format = format } diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RealmSubjectConverter.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RealmSubjectConverter.kt index 5b4ceff415..f8d1e5843d 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RealmSubjectConverter.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RealmSubjectConverter.kt @@ -1,8 +1,7 @@ package com.simprints.infra.enrolment.records.repository.local.models import com.simprints.core.domain.externalcredential.ExternalCredential -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample +import com.simprints.core.domain.sample.Sample import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.core.domain.tokenization.isTokenized @@ -31,7 +30,7 @@ internal fun RealmSubject.toDomain(): Subject { updatedAt = updatedAt?.toDate(), fingerprintSamples = fingerprintSamples.map(DbFingerprintSample::toDomain), faceSamples = faceSamples.map(DbFaceSample::toDomain), - externalCredentials = externalCredentials.map(DbExternalCredential::toDomain) + externalCredentials = externalCredentials.map(DbExternalCredential::toDomain), ) } @@ -43,8 +42,8 @@ internal fun Subject.toRealmDb(): RealmSubject = RealmSubject().also { subject - subject.createdAt = createdAt?.toRealmInstant() subject.updatedAt = updatedAt?.toRealmInstant() subject.fingerprintSamples = - fingerprintSamples.map(FingerprintSample::toRealmDb).toRealmList() - subject.faceSamples = faceSamples.map(FaceSample::toRealmDb).toRealmList() + fingerprintSamples.map(Sample::toRealmFingerprintDb).toRealmList() + subject.faceSamples = faceSamples.map(Sample::toRealmFaceDb).toRealmList() subject.isModuleIdTokenized = moduleId.isTokenized() subject.isAttendantIdTokenized = attendantId.isTokenized() subject.externalCredentials = externalCredentials.map(ExternalCredential::toRealmDb).toRealmList() diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RoomBiometricTemplateConverter.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RoomBiometricTemplateConverter.kt index f7e7954f34..90e297ae3a 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RoomBiometricTemplateConverter.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RoomBiometricTemplateConverter.kt @@ -1,40 +1,26 @@ package com.simprints.infra.enrolment.records.repository.local.models -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample +import com.simprints.core.domain.sample.Sample import com.simprints.infra.enrolment.records.room.store.models.DbBiometricTemplate -import com.simprints.infra.enrolment.records.room.store.models.Modality +import com.simprints.infra.enrolment.records.room.store.models.DbModality +import com.simprints.infra.enrolment.records.room.store.models.fromDomain +import com.simprints.infra.enrolment.records.room.store.models.toDomain -internal fun DbBiometricTemplate.toFingerprintSample(): FingerprintSample = FingerprintSample( +internal fun DbBiometricTemplate.toSample(): Sample = Sample( id = uuid, - fingerIdentifier = IFingerIdentifier.fromId(identifier!!).toDomain(), - template = templateData, - format = format, + identifier = identifier?.let { DbSampleIdentifier.fromId(it) }.toDomain(), + modality = DbModality.fromId(modality).toDomain(), referenceId = referenceId, -) - -internal fun DbBiometricTemplate.toFaceSample(): FaceSample = FaceSample( - id = uuid, - template = templateData, format = format, - referenceId = referenceId, -) - -internal fun FaceSample.toRoomDb(subjectId: String): DbBiometricTemplate = DbBiometricTemplate( - uuid = id, - templateData = template, - format = format, - subjectId = subjectId, - referenceId = referenceId, - modality = Modality.FACE.id, + template = templateData, ) -internal fun FingerprintSample.toRoomDb(subjectId: String) = DbBiometricTemplate( +internal fun Sample.toRoomDb(subjectId: String): DbBiometricTemplate = DbBiometricTemplate( uuid = id, - identifier = fingerIdentifier.fromDomain().id, templateData = template, format = format, + identifier = identifier.fromDomain()?.id, subjectId = subjectId, referenceId = referenceId, - modality = Modality.FINGERPRINT.id, + modality = modality.fromDomain().id, ) diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RoomSubjectConverter.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RoomSubjectConverter.kt index 456b54b7e6..631805e442 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RoomSubjectConverter.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/local/models/RoomSubjectConverter.kt @@ -2,7 +2,7 @@ package com.simprints.infra.enrolment.records.repository.local.models import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.infra.enrolment.records.repository.domain.models.Subject -import com.simprints.infra.enrolment.records.room.store.models.Modality +import com.simprints.infra.enrolment.records.room.store.models.DbModality import com.simprints.infra.enrolment.records.room.store.models.SubjectBiometrics import java.util.Date @@ -13,8 +13,8 @@ internal fun SubjectBiometrics.toDomain() = Subject( moduleId = subject.moduleId.asTokenizableEncrypted(), createdAt = subject.createdAt?.toDate(), updatedAt = subject.updatedAt?.toDate(), - fingerprintSamples = biometricTemplates.filter { it.modality == Modality.FINGERPRINT.id }.map { it.toFingerprintSample() }, - faceSamples = biometricTemplates.filter { it.modality == Modality.FACE.id }.map { it.toFaceSample() }, + fingerprintSamples = biometricTemplates.filter { it.modality == DbModality.FINGERPRINT.id }.map { it.toSample() }, + faceSamples = biometricTemplates.filter { it.modality == DbModality.FACE.id }.map { it.toSample() }, externalCredentials = externalCredentials.map { it.toDomain() }, ) diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/ApiEnrolmentRecord.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/ApiEnrolmentRecord.kt index 3ef913332e..9353ec3f1c 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/ApiEnrolmentRecord.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/ApiEnrolmentRecord.kt @@ -1,12 +1,11 @@ package com.simprints.infra.enrolment.records.repository.remote.models import androidx.annotation.Keep -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample +import com.simprints.core.domain.sample.Sample import com.simprints.core.tools.utils.EncodingUtils import com.simprints.infra.enrolment.records.repository.domain.models.Subject -import com.simprints.infra.enrolment.records.repository.remote.models.face.toApi -import com.simprints.infra.enrolment.records.repository.remote.models.fingerprint.toApi +import com.simprints.infra.enrolment.records.repository.remote.models.face.toFaceApi +import com.simprints.infra.enrolment.records.repository.remote.models.fingerprint.toFingerprintApi @Keep internal data class ApiEnrolmentRecord( @@ -24,17 +23,17 @@ internal fun Subject.toEnrolmentRecord(encoder: EncodingUtils): ApiEnrolmentReco ) internal fun buildBiometricReferences( - fingerprintSamples: List, - faceSamples: List, + fingerprintSamples: List, + faceSamples: List, encoder: EncodingUtils, ): List { val biometricReferences = mutableListOf() - fingerprintSamples.toApi(encoder)?.let { + fingerprintSamples.toFingerprintApi(encoder)?.let { biometricReferences.add(it) } - faceSamples.toApi(encoder)?.let { + faceSamples.toFaceApi(encoder)?.let { biometricReferences.add(it) } diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/face/ApiFaceReference.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/face/ApiFaceReference.kt index 41d0ac2807..b8ee1f1c54 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/face/ApiFaceReference.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/face/ApiFaceReference.kt @@ -3,7 +3,7 @@ package com.simprints.infra.enrolment.records.repository.remote.models.face import androidx.annotation.Keep import com.fasterxml.jackson.annotation.JsonTypeInfo import com.simprints.core.ExcludedFromGeneratedTestCoverageReports -import com.simprints.core.domain.face.FaceSample +import com.simprints.core.domain.sample.Sample import com.simprints.core.tools.utils.EncodingUtils import com.simprints.infra.enrolment.records.repository.remote.models.ApiBiometricReference @@ -20,7 +20,7 @@ internal data class ApiFaceReference( val metadata: HashMap? = null, ) : ApiBiometricReference(ApiBiometricReferenceType.FaceReference) -internal fun List.toApi(encoder: EncodingUtils): ApiFaceReference? = if (isNotEmpty()) { +internal fun List.toFaceApi(encoder: EncodingUtils): ApiFaceReference? = if (isNotEmpty()) { ApiFaceReference( first().referenceId, map { ApiFaceTemplate(encoder.byteArrayToBase64(it.template)) }, diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/fingerprint/ApiFinger.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/fingerprint/ApiFinger.kt index a28bdbe8eb..7c76a0eee5 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/fingerprint/ApiFinger.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/fingerprint/ApiFinger.kt @@ -1,7 +1,7 @@ package com.simprints.infra.enrolment.records.repository.remote.models.fingerprint import androidx.annotation.Keep -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier @Keep internal enum class ApiFinger { @@ -17,15 +17,16 @@ internal enum class ApiFinger { LEFT_5TH_FINGER, } -internal fun IFingerIdentifier.toApi(): ApiFinger = when (this) { - IFingerIdentifier.RIGHT_5TH_FINGER -> ApiFinger.RIGHT_5TH_FINGER - IFingerIdentifier.RIGHT_4TH_FINGER -> ApiFinger.RIGHT_4TH_FINGER - IFingerIdentifier.RIGHT_3RD_FINGER -> ApiFinger.RIGHT_3RD_FINGER - IFingerIdentifier.RIGHT_INDEX_FINGER -> ApiFinger.RIGHT_INDEX_FINGER - IFingerIdentifier.RIGHT_THUMB -> ApiFinger.RIGHT_THUMB - IFingerIdentifier.LEFT_THUMB -> ApiFinger.LEFT_THUMB - IFingerIdentifier.LEFT_INDEX_FINGER -> ApiFinger.LEFT_INDEX_FINGER - IFingerIdentifier.LEFT_3RD_FINGER -> ApiFinger.LEFT_3RD_FINGER - IFingerIdentifier.LEFT_4TH_FINGER -> ApiFinger.LEFT_4TH_FINGER - IFingerIdentifier.LEFT_5TH_FINGER -> ApiFinger.LEFT_5TH_FINGER +internal fun SampleIdentifier.toApi(): ApiFinger = when (this) { + SampleIdentifier.RIGHT_5TH_FINGER -> ApiFinger.RIGHT_5TH_FINGER + SampleIdentifier.RIGHT_4TH_FINGER -> ApiFinger.RIGHT_4TH_FINGER + SampleIdentifier.RIGHT_3RD_FINGER -> ApiFinger.RIGHT_3RD_FINGER + SampleIdentifier.RIGHT_INDEX_FINGER -> ApiFinger.RIGHT_INDEX_FINGER + SampleIdentifier.RIGHT_THUMB -> ApiFinger.RIGHT_THUMB + SampleIdentifier.LEFT_THUMB -> ApiFinger.LEFT_THUMB + SampleIdentifier.LEFT_INDEX_FINGER -> ApiFinger.LEFT_INDEX_FINGER + SampleIdentifier.LEFT_3RD_FINGER -> ApiFinger.LEFT_3RD_FINGER + SampleIdentifier.LEFT_4TH_FINGER -> ApiFinger.LEFT_4TH_FINGER + SampleIdentifier.LEFT_5TH_FINGER -> ApiFinger.LEFT_5TH_FINGER + SampleIdentifier.NONE -> throw IllegalArgumentException("Must be a finger sample identifier") } diff --git a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/fingerprint/ApiFingerprintReference.kt b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/fingerprint/ApiFingerprintReference.kt index f301bffe29..58ad01c6ff 100644 --- a/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/fingerprint/ApiFingerprintReference.kt +++ b/infra/enrolment-records/repository/src/main/java/com/simprints/infra/enrolment/records/repository/remote/models/fingerprint/ApiFingerprintReference.kt @@ -3,7 +3,7 @@ package com.simprints.infra.enrolment.records.repository.remote.models.fingerpri import androidx.annotation.Keep import com.fasterxml.jackson.annotation.JsonTypeInfo import com.simprints.core.ExcludedFromGeneratedTestCoverageReports -import com.simprints.core.domain.fingerprint.FingerprintSample +import com.simprints.core.domain.sample.Sample import com.simprints.core.tools.utils.EncodingUtils import com.simprints.infra.enrolment.records.repository.remote.models.ApiBiometricReference @@ -20,13 +20,13 @@ internal data class ApiFingerprintReference( val metadata: HashMap? = null, ) : ApiBiometricReference(ApiBiometricReferenceType.FingerprintReference) -internal fun List.toApi(encoder: EncodingUtils): ApiFingerprintReference? = if (isNotEmpty()) { +internal fun List.toFingerprintApi(encoder: EncodingUtils): ApiFingerprintReference? = if (isNotEmpty()) { ApiFingerprintReference( first().referenceId, map { ApiFingerprintTemplate( encoder.byteArrayToBase64(it.template), - it.fingerIdentifier.toApi(), + it.identifier.toApi(), ) }, first().format, diff --git a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/EnrolmentRecordRepositoryImplTest.kt b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/EnrolmentRecordRepositoryImplTest.kt index aa96205a26..839071e228 100644 --- a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/EnrolmentRecordRepositoryImplTest.kt +++ b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/EnrolmentRecordRepositoryImplTest.kt @@ -1,6 +1,7 @@ package com.simprints.infra.enrolment.records.repository import android.content.SharedPreferences +import com.simprints.core.domain.sample.Identity import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.core.tools.time.Timestamp @@ -8,8 +9,6 @@ import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.store.models.TokenKeyType import com.simprints.infra.config.store.tokenization.TokenizationProcessor import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource -import com.simprints.infra.enrolment.records.repository.domain.models.FaceIdentity -import com.simprints.infra.enrolment.records.repository.domain.models.FingerprintIdentity import com.simprints.infra.enrolment.records.repository.domain.models.IdentityBatch import com.simprints.infra.enrolment.records.repository.domain.models.Subject import com.simprints.infra.enrolment.records.repository.domain.models.SubjectAction @@ -287,7 +286,7 @@ class EnrolmentRecordRepositoryImplTest { fun `should forward the call to the local data source when loading fingerprint identities and dataSource is Simprints`() = runTest { val expectedSubjectQuery = SubjectQuery() val expectedRange = listOf(0..10) - val expectedFingerprintIdentities = listOf() + val expectedFingerprintIdentities = listOf() coEvery { localDataSource.loadFingerprintIdentities( expectedSubjectQuery, @@ -299,7 +298,7 @@ class EnrolmentRecordRepositoryImplTest { ) } returns createTestChannel(expectedFingerprintIdentities) - val fingerprintIdentities = mutableListOf() + val fingerprintIdentities = mutableListOf() repository .loadFingerprintIdentities( query = expectedSubjectQuery, @@ -329,7 +328,7 @@ class EnrolmentRecordRepositoryImplTest { fun `should forward the call to the commcare data source when loading fingerprint identities and dataSource is CommCare`() = runTest { val expectedSubjectQuery = SubjectQuery() val expectedRange = listOf(0..10) - val expectedFingerprintIdentities = listOf() + val expectedFingerprintIdentities = listOf() coEvery { commCareDataSource.loadFingerprintIdentities( expectedSubjectQuery, @@ -340,7 +339,7 @@ class EnrolmentRecordRepositoryImplTest { onCandidateLoaded, ) } returns createTestChannel(expectedFingerprintIdentities) - val fingerprintIdentities = mutableListOf() + val fingerprintIdentities = mutableListOf() repository .loadFingerprintIdentities( query = expectedSubjectQuery, @@ -370,7 +369,7 @@ class EnrolmentRecordRepositoryImplTest { fun `should forward the call to the local data source when loading face identities and dataSource is Simprints`() = runTest { val expectedSubjectQuery = SubjectQuery() val expectedRange = listOf(0..10) - val expectedFaceIdentities = listOf() + val expectedFaceIdentities = listOf() coEvery { localDataSource.loadFaceIdentities( expectedSubjectQuery, @@ -382,7 +381,7 @@ class EnrolmentRecordRepositoryImplTest { ) } returns createTestChannel(expectedFaceIdentities) - val faceIdentities = mutableListOf() + val faceIdentities = mutableListOf() repository .loadFaceIdentities( query = expectedSubjectQuery, @@ -412,7 +411,7 @@ class EnrolmentRecordRepositoryImplTest { fun `should forward the call to the commcare data source when loading face identities and dataSource is CommCare`() = runTest { val expectedSubjectQuery = SubjectQuery() val expectedRange = listOf(0..10) - val expectedFaceIdentities = listOf() + val expectedFaceIdentities = listOf() coEvery { commCareDataSource.loadFaceIdentities( expectedSubjectQuery, @@ -424,7 +423,7 @@ class EnrolmentRecordRepositoryImplTest { ) } returns createTestChannel(expectedFaceIdentities) - val faceIdentities = mutableListOf() + val faceIdentities = mutableListOf() repository .loadFaceIdentities( @@ -461,7 +460,7 @@ class EnrolmentRecordRepositoryImplTest { identities = list, loadingStartTime = Timestamp(time++), loadingEndTime = Timestamp(time++), - ) + ), ) } channel.close() diff --git a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/commcare/CommCareIdentityDataSourceTest.kt b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/commcare/CommCareIdentityDataSourceTest.kt index e747f16a3a..76427f95dc 100644 --- a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/commcare/CommCareIdentityDataSourceTest.kt +++ b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/commcare/CommCareIdentityDataSourceTest.kt @@ -4,10 +4,11 @@ import android.content.ContentResolver import android.content.Context import android.database.Cursor import android.net.Uri -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample -import com.simprints.core.domain.fingerprint.IFingerIdentifier.LEFT_INDEX_FINGER -import com.simprints.core.domain.fingerprint.IFingerIdentifier.LEFT_THUMB +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier.LEFT_INDEX_FINGER +import com.simprints.core.domain.sample.SampleIdentifier.LEFT_THUMB import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.tools.json.JsonHelper import com.simprints.core.tools.time.TimeHelper @@ -17,8 +18,6 @@ import com.simprints.infra.config.store.models.Project import com.simprints.infra.enrolment.records.repository.commcare.CommCareIdentityDataSource.Companion.COLUMN_DATUM_ID import com.simprints.infra.enrolment.records.repository.commcare.CommCareIdentityDataSource.Companion.COLUMN_VALUE import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource -import com.simprints.infra.enrolment.records.repository.domain.models.FaceIdentity -import com.simprints.infra.enrolment.records.repository.domain.models.FingerprintIdentity import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery import com.simprints.infra.enrolment.records.repository.usecases.CompareImplicitTokenizedStringsUseCase import com.simprints.infra.logging.Simber @@ -51,59 +50,65 @@ class CommCareIdentityDataSourceTest { """{"events":[{"id":"0dafcd03-96c4-4ca5-b802-292da6d4f799","payload":{"subjectId":"a961fcb4-8573-4270-a1b2-088e88275b00","projectId":"nXcj9neYhXP9rFp56uWk","moduleId":{"value":"AWuA3H0WGtHI2uod+ePZ3yiWTt9etQ=="},"attendantId":{"value":"AdySMrjuy7uq0Dcxov3rUFIw66uXTFrKd0BnzSr9MYXl5maWEpyKQT8AUdcPuVHUWpOkO88="},"biometricReferences":[{"id":"2b9b4991-29d7-3eee-ac02-191afaa0c1a2","templates":[{"quality":77,"template":"123","finger":"LEFT_THUMB"},{"quality":66,"template":"123","finger":"LEFT_INDEX_FINGER"}],"format":"NEC_1_5","type":"FINGERPRINT_REFERENCE"},{"id":"2b9b4991-29d7-3eee-ac02-191afaa0c1a2","templates":[{"template":"123"}],"format":"ROC_3","type":"FACE_REFERENCE"}]},"type":"EnrolmentRecordCreation"}]}""" private val expectedFingerprintIdentities = listOf( - FingerprintIdentity( + Identity( subjectId = "b26c91bc-b307-4131-80c3-55090ba5dbf2", - fingerprints = listOf( - FingerprintSample( - fingerIdentifier = LEFT_THUMB, + samples = listOf( + Sample( + identifier = LEFT_THUMB, template = byteArrayOf(), format = "ISO_19794_2", referenceId = "referenceId", + modality = Modality.FINGERPRINT, ), - FingerprintSample( - fingerIdentifier = LEFT_INDEX_FINGER, + Sample( + identifier = LEFT_INDEX_FINGER, template = byteArrayOf(), format = "ISO_19794_2", referenceId = "referenceId", + modality = Modality.FINGERPRINT, ), ), ), - FingerprintIdentity( + Identity( subjectId = "a961fcb4-8573-4270-a1b2-088e88275b00", - fingerprints = listOf( - FingerprintSample( - fingerIdentifier = LEFT_THUMB, + samples = listOf( + Sample( + identifier = LEFT_THUMB, template = byteArrayOf(), format = "ISO_19794_2", referenceId = "referenceId", + modality = Modality.FINGERPRINT, ), - FingerprintSample( - fingerIdentifier = LEFT_INDEX_FINGER, + Sample( + identifier = LEFT_INDEX_FINGER, template = byteArrayOf(), format = "ISO_19794_2", referenceId = "referenceId", + modality = Modality.FINGERPRINT, ), ), ), ) val expectedFaceIdentities = listOf( - FaceIdentity( + Identity( subjectId = "b26c91bc-b307-4131-80c3-55090ba5dbf2", - faces = listOf( - FaceSample( + samples = listOf( + Sample( template = byteArrayOf(), format = "ROC_1_23", referenceId = "referenceId", + modality = Modality.FACE, ), ), ), - FaceIdentity( + Identity( subjectId = "a961fcb4-8573-4270-a1b2-088e88275b00", - faces = listOf( - FaceSample( + samples = listOf( + Sample( template = byteArrayOf(), format = "ROC_3", referenceId = "referenceId", + modality = Modality.FACE, ), ), ), @@ -246,7 +251,7 @@ class CommCareIdentityDataSourceTest { val templateFormat = "ISO_19794_2" val query = SubjectQuery(fingerprintSampleFormat = templateFormat) val range = 0..expectedFingerprintIdentities.size - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFingerprintIdentities( @@ -263,12 +268,12 @@ class CommCareIdentityDataSourceTest { assertEquals(1, actualIdentities.size) val areContentsEqual = expectedFingerprintIdentities - .filter { identity -> identity.fingerprints.any { it.format == templateFormat } } + .filter { identity -> identity.samples.any { it.format == templateFormat } } .zip(actualIdentities) { expected, actual -> expected.subjectId == actual.subjectId && - expected.fingerprints - .zip(actual.fingerprints) { expectedFingerprint, actualFingerprint -> - expectedFingerprint.fingerIdentifier == actualFingerprint.fingerIdentifier && + expected.samples + .zip(actual.samples) { expectedFingerprint, actualFingerprint -> + expectedFingerprint.identifier == actualFingerprint.identifier && expectedFingerprint.template.contentEquals( actualFingerprint.template, ) && @@ -308,7 +313,7 @@ class CommCareIdentityDataSourceTest { subjectId = "b26c91bc-b307-4131-80c3-55090ba5dbf2", ) val range = 0..expectedFaceIdentities.size - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFaceIdentities( query = query, @@ -324,11 +329,11 @@ class CommCareIdentityDataSourceTest { assertEquals(1, actualIdentities.size) val areContentsEqual = expectedFaceIdentities - .filter { identity -> identity.faces.any { it.format == templateFormat } } + .filter { identity -> identity.samples.any { it.format == templateFormat } } .zip(actualIdentities) { expected, actual -> expected.subjectId == actual.subjectId && - expected.faces - .zip(actual.faces) { expectedFace, actualFace -> + expected.samples + .zip(actual.samples) { expectedFace, actualFace -> expectedFace.template.contentEquals(actualFace.template) && expectedFace.format == actualFace.format }.all { it } }.all { it } @@ -361,7 +366,7 @@ class CommCareIdentityDataSourceTest { val templateFormat = "NEC_1_5" val query = SubjectQuery(fingerprintSampleFormat = templateFormat) val range = 0..expectedFingerprintIdentities.size - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFingerprintIdentities( query = query, @@ -377,12 +382,12 @@ class CommCareIdentityDataSourceTest { assertEquals(1, actualIdentities.size) val areContentsEqual = expectedFingerprintIdentities - .filter { identity -> identity.fingerprints.any { it.format == templateFormat } } + .filter { identity -> identity.samples.any { it.format == templateFormat } } .zip(actualIdentities) { expected, actual -> expected.subjectId == actual.subjectId && - expected.fingerprints - .zip(actual.fingerprints) { expectedFingerprint, actualFingerprint -> - expectedFingerprint.fingerIdentifier == actualFingerprint.fingerIdentifier && + expected.samples + .zip(actual.samples) { expectedFingerprint, actualFingerprint -> + expectedFingerprint.identifier == actualFingerprint.identifier && expectedFingerprint.template.contentEquals( actualFingerprint.template, ) && @@ -419,7 +424,7 @@ class CommCareIdentityDataSourceTest { val templateFormat = "ROC_1_23" val query = SubjectQuery(faceSampleFormat = templateFormat) val range = 0..expectedFaceIdentities.size - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFaceIdentities( query = query, @@ -435,11 +440,11 @@ class CommCareIdentityDataSourceTest { assertEquals(1, actualIdentities.size) val areContentsEqual = expectedFaceIdentities - .filter { identity -> identity.faces.any { it.format == templateFormat } } + .filter { identity -> identity.samples.any { it.format == templateFormat } } .zip(actualIdentities) { expected, actual -> expected.subjectId == actual.subjectId && - expected.faces - .zip(actual.faces) { expectedFace, actualFace -> + expected.samples + .zip(actual.samples) { expectedFace, actualFace -> expectedFace.template.contentEquals(actualFace.template) && expectedFace.format == actualFace.format }.all { it } }.all { it } @@ -469,7 +474,7 @@ class CommCareIdentityDataSourceTest { val templateFormat = "ISO_19794_2" val query = SubjectQuery(fingerprintSampleFormat = templateFormat) val range = 0..expectedFingerprintIdentities.size - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFingerprintIdentities( query = query, @@ -485,12 +490,12 @@ class CommCareIdentityDataSourceTest { assertEquals(1, actualIdentities.size) val areContentsEqual = expectedFingerprintIdentities - .filter { identity -> identity.fingerprints.any { it.format == templateFormat } } + .filter { identity -> identity.samples.any { it.format == templateFormat } } .zip(actualIdentities) { expected, actual -> expected.subjectId == actual.subjectId && - expected.fingerprints - .zip(actual.fingerprints) { expectedFingerprint, actualFingerprint -> - expectedFingerprint.fingerIdentifier == actualFingerprint.fingerIdentifier && + expected.samples + .zip(actual.samples) { expectedFingerprint, actualFingerprint -> + expectedFingerprint.identifier == actualFingerprint.identifier && expectedFingerprint.template.contentEquals( actualFingerprint.template, ) && @@ -523,7 +528,7 @@ class CommCareIdentityDataSourceTest { val templateFormat = "ROC_1_23" val query = SubjectQuery(faceSampleFormat = templateFormat) val range = 0..expectedFaceIdentities.size - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFaceIdentities( query = query, @@ -539,11 +544,11 @@ class CommCareIdentityDataSourceTest { assertEquals(1, actualIdentities.size) val areContentsEqual = expectedFaceIdentities - .filter { identity -> identity.faces.any { it.format == templateFormat } } + .filter { identity -> identity.samples.any { it.format == templateFormat } } .zip(actualIdentities) { expected, actual -> expected.subjectId == actual.subjectId && - expected.faces - .zip(actual.faces) { expectedFace, actualFace -> + expected.samples + .zip(actual.samples) { expectedFace, actualFace -> expectedFace.template.contentEquals(actualFace.template) && expectedFace.format == actualFace.format }.all { it } }.all { it } @@ -579,7 +584,7 @@ class CommCareIdentityDataSourceTest { val query = SubjectQuery() val range = 0..0 - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFingerprintIdentities( query = query, @@ -611,7 +616,7 @@ class CommCareIdentityDataSourceTest { val query = SubjectQuery() val range = 2..3 - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFingerprintIdentities( query = query, @@ -660,7 +665,7 @@ class CommCareIdentityDataSourceTest { val templateFormat = "ISO_19794_2" val query = SubjectQuery(fingerprintSampleFormat = templateFormat) val range = expectedFingerprintIdentities.indices - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFingerprintIdentities( query = query, @@ -676,12 +681,12 @@ class CommCareIdentityDataSourceTest { assertEquals(1, actualIdentities.size) val areContentsEqual = expectedFingerprintIdentities - .filter { identity -> identity.fingerprints.any { it.format == templateFormat } } + .filter { identity -> identity.samples.any { it.format == templateFormat } } .zip(actualIdentities) { expected, actual -> expected.subjectId == actual.subjectId && - expected.fingerprints - .zip(actual.fingerprints) { expectedFingerprint, actualFingerprint -> - expectedFingerprint.fingerIdentifier == actualFingerprint.fingerIdentifier && + expected.samples + .zip(actual.samples) { expectedFingerprint, actualFingerprint -> + expectedFingerprint.identifier == actualFingerprint.identifier && expectedFingerprint.template.contentEquals( actualFingerprint.template, ) && @@ -703,7 +708,7 @@ class CommCareIdentityDataSourceTest { val query = SubjectQuery() val range = 0..2 - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFingerprintIdentities( query = query, @@ -743,7 +748,7 @@ class CommCareIdentityDataSourceTest { val query = SubjectQuery() val range = 0..2 - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFingerprintIdentities( query = query, @@ -787,7 +792,7 @@ class CommCareIdentityDataSourceTest { val query = SubjectQuery() val range = 0..2 - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFingerprintIdentities( query = query, @@ -818,7 +823,7 @@ class CommCareIdentityDataSourceTest { val query = SubjectQuery() val range = 0..2 - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFingerprintIdentities( query = query, @@ -854,7 +859,7 @@ class CommCareIdentityDataSourceTest { val query = SubjectQuery() val range = 0..2 - val actualIdentities = mutableListOf() + val actualIdentities = mutableListOf() dataSource .loadFingerprintIdentities( query = query, @@ -930,14 +935,15 @@ class CommCareIdentityDataSourceTest { every { mockDataCursor.getString(1) } returns SUBJECT_ACTIONS_FINGERPRINT_1 val query = SubjectQuery(metadata = "test-metadata") - dataSource.loadFingerprintIdentities( - query = query, - ranges = listOf(0..1), - project = project, - dataSource = commCareBiometricDataSource, - scope = this, - onCandidateLoaded = { onCandidateLoadedCalled = true } - ).consumeEach { } + dataSource + .loadFingerprintIdentities( + query = query, + ranges = listOf(0..1), + project = project, + dataSource = commCareBiometricDataSource, + scope = this, + onCandidateLoaded = { onCandidateLoadedCalled = true }, + ).consumeEach { } assertTrue(onCandidateLoadedCalled) coVerify { mockContentResolver.query(mockDataCaseIdUri, any(), any(), any(), any()) } diff --git a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/domain/models/FingerIdentifierTest.kt b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/domain/models/FingerIdentifierTest.kt deleted file mode 100644 index 8c2791f54d..0000000000 --- a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/domain/models/FingerIdentifierTest.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.simprints.infra.enrolment.records.repository.domain.models - -import com.google.common.truth.Truth -import com.simprints.core.domain.fingerprint.IFingerIdentifier -import org.junit.Test - -class FingerIdentifierTest { - @Test - fun `should map correctly the Finger enums`() { - val mapping = mapOf( - IFingerIdentifier.LEFT_THUMB to FingerIdentifier.LEFT_THUMB, - IFingerIdentifier.LEFT_INDEX_FINGER to FingerIdentifier.LEFT_INDEX_FINGER, - IFingerIdentifier.LEFT_3RD_FINGER to FingerIdentifier.LEFT_3RD_FINGER, - IFingerIdentifier.LEFT_4TH_FINGER to FingerIdentifier.LEFT_4TH_FINGER, - IFingerIdentifier.LEFT_5TH_FINGER to FingerIdentifier.LEFT_5TH_FINGER, - IFingerIdentifier.RIGHT_THUMB to FingerIdentifier.RIGHT_THUMB, - IFingerIdentifier.RIGHT_INDEX_FINGER to FingerIdentifier.RIGHT_INDEX_FINGER, - IFingerIdentifier.RIGHT_3RD_FINGER to FingerIdentifier.RIGHT_3RD_FINGER, - IFingerIdentifier.RIGHT_4TH_FINGER to FingerIdentifier.RIGHT_4TH_FINGER, - IFingerIdentifier.RIGHT_5TH_FINGER to FingerIdentifier.RIGHT_5TH_FINGER, - ) - - mapping.forEach { - Truth.assertThat(it.key.fromModuleApiToDomain()).isEqualTo(it.value) - Truth.assertThat(it.value.fromDomainToModuleApi()).isEqualTo(it.key) - } - } -} diff --git a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/local/RealmEnrolmentRecordLocalDataSourceTest.kt b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/local/RealmEnrolmentRecordLocalDataSourceTest.kt index a87c08bd00..dea9e53373 100644 --- a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/local/RealmEnrolmentRecordLocalDataSourceTest.kt +++ b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/local/RealmEnrolmentRecordLocalDataSourceTest.kt @@ -1,11 +1,12 @@ package com.simprints.infra.enrolment.records.repository.local import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredential import com.simprints.core.domain.externalcredential.ExternalCredentialType -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.core.tools.time.TimeHelper @@ -17,8 +18,6 @@ import com.simprints.infra.enrolment.records.realm.store.models.DbFaceSample import com.simprints.infra.enrolment.records.realm.store.models.DbFingerprintSample import com.simprints.infra.enrolment.records.realm.store.models.DbSubject import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource -import com.simprints.infra.enrolment.records.repository.domain.models.FaceIdentity -import com.simprints.infra.enrolment.records.repository.domain.models.FingerprintIdentity import com.simprints.infra.enrolment.records.repository.domain.models.Subject import com.simprints.infra.enrolment.records.repository.domain.models.SubjectAction import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery @@ -146,7 +145,7 @@ class RealmEnrolmentRecordLocalDataSourceTest { val savedPersons = saveFakePeople(getRandomPeople(20)) val fakePerson = savedPersons[0].toRealmDb() - val people = mutableListOf() + val people = mutableListOf() enrolmentRecordLocalDataSource .loadFingerprintIdentities( SubjectQuery(), @@ -210,7 +209,7 @@ class RealmEnrolmentRecordLocalDataSourceTest { val savedPersons = saveFakePeople(getRandomPeople(20)) val fakePerson = savedPersons[0].toRealmDb() - val people = mutableListOf() + val people = mutableListOf() enrolmentRecordLocalDataSource .loadFaceIdentities( SubjectQuery(), @@ -502,11 +501,11 @@ class RealmEnrolmentRecordLocalDataSourceTest { projectId: String = UUID.randomUUID().toString(), userId: String = UUID.randomUUID().toString(), moduleId: String = UUID.randomUUID().toString(), - faceSamples: List = listOf( + faceSamples: List = listOf( getRandomFaceSample(), getRandomFaceSample(), ), - fingerprintSamples: List = listOf(), + fingerprintSamples: List = listOf(), externalCredentials: List = listOf( getRandomExternalCredential(), ), @@ -523,12 +522,25 @@ class RealmEnrolmentRecordLocalDataSourceTest { private fun getRandomFaceSample( id: String = UUID.randomUUID().toString(), referenceId: String = "referenceId", - ) = FaceSample(Random.nextBytes(64), "faceTemplateFormat", referenceId, id) + ) = Sample( + id = id, + referenceId = referenceId, + template = Random.nextBytes(64), + format = "faceTemplateFormat", + modality = Modality.FACE, + ) private fun getRandomFingerprintSample( id: String = UUID.randomUUID().toString(), referenceId: String = "referenceId", - ) = FingerprintSample(IFingerIdentifier.LEFT_3RD_FINGER, Random.nextBytes(64), "fingerprintTemplateFormat", referenceId, id) + ) = Sample( + id = id, + referenceId = referenceId, + identifier = SampleIdentifier.LEFT_3RD_FINGER, + template = Random.nextBytes(64), + format = "fingerprintTemplateFormat", + modality = Modality.FINGERPRINT, + ) private fun getRandomExternalCredential(id: String = "id") = ExternalCredential( id = id, diff --git a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/local/RoomEnrolmentRecordLocalDataSourceTest.kt b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/local/RoomEnrolmentRecordLocalDataSourceTest.kt index 1b82dd0813..b6e8ad9d82 100644 --- a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/local/RoomEnrolmentRecordLocalDataSourceTest.kt +++ b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/local/RoomEnrolmentRecordLocalDataSourceTest.kt @@ -2,11 +2,11 @@ package com.simprints.infra.enrolment.records.repository.local import androidx.test.core.app.* import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredential import com.simprints.core.domain.externalcredential.ExternalCredentialType -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.tools.time.TimeHelper @@ -72,44 +72,50 @@ class RoomEnrolmentRecordLocalDataSourceTest { private val date = Date() // Use a fixed date for consistent timestamps in tests // Samples defined first - private val faceSample1 = FaceSample( + private val faceSample1 = Sample( template = byteArrayOf(1, 2, 3), format = ROC_1_FORMAT, referenceId = "ref-face-1", id = "face-uuid-1", + modality = Modality.FACE, ) - private val faceSample2 = FaceSample( + private val faceSample2 = Sample( template = byteArrayOf(4, 5, 6), format = ROC_3_FORMAT, referenceId = "ref-face-2", id = "face-uuid-2", + modality = Modality.FACE, ) - private val faceSample3 = FaceSample( + private val faceSample3 = Sample( template = byteArrayOf(7, 8, 9), format = ROC_1_FORMAT, referenceId = "ref-face-3-p2", id = "face-uuid-3-p2", + modality = Modality.FACE, ) - private val fingerprintSample1 = FingerprintSample( - fingerIdentifier = IFingerIdentifier.LEFT_THUMB, + private val fingerprintSample1 = Sample( + identifier = SampleIdentifier.LEFT_THUMB, template = byteArrayOf(10, 11), format = NEC_FORMAT, referenceId = "ref-fp-1", id = "fp-uuid-1", + modality = Modality.FINGERPRINT, ) - private val fingerprintSample2 = FingerprintSample( - fingerIdentifier = IFingerIdentifier.RIGHT_THUMB, + private val fingerprintSample2 = Sample( + identifier = SampleIdentifier.RIGHT_THUMB, template = byteArrayOf(12, 13), format = ISO_FORMAT, referenceId = "ref-fp-2", id = "fp-uuid-2", + modality = Modality.FINGERPRINT, ) - private val fingerprintSample3 = FingerprintSample( - fingerIdentifier = IFingerIdentifier.LEFT_INDEX_FINGER, + private val fingerprintSample3 = Sample( + identifier = SampleIdentifier.LEFT_INDEX_FINGER, template = byteArrayOf(14, 15), format = NEC_FORMAT, referenceId = "ref-fp-3-p2", id = "fp-uuid-3-p2", + modality = Modality.FINGERPRINT, ) // Subjects defined using the samples @@ -871,22 +877,22 @@ class RoomEnrolmentRecordLocalDataSourceTest { // Then - P1 NEC assertThat(loadedP1Nec).hasSize(1) assertThat(loadedP1Nec[0].subjectId).isEqualTo(subject2P1WithFinger.subjectId) - assertThat(loadedP1Nec[0].fingerprints).hasSize(1) - assertThat(loadedP1Nec[0].fingerprints[0].format).isEqualTo(NEC_FORMAT) - assertThat(loadedP1Nec[0].fingerprints).isEqualTo(subject2P1WithFinger.fingerprintSamples) + assertThat(loadedP1Nec[0].samples).hasSize(1) + assertThat(loadedP1Nec[0].samples[0].format).isEqualTo(NEC_FORMAT) + assertThat(loadedP1Nec[0].samples).isEqualTo(subject2P1WithFinger.fingerprintSamples) // Then - P1 ISO assertThat(loadedP1Iso).hasSize(1) assertThat(loadedP1Iso[0].subjectId).isEqualTo(subject3P1WithBoth.subjectId) - assertThat(loadedP1Iso[0].fingerprints).hasSize(1) - assertThat(loadedP1Iso[0].fingerprints[0].format).isEqualTo(ISO_FORMAT) - assertThat(loadedP1Iso[0].fingerprints).isEqualTo(subject3P1WithBoth.fingerprintSamples) + assertThat(loadedP1Iso[0].samples).hasSize(1) + assertThat(loadedP1Iso[0].samples[0].format).isEqualTo(ISO_FORMAT) + assertThat(loadedP1Iso[0].samples).isEqualTo(subject3P1WithBoth.fingerprintSamples) // Then - P2 NEC assertThat(loadedP2Nec).hasSize(2) assertThat(loadedP2Nec[0].subjectId).isEqualTo(subject4P2WithBoth.subjectId) - assertThat(loadedP2Nec[0].fingerprints).hasSize(1) - assertThat(loadedP2Nec[0].fingerprints[0].format).isEqualTo(NEC_FORMAT) + assertThat(loadedP2Nec[0].samples).hasSize(1) + assertThat(loadedP2Nec[0].samples[0].format).isEqualTo(NEC_FORMAT) verify(exactly = 4) { mockCallback() } } @@ -1079,16 +1085,16 @@ class RoomEnrolmentRecordLocalDataSourceTest { // Then - P1 ROC_1 assertThat(loadedP1Roc1).hasSize(1) assertThat(loadedP1Roc1[0].subjectId).isEqualTo(subject1P1WithFace.subjectId) - assertThat(loadedP1Roc1[0].faces).hasSize(1) - assertThat(loadedP1Roc1[0].faces[0].format).isEqualTo(ROC_1_FORMAT) - assertThat(loadedP1Roc1[0].faces).isEqualTo(subject1P1WithFace.faceSamples) + assertThat(loadedP1Roc1[0].samples).hasSize(1) + assertThat(loadedP1Roc1[0].samples[0].format).isEqualTo(ROC_1_FORMAT) + assertThat(loadedP1Roc1[0].samples).isEqualTo(subject1P1WithFace.faceSamples) // Then - P1 ROC_3 assertThat(loadedP1Roc3).hasSize(1) assertThat(loadedP1Roc3[0].subjectId).isEqualTo(subject3P1WithBoth.subjectId) - assertThat(loadedP1Roc3[0].faces).hasSize(1) - assertThat(loadedP1Roc3[0].faces[0].format).isEqualTo(ROC_3_FORMAT) - assertThat(loadedP1Roc3[0].faces).isEqualTo(subject3P1WithBoth.faceSamples) + assertThat(loadedP1Roc3[0].samples).hasSize(1) + assertThat(loadedP1Roc3[0].samples[0].format).isEqualTo(ROC_3_FORMAT) + assertThat(loadedP1Roc3[0].samples).isEqualTo(subject3P1WithBoth.faceSamples) // Then - P2 ROC_1 assertThat(loadedP2Roc1).hasSize(2) diff --git a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/local/models/DbSubjectTest.kt b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/local/models/DbSubjectTest.kt index 74bd034aee..4ace060947 100644 --- a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/local/models/DbSubjectTest.kt +++ b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/local/models/DbSubjectTest.kt @@ -1,9 +1,9 @@ package com.simprints.infra.enrolment.records.repository.local.models -import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.infra.enrolment.records.realm.store.models.DbFaceSample import com.simprints.infra.enrolment.records.realm.store.models.DbFingerprintSample @@ -27,13 +27,19 @@ class DbSubjectTest { @Test fun fromDomainToDbModel() { - val fingerprintSample = FingerprintSample( - IFingerIdentifier.RIGHT_3RD_FINGER, - Random.nextBytes(64), - "NEC_1", - REFERENCE_ID, + val fingerprintSample = Sample( + identifier = SampleIdentifier.RIGHT_3RD_FINGER, + template = Random.nextBytes(64), + format = "NEC_1", + referenceId = REFERENCE_ID, + modality = Modality.FINGERPRINT, + ) + val faceSample = Sample( + template = Random.nextBytes(64), + format = "RANK_ONE_1_23", + referenceId = REFERENCE_ID, + modality = Modality.FACE, ) - val faceSample = FaceSample(Random.nextBytes(64), "RANK_ONE_1_23", REFERENCE_ID) val domainSubject = Subject( subjectId = GUID, @@ -65,7 +71,7 @@ class DbSubjectTest { @Test fun fromDbModelToDomain() { val fingerprintSample = DbFingerprintSample().apply { - fingerIdentifier = IFingerIdentifier.RIGHT_3RD_FINGER.ordinal + fingerIdentifier = SampleIdentifier.RIGHT_3RD_FINGER.ordinal template = Random.nextBytes(64) format = "NEC_1" referenceId = REFERENCE_ID diff --git a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/remote/EnrolmentRecordRemoteDataSourceImplTest.kt b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/remote/EnrolmentRecordRemoteDataSourceImplTest.kt index f22b4353c9..981786d2c1 100644 --- a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/remote/EnrolmentRecordRemoteDataSourceImplTest.kt +++ b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/remote/EnrolmentRecordRemoteDataSourceImplTest.kt @@ -1,9 +1,9 @@ package com.simprints.infra.enrolment.records.repository.remote -import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.tools.utils.EncodingUtils import com.simprints.infra.authstore.AuthStore @@ -20,10 +20,7 @@ import com.simprints.infra.network.exceptions.BackendMaintenanceException import com.simprints.infra.network.exceptions.SyncCloudIntegrationException import com.simprints.testtools.common.alias.InterfaceInvocation import com.simprints.testtools.common.syntax.assertThrows -import io.mockk.coEvery -import io.mockk.coVerify -import io.mockk.every -import io.mockk.mockk +import io.mockk.* import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -72,14 +69,22 @@ class EnrolmentRecordRemoteDataSourceImplTest { moduleId = MODULE_ID, attendantId = ATTENDANT_ID, fingerprintSamples = listOf( - FingerprintSample( - IFingerIdentifier.LEFT_3RD_FINGER, - FINGERPRINT_TEMPLATE, - "ISO_19794_2", - "5289df73-7df5-3326-bcdd-22597afb1fac", + Sample( + identifier = SampleIdentifier.LEFT_3RD_FINGER, + template = FINGERPRINT_TEMPLATE, + format = "ISO_19794_2", + referenceId = "5289df73-7df5-3326-bcdd-22597afb1fac", + modality = Modality.FINGERPRINT, + ), + ), + faceSamples = listOf( + Sample( + template = FACE_TEMPLATE, + format = "faceTemplateFormat", + referenceId = "b4a3ba90-6413-32b4-a4ea-a841a5a400ec", + modality = Modality.FACE, ), ), - faceSamples = listOf(FaceSample(FACE_TEMPLATE, "faceTemplateFormat", "b4a3ba90-6413-32b4-a4ea-a841a5a400ec")), ) val expectedRecord = ApiEnrolmentRecord( subjectId = SUBJECT_ID, diff --git a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/remote/models/fingerprint/ApiFingerTest.kt b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/remote/models/fingerprint/ApiFingerTest.kt index 3a63a07bd3..3b846e988b 100644 --- a/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/remote/models/fingerprint/ApiFingerTest.kt +++ b/infra/enrolment-records/repository/src/test/java/com/simprints/infra/enrolment/records/repository/remote/models/fingerprint/ApiFingerTest.kt @@ -1,23 +1,23 @@ package com.simprints.infra.enrolment.records.repository.remote.models.fingerprint import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import org.junit.Test class ApiFingerTest { @Test fun `should map correctly the Finger enums`() { val mapping = mapOf( - IFingerIdentifier.LEFT_THUMB to ApiFinger.LEFT_THUMB, - IFingerIdentifier.LEFT_INDEX_FINGER to ApiFinger.LEFT_INDEX_FINGER, - IFingerIdentifier.LEFT_3RD_FINGER to ApiFinger.LEFT_3RD_FINGER, - IFingerIdentifier.LEFT_4TH_FINGER to ApiFinger.LEFT_4TH_FINGER, - IFingerIdentifier.LEFT_5TH_FINGER to ApiFinger.LEFT_5TH_FINGER, - IFingerIdentifier.RIGHT_THUMB to ApiFinger.RIGHT_THUMB, - IFingerIdentifier.RIGHT_INDEX_FINGER to ApiFinger.RIGHT_INDEX_FINGER, - IFingerIdentifier.RIGHT_3RD_FINGER to ApiFinger.RIGHT_3RD_FINGER, - IFingerIdentifier.RIGHT_4TH_FINGER to ApiFinger.RIGHT_4TH_FINGER, - IFingerIdentifier.RIGHT_5TH_FINGER to ApiFinger.RIGHT_5TH_FINGER, + SampleIdentifier.LEFT_THUMB to ApiFinger.LEFT_THUMB, + SampleIdentifier.LEFT_INDEX_FINGER to ApiFinger.LEFT_INDEX_FINGER, + SampleIdentifier.LEFT_3RD_FINGER to ApiFinger.LEFT_3RD_FINGER, + SampleIdentifier.LEFT_4TH_FINGER to ApiFinger.LEFT_4TH_FINGER, + SampleIdentifier.LEFT_5TH_FINGER to ApiFinger.LEFT_5TH_FINGER, + SampleIdentifier.RIGHT_THUMB to ApiFinger.RIGHT_THUMB, + SampleIdentifier.RIGHT_INDEX_FINGER to ApiFinger.RIGHT_INDEX_FINGER, + SampleIdentifier.RIGHT_3RD_FINGER to ApiFinger.RIGHT_3RD_FINGER, + SampleIdentifier.RIGHT_4TH_FINGER to ApiFinger.RIGHT_4TH_FINGER, + SampleIdentifier.RIGHT_5TH_FINGER to ApiFinger.RIGHT_5TH_FINGER, ) mapping.forEach { diff --git a/infra/enrolment-records/room-store/src/main/java/com/simprints/infra/enrolment/records/room/store/models/DbBiometricTemplate.kt b/infra/enrolment-records/room-store/src/main/java/com/simprints/infra/enrolment/records/room/store/models/DbBiometricTemplate.kt index 91c0075666..27314313dc 100644 --- a/infra/enrolment-records/room-store/src/main/java/com/simprints/infra/enrolment/records/room/store/models/DbBiometricTemplate.kt +++ b/infra/enrolment-records/room-store/src/main/java/com/simprints/infra/enrolment/records/room/store/models/DbBiometricTemplate.kt @@ -32,7 +32,7 @@ data class DbBiometricTemplate( val templateData: ByteArray = byteArrayOf(), val format: String = "", val referenceId: String = "", - val modality: Int = Modality.FINGERPRINT.id, + val modality: Int = DbModality.FINGERPRINT.id, ) { companion object { const val TEMPLATE_TABLE_NAME = "DbBiometricTemplate" diff --git a/infra/enrolment-records/room-store/src/main/java/com/simprints/infra/enrolment/records/room/store/models/DbModality.kt b/infra/enrolment-records/room-store/src/main/java/com/simprints/infra/enrolment/records/room/store/models/DbModality.kt new file mode 100644 index 0000000000..946845e760 --- /dev/null +++ b/infra/enrolment-records/room-store/src/main/java/com/simprints/infra/enrolment/records/room/store/models/DbModality.kt @@ -0,0 +1,26 @@ +package com.simprints.infra.enrolment.records.room.store.models + +import com.simprints.core.domain.common.Modality + +enum class DbModality( + val id: Int, +) { + FINGERPRINT(0), + FACE(1), + ; + + companion object Companion { + fun fromId(id: Int) = DbModality.entries.firstOrNull { it.id == id } + ?: throw IllegalArgumentException("Unknown sample identifier id: $id") + } +} + +fun DbModality.toDomain() = when (this) { + DbModality.FINGERPRINT -> Modality.FINGERPRINT + DbModality.FACE -> Modality.FACE +} + +fun Modality.fromDomain() = when (this) { + Modality.FINGERPRINT -> DbModality.FINGERPRINT + Modality.FACE -> DbModality.FACE +} diff --git a/infra/enrolment-records/room-store/src/main/java/com/simprints/infra/enrolment/records/room/store/models/Modality.kt b/infra/enrolment-records/room-store/src/main/java/com/simprints/infra/enrolment/records/room/store/models/Modality.kt deleted file mode 100644 index 4aa4944e19..0000000000 --- a/infra/enrolment-records/room-store/src/main/java/com/simprints/infra/enrolment/records/room/store/models/Modality.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.simprints.infra.enrolment.records.room.store.models - -enum class Modality( - val id: Int, -) { - FINGERPRINT(0), - FACE(1), -} diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/EventSyncManagerImpl.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/EventSyncManagerImpl.kt index 62cac8fab8..90031395fd 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/EventSyncManagerImpl.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/EventSyncManagerImpl.kt @@ -93,7 +93,7 @@ internal class EventSyncManagerImpl @Inject constructor( val deviceConfig = configRepository.getDeviceConfiguration() val downSyncScope = downSyncScopeRepository.getDownSyncScope( - modes = getProjectModes(projectConfig), + modes = getProjectModalities(projectConfig), selectedModuleIDs = deviceConfig.selectedModules.values(), syncPartitioning = simprintsDownConfig.partitionType.toDomain(), ) @@ -120,7 +120,7 @@ internal class EventSyncManagerImpl @Inject constructor( RemoteEventQuery( projectId = projectId, subjectId = subjectId, - modes = getProjectModes(projectConfiguration), + modes = getProjectModalities(projectConfiguration), ), ) simprintsDownSyncTask.downSync(this, op, eventScope, configRepository.getProject()).toList() @@ -131,7 +131,7 @@ internal class EventSyncManagerImpl @Inject constructor( projectId = projectId, subjectId = subjectId, externalIds = caseId?.let { listOf(it) }, - modes = getProjectModes(projectConfiguration), + modes = getProjectModalities(projectConfiguration), ), ) commCareSyncTask.downSync(this, op, eventScope, configRepository.getProject()).toList() @@ -139,12 +139,12 @@ internal class EventSyncManagerImpl @Inject constructor( eventRepository.closeEventScope(eventScope, EventScopeEndCause.WORKFLOW_ENDED) } - private fun getProjectModes(projectConfiguration: ProjectConfiguration) = projectConfiguration.general.modalities.map { it.toMode() } + private fun getProjectModalities(projectConfiguration: ProjectConfiguration) = projectConfiguration.general.modalities override suspend fun deleteModules(unselectedModules: List) { downSyncScopeRepository.deleteOperations( unselectedModules, - modes = getProjectModes(configRepository.getProjectConfiguration()), + modes = getProjectModalities(configRepository.getProjectConfiguration()), ) } diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/ApiFingerprintCaptureBiometricsPayload.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/ApiFingerprintCaptureBiometricsPayload.kt index 562c224594..2e68ff8e17 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/ApiFingerprintCaptureBiometricsPayload.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/ApiFingerprintCaptureBiometricsPayload.kt @@ -1,7 +1,7 @@ package com.simprints.infra.eventsync.event.remote.models import androidx.annotation.Keep -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.infra.config.store.models.TokenKeyType import com.simprints.infra.events.event.domain.models.fingerprint.FingerprintCaptureBiometricsEvent @@ -13,7 +13,7 @@ internal data class ApiFingerprintCaptureBiometricsPayload( ) : ApiEventPayload(startTime) { @Keep data class Fingerprint( - val finger: IFingerIdentifier, + val finger: SampleIdentifier, val template: String, val quality: Int, val format: String, diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/ApiFingerprintCapturePayload.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/ApiFingerprintCapturePayload.kt index 2325b52e54..28ac3f3cf3 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/ApiFingerprintCapturePayload.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/ApiFingerprintCapturePayload.kt @@ -3,7 +3,7 @@ package com.simprints.infra.eventsync.event.remote.models import androidx.annotation.Keep import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonInclude.Include -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.infra.config.store.models.TokenKeyType import com.simprints.infra.events.event.domain.models.fingerprint.FingerprintCaptureEvent.FingerprintCapturePayload import com.simprints.infra.events.event.domain.models.fingerprint.FingerprintCaptureEvent.FingerprintCapturePayload.Result.BAD_QUALITY @@ -20,13 +20,13 @@ internal data class ApiFingerprintCapturePayload( override val startTime: ApiTimestamp, val endTime: ApiTimestamp?, val qualityThreshold: Int, - val finger: IFingerIdentifier, + val finger: SampleIdentifier, val result: ApiResult, val fingerprint: ApiFingerprint?, ) : ApiEventPayload(startTime) { @Keep data class ApiFingerprint( - val finger: IFingerIdentifier, + val finger: SampleIdentifier, val quality: Int, val format: String, ) { diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/ApiModality.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/ApiModality.kt index a438316768..49c9793af6 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/ApiModality.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/ApiModality.kt @@ -1,6 +1,6 @@ package com.simprints.infra.eventsync.event.remote.models -import com.simprints.infra.config.store.models.GeneralConfiguration.Modality +import com.simprints.core.domain.common.Modality import com.simprints.infra.eventsync.event.remote.models.ApiModality.FACE import com.simprints.infra.eventsync.event.remote.models.ApiModality.FINGERPRINT diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/subject/biometricref/ApiBiometricReference.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/subject/biometricref/ApiBiometricReference.kt index 46e5ba36a6..6c0ecd7be0 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/subject/biometricref/ApiBiometricReference.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/subject/biometricref/ApiBiometricReference.kt @@ -4,7 +4,7 @@ import androidx.annotation.Keep import com.fasterxml.jackson.annotation.JsonSubTypes import com.fasterxml.jackson.annotation.JsonTypeInfo import com.simprints.core.ExcludedFromGeneratedTestCoverageReports -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.infra.events.event.domain.models.subject.FaceTemplate import com.simprints.infra.events.event.domain.models.subject.FingerprintTemplate import com.simprints.infra.eventsync.event.remote.models.subject.biometricref.face.ApiFaceReference @@ -58,4 +58,4 @@ internal fun FaceTemplate.fromDomainToApi() = ApiFaceTemplate(template) internal fun ApiFingerprintReference.fromApiToDomain() = DomainFingerprintReference(id, templates.map { it.fromApiToDomain() }, format, metadata) -internal fun ApiFingerprintTemplate.fromApiToDomain() = FingerprintTemplate(template, IFingerIdentifier.valueOf(finger.name)) +internal fun ApiFingerprintTemplate.fromApiToDomain() = FingerprintTemplate(template, SampleIdentifier.valueOf(finger.name)) diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/subject/biometricref/fingerprint/ApiFingerprintTemplate.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/subject/biometricref/fingerprint/ApiFingerprintTemplate.kt index 7648da0d3e..89786f8b89 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/subject/biometricref/fingerprint/ApiFingerprintTemplate.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/event/remote/models/subject/biometricref/fingerprint/ApiFingerprintTemplate.kt @@ -1,10 +1,10 @@ package com.simprints.infra.eventsync.event.remote.models.subject.biometricref.fingerprint import androidx.annotation.Keep -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier @Keep internal data class ApiFingerprintTemplate( val template: String, - val finger: IFingerIdentifier, + val finger: SampleIdentifier, ) diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/status/down/EventDownSyncScopeRepository.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/status/down/EventDownSyncScopeRepository.kt index 1c133d8d35..d64d549d91 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/status/down/EventDownSyncScopeRepository.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/status/down/EventDownSyncScopeRepository.kt @@ -1,7 +1,7 @@ package com.simprints.infra.eventsync.status.down +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.common.Partitioning -import com.simprints.core.domain.modality.Modes import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.infra.authstore.AuthStore import com.simprints.infra.config.store.models.TokenKeyType @@ -26,7 +26,7 @@ internal class EventDownSyncScopeRepository @Inject constructor( private val tokenizationProcessor: TokenizationProcessor, ) { suspend fun getDownSyncScope( - modes: List, + modes: List, selectedModuleIDs: List, syncPartitioning: Partitioning, ): EventDownSyncScope { @@ -90,7 +90,7 @@ internal class EventDownSyncScopeRepository @Inject constructor( suspend fun deleteOperations( moduleIds: List, - modes: List, + modes: List, ) { val scope = SubjectModuleScope(getProjectId(), moduleIds, modes) scope.operations.forEach { diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/status/down/domain/EventDownSyncScope.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/status/down/domain/EventDownSyncScope.kt index 354445e7e6..873db7141e 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/status/down/domain/EventDownSyncScope.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/status/down/domain/EventDownSyncScope.kt @@ -3,7 +3,7 @@ package com.simprints.infra.eventsync.status.down.domain import androidx.annotation.Keep import com.fasterxml.jackson.annotation.JsonSubTypes import com.fasterxml.jackson.annotation.JsonTypeInfo -import com.simprints.core.domain.modality.Modes +import com.simprints.core.domain.common.Modality import com.simprints.infra.eventsync.status.down.domain.EventDownSyncScope.SubjectModuleScope import com.simprints.infra.eventsync.status.down.domain.EventDownSyncScope.SubjectUserScope import com.simprints.infra.eventsync.status.up.domain.EventUpSyncScope.ProjectScope @@ -26,7 +26,7 @@ internal sealed class EventDownSyncScope( @Keep data class SubjectProjectScope( val projectId: String, - val modes: List, + val modes: List, ) : EventDownSyncScope() { override var operations = listOf( @@ -43,7 +43,7 @@ internal sealed class EventDownSyncScope( data class SubjectUserScope( val projectId: String, val attendantId: String, - val modes: List, + val modes: List, ) : EventDownSyncScope() { override var operations = listOf( @@ -61,7 +61,7 @@ internal sealed class EventDownSyncScope( data class SubjectModuleScope( val projectId: String, val moduleIds: List, - val modes: List, + val modes: List, ) : EventDownSyncScope() { override var operations = moduleIds.map { diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/status/down/domain/RemoteEventQuery.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/status/down/domain/RemoteEventQuery.kt index 7bdda6bc1a..aecd10a61b 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/status/down/domain/RemoteEventQuery.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/status/down/domain/RemoteEventQuery.kt @@ -1,7 +1,7 @@ package com.simprints.infra.eventsync.status.down.domain import androidx.annotation.Keep -import com.simprints.core.domain.modality.Modes +import com.simprints.core.domain.common.Modality import com.simprints.infra.eventsync.event.remote.ApiRemoteEventQuery @Keep @@ -12,7 +12,7 @@ internal data class RemoteEventQuery( val subjectId: String? = null, val lastEventId: String? = null, val externalIds: List? = null, - val modes: List, + val modes: List, ) { internal fun fromDomainToApi() = ApiRemoteEventQuery( projectId = projectId, diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/common/SubjectFactory.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/common/SubjectFactory.kt index 9e28301c3c..6e9ba73d98 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/common/SubjectFactory.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/common/SubjectFactory.kt @@ -1,13 +1,12 @@ package com.simprints.infra.eventsync.sync.common +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredential -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample +import com.simprints.core.domain.sample.CaptureIdentity +import com.simprints.core.domain.sample.Sample import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.utils.EncodingUtils -import com.simprints.face.capture.FaceCaptureResult -import com.simprints.fingerprint.capture.FingerprintCaptureResult import com.simprints.infra.enrolment.records.repository.domain.models.Subject import com.simprints.infra.events.event.domain.models.subject.BiometricReference import com.simprints.infra.events.event.domain.models.subject.EnrolmentRecordCreationEvent.EnrolmentRecordCreationPayload @@ -18,7 +17,6 @@ import com.simprints.infra.events.event.domain.models.subject.FaceTemplate import com.simprints.infra.events.event.domain.models.subject.FingerprintReference import com.simprints.infra.events.event.domain.models.subject.FingerprintTemplate import java.util.Date -import java.util.UUID import javax.inject.Inject class SubjectFactory @Inject constructor( @@ -76,8 +74,8 @@ class SubjectFactory @Inject constructor( projectId: String, attendantId: TokenizableString, moduleId: TokenizableString, - fingerprintResponse: FingerprintCaptureResult?, - faceResponse: FaceCaptureResult?, + fingerprintResponse: CaptureIdentity?, + faceResponse: CaptureIdentity?, externalCredential: ExternalCredential?, ): Subject = buildSubject( subjectId = subjectId, @@ -97,8 +95,8 @@ class SubjectFactory @Inject constructor( moduleId: TokenizableString, createdAt: Date? = null, updatedAt: Date? = null, - fingerprintSamples: List = emptyList(), - faceSamples: List = emptyList(), + fingerprintSamples: List = emptyList(), + faceSamples: List = emptyList(), externalCredentials: List = emptyList(), ) = Subject( subjectId = subjectId, @@ -112,21 +110,24 @@ class SubjectFactory @Inject constructor( externalCredentials = externalCredentials, ) - private fun extractFingerprintSamples(fingerprintResponse: FingerprintCaptureResult) = - fingerprintResponse.results.mapNotNull { captureResult -> - captureResult.sample?.let { sample -> - FingerprintSample( - captureResult.identifier, - sample.template, - sample.format, - fingerprintResponse.referenceId, - ) - } - } + private fun extractFingerprintSamples(fingerprintResponse: CaptureIdentity) = fingerprintResponse.samples.map { sample -> + Sample( + identifier = sample.identifier, + template = sample.template, + format = sample.format, + referenceId = fingerprintResponse.referenceId, + modality = sample.modality, + ) + } - private fun extractFaceSamples(faceResponse: FaceCaptureResult) = faceResponse.results - .mapNotNull { it.sample } - .map { FaceSample(it.template, it.format, faceResponse.referenceId) } + private fun extractFaceSamples(faceResponse: CaptureIdentity) = faceResponse.samples.map { + Sample( + template = it.template, + format = it.format, + referenceId = faceResponse.referenceId, + modality = it.modality, + ) + } fun extractFingerprintSamplesFromBiometricReferences(biometricReferences: List?) = biometricReferences ?.filterIsInstance() @@ -138,11 +139,12 @@ class SubjectFactory @Inject constructor( template: FingerprintTemplate, format: String, referenceId: String, - ): FingerprintSample = FingerprintSample( - fingerIdentifier = template.finger, + ): Sample = Sample( + identifier = template.finger, template = encodingUtils.base64ToBytes(template.template), format = format, referenceId = referenceId, + modality = Modality.FINGERPRINT, ) fun extractFaceSamplesFromBiometricReferences(biometricReferences: List?) = biometricReferences @@ -155,9 +157,10 @@ class SubjectFactory @Inject constructor( template: FaceTemplate, format: String, referenceId: String, - ) = FaceSample( + ) = Sample( template = encodingUtils.base64ToBytes(template.template), format = format, referenceId = referenceId, + modality = Modality.FACE, ) } diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/CommCareEventSyncWorkersBuilder.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/CommCareEventSyncWorkersBuilder.kt index c5c1c787f1..83e1f944eb 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/CommCareEventSyncWorkersBuilder.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/CommCareEventSyncWorkersBuilder.kt @@ -6,8 +6,8 @@ import com.simprints.core.domain.common.Partitioning import com.simprints.core.tools.json.JsonHelper import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.eventsync.status.down.EventDownSyncScopeRepository -import com.simprints.infra.eventsync.sync.down.workers.CommCareEventSyncDownloaderWorker import com.simprints.infra.eventsync.sync.down.workers.BaseEventDownSyncDownloaderWorker +import com.simprints.infra.eventsync.sync.down.workers.CommCareEventSyncDownloaderWorker import javax.inject.Inject internal class CommCareEventSyncWorkersBuilder @Inject constructor( @@ -15,12 +15,11 @@ internal class CommCareEventSyncWorkersBuilder @Inject constructor( jsonHelper: JsonHelper, configManager: ConfigManager, ) : BaseEventDownSyncWorkersBuilder( - downSyncScopeRepository, - jsonHelper, - configManager, -) { - override fun getWorkerClass(): Class = - CommCareEventSyncDownloaderWorker::class.java + downSyncScopeRepository, + jsonHelper, + configManager, + ) { + override fun getWorkerClass(): Class = CommCareEventSyncDownloaderWorker::class.java override fun getDownSyncWorkerConstraints() = Constraints .Builder() @@ -33,7 +32,7 @@ internal class CommCareEventSyncWorkersBuilder @Inject constructor( val projectConfiguration = configManager.getProjectConfiguration() val downSyncScope = downSyncScopeRepository.getDownSyncScope( - modes = projectConfiguration.general.modalities.map { it.toMode() }, + modes = projectConfiguration.general.modalities, selectedModuleIDs = emptyList(), syncPartitioning = Partitioning.GLOBAL, ) diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/SimprintsEventDownSyncWorkersBuilder.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/SimprintsEventDownSyncWorkersBuilder.kt index fd4eeec821..c4baca270d 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/SimprintsEventDownSyncWorkersBuilder.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/SimprintsEventDownSyncWorkersBuilder.kt @@ -16,12 +16,11 @@ internal class SimprintsEventDownSyncWorkersBuilder @Inject constructor( jsonHelper: JsonHelper, configManager: ConfigManager, ) : BaseEventDownSyncWorkersBuilder( - downSyncScopeRepository, - jsonHelper, - configManager, -) { - override fun getWorkerClass(): Class = - SimprintsEventDownSyncDownloaderWorker::class.java + downSyncScopeRepository, + jsonHelper, + configManager, + ) { + override fun getWorkerClass(): Class = SimprintsEventDownSyncDownloaderWorker::class.java override fun getDownSyncWorkerConstraints() = Constraints .Builder() @@ -36,9 +35,11 @@ internal class SimprintsEventDownSyncWorkersBuilder @Inject constructor( val deviceConfiguration = configManager.getDeviceConfiguration() val downSyncScope = downSyncScopeRepository.getDownSyncScope( - modes = projectConfiguration.general.modalities.map { it.toMode() }, + modes = projectConfiguration.general.modalities, selectedModuleIDs = deviceConfiguration.selectedModules.values(), - syncPartitioning = projectConfiguration.synchronization.down.simprints!!.partitionType.toDomain(), + syncPartitioning = projectConfiguration.synchronization.down.simprints!! + .partitionType + .toDomain(), ) return downSyncScope.operations.map { downSyncOperation -> diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/ApiFingerprintCapturePayloadTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/ApiFingerprintCapturePayloadTest.kt index e020900159..8b92671e1a 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/ApiFingerprintCapturePayloadTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/ApiFingerprintCapturePayloadTest.kt @@ -1,7 +1,7 @@ package com.simprints.infra.eventsync.event.remote.models import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.tools.utils.randomUUID import com.simprints.infra.config.store.models.TokenKeyType import com.simprints.infra.events.event.domain.models.fingerprint.FingerprintCaptureEvent @@ -13,7 +13,7 @@ class ApiFingerprintCapturePayloadTest { fun `creating fingerprint capture object has correct values`() { val fingerprint = ApiFingerprintCapturePayload.ApiFingerprint( FingerprintCaptureEvent.FingerprintCapturePayload.Fingerprint( - finger = IFingerIdentifier.LEFT_3RD_FINGER, + finger = SampleIdentifier.LEFT_3RD_FINGER, quality = 23, format = "ISO_19794_2", ), @@ -23,7 +23,7 @@ class ApiFingerprintCapturePayloadTest { startTime = ApiTimestamp(1), endTime = ApiTimestamp(1), qualityThreshold = 23, - finger = IFingerIdentifier.LEFT_3RD_FINGER, + finger = SampleIdentifier.LEFT_3RD_FINGER, result = ApiFingerprintCapturePayload.ApiResult.GOOD_SCAN, fingerprint = fingerprint, ) @@ -33,7 +33,7 @@ class ApiFingerprintCapturePayloadTest { assertThat(startTime).isEqualTo(ApiTimestamp(1)) assertThat(endTime).isEqualTo(ApiTimestamp(1)) assertThat(qualityThreshold).isEqualTo(23) - assertThat(finger).isEqualTo(IFingerIdentifier.LEFT_3RD_FINGER) + assertThat(finger).isEqualTo(SampleIdentifier.LEFT_3RD_FINGER) assertThat(result).isEqualTo(ApiFingerprintCapturePayload.ApiResult.GOOD_SCAN) assertThat(fingerprint).isEqualTo(fingerprint) } diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/subject/ApiEnrolmentRecordCreationEventTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/subject/ApiEnrolmentRecordCreationEventTest.kt index 1456f98a7f..96f2f95e93 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/subject/ApiEnrolmentRecordCreationEventTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/subject/ApiEnrolmentRecordCreationEventTest.kt @@ -1,9 +1,9 @@ package com.simprints.infra.eventsync.event.remote.models.subject -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* import com.simprints.core.domain.externalcredential.ExternalCredential import com.simprints.core.domain.externalcredential.ExternalCredentialType -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.infra.config.store.remote.models.ApiExternalCredentialType import com.simprints.infra.events.event.domain.models.subject.EnrolmentRecordCreationEvent @@ -25,7 +25,7 @@ class ApiEnrolmentRecordCreationEventTest { ApiFingerprintReference( "fpRefId", listOf( - ApiFingerprintTemplate("template", IFingerIdentifier.LEFT_THUMB), + ApiFingerprintTemplate("template", SampleIdentifier.LEFT_THUMB), ), "NEC_1", ), @@ -47,7 +47,7 @@ class ApiEnrolmentRecordCreationEventTest { FingerprintReference( "fpRefId", listOf( - FingerprintTemplate("template", IFingerIdentifier.LEFT_THUMB), + FingerprintTemplate("template", SampleIdentifier.LEFT_THUMB), ), "NEC_1", ), diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/subject/ApiEnrolmentRecordMoveEventTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/subject/ApiEnrolmentRecordMoveEventTest.kt index ab91b997b3..d4c4cf4de1 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/subject/ApiEnrolmentRecordMoveEventTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/subject/ApiEnrolmentRecordMoveEventTest.kt @@ -1,9 +1,9 @@ package com.simprints.infra.eventsync.event.remote.models.subject -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* import com.simprints.core.domain.externalcredential.ExternalCredential import com.simprints.core.domain.externalcredential.ExternalCredentialType -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.infra.config.store.remote.models.ApiExternalCredentialType import com.simprints.infra.events.event.domain.models.subject.EnrolmentRecordMoveEvent @@ -26,7 +26,7 @@ class ApiEnrolmentRecordMoveEventTest { ApiFingerprintReference( "fpRefId", listOf( - ApiFingerprintTemplate("template", IFingerIdentifier.LEFT_THUMB), + ApiFingerprintTemplate("template", SampleIdentifier.LEFT_THUMB), ), "NEC_1", ), @@ -54,7 +54,7 @@ class ApiEnrolmentRecordMoveEventTest { FingerprintReference( "fpRefId", listOf( - FingerprintTemplate("template", IFingerIdentifier.LEFT_THUMB), + FingerprintTemplate("template", SampleIdentifier.LEFT_THUMB), ), "NEC_1", ), diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/subject/ApiEnrolmentRecordUpdateEventTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/subject/ApiEnrolmentRecordUpdateEventTest.kt index 98e24e00e4..27ecfdffce 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/subject/ApiEnrolmentRecordUpdateEventTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/event/remote/models/subject/ApiEnrolmentRecordUpdateEventTest.kt @@ -1,9 +1,9 @@ package com.simprints.infra.eventsync.event.remote.models.subject -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* import com.simprints.core.domain.externalcredential.ExternalCredential import com.simprints.core.domain.externalcredential.ExternalCredentialType -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.infra.config.store.remote.models.ApiExternalCredentialType import com.simprints.infra.events.event.domain.models.subject.EnrolmentRecordUpdateEvent @@ -26,7 +26,7 @@ class ApiEnrolmentRecordUpdateEventTest { ApiFingerprintReference( "fpRefId", listOf( - ApiFingerprintTemplate("template", IFingerIdentifier.LEFT_THUMB), + ApiFingerprintTemplate("template", SampleIdentifier.LEFT_THUMB), ), "NEC_1", ), @@ -50,7 +50,7 @@ class ApiEnrolmentRecordUpdateEventTest { biometricReferencesAdded = listOf( FingerprintReference( "fpRefId", - listOf(FingerprintTemplate("template", IFingerIdentifier.LEFT_THUMB)), + listOf(FingerprintTemplate("template", SampleIdentifier.LEFT_THUMB)), "NEC_1", ), FaceReference( diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/status/down/EventDownSyncScopeRepositoryTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/status/down/EventDownSyncScopeRepositoryTest.kt index 2d13979549..10950e92ac 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/status/down/EventDownSyncScopeRepositoryTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/status/down/EventDownSyncScopeRepositoryTest.kt @@ -1,8 +1,8 @@ package com.simprints.infra.eventsync.status.down import com.google.common.truth.Truth.assertThat +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.common.Partitioning -import com.simprints.core.domain.modality.Modes import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.infra.authstore.AuthStore @@ -92,7 +92,7 @@ internal class EventDownSyncScopeRepositoryTest { @Test fun buildProjectDownSyncScope() = runTest(UnconfinedTestDispatcher()) { val syncScope = eventDownSyncScopeRepository.getDownSyncScope( - listOf(Modes.FINGERPRINT), + listOf(Modality.FINGERPRINT), DEFAULT_MODULES.toList(), Partitioning.GLOBAL, ) @@ -106,7 +106,7 @@ internal class EventDownSyncScopeRepositoryTest { every { tokenizationProcessor.encrypt(any(), any(), any()) } returns TokenizableString.Tokenized(DEFAULT_USER_ID.value) val syncScope = eventDownSyncScopeRepository.getDownSyncScope( - listOf(Modes.FINGERPRINT), + listOf(Modality.FINGERPRINT), DEFAULT_MODULES.toList(), Partitioning.USER, ) @@ -120,7 +120,7 @@ internal class EventDownSyncScopeRepositoryTest { every { tokenizationProcessor.encrypt(any(), any(), any()) } returns TokenizableString.Tokenized(DEFAULT_USER_ID.value) val syncScope = eventDownSyncScopeRepository.getDownSyncScope( - listOf(Modes.FINGERPRINT), + listOf(Modality.FINGERPRINT), DEFAULT_MODULES.toList(), Partitioning.USER, ) @@ -133,7 +133,7 @@ internal class EventDownSyncScopeRepositoryTest { every { authStore.signedInUserId } returns TokenizableString.Tokenized(DEFAULT_USER_ID.value) val syncScope = eventDownSyncScopeRepository.getDownSyncScope( - listOf(Modes.FINGERPRINT), + listOf(Modality.FINGERPRINT), DEFAULT_MODULES.toList(), Partitioning.USER, ) @@ -144,7 +144,7 @@ internal class EventDownSyncScopeRepositoryTest { @Test fun buildModuleDownSyncScope() = runTest(UnconfinedTestDispatcher()) { val syncScope = eventDownSyncScopeRepository.getDownSyncScope( - listOf(Modes.FINGERPRINT), + listOf(Modality.FINGERPRINT), DEFAULT_MODULES.toList(), Partitioning.MODULE, ) @@ -158,7 +158,7 @@ internal class EventDownSyncScopeRepositoryTest { assertThrows { eventDownSyncScopeRepository.getDownSyncScope( - listOf(Modes.FINGERPRINT), + listOf(Modality.FINGERPRINT), DEFAULT_MODULES.toList(), Partitioning.GLOBAL, ) @@ -174,7 +174,7 @@ internal class EventDownSyncScopeRepositoryTest { assertThrows { eventDownSyncScopeRepository.getDownSyncScope( - listOf(Modes.FINGERPRINT), + listOf(Modality.FINGERPRINT), DEFAULT_MODULES.toList(), Partitioning.USER, ) @@ -201,14 +201,14 @@ internal class EventDownSyncScopeRepositoryTest { fun deleteOperations_shouldDeleteOpsFromDb() = runTest { eventDownSyncScopeRepository.deleteOperations( DEFAULT_MODULES.toList(), - listOf(Modes.FINGERPRINT), + listOf(Modality.FINGERPRINT), ) DEFAULT_MODULES.forEach { moduleId -> val scope = SubjectModuleScope( DEFAULT_PROJECT_ID, listOf(moduleId), - listOf(Modes.FINGERPRINT), + listOf(Modality.FINGERPRINT), ) coVerify(exactly = 1) { downSyncOperationOperationDao.delete( @@ -254,7 +254,7 @@ internal class EventDownSyncScopeRepositoryTest { assertThat(syncScope).isInstanceOf(SubjectProjectScope::class.java) with((syncScope as SubjectProjectScope)) { assertThat(projectId).isEqualTo(DEFAULT_PROJECT_ID) - assertThat(modes).isEqualTo(listOf(Modes.FINGERPRINT)) + assertThat(modes).isEqualTo(listOf(Modality.FINGERPRINT)) } } @@ -263,7 +263,7 @@ internal class EventDownSyncScopeRepositoryTest { with((syncScope as SubjectUserScope)) { assertThat(projectId).isEqualTo(DEFAULT_PROJECT_ID) assertThat(attendantId).isEqualTo(DEFAULT_USER_ID.value) - assertThat(modes).isEqualTo(listOf(Modes.FINGERPRINT)) + assertThat(modes).isEqualTo(listOf(Modality.FINGERPRINT)) } } @@ -275,7 +275,7 @@ internal class EventDownSyncScopeRepositoryTest { DEFAULT_MODULE_ID.value, DEFAULT_MODULE_ID_2.value, ) - assertThat(modes).isEqualTo(listOf(Modes.FINGERPRINT)) + assertThat(modes).isEqualTo(listOf(Modality.FINGERPRINT)) } } diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/CommCareEventSyncWorkersBuilderTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/CommCareEventSyncWorkersBuilderTest.kt index d28dc2e54a..0336431c69 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/CommCareEventSyncWorkersBuilderTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/CommCareEventSyncWorkersBuilderTest.kt @@ -3,8 +3,8 @@ package com.simprints.infra.eventsync.sync.down import androidx.work.WorkRequest import androidx.work.workDataOf import com.google.common.truth.Truth.assertThat +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.common.Partitioning -import com.simprints.core.domain.modality.Modes import com.simprints.core.tools.json.JsonHelper import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.sync.ConfigManager @@ -30,7 +30,6 @@ import org.junit.Before import org.junit.Test class CommCareEventSyncWorkersBuilderTest { - @MockK private lateinit var generalConfiguration: GeneralConfiguration @@ -59,10 +58,10 @@ class CommCareEventSyncWorkersBuilderTest { @Test fun builder_forCommCareDownSyncWithFingerprintModality_shouldReturnTheRightWorkers() = runTest { - every { generalConfiguration.modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { generalConfiguration.modalities } returns listOf(Modality.FINGERPRINT) coEvery { eventDownSyncScopeRepository.getDownSyncScope( - modes = listOf(Modes.FINGERPRINT), + modes = listOf(Modality.FINGERPRINT), selectedModuleIDs = emptyList(), syncPartitioning = Partitioning.GLOBAL, ) @@ -77,10 +76,10 @@ class CommCareEventSyncWorkersBuilderTest { @Test fun builder_forCommCareDownSyncWithFaceModality_shouldReturnTheRightWorkers() = runTest { - every { generalConfiguration.modalities } returns listOf(GeneralConfiguration.Modality.FACE) + every { generalConfiguration.modalities } returns listOf(Modality.FACE) coEvery { eventDownSyncScopeRepository.getDownSyncScope( - modes = listOf(Modes.FACE), + modes = listOf(Modality.FACE), selectedModuleIDs = emptyList(), syncPartitioning = Partitioning.GLOBAL, ) @@ -95,10 +94,10 @@ class CommCareEventSyncWorkersBuilderTest { @Test fun builder_periodicDownSyncWorkers_shouldHaveTheRightTags() = runTest { - every { generalConfiguration.modalities } returns listOf(GeneralConfiguration.Modality.FACE) + every { generalConfiguration.modalities } returns listOf(Modality.FACE) coEvery { eventDownSyncScopeRepository.getDownSyncScope( - modes = listOf(Modes.FACE), + modes = listOf(Modality.FACE), selectedModuleIDs = emptyList(), syncPartitioning = Partitioning.GLOBAL, ) @@ -113,10 +112,10 @@ class CommCareEventSyncWorkersBuilderTest { @Test fun builder_oneTimeDownSyncWorkers_shouldHaveTheRightTags() = runTest { - every { generalConfiguration.modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { generalConfiguration.modalities } returns listOf(Modality.FINGERPRINT) coEvery { eventDownSyncScopeRepository.getDownSyncScope( - modes = listOf(Modes.FINGERPRINT), + modes = listOf(Modality.FINGERPRINT), selectedModuleIDs = emptyList(), syncPartitioning = Partitioning.GLOBAL, ) diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/SimprintsEventDownSyncWorkersBuilderTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/SimprintsEventDownSyncWorkersBuilderTest.kt index 66758b1282..aa95b4d17f 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/SimprintsEventDownSyncWorkersBuilderTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/SimprintsEventDownSyncWorkersBuilderTest.kt @@ -3,8 +3,8 @@ package com.simprints.infra.eventsync.sync.down import androidx.work.WorkRequest import androidx.work.workDataOf import com.google.common.truth.Truth.assertThat +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.common.Partitioning -import com.simprints.core.domain.modality.Modes import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.domain.tokenization.values import com.simprints.core.tools.json.JsonHelper @@ -77,11 +77,11 @@ class SimprintsEventDownSyncWorkersBuilderTest { @Test fun builder_forProjectDownSync_shouldReturnTheRightWorkers() = runTest { - every { generalConfiguration.modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { generalConfiguration.modalities } returns listOf(Modality.FINGERPRINT) every { downSyncConfiguration.simprints?.partitionType } returns DownSynchronizationConfiguration.PartitionType.PROJECT coEvery { eventDownSyncScopeRepository.getDownSyncScope( - modes = listOf(Modes.FINGERPRINT), + modes = listOf(Modality.FINGERPRINT), selectedModuleIDs = SELECTED_MODULE.values(), syncPartitioning = Partitioning.GLOBAL, ) @@ -96,11 +96,11 @@ class SimprintsEventDownSyncWorkersBuilderTest { @Test fun builder_forUserDownSync_shouldReturnTheRightWorkers() = runTest { - every { generalConfiguration.modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { generalConfiguration.modalities } returns listOf(Modality.FINGERPRINT) every { downSyncConfiguration.simprints?.partitionType } returns DownSynchronizationConfiguration.PartitionType.USER coEvery { eventDownSyncScopeRepository.getDownSyncScope( - modes = listOf(Modes.FINGERPRINT), + modes = listOf(Modality.FINGERPRINT), selectedModuleIDs = SELECTED_MODULE.values(), syncPartitioning = Partitioning.USER, ) @@ -114,11 +114,11 @@ class SimprintsEventDownSyncWorkersBuilderTest { @Test fun builder_forModuleDownSync_shouldReturnTheRightWorkers() = runTest { - every { generalConfiguration.modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { generalConfiguration.modalities } returns listOf(Modality.FINGERPRINT) every { downSyncConfiguration.simprints?.partitionType } returns DownSynchronizationConfiguration.PartitionType.MODULE coEvery { eventDownSyncScopeRepository.getDownSyncScope( - modes = listOf(Modes.FINGERPRINT), + modes = listOf(Modality.FINGERPRINT), selectedModuleIDs = SELECTED_MODULE.values(), syncPartitioning = Partitioning.MODULE, ) @@ -132,11 +132,11 @@ class SimprintsEventDownSyncWorkersBuilderTest { @Test fun builder_periodicDownSyncWorkers_shouldHaveTheRightTags() = runTest { - every { generalConfiguration.modalities } returns listOf(GeneralConfiguration.Modality.FACE) + every { generalConfiguration.modalities } returns listOf(Modality.FACE) every { downSyncConfiguration.simprints?.partitionType } returns DownSynchronizationConfiguration.PartitionType.PROJECT coEvery { eventDownSyncScopeRepository.getDownSyncScope( - modes = listOf(Modes.FACE), + modes = listOf(Modality.FACE), selectedModuleIDs = SELECTED_MODULE.values(), syncPartitioning = Partitioning.GLOBAL, ) @@ -151,11 +151,11 @@ class SimprintsEventDownSyncWorkersBuilderTest { @Test fun builder_oneTimeDownSyncWorkers_shouldHaveTheRightTags() = runTest { - every { generalConfiguration.modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { generalConfiguration.modalities } returns listOf(Modality.FINGERPRINT) every { downSyncConfiguration.simprints?.partitionType } returns DownSynchronizationConfiguration.PartitionType.PROJECT coEvery { eventDownSyncScopeRepository.getDownSyncScope( - modes = listOf(Modes.FINGERPRINT), + modes = listOf(Modality.FINGERPRINT), selectedModuleIDs = SELECTED_MODULE.values(), syncPartitioning = Partitioning.GLOBAL, ) diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/CommCareEventSyncTaskTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/CommCareEventSyncTaskTest.kt index 7a44a0b38f..5af99c2c14 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/CommCareEventSyncTaskTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/CommCareEventSyncTaskTest.kt @@ -1,9 +1,10 @@ package com.simprints.infra.eventsync.sync.down.tasks -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredential import com.simprints.core.domain.externalcredential.ExternalCredentialType -import com.simprints.core.domain.face.FaceSample +import com.simprints.core.domain.sample.Sample import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.core.tools.time.TimeHelper @@ -13,7 +14,9 @@ import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.repository.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.repository.domain.models.Subject import com.simprints.infra.enrolment.records.repository.domain.models.SubjectAction -import com.simprints.infra.enrolment.records.repository.domain.models.SubjectAction.* +import com.simprints.infra.enrolment.records.repository.domain.models.SubjectAction.Creation +import com.simprints.infra.enrolment.records.repository.domain.models.SubjectAction.Deletion +import com.simprints.infra.enrolment.records.repository.domain.models.SubjectAction.Update import com.simprints.infra.events.EventRepository import com.simprints.infra.events.event.domain.models.downsync.EventDownSyncRequestEvent import com.simprints.infra.events.event.domain.models.scope.EventScope @@ -39,9 +42,7 @@ import com.simprints.infra.eventsync.sync.common.SubjectFactory import com.simprints.infra.eventsync.sync.down.tasks.BaseEventDownSyncTask.Companion.EVENTS_BATCH_SIZE import com.simprints.testtools.common.coroutines.TestCoroutineRule import com.simprints.testtools.unit.EncodingUtilsImplForTests -import io.mockk.MockKAnnotations -import io.mockk.coEvery -import io.mockk.coVerify +import io.mockk.* import io.mockk.impl.annotations.MockK import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.toList @@ -332,7 +333,12 @@ class CommCareEventSyncTaskTest { attendantId = "moduleId".asTokenizableRaw(), moduleId = "attendantId".asTokenizableRaw(), faceSamples = listOf( - FaceSample(byteArrayOf(), "format", "referenceId"), + Sample( + template = byteArrayOf(), + format = "format", + referenceId = "referenceId", + modality = Modality.FACE, + ), ), ), ) diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/SimprintsEventDownSyncTaskTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/SimprintsEventDownSyncTaskTest.kt index b7764841c9..e92f4184c8 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/SimprintsEventDownSyncTaskTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/SimprintsEventDownSyncTaskTest.kt @@ -1,9 +1,10 @@ package com.simprints.infra.eventsync.sync.down.tasks import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredential import com.simprints.core.domain.externalcredential.ExternalCredentialType -import com.simprints.core.domain.face.FaceSample +import com.simprints.core.domain.sample.Sample import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.core.tools.time.TimeHelper @@ -555,7 +556,12 @@ class SimprintsEventDownSyncTaskTest { attendantId = "moduleId".asTokenizableRaw(), moduleId = "attendantId".asTokenizableRaw(), faceSamples = listOf( - FaceSample(byteArrayOf(), "format", "referenceId"), + Sample( + template = byteArrayOf(), + format = "format", + referenceId = "referenceId", + modality = Modality.FACE, + ), ), externalCredentials = listOf( ExternalCredential( diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/SubjectFactoryTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/SubjectFactoryTest.kt index fc33c754b5..55870750d0 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/SubjectFactoryTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/SubjectFactoryTest.kt @@ -1,17 +1,17 @@ package com.simprints.infra.eventsync.sync.down.tasks -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredential import com.simprints.core.domain.externalcredential.ExternalCredentialType -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.CaptureIdentity +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.utils.EncodingUtils -import com.simprints.face.capture.FaceCaptureResult -import com.simprints.fingerprint.capture.FingerprintCaptureResult import com.simprints.infra.enrolment.records.repository.domain.models.Subject import com.simprints.infra.events.event.domain.models.subject.EnrolmentRecordCreationEvent import com.simprints.infra.events.event.domain.models.subject.EnrolmentRecordMoveEvent @@ -22,11 +22,8 @@ import com.simprints.infra.events.event.domain.models.subject.FingerprintReferen import com.simprints.infra.events.event.domain.models.subject.FingerprintTemplate import com.simprints.infra.events.sampledata.SampleDefaults.GUID1 import com.simprints.infra.eventsync.sync.common.SubjectFactory -import io.mockk.MockKAnnotations -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK -import io.mockk.mockkStatic -import io.mockk.unmockkStatic import org.junit.After import org.junit.Before import org.junit.Test @@ -74,18 +71,20 @@ class SubjectFactoryTest { attendantId = ATTENDANT_ID, moduleId = MODULE_ID, fingerprintSamples = listOf( - FingerprintSample( - fingerIdentifier = IDENTIFIER, + Sample( + identifier = IDENTIFIER, template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = REFERENCE_ID, + modality = Modality.FINGERPRINT, ), ), faceSamples = listOf( - FaceSample( + Sample( template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = REFERENCE_ID, + modality = Modality.FACE, ), ), ) @@ -110,18 +109,20 @@ class SubjectFactoryTest { attendantId = ATTENDANT_ID, moduleId = MODULE_ID, fingerprintSamples = listOf( - FingerprintSample( - fingerIdentifier = IDENTIFIER, + Sample( + identifier = IDENTIFIER, template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = REFERENCE_ID, + modality = Modality.FINGERPRINT, ), ), faceSamples = listOf( - FaceSample( + Sample( template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = REFERENCE_ID, + modality = Modality.FACE, ), ), ) @@ -136,29 +137,33 @@ class SubjectFactoryTest { attendantId = ATTENDANT_ID, moduleId = MODULE_ID, fingerprintSamples = listOf( - FingerprintSample( - fingerIdentifier = IDENTIFIER, + Sample( + identifier = IDENTIFIER, template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = "referenceId-finger-1", + modality = Modality.FINGERPRINT, ), - FingerprintSample( - fingerIdentifier = IDENTIFIER, + Sample( + identifier = IDENTIFIER, template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = "referenceId-finger-2", + modality = Modality.FINGERPRINT, ), ), faceSamples = listOf( - FaceSample( + Sample( template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = "referenceId-finger-3", + modality = Modality.FACE, ), - FaceSample( + Sample( template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = "referenceId-finger-4", + modality = Modality.FACE, ), ), externalCredentials = listOf(EXTERNAL_CREDENTIAL), @@ -174,7 +179,7 @@ class SubjectFactoryTest { templates = listOf( FingerprintTemplate( template = BASE_64_BYTES.toString(), - finger = IFingerIdentifier.LEFT_THUMB, + finger = SampleIdentifier.LEFT_THUMB, ), ), ), @@ -194,29 +199,33 @@ class SubjectFactoryTest { attendantId = ATTENDANT_ID, moduleId = MODULE_ID, fingerprintSamples = listOf( - FingerprintSample( - fingerIdentifier = IDENTIFIER, + Sample( + identifier = IDENTIFIER, template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = "referenceId-finger-1", + modality = Modality.FINGERPRINT, ), - FingerprintSample( - fingerIdentifier = IDENTIFIER, + Sample( + identifier = IDENTIFIER, template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = "referenceId-finger-5", + modality = Modality.FINGERPRINT, ), ), faceSamples = listOf( - FaceSample( + Sample( template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = "referenceId-finger-4", + modality = Modality.FACE, ), - FaceSample( + Sample( template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = "referenceId-finger-6", + modality = Modality.FACE, ), ), externalCredentials = listOf(EXTERNAL_CREDENTIAL), @@ -235,18 +244,20 @@ class SubjectFactoryTest { moduleId = MODULE_ID, createdAt = Date(0L), fingerprintSamples = listOf( - FingerprintSample( - fingerIdentifier = IDENTIFIER, + Sample( + identifier = IDENTIFIER, template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = REFERENCE_ID, + modality = Modality.FINGERPRINT, ), ), faceSamples = listOf( - FaceSample( + Sample( template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = REFERENCE_ID, + modality = Modality.FACE, ), ), externalCredentials = listOf(EXTERNAL_CREDENTIAL), @@ -257,34 +268,28 @@ class SubjectFactoryTest { projectId = expected.projectId, attendantId = expected.attendantId, moduleId = expected.moduleId, - fingerprintResponse = FingerprintCaptureResult( + fingerprintResponse = CaptureIdentity( GUID1, + Modality.FINGERPRINT, listOf( - FingerprintCaptureResult.Item( + CaptureSample( captureEventId = GUID1, identifier = IDENTIFIER, - sample = FingerprintCaptureResult.Sample( - template = BASE_64_BYTES, - templateQualityScore = QUALITY, - format = REFERENCE_FORMAT, - imageRef = null, - fingerIdentifier = IDENTIFIER, - ), + template = BASE_64_BYTES, + format = REFERENCE_FORMAT, + modality = Modality.FINGERPRINT, ), ), ), - faceResponse = FaceCaptureResult( + faceResponse = CaptureIdentity( GUID1, + Modality.FACE, listOf( - FaceCaptureResult.Item( + CaptureSample( captureEventId = GUID1, - index = 0, - sample = FaceCaptureResult.Sample( - template = BASE_64_BYTES, - format = REFERENCE_FORMAT, - faceId = REFERENCE_ID, - imageRef = null, - ), + template = BASE_64_BYTES, + format = REFERENCE_FORMAT, + modality = Modality.FACE, ), ), ), @@ -301,18 +306,20 @@ class SubjectFactoryTest { attendantId = ATTENDANT_ID, moduleId = MODULE_ID, fingerprintSamples = listOf( - FingerprintSample( - fingerIdentifier = IDENTIFIER, + Sample( + identifier = IDENTIFIER, template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = REFERENCE_ID, + modality = Modality.FINGERPRINT, ), ), faceSamples = listOf( - FaceSample( + Sample( template = BASE_64_BYTES, format = REFERENCE_FORMAT, referenceId = REFERENCE_ID, + modality = Modality.FACE, ), ), externalCredentials = listOf(EXTERNAL_CREDENTIAL), @@ -343,8 +350,7 @@ class SubjectFactoryTest { private const val TEMPLATE_NAME = "template" private val EXTERNAL_CREDENTIAL_VALUE = "value".asTokenizableEncrypted() private val EXTERNAL_CREDENTIAL_TYPE = ExternalCredentialType.NHISCard - private val IDENTIFIER = IFingerIdentifier.LEFT_THUMB - private const val QUALITY = 10 + private val IDENTIFIER = SampleIdentifier.LEFT_THUMB private val FINGERPRINT_REFERENCE = FingerprintReference( id = REFERENCE_ID, format = REFERENCE_FORMAT, diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/up/EventUpSyncWorkersBuilderTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/up/EventUpSyncWorkersBuilderTest.kt index 6e72d56130..1af3370e22 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/up/EventUpSyncWorkersBuilderTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/up/EventUpSyncWorkersBuilderTest.kt @@ -2,7 +2,8 @@ package com.simprints.infra.eventsync.sync.up import androidx.work.WorkRequest import androidx.work.workDataOf -import com.google.common.truth.Truth.assertThat +import com.google.common.truth.Truth.* +import com.simprints.core.domain.common.Modality import com.simprints.core.tools.json.JsonHelper import com.simprints.infra.config.store.models.DownSynchronizationConfiguration import com.simprints.infra.config.store.models.GeneralConfiguration @@ -17,9 +18,7 @@ import com.simprints.infra.eventsync.sync.common.TAG_UP_MASTER_SYNC_ID import com.simprints.infra.eventsync.sync.up.workers.EventUpSyncUploaderWorker import com.simprints.infra.eventsync.sync.up.workers.EventUpSyncUploaderWorker.Companion.INPUT_EVENT_UP_SYNC_SCOPE_ID import com.simprints.infra.eventsync.sync.up.workers.EventUpSyncUploaderWorker.Companion.INPUT_UP_SYNC -import io.mockk.MockKAnnotations -import io.mockk.coEvery -import io.mockk.every +import io.mockk.* import io.mockk.impl.annotations.MockK import kotlinx.coroutines.test.runTest import org.junit.Before @@ -46,7 +45,7 @@ class EventUpSyncWorkersBuilderTest { @Test fun builder_forProjectUpSync_shouldReturnTheRightWorkers() = runTest { - every { generalConfiguration.modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { generalConfiguration.modalities } returns listOf(Modality.FINGERPRINT) every { downSyncConfiguration.simprints?.partitionType } returns DownSynchronizationConfiguration.PartitionType.PROJECT coEvery { eventUpSyncScopeRepository.getUpSyncScope() @@ -61,7 +60,7 @@ class EventUpSyncWorkersBuilderTest { @Test fun builder_periodicUpSyncWorkers_shouldHaveTheRightTags() = runTest { - every { generalConfiguration.modalities } returns listOf(GeneralConfiguration.Modality.FACE) + every { generalConfiguration.modalities } returns listOf(Modality.FACE) every { downSyncConfiguration.simprints?.partitionType } returns DownSynchronizationConfiguration.PartitionType.PROJECT coEvery { eventUpSyncScopeRepository.getUpSyncScope() @@ -77,7 +76,7 @@ class EventUpSyncWorkersBuilderTest { @Test fun builder_oneTimeDownSyncWorkers_shouldHaveTheRightTags() = runTest { - every { generalConfiguration.modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) + every { generalConfiguration.modalities } returns listOf(Modality.FINGERPRINT) every { downSyncConfiguration.simprints?.partitionType } returns DownSynchronizationConfiguration.PartitionType.PROJECT coEvery { eventUpSyncScopeRepository.getUpSyncScope() diff --git a/infra/events/src/debug/java/com/simprints/infra/events/sampledata/EventFactoryUtils.kt b/infra/events/src/debug/java/com/simprints/infra/events/sampledata/EventFactoryUtils.kt index 17925d2d93..2937ed8ac2 100644 --- a/infra/events/src/debug/java/com/simprints/infra/events/sampledata/EventFactoryUtils.kt +++ b/infra/events/src/debug/java/com/simprints/infra/events/sampledata/EventFactoryUtils.kt @@ -1,12 +1,12 @@ package com.simprints.infra.events.sampledata import android.os.Build -import com.simprints.core.domain.fingerprint.IFingerIdentifier.LEFT_THUMB +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.response.AppMatchConfidence.MEDIUM +import com.simprints.core.domain.sample.SampleIdentifier.LEFT_THUMB import com.simprints.core.tools.time.Timestamp import com.simprints.core.tools.utils.SimNetworkUtils import com.simprints.core.tools.utils.SimNetworkUtils.Connection -import com.simprints.infra.config.store.models.GeneralConfiguration.Modality import com.simprints.infra.events.event.domain.models.AgeGroupSelectionEvent import com.simprints.infra.events.event.domain.models.AlertScreenEvent import com.simprints.infra.events.event.domain.models.AlertScreenEvent.AlertScreenPayload.AlertScreenEventType.BLUETOOTH_NOT_ENABLED diff --git a/infra/events/src/debug/java/com/simprints/infra/events/sampledata/SampleDefaults.kt b/infra/events/src/debug/java/com/simprints/infra/events/sampledata/SampleDefaults.kt index 7a349d360f..b5f289f5f0 100644 --- a/infra/events/src/debug/java/com/simprints/infra/events/sampledata/SampleDefaults.kt +++ b/infra/events/src/debug/java/com/simprints/infra/events/sampledata/SampleDefaults.kt @@ -1,8 +1,8 @@ package com.simprints.infra.events.sampledata +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredential import com.simprints.core.domain.externalcredential.ExternalCredentialType -import com.simprints.core.domain.modality.Modes import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.core.tools.time.Timestamp @@ -30,7 +30,8 @@ object SampleDefaults { val TIME1 = System.currentTimeMillis() - val DEFAULT_MODES = listOf(Modes.FINGERPRINT) + val DEFAULT_MODES = listOf(Modality.FINGERPRINT) + const val CREDENTIAL_ID = "CREDENTIAL_ID" val CREDENTIAL_TYPE = ExternalCredentialType.NHISCard val CREDENTIAL_VALUE = "CREDENTIAL_VALUE".asTokenizableEncrypted() diff --git a/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureBiometricsEvent.kt b/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureBiometricsEvent.kt index 21d92ba7a5..fdb51b9bc7 100644 --- a/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureBiometricsEvent.kt +++ b/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureBiometricsEvent.kt @@ -1,7 +1,7 @@ package com.simprints.infra.events.event.domain.models.fingerprint import androidx.annotation.Keep -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.tools.time.Timestamp import com.simprints.core.tools.utils.randomUUID @@ -51,7 +51,7 @@ data class FingerprintCaptureBiometricsEvent( @Keep data class Fingerprint( - val finger: IFingerIdentifier, + val finger: SampleIdentifier, val template: String, val quality: Int, val format: String, diff --git a/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureEvent.kt b/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureEvent.kt index 669aba6192..14da649a0c 100644 --- a/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureEvent.kt +++ b/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureEvent.kt @@ -1,7 +1,7 @@ package com.simprints.infra.events.event.domain.models.fingerprint import androidx.annotation.Keep -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.tools.time.Timestamp import com.simprints.core.tools.utils.randomUUID @@ -22,7 +22,7 @@ data class FingerprintCaptureEvent( constructor( createdAt: Timestamp, endTime: Timestamp, - finger: IFingerIdentifier, + finger: SampleIdentifier, qualityThreshold: Int, result: FingerprintCapturePayload.Result, fingerprint: FingerprintCapturePayload.Fingerprint?, @@ -52,7 +52,7 @@ data class FingerprintCaptureEvent( override val createdAt: Timestamp, override val eventVersion: Int, override var endedAt: Timestamp?, - val finger: IFingerIdentifier, + val finger: SampleIdentifier, val qualityThreshold: Int, val result: Result, val fingerprint: Fingerprint?, @@ -64,7 +64,7 @@ data class FingerprintCaptureEvent( @Keep data class Fingerprint( - val finger: IFingerIdentifier, + val finger: SampleIdentifier, val quality: Int, val format: String, ) diff --git a/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/scope/EventScopePayload.kt b/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/scope/EventScopePayload.kt index 27afaec141..0652d64a19 100644 --- a/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/scope/EventScopePayload.kt +++ b/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/scope/EventScopePayload.kt @@ -1,7 +1,7 @@ package com.simprints.infra.events.event.domain.models.scope import androidx.annotation.Keep -import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.core.domain.common.Modality @Keep data class EventScopePayload( @@ -11,7 +11,7 @@ data class EventScopePayload( val language: String, val projectConfigurationUpdatedAt: String, val projectConfigurationId: String? = null, - val modalities: List, + val modalities: List, val device: Device, val databaseInfo: DatabaseInfo, val location: Location? = null, diff --git a/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/subject/EnrolmentRecordCreationEvent.kt b/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/subject/EnrolmentRecordCreationEvent.kt index 3e17b20424..e6bf478f36 100644 --- a/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/subject/EnrolmentRecordCreationEvent.kt +++ b/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/subject/EnrolmentRecordCreationEvent.kt @@ -3,8 +3,7 @@ package com.simprints.infra.events.event.domain.models.subject import androidx.annotation.Keep import com.simprints.core.ExcludedFromGeneratedTestCoverageReports import com.simprints.core.domain.externalcredential.ExternalCredential -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample +import com.simprints.core.domain.sample.Sample import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.tools.utils.EncodingUtils import java.util.UUID @@ -41,13 +40,13 @@ data class EnrolmentRecordCreationEvent( val moduleId: TokenizableString, val attendantId: TokenizableString, val biometricReferences: List, - val externalCredentials: List + val externalCredentials: List, ) companion object { fun buildBiometricReferences( - fingerprintSamples: List, - faceSamples: List, + fingerprintSamples: List, + faceSamples: List, encoder: EncodingUtils, ): List { val biometricReferences = mutableListOf() @@ -64,7 +63,7 @@ data class EnrolmentRecordCreationEvent( } private fun buildFingerprintReference( - fingerprintSamples: List, + fingerprintSamples: List, encoder: EncodingUtils, ) = if (fingerprintSamples.isNotEmpty()) { FingerprintReference( @@ -72,7 +71,7 @@ data class EnrolmentRecordCreationEvent( fingerprintSamples.map { FingerprintTemplate( encoder.byteArrayToBase64(it.template), - it.fingerIdentifier, + it.identifier, ) }, fingerprintSamples.first().format, @@ -82,7 +81,7 @@ data class EnrolmentRecordCreationEvent( } private fun buildFaceReference( - faceSamples: List, + faceSamples: List, encoder: EncodingUtils, ) = if (faceSamples.isNotEmpty()) { FaceReference( diff --git a/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/subject/FingerprintTemplate.kt b/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/subject/FingerprintTemplate.kt index 38fe2c9f5f..8da5a26d52 100644 --- a/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/subject/FingerprintTemplate.kt +++ b/infra/events/src/main/java/com/simprints/infra/events/event/domain/models/subject/FingerprintTemplate.kt @@ -1,10 +1,10 @@ package com.simprints.infra.events.event.domain.models.subject import androidx.annotation.Keep -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier @Keep data class FingerprintTemplate( val template: String, - val finger: IFingerIdentifier, + val finger: SampleIdentifier, ) diff --git a/infra/events/src/main/java/com/simprints/infra/events/event/local/migrations/EventMigration10to11.kt b/infra/events/src/main/java/com/simprints/infra/events/event/local/migrations/EventMigration10to11.kt index 79e318aaea..9bf387ac19 100644 --- a/infra/events/src/main/java/com/simprints/infra/events/event/local/migrations/EventMigration10to11.kt +++ b/infra/events/src/main/java/com/simprints/infra/events/event/local/migrations/EventMigration10to11.kt @@ -7,9 +7,9 @@ import androidx.annotation.Keep import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase import com.fasterxml.jackson.core.type.TypeReference +import com.simprints.core.domain.common.Modality import com.simprints.core.tools.extentions.getStringWithColumnName import com.simprints.core.tools.json.JsonHelper -import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.events.event.domain.models.scope.DatabaseInfo import com.simprints.infra.events.event.domain.models.scope.Device import com.simprints.infra.events.event.domain.models.scope.EventScopeEndCause @@ -141,7 +141,7 @@ internal class EventMigration10to11 : Migration(10, 11) { data class SessionCapturePayload( var projectId: String, val createdAt: Long, - var modalities: List, + var modalities: List, val appVersionName: String, val libVersionName: String, var language: String, diff --git a/infra/events/src/test/java/com/simprints/infra/events/EventRepositoryImplTest.kt b/infra/events/src/test/java/com/simprints/infra/events/EventRepositoryImplTest.kt index 925ab24ced..5624f12a5e 100644 --- a/infra/events/src/test/java/com/simprints/infra/events/EventRepositoryImplTest.kt +++ b/infra/events/src/test/java/com/simprints/infra/events/EventRepositoryImplTest.kt @@ -2,11 +2,11 @@ package com.simprints.infra.events import android.os.Build import com.google.common.truth.Truth.assertThat +import com.simprints.core.domain.common.Modality import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp import com.simprints.infra.authstore.AuthStore import com.simprints.infra.config.store.ConfigRepository -import com.simprints.infra.config.store.models.GeneralConfiguration.Modality import com.simprints.infra.events.EventRepositoryImpl.Companion.PROJECT_ID_FOR_NOT_SIGNED_IN import com.simprints.infra.events.event.domain.models.EventType import com.simprints.infra.events.event.domain.models.scope.DatabaseInfo diff --git a/infra/events/src/test/java/com/simprints/infra/events/event/domain/models/EventPayloadTest.kt b/infra/events/src/test/java/com/simprints/infra/events/event/domain/models/EventPayloadTest.kt index ac441a3c13..df340a167e 100644 --- a/infra/events/src/test/java/com/simprints/infra/events/event/domain/models/EventPayloadTest.kt +++ b/infra/events/src/test/java/com/simprints/infra/events/event/domain/models/EventPayloadTest.kt @@ -1,8 +1,8 @@ package com.simprints.infra.events.event.domain.models import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.fingerprint.IFingerIdentifier import com.simprints.core.domain.response.AppMatchConfidence +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.tools.utils.SimNetworkUtils import com.simprints.core.tools.utils.SimNetworkUtils.Connection import com.simprints.infra.events.event.domain.models.AlertScreenEvent.AlertScreenPayload.AlertScreenEventType.BLUETOOTH_NOT_ENABLED @@ -160,7 +160,7 @@ class EventPayloadTest { FingerprintCaptureBiometricsEvent( createdAt = CREATED_AT, fingerprint = FingerprintCaptureBiometricsEvent.FingerprintCaptureBiometricsPayload.Fingerprint( - finger = IFingerIdentifier.LEFT_3RD_FINGER, + finger = SampleIdentifier.LEFT_3RD_FINGER, template = "template", quality = 1, format = "ISO_19794_2", @@ -170,11 +170,11 @@ class EventPayloadTest { FingerprintCaptureEvent( createdAt = CREATED_AT, endTime = ENDED_AT, - finger = IFingerIdentifier.LEFT_THUMB, + finger = SampleIdentifier.LEFT_THUMB, qualityThreshold = 10, result = FingerprintCaptureEvent.FingerprintCapturePayload.Result.BAD_QUALITY, fingerprint = FingerprintCaptureEvent.FingerprintCapturePayload.Fingerprint( - finger = IFingerIdentifier.LEFT_THUMB, + finger = SampleIdentifier.LEFT_THUMB, quality = 8, format = "ISO_19794_2", ), diff --git a/infra/events/src/test/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureBiometricsEventTest.kt b/infra/events/src/test/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureBiometricsEventTest.kt index 530e62ec37..ba3b57f002 100644 --- a/infra/events/src/test/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureBiometricsEventTest.kt +++ b/infra/events/src/test/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureBiometricsEventTest.kt @@ -1,7 +1,7 @@ package com.simprints.infra.events.event.domain.models.fingerprint import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.infra.events.event.domain.models.EventType import com.simprints.infra.events.sampledata.SampleDefaults import org.junit.Test @@ -11,7 +11,7 @@ class FingerprintCaptureBiometricsEventTest { fun create_FingerprintCaptureBiometricsEvent() { val fingerArg = FingerprintCaptureBiometricsEvent.FingerprintCaptureBiometricsPayload.Fingerprint( - IFingerIdentifier.LEFT_3RD_FINGER, + SampleIdentifier.LEFT_3RD_FINGER, "template", 1, "ISO_19794_2", diff --git a/infra/events/src/test/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureEventTest.kt b/infra/events/src/test/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureEventTest.kt index 95df012e05..742a9adf60 100644 --- a/infra/events/src/test/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureEventTest.kt +++ b/infra/events/src/test/java/com/simprints/infra/events/event/domain/models/fingerprint/FingerprintCaptureEventTest.kt @@ -1,7 +1,7 @@ package com.simprints.infra.events.event.domain.models.fingerprint import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.infra.events.event.domain.models.EventType import com.simprints.infra.events.sampledata.SampleDefaults import org.junit.Test @@ -10,14 +10,14 @@ class FingerprintCaptureEventTest { @Test fun create_FingerprintCaptureEvent() { val fingerprint = FingerprintCaptureEvent.FingerprintCapturePayload.Fingerprint( - IFingerIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_THUMB, 8, "ISO_19794_2", ) val event = FingerprintCaptureEvent( SampleDefaults.CREATED_AT, SampleDefaults.ENDED_AT, - IFingerIdentifier.LEFT_THUMB, + SampleIdentifier.LEFT_THUMB, 10, FingerprintCaptureEvent.FingerprintCapturePayload.Result.BAD_QUALITY, fingerprint, @@ -30,7 +30,7 @@ class FingerprintCaptureEventTest { assertThat(endedAt).isEqualTo(SampleDefaults.ENDED_AT) assertThat(eventVersion).isEqualTo(FingerprintCaptureEvent.EVENT_VERSION) assertThat(type).isEqualTo(EventType.FINGERPRINT_CAPTURE) - assertThat(finger).isEqualTo(IFingerIdentifier.LEFT_THUMB) + assertThat(finger).isEqualTo(SampleIdentifier.LEFT_THUMB) assertThat(qualityThreshold).isEqualTo(10) assertThat(fingerprint).isEqualTo(fingerprint) } diff --git a/infra/events/src/test/java/com/simprints/infra/events/event/local/migrations/EventMigration10to11Test.kt b/infra/events/src/test/java/com/simprints/infra/events/event/local/migrations/EventMigration10to11Test.kt index bb59f28aa7..57b12fdfbb 100644 --- a/infra/events/src/test/java/com/simprints/infra/events/event/local/migrations/EventMigration10to11Test.kt +++ b/infra/events/src/test/java/com/simprints/infra/events/event/local/migrations/EventMigration10to11Test.kt @@ -9,6 +9,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import com.fasterxml.jackson.core.type.TypeReference import com.google.common.truth.Truth.assertThat +import com.simprints.core.domain.common.Modality import com.simprints.core.tools.extentions.getLongWithColumnName import com.simprints.core.tools.extentions.getStringWithColumnName import com.simprints.core.tools.json.JsonHelper @@ -233,8 +234,8 @@ class EventMigration10to11Test { assertThat(scopePayload.sidVersion).isEqualTo("1.0.0") assertThat(scopePayload.modalities).isEqualTo( listOf( - GeneralConfiguration.Modality.FINGERPRINT, - GeneralConfiguration.Modality.FACE, + Modality.FINGERPRINT, + Modality.FACE, ), ) assertThat(scopePayload.device).isEqualTo(Device("29", "Pixel 3", DEVICE_ID)) diff --git a/infra/events/src/test/java/com/simprints/infra/events/event/local/migrations/EventMigration7To8Test.kt b/infra/events/src/test/java/com/simprints/infra/events/event/local/migrations/EventMigration7To8Test.kt index e7b7ba0944..0763185a86 100644 --- a/infra/events/src/test/java/com/simprints/infra/events/event/local/migrations/EventMigration7To8Test.kt +++ b/infra/events/src/test/java/com/simprints/infra/events/event/local/migrations/EventMigration7To8Test.kt @@ -9,7 +9,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import com.google.common.truth.Truth.assertThat -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.tools.extentions.getStringWithColumnName import com.simprints.core.tools.utils.randomUUID import com.simprints.infra.events.event.local.EventRoomDatabase @@ -475,7 +475,7 @@ class EventMigration7To8Test { private const val SESSION_ID = "aSessionID" private const val DEVICE_ID = "aDeviceID" private const val TEMPLATE = "template" - private val FINGER = IFingerIdentifier.LEFT_3RD_FINGER + private val FINGER = SampleIdentifier.LEFT_3RD_FINGER private val CREATED_AT = 1611584017198 private val ENDED_AT = 1621588617198 private const val QUALITY = 85 diff --git a/infra/images/src/main/java/com/simprints/infra/images/ImageRepository.kt b/infra/images/src/main/java/com/simprints/infra/images/ImageRepository.kt index 8d727a55cd..f501b8d31c 100644 --- a/infra/images/src/main/java/com/simprints/infra/images/ImageRepository.kt +++ b/infra/images/src/main/java/com/simprints/infra/images/ImageRepository.kt @@ -1,6 +1,6 @@ package com.simprints.infra.images -import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.core.domain.common.Modality import com.simprints.infra.images.model.SecuredImageRef /** @@ -21,7 +21,7 @@ interface ImageRepository { suspend fun storeSample( projectId: String, sessionId: String, - modality: GeneralConfiguration.Modality, + modality: Modality, sampleId: String, fileExtension: String, sampleBytes: ByteArray, diff --git a/infra/images/src/main/java/com/simprints/infra/images/ImageRepositoryImpl.kt b/infra/images/src/main/java/com/simprints/infra/images/ImageRepositoryImpl.kt index c270e3b44e..4982bd9bd7 100644 --- a/infra/images/src/main/java/com/simprints/infra/images/ImageRepositoryImpl.kt +++ b/infra/images/src/main/java/com/simprints/infra/images/ImageRepositoryImpl.kt @@ -1,6 +1,6 @@ package com.simprints.infra.images -import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.core.domain.common.Modality import com.simprints.infra.images.local.ImageLocalDataSource import com.simprints.infra.images.metadata.ImageMetadataStore import com.simprints.infra.images.model.SecuredImageRef @@ -20,13 +20,13 @@ internal class ImageRepositoryImpl @Inject internal constructor( override suspend fun storeSample( projectId: String, sessionId: String, - modality: GeneralConfiguration.Modality, + modality: Modality, sampleId: String, fileExtension: String, sampleBytes: ByteArray, optionalMetadata: Map, ): SecuredImageRef? { - val logTag = if (modality == GeneralConfiguration.Modality.FACE) FACE_CAPTURE else FINGER_CAPTURE + val logTag = if (modality == Modality.FACE) FACE_CAPTURE else FINGER_CAPTURE val relativePath = samplePathConverter.create(sessionId, modality, sampleId, fileExtension) Simber.d("Saving $modality sample to ${relativePath.compose()}", tag = logTag) diff --git a/infra/images/src/main/java/com/simprints/infra/images/usecase/SamplePathConverter.kt b/infra/images/src/main/java/com/simprints/infra/images/usecase/SamplePathConverter.kt index 824a6091cc..60618a22e4 100644 --- a/infra/images/src/main/java/com/simprints/infra/images/usecase/SamplePathConverter.kt +++ b/infra/images/src/main/java/com/simprints/infra/images/usecase/SamplePathConverter.kt @@ -1,20 +1,20 @@ package com.simprints.infra.images.usecase -import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.core.domain.common.Modality import com.simprints.infra.images.model.Path import javax.inject.Inject internal class SamplePathConverter @Inject constructor() { fun create( sessionId: String, - modality: GeneralConfiguration.Modality, + modality: Modality, sampleId: String, fileExtension: String, ) = Path( arrayOf( SESSIONS_PATH, sessionId, - if (modality == GeneralConfiguration.Modality.FACE) FACES_PATH else FINGERPRINTS_PATH, + if (modality == Modality.FACE) FACES_PATH else FINGERPRINTS_PATH, "$sampleId.$fileExtension", ), ) @@ -26,8 +26,8 @@ internal class SamplePathConverter @Inject constructor() { val sessionId = parts[sessionsPathIndex + 1] val modality = parts[sessionsPathIndex + 2].let { when (it) { - FACES_PATH -> GeneralConfiguration.Modality.FACE - else -> GeneralConfiguration.Modality.FINGERPRINT + FACES_PATH -> Modality.FACE + else -> Modality.FINGERPRINT } } val sampleId = parts[sessionsPathIndex + 3].substringBefore(".") @@ -37,7 +37,7 @@ internal class SamplePathConverter @Inject constructor() { data class PathData( val sessionId: String, - val modality: GeneralConfiguration.Modality, + val modality: Modality, val sampleId: String, ) diff --git a/infra/images/src/test/java/com/simprints/infra/images/ImageRepositoryImplTest.kt b/infra/images/src/test/java/com/simprints/infra/images/ImageRepositoryImplTest.kt index ec105357cc..dbf36975c4 100644 --- a/infra/images/src/test/java/com/simprints/infra/images/ImageRepositoryImplTest.kt +++ b/infra/images/src/test/java/com/simprints/infra/images/ImageRepositoryImplTest.kt @@ -1,7 +1,7 @@ package com.simprints.infra.images import com.google.common.truth.Truth.* -import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.core.domain.common.Modality import com.simprints.infra.images.local.ImageLocalDataSource import com.simprints.infra.images.metadata.ImageMetadataStore import com.simprints.infra.images.model.Path @@ -60,7 +60,7 @@ internal class ImageRepositoryImplTest { val imageRef = repository.storeSample( projectId = PROJECT_ID, sessionId = "sessionId", - modality = GeneralConfiguration.Modality.FACE, + modality = Modality.FACE, sampleId = "sampleId", fileExtension = "jpg", sampleBytes = ByteArray(10), @@ -79,7 +79,7 @@ internal class ImageRepositoryImplTest { val imageRef = repository.storeSample( projectId = PROJECT_ID, sessionId = "sessionId", - modality = GeneralConfiguration.Modality.FACE, + modality = Modality.FACE, sampleId = "sampleId", fileExtension = "jpg", sampleBytes = ByteArray(10), @@ -99,7 +99,7 @@ internal class ImageRepositoryImplTest { val imageRef = repository.storeSample( projectId = PROJECT_ID, sessionId = "sessionId", - modality = GeneralConfiguration.Modality.FACE, + modality = Modality.FACE, sampleId = "sampleId", fileExtension = "jpg", sampleBytes = ByteArray(10), diff --git a/infra/images/src/test/java/com/simprints/infra/images/remote/firebase/FirebaseSampleUploaderTest.kt b/infra/images/src/test/java/com/simprints/infra/images/remote/firebase/FirebaseSampleUploaderTest.kt index 6d89faac9e..d9e34de344 100644 --- a/infra/images/src/test/java/com/simprints/infra/images/remote/firebase/FirebaseSampleUploaderTest.kt +++ b/infra/images/src/test/java/com/simprints/infra/images/remote/firebase/FirebaseSampleUploaderTest.kt @@ -3,6 +3,7 @@ package com.simprints.infra.images.remote.firebase import androidx.test.ext.junit.runners.* import com.google.common.truth.Truth.* import com.google.firebase.storage.FirebaseStorage +import com.simprints.core.domain.common.Modality import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp import com.simprints.infra.authstore.AuthStore @@ -73,7 +74,7 @@ class FirebaseSampleUploaderTest { every { timeHelper.now() } returns Timestamp(0L) every { samplePathUtil.extract(any()) } returns - SamplePathConverter.PathData("sessionID", GeneralConfiguration.Modality.FACE, "sampleId") + SamplePathConverter.PathData("sessionID", Modality.FACE, "sampleId") coEvery { eventRepository.createEventScope(any(), any()) } returns mockk() coJustRun { eventRepository.closeEventScope(any(), any()) } diff --git a/infra/images/src/test/java/com/simprints/infra/images/remote/signedurl/usecase/PrepareImageUploadDataUseCaseTest.kt b/infra/images/src/test/java/com/simprints/infra/images/remote/signedurl/usecase/PrepareImageUploadDataUseCaseTest.kt index 01642834ee..fd46949cdf 100644 --- a/infra/images/src/test/java/com/simprints/infra/images/remote/signedurl/usecase/PrepareImageUploadDataUseCaseTest.kt +++ b/infra/images/src/test/java/com/simprints/infra/images/remote/signedurl/usecase/PrepareImageUploadDataUseCaseTest.kt @@ -1,7 +1,7 @@ package com.simprints.infra.images.remote.signedurl.usecase import com.google.common.truth.Truth.* -import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.core.domain.common.Modality import com.simprints.infra.images.local.ImageLocalDataSource import com.simprints.infra.images.metadata.ImageMetadataStore import com.simprints.infra.images.model.SecuredImageRef @@ -53,7 +53,7 @@ internal class PrepareImageUploadDataUseCaseTest { coEvery { calculateFileMd5AndSize(any()) } returns CalculateFileMd5AndSizeUseCase.CalculationResult("base64-md5", 10L) every { samplePathUtil.extract(any()) } returns - SamplePathConverter.PathData("sessionId", GeneralConfiguration.Modality.FINGERPRINT, "sampleId") + SamplePathConverter.PathData("sessionId", Modality.FINGERPRINT, "sampleId") coEvery { metadataStore.getMetadata(any()) } returns mapOf("k" to "v") val result = useCase(imageRef) diff --git a/infra/images/src/test/java/com/simprints/infra/images/usecase/SamplePathConvertorTest.kt b/infra/images/src/test/java/com/simprints/infra/images/usecase/SamplePathConvertorTest.kt index aa988374ec..b64a6973af 100644 --- a/infra/images/src/test/java/com/simprints/infra/images/usecase/SamplePathConvertorTest.kt +++ b/infra/images/src/test/java/com/simprints/infra/images/usecase/SamplePathConvertorTest.kt @@ -1,7 +1,7 @@ package com.simprints.infra.images.usecase import com.google.common.truth.Truth.* -import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.core.domain.common.Modality import com.simprints.infra.images.model.Path import org.junit.Before import org.junit.Test @@ -19,7 +19,7 @@ class SamplePathConvertorTest { val expectedPath = "sessions/sessionId/faces/captureEventId.jpg" val result = pathUtil.create( sessionId = "sessionId", - modality = GeneralConfiguration.Modality.FACE, + modality = Modality.FACE, sampleId = "captureEventId", fileExtension = "jpg", ) @@ -33,7 +33,7 @@ class SamplePathConvertorTest { val result = pathUtil.create( sessionId = "sessionId", - modality = GeneralConfiguration.Modality.FINGERPRINT, + modality = Modality.FINGERPRINT, sampleId = "captureEventId", fileExtension = "swq", ) @@ -48,7 +48,7 @@ class SamplePathConvertorTest { assertThat(result).isNotNull() assertThat(result?.sessionId).isEqualTo("sessionId") assertThat(result?.sampleId).isEqualTo("captureEventId") - assertThat(result?.modality).isEqualTo(GeneralConfiguration.Modality.FINGERPRINT) + assertThat(result?.modality).isEqualTo(Modality.FINGERPRINT) } @Test @@ -58,7 +58,7 @@ class SamplePathConvertorTest { assertThat(result).isNotNull() assertThat(result?.sessionId).isEqualTo("sessionId") assertThat(result?.sampleId).isEqualTo("captureEventId") - assertThat(result?.modality).isEqualTo(GeneralConfiguration.Modality.FACE) + assertThat(result?.modality).isEqualTo(Modality.FACE) } @Test @@ -68,7 +68,7 @@ class SamplePathConvertorTest { assertThat(result).isNotNull() assertThat(result?.sessionId).isEqualTo("sessionId") assertThat(result?.sampleId).isEqualTo("captureEventId") - assertThat(result?.modality).isEqualTo(GeneralConfiguration.Modality.FINGERPRINT) + assertThat(result?.modality).isEqualTo(Modality.FINGERPRINT) } @Test diff --git a/infra/matching/src/main/java/com/simprints/infra/matching/MatchParams.kt b/infra/matching/src/main/java/com/simprints/infra/matching/MatchParams.kt index 5d32f1b864..8ee2417870 100644 --- a/infra/matching/src/main/java/com/simprints/infra/matching/MatchParams.kt +++ b/infra/matching/src/main/java/com/simprints/infra/matching/MatchParams.kt @@ -2,81 +2,23 @@ package com.simprints.infra.matching import androidx.annotation.Keep import com.simprints.core.domain.common.FlowType -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.common.ModalitySdkType +import com.simprints.core.domain.sample.CaptureSample import com.simprints.core.domain.step.StepParams import com.simprints.infra.config.store.models.FaceConfiguration import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery -import com.simprints.infra.uibase.annotations.ExcludedFromGeneratedTestCoverageReports @Keep data class MatchParams( val probeReferenceId: String, - val probeFaceSamples: List = emptyList(), - val faceSDK: FaceConfiguration.BioSdk? = null, - val probeFingerprintSamples: List = emptyList(), - val fingerprintSDK: FingerprintConfiguration.BioSdk? = null, + val bioSdk: ModalitySdkType, + val probeFaceSamples: List = emptyList(), + val probeFingerprintSamples: List = emptyList(), val flowType: FlowType, val queryForCandidates: SubjectQuery, val biometricDataSource: BiometricDataSource, ) : StepParams { fun isFaceMatch() = probeFaceSamples.isNotEmpty() - - @Keep - @ExcludedFromGeneratedTestCoverageReports("Generated code") - data class FaceSample( - val faceId: String, - val template: ByteArray, - ) : StepParams { - // Auto-generated by Android Studio to ensure - // byte array field is compared correctly - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as FaceSample - - if (faceId != other.faceId) return false - if (!template.contentEquals(other.template)) return false - - return true - } - - override fun hashCode(): Int { - var result = faceId.hashCode() - result = 31 * result + template.contentHashCode() - return result - } - } - - @Keep - @ExcludedFromGeneratedTestCoverageReports("Generated code") - data class FingerprintSample( - val fingerId: IFingerIdentifier, - val format: String, - val template: ByteArray, - ) : StepParams { - // Auto-generated by Android Studio to ensure - // byte array field is compared correctly - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as FingerprintSample - - if (fingerId != other.fingerId) return false - if (format != other.format) return false - if (!template.contentEquals(other.template)) return false - - return true - } - - override fun hashCode(): Int { - var result = fingerId.hashCode() - result = 31 * result + format.hashCode() - result = 31 * result + template.contentHashCode() - return result - } - } } diff --git a/infra/matching/src/main/java/com/simprints/infra/matching/MatchResult.kt b/infra/matching/src/main/java/com/simprints/infra/matching/MatchResult.kt index 6cf595c3eb..755ce5634d 100644 --- a/infra/matching/src/main/java/com/simprints/infra/matching/MatchResult.kt +++ b/infra/matching/src/main/java/com/simprints/infra/matching/MatchResult.kt @@ -1,44 +1,12 @@ package com.simprints.infra.matching import androidx.annotation.Keep +import com.simprints.core.domain.common.ModalitySdkType +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.core.domain.step.StepResult -import com.simprints.infra.config.store.models.FaceConfiguration -import com.simprints.infra.config.store.models.FingerprintConfiguration @Keep -interface MatchResult : StepResult { - val results: List -} - -/** - * This is required to bridge different interfaces from moduleApi module. - */ -@Keep -interface MatchResultItem : StepResult { - val subjectId: String - val confidence: Float -} - -@Keep -data class FaceMatchResult( - override val results: List, - val sdk: FaceConfiguration.BioSdk, -) : MatchResult { - @Keep - data class Item( - override val subjectId: String, - override val confidence: Float, - ) : MatchResultItem -} - -@Keep -data class FingerprintMatchResult( - override val results: List, - val sdk: FingerprintConfiguration.BioSdk, -) : MatchResult { - @Keep - data class Item( - override val subjectId: String, - override val confidence: Float, - ) : MatchResultItem -} +data class MatchResult( + val results: List, + val sdk: ModalitySdkType, +) : StepResult diff --git a/infra/matching/src/main/java/com/simprints/infra/matching/usecase/FaceMatcherUseCase.kt b/infra/matching/src/main/java/com/simprints/infra/matching/usecase/FaceMatcherUseCase.kt index 227e4de282..de82db7fcc 100644 --- a/infra/matching/src/main/java/com/simprints/infra/matching/usecase/FaceMatcherUseCase.kt +++ b/infra/matching/src/main/java/com/simprints/infra/matching/usecase/FaceMatcherUseCase.kt @@ -1,18 +1,19 @@ package com.simprints.infra.matching.usecase import com.simprints.core.DispatcherBG +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.core.tools.time.TimeHelper -import com.simprints.face.infra.basebiosdk.matching.FaceIdentity import com.simprints.face.infra.basebiosdk.matching.FaceMatcher -import com.simprints.face.infra.basebiosdk.matching.FaceSample import com.simprints.face.infra.biosdkresolver.FaceBioSDK import com.simprints.face.infra.biosdkresolver.ResolveFaceBioSdkUseCase +import com.simprints.infra.config.store.models.FaceConfiguration import com.simprints.infra.config.store.models.Project import com.simprints.infra.enrolment.records.repository.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.repository.domain.models.IdentityBatch import com.simprints.infra.logging.LoggingConstants import com.simprints.infra.logging.Simber -import com.simprints.infra.matching.FaceMatchResult import com.simprints.infra.matching.MatchBatchInfo import com.simprints.infra.matching.MatchParams import com.simprints.infra.matching.usecase.MatcherUseCase.MatcherState @@ -23,7 +24,6 @@ import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.flow.flowOn import java.util.concurrent.atomic.AtomicInteger import javax.inject.Inject -import com.simprints.infra.enrolment.records.repository.domain.models.FaceIdentity as DomainFaceIdentity class FaceMatcherUseCase @Inject constructor( private val timeHelper: TimeHelper, @@ -39,18 +39,17 @@ class FaceMatcherUseCase @Inject constructor( project: Project, ): Flow = channelFlow { Simber.i("Initialising matcher", tag = crashReportTag) - if (matchParams.faceSDK == null) { + if (matchParams.bioSdk !is FaceConfiguration.BioSdk) { Simber.w("Face SDK was not provided", tag = crashReportTag) send(MatcherState.Success(emptyList(), emptyList(), 0, "")) return@channelFlow } - val bioSdk = resolveFaceBioSdk(matchParams.faceSDK) + val bioSdk = resolveFaceBioSdk(matchParams.bioSdk) if (matchParams.probeFaceSamples.isEmpty()) { send(MatcherState.Success(emptyList(), emptyList(), 0, bioSdk.matcherName())) return@channelFlow } - val samples = mapSamples(matchParams.probeFaceSamples) val queryWithSupportedFormat = matchParams.queryForCandidates.copy( faceSampleFormat = bioSdk.templateFormat(), ) @@ -71,7 +70,7 @@ class FaceMatcherUseCase @Inject constructor( // as it's count function does not take into account filtering criteria val loadedCandidates = AtomicInteger(0) val ranges = createRanges(expectedCandidates) - val resultSet = MatchResultSet() + val resultSet = MatchResultSet() val candidatesChannel = enrolmentRecordRepository .loadFaceIdentities( query = queryWithSupportedFormat, @@ -84,21 +83,21 @@ class FaceMatcherUseCase @Inject constructor( this@channelFlow.send(MatcherState.CandidateLoaded) } - val batchInfo = consumeAndMatch(candidatesChannel, samples, resultSet, bioSdk) + val batchInfo = consumeAndMatch(candidatesChannel, matchParams.probeFaceSamples, resultSet, bioSdk) send(MatcherState.Success(resultSet.toList(), batchInfo, loadedCandidates.get(), bioSdk.matcherName())) }.flowOn(dispatcherBG) private suspend fun consumeAndMatch( - candidatesChannel: ReceiveChannel>, - samples: List, - resultSet: MatchResultSet, + candidatesChannel: ReceiveChannel>, + samples: List, + resultSet: MatchResultSet, bioSdk: FaceBioSDK, ): List { val matchBatches = mutableListOf() for (batch in candidatesChannel) { val comparingStartTime = timeHelper.now() val results = bioSdk.createMatcher(samples).use { matcher -> - match(matcher, batch.identities.mapToFaceIdentities()) + match(matcher, batch.identities) } resultSet.addAll(results) val comparingEndTime = timeHelper.now() @@ -115,29 +114,15 @@ class FaceMatcherUseCase @Inject constructor( return matchBatches } - private fun mapSamples(probes: List) = probes.map { FaceSample(it.faceId, it.template) } - private suspend fun match( matcher: FaceMatcher, - batchCandidates: List, - ) = batchCandidates.fold(MatchResultSet()) { acc, candidate -> + batchCandidates: List, + ) = batchCandidates.fold(MatchResultSet()) { acc, candidate -> acc.add( - FaceMatchResult.Item( + MatchComparisonResult( candidate.subjectId, matcher.getHighestComparisonScoreForCandidate(candidate), ), ) } - - private fun List.mapToFaceIdentities(): List = map { identity -> - FaceIdentity( - identity.subjectId, - identity.faces.map { sample -> - FaceSample( - sample.referenceId, - sample.template, - ) - }, - ) - } } diff --git a/infra/matching/src/main/java/com/simprints/infra/matching/usecase/FingerprintMatcherUseCase.kt b/infra/matching/src/main/java/com/simprints/infra/matching/usecase/FingerprintMatcherUseCase.kt index 0a48bbc1c1..ce83a733d8 100644 --- a/infra/matching/src/main/java/com/simprints/infra/matching/usecase/FingerprintMatcherUseCase.kt +++ b/infra/matching/src/main/java/com/simprints/infra/matching/usecase/FingerprintMatcherUseCase.kt @@ -2,11 +2,9 @@ package com.simprints.infra.matching.usecase import com.simprints.core.DispatcherBG import com.simprints.core.domain.common.FlowType -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity import com.simprints.core.tools.time.TimeHelper -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifier -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.Fingerprint -import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity import com.simprints.fingerprint.infra.biosdk.BioSdkWrapper import com.simprints.fingerprint.infra.biosdk.ResolveBioSdkWrapperUseCase import com.simprints.infra.config.store.models.FingerprintConfiguration @@ -17,7 +15,6 @@ import com.simprints.infra.enrolment.records.repository.EnrolmentRecordRepositor import com.simprints.infra.enrolment.records.repository.domain.models.IdentityBatch import com.simprints.infra.logging.LoggingConstants import com.simprints.infra.logging.Simber -import com.simprints.infra.matching.FingerprintMatchResult import com.simprints.infra.matching.MatchBatchInfo import com.simprints.infra.matching.MatchParams import com.simprints.infra.matching.usecase.MatcherUseCase.MatcherState @@ -28,7 +25,6 @@ import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.flow.flowOn import java.util.concurrent.atomic.AtomicInteger import javax.inject.Inject -import com.simprints.infra.enrolment.records.repository.domain.models.FingerprintIdentity as DomainFingerprintIdentity class FingerprintMatcherUseCase @Inject constructor( private val timeHelper: TimeHelper, @@ -45,18 +41,17 @@ class FingerprintMatcherUseCase @Inject constructor( project: Project, ): Flow = channelFlow { Simber.i("Initialising matcher", tag = crashReportTag) - if (matchParams.fingerprintSDK == null) { + if (matchParams.bioSdk !is FingerprintConfiguration.BioSdk) { Simber.w("Fingerprint SDK was not provided", tag = crashReportTag) send(MatcherState.Success(emptyList(), emptyList(), 0, "")) return@channelFlow } - val bioSdkWrapper = resolveBioSdkWrapper(matchParams.fingerprintSDK) + val bioSdkWrapper = resolveBioSdkWrapper(matchParams.bioSdk) if (matchParams.probeFingerprintSamples.isEmpty()) { send(MatcherState.Success(emptyList(), emptyList(), 0, bioSdkWrapper.matcherName)) return@channelFlow } - val samples = mapSamples(matchParams.probeFingerprintSamples) // Only candidates with supported template format are considered val queryWithSupportedFormat = matchParams.queryForCandidates.copy( @@ -88,29 +83,40 @@ class FingerprintMatcherUseCase @Inject constructor( this@channelFlow.send(MatcherState.CandidateLoaded) } - val resultSet = MatchResultSet() + val resultSet = MatchResultSet() - val batchInfo = consumeAndMatch(channel, samples, resultSet, bioSdkWrapper, matchParams) + val batchInfo = consumeAndMatch( + channel = channel, + samples = matchParams.probeFingerprintSamples, + resultSet = resultSet, + bioSdk = matchParams.bioSdk, + bioSdkWrapper = bioSdkWrapper, + flowType = matchParams.flowType, + ) Simber.i("Matched $loadedCandidates candidates", tag = crashReportTag) send(MatcherState.Success(resultSet.toList(), batchInfo, loadedCandidates.get(), bioSdkWrapper.matcherName)) }.flowOn(dispatcherBG) private suspend fun consumeAndMatch( - channel: ReceiveChannel>, - samples: List, - resultSet: MatchResultSet, + channel: ReceiveChannel>, + samples: List, + resultSet: MatchResultSet, + bioSdk: FingerprintConfiguration.BioSdk, bioSdkWrapper: BioSdkWrapper, - matchParams: MatchParams, + flowType: FlowType, ): List { val matchBatches = mutableListOf() for (batch in channel) { val comparingStartTime = timeHelper.now() val matchResults = - match(samples, batch.identities.mapToFingerprintIdentity(), matchParams.flowType, bioSdkWrapper, bioSdk = matchParams.fingerprintSDK!!) - .fold(MatchResultSet()) { acc, item -> - acc.add(FingerprintMatchResult.Item(item.id, item.score)) - } + match( + probes = samples, + candidates = batch.identities, + flowType = flowType, + bioSdkWrapper = bioSdkWrapper, + bioSdk = bioSdk, + ).fold(MatchResultSet()) { acc, item -> acc.add(item) } resultSet.addAll(matchResults) val comparingEndTime = timeHelper.now() matchBatches.add( @@ -126,17 +132,14 @@ class FingerprintMatcherUseCase @Inject constructor( return matchBatches } - private fun mapSamples(probes: List) = probes - .map { Fingerprint(it.fingerId.toMatcherDomain(), it.template, it.format) } - private suspend fun match( - probes: List, - candidates: List, + probes: List, + candidates: List, flowType: FlowType, bioSdkWrapper: BioSdkWrapper, bioSdk: FingerprintConfiguration.BioSdk, ) = bioSdkWrapper.match( - FingerprintIdentity("", probes), + probes, candidates, isCrossFingerMatchingEnabled(flowType, bioSdk), ) @@ -150,30 +153,4 @@ class FingerprintMatcherUseCase @Inject constructor( ?.fingerprint ?.getSdkConfiguration(bioSdk) ?.comparisonStrategyForVerification == CROSS_FINGER_USING_MEAN_OF_MAX - - private fun IFingerIdentifier.toMatcherDomain() = when (this) { - IFingerIdentifier.RIGHT_5TH_FINGER -> FingerIdentifier.RIGHT_5TH_FINGER - IFingerIdentifier.RIGHT_4TH_FINGER -> FingerIdentifier.RIGHT_4TH_FINGER - IFingerIdentifier.RIGHT_3RD_FINGER -> FingerIdentifier.RIGHT_3RD_FINGER - IFingerIdentifier.RIGHT_INDEX_FINGER -> FingerIdentifier.RIGHT_INDEX_FINGER - IFingerIdentifier.RIGHT_THUMB -> FingerIdentifier.RIGHT_THUMB - IFingerIdentifier.LEFT_THUMB -> FingerIdentifier.LEFT_THUMB - IFingerIdentifier.LEFT_INDEX_FINGER -> FingerIdentifier.LEFT_INDEX_FINGER - IFingerIdentifier.LEFT_3RD_FINGER -> FingerIdentifier.LEFT_3RD_FINGER - IFingerIdentifier.LEFT_4TH_FINGER -> FingerIdentifier.LEFT_4TH_FINGER - IFingerIdentifier.LEFT_5TH_FINGER -> FingerIdentifier.LEFT_5TH_FINGER - } - - private fun List.mapToFingerprintIdentity() = map { - FingerprintIdentity( - it.subjectId, - it.fingerprints.map { finger -> - Fingerprint( - finger.fingerIdentifier.toMatcherDomain(), - finger.template, - finger.format, - ) - }, - ) - } } diff --git a/infra/matching/src/main/java/com/simprints/infra/matching/usecase/MatchResultSet.kt b/infra/matching/src/main/java/com/simprints/infra/matching/usecase/MatchResultSet.kt index f0129ff06f..cd9b711347 100644 --- a/infra/matching/src/main/java/com/simprints/infra/matching/usecase/MatchResultSet.kt +++ b/infra/matching/src/main/java/com/simprints/infra/matching/usecase/MatchResultSet.kt @@ -1,22 +1,22 @@ package com.simprints.infra.matching.usecase -import com.simprints.infra.matching.MatchResultItem +import com.simprints.core.domain.sample.MatchComparisonResult import java.util.concurrent.ConcurrentSkipListSet import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.locks.ReentrantLock import kotlin.concurrent.withLock -class MatchResultSet( +internal class MatchResultSet( private val maxSize: Int = MAX_RESULTS, ) { private val lowestConfidence = AtomicReference(0f) private val lock = ReentrantLock() private val skipListSet = ConcurrentSkipListSet( - compareByDescending { it.confidence }.thenByDescending { it.subjectId }, + compareByDescending { it.confidence }.thenByDescending { it.subjectId }, ) - fun add(element: T): MatchResultSet { + fun add(element: MatchComparisonResult): MatchResultSet { // Use a lock to ensure thread safety during the entire add operation lock.withLock { // Only perform this optimization when we know the set is at max capacity @@ -37,12 +37,12 @@ class MatchResultSet( } } - fun addAll(elements: MatchResultSet): MatchResultSet { + fun addAll(elements: MatchResultSet): MatchResultSet { elements.skipListSet.forEach { add(it) } return this } - fun toList(): List = skipListSet.toList() + fun toList(): List = skipListSet.toList() companion object { /** diff --git a/infra/matching/src/main/java/com/simprints/infra/matching/usecase/MatcherUseCase.kt b/infra/matching/src/main/java/com/simprints/infra/matching/usecase/MatcherUseCase.kt index 061a39fc4c..8fde808145 100644 --- a/infra/matching/src/main/java/com/simprints/infra/matching/usecase/MatcherUseCase.kt +++ b/infra/matching/src/main/java/com/simprints/infra/matching/usecase/MatcherUseCase.kt @@ -1,30 +1,32 @@ package com.simprints.infra.matching.usecase +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.infra.config.store.models.Project import com.simprints.infra.logging.LoggingConstants import com.simprints.infra.matching.MatchBatchInfo import com.simprints.infra.matching.MatchParams -import com.simprints.infra.matching.MatchResultItem import kotlinx.coroutines.flow.Flow interface MatcherUseCase { val crashReportTag: LoggingConstants.CrashReportTag - /** - * Returns a MatcherResult which contains a list of [MatchResultItem]s sorted by confidence score in descending order, - * the total number of candidates that were considered and the name of the matcher that was used - */ - suspend operator fun invoke(matchParams: MatchParams, project: Project): Flow + suspend operator fun invoke( + matchParams: MatchParams, + project: Project, + ): Flow sealed class MatcherState { - data class LoadingStarted(val totalCandidates: Int) : MatcherState() + data class LoadingStarted( + val totalCandidates: Int, + ) : MatcherState() + data object CandidateLoaded : MatcherState() + data class Success( - val matchResultItems: List, + val comparisonResults: List, val matchBatches: List, val totalCandidates: Int, val matcherName: String, ) : MatcherState() } - } diff --git a/infra/matching/src/main/java/com/simprints/infra/matching/usecase/SaveMatchEventUseCase.kt b/infra/matching/src/main/java/com/simprints/infra/matching/usecase/SaveMatchEventUseCase.kt index b223d97f03..a59b2ca6f5 100644 --- a/infra/matching/src/main/java/com/simprints/infra/matching/usecase/SaveMatchEventUseCase.kt +++ b/infra/matching/src/main/java/com/simprints/infra/matching/usecase/SaveMatchEventUseCase.kt @@ -2,6 +2,7 @@ package com.simprints.infra.matching.usecase import com.simprints.core.SessionCoroutineScope import com.simprints.core.domain.common.FlowType +import com.simprints.core.domain.sample.MatchComparisonResult import com.simprints.core.tools.time.Timestamp import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.sync.ConfigManager @@ -13,7 +14,6 @@ import com.simprints.infra.events.event.domain.models.OneToOneMatchEvent import com.simprints.infra.events.session.SessionEventRepository import com.simprints.infra.matching.MatchBatchInfo import com.simprints.infra.matching.MatchParams -import com.simprints.infra.matching.MatchResultItem import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import javax.inject.Inject @@ -30,7 +30,7 @@ class SaveMatchEventUseCase @Inject constructor( matchParams: MatchParams, candidatesCount: Int, matcherName: String, - results: List, + results: List, batches: List, ) { sessionCoroutineScope.launch { @@ -42,7 +42,9 @@ class SaveMatchEventUseCase @Inject constructor( matcherName, matchParams.queryForCandidates, matchEntries.firstOrNull(), - if (matchParams.isFaceMatch()) null else getFingerprintComparisonStrategy(matchParams.fingerprintSDK!!), + matchParams.bioSdk + .let { it as? FingerprintConfiguration.BioSdk } + ?.let { getFingerprintComparisonStrategy(it) }, matchParams.probeReferenceId, ) } else { diff --git a/infra/matching/src/test/java/com/simprints/infra/matching/usecase/FaceMatcherUseCaseTest.kt b/infra/matching/src/test/java/com/simprints/infra/matching/usecase/FaceMatcherUseCaseTest.kt index 941c902404..099cb37175 100644 --- a/infra/matching/src/test/java/com/simprints/infra/matching/usecase/FaceMatcherUseCaseTest.kt +++ b/infra/matching/src/test/java/com/simprints/infra/matching/usecase/FaceMatcherUseCaseTest.kt @@ -3,7 +3,11 @@ package com.simprints.infra.matching.usecase import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.google.common.truth.Truth.* import com.simprints.core.domain.common.FlowType -import com.simprints.core.domain.face.FaceSample +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.MatchComparisonResult +import com.simprints.core.domain.sample.Sample import com.simprints.core.tools.time.TimeHelper import com.simprints.face.infra.basebiosdk.matching.FaceMatcher import com.simprints.face.infra.biosdkresolver.ResolveFaceBioSdkUseCase @@ -11,9 +15,7 @@ import com.simprints.infra.config.store.models.FaceConfiguration import com.simprints.infra.config.store.models.Project import com.simprints.infra.enrolment.records.repository.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource -import com.simprints.infra.enrolment.records.repository.domain.models.FaceIdentity import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery -import com.simprints.infra.matching.FaceMatchResult import com.simprints.infra.matching.MatchParams import com.simprints.testtools.common.coroutines.TestCoroutineRule import io.mockk.* @@ -74,6 +76,7 @@ internal class FaceMatcherUseCaseTest { probeReferenceId = "referenceId", flowType = FlowType.VERIFY, queryForCandidates = SubjectQuery(), + bioSdk = FaceConfiguration.BioSdk.RANK_ONE, biometricDataSource = BiometricDataSource.Simprints, ), project, @@ -83,7 +86,7 @@ internal class FaceMatcherUseCaseTest { assertThat(results).containsExactly( MatcherUseCase.MatcherState.Success( - matchResultItems = emptyList(), + comparisonResults = emptyList(), totalCandidates = 0, matcherName = "", matchBatches = emptyList(), @@ -100,9 +103,14 @@ internal class FaceMatcherUseCaseTest { MatchParams( probeReferenceId = "referenceId", probeFaceSamples = listOf( - MatchParams.FaceSample("faceId", byteArrayOf(1, 2, 3)), + CaptureSample( + captureEventId = "faceId", + template = byteArrayOf(1, 2, 3), + modality = Modality.FACE, + format = "format", + ), ), - faceSDK = FaceConfiguration.BioSdk.RANK_ONE, + bioSdk = FaceConfiguration.BioSdk.RANK_ONE, flowType = FlowType.VERIFY, queryForCandidates = SubjectQuery(), biometricDataSource = BiometricDataSource.Simprints, @@ -114,7 +122,7 @@ internal class FaceMatcherUseCaseTest { assertThat(results).containsExactly( MatcherUseCase.MatcherState.Success( - matchResultItems = emptyList(), + comparisonResults = emptyList(), totalCandidates = 0, matcherName = "", matchBatches = emptyList(), @@ -126,9 +134,16 @@ internal class FaceMatcherUseCaseTest { fun `Correctly calls SDK matcher`() = runTest { val totalCandidates = 1 val faceIdentities = listOf( - FaceIdentity( + Identity( "subjectId", - listOf(FaceSample(byteArrayOf(1, 2, 3), "format", "faceTemplate")), + listOf( + Sample( + template = byteArrayOf(1, 2, 3), + format = "format", + referenceId = "faceTemplate", + modality = Modality.FACE, + ), + ), ), ) coEvery { enrolmentRecordRepository.count(any(), any()) } returns 1 @@ -152,9 +167,14 @@ internal class FaceMatcherUseCaseTest { matchParams = MatchParams( probeReferenceId = "referenceId", probeFaceSamples = listOf( - MatchParams.FaceSample("faceId", byteArrayOf(1, 2, 3)), + CaptureSample( + captureEventId = "faceId", + template = byteArrayOf(1, 2, 3), + modality = Modality.FACE, + format = "format", + ), ), - faceSDK = FaceConfiguration.BioSdk.RANK_ONE, + bioSdk = FaceConfiguration.BioSdk.RANK_ONE, flowType = FlowType.VERIFY, queryForCandidates = SubjectQuery(), biometricDataSource = BiometricDataSource.Simprints, @@ -170,7 +190,7 @@ internal class FaceMatcherUseCaseTest { assertThat(results[1]).isInstanceOf(MatcherUseCase.MatcherState.CandidateLoaded::class.java) val successState = results[2] as MatcherUseCase.MatcherState.Success - assertThat(successState.matchResultItems).containsExactly(FaceMatchResult.Item("subjectId", 42f)) + assertThat(successState.comparisonResults).containsExactly(MatchComparisonResult("subjectId", 42f)) assertThat(successState.totalCandidates).isEqualTo(totalCandidates) assertThat(successState.matcherName).isEqualTo("") diff --git a/infra/matching/src/test/java/com/simprints/infra/matching/usecase/FingerprintMatcherUseCaseTest.kt b/infra/matching/src/test/java/com/simprints/infra/matching/usecase/FingerprintMatcherUseCaseTest.kt index f11bfacf83..5f5f1b838e 100644 --- a/infra/matching/src/test/java/com/simprints/infra/matching/usecase/FingerprintMatcherUseCaseTest.kt +++ b/infra/matching/src/test/java/com/simprints/infra/matching/usecase/FingerprintMatcherUseCaseTest.kt @@ -3,8 +3,11 @@ package com.simprints.infra.matching.usecase import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.google.common.truth.Truth.* import com.simprints.core.domain.common.FlowType -import com.simprints.core.domain.fingerprint.FingerprintSample -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.Identity +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp import com.simprints.fingerprint.infra.biosdk.BioSdkWrapper @@ -14,7 +17,6 @@ import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.repository.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.repository.domain.models.BiometricDataSource -import com.simprints.infra.enrolment.records.repository.domain.models.FingerprintIdentity import com.simprints.infra.enrolment.records.repository.domain.models.IdentityBatch import com.simprints.infra.enrolment.records.repository.domain.models.SubjectQuery import com.simprints.infra.matching.MatchParams @@ -84,7 +86,7 @@ internal class FingerprintMatcherUseCaseTest { MatchParams( probeReferenceId = "referenceId", probeFingerprintSamples = emptyList(), - fingerprintSDK = SECUGEN_SIM_MATCHER, + bioSdk = SECUGEN_SIM_MATCHER, flowType = FlowType.VERIFY, queryForCandidates = SubjectQuery(), biometricDataSource = BiometricDataSource.Simprints, @@ -96,7 +98,7 @@ internal class FingerprintMatcherUseCaseTest { assertThat(results).containsExactly( MatcherUseCase.MatcherState.Success( - matchResultItems = emptyList(), + comparisonResults = emptyList(), totalCandidates = 0, matcherName = "", matchBatches = emptyList(), @@ -116,13 +118,15 @@ internal class FingerprintMatcherUseCaseTest { MatchParams( probeReferenceId = "referenceId", probeFingerprintSamples = listOf( - MatchParams.FingerprintSample( - IFingerIdentifier.LEFT_3RD_FINGER, - "format", - byteArrayOf(1, 2, 3), + CaptureSample( + captureEventId = "fingerprintId", + template = byteArrayOf(1, 2, 3), + modality = Modality.FINGERPRINT, + format = "format", + identifier = SampleIdentifier.LEFT_3RD_FINGER, ), ), - fingerprintSDK = SECUGEN_SIM_MATCHER, + bioSdk = SECUGEN_SIM_MATCHER, flowType = FlowType.VERIFY, queryForCandidates = SubjectQuery(), biometricDataSource = BiometricDataSource.Simprints, @@ -134,7 +138,7 @@ internal class FingerprintMatcherUseCaseTest { assertThat(results).containsExactly( MatcherUseCase.MatcherState.Success( - matchResultItems = emptyList(), + comparisonResults = emptyList(), totalCandidates = 0, matcherName = "", matchBatches = emptyList(), @@ -155,26 +159,25 @@ internal class FingerprintMatcherUseCaseTest { any(), any(), ) - } returns - createTestChannel( - listOf( - FingerprintIdentity( - "personId", - listOf( - fingerprintSample(IFingerIdentifier.RIGHT_5TH_FINGER), - fingerprintSample(IFingerIdentifier.RIGHT_4TH_FINGER), - fingerprintSample(IFingerIdentifier.RIGHT_3RD_FINGER), - fingerprintSample(IFingerIdentifier.RIGHT_INDEX_FINGER), - fingerprintSample(IFingerIdentifier.RIGHT_THUMB), - fingerprintSample(IFingerIdentifier.LEFT_THUMB), - fingerprintSample(IFingerIdentifier.LEFT_INDEX_FINGER), - fingerprintSample(IFingerIdentifier.LEFT_3RD_FINGER), - fingerprintSample(IFingerIdentifier.LEFT_4TH_FINGER), - fingerprintSample(IFingerIdentifier.LEFT_5TH_FINGER), - ), + } returns createTestChannel( + listOf( + Identity( + "personId", + listOf( + fingerprintSample(SampleIdentifier.RIGHT_5TH_FINGER), + fingerprintSample(SampleIdentifier.RIGHT_4TH_FINGER), + fingerprintSample(SampleIdentifier.RIGHT_3RD_FINGER), + fingerprintSample(SampleIdentifier.RIGHT_INDEX_FINGER), + fingerprintSample(SampleIdentifier.RIGHT_THUMB), + fingerprintSample(SampleIdentifier.LEFT_THUMB), + fingerprintSample(SampleIdentifier.LEFT_INDEX_FINGER), + fingerprintSample(SampleIdentifier.LEFT_3RD_FINGER), + fingerprintSample(SampleIdentifier.LEFT_4TH_FINGER), + fingerprintSample(SampleIdentifier.LEFT_5TH_FINGER), ), ), - ) + ), + ) coEvery { bioSdkWrapper.match(any(), any(), any()) } returns listOf() useCase @@ -182,13 +185,15 @@ internal class FingerprintMatcherUseCaseTest { matchParams = MatchParams( probeReferenceId = "referenceId", probeFingerprintSamples = listOf( - MatchParams.FingerprintSample( - IFingerIdentifier.LEFT_3RD_FINGER, - "format", - byteArrayOf(1, 2, 3), + CaptureSample( + captureEventId = "fingerprintId", + template = byteArrayOf(1, 2, 3), + modality = Modality.FINGERPRINT, + format = "format", + identifier = SampleIdentifier.LEFT_3RD_FINGER, ), ), - fingerprintSDK = SECUGEN_SIM_MATCHER, + bioSdk = SECUGEN_SIM_MATCHER, flowType = FlowType.VERIFY, queryForCandidates = SubjectQuery(), biometricDataSource = BiometricDataSource.Simprints, @@ -198,11 +203,17 @@ internal class FingerprintMatcherUseCaseTest { coVerify { bioSdkWrapper.match(any(), any(), any()) } } - private fun fingerprintSample(finger: IFingerIdentifier) = FingerprintSample(finger, byteArrayOf(1), "format", "referenceId") + private fun fingerprintSample(finger: SampleIdentifier) = Sample( + identifier = finger, + template = byteArrayOf(1), + format = "format", + referenceId = "referenceId", + modality = Modality.FINGERPRINT, + ) } -fun createTestChannel(vararg lists: List): ReceiveChannel> { - val channel = Channel>(lists.size) +fun createTestChannel(vararg lists: List): ReceiveChannel> { + val channel = Channel>(lists.size) runBlocking { var time = 0L for (list in lists) { @@ -211,7 +222,7 @@ fun createTestChannel(vararg lists: List): ReceiveChannel(3) + val set = MatchResultSet(3) - set.add(FingerprintMatchResult.Item("4", 0.4f)) - set.add(FingerprintMatchResult.Item("1", 0.1f)) - set.add(FingerprintMatchResult.Item("3", 0.3f)) - set.add(FingerprintMatchResult.Item("3", 0.1f)) - set.add(FingerprintMatchResult.Item("2", 0.2f)) + set.add(MatchComparisonResult("4", 0.4f)) + set.add(MatchComparisonResult("1", 0.1f)) + set.add(MatchComparisonResult("3", 0.3f)) + set.add(MatchComparisonResult("3", 0.1f)) + set.add(MatchComparisonResult("2", 0.2f)) assertThat(set.toList()).isEqualTo( listOf( - FingerprintMatchResult.Item("4", 0.4f), - FingerprintMatchResult.Item("3", 0.3f), - FingerprintMatchResult.Item("2", 0.2f), + MatchComparisonResult("4", 0.4f), + MatchComparisonResult("3", 0.3f), + MatchComparisonResult("2", 0.2f), ), ) } @Test fun `Merges sets preserving the total limit`() { - val setOne = MatchResultSet(2) - setOne.add(FingerprintMatchResult.Item("1", 0.1f)) - setOne.add(FingerprintMatchResult.Item("3", 0.3f)) + val setOne = MatchResultSet(2) + setOne.add(MatchComparisonResult("1", 0.1f)) + setOne.add(MatchComparisonResult("3", 0.3f)) - val setTwo = MatchResultSet(2) - setTwo.add(FingerprintMatchResult.Item("2", 0.2f)) - setTwo.add(FingerprintMatchResult.Item("4", 0.4f)) + val setTwo = MatchResultSet(2) + setTwo.add(MatchComparisonResult("2", 0.2f)) + setTwo.add(MatchComparisonResult("4", 0.4f)) - val set = MatchResultSet(3) + val set = MatchResultSet(3) set.addAll(setOne) set.addAll(setTwo) assertThat(set.toList()).isEqualTo( listOf( - FingerprintMatchResult.Item("4", 0.4f), - FingerprintMatchResult.Item("3", 0.3f), - FingerprintMatchResult.Item("2", 0.2f), + MatchComparisonResult("4", 0.4f), + MatchComparisonResult("3", 0.3f), + MatchComparisonResult("2", 0.2f), ), ) } @@ -53,25 +53,25 @@ class MatchResultSetTest { // On equal confidence scores sort by id @Test fun `Stores results sorted descending by confidence and id`() { - val set = MatchResultSet(3) + val set = MatchResultSet(3) - set.add(FingerprintMatchResult.Item("4", 0.4f)) - set.add(FingerprintMatchResult.Item("1", 0.4f)) - set.add(FingerprintMatchResult.Item("3", 0.3f)) - set.add(FingerprintMatchResult.Item("2", 0.3f)) + set.add(MatchComparisonResult("4", 0.4f)) + set.add(MatchComparisonResult("1", 0.4f)) + set.add(MatchComparisonResult("3", 0.3f)) + set.add(MatchComparisonResult("2", 0.3f)) assertThat(set.toList()).isEqualTo( listOf( - FingerprintMatchResult.Item("4", 0.4f), - FingerprintMatchResult.Item("1", 0.4f), - FingerprintMatchResult.Item("3", 0.3f), + MatchComparisonResult("4", 0.4f), + MatchComparisonResult("1", 0.4f), + MatchComparisonResult("3", 0.3f), ), ) } @Test fun `Concurrent add operations maintain thread safety`() { - val set = MatchResultSet(5) + val set = MatchResultSet(5) val threadCount = 10 val elementsPerThread = 20 val latch = CountDownLatch(1) @@ -88,7 +88,7 @@ class MatchResultSetTest { // Each thread adds its own batch of elements repeat(elementsPerThread) { i -> val confidence = (threadIndex * elementsPerThread + i) / 100f - set.add(FingerprintMatchResult.Item("T$threadIndex-$i", confidence)) + set.add(MatchComparisonResult("T$threadIndex-$i", confidence)) } } catch (e: Exception) { e.printStackTrace() @@ -120,16 +120,16 @@ class MatchResultSetTest { @Test fun `Concurrent addAll operations maintain thread safety`() { - val targetSet = MatchResultSet(5) + val targetSet = MatchResultSet(5) val threadCount = 5 val latch = CountDownLatch(1) // Create source sets with different items val sourceSets = List(threadCount) { threadIndex -> - MatchResultSet(3).apply { + MatchResultSet(3).apply { repeat(5) { i -> val confidence = 0.5f + (threadIndex * 5 + i) / 100f - add(FingerprintMatchResult.Item("S$threadIndex-$i", confidence)) + add(MatchComparisonResult("S$threadIndex-$i", confidence)) } } } @@ -172,21 +172,21 @@ class MatchResultSetTest { @Test fun `addAll correctly filters elements with lower confidence than current minimum`() { - val set = MatchResultSet(3) + val set = MatchResultSet(3) // Add higher confidence items first to fill the set - set.add(FingerprintMatchResult.Item("A", 0.8f)) - set.add(FingerprintMatchResult.Item("B", 0.7f)) - set.add(FingerprintMatchResult.Item("C", 0.6f)) + set.add(MatchComparisonResult("A", 0.8f)) + set.add(MatchComparisonResult("B", 0.7f)) + set.add(MatchComparisonResult("C", 0.6f)) // Try to add a new set with lower confidence items - val lowerSet = MatchResultSet(3) - lowerSet.add(FingerprintMatchResult.Item("D", 0.5f)) - lowerSet.add(FingerprintMatchResult.Item("E", 0.4f)) - lowerSet.add(FingerprintMatchResult.Item("F", 0.3f)) + val lowerSet = MatchResultSet(3) + lowerSet.add(MatchComparisonResult("D", 0.5f)) + lowerSet.add(MatchComparisonResult("E", 0.4f)) + lowerSet.add(MatchComparisonResult("F", 0.3f)) // Add one higher item to verify it still gets added - lowerSet.add(FingerprintMatchResult.Item("G", 0.9f)) + lowerSet.add(MatchComparisonResult("G", 0.9f)) set.addAll(lowerSet) diff --git a/infra/matching/src/test/java/com/simprints/infra/matching/usecase/SaveMatchEventUseCaseTest.kt b/infra/matching/src/test/java/com/simprints/infra/matching/usecase/SaveMatchEventUseCaseTest.kt index ae84096e7c..dd4ec47135 100644 --- a/infra/matching/src/test/java/com/simprints/infra/matching/usecase/SaveMatchEventUseCaseTest.kt +++ b/infra/matching/src/test/java/com/simprints/infra/matching/usecase/SaveMatchEventUseCaseTest.kt @@ -2,9 +2,13 @@ package com.simprints.infra.matching.usecase import com.google.common.truth.Truth.* import com.simprints.core.domain.common.FlowType -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.CaptureSample +import com.simprints.core.domain.sample.MatchComparisonResult +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.tools.time.Timestamp +import com.simprints.infra.config.store.models.FaceConfiguration import com.simprints.infra.config.store.models.FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER import com.simprints.infra.config.store.models.FingerprintConfiguration.FingerComparisonStrategy import com.simprints.infra.config.sync.ConfigManager @@ -15,7 +19,6 @@ import com.simprints.infra.events.event.domain.models.OneToManyMatchEvent.OneToM import com.simprints.infra.events.event.domain.models.OneToOneMatchEvent import com.simprints.infra.events.event.domain.models.OneToOneMatchEvent.OneToOneMatchPayload.OneToOneMatchPayloadV4 import com.simprints.infra.events.session.SessionEventRepository -import com.simprints.infra.matching.FaceMatchResult import com.simprints.infra.matching.MatchBatchInfo import com.simprints.infra.matching.MatchParams import com.simprints.testtools.common.coroutines.TestCoroutineRule @@ -68,15 +71,23 @@ class SaveMatchEventUseCaseTest { MatchParams( probeReferenceId = "referenceId", flowType = FlowType.VERIFY, + bioSdk = FaceConfiguration.BioSdk.RANK_ONE, queryForCandidates = SubjectQuery(subjectId = "subjectId"), - probeFaceSamples = listOf(MatchParams.FaceSample("faceId", byteArrayOf(1, 2, 3))), + probeFaceSamples = listOf( + CaptureSample( + captureEventId = "faceId", + template = byteArrayOf(1, 2, 3), + modality = Modality.FACE, + format = "format", + ), + ), biometricDataSource = BiometricDataSource.Simprints, ), 2, "faceMatcherName", listOf( - FaceMatchResult.Item("guid1", 0.5f), - FaceMatchResult.Item("guid2", 0.1f), + MatchComparisonResult("guid1", 0.5f), + MatchComparisonResult("guid2", 0.1f), ), batches = emptyList(), ) @@ -108,20 +119,22 @@ class SaveMatchEventUseCaseTest { flowType = FlowType.VERIFY, queryForCandidates = SubjectQuery(subjectId = "subjectId"), probeFingerprintSamples = listOf( - MatchParams.FingerprintSample( - IFingerIdentifier.RIGHT_5TH_FINGER, - "format", - byteArrayOf(1, 2, 3), + CaptureSample( + captureEventId = "fingerprintId", + template = byteArrayOf(1, 2, 3), + modality = Modality.FINGERPRINT, + format = "format", + identifier = SampleIdentifier.RIGHT_5TH_FINGER, ), ), - fingerprintSDK = SECUGEN_SIM_MATCHER, + bioSdk = SECUGEN_SIM_MATCHER, biometricDataSource = BiometricDataSource.Simprints, ), 2, "faceMatcherName", listOf( - FaceMatchResult.Item("guid1", 0.5f), - FaceMatchResult.Item("guid2", 0.1f), + MatchComparisonResult("guid1", 0.5f), + MatchComparisonResult("guid2", 0.1f), ), batches = emptyList(), ) @@ -156,7 +169,7 @@ class SaveMatchEventUseCaseTest { probeReferenceId = "referenceId", probeFaceSamples = emptyList(), probeFingerprintSamples = emptyList(), - fingerprintSDK = null, + bioSdk = FaceConfiguration.BioSdk.RANK_ONE, flowType = FlowType.IDENTIFY, queryForCandidates = SubjectQuery(), biometricDataSource = BiometricDataSource.Simprints, @@ -164,8 +177,8 @@ class SaveMatchEventUseCaseTest { candidatesCount = 2, matcherName = "faceMatcherName", results = listOf( - FaceMatchResult.Item("guid1", 0.5f), - FaceMatchResult.Item("guid2", 0.1f), + MatchComparisonResult("guid1", 0.5f), + MatchComparisonResult("guid2", 0.1f), ), batches = batches, ) @@ -217,12 +230,13 @@ class SaveMatchEventUseCaseTest { MatchParams( probeReferenceId = "referenceId", flowType = FlowType.IDENTIFY, + bioSdk = FaceConfiguration.BioSdk.RANK_ONE, queryForCandidates = SubjectQuery(attendantId = "userId".asTokenizableEncrypted()), biometricDataSource = BiometricDataSource.Simprints, ), 0, "faceMatcherName", - listOf(FaceMatchResult.Item("guid1", 0.5f)), + listOf(MatchComparisonResult("guid1", 0.5f)), batches = batches, ) @@ -254,6 +268,7 @@ class SaveMatchEventUseCaseTest { MatchParams( probeReferenceId = "referenceId", flowType = FlowType.IDENTIFY, + bioSdk = FaceConfiguration.BioSdk.RANK_ONE, queryForCandidates = SubjectQuery(moduleId = "moduleId".asTokenizableEncrypted()), biometricDataSource = BiometricDataSource.Simprints, ), @@ -290,7 +305,8 @@ class SaveMatchEventUseCaseTest { Timestamp(2L), MatchParams( probeReferenceId = "referenceId", - emptyList(), + bioSdk = FaceConfiguration.BioSdk.RANK_ONE, + probeFaceSamples = emptyList(), flowType = FlowType.IDENTIFY, queryForCandidates = SubjectQuery(), biometricDataSource = BiometricDataSource.Simprints, 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 c02ebe005a..4c8bf507be 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,13 +1,14 @@ package com.simprints.infra.sync.config.testtools +import com.simprints.core.domain.common.Modality import com.simprints.core.domain.externalcredential.ExternalCredentialType +import com.simprints.core.domain.sample.SampleIdentifier 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 import com.simprints.infra.config.store.models.FaceConfiguration -import com.simprints.infra.config.store.models.Finger import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.Frequency import com.simprints.infra.config.store.models.GeneralConfiguration @@ -26,8 +27,8 @@ import com.simprints.infra.config.store.models.Vero1Configuration import com.simprints.infra.config.store.models.Vero2Configuration internal val generalConfiguration = GeneralConfiguration( - listOf(GeneralConfiguration.Modality.FACE), - listOf(GeneralConfiguration.Modality.FACE), + listOf(Modality.FACE), + listOf(Modality.FACE), listOf("en"), "en", collectLocation = true, @@ -67,7 +68,7 @@ internal val fingerprintConfiguration = FingerprintConfiguration( allowedSDKs = listOf(FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER), displayHandIcons = true, secugenSimMatcher = FingerprintConfiguration.FingerprintSdkConfiguration( - listOf(Finger.LEFT_3RD_FINGER), + listOf(SampleIdentifier.LEFT_3RD_FINGER), decisionPolicy, FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER, vero1 = Vero1Configuration(10), @@ -119,7 +120,7 @@ internal val simprintsDownSyncConfigurationConfiguration = DownSynchronizationCo internal val allowedExternalCredential = ExternalCredentialType.NHISCard internal val multiFactorIdConfiguration = MultiFactorIdConfiguration( - allowedExternalCredentials = listOf(allowedExternalCredential) + allowedExternalCredentials = listOf(allowedExternalCredential), ) internal val synchronizationConfiguration = SynchronizationConfiguration( @@ -150,7 +151,7 @@ internal val projectConfiguration = ProjectConfiguration( identification = identificationConfiguration, synchronization = synchronizationConfiguration, multifactorId = multiFactorIdConfiguration, - custom = null + custom = null, ) internal const val TOKENIZATION_JSON = diff --git a/testing/data-generator/src/main/java/com/simprints/feature/datagenerator/enrollmentrecords/InsertEnrollmentRecordsUseCase.kt b/testing/data-generator/src/main/java/com/simprints/feature/datagenerator/enrollmentrecords/InsertEnrollmentRecordsUseCase.kt index 3a6c4b55e9..bafacc528b 100644 --- a/testing/data-generator/src/main/java/com/simprints/feature/datagenerator/enrollmentrecords/InsertEnrollmentRecordsUseCase.kt +++ b/testing/data-generator/src/main/java/com/simprints/feature/datagenerator/enrollmentrecords/InsertEnrollmentRecordsUseCase.kt @@ -2,9 +2,9 @@ package com.simprints.feature.datagenerator.enrollmentrecords import android.os.Bundle import com.simprints.core.DispatcherIO -import com.simprints.core.domain.face.FaceSample -import com.simprints.core.domain.fingerprint.FingerprintSample -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.common.Modality +import com.simprints.core.domain.sample.Sample +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.core.tools.time.TimeHelper import com.simprints.infra.config.store.ConfigRepository @@ -77,8 +77,8 @@ internal class InsertEnrollmentRecordsUseCase @Inject constructor( emit("Inserted $numRecords biometric records") }.flowOn(dispatcher) - private fun generateFaceSamples(templatesPerFormat: Bundle): List { - val faceSamples = mutableListOf() + private fun generateFaceSamples(templatesPerFormat: Bundle): List { + val faceSamples = mutableListOf() for (key in templatesPerFormat.keySet()) { if (FINGERPRINT_FORMATES.contains(key)) { // Skip non-face formats @@ -87,11 +87,12 @@ internal class InsertEnrollmentRecordsUseCase @Inject constructor( val numSamples = templatesPerFormat.getInt(key, 0) repeat(numSamples) { faceSamples.add( - FaceSample( + Sample( template = getTemplateForFormat(key), format = key, referenceId = UUID.randomUUID().toString(), id = UUID.randomUUID().toString(), + modality = Modality.FACE, ), ) } @@ -102,8 +103,8 @@ internal class InsertEnrollmentRecordsUseCase @Inject constructor( private fun generateFingerprintTemplates( templatesPerFormat: Bundle, fingerOrder: Bundle?, - ): List { - val fingerprintSamples = mutableListOf() + ): List { + val fingerprintSamples = mutableListOf() for (key in templatesPerFormat.keySet()) { if (FACE_FORMATES.contains(key)) { @@ -115,16 +116,17 @@ internal class InsertEnrollmentRecordsUseCase @Inject constructor( val numSamples = templatesPerFormat.getInt(key, 0) for (i in 0 until numSamples) { fingerprintSamples.add( - FingerprintSample( + Sample( template = getTemplateForFormat(key), format = key, referenceId = UUID.randomUUID().toString(), id = UUID.randomUUID().toString(), - fingerIdentifier = if (fingerIdentifiers.isNullOrEmpty()) { - IFingerIdentifier.LEFT_THUMB + identifier = if (fingerIdentifiers.isNullOrEmpty()) { + SampleIdentifier.LEFT_THUMB } else { fingerIdentifiers[i % fingerIdentifiers.size].toFingerIdentifier() }, + modality = Modality.FINGERPRINT, ), ) } @@ -133,18 +135,18 @@ internal class InsertEnrollmentRecordsUseCase @Inject constructor( } private fun String.toFingerIdentifier() = when (this.uppercase()) { - "LEFT_THUMB" -> IFingerIdentifier.LEFT_THUMB - "LEFT_INDEX_FINGER" -> IFingerIdentifier.LEFT_INDEX_FINGER - "LEFT_3RD_FINGER" -> IFingerIdentifier.LEFT_3RD_FINGER - "LEFT_4TH_FINGER" -> IFingerIdentifier.LEFT_4TH_FINGER - "LEFT_5TH_FINGER" -> IFingerIdentifier.LEFT_5TH_FINGER - "RIGHT_THUMB" -> IFingerIdentifier.RIGHT_THUMB - "RIGHT_INDEX_FINGER" -> IFingerIdentifier.RIGHT_INDEX_FINGER - "RIGHT_3RD_FINGER" -> IFingerIdentifier.RIGHT_3RD_FINGER - "RIGHT_4TH_FINGER" -> IFingerIdentifier.RIGHT_4TH_FINGER - "RIGHT_5TH_FINGER" -> IFingerIdentifier.RIGHT_5TH_FINGER + "LEFT_THUMB" -> SampleIdentifier.LEFT_THUMB + "LEFT_INDEX_FINGER" -> SampleIdentifier.LEFT_INDEX_FINGER + "LEFT_3RD_FINGER" -> SampleIdentifier.LEFT_3RD_FINGER + "LEFT_4TH_FINGER" -> SampleIdentifier.LEFT_4TH_FINGER + "LEFT_5TH_FINGER" -> SampleIdentifier.LEFT_5TH_FINGER + "RIGHT_THUMB" -> SampleIdentifier.RIGHT_THUMB + "RIGHT_INDEX_FINGER" -> SampleIdentifier.RIGHT_INDEX_FINGER + "RIGHT_3RD_FINGER" -> SampleIdentifier.RIGHT_3RD_FINGER + "RIGHT_4TH_FINGER" -> SampleIdentifier.RIGHT_4TH_FINGER + "RIGHT_5TH_FINGER" -> SampleIdentifier.RIGHT_5TH_FINGER else -> { - IFingerIdentifier.LEFT_THUMB + SampleIdentifier.LEFT_THUMB } } diff --git a/testing/data-generator/src/test/java/com/simprints/feature/datagenerator/InsertEnrollmentRecordsUseCaseTest.kt b/testing/data-generator/src/test/java/com/simprints/feature/datagenerator/InsertEnrollmentRecordsUseCaseTest.kt index e96ea4ad66..ded730f120 100644 --- a/testing/data-generator/src/test/java/com/simprints/feature/datagenerator/InsertEnrollmentRecordsUseCaseTest.kt +++ b/testing/data-generator/src/test/java/com/simprints/feature/datagenerator/InsertEnrollmentRecordsUseCaseTest.kt @@ -4,7 +4,7 @@ import android.os.Bundle import androidx.core.os.bundleOf import androidx.test.ext.junit.runners.* import com.google.common.truth.Truth.* -import com.simprints.core.domain.fingerprint.IFingerIdentifier +import com.simprints.core.domain.sample.SampleIdentifier import com.simprints.feature.datagenerator.enrollmentrecords.InsertEnrollmentRecordsUseCase import com.simprints.feature.datagenerator.enrollmentrecords.InsertEnrollmentRecordsUseCase.Companion.BATCH_SIZE import com.simprints.infra.config.store.ConfigRepository @@ -248,8 +248,8 @@ internal class InsertEnrollmentRecordsUseCaseTest { // Then val subject = subjectActionsSlot.captured.first().subject assertThat(subject.fingerprintSamples).hasSize(2) - assertThat(subject.fingerprintSamples[0].fingerIdentifier).isEqualTo(IFingerIdentifier.LEFT_THUMB) - assertThat(subject.fingerprintSamples[1].fingerIdentifier).isEqualTo(IFingerIdentifier.LEFT_THUMB) + assertThat(subject.fingerprintSamples[0].identifier).isEqualTo(SampleIdentifier.LEFT_THUMB) + assertThat(subject.fingerprintSamples[1].identifier).isEqualTo(SampleIdentifier.LEFT_THUMB) } @Test @@ -279,14 +279,14 @@ internal class InsertEnrollmentRecordsUseCaseTest { // Then val subject = subjectActionsSlot.captured.first().subject - val fingers = subject.fingerprintSamples.map { it.fingerIdentifier } + val fingers = subject.fingerprintSamples.map { it.identifier } assertThat(fingers).hasSize(4) assertThat(fingers) .containsExactly( - IFingerIdentifier.RIGHT_THUMB, - IFingerIdentifier.RIGHT_INDEX_FINGER, - IFingerIdentifier.RIGHT_THUMB, // cycles back - IFingerIdentifier.RIGHT_INDEX_FINGER, + SampleIdentifier.RIGHT_THUMB, + SampleIdentifier.RIGHT_INDEX_FINGER, + SampleIdentifier.RIGHT_THUMB, // cycles back + SampleIdentifier.RIGHT_INDEX_FINGER, ).inOrder() } }