From db13a29bbfbec43f1c7f976f35596562951f4878 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Sat, 4 Apr 2026 22:03:58 +0530 Subject: [PATCH] test(android): cover talk.speak playback helpers --- .../openclaw/app/voice/TalkAudioPlayerTest.kt | 44 ++++++++ .../openclaw/app/voice/TalkSpeakClientTest.kt | 106 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 apps/android/app/src/test/java/ai/openclaw/app/voice/TalkAudioPlayerTest.kt create mode 100644 apps/android/app/src/test/java/ai/openclaw/app/voice/TalkSpeakClientTest.kt diff --git a/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkAudioPlayerTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkAudioPlayerTest.kt new file mode 100644 index 00000000000..b19d0b0ae8d --- /dev/null +++ b/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkAudioPlayerTest.kt @@ -0,0 +1,44 @@ +package ai.openclaw.app.voice + +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test + +class TalkAudioPlayerTest { + @Test + fun resolvesPcmPlaybackFromOutputFormat() { + val mode = + TalkAudioPlayer.resolvePlaybackMode( + outputFormat = "pcm_24000", + mimeType = null, + fileExtension = null, + ) + + assertEquals(TalkPlaybackMode.Pcm(sampleRate = 24_000), mode) + } + + @Test + fun resolvesCompressedPlaybackFromMimeType() { + val mode = + TalkAudioPlayer.resolvePlaybackMode( + outputFormat = null, + mimeType = "audio/mpeg", + fileExtension = null, + ) + + assertEquals(TalkPlaybackMode.Compressed(fileExtension = ".mp3"), mode) + } + + @Test + fun preservesProvidedExtensionForCompressedPlayback() { + val mode = + TalkAudioPlayer.resolvePlaybackMode( + outputFormat = null, + mimeType = "audio/webm", + fileExtension = "webm", + ) + + assertTrue(mode is TalkPlaybackMode.Compressed) + assertEquals(".webm", (mode as TalkPlaybackMode.Compressed).fileExtension) + } +} diff --git a/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkSpeakClientTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkSpeakClientTest.kt new file mode 100644 index 00000000000..139403953d8 --- /dev/null +++ b/apps/android/app/src/test/java/ai/openclaw/app/voice/TalkSpeakClientTest.kt @@ -0,0 +1,106 @@ +package ai.openclaw.app.voice + +import ai.openclaw.app.gateway.GatewayConnectErrorDetails +import ai.openclaw.app.gateway.GatewaySession +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test + +class TalkSpeakClientTest { + @Test + fun buildsRequestFromDirective() { + val request = + TalkSpeakRequest.from( + text = "Hello from talk mode.", + directive = + TalkDirective( + voiceId = "voice-123", + modelId = "model-abc", + speed = 1.1, + rateWpm = 190, + stability = 0.5, + similarity = 0.7, + style = 0.2, + speakerBoost = true, + seed = 42, + normalize = "auto", + language = "en", + outputFormat = "pcm_24000", + latencyTier = 3, + once = true, + ), + ) + + assertEquals("Hello from talk mode.", request.text) + assertEquals("voice-123", request.voiceId) + assertEquals("model-abc", request.modelId) + assertEquals(1.1, request.speed) + assertEquals(190, request.rateWpm) + assertEquals(0.5, request.stability) + assertEquals(0.7, request.similarity) + assertEquals(0.2, request.style) + assertEquals(true, request.speakerBoost) + assertEquals(42L, request.seed) + assertEquals("auto", request.normalize) + assertEquals("en", request.language) + assertEquals("pcm_24000", request.outputFormat) + assertEquals(3, request.latencyTier) + } + + @Test + fun fallsBackOnlyForUnavailableReasons() = runTest { + val client = + TalkSpeakClient( + requestDetailed = { _, _, _ -> + GatewaySession.RpcResult( + ok = false, + payloadJson = null, + error = + GatewaySession.ErrorShape( + code = "UNAVAILABLE", + message = "talk unavailable", + details = + GatewayConnectErrorDetails( + code = null, + canRetryWithDeviceToken = false, + recommendedNextStep = null, + reason = "talk_unconfigured", + ), + ), + ) + }, + ) + + val result = client.synthesize(text = "Hello", directive = null) + assertTrue(result is TalkSpeakResult.FallbackToLocal) + } + + @Test + fun doesNotFallBackForSynthesisFailure() = runTest { + val client = + TalkSpeakClient( + requestDetailed = { _, _, _ -> + GatewaySession.RpcResult( + ok = false, + payloadJson = null, + error = + GatewaySession.ErrorShape( + code = "UNAVAILABLE", + message = "provider failed", + details = + GatewayConnectErrorDetails( + code = null, + canRetryWithDeviceToken = false, + recommendedNextStep = null, + reason = "synthesis_failed", + ), + ), + ) + }, + ) + + val result = client.synthesize(text = "Hello", directive = null) + assertTrue(result is TalkSpeakResult.Failure) + } +}