SPB Git

Repository Public

names.test.ts 2.4 KB 46 lines typescript

1import { describe, expect, it } from 'vitest';2import { extOf, nameKey, nextFreeName, previewKind, safePathSegments, sanitizeName, splitExt } from '../src/index.ts';34describe('sanitizeName', () => {5  it('neutralises paths, control characters and reserved names', () => {6    expect(sanitizeName('../../etc/passwd')).toBe('_.._etc_passwd');7    expect(sanitizeName('..')).toBe('sans-nom');8    expect(sanitizeName('.htaccess')).toBe('htaccess');9    expect(sanitizeName('a\u0000b\nc.txt')).toBe('a_b_c.txt');10    expect(sanitizeName('C:\\Windows\\cmd.exe')).toBe('C__Windows_cmd.exe');11    expect(sanitizeName('CON.txt')).toBe('_CON.txt');12    expect(sanitizeName('  rapport final .pdf.  ')).toBe('rapport final .pdf');13    expect(sanitizeName('facture\u202Efdp.exe')).toBe('facture_fdp.exe'); // right-to-left override trick14    expect(sanitizeName('')).toBe('sans-nom');15  });16  it('never returns a separator or a name over 255 bytes', () => {17    const long = sanitizeName(`${'é'.repeat(400)}.pdf`);18    expect(new TextEncoder().encode(long).length).toBeLessThanOrEqual(255);19    expect(long.endsWith('.pdf')).toBe(true);20    for (const raw of ['a/b', 'a\\b', '/abs', '~/x', 'x/../../y']) expect(sanitizeName(raw)).not.toMatch(/[/\\]/);21  });22  it('normalises Unicode so two spellings of one name collide', () => {23    expect(nameKey(sanitizeName('Cafe\u0301.TXT'))).toBe(nameKey(sanitizeName('Café.txt')));24  });25});26describe('names', () => {27  it('splits extensions', () => {28    expect(splitExt('archive.tar.gz')).toEqual(['archive', '.tar.gz']);29    expect(splitExt('README')).toEqual(['README', '']);30    expect(extOf('Photo.HEIC')).toBe('heic');31  });32  it('finds the next free name', () => {33    const taken = new Set(['a.txt', 'a (2).txt']);34    expect(nextFreeName('a.txt', (k) => taken.has(k))).toBe('a (3).txt');35    expect(nextFreeName('b.txt', (k) => taken.has(k))).toBe('b.txt');36  });37  it('keeps relative paths inside the tree', () => {38    expect(safePathSegments('../../a/./b/../c.txt')).toEqual(['a', 'b', 'c.txt']);39    expect(safePathSegments('/etc/passwd')).toEqual(['etc', 'passwd']);40  });41  it('classifies previews by name', () => {42    expect(previewKind('x.pdf')).toBe('pdf'); expect(previewKind('x.HEIC')).toBe('heic'); expect(previewKind('x.tar.gz')).toBe('archive');43    expect(previewKind('x.gz')).toBe('none'); expect(previewKind('x.docx')).toBe('office'); expect(previewKind('x.xlsx')).toBe('sheet'); expect(previewKind('x.bin')).toBe('none');44  });45});46
Files main
Menu

Theme