@@ -400,3 +400,140 @@ test('Response is not cached', async (t) => {
400400 t . false ( response . isFromCache ) ;
401401 t . deepEqual ( response . body , { name : 'foo' } ) ;
402402} ) ;
403+
404+ test ( 'Response is not cached due to origin error' , async ( t ) => {
405+ const baseURL = 'https://api.example.com' ;
406+ const { path} = t . context ;
407+ const scopeSuccess = nock ( baseURL ) . get ( path ) . once ( ) . reply (
408+ 200 ,
409+ { name : 'foo' } ,
410+ {
411+ 'Cache-Control' : 'public, max-age=0'
412+ }
413+ ) ;
414+
415+ let dataSource = new ( class extends RESTDataSource {
416+ baseURL = baseURL ;
417+
418+ async getFoo ( ) {
419+ return this . get ( path , {
420+ cacheOptions : {
421+ shared : true ,
422+ cacheHeuristic : 0.1 ,
423+ immutableMinTimeToLive : 24 * 3600 * 1000 , // 24h
424+ ignoreCargoCult : false
425+ }
426+ } ) ;
427+ }
428+ } ) ( ) ;
429+
430+ const map = new Map < string , string > ( ) ;
431+
432+ const config : DataSourceConfig < Record < string , unknown > > = {
433+ context : { } ,
434+ cache : {
435+ async delete ( key : string ) {
436+ return map . delete ( key ) ;
437+ } ,
438+ async get ( key : string ) {
439+ return map . get ( key ) ;
440+ } ,
441+ async set ( key : string , value : string ) {
442+ map . set ( key , value ) ;
443+ }
444+ }
445+ } ;
446+
447+ dataSource . initialize ( config ) ;
448+
449+ const response = await dataSource . getFoo ( ) ;
450+
451+ t . is ( scopeSuccess . isDone ( ) , true ) ;
452+ t . false ( response . isFromCache ) ;
453+ t . deepEqual ( response . body , { name : 'foo' } ) ;
454+ t . true ( map . size > 0 ) ;
455+
456+ dataSource = new ( class extends RESTDataSource {
457+ baseURL = baseURL ;
458+
459+ async getFoo ( ) {
460+ return this . get ( path ) ;
461+ }
462+ } ) ( ) ;
463+
464+ dataSource . initialize ( config ) ;
465+
466+ const scopeError = nock ( baseURL ) . get ( path ) . once ( ) . reply ( 500 ) ;
467+
468+ await t . throwsAsync (
469+ dataSource . getFoo ( ) ,
470+ {
471+ message : 'Response code 500 (Internal Server Error)'
472+ } ,
473+ 'message'
474+ ) ;
475+ t . is ( scopeError . isDone ( ) , true ) ;
476+ t . false ( response . isFromCache ) ;
477+ } ) ;
478+
479+ test ( 'Response is cached due to stale-if-error' , async ( t ) => {
480+ const baseURL = 'https://api.example.com' ;
481+ const { path} = t . context ;
482+ const scopeSuccess = nock ( baseURL ) . get ( path ) . once ( ) . reply (
483+ 200 ,
484+ { name : 'foo' } ,
485+ {
486+ 'Cache-Control' : 'public, max-age=0, stale-if-error=200'
487+ }
488+ ) ;
489+ const scopeError = nock ( baseURL ) . get ( path ) . once ( ) . reply ( 500 ) ;
490+
491+ let dataSource = new ( class extends RESTDataSource {
492+ baseURL = baseURL ;
493+
494+ async getFoo ( ) {
495+ return this . get ( path ) ;
496+ }
497+ } ) ( ) ;
498+
499+ const map = new Map < string , string > ( ) ;
500+
501+ const config : DataSourceConfig < Record < string , unknown > > = {
502+ context : { } ,
503+ cache : {
504+ async delete ( key : string ) {
505+ return map . delete ( key ) ;
506+ } ,
507+ async get ( key : string ) {
508+ return map . get ( key ) ;
509+ } ,
510+ async set ( key : string , value : string ) {
511+ map . set ( key , value ) ;
512+ }
513+ }
514+ } ;
515+
516+ dataSource . initialize ( config ) ;
517+
518+ let response = await dataSource . getFoo ( ) ;
519+
520+ t . is ( scopeSuccess . isDone ( ) , true ) ;
521+ t . false ( response . isFromCache ) ;
522+ t . deepEqual ( response . body , { name : 'foo' } ) ;
523+ t . true ( map . size > 0 ) ;
524+
525+ dataSource = new ( class extends RESTDataSource {
526+ baseURL = baseURL ;
527+
528+ async getFoo ( ) {
529+ return this . get ( path ) ;
530+ }
531+ } ) ( ) ;
532+
533+ dataSource . initialize ( config ) ;
534+
535+ response = await dataSource . getFoo ( ) ;
536+ t . is ( scopeError . isDone ( ) , true ) ;
537+ t . true ( response . isFromCache ) ;
538+ t . deepEqual ( response . body , { name : 'foo' } ) ;
539+ } ) ;
0 commit comments