From 646888da0440d29fea55278cf3c4d29de1618aa5 Mon Sep 17 00:00:00 2001 From: Sergejs Luhmirins Date: Tue, 10 Jun 2025 17:41:21 +0300 Subject: [PATCH] MS-997 Reset local records when sync partitioning changes --- ...ResetLocalRecordsIfConfigChangedUseCase.kt | 30 ++++++ .../worker/ProjectConfigDownSyncWorker.kt | 4 +- ...tLocalRecordsIfConfigChangedUseCaseTest.kt | 91 +++++++++++++++++++ .../worker/ProjectConfigDownSyncWorkerTest.kt | 6 ++ 4 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 infra/sync/src/main/java/com/simprints/infra/sync/config/usecase/ResetLocalRecordsIfConfigChangedUseCase.kt create mode 100644 infra/sync/src/test/java/com/simprints/infra/sync/config/usecase/ResetLocalRecordsIfConfigChangedUseCaseTest.kt diff --git a/infra/sync/src/main/java/com/simprints/infra/sync/config/usecase/ResetLocalRecordsIfConfigChangedUseCase.kt b/infra/sync/src/main/java/com/simprints/infra/sync/config/usecase/ResetLocalRecordsIfConfigChangedUseCase.kt new file mode 100644 index 0000000000..5931e471ad --- /dev/null +++ b/infra/sync/src/main/java/com/simprints/infra/sync/config/usecase/ResetLocalRecordsIfConfigChangedUseCase.kt @@ -0,0 +1,30 @@ +package com.simprints.infra.sync.config.usecase + +import com.simprints.infra.config.store.models.ProjectConfiguration +import com.simprints.infra.enrolment.records.repository.EnrolmentRecordRepository +import com.simprints.infra.eventsync.EventSyncManager +import com.simprints.infra.sync.SyncOrchestrator +import javax.inject.Inject + +internal class ResetLocalRecordsIfConfigChangedUseCase @Inject constructor( + private val syncOrchestrator: SyncOrchestrator, + private val eventSyncManager: EventSyncManager, + private val enrolmentRecordRepository: EnrolmentRecordRepository, +) { + suspend operator fun invoke( + oldConfig: ProjectConfiguration, + newConfig: ProjectConfiguration, + ) { + if (hasPartitionTypeChanged(oldConfig, newConfig)) { + syncOrchestrator.cancelEventSync() + eventSyncManager.resetDownSyncInfo() + enrolmentRecordRepository.deleteAll() + syncOrchestrator.rescheduleEventSync() + } + } + + private fun hasPartitionTypeChanged( + oldConfig: ProjectConfiguration, + newConfig: ProjectConfiguration, + ) = oldConfig.synchronization.down.partitionType != newConfig.synchronization.down.partitionType +} 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 8ed55f099e..39796fe98d 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 @@ -9,6 +9,7 @@ import com.simprints.infra.authstore.AuthStore import com.simprints.infra.config.sync.ConfigManager import com.simprints.infra.sync.config.usecase.HandleProjectStateUseCase import com.simprints.infra.sync.config.usecase.RescheduleWorkersIfConfigChangedUseCase +import com.simprints.infra.sync.config.usecase.ResetLocalRecordsIfConfigChangedUseCase import dagger.assisted.Assisted import dagger.assisted.AssistedInject import kotlinx.coroutines.CoroutineDispatcher @@ -22,6 +23,7 @@ internal class ProjectConfigDownSyncWorker @AssistedInject constructor( private val configManager: ConfigManager, private val handleProjectState: HandleProjectStateUseCase, private val rescheduleWorkersIfConfigChanged: RescheduleWorkersIfConfigChangedUseCase, + private val resetLocalRecordsIfConfigChanged: ResetLocalRecordsIfConfigChangedUseCase, @DispatcherBG private val dispatcher: CoroutineDispatcher, ) : SimCoroutineWorker(context, params) { override val tag = "ProjectConfigDownSync" @@ -40,7 +42,7 @@ internal class ProjectConfigDownSyncWorker @AssistedInject constructor( val (project, config) = configManager.refreshProject(projectId) handleProjectState(project.state) rescheduleWorkersIfConfigChanged(oldConfig, config) - + resetLocalRecordsIfConfigChanged(oldConfig, config) success() } } catch (t: Throwable) { diff --git a/infra/sync/src/test/java/com/simprints/infra/sync/config/usecase/ResetLocalRecordsIfConfigChangedUseCaseTest.kt b/infra/sync/src/test/java/com/simprints/infra/sync/config/usecase/ResetLocalRecordsIfConfigChangedUseCaseTest.kt new file mode 100644 index 0000000000..4c84ddcf7f --- /dev/null +++ b/infra/sync/src/test/java/com/simprints/infra/sync/config/usecase/ResetLocalRecordsIfConfigChangedUseCaseTest.kt @@ -0,0 +1,91 @@ +package com.simprints.infra.sync.config.usecase + +import com.simprints.infra.config.store.models.DownSynchronizationConfiguration +import com.simprints.infra.enrolment.records.repository.EnrolmentRecordRepository +import com.simprints.infra.eventsync.EventSyncManager +import com.simprints.infra.sync.SyncOrchestrator +import com.simprints.infra.sync.config.testtools.projectConfiguration +import com.simprints.infra.sync.config.testtools.synchronizationConfiguration +import io.mockk.* +import io.mockk.impl.annotations.MockK +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test + +class ResetLocalRecordsIfConfigChangedUseCaseTest { + @MockK + private lateinit var syncOrchestrator: SyncOrchestrator + + @MockK + private lateinit var eventSyncManager: EventSyncManager + + @MockK + private lateinit var enrolmentRecordRepository: EnrolmentRecordRepository + + private lateinit var useCase: ResetLocalRecordsIfConfigChangedUseCase + + @Before + fun setUp() { + MockKAnnotations.init(this, relaxed = true) + + useCase = ResetLocalRecordsIfConfigChangedUseCase( + syncOrchestrator = syncOrchestrator, + eventSyncManager = eventSyncManager, + enrolmentRecordRepository = enrolmentRecordRepository, + ) + } + + @Test + fun `should not reset local records when partition type not changes`() = runTest { + useCase( + projectConfiguration.copy( + synchronization = synchronizationConfiguration.copy( + down = synchronizationConfiguration.down.copy( + partitionType = DownSynchronizationConfiguration.PartitionType.MODULE, + ), + ), + ), + projectConfiguration.copy( + synchronization = synchronizationConfiguration.copy( + down = synchronizationConfiguration.down.copy( + partitionType = DownSynchronizationConfiguration.PartitionType.MODULE, + ), + ), + ), + ) + + coVerify(exactly = 0) { + syncOrchestrator.cancelEventSync() + syncOrchestrator.rescheduleEventSync() + eventSyncManager.resetDownSyncInfo() + enrolmentRecordRepository.deleteAll() + } + } + + @Test + fun `should reset local records when partition type not changes`() = runTest { + useCase( + projectConfiguration.copy( + synchronization = synchronizationConfiguration.copy( + down = synchronizationConfiguration.down.copy( + partitionType = DownSynchronizationConfiguration.PartitionType.PROJECT, + ), + ), + ), + projectConfiguration.copy( + synchronization = synchronizationConfiguration.copy( + down = synchronizationConfiguration.down.copy( + partitionType = DownSynchronizationConfiguration.PartitionType.MODULE, + ), + ), + ), + ) + + coVerify { + syncOrchestrator.cancelEventSync() + syncOrchestrator.rescheduleEventSync() + eventSyncManager.resetDownSyncInfo() + enrolmentRecordRepository.deleteAll() + } + } +} 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 c4250f63b3..5f6b048477 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 @@ -9,6 +9,7 @@ import com.simprints.infra.sync.config.testtools.project import com.simprints.infra.sync.config.testtools.projectConfiguration import com.simprints.infra.sync.config.usecase.HandleProjectStateUseCase import com.simprints.infra.sync.config.usecase.RescheduleWorkersIfConfigChangedUseCase +import com.simprints.infra.sync.config.usecase.ResetLocalRecordsIfConfigChangedUseCase import com.simprints.testtools.common.coroutines.TestCoroutineRule import io.mockk.MockKAnnotations import io.mockk.coEvery @@ -37,6 +38,9 @@ class ProjectConfigDownSyncWorkerTest { @MockK private lateinit var rescheduleWorkersIfConfigChangedUseCase: RescheduleWorkersIfConfigChangedUseCase + @MockK + private lateinit var resetLocalRecordsIfConfigChangedUseCase: ResetLocalRecordsIfConfigChangedUseCase + private lateinit var projectConfigDownSyncWorker: ProjectConfigDownSyncWorker @Before @@ -50,6 +54,7 @@ class ProjectConfigDownSyncWorkerTest { configManager = configManager, handleProjectState = handleProjectStateUseCase, rescheduleWorkersIfConfigChanged = rescheduleWorkersIfConfigChangedUseCase, + resetLocalRecordsIfConfigChanged = resetLocalRecordsIfConfigChangedUseCase, dispatcher = testCoroutineRule.testCoroutineDispatcher, ) } @@ -85,6 +90,7 @@ class ProjectConfigDownSyncWorkerTest { coVerify { handleProjectStateUseCase.invoke(any()) rescheduleWorkersIfConfigChangedUseCase.invoke(any(), any()) + resetLocalRecordsIfConfigChangedUseCase.invoke(any(), any()) } }