openreader/tests/unit/tts-audio-format.vitest.spec.ts
Richard R e85641bcfe refactor(tts): enhance mp3 format detection and improve ffmpeg abort handling
Update audio format sniffing to require a full 10-byte ID3 header for mp3 detection and add stricter validation of MPEG frame headers to avoid false positives. Refactor ffmpeg process spawning to register abort listeners before module import, ensuring abort signals are handled promptly and preventing orphaned processes. Expand tests to cover edge cases in mp3 header detection.
2026-06-09 09:58:40 -06:00

59 lines
2.1 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { sniffAudioFormat } from '@/lib/server/tts/audio-format';
function bytes(...values: number[]): Buffer {
return Buffer.from(values);
}
describe('sniffAudioFormat', () => {
it('detects wav from RIFF/WAVE header', () => {
const wav = Buffer.concat([
Buffer.from('RIFF'),
bytes(0x24, 0x00, 0x00, 0x00),
Buffer.from('WAVE'),
]);
expect(sniffAudioFormat(wav)).toBe('wav');
});
it('detects ogg', () => {
expect(sniffAudioFormat(Buffer.from('OggS....'))).toBe('ogg');
});
it('detects flac', () => {
expect(sniffAudioFormat(Buffer.from('fLaC....'))).toBe('flac');
});
it('detects ID3-tagged mp3 with a full 10-byte header', () => {
// "ID3" + version(2) + flags(1) + size(4) = 10 bytes
const id3 = Buffer.concat([Buffer.from('ID3'), bytes(0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21)]);
expect(sniffAudioFormat(id3)).toBe('mp3');
});
it('does not claim mp3 on a truncated ID3 header', () => {
expect(sniffAudioFormat(Buffer.concat([Buffer.from('ID3'), bytes(0x03, 0x00)]))).toBe('unknown');
});
it('does not claim mp3 on a frame sync with an invalid header', () => {
// valid 11-bit sync + nonzero layer, but bitrate index 0b1111 ("bad")
expect(sniffAudioFormat(bytes(0xff, 0xfb, 0xf0, 0x00))).toBe('unknown');
});
it('detects mp3 frame sync (MPEG-1 Layer III)', () => {
expect(sniffAudioFormat(bytes(0xff, 0xfb, 0x90, 0x00))).toBe('mp3');
});
it('detects mp3 frame sync (MPEG-2 Layer III)', () => {
expect(sniffAudioFormat(bytes(0xff, 0xf3, 0x00, 0x00))).toBe('mp3');
});
it('distinguishes ADTS aac from mp3 via the layer bits', () => {
expect(sniffAudioFormat(bytes(0xff, 0xf1, 0x00, 0x00))).toBe('aac');
expect(sniffAudioFormat(bytes(0xff, 0xf9, 0x00, 0x00))).toBe('aac');
});
it('returns unknown for unrecognized or short buffers', () => {
expect(sniffAudioFormat(bytes(0x00, 0x01, 0x02, 0x03))).toBe('unknown');
expect(sniffAudioFormat(bytes(0x00))).toBe('unknown');
expect(sniffAudioFormat(Buffer.alloc(0))).toBe('unknown');
});
});