Files
immich-folio/lib/__tests__/proofExport.test.ts

53 lines
1.7 KiB
TypeScript
Raw Normal View History

import { describe, it, expect } from 'vitest';
import { baseName, formatExport } from '../proofExport';
const picks = [
{ position: 3, fileName: 'IMG_0412.JPG', takenAt: '2026-05-01T10:00:00' },
{ position: 7, fileName: 'IMG_0412.CR3' },
{ position: 9, fileName: 'wedding "first", look.jpg' },
];
describe('baseName', () => {
it('drops only the last extension', () => {
expect(baseName('IMG_0412.JPG')).toBe('IMG_0412');
expect(baseName('a.b.tif')).toBe('a.b');
expect(baseName('.hidden')).toBe('.hidden');
expect(baseName('noext')).toBe('noext');
});
});
describe('formatExport', () => {
it('lists de-duplicated base names for a Lightroom filter', () => {
expect(formatExport(picks, 'lightroom')).toBe('IMG_0412, wedding "first", look');
});
it('lists full names one per line', () => {
expect(formatExport(picks, 'txt')).toBe(
'IMG_0412.JPG\nIMG_0412.CR3\nwedding "first", look.jpg\n',
);
expect(formatExport([], 'txt')).toBe('');
});
it('writes RFC 4180 CSV', () => {
expect(formatExport(picks, 'csv').split('\r\n')).toEqual([
'position,file_name,taken_at',
'3,IMG_0412.JPG,2026-05-01T10:00:00',
'7,IMG_0412.CR3,',
'9,"wedding ""first"", look.jpg",',
'',
]);
});
it('never lets a file name become a spreadsheet formula', () => {
const csv = formatExport([{ position: 1, fileName: '=HYPERLINK("x")' }], 'csv');
expect(csv).toContain(`"'=HYPERLINK(""x"")"`);
});
it('also neutralises names starting with a tab or carriage return', () => {
for (const name of ['\t=1+1', '\r=1+1']) {
const row = formatExport([{ position: 1, fileName: name }], 'csv').split('\r\n')[1];
expect(row).toMatch(/^1,"?'/);
}
});
});