TEST REPORT: Failed Payment Dunning (for Stripe), n8n pack v1.0.0
Run from a clean unzipped copy of the dist zip (fresh npm install / pip install). Started 2026-10-17 06:24:25 BST (UTC+01:00), finished 2026-10-17 06:25:12 BST (UTC+01:00) (times from date at run time). Box: Linux, Node v24.22.0, Python 3.13.5. n8n 2.43.7 (npm) on Node v24.22.0, task runner in internal mode (deprecated by n8n, see SETUP.md).
Result: 21/21 static checks + 22/22 end-to-end checks passed.
1. Static validation: python3 tests/validate_workflow.py
PASS has name, nodes, connections
PASS node names unique
PASS node ids unique
PASS every node has type/typeVersion/position/parameters
PASS connections reference existing nodes
PASS every non-trigger node is connected
PASS exactly one webhook trigger, POST, responseNode
PASS no real-looking secrets shipped
PASS workflow inactive on import
PASS n8n-nodes-base.webhook v2 exists in installed n8n
PASS n8n-nodes-base.set v3.4 exists in installed n8n
PASS n8n-nodes-base.code v2 exists in installed n8n
PASS n8n-nodes-base.if v2.2 exists in installed n8n
PASS n8n-nodes-base.respondToWebhook v1.1 exists in installed n8n
PASS n8n-nodes-base.respondToWebhook v1.1 exists in installed n8n
PASS n8n-nodes-base.removeDuplicates v2 exists in installed n8n
PASS n8n-nodes-base.if v2.2 exists in installed n8n
PASS n8n-nodes-base.code v2 exists in installed n8n
PASS n8n-nodes-base.httpRequest v4.2 exists in installed n8n
PASS n8n-nodes-base.if v2.2 exists in installed n8n
PASS n8n-nodes-base.emailSend v2.1 exists in installed n8n
21/21 passed
2. End-to-end in real n8n: tests/e2e_n8n.py
The harness creates a throwaway n8n home and uses the n8n CLI to import the workflow and an SMTP credential and publish the workflow. It then runs n8n start and posts signed sample events. Slack is a local mock HTTP server and email goes to a local SMTP sink. Both are mocked.
The harness deletes its throwaway n8n home after a passing run, so no local paths are printed. It also checks that a "Final notice" is sent only when next_payment_attempt is null. A fixture (attempt 3, retry still scheduled) checks that this case gets the normal notice.
PASS n8n import:credentials
PASS n8n import:workflow
PASS n8n publish:workflow
PASS bad signature -> 400
PASS stale timestamp -> 400
PASS tampered body -> 400
PASS no alerts for rejected requests
PASS valid payment_failed -> 200
PASS slack alert sent once
PASS slack text has amount, attempt, retry
PASS customer email sent to jamie@example.com
PASS email has hosted invoice link
PASS duplicate delivery -> 200
PASS duplicate produced no new alert/email
PASS attempt 3 with retry pending -> 200
PASS attempt 3 + retry pending is NOT a final notice
PASS final failed attempt (next_payment_attempt null) -> 200
PASS final notice subject + no-more-retries text
PASS recovered payment -> 200
PASS recovery slack alert, no customer email
PASS first-try paid -> 200
PASS first-try paid is silent
22/22 checks passed (throwaway n8n home deleted)
Not tested
- Real Slack, real SMTP providers, and live Stripe deliveries.
- n8n Cloud, n8n 1.x, and the external task-runner mode.
- The Stripe Dashboard steps in SETUP.md (written from Stripe's docs).