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 @@ -4,6 +4,7 @@ data class SyncInfo(
val isLoggedIn: Boolean = true,
val isConfigurationLoadingProgressBarVisible: Boolean = false,
val isLoginPromptSectionVisible: Boolean = false,
val isImageSyncSectionVisible: Boolean = false,
val syncInfoSectionRecords: SyncInfoSectionRecords = SyncInfoSectionRecords(),
val syncInfoSectionImages: SyncInfoSectionImages = SyncInfoSectionImages(),
val syncInfoSectionModules: SyncInfoSectionModules = SyncInfoSectionModules(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.core.view.isGone
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
Expand Down Expand Up @@ -195,7 +196,7 @@ internal class SyncInfoFragment : Fragment(R.layout.fragment_sync_info) {
renderRecordsSection(syncInfo.syncInfoSectionRecords, config)

// Images section
binding.layoutImagesSync.isGone = !config.isSyncInfoImageSyncVisible
binding.layoutImagesSync.isVisible = config.isSyncInfoImageSyncVisible && syncInfo.isImageSyncSectionVisible
renderImagesSection(syncInfo.syncInfoSectionImages)

// Modules section
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.simprints.infra.config.store.models.TokenKeyType
import com.simprints.infra.config.store.models.canSyncDataToSimprints
import com.simprints.infra.config.store.models.isCommCareEventDownSyncAllowed
import com.simprints.infra.config.store.models.isModuleSelectionAvailable
import com.simprints.infra.config.store.models.isSampleUploadEnabledInProject
import com.simprints.infra.config.store.models.isSimprintsEventDownSyncAllowed
import com.simprints.infra.config.store.tokenization.TokenizationProcessor
import com.simprints.infra.config.sync.ConfigManager
Expand Down Expand Up @@ -320,12 +321,13 @@ internal class ObserveSyncInfoUseCase @Inject constructor(
)

val syncInfo = SyncInfo(
isLoggedIn,
isLoggedIn = isLoggedIn,
isConfigurationLoadingProgressBarVisible = isRefreshing,
isLoginPromptSectionVisible = isReLoginRequired && !isPreLogoutUpSync,
syncInfoSectionRecords,
syncInfoSectionImages,
syncInfoSectionModules,
isImageSyncSectionVisible = projectConfig.isSampleUploadEnabledInProject(),
syncInfoSectionRecords = syncInfoSectionRecords,
syncInfoSectionImages = syncInfoSectionImages,
syncInfoSectionModules = syncInfoSectionModules,
)
return@combine9 syncInfo
}.onRecordSyncComplete {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.simprints.infra.config.store.models.UpSynchronizationConfiguration
import com.simprints.infra.config.store.models.canSyncDataToSimprints
import com.simprints.infra.config.store.models.isCommCareEventDownSyncAllowed
import com.simprints.infra.config.store.models.isModuleSelectionAvailable
import com.simprints.infra.config.store.models.isSampleUploadEnabledInProject
import com.simprints.infra.config.store.models.isSimprintsEventDownSyncAllowed
import com.simprints.infra.config.store.tokenization.TokenizationProcessor
import com.simprints.infra.config.sync.ConfigManager
Expand Down Expand Up @@ -180,6 +181,7 @@ class ObserveSyncInfoUseCaseTest {
every { any<ProjectConfiguration>().isModuleSelectionAvailable() } returns false
every { any<ProjectConfiguration>().isSimprintsEventDownSyncAllowed() } returns true
every { any<ProjectConfiguration>().isCommCareEventDownSyncAllowed() } returns false
every { any<ProjectConfiguration>().isSampleUploadEnabledInProject() } returns true
every { commCarePermissionChecker.hasCommCarePermissions() } returns true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,30 @@ fun ProjectConfiguration.canSyncBiometricDataToSimprints(): Boolean =
fun ProjectConfiguration.canSyncAnalyticsDataToSimprints(): Boolean =
synchronization.up.simprints.kind == UpSynchronizationConfiguration.UpSynchronizationKind.ONLY_ANALYTICS

fun ProjectConfiguration.isSimprintsEventDownSyncAllowed(): Boolean =
synchronization.down.simprints != null &&
fun ProjectConfiguration.isSimprintsEventDownSyncAllowed(): Boolean = synchronization.down.simprints != null &&
synchronization.down.simprints.frequency != Frequency.ONLY_PERIODICALLY_UP_SYNC

fun ProjectConfiguration.isCommCareEventDownSyncAllowed(): Boolean = synchronization.down.commCare != null

fun ProjectConfiguration.imagesUploadRequiresUnmeteredConnection(): Boolean = synchronization.up.simprints.imagesRequireUnmeteredConnection

fun ProjectConfiguration.isSampleUploadEnabledInProject(): Boolean = listOfNotNull(
face?.rankOne?.imageSavingStrategy?.let { it != FaceConfiguration.ImageSavingStrategy.NEVER },
face?.simFace?.imageSavingStrategy?.let { it != FaceConfiguration.ImageSavingStrategy.NEVER },
fingerprint
?.nec
?.vero2
?.imageSavingStrategy
?.let { it != Vero2Configuration.ImageSavingStrategy.NEVER },
fingerprint
?.secugenSimMatcher
?.vero2
?.imageSavingStrategy
?.let { it != Vero2Configuration.ImageSavingStrategy.NEVER },
).let { explicitStrategies ->
explicitStrategies.isNotEmpty() && explicitStrategies.any { it }
}

fun ProjectConfiguration.allowedAgeRanges(): List<AgeGroup> = listOfNotNull(
face?.rankOne?.allowedAgeRange,
fingerprint?.secugenSimMatcher?.allowedAgeRange,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.simprints.infra.config.store.models

import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.*
import com.simprints.infra.config.store.models.UpSynchronizationConfiguration.CoSyncUpSynchronizationConfiguration
import com.simprints.infra.config.store.models.UpSynchronizationConfiguration.SimprintsUpSynchronizationConfiguration
import com.simprints.infra.config.store.models.UpSynchronizationConfiguration.UpSynchronizationKind.ALL
Expand All @@ -10,10 +10,12 @@ import com.simprints.infra.config.store.models.UpSynchronizationConfiguration.Up
import com.simprints.infra.config.store.testtools.faceConfiguration
import com.simprints.infra.config.store.testtools.faceSdkConfiguration
import com.simprints.infra.config.store.testtools.fingerprintConfiguration
import com.simprints.infra.config.store.testtools.fingerprintSdkConfiguration
import com.simprints.infra.config.store.testtools.projectConfiguration
import com.simprints.infra.config.store.testtools.simprintsDownSyncConfigurationConfiguration
import com.simprints.infra.config.store.testtools.simprintsUpSyncConfigurationConfiguration
import com.simprints.infra.config.store.testtools.synchronizationConfiguration
import com.simprints.infra.config.store.testtools.vero2Configuration
import org.junit.Test

class ProjectConfigurationTest {
Expand Down Expand Up @@ -232,7 +234,7 @@ class ProjectConfigurationTest {
val config = projectConfiguration.copy(
synchronization = synchronizationConfiguration.copy(
down = synchronizationConfiguration.down.copy(
simprints = null
simprints = null,
),
),
)
Expand All @@ -245,7 +247,7 @@ class ProjectConfigurationTest {
val config = projectConfiguration.copy(
synchronization = synchronizationConfiguration.copy(
down = synchronizationConfiguration.down.copy(
commCare = DownSynchronizationConfiguration.CommCareDownSynchronizationConfiguration
commCare = DownSynchronizationConfiguration.CommCareDownSynchronizationConfiguration,
),
),
)
Expand All @@ -258,7 +260,7 @@ class ProjectConfigurationTest {
val config = projectConfiguration.copy(
synchronization = synchronizationConfiguration.copy(
down = synchronizationConfiguration.down.copy(
commCare = null
commCare = null,
),
),
)
Expand All @@ -284,6 +286,74 @@ class ProjectConfigurationTest {
}
}

@Test
fun `isSampleUploadEnabledInProject should return correct based on available saving strategy`() {
data class TestData(
val rankOneStrategy: FaceConfiguration.ImageSavingStrategy? = null,
val simFaceStrategy: FaceConfiguration.ImageSavingStrategy? = null,
val secugenStrategy: Vero2Configuration.ImageSavingStrategy? = null,
val necStragery: Vero2Configuration.ImageSavingStrategy? = null,
val result: Boolean,
)
listOf(
TestData(
rankOneStrategy = FaceConfiguration.ImageSavingStrategy.ONLY_GOOD_SCAN,
simFaceStrategy = FaceConfiguration.ImageSavingStrategy.NEVER,
result = true,
),
TestData(
necStragery = Vero2Configuration.ImageSavingStrategy.NEVER,
secugenStrategy = Vero2Configuration.ImageSavingStrategy.ONLY_GOOD_SCAN,
result = true,
),
TestData(
simFaceStrategy = FaceConfiguration.ImageSavingStrategy.ONLY_GOOD_SCAN,
secugenStrategy = Vero2Configuration.ImageSavingStrategy.NEVER,
result = true,
),
TestData(
simFaceStrategy = FaceConfiguration.ImageSavingStrategy.ONLY_GOOD_SCAN,
secugenStrategy = Vero2Configuration.ImageSavingStrategy.ONLY_GOOD_SCAN,
result = true,
),
TestData(
necStragery = Vero2Configuration.ImageSavingStrategy.ONLY_GOOD_SCAN,
result = true,
),
TestData(
rankOneStrategy = FaceConfiguration.ImageSavingStrategy.NEVER,
simFaceStrategy = FaceConfiguration.ImageSavingStrategy.NEVER,
necStragery = Vero2Configuration.ImageSavingStrategy.NEVER,
secugenStrategy = Vero2Configuration.ImageSavingStrategy.NEVER,
result = false,
),
TestData(
rankOneStrategy = FaceConfiguration.ImageSavingStrategy.NEVER,
necStragery = Vero2Configuration.ImageSavingStrategy.NEVER,
result = false,
),
TestData(result = false),
).forEach { (rankOne, simFace, secugen, nec, result) ->
assertThat(
projectConfiguration
.copy(
face = faceConfiguration.copy(
rankOne = rankOne?.let { faceSdkConfiguration.copy(imageSavingStrategy = it) },
simFace = simFace?.let { faceSdkConfiguration.copy(imageSavingStrategy = it) },
),
fingerprint = fingerprintConfiguration.copy(
secugenSimMatcher = secugen?.let {
fingerprintSdkConfiguration.copy(vero2 = vero2Configuration.copy(imageSavingStrategy = it))
},
nec = nec?.let {
fingerprintSdkConfiguration.copy(vero2 = vero2Configuration.copy(imageSavingStrategy = it))
},
),
).isSampleUploadEnabledInProject(),
).isEqualTo(result)
}
}

@Test
fun `allowedAgeRanges returns all non-null age ranges`() {
val faceAgeRange = AgeGroup(10, 20)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,20 +261,22 @@ internal val apiFingerprintConfiguration = ApiFingerprintConfiguration(
nec = null,
)

internal val fingerprintSdkConfiguration = FingerprintConfiguration.FingerprintSdkConfiguration(
fingersToCapture = listOf(Finger.LEFT_3RD_FINGER),
decisionPolicy = decisionPolicy,
comparisonStrategyForVerification = FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER,
vero1 = Vero1Configuration(qualityThreshold = 10),
vero2 = vero2Configuration,
allowedAgeRange = allowedAgeRange,
verificationMatchThreshold = 42.0f,
maxCaptureAttempts = MaxCaptureAttempts(noFingerDetected = 17),
)

internal val fingerprintConfiguration = FingerprintConfiguration(
allowedScanners = listOf(FingerprintConfiguration.VeroGeneration.VERO_2),
allowedSDKs = listOf(FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER),
displayHandIcons = true,
secugenSimMatcher = FingerprintConfiguration.FingerprintSdkConfiguration(
fingersToCapture = listOf(Finger.LEFT_3RD_FINGER),
decisionPolicy = decisionPolicy,
comparisonStrategyForVerification = FingerprintConfiguration.FingerComparisonStrategy.SAME_FINGER,
vero1 = Vero1Configuration(qualityThreshold = 10),
vero2 = vero2Configuration,
allowedAgeRange = allowedAgeRange,
verificationMatchThreshold = 42.0f,
maxCaptureAttempts = MaxCaptureAttempts(noFingerDetected = 17),
),
secugenSimMatcher = fingerprintSdkConfiguration,
nec = null,
)

Expand Down