d3ro-voice/packages/api-client/__tests__/transcribe.test.ts
Yun Chan 708e20f747
Some checks failed
CI Pipeline / Code Quality & Typecheck (push) Waiting to run
CI Pipeline / Test Suite (macos-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (ubuntu-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (windows-latest) (push) Blocked by required conditions
CI Pipeline / Build Validation (admin) (push) Blocked by required conditions
CI Pipeline / Build Validation (desktop) (push) Blocked by required conditions
Deploy Landing Page / deploy (push) Blocked by required conditions
Deploy Landing Page / build (push) Waiting to run
Release & Packaging Pipeline / Build & Publish Admin Docker Image (push) Failing after 8s
Release & Code Signing CA Pipeline / build-and-sign-windows (push) Failing after 1m51s
Build macOS / Build & Package (macOS) (push) Failing after 4s
Build macOS / Build & Package (macOS)-1 (push) Failing after 5s
Release & Code Signing CA Pipeline / build-and-sign-macos (push) Failing after 3s
Release & Packaging Pipeline / Package macOS Desktop App (push) Failing after 4s
Release & Packaging Pipeline / Package Windows Desktop App (push) Failing after 2m28s
Release & Packaging Pipeline / Publish Official GitHub Release (push) Has been skipped
feat: complete release preparation, 10+ ad mediation, CI/CD, and docker deployment
2026-08-20 11:12:05 +09:00

108 lines
3.4 KiB
TypeScript

// packages/api-client/__tests__/transcribe.test.ts
// transcribeAudio 함수 단위 및 통합 인터페이스 테스트
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { transcribeAudio } from '../src/transcribe'
describe('transcribeAudio', () => {
beforeEach(() => {
vi.restoreAllMocks()
})
it('Blob 입력 시 multipart/form-data로 /api/stt/transcribe를 호출하여 전사 결과를 반환한다', async () => {
const mockAudioBlob = new Blob(['mock-audio-content'], { type: 'audio/webm' })
const mockResponse = {
text: '안녕하세요, 클라우드 음성 전사 테스트입니다.',
confidence: 0.99,
language: 'ko',
durationSeconds: 2.5,
provider: 'groq',
modelId: 'whisper-large-v3-turbo',
latencyMs: 145,
cost: 0.000021,
}
const fetchMock = vi.fn().mockResolvedValue({
ok: true,
status: 200,
json: async () => mockResponse,
})
vi.stubGlobal('fetch', fetchMock)
const result = await transcribeAudio({
audio: mockAudioBlob,
language: 'ko',
apiBaseUrl: 'http://localhost:5000',
token: 'test-token',
})
expect(fetchMock).toHaveBeenCalledTimes(1)
const [url, options] = fetchMock.mock.calls[0]
expect(url).toBe('http://localhost:5000/api/stt/transcribe')
expect(options.method).toBe('POST')
expect(options.headers['Authorization']).toBe('Bearer test-token')
expect(options.body).toBeInstanceOf(FormData)
expect(result.text).toBe('안녕하세요, 클라우드 음성 전사 테스트입니다.')
expect(result.provider).toBe('groq')
expect(result.durationSeconds).toBe(2.5)
expect(result.latencyMs).toBe(145)
})
it('Base64 문자열 입력 시 JSON 페이로드로 전송한다', async () => {
const mockBase64 = 'UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQAAAAA='
const mockResponse = {
text: 'Base64 전사 성공',
confidence: 0.98,
language: 'ko',
durationSeconds: 1.0,
provider: 'openai',
modelId: 'whisper-1',
latencyMs: 320,
cost: 0.0001,
}
const fetchMock = vi.fn().mockResolvedValue({
ok: true,
status: 200,
json: async () => mockResponse,
})
vi.stubGlobal('fetch', fetchMock)
const result = await transcribeAudio({
audio: mockBase64,
language: 'ko',
prompt: '의료 용어 가이드',
apiBaseUrl: 'http://localhost:5000',
})
expect(fetchMock).toHaveBeenCalledTimes(1)
const [url, options] = fetchMock.mock.calls[0]
expect(url).toBe('http://localhost:5000/api/stt/transcribe')
expect(options.headers['Content-Type']).toBe('application/json')
const body = JSON.parse(options.body)
expect(body.audioBase64).toBe(mockBase64)
expect(body.language).toBe('ko')
expect(body.initialPrompt).toBe('의료 용어 가이드')
expect(result.text).toBe('Base64 전사 성공')
})
it('서버 응답이 4xx/5xx 실패 시 에러를 throw한다', async () => {
vi.stubGlobal(
'fetch',
vi.fn().mockResolvedValue({
ok: false,
status: 500,
text: async () => 'Internal STT Proxy Failure',
})
)
await expect(
transcribeAudio({
audio: new Blob(['data']),
apiBaseUrl: 'http://localhost:5000',
})
).rejects.toThrow('STT transcription failed (500): Internal STT Proxy Failure')
})
})