Skip to content

Commit

Permalink
fix(MockInterceptor): callback options.headers w/ fetch (#1559)
Browse files Browse the repository at this point in the history
  • Loading branch information
KhafraDev committed Jul 18, 2022
1 parent 23f80fb commit 0ab421f
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 8 deletions.
25 changes: 18 additions & 7 deletions lib/mock/mock-utils.js
Expand Up @@ -51,15 +51,20 @@ function getHeaderByName (headers, key) {
}
}

/** @param {string[]} headers */
function buildHeadersFromArray (headers) { // fetch HeadersList
const clone = headers.slice()
const entries = []
for (let index = 0; index < clone.length; index += 2) {
entries.push([clone[index], clone[index + 1]])
}
return Object.fromEntries(entries)
}

function matchHeaders (mockDispatch, headers) {
if (typeof mockDispatch.headers === 'function') {
if (Array.isArray(headers)) { // fetch HeadersList
const clone = headers.slice()
const entries = []
for (let index = 0; index < clone.length; index += 2) {
entries.push([clone[index], clone[index + 1]])
}
headers = Object.fromEntries(entries)
headers = buildHeadersFromArray(headers)
}
return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {})
}
Expand Down Expand Up @@ -284,7 +289,13 @@ function mockDispatch (opts, handler) {
}

function handleReply (mockDispatches) {
const responseData = getResponseData(typeof data === 'function' ? data(opts) : data)
// fetch's HeadersList is a 1D string array
const optsHeaders = Array.isArray(opts.headers)
? buildHeadersFromArray(opts.headers)
: opts.headers
const responseData = getResponseData(
typeof data === 'function' ? data({ ...opts, headers: optsHeaders }) : data
)
const responseHeaders = generateKeyValues(headers)
const responseTrailers = generateKeyValues(trailers)

Expand Down
32 changes: 32 additions & 0 deletions test/mock-agent.js
Expand Up @@ -2431,3 +2431,35 @@ test('MockAgent - using fetch yields correct statusText', { skip: nodeMajor < 16

t.end()
})

// https://github.com/nodejs/undici/issues/1556
test('MockAgent - using fetch yields a headers object in the reply callback', { skip: nodeMajor < 16 }, async (t) => {
const { fetch } = require('..')

const mockAgent = new MockAgent()
mockAgent.disableNetConnect()
t.teardown(mockAgent.close.bind(mockAgent))

const mockPool = mockAgent.get('http://localhost:3000')

mockPool.intercept({
path: '/headers',
method: 'GET'
}).reply(200, (opts) => {
t.same(opts.headers, {
accept: '*/*',
'accept-language': '*',
'sec-fetch-mode': 'cors',
'user-agent': 'undici',
'accept-encoding': 'gzip, deflate'
})

return {}
})

await fetch('http://localhost:3000/headers', {
dispatcher: mockAgent
})

t.end()
})
4 changes: 4 additions & 0 deletions test/types/mock-interceptor.test-d.ts
Expand Up @@ -36,6 +36,10 @@ expectAssignable<BodyInit | Dispatcher.DispatchOptions['body']>(mockResponseCall
expectAssignable<MockScope>(mockInterceptor.reply(() => ({ statusCode: 200, data: { foo: 'bar' }, responseOptions: {
trailers: { foo: 'bar' }
}})))
mockInterceptor.reply((options) => {
expectAssignable<MockInterceptor.MockResponseCallbackOptions['headers']>(options.headers);
return { statusCode: 200, data: { foo: 'bar' } }
})

// replyWithError
class CustomError extends Error {
Expand Down
2 changes: 1 addition & 1 deletion types/mock-interceptor.d.ts
Expand Up @@ -74,7 +74,7 @@ declare namespace MockInterceptor {
origin: string;
method: string;
body?: BodyInit | Dispatcher.DispatchOptions['body'];
headers: Headers;
headers: Headers | Record<string, string>;
maxRedirections: number;
}

Expand Down

0 comments on commit 0ab421f

Please sign in to comment.