/** * scripts/test_tv_playlist.js — node scripts/test_tv_playlist.js * * Pruebas de la subida de la playlist del televisor, contra el código real de * configuracion.php. Vigilan el defecto reportado: «subí 5 videos y solo * salieron 2» — los archivos se subían todos en paralelo, los lentos morían * por timeout y el aviso era un toast que desaparecía en segundos. */ const fs = require('fs'); let fallos = 0; const ok = (d, c) => { console.log((c ? ' ok ' : ' FALLA ') + d); if (!c) fallos++; }; const src = fs.readFileSync(__dirname + '/../modules/turnero/views/configuracion.php', 'utf8') .replace(/<\?(php|=)[\s\S]*?\?>/g, '"PHP"'); // ── extracciones ──────────────────────────────────────────────────────── const iCola = src.indexOf('const escHtml'); const fCola = src.indexOf('function subirTvMedia(file)'); const colaSrc = src.slice(iCola, fCola); // escHtml + subirTvMediaEnCola const fFin = src.indexOf('function agregarItemTvMedia'); const subirSrc = src.slice(fCola, fFin); // subirTvMedia real ok('el selector de archivos usa la cola, no la andanada paralela', src.includes('subirTvMediaEnCola(Array.from(inp.files))')); ok('el reproductor salta al siguiente si un video falla', src.includes("addEventListener('error', siguiente)") || fs.readFileSync(__dirname + '/../modules/turnero/views/display_global.php', 'utf8') .includes("addEventListener('error', siguiente)")); // ── 1. La cola sube de a UNO y no se detiene ante un fallo ────────────── { const orden = []; let simultaneos = 0, picoSimultaneos = 0; const resumenDiv = { style: {}, innerHTML: '', className: '' }; const doc = { getElementById: id => (id === 'tv-upload-resumen' ? resumenDiv : null) }; // subirTvMedia de mentira: tarda distinto por archivo, falla el 2º y el 4º const stub = async (f) => { simultaneos++; picoSimultaneos = Math.max(picoSimultaneos, simultaneos); orden.push('inicio:' + f.name); await new Promise(x => setTimeout(x, f.ms)); simultaneos--; orden.push('fin:' + f.name); return f.falla ? { ok: false, nombre: f.name, motivo: 'timeout simulado' } : { ok: true, nombre: f.name }; }; const enCola = new Function('subirTvMedia', 'document', colaSrc + '; return subirTvMediaEnCola;')(stub, doc); const files = [ { name: 'v1.mp4', ms: 30 }, { name: 'v2.mp4', ms: 10, falla: true }, { name: 'v3.mp4', ms: 20 }, { name: 'v4.mp4', ms: 10, falla: true }, { name: 'v5.mp4', ms: 15 }, ]; enCola(files).then(() => { ok('sube estrictamente de a uno (nunca hubo dos a la vez)', picoSimultaneos === 1); ok('un fallo no frena a los que siguen: los 5 se intentaron', orden.filter(x => x.startsWith('inicio:')).length === 5); ok('respeta el orden elegido', orden.filter(x => x.startsWith('inicio:')).join(',') === 'inicio:v1.mp4,inicio:v2.mp4,inicio:v3.mp4,inicio:v4.mp4,inicio:v5.mp4'); ok('el resumen dice cuántos entraron: «3 de 5»', resumenDiv.innerHTML.includes('3 de 5')); ok('el resumen NOMBRA los que fallaron y su motivo', resumenDiv.innerHTML.includes('v2.mp4') && resumenDiv.innerHTML.includes('v4.mp4') && resumenDiv.innerHTML.includes('timeout simulado')); ok('el resumen queda visible (no es un toast fugaz)', resumenDiv.style.display === ''); // ── 2. Los pre-chequeos rechazan claro y ANTES de tocar la red ────── const docTrampa = { getElementById: () => { throw new Error('tocó el DOM'); } }; const subir = new Function('document', 'XMLHttpRequest', 'FormData', 'API', 'TV_LIMITE_BYTES', 'TV_LIMITE_TXT', subirSrc + '; return subirTvMedia;')( docTrampa, function () { throw new Error('tocó la red'); }, function () {}, '', 500 * 1024 * 1024, '500 MB'); Promise.all([ subir({ name: 'clip.mov', type: 'video/quicktime', size: 1000 }), subir({ name: 'doc.pdf', type: 'application/pdf', size: 1000 }), subir({ name: 'giga.mp4', type: 'video/mp4', size: 600 * 1024 * 1024 }), ]).then(([mov, pdf, giga]) => { ok('un .mov de iPhone se rechaza con instrucción de convertir a MP4', !mov.ok && /iPhone|MP4/.test(mov.motivo)); ok('un formato ajeno se rechaza nombrando los admitidos', !pdf.ok && /MP4/.test(pdf.motivo)); ok('el que pasa de 500 MB se rechaza por tamaño', !giga.ok && /500/.test(giga.motivo)); console.log(); console.log(fallos === 0 ? 'Todo correcto.' : fallos + ' pruebas fallaron.'); process.exit(fallos === 0 ? 0 : 1); }); }); }