Import d'un pack par la route de fusion, champs fermes, correction des champs vides
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m44s
build / Garde-fou (push) Successful in 10m44s
build / Images Harbor (web, Dockerfile) (push) Successful in 13m25s

This commit is contained in:
hcornet committed 2026-09-11 21:15:23 +02:00
1 parent ec195cac8f
commit bc18f93196
5 files changed
+287 -51

No files matched your search

+73
View File
@@ -29,6 +29,26 @@ const dom = new JSDOM(html, {
const { window } = dom;
// Reponses minimales mais de la bonne forme, comme celles du serveur.
// Ce que renverrait le serveur pour une fusion : le pack apporte bien plus que
// des commandes et des modeles.
const PROJET_FUSIONNE = {
name: 'Essai', centreon_version: '25.10', prefix: '', plugins_dir: '/usr/lib/centreon/plugins',
poller: 'Central', apply_config: true, notif_dir: '/usr/share/centreon/notifications',
commands: [{ name: 'App-Essai-Cpu', type: 'check', line: '$USER1$/check', comment: '' }],
service_templates: [], hosts: [],
host_templates: [{ name: 'App-Essai-custom', alias: 'Essai', parents: [], macros: [],
perimetre: 'Essai', check_command: '', check_command_args: '',
snmp_version: '', snmp_community: '', timezone: '' }],
groupes_hotes: [{ name: 'HG-App-Essai', alias: 'Essai' }],
calendriers: [{ name: 'Heures-Ouvrees', alias: '8h-18h', jours: { monday: '08:00-18:00' } }],
perimetres: [{ name: 'Essai', description: '', calendrier: 'Heures-Ouvrees', contacts: [],
groupe: 'CG-App-Essai', options_hote: 'd,u,r', options_service: 'w,c,r',
intervalle: 30, application: '', responsable: '', procedure: '',
criticite: 'Majeure', impact: 'Essai', couleur: '#2f6f9f',
sujet_hote: '', sujet_service: '', blocs_hote: [], blocs_service: [] }],
prerequis: { paquets_debian: ['libwww-perl'], paquets_rhel: [], verifications: [], notes: '' },
};
const reponses = {
'/api/packs': [
{ id: 'app-essai', name: 'Essai', category: 'applications', category_label: 'Applications',
@@ -37,6 +57,11 @@ const reponses = {
],
'/api/generer': { summary: {}, issues: [], files: { 'deploy.clapi': '' } },
'/api/projets': [],
'/api/packs/app-essai/fusionner': { project: PROJET_FUSIONNE, ignores: [] },
'/api/valeurs-standards': {},
'/api/fuseaux': ['Europe/Paris'],
'/api/commandes-usuelles': [{ nom: 'check_centreon_ping', description: 'Ping' }],
'/api/macros-notification': [],
};
window.fetch = (url) => Promise.resolve({
ok: true,
@@ -94,6 +119,36 @@ if (erreurs.length === 0) {
}
}
// L'import d'un pack doit apporter tout ce que le serveur renvoie, pas
// seulement les commandes et les modeles.
try {
document.getElementById('btn-pack').click();
await new Promise((r) => setTimeout(r, 30));
const importer = [...document.querySelectorAll('#modal-corps button')]
.find((b) => b.textContent === 'Sondes par defaut');
if (!importer) {
erreurs.push('aucun bouton d import dans le catalogue');
} else {
importer.click();
await new Promise((r) => setTimeout(r, 40));
const projet = window.projetCourant();
for (const [cle, libelle] of [
['groupes_hotes', "groupe d'hotes"],
['calendriers', 'calendrier'],
['perimetres', 'perimetre'],
]) {
if (!projet[cle] || projet[cle].length === 0) {
erreurs.push(`l import d un pack n apporte pas le ${libelle}`);
}
}
if (!projet.prerequis || !projet.prerequis.paquets_debian.length) {
erreurs.push('l import d un pack n apporte pas les prerequis');
}
}
} catch (erreur) {
erreurs.push('import d un pack : ' + erreur.message);
}
// Un pack deja dans le projet ne doit plus etre proposable a l'import.
try {
window.eval("projetCourant().host_templates.push({ name: 'App-Essai-custom', macros: [], parents: [] });");
@@ -130,8 +185,26 @@ if (erreurs.length === 0) {
erreurs.push('catalogue de packs : ' + erreur.message);
}
// Un champ sans valeur ne doit jamais afficher le mot « undefined ».
for (const entree of rail.querySelectorAll('.rail-item')) {
principal.innerHTML = '';
entree.click();
const champs = [...principal.querySelectorAll('input, textarea, select')];
const fautifs = champs.filter((c) => String(c.value).includes('undefined'));
if (fautifs.length) {
erreurs.push(
`${entree.textContent.trim()} : ${fautifs.length} champ(s) affichent undefined`
);
break;
}
}
// Les notifications doivent s'afficher, avec leur type.
try {
// Les actions precedentes ont pu en laisser : on part d'une zone vide.
const zoneExistante = document.getElementById('notifications');
if (zoneExistante) zoneExistante.innerHTML = '';
window.eval("notifier('essai de reussite', 'succes'); notifier('essai d erreur', 'erreur');");
const zone = document.getElementById('notifications');
if (!zone || zone.children.length !== 2) {
+14
View File
@@ -299,3 +299,17 @@ def test_nom_affiche_et_baseline():
assert "Générateur de configuration pour Centreon avec CLAPI" in page
# La mention d'independance devient d'autant plus necessaire.
assert "Centreon SAS" in page
def test_l_editeur_utilise_la_route_de_fusion():
"""Garde-fou contre une correction qui n'a pas ete appliquee.
L'import d'un pack a laisse deux versions durant, une ancienne fonction qui
ne recopiait que trois listes : le remplacement avait echoue en silence, et
aucun test n'empruntait ce chemin.
"""
from pathlib import Path
script = Path("enclume/static/editeur.js").read_text(encoding="utf-8")
assert "/fusionner" in script, "l'import n'appelle pas la route de fusion"
assert "'service_templates', 'host_templates'" not in script, "l'ancien import subsiste"