gestion_table_tournante_libre/src/interface/impression/ReglagesIllisibles.navigateur.test.js
Mathieu Benoit 73d08294f5 [FIX] local settings: an unreadable or unwritable file no longer blocks
An unreadable reglages_locaux.json, or a folder that refused to write it,
refused the paper choice, so no badge sheet or preview could be produced
on that machine. The chosen paper now holds for the session on that
working folder, in memory, and the file is never overwritten. On that
folder it wins over a stale paper still in the file; the first settings
write that succeeds there retains it and withdraws the warning. The
warning names the file and no longer promises defaults never written.
Checked: node 3918, browser 773; each fix red under the previous code.

--- FR ---

[FIX] réglages locaux : un fichier illisible ou non écrit ne bloque plus

Un reglages_locaux.json illisible, ou un dossier qui refusait de l'écrire,
refusait le choix du papier : ni planche ni aperçu sur cette machine. Le
papier choisi vaut désormais pour la séance sur ce dossier de travail, en
mémoire, et le fichier n'est jamais écrasé. Sur ce dossier, il l'emporte
sur un papier périmé du fichier ; la première écriture des réglages qui y
réussit le retient et retire l'avertissement. L'avertissement nomme le
fichier et ne promet plus de valeurs par défaut jamais écrites.
Vérifié : node 3918, navigateur 773 ; chaque correction rouge avant elle.

Assisted-by: Claude Opus 5.5
2026-10-10 20:20:04 -04:00

110 lines
5.8 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.

