diff --git a/face/infra/bio-sdk-resolver/.gitignore b/face/infra/bio-sdk-resolver/.gitignore index 796b96d1c4..bc1e49f5f4 100644 --- a/face/infra/bio-sdk-resolver/.gitignore +++ b/face/infra/bio-sdk-resolver/.gitignore @@ -1 +1,2 @@ /build +!/src/release/java diff --git a/face/infra/bio-sdk-resolver/build.gradle.kts b/face/infra/bio-sdk-resolver/build.gradle.kts index 55f0b9b37f..ee7fa64dde 100644 --- a/face/infra/bio-sdk-resolver/build.gradle.kts +++ b/face/infra/bio-sdk-resolver/build.gradle.kts @@ -10,5 +10,6 @@ dependencies { implementation(project(":face:infra:base-bio-sdk")) implementation(project(":face:infra:roc-v1")) api(project(":face:infra:roc-v3")) - implementation(project(":face:infra:simface")) + + debugImplementation(project(":face:infra:simface")) } diff --git a/face/infra/bio-sdk-resolver/src/debug/java/com/simprints/face/infra/biosdkresolver/ResolveSimFaceVersionUseCase.kt b/face/infra/bio-sdk-resolver/src/debug/java/com/simprints/face/infra/biosdkresolver/ResolveSimFaceVersionUseCase.kt new file mode 100644 index 0000000000..73720ad762 --- /dev/null +++ b/face/infra/bio-sdk-resolver/src/debug/java/com/simprints/face/infra/biosdkresolver/ResolveSimFaceVersionUseCase.kt @@ -0,0 +1,13 @@ +package com.simprints.face.infra.biosdkresolver + +import javax.inject.Inject + +/** + * At the moment this is just a wrapper to make it simpler to stub it in different source sets. + * In future we could actually need custom resolution logic. + */ +internal class ResolveSimFaceVersionUseCase @Inject constructor( + private val simFaceBioSdk: SimFaceBioSdk, +) { + operator fun invoke(): FaceBioSDK = simFaceBioSdk +} diff --git a/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt b/face/infra/bio-sdk-resolver/src/debug/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt similarity index 100% rename from face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt rename to face/infra/bio-sdk-resolver/src/debug/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt diff --git a/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/ResolveFaceBioSdkUseCase.kt b/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/ResolveFaceBioSdkUseCase.kt index 407a305a8a..da8660b069 100644 --- a/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/ResolveFaceBioSdkUseCase.kt +++ b/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/ResolveFaceBioSdkUseCase.kt @@ -1,28 +1,16 @@ package com.simprints.face.infra.biosdkresolver -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FaceConfiguration import javax.inject.Inject import javax.inject.Singleton @Singleton -class ResolveFaceBioSdkUseCase @Inject constructor( - private val configRepository: ConfigRepository, - private val rocV1BioSdk: RocV1BioSdk, - private val rocV3BioSdk: RocV3BioSdk, - private val simFaceBioSdk: SimFaceBioSdk, +class ResolveFaceBioSdkUseCase @Inject internal constructor( + private val resolveRankOneVersionUseCase: ResolveRankOneVersionUseCase, + private val resolveSimFaceVersionUseCase: ResolveSimFaceVersionUseCase, ) { suspend operator fun invoke(bioSdk: FaceConfiguration.BioSdk): FaceBioSDK = when (bioSdk) { - FaceConfiguration.BioSdk.SIM_FACE -> simFaceBioSdk - FaceConfiguration.BioSdk.RANK_ONE -> { - val version = configRepository - .getProjectConfiguration() - .face - ?.rankOne - ?.version - ?.takeIf { it.isNotBlank() } // Ensures version is not null or empty - requireNotNull(version) { "FaceBioSDK version is null or empty" } - if (version == rocV3BioSdk.version) rocV3BioSdk else rocV1BioSdk - } + FaceConfiguration.BioSdk.SIM_FACE -> resolveSimFaceVersionUseCase() + FaceConfiguration.BioSdk.RANK_ONE -> resolveRankOneVersionUseCase() } } diff --git a/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/ResolveRankOneVersionUseCase.kt b/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/ResolveRankOneVersionUseCase.kt new file mode 100644 index 0000000000..a34322b592 --- /dev/null +++ b/face/infra/bio-sdk-resolver/src/main/java/com/simprints/face/infra/biosdkresolver/ResolveRankOneVersionUseCase.kt @@ -0,0 +1,21 @@ +package com.simprints.face.infra.biosdkresolver + +import com.simprints.infra.config.store.ConfigRepository +import javax.inject.Inject + +internal class ResolveRankOneVersionUseCase @Inject constructor( + private val configRepository: ConfigRepository, + private val rocV1BioSdk: RocV1BioSdk, + private val rocV3BioSdk: RocV3BioSdk, +) { + suspend operator fun invoke(): FaceBioSDK { + val version = configRepository + .getProjectConfiguration() + .face + ?.rankOne + ?.version + ?.takeIf { it.isNotBlank() } // Ensures version is not null or empty + requireNotNull(version) { "FaceBioSDK version is null or empty" } + return if (version == rocV3BioSdk.version) rocV3BioSdk else rocV1BioSdk + } +} diff --git a/face/infra/bio-sdk-resolver/src/release/java/com/simprints/face/infra/biosdkresolver/ResolveSimFaceVersionUseCase.kt b/face/infra/bio-sdk-resolver/src/release/java/com/simprints/face/infra/biosdkresolver/ResolveSimFaceVersionUseCase.kt new file mode 100644 index 0000000000..dac89c1d57 --- /dev/null +++ b/face/infra/bio-sdk-resolver/src/release/java/com/simprints/face/infra/biosdkresolver/ResolveSimFaceVersionUseCase.kt @@ -0,0 +1,14 @@ +package com.simprints.face.infra.biosdkresolver + +import javax.inject.Inject + +/** + * Class interfaces in the different build types must be identical for it to work, + * therefore we have to stub the whole class for now. + */ +@ExcludedFromGeneratedTestCoverageReports("Stubs for build types") +internal class ResolveSimFaceVersionUseCase @Inject constructor( + private val simFaceBioSdk: SimFaceBioSdk, +) { + operator fun invoke(): FaceBioSDK = TODO("SimFace is not available in release build") +} 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 new file mode 100644 index 0000000000..2109511478 --- /dev/null +++ b/face/infra/bio-sdk-resolver/src/release/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt @@ -0,0 +1,26 @@ +package com.simprints.face.infra.biosdkresolver + +import com.simprints.face.infra.basebiosdk.matching.FaceMatcher +import com.simprints.face.infra.basebiosdk.matching.FaceSample +import javax.inject.Inject + +/** + * Class interfaces in the different build types must be identical for it to work, + * therefore we have to stub the whole class for now. + */ +@ExcludedFromGeneratedTestCoverageReports("Stubs for build types") +@Singleton +class SimFaceBioSdk @Inject constructor() : FaceBioSDK { + override val initializer: FaceBioSdkInitializer + get() = TODO() + override val detector: FaceDetector + get() = TODO() + override val version: String + get() = TODO() + override val templateFormat: String + get() = TODO() + override val matcherName: String + get() = TODO() + + override fun createMatcher(probeSamples: List): FaceMatcher = TODO() +} diff --git a/face/infra/bio-sdk-resolver/src/staging/java/com/simprints/face/infra/biosdkresolver/ResolveSimFaceVersionUseCase.kt b/face/infra/bio-sdk-resolver/src/staging/java/com/simprints/face/infra/biosdkresolver/ResolveSimFaceVersionUseCase.kt new file mode 100644 index 0000000000..ea4400352c --- /dev/null +++ b/face/infra/bio-sdk-resolver/src/staging/java/com/simprints/face/infra/biosdkresolver/ResolveSimFaceVersionUseCase.kt @@ -0,0 +1,15 @@ +package com.simprints.face.infra.biosdkresolver + +import com.simprints.core.ExcludedFromGeneratedTestCoverageReports +import javax.inject.Inject + +/** + * Class interfaces in the different build types must be identical for it to work, + * therefore we have to stub the whole class for now. + */ +@ExcludedFromGeneratedTestCoverageReports("Stubs for build types") +internal class ResolveSimFaceVersionUseCase @Inject constructor( + private val simFaceBioSdk: SimFaceBioSdk, +) { + operator fun invoke(): FaceBioSDK = TODO("SimFace is not available in staging build") +} 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 new file mode 100644 index 0000000000..4ae53e98a3 --- /dev/null +++ b/face/infra/bio-sdk-resolver/src/staging/java/com/simprints/face/infra/biosdkresolver/SimFaceBioSdk.kt @@ -0,0 +1,30 @@ +package com.simprints.face.infra.biosdkresolver + +import com.simprints.core.ExcludedFromGeneratedTestCoverageReports +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 + +/** + * Class interfaces in the different build types must be identical for it to work, + * therefore we have to stub the whole class for now. + */ +@ExcludedFromGeneratedTestCoverageReports("Stubs for build types") +@Singleton +class SimFaceBioSdk @Inject constructor() : FaceBioSDK { + override val initializer: FaceBioSdkInitializer + get() = TODO() + override val detector: FaceDetector + get() = TODO() + override val version: String + get() = TODO() + override val templateFormat: String + get() = TODO() + override val matcherName: String + get() = TODO() + + override fun createMatcher(probeSamples: List): FaceMatcher = TODO() +} diff --git a/face/infra/bio-sdk-resolver/src/test/java/com/simprints/face/infra/biosdkresolver/ResolveFaceBioSdkUseCaseTest.kt b/face/infra/bio-sdk-resolver/src/test/java/com/simprints/face/infra/biosdkresolver/ResolveFaceBioSdkUseCaseTest.kt index 21f8ec64d8..c763de3e33 100644 --- a/face/infra/bio-sdk-resolver/src/test/java/com/simprints/face/infra/biosdkresolver/ResolveFaceBioSdkUseCaseTest.kt +++ b/face/infra/bio-sdk-resolver/src/test/java/com/simprints/face/infra/biosdkresolver/ResolveFaceBioSdkUseCaseTest.kt @@ -1,108 +1,48 @@ package com.simprints.face.infra.biosdkresolver import com.google.common.truth.Truth.* -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FaceConfiguration import io.mockk.* +import io.mockk.impl.annotations.MockK import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test class ResolveFaceBioSdkUseCaseTest { - private lateinit var resolveFaceBioSdkUseCase: ResolveFaceBioSdkUseCase - private val configRepository: ConfigRepository = mockk() - private lateinit var rocV1BioSdk: RocV1BioSdk - private lateinit var rocV3BioSdk: RocV3BioSdk - private lateinit var simFaceBioSdk: SimFaceBioSdk - - @Before - fun setUp() { - rocV1BioSdk = RocV1BioSdk(mockk(), mockk()) - rocV3BioSdk = RocV3BioSdk(mockk(), mockk()) - simFaceBioSdk = SimFaceBioSdk(mockk(), mockk(), mockk(relaxed = true)) + @MockK + private lateinit var resolveRankOneVersionUseCase: ResolveRankOneVersionUseCase - resolveFaceBioSdkUseCase = ResolveFaceBioSdkUseCase(configRepository, rocV1BioSdk, rocV3BioSdk, simFaceBioSdk) - } - - @Test - fun `return SimFace SDK when requested`() = runTest { - // When - val result = resolveFaceBioSdkUseCase.invoke(FaceConfiguration.BioSdk.SIM_FACE) - - // Then - assertThat(result).isEqualTo(simFaceBioSdk) - } + @MockK + private lateinit var rocBioSdk: RocV1BioSdk - @Test(expected = IllegalArgumentException::class) - fun `throw exception when RankOne version is null`() = runTest { - // Given - coEvery { - configRepository - .getProjectConfiguration() - .face - ?.rankOne - ?.version - } returns null + @MockK + private lateinit var resolveSimFaceVersionUseCase: ResolveSimFaceVersionUseCase - // When - resolveFaceBioSdkUseCase.invoke(FaceConfiguration.BioSdk.RANK_ONE) + @MockK + private lateinit var simFaceBioSdk: SimFaceBioSdk - // Then: Expect IllegalArgumentException to be thrown - } + private lateinit var resolveFaceBioSdkUseCase: ResolveFaceBioSdkUseCase - @Test(expected = IllegalArgumentException::class) - fun `throw exception when RankOne version is empty`() = runTest { - // Given - coEvery { - configRepository - .getProjectConfiguration() - .face - ?.rankOne - ?.version - } returns "" + @Before + fun setUp() { + MockKAnnotations.init(this, relaxed = true) - // When - resolveFaceBioSdkUseCase.invoke(FaceConfiguration.BioSdk.RANK_ONE) + coEvery { resolveRankOneVersionUseCase() } returns rocBioSdk + coEvery { resolveSimFaceVersionUseCase() } returns simFaceBioSdk - // Then: Expect IllegalArgumentException to be thrown + resolveFaceBioSdkUseCase = ResolveFaceBioSdkUseCase( + resolveRankOneVersionUseCase, + resolveSimFaceVersionUseCase, + ) } - // Given that version is valid and matches ROC V3 @Test - fun `return ROC V3 SDK when version is valid and matches ROC V3`() = runTest { - // Given - - coEvery { - configRepository - .getProjectConfiguration() - .face - ?.rankOne - ?.version - } returns rocV3BioSdk.version - - // When - val result = resolveFaceBioSdkUseCase.invoke(FaceConfiguration.BioSdk.RANK_ONE) - - // Then - assertThat(result).isEqualTo(rocV3BioSdk) + fun `return SimFace SDK when requested`() = runTest { + assertThat(resolveFaceBioSdkUseCase.invoke(FaceConfiguration.BioSdk.SIM_FACE)).isEqualTo(simFaceBioSdk) } - // Given that version is valid and does not match ROC V3 (should match ROC V1) @Test - fun `return ROC V1 SDK when version is valid and does not match ROC V3`() = runTest { - // Given - coEvery { - configRepository - .getProjectConfiguration() - .face - ?.rankOne - ?.version - } returns rocV1BioSdk.version - - // When - val result = resolveFaceBioSdkUseCase.invoke(FaceConfiguration.BioSdk.RANK_ONE) - - // Then - assertThat(result).isEqualTo(rocV1BioSdk) + fun `return RankOne SDK when requested`() = runTest { + assertThat(resolveFaceBioSdkUseCase.invoke(FaceConfiguration.BioSdk.RANK_ONE)).isEqualTo(rocBioSdk) } } diff --git a/face/infra/bio-sdk-resolver/src/test/java/com/simprints/face/infra/biosdkresolver/ResolveRankOneVersionUseCaseTest.kt b/face/infra/bio-sdk-resolver/src/test/java/com/simprints/face/infra/biosdkresolver/ResolveRankOneVersionUseCaseTest.kt new file mode 100644 index 0000000000..25624f7576 --- /dev/null +++ b/face/infra/bio-sdk-resolver/src/test/java/com/simprints/face/infra/biosdkresolver/ResolveRankOneVersionUseCaseTest.kt @@ -0,0 +1,100 @@ +package com.simprints.face.infra.biosdkresolver + +import com.google.common.truth.* +import com.simprints.infra.config.store.ConfigRepository +import io.mockk.* +import io.mockk.impl.annotations.MockK +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test + +class ResolveRankOneVersionUseCaseTest { + @MockK + private lateinit var configRepository: ConfigRepository + private lateinit var rocV1BioSdk: RocV1BioSdk + private lateinit var rocV3BioSdk: RocV3BioSdk + + private lateinit var resolveTheVersionUseCase: ResolveRankOneVersionUseCase + + @Before + fun setUp() { + MockKAnnotations.init(this, relaxed = true) + rocV1BioSdk = RocV1BioSdk(mockk(), mockk()) + rocV3BioSdk = RocV3BioSdk(mockk(), mockk()) + + resolveTheVersionUseCase = ResolveRankOneVersionUseCase(configRepository, rocV1BioSdk, rocV3BioSdk) + } + + @Test(expected = IllegalArgumentException::class) + fun `throw exception when RankOne version is null`() = runTest { + // Given + coEvery { + configRepository + .getProjectConfiguration() + .face + ?.rankOne + ?.version + } returns null + + // When + resolveTheVersionUseCase.invoke() + + // Then: Expect IllegalArgumentException to be thrown + } + + @Test(expected = IllegalArgumentException::class) + fun `throw exception when RankOne version is empty`() = runTest { + // Given + coEvery { + configRepository + .getProjectConfiguration() + .face + ?.rankOne + ?.version + } returns "" + + // When + resolveTheVersionUseCase.invoke() + + // Then: Expect IllegalArgumentException to be thrown + } + + // Given that version is valid and matches ROC V3 + @Test + fun `return ROC V3 SDK when version is valid and matches ROC V3`() = runTest { + // Given + + coEvery { + configRepository + .getProjectConfiguration() + .face + ?.rankOne + ?.version + } returns rocV3BioSdk.version + + // When + val result = resolveTheVersionUseCase.invoke() + + // Then + Truth.assertThat(result).isEqualTo(rocV3BioSdk) + } + + // Given that version is valid and does not match ROC V3 (should match ROC V1) + @Test + fun `return ROC V1 SDK when version is valid and does not match ROC V3`() = runTest { + // Given + coEvery { + configRepository + .getProjectConfiguration() + .face + ?.rankOne + ?.version + } returns rocV1BioSdk.version + + // When + val result = resolveTheVersionUseCase.invoke() + + // Then + Truth.assertThat(result).isEqualTo(rocV1BioSdk) + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1a8ebbb350..c03b0b807a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -69,7 +69,7 @@ roc_wrapper_version = "1.23.0" roc_wrapper-v3_version = "3.1.0" nec_version = "1.5.0" secugen_version = "1.1.0" -simface = "2025.2.0" +simface = "2025.2.1" junit_version = "4.13.2" junit_ext_version = "1.2.1"