// concierge-health.test.js — vérifie la MACHINE À ÉTATS des alertes (dédup + transitions). // Aucun réseau, aucun secret : HA_TOKEN_FILE pointe sur un fichier absent → haToken() = null // → aucun appel HA émis ; l'état vit dans un fichier temporaire isolé (pas celui de prod). // Lancer : node concierge-health.test.js 'use strict'; const fs = require('fs'); const os = require('os'); const path = require('path'); const STATE = path.join(os.tmpdir(), `concierge-health-test-${process.pid}.json`); process.env.CONCIERGE_HEALTH_STATE = STATE; process.env.HA_TOKEN_FILE = path.join(os.tmpdir(), 'no-such-ha-token-xyz'); try { fs.rmSync(STATE, { force: true }); } catch { /* neuf */ } const { publish } = require('./concierge-health.js'); let failures = 0; const check = (label, cond) => { console.log(`${cond ? 'ok ' : 'FAIL'} ${label}`); if (!cond) failures++; }; (async () => { const s1 = await publish({ ok: true }); check('sain au démarrage → aucun message', s1 === ''); const s2 = await publish({ ok: false, detail: 'password authentication failed' }); check('bascule sain→panne → alerte émise', /en panne/.test(s2)); const s3 = await publish({ ok: false, detail: 'password authentication failed' }); check('panne persistante → PAS de ré-alerte (dédup)', s3 === ''); const s4 = await publish({ ok: true }); check('bascule panne→sain → « de nouveau opérationnel »', /opérationnel/.test(s4)); const s5 = await publish({ ok: true }); check('sain persistant → aucun message', s5 === ''); try { fs.rmSync(STATE, { force: true }); } catch { /* nettoyage */ } if (failures) { console.error(`\n${failures} test(s) en échec`); process.exit(1); } console.log('\nTOUT VERT — machine à états santé concierge conforme'); })().catch(e => { console.error('[test]', e); process.exit(1); });