Add recent-photo entry points to face recognition and its result page, preserve selection on back navigation, and reuse photo selection and payment flows. Switch face search to v3 with server defaults. Include cropped guidance audio, request and UI coverage, and verification artifacts.
53 lines
2.6 KiB
Kotlin
53 lines
2.6 KiB
Kotlin
package com.yzx.kiosk.audio
|
|
|
|
import androidx.media3.common.MediaItem
|
|
import androidx.media3.common.Player
|
|
import androidx.media3.exoplayer.ExoPlayer
|
|
import androidx.test.platform.app.InstrumentationRegistry
|
|
import com.yzx.kiosk.R
|
|
import com.yzx.kiosk.navigation.routes.AppRoutes
|
|
import org.junit.Assert.*
|
|
import org.junit.Test
|
|
import java.util.concurrent.atomic.AtomicInteger
|
|
|
|
class LocalAudioPlaybackTest {
|
|
@Test fun recentAndFaceEntriesSwitchAudioWithoutDuplicatePlayback() {
|
|
val instrumentation = InstrumentationRegistry.getInstrumentation()
|
|
lateinit var service: LocalAudioPlayService
|
|
lateinit var player: ExoPlayer
|
|
val transitions = AtomicInteger()
|
|
instrumentation.runOnMainSync {
|
|
service = LocalAudioPlayService(instrumentation.targetContext)
|
|
player = LocalAudioPlayService::class.java.getDeclaredField("exoPlayer").apply { isAccessible = true }.get(service) as ExoPlayer
|
|
player.addListener(object : Player.Listener {
|
|
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) { transitions.incrementAndGet() }
|
|
})
|
|
}
|
|
try {
|
|
instrumentation.runOnMainSync { service.playByRoute(AppRoutes.buildRecentPhotosRoute()) }
|
|
awaitPlaying(service)
|
|
assertEquals(R.raw.recent_photos_result_page, service.currentResId.value)
|
|
assertEquals(1, transitions.get())
|
|
instrumentation.runOnMainSync { service.playByRoute(AppRoutes.buildRecentPhotosRoute()) }
|
|
instrumentation.waitForIdleSync()
|
|
assertEquals("Repeated recent entry must not reset the media item", 1, transitions.get())
|
|
|
|
instrumentation.runOnMainSync { service.playByRoute("${AppRoutes.FACE_RECOGNITION_RESULT}?results=%5B%5D&source=face") }
|
|
awaitPlaying(service)
|
|
assertEquals(R.raw.face_recognition_success_result_page, service.currentResId.value)
|
|
assertEquals(2, transitions.get())
|
|
instrumentation.runOnMainSync { service.playByRoute(AppRoutes.FACE_RECOGNITION_RESULT) }
|
|
instrumentation.waitForIdleSync()
|
|
assertEquals("Legacy face route uses the same success clip", 2, transitions.get())
|
|
} finally {
|
|
instrumentation.runOnMainSync { service.release() }
|
|
}
|
|
}
|
|
|
|
private fun awaitPlaying(service: LocalAudioPlayService) {
|
|
val deadline = System.currentTimeMillis() + 5000
|
|
while (!service.isPlaying.value && System.currentTimeMillis() < deadline) Thread.sleep(20)
|
|
assertTrue("Local audio should enter playback", service.isPlaying.value)
|
|
}
|
|
}
|