const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const vm = require('node:vm'); const html = fs.readFileSync(path.join(__dirname, '..', 'index.html'), 'utf8'); assert.match(html, /id="downloadPdf"[^>]*>PDF herunterladen<\/button>/, 'PDF-Download-Button fehlt'); const start = html.indexOf('/* PDF-DOWNLOAD */'); const end = html.indexOf('/* PDF = Druckdialog', start); assert.ok(start >= 0 && end > start, 'PDF-Download-Implementierung fehlt'); const sandbox = { Uint8Array, TextEncoder, Blob }; vm.createContext(sandbox); vm.runInContext(`${html.slice(start, end)}\nglobalThis.api={pdfFilename,buildPdfBytes};`, sandbox); const { pdfFilename, buildPdfBytes } = sandbox.api; assert.equal( pdfFilename('Napoletana', 4, 250, '24 Stunden'), 'Pizzateig-Napoletana-4x250g-24-Stunden.pdf' ); assert.equal( pdfFilename('Frei/Test', 2, 199.6, 'Same:Day'), 'Pizzateig-Frei-Test-2x200g-Same-Day.pdf' ); assert.equal( pdfFilename('Römisch tonda', 4, 200, 'Über Nacht'), 'Pizzateig-Romisch-tonda-4x200g-Uber-Nacht.pdf' ); const bytes = buildPdfBytes([ 'PIZZATEIG — Napoletana', '4 Teiglinge à 250 g · 1.000 g Teig', 'Mehl: Caputo Pizzeria · Hydration 62 %', '', 'ZUTATEN', ' Mehl 605 g', ' Wasser 375 g', ' Frischhefe 2,3 g', ' Salz 17 g', '', 'ZEITPLAN', ' 19:00 Mo — Teig kneten und ruhen lassen (30 Min.)', ' 19:30 Mo — Ballen formen und bei Raumtemperatur reifen lassen', ' 23:00 Mo — Ballen in den Kühlschrank stellen', ' 15:00 Di — Ballen aus dem Kühlschrank nehmen', ' 19:00 Di — Pizza backen', '', 'https://teig.deploybar.de/#style=napo&balls=4&ball=250&plan=d24', ]); assert.ok(bytes instanceof Uint8Array); const ascii = Buffer.from(bytes).toString('latin1'); assert.ok(ascii.startsWith('%PDF-1.4')); assert.match(ascii, /\/Type \/Catalog/); assert.match(ascii, /\/Type \/Page\b/); assert.match(ascii, /\/Encoding \/WinAnsiEncoding/); assert.match(ascii, /0\.027 0\.031 0\.043 rg/); // dunkler Cyberpunk-Hintergrund assert.match(ascii, /0 0\.941 1 rg/); // Cyan-Akzent assert.match(ascii, /1 0\.176 0\.471 rg/); // Magenta-Akzent assert.match(ascii, /xref\n0 \d+/); assert.match(ascii, /%%EOF\n$/); assert.match(ascii, /\/Count 1\b/); const longPdf = Buffer.from(buildPdfBytes([ 'PIZZATEIG — Belastungstest', ...Array.from({ length: 120 }, (_, i) => `ZEILE ${i + 1} — Rezeptinformation`), ])).toString('latin1'); assert.match(longPdf, /\/Count 1\b/, 'PDF muss auf genau eine Seite begrenzt bleiben'); assert.equal((longPdf.match(/\/Type \/Page\b/g) || []).length, 1, 'PDF enthält mehr als eine A4-Seite'); fs.writeFileSync('/tmp/teig-terminal-download-test.pdf', Buffer.from(bytes)); console.log('pdf download tests: OK');