teach/test/body-parser.test.js
Ramon 45f66044f2
All checks were successful
dev - build & deploy naar test / build-and-deploy (push) Successful in 38s
fix: alle DELETE-verzoeken faalden op een lege JSON-body (v0.4.02-beta)
De echte, uiteindelijke oorzaak achter elke "serverfout" die niet door een
route-eigen foutafhandeling kwam (klas verwijderen, en zeer waarschijnlijk
ook de oorspronkelijke gebruiker-verwijderen-bug): de client stuurde bij élk
verzoek altijd "Content-Type: application/json" mee, ook bij een DELETE
zonder body. Fastify's standaard JSON-parser weigert zo'n leeg lichaam met
"Body cannot be empty when content-type is set to 'application/json'" -
vóórdat er ook maar één hook of route-handler heeft kunnen draaien, dus nog
vóór req.user gezet wordt en vóór enige try/catch in een route. Dat verklaart
waarom eerdere per-route foutafhandeling dit nooit kon vangen: de fout zat
vóór elke route.

- public/js/core.js: api() stuurt Content-Type alleen nog mee als er
  werkelijk een JSON-body is
- src/body-parser.js (nieuw): serverside vangnet dat een leeg lichaam bij
  Content-Type: application/json gewoon toestaat i.p.v. te weigeren -
  ongeacht wat een client meestuurt
- test/body-parser.test.js: reproduceert de exacte foutmelding tegen een
  echte Fastify-requestcyclus (de gemockte-pool-tests konden dit principieel
  nooit vangen, vandaar dat dit alle eerdere testrondes overleefde)
2026-07-18 03:44:39 +02:00

49 lines
2.1 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import Fastify from 'fastify';
import { registerEmptyJsonBodyParser } from '../src/body-parser.js';
// Dit is precies wat public/js/core.js's api() vóór de fix altijd deed voor
// een DELETE zonder body: Content-Type: application/json meesturen zonder
// werkelijke inhoud. Fastify's ingebouwde JSON-parser weigert dat met "Body
// cannot be empty when content-type is set to 'application/json'" - vóórdat
// er ook maar één hook of route-handler heeft kunnen draaien. Geen enkele
// gemockte-pool-test kon dit vangen (die simuleren geen echte HTTP-requests),
// vandaar deze losse test tegen een echte Fastify-request-cyclus.
test('leeg lichaam met Content-Type: application/json wordt niet geweigerd', async () => {
const app = Fastify();
registerEmptyJsonBodyParser(app);
app.delete('/thing/:id', async () => ({ ok: true }));
await app.ready();
const res = await app.inject({
method: 'DELETE', url: '/thing/1', headers: { 'content-type': 'application/json' },
});
assert.equal(res.statusCode, 200, res.body);
assert.deepEqual(res.json(), { ok: true });
await app.close();
});
test('ongeldige JSON in het lichaam geeft nog steeds een nette 400', async () => {
const app = Fastify();
registerEmptyJsonBodyParser(app);
app.post('/thing', async (req) => ({ received: req.body }));
await app.ready();
const res = await app.inject({
method: 'POST', url: '/thing', headers: { 'content-type': 'application/json' }, payload: '{niet geldig',
});
assert.equal(res.statusCode, 400);
await app.close();
});
test('een echte JSON-body werkt gewoon zoals voorheen', async () => {
const app = Fastify();
registerEmptyJsonBodyParser(app);
app.post('/thing', async (req) => ({ received: req.body }));
await app.ready();
const res = await app.inject({
method: 'POST', url: '/thing', headers: { 'content-type': 'application/json' }, payload: { a: 1 },
});
assert.equal(res.statusCode, 200, res.body);
assert.deepEqual(res.json(), { received: { a: 1 } });
await app.close();
});