Files
Webklar-Kundenbereich/test/kundenansichtEntscheidungen.test.js
T
ClaudeandClaude Opus 5.5 64f1a3b26b Rechtsrunde Fassung 6 freigegeben (28.10.2026): Datum, Entwurfsmarken, R8b
Der Inhaber hat am 28.10.2026 alle Vorschläge R1 bis R18 angenommen (R10 = Option A)
und zusätzlich R8b entschieden: Webshop und Buchungskalender kehren nach einem neuen
Wartungs-Abo in der Frist automatisch zurück, wie der Server es schon tut.

- Fassungen: Abo 2026-10-28-v6, Funktionsunterlagen 2026-10-28 (Seiten neu gebaut)
- Entwurfsmarken und meta robots noindex entfernt, ENTWURF_V6 = false
- WORTLAUT_STATUS = 'freigegeben'
- Nr. 10 Abs. 5 Webshop/Buchungskalender ohne "auf Wunsch in Textform" (R8b)
- Entscheidungsliste: Abschnitt "Freigabe"; Prüfpunkte D1 bis D8 auf die aktuelle
  Datenschutzerklärung (Fassung 22.10.2026, eine Zeile tiefer) umgestellt
- Tests auf das neue Datum und den Status freigegeben gezogen

Live ändert sich für Kunden nichts: die Seiten liegen unter /neu/ und gelten nur in der
neuen Ansicht (Pilot). Umschalten (P10) folgt erst auf ausdrückliches "umschalten".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 14:46:53 +00:00

44 lines
3.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.
import { test } from 'node:test'
import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
// Entscheidungsliste, Kanzlei-Fragen, Ablauf nach der Freigabe und Datenschutz-Prüfpunkte der Rechtsrunde Fassung 6 (Task 11).
const lies = (rel) => readFileSync(new URL(`../${rel}`, import.meta.url), 'utf8')
const ENTWURF = false
const md = lies('docs/rechtliches/kundenansicht-entscheidungen.md'), dsg = lies('docs/rechtliches/datenschutz-kundenansicht-pruefpunkte.md')
test('Entscheidungsliste: R1 bis R18, je Punkt Vorschlag, Alternative und Kanzlei-Frage', () => {
const z = md.split('\n').filter((l) => /^\| R\d+ \|/.test(l)).map((l) => l.split('|').slice(1, -1).map((s) => s.trim()))
assert.deepEqual(z.map((r) => r[0]), Array.from({ length: 18 }, (_, i) => `R${i + 1}`))
for (const r of z) { assert.equal(r.length, 5); assert.ok(r.every(Boolean), r[0]); assert.match(r[4], /^(–|KQ\d+(, KQ\d+)*)$/, r[0]) }
const kq = [...md.matchAll(/^### (KQ\d+): .+$/gm)].map((m) => m[1])
assert.deepEqual(kq, Array.from({ length: 9 }, (_, i) => `KQ${i + 1}`))
for (const r of z) for (const id of r[4].match(/KQ\d+/g) ?? []) assert.ok(kq.includes(id), `${r[0]} nennt ${id}`)
assert.equal(md.includes('Entwurf zur Freigabe, keine Rechtsberatung'), ENTWURF)
})
test('R8 ist mit P4/P6 abgestimmt: Zeiten laufen 30 Tage weiter, die übrigen schalten am Folgetag ab, kein Behalten', () => {
const [, punkt, vorschlag, alternative] = md.split('\n').find((l) => l.startsWith('| R8 |')).split('|').slice(1, -1).map((s) => s.trim())
assert.match(punkt, /mit P4\/P6 abgestimmt/)
for (const s of ['spätestens am Folgetag', 'Öffnungszeiten live läuft nach dem Ende noch 30 Tage unverändert weiter', 'kein Behalten']) assert.ok(vorschlag.includes(s), s)
assert.doesNotMatch(vorschlag, /Karenz|entfällt/)
assert.ok(alternative.includes('Öffnungszeiten live schalten wie die übrigen spätestens am Folgetag ab'))
})
test('Kanzlei-Fragen haben vier Teile', () => {
for (const teil of md.split(/\n(?=### KQ\d+:)/).slice(1)) for (const k of ['**Frage.**', '**Fundstelle im Text.**', '**Unsere Annahme.**', '**Alternative.**']) assert.ok(teil.includes(k), `${teil.slice(0, 8)} ${k}`)
})
test('AVV-Struktur nennt A, B und C; Ablauf nach der Freigabe in fester Reihenfolge mit Schutzbefehlen', () => {
const avv = md.slice(md.indexOf('## AVV-Struktur'), md.indexOf('## Ablauf nach der Freigabe'))
for (const s of ['Option A', 'Option B', 'Option C', 'Anlage 1']) assert.ok(avv.includes(s), s)
const a = md.slice(md.indexOf('## Ablauf nach der Freigabe'))
const reihenfolge = ['Freigabe des Inhabers', 'ENTWURF = false', 'scripts/build-legal-html.mjs funktionen6', 'free -m', 'nice -n 10 scripts/build-legal-pdfs.sh abo6', 'nice -n 10 scripts/build-legal-pdfs.sh funktionen6', 'rechtliches-hochladen.mjs --probe', '--karten-anlegen', 'ein Aufruf je Dokument', '--freigabe=', '--pruefen']
const pos = reihenfolge.map((s) => { const i = a.indexOf(s); assert.ok(i >= 0, s); return i })
assert.deepEqual([...pos].sort((x, y) => x - y), pos, 'Reihenfolge')
assert.ok(a.includes('Datum der Fassungen') && a.includes('Entwurfsmarke'), 'Datum setzen und Marken entfernen')
})
test('Datenschutz-Prüfpunkte D1 bis D8 mit gültiger Fundstelle in public/datenschutz.html', () => {
assert.deepEqual([...dsg.matchAll(/^\*\*(D\d)\*\*/gm)].map((m) => m[1]), ['D1', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8'])
const zeilen = lies('public/datenschutz.html').split('\n')
const refs = [...dsg.matchAll(/public\/datenschutz\.html:(\d+)/g)].map((m) => Number(m[1]))
assert.ok(refs.length >= 8 && refs.every((n) => n >= 1 && n <= zeilen.length))
assert.ok(zeilen[127].includes('Zahlungspflichtig bestellen') && zeilen[126].includes('Leistungsbeginn') && zeilen[102].includes('Wartungs-Abo'), 'D1, D2, D5 zitieren die richtigen Zeilen')
})