mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-15 00:42:54 +01:00
library: fix credited fallback and stale marker writes
Restore the both-tables-empty fallback in the credit recompute, skip redundant marker writes, append albumless tracks after album tracks, and make the paged artist query observe sources. Add tests for an interrupted sync and the partial-relation migration guard.
This commit is contained in:
@@ -246,6 +246,32 @@ class MigrationsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun theCreditedBackfillKeepsArtistsVisibleWhileRelationsAreIncomplete() =
|
||||
runTest {
|
||||
driver.open(":memory:").use { migrated ->
|
||||
applySchema(migrated, 31)
|
||||
migrated.execSQL(
|
||||
"INSERT INTO sources (id, name, address, isActive, createdAt) VALUES (1, 's', 'http://x', 1, 0)",
|
||||
)
|
||||
migrated.execSQL("INSERT INTO artists (sourceId, id, name, albumCount) VALUES (1, 'a1', 'Alpha', 1)")
|
||||
migrated.execSQL("INSERT INTO artists (sourceId, id, name, albumCount) VALUES (1, 'combo', 'Alpha & Beta', 1)")
|
||||
migrated.execSQL(
|
||||
"INSERT INTO albums (sourceId, id, artistId, name, albumArtist, created, songCount) " +
|
||||
"VALUES (1, 'al1', 'a1', 'Album', 'Alpha', 0, 0)",
|
||||
)
|
||||
migrated.execSQL(
|
||||
"INSERT INTO album_artists (sourceId, albumId, position, artistId, name) " +
|
||||
"VALUES (1, 'al1', 0, 'a1', 'Alpha')",
|
||||
)
|
||||
|
||||
MIGRATION_31_32.migrate(migrated)
|
||||
|
||||
assertEquals(1L, long(migrated, "SELECT credited FROM artists WHERE id = 'a1'"))
|
||||
assertEquals(1L, long(migrated, "SELECT credited FROM artists WHERE id = 'combo'"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun text(
|
||||
connection: SQLiteConnection,
|
||||
sql: String,
|
||||
|
||||
@@ -1167,6 +1167,44 @@ class SyncServiceTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun anInterruptedSyncLeavesTheCreditMarkerStale() =
|
||||
runTest {
|
||||
insertSource()
|
||||
val source =
|
||||
FakeMusicSource(
|
||||
artists = listOf(artist("a1", "Alpha"), artist("combo", "Alpha & Beta")),
|
||||
albums = listOf(album("al1")),
|
||||
songs = listOf(song("s1")),
|
||||
songsFailure = java.io.IOException("boom"),
|
||||
)
|
||||
|
||||
runCatching { SyncService(db, source).sync() }
|
||||
|
||||
assertEquals(true, db.sourcesDao().creditsStale(1))
|
||||
assertEquals(
|
||||
listOf("a1", "combo"),
|
||||
db
|
||||
.libraryDao()
|
||||
.artistsByName(1, 0, "")
|
||||
.allRows()
|
||||
.map { it.id },
|
||||
)
|
||||
|
||||
source.songsFailure = null
|
||||
SyncService(db, source).sync()
|
||||
|
||||
assertEquals(false, db.sourcesDao().creditsStale(1))
|
||||
assertEquals(
|
||||
listOf("a1"),
|
||||
db
|
||||
.libraryDao()
|
||||
.artistsByName(1, 0, "")
|
||||
.allRows()
|
||||
.map { it.id },
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun aStaleCreditMarkerForcesARecomputeOnTheNextSync() =
|
||||
runTest {
|
||||
@@ -1513,6 +1551,7 @@ private class FakeMusicSource(
|
||||
var songs: List<Song> = emptyList(),
|
||||
var playlists: List<Playlist> = emptyList(),
|
||||
var playlistSongs: List<PlaylistSong> = emptyList(),
|
||||
var songsFailure: Throwable? = null,
|
||||
private val batchSize: Int = 1000,
|
||||
) : MusicSource {
|
||||
val requestedPlaylistIds = mutableListOf<List<String>>()
|
||||
@@ -1535,7 +1574,12 @@ private class FakeMusicSource(
|
||||
|
||||
override fun albums(): Flow<List<Album>> = batches(albums)
|
||||
|
||||
override fun songs(): Flow<List<Song>> = batches(songs)
|
||||
override fun songs(): Flow<List<Song>> =
|
||||
if (songsFailure == null) {
|
||||
batches(songs)
|
||||
} else {
|
||||
flow { throw songsFailure!! }
|
||||
}
|
||||
|
||||
override fun playlists(): Flow<List<Playlist>> = batches(playlists)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user