// Draait de echte Alpine-component uit index.html en toetst dat pollJob niet // twee keer tegelijk vraagt. Wordt aangeroepen door tests/test_ui_logica.py; // los draaien kan met: node tests/js/joblog.test.js const fs = require('fs'); const html = fs.readFileSync(__dirname + '/../../server-up/templates/index.html', 'utf8'); const start = html.indexOf('function app() {'); const eind = html.indexOf('', start); const bron = html.slice(start, eind); global.localStorage = { getItem: () => null, setItem: () => {} }; global.location = { hash: '', search: '' }; global.window = { matchMedia: () => ({matches:false, addEventListener(){}}), addEventListener(){}, innerWidth: 1200 }; global.document = { documentElement: {classList:{add(){},remove(){}}}, addEventListener(){}, querySelector: () => null }; global.navigator = { clipboard: { writeText: async () => {} }, language: 'nl' }; global.crypto = require('crypto').webcrypto; eval(bron); let fouten = 0; const check = (naam, waar) => { if (!waar) { fouten++; console.log(' ✖ ' + naam); } else console.log(' ✓ ' + naam); }; const rustig = () => new Promise(r => setTimeout(r, 0)); (async () => { const c = app(); c.t = (k) => k; c.$nextTick = (fn) => fn(); c.$refs = {}; // De tikken van setInterval zelf in de hand houden: zo kunnen we een tweede // tik afvuren terwijl het antwoord op de eerste nog onderweg is — precies // wat er gebeurt bij een trage stap zoals een backup terugzetten. let tik = null; global.setInterval = (fn) => { tik = fn; return 1; }; global.clearInterval = () => {}; const openstaand = []; c.rpc = () => new Promise(res => openstaand.push(res)); c.pollJob('abc123'); tik(); await rustig(); tik(); await rustig(); tik(); await rustig(); check('maar één verzoek tegelijk onderweg', openstaand.length === 1); openstaand.forEach(res => res({lines: [{level: 'dim', text: 'Backup wordt teruggezet…'}], status: 'running'})); await rustig(); check('de regel staat er één keer', c.job.lines.filter(l => l.text === 'Backup wordt teruggezet…').length === 1); // Daarna schuift de offset op en mag er weer gevraagd worden. tik(); await rustig(); check('volgende tik vraagt verder vanaf de nieuwe offset', openstaand.length === 2); let klaar = ''; c.job.timer = 1; openstaand[1]({lines: [], status: 'done'}); await rustig(); check('afgeronde job stopt de poll', c.job.status === 'done'); console.log(fouten === 0 ? '\nAlle joblogcontroles geslaagd' : `\n${fouten} FOUTEN`); process.exit(fouten ? 1 : 0); })();