fix: handle artist bio failure and refresh edge cases

Retry a failed download bio fetch instead of blacklisting the artist for
the rest of the process, and give a failed or offline refresh its own
message so it is not mistaken for a server with no biography.

Wait for the stored row before choosing the bio text, so a cached bio no
longer flashes the loading state on entry, and bound the page refresh so
a stalled response cannot leave the loading state up indefinitely.

Render an oversized first token instead of a blank collapsed line, and
check whether the whole remainder fits in one measurement.
This commit is contained in:
austinried
2026-10-19 13:14:08 +00:00
parent 889bdb452b
commit d4ba9c0faf
6 changed files with 128 additions and 50 deletions
@@ -44,6 +44,8 @@ class ArtistDetailScreenTest {
albumsLoaded: Boolean = true,
bio: String? = null,
bioLoading: Boolean = false,
bioUnavailable: Boolean = false,
bioPending: Boolean = false,
) {
composeRule.setContent {
var expanded by remember { mutableStateOf(false) }
@@ -55,6 +57,8 @@ class ArtistDetailScreenTest {
albumsLoaded = albumsLoaded,
bio = bio,
bioLoading = bioLoading,
bioUnavailable = bioUnavailable,
bioPending = bioPending,
bioExpanded = expanded,
art = null,
coverArt = { _, _ -> null },
@@ -151,6 +155,32 @@ class ArtistDetailScreenTest {
composeRule.onNodeWithText("No artist bio available.").assertDoesNotExist()
}
@Test
fun theBioAreaWaitsForTheStoredValueBeforeChoosingAText() {
render(
artist = Artist(sourceId = 1, id = "ar-1", name = "Radiohead", albumCount = 1, starred = null),
artistName = "Radiohead",
bioLoading = true,
bioPending = true,
)
composeRule.onNodeWithText("Loading artist bio…").assertDoesNotExist()
composeRule.onNodeWithText("No artist bio available.").assertDoesNotExist()
composeRule.onNodeWithText("Artist bio unavailable.").assertDoesNotExist()
}
@Test
fun aFailedRefreshIsNotMistakenForAnArtistWithoutABio() {
render(
artist = Artist(sourceId = 1, id = "ar-1", name = "Radiohead", albumCount = 1, starred = null),
artistName = "Radiohead",
bioUnavailable = true,
)
composeRule.onNodeWithText("Artist bio unavailable.").assertExists()
composeRule.onNodeWithText("No artist bio available.").assertDoesNotExist()
}
@Test
fun aMissingBioShowsTheEmptyStateAfterTheRefresh() {
render(
@@ -218,6 +248,33 @@ class ArtistDetailScreenTest {
)
}
@Test
fun anOversizedFirstWordIsStillShown() {
var result: BioLines? = null
composeRule.setContent {
val measurer = rememberTextMeasurer()
result =
splitBioCollapsed(
measurer,
"Supercalifragilisticexpialidocious and the rest",
TextStyle(fontSize = 14.sp),
20,
0,
"More",
)
}
composeRule.waitForIdle()
val lines = requireNotNull(result)
assertTrue(lines.more)
assertTrue(
lines.lines
.first()
.text
.isNotBlank(),
)
}
private fun album(
id: String,
name: String,