Assessor_2.0/tests/features/gpo-folder-file-capture.tes...

104 lines
3.7 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
captureGpoFolderFiles,
captureReadableGpoSelectedFiles,
collectGpoDirectoryFiles
} from '../../src/features/project-import/GpoFolderImport';
describe('GPO folder browser file capture', () => {
it('starts every selected file read before the transport requests the first result', async () => {
const started: string[] = [];
const selected = ['first', 'second', 'third'].map(name => ({
webkitRelativePath: `Synthetic/${name}.xml`,
size: name.length,
arrayBuffer: async () => {
started.push(name);
return new TextEncoder().encode(name).buffer;
}
})) as unknown as File[];
const sources = captureGpoFolderFiles(selected);
expect(started).toEqual(['first', 'second', 'third']);
expect(new TextDecoder().decode(await sources[0].readBytes())).toBe('first');
});
it('turns an inaccessible browser file into the bounded local-read error', async () => {
const selected = [{
webkitRelativePath: 'Synthetic/unavailable.xml',
size: 1,
arrayBuffer: async () => { throw new DOMException('unavailable', 'NotFoundError'); }
}] as unknown as File[];
const [source] = captureGpoFolderFiles(selected);
await expect(source.readBytes()).rejects.toThrow('konnte nicht lokal gelesen werden');
});
it('rejects oversized metadata before starting any browser file read', () => {
let started = 0;
const selected = [{
webkitRelativePath: 'Synthetic/oversized.bin',
size: 513 * 1024 * 1024,
arrayBuffer: async () => {
started += 1;
return new ArrayBuffer(0);
}
}] as unknown as File[];
expect(() => captureGpoFolderFiles(selected)).toThrow('ungültige oder zu große Dateigröße');
expect(started).toBe(0);
});
it('collects a directly granted directory recursively with stable relative paths', async () => {
const file = {
size: 3,
arrayBuffer: async () => new TextEncoder().encode('gpo').buffer
} as unknown as File;
const nested = {
kind: 'directory',
name: 'DomainSysvol',
async *values() {
yield { kind: 'file', name: 'gpt.ini', getFile: async () => file };
}
};
const root = {
kind: 'directory',
name: 'SyntheticBackup',
async *values() { yield nested; }
};
const selected = await collectGpoDirectoryFiles(root as never);
expect(selected.unreadableEntries).toBe(0);
expect(selected.files.map(entry => entry.relativePath)).toEqual([
'SyntheticBackup/DomainSysvol/gpt.ini'
]);
});
it('keeps readable entries and counts inaccessible handles and file bodies', async () => {
const readable = {
size: 3,
arrayBuffer: async () => new TextEncoder().encode('gpo').buffer
} as File;
const unreadableBody = {
size: 1,
arrayBuffer: async () => { throw new DOMException('unavailable', 'NotFoundError'); }
} as unknown as File;
const root = {
kind: 'directory',
name: 'SyntheticBackup',
async *values() {
yield { kind: 'file', name: 'gpt.ini', getFile: async () => readable };
yield { kind: 'file', name: 'missing.xml', getFile: async () => { throw new DOMException('missing', 'NotFoundError'); } };
yield { kind: 'file', name: 'locked.xml', getFile: async () => unreadableBody };
}
};
const collected = await collectGpoDirectoryFiles(root as never);
const captured = await captureReadableGpoSelectedFiles(collected.files);
expect(collected.unreadableEntries).toBe(1);
expect(captured.unreadableEntries).toBe(1);
expect(captured.sources.map(source => source.relativePath)).toEqual([
'SyntheticBackup/gpt.ini'
]);
});
});