source: Klonkt/test/playlist-editor-i18n.test.js

main
Last change on this file was d68ee3a, checked in by Robin <roboburr@…>, 3 weeks ago

Playlist-modal: de teksten door i18n

Ze stonden hard in mod/playlist-editor.js -- 34 stuks, van "Titel *" tot
"Upload mislukt". Dat viel niet op omdat het toevallig de brontaal was:
een Engelse of Duitse beheerder kreeg een Nederlandse modal midden in een
verder vertaalde pagina, en daar valt niets van om.

EIGEN GEGEVENSBLOK, niet partials/page-data.ejs. pageData() pakt met
querySelector EEN blok, en deze modal hangt onder pagina's die er zelf al
een hebben (admin-playlists, post-edit). Een tweede blok zou daar
stilzwijgend genegeerd worden -- en dan was de modal alsnog Nederlands
zonder dat er een fout verscheen.

De terugval in T() is de SLEUTELNAAM en niet de Nederlandse tekst:
ontbreekt er iets, dan zie je DAT er iets ontbreekt in plaats van een
scherm dat er half vertaald uitziet en waarvan niemand merkt welke helft.

De test sluit de hele keten -- script vraagt T('x'), partial geeft 'x'
door, i18n kent 'ple.x' in alle drie de talen. Drie schakels die elk los
kunnen kloppen terwijl het geheel stuk is, en de vergeten TAAL is de
schakel die niemand ziet die in het Nederlands werkt. Hij vond meteen een
echte misser: saveBtn.textContent = 'Opslaan...' was ik overgeslagen.

Zijn eerste versie sloeg ook alarm op een COMMENTAAR dat die woorden
noemde. Dat is nu weggefilterd: een test die op uitleg valt leert je hem
negeren.

Co-Authored-By: Claude Opus 5 <noreply@…>

  • Property mode set to 100644
File size: 3.6 KB
Line 
1// De playlist-modal spreekt de taal van de pagina (16-8).
2//
3// Tot vandaag stonden de teksten hard in mod/playlist-editor.js. Dat viel niet
4// op omdat het toevallig de brontaal was: een Engelse of Duitse beheerder kreeg
5// een Nederlandse modal midden in een verder vertaalde pagina, en er is geen
6// foutmelding die dat meldt.
7//
8// Deze test sluit de KETEN, en dat is het punt -- er zijn drie schakels en elke
9// schakel kan los kloppen terwijl het geheel stuk is:
10//
11// het script vraagt T('x') -> de partial zet 'x' in het gegevensblok
12// -> i18n.js kent 'ple.x' in nl, en EN de
13//
14// Een nieuwe tekst toevoegen en een van de drie vergeten is de fout die dit
15// vangt, en juist de vergeten TAAL merkt niemand die in het Nederlands werkt.
16import { test } from 'node:test';
17import assert from 'node:assert/strict';
18import fs from 'node:fs';
19
20const script = fs.readFileSync('src/assets/js/mod/playlist-editor.js', 'utf8');
21const partial = fs.readFileSync('src/views/partials/playlist-editor.ejs', 'utf8');
22const i18n = fs.readFileSync('src/services/i18n.js', 'utf8');
23
24// Alle sleutels die het script opvraagt. De declaratie van T() zelf niet.
25const gevraagd = new Set(
26 [...script.matchAll(/\bT\('([a-z0-9_]+)'\)/g)].map((m) => m[1])
27);
28
29test('het script vraagt uberhaupt sleutels op', () => {
30 assert.ok(gevraagd.size > 20, `maar ${gevraagd.size} sleutels gevonden -- klopt het patroon nog?`);
31});
32
33test('elke gevraagde sleutel staat in het gegevensblok van de partial', () => {
34 const blok = /data-playlist-editor-i18n><%-([\s\S]*?)%><\/script>/.exec(partial);
35 assert.ok(blok, 'geen i18n-blok in de partial');
36 const ontbreekt = [...gevraagd].filter((k) => !new RegExp(`\\b${k}:\\s*t\\('ple\\.${k}'\\)`).test(blok[1]));
37 assert.deepEqual(ontbreekt, [], `niet doorgegeven vanuit de partial: ${ontbreekt.join(', ')}`);
38});
39
40test('elke sleutel bestaat in alle drie de talen', () => {
41 // De taalblokken staan achter elkaar in i18n.js; per sleutel tellen hoe vaak
42 // hij voorkomt is genoeg om een vergeten vertaling te vinden.
43 const tekort = [];
44 for (const k of gevraagd) {
45 const n = (i18n.match(new RegExp(`'ple\\.${k}':`, 'g')) || []).length;
46 if (n !== 3) tekort.push(`${k} (${n}x)`);
47 }
48 assert.deepEqual(tekort, [], `niet in alle drie de talen: ${tekort.join(', ')}`);
49});
50
51test('er staat geen losse Nederlandse knoptekst meer in het script', () => {
52 // Grof maar effectief: dit zijn de woorden die er tot vandaag in stonden.
53 // Komt er een terug, dan is iemand de T() vergeten.
54 const verdacht = ['Annuleren', 'Opslaan', 'Aanmaken', 'Sluiten', 'Verslepen', 'Verwijderen',
55 'Beschikbare tracks', 'Geen resultaten', 'Uitgavedatum', 'Jaar', 'Artiest'];
56 // COMMENTAAR ERAF. De eerste versie sloeg alarm op een regel die alleen
57 // uitlegde wat er gebeurt -- en een test die op uitleg valt leert je hem
58 // negeren.
59 const code = script.replace(/\/\*[\s\S]*?\*\//g, ' ').replace(/^\s*\/\/.*$/gm, ' ');
60 const gevonden = verdacht.filter((w) => new RegExp(`['"\`>]${w}`).test(code));
61 assert.deepEqual(gevonden, [], `hardgecodeerde tekst terug in het script: ${gevonden.join(', ')}`);
62});
63
64test('het eigen gegevensblok botst niet met dat van de pagina', () => {
65 // pageData() pakt met querySelector EEN blok. Zou deze partial het gewone
66 // data-page-data gebruiken, dan won het blok van de gastpagina en bleef de
67 // modal onvertaald -- zonder dat er iets omvalt.
68 assert.ok(partial.includes('data-playlist-editor-i18n'), 'eigen kenmerk weg');
69 assert.ok(!/data-page-data/.test(partial), 'de partial gebruikt het gedeelde blok');
70 assert.ok(script.includes('data-playlist-editor-i18n'), 'het script leest het eigen blok niet');
71});
Note: See TracBrowser for help on using the repository browser.