test(httpkernel): enforce compile-time validation for signatures
- Replace runtime 500 errors with compile-time validation for invalid middleware and handler signatures using `assertThrows` - Improve test clarity by explicitly checking for expected exceptions and error messages
This commit is contained in:
@@ -1,4 +1,7 @@
|
|||||||
import { assertEquals } from 'https://deno.land/std@0.204.0/assert/mod.ts';
|
import {
|
||||||
|
assertEquals,
|
||||||
|
assertThrows,
|
||||||
|
} from 'https://deno.land/std@0.204.0/assert/mod.ts';
|
||||||
import { HttpKernel } from '../HttpKernel.ts';
|
import { HttpKernel } from '../HttpKernel.ts';
|
||||||
import type { IRouteDefinition } from '../Interfaces/mod.ts';
|
import type { IRouteDefinition } from '../Interfaces/mod.ts';
|
||||||
|
|
||||||
@@ -88,30 +91,32 @@ Deno.test('HttpKernel: middleware short-circuits pipeline', async () => {
|
|||||||
assertEquals(calls, ['mw1']);
|
assertEquals(calls, ['mw1']);
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test('HttpKernel: invalid middleware or handler signature triggers 500', async () => {
|
Deno.test('HttpKernel: invalid middleware or handler signature throws at compile time', () => {
|
||||||
const kernel = new HttpKernel();
|
const kernel = new HttpKernel();
|
||||||
|
|
||||||
// Middleware with wrong signature (missing ctx, next)
|
// Middleware with wrong signature (missing ctx, next)
|
||||||
kernel.route({ method: 'GET', path: '/bad-mw' })
|
assertThrows(
|
||||||
// @ts-expect-error invalid middleware
|
() => {
|
||||||
.middleware(() => new Response('invalid'))
|
kernel.route({ method: 'GET', path: '/bad-mw' })
|
||||||
.handle((_ctx) => Promise.resolve(new Response('ok')));
|
// @ts-expect-error invalid middleware
|
||||||
|
.middleware(() => new Response('invalid'))
|
||||||
const res1 = await kernel.handle(new Request('http://localhost/bad-mw'));
|
.handle((_ctx) => Promise.resolve(new Response('ok')));
|
||||||
assertEquals(res1.status, 500);
|
},
|
||||||
assertEquals(await res1.text(), 'Internal Server Error');
|
TypeError,
|
||||||
|
'Middleware at index 0 is not a valid function.',
|
||||||
|
);
|
||||||
|
|
||||||
// Handler with wrong signature (no ctx)
|
// Handler with wrong signature (no ctx)
|
||||||
kernel.route({ method: 'GET', path: '/bad-handler' })
|
assertThrows(
|
||||||
.middleware(async (_ctx, next) => await next())
|
() => {
|
||||||
// @ts-expect-error invalid handler
|
kernel.route({ method: 'GET', path: '/bad-handler' })
|
||||||
.handle(() => new Response('invalid'));
|
.middleware(async (_ctx, next) => await next())
|
||||||
|
// @ts-expect-error invalid handler
|
||||||
const res2 = await kernel.handle(
|
.handle(() => new Response('invalid'));
|
||||||
new Request('http://localhost/bad-handler'),
|
},
|
||||||
|
TypeError,
|
||||||
|
'Route handler must be a function returning a Promise<Response>.',
|
||||||
);
|
);
|
||||||
assertEquals(res2.status, 500);
|
|
||||||
assertEquals(await res2.text(), 'Internal Server Error');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test('HttpKernel: 404 for unmatched route', async () => {
|
Deno.test('HttpKernel: 404 for unmatched route', async () => {
|
||||||
@@ -124,7 +129,7 @@ Deno.test('HttpKernel: skips route with wrong method', async () => {
|
|||||||
const kernel = new HttpKernel();
|
const kernel = new HttpKernel();
|
||||||
|
|
||||||
kernel.route({ method: 'POST', path: '/only-post' })
|
kernel.route({ method: 'POST', path: '/only-post' })
|
||||||
.handle(() => Promise.resolve(new Response('nope')));
|
.handle((_ctx) => Promise.resolve(new Response('nope')));
|
||||||
|
|
||||||
const res = await kernel.handle(
|
const res = await kernel.handle(
|
||||||
new Request('http://localhost/only-post', { method: 'GET' }),
|
new Request('http://localhost/only-post', { method: 'GET' }),
|
||||||
@@ -152,7 +157,7 @@ Deno.test('HttpKernel: handler throws → error propagates', async () => {
|
|||||||
const kernel = new HttpKernel();
|
const kernel = new HttpKernel();
|
||||||
|
|
||||||
kernel.route({ method: 'GET', path: '/throw' })
|
kernel.route({ method: 'GET', path: '/throw' })
|
||||||
.handle(() => {
|
.handle((_ctx) => {
|
||||||
throw new Error('fail!');
|
throw new Error('fail!');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user