@@ -214,45 +214,105 @@ describe('Path Utilities', () => {
214
214
} ) ;
215
215
216
216
describe ( 'isAPIGatewayProxyEvent' , ( ) => {
217
- it ( 'should return true for valid API Gateway Proxy event' , ( ) => {
218
- const validEvent : APIGatewayProxyEvent = {
219
- httpMethod : 'GET' ,
217
+ const baseValidEvent = {
218
+ httpMethod : 'GET' ,
219
+ path : '/test' ,
220
+ resource : '/test' ,
221
+ headers : { } ,
222
+ multiValueHeaders : { } ,
223
+ queryStringParameters : { } ,
224
+ multiValueQueryStringParameters : { } ,
225
+ pathParameters : { } ,
226
+ stageVariables : { } ,
227
+ requestContext : { stage : 'test' } ,
228
+ isBase64Encoded : false ,
229
+ body : null ,
230
+ } ;
231
+
232
+ it ( 'should return true for valid API Gateway Proxy event with all fields populated' , ( ) => {
233
+ expect ( isAPIGatewayProxyEvent ( baseValidEvent ) ) . toBe ( true ) ;
234
+ } ) ;
235
+
236
+ it ( 'should return true for real API Gateway event with null fields' , ( ) => {
237
+ const realEvent = {
238
+ resource : '/{proxy+}' ,
220
239
path : '/test' ,
221
- resource : '/test' ,
222
- headers : { } ,
240
+ httpMethod : 'GET' ,
241
+ headers : null ,
242
+ multiValueHeaders : null ,
243
+ queryStringParameters : null ,
244
+ multiValueQueryStringParameters : null ,
245
+ pathParameters : { proxy : 'test' } ,
246
+ stageVariables : null ,
223
247
requestContext : {
224
- accountId : '123456789012 ' ,
225
- apiId : 'test-api ' ,
248
+ resourceId : 'ovdb9g ' ,
249
+ resourcePath : '/{proxy+} ' ,
226
250
httpMethod : 'GET' ,
227
- requestId : 'test-request-id' ,
228
- resourceId : 'test-resource' ,
229
- resourcePath : '/test' ,
230
- stage : 'test' ,
231
- identity : {
232
- sourceIp : '127.0.0.1' ,
233
- } ,
234
- } as any ,
235
- isBase64Encoded : false ,
251
+ stage : 'test-invoke-stage' ,
252
+ requestId : 'eecdfcfa-225a-4ee3-bdca-05fc31b6018a' ,
253
+ identity : { sourceIp : 'test-invoke-source-ip' } ,
254
+ } ,
236
255
body : null ,
237
- } as APIGatewayProxyEvent ;
256
+ isBase64Encoded : false ,
257
+ } ;
238
258
239
- expect ( isAPIGatewayProxyEvent ( validEvent ) ) . toBe ( true ) ;
259
+ expect ( isAPIGatewayProxyEvent ( realEvent ) ) . toBe ( true ) ;
240
260
} ) ;
241
261
242
- it ( 'should return true for valid event with string body' , ( ) => {
243
- const validEvent = {
262
+ it ( 'should return true for event with string body' , ( ) => {
263
+ const eventWithBody = {
264
+ ...baseValidEvent ,
244
265
httpMethod : 'POST' ,
245
- path : '/test' ,
246
- resource : '/test' ,
247
- headers : { 'content-type' : 'application/json' } ,
248
- requestContext : { stage : 'test' } ,
249
- isBase64Encoded : false ,
250
266
body : '{"key":"value"}' ,
251
267
} ;
252
268
253
- expect ( isAPIGatewayProxyEvent ( validEvent ) ) . toBe ( true ) ;
269
+ expect ( isAPIGatewayProxyEvent ( eventWithBody ) ) . toBe ( true ) ;
254
270
} ) ;
255
271
272
+ it . each ( [
273
+ // Headers can be null in reality (even though types say otherwise)
274
+ { field : 'headers' , value : null } ,
275
+ { field : 'headers' , value : undefined } ,
276
+ { field : 'multiValueHeaders' , value : null } ,
277
+ { field : 'multiValueHeaders' , value : undefined } ,
278
+ // These are officially nullable in the type definition
279
+ { field : 'body' , value : null } ,
280
+ { field : 'pathParameters' , value : null } ,
281
+ { field : 'queryStringParameters' , value : null } ,
282
+ { field : 'multiValueQueryStringParameters' , value : null } ,
283
+ { field : 'stageVariables' , value : null } ,
284
+ ] ) ( 'should return true when $field is $value' , ( { field, value } ) => {
285
+ const event = { ...baseValidEvent , [ field ] : value } ;
286
+ expect ( isAPIGatewayProxyEvent ( event ) ) . toBe ( true ) ;
287
+ } ) ;
288
+
289
+ it . each ( [
290
+ {
291
+ field : 'headers' ,
292
+ value : { 'content-type' : undefined , 'x-api-key' : 'test' } ,
293
+ } ,
294
+ {
295
+ field : 'multiValueHeaders' ,
296
+ value : { accept : undefined , 'x-custom' : [ 'val1' , 'val2' ] } ,
297
+ } ,
298
+ { field : 'pathParameters' , value : { id : undefined , name : 'test' } } ,
299
+ {
300
+ field : 'queryStringParameters' ,
301
+ value : { filter : undefined , sort : 'asc' } ,
302
+ } ,
303
+ {
304
+ field : 'multiValueQueryStringParameters' ,
305
+ value : { tags : undefined , categories : [ 'a' , 'b' ] } ,
306
+ } ,
307
+ { field : 'stageVariables' , value : { env : undefined , version : 'v1' } } ,
308
+ ] ) (
309
+ 'should return true when $field contains undefined values' ,
310
+ ( { field, value } ) => {
311
+ const event = { ...baseValidEvent , [ field ] : value } ;
312
+ expect ( isAPIGatewayProxyEvent ( event ) ) . toBe ( true ) ;
313
+ }
314
+ ) ;
315
+
256
316
it . each ( [
257
317
{ case : 'null' , event : null } ,
258
318
{ case : 'undefined' , event : undefined } ,
@@ -266,42 +326,52 @@ describe('Path Utilities', () => {
266
326
it . each ( [
267
327
{ field : 'httpMethod' , value : 123 } ,
268
328
{ field : 'httpMethod' , value : null } ,
329
+ { field : 'httpMethod' , value : undefined } ,
269
330
{ field : 'path' , value : 123 } ,
270
331
{ field : 'path' , value : null } ,
332
+ { field : 'path' , value : undefined } ,
271
333
{ field : 'resource' , value : 123 } ,
272
334
{ field : 'resource' , value : null } ,
335
+ { field : 'resource' , value : undefined } ,
273
336
{ field : 'headers' , value : 'not an object' } ,
274
- { field : 'headers' , value : null } ,
337
+ { field : 'headers' , value : 123 } ,
338
+ { field : 'multiValueHeaders' , value : 'not an object' } ,
339
+ { field : 'multiValueHeaders' , value : 123 } ,
340
+ { field : 'queryStringParameters' , value : 'not an object' } ,
341
+ { field : 'queryStringParameters' , value : 123 } ,
342
+ { field : 'multiValueQueryStringParameters' , value : 'not an object' } ,
343
+ { field : 'multiValueQueryStringParameters' , value : 123 } ,
344
+ { field : 'pathParameters' , value : 'not an object' } ,
345
+ { field : 'pathParameters' , value : 123 } ,
346
+ { field : 'stageVariables' , value : 'not an object' } ,
347
+ { field : 'stageVariables' , value : 123 } ,
275
348
{ field : 'requestContext' , value : 'not an object' } ,
276
349
{ field : 'requestContext' , value : null } ,
350
+ { field : 'requestContext' , value : undefined } ,
351
+ { field : 'requestContext' , value : 123 } ,
277
352
{ field : 'isBase64Encoded' , value : 'not a boolean' } ,
278
353
{ field : 'isBase64Encoded' , value : null } ,
354
+ { field : 'isBase64Encoded' , value : undefined } ,
355
+ { field : 'isBase64Encoded' , value : 123 } ,
279
356
{ field : 'body' , value : 123 } ,
357
+ { field : 'body' , value : { } } ,
280
358
] ) (
281
359
'should return false when $field is invalid ($value)' ,
282
360
( { field, value } ) => {
283
- const baseEvent = {
284
- httpMethod : 'GET' ,
285
- path : '/test' ,
286
- resource : '/test' ,
287
- headers : { } ,
288
- requestContext : { } ,
289
- isBase64Encoded : false ,
290
- body : null ,
291
- } ;
292
-
293
- const invalidEvent = { ...baseEvent , [ field ] : value } ;
361
+ const invalidEvent = { ...baseValidEvent , [ field ] : value } ;
294
362
expect ( isAPIGatewayProxyEvent ( invalidEvent ) ) . toBe ( false ) ;
295
363
}
296
364
) ;
297
365
298
- it ( 'should return false when required fields are missing' , ( ) => {
299
- const incompleteEvent = {
300
- httpMethod : 'GET' ,
301
- path : '/test' ,
302
- // missing resource, headers, requestContext, isBase64Encoded, body
303
- } ;
304
-
366
+ it . each ( [
367
+ 'httpMethod' ,
368
+ 'path' ,
369
+ 'resource' ,
370
+ 'requestContext' ,
371
+ 'isBase64Encoded' ,
372
+ ] ) ( 'should return false when required field %s is missing' , ( field ) => {
373
+ const incompleteEvent = { ...baseValidEvent } ;
374
+ delete incompleteEvent [ field as keyof typeof incompleteEvent ] ;
305
375
expect ( isAPIGatewayProxyEvent ( incompleteEvent ) ) . toBe ( false ) ;
306
376
} ) ;
307
377
} ) ;
0 commit comments