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 @@ -148,6 +148,7 @@ class ClientApiViewModel @Inject internal constructor(
sessionId = currentSessionId,
identifications = identifyResponse.identifications,
isMultiFactorIdEnabled = identifyResponse.isMultiFactorIdEnabled,
scannedCredential = identifyResponse.scannedCredential,
),
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ internal class LibSimprintsResponseMapper @Inject constructor(
.toJson(),
)
}
}
}.appendExternalCredential(response.scannedCredential.takeIf { response.isMultiFactorIdEnabled })
Comment thread
alexandr-simprints marked this conversation as resolved.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the takeIf kinda redundant here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it as well, but this approach seems less error-prone if we ever want to change the logic of the returned credential


is ActionResponse.ConfirmActionResponse -> {
bundleOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ internal class ClientApiViewModelTest {
mockk {
every { identifications } returns emptyList()
every { isMultiFactorIdEnabled } returns false
every { scannedCredential } returns null
},
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class CommCareResponseMapperTest {
),
),
isMultiFactorIdEnabled = false,
scannedCredential = null,
),
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.simprints.feature.clientapi.mappers.response

import android.os.Bundle
import androidx.test.ext.junit.runners.*
import com.google.common.truth.Truth.*
import com.simprints.core.domain.externalcredential.ExternalCredentialType
Expand All @@ -16,6 +17,7 @@ import com.simprints.feature.clientapi.mappers.response.LibSimprintsResponseMapp
import com.simprints.feature.clientapi.mappers.response.LibSimprintsResponseMapper.Companion.SCANNED_CREDENTIAL_TYPE
import com.simprints.feature.clientapi.mappers.response.LibSimprintsResponseMapper.Companion.SCANNED_CREDENTIAL_VALUE
import com.simprints.infra.orchestration.data.ActionResponse
import com.simprints.infra.orchestration.data.responses.AppExternalCredential
import com.simprints.infra.orchestration.data.responses.AppMatchResult
import com.simprints.libsimprints.Constants
import com.simprints.libsimprints.contracts.VersionsList
Expand Down Expand Up @@ -93,6 +95,7 @@ class LibSimprintsResponseMapperTest {
),
),
isMultiFactorIdEnabled = false,
scannedCredential = null,
),
)

Expand Down Expand Up @@ -121,6 +124,7 @@ class LibSimprintsResponseMapperTest {
),
),
isMultiFactorIdEnabled = false,
scannedCredential = null,
),
)

Expand Down Expand Up @@ -469,6 +473,7 @@ class LibSimprintsResponseMapperTest {
sessionId = "sessionId",
identifications = listOf(identification1, identification2),
isMultiFactorIdEnabled = true,
scannedCredential = null,
),
)

Expand Down Expand Up @@ -496,6 +501,7 @@ class LibSimprintsResponseMapperTest {
),
),
isMultiFactorIdEnabled = true,
scannedCredential = null,
),
)

Expand Down Expand Up @@ -523,6 +529,7 @@ class LibSimprintsResponseMapperTest {
),
),
isMultiFactorIdEnabled = false,
scannedCredential = null,
),
)

Expand All @@ -531,6 +538,76 @@ class LibSimprintsResponseMapperTest {
)
}

@Test
fun `when MFID is enabled, identify response contains scanned credential`() {
val expectedValue = "expectedValue".asTokenizableRaw()
val expectedType = ExternalCredentialType.NHISCard
val expectedJson = "{\"$SCANNED_CREDENTIAL_VALUE\":\"$expectedValue\",\"$SCANNED_CREDENTIAL_TYPE\":\"$expectedType\"}"
val scannedCredential = mockk<AppExternalCredential> {
every { value } returns expectedValue
every { type } returns expectedType
}

val extras = mapper(
createIdentifyActionResponse(
isMultiFactorIdEnabled = true,
scannedCredential = scannedCredential,
),
)

assertCommonMfidIdentifyFields(extras)
assertThat(extras.getString(SCANNED_CREDENTIAL)).isEqualTo(expectedJson)
}

@Test
fun `when MFID is disabled, identify response does not contain credential`() {
val expectedValue = "expectedValue".asTokenizableRaw()
val expectedType = ExternalCredentialType.NHISCard
val scannedCredential = mockk<AppExternalCredential> {
every { value } returns expectedValue
every { type } returns expectedType
}

val extras = mapper(
createIdentifyActionResponse(
isMultiFactorIdEnabled = false,
scannedCredential = scannedCredential,
),
)

assertCommonMfidIdentifyFields(extras)
assertThat(extras.keySet()).doesNotContain(SCANNED_CREDENTIAL)
}

// Helper functions
private fun createIdentifyActionResponse(
sessionId: String = "sessionId",
isMultiFactorIdEnabled: Boolean,
scannedCredential: AppExternalCredential? = null,
identifications: List<AppMatchResult> = listOf(
AppMatchResult(
guid = "guid-1",
confidenceScore = 100,
matchConfidence = AppMatchConfidence.MEDIUM,
isLinkedToScannedCredential = true,
isCredentialVerified = true,
),
),
) = ActionResponse.IdentifyActionResponse(
actionIdentifier = IdentifyRequestActionFactory.getIdentifier(),
sessionId = sessionId,
identifications = identifications,
isMultiFactorIdEnabled = isMultiFactorIdEnabled,
scannedCredential = scannedCredential,
)

