@@ -308,14 +308,52 @@ describe('SSEClientTransport', () => {
308308
309309 await transport.start();
310310
311- // Store original fetch
312311 const originalFetch = global.fetch;
312+ try {
313+ global.fetch = vi.fn().mockResolvedValue({ ok: true });
314+
315+ const message: JSONRPCMessage = {
316+ jsonrpc: '2.0',
317+ id: '1',
318+ method: 'test',
319+ params: {}
320+ };
321+
322+ await transport.send(message);
323+
324+ const calledHeaders = (global.fetch as Mock).mock.calls[0][1].headers;
325+ expect(calledHeaders.get('Authorization')).toBe('Bearer test-token');
326+ expect(calledHeaders.get('X-Custom-Header')).toBe('custom-value');
327+ expect(calledHeaders.get('content-type')).toBe('application/json');
328+
329+ customHeaders['X-Custom-Header'] = 'updated-value';
330+
331+ await transport.send(message);
332+
333+ const updatedHeaders = (global.fetch as Mock).mock.calls[1][1].headers;
334+ expect(updatedHeaders.get('X-Custom-Header')).toBe('updated-value');
335+ } finally {
336+ global.fetch = originalFetch;
337+ }
338+ });
339+
340+ it('passes custom headers to fetch requests (Headers class)', async () => {
341+ const customHeaders = new Headers({
342+ Authorization: 'Bearer test-token',
343+ 'X-Custom-Header': 'custom-value'
344+ });
345+
346+ transport = new SSEClientTransport(resourceBaseUrl, {
347+ requestInit: {
348+ headers: customHeaders
349+ }
350+ });
351+
352+ await transport.start();
313353
354+ const originalFetch = global.fetch;
314355 try {
315- // Mock fetch for the message sending test
316- global.fetch = vi.fn().mockResolvedValue({
317- ok: true
318- });
356+ global.fetch = vi.fn().mockResolvedValue({ ok: true });
319357
320358 const message: JSONRPCMessage = {
321359 jsonrpc: '2.0',
@@ -326,20 +364,45 @@ describe('SSEClientTransport', () => {
326364
327365 await transport.send(message);
328366
329- // Verify fetch was called with correct headers
330- expect(global.fetch).toHaveBeenCalledWith(
331- expect.any(URL),
332- expect.objectContaining({
333- headers: expect.any(Headers)
334- })
335- );
367+ const calledHeaders = (global.fetch as Mock).mock.calls[0][1].headers;
368+ expect(calledHeaders.get('Authorization')).toBe('Bearer test-token');
369+ expect(calledHeaders.get('X-Custom-Header')).toBe('custom-value');
370+ expect(calledHeaders.get('content-type')).toBe('application/json');
371+
372+ customHeaders.set('X-Custom-Header', 'updated-value');
373+
374+ await transport.send(message);
375+
376+ const updatedHeaders = (global.fetch as Mock).mock.calls[1][1].headers;
377+ expect(updatedHeaders.get('X-Custom-Header')).toBe('updated-value');
378+ } finally {
379+ global.fetch = originalFetch;
380+ }
381+ });
382+
383+ it('passes custom headers to fetch requests (array of tuples)', async () => {
384+ transport = new SSEClientTransport(resourceBaseUrl, {
385+ requestInit: {
386+ headers: [
387+ ['Authorization', 'Bearer test-token'],
388+ ['X-Custom-Header', 'custom-value']
389+ ]
390+ }
391+ });
392+
393+ await transport.start();
394+
395+ const originalFetch = global.fetch;
396+ try {
397+ global.fetch = vi.fn().mockResolvedValue({ ok: true });
398+
399+ await transport.send({ jsonrpc: '2.0', id: '1', method: 'test', params: {} });
336400
337401 const calledHeaders = (global.fetch as Mock).mock.calls[0][1].headers;
338- expect(calledHeaders.get('Authorization')).toBe(customHeaders.Authorization );
339- expect(calledHeaders.get('X-Custom-Header')).toBe(customHeaders['X-Custom-Header'] );
402+ expect(calledHeaders.get('Authorization')).toBe('Bearer test-token' );
403+ expect(calledHeaders.get('X-Custom-Header')).toBe('custom-value' );
340404 expect(calledHeaders.get('content-type')).toBe('application/json');
341405 } finally {
342- // Restore original fetch
343406 global.fetch = originalFetch;
344407 }
345408 });
0 commit comments