Files
Webklar-Kundenbereich/test/legalDocs.test.js
T
ClaudeandClaude Opus 5.5 0e74f1669c Webshop A3: Register-Eintrag shop, Haken, Rechtstext-Satz und Ticket-Details
Registereintrag config.features.shop (Bestelltexte mit Fassung config.shop.fassung, Rechtsunterlagen-Getter,
Mailtexte, Ticket), STANDARD_HAKEN.shop (Schalter, Bestellpruefung ueber shop/anfrage.js, Unterlagen, Belehrung),
legalDocs-Satz shop, shopTicketDetails sowie Rumpf von anfrageOffenePunkte. Tests angepasst und um Shop-Faelle erweitert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 08:35:28 +00:00

418 lines
22 KiB
JavaScript

import { test, after, mock } from 'node:test'
import assert from 'node:assert/strict'
import { closeSync, copyFileSync, existsSync, mkdirSync, mkdtempSync, openSync, readFileSync, rmSync, writeFileSync, writeSync } from 'node:fs'
import fsp from 'node:fs/promises'
import { syncBuiltinESMExports } from 'node:module'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { Router } from 'express'
import { useTestEnv } from './support/testEnv.js'
useTestEnv({ appwriteUrl: 'http://127.0.0.1:1', stripeUrl: 'http://127.0.0.1:1' })
const { config } = await import('../server/config.js')
const { startTestApp } = await import('./support/testApp.js')
const { legalPaths, legalPdfFiles, legalPdfAttachments, featureLegalAttachments, featureLegalReady, featureLegalPaths, legalRouter, setLegalDirForTests } = await import(
'../server/services/legalDocs.js'
)
const analyse = await import('../server/services/analyseLegal.js')
const { featureConfig } = await import('../server/services/featureRegistry.js')
const V = config.termine.avvVersion
const ALT = '2026-10-02' // eingefrorene Altfassung der Gaestetexte und der Analyse-Rechtstexte
const root = (rel) => new URL(`../${rel}`, import.meta.url)
// Router mit eigenem Verzeichnis: die Adressen ohne Fassung liefern die Datei der Fassung aus config
const dir = mkdtempSync(join(tmpdir(), 'legaldocs-'))
const inhalt = (name, version) => `<p>${name} ${version}</p>`
const DATEIEN = ['leistungsbeschreibung-terminplaner', 'avv-terminplaner', 'widerrufsbelehrung-funktionen']
for (const slug of DATEIEN) writeFileSync(join(dir, `${slug}-${V}.html`), inhalt(slug, V))
writeFileSync(join(dir, `avv-website-analyse-${ALT}.html`), inhalt('avv-website-analyse', ALT))
const rechtliches = Router()
rechtliches.use(legalRouter({ dir }))
const app = await startTestApp({ '/rechtliches': rechtliches })
after(() => {
app.close()
rmSync(dir, { recursive: true, force: true })
})
const get = async (path) => {
const r = await fetch(app.url + path)
return { status: r.status, text: await r.text() }
}
/** Konstante und Register fuer einen Test setzen; stellt sie danach wieder her. */
async function mitFassung(fassung, fn) {
const alt = config.termine.avvVersion
config.termine.avvVersion = fassung
try {
return await fn()
} finally {
config.termine.avvVersion = alt
}
}
test('legalPaths("termine", V) nennt drei versionierte Adressen', () => {
assert.deepEqual(legalPaths('termine', V), {
lb: `/rechtliches/leistungsbeschreibung-terminplaner-${V}.html`,
avv: `/rechtliches/avv-terminplaner-${V}.html`,
widerruf: `/rechtliches/widerrufsbelehrung-funktionen-${V}.html`,
})
assert.deepEqual(Object.keys(legalPaths('termine', V)), ['lb', 'avv', 'widerruf'])
assert.deepEqual(legalPaths('analyse', ALT), {
avv: `/rechtliches/avv-website-analyse-${ALT}.html`,
lb: `/rechtliches/leistungsbeschreibung-website-analyse-${ALT}.html`,
})
})
test('legalPaths: ungültige Fassung und unbekannter Satz werfen', () => {
for (const satz of ['termine', 'analyse']) {
for (const v of ['../x', '2026-10-5', '2026-10-05x', 'ENTWURF', '', undefined, null, '2026-10-05/../x']) {
assert.throws(() => legalPaths(satz, v), /Fassung/, `${satz}: ${String(v)}`)
assert.throws(() => legalPdfFiles(satz, v), /Fassung/)
}
}
for (const satz of ['news', 'unbekannt', '__proto__', 'toString', '', undefined]) {
assert.throws(() => legalPaths(satz, V), /Satz/, String(satz))
assert.throws(() => legalPdfFiles(satz, V), /Satz/)
}
})
test('legalPdfFiles: Dateinamen und Pfade je Satz und Fassung', () => {
const t = legalPdfFiles('termine', V)
assert.deepEqual(Object.keys(t), ['lb', 'avv', 'widerruf'])
assert.equal(t.lb.filename, `Leistungsbeschreibung-Terminplaner-${V}.pdf`)
assert.equal(t.avv.filename, `AVV-Terminplaner-${V}.pdf`)
assert.equal(t.widerruf.filename, `Widerrufsbelehrung-Muster-Widerrufsformular-${V}.pdf`)
assert.equal(t.lb.path, new URL(`../public/rechtliches/leistungsbeschreibung-terminplaner-${V}.pdf`, import.meta.url).pathname)
assert.equal(t.avv.path, new URL(`../public/rechtliches/avv-terminplaner-${V}.pdf`, import.meta.url).pathname)
assert.equal(t.widerruf.path, new URL(`../public/rechtliches/widerrufsbelehrung-funktionen-${V}.pdf`, import.meta.url).pathname)
const a = legalPdfFiles('analyse', ALT)
assert.deepEqual(Object.keys(a), ['avv', 'lb'])
assert.equal(a.avv.filename, `AVV-Website-Analyse-${ALT}.pdf`)
assert.equal(a.lb.filename, `Leistungsbeschreibung-Website-Analyse-${ALT}.pdf`)
})
test('legalPdfAttachments: fehlende Datei wirft, Analyse liefert avv und lb, ohne lässt Dokumente weg', async () => {
await assert.rejects(legalPdfAttachments('termine', '1999-01-01'))
await assert.rejects(legalPdfAttachments('analyse', '1999-01-01'))
await assert.rejects(legalPdfAttachments('unbekannt', V), /Satz/)
const alle = await legalPdfAttachments('analyse', ALT)
assert.deepEqual(alle.map((x) => x.filename), [`AVV-Website-Analyse-${ALT}.pdf`, `Leistungsbeschreibung-Website-Analyse-${ALT}.pdf`])
for (const x of alle) {
assert.equal(x.contentType, 'application/pdf')
assert.equal(x.content.subarray(0, 4).toString(), '%PDF')
}
const ohneAvv = await legalPdfAttachments('analyse', ALT, { ohne: ['avv'] })
assert.deepEqual(ohneAvv.map((x) => x.filename), [`Leistungsbeschreibung-Website-Analyse-${ALT}.pdf`])
// eine ausgelassene Datei muss nicht vorhanden sein
assert.deepEqual(await legalPdfAttachments('termine', '1999-01-01', { ohne: ['lb', 'avv', 'widerruf'] }), [])
await assert.rejects(legalPdfAttachments('analyse', ALT, { ohne: ['gibtsnicht'] }), /Dokument/)
})
test('featureLegalAttachments / featureLegalReady: news ohne Dokumente, unbekannte Funktion nie bereit', async () => {
assert.deepEqual(await featureLegalAttachments('news'), [])
assert.deepEqual(await featureLegalAttachments('news', { ohne: ['lb'] }), [])
assert.equal(await featureLegalReady('news'), true)
await assert.rejects(featureLegalAttachments('gibtsnicht'), /Funktion/)
await assert.rejects(featureLegalAttachments('analyse'), /Funktion/)
await assert.rejects(featureLegalAttachments('__proto__'), /Funktion/)
assert.equal(await featureLegalReady('gibtsnicht'), false)
assert.equal(await featureLegalReady('analyse'), false)
})
test('featureLegalAttachments("termine") liest die Fassung aus config.termine.avvVersion; fehlt eine Datei, ist die Funktion nicht bereit', async () => {
await mitFassung('1999-01-01', async () => {
await assert.rejects(featureLegalAttachments('termine'))
assert.equal(await featureLegalReady('termine'), false)
})
})
// R114 (Task F8): featureLegalReady läuft bei jeder Bestellung (Stufe 5b des Checkouts) und prüft je PDF nur stat (Größe > 0) und die
// ersten fünf Bytes "%PDF-", nie den ganzen Inhalt. Die Dateien liegen für den Test in einem Verzeichnis mit Kopien.
test('featureLegalReady("termine"): je PDF stat und "%PDF-", nie den ganzen Inhalt lesen; jeder Mangel und jeder Fehler ergibt false, nie einen Wurf', async () => {
const kopien = mkdtempSync(join(tmpdir(), 'legal-ready-'))
mkdirSync(join(kopien, 'rechtliches'))
// Quellen: die ausgelieferten Dateien (vor dem Tausch des Verzeichnisses ermittelt)
const echteHtml = legalPaths('termine', V)
const echtePdf = Object.fromEntries(Object.entries(legalPdfFiles('termine', V)).map(([doc, f]) => [doc, f.path]))
const bereit = () => {
for (const adresse of Object.values(echteHtml)) copyFileSync(root(`public${adresse}`), join(kopien, adresse))
for (const pfad of Object.values(echtePdf)) copyFileSync(pfad, join(kopien, 'rechtliches', pfad.split('/').at(-1)))
}
const pdfPfad = (doc) => join(kopien, 'rechtliches', echtePdf[doc].split('/').at(-1))
const htmlPfad = (doc) => join(kopien, echteHtml[doc])
const lesen = mock.method(fsp, 'readFile')
syncBuiltinESMExports()
try {
setLegalDirForTests(kopien)
bereit()
assert.equal(await featureLegalReady('termine'), true)
assert.equal(lesen.mock.callCount(), 0, 'readFile wird nicht aufgerufen')
// ein riesiges PDF mit gültigem Kopf (nur Loch im Dateisystem): bereit, ohne es zu lesen
const gross = openSync(pdfPfad('lb'), 'w')
writeSync(gross, '%PDF-1.4\n')
closeSync(gross)
await fsp.truncate(pdfPfad('lb'), 512 * 1024 * 1024)
assert.equal(await featureLegalReady('termine'), true)
assert.equal(lesen.mock.callCount(), 0, 'auch ein 512-MB-PDF wird nicht gelesen')
bereit()
// Mängel je Datei: fehlend, leer, falscher Kopf, zu kurz, Verzeichnis statt Datei
for (const doc of ['lb', 'avv', 'widerruf']) {
const pfad = pdfPfad(doc)
rmSync(pfad)
assert.equal(await featureLegalReady('termine'), false, `${doc}: PDF fehlt`)
writeFileSync(pfad, '')
assert.equal(await featureLegalReady('termine'), false, `${doc}: PDF leer`)
writeFileSync(pfad, '<html>kein PDF</html>')
assert.equal(await featureLegalReady('termine'), false, `${doc}: kein %PDF-`)
writeFileSync(pfad, '%PDF')
assert.equal(await featureLegalReady('termine'), false, `${doc}: zu kurz`)
rmSync(pfad)
mkdirSync(pfad)
assert.equal(await featureLegalReady('termine'), false, `${doc}: Verzeichnis statt Datei`)
rmSync(pfad, { recursive: true })
bereit()
assert.equal(await featureLegalReady('termine'), true, `${doc}: wieder bereit`)
// die HTML-Seite fehlt
rmSync(htmlPfad(doc))
assert.equal(await featureLegalReady('termine'), false, `${doc}: HTML fehlt`)
bereit()
}
assert.equal(lesen.mock.callCount(), 0, 'nie readFile')
// ohne Verzeichnis, mit unbekannter Funktion und mit unbekannter Fassung: false statt Wurf
await mitFassung('1999-01-01', async () => assert.equal(await featureLegalReady('termine'), false))
assert.equal(await featureLegalReady('gibtsnicht'), false)
setLegalDirForTests(join(kopien, 'gibtsnicht'))
assert.equal(await featureLegalReady('termine'), false)
// die Anhänge der Mail lesen dagegen die ganzen Dateien (legalPdfAttachments)
setLegalDirForTests(kopien)
bereit()
assert.equal((await featureLegalAttachments('termine')).length, 3)
assert.ok(lesen.mock.callCount() >= 3)
} finally {
setLegalDirForTests(null)
mock.restoreAll()
syncBuiltinESMExports()
rmSync(kopien, { recursive: true, force: true })
}
assert.equal(await featureLegalReady('termine'), true, 'mit den ausgelieferten Dateien bereit')
})
// R121: ein Anhang ist ein PDF. Eine leere oder keine PDF-Datei wird nie angehängt, sondern wirft (die Aufrufer fangen den Wurf).
test('legalPdfAttachments: eine leere Datei oder eine Datei ohne "%PDF-" am Anfang wirft, ausgenommene Dokumente zählen nicht', async () => {
const kopien = mkdtempSync(join(tmpdir(), 'legal-anhang-'))
mkdirSync(join(kopien, 'rechtliches'))
const echtePdf = Object.fromEntries(Object.entries(legalPdfFiles('termine', V)).map(([doc, f]) => [doc, f.path]))
const pdfPfad = (doc) => join(kopien, 'rechtliches', echtePdf[doc].split('/').at(-1))
const bereit = () => {
for (const pfad of Object.values(echtePdf)) copyFileSync(pfad, join(kopien, 'rechtliches', pfad.split('/').at(-1)))
}
try {
setLegalDirForTests(kopien)
bereit()
const gut = await legalPdfAttachments('termine', V)
assert.equal(gut.length, 3)
for (const a of gut) assert.equal(a.content.subarray(0, 5).toString('latin1'), '%PDF-')
for (const doc of ['lb', 'avv', 'widerruf']) {
for (const [mangel, inhaltDatei] of [['leer', ''], ['kein PDF', '<html>kein PDF</html>'], ['zu kurz', '%PDF'], ['PDF nicht am Anfang', ' %PDF-1.4\n']]) {
writeFileSync(pdfPfad(doc), inhaltDatei)
await assert.rejects(legalPdfAttachments('termine', V), /PDF/, `${doc}: ${mangel}`)
await assert.rejects(featureLegalAttachments('termine'), /PDF/, `${doc}: ${mangel} (Funktion)`)
// ein ausgenommenes Dokument wird nicht gelesen und darf kaputt sein
const ohne = await legalPdfAttachments('termine', V, { ohne: [doc] })
assert.equal(ohne.length, 2, `${doc}: ${mangel}, ausgenommen`)
}
bereit()
assert.equal((await legalPdfAttachments('termine', V)).length, 3, `${doc}: wieder in Ordnung`)
}
} finally {
setLegalDirForTests(null)
rmSync(kopien, { recursive: true, force: true })
}
})
// Fassung wählbar (Task F8, Fix-Runde 1): K15 schickt die Unterlagen der Fassung, der der Kunde zugestimmt hat
test('featureLegalAttachments / featureLegalReady / featureLegalPaths mit opts.fassung', async () => {
assert.deepEqual(featureLegalPaths('termine'), legalPaths('termine', V))
assert.deepEqual(featureLegalPaths('termine', { fassung: '2026-10-01' }), legalPaths('termine', '2026-10-01'))
assert.equal(featureLegalPaths('news'), null)
assert.throws(() => featureLegalPaths('gibtsnicht'), /Funktion/)
assert.throws(() => featureLegalPaths('termine', { fassung: '2026-10-5' }), /Fassung/)
// ausdrücklich die aktuelle Fassung = ohne Angabe
assert.deepEqual((await featureLegalAttachments('termine', { fassung: V })).map((a) => a.filename), (await featureLegalAttachments('termine')).map((a) => a.filename))
assert.equal(await featureLegalReady('termine', { fassung: V }), true)
// andere Fassung ohne Dateien: Wurf bei den Anhängen, false bei der Prüfung, news weiter []
await assert.rejects(featureLegalAttachments('termine', { fassung: '1999-01-01' }))
assert.equal(await featureLegalReady('termine', { fassung: '1999-01-01' }), false)
assert.equal(await featureLegalReady('termine', { fassung: 'kaputt' }), false)
assert.deepEqual(await featureLegalAttachments('news', { fassung: '1999-01-01' }), [])
// opts.ohne wirkt weiter neben fassung
assert.deepEqual((await featureLegalAttachments('termine', { fassung: V, ohne: ['avv'] })).map((a) => a.filename.split('-')[0]), ['Leistungsbeschreibung', 'Widerrufsbelehrung'])
})
test('config.termine.avvVersion: Datumsmuster, nach der Altfassung der Gästetexte, echter Tag', () => {
assert.match(config.termine.avvVersion, /^\d{4}-\d{2}-\d{2}$/)
assert.ok(config.termine.avvVersion > ALT, `${config.termine.avvVersion} liegt nicht nach ${ALT}`)
assert.ok(config.termine.avvVersion >= '2026-10-03')
assert.ok(!Number.isNaN(Date.parse(`${config.termine.avvVersion}T00:00:00Z`)))
assert.equal(new Date(`${config.termine.avvVersion}T00:00:00Z`).toISOString().slice(0, 10), config.termine.avvVersion)
})
test('config.ustHinweis bleibt wörtlich', () => {
assert.equal(config.ustHinweis, 'ohne Umsatzsteuer gemäß § 19 UStG')
})
test('Register: leistungsbeschreibung und avv des Terminplaners folgen der Konstante (Getter, Drift-Wächter)', async () => {
const t = featureConfig('termine')
assert.deepEqual(t.leistungsbeschreibung, { version: V, url: legalPaths('termine', V).lb })
assert.deepEqual(t.avv, { version: V, url: legalPaths('termine', V).avv })
assert.doesNotMatch(JSON.stringify([t.leistungsbeschreibung, t.avv]), /ENTWURF/)
// zur Laufzeit geaendert: der Getter folgt
await mitFassung('2099-01-02', async () => {
assert.deepEqual(t.leistungsbeschreibung, { version: '2099-01-02', url: legalPaths('termine', '2099-01-02').lb })
assert.deepEqual(t.avv, { version: '2099-01-02', url: legalPaths('termine', '2099-01-02').avv })
})
assert.deepEqual(t.leistungsbeschreibung, { version: V, url: legalPaths('termine', V).lb })
// ein Test darf den Eintrag ueberschreiben (siehe termineFragebogen.test.js)
const merke = t.leistungsbeschreibung
t.leistungsbeschreibung = { version: 'T1', url: '/x' }
assert.deepEqual(t.leistungsbeschreibung, { version: 'T1', url: '/x' })
t.leistungsbeschreibung = merke
assert.deepEqual(t.leistungsbeschreibung, merke)
})
test('News: Leistungsbeschreibung folgt der Fassung <F> (Adresse unverändert, kein AVV, kein Getter am Eintrag)', () => {
const n = featureConfig('news')
assert.deepEqual(n.leistungsbeschreibung, { version: config.termine.avvVersion, url: '/vertragsunterlagen/funktionen-leistungsbeschreibung.html' })
assert.equal(n.avv, null)
assert.deepEqual(analyse.legalPaths(ALT), legalPaths('analyse', ALT))
assert.equal(Object.getOwnPropertyDescriptor(n, 'leistungsbeschreibung').get, undefined)
})
// Webshop (Block A3): eigener Satz mit eigener Fassung config.shop.fassung; die Dateien legt Block J an
test('Webshop-Satz: Adressen, PDF-Namen und Funktionszuordnung folgen config.shop.fassung', async () => {
const S = config.shop.fassung
assert.match(S, /^\d{4}-\d{2}-\d{2}$/)
assert.deepEqual(legalPaths('shop', S), {
lb: `/rechtliches/leistungsbeschreibung-webshop-${S}.html`,
avv: `/rechtliches/avv-webshop-${S}.html`,
widerruf: `/rechtliches/widerrufsbelehrung-funktionen-${S}.html`,
})
assert.deepEqual(Object.keys(legalPaths('shop', S)), ['lb', 'avv', 'widerruf'])
const f = legalPdfFiles('shop', S)
assert.equal(f.lb.filename, `Leistungsbeschreibung-Webshop-${S}.pdf`)
assert.equal(f.avv.filename, `AVV-Webshop-${S}.pdf`)
assert.equal(f.widerruf.filename, `Widerrufsbelehrung-Muster-Widerrufsformular-${S}.pdf`)
assert.equal(f.avv.path, new URL(`../public/rechtliches/avv-webshop-${S}.pdf`, import.meta.url).pathname)
assert.throws(() => legalPaths('shop', '2026-10-5'), /Fassung/)
// die aktuelle Fassung des Satzes shop ist config.shop.fassung (nicht die der Termine)
assert.deepEqual(featureLegalPaths('shop'), legalPaths('shop', S))
const alt = config.shop.fassung
config.shop.fassung = '2099-01-02'
try {
assert.deepEqual(featureLegalPaths('shop'), legalPaths('shop', '2099-01-02'))
assert.deepEqual(featureLegalPaths('termine'), legalPaths('termine', V), 'Termine bleiben bei ihrer Fassung')
await assert.rejects(featureLegalAttachments('shop'))
} finally {
config.shop.fassung = alt
}
assert.deepEqual(featureLegalPaths('shop', { fassung: '2026-10-01' }), legalPaths('shop', '2026-10-01'))
assert.deepEqual(featureLegalPaths('termine'), legalPaths('termine', V))
})
test('featureLegalReady("shop") ist true genau dann, wenn alle sechs Dateien der Fassung da sind (bis Block J: false)', async () => {
const S = config.shop.fassung
const html = Object.values(legalPaths('shop', S))
const pdfs = Object.values(legalPdfFiles('shop', S)).map((x) => x.path)
const alleDa = html.every((p) => existsSync(root(`public${p}`))) && pdfs.every((p) => existsSync(p))
assert.equal(await featureLegalReady('shop'), alleDa)
assert.equal(await featureLegalReady('shop', { fassung: '1999-01-01' }), false)
// nie ein Wurf bei fehlenden Dateien; die Anhaenge werfen dagegen
if (!alleDa) await assert.rejects(featureLegalAttachments('shop'))
})
test('Register: leistungsbeschreibung, avv und widerruf des Webshops folgen config.shop.fassung (Drift-Wächter)', () => {
const s = featureConfig('shop')
const S = config.shop.fassung
const p = legalPaths('shop', S)
assert.deepEqual(s.leistungsbeschreibung, { version: S, url: p.lb })
assert.deepEqual(s.avv, { version: S, url: p.avv })
assert.deepEqual(s.widerruf, { version: S, url: p.widerruf })
assert.equal(s.consent.version, S)
})
test('config.js importiert legalDocs.js nicht (Adresse aus Slug und Version gebaut)', () => {
const src = readFileSync(root('server/config.js'), 'utf8')
assert.doesNotMatch(src, /^\s*(import\b[^\n]*|.*\bimport\()['"`][^'"`]*legalDocs/m)
assert.doesNotMatch(src, /^import .* from '\.\/services\//m)
})
test('analyseLegal.js ist ein dünner Wrapper um die Registry', async () => {
assert.deepEqual(analyse.legalPaths(ALT), legalPaths('analyse', ALT))
assert.deepEqual(analyse.legalPdfFiles(ALT), legalPdfFiles('analyse', ALT))
assert.deepEqual(await analyse.legalPdfAttachments(ALT), await legalPdfAttachments('analyse', ALT))
assert.throws(() => analyse.legalPaths('../x'), /Fassung/)
await assert.rejects(analyse.legalPdfAttachments('1999-01-01'))
assert.equal(typeof analyse.analyseLegalRouter, 'function')
})
test('Router: Adressen ohne Fassung liefern die Fassung aus config (Terminplaner)', async () => {
for (const slug of DATEIEN) {
const r = await get(`/rechtliches/${slug}.html`)
assert.equal(r.status, 200, slug)
assert.equal(r.text, inhalt(slug, V))
}
// die Fassung folgt der Konstante zur Laufzeit: fuer eine andere Fassung gibt es keine Datei => 404
await mitFassung('2099-01-02', async () => {
assert.equal((await get('/rechtliches/avv-terminplaner.html')).status, 404)
})
assert.equal((await get('/rechtliches/avv-terminplaner.html')).status, 200)
})
test('Router: Adressen ohne Fassung der Analyse liefern config.analyse.avvVersion', async () => {
assert.equal(config.analyse.avvVersion, ALT)
const r = await get('/rechtliches/avv-website-analyse.html')
assert.equal(r.status, 200)
assert.equal(r.text, inhalt('avv-website-analyse', ALT))
// die zweite Analyse-Datei fehlt im Testverzeichnis: 404, kein 500
assert.equal((await get('/rechtliches/leistungsbeschreibung-website-analyse.html')).status, 404)
})
test('Router: nur die festen Adressen, versionierte und fremde Pfade fallen durch', async () => {
for (const p of [
`/rechtliches/avv-terminplaner-${V}.html`, // versionierte Adressen liefert express.static in index.js
'/rechtliches/avv-terminplaner.pdf',
'/rechtliches/../config.js',
'/rechtliches/gibtsnicht.html',
'/rechtliches/',
]) {
assert.equal((await get(p)).status, 404, p)
}
const post = await fetch(`${app.url}/rechtliches/avv-terminplaner.html`, { method: 'POST' })
assert.equal(post.status, 404)
})
test('Router: legalRouter() ohne Verzeichnis liefert die Analyse-Adressen aus public/rechtliches', async () => {
const echt = Router()
echt.use(legalRouter())
const a = await startTestApp({ '/rechtliches': echt })
try {
const r = await fetch(`${a.url}/rechtliches/avv-website-analyse.html`)
assert.equal(r.status, 200)
assert.deepEqual(Buffer.from(await r.arrayBuffer()), readFileSync(root(`public/rechtliches/avv-website-analyse-${ALT}.html`)))
} finally {
a.close()
}
})
test('server/index.js hängt den gemeinsamen Router vor express.static ein', () => {
const index = readFileSync(root('server/index.js'), 'utf8')
assert.match(index, /import \{ legalRouter \} from '\.\/services\/legalDocs\.js'/)
assert.ok(index.includes("app.use('/rechtliches', legalRouter())"))
assert.ok(!index.includes('analyseLegalRouter'))
assert.ok(index.indexOf("app.use('/rechtliches', legalRouter())") < index.indexOf('app.use(express.static(publicDir))'))
})