Files
portail-santinova/test/portal-contract.test.js
Manus Deployment 263eff99b8
All checks were successful
Validation applicative / Tests de contrat (push) Successful in 17s
fix: corriger les vignettes du portail production
2026-09-30 12:44:27 +00:00

92 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Contrat de non-régression du portail de production.
* Il vérifie la séparation stricte des environnements, la publication
* dynamique des applications et les exceptions explicitement demandées.
*/
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const vm = require('node:vm');
const root = path.join(__dirname, '..');
const html = fs.readFileSync(path.join(root, 'index.html'), 'utf8');
const attributions = fs.readFileSync(path.join(root, 'images', 'ATTRIBUTIONS.md'), 'utf8');
assert.equal(/^(<<<<<<<|=======|>>>>>>>)/m.test(html), false, 'aucun marqueur de conflit Git ne doit être livré');
assert.equal((html.match(/var DASHBOARD_APPS_URL/g) || []).length, 1, 'une seule URL API applications doit être déclarée');
assert.equal((html.match(/var DASHBOARD_STATUS_URL/g) || []).length, 1, 'une seule URL API statuts doit être déclarée');
assert.match(html, /var ENV = 'prod';/, 'la version production doit déclarer explicitement son environnement');
assert.match(html, /app\.urls\[ENV\]/, 'les liens doivent être sélectionnés depuis l’environnement déclaré');
assert.match(html, /app\.category === 'INFRA'/, 'les tuiles INFRA doivent rester dans leur onglet dédié');
assert.match(html, /var STATUS_REFRESH_MS = 30000;/, 'le délai de grisage doit être explicite');
assert.match(html, /setInterval\(fetchAndApplyStatuses, STATUS_REFRESH_MS\)/, 'le grisage doit être réactualisé périodiquement');
for (const imageName of ['budget-si.jpg', 'studio-portee.png']) {
const imagePath = path.join(root, 'images', imageName);
assert.equal(fs.existsSync(imagePath), true, `l’asset ${imageName} doit être publié`);
assert.ok(fs.statSync(imagePath).size > 2048, `l’asset ${imageName} ne doit pas être vide`);
assert.match(attributions, new RegExp(imageName.replace('.', '\\.')), `l’attribution de ${imageName} doit être documentée`);
}
const script = html.match(/<script>([\s\S]*?)<\/script>/)?.[1];
assert.ok(script, 'le script dynamique du portail doit être présent');
const elements = new Map();
function element(id) {
if (!elements.has(id)) {
elements.set(id, {
innerHTML: '',
textContent: '',
classList: { toggle() {} },
setAttribute() {}
});
}
return elements.get(id);
}
const sandbox = {
AbortController,
Map,
Set,
URL,
console,
document: {
addEventListener() {},
getElementById: element,
querySelectorAll() { return []; }
},
setInterval() {},
setTimeout() { return 0; },
clearTimeout() {}
};
vm.createContext(sandbox);
vm.runInContext(script, sandbox);
sandbox.renderApps([
{
id: 'itinova-budget-si',
name: 'Gestion budget informatique',
category: 'SANTINOVA',
image: 'images/budget-si.jpg',
urls: { prod: 'https://budget-si.santinova-soft.org' },
status: 'online',
containerRunning: true
},
{
id: 'santelis-gestion',
name: 'SANTELIS Gestion',
category: 'SANTINOVA',
image: 'images/santelis-gestion.png',
urls: { prod: 'https://gestion-santelis.santinova-soft.org' },
status: 'online',
containerRunning: true
}
]);
const santinovaMarkup = element('grid-santinova').innerHTML;
assert.match(santinovaMarkup, /Gestion budget informatique/, 'Budget informatique doit être rendu dans le portail production');
assert.doesNotMatch(santinovaMarkup, /SANTELIS Gestion/, 'SANTELIS Gestion ne doit pas être rendu dans le portail production');
assert.equal(element('count-santinova').textContent, 1, 'le compteur Santinova ne doit retenir que les applications visibles');
console.log('OK portal-contract');