Files
OPENCLAW_ARCHIVE3_17/workspace/concierge-write.test.js
Thierry Tallagrand 534ae0d663 Concierge vehicule : code (detection, live, write + test de portee)
Complete le commit doc precedent : ajoute le code JS du concierge, exclu jusqu'ici
par la liste blanche workspace/*. Exception ciblee !workspace/concierge-*.js dans
.gitignore (aucun secret : les tokens sont lus depuis .ha-token/.pg-airtria, ignores).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RZsbhyGmRwZogdoBwT6C6y
2026-09-14 02:39:00 +02:00

58 lines
2.4 KiB
JavaScript

// concierge-write.test.js — Test de PORTÉE D'ÉCRITURE (garde-fou du canal HA).
// Doit ÉCHOUER si une écriture peut sortir de la constante airtria_vehicle_label.
// À faire tourner à CHAQUE modification, pas une seule fois (cf. EVCS advisor).
// Pur statique + require : aucun réseau, aucun token, aucune écriture.
'use strict';
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const SRC = path.join(__dirname, 'concierge-write.js');
const src = fs.readFileSync(SRC, 'utf8');
const mod = require('./concierge-write.js');
let ko = 0;
const check = (name, fn) => {
try { fn(); console.log(` ok ${name}`); }
catch (e) { ko++; console.log(` FAIL ${name} : ${e.message}`); }
};
console.log('=== Test de portée d\'écriture concierge-write.js ===');
// 1. La constante est exactement l'entité attendue.
check('constante = input_text.airtria_vehicle_label', () =>
assert.strictEqual(mod.HELPER_ENTITY, 'input_text.airtria_vehicle_label'));
// 2. entity_id n'est JAMAIS accolé à autre chose que la constante
// (pas de littéral d'entité, pas d'interpolation, pas de concaténation).
check('entity_id uniquement = HELPER_ENTITY', () => {
const occ = [...src.matchAll(/entity_id\s*:\s*([^,}\n]+)/g)].map(m => m[1].trim());
assert(occ.length > 0, 'aucun entity_id trouvé');
for (const v of occ) assert.strictEqual(v, 'HELPER_ENTITY',
`entity_id dynamique ou littéral interdit : ${v}`);
});
// 3. Aucune autre entité HA en dur (aucun autre "domaine.entite") que la constante.
check('aucune entité HA littérale hors la constante', () => {
const decl = "'input_text.airtria_vehicle_label'";
const lits = [...src.matchAll(/['"`]([a-z_]+\.[a-z0-9_]+)['"`]/g)].map(m => m[0]);
for (const l of lits) assert.strictEqual(l, decl,
`littéral d'entité interdit : ${l}`);
});
// 4. Un SEUL appel de service, et c'est input_text/set_value (aucun actionneur).
check('seul service = input_text/set_value', () => {
const services = [...src.matchAll(/\/api\/services\/([a-z_]+\/[a-z_]+)/g)]
.map(m => m[1]);
assert.deepStrictEqual(services, ['input_text/set_value'],
`services inattendus : ${services.join(', ') || '(aucun)'}`);
});
// 5. La relecture existe (garde-fou rejet silencieux).
check('relecture présente (/api/states/)', () =>
assert(/\/api\/states\//.test(src), 'pas de relecture après écriture'));
console.log(ko === 0 ? '\nTOUT VERT' : `\n${ko} test(s) EN ÉCHEC`);
process.exit(ko === 0 ? 0 : 1);