@@ -76,6 +76,126 @@ describe( 'initializeFetchInterceptor', () => {
7676 expect ( window . fetch ) . toBe ( currentFetch ) ;
7777 } ) ;
7878
79+ describe ( 'request header capture' , ( ) => {
80+ it ( 'should capture headers from plain object with string URL' , async ( ) => {
81+ initializeFetchInterceptor ( ) ;
82+
83+ await window . fetch ( 'https://example.com/api' , {
84+ method : 'POST' ,
85+ headers : {
86+ 'Content-Type' : 'application/json' ,
87+ Authorization : 'Bearer test-token' ,
88+ 'X-Custom-Header' : 'custom-value' ,
89+ } ,
90+ } ) ;
91+
92+ await waitForAsyncLogging ( ) ;
93+
94+ expect ( bridge . onNetworkRequest ) . toHaveBeenCalledWith (
95+ expect . objectContaining ( {
96+ requestHeaders : expect . objectContaining ( {
97+ 'Content-Type' : 'application/json' ,
98+ Authorization : 'Bearer test-token' ,
99+ 'X-Custom-Header' : 'custom-value' ,
100+ } ) ,
101+ } )
102+ ) ;
103+ } ) ;
104+
105+ it ( 'should capture headers from Request object' , async ( ) => {
106+ initializeFetchInterceptor ( ) ;
107+
108+ const request = new Request ( 'https://example.com/api' , {
109+ method : 'GET' ,
110+ headers : {
111+ Accept : 'application/json' ,
112+ 'X-Request-ID' : '12345' ,
113+ } ,
114+ } ) ;
115+
116+ await window . fetch ( request ) ;
117+
118+ await waitForAsyncLogging ( ) ;
119+
120+ expect ( bridge . onNetworkRequest ) . toHaveBeenCalledWith (
121+ expect . objectContaining ( {
122+ requestHeaders : expect . objectContaining ( {
123+ accept : 'application/json' ,
124+ 'x-request-id' : '12345' ,
125+ } ) ,
126+ } )
127+ ) ;
128+ } ) ;
129+
130+ it ( 'should merge Request headers with init override' , async ( ) => {
131+ initializeFetchInterceptor ( ) ;
132+
133+ const request = new Request ( 'https://example.com/api' , {
134+ headers : {
135+ 'Content-Type' : 'application/json' ,
136+ 'X-Original' : 'original-value' ,
137+ } ,
138+ } ) ;
139+
140+ await window . fetch ( request , {
141+ headers : {
142+ 'Content-Type' : 'application/xml' , // Override
143+ 'X-Additional' : 'additional-value' , // Additional
144+ } ,
145+ } ) ;
146+
147+ await waitForAsyncLogging ( ) ;
148+
149+ expect ( bridge . onNetworkRequest ) . toHaveBeenCalledWith (
150+ expect . objectContaining ( {
151+ requestHeaders : expect . objectContaining ( {
152+ 'content-type' : 'application/xml' , // Overridden (lowercase)
153+ 'x-original' : 'original-value' , // Preserved (lowercase)
154+ 'x-additional' : 'additional-value' , // Added (lowercase)
155+ } ) ,
156+ } )
157+ ) ;
158+ } ) ;
159+
160+ it ( 'should handle empty headers' , async ( ) => {
161+ initializeFetchInterceptor ( ) ;
162+
163+ await window . fetch ( 'https://example.com/api' ) ;
164+
165+ await waitForAsyncLogging ( ) ;
166+
167+ expect ( bridge . onNetworkRequest ) . toHaveBeenCalledWith (
168+ expect . objectContaining ( {
169+ requestHeaders : { } ,
170+ } )
171+ ) ;
172+ } ) ;
173+
174+ it ( 'should handle Headers instance' , async ( ) => {
175+ initializeFetchInterceptor ( ) ;
176+
177+ const headers = new Headers ( ) ;
178+ headers . append ( 'Authorization' , 'Bearer token123' ) ;
179+ headers . append ( 'Content-Type' , 'application/json' ) ;
180+
181+ await window . fetch ( 'https://example.com/api' , {
182+ method : 'POST' ,
183+ headers,
184+ } ) ;
185+
186+ await waitForAsyncLogging ( ) ;
187+
188+ expect ( bridge . onNetworkRequest ) . toHaveBeenCalledWith (
189+ expect . objectContaining ( {
190+ requestHeaders : expect . objectContaining ( {
191+ authorization : 'Bearer token123' ,
192+ 'content-type' : 'application/json' ,
193+ } ) ,
194+ } )
195+ ) ;
196+ } ) ;
197+ } ) ;
198+
79199 describe ( 'request body serialization' , ( ) => {
80200 it ( 'should serialize FormData with files correctly' , async ( ) => {
81201 initializeFetchInterceptor ( ) ;
0 commit comments