/**
* Unit tests for validation utility
*/
import { describe, it, expect } from 'vitest';
import {
validateAudioUrl,
validateJobId,
isSupportedExtension,
getFileExtension,
formatSupportedFormats,
SUPPORTED_EXTENSIONS,
SUPPORTED_MIME_TYPES,
MAX_FILE_SIZE_MB,
} from '../../../src/utils/validation.js';
describe('validation utility', () => {
describe('validateAudioUrl', () => {
describe('valid URLs', () => {
it('should accept valid HTTPS URL with MP3', () => {
const result = validateAudioUrl('https://example.com/audio.mp3');
expect(result.valid).toBe(true);
expect(result.error).toBeUndefined();
});
it('should accept valid HTTP URL with WAV', () => {
const result = validateAudioUrl('http://example.com/audio.wav');
expect(result.valid).toBe(true);
});
it('should accept URL with FLAC extension', () => {
const result = validateAudioUrl('https://cdn.example.com/song.flac');
expect(result.valid).toBe(true);
});
it('should accept URL with OGG extension', () => {
const result = validateAudioUrl('https://example.com/audio.ogg');
expect(result.valid).toBe(true);
});
it('should accept URL with M4A extension', () => {
const result = validateAudioUrl('https://example.com/audio.m4a');
expect(result.valid).toBe(true);
});
it('should accept URL with query parameters', () => {
const result = validateAudioUrl('https://example.com/audio?file=song.mp3&token=abc');
expect(result.valid).toBe(true);
});
it('should trim whitespace from URL', () => {
const result = validateAudioUrl(' https://example.com/audio.mp3 ');
expect(result.valid).toBe(true);
});
it('should accept URL with uppercase extension', () => {
const result = validateAudioUrl('https://example.com/audio.MP3');
expect(result.valid).toBe(true);
});
});
describe('invalid URLs', () => {
it('should reject empty string', () => {
const result = validateAudioUrl('');
expect(result.valid).toBe(false);
expect(result.error?.code).toBe('INVALID_URL');
});
it('should reject whitespace only', () => {
const result = validateAudioUrl(' ');
expect(result.valid).toBe(false);
expect(result.error?.code).toBe('INVALID_URL');
});
it('should reject FTP URLs', () => {
const result = validateAudioUrl('ftp://example.com/audio.mp3');
expect(result.valid).toBe(false);
expect(result.error?.code).toBe('INVALID_URL');
});
it('should reject file:// URLs', () => {
const result = validateAudioUrl('file:///path/to/audio.mp3');
expect(result.valid).toBe(false);
expect(result.error?.code).toBe('INVALID_URL');
});
it('should reject malformed URLs', () => {
const result = validateAudioUrl('not a url at all');
expect(result.valid).toBe(false);
expect(result.error?.code).toBe('INVALID_URL');
});
it('should reject URL without extension and no query params', () => {
const result = validateAudioUrl('https://example.com/audio');
expect(result.valid).toBe(false);
expect(result.error?.code).toBe('UNSUPPORTED_FORMAT');
});
});
});
describe('validateJobId', () => {
describe('valid job IDs', () => {
it('should accept alphanumeric job ID', () => {
const result = validateJobId('abc123');
expect(result.valid).toBe(true);
});
it('should accept job ID with dashes', () => {
const result = validateJobId('job-123-abc');
expect(result.valid).toBe(true);
});
it('should accept job ID with underscores', () => {
const result = validateJobId('job_123_abc');
expect(result.valid).toBe(true);
});
it('should accept UUID-like job ID', () => {
const result = validateJobId('550e8400-e29b-41d4-a716-446655440000');
expect(result.valid).toBe(true);
});
it('should trim whitespace', () => {
const result = validateJobId(' job123 ');
expect(result.valid).toBe(true);
});
});
describe('invalid job IDs', () => {
it('should reject empty string', () => {
const result = validateJobId('');
expect(result.valid).toBe(false);
expect(result.error?.code).toBe('JOB_NOT_FOUND');
});
it('should reject whitespace only', () => {
const result = validateJobId(' ');
expect(result.valid).toBe(false);
expect(result.error?.code).toBe('JOB_NOT_FOUND');
});
it('should reject job ID with special characters', () => {
const result = validateJobId('job@123!');
expect(result.valid).toBe(false);
expect(result.error?.code).toBe('JOB_NOT_FOUND');
});
it('should reject job ID with spaces', () => {
const result = validateJobId('job 123');
expect(result.valid).toBe(false);
expect(result.error?.code).toBe('JOB_NOT_FOUND');
});
});
});
describe('isSupportedExtension', () => {
it('should return true for supported extensions', () => {
expect(isSupportedExtension('song.mp3')).toBe(true);
expect(isSupportedExtension('song.wav')).toBe(true);
expect(isSupportedExtension('song.flac')).toBe(true);
expect(isSupportedExtension('song.ogg')).toBe(true);
expect(isSupportedExtension('song.m4a')).toBe(true);
});
it('should return true for uppercase extensions', () => {
expect(isSupportedExtension('song.MP3')).toBe(true);
expect(isSupportedExtension('song.WAV')).toBe(true);
});
it('should return false for unsupported extensions', () => {
expect(isSupportedExtension('song.aac')).toBe(false);
expect(isSupportedExtension('song.wma')).toBe(false);
expect(isSupportedExtension('song.txt')).toBe(false);
});
it('should return false for no extension', () => {
expect(isSupportedExtension('song')).toBe(false);
});
});
describe('getFileExtension', () => {
it('should extract extension from filename', () => {
expect(getFileExtension('song.mp3')).toBe('.mp3');
expect(getFileExtension('my.song.wav')).toBe('.wav');
});
it('should extract extension from URL', () => {
expect(getFileExtension('https://example.com/audio.flac')).toBe('.flac');
expect(getFileExtension('https://example.com/path/to/audio.ogg')).toBe('.ogg');
});
it('should return lowercase extension', () => {
expect(getFileExtension('song.MP3')).toBe('.mp3');
expect(getFileExtension('https://example.com/AUDIO.WAV')).toBe('.wav');
});
it('should return null for no extension', () => {
expect(getFileExtension('song')).toBeNull();
expect(getFileExtension('https://example.com/audio')).toBeNull();
});
});
describe('formatSupportedFormats', () => {
it('should return formatted string of supported formats', () => {
const formatted = formatSupportedFormats();
expect(formatted).toContain('MP3');
expect(formatted).toContain('WAV');
expect(formatted).toContain('FLAC');
expect(formatted).toContain('OGG');
expect(formatted).toContain('M4A');
});
});
describe('constants', () => {
it('should have correct supported extensions', () => {
expect(SUPPORTED_EXTENSIONS).toContain('.mp3');
expect(SUPPORTED_EXTENSIONS).toContain('.wav');
expect(SUPPORTED_EXTENSIONS).toContain('.flac');
expect(SUPPORTED_EXTENSIONS).toContain('.ogg');
expect(SUPPORTED_EXTENSIONS).toContain('.m4a');
});
it('should have correct MIME types', () => {
expect(SUPPORTED_MIME_TYPES).toContain('audio/mpeg');
expect(SUPPORTED_MIME_TYPES).toContain('audio/wav');
expect(SUPPORTED_MIME_TYPES).toContain('audio/flac');
});
it('should have max file size of 100MB', () => {
expect(MAX_FILE_SIZE_MB).toBe(100);
});
});
});