@@ -473,4 +473,169 @@ describe('Static Plugin', () => {
473473 const jsFile = await app . handle ( req ( '/public/js/index.js' ) )
474474 expect ( jsFile . headers . get ( 'content-type' ) ) . toContain ( '/javascript' )
475475 } )
476+
477+ it ( 'preserves content-type on cached file responses' , async ( ) => {
478+ const app = new Elysia ( ) . use ( staticPlugin ( ) )
479+
480+ await app . modules
481+
482+ const first = await app . handle ( req ( '/public/js/index.js' ) )
483+ expect ( first . status ) . toBe ( 200 )
484+ expect ( first . headers . get ( 'content-type' ) ) . toContain ( '/javascript' )
485+
486+ const second = await app . handle ( req ( '/public/js/index.js' ) )
487+ expect ( second . status ) . toBe ( 200 )
488+ expect ( second . headers . get ( 'content-type' ) ) . toContain ( '/javascript' )
489+ } )
490+
491+ it ( 'preserves custom headers on cached file responses' , async ( ) => {
492+ const app = new Elysia ( ) . use (
493+ staticPlugin ( {
494+ headers : {
495+ 'x-static-test' : 'cached'
496+ }
497+ } )
498+ )
499+
500+ await app . modules
501+
502+ const first = await app . handle ( req ( '/public/takodachi.png' ) )
503+ expect ( first . status ) . toBe ( 200 )
504+ expect ( first . headers . get ( 'x-static-test' ) ) . toBe ( 'cached' )
505+
506+ const second = await app . handle ( req ( '/public/takodachi.png' ) )
507+ expect ( second . status ) . toBe ( 200 )
508+ expect ( second . headers . get ( 'x-static-test' ) ) . toBe ( 'cached' )
509+ } )
510+
511+ it ( 'preserves etag and cache-control headers on cached file responses' , async ( ) => {
512+ const app = new Elysia ( ) . use (
513+ staticPlugin ( {
514+ maxAge : 3600 ,
515+ directive : 'private'
516+ } )
517+ )
518+
519+ await app . modules
520+
521+ const first = await app . handle ( req ( '/public/takodachi.png' ) )
522+ expect ( first . status ) . toBe ( 200 )
523+
524+ const etag = first . headers . get ( 'etag' )
525+ expect ( etag ) . toBeTruthy ( )
526+ expect ( first . headers . get ( 'cache-control' ) ) . toBe ( 'private, max-age=3600' )
527+
528+ const second = await app . handle ( req ( '/public/takodachi.png' ) )
529+ expect ( second . status ) . toBe ( 200 )
530+ expect ( second . headers . get ( 'etag' ) ) . toBe ( etag )
531+ expect ( second . headers . get ( 'cache-control' ) ) . toBe (
532+ 'private, max-age=3600'
533+ )
534+ } )
535+
536+ it ( 'returns 304 for if-none-match after the file has been cached' , async ( ) => {
537+ const app = new Elysia ( ) . use ( staticPlugin ( ) )
538+
539+ await app . modules
540+
541+ const first = await app . handle ( req ( '/public/takodachi.png' ) )
542+ expect ( first . status ) . toBe ( 200 )
543+
544+ const etag = first . headers . get ( 'etag' )
545+ expect ( etag ) . toBeTruthy ( )
546+
547+ const request = req ( '/public/takodachi.png' )
548+ request . headers . set ( 'if-none-match' , etag ! )
549+
550+ const second = await app . handle ( request )
551+
552+ expect ( second . status ) . toBe ( 304 )
553+ expect ( second . body ) . toBe ( null )
554+ } )
555+
556+ it ( 'does not return 304 when cache-control no-cache is sent after file is cached' , async ( ) => {
557+ const app = new Elysia ( ) . use ( staticPlugin ( ) )
558+
559+ await app . modules
560+
561+ const first = await app . handle ( req ( '/public/takodachi.png' ) )
562+ expect ( first . status ) . toBe ( 200 )
563+
564+ const etag = first . headers . get ( 'etag' )
565+ expect ( etag ) . toBeTruthy ( )
566+
567+ const request = req ( '/public/takodachi.png' )
568+ request . headers . set ( 'if-none-match' , etag ! )
569+ request . headers . set ( 'cache-control' , 'no-cache' )
570+
571+ const second = await app . handle ( request )
572+
573+ expect ( second . status ) . toBe ( 200 )
574+ expect ( await second . blob ( ) . then ( ( b ) => b . text ( ) ) ) . toBe ( takodachi . toString ( ) )
575+ } )
576+
577+ it ( 'returns 304 for if-none-match after cached alwaysStatic route response' , async ( ) => {
578+ const app = new Elysia ( ) . use (
579+ staticPlugin ( {
580+ alwaysStatic : true ,
581+ extension : false
582+ } )
583+ )
584+
585+ await app . modules
586+
587+ const first = await app . handle ( req ( '/public/takodachi' ) )
588+ expect ( first . status ) . toBe ( 200 )
589+
590+ const etag = first . headers . get ( 'etag' )
591+ expect ( etag ) . toBeTruthy ( )
592+
593+ const request = req ( '/public/takodachi' )
594+ request . headers . set ( 'if-none-match' , etag ! )
595+
596+ const second = await app . handle ( request )
597+
598+ expect ( second . status ) . toBe ( 304 )
599+ expect ( second . body ) . toBe ( null )
600+ } )
601+
602+ it ( 'serves index.html from cache with content-type and cache headers' , async ( ) => {
603+ const app = new Elysia ( ) . use ( staticPlugin ( ) )
604+
605+ await app . modules
606+
607+ const first = await app . handle ( req ( '/public/html' ) )
608+ expect ( first . status ) . toBe ( 200 )
609+ expect ( first . headers . get ( 'content-type' ) ) . toContain ( 'text/html' )
610+
611+ const etag = first . headers . get ( 'etag' )
612+ expect ( etag ) . toBeTruthy ( )
613+ expect ( first . headers . get ( 'cache-control' ) ) . toBe ( 'public, max-age=86400' )
614+
615+ const second = await app . handle ( req ( '/public/html' ) )
616+ expect ( second . status ) . toBe ( 200 )
617+ expect ( second . headers . get ( 'content-type' ) ) . toContain ( 'text/html' )
618+ expect ( second . headers . get ( 'etag' ) ) . toBe ( etag )
619+ expect ( second . headers . get ( 'cache-control' ) ) . toBe ( 'public, max-age=86400' )
620+ } )
621+
622+ it ( 'returns 304 for cached index.html default route' , async ( ) => {
623+ const app = new Elysia ( ) . use ( staticPlugin ( ) )
624+
625+ await app . modules
626+
627+ const first = await app . handle ( req ( '/public/html' ) )
628+ expect ( first . status ) . toBe ( 200 )
629+
630+ const etag = first . headers . get ( 'etag' )
631+ expect ( etag ) . toBeTruthy ( )
632+
633+ const request = req ( '/public/html' )
634+ request . headers . set ( 'if-none-match' , etag ! )
635+
636+ const second = await app . handle ( request )
637+
638+ expect ( second . status ) . toBe ( 304 )
639+ expect ( second . body ) . toBe ( null )
640+ } )
476641} )
0 commit comments