const { test } = require('node:test'); const assert = require('node:assert/strict'); const DownloadsPage = require('./downloads-page.js'); test('groupJobs categorizes active, queued, paused, and failed jobs correctly', () => { const jobs = [ { id: '1', title: 'Job 1', status: 'active' }, { id: '2', title: 'Job 2', status: 'queued' }, { id: '3', title: 'Job 3', status: 'paused' }, { id: '4', title: 'Job 4', status: 'failed', error: 'Network error' } ]; const groups = DownloadsPage.groupJobs(jobs); assert.equal(groups.active.length, 1); assert.equal(groups.queued.length, 1); assert.equal(groups.paused.length, 1); assert.equal(groups.failed.length, 1); assert.equal(groups.active[0].id, '1'); assert.equal(groups.failed[0].error, 'Network error'); }); test('formatJobStatus produces plain text labels without emojis for all job states', () => { assert.equal(DownloadsPage.formatJobStatus({ status: 'failed', error: 'Connection lost' }), 'Failed: Connection lost'); assert.equal(DownloadsPage.formatJobStatus({ status: 'failed' }), 'Save failed'); assert.equal(DownloadsPage.formatJobStatus({ status: 'paused' }), 'Paused — resume when you’re ready'); assert.equal(DownloadsPage.formatJobStatus({ status: 'queued' }), 'Waiting for a free slot…'); assert.equal( DownloadsPage.formatJobStatus({ status: 'active', progress: { received: 10485760, total: 52428800 } }), '10.0 / 50.0 MB' ); assert.equal( DownloadsPage.formatJobStatus({ status: 'active', progress: { phase: 'preparing', elapsed: 3000 } }), 'Preparing on server… 3 s' ); assert.equal(DownloadsPage.formatJobStatus({ status: 'active', progress: { phase: 'verifying' } }), 'Verifying…'); assert.equal(DownloadsPage.formatJobStatus({ status: 'active' }), 'Saving for offline…'); }); test('bytes formatting handles bytes, MB, GB and invalid input safely', () => { assert.equal(DownloadsPage.bytes(0), '0 MB'); assert.equal(DownloadsPage.bytes(10485760), '10.0 MB'); assert.equal(DownloadsPage.bytes(1073741824), '1.0 GB'); assert.equal(DownloadsPage.bytes(-100), '0 MB'); assert.equal(DownloadsPage.bytes(null), '0 MB'); }); test('escapeHtml escapes dangerous HTML characters', () => { assert.equal(DownloadsPage.escapeHtml(''), '<script>alert("xss")</script>'); assert.equal(DownloadsPage.escapeHtml('Tom & Jerry'), 'Tom & Jerry'); });