mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 23:21:59 +01:00
address review: localize connection errors, tighten i18n guard, drop dead resources
- AddSourceViewModel resolves SubsonicException.uiMessage too, so malformed/ HTTP/truncated responses show localized text instead of the raw parser message; add a regression test. - StringResourcesTest now requires an 'other' quantity in every plural and asserts exact placeholder (index and conversion) equality, both of which could previously pass while crashing getQuantityString at runtime. - Map the pre-enum song_downloads.error sentences back to their DownloadError so existing failed rows keep their specific message. - Localize the media-session star/unstar button label. - Remove 12 unreferenced resources (queue name, filter year, sync_failed, and the unused codec_* strings; codec labels stay in AudioEncoding). - Make buildTree's fallback arguments required; only tests used the defaults.
This commit is contained in:
@@ -24,6 +24,12 @@ class StringResourcesTest {
|
||||
val default = parse(defaultFile)
|
||||
assertTrue("default strings.xml should not be empty", default.isNotEmpty())
|
||||
|
||||
default.forEach { (name, resource) ->
|
||||
if (resource.kind == "plurals") {
|
||||
assertTrue("$name in values/strings.xml is missing the required 'other' quantity", "other" in resource.quantities)
|
||||
}
|
||||
}
|
||||
|
||||
localeFiles().forEach { file ->
|
||||
val locale = parse(file)
|
||||
locale.forEach { (name, resource) ->
|
||||
@@ -35,12 +41,12 @@ class StringResourcesTest {
|
||||
"$name has an invalid quantity in ${file.parentFile.name}",
|
||||
resource.quantities.all { it in validQuantities },
|
||||
)
|
||||
assertTrue("$name in ${file.parentFile.name} is missing the required 'other' quantity", "other" in resource.quantities)
|
||||
}
|
||||
val baseArgs = placeholderIndices(base.text)
|
||||
val localeArgs = placeholderIndices(resource.text)
|
||||
assertTrue(
|
||||
"$name in ${file.parentFile.name} uses placeholders $localeArgs not present in the default $baseArgs",
|
||||
baseArgs.containsAll(localeArgs),
|
||||
assertEquals(
|
||||
"$name placeholders differ in ${file.parentFile.name}",
|
||||
placeholders(base.text),
|
||||
placeholders(resource.text),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -84,6 +90,6 @@ class StringResourcesTest {
|
||||
return (0 until items.length).joinToString(" ") { items.item(it).textContent }
|
||||
}
|
||||
|
||||
private fun placeholderIndices(text: String): Set<Int> =
|
||||
Regex("""%(\d+)\$""").findAll(text).mapTo(mutableSetOf()) { it.groupValues[1].toInt() }
|
||||
private fun placeholders(text: String): Map<Int, Char> =
|
||||
Regex("""%(\d+)\$([a-zA-Z])""").findAll(text).associate { it.groupValues[1].toInt() to it.groupValues[2][0] }
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ class DownloadTreeTest {
|
||||
song("s3", "Three", "ar1", "Artist", "al2", "Second", size = 5),
|
||||
song("s4", "Four", "ar2", "Other", "al3", "Third", size = 1),
|
||||
),
|
||||
"Unknown artist",
|
||||
"Unknown album",
|
||||
)
|
||||
|
||||
assertEquals(listOf("Artist", "Other"), tree.artists.map { it.name })
|
||||
@@ -37,7 +39,7 @@ class DownloadTreeTest {
|
||||
|
||||
@Test
|
||||
fun aSongWithNoArtistOrAlbumIsStillShown() {
|
||||
val tree = buildTree(listOf(song("s1", "One", null, null, null, null, size = 3)))
|
||||
val tree = buildTree(listOf(song("s1", "One", null, null, null, null, size = 3)), "Unknown artist", "Unknown album")
|
||||
|
||||
val artist = tree.artists.single()
|
||||
assertEquals("Unknown artist", artist.name)
|
||||
|
||||
@@ -104,6 +104,20 @@ class AddSourceViewModelTest {
|
||||
assertEquals("Failed: Wrong username", state.message)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun aMalformedResponseIsReportedWithTheLocalizedMessage() {
|
||||
val viewModel = viewModel()
|
||||
viewModel.setAddress(server.url("/").toString())
|
||||
viewModel.setUsername("u")
|
||||
viewModel.setPassword("p")
|
||||
server.enqueue(MockResponse().setBody("not an xml document"))
|
||||
|
||||
viewModel.testConnection()
|
||||
await { !viewModel.state.value.busy && viewModel.state.value.isError }
|
||||
|
||||
assertEquals("Malformed response from the server", viewModel.state.value.message)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun aSuccessfulPingClearsAnEarlierError() {
|
||||
val viewModel = viewModel()
|
||||
|
||||
Reference in New Issue
Block a user