91 lines
4.1 KiB
TypeScript
91 lines
4.1 KiB
TypeScript
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
|
import { MaryttsClient, MaryttsIntegration, type IMaryttsAudioResult } from '../../ts/integrations/marytts/index.js';
|
|
|
|
tap.test('posts MaryTTS /process form data and returns audio bytes', async () => {
|
|
const originalFetch = globalThis.fetch;
|
|
const calls: Array<{ url: string; method?: string; body: string; contentType?: string }> = [];
|
|
globalThis.fetch = (async (inputArg: RequestInfo | URL, initArg?: RequestInit) => {
|
|
calls.push({
|
|
url: String(inputArg),
|
|
method: initArg?.method,
|
|
body: String(initArg?.body || ''),
|
|
contentType: (initArg?.headers as Record<string, string> | undefined)?.['content-type'],
|
|
});
|
|
return new Response(Buffer.from([0x52, 0x49, 0x46, 0x46]), { status: 200, headers: { 'content-type': 'audio/wav' } });
|
|
}) as typeof globalThis.fetch;
|
|
|
|
try {
|
|
const client = new MaryttsClient({ host: '127.0.0.1', port: 59126, effect: { Robot: 'amount:100.0;' } });
|
|
const result = await client.speak('Hello world', { codec: 'WAVE_FILE', language: 'en_US', effects: { Volume: 'amount:2.0;' } });
|
|
const params = new URLSearchParams(calls[0].body);
|
|
|
|
expect(calls[0].url).toEqual('http://127.0.0.1:59126/process');
|
|
expect(calls[0].method).toEqual('POST');
|
|
expect(calls[0].contentType).toEqual('application/x-www-form-urlencoded');
|
|
expect(params.get('INPUT_TEXT')).toEqual('Hello world');
|
|
expect(params.get('OUTPUT_TYPE')).toEqual('AUDIO');
|
|
expect(params.get('INPUT_TYPE')).toEqual('TEXT');
|
|
expect(params.get('LOCALE')).toEqual('en_US');
|
|
expect(params.get('AUDIO')).toEqual('WAVE_FILE');
|
|
expect(params.get('VOICE')).toEqual('cmu-slt-hsmm');
|
|
expect(params.get('effect_Robot_selected')).toEqual('on');
|
|
expect(params.get('effect_Robot_parameters')).toEqual('amount:100.0;');
|
|
expect(params.get('effect_Volume_selected')).toEqual('on');
|
|
expect(result.format).toEqual('wav');
|
|
expect(result.contentType).toEqual('audio/wav');
|
|
expect(Buffer.isBuffer(result.audio)).toBeTrue();
|
|
expect(result.audio.toString('ascii')).toEqual('RIFF');
|
|
} finally {
|
|
globalThis.fetch = originalFetch;
|
|
}
|
|
});
|
|
|
|
tap.test('routes tts.speak through the MaryTTS runtime and reports HTTP failures', async () => {
|
|
const originalFetch = globalThis.fetch;
|
|
const calls: string[] = [];
|
|
globalThis.fetch = (async (inputArg: RequestInfo | URL, initArg?: RequestInit) => {
|
|
calls.push(`${initArg?.method || 'GET'} ${String(inputArg)}`);
|
|
if (String(inputArg).endsWith('/process')) {
|
|
return new Response(Buffer.from([1, 2, 3]), { status: 200, headers: { 'content-type': 'audio/aiff' } });
|
|
}
|
|
return new Response('MaryTTS demo', { status: 200 });
|
|
}) as typeof globalThis.fetch;
|
|
|
|
try {
|
|
const runtime = await new MaryttsIntegration().setup({ url: 'http://mary.test/base', codec: 'AIFF_FILE' }, {});
|
|
const result = await runtime.callService?.({
|
|
domain: 'tts',
|
|
service: 'speak',
|
|
target: {},
|
|
data: { message: 'Runtime hello', options: { effect: { Robot: 'amount:100.0;' } } },
|
|
});
|
|
const audio = (result?.data as IMaryttsAudioResult).audio;
|
|
|
|
expect(result?.success).toBeTrue();
|
|
expect((result?.data as IMaryttsAudioResult).format).toEqual('aiff');
|
|
expect(Buffer.isBuffer(audio)).toBeTrue();
|
|
expect(calls.includes('POST http://mary.test/base/process')).toBeTrue();
|
|
|
|
await runtime.destroy();
|
|
} finally {
|
|
globalThis.fetch = originalFetch;
|
|
}
|
|
});
|
|
|
|
tap.test('does not report MaryTTS synthesis success on non-2xx response', async () => {
|
|
const originalFetch = globalThis.fetch;
|
|
globalThis.fetch = (async () => new Response('boom', { status: 500 })) as typeof globalThis.fetch;
|
|
|
|
try {
|
|
const runtime = await new MaryttsIntegration().setup({ host: '127.0.0.1', port: 59126 }, {});
|
|
const result = await runtime.callService?.({ domain: 'tts', service: 'speak', target: {}, data: { message: 'fail' } });
|
|
expect(result?.success).toBeFalse();
|
|
expect(result?.error?.includes('HTTP 500')).toBeTrue();
|
|
await runtime.destroy();
|
|
} finally {
|
|
globalThis.fetch = originalFetch;
|
|
}
|
|
});
|
|
|
|
export default tap.start();
|