@@ -89,32 +89,54 @@ describe('Response', () => {
8989 expect ( childResponse . headers . get ( 'content-type' ) ) . toEqual ( 'application/json' )
9090 } )
9191
92- it ( 'Should preserve headers mutated after construction when cloned via new Response(body, init)' , ( ) => {
93- // Regression test for https://github.com/honojs/node-server/issues/304.
94- // Headers appended (or set/deleted) after construction must be visible on
95- // a clone built with `new Response(body, parent)` — which is the pattern
96- // used by middleware such as `cors` and `compress`.
92+ it ( 'Should preserve mutated headers when cloned before body access' , ( ) => {
9793 const parentResponse = new Response ( 'hello' , {
9894 status : 200 ,
9995 headers : { 'content-type' : 'application/json' } ,
10096 } )
10197 parentResponse . headers . append ( 'set-cookie' , 'session=abc; Path=/; HttpOnly' )
10298
103- // Pattern 1: clone before any `getResponseCache`-triggering access.
10499 const childResponse = new Response ( 'hello' , parentResponse )
105100 expect ( childResponse . headers . get ( 'set-cookie' ) ) . toEqual ( 'session=abc; Path=/; HttpOnly' )
106101 expect ( childResponse . headers . get ( 'content-type' ) ) . toEqual ( 'application/json' )
102+ } )
107103
108- // Pattern 2: clone after `.body` has materialized the GlobalResponse —
109- // this is what middleware does when streaming a raw Response body.
110- const parentForBody = new Response ( 'hello' , {
104+ it ( 'Should preserve mutated headers when cloned after body access' , ( ) => {
105+ const parentResponse = new Response ( 'hello' , {
111106 status : 200 ,
112107 headers : { 'content-type' : 'application/json' } ,
113108 } )
114- parentForBody . headers . append ( 'set-cookie' , 'session=xyz; Path=/; HttpOnly' )
115- const streamedChild = new Response ( parentForBody . body , parentForBody )
116- expect ( streamedChild . headers . get ( 'set-cookie' ) ) . toEqual ( 'session=xyz; Path=/; HttpOnly' )
117- expect ( streamedChild . headers . get ( 'content-type' ) ) . toEqual ( 'application/json' )
109+ parentResponse . headers . append ( 'set-cookie' , 'session=xyz; Path=/; HttpOnly' )
110+
111+ const childResponse = new Response ( parentResponse . body , parentResponse )
112+ expect ( childResponse . headers . get ( 'set-cookie' ) ) . toEqual ( 'session=xyz; Path=/; HttpOnly' )
113+ expect ( childResponse . headers . get ( 'content-type' ) ) . toEqual ( 'application/json' )
114+ } )
115+
116+ it ( 'Should preserve status and statusText when headers are mutated' , ( ) => {
117+ const res = new Response ( 'hello' , {
118+ status : 201 ,
119+ statusText : 'Created' ,
120+ headers : { 'content-type' : 'application/json' } ,
121+ } )
122+ res . headers . append ( 'set-cookie' , 'session=abc; Path=/; HttpOnly' )
123+
124+ expect ( res . status ) . toEqual ( 201 )
125+ expect ( res . statusText ) . toEqual ( 'Created' )
126+ expect ( res . headers . get ( 'set-cookie' ) ) . toEqual ( 'session=abc; Path=/; HttpOnly' )
127+ } )
128+
129+ it ( 'Should preserve status from a native Response after materialization' , ( ) => {
130+ const nativeRedirect = new GlobalResponse ( null , {
131+ status : 302 ,
132+ headers : { location : 'https://example.com/' } ,
133+ } )
134+ const res = new Response ( nativeRedirect . body , nativeRedirect )
135+
136+ expect ( res . status ) . toEqual ( 302 )
137+ void res . body
138+ expect ( res . status ) . toEqual ( 302 )
139+ expect ( res . headers . get ( 'location' ) ) . toEqual ( 'https://example.com/' )
118140 } )
119141
120142 it ( 'Nested constructors should not cause an error even if ReadableStream is specified' , async ( ) => {
0 commit comments