Files
Multi-Hoster-Upload/tests/upload-recovery.test.js
T
Sucukdeluxe 746ae29a4f Retain exact recovery after batch start failure
Persist job-ID terminal outcomes before final queue acknowledgement and clear recovery evidence only after both the terminal marker and renderer queue are durable.
2026-08-13 21:16:04 +02:00

95 lines
4.5 KiB
JavaScript

const test = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
test('catastrophic batch starts retain exact terminal outcomes for every job', () => {
const { buildFailedUploadSummary, buildTerminalJobSnapshots } = require('../lib/upload-recovery');
const summary = buildFailedUploadSummary([
{ jobId: 'job-a', file: 'C:\\one\\same.mkv', hoster: 'doodstream.com' },
{ jobId: 'job-b', file: 'D:\\two\\same.mkv', hoster: 'voe.sx' }
], 'Upload konnte nicht gestartet werden', Date.UTC(2026, 7, 13));
assert.equal(summary.total, 2);
assert.equal(summary.failed, 2);
assert.deepEqual(buildTerminalJobSnapshots(summary).map(entry => [entry.jobId, entry.status]), [
['job-a', 'error'],
['job-b', 'error']
]);
});
test('terminal recovery snapshots retain exact job outcomes and canonical links', () => {
const { buildTerminalJobSnapshots } = require('../lib/upload-recovery');
const snapshots = buildTerminalJobSnapshots({
files: [{
name: 'episode.mkv',
results: [
{ jobId: 'done-job', hoster: 'doodstream.com', status: 'done', download_url: 'https://doodstream.com/d/abc123', file_code: 'abc123' },
{ jobId: 'error-job', hoster: 'voe.sx', status: 'error', error: 'rejected', failureDetails: { kind: 'hoster' } },
{ hoster: 'byse.sx', status: 'done', download_url: 'https://byse.sx/d/no-id' }
]
}]
});
assert.deepEqual(snapshots, [
{
jobId: 'done-job',
status: 'done',
error: null,
failureDetails: null,
result: { download_url: 'https://doodstream.com/d/abc123', embed_url: null, file_code: 'abc123' }
},
{
jobId: 'error-job',
status: 'error',
error: 'rejected',
failureDetails: { kind: 'hoster' },
result: null
}
]);
});
test('recovery markers affect only their exact job IDs and never restart terminal outcomes', () => {
const { getRecoveryOutcome } = require('../lib/upload-recovery');
const recovery = {
jobIds: ['done-job', 'active-job'],
terminalJobs: [{
jobId: 'done-job',
status: 'done',
error: null,
failureDetails: null,
result: { download_url: 'https://doodstream.com/d/abc123', embed_url: null, file_code: 'abc123' }
}]
};
assert.deepEqual(getRecoveryOutcome({ id: 'done-job', status: 'preview' }, recovery), {
status: 'done',
error: null,
failureDetails: null,
result: { download_url: 'https://doodstream.com/d/abc123', embed_url: null, file_code: 'abc123' },
interrupted: false
});
assert.deepEqual(getRecoveryOutcome({ id: 'active-job', status: 'queued' }, recovery), { status: 'queued', interrupted: true });
assert.deepEqual(getRecoveryOutcome({ id: 'foreign-job', status: 'queued' }, recovery), { status: 'queued', interrupted: false });
assert.deepEqual(getRecoveryOutcome({ id: 'already-done', status: 'done' }, recovery), { status: 'done', interrupted: false });
});
test('main and renderer keep recovery evidence until final queue persistence succeeds', () => {
const root = path.join(__dirname, '..');
const mainSource = fs.readFileSync(path.join(root, 'main.js'), 'utf8');
const rendererSource = fs.readFileSync(path.join(root, 'renderer', 'app.js'), 'utf8');
const indexSource = fs.readFileSync(path.join(root, 'renderer', 'index.html'), 'utf8');
const batchDone = mainSource.slice(mainSource.indexOf("uploadManager.on('batch-done'"), mainSource.indexOf("ipcMain.handle('cancel-upload'"));
assert.match(batchDone, /buildTerminalJobSnapshots\(summary\)/);
assert.match(batchDone, /if \(queuePersisted && terminalRecoveryPersisted\)[\s\S]*saveUploadRecovery\(null\)/);
assert.ok(batchDone.indexOf('saveUploadRecovery(recoveryWithTerminalJobs)') < batchDone.indexOf('requestUploadFinalization(summary, historyPersisted)'));
const startFailure = batchDone.slice(batchDone.indexOf('startBatch(tasks'));
assert.match(startFailure, /buildFailedUploadSummary\(tasks/);
assert.match(startFailure, /saveUploadRecovery\(terminalRecovery\)/);
assert.match(startFailure, /requestUploadFinalization\(errorSummary, historyPersisted\)/);
assert.match(startFailure, /if \(queuePersisted && terminalRecoveryPersisted\)[\s\S]*saveUploadRecovery\(null\)/);
assert.match(rendererSource, /window\.UploadRecovery\.getRecoveryOutcome/);
assert.match(rendererSource, /data\.historyPersisted !== true/);
assert.ok(indexSource.indexOf('../lib/upload-recovery.js') < indexSource.indexOf('app.js'));
});