import { describe, expect, it } from 'vitest'; import { createSafeVirtualFileName, safeFileName, safeOutputFileName, splitFileName, } from '../../../src/media/safe-file-name'; describe('safe filenames', () => { it('removes path traversal, control characters and shell-like punctuation', () => { expect(safeFileName('../../My $ video\u0000 (final).MP4')).toBe( 'My-video-final.mp4' ); expect(safeFileName('..\\..\\evil.webm')).toBe('evil.webm'); expect(safeFileName('../')).toBe('file'); }); it('handles Unicode, hidden names and reserved device names', () => { expect(safeFileName('Crème brûlée.mov')).toBe('Creme-brulee.mov'); expect(safeFileName('.env')).toBe('env'); expect(safeFileName('CON.mp4')).toBe('_CON.mp4'); }); it('preserves a short extension while enforcing the requested maximum', () => { const result = safeFileName(`${'a'.repeat(200)}.mp4`, { maxLength: 32, }); expect(result).toHaveLength(32); expect(result.endsWith('.mp4')).toBe(true); }); it('creates generated virtual names without leaking the original stem', () => { expect(createSafeVirtualFileName('private-holiday.mov', 3)).toBe( 'source-3.mov' ); expect(() => createSafeVirtualFileName('x.mp4', -1)).toThrow(); }); it('creates deterministic download names and splits compound extensions', () => { expect(safeOutputFileName('My export (1)', '.WEBM')).toBe( 'My-export-1.webm' ); expect(safeOutputFileName('Project', 'avproject.json')).toBe( 'Project.avproject.json' ); expect(safeOutputFileName('Project.v2', 'mp4')).toBe('Project.v2.mp4'); expect(splitFileName('archive.tar.gz')).toEqual({ stem: 'archive.tar', extension: '.gz', }); }); });