v2026.06.03 — Media3 like button + Bluetooth/UPnP picker + system playlist daily rotation #77

Merged
bvandeusen merged 29 commits from dev into main 2026-06-03 14:09:23 -04:00
3 changed files with 11 additions and 15 deletions
Showing only changes of commit 1f02813cc6 - Show all commits
+6
View File
@@ -187,6 +187,12 @@ dependencies {
testImplementation(libs.mockk)
testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.okhttp.mockwebserver)
// kxml2 — provides an org.xmlpull.v1 impl on the JVM unit-test
// classpath. Android's stock XmlPullParserFactory resolves to the
// android.jar Stub on JVM tests; kxml2 is picked up via service-
// provider lookup and makes XmlPullParserFactory.newInstance() work
// unconditionally so DeviceDescriptionTest runs in CI.
testImplementation(libs.kxml2)
// kotlin.test for assertEquals/assertNull/etc. — version managed by
// the applied Kotlin plugin so no explicit version pin needed.
testImplementation(kotlin("test"))
@@ -1,10 +1,7 @@
package com.fabledsword.minstrel.player.output.upnp
import okhttp3.HttpUrl.Companion.toHttpUrl
import org.junit.jupiter.api.Assumptions.assumeTrue
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.xmlpull.v1.XmlPullParserFactory
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
@@ -14,23 +11,14 @@ import kotlin.test.assertNull
*
* Android's stock `XmlPullParserFactory.newInstance()` resolves to a
* real impl on-device but resolves to the android.jar stub class on
* JVM unit tests unless an org.xmlpull impl (kxml2) is present on the
* test classpath. The @BeforeEach probe skips the suite gracefully on
* runners where the factory can't be constructed — keeps CI green on
* minimal classpaths while still running the assertions when the
* impl IS available (Android instrumentation, Robolectric, or any
* runner that bundles kxml2 transitively).
* JVM unit tests. kxml2 is added as a testImplementation dep so
* `XmlPullParserFactory.newInstance()` finds it via service-provider
* lookup on the test classpath; the tests run unconditionally.
*/
class DeviceDescriptionTest {
private val base = "http://192.168.1.50:1400/xml/device_description.xml".toHttpUrl()
@BeforeEach
fun skipIfStubFactory() {
val ok = runCatching { XmlPullParserFactory.newInstance().newPullParser() }.isSuccess
assumeTrue(ok, "XmlPullParserFactory unavailable on this JVM classpath")
}
@Test
fun `parses Sonos-shaped description`() {
val xml = """
+2
View File
@@ -34,6 +34,7 @@ mockk = "1.13.13"
compose-test = "1.7.5"
ktlint-gradle = "12.1.1"
detekt = "2.0.0-alpha.3"
kxml2 = "2.3.0"
[libraries]
androidx-core-ktx = { module = "androidx.core:core-ktx", version = "1.13.1" }
@@ -89,6 +90,7 @@ turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" }
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
compose-ui-test = { module = "androidx.compose.ui:ui-test-junit4" }
compose-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest" }
kxml2 = { module = "net.sf.kxml:kxml2", version.ref = "kxml2" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }