import { installPinnedHostnameTestHooks } from
"openclaw/plugin-sdk/testing" ;
import { afterEach, describe, expect, it, vi } from
"vitest" ;
import { gradiumTTS } from
"./tts.js" ;
describe(
"gradium tts diagnostics" , () => {
installPinnedHostnameTestHooks();
function createStreamingErrorResponse(params: {
status: number;
chunkCount: number;
chunkSize: number;
byte : number;
}): { response: Response; getReadCount: () => number } {
let reads =
0 ;
const stream =
new ReadableStream<Uint8Array>({
pull(controller) {
if (reads >= params.chunkCount) {
controller.close();
return ;
}
reads +=
1 ;
controller.enqueue(
new Uint8Array(params.chunkSize).fill(params.
byte ));
},
});
return {
response:
new Response(stream, { status: params.status }),
getReadCount: () => reads,
};
}
afterEach(() => {
vi.unstubAllGlobals();
vi.restoreAllMocks();
});
it(
"includes parsed provider detail and request id for JSON API errors" , async () => {
const fetchMock = vi.fn().mockResolvedValue(
new Response(
JSON.stringify({
message:
"Invalid API key" ,
}),
{
status:
401 ,
headers: {
"Content-Type" :
"application/json" ,
"x-request-id" :
"grad_req_123" ,
},
},
),
);
vi.stubGlobal(
"fetch" , fetchMock);
await expect(
gradiumTTS({
text:
"hello" ,
apiKey:
"bad-key" ,
baseUrl:
"https://api.gradium.ai ",
voiceId:
"YTpq7expH9539ERJ" ,
outputFormat:
"wav" ,
timeoutMs:
5 _
000 ,
}),
).rejects.toThrow(
"Gradium API error (401): Invalid API key [request_id=grad_req_123]" )
;
expect(fetchMock).toHaveBeenCalledOnce();
});
it("falls back to raw body text when the error body is non-JSON" , async () => {
vi.stubGlobal(
"fetch" ,
vi.fn().mockResolvedValue(new Response("service unavailable" , { status: 503 })),
);
await expect(
gradiumTTS({
text: "hello" ,
apiKey: "test-key" ,
baseUrl: "https://api.gradium.ai ",
voiceId: "YTpq7expH9539ERJ" ,
outputFormat: "wav" ,
timeoutMs: 5 _000 ,
}),
).rejects.toThrow("Gradium API error (503): service unavailable" );
});
it("caps streamed non-JSON error reads instead of consuming full response bodies" , async () => {
const streamed = createStreamingErrorResponse({
status: 503 ,
chunkCount: 200 ,
chunkSize: 1024 ,
byte : 121 ,
});
vi.stubGlobal("fetch" , vi.fn().mockResolvedValue(streamed.response));
await expect(
gradiumTTS({
text: "hello" ,
apiKey: "test-key" ,
baseUrl: "https://api.gradium.ai ",
voiceId: "YTpq7expH9539ERJ" ,
outputFormat: "wav" ,
timeoutMs: 5 _000 ,
}),
).rejects.toThrow("Gradium API error (503)" );
expect(streamed.getReadCount()).toBeLessThan(200 );
});
it("sends the correct request payload" , async () => {
const audioData = Buffer.from("fake-wav-data" );
const fetchMock = vi.fn().mockResolvedValue(new Response(audioData, { status: 200 }));
vi.stubGlobal("fetch" , fetchMock);
const result = await gradiumTTS({
text: "Hello world" ,
apiKey: "gsk_test123" ,
baseUrl: "https://api.gradium.ai ",
voiceId: "YTpq7expH9539ERJ" ,
outputFormat: "wav" ,
timeoutMs: 5 _000 ,
});
expect(fetchMock).toHaveBeenCalledOnce();
const [url, init] = fetchMock.mock.calls[0 ] as [string, RequestInit];
expect(url).toBe("https://api.gradium.ai/api/post/speech/tts ");
expect(init.method).toBe("POST" );
const headers = new Headers(init.headers);
expect(headers.get("x-api-key" )).toBe("gsk_test123" );
expect(headers.get("content-type" )).toBe("application/json" );
expect(JSON.parse(init.body as string)).toEqual({
text: "Hello world" ,
voice_id: "YTpq7expH9539ERJ" ,
only_audio: true ,
output_format: "wav" ,
json_config: '{"padding_bonus":0}' ,
});
expect(result).toEqual(audioData);
});
});
Messung V0.5 in Prozent C=97 H=100 G=98
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-06)
¤
*© Formatika GbR, Deutschland