Skip to content

test: snapshot invoice PDF structure and totals - #1397

Open
Ebomi wants to merge 3 commits into
CalloraOrg:mainfrom
Ebomi:security/issue-1301-snapshot-invoice-pdf-structure-and-totals
Open

Ebomi wants to merge 3 commits into
CalloraOrg:mainfrom
Ebomi:security/issue-1301-snapshot-invoice-pdf-structure-and-totals

Conversation

@Ebomi

@Ebomi Ebomi commented Sep 29, 2026

Copy link
Copy Markdown

Overview

This PR adds test coverage for generateInvoicePdf in src/services/invoicePdf.ts, which previously built a customer-facing PDF Buffer from InvoicePdfData with no tests. The tests snapshot the PDF structure (header/footer), assert that line item totals are reflected in the output, and cover zero-line-item and special-character edge cases. A small hardening change to the PDF text escaping was needed to satisfy the special-character criterion.

Related Issue

Changes

🧾 Invoice PDF tests

  • [ADD] src/services/invoicePdf.test.ts
    • Asserts the generated buffer starts with the %PDF- header and ends with %%EOF.
    • Asserts the invoice number and computed total appear in the PDF content.
    • Asserts each line item total matches the input (quantity × unit price).
    • Covers the empty line-item list case and asserts a valid PDF is still produced.
    • Covers parentheses and backslashes in API names and asserts the document is not corrupted (header/footer intact, escaped text present, no stray unescaped delimiters).

🛡️ PDF text escaping

  • [MODIFY] src/services/invoicePdf.ts
    • Escapes (, ), and \ in text drawn into the PDF content stream so API names containing these characters cannot break the document structure.
    • No change to the public signature of generateInvoicePdf or to InvoicePdfData; existing callers are unaffected.

Verification Results

npm test -- src/services/invoicePdf.test.ts
✅ all tests passed
Acceptance Criteria Status
Output begins with the PDF header and ends with %%EOF ✅ Asserted in invoicePdf.test.ts
Line item totals match the input ✅ Per-item totals asserted against quantity × unit price
Parentheses and backslashes in names do not corrupt the document ✅ Escaping added in invoicePdf.ts; covered by test
Empty line-item lists still generate a valid PDF ✅ Zero-line-item case asserted to produce header/footer-valid output

Security and Failure Modes

  • Injection into the PDF content stream: Unescaped (, ), or \ in API names could terminate or corrupt a text object. Escaping these characters in invoicePdf.ts prevents malformed output and keeps the document parseable.
  • Empty input: The zero-line-item path is exercised so a missing/empty lineItems array cannot silently produce a broken buffer.
  • No weakened validation: No safeguards were removed; the only production change is additive escaping.

Compatibility

  • generateInvoicePdf signature and InvoicePdfData shape are unchanged.
  • Escaping only affects text rendering for names containing (, ), or \; names without these characters render identically.
  • No dependency or config changes.

Closes #1301

@drips-wave

drips-wave Bot commented Sep 29, 2026

Copy link
Copy Markdown

@Ebomi Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Snapshot invoice PDF structure and totals

1 participant