Files
Multi-Hoster-Upload/tests/import-preflight.test.js
T
Sucukdeluxe 88a3ee0937 feat: add import preflight summaries
Inspect every manual file, folder, and drag-and-drop import before queue admission. Report exact duplicate, filename-filter, filesystem, destination, configured size-limit, and resulting job counts in the host selection dialog with live bilingual updates.
2026-08-16 21:31:56 +02:00

105 lines
3.6 KiB
JavaScript

const { describe, it } = require('node:test');
const assert = require('node:assert/strict');
const {
inspectImportEntries,
summarizeImportPlan
} = require('../lib/import-preflight');
describe('import preflight', () => {
it('accounts for candidates, existing and repeated paths, filename filters, unreadable entries and accepted files', async () => {
const sizes = new Map([
['C:\\incoming\\duplicate-new.bin', 2 * 1024 * 1024],
['C:\\incoming\\missing.bin', null],
['C:\\incoming\\unreadable.bin', 'unreadable'],
['C:\\incoming\\empty.bin', 0],
['C:\\incoming\\accepted.xyz', 5 * 1024 * 1024]
]);
const inspection = await inspectImportEntries([
'C:/queue/existing.bin',
'C:/incoming/duplicate-new.bin',
'C:\\incoming\\duplicate-new.bin',
'C:/incoming/skip.sample.bin',
'C:/incoming/missing.bin',
'C:/incoming/unreadable.bin',
'C:/incoming/empty.bin',
'C:/incoming/accepted.xyz'
], {
existingPaths: ['C:\\QUEUE\\existing.bin'],
filenameFilter: {
enabled: true,
action: 'exclude',
conditions: [{ operator: 'contains', value: '.sample.' }]
},
inspectPath: async filePath => {
const value = sizes.get(filePath);
if (value === null) return { exists: false };
if (value === 'unreadable') return { exists: true, readable: false, size: 10 };
return { exists: true, readable: true, size: value };
}
});
assert.equal(inspection.candidateCount, 8);
assert.equal(inspection.duplicateCount, 2);
assert.equal(inspection.filteredCount, 1);
assert.equal(inspection.unavailableCount, 3);
assert.equal(inspection.acceptedCount, 2);
assert.deepEqual(inspection.unavailable.map(entry => entry.reason).sort(), ['empty', 'missing', 'unreadable']);
assert.deepEqual(inspection.accepted.map(entry => entry.name).sort(), ['accepted.xyz', 'duplicate-new.bin']);
assert.equal(inspection.accepted.find(entry => entry.name === 'accepted.xyz').size, 5 * 1024 * 1024);
});
it('counts jobs and only removes jobs blocked by configured host maximum sizes', () => {
const summary = summarizeImportPlan({
inspection: {
candidateCount: 8,
duplicateCount: 2,
filteredCount: 1,
unavailableCount: 3,
accepted: [
{ path: 'C:\\incoming\\small.bin', name: 'small.bin', size: 2 * 1024 * 1024 },
{ path: 'C:\\incoming\\large.custom', name: 'large.custom', size: 5 * 1024 * 1024 }
]
},
selectedHosters: ['unlimited.example', 'limited.example', 'unlimited.example'],
hosterSettings: {
'unlimited.example': { maxSizeMb: 0 },
'limited.example': { maxSizeMb: 3 },
'unknown.example': { maxSizeMb: 1 }
}
});
assert.deepEqual(summary, {
candidateCount: 8,
duplicateCount: 2,
filteredCount: 1,
unavailableCount: 3,
acceptedCount: 2,
targetCount: 2,
jobCount: 3,
sizeLimitedJobCount: 1
});
});
it('limits concurrent file inspections', async () => {
let active = 0;
let maximumActive = 0;
const inspection = await inspectImportEntries(
Array.from({ length: 12 }, (_, index) => `C:/incoming/file-${index}.bin`),
{
concurrency: 3,
inspectPath: async () => {
active++;
maximumActive = Math.max(maximumActive, active);
await new Promise(resolve => setTimeout(resolve, 5));
active--;
return { exists: true, readable: true, size: 1 };
}
}
);
assert.equal(inspection.acceptedCount, 12);
assert.equal(maximumActive, 3);
});
});