import { buildDictionaryHints, createDeepgramSttUrl, createInternalSttGatewayUrl, MAX_STT_AUDIO_BYTES, normalizeSttResult, SttInputError, validateSttAudio, } from './stt-contract.ts' function assert(condition: boolean, message: string): asserts condition { if (!condition) throw new Error(message) } Deno.test('STT input contract accepts real supported audio and preserves its type', () => { const audio = new Blob([new Uint8Array([1, 2, 3])], { type: 'audio/mp4' }) const result = validateSttAudio(audio, 'ko') assert(result.fileName === 'audio.m4a', 'm4a filename was not preserved') assert(result.contentType === 'audio/mp4', 'content type was not preserved') assert(result.languageCode === 'ko', 'language was not normalized') }) Deno.test('STT input contract rejects empty, oversized, disguised, and invalid-language input', () => { const cases: Array<() => unknown> = [ () => validateSttAudio(new Blob([], { type: 'audio/wav' }), 'ko'), () => validateSttAudio( new Blob([new Uint8Array(MAX_STT_AUDIO_BYTES + 1)], { type: 'audio/wav' }), 'ko', ), () => validateSttAudio(new Blob(['not audio'], { type: 'text/plain' }), 'ko'), () => validateSttAudio(new Blob(['x'], { type: 'audio/wav' }), 'ko&keyterm=forged'), ] for (const run of cases) { let caught: unknown = null try { run() } catch (error) { caught = error } assert(caught instanceof SttInputError, 'invalid input was not rejected') } }) Deno.test('dictionary hints are bounded, normalized, and de-duplicated', () => { const hints = buildDictionaryHints([ { word: ' D3RO\nVoice ', pronunciation: '디쓰리로 보이스' }, { word: 'd3ro voice', pronunciation: 'duplicate' }, { word: 'Supabase', pronunciation: null }, { word: '', pronunciation: 'ignored' }, ]) assert(hints.keyterms.length === 2, 'duplicate or empty terms were not removed') assert(hints.prompt === 'D3RO Voice (디쓰리로 보이스), Supabase', 'prompt was not normalized') assert(hints.prompt.length <= 900, 'prompt exceeded its provider bound') }) Deno.test('Deepgram Nova-3 uses repeated encoded keyterm parameters', () => { const url = new URL(createDeepgramSttUrl('ko', ['D3RO Voice', '수파베이스'])) assert(url.searchParams.get('model') === 'nova-3', 'Nova-3 was not selected') assert(url.searchParams.getAll('keyterm').length === 2, 'keyterms were not repeated') assert(url.searchParams.getAll('keyterm')[0] === 'D3RO Voice', 'keyterm encoding changed its value') }) Deno.test('STT result contract accepts only bounded real provider output', () => { const result = normalizeSttResult({ transcript: ' 실제 전사 결과 ', confidence: 0.97, language_code: 'KO', duration_seconds: 12.5, provider: 'd3ro-gateway', }) assert(result.transcript === '실제 전사 결과', 'transcript was not normalized') assert(result.language_code === 'ko', 'language was not normalized') for (const value of [ { ...result, transcript: ' ' }, { ...result, confidence: Number.NaN }, { ...result, confidence: 2 }, { ...result, language_code: 'auto' }, { ...result, duration_seconds: -1 }, { ...result, provider: 'invalid provider' }, ]) { let rejected = false try { normalizeSttResult(value) } catch { rejected = true } assert(rejected, 'invalid provider output was accepted') } }) Deno.test('internal gateway URL never leaks its service token over public HTTP', () => { assert( createInternalSttGatewayUrl('https://voice.example.com/base') === 'https://voice.example.com/api/stt/internal/transcribe', 'HTTPS gateway path is not canonical', ) assert( createInternalSttGatewayUrl('http://host.docker.internal:5000') === 'http://host.docker.internal:5000/api/stt/internal/transcribe', 'known local Docker gateway was rejected', ) for (const unsafe of ['http://public.example.com', 'ftp://voice.example.com', 'https://user:pass@voice.example.com']) { let rejected = false try { createInternalSttGatewayUrl(unsafe) } catch { rejected = true } assert(rejected, 'unsafe gateway origin was accepted') } })