← back to Estimate Instant
Bound JSON parsing and validate roll snapshots
28cfeb66ecfbf001a3ba94f966546c99f8931c40 · 2026-08-29 06:28:15 -0700 · Steve Abrams
Files touched
M test/calculate-coverage.test.js
Diff
commit 28cfeb66ecfbf001a3ba94f966546c99f8931c40
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sat Aug 29 06:28:15 2026 -0700
Bound JSON parsing and validate roll snapshots
---
test/calculate-coverage.test.js | 50 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/test/calculate-coverage.test.js b/test/calculate-coverage.test.js
index a4ed230..9cd0e3a 100644
--- a/test/calculate-coverage.test.js
+++ b/test/calculate-coverage.test.js
@@ -2,8 +2,9 @@
const test = require('node:test');
const assert = require('node:assert/strict');
+const { EventEmitter } = require('node:events');
const http = require('node:http');
-const { calculateCoverage, handleRequest } = require('../server.js');
+const { body, calculateCoverage, handleRequest, loadRolls, validateRollSnapshot, MAX_JSON_BODY_BYTES } = require('../server.js');
const roll = {
sku: 'DW-TEST-1',
@@ -150,4 +151,51 @@ test('serves the real local HTTP journey and returns 400 on bad input', async (t
});
assert.equal(bad.status, 400);
assert.equal((await bad.json()).ok, false);
+
+ for (const route of ['/api/calculate-coverage', '/api/estimate', '/api/lead']) {
+ const malformed = await fetch(`${base}${route}`, {
+ method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{bad',
+ });
+ assert.equal(malformed.status, 400, route);
+ assert.match((await malformed.json()).error, /malformed or invalid UTF-8 JSON/i);
+
+ const oversized = await fetch(`${base}${route}`, {
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ padding: 'x'.repeat(MAX_JSON_BODY_BYTES) }),
+ });
+ assert.equal(oversized.status, 413, route);
+ assert.match((await oversized.json()).error, /exceeds/i);
+ }
+});
+
+test('parses split UTF-8 exactly and settles aborted bodies', async () => {
+ const encoded = Buffer.from(JSON.stringify({ name: 'café ����' }));
+ const split = encoded.indexOf(Buffer.from('����')) + 2;
+ const req = new EventEmitter();
+ const parsedPromise = body(req);
+ req.emit('data', encoded.subarray(0, split));
+ req.emit('data', encoded.subarray(split));
+ req.emit('end');
+ assert.deepEqual(await parsedPromise, { ok: true, value: { name: 'café ����' } });
+
+ const aborted = new EventEmitter();
+ const abortedPromise = body(aborted);
+ aborted.emit('data', Buffer.from('{"name":'));
+ aborted.emit('aborted');
+ assert.deepEqual(await abortedPromise, { ok: false, status: 400, error: 'Request body was aborted.' });
+});
+
+test('validates the complete checked-in roll snapshot and rejects bad schemas', () => {
+ const actual = loadRolls();
+ assert.equal(validateRollSnapshot(actual).ok, true);
+ for (const broken of [
+ [],
+ [{ ...roll, roll_width_in: 0 }],
+ [{ ...roll, match: 'mystery' }],
+ [{ ...roll, shopify_match: true, shopify_sku: '', shopify_price: 0 }],
+ [{ ...roll }, { ...roll }],
+ [{ ...roll, sku: ' DW-TEST-1' }],
+ [{ ...roll, match: ' half-drop ' }],
+ [{ ...roll, shopify_sku: ' DW-SHOPIFY-1 ' }],
+ ]) assert.equal(validateRollSnapshot(broken).ok, false);
});
← 014cf2e fix: return HTTP 400 on estimate error (null roll / invalid
·
back to Estimate Instant
·
Persist parser boundary regressions 943a9a7 →