const { test } = require('node:test') const assert = require('node:assert/strict') const fs = require('node:fs') const vm = require('node:vm') const vue = require('vue') async function setup(getJob, scanData = {}, agents = [{ id: 'agent', active: true, capabilities: { scan: true, ocr: true, backgroundCleanup: true }, scannerNames: ['fujitsu:ScanSnap iX1600:test'] }]) { const notices = [] const requests = [] let unmount const context = vm.createContext({ ref: vue.ref, reactive: vue.reactive, computed: vue.computed, watch: vue.watch, onBeforeUnmount: handler => { unmount = handler }, defineProps: () => ({ scanData: { folder: 'folder-1', type: 'document', ...scanData } }), defineEmits: () => () => {}, useModal: () => ({ close() {} }), useToast: () => ({ add: notice => notices.push(notice) }), setTimeout: callback => queueMicrotask(callback), useNuxtApp: () => ({ $api: async (url, options) => { requests.push({ url, options }) if (url === '/api/instance-agents') return { agents } if (url === '/api/scan-jobs') return { job: { id: 'job' } } return getJob() } }), }) const source = fs.readFileSync(`${__dirname}/../components/FileScanModal.vue`, 'utf8').split('')[0] vm.runInContext(source, context) await new Promise(setImmediate) return { run: code => vm.runInContext(code, context), notices, requests, close: () => unmount() } } test('duplex scanning continues past the former three-minute polling limit', async () => { let polls = 0 const ui = await setup(() => ({ job: { status: ++polls > 95 ? 'completed' : 'running', agentMessage: '4 Seiten gescannt.' } })) await ui.run('startScan()') assert.equal(polls, 96) assert.equal(ui.notices[0].title, 'Scan gespeichert') const body = ui.requests.find(request => request.url === '/api/scan-jobs').options.body assert.equal(body.settings.source, 'ADF Duplex') assert.equal(body.settings.paperSize, 'A4') assert.equal(body.settings.ocr, true) assert.equal(body.settings.ocrLanguage, 'deu+eng') assert.equal(body.settings.backgroundCleanup, true) assert.equal(body.target.folder, 'folder-1') }) test('temporary status connection failures do not create duplicate scans', async () => { let polls = 0 const ui = await setup(() => { if (++polls < 3) throw Error('offline') return { job: { status: 'completed' } } }) await ui.run('startScan()') assert.equal(ui.requests.filter(request => request.url === '/api/scan-jobs').length, 1) assert.equal(ui.notices[0].title, 'Scan gespeichert') }) test('closing the modal stops polling without reporting that a background scan failed', async () => { const ui = await setup(() => { throw Error('must not poll') }) ui.close() assert.equal(await ui.run('waitForJob("job")'), null) assert.equal(ui.notices.length, 0) }) test('iX1600 preset resets image settings and normalizes the output filename to PDF', async () => { const ui = await setup(() => ({})) ui.run('scanForm.format="png"; scanForm.source="Flatbed"; scanForm.filename="document.png"; scanForm.postprocess=true') await new Promise(setImmediate) ui.run('applyIx1600Preset()') await new Promise(setImmediate) assert.equal(ui.run('scanForm.format'), 'pdf') assert.equal(ui.run('scanForm.filename'), 'document.pdf') assert.equal(ui.run('scanForm.postprocess'), false) assert.equal(ui.run('scanForm.resolution'), 300) }) test('setup test scan uses the requested agent even when another agent is first', async () => { const agents = ['first', 'configured'].map(id => ({ id, active: true, capabilities: { scan: true, ocr: true, backgroundCleanup: true }, scannerNames: ['scanner-' + id] })) const ui = await setup(() => ({ job: { status: 'completed' } }), { agentId: 'configured' }, agents) await ui.run('startScan()') assert.equal(ui.requests.find(request => request.url === '/api/scan-jobs').options.body.agentId, 'configured') }) test('an unavailable setup agent never silently scans with another device', async () => { const ui = await setup(() => ({}), { agentId: 'missing' }) await ui.run('startScan()') assert.equal(ui.requests.filter(request => request.url === '/api/scan-jobs').length, 0) }) test('an old agent cannot silently produce an image-only PDF when OCR was requested', async () => { const ui = await setup(() => ({}), {}, [{ id: 'old', active: true, capabilities: { scan: true }, scannerNames: ['scanner'] }]) await ui.run('startScan()') assert.equal(ui.requests.filter(request => request.url === '/api/scan-jobs').length, 0) assert.equal(ui.notices[0].title, 'Agent aktualisieren') })