mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-15 00:42:54 +01:00
library: rank artist cover fallback like the materialized list
Reuse the materialized ranking CTE chain for the per-artist fallback so duplicate covers keep the same album, exercise the four-row cap, and test every credit path plus source isolation. Resolve the art input as a pure function and key the artist and covers off the same source.
This commit is contained in:
@@ -656,7 +656,7 @@ class LibraryDaoTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun coverArtFallbackFindsTrackCreditsWithoutAnArtistRow() =
|
||||
fun coverArtFallbackFindsEveryCreditPath() =
|
||||
runTest {
|
||||
val sourceId = source()
|
||||
val dao = db.libraryDao()
|
||||
@@ -696,9 +696,44 @@ class LibraryDaoTest {
|
||||
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"))
|
||||
assertEquals(listOf("track-art"), dao.artistCoverArts(sourceId, "ar-missing").first())
|
||||
assertEquals(listOf("featured-art", "track-art"), dao.artistCoverArts(sourceId, "ar-other").first())
|
||||
assertEquals(listOf("featured-art"), dao.artistCoverArts(sourceId, "ar-featured").first())
|
||||
assertEquals(listOf("featured-art"), dao.artistCoverArts(sourceId, "ar-guest").first())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun artistCoverArtsRanksDeduplicatesCapsAndStaysInSource() =
|
||||
runTest {
|
||||
val sourceId = source()
|
||||
val otherSourceId = source()
|
||||
val dao = db.libraryDao()
|
||||
dao.upsertArtists(listOf(artist(sourceId, "ar-rank", "Rank", albumCount = 0)))
|
||||
dao.upsertAlbums(
|
||||
listOf(
|
||||
album(sourceId, "a-new", "New", year = 2020, starred = null)
|
||||
.copy(artistId = "ar-rank", coverArt = "shared"),
|
||||
album(sourceId, "a-mid", "Mid", year = 2015, starred = null)
|
||||
.copy(artistId = "ar-rank", coverArt = "other"),
|
||||
album(sourceId, "a-old", "Old", year = 2010, starred = null)
|
||||
.copy(artistId = "ar-rank", coverArt = "shared"),
|
||||
album(sourceId, "a-4", "Four", year = 2012, starred = null)
|
||||
.copy(artistId = "ar-rank", coverArt = "c4"),
|
||||
album(sourceId, "a-5", "Five", year = 2011, starred = null)
|
||||
.copy(artistId = "ar-rank", coverArt = "c5"),
|
||||
album(sourceId, "a-6", "Six", year = 2009, starred = null)
|
||||
.copy(artistId = "ar-rank", coverArt = "c6"),
|
||||
album(otherSourceId, "a-leak", "Leak", year = 2025, starred = null)
|
||||
.copy(artistId = "ar-rank", coverArt = "leak"),
|
||||
),
|
||||
)
|
||||
|
||||
val expected = listOf("shared", "other", "c4", "c5")
|
||||
assertEquals(expected, dao.artistCoverArts(sourceId, "ar-rank").first())
|
||||
|
||||
dao.recomputeArtistArt(sourceId)
|
||||
|
||||
assertEquals(expected, dao.artistOnce(sourceId, "ar-rank")!!.coverArts)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.subtracks.ui.library
|
||||
|
||||
import com.subtracks.data.model.Artist
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
|
||||
class ArtistDetailArtTest {
|
||||
@Test
|
||||
fun aCreditedArtistWithoutARowUsesTheCreditCovers() {
|
||||
val resolved =
|
||||
resolveArtistArtInput(
|
||||
ArtistArtInput(
|
||||
artist = null,
|
||||
artistId = "ar1",
|
||||
offline = false,
|
||||
sourceId = 7,
|
||||
covers = listOf("a", "b"),
|
||||
),
|
||||
)
|
||||
|
||||
assertEquals(7L, resolved?.sourceId)
|
||||
assertEquals("ar1", resolved?.id)
|
||||
assertEquals(listOf("a", "b"), resolved?.coverArts)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun anOfflineArtistKeepsItsDownloadedCovers() {
|
||||
val resolved =
|
||||
resolveArtistArtInput(
|
||||
ArtistArtInput(
|
||||
artist = artist(coverArts = listOf("online"), downloadedCoverArts = listOf("downloaded")),
|
||||
artistId = "ar1",
|
||||
offline = true,
|
||||
sourceId = 7,
|
||||
covers = listOf("online", "other"),
|
||||
),
|
||||
)
|
||||
|
||||
assertEquals(listOf("online", "other"), resolved?.coverArts)
|
||||
assertEquals(listOf("downloaded"), resolved?.downloadedCoverArts)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun anOfflineArtistWithoutDownloadedCoversFallsBackToTheCreditCovers() {
|
||||
val resolved =
|
||||
resolveArtistArtInput(
|
||||
ArtistArtInput(
|
||||
artist = artist(downloadedCoverArts = emptyList()),
|
||||
artistId = "ar1",
|
||||
offline = true,
|
||||
sourceId = 7,
|
||||
covers = listOf("a", "b"),
|
||||
),
|
||||
)
|
||||
|
||||
assertEquals(listOf("a", "b"), resolved?.downloadedCoverArts)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun anArtistWithMaterializedCoversIsKeptWhenTheCreditQueryIsEmpty() {
|
||||
val original = artist(coverArts = listOf("materialized"))
|
||||
|
||||
val resolved =
|
||||
resolveArtistArtInput(
|
||||
ArtistArtInput(
|
||||
artist = original,
|
||||
artistId = "ar1",
|
||||
offline = false,
|
||||
sourceId = 7,
|
||||
covers = emptyList(),
|
||||
),
|
||||
)
|
||||
|
||||
assertEquals(original, resolved)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun noArtistAndNoCoversClearsTheArt() {
|
||||
assertNull(
|
||||
resolveArtistArtInput(
|
||||
ArtistArtInput(
|
||||
artist = null,
|
||||
artistId = "ar1",
|
||||
offline = false,
|
||||
sourceId = 7,
|
||||
covers = emptyList(),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun artist(
|
||||
coverArts: List<String> = emptyList(),
|
||||
downloadedCoverArts: List<String> = emptyList(),
|
||||
) = Artist(
|
||||
sourceId = 7,
|
||||
id = "ar1",
|
||||
name = "Artist",
|
||||
albumCount = 1,
|
||||
starred = null,
|
||||
coverArts = coverArts,
|
||||
downloadedCoverArts = downloadedCoverArts,
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user