66 lines
2.4 KiB
TypeScript
66 lines
2.4 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import { sanitizeFilename } from './youtube'
|
|
|
|
describe('sanitizeFilename', () => {
|
|
it('replaces special characters with underscores', () => {
|
|
expect(sanitizeFilename('My Video!@#$%')).toBe('My_Video_')
|
|
expect(sanitizeFilename('hello world')).toBe('hello_world')
|
|
expect(sanitizeFilename('file/with\\slashes')).toBe('file_with_slashes')
|
|
})
|
|
|
|
it('collapses multiple underscores', () => {
|
|
expect(sanitizeFilename('a!!!b')).toBe('a_b')
|
|
expect(sanitizeFilename('test file')).toBe('test_file')
|
|
expect(sanitizeFilename('no___multiple___underscores')).toBe('no_multiple_underscores')
|
|
})
|
|
|
|
it('preserves alphanumeric characters', () => {
|
|
expect(sanitizeFilename('Video123')).toBe('Video123')
|
|
expect(sanitizeFilename('ABC_xyz_123')).toBe('ABC_xyz_123')
|
|
expect(sanitizeFilename('simple')).toBe('simple')
|
|
})
|
|
|
|
it('truncates to 200 characters', () => {
|
|
const longName = 'a'.repeat(250)
|
|
expect(sanitizeFilename(longName).length).toBe(200)
|
|
expect(sanitizeFilename(longName)).toBe('a'.repeat(200))
|
|
})
|
|
|
|
it('handles edge cases', () => {
|
|
expect(sanitizeFilename('')).toBe('')
|
|
expect(sanitizeFilename(' ')).toBe('_')
|
|
expect(sanitizeFilename('___')).toBe('_')
|
|
})
|
|
|
|
it('handles unicode and emoji', () => {
|
|
expect(sanitizeFilename('日本語タイトル')).toBe('_')
|
|
expect(sanitizeFilename('Café')).toBe('Caf_')
|
|
expect(sanitizeFilename('🎵 Music 🎵')).toBe('_Music_')
|
|
})
|
|
|
|
it('handles typical YouTube video titles', () => {
|
|
expect(sanitizeFilename('Never Gonna Give You Up (Official Video)')).toBe('Never_Gonna_Give_You_Up_Official_Video_')
|
|
expect(sanitizeFilename("Lofi Hip Hop Radio 📚 - Beats to Relax/Study")).toBe('Lofi_Hip_Hop_Radio_Beats_to_Relax_Study')
|
|
expect(sanitizeFilename('[4K] Amazing Nature Video')).toBe('_4K_Amazing_Nature_Video')
|
|
expect(sanitizeFilename('Song Title | Artist Name (Lyrics)')).toBe('Song_Title_Artist_Name_Lyrics_')
|
|
})
|
|
})
|
|
|
|
describe('format selection logic', () => {
|
|
it('maps audio formats correctly', () => {
|
|
const audioFormats = ['mp3', 'wav', 'm4a', 'opus'] as const
|
|
|
|
audioFormats.forEach((format) => {
|
|
expect(['mp3', 'wav', 'm4a', 'opus']).toContain(format)
|
|
})
|
|
})
|
|
|
|
it('maps video formats correctly', () => {
|
|
const videoFormats = ['mp4', 'webm', 'mkv', 'avi'] as const
|
|
|
|
videoFormats.forEach((format) => {
|
|
expect(['mp4', 'webm', 'mkv', 'avi']).toContain(format)
|
|
})
|
|
})
|
|
})
|