@@ -433,6 +433,200 @@ describe('Cache Middleware Tests', () => {
433433 } )
434434} )
435435
436+ describe ( 'GOG Endpoint Cache Middleware' , ( ) => {
437+ let mockReq
438+ let mockRes
439+ let mockNext
440+
441+ beforeEach ( ( ) => {
442+ // Clear cache before each test
443+ cache . clear ( )
444+
445+ // Reset mock request
446+ mockReq = {
447+ method : 'POST' ,
448+ body : { } ,
449+ query : { } ,
450+ params : { }
451+ }
452+
453+ // Reset mock response
454+ mockRes = {
455+ statusCode : 200 ,
456+ headers : { } ,
457+ set : jest . fn ( function ( key , value ) {
458+ if ( typeof key === 'object' ) {
459+ Object . assign ( this . headers , key )
460+ } else {
461+ this . headers [ key ] = value
462+ }
463+ return this
464+ } ) ,
465+ status : jest . fn ( function ( code ) {
466+ this . statusCode = code
467+ return this
468+ } ) ,
469+ json : jest . fn ( function ( data ) {
470+ this . jsonData = data
471+ return this
472+ } )
473+ }
474+
475+ // Reset mock next
476+ mockNext = jest . fn ( )
477+ } )
478+
479+ afterEach ( ( ) => {
480+ cache . clear ( )
481+ } )
482+
483+ describe ( 'cacheGogFragments middleware' , ( ) => {
484+ it ( 'should pass through when ManuscriptWitness is missing' , ( ) => {
485+ mockReq . body = { }
486+
487+ cacheGogFragments ( mockReq , mockRes , mockNext )
488+
489+ expect ( mockNext ) . toHaveBeenCalled ( )
490+ expect ( mockRes . json ) . not . toHaveBeenCalled ( )
491+ } )
492+
493+ it ( 'should pass through when ManuscriptWitness is invalid' , ( ) => {
494+ mockReq . body = { ManuscriptWitness : 'not-a-url' }
495+
496+ cacheGogFragments ( mockReq , mockRes , mockNext )
497+
498+ expect ( mockNext ) . toHaveBeenCalled ( )
499+ expect ( mockRes . json ) . not . toHaveBeenCalled ( )
500+ } )
501+
502+ it ( 'should return cache MISS on first request' , ( ) => {
503+ mockReq . body = { ManuscriptWitness : 'https://example.org/manuscript/1' }
504+ mockReq . query = { limit : '50' , skip : '0' }
505+
506+ cacheGogFragments ( mockReq , mockRes , mockNext )
507+
508+ expect ( mockRes . headers [ 'X-Cache' ] ) . toBe ( 'MISS' )
509+ expect ( mockNext ) . toHaveBeenCalled ( )
510+ } )
511+
512+ it ( 'should return cache HIT on second identical request' , ( ) => {
513+ mockReq . body = { ManuscriptWitness : 'https://example.org/manuscript/1' }
514+ mockReq . query = { limit : '50' , skip : '0' }
515+
516+ // First request - populate cache
517+ cacheGogFragments ( mockReq , mockRes , mockNext )
518+ mockRes . json ( [ { '@id' : 'fragment1' , '@type' : 'WitnessFragment' } ] )
519+
520+ // Reset mocks for second request
521+ mockRes . headers = { }
522+ mockRes . json = jest . fn ( )
523+ mockNext = jest . fn ( )
524+
525+ // Second request - should hit cache
526+ cacheGogFragments ( mockReq , mockRes , mockNext )
527+
528+ expect ( mockRes . headers [ 'X-Cache' ] ) . toBe ( 'HIT' )
529+ expect ( mockRes . json ) . toHaveBeenCalledWith ( [ { '@id' : 'fragment1' , '@type' : 'WitnessFragment' } ] )
530+ expect ( mockNext ) . not . toHaveBeenCalled ( )
531+ } )
532+
533+ it ( 'should cache based on pagination parameters' , ( ) => {
534+ const manuscriptURI = 'https://example.org/manuscript/1'
535+
536+ // Request with limit=50, skip=0
537+ mockReq . body = { ManuscriptWitness : manuscriptURI }
538+ mockReq . query = { limit : '50' , skip : '0' }
539+
540+ cacheGogFragments ( mockReq , mockRes , mockNext )
541+ mockRes . json ( [ { '@id' : 'fragment1' } ] )
542+
543+ // Request with different pagination - should be MISS
544+ mockRes . headers = { }
545+ mockRes . json = jest . fn ( )
546+ mockNext = jest . fn ( )
547+ mockReq . query = { limit : '100' , skip : '0' }
548+
549+ cacheGogFragments ( mockReq , mockRes , mockNext )
550+
551+ expect ( mockRes . headers [ 'X-Cache' ] ) . toBe ( 'MISS' )
552+ expect ( mockNext ) . toHaveBeenCalled ( )
553+ } )
554+ } )
555+
556+ describe ( 'cacheGogGlosses middleware' , ( ) => {
557+ it ( 'should pass through when ManuscriptWitness is missing' , ( ) => {
558+ mockReq . body = { }
559+
560+ cacheGogGlosses ( mockReq , mockRes , mockNext )
561+
562+ expect ( mockNext ) . toHaveBeenCalled ( )
563+ expect ( mockRes . json ) . not . toHaveBeenCalled ( )
564+ } )
565+
566+ it ( 'should pass through when ManuscriptWitness is invalid' , ( ) => {
567+ mockReq . body = { ManuscriptWitness : 'not-a-url' }
568+
569+ cacheGogGlosses ( mockReq , mockRes , mockNext )
570+
571+ expect ( mockNext ) . toHaveBeenCalled ( )
572+ expect ( mockRes . json ) . not . toHaveBeenCalled ( )
573+ } )
574+
575+ it ( 'should return cache MISS on first request' , ( ) => {
576+ mockReq . body = { ManuscriptWitness : 'https://example.org/manuscript/1' }
577+ mockReq . query = { limit : '50' , skip : '0' }
578+
579+ cacheGogGlosses ( mockReq , mockRes , mockNext )
580+
581+ expect ( mockRes . headers [ 'X-Cache' ] ) . toBe ( 'MISS' )
582+ expect ( mockNext ) . toHaveBeenCalled ( )
583+ } )
584+
585+ it ( 'should return cache HIT on second identical request' , ( ) => {
586+ mockReq . body = { ManuscriptWitness : 'https://example.org/manuscript/1' }
587+ mockReq . query = { limit : '50' , skip : '0' }
588+
589+ // First request - populate cache
590+ cacheGogGlosses ( mockReq , mockRes , mockNext )
591+ mockRes . json ( [ { '@id' : 'gloss1' , '@type' : 'Gloss' } ] )
592+
593+ // Reset mocks for second request
594+ mockRes . headers = { }
595+ mockRes . json = jest . fn ( )
596+ mockNext = jest . fn ( )
597+
598+ // Second request - should hit cache
599+ cacheGogGlosses ( mockReq , mockRes , mockNext )
600+
601+ expect ( mockRes . headers [ 'X-Cache' ] ) . toBe ( 'HIT' )
602+ expect ( mockRes . json ) . toHaveBeenCalledWith ( [ { '@id' : 'gloss1' , '@type' : 'Gloss' } ] )
603+ expect ( mockNext ) . not . toHaveBeenCalled ( )
604+ } )
605+
606+ it ( 'should cache based on pagination parameters' , ( ) => {
607+ const manuscriptURI = 'https://example.org/manuscript/1'
608+
609+ // Request with limit=50, skip=0
610+ mockReq . body = { ManuscriptWitness : manuscriptURI }
611+ mockReq . query = { limit : '50' , skip : '0' }
612+
613+ cacheGogGlosses ( mockReq , mockRes , mockNext )
614+ mockRes . json ( [ { '@id' : 'gloss1' } ] )
615+
616+ // Request with different pagination - should be MISS
617+ mockRes . headers = { }
618+ mockRes . json = jest . fn ( )
619+ mockNext = jest . fn ( )
620+ mockReq . query = { limit : '100' , skip : '0' }
621+
622+ cacheGogGlosses ( mockReq , mockRes , mockNext )
623+
624+ expect ( mockRes . headers [ 'X-Cache' ] ) . toBe ( 'MISS' )
625+ expect ( mockNext ) . toHaveBeenCalled ( )
626+ } )
627+ } )
628+ } )
629+
436630describe ( 'Cache Statistics' , ( ) => {
437631 beforeEach ( ( ) => {
438632 cache . clear ( )
0 commit comments