library: resolve artist art from live credits

Artist detail only used the materialized artist cover list, so credited
track artists without an artists row, or with an empty or stale cover
list, always fell back to the letter placeholder even though their
appearances albums had art. Observe the credit-derived cover query and
use it for the detail art, preferring the cached downloaded covers when
offline. The query covers album, album_artists, song and song_artists
credits.
This commit is contained in:
austinried
2026-10-21 10:14:01 +00:00
parent 8765c5d37b
commit 1dbfb027fe
4 changed files with 126 additions and 6 deletions
@@ -655,6 +655,52 @@ class LibraryDaoTest {
)
}
@Test
fun coverArtFallbackFindsTrackCreditsWithoutAnArtistRow() =
runTest {
val sourceId = source()
val dao = db.libraryDao()
dao.upsertAlbums(
listOf(
album(sourceId, "al-1", "Album", year = 2020, starred = null)
.copy(artistId = "ar-other", coverArt = "track-art"),
album(sourceId, "al-2", "Featured", year = 2021, starred = null)
.copy(artistId = "ar-other", coverArt = "featured-art"),
),
)
dao.upsertSongs(
listOf(
song(sourceId, "s-1", "Song", starred = null)
.copy(albumId = "al-1", artistId = "ar-missing"),
song(sourceId, "s-2", "Featured", starred = null)
.copy(albumId = "al-2", artistId = "ar-other"),
),
)
db.useWriterConnection { connection ->
connection.usePrepared(
"INSERT INTO album_artists (sourceId, albumId, position, artistId, name) " +
"VALUES (?, 'al-2', 0, 'ar-featured', 'Featured')",
) { statement ->
statement.bindLong(1, sourceId)
statement.step()
}
connection.usePrepared(
"INSERT INTO song_artists (sourceId, songId, position, artistId, name) " +
"VALUES (?, 's-2', 0, 'ar-guest', 'Guest')",
) { statement ->
statement.bindLong(1, sourceId)
statement.step()
}
}
assertNull(dao.artistOnce(sourceId, "ar-missing"))
assertNull(dao.artistOnce(sourceId, "ar-featured"))
assertNull(dao.artistOnce(sourceId, "ar-guest"))
assertEquals(listOf("track-art"), dao.artistCoverArts(sourceId, "ar-missing"))
assertEquals(listOf("featured-art"), dao.artistCoverArts(sourceId, "ar-featured"))
assertEquals(listOf("featured-art"), dao.artistCoverArts(sourceId, "ar-guest"))
}
@Test
fun downloadedArtistArtUsesOnlyDownloadedAlbums() =
runTest {