test: live AITUNNEL integration test, skipped without AITUNNEL_API_KEY
Refs #5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QKHeGuAYh4W1jNdjMConZa
This commit is contained in:
parent
812ace7f3c
commit
87826bc427
39
tests/integration/aitunnel.test.ts
Normal file
39
tests/integration/aitunnel.test.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { DEFAULT_OPENAI, OpenAiTranscriber } from '../../src/core/openai';
|
||||
import type { HttpClient } from '../../src/core/ports';
|
||||
|
||||
// Ключ — только из окружения, никогда в репозитории.
|
||||
const KEY = process.env.AITUNNEL_API_KEY ?? '';
|
||||
|
||||
// Под Node нет requestUrl: тот же порт на fetch. contentType уходит заголовком.
|
||||
const fetchHttp: HttpClient = {
|
||||
async post(req) {
|
||||
const res = await fetch(req.url, {
|
||||
method: 'POST',
|
||||
headers: { ...req.headers, 'Content-Type': req.contentType },
|
||||
body: req.body,
|
||||
});
|
||||
return { status: res.status, text: await res.text() };
|
||||
},
|
||||
};
|
||||
|
||||
// Характерные слова эталона tests/fixtures/test-01.txt.
|
||||
const WORDS = ['тестовая', 'запись', 'проверки', 'распознавания', 'речи', 'whisper'];
|
||||
|
||||
describe.skipIf(!KEY)('AITUNNEL gpt-4o-transcribe (live)', () => {
|
||||
it('transcribes test-01.m4a', { timeout: 120_000 }, async () => {
|
||||
const audio = new Uint8Array(readFileSync(new URL('../fixtures/test-01.m4a', import.meta.url))).buffer;
|
||||
const reference = readFileSync(new URL('../fixtures/test-01.txt', import.meta.url), 'utf8').toLowerCase();
|
||||
for (const word of WORDS) expect(reference).toContain(word);
|
||||
|
||||
const t = new OpenAiTranscriber(fetchHttp, () => ({ ...DEFAULT_OPENAI, apiKey: KEY }), Math.random);
|
||||
const result = await t.transcribe(audio, 'audio/mp4', new AbortController().signal);
|
||||
|
||||
expect(result).toMatchObject({ ok: true });
|
||||
const text = result.ok ? result.text.toLowerCase() : '';
|
||||
expect(text.trim()).not.toBe('');
|
||||
const hits = WORDS.filter((w) => text.includes(w));
|
||||
expect(hits.length, `распознано: ${text}`).toBeGreaterThanOrEqual(4);
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user