From fc3f0b8a560caecc01508cff4a9eaa1623a84cf3 Mon Sep 17 00:00:00 2001 From: marsof02 <66377681+marsof02@users.noreply.github.com> Date: Mon, 22 Jun 2026 20:28:07 -0400 Subject: [PATCH] refactor: migrate location and sync/dashboard to entity DAOs (#1235) --- .../TreeTracker/background/TreeSyncWorker.kt | 6 +-- .../dashboard/DashboardViewModel.kt | 12 +++--- .../android/TreeTracker/di/AppModule.kt | 2 +- .../models/location/LocationDataCapturer.kt | 6 +-- .../TreeTracker/usecases/SyncDataUseCase.kt | 8 ++-- .../usecases/UploadLocationDataUseCase.kt | 14 ++++--- .../dashboard/DashboardViewModelTest.kt | 34 ++++++++--------- .../location/LocationDataCapturerTest.kt | 8 ++-- .../usecases/SyncDataUseCaseTest.kt | 38 +++++++++---------- 9 files changed, 65 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/org/greenstand/android/TreeTracker/background/TreeSyncWorker.kt b/app/src/main/java/org/greenstand/android/TreeTracker/background/TreeSyncWorker.kt index 2e9aeae4b..8ef5d547f 100644 --- a/app/src/main/java/org/greenstand/android/TreeTracker/background/TreeSyncWorker.kt +++ b/app/src/main/java/org/greenstand/android/TreeTracker/background/TreeSyncWorker.kt @@ -35,7 +35,7 @@ import org.greenstand.android.TreeTracker.R import org.greenstand.android.TreeTracker.activities.TreeTrackerActivity import org.greenstand.android.TreeTracker.analytics.ExceptionDataCollector import org.greenstand.android.TreeTracker.dashboard.TreesToSyncHelper -import org.greenstand.android.TreeTracker.database.TreeTrackerDAO +import org.greenstand.android.TreeTracker.database.dao.TreeDAO import org.greenstand.android.TreeTracker.usecases.SyncDataUseCase import org.koin.core.component.KoinComponent import org.koin.core.component.inject @@ -48,7 +48,7 @@ class TreeSyncWorker( private val exceptionDataCollector: ExceptionDataCollector by inject() private val syncDataBundleUseCase: SyncDataUseCase by inject() private val syncNotificationManager: SyncNotificationManager by inject() - private val dao: TreeTrackerDAO by inject() + private val treeDao: TreeDAO by inject() private val treesToSyncHelper: TreesToSyncHelper by inject() override suspend fun doWork(): Result { @@ -63,7 +63,7 @@ class TreeSyncWorker( delay(750) val remaining = withContext(Dispatchers.IO) { - dao.getNonUploadedLegacyTreeCaptureImageCount() + dao.getNonUploadedTreeImageCount() + treeDao.getNonUploadedLegacyTreeCaptureImageCount() + treeDao.getNonUploadedTreeImageCount() } val uploaded = (totalTreesToSync - remaining).coerceAtLeast(0) val contentText = applicationContext.getString(R.string.uploading_trees) + " ($uploaded/$totalTreesToSync)" diff --git a/app/src/main/java/org/greenstand/android/TreeTracker/dashboard/DashboardViewModel.kt b/app/src/main/java/org/greenstand/android/TreeTracker/dashboard/DashboardViewModel.kt index 30d6555fe..cbacd91e6 100644 --- a/app/src/main/java/org/greenstand/android/TreeTracker/dashboard/DashboardViewModel.kt +++ b/app/src/main/java/org/greenstand/android/TreeTracker/dashboard/DashboardViewModel.kt @@ -33,7 +33,7 @@ import org.greenstand.android.TreeTracker.R import org.greenstand.android.TreeTracker.analytics.Analytics import org.greenstand.android.TreeTracker.background.NotificationConstants import org.greenstand.android.TreeTracker.background.TreeSyncWorker -import org.greenstand.android.TreeTracker.database.TreeTrackerDAO +import org.greenstand.android.TreeTracker.database.dao.TreeDAO import org.greenstand.android.TreeTracker.models.FeatureFlags import org.greenstand.android.TreeTracker.models.location.LocationDataCapturer import org.greenstand.android.TreeTracker.models.messages.MessagesRepo @@ -74,7 +74,7 @@ sealed class DashboardAction : Action { } class DashboardViewModel( - private val dao: TreeTrackerDAO, + private val treeDao: TreeDAO, private val workManager: WorkManager, private val analytics: Analytics, @Suppress("unused") private val treesToSyncHelper: TreesToSyncHelper, @@ -179,10 +179,10 @@ class DashboardViewModel( private fun observeTreeCounts() { viewModelScope.launch { combine( - dao.getUploadedLegacyTreeImageCountFlow(), - dao.getUploadedTreeImageCountFlow(), - dao.getNonUploadedLegacyTreeCaptureImageCountFlow(), - dao.getNonUploadedTreeImageCountFlow(), + treeDao.getUploadedLegacyTreeImageCountFlow(), + treeDao.getUploadedTreeImageCountFlow(), + treeDao.getNonUploadedLegacyTreeCaptureImageCountFlow(), + treeDao.getNonUploadedTreeImageCountFlow(), ) { uploadedLegacy, uploadedNew, nonUploadedLegacy, nonUploadedNew -> val synced = uploadedLegacy + uploadedNew val remaining = nonUploadedLegacy + nonUploadedNew diff --git a/app/src/main/java/org/greenstand/android/TreeTracker/di/AppModule.kt b/app/src/main/java/org/greenstand/android/TreeTracker/di/AppModule.kt index 93faf175b..993d286ca 100644 --- a/app/src/main/java/org/greenstand/android/TreeTracker/di/AppModule.kt +++ b/app/src/main/java/org/greenstand/android/TreeTracker/di/AppModule.kt @@ -241,7 +241,7 @@ val appModule = factory { UploadImageUseCase(get()) } - factory { UploadLocationDataUseCase(get(), get()) } + factory { UploadLocationDataUseCase(get(), get(), get()) } factory { CreateTreeUseCase(get(), get(), get()) } diff --git a/app/src/main/java/org/greenstand/android/TreeTracker/models/location/LocationDataCapturer.kt b/app/src/main/java/org/greenstand/android/TreeTracker/models/location/LocationDataCapturer.kt index 7289e1553..1986adc98 100644 --- a/app/src/main/java/org/greenstand/android/TreeTracker/models/location/LocationDataCapturer.kt +++ b/app/src/main/java/org/greenstand/android/TreeTracker/models/location/LocationDataCapturer.kt @@ -28,7 +28,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withTimeout import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json -import org.greenstand.android.TreeTracker.database.TreeTrackerDAO +import org.greenstand.android.TreeTracker.database.dao.LocationDAO import org.greenstand.android.TreeTracker.database.entity.LocationEntity import org.greenstand.android.TreeTracker.models.ConvergenceConfiguration import org.greenstand.android.TreeTracker.models.ConvergenceStatus @@ -42,7 +42,7 @@ import kotlin.properties.Delegates class LocationDataCapturer( private val locationUpdateManager: LocationUpdateManager, - private val treeTrackerDAO: TreeTrackerDAO, + private val locationDao: LocationDAO, private val convergenceConfiguration: ConvergenceConfiguration, private val json: Json, private val sessionTracker: SessionTracker, @@ -138,7 +138,7 @@ class LocationDataCapturer( ) val jsonValue = json.encodeToString(locationData) Timber.d("Inserting new location data $jsonValue") - treeTrackerDAO.insertLocationData( + locationDao.insertLocationData( LocationEntity( locationDataJson = jsonValue, sessionId = currentSessionId, diff --git a/app/src/main/java/org/greenstand/android/TreeTracker/usecases/SyncDataUseCase.kt b/app/src/main/java/org/greenstand/android/TreeTracker/usecases/SyncDataUseCase.kt index 48dcabdd1..fe8df1e0d 100644 --- a/app/src/main/java/org/greenstand/android/TreeTracker/usecases/SyncDataUseCase.kt +++ b/app/src/main/java/org/greenstand/android/TreeTracker/usecases/SyncDataUseCase.kt @@ -21,7 +21,7 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.isActive import kotlinx.coroutines.tasks.await import kotlinx.coroutines.withContext -import org.greenstand.android.TreeTracker.database.TreeTrackerDAO +import org.greenstand.android.TreeTracker.database.dao.TreeDAO import org.greenstand.android.TreeTracker.models.DeviceConfigUploader import org.greenstand.android.TreeTracker.models.PlanterUploader import org.greenstand.android.TreeTracker.models.SessionUploader @@ -35,7 +35,7 @@ import kotlin.coroutines.coroutineContext class SyncDataUseCase( private val treeUploader: TreeUploader, private val uploadLocationDataUseCase: UploadLocationDataUseCase, - private val dao: TreeTrackerDAO, + private val treeDao: TreeDAO, private val planterUploader: PlanterUploader, private val sessionUploader: SessionUploader, private val deviceConfigUploader: DeviceConfigUploader, @@ -73,13 +73,13 @@ class SyncDataUseCase( treeUpload( syncStep = SyncStep.LEGACY_TREES, - onGetTreeIds = { dao.getAllTreeCaptureIdsToUpload() }, + onGetTreeIds = { treeDao.getAllTreeCaptureIdsToUpload() }, onUpload = { treeUploader.uploadLegacyTrees(it, instanceId) }, ) treeUpload( syncStep = SyncStep.TREES, - onGetTreeIds = { dao.getAllTreeIdsToUpload() }, + onGetTreeIds = { treeDao.getAllTreeIdsToUpload() }, onUpload = { treeUploader.uploadTrees(it) }, ) diff --git a/app/src/main/java/org/greenstand/android/TreeTracker/usecases/UploadLocationDataUseCase.kt b/app/src/main/java/org/greenstand/android/TreeTracker/usecases/UploadLocationDataUseCase.kt index c75bebb54..76c83a6af 100644 --- a/app/src/main/java/org/greenstand/android/TreeTracker/usecases/UploadLocationDataUseCase.kt +++ b/app/src/main/java/org/greenstand/android/TreeTracker/usecases/UploadLocationDataUseCase.kt @@ -24,13 +24,15 @@ import org.greenstand.android.TreeTracker.api.ObjectStorageClient import org.greenstand.android.TreeTracker.api.models.requests.LocationRequest import org.greenstand.android.TreeTracker.api.models.requests.TracksRequest import org.greenstand.android.TreeTracker.api.models.requests.UploadBundle -import org.greenstand.android.TreeTracker.database.TreeTrackerDAO +import org.greenstand.android.TreeTracker.database.dao.LocationDAO +import org.greenstand.android.TreeTracker.database.dao.SessionDAO import org.greenstand.android.TreeTracker.models.LocationData import org.greenstand.android.TreeTracker.utilities.md5 import timber.log.Timber class UploadLocationDataUseCase( - private val dao: TreeTrackerDAO, + private val locationDAO: LocationDAO, + private val sessionDao: SessionDAO, private val json: Json, ) : UseCase() { private val storageClient = ObjectStorageClient.instance() @@ -40,7 +42,7 @@ class UploadLocationDataUseCase( Timber.d("Processing tree location data") withContext(Dispatchers.IO) { // V2 - val locationEntities = dao.getLocationData() + val locationEntities = locationDAO.getLocationData() val sessionIdToLocations = locationEntities.groupBy { it.sessionId } val sessionIdToLocationRequests = sessionIdToLocations @@ -59,7 +61,7 @@ class UploadLocationDataUseCase( return@map sessionId to locationRequests } - val sessionEntities = sessionIdToLocations.map { dao.getSessionById(it.key) } + val sessionEntities = sessionIdToLocations.map { sessionDao.getSessionById(it.key) } val trackRequests = sessionIdToLocationRequests.map { (sessionId, locationList) -> TracksRequest( @@ -79,8 +81,8 @@ class UploadLocationDataUseCase( "${dataBundle.md5()}_tracks", ) - dao.updateLocationDataUploadStatus(locationEntities.map { it.id }, true) - dao.purgeUploadedLocations() + locationDAO.updateLocationDataUploadStatus(locationEntities.map { it.id }, true) + locationDAO.purgeUploadedLocations() Timber.tag("Location Upload").d("Completed uploading ${locationEntities.size} V2 GPS locations") } diff --git a/app/src/test/java/org/greenstand/android/TreeTracker/dashboard/DashboardViewModelTest.kt b/app/src/test/java/org/greenstand/android/TreeTracker/dashboard/DashboardViewModelTest.kt index 6e06c9ee1..5eb4b89c8 100644 --- a/app/src/test/java/org/greenstand/android/TreeTracker/dashboard/DashboardViewModelTest.kt +++ b/app/src/test/java/org/greenstand/android/TreeTracker/dashboard/DashboardViewModelTest.kt @@ -33,7 +33,7 @@ import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.greenstand.android.TreeTracker.MainCoroutineRule import org.greenstand.android.TreeTracker.analytics.Analytics -import org.greenstand.android.TreeTracker.database.TreeTrackerDAO +import org.greenstand.android.TreeTracker.database.dao.TreeDAO import org.greenstand.android.TreeTracker.models.location.LocationDataCapturer import org.greenstand.android.TreeTracker.models.messages.MessagesRepo import org.greenstand.android.TreeTracker.models.organization.OrgRepo @@ -59,7 +59,7 @@ class DashboardViewModelTest { var mainCoroutineRule = MainCoroutineRule() @MockK(relaxed = true) - private lateinit var dao: TreeTrackerDAO + private lateinit var treeDao: TreeDAO @MockK(relaxed = true) private lateinit var workManager: WorkManager @@ -87,10 +87,10 @@ class DashboardViewModelTest { fun setup() { MockKAnnotations.init(this) coEvery { analytics.syncButtonTapped(any(), any(), any()) } just Runs - every { dao.getUploadedLegacyTreeImageCountFlow() } returns flowOf(3) - every { dao.getUploadedTreeImageCountFlow() } returns flowOf(5) - every { dao.getNonUploadedLegacyTreeCaptureImageCountFlow() } returns flowOf(2) - every { dao.getNonUploadedTreeImageCountFlow() } returns flowOf(4) + every { treeDao.getUploadedLegacyTreeImageCountFlow() } returns flowOf(3) + every { treeDao.getUploadedTreeImageCountFlow() } returns flowOf(5) + every { treeDao.getNonUploadedLegacyTreeCaptureImageCountFlow() } returns flowOf(2) + every { treeDao.getNonUploadedTreeImageCountFlow() } returns flowOf(4) coEvery { checkForInternetUseCase.execute(Unit) } returns true coEvery { messagesRepo.syncMessages() } just Runs coEvery { treesToSyncHelper.getTreeCountToSync() } returns 6 @@ -99,7 +99,7 @@ class DashboardViewModelTest { every { workManager.enqueueUniqueWork(any(), any(), any()) } returns mockk() testSubject = DashboardViewModel( - dao = dao, + treeDao = treeDao, workManager = workManager, analytics = analytics, treesToSyncHelper = treesToSyncHelper, @@ -148,14 +148,14 @@ class DashboardViewModelTest { fun `observeTreeCounts reacts to Flow changes`() = runTest { val nonUploadedFlow = MutableStateFlow(4) - every { dao.getUploadedLegacyTreeImageCountFlow() } returns flowOf(3) - every { dao.getUploadedTreeImageCountFlow() } returns flowOf(5) - every { dao.getNonUploadedLegacyTreeCaptureImageCountFlow() } returns flowOf(2) - every { dao.getNonUploadedTreeImageCountFlow() } returns nonUploadedFlow + every { treeDao.getUploadedLegacyTreeImageCountFlow() } returns flowOf(3) + every { treeDao.getUploadedTreeImageCountFlow() } returns flowOf(5) + every { treeDao.getNonUploadedLegacyTreeCaptureImageCountFlow() } returns flowOf(2) + every { treeDao.getNonUploadedTreeImageCountFlow() } returns nonUploadedFlow val vm = DashboardViewModel( - dao = dao, + treeDao = treeDao, workManager = workManager, analytics = analytics, treesToSyncHelper = treesToSyncHelper, @@ -178,14 +178,14 @@ class DashboardViewModelTest { @Test fun `showTreeSyncReminderDialog is true when remaining trees reach threshold`() = runTest { - every { dao.getUploadedLegacyTreeImageCountFlow() } returns flowOf(0) - every { dao.getUploadedTreeImageCountFlow() } returns flowOf(0) - every { dao.getNonUploadedLegacyTreeCaptureImageCountFlow() } returns flowOf(1000) - every { dao.getNonUploadedTreeImageCountFlow() } returns flowOf(1000) + every { treeDao.getUploadedLegacyTreeImageCountFlow() } returns flowOf(0) + every { treeDao.getUploadedTreeImageCountFlow() } returns flowOf(0) + every { treeDao.getNonUploadedLegacyTreeCaptureImageCountFlow() } returns flowOf(1000) + every { treeDao.getNonUploadedTreeImageCountFlow() } returns flowOf(1000) val vm = DashboardViewModel( - dao = dao, + treeDao = treeDao, workManager = workManager, analytics = analytics, treesToSyncHelper = treesToSyncHelper, diff --git a/app/src/test/java/org/greenstand/android/TreeTracker/models/location/LocationDataCapturerTest.kt b/app/src/test/java/org/greenstand/android/TreeTracker/models/location/LocationDataCapturerTest.kt index 790fa1d21..d38993192 100644 --- a/app/src/test/java/org/greenstand/android/TreeTracker/models/location/LocationDataCapturerTest.kt +++ b/app/src/test/java/org/greenstand/android/TreeTracker/models/location/LocationDataCapturerTest.kt @@ -31,7 +31,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.test.runTest import kotlinx.datetime.Instant import kotlinx.serialization.json.Json -import org.greenstand.android.TreeTracker.database.TreeTrackerDAO +import org.greenstand.android.TreeTracker.database.dao.LocationDAO import org.greenstand.android.TreeTracker.models.ConvergenceConfiguration import org.greenstand.android.TreeTracker.models.LocationDataConfig import org.greenstand.android.TreeTracker.models.SessionTracker @@ -64,7 +64,7 @@ class LocationDataCapturerTest { private lateinit var preferences: Preferences @MockK(relaxed = true) - private lateinit var treeTrackerDAO: TreeTrackerDAO + private lateinit var locationDao: LocationDAO @MockK(relaxed = true) private lateinit var sessionTracker: SessionTracker @@ -80,7 +80,7 @@ class LocationDataCapturerTest { locationDataCapturer = LocationDataCapturer( locationUpdateManager, - treeTrackerDAO, + locationDao, convergenceConfiguration, Json { explicitNulls = true @@ -110,7 +110,7 @@ class LocationDataCapturerTest { every { locationUpdateManager.locationUpdateLiveData } returns locationsLiveData every { sessionTracker.currentSessionId } returns 1L every { timeProvider.currentTime() } returns Instant.fromEpochMilliseconds(1000) - coEvery { treeTrackerDAO.insertLocationData(any()) } coAnswers { + coEvery { locationDao.insertLocationData(any()) } coAnswers { delay(500) insertCompleted.countDown() 1L diff --git a/app/src/test/java/org/greenstand/android/TreeTracker/usecases/SyncDataUseCaseTest.kt b/app/src/test/java/org/greenstand/android/TreeTracker/usecases/SyncDataUseCaseTest.kt index 9425fce5f..70fa90824 100644 --- a/app/src/test/java/org/greenstand/android/TreeTracker/usecases/SyncDataUseCaseTest.kt +++ b/app/src/test/java/org/greenstand/android/TreeTracker/usecases/SyncDataUseCaseTest.kt @@ -30,7 +30,7 @@ import io.mockk.verify import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.greenstand.android.TreeTracker.MainCoroutineRule -import org.greenstand.android.TreeTracker.database.TreeTrackerDAO +import org.greenstand.android.TreeTracker.database.dao.TreeDAO import org.greenstand.android.TreeTracker.models.DeviceConfigUploader import org.greenstand.android.TreeTracker.models.PlanterUploader import org.greenstand.android.TreeTracker.models.SessionUploader @@ -60,7 +60,7 @@ class SyncDataUseCaseTest { private lateinit var uploadLocationDataUseCase: UploadLocationDataUseCase @MockK(relaxed = true) - private lateinit var dao: TreeTrackerDAO + private lateinit var treeDao: TreeDAO @MockK(relaxed = true) private lateinit var planterUploader: PlanterUploader @@ -91,7 +91,7 @@ class SyncDataUseCaseTest { SyncDataUseCase( treeUploader = treeUploader, uploadLocationDataUseCase = uploadLocationDataUseCase, - dao = dao, + treeDao = treeDao, planterUploader = planterUploader, sessionUploader = sessionUploader, deviceConfigUploader = deviceConfigUploader, @@ -108,8 +108,8 @@ class SyncDataUseCaseTest { @Test fun `WHEN all steps succeed THEN returns true`() = runTest { - coEvery { dao.getAllTreeCaptureIdsToUpload() } returns emptyList() - coEvery { dao.getAllTreeIdsToUpload() } returns emptyList() + coEvery { treeDao.getAllTreeCaptureIdsToUpload() } returns emptyList() + coEvery { treeDao.getAllTreeIdsToUpload() } returns emptyList() val result = syncDataUseCase.execute(Unit) @@ -119,8 +119,8 @@ class SyncDataUseCaseTest { @Test fun `WHEN all steps succeed THEN calls each uploader in order`() = runTest { - coEvery { dao.getAllTreeCaptureIdsToUpload() } returns emptyList() - coEvery { dao.getAllTreeIdsToUpload() } returns emptyList() + coEvery { treeDao.getAllTreeCaptureIdsToUpload() } returns emptyList() + coEvery { treeDao.getAllTreeIdsToUpload() } returns emptyList() syncDataUseCase.execute(Unit) @@ -144,8 +144,8 @@ class SyncDataUseCaseTest { @Test fun `WHEN tree upload fails THEN returns false`() = runTest { - coEvery { dao.getAllTreeCaptureIdsToUpload() } returns emptyList() - coEvery { dao.getAllTreeIdsToUpload() } returns listOf(1L, 2L) + coEvery { treeDao.getAllTreeCaptureIdsToUpload() } returns emptyList() + coEvery { treeDao.getAllTreeIdsToUpload() } returns listOf(1L, 2L) coEvery { treeUploader.uploadTrees(any()) } throws RuntimeException("Upload failed") val result = syncDataUseCase.execute(Unit) @@ -156,8 +156,8 @@ class SyncDataUseCaseTest { @Test fun `WHEN sync succeeds THEN starts and ends sync on progress tracker`() = runTest { - coEvery { dao.getAllTreeCaptureIdsToUpload() } returns emptyList() - coEvery { dao.getAllTreeIdsToUpload() } returns emptyList() + coEvery { treeDao.getAllTreeCaptureIdsToUpload() } returns emptyList() + coEvery { treeDao.getAllTreeIdsToUpload() } returns emptyList() syncDataUseCase.execute(Unit) @@ -180,8 +180,8 @@ class SyncDataUseCaseTest { fun `WHEN sync has trees to upload THEN uploads them`() = runTest { val treeIds = listOf(1L, 2L, 3L) - coEvery { dao.getAllTreeCaptureIdsToUpload() } returns emptyList() - coEvery { dao.getAllTreeIdsToUpload() } returnsMany listOf(treeIds, emptyList()) + coEvery { treeDao.getAllTreeCaptureIdsToUpload() } returns emptyList() + coEvery { treeDao.getAllTreeIdsToUpload() } returnsMany listOf(treeIds, emptyList()) syncDataUseCase.execute(Unit) @@ -192,8 +192,8 @@ class SyncDataUseCaseTest { fun `WHEN sync has legacy trees to upload THEN uploads them`() = runTest { val legacyTreeIds = listOf(10L, 20L) - coEvery { dao.getAllTreeCaptureIdsToUpload() } returnsMany listOf(legacyTreeIds, emptyList()) - coEvery { dao.getAllTreeIdsToUpload() } returns emptyList() + coEvery { treeDao.getAllTreeCaptureIdsToUpload() } returnsMany listOf(legacyTreeIds, emptyList()) + coEvery { treeDao.getAllTreeIdsToUpload() } returns emptyList() syncDataUseCase.execute(Unit) @@ -207,8 +207,8 @@ class SyncDataUseCaseTest { every { FirebaseInstallations.getInstance() } returns mockInstallations every { mockInstallations.id } returns Tasks.forException(RuntimeException("Firebase unavailable")) - coEvery { dao.getAllTreeCaptureIdsToUpload() } returns emptyList() - coEvery { dao.getAllTreeIdsToUpload() } returns emptyList() + coEvery { treeDao.getAllTreeCaptureIdsToUpload() } returns emptyList() + coEvery { treeDao.getAllTreeIdsToUpload() } returns emptyList() val result = syncDataUseCase.execute(Unit) @@ -219,8 +219,8 @@ class SyncDataUseCaseTest { @Test fun `WHEN sync succeeds THEN tracks each step`() = runTest { - coEvery { dao.getAllTreeCaptureIdsToUpload() } returns emptyList() - coEvery { dao.getAllTreeIdsToUpload() } returns emptyList() + coEvery { treeDao.getAllTreeCaptureIdsToUpload() } returns emptyList() + coEvery { treeDao.getAllTreeIdsToUpload() } returns emptyList() syncDataUseCase.execute(Unit)