import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import test from 'node:test'; import UploadSessionManager from '../src/services/file/UploadSessionManager.ts'; function makeSessionManager(ttlMs = 60_000): { manager: UploadSessionManager; rootDir: string; } { const rootDir = fs.mkdtempSync(path.join(os.tmpdir(), 'upload-sessions-')); return { manager: new UploadSessionManager({ sessionDir: rootDir, ttlMs }), rootDir, }; } void test('UploadSessionManager creates metadata and tracks uploaded chunks', async () => { const { manager, rootDir } = makeSessionManager(); try { const sessionId = manager.createSession({ filename: 'tour.mp4', folder: 'assets', totalChunks: 2, totalSize: 11, userId: 'user-1', contentType: 'video/mp4', }); let meta = manager.readMeta(sessionId); assert.equal(meta?.filename, 'tour.mp4'); assert.equal(meta?.uploadedChunks !== undefined, true); assert.equal(manager.isComplete(sessionId), false); await manager.saveChunk(sessionId, 0, Buffer.from('hello ')); await manager.saveChunk(sessionId, 1, Buffer.from('world')); meta = manager.readMeta(sessionId); assert.equal(meta?.uploadedChunks[0]?.size, 6); assert.equal(meta?.uploadedChunks[1]?.size, 5); assert.equal(manager.chunkExists(sessionId, 0), true); assert.equal(manager.isComplete(sessionId), true); } finally { fs.rmSync(rootDir, { recursive: true, force: true }); } }); void test('UploadSessionManager assembles chunks in index order', async () => { const { manager, rootDir } = makeSessionManager(); try { const sessionId = manager.createSession({ filename: 'image.bin', folder: 'assets', totalChunks: 3, totalSize: 9, }); await manager.saveChunk(sessionId, 2, Buffer.from('ghi')); await manager.saveChunk(sessionId, 0, Buffer.from('abc')); await manager.saveChunk(sessionId, 1, Buffer.from('def')); const targetPath = path.join(rootDir, 'assembled', 'image.bin'); await manager.assembleChunks(sessionId, targetPath); assert.equal(fs.readFileSync(targetPath, 'utf8'), 'abcdefghi'); } finally { fs.rmSync(rootDir, { recursive: true, force: true }); } }); void test('UploadSessionManager removes expired and invalid sessions during cleanup', () => { const { manager, rootDir } = makeSessionManager(1); try { const expiredSessionId = manager.createSession({ filename: 'expired.txt', folder: 'assets', totalChunks: 1, totalSize: 1, }); const meta = manager.readMeta(expiredSessionId); assert.ok(meta); meta.updatedAt = new Date(Date.now() - 10_000).toISOString(); manager.writeMeta(expiredSessionId, meta); const invalidSessionId = 'invalid-session'; const invalidSessionDir = manager.getSessionDir(invalidSessionId); fs.mkdirSync(invalidSessionDir, { recursive: true }); fs.writeFileSync( manager.getMetaPath(invalidSessionId), JSON.stringify({ sessionId: invalidSessionId }), 'utf8', ); manager.cleanupExpiredSessions(); assert.equal(fs.existsSync(manager.getSessionDir(expiredSessionId)), false); assert.equal(fs.existsSync(invalidSessionDir), false); } finally { fs.rmSync(rootDir, { recursive: true, force: true }); } });