/** * scripts/test_rips_sondeo.js — node scripts/test_rips_sondeo.js * * Pruebas del sondeo RIPS contra el código real de recepcion.php. * * El defecto que esto vigila: la consulta a RIPS se hacía UNA vez al vincular * al paciente, y en 7 días 547 de 549 registros llegaron después de esa única * consulta. El sondeo reintenta cada 10 s hasta 10 minutos y debe detenerse * al encontrar, al limpiar la ficha, o al agotar los intentos. */ 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/recepcion.php', 'utf8') .replace(/<\?(php|=)[\s\S]*?\?>/g, '"PHP"'); // Se extraen exactamente las tres piezas del control de sondeo const m = src.match(/let _ripsSondeoId[\s\S]*?function detenerSondeoRips\(\) \{[\s\S]*?\n\}/); if (!m) { console.log(' FALLA no se encontró el bloque de sondeo'); process.exit(1); } function armar() { let consultas = 0; const intervalos = new Map(); let proximoId = 1; const setIntervalFake = (fn, ms) => { const id = proximoId++; intervalos.set(id, { fn, ms }); return id; }; const clearIntervalFake = (id) => intervalos.delete(id); const api = new Function( 'setInterval', 'clearInterval', 'INTERVALOS', 'CONTADOR', 'let _ripsData = null;' + 'const consultarExamenesRips = (c) => { CONTADOR.n++; };' + m[0] + `; return { iniciar: iniciarSondeoRips, detener: detenerSondeoRips, tic() { for (const v of [...INTERVALOS.values()]) v.fn(); }, activo() { return _ripsSondeoId !== null; }, encontrado() { _ripsData = { encontrados: [1] }; }, };` )(setIntervalFake, clearIntervalFake, intervalos, (globalThis.__c = { n: 0 })); return { api, contador: globalThis.__c, intervalos }; } // ── 1. Consulta de inmediato y reintenta ──────────────────────────────── { const { api, contador } = armar(); api.iniciar('12345678'); ok('consulta de inmediato al vincular', contador.n === 1); api.tic(); api.tic(); api.tic(); ok('reintenta en cada ciclo mientras no encuentra', contador.n === 4); } // ── 2. Al encontrar, deja de sondear ──────────────────────────────────── { const { api, contador } = armar(); api.iniciar('12345678'); api.tic(); api.encontrado(); api.tic(); // este ciclo detecta _ripsData y se apaga const n = contador.n; api.tic(); api.tic(); ok('al encontrar los exámenes se apaga y no consulta más', contador.n === n && !api.activo()); } // ── 3. Limpiar la ficha lo detiene ────────────────────────────────────── { const { api, contador } = armar(); api.iniciar('12345678'); api.detener(); const n = contador.n; api.tic(); api.tic(); ok('limpiar la ficha detiene el sondeo en seco', contador.n === n && !api.activo()); } // ── 4. Tope de intentos: no sondea para siempre ───────────────────────── { const { api, contador } = armar(); api.iniciar('12345678'); for (let i = 0; i < 80; i++) api.tic(); ok('se rinde tras ~60 intentos (10 min), no queda sondeando eternamente', contador.n <= 61 && !api.activo()); } // ── 5. Vincular a otro paciente reinicia sin duplicar intervalos ──────── { const { api, contador, intervalos } = armar(); api.iniciar('11111111'); api.iniciar('22222222'); ok('re-vincular no deja dos sondeos corriendo a la vez', intervalos.size === 1); } // ── 6. Sin cédula no arranca ──────────────────────────────────────────── { const { api, contador } = armar(); api.iniciar(''); ok('sin cédula no consulta ni deja intervalos', contador.n === 0 && !api.activo()); } console.log(); console.log(fallos === 0 ? 'Todo correcto.' : fallos + ' pruebas fallaron.'); process.exit(fallos === 0 ? 0 : 1);