- presets.js : EC huile (5 mg IM), EB (1 mg IM), EUCS suspension cristalline (10 mg SC) — 25 entrées, champs Bateman informatifs - pk-engine.js : Esters.EUCS manquant (portage v1.9.0 incomplet — le preset référençait undefined) - models.js : choicesForModel ESE = 6 esters (parité Android v1.9.0 ; était resté sur la couverture des tables ODS à 3) + KDoc à jour - treatment-editor.js : liste des esters = choicesForModel(model) — rebascule sur EV si l'ester sort de la couverture au changement de modèle (garde anti 0 pg/mL) + re-render du formulaire - tests/presets.test.js (nouveau, 6) : couverture 6 esters ESE, unicité, i18n EN/FR, TFS 7 / WHSAH 6 inchangés, choicesForModel aligné dispatchs - versions 1.9.4 (settings + e2e) + CHANGELOG/§4/§8/README
71 lines
3.5 KiB
JavaScript
71 lines
3.5 KiB
JavaScript
/**
|
|
* Tests des PRESETS de traitements (v1.9.4 — miroir de `PKPresets.kt`) :
|
|
* le modèle ESE ANALYTIQUE couvre 6 esters injectables — les presets de
|
|
* création doivent offrir les 6 (comme TFS offre les 7 du V3C et WHSAH
|
|
* les 6 du fit Mona). Avant v1.9.4, les presets ESE n'offraient que
|
|
* EV/EU/EEn (l'héritage des tables ODS) — remontée : « les presets n'ont
|
|
* pas été mis à jour lors de l'ajout du modèle source ESE ».
|
|
*/
|
|
|
|
import { test, describe } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { all } from '../js/pk/presets.js';
|
|
|
|
describe('PKPresets web (presets ESE étendus — v1.9.4)', () => {
|
|
test('les presets ESE couvrent les 6 esters du fit analytique', () => {
|
|
const eseInjectable = all.filter((p) => p.pkModel === 'ESE' && p.esterType !== 'NONE');
|
|
const esters = eseInjectable.map((p) => p.esterType).sort();
|
|
assert.deepEqual(esters, ['EB', 'EC', 'EEN', 'EU', 'EUCS', 'EV']);
|
|
});
|
|
|
|
test('chaque ester couvert a EXACTEMENT un preset ESE (pas de doublon)', () => {
|
|
const eseInjectable = all.filter((p) => p.pkModel === 'ESE' && p.esterType !== 'NONE');
|
|
const names = eseInjectable.map((p) => p.nameKey);
|
|
assert.equal(new Set(names).size, names.length);
|
|
});
|
|
|
|
test('chaque preset a une clé i18n présente dans EN et FR', async () => {
|
|
const { store } = await import('../js/data/store.js');
|
|
store.setBackend(new Map()); // Node : pas de localStorage
|
|
const i18n = await import('../js/util/i18n.js');
|
|
// t() lit la langue du store (pas de setLanguage exporté) : on force
|
|
// successivement 'en' puis 'fr' via les settings (miroir de l'app).
|
|
for (const lang of ['en', 'fr']) {
|
|
store.setSettings({ language: lang });
|
|
for (const p of all) {
|
|
// t() retombe sur la clé brute si absente : un libellé égal à la
|
|
// clé = clé manquante (leçon §12 web : une string manquante
|
|
// s'affiche brute dans l'UI)
|
|
assert.notEqual(i18n.t(p.nameKey), p.nameKey, `clé i18n manquante (${lang}) : ${p.nameKey}`);
|
|
}
|
|
}
|
|
});
|
|
|
|
test('les presets TFS (7) et WHSAH (6) restent inchangés', () => {
|
|
const injectables = (model) => all.filter((p) => p.pkModel === model && p.esterType !== 'NONE');
|
|
assert.equal(injectables('TFS').length, 7);
|
|
assert.equal(injectables('WHS').length, 6);
|
|
});
|
|
|
|
test('choicesForModel (éditeur + dialog de dose) suit la couverture du fit ESE', async () => {
|
|
// v1.9.4 : l'éditeur liste choicesForModel(model) — si ce helper restait
|
|
// sur la couverture des tables ODS (3 esters), l'éditeur n'offrirait pas
|
|
// EC/EB/EUCS même avec les presets à jour (parité Android v1.9.0).
|
|
const { choicesForModel } = await import('../js/data/models.js');
|
|
assert.deepEqual(choicesForModel('ESE').sort(), ['EB', 'EC', 'EEN', 'EU', 'EUCS', 'EV']);
|
|
// TFS reste EXPLICITE à 7 (pas d'EUCS dans le V3C — sinon 0 pg/mL) et
|
|
// WHSAH à 6 (PEP non couvert).
|
|
assert.deepEqual(choicesForModel('TFS').sort(), ['EB', 'EC', 'ECS', 'EEN', 'EU', 'EV', 'PEP']);
|
|
assert.deepEqual(choicesForModel('WHS').sort(), ['EB', 'EC', 'ECS', 'EEN', 'EU', 'EV']);
|
|
assert.equal(choicesForModel('TFS').includes('EUCS'), false);
|
|
});
|
|
|
|
test('les presets ESE non-injectables (gel/patch/oral) restent en Bateman', () => {
|
|
const eseNonInjectable = all.filter(
|
|
(p) => p.pkModel === 'ESE' && (p.esterType === 'NONE' || p.esterType == null),
|
|
);
|
|
assert.ok(eseNonInjectable.length >= 3, 'gel/patch/oral toujours présents');
|
|
assert.ok(eseNonInjectable.every((p) => p.esterType === 'NONE'));
|
|
});
|
|
});
|