private fun assertCommonMfidIdentifyFields(extras: Bundle) {
assertThat(extras.getString(Constants.SIMPRINTS_SESSION_ID)).isEqualTo("sessionId")
assertThat(extras.getString(Constants.SIMPRINTS_DEVICE_ID)).isEqualTo("deviceId")
assertThat(extras.getString(Constants.SIMPRINTS_APP_VERSION_NAME)).isEqualTo("appVersionName")
assertThat(extras.getBoolean(Constants.SIMPRINTS_BIOMETRICS_COMPLETE_CHECK)).isTrue()
}

private fun AppMatchResult.toResponseJson(): String {
val jsonBuilder = StringBuilder()
jsonBuilder.append("{\"guid\":\"$guid\"")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class OdkResponseMapperTest {
),
),
isMultiFactorIdEnabled = false,
scannedCredential = null,
),
)

Expand All @@ -75,6 +76,7 @@ class OdkResponseMapperTest {
sessionId = "sessionId",
identifications = listOf(),
isMultiFactorIdEnabled = false,
scannedCredential = null,
),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,14 @@ internal class MapRefusalOrErrorResultUseCase @Inject constructor(
is ValidateSubjectPoolResult ->
result
.takeUnless { it.isValid }
?.let { AppIdentifyResponse(emptyList(), eventRepository.getCurrentSessionScope().id, isMultiFactorIdEnabled = false) }
?.let {
AppIdentifyResponse(
identifications = emptyList(),
sessionId = eventRepository.getCurrentSessionScope().id,
isMultiFactorIdEnabled = false,
scannedCredential = null,
)
}

is SelectSubjectAgeGroupResult ->
result
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.simprints.feature.orchestrator.usecases.response

import com.simprints.feature.externalcredential.ExternalCredentialSearchResult
import com.simprints.feature.externalcredential.screens.search.model.ScannedCredential
import com.simprints.infra.config.store.models.DecisionPolicy
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.orchestration.data.responses.AppExternalCredential
import com.simprints.infra.orchestration.data.responses.AppIdentifyResponse
import com.simprints.infra.orchestration.data.responses.AppMatchResult
import com.simprints.infra.orchestration.data.responses.AppResponse
Expand Down Expand Up @@ -45,10 +47,25 @@ internal class CreateIdentifyResponseUseCase @Inject constructor(
.distinctBy(AppMatchResult::guid)
.take(projectConfiguration.identification.maxNbOfReturnedCandidates)

val externalCredential = results
.filterIsInstance(ExternalCredentialSearchResult::class.java)
.lastOrNull()
?.scannedCredential
.toAppExternalCredential()

return AppIdentifyResponse(
sessionId = currentSessionId,
isMultiFactorIdEnabled = isMultiFactorIdEnabled,
identifications = identifications,
scannedCredential = externalCredential,
)
}

private fun ScannedCredential?.toAppExternalCredential(): AppExternalCredential? = this?.let { scannedCredential ->
AppExternalCredential(
id = scannedCredential.credentialScanId,
value = scannedCredential.scannedValue,
type = scannedCredential.credentialType,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class AddCallbackEventUseCaseTest {
listOf(AppMatchResult("guid", 0, AppMatchConfidence.HIGH)),
"sessionId",
isMultiFactorIdEnabled = false,
scannedCredential = null,
),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class UpdateDailyActivityUseCaseTest {

@Test
fun `Update daily activity on identify response`() = runTest {
useCase(AppIdentifyResponse(emptyList(), "guid", isMultiFactorIdEnabled = false))
useCase(AppIdentifyResponse(emptyList(), "guid", isMultiFactorIdEnabled = false, scannedCredential = null))

coVerify { recentUserActivityManager.updateRecentUserActivity(any()) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ class CreateIdentifyResponseUseCaseTest {
results = listOf(
mockk<ExternalCredentialSearchResult> {
every { matchResults } returns fingerprintMatches + faceMatches
every { scannedCredential } returns null
},
),
)
Expand Down Expand Up @@ -304,6 +305,7 @@ class CreateIdentifyResponseUseCaseTest {
results = listOf(
mockk<ExternalCredentialSearchResult> {
every { matchResults } returns credentialFaceMatches
every { scannedCredential } returns null
},
FaceMatchResult(
listOf(
Expand Down Expand Up @@ -355,6 +357,7 @@ class CreateIdentifyResponseUseCaseTest {
results = listOf(
mockk<ExternalCredentialSearchResult> {
every { matchResults } returns credentialFingerprintMatches
every { scannedCredential } returns null
},
FingerprintMatchResult(
listOf(
Expand Down Expand Up @@ -430,6 +433,7 @@ class CreateIdentifyResponseUseCaseTest {
results = listOf(
mockk<ExternalCredentialSearchResult> {
every { matchResults } returns credentialFaceMatches
every { scannedCredential } returns null
},
faceMatchResults,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ sealed class ActionResponse(
override val sessionId: String,
val identifications: List<AppMatchResult>,
val isMultiFactorIdEnabled: Boolean,
Comment thread
alexandr-simprints marked this conversation as resolved.
val scannedCredential: AppExternalCredential?,
) : ActionResponse(actionIdentifier, sessionId)

@ExcludedFromGeneratedTestCoverageReports("Data struct")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ data class AppIdentifyResponse(
val identifications: List<AppMatchResult>,
val sessionId: String,
val isMultiFactorIdEnabled: Boolean,
val scannedCredential: AppExternalCredential?,
) : AppResponse()