11import type { SupportedVerb } from "./Store.ts" ;
2- import { type Context , RouteContext } from "../deps.ts" ;
3- import { assertEquals , assertSnapshot , oakTesting } from "../dev_deps.ts" ;
2+ import {
3+ type Context ,
4+ type ErrorStatus ,
5+ RouteContext ,
6+ Status ,
7+ z ,
8+ } from "../deps.ts" ;
9+ import {
10+ assertEquals ,
11+ assertSnapshot ,
12+ assertSpyCallArg ,
13+ assertSpyCalls ,
14+ oakTesting ,
15+ spy ,
16+ } from "../dev_deps.ts" ;
417import {
518 Controller ,
619 type ControllerMethodArg ,
@@ -94,6 +107,14 @@ class TestController {
94107 uah ( body : ArrayBuffer ) {
95108 return `hello, ArrayBuffer body with byteLength=${ body . byteLength } ` ;
96109 }
110+ @Get ( "/zodError" )
111+ zodError ( ) {
112+ z . enum ( [ "alice" , "bob" ] ) . parse ( "camela" ) ;
113+ }
114+ @Post ( "/arbitraryError" )
115+ arbitraryError ( ) {
116+ throw new Error ( "nah" ) ;
117+ }
97118}
98119
99120/**
@@ -109,6 +130,9 @@ type TestCaseDefinition = {
109130 mockRequestPathParams ?: Record < string , string > ;
110131 mockRequestBody ?: MockRequestBodyDefinition ;
111132 expectedResponse : unknown ;
133+ expectedCtxThrow ?: boolean ;
134+ expectedError ?: unknown ;
135+ expectedResponseStatus ?: Status ;
112136} ;
113137
114138Deno . test ( "useOakServer - noop Controller" , ( ) => {
@@ -218,6 +242,32 @@ Deno.test({
218242 } ,
219243 expectedResponse : "hello, ArrayBuffer body with byteLength=42" ,
220244 } ,
245+ {
246+ caseDescription : "handler where a ZodError (validation error) happens" ,
247+ method : "get" ,
248+ expectedCtxThrow : true ,
249+ expectedError : `[
250+ {
251+ "received": "camela",
252+ "code": "invalid_enum_value",
253+ "options": [
254+ "alice",
255+ "bob"
256+ ],
257+ "path": [],
258+ "message": "Invalid enum value. Expected 'alice' | 'bob', received 'camela'"
259+ }
260+ ]` ,
261+ expectedResponse : undefined ,
262+ expectedResponseStatus : Status . BadRequest ,
263+ } ,
264+ {
265+ caseDescription : "handler where an arbitrary error happens" ,
266+ method : "post" ,
267+ expectedError : "nah" ,
268+ expectedResponse : undefined ,
269+ expectedResponseStatus : Status . InternalServerError ,
270+ } ,
221271 ] ;
222272
223273 await Promise . all (
@@ -228,6 +278,9 @@ Deno.test({
228278 mockRequestPathParams = undefined ,
229279 mockRequestBody = undefined ,
230280 expectedResponse,
281+ expectedCtxThrow,
282+ expectedError,
283+ expectedResponseStatus,
231284 } , i ) =>
232285 t . step ( {
233286 name : `case ${ i + 1 } : ${ caseDescription } ` ,
@@ -245,7 +298,35 @@ Deno.test({
245298 const next = oakTesting . createMockNext ( ) ;
246299 useOakServer ( ctx . app , [ TestController ] ) ;
247300 const routes = Array . from ( useOakServerInternal . oakRouter . values ( ) ) ;
248- await routes [ i ] . middleware [ 0 ] ?.( ctx , next ) ; // simulate the route being requested
301+ const spyCtxThrow = spy ( ctx , "throw" ) ;
302+ try {
303+ // simulate the route being requested
304+ await routes [ i ] . middleware [ 0 ] ?.( ctx , next ) ;
305+ } catch ( e ) {
306+ const theErrMsg = ( e as Error ) . message ;
307+ if ( expectedCtxThrow ) {
308+ assertSpyCalls ( spyCtxThrow , 1 ) ;
309+ assertSpyCallArg (
310+ spyCtxThrow ,
311+ 0 ,
312+ 0 ,
313+ expectedResponseStatus as ErrorStatus ,
314+ ) ;
315+ assertSpyCallArg (
316+ spyCtxThrow ,
317+ 0 ,
318+ 1 ,
319+ JSON . stringify (
320+ JSON . parse ( expectedError as string ) ,
321+ undefined ,
322+ 2 ,
323+ ) ,
324+ ) ;
325+ } else {
326+ assertSpyCalls ( spyCtxThrow , 0 ) ;
327+ assertEquals ( theErrMsg , expectedError ) ;
328+ }
329+ }
249330 assertEquals ( ctx . response . body , expectedResponse ) ;
250331 } ,
251332 sanitizeOps : false ,
0 commit comments