// © 2026 TechnoLibre (http://www.technolibre.ca)
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
// L'aperçu avant impression sur des réglages locaux que la lecture ne prend
// pas, ou que le dossier de travail refuse d'écrire (§ 8.5, § 11.2, § 11.7) :
// la question du papier se pose, le choix vaut pour la séance sans que
// reglages_locaux.json le retienne, et l'aperçu rend son document, sur le
// papier choisi, et sa commande « Imprimer » au lieu de reposer la question.
// Rien ne s'écrit : ni le fichier illisible, ni l'événement ; sous un dossier
// qui refuse l'écriture, la seule tentative est celle des réglages.
//
// App est montée par test/navigateur/ecrans.js sur le système de fichiers
// simulé, au cadre de 1 366 × 700.
//
// Le projet navigateur emploie expect, et test et describe de Vitest
// (§ 14.8).
import { afterEach, beforeEach, describe, expect, test } from 'vitest';
import { PAPIERS } from '../../geometrie/papiers.js';
import { FICHIER_REGLAGES } from '../../stockage/reglages_locaux.js';
import { fixerCadre } from '../../../test/navigateur/entrees.js';
import { attendre, chargePrincipale, cliquer, creerContexte, ouvrirApercu } from '../../../test/navigateur/ecrans.js';
import { creerImprimanteSimulee } from '../../../test/imprimante_simulee.js';
import { MM_PAR_PX } from './modele.js';
// Images attendues au plus par étape, comme dans Apercu.navigateur.test.js.
const IMAGES = 300;
// Une feuille se mesure au dixième de millimètre (§ 11.7).
const TOLERANCE_MM = 0.1;
let contexte = null;
beforeEach(async () => {
await fixerCadre(1366, 700);
contexte = creerContexte();
});
afterEach(async () => {
const erreurs = contexte.erreurs();
await contexte.defaire();
expect(erreurs, 'erreurs reçues par le collecteur').toEqual([]);
});
const dans = (m, selecteur) => m.racine.querySelector(selecteur);
const feuilles = (m) => [...m.racine.querySelectorAll('[data-impression] [data-feuille]')];
// Des réglages que la lecture ne prend pas : un format plus récent qui porte
// un papier inconnu de cette construction, et un texte tronqué.
const ILLISIBLES = [
['FORME', '{"format":2,"papier":"Legal","cadrages":[]}'],
['JSON', '{"format":1,"papier":"A4","cadr'],
];
describe('des réglages locaux illisibles ne bloquent pas l’aperçu (§ 8.5, § 11.7)', () => {
for (const [raison, texte] of ILLISIBLES) {
test(`${raison} : le papier choisi, l’aperçu montre le document et « Imprimer » au lieu de la question ; le fichier intact, rien ne s’écrit`, async () => {
const imprimante = creerImprimanteSimulee();
const m = await ouvrirApercu(contexte, chargePrincipale(), {
papier: null,
options: { imprimante, fichiers: [{ racine: 'documents', chemin: FICHIER_REGLAGES, texte }] },
});
const octets = m.fs.octets('documents', FICHIER_REGLAGES);
expect(dans(m, '[data-ecran="apercu"] [data-papier="question"]')).not.toBeNull();
expect(dans(m, '[data-impression]')).toBeNull();
const avant = m.trace.length;
await cliquer(m, '[data-papier="question"] [data-cible="A4"] [data-commande="choisirPapier"]');
await attendre('le document sur A4', () => feuilles(m).length > 0, IMAGES);
expect(m.seance.etat().papier).toBe('A4');
const boite = feuilles(m)[0].getBoundingClientRect();
const dims = [boite.width * MM_PAR_PX, boite.height * MM_PAR_PX].sort((a, b) => a - b);
expect(Math.abs(dims[0] - PAPIERS.A4.largeur)).toBeLessThanOrEqual(TOLERANCE_MM);
expect(Math.abs(dims[1] - PAPIERS.A4.hauteur)).toBeLessThanOrEqual(TOLERANCE_MM);
expect(dans(m, '[data-papier="question"]')).toBeNull();
expect(dans(m, '[data-ecran="apercu"] [data-refus]')).toBeNull();
const avis = m.seance.etat().avertissements.filter(({ code }) => code === 'REGLAGES_ILLISIBLES');
expect(avis).toEqual([{ code: 'REGLAGES_ILLISIBLES', details: { chemin: FICHIER_REGLAGES, raison } }]);
await cliquer(m, '[data-ecran="apercu"] [data-commande="imprimer"]');
await attendre("l'impression demandée", () => imprimante.appels().length === 1, IMAGES);
expect(imprimante.appels()[0].papier).toBe('A4');
expect(m.trace.slice(avant)).toEqual([]);
expect(m.fs.octets('documents', FICHIER_REGLAGES)).toEqual(octets);
});
}
});
describe('un dossier qui refuse l’écriture des réglages ne bloque pas l’aperçu (§ 8.5, § 11.7)', () => {
test('EROFS : le papier choisi, l’aperçu montre le document et « Imprimer » ; un avis le dit, et rien ne s’écrit', async () => {
const imprimante = creerImprimanteSimulee();
const m = await ouvrirApercu(contexte, chargePrincipale(), { papier: null, options: { imprimante } });
expect(dans(m, '[data-ecran="apercu"] [data-papier="question"]')).not.toBeNull();
m.fs.pannes.ecriture('documents');
const avant = m.trace.length;
await cliquer(m, '[data-papier="question"] [data-cible="A4"] [data-commande="choisirPapier"]');
await attendre('le document sur A4', () => feuilles(m).length > 0, IMAGES);
expect(m.seance.etat().papier).toBe('A4');
expect(dans(m, '[data-papier="question"]')).toBeNull();
expect(dans(m, '[data-ecran="apercu"] [data-refus]')).toBeNull();
const avis = m.seance.etat().avertissements.filter(({ code }) => code === 'REGLAGES_NON_ECRITS');
expect(avis).toEqual([
{ code: 'REGLAGES_NON_ECRITS', details: { chemin: FICHIER_REGLAGES, dossier: expect.any(String), cause: 'EROFS' } },
]);
await cliquer(m, '[data-ecran="apercu"] [data-commande="imprimer"]');
await attendre("l'impression demandée", () => imprimante.appels().length === 1, IMAGES);
expect(imprimante.appels()[0].papier).toBe('A4');
expect(m.trace.slice(avant)).toEqual([['ecrireAtomique', 'documents', FICHIER_REGLAGES]]);
expect(m.fs.contenu('documents', FICHIER_REGLAGES)).toBeNull();
});
});