diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index efdfd37c3a..c5b2b689d2 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -31,6 +31,7 @@ jobs: infra:realm infra:recent-user-activity infra:config-store + infra:config-sync infra:sync infra:auth-store infra:auth-logic diff --git a/face/capture/build.gradle.kts b/face/capture/build.gradle.kts index cc145492df..2dc2af5612 100644 --- a/face/capture/build.gradle.kts +++ b/face/capture/build.gradle.kts @@ -19,6 +19,7 @@ dependencies { implementation(project(":infra:orchestrator-data")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:enrolment-records-store")) implementation(project(":infra:events")) implementation(project(":infra:images")) 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 8d2850ce24..33d94e722b 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 @@ -14,8 +14,7 @@ import com.simprints.face.capture.models.FaceDetection import com.simprints.face.capture.usecases.BitmapToByteArrayUseCase import com.simprints.face.capture.usecases.SaveFaceImageUseCase import com.simprints.face.capture.usecases.SimpleCaptureEventReporter -import com.simprints.infra.config.store.ConfigRepository -import com.simprints.infra.config.store.models.FaceConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.facebiosdk.initialization.FaceBioSdkInitializer import com.simprints.infra.license.LicenseRepository import com.simprints.infra.license.LicenseStatus @@ -31,7 +30,7 @@ import javax.inject.Inject @HiltViewModel internal class FaceCaptureViewModel @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val saveFaceImage: SaveFaceImageUseCase, private val eventReporter: SimpleCaptureEventReporter, private val bitmapToByteArray: BitmapToByteArrayUseCase, @@ -99,7 +98,7 @@ internal class FaceCaptureViewModel @Inject constructor( fun flowFinished() { viewModelScope.launch { - val projectConfiguration = configRepository.getProjectConfiguration() + val projectConfiguration = configManager.getProjectConfiguration() if (projectConfiguration.face?.imageSavingStrategy?.shouldSaveImage() == true) { saveFaceDetections() } diff --git a/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedback/LiveFeedbackFragmentViewModel.kt b/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedback/LiveFeedbackFragmentViewModel.kt index e946ede860..1f1f400550 100644 --- a/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedback/LiveFeedbackFragmentViewModel.kt +++ b/face/capture/src/main/java/com/simprints/face/capture/screens/livefeedback/LiveFeedbackFragmentViewModel.kt @@ -13,7 +13,7 @@ import com.simprints.face.capture.models.FaceDetection import com.simprints.face.capture.models.FaceTarget import com.simprints.face.capture.models.SymmetricTarget import com.simprints.face.capture.usecases.SimpleCaptureEventReporter -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.facebiosdk.detection.Face import com.simprints.infra.facebiosdk.detection.FaceDetector import dagger.hilt.android.lifecycle.HiltViewModel @@ -28,7 +28,7 @@ import javax.inject.Inject internal class LiveFeedbackFragmentViewModel @Inject constructor( private val frameProcessor: FrameProcessor, private val faceDetector: FaceDetector, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val eventReporter: SimpleCaptureEventReporter, private val timeHelper: TimeHelper, ) : ViewModel() { @@ -101,7 +101,7 @@ internal class LiveFeedbackFragmentViewModel @Inject constructor( */ private fun finishCapture(attemptNumber: Int) { viewModelScope.launch { - val projectConfiguration = configRepository.getProjectConfiguration() + val projectConfiguration = configManager.getProjectConfiguration() sortedQualifyingCaptures = userCaptures .filter { it.hasValidStatus() && it.isAboveQualityThreshold(projectConfiguration.face!!.qualityThreshold) } .sortedByDescending { it.face?.quality } @@ -207,7 +207,7 @@ internal class LiveFeedbackFragmentViewModel @Inject constructor( private suspend fun sendCaptureEvent(faceDetection: FaceDetection, attemptNumber: Int) { val qualityThreshold = - configRepository.getProjectConfiguration().face!!.qualityThreshold.toFloat() + configManager.getProjectConfiguration().face!!.qualityThreshold.toFloat() eventReporter.addCaptureEvents(faceDetection, attemptNumber, qualityThreshold) } diff --git a/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt b/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt index 160c42505b..d174455648 100644 --- a/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt +++ b/face/capture/src/test/java/com/simprints/face/capture/screens/FaceCaptureViewModelTest.kt @@ -7,8 +7,8 @@ import com.simprints.face.capture.models.FaceDetection import com.simprints.face.capture.usecases.BitmapToByteArrayUseCase import com.simprints.face.capture.usecases.SaveFaceImageUseCase import com.simprints.face.capture.usecases.SimpleCaptureEventReporter -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FaceConfiguration.ImageSavingStrategy +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.facebiosdk.initialization.FaceBioSdkInitializer import com.simprints.infra.license.LicenseRepository import com.simprints.infra.license.LicenseStatus @@ -41,7 +41,7 @@ class FaceCaptureViewModelTest { val testCoroutineRule = TestCoroutineRule() @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var faceImageUseCase: SaveFaceImageUseCase @@ -77,7 +77,7 @@ class FaceCaptureViewModelTest { every { bitmapToByteArrayUseCase.invoke(any()) } returns byteArrayOf() viewModel = FaceCaptureViewModel( - configRepository, + configManager, faceImageUseCase, eventReporter, bitmapToByteArrayUseCase, @@ -89,7 +89,7 @@ class FaceCaptureViewModelTest { @Test fun `Save face detections should not be called when image saving strategy set to NEVER`() { - coEvery { configRepository.getProjectConfiguration().face?.imageSavingStrategy } returns ImageSavingStrategy.NEVER + coEvery { configManager.getProjectConfiguration().face?.imageSavingStrategy } returns ImageSavingStrategy.NEVER viewModel.captureFinished(faceDetections) viewModel.flowFinished() @@ -97,8 +97,8 @@ class FaceCaptureViewModelTest { } @Test - fun `Save face detections should be called when image saving strategy set to ONLY_GOO_SCAN`() { - coEvery { configRepository.getProjectConfiguration().face?.imageSavingStrategy } returns ImageSavingStrategy.ONLY_USED_IN_REFERENCE + fun `Save face detections should be called when image saving strategy set to ONLY_GOOD_SCAN`() { + coEvery { configManager.getProjectConfiguration().face?.imageSavingStrategy } returns ImageSavingStrategy.ONLY_GOOD_SCAN viewModel.captureFinished(faceDetections) viewModel.flowFinished() diff --git a/face/capture/src/test/java/com/simprints/face/capture/screens/livefeedback/LiveFeedbackFragmentViewModelTest.kt b/face/capture/src/test/java/com/simprints/face/capture/screens/livefeedback/LiveFeedbackFragmentViewModelTest.kt index 335f6eae49..9e8ab9b2f8 100644 --- a/face/capture/src/test/java/com/simprints/face/capture/screens/livefeedback/LiveFeedbackFragmentViewModelTest.kt +++ b/face/capture/src/test/java/com/simprints/face/capture/screens/livefeedback/LiveFeedbackFragmentViewModelTest.kt @@ -11,20 +11,23 @@ import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp import com.simprints.face.capture.models.FaceDetection import com.simprints.face.capture.usecases.SimpleCaptureEventReporter -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.facebiosdk.detection.Face import com.simprints.infra.facebiosdk.detection.FaceDetector import com.simprints.testtools.common.coroutines.TestCoroutineRule import com.simprints.testtools.common.livedata.testObserver -import io.mockk.* +import io.mockk.MockKAnnotations +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every import io.mockk.impl.annotations.MockK +import io.mockk.justRun import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner -import java.util.* import kotlin.random.Random @RunWith(RobolectricTestRunner::class) @@ -52,7 +55,7 @@ internal class LiveFeedbackFragmentViewModelTest { lateinit var rectF: RectF @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager @MockK lateinit var eventReporter: SimpleCaptureEventReporter @@ -68,7 +71,7 @@ internal class LiveFeedbackFragmentViewModelTest { fun setUp() { MockKAnnotations.init(this, relaxed = true) - coEvery { configRepository.getProjectConfiguration().face?.qualityThreshold } returns QUALITY_THRESHOLD + coEvery { configManager.getProjectConfiguration().face?.qualityThreshold } returns QUALITY_THRESHOLD every { timeHelper.now() } returnsMany (0..100L).map { Timestamp(it) } justRun { frameProcessor.init(any(), any()) } justRun { frame.close() } @@ -78,7 +81,7 @@ internal class LiveFeedbackFragmentViewModelTest { viewModel = LiveFeedbackFragmentViewModel( frameProcessor, faceDetector, - configRepository, + configManager, eventReporter, timeHelper ) diff --git a/feature/client-api/build.gradle.kts b/feature/client-api/build.gradle.kts index d6bd834aa6..ac38ee44bd 100644 --- a/feature/client-api/build.gradle.kts +++ b/feature/client-api/build.gradle.kts @@ -10,6 +10,7 @@ dependencies { implementation(project(":infra:auth-store")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:events")) implementation(project(":infra:enrolment-records-store")) implementation(project(":infra:orchestrator-data")) diff --git a/feature/client-api/src/main/java/com/simprints/feature/clientapi/ClientApiViewModel.kt b/feature/client-api/src/main/java/com/simprints/feature/clientapi/ClientApiViewModel.kt index cef0654793..c674b5d0d4 100644 --- a/feature/client-api/src/main/java/com/simprints/feature/clientapi/ClientApiViewModel.kt +++ b/feature/client-api/src/main/java/com/simprints/feature/clientapi/ClientApiViewModel.kt @@ -21,7 +21,7 @@ import com.simprints.feature.clientapi.usecases.GetEventsForCoSyncUseCase import com.simprints.feature.clientapi.usecases.IsFlowCompletedWithErrorUseCase import com.simprints.feature.clientapi.usecases.SimpleEventReporter import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.logging.Simber import com.simprints.infra.orchestration.data.ActionRequest import com.simprints.infra.orchestration.data.ActionRequestIdentifier @@ -48,7 +48,7 @@ class ClientApiViewModel @Inject internal constructor( private val deleteSessionEventsIfNeeded: DeleteSessionEventsIfNeededUseCase, private val isFlowCompletedWithError: IsFlowCompletedWithErrorUseCase, private val authStore: AuthStore, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, ) : ViewModel() { val returnResponse: LiveData> @@ -64,7 +64,7 @@ class ClientApiViewModel @Inject internal constructor( private val _showAlert = MutableLiveData>() private suspend fun getProject() = - runCatching { configRepository.getProject(authStore.signedInProjectId) }.getOrNull() + runCatching { configManager.getProject(authStore.signedInProjectId) }.getOrNull() suspend fun handleIntent(action: String, extras: Bundle): ActionRequest? { val extrasMap = extras.toMap() diff --git a/feature/client-api/src/main/java/com/simprints/feature/clientapi/usecases/DeleteSessionEventsIfNeededUseCase.kt b/feature/client-api/src/main/java/com/simprints/feature/clientapi/usecases/DeleteSessionEventsIfNeededUseCase.kt index bfc315a265..ce3b03dfae 100644 --- a/feature/client-api/src/main/java/com/simprints/feature/clientapi/usecases/DeleteSessionEventsIfNeededUseCase.kt +++ b/feature/client-api/src/main/java/com/simprints/feature/clientapi/usecases/DeleteSessionEventsIfNeededUseCase.kt @@ -1,21 +1,21 @@ package com.simprints.feature.clientapi.usecases import com.simprints.core.ExternalScope -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.canSyncDataToSimprints +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.EventRepository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import javax.inject.Inject internal class DeleteSessionEventsIfNeededUseCase @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val eventRepository: EventRepository, @ExternalScope private val externalScope: CoroutineScope, ) { suspend operator fun invoke(sessionId: String) = externalScope.launch { - if (!configRepository.getProjectConfiguration().canSyncDataToSimprints()) { + if (!configManager.getProjectConfiguration().canSyncDataToSimprints()) { eventRepository.deleteEventScope(sessionId) } } diff --git a/feature/client-api/src/main/java/com/simprints/feature/clientapi/usecases/GetEnrolmentCreationEventForSubjectUseCase.kt b/feature/client-api/src/main/java/com/simprints/feature/clientapi/usecases/GetEnrolmentCreationEventForSubjectUseCase.kt index 15e713aaa5..4367dfa3bb 100644 --- a/feature/client-api/src/main/java/com/simprints/feature/clientapi/usecases/GetEnrolmentCreationEventForSubjectUseCase.kt +++ b/feature/client-api/src/main/java/com/simprints/feature/clientapi/usecases/GetEnrolmentCreationEventForSubjectUseCase.kt @@ -2,24 +2,24 @@ package com.simprints.feature.clientapi.usecases import com.simprints.core.tools.json.JsonHelper import com.simprints.core.tools.utils.EncodingUtils -import com.simprints.infra.events.event.cosync.CoSyncEnrolmentRecordEvents -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.canCoSyncAllData import com.simprints.infra.config.store.models.canCoSyncBiometricData +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.store.domain.models.Subject import com.simprints.infra.enrolment.records.store.domain.models.SubjectQuery +import com.simprints.infra.events.event.cosync.CoSyncEnrolmentRecordEvents import com.simprints.infra.events.event.domain.models.subject.EnrolmentRecordCreationEvent import javax.inject.Inject internal class GetEnrolmentCreationEventForSubjectUseCase @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val enrolmentRecordRepository: EnrolmentRecordRepository, private val encoder: EncodingUtils, private val jsonHelper: JsonHelper, ) { suspend operator fun invoke(projectId: String, subjectId: String): String? { - val config = configRepository.getProjectConfiguration() + val config = configManager.getProjectConfiguration() if (!config.canCoSyncAllData() && !config.canCoSyncBiometricData()) { return null diff --git a/feature/client-api/src/main/java/com/simprints/feature/clientapi/usecases/GetEventsForCoSyncUseCase.kt b/feature/client-api/src/main/java/com/simprints/feature/clientapi/usecases/GetEventsForCoSyncUseCase.kt index 4d6b7e2d56..5a87f06e2b 100644 --- a/feature/client-api/src/main/java/com/simprints/feature/clientapi/usecases/GetEventsForCoSyncUseCase.kt +++ b/feature/client-api/src/main/java/com/simprints/feature/clientapi/usecases/GetEventsForCoSyncUseCase.kt @@ -4,15 +4,15 @@ import com.fasterxml.jackson.databind.module.SimpleModule import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.domain.tokenization.serialization.TokenizationAsStringSerializer import com.simprints.core.tools.json.JsonHelper -import com.simprints.infra.events.event.cosync.CoSyncEvents -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.store.models.canCoSyncAllData import com.simprints.infra.config.store.models.canCoSyncAnalyticsData import com.simprints.infra.config.store.models.canCoSyncBiometricData import com.simprints.infra.config.store.models.canCoSyncData import com.simprints.infra.config.store.tokenization.TokenizationProcessor +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.EventRepository +import com.simprints.infra.events.event.cosync.CoSyncEvents import com.simprints.infra.events.event.domain.models.EnrolmentEventV2 import com.simprints.infra.events.event.domain.models.Event import com.simprints.infra.events.event.domain.models.PersonCreationEvent @@ -21,14 +21,14 @@ import com.simprints.infra.events.event.domain.models.fingerprint.FingerprintCap import javax.inject.Inject internal class GetEventsForCoSyncUseCase @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val eventRepository: EventRepository, private val jsonHelper: JsonHelper, private val tokenizationProcessor: TokenizationProcessor, ) { suspend operator fun invoke(sessionId: String, project: Project?): String? { - val config = configRepository.getProjectConfiguration() + val config = configManager.getProjectConfiguration() if (!config.canCoSyncData()) { return null diff --git a/feature/client-api/src/test/java/com/simprints/feature/clientapi/ClientApiViewModelTest.kt b/feature/client-api/src/test/java/com/simprints/feature/clientapi/ClientApiViewModelTest.kt index 601e12bf0f..74e8ef7323 100644 --- a/feature/client-api/src/test/java/com/simprints/feature/clientapi/ClientApiViewModelTest.kt +++ b/feature/client-api/src/test/java/com/simprints/feature/clientapi/ClientApiViewModelTest.kt @@ -15,7 +15,7 @@ import com.simprints.feature.clientapi.usecases.GetEventsForCoSyncUseCase import com.simprints.feature.clientapi.usecases.IsFlowCompletedWithErrorUseCase import com.simprints.feature.clientapi.usecases.SimpleEventReporter import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.orchestration.data.ActionRequest import com.simprints.infra.orchestration.data.ActionRequestIdentifier import com.simprints.infra.orchestration.data.ActionResponse @@ -73,7 +73,7 @@ internal class ClientApiViewModelTest { lateinit var authStore: AuthStore @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager private lateinit var viewModel: ClientApiViewModel @@ -100,7 +100,7 @@ internal class ClientApiViewModelTest { deleteSessionEventsIfNeeded = deleteSessionEventsIfNeeded, isFlowCompletedWithError = isFlowCompletedWithError, authStore = authStore, - configRepository = configRepository + configManager = configManager ) } diff --git a/feature/client-api/src/test/java/com/simprints/feature/clientapi/usecases/DeleteSessionEventsIfNeededUseCaseTest.kt b/feature/client-api/src/test/java/com/simprints/feature/clientapi/usecases/DeleteSessionEventsIfNeededUseCaseTest.kt index efb9927ab0..d96b328155 100644 --- a/feature/client-api/src/test/java/com/simprints/feature/clientapi/usecases/DeleteSessionEventsIfNeededUseCaseTest.kt +++ b/feature/client-api/src/test/java/com/simprints/feature/clientapi/usecases/DeleteSessionEventsIfNeededUseCaseTest.kt @@ -1,7 +1,7 @@ package com.simprints.feature.clientapi.usecases -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.UpSynchronizationConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.EventRepository import com.simprints.testtools.common.coroutines.TestCoroutineRule import io.mockk.MockKAnnotations @@ -21,7 +21,7 @@ class DeleteSessionEventsIfNeededUseCaseTest { val testCoroutineRule = TestCoroutineRule() @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var eventRepository: EventRepository @@ -33,7 +33,7 @@ class DeleteSessionEventsIfNeededUseCaseTest { MockKAnnotations.init(this, relaxed = true) deleteUseCase = DeleteSessionEventsIfNeededUseCase( - configRepository, + configManager, eventRepository, CoroutineScope(testCoroutineRule.testCoroutineDispatcher), ) @@ -41,7 +41,7 @@ class DeleteSessionEventsIfNeededUseCaseTest { @Test fun `deletes session events if data sync disabled`() = runTest { - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { coEvery { synchronization.up.simprints.kind } returns UpSynchronizationConfiguration.UpSynchronizationKind.NONE } @@ -54,7 +54,7 @@ class DeleteSessionEventsIfNeededUseCaseTest { @Test fun `does not delete session events if data sync enabled`() = runTest { - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { coEvery { synchronization.up.simprints.kind } returns UpSynchronizationConfiguration.UpSynchronizationKind.ALL } diff --git a/feature/client-api/src/test/java/com/simprints/feature/clientapi/usecases/GetEnrolmentCreationEventForSubjectUseCaseTest.kt b/feature/client-api/src/test/java/com/simprints/feature/clientapi/usecases/GetEnrolmentCreationEventForSubjectUseCaseTest.kt index 7e99958797..3bca910ae1 100644 --- a/feature/client-api/src/test/java/com/simprints/feature/clientapi/usecases/GetEnrolmentCreationEventForSubjectUseCaseTest.kt +++ b/feature/client-api/src/test/java/com/simprints/feature/clientapi/usecases/GetEnrolmentCreationEventForSubjectUseCaseTest.kt @@ -3,8 +3,8 @@ package com.simprints.feature.clientapi.usecases import com.google.common.truth.Truth.assertThat import com.simprints.core.tools.json.JsonHelper import com.simprints.core.tools.utils.EncodingUtils -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.UpSynchronizationConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.testtools.common.coroutines.TestCoroutineRule import io.mockk.MockKAnnotations @@ -24,7 +24,7 @@ class GetEnrolmentCreationEventForSubjectUseCaseTest { val testCoroutineRule = TestCoroutineRule() @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var enrolmentRecordRepository: EnrolmentRecordRepository @@ -44,7 +44,7 @@ class GetEnrolmentCreationEventForSubjectUseCaseTest { every { jsonHelper.toJson(any()) } returns "json" useCase = GetEnrolmentCreationEventForSubjectUseCase( - configRepository, + configManager, enrolmentRecordRepository, encoder, jsonHelper @@ -53,7 +53,7 @@ class GetEnrolmentCreationEventForSubjectUseCaseTest { @Test fun `returns null if coSync disabled`() = runTest { - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { synchronization.up.coSync.kind } returns UpSynchronizationConfiguration.UpSynchronizationKind.NONE } @@ -65,7 +65,7 @@ class GetEnrolmentCreationEventForSubjectUseCaseTest { @Test fun `returns null if only analytics sync enabled`() = runTest { - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { synchronization.up.coSync.kind } returns UpSynchronizationConfiguration.UpSynchronizationKind.ONLY_ANALYTICS } @@ -77,7 +77,7 @@ class GetEnrolmentCreationEventForSubjectUseCaseTest { @Test fun `returns null if no creation event`() = runTest { - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { synchronization.up.coSync.kind } returns UpSynchronizationConfiguration.UpSynchronizationKind.ONLY_BIOMETRICS } @@ -90,7 +90,7 @@ class GetEnrolmentCreationEventForSubjectUseCaseTest { @Test fun `returns event if biometrics coSync enabled`() = runTest { - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { synchronization.up.coSync.kind } returns UpSynchronizationConfiguration.UpSynchronizationKind.ONLY_BIOMETRICS } diff --git a/feature/client-api/src/test/java/com/simprints/feature/clientapi/usecases/GetEventsForCoSyncUseCaseTest.kt b/feature/client-api/src/test/java/com/simprints/feature/clientapi/usecases/GetEventsForCoSyncUseCaseTest.kt index 1c3c96902c..181aded274 100644 --- a/feature/client-api/src/test/java/com/simprints/feature/clientapi/usecases/GetEventsForCoSyncUseCaseTest.kt +++ b/feature/client-api/src/test/java/com/simprints/feature/clientapi/usecases/GetEventsForCoSyncUseCaseTest.kt @@ -2,11 +2,11 @@ package com.simprints.feature.clientapi.usecases import com.google.common.truth.Truth.assertThat import com.simprints.core.tools.json.JsonHelper -import com.simprints.infra.events.event.cosync.CoSyncEvents -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.UpSynchronizationConfiguration import com.simprints.infra.config.store.tokenization.TokenizationProcessor +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.EventRepository +import com.simprints.infra.events.event.cosync.CoSyncEvents import com.simprints.infra.events.event.domain.models.EnrolmentEventV2 import com.simprints.infra.events.event.domain.models.PersonCreationEvent import com.simprints.infra.events.event.domain.models.face.FaceCaptureBiometricsEvent @@ -27,7 +27,7 @@ class GetEventsForCoSyncUseCaseTest { val testCoroutineRule = TestCoroutineRule() @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var eventRepository: EventRepository @@ -52,12 +52,12 @@ class GetEventsForCoSyncUseCaseTest { mockk(relaxed = true), ) - useCase = GetEventsForCoSyncUseCase(configRepository, eventRepository, jsonHelper, tokenizationProcessor) + useCase = GetEventsForCoSyncUseCase(configManager, eventRepository, jsonHelper, tokenizationProcessor) } @Test fun `returns null if coSync disabled`() = runTest { - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { synchronization.up.coSync.kind } returns UpSynchronizationConfiguration.UpSynchronizationKind.NONE } @@ -68,7 +68,7 @@ class GetEventsForCoSyncUseCaseTest { @Test fun `returns all events if full coSync enabled`() = runTest { - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { synchronization.up.coSync.kind } returns UpSynchronizationConfiguration.UpSynchronizationKind.ALL } every { jsonHelper.toJson(any ()) } returns "json" @@ -80,7 +80,7 @@ class GetEventsForCoSyncUseCaseTest { @Test fun `returns only analytics events if analytics coSync enabled`() = runTest { - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { synchronization.up.coSync.kind } returns UpSynchronizationConfiguration.UpSynchronizationKind.ONLY_ANALYTICS } every { jsonHelper.toJson(any ()) } returns "json" @@ -92,7 +92,7 @@ class GetEventsForCoSyncUseCaseTest { @Test fun `returns only biometric events if biometric coSync enabled`() = runTest { - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { synchronization.up.coSync.kind } returns UpSynchronizationConfiguration.UpSynchronizationKind.ONLY_BIOMETRICS } every { jsonHelper.toJson(any ()) } returns "json" diff --git a/feature/consent/build.gradle.kts b/feature/consent/build.gradle.kts index 341d9d9e71..b3237edef4 100644 --- a/feature/consent/build.gradle.kts +++ b/feature/consent/build.gradle.kts @@ -9,6 +9,7 @@ android { dependencies { implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:auth-store")) implementation(project(":infra:events")) implementation(project(":feature:exit-form")) diff --git a/feature/consent/src/main/java/com/simprints/feature/consent/screens/consent/ConsentViewModel.kt b/feature/consent/src/main/java/com/simprints/feature/consent/screens/consent/ConsentViewModel.kt index 7ac1259249..f5fe1977ea 100644 --- a/feature/consent/src/main/java/com/simprints/feature/consent/screens/consent/ConsentViewModel.kt +++ b/feature/consent/src/main/java/com/simprints/feature/consent/screens/consent/ConsentViewModel.kt @@ -16,9 +16,9 @@ import com.simprints.feature.exitform.ExitFormConfigurationBuilder import com.simprints.feature.exitform.ExitFormResult import com.simprints.feature.exitform.exitFormConfiguration import com.simprints.feature.exitform.scannerOptions -import com.simprints.infra.config.store.ConfigRepository 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.SessionEventRepository import com.simprints.infra.events.event.domain.models.ConsentEvent import com.simprints.infra.resources.R @@ -31,7 +31,7 @@ import javax.inject.Inject @HiltViewModel internal class ConsentViewModel @Inject constructor( private val timeHelper: TimeHelper, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val eventRepository: SessionEventRepository, private val generalConsentTextHelper: GeneralConsentTextHelper, private val parentalConsentTextHelper: ParentalConsentTextHelper, @@ -54,7 +54,7 @@ internal class ConsentViewModel @Inject constructor( fun loadConfiguration(consentType: ConsentType) { viewModelScope.launch { - val projectConfig = configRepository.getProjectConfiguration() + val projectConfig = configManager.getProjectConfiguration() _viewState.postValue(mapConfigToViewState(projectConfig, consentType)) } } @@ -67,7 +67,7 @@ internal class ConsentViewModel @Inject constructor( fun declineClicked(currentConsentTab: ConsentTab) { saveConsentEvent(currentConsentTab, ConsentEvent.ConsentPayload.Result.DECLINED) viewModelScope.launch { - val projectConfig = configRepository.getProjectConfiguration() + val projectConfig = configManager.getProjectConfiguration() _showExitForm.send(getExitFormFromModalities(projectConfig.general.modalities)) } } diff --git a/feature/consent/src/main/java/com/simprints/feature/consent/screens/privacy/PrivacyNoticeViewModel.kt b/feature/consent/src/main/java/com/simprints/feature/consent/screens/privacy/PrivacyNoticeViewModel.kt index a706b70403..dbcf9aa948 100644 --- a/feature/consent/src/main/java/com/simprints/feature/consent/screens/privacy/PrivacyNoticeViewModel.kt +++ b/feature/consent/src/main/java/com/simprints/feature/consent/screens/privacy/PrivacyNoticeViewModel.kt @@ -8,12 +8,12 @@ import com.simprints.core.livedata.LiveDataEvent import com.simprints.core.livedata.send import com.simprints.core.tools.utils.TimeUtils import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.PrivacyNoticeResult import com.simprints.infra.config.store.models.PrivacyNoticeResult.Failed import com.simprints.infra.config.store.models.PrivacyNoticeResult.FailedBecauseBackendMaintenance import com.simprints.infra.config.store.models.PrivacyNoticeResult.InProgress import com.simprints.infra.config.store.models.PrivacyNoticeResult.Succeed +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.network.ConnectivityTracker import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.catch @@ -24,7 +24,7 @@ import javax.inject.Inject @HiltViewModel internal class PrivacyNoticeViewModel @Inject constructor( private val connectivityTracker: ConnectivityTracker, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val authStore: AuthStore, ) : ViewModel() { @@ -43,8 +43,8 @@ internal class PrivacyNoticeViewModel @Inject constructor( } fun retrievePrivacyNotice() = viewModelScope.launch { - val deviceConfiguration = configRepository.getDeviceConfiguration() - configRepository.getPrivacyNotice( + val deviceConfiguration = configManager.getDeviceConfiguration() + configManager.getPrivacyNotice( authStore.signedInProjectId, deviceConfiguration.language ) 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 0824aab62f..33f3a5ab14 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 @@ -9,9 +9,9 @@ import com.simprints.feature.consent.ConsentType import com.simprints.feature.consent.screens.consent.helpers.GeneralConsentTextHelper import com.simprints.feature.consent.screens.consent.helpers.ParentalConsentTextHelper import com.simprints.feature.exitform.ExitFormResult -import com.simprints.infra.config.store.ConfigRepository 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.SessionEventRepository import com.simprints.infra.events.event.domain.models.ConsentEvent import com.simprints.testtools.common.coroutines.TestCoroutineRule @@ -50,7 +50,7 @@ class ConsentViewModelTest { private lateinit var parentalConsentTextHelper: ParentalConsentTextHelper @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var projectConfig: ProjectConfiguration @@ -66,7 +66,7 @@ class ConsentViewModelTest { @Before fun setUp() { MockKAnnotations.init(this, relaxed = true) - coEvery { configRepository.getProjectConfiguration() } returns projectConfig + coEvery { configManager.getProjectConfiguration() } returns projectConfig every { projectConfig.consent } returns mockk() every { timeHelper.now() } returns TIMESTAMP @@ -75,7 +75,7 @@ class ConsentViewModelTest { vm = ConsentViewModel( timeHelper, - configRepository, + configManager, eventRepository, generalConsentTextHelper, parentalConsentTextHelper, @@ -92,7 +92,7 @@ class ConsentViewModelTest { vm.loadConfiguration(ConsentType.ENROL) val state = vm.viewState.getOrAwaitValue() - coVerify { configRepository.getProjectConfiguration() } + coVerify { configManager.getProjectConfiguration() } verify { generalConsentTextHelper.assembleText(any(), eq(defaultModalityList), eq(ConsentType.ENROL)) } verify { parentalConsentTextHelper.assembleText(any(), eq(defaultModalityList), eq(ConsentType.ENROL)) } diff --git a/feature/consent/src/test/java/com/simprints/feature/consent/screens/privacy/PrivacyNoticeViewModelTest.kt b/feature/consent/src/test/java/com/simprints/feature/consent/screens/privacy/PrivacyNoticeViewModelTest.kt index a2be2fc132..e77f578a56 100644 --- a/feature/consent/src/test/java/com/simprints/feature/consent/screens/privacy/PrivacyNoticeViewModelTest.kt +++ b/feature/consent/src/test/java/com/simprints/feature/consent/screens/privacy/PrivacyNoticeViewModelTest.kt @@ -3,9 +3,9 @@ package com.simprints.feature.consent.screens.privacy import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.google.common.truth.Truth import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.DeviceConfiguration import com.simprints.infra.config.store.models.PrivacyNoticeResult +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.network.ConnectivityTracker import com.simprints.testtools.common.coroutines.TestCoroutineRule import com.simprints.testtools.common.livedata.getOrAwaitValue @@ -36,7 +36,7 @@ internal class PrivacyNoticeViewModelTest { lateinit var connectivityTracker: ConnectivityTracker @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager @MockK lateinit var authStore: AuthStore @@ -48,19 +48,19 @@ internal class PrivacyNoticeViewModelTest { fun setUp() { MockKAnnotations.init(this, relaxed = true) - coEvery { configRepository.getDeviceConfiguration() } returns DeviceConfiguration(LANGUAGE, listOf(), "") + coEvery { configManager.getDeviceConfiguration() } returns DeviceConfiguration(LANGUAGE, listOf(), "") every { authStore.signedInProjectId } returns PROJECT_ID privacyNoticeViewModel = PrivacyNoticeViewModel( connectivityTracker, - configRepository, + configManager, authStore, ) } @Test fun `retrievePrivacyNotice should return DownloadInProgress when trying download`() = runTest { - coEvery { configRepository.getPrivacyNotice(PROJECT_ID, LANGUAGE) } returns flowOf( + coEvery { configManager.getPrivacyNotice(PROJECT_ID, LANGUAGE) } returns flowOf( PrivacyNoticeResult.InProgress(LANGUAGE), ) @@ -73,7 +73,7 @@ internal class PrivacyNoticeViewModelTest { @Test fun `retrievePrivacyNotice should return ContentAvailable when success received`() = runTest { - coEvery { configRepository.getPrivacyNotice(PROJECT_ID, LANGUAGE) } returns flowOf( + coEvery { configManager.getPrivacyNotice(PROJECT_ID, LANGUAGE) } returns flowOf( PrivacyNoticeResult.InProgress(LANGUAGE), PrivacyNoticeResult.Succeed(LANGUAGE, "some long consent") ) @@ -87,7 +87,7 @@ internal class PrivacyNoticeViewModelTest { @Test fun `retrievePrivacyNotice should return ConsentNotAvailable when Failed received`() = runTest { - coEvery { configRepository.getPrivacyNotice(PROJECT_ID, LANGUAGE) } returns flowOf( + coEvery { configManager.getPrivacyNotice(PROJECT_ID, LANGUAGE) } returns flowOf( PrivacyNoticeResult.InProgress(LANGUAGE), PrivacyNoticeResult.Failed(LANGUAGE, Throwable()) ) @@ -101,7 +101,7 @@ internal class PrivacyNoticeViewModelTest { @Test fun `retrievePrivacyNotice should return BackendMaintenance when FailedBecauseBackendMaintenance received`() = runTest { - coEvery { configRepository.getPrivacyNotice(PROJECT_ID, LANGUAGE) } returns flowOf( + coEvery { configManager.getPrivacyNotice(PROJECT_ID, LANGUAGE) } returns flowOf( PrivacyNoticeResult.InProgress(LANGUAGE), PrivacyNoticeResult.FailedBecauseBackendMaintenance(LANGUAGE, Throwable()) ) @@ -115,7 +115,7 @@ internal class PrivacyNoticeViewModelTest { @Test fun `retrievePrivacyNotice should return BackendMaintenance with estimation when FailedBecauseBackendMaintenance received`() = runTest { - coEvery { configRepository.getPrivacyNotice(PROJECT_ID, LANGUAGE) } returns flowOf( + coEvery { configManager.getPrivacyNotice(PROJECT_ID, LANGUAGE) } returns flowOf( PrivacyNoticeResult.InProgress(LANGUAGE), PrivacyNoticeResult.FailedBecauseBackendMaintenance(LANGUAGE, Throwable(), 1000L) ) @@ -131,7 +131,7 @@ internal class PrivacyNoticeViewModelTest { @Test fun `downloadPressed should retrieve notice when online`() = runTest { every { connectivityTracker.isConnected() } returns true - coEvery { configRepository.getPrivacyNotice(PROJECT_ID, LANGUAGE) } returns flowOf(PrivacyNoticeResult.InProgress(LANGUAGE)) + coEvery { configManager.getPrivacyNotice(PROJECT_ID, LANGUAGE) } returns flowOf(PrivacyNoticeResult.InProgress(LANGUAGE)) val privacyNoticeLiveData = privacyNoticeViewModel.viewState() val showOfflineLiveData = privacyNoticeViewModel.showOffline() diff --git a/feature/dashboard/build.gradle.kts b/feature/dashboard/build.gradle.kts index c4399d9326..fccff5a847 100644 --- a/feature/dashboard/build.gradle.kts +++ b/feature/dashboard/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { implementation(project(":infra:events")) implementation(project(":infra:event-sync")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:sync")) implementation(project(":infra:enrolment-records-store")) implementation(project(":infra:images")) diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/debug/DebugFragment.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/debug/DebugFragment.kt index 26d2e7ad58..def2f211e5 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/debug/DebugFragment.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/debug/DebugFragment.kt @@ -14,7 +14,7 @@ import com.simprints.core.DispatcherIO import com.simprints.feature.dashboard.R import com.simprints.feature.dashboard.databinding.FragmentDebugBinding import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.events.EventRepository import com.simprints.infra.eventsync.EventSyncManager @@ -35,7 +35,7 @@ internal class DebugFragment : Fragment(R.layout.fragment_debug) { lateinit var eventSyncManager: EventSyncManager @Inject - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager @Inject lateinit var syncOrchestrator: SyncOrchestrator @@ -99,9 +99,7 @@ internal class DebugFragment : Fragment(R.layout.fragment_debug) { binding.logs.append("\nGetting Configs from BFSID") lifecycleScope.launch { try { - configRepository.refreshProject(authStore.signedInProjectId).also { (project, _) -> - enrolmentRecordRepository.tokenizeExistingRecords(project) - } + configManager.refreshProject(authStore.signedInProjectId) binding.logs.append("\nGot Configs from BFSID") } catch (e: Exception) { binding.logs.append("\nFailed to refresh the project configuration") diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/logout/LogoutSyncViewModel.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/logout/LogoutSyncViewModel.kt index b654cb957a..8888b549e9 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/logout/LogoutSyncViewModel.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/logout/LogoutSyncViewModel.kt @@ -6,20 +6,20 @@ import androidx.lifecycle.liveData import androidx.lifecycle.viewModelScope import com.simprints.core.livedata.LiveDataEventWithContent import com.simprints.feature.dashboard.logout.usecase.LogoutUseCase -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.SettingsPasswordConfig +import com.simprints.infra.config.sync.ConfigManager import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @HiltViewModel internal class LogoutSyncViewModel @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val logoutUseCase: LogoutUseCase, ) : ViewModel() { val settingsLocked: LiveData> get() = liveData(context = viewModelScope.coroutineContext) { - emit(LiveDataEventWithContent(configRepository.getProjectConfiguration().general.settingsPassword)) + emit(LiveDataEventWithContent(configManager.getProjectConfiguration().general.settingsPassword)) } diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/main/MainViewModel.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/main/MainViewModel.kt index 64ffbdbfc2..56a77a6b43 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/main/MainViewModel.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/main/MainViewModel.kt @@ -6,7 +6,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.simprints.core.livedata.LiveDataEvent import com.simprints.core.livedata.send -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.logging.Simber import com.simprints.infra.security.SecurityManager import com.simprints.infra.security.exceptions.RootedDeviceException @@ -16,7 +16,7 @@ import javax.inject.Inject @HiltViewModel internal class MainViewModel @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val securityManager: SecurityManager ) : ViewModel() { @@ -33,7 +33,7 @@ internal class MainViewModel @Inject constructor( } private fun load() = viewModelScope.launch { - _consentRequired.postValue(configRepository.getProjectConfiguration().consent.collectConsent) + _consentRequired.postValue(configManager.getProjectConfiguration().consent.collectConsent) checkIfDeviceIsSafe() } diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/main/projectdetails/ProjectDetailsViewModel.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/main/projectdetails/ProjectDetailsViewModel.kt index c5c100c983..ce891190f8 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/main/projectdetails/ProjectDetailsViewModel.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/main/projectdetails/ProjectDetailsViewModel.kt @@ -6,9 +6,9 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.TokenKeyType import com.simprints.infra.config.store.tokenization.TokenizationProcessor +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.recent.user.activity.RecentUserActivityManager import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch @@ -16,7 +16,7 @@ import javax.inject.Inject @HiltViewModel internal class ProjectDetailsViewModel @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val authStore: AuthStore, private val recentUserActivityManager: RecentUserActivityManager, private val tokenizationProcessor: TokenizationProcessor @@ -33,7 +33,7 @@ internal class ProjectDetailsViewModel @Inject constructor( fun load() = viewModelScope.launch { val state = try { val projectId = authStore.signedInProjectId - val cachedProject = configRepository.getProject(projectId) + val cachedProject = configManager.getProject(projectId) val recentUserActivity = recentUserActivityManager.getRecentUserActivity() val decryptedUserId = when(val userId = recentUserActivity.lastUserUsed) { is TokenizableString.Raw -> userId diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/main/sync/SyncViewModel.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/main/sync/SyncViewModel.kt index 0e37cfe292..9573cd7716 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/main/sync/SyncViewModel.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/main/sync/SyncViewModel.kt @@ -27,12 +27,12 @@ import com.simprints.feature.dashboard.views.SyncCardState.SyncTryAgain import com.simprints.feature.login.LoginContract import com.simprints.feature.login.LoginResult import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.DownSynchronizationConfiguration import com.simprints.infra.config.store.models.ProjectState import com.simprints.infra.config.store.models.SynchronizationConfiguration import com.simprints.infra.config.store.models.canSyncDataToSimprints import com.simprints.infra.config.store.models.isEventDownSyncAllowed +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.event.domain.models.EventType import com.simprints.infra.eventsync.EventSyncManager import com.simprints.infra.eventsync.status.models.EventSyncState @@ -52,7 +52,7 @@ internal class SyncViewModel @Inject constructor( private val eventSyncManager: EventSyncManager, private val syncOrchestrator: SyncOrchestrator, private val connectivityTracker: ConnectivityTracker, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val timeHelper: TimeHelper, private val authStore: AuthStore, private val logout: LogoutUseCase, @@ -101,7 +101,7 @@ internal class SyncViewModel @Inject constructor( viewModelScope.launch { val isSyncComplete = cardState is SyncComplete val isProjectEnding = - configRepository.getProject(authStore.signedInProjectId).state == ProjectState.PROJECT_ENDING + configManager.getProject(authStore.signedInProjectId).state == ProjectState.PROJECT_ENDING if (isSyncComplete && isProjectEnding) { viewModelScope.launch { @@ -182,7 +182,7 @@ internal class SyncViewModel @Inject constructor( ) } } - configRepository.getProjectConfiguration().also { configuration -> + configManager.getProjectConfiguration().also { configuration -> _syncToBFSIDAllowed.postValue(configuration.canSyncDataToSimprints() || configuration.isEventDownSyncAllowed()) } eventSyncManager @@ -264,13 +264,13 @@ internal class SyncViewModel @Inject constructor( isDownSyncAllowed() && isSelectedModulesEmpty() && isModuleSync() private suspend fun isDownSyncAllowed() = - configRepository.getProjectConfiguration().synchronization.frequency != SynchronizationConfiguration.Frequency.ONLY_PERIODICALLY_UP_SYNC + configManager.getProjectConfiguration().synchronization.frequency != SynchronizationConfiguration.Frequency.ONLY_PERIODICALLY_UP_SYNC private suspend fun isSelectedModulesEmpty() = - configRepository.getDeviceConfiguration().selectedModules.isEmpty() + configManager.getDeviceConfiguration().selectedModules.isEmpty() private suspend fun isModuleSync() = - configRepository.getProjectConfiguration().synchronization.down.partitionType == DownSynchronizationConfiguration.PartitionType.MODULE + configManager.getProjectConfiguration().synchronization.down.partitionType == DownSynchronizationConfiguration.PartitionType.MODULE private fun isConnected() = connectivityTracker.observeIsConnected().value ?: true diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/SettingsViewModel.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/SettingsViewModel.kt index 768aa30636..4f4774977f 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/SettingsViewModel.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/SettingsViewModel.kt @@ -4,9 +4,9 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.store.models.SettingsPasswordConfig +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.logging.LoggingConstants import com.simprints.infra.logging.Simber import dagger.hilt.android.lifecycle.HiltViewModel @@ -15,7 +15,7 @@ import javax.inject.Inject @HiltViewModel internal class SettingsViewModel @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, ) : ViewModel() { val generalConfiguration: LiveData @@ -36,16 +36,16 @@ internal class SettingsViewModel @Inject constructor( fun updateLanguagePreference(language: String) { viewModelScope.launch { - configRepository.updateDeviceConfiguration { it.apply { it.language = language } } + configManager.updateDeviceConfiguration { it.apply { it.language = language } } _languagePreference.postValue(language) Simber.tag(LoggingConstants.CrashReportTag.SETTINGS.name).i("Language set to $language") } } private fun load() = viewModelScope.launch { - val configuration = configRepository.getProjectConfiguration().general + val configuration = configManager.getProjectConfiguration().general - _languagePreference.postValue(configRepository.getDeviceConfiguration().language) + _languagePreference.postValue(configManager.getDeviceConfiguration().language) _generalConfiguration.postValue(configuration) _settingsLocked.postValue(configuration.settingsPassword) } 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 c870e03e99..8d03b9f05d 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 @@ -7,10 +7,10 @@ import androidx.lifecycle.viewModelScope import com.simprints.core.livedata.LiveDataEventWithContent import com.simprints.core.livedata.send import com.simprints.feature.dashboard.logout.usecase.LogoutUseCase -import com.simprints.infra.config.store.ConfigRepository 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 import com.simprints.infra.eventsync.EventSyncManager import com.simprints.infra.recent.user.activity.RecentUserActivityManager import com.simprints.infra.recent.user.activity.domain.RecentUserActivity @@ -21,8 +21,8 @@ import javax.inject.Inject @HiltViewModel internal class AboutViewModel @Inject constructor( - private val configRepository: ConfigRepository, - private val logout: LogoutUseCase, + private val configManager: ConfigManager, + private val logoutUseCase: LogoutUseCase, private val eventSyncManager: EventSyncManager, private val recentUserActivityManager: RecentUserActivityManager, ) : ViewModel() { @@ -58,7 +58,7 @@ internal class AboutViewModel @Inject constructor( when (canSyncDataToSimprints() && hasEventsToUpload()) { true -> LogoutDestination.LogoutDataSyncScreen false -> { - logout() + logoutUseCase() LogoutDestination.LoginScreen } } @@ -70,11 +70,11 @@ internal class AboutViewModel @Inject constructor( eventSyncManager.countEventsToUpload(type = null).first() > 0 private suspend fun canSyncDataToSimprints(): Boolean = - configRepository.getProjectConfiguration().canSyncDataToSimprints() + configManager.getProjectConfiguration().canSyncDataToSimprints() private fun load() = viewModelScope.launch { - val configuration = configRepository.getProjectConfiguration() + val configuration = configManager.getProjectConfiguration() val syncAndSearchConfig = SyncAndSearchConfig( configuration.synchronization.down.partitionType.name, configuration.identification.poolType.name, 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 e1cf2238af..0a1753b9f6 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,15 +4,15 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.Finger +import com.simprints.infra.config.sync.ConfigManager import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel internal class FingerSelectionViewModel @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, ) : ViewModel() { val fingerSelections: LiveData> @@ -22,7 +22,7 @@ internal class FingerSelectionViewModel @Inject constructor( fun start() { viewModelScope.launch { _fingerSelections.postValue( - configRepository.getProjectConfiguration().fingerprint!!.bioSdkConfiguration.fingersToCapture + configManager.getProjectConfiguration().fingerprint!!.bioSdkConfiguration.fingersToCapture .toFingerSelectionItems() ) } diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/syncinfo/SyncInfoViewModel.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/syncinfo/SyncInfoViewModel.kt index d7d1c20be1..724b3b8619 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/syncinfo/SyncInfoViewModel.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/syncinfo/SyncInfoViewModel.kt @@ -13,13 +13,13 @@ import com.simprints.feature.dashboard.settings.syncinfo.modulecount.ModuleCount import com.simprints.feature.login.LoginContract import com.simprints.feature.login.LoginResult import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.DownSynchronizationConfiguration import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.SynchronizationConfiguration import com.simprints.infra.config.store.models.TokenKeyType import com.simprints.infra.config.store.models.isEventDownSyncAllowed import com.simprints.infra.config.store.tokenization.TokenizationProcessor +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.store.domain.models.SubjectQuery import com.simprints.infra.events.event.domain.models.EventType @@ -41,7 +41,7 @@ import javax.inject.Inject @HiltViewModel internal class SyncInfoViewModel @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, connectivityTracker: ConnectivityTracker, private val enrolmentRecordRepository: EnrolmentRecordRepository, private val authStore: AuthStore, @@ -180,7 +180,7 @@ internal class SyncInfoViewModel @Inject constructor( val projectId = authStore.signedInProjectId awaitAll( - async { _configuration.postValue(configRepository.getProjectConfiguration()) }, + async { _configuration.postValue(configManager.getProjectConfiguration()) }, async { _recordsInLocal.postValue(getRecordsInLocal(projectId)) }, async { _recordsToUpSync.postValue(getRecordsToUpSync()) }, async { _recordsToDownSync.postValue(fetchRecordsToCreateAndDeleteCount()) }, @@ -216,7 +216,7 @@ internal class SyncInfoViewModel @Inject constructor( ?: 0 private suspend fun fetchRecordsToCreateAndDeleteCount(): DownSyncCounts = - if (configRepository.getProjectConfiguration().isEventDownSyncAllowed()) { + if (configManager.getProjectConfiguration().isEventDownSyncAllowed()) { fetchAndUpdateRecordsToDownSyncAndDeleteCount() } else { DownSyncCounts(0, isLowerBound = false) @@ -231,7 +231,7 @@ internal class SyncInfoViewModel @Inject constructor( } private suspend fun getModuleCounts(projectId: String): List = - configRepository.getDeviceConfiguration().selectedModules.map { moduleName -> + configManager.getDeviceConfiguration().selectedModules.map { moduleName -> val count = enrolmentRecordRepository.count( SubjectQuery(projectId = projectId, moduleId = moduleName.value) ) @@ -240,7 +240,7 @@ internal class SyncInfoViewModel @Inject constructor( is TokenizableString.Tokenized -> tokenizationProcessor.decrypt( encrypted = moduleName, tokenKeyType = TokenKeyType.ModuleId, - project = configRepository.getProject(projectId) + project = configManager.getProject(projectId) ) } return@map ModuleCount(name = decryptedName.value, count = count) diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/ModuleSelectionViewModel.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/ModuleSelectionViewModel.kt index 229ebaba67..f43f2ec84c 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/ModuleSelectionViewModel.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/ModuleSelectionViewModel.kt @@ -11,10 +11,10 @@ import com.simprints.feature.dashboard.settings.syncinfo.moduleselection.excepti import com.simprints.feature.dashboard.settings.syncinfo.moduleselection.repository.Module import com.simprints.feature.dashboard.settings.syncinfo.moduleselection.repository.ModuleRepository import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.SettingsPasswordConfig import com.simprints.infra.config.store.models.TokenKeyType import com.simprints.infra.config.store.tokenization.TokenizationProcessor +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.sync.SyncOrchestrator import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.CoroutineScope @@ -26,7 +26,7 @@ internal class ModuleSelectionViewModel @Inject constructor( private val authStore: AuthStore, private val moduleRepository: ModuleRepository, private val syncOrchestrator: SyncOrchestrator, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val tokenizationProcessor: TokenizationProcessor, @ExternalScope private val externalScope: CoroutineScope, ) : ViewModel() { @@ -55,7 +55,7 @@ internal class ModuleSelectionViewModel @Inject constructor( is TokenizableString.Tokenized -> tokenizationProcessor.decrypt( encrypted = name, tokenKeyType = TokenKeyType.ModuleId, - project = configRepository.getProject(authStore.signedInProjectId) + project = configManager.getProject(authStore.signedInProjectId) ) } module.copy(name = decryptedName) @@ -66,7 +66,7 @@ internal class ModuleSelectionViewModel @Inject constructor( fun loadPasswordSettings() { viewModelScope.launch { - configRepository.getProjectConfiguration() + configManager.getProjectConfiguration() .general .settingsPassword .let { _screenLocked.postValue(it) } @@ -100,7 +100,7 @@ internal class ModuleSelectionViewModel @Inject constructor( is TokenizableString.Raw -> tokenizationProcessor.encrypt( decrypted = name, tokenKeyType = TokenKeyType.ModuleId, - project = configRepository.getProject(authStore.signedInProjectId) + project = configManager.getProject(authStore.signedInProjectId) ) is TokenizableString.Tokenized -> name diff --git a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/repository/ModuleRepositoryImpl.kt b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/repository/ModuleRepositoryImpl.kt index 4cbcfbe48a..227e4d4a40 100644 --- a/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/repository/ModuleRepositoryImpl.kt +++ b/feature/dashboard/src/main/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/repository/ModuleRepositoryImpl.kt @@ -1,7 +1,7 @@ package com.simprints.feature.dashboard.settings.syncinfo.moduleselection.repository import com.simprints.core.domain.tokenization.values -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.store.domain.models.SubjectQuery import com.simprints.infra.eventsync.EventSyncManager @@ -12,13 +12,13 @@ import javax.inject.Inject // TODO move into the event system infra module? internal class ModuleRepositoryImpl @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val enrolmentRecordRepository: EnrolmentRecordRepository, private val eventSyncManager: EventSyncManager, ) : ModuleRepository { override suspend fun getModules(): List = - configRepository.getProjectConfiguration().synchronization.down.moduleOptions.map { + configManager.getProjectConfiguration().synchronization.down.moduleOptions.map { Module(it, isModuleSelected(it.value)) } @@ -28,15 +28,15 @@ internal class ModuleRepositoryImpl @Inject constructor( } override suspend fun getMaxNumberOfModules(): Int = - configRepository.getProjectConfiguration().synchronization.down.maxNbOfModules + configManager.getProjectConfiguration().synchronization.down.maxNbOfModules private suspend fun isModuleSelected(moduleName: String): Boolean { - return configRepository.getDeviceConfiguration().selectedModules.values() + return configManager.getDeviceConfiguration().selectedModules.values() .contains(moduleName) } private suspend fun setSelectedModules(selectedModules: List) { - configRepository.updateDeviceConfiguration { + configManager.updateDeviceConfiguration { it.apply { this.selectedModules = selectedModules.map { module -> module.name } logMessageForCrashReport("Modules set to ${this.selectedModules.values()}") diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/logout/LogoutSyncViewModelTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/logout/LogoutSyncViewModelTest.kt index 9b001af196..d48e9191a0 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/logout/LogoutSyncViewModelTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/logout/LogoutSyncViewModelTest.kt @@ -3,8 +3,8 @@ package com.simprints.feature.dashboard.logout import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.google.common.truth.Truth.assertThat import com.simprints.feature.dashboard.logout.usecase.LogoutUseCase -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.SettingsPasswordConfig +import com.simprints.infra.config.sync.ConfigManager import com.simprints.testtools.common.coroutines.TestCoroutineRule import com.simprints.testtools.common.livedata.getOrAwaitValue import io.mockk.MockKAnnotations @@ -24,7 +24,7 @@ internal class LogoutSyncViewModelTest { lateinit var logoutUseCase: LogoutUseCase @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager @get:Rule val rule = InstantTaskExecutorRule() @@ -40,7 +40,7 @@ internal class LogoutSyncViewModelTest { @Test fun `should logout correctly`() { val viewModel = LogoutSyncViewModel( - configRepository = configRepository, + configManager = configManager, logoutUseCase = logoutUseCase, ) @@ -52,13 +52,13 @@ internal class LogoutSyncViewModelTest { @Test fun `password config should be fetched after initialization`() { val config = SettingsPasswordConfig.Locked(password = "123") - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { general } returns mockk { every { settingsPassword } returns config } } val viewModel = LogoutSyncViewModel( - configRepository = configRepository, + configManager = configManager, logoutUseCase = logoutUseCase, ) val resultConfig = viewModel.settingsLocked.getOrAwaitValue() diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/main/MainViewModelTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/main/MainViewModelTest.kt index 940a5dd8f2..1103325d87 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/main/MainViewModelTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/main/MainViewModelTest.kt @@ -2,7 +2,7 @@ package com.simprints.feature.dashboard.main import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.google.common.truth.Truth.assertThat -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.security.SecurityManager import com.simprints.infra.security.exceptions.RootedDeviceException import com.simprints.testtools.common.coroutines.TestCoroutineRule @@ -20,7 +20,7 @@ class MainViewModelTest { @get:Rule val testCoroutineRule = TestCoroutineRule() - private val configRepository = mockk { + private val configManager = mockk { coEvery { getProjectConfiguration() } returns mockk { every { consent } returns mockk { every { collectConsent } returns true @@ -32,14 +32,14 @@ class MainViewModelTest { @Test fun `should initialize the live data correctly`() { - val viewModel = MainViewModel(configRepository, securityManager) + val viewModel = MainViewModel(configManager, securityManager) assertThat(viewModel.consentRequired.value).isEqualTo(true) } @Test fun `should show rooted device detected if device is rooted`() { coEvery { securityManager.checkIfDeviceIsRooted() } throws RootedDeviceException() - val viewModel = MainViewModel(configRepository, securityManager) + val viewModel = MainViewModel(configManager, securityManager) assertThat(viewModel.rootedDeviceDetected.value).isNotNull() } diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/main/projectdetails/ProjectDetailsViewModelTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/main/projectdetails/ProjectDetailsViewModelTest.kt index 39ece27369..19a4c30858 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/main/projectdetails/ProjectDetailsViewModelTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/main/projectdetails/ProjectDetailsViewModelTest.kt @@ -5,11 +5,11 @@ import com.google.common.truth.Truth.assertThat import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.store.models.ProjectState import com.simprints.infra.config.store.models.TokenKeyType import com.simprints.infra.config.store.tokenization.TokenizationProcessor +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.recent.user.activity.RecentUserActivityManager import com.simprints.infra.recent.user.activity.domain.RecentUserActivity import com.simprints.testtools.common.coroutines.TestCoroutineRule @@ -35,7 +35,7 @@ class ProjectDetailsViewModelTest { private lateinit var authStore: AuthStore @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var tokenizationProcessor: TokenizationProcessor @@ -55,7 +55,7 @@ class ProjectDetailsViewModelTest { @Test fun `should initialize the live data correctly`() = runTest { - coEvery { configRepository.getProject(PROJECT_ID) } returns PROJECT + coEvery { configManager.getProject(PROJECT_ID) } returns PROJECT every { tokenizationProcessor.decrypt( RECENT_USER_ACTIVITY.lastUserUsed as TokenizableString.Tokenized, @@ -65,7 +65,7 @@ class ProjectDetailsViewModelTest { } returns RECENT_USER_ACTIVITY.lastUserUsed viewModel = ProjectDetailsViewModel( - configRepository = configRepository, + configManager = configManager, authStore = authStore, recentUserActivityManager = recentUserActivityManager, tokenizationProcessor = tokenizationProcessor @@ -77,10 +77,10 @@ class ProjectDetailsViewModelTest { @Test fun `Should handle exception by producing correct state`() = runTest { - coEvery { configRepository.getProject(PROJECT_ID) } throws Exception() + coEvery { configManager.getProject(PROJECT_ID) } throws Exception() viewModel = ProjectDetailsViewModel( - configRepository = configRepository, + configManager = configManager, authStore = authStore, recentUserActivityManager = recentUserActivityManager, tokenizationProcessor = tokenizationProcessor diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/main/sync/SyncViewModelTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/main/sync/SyncViewModelTest.kt index 12da030ad2..d5f037889e 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/main/sync/SyncViewModelTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/main/sync/SyncViewModelTest.kt @@ -20,7 +20,6 @@ import com.simprints.feature.dashboard.views.SyncCardState.SyncTooManyRequests import com.simprints.feature.dashboard.views.SyncCardState.SyncTryAgain import com.simprints.feature.login.LoginResult import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.DeviceConfiguration import com.simprints.infra.config.store.models.DownSynchronizationConfiguration import com.simprints.infra.config.store.models.ProjectState @@ -28,6 +27,7 @@ import com.simprints.infra.config.store.models.SynchronizationConfiguration import com.simprints.infra.config.store.models.UpSynchronizationConfiguration import com.simprints.infra.config.store.models.UpSynchronizationConfiguration.SimprintsUpSynchronizationConfiguration import com.simprints.infra.config.store.models.UpSynchronizationConfiguration.UpSynchronizationKind.ALL +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.eventsync.EventSyncManager import com.simprints.infra.eventsync.status.models.EventSyncState import com.simprints.infra.eventsync.status.models.EventSyncWorkerState @@ -80,7 +80,7 @@ internal class SyncViewModelTest { lateinit var connectivityTracker: ConnectivityTracker @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager @MockK lateinit var timeHelper: TimeHelper @@ -100,7 +100,7 @@ internal class SyncViewModelTest { every { eventSyncManager.getLastSyncState() } returns syncState every { connectivityTracker.observeIsConnected() } returns isConnected - coEvery { configRepository.getProjectConfiguration().synchronization } returns mockk { + coEvery { configManager.getProjectConfiguration().synchronization } returns mockk { every { up.simprints } returns SimprintsUpSynchronizationConfiguration( kind = ALL, batchSizes = UpSynchronizationConfiguration.UpSyncBatchSizes.default(), @@ -166,7 +166,7 @@ internal class SyncViewModelTest { @Test fun `should post a SyncHasNoModules card state if the module selection is empty`() { - coEvery { configRepository.getDeviceConfiguration() } returns DeviceConfiguration( + coEvery { configManager.getDeviceConfiguration() } returns DeviceConfiguration( "", listOf(), "" @@ -179,7 +179,7 @@ internal class SyncViewModelTest { @Test fun `should post a SyncOffline card state if the device is not connected`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration isConnected.value = false val syncCardLiveData = initViewModel().syncCardLiveData.getOrAwaitValue() @@ -188,7 +188,7 @@ internal class SyncViewModelTest { @Test fun `should post a SyncConnecting card state if the sync is running but not info are available`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration isConnected.value = true syncState.value = null val syncCardLiveData = initViewModel().syncCardLiveData.getOrAwaitValue() @@ -198,7 +198,7 @@ internal class SyncViewModelTest { @Test fun `should post a SyncDefault card state if there is no sync history`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration isConnected.value = true syncState.value = EventSyncState("", 0, 0, listOf(), listOf()) val syncCardLiveData = initViewModel().syncCardLiveData.getOrAwaitValue() @@ -208,7 +208,7 @@ internal class SyncViewModelTest { @Test fun `should post a SyncComplete card state if the sync is completed`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration isConnected.value = true syncState.value = EventSyncState( "", 0, 0, listOf(), @@ -226,7 +226,7 @@ internal class SyncViewModelTest { @Test fun `should post a SyncPendingUpload card state if there are records to upload`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration coEvery { eventSyncManager.countEventsToUpload(any()) }.returns(flowOf(2)) isConnected.value = true @@ -245,7 +245,7 @@ internal class SyncViewModelTest { @Test fun `should post a SyncProgress card state if the sync is in progress`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration isConnected.value = true syncState.value = EventSyncState( "", 10, 40, listOf(), @@ -263,7 +263,7 @@ internal class SyncViewModelTest { @Test fun `should post a SyncConnecting card state if the sync is enqueued`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration isConnected.value = true syncState.value = EventSyncState( "", 10, 40, listOf(), @@ -281,7 +281,7 @@ internal class SyncViewModelTest { @Test fun `should post a SyncTooManyRequests card state if there are too many sync requests`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration isConnected.value = true syncState.value = EventSyncState( "", 10, 40, listOf(), listOf( @@ -298,7 +298,7 @@ internal class SyncViewModelTest { @Test fun `should post a SyncFailed card state if the sync fails because of cloud integration`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration isConnected.value = true syncState.value = EventSyncState( "", 10, 40, listOf(), listOf( @@ -315,7 +315,7 @@ internal class SyncViewModelTest { @Test fun `should post a ReloginRequired card state if the sync fails with such problem`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration isConnected.value = true syncState.value = EventSyncState( "", 10, 40, listOf(), listOf( @@ -360,7 +360,7 @@ internal class SyncViewModelTest { @Test fun `should post a SyncFailedBackendMaintenance card state if the sync fails because of cloud maintenance`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration isConnected.value = true syncState.value = EventSyncState( "", 10, 40, listOf(), @@ -378,7 +378,7 @@ internal class SyncViewModelTest { @Test fun `should post a SyncFailedBackendMaintenance with estimated outage card state if the sync fails because of cloud maintenance with outage`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration isConnected.value = true syncState.value = EventSyncState( "", 10, 40, listOf(), listOf( @@ -398,7 +398,7 @@ internal class SyncViewModelTest { @Test fun `should post a SyncTryAgain card state if the sync fails because of another thing`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration isConnected.value = true syncState.value = EventSyncState( "", 10, 40, listOf(), @@ -416,8 +416,8 @@ internal class SyncViewModelTest { @Test fun `should logout when project is ending and sync is complete`() { - coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration - coEvery { configRepository.getProject(any()).state } returns ProjectState.PROJECT_ENDING + coEvery { configManager.getDeviceConfiguration() } returns deviceConfiguration + coEvery { configManager.getProject(any()).state } returns ProjectState.PROJECT_ENDING isConnected.value = true syncState.value = EventSyncState( "", 0, 0, listOf(), @@ -440,7 +440,7 @@ internal class SyncViewModelTest { eventSyncManager = eventSyncManager, syncOrchestrator = syncOrchestrator, connectivityTracker = connectivityTracker, - configRepository = configRepository, + configManager = configManager, timeHelper = timeHelper, authStore = authStore, logout = logoutUseCase, 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 f404b65da8..089ec3ed72 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 @@ -2,10 +2,10 @@ package com.simprints.feature.dashboard.settings import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.google.common.truth.Truth.assertThat -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.DeviceConfiguration import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.store.models.SettingsPasswordConfig +import com.simprints.infra.config.sync.ConfigManager import com.simprints.testtools.common.coroutines.TestCoroutineRule import io.mockk.MockKAnnotations import io.mockk.coEvery @@ -34,7 +34,7 @@ class SettingsViewModelTest { ) @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager private lateinit var viewModel: SettingsViewModel @@ -42,10 +42,10 @@ class SettingsViewModelTest { fun setup() { MockKAnnotations.init(this, relaxed = true) - coEvery { configRepository.getProjectConfiguration().general } returns generalConfiguration - coEvery { configRepository.getDeviceConfiguration().language } returns LANGUAGE + coEvery { configManager.getProjectConfiguration().general } returns generalConfiguration + coEvery { configManager.getDeviceConfiguration().language } returns LANGUAGE - viewModel = SettingsViewModel(configRepository) + viewModel = SettingsViewModel(configManager) } @Test @@ -59,7 +59,7 @@ class SettingsViewModelTest { fun `updateLanguagePreference should update the language`() = runTest { val updatedLanguage = "en" val updateConfigFn = slot DeviceConfiguration>() - coEvery { configRepository.updateDeviceConfiguration(capture(updateConfigFn)) } returns Unit + coEvery { configManager.updateDeviceConfiguration(capture(updateConfigFn)) } returns Unit viewModel.updateLanguagePreference(updatedLanguage) 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 7367f5bb55..bd06ec4c3f 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 @@ -4,13 +4,13 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.google.common.truth.Truth.assertThat import com.simprints.core.domain.tokenization.asTokenizableEncrypted import com.simprints.feature.dashboard.logout.usecase.LogoutUseCase -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.DownSynchronizationConfiguration import com.simprints.infra.config.store.models.GeneralConfiguration import com.simprints.infra.config.store.models.IdentificationConfiguration import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.SettingsPasswordConfig import com.simprints.infra.config.store.models.UpSynchronizationConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.eventsync.EventSyncManager import com.simprints.infra.recent.user.activity.RecentUserActivityManager import com.simprints.infra.recent.user.activity.domain.RecentUserActivity @@ -50,7 +50,7 @@ class AboutViewModelTest { ) private val eventSyncManager = mockk() - private val configRepository = mockk { + private val configManager = mockk { coEvery { getProjectConfiguration() } returns buildProjectConfigurationMock() } @@ -62,10 +62,10 @@ class AboutViewModelTest { @Test fun `should initialize the live data correctly`() { val viewModel = AboutViewModel( - configRepository = configRepository, + configManager = configManager, eventSyncManager = eventSyncManager, recentUserActivityManager = recentUserActivityManager, - logout = logoutUseCase, + logoutUseCase = logoutUseCase, ) assertThat(viewModel.modalities.value).isEqualTo(MODALITIES) @@ -177,14 +177,14 @@ class AboutViewModelTest { coEvery { eventSyncManager.countEventsToUpload(any()) } returns flowOf( countEventsToUpload ) - coEvery { configRepository.getProjectConfiguration() } returns buildProjectConfigurationMock( + coEvery { configManager.getProjectConfiguration() } returns buildProjectConfigurationMock( upSyncKind ) return AboutViewModel( - configRepository = configRepository, + configManager = configManager, eventSyncManager = eventSyncManager, recentUserActivityManager = recentUserActivityManager, - logout = logoutUseCase, + logoutUseCase = logoutUseCase, ) } } 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 03a7151161..38a54de321 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 @@ -2,7 +2,6 @@ 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.ConfigRepository 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 @@ -14,6 +13,7 @@ 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.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 @@ -34,11 +34,11 @@ class FingerSelectionViewModelTest { private val fingerprintConfiguration = mockk { every { bioSdkConfiguration } returns bioSdkConfigurationMock } - private val configRepository = mockk(relaxed = true) { + private val configManager = mockk(relaxed = true) { coEvery { getProjectConfiguration().fingerprint } returns fingerprintConfiguration } private val viewModel = FingerSelectionViewModel( - configRepository, + configManager, ) @Test 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 b38f933069..94f5fab02e 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 @@ -8,13 +8,13 @@ import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.feature.dashboard.settings.syncinfo.modulecount.ModuleCount import com.simprints.feature.login.LoginResult import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.DownSynchronizationConfiguration import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.SynchronizationConfiguration import com.simprints.infra.config.store.models.TokenKeyType import com.simprints.infra.config.store.tokenization.TokenizationProcessor +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.store.domain.models.SubjectQuery import com.simprints.infra.events.event.domain.models.EventType @@ -57,7 +57,7 @@ class SyncInfoViewModelTest { val testCoroutineRule = TestCoroutineRule() @MockK - private lateinit var configRepo: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var enrolmentRecordRepository: EnrolmentRecordRepository @@ -102,9 +102,9 @@ class SyncInfoViewModelTest { stateLiveData = MutableLiveData() every { eventSyncManager.getLastSyncState() } returns stateLiveData - coEvery { configRepo.getProject(PROJECT_ID) } returns project + coEvery { configManager.getProject(PROJECT_ID) } returns project viewModel = SyncInfoViewModel( - configRepository = configRepo, + configManager = configManager, connectivityTracker = connectivityTracker, enrolmentRecordRepository = enrolmentRecordRepository, authStore = authStore, @@ -119,7 +119,7 @@ class SyncInfoViewModelTest { @Test fun `should initialize the configuration live data correctly`() = runTest { val configuration = mockk(relaxed = true) - coEvery { configRepo.getProjectConfiguration() } returns configuration + coEvery { configManager.getProjectConfiguration() } returns configuration viewModel.refreshInformation() @@ -164,7 +164,7 @@ class SyncInfoViewModelTest { val module2 = "module2".asTokenizableEncrypted() val numberForModule1 = 10 val numberForModule2 = 20 - coEvery { configRepo.getDeviceConfiguration() } returns mockk { + coEvery { configManager.getDeviceConfiguration() } returns mockk { every { selectedModules } returns listOf(module1, module2) } coEvery { @@ -207,7 +207,7 @@ class SyncInfoViewModelTest { fun `should initialize the recordsToDownSync live data to the count otherwise`() = runTest { val module1 = "module1".asTokenizableEncrypted() - coEvery { configRepo.getDeviceConfiguration() } returns mockk { + coEvery { configManager.getDeviceConfiguration() } returns mockk { every { selectedModules } returns listOf(module1) } coEvery { @@ -223,7 +223,7 @@ class SyncInfoViewModelTest { fun `should initialize the recordsToDownSync live data to the default count value if fetch fails`() = runTest { val module1 = "module1".asTokenizableEncrypted() - coEvery { configRepo.getDeviceConfiguration() } returns mockk { + coEvery { configManager.getDeviceConfiguration() } returns mockk { every { selectedModules } returns listOf(module1) } coEvery { @@ -355,7 +355,7 @@ class SyncInfoViewModelTest { @Test fun `emit correct sync availability when connection status changes`() = runTest { - coEvery { configRepo.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { synchronization } returns createMockDownSyncConfig( partitionType = DownSynchronizationConfiguration.PartitionType.MODULE, modules = listOf("module") @@ -373,7 +373,7 @@ class SyncInfoViewModelTest { @Test fun `emit correct sync availability when sync status changes`() = runTest { - coEvery { configRepo.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { synchronization } returns createMockDownSyncConfig( partitionType = DownSynchronizationConfiguration.PartitionType.MODULE, modules = listOf("module") @@ -416,7 +416,7 @@ class SyncInfoViewModelTest { @Test fun `emit correct sync availability when non-module config`() = runTest { - coEvery { configRepo.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { synchronization } returns createMockDownSyncConfig( partitionType = DownSynchronizationConfiguration.PartitionType.USER, ) @@ -430,7 +430,7 @@ class SyncInfoViewModelTest { @Test fun `emit correct sync availability when module config without modules`() = runTest { - coEvery { configRepo.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { synchronization } returns createMockDownSyncConfig( partitionType = DownSynchronizationConfiguration.PartitionType.MODULE, modules = emptyList() diff --git a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/ModuleSelectionViewModelTest.kt b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/ModuleSelectionViewModelTest.kt index e1b5742b5b..7485fd6b47 100644 --- a/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/ModuleSelectionViewModelTest.kt +++ b/feature/dashboard/src/test/java/com/simprints/feature/dashboard/settings/syncinfo/moduleselection/ModuleSelectionViewModelTest.kt @@ -11,18 +11,22 @@ import com.simprints.feature.dashboard.settings.syncinfo.moduleselection.excepti import com.simprints.feature.dashboard.settings.syncinfo.moduleselection.repository.Module import com.simprints.feature.dashboard.settings.syncinfo.moduleselection.repository.ModuleRepository import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.store.models.SettingsPasswordConfig import com.simprints.infra.config.store.models.TokenKeyType import com.simprints.infra.config.store.tokenization.TokenizationProcessor +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.eventsync.EventSyncManager import com.simprints.infra.sync.SyncOrchestrator import com.simprints.testtools.common.coroutines.TestCoroutineRule import com.simprints.testtools.common.livedata.getOrAwaitValue import com.simprints.testtools.common.syntax.assertThrows -import io.mockk.* +import io.mockk.MockKAnnotations +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every import io.mockk.impl.annotations.MockK +import io.mockk.mockk import kotlinx.coroutines.CoroutineScope import org.junit.Before import org.junit.Rule @@ -48,7 +52,7 @@ class ModuleSelectionViewModelTest { private lateinit var syncOrchestrator: SyncOrchestrator @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var tokenizationProcessor: TokenizationProcessor @@ -73,11 +77,11 @@ class ModuleSelectionViewModelTest { ) coEvery { repository.getModules() } returns modulesDefault coEvery { repository.getMaxNumberOfModules() } returns 2 - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { general.settingsPassword } returns SettingsPasswordConfig.Locked("1234") } every { authStore.signedInProjectId } returns PROJECT_ID - coEvery { configRepository.getProject(PROJECT_ID) } returns project + coEvery { configManager.getProject(PROJECT_ID) } returns project modulesDefault.forEach { coEvery { tokenizationProcessor.decrypt( @@ -92,7 +96,7 @@ class ModuleSelectionViewModelTest { authStore = authStore, moduleRepository = repository, syncOrchestrator = syncOrchestrator, - configRepository = configRepository, + configManager = configManager, tokenizationProcessor = tokenizationProcessor, externalScope = CoroutineScope(testCoroutineRule.testCoroutineDispatcher), ) 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 8bd40cb338..74c95f493a 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 @@ -3,11 +3,11 @@ package com.simprints.feature.dashboard.settings.syncinfo.moduleselection.reposi import com.google.common.truth.Truth.assertThat import com.simprints.core.domain.tokenization.TokenizableString import com.simprints.core.domain.tokenization.asTokenizableRaw -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.DeviceConfiguration import com.simprints.infra.config.store.models.DownSynchronizationConfiguration 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.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.eventsync.EventSyncManager import io.mockk.MockKAnnotations @@ -29,7 +29,7 @@ class ModuleRepositoryImplTest { lateinit var projectConfiguration: ProjectConfiguration @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager @MockK lateinit var enrolmentRecordRepository: EnrolmentRecordRepository @@ -46,16 +46,16 @@ class ModuleRepositoryImplTest { every { projectConfiguration.general.modalities } returns listOf(GeneralConfiguration.Modality.FINGERPRINT) every { projectConfiguration.synchronization.down } returns downSynchronizationConfiguration - coEvery { configRepository.getProjectConfiguration() } returns projectConfiguration + coEvery { configManager.getProjectConfiguration() } returns projectConfiguration every { downSynchronizationConfiguration.moduleOptions } returns listOf("a", "b", "c", "d").map(String::asTokenizableRaw) coEvery { - configRepository.getDeviceConfiguration() + configManager.getDeviceConfiguration() } returns DeviceConfiguration("", listOf("b", "c").map(TokenizableString::Tokenized), "") repository = ModuleRepositoryImpl( - configRepository, + configManager, enrolmentRecordRepository, eventSyncManager ) @@ -64,7 +64,7 @@ class ModuleRepositoryImplTest { @Test fun saveModules_shouldSaveSelectedModules() = runTest { val updateConfigFn = slot DeviceConfiguration>() - coEvery { configRepository.updateDeviceConfiguration(capture(updateConfigFn)) } returns Unit + coEvery { configManager.updateDeviceConfiguration(capture(updateConfigFn)) } returns Unit val modules = listOf( Module("1".asTokenizableRaw(), true), Module("2".asTokenizableRaw(), true), diff --git a/feature/enrol-last-biometric/build.gradle.kts b/feature/enrol-last-biometric/build.gradle.kts index 2f0944054f..8cf1870191 100644 --- a/feature/enrol-last-biometric/build.gradle.kts +++ b/feature/enrol-last-biometric/build.gradle.kts @@ -12,6 +12,7 @@ dependencies { implementation(project(":feature:alert")) implementation(project(":infra:event-sync")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:events")) implementation(project(":infra:enrolment-records-store")) diff --git a/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/EnrolLastBiometricViewModel.kt b/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/EnrolLastBiometricViewModel.kt index 55cc8a36c3..5ec1f7fac7 100644 --- a/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/EnrolLastBiometricViewModel.kt +++ b/feature/enrol-last-biometric/src/main/java/com/simprints/feature/enrollast/screen/EnrolLastBiometricViewModel.kt @@ -13,7 +13,7 @@ import com.simprints.feature.enrollast.screen.EnrolLastState.ErrorType.DUPLICATE 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.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.store.domain.models.Subject import com.simprints.infra.enrolment.records.store.domain.models.SubjectAction @@ -29,7 +29,7 @@ import javax.inject.Inject @HiltViewModel internal class EnrolLastBiometricViewModel @Inject constructor( private val timeHelper: TimeHelper, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val eventRepository: SessionEventRepository, private val enrolmentRecordRepository: EnrolmentRecordRepository, private val hasDuplicateEnrolments: HasDuplicateEnrolmentsUseCase, @@ -51,7 +51,7 @@ internal class EnrolLastBiometricViewModel @Inject constructor( fun enrolBiometric(params: EnrolLastBiometricParams) = viewModelScope.launch { enrolWasAttempted = true - val projectConfig = configRepository.getProjectConfiguration() + val projectConfig = configManager.getProjectConfiguration() val modalities = projectConfig.general.modalities val previousLastEnrolmentResult = getPreviousEnrolmentResult(params.steps) diff --git a/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/screen/EnrolLastBiometricViewModelTest.kt b/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/screen/EnrolLastBiometricViewModelTest.kt index 32e8f529a2..8f2be94986 100644 --- a/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/screen/EnrolLastBiometricViewModelTest.kt +++ b/feature/enrol-last-biometric/src/test/java/com/simprints/feature/enrollast/screen/EnrolLastBiometricViewModelTest.kt @@ -9,8 +9,8 @@ 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.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.ProjectConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.store.domain.models.Subject import com.simprints.infra.events.SessionEventRepository @@ -22,7 +22,6 @@ import io.mockk.coVerify import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.mockk -import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Rule @@ -40,7 +39,7 @@ internal class EnrolLastBiometricViewModelTest { lateinit var timeHelper: TimeHelper @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager @MockK lateinit var projectConfig: ProjectConfiguration @@ -67,7 +66,7 @@ internal class EnrolLastBiometricViewModelTest { fun setUp() { MockKAnnotations.init(this, relaxed = true) - coEvery { configRepository.getProjectConfiguration() } returns projectConfig + coEvery { configManager.getProjectConfiguration() } returns projectConfig every { projectConfig.general.modalities } returns emptyList() coEvery { eventRepository.getCurrentSessionScope() } returns mockk { @@ -79,7 +78,7 @@ internal class EnrolLastBiometricViewModelTest { viewModel = EnrolLastBiometricViewModel( timeHelper, - configRepository, + configManager, eventRepository, enrolmentRecordRepository, hasDuplicateEnrolments, @@ -96,7 +95,7 @@ internal class EnrolLastBiometricViewModelTest { EnrolLastBiometricStepResult.EnrolLastBiometricsResult("previousSubjectId") ))) - coVerify(exactly = 1) { configRepository.getProjectConfiguration() } + coVerify(exactly = 1) { configManager.getProjectConfiguration() } } @Test diff --git a/feature/fetch-subject/build.gradle.kts b/feature/fetch-subject/build.gradle.kts index 98ebdf4fd4..e7860c6c5d 100644 --- a/feature/fetch-subject/build.gradle.kts +++ b/feature/fetch-subject/build.gradle.kts @@ -16,5 +16,6 @@ dependencies { implementation(project(":infra:event-sync")) implementation(project(":infra:events")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) } diff --git a/feature/fetch-subject/src/main/java/com/simprints/feature/fetchsubject/screen/FetchSubjectViewModel.kt b/feature/fetch-subject/src/main/java/com/simprints/feature/fetchsubject/screen/FetchSubjectViewModel.kt index 51c0e76da9..ce071d6fce 100644 --- a/feature/fetch-subject/src/main/java/com/simprints/feature/fetchsubject/screen/FetchSubjectViewModel.kt +++ b/feature/fetch-subject/src/main/java/com/simprints/feature/fetchsubject/screen/FetchSubjectViewModel.kt @@ -9,7 +9,7 @@ import com.simprints.core.livedata.send import com.simprints.core.tools.time.TimeHelper import com.simprints.feature.fetchsubject.screen.usecase.FetchSubjectUseCase import com.simprints.feature.fetchsubject.screen.usecase.SaveSubjectFetchEventUseCase -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import javax.inject.Inject @@ -19,7 +19,7 @@ internal class FetchSubjectViewModel @Inject constructor( private val timeHelper: TimeHelper, private val fetchSubjectUseCase: FetchSubjectUseCase, private val saveSubjectFetchEventUseCase: SaveSubjectFetchEventUseCase, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, ) : ViewModel() { val subjectState: LiveData> @@ -47,7 +47,7 @@ internal class FetchSubjectViewModel @Inject constructor( fun startExitForm() { viewModelScope.launch { - val modalities = configRepository.getProjectConfiguration().general.modalities + val modalities = configManager.getProjectConfiguration().general.modalities _subjectState.send(FetchSubjectState.ShowExitForm(modalities)) } } diff --git a/feature/fetch-subject/src/test/java/com/simprints/feature/fetchsubject/screen/FetchSubjectViewModelTest.kt b/feature/fetch-subject/src/test/java/com/simprints/feature/fetchsubject/screen/FetchSubjectViewModelTest.kt index f87f7dd425..094ff8a387 100644 --- a/feature/fetch-subject/src/test/java/com/simprints/feature/fetchsubject/screen/FetchSubjectViewModelTest.kt +++ b/feature/fetch-subject/src/test/java/com/simprints/feature/fetchsubject/screen/FetchSubjectViewModelTest.kt @@ -7,8 +7,8 @@ import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp import com.simprints.feature.fetchsubject.screen.usecase.FetchSubjectUseCase import com.simprints.feature.fetchsubject.screen.usecase.SaveSubjectFetchEventUseCase -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.testtools.common.coroutines.TestCoroutineRule import io.mockk.MockKAnnotations import io.mockk.coEvery @@ -38,7 +38,7 @@ internal class FetchSubjectViewModelTest { lateinit var saveSubjectFetchEventUseCase: SaveSubjectFetchEventUseCase @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager private lateinit var viewModel: FetchSubjectViewModel @@ -52,7 +52,7 @@ internal class FetchSubjectViewModelTest { timeHelper, fetchSubjectUseCase, saveSubjectFetchEventUseCase, - configRepository, + configManager, ) } @@ -99,7 +99,7 @@ internal class FetchSubjectViewModelTest { @Test fun `startExitForm returns list of modalities`() { - coEvery { configRepository.getProjectConfiguration().general.modalities } returns listOf( + coEvery { configManager.getProjectConfiguration().general.modalities } returns listOf( GeneralConfiguration.Modality.FACE ) diff --git a/feature/login-check/build.gradle.kts b/feature/login-check/build.gradle.kts index 6063495f71..8bba4d117c 100644 --- a/feature/login-check/build.gradle.kts +++ b/feature/login-check/build.gradle.kts @@ -12,6 +12,7 @@ dependencies { implementation(project(":infra:orchestrator-data")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:sync")) implementation(project(":infra:events")) implementation(project(":infra:event-sync")) diff --git a/feature/login-check/src/main/java/com/simprints/feature/logincheck/LoginCheckViewModel.kt b/feature/login-check/src/main/java/com/simprints/feature/logincheck/LoginCheckViewModel.kt index 7d318c15d3..199cb6678b 100644 --- a/feature/login-check/src/main/java/com/simprints/feature/logincheck/LoginCheckViewModel.kt +++ b/feature/login-check/src/main/java/com/simprints/feature/logincheck/LoginCheckViewModel.kt @@ -9,12 +9,20 @@ import com.simprints.core.livedata.LiveDataEventWithContent import com.simprints.core.livedata.send import com.simprints.feature.login.LoginError import com.simprints.feature.login.LoginResult -import com.simprints.feature.logincheck.usecases.* +import com.simprints.feature.logincheck.usecases.AddAuthorizationEventUseCase +import com.simprints.feature.logincheck.usecases.ExtractCrashKeysUseCase +import com.simprints.feature.logincheck.usecases.ExtractParametersForAnalyticsUseCase +import com.simprints.feature.logincheck.usecases.IsUserSignedInUseCase import com.simprints.feature.logincheck.usecases.IsUserSignedInUseCase.SignedInState.MISMATCHED_PROJECT_ID import com.simprints.feature.logincheck.usecases.IsUserSignedInUseCase.SignedInState.NOT_SIGNED_IN import com.simprints.feature.logincheck.usecases.IsUserSignedInUseCase.SignedInState.SIGNED_IN -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.feature.logincheck.usecases.ReportActionRequestEventsUseCase +import com.simprints.feature.logincheck.usecases.StartBackgroundSyncUseCase +import com.simprints.feature.logincheck.usecases.UpdateProjectInCurrentSessionUseCase +import com.simprints.feature.logincheck.usecases.UpdateSessionScopePayloadUseCase +import com.simprints.feature.logincheck.usecases.UpdateStoredUserIdUseCase import com.simprints.infra.config.store.models.ProjectState +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.logging.Simber import com.simprints.infra.orchestration.data.ActionRequest import com.simprints.infra.security.SecurityManager @@ -35,7 +43,7 @@ class LoginCheckViewModel @Inject internal constructor( private val extractParametersForCrashReport: ExtractCrashKeysUseCase, private val addAuthorizationEvent: AddAuthorizationEventUseCase, private val isUserSignedIn: IsUserSignedInUseCase, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val startBackgroundSync: StartBackgroundSyncUseCase, private val syncOrchestrator: SyncOrchestrator, private val updateDatabaseCountsInCurrentSession: UpdateSessionScopePayloadUseCase, @@ -123,7 +131,7 @@ class LoginCheckViewModel @Inject internal constructor( } private suspend fun validateProjectAndProceed(actionRequest: ActionRequest) { - when (configRepository.getProject(actionRequest.projectId).state) { + when (configManager.getProject(actionRequest.projectId).state) { ProjectState.PROJECT_PAUSED -> _showAlert.send(LoginCheckError.PROJECT_PAUSED) ProjectState.PROJECT_ENDING -> _showAlert.send(LoginCheckError.PROJECT_ENDING) ProjectState.PROJECT_ENDED -> startSignInAttempt(actionRequest) diff --git a/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/ExtractCrashKeysUseCase.kt b/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/ExtractCrashKeysUseCase.kt index a0b592e228..43cb6c8c27 100644 --- a/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/ExtractCrashKeysUseCase.kt +++ b/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/ExtractCrashKeysUseCase.kt @@ -1,20 +1,20 @@ package com.simprints.feature.logincheck.usecases import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.logging.LoggingConstants.CrashReportingCustomKeys import com.simprints.infra.logging.Simber import com.simprints.infra.orchestration.data.ActionRequest import javax.inject.Inject internal class ExtractCrashKeysUseCase @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val authStore: AuthStore, ) { suspend operator fun invoke(action: ActionRequest) { - val projectConfiguration = configRepository.getProjectConfiguration() - val deviceConfiguration = configRepository.getDeviceConfiguration() + val projectConfiguration = configManager.getProjectConfiguration() + val deviceConfiguration = configManager.getDeviceConfiguration() Simber.tag(CrashReportingCustomKeys.PROJECT_ID, true).i(authStore.signedInProjectId) Simber.tag(CrashReportingCustomKeys.USER_ID, true).i(action.userId.toString()) Simber.tag(CrashReportingCustomKeys.MODULE_IDS, true).i(deviceConfiguration.selectedModules.toString()) diff --git a/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/StartBackgroundSyncIfNeededUseCase.kt b/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/StartBackgroundSyncIfNeededUseCase.kt index cccb152678..8257dc55c7 100644 --- a/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/StartBackgroundSyncIfNeededUseCase.kt +++ b/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/StartBackgroundSyncIfNeededUseCase.kt @@ -1,19 +1,19 @@ package com.simprints.feature.logincheck.usecases -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.SynchronizationConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.sync.SyncOrchestrator import javax.inject.Inject internal class StartBackgroundSyncUseCase @Inject constructor( private val syncOrchestrator: SyncOrchestrator, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, ) { suspend operator fun invoke() { syncOrchestrator.scheduleBackgroundWork() - val frequency = configRepository.getProjectConfiguration().synchronization.frequency + val frequency = configManager.getProjectConfiguration().synchronization.frequency if (frequency == SynchronizationConfiguration.Frequency.PERIODICALLY_AND_ON_SESSION_START) { syncOrchestrator.startEventSync() } diff --git a/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/UpdateProjectInCurrentSessionUseCase.kt b/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/UpdateProjectInCurrentSessionUseCase.kt index 2cf2233faa..0cbaf3630e 100644 --- a/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/UpdateProjectInCurrentSessionUseCase.kt +++ b/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/UpdateProjectInCurrentSessionUseCase.kt @@ -1,14 +1,14 @@ package com.simprints.feature.logincheck.usecases import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.SessionEventRepository import javax.inject.Inject internal class UpdateProjectInCurrentSessionUseCase @Inject constructor( private val eventRepository: SessionEventRepository, private val authStore: AuthStore, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, ) { suspend operator fun invoke() { @@ -19,8 +19,8 @@ internal class UpdateProjectInCurrentSessionUseCase @Inject constructor( val updatedSessionScope = sessionScope.copy( projectId = signedProjectId, payload = sessionScope.payload.copy( - modalities = configRepository.getProjectConfiguration().general.modalities, - language = configRepository.getDeviceConfiguration().language, + modalities = configManager.getProjectConfiguration().general.modalities, + language = configManager.getDeviceConfiguration().language, ) ) diff --git a/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/UpdateSessionScopePayloadUseCase.kt b/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/UpdateSessionScopePayloadUseCase.kt index 38871a5698..418369dc64 100644 --- a/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/UpdateSessionScopePayloadUseCase.kt +++ b/feature/login-check/src/main/java/com/simprints/feature/logincheck/usecases/UpdateSessionScopePayloadUseCase.kt @@ -1,6 +1,6 @@ package com.simprints.feature.logincheck.usecases -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.events.SessionEventRepository import javax.inject.Inject @@ -8,11 +8,11 @@ import javax.inject.Inject internal class UpdateSessionScopePayloadUseCase @Inject constructor( private val eventRepository: SessionEventRepository, private val enrolmentRecordRepository: EnrolmentRecordRepository, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, ) { suspend operator fun invoke() { - val configUpdatedAt = configRepository.getProjectConfiguration().updatedAt + val configUpdatedAt = configManager.getProjectConfiguration().updatedAt val recordCount = enrolmentRecordRepository.count() val sessionScope = eventRepository.getCurrentSessionScope() diff --git a/feature/login-check/src/test/java/com/simprints/feature/logincheck/LoginCheckViewModelTest.kt b/feature/login-check/src/test/java/com/simprints/feature/logincheck/LoginCheckViewModelTest.kt index 3a25230445..de7acd3360 100644 --- a/feature/login-check/src/test/java/com/simprints/feature/logincheck/LoginCheckViewModelTest.kt +++ b/feature/login-check/src/test/java/com/simprints/feature/logincheck/LoginCheckViewModelTest.kt @@ -5,9 +5,18 @@ import com.google.common.truth.Truth.assertThat import com.jraska.livedata.test import com.simprints.feature.login.LoginError import com.simprints.feature.login.LoginResult -import com.simprints.feature.logincheck.usecases.* -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.feature.logincheck.usecases.ActionFactory +import com.simprints.feature.logincheck.usecases.AddAuthorizationEventUseCase +import com.simprints.feature.logincheck.usecases.ExtractCrashKeysUseCase +import com.simprints.feature.logincheck.usecases.ExtractParametersForAnalyticsUseCase +import com.simprints.feature.logincheck.usecases.IsUserSignedInUseCase +import com.simprints.feature.logincheck.usecases.ReportActionRequestEventsUseCase +import com.simprints.feature.logincheck.usecases.StartBackgroundSyncUseCase +import com.simprints.feature.logincheck.usecases.UpdateProjectInCurrentSessionUseCase +import com.simprints.feature.logincheck.usecases.UpdateSessionScopePayloadUseCase +import com.simprints.feature.logincheck.usecases.UpdateStoredUserIdUseCase import com.simprints.infra.config.store.models.ProjectState +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.security.SecurityManager import com.simprints.infra.security.exceptions.RootedDeviceException import com.simprints.infra.sync.SyncOrchestrator @@ -50,7 +59,7 @@ internal class LoginCheckViewModelTest { lateinit var isUserSignedInUseCase: IsUserSignedInUseCase @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager @MockK lateinit var startBackgroundSync: StartBackgroundSyncUseCase @@ -80,7 +89,7 @@ internal class LoginCheckViewModelTest { extractCrashKeysUseCase, addAuthorizationEventUseCase, isUserSignedInUseCase, - configRepository, + configManager, startBackgroundSync, syncOrchestrator, updateSessionScopePayloadUseCase, @@ -246,7 +255,7 @@ internal class LoginCheckViewModelTest { viewModel.validateSignInAndProceed(ActionFactory.getFlowRequest()) viewModel.handleLoginResult(LoginResult(true, null)) - coVerify { configRepository.getProject(any()) } + coVerify { configManager.getProject(any()) } } @Test @@ -255,13 +264,13 @@ internal class LoginCheckViewModelTest { viewModel.validateSignInAndProceed(ActionFactory.getFlowRequest()) - coVerify { configRepository.getProject(any()) } + coVerify { configManager.getProject(any()) } } @Test fun `Triggers alert if project is paused`() = runTest { coEvery { isUserSignedInUseCase.invoke(any()) } returns IsUserSignedInUseCase.SignedInState.SIGNED_IN - coEvery { configRepository.getProject(any()).state } returns ProjectState.PROJECT_PAUSED + coEvery { configManager.getProject(any()).state } returns ProjectState.PROJECT_PAUSED viewModel.validateSignInAndProceed(ActionFactory.getFlowRequest()) @@ -272,7 +281,7 @@ internal class LoginCheckViewModelTest { @Test fun `Triggers alert if project is ending`() = runTest { coEvery { isUserSignedInUseCase.invoke(any()) } returns IsUserSignedInUseCase.SignedInState.SIGNED_IN - coEvery { configRepository.getProject(any()).state } returns ProjectState.PROJECT_ENDING + coEvery { configManager.getProject(any()).state } returns ProjectState.PROJECT_ENDING viewModel.validateSignInAndProceed(ActionFactory.getFlowRequest()) @@ -283,7 +292,7 @@ internal class LoginCheckViewModelTest { @Test fun `Triggers login attempt if project has ended`() = runTest { coEvery { isUserSignedInUseCase.invoke(any()) } returns IsUserSignedInUseCase.SignedInState.SIGNED_IN - coEvery { configRepository.getProject(any()).state } returns ProjectState.PROJECT_ENDED + coEvery { configManager.getProject(any()).state } returns ProjectState.PROJECT_ENDED viewModel.validateSignInAndProceed(ActionFactory.getFlowRequest()) @@ -294,7 +303,7 @@ internal class LoginCheckViewModelTest { @Test fun `Correctly handles if user signed in active project`() = runTest { coEvery { isUserSignedInUseCase.invoke(any()) } returns IsUserSignedInUseCase.SignedInState.SIGNED_IN - coEvery { configRepository.getProject(any()).state } returns ProjectState.RUNNING + coEvery { configManager.getProject(any()).state } returns ProjectState.RUNNING viewModel.validateSignInAndProceed(ActionFactory.getFlowRequest()) diff --git a/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/ExtractCrashKeysUseCaseTest.kt b/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/ExtractCrashKeysUseCaseTest.kt index e6edf462e6..0c9eed032b 100644 --- a/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/ExtractCrashKeysUseCaseTest.kt +++ b/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/ExtractCrashKeysUseCaseTest.kt @@ -2,8 +2,8 @@ package com.simprints.feature.logincheck.usecases import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.SynchronizationConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.logging.Simber import io.mockk.MockKAnnotations import io.mockk.coEvery @@ -21,7 +21,7 @@ import org.junit.Test class ExtractCrashKeysUseCaseTest { @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager @MockK lateinit var authStore: AuthStore @@ -33,7 +33,7 @@ class ExtractCrashKeysUseCaseTest { MockKAnnotations.init(this, relaxed = true) mockkObject(Simber) - useCase = ExtractCrashKeysUseCase(configRepository, authStore) + useCase = ExtractCrashKeysUseCase(configManager, authStore) } @After @@ -43,10 +43,10 @@ class ExtractCrashKeysUseCaseTest { @Test fun `Sets values to Simber`() = runTest { - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { synchronization.frequency } returns SynchronizationConfiguration.Frequency.PERIODICALLY } - coEvery { configRepository.getDeviceConfiguration() } returns mockk { + coEvery { configManager.getDeviceConfiguration() } returns mockk { every { selectedModules } returns listOf( "module1".asTokenizableRaw(), "module2".asTokenizableRaw() diff --git a/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/StartBackgroundSyncUseCaseTest.kt b/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/StartBackgroundSyncUseCaseTest.kt index d995e4e301..f8ad579f1c 100644 --- a/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/StartBackgroundSyncUseCaseTest.kt +++ b/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/StartBackgroundSyncUseCaseTest.kt @@ -1,7 +1,7 @@ package com.simprints.feature.logincheck.usecases -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.SynchronizationConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.sync.SyncOrchestrator import io.mockk.MockKAnnotations import io.mockk.coEvery @@ -18,7 +18,7 @@ class StartBackgroundSyncUseCaseTest { lateinit var syncOrchestrator: SyncOrchestrator @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager private lateinit var useCase: StartBackgroundSyncUseCase @@ -28,13 +28,13 @@ class StartBackgroundSyncUseCaseTest { useCase = StartBackgroundSyncUseCase( syncOrchestrator, - configRepository, + configManager, ) } @Test fun `Schedules all syncs when called`() = runTest { - coEvery { configRepository.getProjectConfiguration().synchronization.frequency } returns SynchronizationConfiguration.Frequency.PERIODICALLY + coEvery { configManager.getProjectConfiguration().synchronization.frequency } returns SynchronizationConfiguration.Frequency.PERIODICALLY useCase.invoke() @@ -45,7 +45,7 @@ class StartBackgroundSyncUseCaseTest { @Test fun `Starts event sync on start if required`() = runTest { - coEvery { configRepository.getProjectConfiguration().synchronization.frequency } returns SynchronizationConfiguration.Frequency.PERIODICALLY_AND_ON_SESSION_START + coEvery { configManager.getProjectConfiguration().synchronization.frequency } returns SynchronizationConfiguration.Frequency.PERIODICALLY_AND_ON_SESSION_START useCase.invoke() @@ -54,7 +54,7 @@ class StartBackgroundSyncUseCaseTest { @Test fun `Does not start event sync on start if not required`() = runTest { - coEvery { configRepository.getProjectConfiguration().synchronization.frequency } returns SynchronizationConfiguration.Frequency.PERIODICALLY + coEvery { configManager.getProjectConfiguration().synchronization.frequency } returns SynchronizationConfiguration.Frequency.PERIODICALLY useCase.invoke() diff --git a/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/UpdateProjectInCurrentSessionUseCaseTest.kt b/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/UpdateProjectInCurrentSessionUseCaseTest.kt index 440bd6c387..99a2845201 100644 --- a/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/UpdateProjectInCurrentSessionUseCaseTest.kt +++ b/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/UpdateProjectInCurrentSessionUseCaseTest.kt @@ -3,8 +3,7 @@ package com.simprints.feature.logincheck.usecases import com.google.common.truth.Truth.assertThat import com.simprints.core.tools.time.Timestamp import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository -import com.simprints.infra.events.EventRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.SessionEventRepository import com.simprints.infra.events.event.domain.models.Event import com.simprints.infra.events.event.domain.models.EventType @@ -20,8 +19,6 @@ import io.mockk.coVerify import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.mockk -import kotlinx.coroutines.flow.emptyFlow -import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test @@ -35,7 +32,7 @@ internal class UpdateProjectInCurrentSessionUseCaseTest { lateinit var authStore: AuthStore @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager lateinit var useCase: UpdateProjectInCurrentSessionUseCase @@ -44,11 +41,11 @@ internal class UpdateProjectInCurrentSessionUseCaseTest { MockKAnnotations.init(this, relaxed = true) every { authStore.signedInProjectId } returns SIGNED_PROJECT_ID - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { general.modalities } returns emptyList() } - useCase = UpdateProjectInCurrentSessionUseCase(eventRepository, authStore, configRepository) + useCase = UpdateProjectInCurrentSessionUseCase(eventRepository, authStore, configManager) } @Test @@ -90,7 +87,7 @@ internal class UpdateProjectInCurrentSessionUseCaseTest { @Test fun `Update language in current session event when project ID updates`() = runTest { val language = "lang" - coEvery { configRepository.getDeviceConfiguration() } returns mockk { + coEvery { configManager.getDeviceConfiguration() } returns mockk { every { this@mockk.language } returns language } coEvery { eventRepository.getCurrentSessionScope() } returns createBlankSessionScope(OTHER_PROJECT_ID) diff --git a/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/UpdateSessionScopePayloadUseCaseTest.kt b/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/UpdateSessionScopePayloadUseCaseTest.kt index 7bce4f9006..f17bc93db2 100644 --- a/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/UpdateSessionScopePayloadUseCaseTest.kt +++ b/feature/login-check/src/test/java/com/simprints/feature/logincheck/usecases/UpdateSessionScopePayloadUseCaseTest.kt @@ -2,7 +2,7 @@ package com.simprints.feature.logincheck.usecases import com.google.common.truth.Truth.assertThat import com.simprints.core.tools.time.Timestamp -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.events.SessionEventRepository import com.simprints.infra.events.event.domain.models.scope.DatabaseInfo @@ -27,7 +27,7 @@ internal class UpdateSessionScopePayloadUseCaseTest { lateinit var enrolmentRecordRepository: EnrolmentRecordRepository @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager private lateinit var useCase: UpdateSessionScopePayloadUseCase @@ -38,14 +38,14 @@ internal class UpdateSessionScopePayloadUseCaseTest { useCase = UpdateSessionScopePayloadUseCase( eventRepository, enrolmentRecordRepository, - configRepository + configManager ) } @Test fun `Updates current scope with data from enrolments`() = runTest { coEvery { enrolmentRecordRepository.count() } returns 42 - coEvery { configRepository.getProjectConfiguration().updatedAt } returns "configUpdatedAt" + coEvery { configManager.getProjectConfiguration().updatedAt } returns "configUpdatedAt" coEvery { eventRepository.getCurrentSessionScope() } returns createBlankSessionScope() diff --git a/feature/matcher/build.gradle.kts b/feature/matcher/build.gradle.kts index 3eb9f7f484..cbb107f7d1 100644 --- a/feature/matcher/build.gradle.kts +++ b/feature/matcher/build.gradle.kts @@ -14,6 +14,7 @@ dependencies { implementation(project(":infra:enrolment-records-store")) implementation(project(":infra:events")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":face:infra:face-bio-sdk")) implementation(project(":face:infra:roc-wrapper")) diff --git a/feature/matcher/src/main/java/com/simprints/matcher/usecases/FingerprintMatcherUseCase.kt b/feature/matcher/src/main/java/com/simprints/matcher/usecases/FingerprintMatcherUseCase.kt index 248f5835d9..ccbba93e06 100644 --- a/feature/matcher/src/main/java/com/simprints/matcher/usecases/FingerprintMatcherUseCase.kt +++ b/feature/matcher/src/main/java/com/simprints/matcher/usecases/FingerprintMatcherUseCase.kt @@ -7,8 +7,8 @@ import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerIdentifi import com.simprints.fingerprint.infra.basebiosdk.matching.domain.Fingerprint import com.simprints.fingerprint.infra.basebiosdk.matching.domain.FingerprintIdentity import com.simprints.fingerprint.infra.biosdk.ResolveBioSdkWrapperUseCase -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FingerprintConfiguration.FingerComparisonStrategy.CROSS_FINGER_USING_MEAN_OF_MAX +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.store.domain.models.BiometricDataSource import com.simprints.infra.enrolment.records.store.domain.models.SubjectQuery @@ -25,7 +25,7 @@ import javax.inject.Inject internal class FingerprintMatcherUseCase @Inject constructor( private val enrolmentRecordRepository: EnrolmentRecordRepository, private val resolveBioSdkWrapper: ResolveBioSdkWrapperUseCase, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val createRanges: CreateRangesUseCase, @DispatcherBG private val dispatcher: CoroutineDispatcher, ) : MatcherUseCase { @@ -99,7 +99,7 @@ internal class FingerprintMatcherUseCase @Inject constructor( isCrossFingerMatchingEnabled(flowType), ) - private suspend fun isCrossFingerMatchingEnabled(flowType: FlowType): Boolean = configRepository + private suspend fun isCrossFingerMatchingEnabled(flowType: FlowType): Boolean = configManager .takeIf { flowType == FlowType.VERIFY } ?.getProjectConfiguration() ?.fingerprint diff --git a/feature/matcher/src/main/java/com/simprints/matcher/usecases/SaveMatchEventUseCase.kt b/feature/matcher/src/main/java/com/simprints/matcher/usecases/SaveMatchEventUseCase.kt index df39faeaf7..2dbbd2e739 100644 --- a/feature/matcher/src/main/java/com/simprints/matcher/usecases/SaveMatchEventUseCase.kt +++ b/feature/matcher/src/main/java/com/simprints/matcher/usecases/SaveMatchEventUseCase.kt @@ -3,7 +3,7 @@ package com.simprints.matcher.usecases import com.simprints.core.ExternalScope import com.simprints.core.domain.common.FlowType import com.simprints.core.tools.time.Timestamp -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.domain.models.SubjectQuery import com.simprints.infra.events.SessionEventRepository import com.simprints.infra.events.event.domain.models.FingerComparisonStrategy @@ -19,7 +19,7 @@ import com.simprints.infra.config.store.models.FingerprintConfiguration.FingerCo internal class SaveMatchEventUseCase @Inject constructor( private val eventRepository: SessionEventRepository, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, @ExternalScope private val externalScope: CoroutineScope, ) { @@ -54,7 +54,7 @@ internal class SaveMatchEventUseCase @Inject constructor( } } - private suspend fun getFingerprintComparisonStrategy() = configRepository.getProjectConfiguration() + private suspend fun getFingerprintComparisonStrategy() = configManager.getProjectConfiguration() .fingerprint ?.bioSdkConfiguration ?.comparisonStrategyForVerification diff --git a/feature/matcher/src/test/java/com/simprints/matcher/usecases/FingerprintMatcherUseCaseTest.kt b/feature/matcher/src/test/java/com/simprints/matcher/usecases/FingerprintMatcherUseCaseTest.kt index f6bbcdc1af..aba584d478 100644 --- a/feature/matcher/src/test/java/com/simprints/matcher/usecases/FingerprintMatcherUseCaseTest.kt +++ b/feature/matcher/src/test/java/com/simprints/matcher/usecases/FingerprintMatcherUseCaseTest.kt @@ -7,8 +7,8 @@ import com.simprints.core.domain.fingerprint.FingerprintSample import com.simprints.core.domain.fingerprint.IFingerIdentifier import com.simprints.fingerprint.infra.biosdk.BioSdkWrapper import com.simprints.fingerprint.infra.biosdk.ResolveBioSdkWrapperUseCase -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.store.domain.models.BiometricDataSource import com.simprints.infra.enrolment.records.store.domain.models.FingerprintIdentity @@ -42,7 +42,7 @@ internal class FingerprintMatcherUseCaseTest { lateinit var resolveBioSdkWrapperUseCase: ResolveBioSdkWrapperUseCase @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager @MockK lateinit var createRangesUseCase: CreateRangesUseCase @@ -54,13 +54,13 @@ internal class FingerprintMatcherUseCaseTest { MockKAnnotations.init(this, relaxed = true) coEvery { resolveBioSdkWrapperUseCase() } returns bioSdkWrapper coEvery { - configRepository.getProjectConfiguration().fingerprint?.allowedSDKs + configManager.getProjectConfiguration().fingerprint?.allowedSDKs } returns listOf(FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER) useCase = FingerprintMatcherUseCase( enrolmentRecordRepository, resolveBioSdkWrapperUseCase, - configRepository, + configManager, createRangesUseCase, testCoroutineRule.testCoroutineDispatcher, ) @@ -69,7 +69,7 @@ internal class FingerprintMatcherUseCaseTest { @Test fun `Correctly get the matcher name`() = runTest { coEvery { bioSdkWrapper.matcherName } returns "SIM_AFIS" - coEvery { configRepository.getProjectConfiguration().fingerprint?.allowedSDKs } returns listOf( + coEvery { configManager.getProjectConfiguration().fingerprint?.allowedSDKs } returns listOf( FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER ) assertThat(useCase.matcherName()).isEqualTo("SIM_AFIS") diff --git a/feature/matcher/src/test/java/com/simprints/matcher/usecases/SaveMatchEventUseCaseTest.kt b/feature/matcher/src/test/java/com/simprints/matcher/usecases/SaveMatchEventUseCaseTest.kt index c6741090d1..e57f1199ac 100644 --- a/feature/matcher/src/test/java/com/simprints/matcher/usecases/SaveMatchEventUseCaseTest.kt +++ b/feature/matcher/src/test/java/com/simprints/matcher/usecases/SaveMatchEventUseCaseTest.kt @@ -4,8 +4,8 @@ import com.google.common.truth.Truth.assertThat import com.simprints.core.domain.common.FlowType import com.simprints.core.domain.fingerprint.IFingerIdentifier import com.simprints.core.tools.time.Timestamp -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FingerprintConfiguration.FingerComparisonStrategy +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.domain.models.BiometricDataSource import com.simprints.infra.enrolment.records.store.domain.models.SubjectQuery import com.simprints.infra.events.SessionEventRepository @@ -35,7 +35,7 @@ class SaveMatchEventUseCaseTest { private lateinit var eventRepository: SessionEventRepository @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager private lateinit var useCase: SaveMatchEventUseCase @@ -46,12 +46,12 @@ class SaveMatchEventUseCaseTest { coEvery { eventRepository.addOrUpdateEvent(any()) } just Runs coEvery { - configRepository.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.comparisonStrategyForVerification + configManager.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.comparisonStrategyForVerification } returns FingerComparisonStrategy.SAME_FINGER useCase = SaveMatchEventUseCase( eventRepository, - configRepository, + configManager, CoroutineScope(testCoroutineRule.testCoroutineDispatcher), ) } diff --git a/feature/orchestrator/build.gradle.kts b/feature/orchestrator/build.gradle.kts index 81ec2f97bc..d0d00a7817 100644 --- a/feature/orchestrator/build.gradle.kts +++ b/feature/orchestrator/build.gradle.kts @@ -30,6 +30,7 @@ dependencies { implementation(project(":infra:enrolment-records-store")) implementation(project(":infra:recent-user-activity")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:events")) implementation(project(":infra:event-sync")) implementation(project(":infra:images")) 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 cce2dfcd41..a26c48924d 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 @@ -28,8 +28,8 @@ import com.simprints.feature.orchestrator.usecases.response.AppResponseBuilderUs import com.simprints.feature.orchestrator.usecases.steps.BuildStepsUseCase import com.simprints.feature.setup.LocationStore import com.simprints.fingerprint.capture.FingerprintCaptureResult -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.logging.Simber import com.simprints.infra.orchestration.data.ActionRequest import com.simprints.matcher.MatchParams @@ -40,7 +40,7 @@ import javax.inject.Inject @HiltViewModel internal class OrchestratorViewModel @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val cache: OrchestratorCache, private val locationStore: LocationStore, private val stepsBuilder: BuildStepsUseCase, @@ -67,7 +67,7 @@ internal class OrchestratorViewModel @Inject constructor( private val _appResponse = MutableLiveData>() fun handleAction(action: ActionRequest) = viewModelScope.launch { - val projectConfiguration = configRepository.getProjectConfiguration() + val projectConfiguration = configManager.getProjectConfiguration() modalities = projectConfiguration.general.modalities.toSet() steps = stepsBuilder.build(action, projectConfiguration) @@ -111,7 +111,7 @@ internal class OrchestratorViewModel @Inject constructor( fun restoreModalitiesIfNeeded() { viewModelScope.launch { if (modalities.isEmpty()) { - val projectConfiguration = configRepository.getProjectConfiguration() + val projectConfiguration = configManager.getProjectConfiguration() modalities = projectConfiguration.general.modalities.toSet() } } @@ -138,7 +138,7 @@ internal class OrchestratorViewModel @Inject constructor( } private fun buildAppResponse() = viewModelScope.launch { - val projectConfiguration = configRepository.getProjectConfiguration() + val projectConfiguration = configManager.getProjectConfiguration() val cachedActionRequest = actionRequest val appResponse = appResponseBuilder( projectConfiguration, 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 4b50886ee8..19e6f94154 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 @@ -24,8 +24,8 @@ import com.simprints.feature.orchestrator.usecases.steps.BuildStepsUseCase import com.simprints.feature.setup.LocationStore import com.simprints.feature.setup.SetupResult import com.simprints.fingerprint.capture.FingerprintCaptureResult -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.domain.models.BiometricDataSource import com.simprints.infra.enrolment.records.store.domain.models.SubjectQuery import com.simprints.infra.orchestration.data.responses.AppErrorResponse @@ -55,7 +55,7 @@ internal class OrchestratorViewModelTest { val testCoroutineRule = TestCoroutineRule() @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var cache: OrchestratorCache @@ -92,7 +92,7 @@ internal class OrchestratorViewModelTest { MockKAnnotations.init(this, relaxed = true) viewModel = OrchestratorViewModel( - configRepository, + configManager, cache, locationStore, stepsBuilder, @@ -261,14 +261,14 @@ internal class OrchestratorViewModelTest { mockk(), mockk(), ) - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { general.modalities } returns emptyList() andThen projectModalities } viewModel.handleAction(mockk()) viewModel.restoreModalitiesIfNeeded() - coVerify(exactly = 3) { configRepository.getProjectConfiguration() } + coVerify(exactly = 3) { configManager.getProjectConfiguration() } } @Test @@ -277,14 +277,14 @@ internal class OrchestratorViewModelTest { mockk(), mockk(), ) - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { general.modalities } returns projectModalities } viewModel.handleAction(mockk()) viewModel.restoreModalitiesIfNeeded() - coVerify(exactly = 2) { configRepository.getProjectConfiguration() } + coVerify(exactly = 2) { configManager.getProjectConfiguration() } } private fun createMockStep(stepId: Int, payload: Bundle = Bundle()) = Step( diff --git a/feature/setup/build.gradle.kts b/feature/setup/build.gradle.kts index 6021bb64db..3de97bb7ca 100644 --- a/feature/setup/build.gradle.kts +++ b/feature/setup/build.gradle.kts @@ -10,6 +10,7 @@ android { dependencies { implementation(project(":infra:events")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:license")) implementation(project(":infra:auth-store")) implementation(project(":feature:alert")) 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 ffaab17f45..9172c50952 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 @@ -7,10 +7,10 @@ import androidx.lifecycle.viewModelScope import com.simprints.core.DeviceID import com.simprints.feature.setup.LocationStore import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository 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 import com.simprints.infra.license.LicenseState import com.simprints.infra.license.LicenseStatus @@ -26,7 +26,7 @@ import javax.inject.Inject @HiltViewModel internal class SetupViewModel @Inject constructor( private val locationStore: LocationStore, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val licenseRepository: LicenseRepository, @DeviceID private val deviceID: String, private val authStore: AuthStore, @@ -65,7 +65,7 @@ internal class SetupViewModel @Inject constructor( fun downloadRequiredLicenses() { viewModelScope.launch { - requiredLicenses = configRepository.getProjectConfiguration().requiredLicenses + requiredLicenses = configManager.getProjectConfiguration().requiredLicenses // if there are no required licenses, then the setup is complete if (requiredLicenses.isEmpty()) { _overallSetupResult.postValue(true) @@ -106,7 +106,7 @@ internal class SetupViewModel @Inject constructor( } private suspend fun shouldCollectLocation() = - configRepository.getProjectConfiguration().general.collectLocation + configManager.getProjectConfiguration().general.collectLocation } 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 bcb7c17694..d0e3e89bf6 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 @@ -4,9 +4,9 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.jraska.livedata.test import com.simprints.feature.setup.LocationStore import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.license.LicenseRepository import com.simprints.infra.license.LicenseState import com.simprints.infra.license.LicenseStatus @@ -50,7 +50,7 @@ class SetupViewModelTest { @MockK private lateinit var saveLicenseCheckEvent: SaveLicenseCheckEventUseCase - private val configRepository = mockk() + private val configManager = mockk() private lateinit var viewModel: SetupViewModel private val deviceID = "deviceID" @@ -63,7 +63,7 @@ class SetupViewModelTest { viewModel = SetupViewModel( locationStore, - configRepository, + configManager, licenseRepository, deviceID, authStore, @@ -74,7 +74,7 @@ class SetupViewModelTest { @Test fun `should request location permission if collectLocation is enabled`() = runTest { // Given - coEvery { configRepository.getProjectConfiguration().general.collectLocation } returns true + coEvery { configManager.getProjectConfiguration().general.collectLocation } returns true // When viewModel.start() @@ -87,7 +87,7 @@ class SetupViewModelTest { @Test fun `should not request location permission if collectLocation is disabled`() = runTest { // Given - coEvery { configRepository.getProjectConfiguration().general.collectLocation } returns false + coEvery { configManager.getProjectConfiguration().general.collectLocation } returns false // when viewModel.start() @@ -115,7 +115,7 @@ class SetupViewModelTest { @Test fun `should request notification permission if collectLocation is disabled`() = runTest { // Given - coEvery { configRepository.getProjectConfiguration().general.collectLocation } returns false + coEvery { configManager.getProjectConfiguration().general.collectLocation } returns false // When viewModel.start() @@ -128,7 +128,7 @@ class SetupViewModelTest { @Test fun `should not request notification permission yet if collectLocation is enabled`() = runTest { // Given - coEvery { configRepository.getProjectConfiguration().general.collectLocation } returns true + coEvery { configManager.getProjectConfiguration().general.collectLocation } returns true // When viewModel.start() @@ -150,7 +150,7 @@ class SetupViewModelTest { @Test fun `should download required licenses`() = runTest { // Given - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { general } returns mockk { every { modalities } returns listOf( GeneralConfiguration.Modality.FINGERPRINT, @@ -177,7 +177,7 @@ class SetupViewModelTest { @Test fun `should not download required licenses if there are no required licenses`() = runTest { // Given - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { general } returns mockk { every { modalities } returns emptyList() } @@ -193,7 +193,7 @@ class SetupViewModelTest { @Test fun `should fail if any license fails`() = runTest { // Given - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { general } returns mockk { every { modalities } returns listOf( GeneralConfiguration.Modality.FINGERPRINT, diff --git a/fingerprint/capture/build.gradle.kts b/fingerprint/capture/build.gradle.kts index ab8333fbb5..3d35e38a46 100644 --- a/fingerprint/capture/build.gradle.kts +++ b/fingerprint/capture/build.gradle.kts @@ -21,6 +21,7 @@ dependencies { implementation(project(":infra:enrolment-records-store")) implementation(project(":fingerprint:infra:scanner")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:auth-store")) implementation(project(":infra:images")) implementation(project(":infra:recent-user-activity")) 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 42b0c7ac77..ca2c25c0d4 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 @@ -40,12 +40,12 @@ import com.simprints.fingerprint.infra.scanner.exceptions.safe.NoFingerDetectedE import com.simprints.fingerprint.infra.scanner.exceptions.safe.ScannerDisconnectedException import com.simprints.fingerprint.infra.scanner.exceptions.safe.ScannerOperationInterruptedException import com.simprints.fingerprint.infra.scanner.wrapper.ScannerWrapper -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FingerprintConfiguration import com.simprints.infra.config.store.models.Vero2Configuration.ImageSavingStrategy.EAGER import com.simprints.infra.config.store.models.Vero2Configuration.ImageSavingStrategy.NEVER import com.simprints.infra.config.store.models.Vero2Configuration.ImageSavingStrategy.ONLY_GOOD_SCAN import com.simprints.infra.config.store.models.Vero2Configuration.ImageSavingStrategy.ONLY_USED_IN_REFERENCE +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 @@ -63,7 +63,7 @@ import kotlin.math.min @HiltViewModel internal class FingerprintCaptureViewModel @Inject constructor( private val scannerManager: ScannerManager, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val timeHelper: TimeHelper, private val resolveBioSdkWrapperUseCase: ResolveBioSdkWrapperUseCase, private val saveImage: SaveImageUseCase, @@ -168,7 +168,7 @@ internal class FingerprintCaptureViewModel @Inject constructor( initBioSdk() // Configuration must be initialised when start returns for UI to be initialised correctly, // and since fetching happens on IO thread execution must be suspended until it is available - configuration = configRepository.getProjectConfiguration().fingerprint!! + configuration = configManager.getProjectConfiguration().fingerprint!! bioSdkConfiguration = configuration.bioSdkConfiguration } 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 c41f24380d..3beeb75b09 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 @@ -31,10 +31,10 @@ import com.simprints.fingerprint.infra.scanner.exceptions.safe.NoFingerDetectedE import com.simprints.fingerprint.infra.scanner.exceptions.safe.ScannerDisconnectedException import com.simprints.fingerprint.infra.scanner.wrapper.ScannerWrapper import com.simprints.fingerprint.testtools.FingerprintGenerator -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.Vero1Configuration import com.simprints.infra.config.store.models.Vero2Configuration import com.simprints.infra.config.store.models.Vero2Configuration.ImageSavingStrategy +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.images.model.Path import com.simprints.testtools.common.coroutines.TestCoroutineRule import com.simprints.testtools.common.livedata.assertEventNotReceived @@ -74,7 +74,7 @@ class FingerprintCaptureViewModelTest { private lateinit var vero2Configuration: Vero2Configuration @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var scanner: ScannerWrapper @@ -111,7 +111,7 @@ class FingerprintCaptureViewModelTest { every { vero2Configuration.displayLiveFeedback } returns false every { vero2Configuration.captureStrategy } returns Vero2Configuration.CaptureStrategy.SECUGEN_ISO_1000_DPI every { vero2Configuration.imageSavingStrategy } returns ImageSavingStrategy.NEVER - coEvery { configRepository.getProjectConfiguration().fingerprint?.bioSdkConfiguration } returns mockk { + coEvery { configManager.getProjectConfiguration().fingerprint?.bioSdkConfiguration } returns mockk { every { vero1 } returns Vero1Configuration(60) every { vero2 } returns vero2Configuration } @@ -130,7 +130,7 @@ class FingerprintCaptureViewModelTest { vm = FingerprintCaptureViewModel( scannerManager, - configRepository, + configManager, timeHelper, resolveBioSdkWrapperUseCase, saveImageUseCase, diff --git a/fingerprint/connect/build.gradle.kts b/fingerprint/connect/build.gradle.kts index a63e7b92cf..ada579c339 100644 --- a/fingerprint/connect/build.gradle.kts +++ b/fingerprint/connect/build.gradle.kts @@ -10,6 +10,7 @@ android { dependencies { implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:events")) implementation(project(":infra:recent-user-activity")) diff --git a/fingerprint/connect/src/main/java/com/simprints/fingerprint/connect/screens/ConnectScannerViewModel.kt b/fingerprint/connect/src/main/java/com/simprints/fingerprint/connect/screens/ConnectScannerViewModel.kt index 25df12f3db..b1e29f4b6e 100644 --- a/fingerprint/connect/src/main/java/com/simprints/fingerprint/connect/screens/ConnectScannerViewModel.kt +++ b/fingerprint/connect/src/main/java/com/simprints/fingerprint/connect/screens/ConnectScannerViewModel.kt @@ -21,8 +21,8 @@ import com.simprints.fingerprint.infra.scanner.exceptions.safe.ScannerDisconnect import com.simprints.fingerprint.infra.scanner.exceptions.safe.ScannerLowBatteryException import com.simprints.fingerprint.infra.scanner.exceptions.safe.ScannerNotPairedException import com.simprints.fingerprint.infra.scanner.exceptions.unexpected.UnknownScannerIssueException -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.logging.LoggingConstants import com.simprints.infra.logging.LoggingConstants.AnalyticsUserProperties import com.simprints.infra.logging.Simber @@ -34,7 +34,7 @@ import javax.inject.Inject @HiltViewModel internal class ConnectScannerViewModel @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val scannerManager: ScannerManager, private val nfcManager: NfcManager, private val recentUserActivityManager: RecentUserActivityManager, @@ -70,7 +70,7 @@ internal class ConnectScannerViewModel @Inject constructor( fun init(params: FingerprintConnectParams) = viewModelScope.launch { isReconnect = params.isReconnect - allowedGenerations = configRepository.getProjectConfiguration() + allowedGenerations = configManager.getProjectConfiguration() .fingerprint ?.allowedScanners .orEmpty() diff --git a/fingerprint/connect/src/main/java/com/simprints/fingerprint/connect/screens/ota/OtaViewModel.kt b/fingerprint/connect/src/main/java/com/simprints/fingerprint/connect/screens/ota/OtaViewModel.kt index 24ef75b8d2..e66d2ed045 100644 --- a/fingerprint/connect/src/main/java/com/simprints/fingerprint/connect/screens/ota/OtaViewModel.kt +++ b/fingerprint/connect/src/main/java/com/simprints/fingerprint/connect/screens/ota/OtaViewModel.kt @@ -14,9 +14,11 @@ import com.simprints.fingerprint.connect.usecase.ReportFirmwareUpdateEventUseCas import com.simprints.fingerprint.infra.scanner.ScannerManager import com.simprints.fingerprint.infra.scanner.domain.ota.AvailableOta import com.simprints.fingerprint.infra.scanner.domain.ota.OtaRecoveryStrategy -import com.simprints.fingerprint.infra.scanner.domain.ota.OtaRecoveryStrategy.* +import com.simprints.fingerprint.infra.scanner.domain.ota.OtaRecoveryStrategy.HARD_RESET +import com.simprints.fingerprint.infra.scanner.domain.ota.OtaRecoveryStrategy.SOFT_RESET +import com.simprints.fingerprint.infra.scanner.domain.ota.OtaRecoveryStrategy.SOFT_RESET_AFTER_DELAY import com.simprints.fingerprint.infra.scanner.domain.ota.OtaStep -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.logging.Simber import com.simprints.infra.network.exceptions.BackendMaintenanceException import com.simprints.infra.recent.user.activity.RecentUserActivityManager @@ -35,7 +37,7 @@ internal class OtaViewModel @Inject constructor( private val reportFirmwareUpdate: ReportFirmwareUpdateEventUseCase, private val timeHelper: TimeHelper, private val recentUserActivityManager: RecentUserActivityManager, - private val configRepository: ConfigRepository + private val configManager: ConfigManager ) : ViewModel() { val progress: LiveData @@ -93,7 +95,7 @@ internal class OtaViewModel @Inject constructor( private suspend fun targetVersions(availableOta: AvailableOta): String { val scannerVersion = recentUserActivityManager.getRecentUserActivity().lastScannerVersion val availableFirmwareVersions = - configRepository.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2?.firmwareVersions + configManager.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2?.firmwareVersions return when (availableOta) { AvailableOta.CYPRESS -> availableFirmwareVersions?.get(scannerVersion)?.cypress ?: "" AvailableOta.STM -> availableFirmwareVersions?.get(scannerVersion)?.stm ?: "" diff --git a/fingerprint/connect/src/test/java/com/simprints/fingerprint/connect/screens/ConnectScannerViewModelTest.kt b/fingerprint/connect/src/test/java/com/simprints/fingerprint/connect/screens/ConnectScannerViewModelTest.kt index f94433c4c0..040c60dc46 100644 --- a/fingerprint/connect/src/test/java/com/simprints/fingerprint/connect/screens/ConnectScannerViewModelTest.kt +++ b/fingerprint/connect/src/test/java/com/simprints/fingerprint/connect/screens/ConnectScannerViewModelTest.kt @@ -26,8 +26,8 @@ import com.simprints.fingerprint.infra.scanner.tools.SerialNumberConverter import com.simprints.fingerprint.infra.scanner.wrapper.ScannerFactory import com.simprints.fingerprint.infra.scanner.wrapper.ScannerWrapper import com.simprints.fingerprint.scannermock.dummy.DummyBluetoothDevice -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.recent.user.activity.RecentUserActivityManager import com.simprints.infra.recent.user.activity.domain.RecentUserActivity import com.simprints.testtools.common.coroutines.TestCoroutineRule @@ -35,8 +35,15 @@ import com.simprints.testtools.common.livedata.assertEventReceivedWithContent import com.simprints.testtools.common.livedata.assertEventReceivedWithContentAssertions import com.simprints.testtools.common.livedata.assertEventWithContentNeverReceived import com.simprints.testtools.common.livedata.testObserver -import io.mockk.* +import io.mockk.MockKAnnotations +import io.mockk.coEvery +import io.mockk.coJustRun +import io.mockk.coVerify +import io.mockk.every import io.mockk.impl.annotations.MockK +import io.mockk.mockk +import io.mockk.slot +import io.mockk.verify import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Rule @@ -57,7 +64,7 @@ class ConnectScannerViewModelTest { private lateinit var fingerprintConfiguration: FingerprintConfiguration @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var bluetoothAdapter: ComponentBluetoothAdapter @@ -86,7 +93,7 @@ class ConnectScannerViewModelTest { FingerprintConfiguration.VeroGeneration.VERO_1, FingerprintConfiguration.VeroGeneration.VERO_2 ) - coEvery { configRepository.getProjectConfiguration().fingerprint } returns fingerprintConfiguration + coEvery { configManager.getProjectConfiguration().fingerprint } returns fingerprintConfiguration coJustRun { scannerFactory.initScannerOperationWrappers(any()) } scannerManager = ScannerManagerImpl( @@ -97,7 +104,7 @@ class ConnectScannerViewModelTest { mockk(relaxed = true), ) viewModel = ConnectScannerViewModel( - configRepository, + configManager, scannerManager, nfcManager, recentUserActivityManager, @@ -205,7 +212,7 @@ class ConnectScannerViewModelTest { fun start_noScannersPairedWithoutFingerprintConfigAndNfc_sendsSerialEntryIssueEvent() = runTest { setupBluetooth(numberOfPairedScanners = 0) setupNfc(doesDeviceHaveNfcCapability = false, isEnabled = true) - coEvery { configRepository.getProjectConfiguration().fingerprint } returns null + coEvery { configManager.getProjectConfiguration().fingerprint } returns null val connectScannerIssueObserver = viewModel.showScannerIssueScreen.testObserver() diff --git a/fingerprint/connect/src/test/java/com/simprints/fingerprint/connect/screens/ota/OtaViewModelTest.kt b/fingerprint/connect/src/test/java/com/simprints/fingerprint/connect/screens/ota/OtaViewModelTest.kt index 256080c3c4..53db35418b 100644 --- a/fingerprint/connect/src/test/java/com/simprints/fingerprint/connect/screens/ota/OtaViewModelTest.kt +++ b/fingerprint/connect/src/test/java/com/simprints/fingerprint/connect/screens/ota/OtaViewModelTest.kt @@ -14,8 +14,8 @@ import com.simprints.fingerprint.infra.scanner.domain.ota.StmOtaStep import com.simprints.fingerprint.infra.scanner.domain.ota.Un20OtaStep import com.simprints.fingerprint.infra.scanner.exceptions.safe.OtaFailedException import com.simprints.fingerprint.infra.scanner.wrapper.ScannerOtaOperationsWrapper -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.Vero2Configuration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.network.exceptions.BackendMaintenanceException import com.simprints.infra.recent.user.activity.RecentUserActivityManager import com.simprints.infra.recent.user.activity.domain.RecentUserActivity @@ -63,7 +63,7 @@ class OtaViewModelTest { private lateinit var recentUserActivityManager: RecentUserActivityManager @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager private lateinit var otaViewModel: OtaViewModel @@ -75,7 +75,7 @@ class OtaViewModelTest { coEvery { recentUserActivityManager.getRecentUserActivity() } returns RecentUserActivity(HARDWARE_VERSION, "", "".asTokenizableRaw(), 0, 0, 0, 0) - coEvery { configRepository.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2?.firmwareVersions } returns mapOf( + coEvery { configManager.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2?.firmwareVersions } returns mapOf( HARDWARE_VERSION to Vero2Configuration.Vero2FirmwareVersions( NEW_CYPRESS_VERSION, NEW_STM_VERSION, @@ -93,7 +93,7 @@ class OtaViewModelTest { reportFirmwareUpdate, timeHelperMock, recentUserActivityManager, - configRepository + configManager ) } diff --git a/fingerprint/infra/bio-sdk/build.gradle.kts b/fingerprint/infra/bio-sdk/build.gradle.kts index 9fdbd9305b..3e1cc89dd7 100644 --- a/fingerprint/infra/bio-sdk/build.gradle.kts +++ b/fingerprint/infra/bio-sdk/build.gradle.kts @@ -9,6 +9,7 @@ android { dependencies { implementation(project(":fingerprint:infra:scanner")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) api(project(":fingerprint:infra:base-bio-sdk")) implementation(project(":fingerprint:infra:simprints-bio-sdk")) implementation(project(":fingerprint:infra:nec-bio-sdk")) diff --git a/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/ResolveBioSdkWrapperUseCase.kt b/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/ResolveBioSdkWrapperUseCase.kt index 2b69094266..7cfc6eedec 100644 --- a/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/ResolveBioSdkWrapperUseCase.kt +++ b/fingerprint/infra/bio-sdk/src/main/java/com/simprints/fingerprint/infra/biosdk/ResolveBioSdkWrapperUseCase.kt @@ -2,12 +2,12 @@ package com.simprints.fingerprint.infra.biosdk import com.simprints.fingerprint.infra.biosdkimpl.SimprintsSdk import com.simprints.fingerprint.infra.necsdkimpl.NecSdk -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.infra.config.sync.ConfigManager import javax.inject.Inject class ResolveBioSdkWrapperUseCase @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, @SimprintsSdk private val simprintsWrapper: BioSdkWrapper, @NecSdk private val necWrapper: BioSdkWrapper, ) { @@ -20,7 +20,7 @@ class ResolveBioSdkWrapperUseCase @Inject constructor( // so we are just using the first allowed SDK for now // See tickets in SIM-81 for more details bioSdkWrapper = - when (configRepository.getProjectConfiguration().fingerprint?.allowedSDKs?.first()) { + when (configManager.getProjectConfiguration().fingerprint?.allowedSDKs?.first()) { FingerprintConfiguration.BioSdk.SECUGEN_SIM_MATCHER -> simprintsWrapper FingerprintConfiguration.BioSdk.NEC -> necWrapper else -> error("Unknown fingerprint configuration") diff --git a/fingerprint/infra/bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdk/ResolveBioSdkWrapperUseCaseTest.kt b/fingerprint/infra/bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdk/ResolveBioSdkWrapperUseCaseTest.kt index 234db047ff..ffe7040457 100644 --- a/fingerprint/infra/bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdk/ResolveBioSdkWrapperUseCaseTest.kt +++ b/fingerprint/infra/bio-sdk/src/test/java/com/simprints/fingerprint/infra/biosdk/ResolveBioSdkWrapperUseCaseTest.kt @@ -1,8 +1,8 @@ package com.simprints.fingerprint.infra.biosdk import com.google.common.truth.Truth -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.infra.config.sync.ConfigManager import io.mockk.MockKAnnotations import io.mockk.coEvery import io.mockk.coVerify @@ -24,7 +24,7 @@ class ResolveBioSdkWrapperUseCaseTest { private lateinit var simprintsBioSdkWrapper: BioSdkWrapper @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var fingerprintConfiguration: FingerprintConfiguration @@ -32,11 +32,11 @@ class ResolveBioSdkWrapperUseCaseTest { @Before fun setUp() { MockKAnnotations.init(this) - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { fingerprint } returns fingerprintConfiguration } bioSdkResolverUseCase = - ResolveBioSdkWrapperUseCase(configRepository, simprintsBioSdkWrapper, necBioSdkWrapper) + ResolveBioSdkWrapperUseCase(configManager, simprintsBioSdkWrapper, necBioSdkWrapper) } @Test diff --git a/fingerprint/infra/scanner/build.gradle.kts b/fingerprint/infra/scanner/build.gradle.kts index 87ad85bff0..c051e88928 100644 --- a/fingerprint/infra/scanner/build.gradle.kts +++ b/fingerprint/infra/scanner/build.gradle.kts @@ -19,6 +19,7 @@ dependencies { runtimeOnly(libs.jackson.core) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:auth-store")) implementation(project(":infra:recent-user-activity")) diff --git a/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/data/FirmwareRepository.kt b/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/data/FirmwareRepository.kt index 2549eaf659..2871fe3e01 100644 --- a/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/data/FirmwareRepository.kt +++ b/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/data/FirmwareRepository.kt @@ -4,7 +4,7 @@ import com.simprints.fingerprint.infra.scanner.data.local.FirmwareLocalDataSourc import com.simprints.fingerprint.infra.scanner.data.remote.FirmwareRemoteDataSource import com.simprints.fingerprint.infra.scanner.domain.ota.DownloadableFirmwareVersion import com.simprints.fingerprint.infra.scanner.domain.ota.DownloadableFirmwareVersion.Chip -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.logging.Simber import javax.inject.Inject @@ -16,7 +16,7 @@ import javax.inject.Inject class FirmwareRepository @Inject internal constructor( private val firmwareRemoteDataSource: FirmwareRemoteDataSource, private val firmwareLocalDataSource: FirmwareLocalDataSource, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, ) { /** @@ -24,7 +24,7 @@ class FirmwareRepository @Inject internal constructor( * first checks the local version and matches that against the remote versions, then subsequently updating the rlocal versios that need to be updated. */ suspend fun updateStoredFirmwareFilesWithLatest() { - configRepository.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2?.firmwareVersions?.keys?.forEach { hardwareVersion -> + configManager.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2?.firmwareVersions?.keys?.forEach { hardwareVersion -> updateStoredFirmwareFilesWithLatest(hardwareVersion) } } @@ -81,7 +81,7 @@ class FirmwareRepository @Inject internal constructor( val cypressOfficialVersions = mutableSetOf() val stmOfficialVersions = mutableSetOf() val un20OfficialVersions = mutableSetOf() - configRepository.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2?.firmwareVersions?.entries?.forEach { + configManager.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2?.firmwareVersions?.entries?.forEach { cypressOfficialVersions.add(it.value.cypress) stmOfficialVersions.add(it.value.stm) un20OfficialVersions.add(it.value.un20) diff --git a/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/data/remote/FirmwareRemoteDataSource.kt b/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/data/remote/FirmwareRemoteDataSource.kt index d5a7fa7710..2510007dfb 100644 --- a/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/data/remote/FirmwareRemoteDataSource.kt +++ b/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/data/remote/FirmwareRemoteDataSource.kt @@ -3,7 +3,7 @@ package com.simprints.fingerprint.infra.scanner.data.remote import com.simprints.fingerprint.infra.scanner.data.remote.network.FingerprintFileDownloader import com.simprints.fingerprint.infra.scanner.domain.ota.DownloadableFirmwareVersion import com.simprints.fingerprint.infra.scanner.domain.versions.getAvailableVersionsForDownload -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.logging.Simber import javax.inject.Inject @@ -14,7 +14,7 @@ import javax.inject.Inject */ internal class FirmwareRemoteDataSource @Inject constructor( private val fingerprintFileDownloader: FingerprintFileDownloader, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, ) { /** @@ -24,7 +24,7 @@ internal class FirmwareRemoteDataSource @Inject constructor( hardwareVersion: String, localFirmwareVersions: Map> ): List = - configRepository.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2?.firmwareVersions?.getAvailableVersionsForDownload( + configManager.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2?.firmwareVersions?.getAvailableVersionsForDownload( hardwareVersion, localFirmwareVersions ) ?: listOf() diff --git a/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/helpers/ScannerInitialSetupHelper.kt b/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/helpers/ScannerInitialSetupHelper.kt index 9982e82a51..07c012378e 100644 --- a/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/helpers/ScannerInitialSetupHelper.kt +++ b/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/helpers/ScannerInitialSetupHelper.kt @@ -9,8 +9,8 @@ import com.simprints.fingerprint.infra.scanner.domain.versions.ScannerVersion import com.simprints.fingerprint.infra.scanner.exceptions.safe.OtaAvailableException import com.simprints.fingerprint.infra.scanner.tools.BatteryLevelChecker import com.simprints.fingerprint.infra.scanner.v2.scanner.Scanner -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.Vero2Configuration +import com.simprints.infra.config.sync.ConfigManager import kotlinx.coroutines.delay import kotlinx.coroutines.rx2.await import javax.inject.Inject @@ -22,7 +22,7 @@ import javax.inject.Inject internal class ScannerInitialSetupHelper @Inject constructor( private val connectionHelper: ConnectionHelper, private val batteryLevelChecker: BatteryLevelChecker, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val firmwareLocalDataSource: FirmwareLocalDataSource, ) { @@ -91,7 +91,7 @@ internal class ScannerInitialSetupHelper @Inject constructor( batteryInfo: BatteryInfo, ) { val availableVersions = - configRepository.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2?.firmwareVersions?.get( + configManager.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2?.firmwareVersions?.get( hardwareVersion ) val availableOtas = determineAvailableOtas(scannerVersion.firmware, availableVersions) diff --git a/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/wrapper/ScannerFactory.kt b/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/wrapper/ScannerFactory.kt index 50b01b7dc2..a059003532 100644 --- a/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/wrapper/ScannerFactory.kt +++ b/fingerprint/infra/scanner/src/main/java/com/simprints/fingerprint/infra/scanner/wrapper/ScannerFactory.kt @@ -12,8 +12,8 @@ import com.simprints.fingerprint.infra.scanner.tools.ScannerGenerationDeterminer import com.simprints.fingerprint.infra.scanner.tools.SerialNumberConverter import com.simprints.fingerprint.infra.scanner.v2.scanner.create import com.simprints.fingerprint.infra.scanner.v2.tools.ScannerUiHelper -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.logging.Simber import kotlinx.coroutines.CoroutineDispatcher import javax.inject.Inject @@ -24,7 +24,7 @@ import com.simprints.fingerprint.infra.scanner.v2.scanner.Scanner as ScannerV2 @Singleton class ScannerFactory @Inject internal constructor( private val bluetoothAdapter: ComponentBluetoothAdapter, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val scannerUiHelper: ScannerUiHelper, private val serialNumberConverter: SerialNumberConverter, private val scannerGenerationDeterminer: ScannerGenerationDeterminer, @@ -45,7 +45,7 @@ class ScannerFactory @Inject internal constructor( suspend fun initScannerOperationWrappers(macAddress: String) { val availableScannerGenerations = - configRepository.getProjectConfiguration().fingerprint?.allowedScanners ?: listOf() + configManager.getProjectConfiguration().fingerprint?.allowedScanners ?: listOf() val scannerGenerationToUse = when (availableScannerGenerations.size) { 1 -> availableScannerGenerations.single() diff --git a/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/data/FirmwareRepositoryTest.kt b/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/data/FirmwareRepositoryTest.kt index e657868b37..705b655f92 100644 --- a/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/data/FirmwareRepositoryTest.kt +++ b/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/data/FirmwareRepositoryTest.kt @@ -4,8 +4,8 @@ import com.simprints.fingerprint.infra.scanner.data.local.FirmwareLocalDataSourc import com.simprints.fingerprint.infra.scanner.data.remote.FirmwareRemoteDataSource import com.simprints.fingerprint.infra.scanner.domain.ota.DownloadableFirmwareVersion import com.simprints.fingerprint.infra.scanner.domain.versions.getAvailableVersionsForDownload -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.Vero2Configuration +import com.simprints.infra.config.sync.ConfigManager import io.mockk.MockKAnnotations import io.mockk.Ordering import io.mockk.coEvery @@ -28,7 +28,7 @@ class FirmwareRepositoryTest { private lateinit var vero2Configuration: Vero2Configuration @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager private lateinit var firmwareRepository: FirmwareRepository @@ -37,7 +37,7 @@ class FirmwareRepositoryTest { MockKAnnotations.init(this, relaxed = true) coEvery { - configRepository.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2 + configManager.getProjectConfiguration().fingerprint?.bioSdkConfiguration?.vero2 } returns vero2Configuration every { vero2Configuration.firmwareVersions } returns mapOf( @@ -51,7 +51,7 @@ class FirmwareRepositoryTest { firmwareRepository = FirmwareRepository( firmwareRemoteDataSourceMock, firmwareLocalDataSourceMock, - configRepository + configManager ) } diff --git a/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/data/remote/FirmwareRemoteDataSourceTest.kt b/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/data/remote/FirmwareRemoteDataSourceTest.kt index dc9fe223af..d39bb32ab8 100644 --- a/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/data/remote/FirmwareRemoteDataSourceTest.kt +++ b/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/data/remote/FirmwareRemoteDataSourceTest.kt @@ -4,8 +4,8 @@ import com.google.common.truth.Truth.assertThat import com.simprints.fingerprint.infra.scanner.data.FirmwareTestData import com.simprints.fingerprint.infra.scanner.data.remote.network.FingerprintFileDownloader import com.simprints.fingerprint.infra.scanner.domain.ota.DownloadableFirmwareVersion -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.Vero2Configuration +import com.simprints.infra.config.sync.ConfigManager import io.mockk.coEvery import io.mockk.every import io.mockk.mockk @@ -15,7 +15,7 @@ import org.junit.Test class FirmwareRemoteDataSourceTest { private val fingerprintFileDownloaderMock: FingerprintFileDownloader = mockk() - private val fingerprintPreferencesMock = mockk { + private val fingerprintPreferencesMock = mockk { coEvery { getProjectConfiguration() } returns mockk { every { fingerprint?.bioSdkConfiguration?.vero2?.firmwareVersions } returns RESPONSE_MAP } diff --git a/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/helpers/ScannerInitialSetupHelperTest.kt b/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/helpers/ScannerInitialSetupHelperTest.kt index 2dd3cdcf0c..68084917fc 100644 --- a/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/helpers/ScannerInitialSetupHelperTest.kt +++ b/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/helpers/ScannerInitialSetupHelperTest.kt @@ -14,8 +14,8 @@ import com.simprints.fingerprint.infra.scanner.v2.domain.root.models.CypressFirm import com.simprints.fingerprint.infra.scanner.v2.domain.root.models.ScannerInformation import com.simprints.fingerprint.infra.scanner.v2.domain.root.models.UnifiedVersionInformation import com.simprints.fingerprint.infra.scanner.v2.scanner.Scanner -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.Vero2Configuration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.testtools.common.syntax.assertThrows import io.mockk.coEvery import io.mockk.coVerify @@ -33,7 +33,7 @@ class ScannerInitialSetupHelperTest { private val connectionHelperMock = mockk() private val batteryLevelChecker = mockk() private val vero2Configuration = mockk() - private val configRepository = mockk { + private val configManager = mockk { coEvery { getProjectConfiguration() } returns mockk { every { fingerprint?.bioSdkConfiguration?.vero2 } returns vero2Configuration } @@ -42,7 +42,7 @@ class ScannerInitialSetupHelperTest { private val scannerInitialSetupHelper = ScannerInitialSetupHelper( connectionHelperMock, batteryLevelChecker, - configRepository, + configManager, firmwareLocalDataSource, ) diff --git a/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/wrapper/ScannerFactoryTest.kt b/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/wrapper/ScannerFactoryTest.kt index 979e9e853a..dfe3869095 100644 --- a/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/wrapper/ScannerFactoryTest.kt +++ b/fingerprint/infra/scanner/src/test/java/com/simprints/fingerprint/infra/scanner/wrapper/ScannerFactoryTest.kt @@ -6,8 +6,8 @@ import com.simprints.fingerprint.infra.scanner.component.bluetooth.ComponentBlue import com.simprints.fingerprint.infra.scanner.tools.ScannerGenerationDeterminer import com.simprints.fingerprint.infra.scanner.tools.SerialNumberConverter import com.simprints.fingerprint.infra.scanner.v2.tools.ScannerUiHelper -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.infra.config.sync.ConfigManager import io.mockk.MockKAnnotations import io.mockk.every import io.mockk.impl.annotations.MockK @@ -25,7 +25,7 @@ class ScannerFactoryTest { private lateinit var componentBluetoothAdapter: ComponentBluetoothAdapter @MockK(relaxed = true) - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var scannerUiHelper: ScannerUiHelper @@ -44,7 +44,7 @@ class ScannerFactoryTest { MockKAnnotations.init(this) scannerFactory = ScannerFactory( componentBluetoothAdapter, - configRepository, + configManager, scannerUiHelper, serialNumberConverter, scannerGenerationDeterminer, diff --git a/infra/auth-logic/build.gradle.kts b/infra/auth-logic/build.gradle.kts index df3f7c3650..161d5916c0 100644 --- a/infra/auth-logic/build.gradle.kts +++ b/infra/auth-logic/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { implementation(project(":infra:auth-store")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:events")) implementation(project(":infra:enrolment-records-store")) diff --git a/infra/auth-logic/src/main/java/com/simprints/infra/authlogic/authenticator/ProjectAuthenticator.kt b/infra/auth-logic/src/main/java/com/simprints/infra/authlogic/authenticator/ProjectAuthenticator.kt index 5325cb6d12..c45f4b046d 100644 --- a/infra/auth-logic/src/main/java/com/simprints/infra/authlogic/authenticator/ProjectAuthenticator.kt +++ b/infra/auth-logic/src/main/java/com/simprints/infra/authlogic/authenticator/ProjectAuthenticator.kt @@ -7,7 +7,7 @@ import com.simprints.infra.authlogic.model.NonceScope import com.simprints.infra.authstore.domain.models.AuthRequest import com.simprints.infra.authstore.domain.models.Token import com.simprints.infra.authstore.exceptions.AuthRequestInvalidCredentialsException -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.network.exceptions.BackendMaintenanceException import com.simprints.infra.network.exceptions.SyncCloudIntegrationException import com.simprints.infra.security.SecurityManager @@ -17,7 +17,7 @@ import javax.inject.Inject internal class ProjectAuthenticator @Inject constructor( private val secureDataManager: SecurityManager, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val signerManager: SignerManager, private val authenticationRemoteDataSource: AuthenticationRemoteDataSource, private val integrityTokenRequester: IntegrityTokenRequester, @@ -39,7 +39,7 @@ internal class ProjectAuthenticator @Inject constructor( makeAuthRequest(prepareAuthRequestParameters(nonceScope, projectSecret), nonceScope) .signIn(nonceScope.projectId) - val config = configRepository.getProjectConfiguration() + val config = configManager.getProjectConfiguration() fetchProjectLongConsentTexts(config.general.languageOptions, config.projectId) } @@ -85,7 +85,7 @@ internal class ProjectAuthenticator @Inject constructor( private suspend fun fetchProjectLongConsentTexts(languages: List, projectId: String) { languages.forEach { language -> - configRepository.getPrivacyNotice(projectId, language).collect() + configManager.getPrivacyNotice(projectId, language).collect() } } } diff --git a/infra/auth-logic/src/main/java/com/simprints/infra/authlogic/authenticator/SignerManager.kt b/infra/auth-logic/src/main/java/com/simprints/infra/authlogic/authenticator/SignerManager.kt index 2553543b86..41ca270fb1 100644 --- a/infra/auth-logic/src/main/java/com/simprints/infra/authlogic/authenticator/SignerManager.kt +++ b/infra/auth-logic/src/main/java/com/simprints/infra/authlogic/authenticator/SignerManager.kt @@ -4,7 +4,7 @@ import com.simprints.core.DispatcherIO import com.simprints.fingerprint.infra.scanner.ScannerManager import com.simprints.infra.authstore.AuthStore import com.simprints.infra.authstore.domain.models.Token -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.events.EventRepository import com.simprints.infra.images.ImageRepository @@ -18,7 +18,7 @@ import kotlinx.coroutines.withContext import javax.inject.Inject internal class SignerManager @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val authStore: AuthStore, private val recentUserActivityManager: RecentUserActivityManager, private val simNetwork: SimNetwork, @@ -37,14 +37,14 @@ internal class SignerManager @Inject constructor( try { // Store Firebase token so it can be used by ConfigManager authStore.storeFirebaseToken(token) - configRepository.refreshProject(projectId) + configManager.refreshProject(projectId) // Only store credentials if all other calls succeeded. This avoids the undefined state // where credentials are store (i.e. user is considered logged in) but project configuration // is missing authStore.signedInProjectId = projectId } catch (e: Exception) { authStore.clearFirebaseToken() - configRepository.clearData() + configManager.clearData() authStore.cleanCredentials() throw e @@ -54,7 +54,7 @@ internal class SignerManager @Inject constructor( suspend fun signOut() = withContext(dispatcher) { simNetwork.resetApiBaseUrl() - configRepository.clearData() + configManager.clearData() recentUserActivityManager.clearRecentActivity() imageRepository.deleteStoredImages() diff --git a/infra/auth-logic/src/test/java/com/simprints/infra/authlogic/authenticator/ProjectAuthenticatorTest.kt b/infra/auth-logic/src/test/java/com/simprints/infra/authlogic/authenticator/ProjectAuthenticatorTest.kt index 0cde4cb01a..3f082bda48 100644 --- a/infra/auth-logic/src/test/java/com/simprints/infra/authlogic/authenticator/ProjectAuthenticatorTest.kt +++ b/infra/auth-logic/src/test/java/com/simprints/infra/authlogic/authenticator/ProjectAuthenticatorTest.kt @@ -7,9 +7,9 @@ import com.simprints.infra.authlogic.integrity.exceptions.RequestingIntegrityTok import com.simprints.infra.authlogic.model.NonceScope import com.simprints.infra.authstore.domain.models.AuthenticationData import com.simprints.infra.authstore.domain.models.Token -import com.simprints.infra.config.store.ConfigRepository 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.network.exceptions.BackendMaintenanceException import com.simprints.infra.security.SecurityManager import com.simprints.testtools.common.syntax.assertThrows @@ -28,7 +28,7 @@ import java.io.IOException class ProjectAuthenticatorTest { @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var secureDataManager: SecurityManager @@ -51,7 +51,7 @@ class ProjectAuthenticatorTest { authenticator = ProjectAuthenticator( secureDataManager, - configRepository, + configManager, signerManager, authenticationRemoteDataSource, integrityTokenRequester, @@ -133,8 +133,8 @@ class ProjectAuthenticatorTest { runTest(StandardTestDispatcher()) { authenticator.authenticate(NonceScope(PROJECT_ID, DEVICE_ID), PROJECT_SECRET) - coVerify(exactly = 1) { configRepository.getPrivacyNotice(PROJECT_ID, LANGUAGE_1) } - coVerify(exactly = 1) { configRepository.getPrivacyNotice(PROJECT_ID, LANGUAGE_2) } + coVerify(exactly = 1) { configManager.getPrivacyNotice(PROJECT_ID, LANGUAGE_1) } + coVerify(exactly = 1) { configManager.getPrivacyNotice(PROJECT_ID, LANGUAGE_2) } } @Test @@ -157,7 +157,7 @@ class ProjectAuthenticatorTest { authenticationRemoteDataSource.requestAuthToken(PROJECT_ID, DEVICE_ID, any()) } returns Token("", "", "", "") - coEvery { configRepository.getProjectConfiguration() } returns ProjectConfiguration( + coEvery { configManager.getProjectConfiguration() } returns ProjectConfiguration( PROJECT_ID, "", general = GeneralConfiguration( @@ -174,7 +174,7 @@ class ProjectAuthenticatorTest { mockk(), mockk(), ) - coEvery { configRepository.getPrivacyNotice(any(), any()) } returns emptyFlow() + coEvery { configManager.getPrivacyNotice(any(), any()) } returns emptyFlow() coEvery { integrityTokenRequester.getToken(any()) } returns "token" } diff --git a/infra/auth-logic/src/test/java/com/simprints/infra/authlogic/authenticator/SignerManagerTest.kt b/infra/auth-logic/src/test/java/com/simprints/infra/authlogic/authenticator/SignerManagerTest.kt index 0e00389546..98342de399 100644 --- a/infra/auth-logic/src/test/java/com/simprints/infra/authlogic/authenticator/SignerManagerTest.kt +++ b/infra/auth-logic/src/test/java/com/simprints/infra/authlogic/authenticator/SignerManagerTest.kt @@ -3,11 +3,11 @@ package com.simprints.infra.authlogic.authenticator import com.simprints.fingerprint.infra.scanner.ScannerManager import com.simprints.infra.authstore.AuthStore import com.simprints.infra.authstore.domain.models.Token -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.ProjectState import com.simprints.infra.config.store.models.ProjectWithConfig +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.events.EventRepository import com.simprints.infra.events.sampledata.SampleDefaults.DEFAULT_PROJECT_ID @@ -31,7 +31,7 @@ import org.junit.Test internal class SignerManagerTest { @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager @MockK lateinit var mockAuthStore: AuthStore @@ -71,7 +71,7 @@ internal class SignerManagerTest { MockKAnnotations.init(this, relaxed = true) signerManager = SignerManager( - configRepository, + configManager, mockAuthStore, mockRecentUserActivityManager, mockSimNetwork, @@ -128,7 +128,7 @@ internal class SignerManagerTest { signIn() - coVerify { configRepository.refreshProject(DEFAULT_PROJECT_ID) } + coVerify { configManager.refreshProject(DEFAULT_PROJECT_ID) } } @Test @@ -140,7 +140,7 @@ internal class SignerManagerTest { assertThrows { signIn() } verify { mockAuthStore.clearFirebaseToken() } - coVerify { configRepository.clearData() } + coVerify { configManager.clearData() } verify { mockAuthStore.cleanCredentials() } } @@ -159,7 +159,7 @@ internal class SignerManagerTest { verify { mockAuthStore.cleanCredentials() } verify { mockAuthStore.clearFirebaseToken() } - coVerify(exactly = 1) { configRepository.clearData() } + coVerify(exactly = 1) { configManager.clearData() } } @Test @@ -180,7 +180,7 @@ internal class SignerManagerTest { fun signOut_clearConfiguration() = runTest(UnconfinedTestDispatcher()) { signerManager.signOut() - coVerify { configRepository.clearData() } + coVerify { configManager.clearData() } } @Test @@ -216,7 +216,7 @@ internal class SignerManagerTest { } private fun mockFetchingProjectInfo(error: Boolean = false) = - coEvery { configRepository.refreshProject(any()) }.apply { + coEvery { configManager.refreshProject(any()) }.apply { if (!error) { this.returns( ProjectWithConfig( diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/ConfigRepository.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/ConfigRepository.kt index b1b3795002..5842fb4ddf 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/ConfigRepository.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/ConfigRepository.kt @@ -11,7 +11,7 @@ import kotlinx.coroutines.flow.Flow interface ConfigRepository { suspend fun refreshProject(projectId: String): ProjectWithConfig - suspend fun getProject(projectId: String): Project + suspend fun getProject(): Project suspend fun getProjectConfiguration(): ProjectConfiguration suspend fun getDeviceState(): DeviceState diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/ConfigRepositoryImpl.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/ConfigRepositoryImpl.kt index 543140568a..1cc78ff6f2 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/ConfigRepositoryImpl.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/ConfigRepositoryImpl.kt @@ -2,7 +2,9 @@ package com.simprints.infra.config.store import androidx.annotation.VisibleForTesting import com.simprints.core.DeviceID +import com.simprints.infra.config.store.local.ConfigLocalDataSource import com.simprints.infra.config.store.models.DeviceConfiguration +import com.simprints.infra.config.store.models.DeviceState import com.simprints.infra.config.store.models.PrivacyNoticeResult import com.simprints.infra.config.store.models.PrivacyNoticeResult.Failed import com.simprints.infra.config.store.models.PrivacyNoticeResult.FailedBecauseBackendMaintenance @@ -10,8 +12,6 @@ import com.simprints.infra.config.store.models.PrivacyNoticeResult.InProgress import com.simprints.infra.config.store.models.PrivacyNoticeResult.Succeed import com.simprints.infra.config.store.models.Project import com.simprints.infra.config.store.models.ProjectConfiguration -import com.simprints.infra.config.store.local.ConfigLocalDataSource -import com.simprints.infra.config.store.models.DeviceState import com.simprints.infra.config.store.models.ProjectWithConfig import com.simprints.infra.config.store.remote.ConfigRemoteDataSource import com.simprints.infra.logging.Simber @@ -35,11 +35,7 @@ internal class ConfigRepositoryImpl @Inject constructor( const val PRIVACY_NOTICE_FILE = "privacy_notice" } - override suspend fun getProject(projectId: String): Project = try { - localDataSource.getProject() - } catch (e: NoSuchElementException) { - refreshProject(projectId).project - } + override suspend fun getProject(): Project = localDataSource.getProject() override suspend fun refreshProject(projectId: String): ProjectWithConfig = remoteDataSource @@ -53,23 +49,7 @@ internal class ConfigRepositoryImpl @Inject constructor( } } - override suspend fun getProjectConfiguration(): ProjectConfiguration { - val localConfig = localDataSource.getProjectConfiguration() - // If projectId is empty, configuration hasn't been downloaded yet - return if (localConfig.projectId.isEmpty()) { - try { - // Try to refresh it with logged in projectId (if any) - refreshProject(localDataSource.getProject().id).configuration - } catch (e: Exception) { - // If not logged in the above will fail. However we still depend on the 'default' - // configuration to create the session when login is attempted. Possibly in other - // places, too. - localConfig - } - } else { - localConfig - } - } + override suspend fun getProjectConfiguration(): ProjectConfiguration = localDataSource.getProjectConfiguration() override suspend fun getDeviceState(): DeviceState { val projectId = localDataSource.getProject().id diff --git a/infra/config-store/src/test/java/com/simprints/infra/config/store/ConfigRepositoryImplTest.kt b/infra/config-store/src/test/java/com/simprints/infra/config/store/ConfigRepositoryImplTest.kt index b652771033..bea7161208 100644 --- a/infra/config-store/src/test/java/com/simprints/infra/config/store/ConfigRepositoryImplTest.kt +++ b/infra/config-store/src/test/java/com/simprints/infra/config/store/ConfigRepositoryImplTest.kt @@ -58,34 +58,19 @@ class ConfigRepositoryImplTest { fun `should get the project locally if available`() = runTest { coEvery { localDataSource.getProject() } returns project - val receivedProject = configServiceImpl.getProject(PROJECT_ID) + val receivedProject = configServiceImpl.getProject() assertThat(receivedProject).isEqualTo(project) coVerify(exactly = 1) { localDataSource.getProject() } coVerify(exactly = 0) { remoteDataSource.getProject(any()) } } - @Test - fun `should get the project remotely if not available locally and save it`() = runTest { - coEvery { localDataSource.saveProject(project) } returns Unit - coEvery { localDataSource.getProject() } throws NoSuchElementException() - coEvery { remoteDataSource.getProject(PROJECT_ID) } returns ProjectWithConfig(project, projectConfiguration) - - val receivedProject = configServiceImpl.getProject(PROJECT_ID) - - assertThat(receivedProject).isEqualTo(project) - coVerify(exactly = 1) { localDataSource.getProject() } - coVerify(exactly = 1) { localDataSource.saveProject(project) } - coVerify(exactly = 1) { localDataSource.saveProjectConfiguration(projectConfiguration) } - coVerify(exactly = 1) { remoteDataSource.getProject(PROJECT_ID) } - } - @Test fun `should throw the exception if there is an issue`() = runTest { val exception = Exception("exception") coEvery { localDataSource.getProject() } throws exception - val receivedException = assertThrows { configServiceImpl.getProject(PROJECT_ID) } + val receivedException = assertThrows { configServiceImpl.getProject() } assertThat(receivedException).isEqualTo(exception) coVerify(exactly = 1) { localDataSource.getProject() } diff --git a/infra/config-sync/.gitignore b/infra/config-sync/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/infra/config-sync/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/infra/config-sync/build.gradle.kts b/infra/config-sync/build.gradle.kts new file mode 100644 index 0000000000..cdf159f3b2 --- /dev/null +++ b/infra/config-sync/build.gradle.kts @@ -0,0 +1,14 @@ +plugins { + id("simprints.infra") + id("kotlin-parcelize") +} + +android { + namespace = "com.simprints.infra.config.sync" +} + +dependencies { + + implementation(project(":infra:config-store")) + implementation(project(":infra:enrolment-records-store")) +} diff --git a/infra/config-sync/consumer-rules.pro b/infra/config-sync/consumer-rules.pro new file mode 100644 index 0000000000..db498be940 --- /dev/null +++ b/infra/config-sync/consumer-rules.pro @@ -0,0 +1,4 @@ +# Protobuf files +-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite { + ; +} diff --git a/infra/config-sync/src/main/AndroidManifest.xml b/infra/config-sync/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..e100076157 --- /dev/null +++ b/infra/config-sync/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + diff --git a/infra/config-sync/src/main/java/com/simprints/infra/config/sync/ConfigManager.kt b/infra/config-sync/src/main/java/com/simprints/infra/config/sync/ConfigManager.kt new file mode 100644 index 0000000000..11352733ff --- /dev/null +++ b/infra/config-sync/src/main/java/com/simprints/infra/config/sync/ConfigManager.kt @@ -0,0 +1,64 @@ +package com.simprints.infra.config.sync + +import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.store.models.DeviceConfiguration +import com.simprints.infra.config.store.models.DeviceState +import com.simprints.infra.config.store.models.PrivacyNoticeResult +import com.simprints.infra.config.store.models.Project +import com.simprints.infra.config.store.models.ProjectConfiguration +import com.simprints.infra.config.store.models.ProjectWithConfig +import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +class ConfigManager @Inject constructor( + private val configRepository: ConfigRepository, + private val enrolmentRecordRepository: EnrolmentRecordRepository +) { + suspend fun refreshProject(projectId: String): ProjectWithConfig { + return configRepository.refreshProject(projectId).also { + enrolmentRecordRepository.tokenizeExistingRecords(it.project) + } + } + + suspend fun getProject(projectId: String): Project = try { + configRepository.getProject() + } catch (e: NoSuchElementException) { + refreshProject(projectId).project + } + + suspend fun getProjectConfiguration(): ProjectConfiguration { + val localConfig = configRepository.getProjectConfiguration() + // If projectId is empty, configuration hasn't been downloaded yet + return if (localConfig.projectId.isEmpty()) { + try { + // Try to refresh it with logged in projectId (if any) + refreshProject(configRepository.getProject().id).configuration + } catch (e: Exception) { + // If not logged in the above will fail. However we still depend on the 'default' + // configuration to create the session when login is attempted. Possibly in other + // places, too. + localConfig + } + } else { + localConfig + } + } + + suspend fun getDeviceConfiguration(): DeviceConfiguration = + configRepository.getDeviceConfiguration() + + suspend fun updateDeviceConfiguration(update: suspend (t: DeviceConfiguration) -> DeviceConfiguration) = + configRepository.updateDeviceConfiguration(update) + + suspend fun getPrivacyNotice(projectId: String, language: String): Flow = + configRepository.getPrivacyNotice( + projectId = projectId, + language = language + ) + + suspend fun clearData() = configRepository.clearData() + + suspend fun getDeviceState(): DeviceState = configRepository.getDeviceState() + +} diff --git a/infra/config-sync/src/test/java/com/simprints/infra/config/sync/ConfigManagerTest.kt b/infra/config-sync/src/test/java/com/simprints/infra/config/sync/ConfigManagerTest.kt new file mode 100644 index 0000000000..c866d647c2 --- /dev/null +++ b/infra/config-sync/src/test/java/com/simprints/infra/config/sync/ConfigManagerTest.kt @@ -0,0 +1,117 @@ +package com.simprints.infra.config.sync + +import com.google.common.truth.Truth.assertThat +import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.store.models.DeviceConfiguration +import com.simprints.infra.config.store.models.Project +import com.simprints.infra.config.store.models.ProjectConfiguration +import com.simprints.infra.config.store.models.ProjectWithConfig +import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository +import io.mockk.MockKAnnotations +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every +import io.mockk.impl.annotations.MockK +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test + +class ConfigManagerTest { + companion object { + private const val PROJECT_ID = "projectId" + private const val LANGUAGE = "fr" + } + + private lateinit var configManager: ConfigManager + + @MockK + private lateinit var configRepository: ConfigRepository + + @MockK + private lateinit var enrolmentRecordRepository: EnrolmentRecordRepository + + @MockK + private lateinit var projectWithConfig: ProjectWithConfig + + @MockK + private lateinit var projectConfiguration: ProjectConfiguration + + @MockK + private lateinit var deviceConfiguration: DeviceConfiguration + + @MockK + private lateinit var project: Project + + @Before + fun setup() { + MockKAnnotations.init(this, relaxed = true) + configManager = ConfigManager( + configRepository = configRepository, + enrolmentRecordRepository = enrolmentRecordRepository + ) + } + + @Test + fun `refreshProject should call the correct method`() = runTest { + coEvery { configRepository.refreshProject(PROJECT_ID) } returns projectWithConfig + + val refreshedProject = configManager.refreshProject(PROJECT_ID) + assertThat(refreshedProject).isEqualTo(projectWithConfig) + } + + @Test + fun `getProject should call the correct method`() = runTest { + coEvery { configRepository.getProject() } returns project + + val gottenProject = configManager.getProject(PROJECT_ID) + assertThat(gottenProject).isEqualTo(project) + } + + @Test + fun `getProjectConfiguration should call the correct method`() = runTest { + coEvery { configRepository.getProjectConfiguration() } returns projectConfiguration + every { projectConfiguration.projectId } returns PROJECT_ID + + val gottenProjectConfiguration = configManager.getProjectConfiguration() + assertThat(gottenProjectConfiguration).isEqualTo(projectConfiguration) + } + + @Test + fun `refreshProjectConfiguration should call the correct method`() = runTest { + coEvery { configRepository.refreshProject(PROJECT_ID) } returns projectWithConfig + + val refreshedProjectConfiguration = configManager.refreshProject(PROJECT_ID) + assertThat(refreshedProjectConfiguration).isEqualTo(projectWithConfig) + } + + @Test + fun `getDeviceConfiguration should call the correct method`() = runTest { + coEvery { configRepository.getDeviceConfiguration() } returns deviceConfiguration + + val gottenDeviceConfiguration = configManager.getDeviceConfiguration() + assertThat(gottenDeviceConfiguration).isEqualTo(deviceConfiguration) + } + + @Test + fun `updateDeviceConfiguration should call the correct method`() = runTest { + val update: (c: DeviceConfiguration) -> DeviceConfiguration = { + it + } + + configManager.updateDeviceConfiguration(update) + coVerify(exactly = 1) { configRepository.updateDeviceConfiguration(update) } + } + + @Test + fun `clearData should call the correct method`() = runTest { + configManager.clearData() + coVerify(exactly = 1) { configRepository.clearData() } + } + + @Test + fun `getPrivacyNotice should call the correct method`() = runTest { + configManager.getPrivacyNotice(PROJECT_ID, LANGUAGE) + coVerify(exactly = 1) { configRepository.getPrivacyNotice(PROJECT_ID, LANGUAGE) } + } + +} diff --git a/infra/event-sync/build.gradle.kts b/infra/event-sync/build.gradle.kts index b0fb5e96d2..900dc452de 100644 --- a/infra/event-sync/build.gradle.kts +++ b/infra/event-sync/build.gradle.kts @@ -28,6 +28,7 @@ dependencies { implementation(project(":infra:images")) implementation(project(":infra:events")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:auth-store")) implementation(project(":infra:enrolment-records-store")) implementation(project(":infra:recent-user-activity")) 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 5d8b5e7d5b..804cf59220 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 @@ -4,9 +4,9 @@ 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.ConfigRepository import com.simprints.infra.config.store.models.TokenKeyType import com.simprints.infra.config.store.tokenization.TokenizationProcessor +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.eventsync.exceptions.MissingArgumentForDownSyncScopeException import com.simprints.infra.eventsync.status.down.domain.EventDownSyncOperation import com.simprints.infra.eventsync.status.down.domain.EventDownSyncScope @@ -22,7 +22,7 @@ internal class EventDownSyncScopeRepository @Inject constructor( private val authStore: AuthStore, private val recentUserActivityManager: RecentUserActivityManager, private val downSyncOperationOperationDao: DbEventDownSyncOperationStateDao, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val tokenizationProcessor: TokenizationProcessor, ) { @@ -63,7 +63,7 @@ internal class EventDownSyncScopeRepository @Inject constructor( is TokenizableString.Raw -> tokenizationProcessor.encrypt( decrypted = possibleUserId, tokenKeyType = TokenKeyType.AttendantId, - project = configRepository.getProject(projectId) + project = configManager.getProject(projectId) ).value is TokenizableString.Tokenized -> possibleUserId.value } diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/EventDownSyncWorkersBuilder.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/EventDownSyncWorkersBuilder.kt index 3ea37090f0..d8afe36cc1 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/EventDownSyncWorkersBuilder.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/EventDownSyncWorkersBuilder.kt @@ -8,7 +8,7 @@ import androidx.work.WorkRequest import androidx.work.workDataOf import com.simprints.core.domain.tokenization.values import com.simprints.core.tools.json.JsonHelper -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.eventsync.status.down.EventDownSyncScopeRepository import com.simprints.infra.eventsync.status.down.domain.EventDownSyncOperation import com.simprints.infra.eventsync.sync.MIN_BACKOFF_SECS @@ -27,15 +27,15 @@ import javax.inject.Inject internal class EventDownSyncWorkersBuilder @Inject constructor( private val downSyncScopeRepository: EventDownSyncScopeRepository, private val jsonHelper: JsonHelper, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, ) { suspend fun buildDownSyncWorkerChain( uniqueSyncId: String, uniqueDownSyncId: String, ): List { - val projectConfiguration = configRepository.getProjectConfiguration() - val deviceConfiguration = configRepository.getDeviceConfiguration() + val projectConfiguration = configManager.getProjectConfiguration() + val deviceConfiguration = configManager.getDeviceConfiguration() val downSyncScope = downSyncScopeRepository.getDownSyncScope( modes = projectConfiguration.general.modalities.map { it.toMode() }, diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/tasks/EventDownSyncTask.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/tasks/EventDownSyncTask.kt index d0e768b129..15ef988505 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/tasks/EventDownSyncTask.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/down/tasks/EventDownSyncTask.kt @@ -5,7 +5,7 @@ import com.simprints.core.domain.tokenization.values import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp import com.simprints.infra.authstore.exceptions.RemoteDbNotSignedInException -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.store.domain.models.SubjectAction import com.simprints.infra.enrolment.records.store.domain.models.SubjectAction.Creation @@ -42,7 +42,7 @@ internal class EventDownSyncTask @Inject constructor( private val enrolmentRecordRepository: EnrolmentRecordRepository, private val eventDownSyncScopeRepository: EventDownSyncScopeRepository, private val subjectFactory: SubjectFactory, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val timeHelper: TimeHelper, private val eventRemoteDataSource: EventRemoteDataSource, private val eventRepository: EventRepository, @@ -285,7 +285,7 @@ internal class EventDownSyncTask @Inject constructor( op.queryEvent.moduleId == moduleId.value private suspend fun EnrolmentRecordCreationInMove.isUnderOverallSyncing() = - moduleId.value.partOf(configRepository.getDeviceConfiguration().selectedModules.values()) + moduleId.value.partOf(configManager.getDeviceConfiguration().selectedModules.values()) private fun String.partOf(modules: List) = modules.contains(this) diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/master/EventSyncMasterWorker.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/master/EventSyncMasterWorker.kt index 924f631261..3a30189d6b 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/master/EventSyncMasterWorker.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/master/EventSyncMasterWorker.kt @@ -2,19 +2,27 @@ package com.simprints.infra.eventsync.sync.master import android.content.Context import androidx.hilt.work.HiltWorker -import androidx.work.* +import androidx.work.OneTimeWorkRequest +import androidx.work.WorkInfo +import androidx.work.WorkManager +import androidx.work.WorkerParameters +import androidx.work.workDataOf import com.simprints.core.DispatcherBG import com.simprints.core.tools.time.TimeHelper import com.simprints.core.workers.SimCoroutineWorker -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.ProjectState import com.simprints.infra.config.store.models.SynchronizationConfiguration import com.simprints.infra.config.store.models.canSyncDataToSimprints import com.simprints.infra.config.store.models.isEventDownSyncAllowed +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.EventRepository import com.simprints.infra.events.event.domain.models.scope.EventScopeType -import com.simprints.infra.eventsync.sync.common.* +import com.simprints.infra.eventsync.sync.common.EventSyncCache +import com.simprints.infra.eventsync.sync.common.SYNC_LOG_TAG +import com.simprints.infra.eventsync.sync.common.getAllSubjectsSyncWorkersInfo +import com.simprints.infra.eventsync.sync.common.getUniqueSyncId +import com.simprints.infra.eventsync.sync.common.sortByScheduledTime import com.simprints.infra.eventsync.sync.down.EventDownSyncWorkersBuilder import com.simprints.infra.eventsync.sync.up.EventUpSyncWorkersBuilder import com.simprints.infra.logging.Simber @@ -23,7 +31,7 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedInject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.withContext -import java.util.* +import java.util.UUID @HiltWorker class EventSyncMasterWorker @AssistedInject internal constructor( @@ -31,7 +39,7 @@ class EventSyncMasterWorker @AssistedInject internal constructor( @Assisted params: WorkerParameters, private val downSyncWorkerBuilder: EventDownSyncWorkersBuilder, private val upSyncWorkerBuilder: EventUpSyncWorkersBuilder, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val eventSyncCache: EventSyncCache, private val eventRepository: EventRepository, private val eventSyncSubMasterWorkersBuilder: EventSyncSubMasterWorkersBuilder, @@ -67,7 +75,7 @@ class EventSyncMasterWorker @AssistedInject internal constructor( // check if device is rooted before starting the sync securityManager.checkIfDeviceIsRooted() crashlyticsLog("Start") - val configuration = configRepository.getProjectConfiguration() + val configuration = configManager.getProjectConfiguration() if (!configuration.canSyncDataToSimprints() && !isEventDownSyncAllowed(configuration)) return@withContext success( message = "Can't sync to SimprintsID, skip" @@ -140,7 +148,7 @@ class EventSyncMasterWorker @AssistedInject internal constructor( private suspend fun isEventDownSyncAllowed(configuration: ProjectConfiguration): Boolean { val isProjectPaused = - configRepository.getProject(configuration.projectId).state == ProjectState.PROJECT_PAUSED + configManager.getProject(configuration.projectId).state == ProjectState.PROJECT_PAUSED val isDownSyncConfigEnabled = configuration.synchronization.frequency != SynchronizationConfiguration.Frequency.ONLY_PERIODICALLY_UP_SYNC diff --git a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/up/tasks/EventUpSyncTask.kt b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/up/tasks/EventUpSyncTask.kt index 5d20ddf15a..9deaee8292 100644 --- a/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/up/tasks/EventUpSyncTask.kt +++ b/infra/event-sync/src/main/java/com/simprints/infra/eventsync/sync/up/tasks/EventUpSyncTask.kt @@ -7,11 +7,11 @@ import com.simprints.core.tools.time.TimeHelper import com.simprints.core.tools.time.Timestamp import com.simprints.infra.authstore.AuthStore import com.simprints.infra.authstore.exceptions.RemoteDbNotSignedInException -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.canSyncAllDataToSimprints import com.simprints.infra.config.store.models.canSyncAnalyticsDataToSimprints import com.simprints.infra.config.store.models.canSyncBiometricDataToSimprints +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.EventRepository import com.simprints.infra.events.event.domain.models.EnrolmentEventV2 import com.simprints.infra.events.event.domain.models.Event @@ -48,7 +48,7 @@ internal class EventUpSyncTask @Inject constructor( private val eventRepository: EventRepository, private val eventRemoteDataSource: EventRemoteDataSource, private val timeHelper: TimeHelper, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val jsonHelper: JsonHelper, ) { @@ -62,7 +62,7 @@ internal class EventUpSyncTask @Inject constructor( } } - val config = configRepository.getProjectConfiguration() + val config = configManager.getProjectConfiguration() var lastOperation = operation.copy() var count = 0 var isUsefulUpload = false diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/EventSyncManagerTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/EventSyncManagerTest.kt index cc2ee4c7f6..211702d668 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/EventSyncManagerTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/EventSyncManagerTest.kt @@ -17,11 +17,16 @@ import com.simprints.infra.eventsync.status.down.EventDownSyncScopeRepository import com.simprints.infra.eventsync.status.models.DownSyncCounts import com.simprints.infra.eventsync.status.up.EventUpSyncScopeRepository import com.simprints.infra.eventsync.sync.EventSyncStateProcessor -import com.simprints.infra.eventsync.sync.common.* +import com.simprints.infra.eventsync.sync.common.EventSyncCache import com.simprints.infra.eventsync.sync.down.tasks.EventDownSyncTask import com.simprints.testtools.common.coroutines.TestCoroutineRule -import io.mockk.* +import io.mockk.MockKAnnotations +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every import io.mockk.impl.annotations.MockK +import io.mockk.mockk +import io.mockk.verify import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.toList import kotlinx.coroutines.test.runTest 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 99ef048def..c3f4b956a2 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 @@ -6,8 +6,8 @@ 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 -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.tokenization.TokenizationProcessor +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.sampledata.SampleDefaults.DEFAULT_MODES import com.simprints.infra.events.sampledata.SampleDefaults.DEFAULT_MODULES import com.simprints.infra.events.sampledata.SampleDefaults.DEFAULT_MODULE_ID @@ -62,7 +62,7 @@ internal class EventDownSyncScopeRepositoryTest { lateinit var downSyncOperationOperationDao: DbEventDownSyncOperationStateDao @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager @MockK lateinit var tokenizationProcessor: TokenizationProcessor @@ -80,7 +80,7 @@ internal class EventDownSyncScopeRepositoryTest { authStore, recentUserActivityManager, downSyncOperationOperationDao, - configRepository, + configManager, tokenizationProcessor, ) diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/EventDownSyncWorkersBuilderTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/EventDownSyncWorkersBuilderTest.kt index fb4841d0d8..cd0929f3c8 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/EventDownSyncWorkersBuilderTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/EventDownSyncWorkersBuilderTest.kt @@ -8,10 +8,10 @@ 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 -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.DeviceConfiguration import com.simprints.infra.config.store.models.DownSynchronizationConfiguration import com.simprints.infra.config.store.models.GeneralConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.eventsync.SampleSyncScopes import com.simprints.infra.eventsync.status.down.EventDownSyncScopeRepository import com.simprints.infra.eventsync.status.down.domain.EventDownSyncScope @@ -47,7 +47,7 @@ class EventDownSyncWorkersBuilderTest { private lateinit var downSyncConfiguration: DownSynchronizationConfiguration @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var eventDownSyncScopeRepository: EventDownSyncScopeRepository @@ -58,12 +58,12 @@ class EventDownSyncWorkersBuilderTest { fun setUp() { MockKAnnotations.init(this, relaxed = true) - coEvery { configRepository.getDeviceConfiguration() } returns DeviceConfiguration( + coEvery { configManager.getDeviceConfiguration() } returns DeviceConfiguration( "", SELECTED_MODULE, "" ) - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProjectConfiguration() } returns mockk { every { general } returns generalConfiguration every { synchronization } returns mockk { every { down } returns downSyncConfiguration @@ -73,7 +73,7 @@ class EventDownSyncWorkersBuilderTest { eventDownSyncWorkersBuilder = EventDownSyncWorkersBuilder( eventDownSyncScopeRepository, JsonHelper, - configRepository + configManager ) } diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/EventDownSyncTaskTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/EventDownSyncTaskTest.kt index f6a77f7709..bb9eec9464 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/EventDownSyncTaskTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/down/tasks/EventDownSyncTaskTest.kt @@ -4,8 +4,8 @@ import com.google.common.truth.Truth.assertThat import com.simprints.core.domain.tokenization.asTokenizableRaw import com.simprints.core.tools.time.TimeHelper import com.simprints.infra.authstore.exceptions.RemoteDbNotSignedInException -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.DeviceConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.enrolment.records.store.domain.models.SubjectAction.Creation import com.simprints.infra.enrolment.records.store.domain.models.SubjectAction.Deletion @@ -93,7 +93,7 @@ class EventDownSyncTaskTest { private lateinit var timeHelper: TimeHelper @MockK - private lateinit var configManager: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var eventRemoteDataSource: EventRemoteDataSource diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/master/EventSyncMasterWorkerTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/master/EventSyncMasterWorkerTest.kt index fbe76c310b..4bca25aca6 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/master/EventSyncMasterWorkerTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/master/EventSyncMasterWorkerTest.kt @@ -10,7 +10,6 @@ import androidx.work.WorkManager import androidx.work.workDataOf import com.google.common.truth.Truth.assertThat import com.simprints.core.tools.time.TimeHelper -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.ProjectState import com.simprints.infra.config.store.models.SynchronizationConfiguration @@ -20,6 +19,7 @@ import com.simprints.infra.config.store.models.UpSynchronizationConfiguration import com.simprints.infra.config.store.models.UpSynchronizationConfiguration.SimprintsUpSynchronizationConfiguration import com.simprints.infra.config.store.models.UpSynchronizationConfiguration.UpSynchronizationKind.ALL import com.simprints.infra.config.store.models.UpSynchronizationConfiguration.UpSynchronizationKind.NONE +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.EventRepository import com.simprints.infra.events.event.domain.models.scope.EventScopeType import com.simprints.infra.eventsync.sync.common.EventSyncCache @@ -98,7 +98,7 @@ internal class EventSyncMasterWorkerTest { lateinit var projectConfiguration: ProjectConfiguration @MockK - lateinit var configRepository: ConfigRepository + lateinit var configManager: ConfigManager @MockK lateinit var timeHelper: TimeHelper @@ -132,7 +132,7 @@ internal class EventSyncMasterWorkerTest { every { synchronizationConfiguration.up.simprints } returns bfsidUpSynchronizationConfiguration every { projectConfiguration.projectId } returns "projectId" every { projectConfiguration.synchronization } returns synchronizationConfiguration - coEvery { configRepository.getProjectConfiguration() } returns projectConfiguration + coEvery { configManager.getProjectConfiguration() } returns projectConfiguration masterWorker = EventSyncMasterWorker( appContext = ctx, @@ -141,7 +141,7 @@ internal class EventSyncMasterWorkerTest { }, downSyncWorkerBuilder = downSyncWorkerBuilder, upSyncWorkerBuilder = upSyncWorkerBuilder, - configRepository = configRepository, + configManager = configManager, eventSyncCache = eventSyncCache, eventSyncSubMasterWorkersBuilder = eventSyncSubMasterWorkersBuilder, timeHelper = timeHelper, @@ -277,7 +277,7 @@ internal class EventSyncMasterWorkerTest { @Test fun `doWork should fail if there is an exception`() = runTest { - coEvery { configRepository.getProjectConfiguration() } throws Throwable() + coEvery { configManager.getProjectConfiguration() } throws Throwable() val result = masterWorker.doWork() assertThat(result).isEqualTo(ListenableWorker.Result.failure()) @@ -308,8 +308,8 @@ internal class EventSyncMasterWorkerTest { projectState: ProjectState, syncConfig: SynchronizationConfiguration.Frequency, ): ListenableWorker.Result { - coEvery { configRepository.getProject(any()).state } returns projectState - coEvery { configRepository.getProjectConfiguration() } returns mockk { + coEvery { configManager.getProject(any()).state } returns projectState + coEvery { configManager.getProjectConfiguration() } returns mockk { every { projectId } returns "projectId" every { synchronization } returns mockk { every { frequency } returns syncConfig diff --git a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/up/tasks/EventUpSyncTaskTest.kt b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/up/tasks/EventUpSyncTaskTest.kt index 849a211b8c..dda483eb95 100644 --- a/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/up/tasks/EventUpSyncTaskTest.kt +++ b/infra/event-sync/src/test/java/com/simprints/infra/eventsync/sync/up/tasks/EventUpSyncTaskTest.kt @@ -8,19 +8,26 @@ import com.simprints.core.tools.time.Timestamp import com.simprints.core.tools.utils.randomUUID import com.simprints.infra.authstore.AuthStore import com.simprints.infra.authstore.exceptions.RemoteDbNotSignedInException -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.ProjectConfiguration import com.simprints.infra.config.store.models.SynchronizationConfiguration import com.simprints.infra.config.store.models.UpSynchronizationConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.events.EventRepository import com.simprints.infra.events.event.domain.models.scope.EventScope import com.simprints.infra.events.event.domain.models.scope.EventScopeType import com.simprints.infra.events.event.domain.models.upsync.EventUpSyncRequestEvent -import com.simprints.infra.events.sampledata.* import com.simprints.infra.events.sampledata.SampleDefaults.DEFAULT_PROJECT_ID import com.simprints.infra.events.sampledata.SampleDefaults.GUID1 import com.simprints.infra.events.sampledata.SampleDefaults.GUID2 import com.simprints.infra.events.sampledata.SampleDefaults.GUID3 +import com.simprints.infra.events.sampledata.createAlertScreenEvent +import com.simprints.infra.events.sampledata.createAuthenticationEvent +import com.simprints.infra.events.sampledata.createEnrolmentEventV2 +import com.simprints.infra.events.sampledata.createEventWithSessionId +import com.simprints.infra.events.sampledata.createFaceCaptureBiometricsEvent +import com.simprints.infra.events.sampledata.createFingerprintCaptureBiometricsEvent +import com.simprints.infra.events.sampledata.createPersonCreationEvent +import com.simprints.infra.events.sampledata.createSessionScope import com.simprints.infra.eventsync.SampleSyncScopes import com.simprints.infra.eventsync.event.remote.EventRemoteDataSource import com.simprints.infra.eventsync.exceptions.TryToUploadEventsForNotSignedProject @@ -72,7 +79,7 @@ internal class EventUpSyncTaskTest { private lateinit var projectConfiguration: ProjectConfiguration @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var eventScope: EventScope @@ -88,7 +95,7 @@ internal class EventUpSyncTaskTest { 10, 10, 10 ) every { projectConfiguration.synchronization } returns synchronizationConfiguration - coEvery { configRepository.getProjectConfiguration() } returns projectConfiguration + coEvery { configManager.getProjectConfiguration() } returns projectConfiguration eventUpSyncTask = EventUpSyncTask( authStore = authStore, @@ -96,7 +103,7 @@ internal class EventUpSyncTaskTest { eventRepository = eventRepo, eventRemoteDataSource = eventRemoteDataSource, timeHelper = timeHelper, - configRepository = configRepository, + configManager = configManager, jsonHelper = JsonHelper, ) } diff --git a/infra/images/build.gradle.kts b/infra/images/build.gradle.kts index 96e1856e74..bf6740850b 100644 --- a/infra/images/build.gradle.kts +++ b/infra/images/build.gradle.kts @@ -12,6 +12,7 @@ android { dependencies { implementation(project(":infra:auth-store")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) // Firebase implementation(libs.firebase.storage) diff --git a/infra/images/src/main/java/com/simprints/infra/images/remote/ImageRemoteDataSourceImpl.kt b/infra/images/src/main/java/com/simprints/infra/images/remote/ImageRemoteDataSourceImpl.kt index 117e202478..499fe1969d 100644 --- a/infra/images/src/main/java/com/simprints/infra/images/remote/ImageRemoteDataSourceImpl.kt +++ b/infra/images/src/main/java/com/simprints/infra/images/remote/ImageRemoteDataSourceImpl.kt @@ -2,7 +2,7 @@ package com.simprints.infra.images.remote import com.google.firebase.storage.FirebaseStorage import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.images.model.SecuredImageRef import com.simprints.infra.logging.Simber import kotlinx.coroutines.tasks.await @@ -10,7 +10,7 @@ import java.io.FileInputStream import javax.inject.Inject internal class ImageRemoteDataSourceImpl @Inject constructor( - private val imageUrlProvider: ConfigRepository, + private val configManager: ConfigManager, private val authStore: AuthStore, ) : ImageRemoteDataSource { @@ -29,7 +29,7 @@ internal class ImageRemoteDataSourceImpl @Inject constructor( return UploadResult(imageRef, UploadResult.Status.FAILED) } - val bucketUrl = imageUrlProvider.getProject(projectId).imageBucket + val bucketUrl = configManager.getProject(projectId).imageBucket val rootRef = FirebaseStorage.getInstance( authStore.getLegacyAppFallback(), diff --git a/infra/images/src/test/java/com/simprints/infra/images/remote/ImageRemoteDataSourceImplTest.kt b/infra/images/src/test/java/com/simprints/infra/images/remote/ImageRemoteDataSourceImplTest.kt index 59b76fb2a9..2c6b626145 100644 --- a/infra/images/src/test/java/com/simprints/infra/images/remote/ImageRemoteDataSourceImplTest.kt +++ b/infra/images/src/test/java/com/simprints/infra/images/remote/ImageRemoteDataSourceImplTest.kt @@ -4,7 +4,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.common.truth.Truth.assertThat import com.google.firebase.storage.FirebaseStorage import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.images.model.SecuredImageRef import io.mockk.MockKAnnotations import io.mockk.coEvery @@ -26,7 +26,7 @@ import java.io.FileInputStream class ImageRemoteDataSourceImplTest { @MockK - private lateinit var configRepo: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var authStore: AuthStore @@ -45,7 +45,7 @@ class ImageRemoteDataSourceImplTest { every { mockSecuredImageRef.relativePath.parts } returns arrayOf("Test1") - remoteDataSource = ImageRemoteDataSourceImpl(configRepo, authStore) + remoteDataSource = ImageRemoteDataSourceImpl(configManager, authStore) // We need to mock statics and global extensions mockkStatic(FirebaseStorage::class) @@ -61,7 +61,7 @@ class ImageRemoteDataSourceImplTest { @Test fun `test image upload flow`() = runTest { - coEvery { configRepo.getProject(any()).imageBucket } returns "gs://`simprints-dev.appspot.com" + coEvery { configManager.getProject(any()).imageBucket } returns "gs://`simprints-dev.appspot.com" every { authStore.getLegacyAppFallback().options.projectId } returns "projectId" every { authStore.signedInProjectId } returns "projectId" @@ -85,7 +85,7 @@ class ImageRemoteDataSourceImplTest { @Test fun `null storage bucket returns failed upload`() = runTest { - coEvery { configRepo.getProject(any()).imageBucket } returns "" + coEvery { configManager.getProject(any()).imageBucket } returns "" every { authStore.getLegacyAppFallback().options.projectId } returns "projectId" val result = remoteDataSource.uploadImage(mockImageStream, mockSecuredImageRef) diff --git a/infra/sync/build.gradle.kts b/infra/sync/build.gradle.kts index 720b10563c..f64040d35c 100644 --- a/infra/sync/build.gradle.kts +++ b/infra/sync/build.gradle.kts @@ -35,6 +35,7 @@ dependencies { implementation(project(":infra:auth-store")) implementation(project(":infra:auth-logic")) implementation(project(":infra:config-store")) + implementation(project(":infra:config-sync")) implementation(project(":infra:enrolment-records-store")) implementation(project(":infra:events")) implementation(project(":infra:event-sync")) diff --git a/infra/sync/src/main/java/com/simprints/infra/sync/SyncOrchestratorImpl.kt b/infra/sync/src/main/java/com/simprints/infra/sync/SyncOrchestratorImpl.kt index 15096edc94..16ca187a60 100644 --- a/infra/sync/src/main/java/com/simprints/infra/sync/SyncOrchestratorImpl.kt +++ b/infra/sync/src/main/java/com/simprints/infra/sync/SyncOrchestratorImpl.kt @@ -8,8 +8,8 @@ import androidx.work.WorkQuery import androidx.work.workDataOf import com.simprints.core.AppScope import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.imagesUploadRequiresUnmeteredConnection +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.eventsync.EventSyncManager import com.simprints.infra.eventsync.sync.master.EventSyncMasterWorker import com.simprints.infra.sync.config.worker.DeviceConfigDownSyncWorker @@ -32,7 +32,7 @@ import javax.inject.Singleton internal class SyncOrchestratorImpl @Inject constructor( private val workManager: WorkManager, private val authStore: AuthStore, - private val configRepo: ConfigRepository, + private val configManager: ConfigManager, private val eventSyncManager: EventSyncManager, private val shouldScheduleFirmwareUpdate: ShouldScheduleFirmwareUpdateUseCase, private val cleanupDeprecatedWorkers: CleanupDeprecatedWorkersUseCase, @@ -152,7 +152,7 @@ internal class SyncOrchestratorImpl @Inject constructor( private suspend fun getImageUploadConstraints(): Constraints { - val networkType = configRepo + val networkType = configManager .getProjectConfiguration() .imagesUploadRequiresUnmeteredConnection() .let { if (it) NetworkType.UNMETERED else NetworkType.CONNECTED } diff --git a/infra/sync/src/main/java/com/simprints/infra/sync/config/worker/DeviceConfigDownSyncWorker.kt b/infra/sync/src/main/java/com/simprints/infra/sync/config/worker/DeviceConfigDownSyncWorker.kt index d2f46734a8..06d6457896 100644 --- a/infra/sync/src/main/java/com/simprints/infra/sync/config/worker/DeviceConfigDownSyncWorker.kt +++ b/infra/sync/src/main/java/com/simprints/infra/sync/config/worker/DeviceConfigDownSyncWorker.kt @@ -5,7 +5,7 @@ import androidx.hilt.work.HiltWorker import androidx.work.WorkerParameters import com.simprints.core.DispatcherBG import com.simprints.core.workers.SimCoroutineWorker -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.sync.SyncOrchestrator import com.simprints.infra.sync.config.usecase.LogoutUseCase import dagger.assisted.Assisted @@ -17,7 +17,7 @@ import kotlinx.coroutines.withContext internal class DeviceConfigDownSyncWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val logoutUseCase: LogoutUseCase, private val syncOrchestrator: SyncOrchestrator, @DispatcherBG private val dispatcher: CoroutineDispatcher, @@ -31,7 +31,7 @@ internal class DeviceConfigDownSyncWorker @AssistedInject constructor( crashlyticsLog("Fetching device config state") try { - val state = configRepository.getDeviceState() + val state = configManager.getDeviceState() if (state.isCompromised) { logoutUseCase() diff --git a/infra/sync/src/main/java/com/simprints/infra/sync/config/worker/ProjectConfigDownSyncWorker.kt b/infra/sync/src/main/java/com/simprints/infra/sync/config/worker/ProjectConfigDownSyncWorker.kt index 2067da8957..3dccc49354 100644 --- a/infra/sync/src/main/java/com/simprints/infra/sync/config/worker/ProjectConfigDownSyncWorker.kt +++ b/infra/sync/src/main/java/com/simprints/infra/sync/config/worker/ProjectConfigDownSyncWorker.kt @@ -6,21 +6,20 @@ import androidx.work.WorkerParameters import com.simprints.core.DispatcherBG import com.simprints.core.workers.SimCoroutineWorker import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.sync.config.usecase.HandleProjectStateUseCase import com.simprints.infra.sync.config.usecase.RescheduleWorkersIfConfigChangedUseCase import dagger.assisted.Assisted import dagger.assisted.AssistedInject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.withContext -import java.lang.IllegalStateException @HiltWorker internal class ProjectConfigDownSyncWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, private val authStore: AuthStore, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, private val handleProjectState: HandleProjectStateUseCase, private val rescheduleWorkersIfConfigChanged: RescheduleWorkersIfConfigChangedUseCase, @DispatcherBG private val dispatcher: CoroutineDispatcher, @@ -33,13 +32,13 @@ internal class ProjectConfigDownSyncWorker @AssistedInject constructor( try { val projectId = authStore.signedInProjectId - val oldConfig = configRepository.getProjectConfiguration() + val oldConfig = configManager.getProjectConfiguration() // if the user is not signed in, we shouldn't try again if (projectId.isEmpty()) { fail(IllegalStateException("User is not signed in")) } else { - val (project, config) = configRepository.refreshProject(projectId) + val (project, config) = configManager.refreshProject(projectId) handleProjectState(project.state) rescheduleWorkersIfConfigChanged(oldConfig, config) diff --git a/infra/sync/src/main/java/com/simprints/infra/sync/enrolments/EnrolmentRecordWorker.kt b/infra/sync/src/main/java/com/simprints/infra/sync/enrolments/EnrolmentRecordWorker.kt index f4ea063b63..403a6f17fd 100644 --- a/infra/sync/src/main/java/com/simprints/infra/sync/enrolments/EnrolmentRecordWorker.kt +++ b/infra/sync/src/main/java/com/simprints/infra/sync/enrolments/EnrolmentRecordWorker.kt @@ -2,11 +2,10 @@ package com.simprints.infra.sync.enrolments import android.content.Context import androidx.hilt.work.HiltWorker -import androidx.work.CoroutineWorker import androidx.work.WorkerParameters import com.simprints.core.DispatcherIO import com.simprints.core.workers.SimCoroutineWorker -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.sync.SyncConstants import dagger.assisted.Assisted @@ -19,7 +18,7 @@ class EnrolmentRecordWorker @AssistedInject constructor( @Assisted context: Context, @Assisted params: WorkerParameters, private val enrolmentRecordRepository: EnrolmentRecordRepository, - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, @DispatcherIO private val dispatcher: CoroutineDispatcher, ) : SimCoroutineWorker(context, params) { @@ -37,7 +36,7 @@ class EnrolmentRecordWorker @AssistedInject constructor( enrolmentRecordRepository.uploadRecords(subjectIds.toList()) - configRepository.updateDeviceConfiguration { + configManager.updateDeviceConfiguration { it.apply { it.lastInstructionId = instructionId } } diff --git a/infra/sync/src/main/java/com/simprints/infra/sync/firmware/ShouldScheduleFirmwareUpdateUseCase.kt b/infra/sync/src/main/java/com/simprints/infra/sync/firmware/ShouldScheduleFirmwareUpdateUseCase.kt index f3f527c605..4759db501e 100644 --- a/infra/sync/src/main/java/com/simprints/infra/sync/firmware/ShouldScheduleFirmwareUpdateUseCase.kt +++ b/infra/sync/src/main/java/com/simprints/infra/sync/firmware/ShouldScheduleFirmwareUpdateUseCase.kt @@ -1,14 +1,14 @@ package com.simprints.infra.sync.firmware -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.infra.config.sync.ConfigManager import javax.inject.Inject class ShouldScheduleFirmwareUpdateUseCase @Inject constructor( - private val configRepository: ConfigRepository, + private val configManager: ConfigManager, ) { - suspend operator fun invoke(): Boolean = configRepository + suspend operator fun invoke(): Boolean = configManager .getProjectConfiguration() .fingerprint ?.allowedScanners diff --git a/infra/sync/src/test/java/com/simprints/infra/sync/SyncOrchestratorImplTest.kt b/infra/sync/src/test/java/com/simprints/infra/sync/SyncOrchestratorImplTest.kt index a1c5ad4f45..22a5231d7f 100644 --- a/infra/sync/src/test/java/com/simprints/infra/sync/SyncOrchestratorImplTest.kt +++ b/infra/sync/src/test/java/com/simprints/infra/sync/SyncOrchestratorImplTest.kt @@ -7,7 +7,7 @@ import androidx.work.WorkInfo import androidx.work.WorkManager import com.google.common.util.concurrent.ListenableFuture import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.eventsync.EventSyncManager import com.simprints.infra.sync.SyncConstants.DEVICE_SYNC_WORK_NAME import com.simprints.infra.sync.SyncConstants.DEVICE_SYNC_WORK_NAME_ONE_TIME @@ -48,7 +48,7 @@ class SyncOrchestratorImplTest { private lateinit var authStore: AuthStore @MockK - private lateinit var configRepo: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var eventSyncManager: EventSyncManager @@ -99,7 +99,7 @@ class SyncOrchestratorImplTest { @Test fun `schedules images with any connection if not specified`() = runTest { coEvery { - configRepo.getProjectConfiguration().synchronization.up.simprints.imagesRequireUnmeteredConnection + configManager.getProjectConfiguration().synchronization.up.simprints.imagesRequireUnmeteredConnection } returns false every { authStore.signedInProjectId } returns "projectId" @@ -117,7 +117,7 @@ class SyncOrchestratorImplTest { @Test fun `schedules images with unmetered constraint if requested`() = runTest { coEvery { - configRepo.getProjectConfiguration().synchronization.up.simprints.imagesRequireUnmeteredConnection + configManager.getProjectConfiguration().synchronization.up.simprints.imagesRequireUnmeteredConnection } returns true every { authStore.signedInProjectId } returns "projectId" coEvery { shouldScheduleFirmwareUpdate.invoke() } returns false @@ -316,7 +316,7 @@ class SyncOrchestratorImplTest { private fun createSyncOrchestrator() = SyncOrchestratorImpl( workManager, authStore, - configRepo, + configManager, eventSyncManager, shouldScheduleFirmwareUpdate, cleanupDeprecatedWorkers, diff --git a/infra/sync/src/test/java/com/simprints/infra/sync/config/worker/DeviceConfigDownSyncWorkerTest.kt b/infra/sync/src/test/java/com/simprints/infra/sync/config/worker/DeviceConfigDownSyncWorkerTest.kt index 5a0f0edd1e..96e49e89dc 100644 --- a/infra/sync/src/test/java/com/simprints/infra/sync/config/worker/DeviceConfigDownSyncWorkerTest.kt +++ b/infra/sync/src/test/java/com/simprints/infra/sync/config/worker/DeviceConfigDownSyncWorkerTest.kt @@ -2,11 +2,11 @@ package com.simprints.infra.sync.config.worker import androidx.work.ListenableWorker import com.google.common.truth.Truth.assertThat -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.DeviceState import com.simprints.infra.config.store.models.UpSyncEnrolmentRecords -import com.simprints.infra.sync.config.usecase.LogoutUseCase +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.sync.SyncOrchestrator +import com.simprints.infra.sync.config.usecase.LogoutUseCase import com.simprints.testtools.common.coroutines.TestCoroutineRule import io.mockk.MockKAnnotations import io.mockk.coEvery @@ -22,7 +22,7 @@ import org.junit.Test class DeviceConfigDownSyncWorkerTest { @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var logoutUseCase: LogoutUseCase @@ -42,7 +42,7 @@ class DeviceConfigDownSyncWorkerTest { deviceConfigWorker = DeviceConfigDownSyncWorker( context = mockk(), params = mockk(relaxed = true), - configRepository = configRepository, + configManager = configManager, logoutUseCase = logoutUseCase, syncOrchestrator = syncOrchestrator, dispatcher = testCoroutineRule.testCoroutineDispatcher, @@ -51,7 +51,7 @@ class DeviceConfigDownSyncWorkerTest { @Test fun `Should succeed if not compromised`() = runTest { - coEvery { configRepository.getDeviceState() } returns DeviceState( + coEvery { configManager.getDeviceState() } returns DeviceState( "deviceId", false, ) @@ -65,7 +65,7 @@ class DeviceConfigDownSyncWorkerTest { @Test fun `Should log out if compromised`() = runTest { - coEvery { configRepository.getDeviceState() } returns DeviceState( + coEvery { configManager.getDeviceState() } returns DeviceState( "deviceId", true, UpSyncEnrolmentRecords("id", listOf("subjectId")) @@ -80,7 +80,7 @@ class DeviceConfigDownSyncWorkerTest { @Test fun `Should schedule record upload if not compromised`() = runTest { - coEvery { configRepository.getDeviceState() } returns DeviceState( + coEvery { configManager.getDeviceState() } returns DeviceState( "deviceId", false, UpSyncEnrolmentRecords("id", listOf("subjectId")) diff --git a/infra/sync/src/test/java/com/simprints/infra/sync/config/worker/ProjectConfigDownSyncWorkerTest.kt b/infra/sync/src/test/java/com/simprints/infra/sync/config/worker/ProjectConfigDownSyncWorkerTest.kt index 74e1b2381e..ab74cc00fa 100644 --- a/infra/sync/src/test/java/com/simprints/infra/sync/config/worker/ProjectConfigDownSyncWorkerTest.kt +++ b/infra/sync/src/test/java/com/simprints/infra/sync/config/worker/ProjectConfigDownSyncWorkerTest.kt @@ -3,8 +3,8 @@ package com.simprints.infra.sync.config.worker import androidx.work.ListenableWorker import com.google.common.truth.Truth.assertThat import com.simprints.infra.authstore.AuthStore -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.ProjectWithConfig +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.sync.config.testtools.project import com.simprints.infra.sync.config.testtools.projectConfiguration import com.simprints.infra.sync.config.usecase.HandleProjectStateUseCase @@ -30,7 +30,7 @@ class ProjectConfigDownSyncWorkerTest { private lateinit var authStore: AuthStore @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager @MockK private lateinit var handleProjectStateUseCase: HandleProjectStateUseCase @@ -48,7 +48,7 @@ class ProjectConfigDownSyncWorkerTest { context = mockk(), params = mockk(relaxed = true), authStore = authStore, - configRepository = configRepository, + configManager = configManager, handleProjectState = handleProjectStateUseCase, rescheduleWorkersIfConfigChanged = rescheduleWorkersIfConfigChangedUseCase, dispatcher = testCoroutineRule.testCoroutineDispatcher, @@ -66,7 +66,7 @@ class ProjectConfigDownSyncWorkerTest { @Test fun `should fail if the config service throws an exception`() = runTest { every { authStore.signedInProjectId } returns PROJECT_ID - coEvery { configRepository.refreshProject(PROJECT_ID) } throws Exception() + coEvery { configManager.refreshProject(PROJECT_ID) } throws Exception() val result = projectConfigDownSyncWorker.doWork() assertThat(result).isEqualTo(ListenableWorker.Result.failure()) @@ -75,7 +75,7 @@ class ProjectConfigDownSyncWorkerTest { @Test fun `should succeed if the config service doesn't throw an exception`() = runTest { every { authStore.signedInProjectId } returns PROJECT_ID - coEvery { configRepository.refreshProject(PROJECT_ID) } returns ProjectWithConfig( + coEvery { configManager.refreshProject(PROJECT_ID) } returns ProjectWithConfig( project, projectConfiguration ) diff --git a/infra/sync/src/test/java/com/simprints/infra/sync/enrolments/EnrolmentRecordWorkerTest.kt b/infra/sync/src/test/java/com/simprints/infra/sync/enrolments/EnrolmentRecordWorkerTest.kt index 98e8159b08..5f5ef47fee 100644 --- a/infra/sync/src/test/java/com/simprints/infra/sync/enrolments/EnrolmentRecordWorkerTest.kt +++ b/infra/sync/src/test/java/com/simprints/infra/sync/enrolments/EnrolmentRecordWorkerTest.kt @@ -3,8 +3,8 @@ package com.simprints.infra.sync.enrolments import androidx.work.WorkerParameters import androidx.work.workDataOf import com.google.common.truth.Truth.assertThat -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.DeviceConfiguration +import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.enrolment.records.store.EnrolmentRecordRepository import com.simprints.infra.sync.SyncConstants import io.mockk.coEvery @@ -24,7 +24,7 @@ class EnrolmentRecordWorkerTest { } private val repository = mockk(relaxed = true) - private val configRepository = mockk() + private val configManager = mockk() private val params = mockk(relaxed = true) { every { inputData } returns workDataOf( SyncConstants.RECORD_UPLOAD_INPUT_ID_NAME to INSTRUCTION_ID, @@ -35,7 +35,7 @@ class EnrolmentRecordWorkerTest { mockk(relaxed = true), params, repository, - configRepository, + configManager, UnconfinedTestDispatcher(), ) @@ -43,7 +43,7 @@ class EnrolmentRecordWorkerTest { @Test fun `should do work correctly`() = runTest { val updateConfigFn = slot DeviceConfiguration>() - coEvery { configRepository.updateDeviceConfiguration(capture(updateConfigFn)) } returns Unit + coEvery { configManager.updateDeviceConfiguration(capture(updateConfigFn)) } returns Unit worker.doWork() diff --git a/infra/sync/src/test/java/com/simprints/infra/sync/firmware/ShouldScheduleFirmwareUpdateUseCaseTest.kt b/infra/sync/src/test/java/com/simprints/infra/sync/firmware/ShouldScheduleFirmwareUpdateUseCaseTest.kt index 83c1aec91e..0ac87b29c5 100644 --- a/infra/sync/src/test/java/com/simprints/infra/sync/firmware/ShouldScheduleFirmwareUpdateUseCaseTest.kt +++ b/infra/sync/src/test/java/com/simprints/infra/sync/firmware/ShouldScheduleFirmwareUpdateUseCaseTest.kt @@ -1,8 +1,8 @@ package com.simprints.infra.sync.firmware import com.google.common.truth.Truth.assertThat -import com.simprints.infra.config.store.ConfigRepository import com.simprints.infra.config.store.models.FingerprintConfiguration +import com.simprints.infra.config.sync.ConfigManager import io.mockk.MockKAnnotations import io.mockk.coEvery import io.mockk.impl.annotations.MockK @@ -13,20 +13,20 @@ import org.junit.Test class ShouldScheduleFirmwareUpdateUseCaseTest { @MockK - private lateinit var configRepository: ConfigRepository + private lateinit var configManager: ConfigManager private lateinit var useCase: ShouldScheduleFirmwareUpdateUseCase @Before fun setup() { MockKAnnotations.init(this, relaxed = true) - useCase = ShouldScheduleFirmwareUpdateUseCase(configRepository) + useCase = ShouldScheduleFirmwareUpdateUseCase(configManager) } @Test fun `should return true if Vero 2 is allowed`() = runTest { coEvery { - configRepository.getProjectConfiguration().fingerprint?.allowedScanners + configManager.getProjectConfiguration().fingerprint?.allowedScanners } returns listOf(FingerprintConfiguration.VeroGeneration.VERO_2) assertThat(useCase()).isTrue() @@ -35,7 +35,7 @@ class ShouldScheduleFirmwareUpdateUseCaseTest { @Test fun `should return false if only Vero 1 is allowed`() = runTest { coEvery { - configRepository.getProjectConfiguration().fingerprint?.allowedScanners + configManager.getProjectConfiguration().fingerprint?.allowedScanners } returns listOf(FingerprintConfiguration.VeroGeneration.VERO_1) assertThat(useCase()).isFalse() @@ -43,7 +43,7 @@ class ShouldScheduleFirmwareUpdateUseCaseTest { @Test fun `should return false if no fingerprint config`() = runTest { - coEvery { configRepository.getProjectConfiguration().fingerprint } returns null + coEvery { configManager.getProjectConfiguration().fingerprint } returns null assertThat(useCase()).isFalse() } diff --git a/settings.gradle.kts b/settings.gradle.kts index f28d94a576..19ffd7b56b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -118,6 +118,7 @@ include( ":infra:test-tools", ":infra:events", ":infra:config-store", + ":infra:config-sync", ":infra:enrolment-records-store", ":infra:images", ":infra:license",