60 lines
3.2 KiB
JavaScript
60 lines
3.2 KiB
JavaScript
import { test } from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
const WURZEL = path.join(path.dirname(fileURLToPath(import.meta.url)), '..')
|
|
const NEU = path.join(WURZEL, 'public', 'neu')
|
|
const MODULE = ['ansicht-hilfen', 'rechnung-offen', 'install-hinweis', 'website-details', 'ansicht-website', 'ansicht-chat', 'ansicht-vertraege', 'vertraege-rechnungen', 'vertraege-abo', 'ansicht-stunden', 'ansicht-speicher', 'ansicht-bestellen', 'ansicht-wechsel', 'ansicht-gutschrift', 'ansicht-passwort', 'bestell-bausteine']
|
|
// Seit P7 sprechen auch die vier Bestellseiten „du“ (Fassung 6, C14); einzige Ausnahme ist der Rechtstext TAKEOVER_CONDITIONS (hash-gepinnt)
|
|
const WORTLAUT = []
|
|
const BESTELLSEITEN = ['ansicht-bestellen', 'ansicht-wechsel', 'ansicht-speicher', 'ansicht-gutschrift', 'bestell-bausteine']
|
|
const vorhanden = MODULE.filter((n) => existsSync(path.join(NEU, `${n}.js`)))
|
|
|
|
const ohneKommentare = (q) => q.replace(/\/\*[\s\S]*?\*\//g, '').replace(/(^|[^:'"`\\])\/\/[^\n]*/g, '$1')
|
|
const lies = (n) => ohneKommentare(readFileSync(path.join(NEU, `${n}.js`), 'utf8'))
|
|
|
|
function dateienUnter(ordner, muster) {
|
|
const aus = []
|
|
for (const name of readdirSync(path.join(WURZEL, ordner))) {
|
|
const pfad = path.join(WURZEL, ordner, name)
|
|
if (statSync(pfad).isDirectory()) aus.push(...dateienUnter(path.join(ordner, name), muster))
|
|
else if (muster.test(name)) aus.push(pfad)
|
|
}
|
|
return aus
|
|
}
|
|
|
|
test('P2-Module: kein HTML-Einsetzen, nur relative Importe, keine Admin-Verweise', () => {
|
|
for (const n of vorhanden) {
|
|
const q = lies(n)
|
|
assert.doesNotMatch(q, /innerHTML|insertAdjacentHTML|outerHTML|document\.write|console\.log/, n)
|
|
assert.doesNotMatch(q, /from\s+'\/|import\(\s*'\//, `${n}: absoluter Import`)
|
|
assert.doesNotMatch(q, /admin\.html|kalkulation\.html|\/api\/portal-admin/, n)
|
|
}
|
|
})
|
|
|
|
/** Quelltext ohne den Rechtstext TAKEOVER_CONDITIONS (er bleibt Zeichen für Zeichen in der Sie-Form). */
|
|
const ohneRechtstext = (q) => {
|
|
const i = q.indexOf('const TAKEOVER_CONDITIONS')
|
|
return i < 0 ? q : q.slice(0, i) + q.slice(q.indexOf(']', i))
|
|
}
|
|
|
|
test('P2-Module: Du-Form in allen Modulen, einzige Ausnahme der Block TAKEOVER_CONDITIONS (C14, P7)', () => {
|
|
for (const n of vorhanden.filter((x) => !WORTLAUT.includes(x))) assert.doesNotMatch(ohneRechtstext(lies(n)), /\b(Sie|Ihr(e[nmrs]?)?|Ihnen)\b/, n)
|
|
assert.match(lies('ansicht-gutschrift'), /Ihr Abo ersetzt/, 'der Rechtstext bleibt unverändert in der Sie-Form')
|
|
})
|
|
|
|
test('Bestellseiten: kein kundenart im Body, keine eigene h1 (Titel meldet die Ansicht)', () => {
|
|
for (const n of BESTELLSEITEN) {
|
|
assert.ok(existsSync(path.join(NEU, `${n}.js`)), n)
|
|
const q = lies(n)
|
|
assert.doesNotMatch(q, /body:\s*\{[^}]*kundenart/s, n)
|
|
assert.doesNotMatch(q, /h\(\s*['"]h1['"]/, n)
|
|
}
|
|
})
|
|
|
|
test('public/neu/: kein Lila in irgendeiner Textdatei (die Prüfung lila liest jedes geladene Stylesheet samt ungenutzter Regeln)', () => {
|
|
for (const pfad of dateienUnter('public/neu', /\.(css|html|js|mjs|svg|webmanifest)$/)) assert.doesNotMatch(readFileSync(pfad, 'utf8'), /#9d3dfe|rgba?\(\s*157\s*,\s*61\s*,\s*254/i, pfad)
|
|
})
|