diff --git a/app/src/main/kotlin/com/subtracks/data/sync/SyncManager.kt b/app/src/main/kotlin/com/subtracks/data/sync/SyncManager.kt index f12ebfd3..d5e620e0 100644 --- a/app/src/main/kotlin/com/subtracks/data/sync/SyncManager.kt +++ b/app/src/main/kotlin/com/subtracks/data/sync/SyncManager.kt @@ -29,6 +29,7 @@ class SyncManager( private val db: SubtracksDatabase, private val sourceRepository: SourceRepository, private val queueRepository: QueueRepository, + private val showMessage: (String) -> Unit = {}, ) { private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default) private val requests = Channel(Channel.CONFLATED) @@ -56,7 +57,9 @@ class SyncManager( throw cancellation } catch (failure: Exception) { Log.w(TAG, "Sync failed", failure) - SyncStatus.Failed(failure.message ?: "Sync failed") + val message = failure.message ?: "unknown error" + showMessage("Sync failed: $message") + SyncStatus.Failed(message) } queueRepository.invalidateLibraryCache() _status.value = result diff --git a/app/src/main/kotlin/com/subtracks/di/AppModule.kt b/app/src/main/kotlin/com/subtracks/di/AppModule.kt index 7c252440..31b45388 100644 --- a/app/src/main/kotlin/com/subtracks/di/AppModule.kt +++ b/app/src/main/kotlin/com/subtracks/di/AppModule.kt @@ -57,7 +57,7 @@ fun appModule( single { NetworkServerActionSink(get()) } single { LibraryRepository(get(), get(), get(), toast) } single { ArtworkSeedRepository(get()) } - single { SyncManager(get(), get(), get()) } + single { SyncManager(get(), get(), get(), showMessage = toast) } single { QueueRepository(get()) } single { ArtworkStore(downloadsRoot(context)) } single { OkHttpArtworkFetcher(get()) } diff --git a/app/src/test/kotlin/com/subtracks/data/sync/SyncManagerTest.kt b/app/src/test/kotlin/com/subtracks/data/sync/SyncManagerTest.kt index f58710cb..82fec166 100644 --- a/app/src/test/kotlin/com/subtracks/data/sync/SyncManagerTest.kt +++ b/app/src/test/kotlin/com/subtracks/data/sync/SyncManagerTest.kt @@ -21,6 +21,7 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import java.io.File +import java.util.concurrent.CopyOnWriteArrayList @RunWith(AndroidJUnit4::class) class SyncManagerTest { @@ -28,6 +29,7 @@ class SyncManagerTest { private lateinit var sourceRepository: SourceRepository private lateinit var queueRepository: QueueRepository private lateinit var manager: SyncManager + private val messages = CopyOnWriteArrayList() @Before fun setUp() { @@ -39,7 +41,7 @@ class SyncManagerTest { .build() sourceRepository = SourceRepository(db, OkHttpClient(), fakeUserPreferences(), ArtworkStore(File(context.cacheDir, "art"))) queueRepository = QueueRepository(db) - manager = SyncManager(db, sourceRepository, queueRepository) + manager = SyncManager(db, sourceRepository, queueRepository, showMessage = { messages += it }) } @After @@ -48,6 +50,15 @@ class SyncManagerTest { db.close() } + @Test + fun aFailedSyncTellsTheUser() = + runBlocking { + manager.requestSync() + withTimeout(10_000) { manager.status.first { it is SyncStatus.Failed } } + + assertEquals(listOf("Sync failed: No server configured"), messages) + } + @Test fun aFailedSyncStillInvalidatesTheLibraryCache() = runBlocking {