66 lines
4.4 KiB
JavaScript
66 lines
4.4 KiB
JavaScript
// Gemeinsame Testdaten und Quelltext-Regeln des Strangs L6 (kein Test, daher nicht *.test.js).
|
|
// Formen laut Übersicht V3 (AuftragOeffentlich) und V5 (Liste im Portal: plus id und kannBestaetigen).
|
|
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
|
|
export const TOKEN = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG' // 43 Zeichen wie ein echter Token (base64url)
|
|
export const BESTAETIGT_AM = '2026-10-07T08:15:00.000Z' // = 07.10.2026, 10:15 Uhr Berliner Zeit (MESZ)
|
|
export const KLEINUNTERNEHMER = 'Gemäß § 19 UStG wird keine Umsatzsteuer berechnet.' // wie AB_TEXTE.kleinunternehmer; die API liefert ihn als texte.kleinunternehmer
|
|
|
|
/** Festpreis-AB eines Unternehmens, gesendet, noch nicht bestätigt. */
|
|
export const ab = (over = {}) => ({
|
|
nummer: 'AB-2026-0002', datum: '2026-10-06', titel: 'Website Anelia Wolf', art: 'festpreis',
|
|
positionen: [
|
|
{ beschreibung: 'Erstellung der Website anelia-wolf.com', menge: 1, einzelpreisCents: 60000, summeCents: 60000 },
|
|
{ beschreibung: 'Texte und Bildbearbeitung', menge: 2, einzelpreisCents: 10000, summeCents: 20000 },
|
|
],
|
|
summeCents: 80000, stundensatzCents: null, schaetzungMinuten: null, aufwandText: null,
|
|
zahlungsplanText: 'Anzahlung 50 % (400,00 €) nach Auftragsbestätigung, Rest (400,00 €) nach Abnahme; zahlbar jeweils innerhalb von 14 Tagen nach Rechnung.',
|
|
startAm: '2026-10-12', fertigBis: '2026-11-30', kundenart: 'unternehmen', status: 'versendet',
|
|
bestaetigtAm: null, fruehbeginn: false, fruehesterBeginn: null, agbUrl: '/rechtliches/agb-2026-09-30.pdf',
|
|
texte: { bestaetigung: 'Ich bestätige den Auftrag zu diesen Bedingungen.', fruehbeginn: null, kleinunternehmer: KLEINUNTERNEHMER },
|
|
...over,
|
|
})
|
|
|
|
/** Dieselbe AB für eine Privatperson (zweites, freiwilliges Häkchen; Texte sind Testtexte, nicht die der Rechtsrunde). */
|
|
export const privat = (over = {}) => ab({
|
|
kundenart: 'privat', fruehesterBeginn: '2026-10-21',
|
|
texte: {
|
|
bestaetigung: 'Ich bestätige den Auftrag zu diesen Bedingungen.',
|
|
fruehbeginn: 'Ich verlange, dass Sie schon vor Ablauf der Widerrufsfrist mit der Arbeit beginnen.',
|
|
kleinunternehmer: KLEINUNTERNEHMER,
|
|
},
|
|
...over,
|
|
})
|
|
|
|
/** Die übergebene AB im Zustand „bestätigt“. */
|
|
export const bestaetigt = (auftrag) => ({ ...auftrag, status: 'bestaetigt', bestaetigtAm: BESTAETIGT_AM })
|
|
|
|
/** Eintrag der Portal-Liste (GET /api/auftraege): AB plus id und kannBestaetigen. */
|
|
export const eintrag = (over = {}) => ({ id: 'ab1', ...ab(), kannBestaetigen: true, ...over })
|
|
|
|
const ohneKommentare = (quelle) => quelle.replace(/\/\*[\s\S]*?\*\//g, '').replace(/(^|\s)\/\/.*$/gm, '$1')
|
|
const DU = /\b(?:du|dein(?:e[nmrs]?)?|dich|dir)\b/i
|
|
const SIE = /\b(?:Sie|Ihr(?:e[nmrs]?)?|Ihnen)\b/
|
|
/** Steht eine Du- bzw. Sie-Form im Text? (Anrede-Prüfungen der Tests) */
|
|
export const hatDuForm = (text) => DU.test(String(text))
|
|
export const hatSieForm = (text) => SIE.test(String(text))
|
|
|
|
/**
|
|
* Quelltext-Regeln für jedes Modul public/auftrag*.js; gibt den Quelltext ohne Kommentare zurück.
|
|
* mitTexten: nur auftrag-ansicht.js enthält Kundentexte (ihre Anrede prüft der Test selbst); alle anderen Module enthalten weder Du- noch Sie-Formen.
|
|
*/
|
|
export function pruefeQuelltext(datei, { fetchAnzahl = 0, importe = [], mitTexten = false } = {}) {
|
|
const quelle = ohneKommentare(readFileSync(new URL(`../public/${datei}`, import.meta.url), 'utf8'))
|
|
assert.doesNotMatch(quelle, /innerHTML|insertAdjacentHTML|outerHTML|document\.write|\beval\(|new Function/, `${datei}: Daten nie als HTML`)
|
|
assert.doesNotMatch(quelle, /localStorage|sessionStorage|document\.cookie|indexedDB/, `${datei}: kein Browserspeicher`)
|
|
assert.doesNotMatch(quelle, /\bconsole\./, `${datei}: nichts ins Protokoll (der Token!)`)
|
|
assert.doesNotMatch(quelle, /\bconfirm\(|\balert\(|\bprompt\(/, `${datei}: keine Browser-Rückfragen`)
|
|
assert.doesNotMatch(quelle, /import\s*\(/, `${datei}: kein dynamischer Import`)
|
|
assert.ok(!quelle.includes(String.fromCodePoint(0xa0)), `${datei}: kein verstecktes geschütztes Leerzeichen im Quelltext`)
|
|
if (!mitTexten) assert.ok(!DU.test(quelle) && !hatSieForm(quelle), `${datei}: keine Kundentexte im Modul (sie stehen in auftrag-ansicht.js; Anrede über ANREDE_SIE/ANREDE_DU)`)
|
|
assert.equal([...quelle.matchAll(/\bfetch\(/g)].length, fetchAnzahl, `${datei}: Anzahl fetch`)
|
|
assert.deepEqual([...quelle.matchAll(/\bfrom\s+'([^']+)'/g)].map((m) => m[1]), importe, `${datei}: Importe`)
|
|
return quelle
|
|
}
|