Skip to content

Commit 0ab421f

Browse files
authored
fix(MockInterceptor): callback options.headers w/ fetch (#1559)
1 parent 23f80fb commit 0ab421f

4 files changed

Lines changed: 55 additions & 8 deletions

File tree

lib/mock/mock-utils.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,20 @@ function getHeaderByName (headers, key) {
5151
}
5252
}
5353

54+
/** @param {string[]} headers */
55+
function buildHeadersFromArray (headers) { // fetch HeadersList
56+
const clone = headers.slice()
57+
const entries = []
58+
for (let index = 0; index < clone.length; index += 2) {
59+
entries.push([clone[index], clone[index + 1]])
60+
}
61+
return Object.fromEntries(entries)
62+
}
63+
5464
function matchHeaders (mockDispatch, headers) {
5565
if (typeof mockDispatch.headers === 'function') {
5666
if (Array.isArray(headers)) { // fetch HeadersList
57-
const clone = headers.slice()
58-
const entries = []
59-
for (let index = 0; index < clone.length; index += 2) {
60-
entries.push([clone[index], clone[index + 1]])
61-
}
62-
headers = Object.fromEntries(entries)
67+
headers = buildHeadersFromArray(headers)
6368
}
6469
return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {})
6570
}
@@ -284,7 +289,13 @@ function mockDispatch (opts, handler) {
284289
}
285290

286291
function handleReply (mockDispatches) {
287-
const responseData = getResponseData(typeof data === 'function' ? data(opts) : data)
292+
// fetch's HeadersList is a 1D string array
293+
const optsHeaders = Array.isArray(opts.headers)
294+
? buildHeadersFromArray(opts.headers)
295+
: opts.headers
296+
const responseData = getResponseData(
297+
typeof data === 'function' ? data({ ...opts, headers: optsHeaders }) : data
298+
)
288299
const responseHeaders = generateKeyValues(headers)
289300
const responseTrailers = generateKeyValues(trailers)
290301

test/mock-agent.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2431,3 +2431,35 @@ test('MockAgent - using fetch yields correct statusText', { skip: nodeMajor < 16
24312431

24322432
t.end()
24332433
})
2434+
2435+
// https://github.com/nodejs/undici/issues/1556
2436+
test('MockAgent - using fetch yields a headers object in the reply callback', { skip: nodeMajor < 16 }, async (t) => {
2437+
const { fetch } = require('..')
2438+
2439+
const mockAgent = new MockAgent()
2440+
mockAgent.disableNetConnect()
2441+
t.teardown(mockAgent.close.bind(mockAgent))
2442+
2443+
const mockPool = mockAgent.get('http://localhost:3000')
2444+
2445+
mockPool.intercept({
2446+
path: '/headers',
2447+
method: 'GET'
2448+
}).reply(200, (opts) => {
2449+
t.same(opts.headers, {
2450+
accept: '*/*',
2451+
'accept-language': '*',
2452+
'sec-fetch-mode': 'cors',
2453+
'user-agent': 'undici',
2454+
'accept-encoding': 'gzip, deflate'
2455+
})
2456+
2457+
return {}
2458+
})
2459+
2460+
await fetch('http://localhost:3000/headers', {
2461+
dispatcher: mockAgent
2462+
})
2463+
2464+
t.end()
2465+
})

test/types/mock-interceptor.test-d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ expectAssignable<BodyInit | Dispatcher.DispatchOptions['body']>(mockResponseCall
3636
expectAssignable<MockScope>(mockInterceptor.reply(() => ({ statusCode: 200, data: { foo: 'bar' }, responseOptions: {
3737
trailers: { foo: 'bar' }
3838
}})))
39+
mockInterceptor.reply((options) => {
40+
expectAssignable<MockInterceptor.MockResponseCallbackOptions['headers']>(options.headers);
41+
return { statusCode: 200, data: { foo: 'bar' } }
42+
})
3943

4044
// replyWithError
4145
class CustomError extends Error {

types/mock-interceptor.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ declare namespace MockInterceptor {
7474
origin: string;
7575
method: string;
7676
body?: BodyInit | Dispatcher.DispatchOptions['body'];
77-
headers: Headers;
77+
headers: Headers | Record<string, string>;
7878
maxRedirections: number;
7979
}
8080

0 commit comments

Comments
 (0)