From 31d157b6951dbb0f75132d5d74a86d657dace8d5 Mon Sep 17 00:00:00 2001 From: Administrator Date: Mon, 6 Apr 2026 22:56:26 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=85=20test:=203=20new=20tests=20for=20add?= =?UTF-8?q?Jobs=20(74/74=20pass)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - addJobs injects new tasks into running batch (verified concurrent execution) - addJobs rejects duplicate jobIds already in batch - addJobs returns added=0 when not running These tests verify the fix in v2.6.3 (files added during upload now get injected into the running batch via addJobsToBatch). Co-Authored-By: Claude Opus 4.6 (1M context) --- tests/upload-manager.test.js | 69 ++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/tests/upload-manager.test.js b/tests/upload-manager.test.js index da57c56..994b137 100644 --- a/tests/upload-manager.test.js +++ b/tests/upload-manager.test.js @@ -409,6 +409,75 @@ describe('UploadManager', () => { assert.ok(maxConcurrent <= 2, `scaleParallelUploads should cap at 2, was ${maxConcurrent}`); }); + it('addJobs injects new tasks into running batch', async () => { + let started = 0; + mockUploadFile.mock.mockImplementation(async (hoster, filePath, apiKey, onProgress) => { + started++; + await new Promise(r => setTimeout(r, 100)); + if (onProgress) onProgress(fakeFileSize, fakeFileSize); + return { download_url: 'ok', embed_url: null, file_code: 'ok' }; + }); + + const mgr = new UploadManager({}); + let summary = null; + mgr.on('batch-done', (s) => { summary = s; }); + + // Start batch with 2 tasks + const batchPromise = mgr.startBatch([ + { jobId: 'job-1', file: '/test/a.mp4', hoster: 'doodstream.com', apiKey: 'k' }, + { jobId: 'job-2', file: '/test/b.mp4', hoster: 'doodstream.com', apiKey: 'k' } + ]); + + // After 30ms (during upload), inject 2 more tasks + await new Promise(r => setTimeout(r, 30)); + const result = mgr.addJobs([ + { jobId: 'job-3', file: '/test/c.mp4', hoster: 'doodstream.com', apiKey: 'k' }, + { jobId: 'job-4', file: '/test/d.mp4', hoster: 'doodstream.com', apiKey: 'k' } + ]); + assert.equal(result.added, 2, 'should add 2 new jobs'); + assert.equal(result.alreadyInBatchJobIds.length, 0); + + await batchPromise; + assert.ok(summary); + assert.equal(started, 4, 'all 4 jobs should have run'); + }); + + it('addJobs rejects duplicates already in running batch', async () => { + mockUploadFile.mock.mockImplementation(async (hoster, filePath, apiKey, onProgress, signal) => { + // Slow upload so we can add jobs while it's running + await new Promise((resolve, reject) => { + const timer = setTimeout(resolve, 200); + if (signal) signal.addEventListener('abort', () => { clearTimeout(timer); reject(new Error('Aborted')); }); + }); + if (onProgress) onProgress(fakeFileSize, fakeFileSize); + return { download_url: 'ok', embed_url: null, file_code: 'ok' }; + }); + + const mgr = new UploadManager({}); + const batchPromise = mgr.startBatch([ + { jobId: 'job-A', file: '/test/x.mp4', hoster: 'doodstream.com', apiKey: 'k' } + ]); + + // Try to add the SAME jobId while it's running + await new Promise(r => setTimeout(r, 50)); + const result = mgr.addJobs([ + { jobId: 'job-A', file: '/test/x.mp4', hoster: 'doodstream.com', apiKey: 'k' }, + { jobId: 'job-B', file: '/test/y.mp4', hoster: 'doodstream.com', apiKey: 'k' } + ]); + assert.equal(result.added, 1, 'should skip duplicate jobId, add only the new one'); + assert.deepEqual(result.alreadyInBatchJobIds, ['job-A']); + + await batchPromise; + }); + + it('addJobs returns added=0 when not running', () => { + const mgr = new UploadManager({}); + const result = mgr.addJobs([ + { jobId: 'job-1', file: '/test/a.mp4', hoster: 'doodstream.com', apiKey: 'k' } + ]); + assert.equal(result.added, 0); + }); + it('stats event contains expected fields', async () => { // Make upload take long enough for stats interval to fire mockUploadFile.mock.mockImplementation(async (hoster, filePath, apiKey, onProgress, signal) => {