Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.simprints.feature.enrollast.R
import com.simprints.feature.enrollast.screen.EnrolLastState.ErrorType
import com.simprints.feature.enrollast.screen.EnrolLastState.ErrorType.DUPLICATE_ENROLMENTS
import com.simprints.feature.enrollast.screen.EnrolLastState.ErrorType.GENERAL_ERROR
import com.simprints.feature.enrollast.screen.EnrolLastState.ErrorType.NO_MATCH_RESULTS
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
Expand Down Expand Up @@ -84,6 +85,7 @@ internal class EnrolLastBiometricFragment : Fragment(R.layout.fragment_enrol_las
}

private fun getAlertMessage(errorType: ErrorType) = when (errorType) {
NO_MATCH_RESULTS -> IDR.string.enrol_last_biometrics_alert_message
DUPLICATE_ENROLMENTS -> IDR.string.enrol_last_biometrics_alert_message_duplicate_records
GENERAL_ERROR -> IDR.string.enrol_last_biometrics_alert_message
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import com.simprints.core.livedata.send
import com.simprints.core.tools.time.TimeHelper
import com.simprints.feature.enrollast.EnrolLastBiometricParams
import com.simprints.feature.enrollast.EnrolLastBiometricStepResult
import com.simprints.feature.enrollast.screen.EnrolLastState.ErrorType.DUPLICATE_ENROLMENTS
import com.simprints.feature.enrollast.screen.EnrolLastState.ErrorType.GENERAL_ERROR
import com.simprints.feature.enrollast.screen.usecase.BuildSubjectUseCase
import com.simprints.feature.enrollast.screen.usecase.HasDuplicateEnrolmentsUseCase
import com.simprints.feature.enrollast.screen.usecase.CheckForDuplicateEnrolmentsUseCase
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
Expand All @@ -32,7 +31,7 @@ internal class EnrolLastBiometricViewModel @Inject constructor(
private val configManager: ConfigManager,
private val eventRepository: SessionEventRepository,
private val enrolmentRecordRepository: EnrolmentRecordRepository,
private val hasDuplicateEnrolments: HasDuplicateEnrolmentsUseCase,
private val checkForDuplicateEnrolments: CheckForDuplicateEnrolmentsUseCase,
private val buildSubject: BuildSubjectUseCase,
) : ViewModel() {
val finish: LiveData<LiveDataEventWithContent<EnrolLastState>>
Expand Down Expand Up @@ -63,8 +62,9 @@ internal class EnrolLastBiometricViewModel @Inject constructor(
)
return@launch
}
if (hasDuplicateEnrolments(projectConfig, params.steps)) {
_finish.send(EnrolLastState.Failed(DUPLICATE_ENROLMENTS, modalities))
val duplicateEnrolmentError = checkForDuplicateEnrolments(projectConfig, params.steps)
if (duplicateEnrolmentError != null) {
_finish.send(EnrolLastState.Failed(duplicateEnrolmentError, modalities))
return@launch
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ internal sealed class EnrolLastState {
) : EnrolLastState()

enum class ErrorType {
NO_MATCH_RESULTS,
DUPLICATE_ENROLMENTS,
GENERAL_ERROR,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@
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.ProjectConfiguration
import com.simprints.infra.logging.LoggingConstants.CrashReportTag.ENROLMENT
import com.simprints.infra.logging.Simber
import javax.inject.Inject

internal class HasDuplicateEnrolmentsUseCase @Inject constructor() {
internal class CheckForDuplicateEnrolmentsUseCase @Inject constructor() {
operator fun invoke(
projectConfig: ProjectConfiguration,
steps: List<EnrolLastBiometricStepResult>,
): Boolean {
if (!projectConfig.general.duplicateBiometricEnrolmentCheck) return false
): EnrolLastState.ErrorType? {
if (!projectConfig.general.duplicateBiometricEnrolmentCheck) return null

val fingerprintResponse = getFingerprintMatchResult(steps)
val faceResponse = getFaceMatchResult(steps)

return when {
fingerprintResponse == null && faceResponse == null -> {
Simber.i("No capture response. Must be either fingerprint, face or both", tag = ENROLMENT)
true
Simber.e(
"No match response. Must be either fingerprint, face or both",
MissingMatchResultException(),
tag = ENROLMENT
)
EnrolLastState.ErrorType.NO_MATCH_RESULTS
}

isAnyResponseWithHighConfidence(projectConfig, fingerprintResponse, faceResponse) -> {
Simber.i("There is a subject with confidence score above the high confidence level", tag = ENROLMENT)
true
EnrolLastState.ErrorType.DUPLICATE_ENROLMENTS
}

else -> false
else -> null
}
}

Expand Down Expand Up @@ -61,4 +66,6 @@ internal class HasDuplicateEnrolmentsUseCase @Inject constructor() {
return fingerprintResponse?.results?.any { it.confidenceScore >= fingerprintThreshold } == true ||
faceResponse?.results?.any { it.confidenceScore >= faceThreshold } == true
}

private class MissingMatchResultException() : IllegalStateException("No match response in duplicate check.")
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.simprints.feature.enrollast.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.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.screen.usecase.BuildSubjectUseCase
import com.simprints.feature.enrollast.screen.usecase.HasDuplicateEnrolmentsUseCase
import com.simprints.feature.enrollast.screen.usecase.CheckForDuplicateEnrolmentsUseCase
import com.simprints.infra.config.store.models.ProjectConfiguration
import com.simprints.infra.config.sync.ConfigManager
import com.simprints.infra.enrolment.records.repository.EnrolmentRecordRepository
Expand All @@ -20,12 +20,8 @@ import com.simprints.infra.events.event.domain.models.EnrolmentEventV4
import com.simprints.infra.events.event.domain.models.PersonCreationEvent
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.test.runTest
import org.junit.Before
import org.junit.Rule
Expand Down Expand Up @@ -54,7 +50,7 @@ internal class EnrolLastBiometricViewModelTest {
lateinit var enrolmentRecordRepository: EnrolmentRecordRepository

@MockK
lateinit var hasDuplicateEnrolments: HasDuplicateEnrolmentsUseCase
lateinit var checkForDuplicateEnrolments: CheckForDuplicateEnrolmentsUseCase

@MockK
lateinit var buildSubject: BuildSubjectUseCase
Expand Down Expand Up @@ -83,7 +79,7 @@ internal class EnrolLastBiometricViewModelTest {
configManager,
eventRepository,
enrolmentRecordRepository,
hasDuplicateEnrolments,
checkForDuplicateEnrolments,
buildSubject,
)
}
Expand Down Expand Up @@ -159,7 +155,7 @@ internal class EnrolLastBiometricViewModelTest {

@Test
fun `returns failure when has duplicate enrolments`() = runTest {
every { hasDuplicateEnrolments.invoke(any(), any()) } returns true
every { checkForDuplicateEnrolments.invoke(any(), any()) } returns EnrolLastState.ErrorType.DUPLICATE_ENROLMENTS

viewModel.enrolBiometric(createParams(listOf()))

Expand All @@ -174,7 +170,7 @@ internal class EnrolLastBiometricViewModelTest {

@Test
fun `returns success when no duplicate enrolments`() = runTest {
every { hasDuplicateEnrolments.invoke(any(), any()) } returns false
every { checkForDuplicateEnrolments.invoke(any(), any()) } returns null
coEvery { buildSubject.invoke(any()) } returns subject

viewModel.enrolBiometric(createParams(listOf()))
Expand All @@ -188,7 +184,7 @@ internal class EnrolLastBiometricViewModelTest {

@Test
fun `saves event and record when no duplicate enrolments`() = runTest {
every { hasDuplicateEnrolments.invoke(any(), any()) } returns false
every { checkForDuplicateEnrolments.invoke(any(), any()) } returns null
coEvery { buildSubject.invoke(any()) } returns subject

viewModel.enrolBiometric(createParams(listOf()))
Expand All @@ -199,7 +195,7 @@ internal class EnrolLastBiometricViewModelTest {

@Test
fun `returns failure record saving fails`() = runTest {
every { hasDuplicateEnrolments.invoke(any(), any()) } returns false
every { checkForDuplicateEnrolments.invoke(any(), any()) } returns null
coEvery { buildSubject.invoke(any()) } returns subject
coEvery { enrolmentRecordRepository.performActions(any(), any()) } throws Exception()

Expand All @@ -215,6 +211,7 @@ internal class EnrolLastBiometricViewModelTest {

@Test
fun `Uses all BiometricReferenceCreationEvent for Enrolment event`() = runTest {
every { checkForDuplicateEnrolments.invoke(any(), any()) } returns null
val biometricReferenceCreationEvent1 = mockk<BiometricReferenceCreationEvent> {
every { id } returns "biometricReferenceCreationEventId1"
every { payload } returns mockk<BiometricReferenceCreationPayload> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package com.simprints.feature.enrollast.screen.usecase

import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.*
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.ProjectConfiguration
import io.mockk.every
import io.mockk.mockk
import io.mockk.*
import org.junit.Before
import org.junit.Test

class HasDuplicateEnrolmentsUseCaseTest {
private lateinit var useCase: HasDuplicateEnrolmentsUseCase
class CheckDuplicateEnrolmentsErrorsUseCaseTest {
private lateinit var useCase: CheckForDuplicateEnrolmentsUseCase

@Before
fun setUp() {
useCase = HasDuplicateEnrolmentsUseCase()
useCase = CheckForDuplicateEnrolmentsUseCase()
}

@Test
Expand All @@ -25,7 +25,7 @@ class HasDuplicateEnrolmentsUseCaseTest {
steps = emptyList(),
)

assertThat(result).isFalse()
assertThat(result).isNull()
}

@Test
Expand All @@ -40,7 +40,7 @@ class HasDuplicateEnrolmentsUseCaseTest {
),
)

assertThat(result).isFalse()
assertThat(result).isNull()
}

@Test
Expand All @@ -56,7 +56,7 @@ class HasDuplicateEnrolmentsUseCaseTest {
),
)

assertThat(result).isFalse()
assertThat(result).isNull()
}

@Test
Expand All @@ -71,7 +71,7 @@ class HasDuplicateEnrolmentsUseCaseTest {
),
)

assertThat(result).isFalse()
assertThat(result).isNull()
}

@Test
Expand All @@ -87,7 +87,7 @@ class HasDuplicateEnrolmentsUseCaseTest {
),
)

assertThat(result).isFalse()
assertThat(result).isNull()
}

@Test
Expand All @@ -97,7 +97,7 @@ class HasDuplicateEnrolmentsUseCaseTest {
steps = emptyList(),
)

assertThat(result).isTrue()
assertThat(result).isEqualTo(EnrolLastState.ErrorType.NO_MATCH_RESULTS)
}

@Test
Expand All @@ -112,7 +112,7 @@ class HasDuplicateEnrolmentsUseCaseTest {
),
)

assertThat(result).isTrue()
assertThat(result).isEqualTo(EnrolLastState.ErrorType.DUPLICATE_ENROLMENTS)
}

@Test
Expand All @@ -128,7 +128,7 @@ class HasDuplicateEnrolmentsUseCaseTest {
),
)

assertThat(result).isTrue()
assertThat(result).isEqualTo(EnrolLastState.ErrorType.DUPLICATE_ENROLMENTS)
}

private fun mockProjectConfig(
Expand Down