address code review: assert page count in multi-page test, document fixes

- Lock in the exact expected page count (4) for the 60+60-row pagination
  test, which previously only checked the buffer was non-trivial. This is
  the scenario most likely to expose a footer/pagination regression.
- Add short comments explaining the footerY height-bound fix and the
  pdfPageCount() regex's coupling to pdfkit's serialization format.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Bastian Wagner
2026-08-04 13:33:48 +02:00
parent 4185efb83a
commit 24c509c0d5
2 changed files with 12 additions and 0 deletions

View File

@@ -1,5 +1,8 @@
import { buildCsv, buildPdf, buildReceivableRows, buildRows } from './cashbox-export.utils';
// Reads the page count directly out of the raw PDF bytes instead of pulling in
// a parser dependency. Coupled to pdfkit's current /Pages dict serialization -
// a pdfkit upgrade that reorders/reflows it could require adjusting this regex.
function pdfPageCount(buffer: Buffer): number {
const match = buffer.toString('latin1').match(/\/Type\s*\/Pages[\s\S]{0,80}?\/Count\s+(\d+)/);
if (!match) throw new Error('Could not find page count in PDF buffer');
@@ -344,5 +347,8 @@ describe('buildPdf', () => {
expect(buffer.subarray(0, 5).toString('utf-8')).toBe('%PDF-');
expect(buffer.length).toBeGreaterThan(2000);
// Guards against the footer loop reintroducing blank trailing pages: with
// the bug, this dataset produced 12 pages (3x the real content pages).
expect(pdfPageCount(buffer)).toBe(4);
});
});

View File

@@ -313,6 +313,12 @@ function addFooters(doc: PDFKit.PDFDocument, teamName: string): void {
for (let i = range.start; i < range.start + range.count; i++) {
doc.switchToPage(i);
const footerY = doc.page.height - 25;
// footerY sits inside the reserved bottom margin (below pdfkit's page
// maxY()). Without an explicit `height`, pdfkit's LineWrapper measures
// overflow against the full-page maxY() and calls addPage() here on every
// iteration - silently appending blank trailing pages. Bounding the text
// to its own small box (well over the 8pt single-line height needed)
// keeps the overflow check local and stops that auto-pagination.
doc
.fontSize(8)
.font('Helvetica')