You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DateKeys-App/src/lib/inspector/files.test.ts

66 lines
3.6 KiB

// Tests of files.ts: the warnings of the paths, compared by their key of R7
// in the words of the CLI of the reference, the files as the page shows
// them, and the names and the order of the downloads.
import { describe, expect, it } from 'vitest';
import type { Head } from '../dkc/head.ts';
import { downloadFileName, downloads, fileFacts, pathWarnings, zipFileName } from './files.ts';
const GIT_INSIDE = 'está dentro de una carpeta .git, cuyos ganchos pueden ejecutar órdenes';
const GIT = 'se llama .git y puede apuntar a otro repositorio';
const INI = 'es la configuración de una carpeta de Windows';
const DASH = "un nombre que empieza por '-' puede tomarse por una opción en una orden";
const SHORTCUT = 'es un acceso directo de Windows: puede abrir otro programa o una dirección';
const PROGRAM = 'es un programa o un script: no lo ejecutes sin saber qué hace';
const file = (path: string, size = 1, mtime?: number) => ({ path, size, start: 0, end: size, sha256: new Uint8Array(32), ...(mtime === undefined ? {} : { mtime }) });
const head = (...paths: string[]): Head => ({ salt: new Uint8Array(32), comment: '', author: '', files: paths.map((p) => file(p)), critical: [], noncritical: [] });
describe('pathWarnings', () => {
it.each([
['nota.txt', []],
['.bashrc', []],
['.git/config', [GIT_INSIDE]],
['repo/.GIT', [GIT]],
['repo/.g\u200dit', [GIT]],
['Desktop.INI', [INI]],
['fotos/-rf', [DASH]],
['Informe.LNK', [SHORTCUT]],
['enlaces/web.url', [SHORTCUT]],
['b\u00fasqueda.searchConnector-ms', [SHORTCUT]],
['x/instalar.EXE', [PROGRAM]],
['a.b.ps1', [PROGRAM]],
['Programa.app', [PROGRAM]],
['-x/.git/y.bat', [DASH, GIT_INSIDE, PROGRAM]],
] as const)('%s', (path, want) => {
expect(pathWarnings(path)).toEqual(want);
});
});
describe('fileFacts', () => {
it('shows each path as text, escaped, with its name, size, mtime in milliseconds and warnings', () => {
const h: Head = { ...head(), files: [file('docs/a\u202eb.txt', 3, 1_790_769_600), file('Informe.lnk', 0)] };
expect(fileFacts(h)).toEqual([
{ path: 'docs/a\u202eb.txt', shown: 'docs/a\\u202eb.txt', name: 'a_b.txt', size: 3, mtimeMs: 1_790_769_600_000, warnings: [] },
{ path: 'Informe.lnk', shown: 'Informe.lnk', name: 'Informe.lnk', size: 0, warnings: [SHORTCUT] },
]);
});
});
describe('the downloads', () => {
it('names a file by its last segment, made safe, and the ZIP by the common folder or by the .dkc', () => {
expect(downloadFileName('a/b/c.txt')).toBe('c.txt');
expect(zipFileName(head('fotos/a.jpg', 'fotos/2025/b.jpg'), 'capsula-20260930T120000Z.dkc')).toBe('fotos.zip');
expect(zipFileName(head('fotos/a.jpg', 'docs/b.txt'), 'capsula-20260930T120000Z.dkc')).toBe('capsula-20260930T120000Z.zip');
expect(zipFileName(head('a.txt', 'b.txt'), 'mia.DKC')).toBe('mia.zip');
expect(zipFileName(head('fotos/a.jpg', 'b.txt'), 'sin extension')).toBe('sin extension.zip');
});
it('offers nothing without files, the file itself when it is the only one, with the ZIP of its folder second, and the ZIP of several with each file', () => {
expect(downloads(head(), 'none', 'c.dkc')).toEqual({ each: false });
expect(downloads(head('nota.txt'), 'file', 'c.dkc')).toEqual({ primary: { kind: 'file', index: 0, name: 'nota.txt' }, each: false });
expect(downloads(head('informes/2026.pdf'), 'zip', 'c.dkc')).toEqual({ primary: { kind: 'file', index: 0, name: '2026.pdf' }, zip: 'informes.zip', each: false });
expect(downloads(head('a.txt', 'b/c.txt'), 'zip', 'c.dkc')).toEqual({ primary: { kind: 'zip', name: 'c.zip' }, each: true });
});
});

Powered by TurnKey Linux.