Skip to content

Commit

Permalink
Migrate handle_request.js to async/await
Browse files Browse the repository at this point in the history
  • Loading branch information
marcbachmann committed Oct 9, 2024
1 parent c1b4a0f commit 47db995
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 124 deletions.
108 changes: 14 additions & 94 deletions src/handle_request.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,7 @@
"use strict";
const utils = require("./utils");

function transformRequest(data) {
if (
utils.isArrayBuffer(data) ||
utils.isBuffer(data) ||
utils.isStream(data) ||
utils.isBlob(data)
) {
return data;
}

// Object and Array: returns a deep copy
if (utils.isObjectOrArray(data)) {
return JSON.parse(JSON.stringify(data));
}

// for primitives like string, undefined, null, number
return data;
}

function makeResponse(result, config) {
return {
status: result[0],
data: transformRequest(result[1]),
headers: result[2],
config: config,
request: {
responseURL: config.url,
},
};
}

function passThroughRequest (mockAdapter, resolve, reject, config) {
function passThroughRequest (mockAdapter, config) {
// Axios v0.17 mutates the url to include the baseURL for non hostnames
// but does not remove the baseURL from the config
let baseURL = config.baseURL;
Expand All @@ -42,20 +11,20 @@ function passThroughRequest (mockAdapter, resolve, reject, config) {

// Axios pre 1.2
if (typeof mockAdapter.originalAdapter === "function") {
return mockAdapter.originalAdapter(config).then(resolve, reject);
return mockAdapter.originalAdapter(config);
}

mockAdapter.axiosInstanceWithoutInterceptors(Object.assign({}, config, {
return mockAdapter.axiosInstanceWithoutInterceptors(Object.assign({}, config, {
baseURL,
// Use the original adapter, not the mock adapter
adapter: mockAdapter.originalAdapter,
// The request transformation runs on the original axios handler already
transformRequest: [],
transformResponse: []
})).then(resolve, reject);
}));
}

function handleRequest(mockAdapter, resolve, reject, config) {
async function handleRequest(mockAdapter, config) {
let url = config.url || "";
// TODO we're not hitting this `if` in any of the tests, investigate
if (
Expand Down Expand Up @@ -87,74 +56,25 @@ function handleRequest(mockAdapter, resolve, reject, config) {

if (handler.passThrough) {
// passThrough handler
passThroughRequest(mockAdapter, resolve, reject, config);
} else if (typeof handler.response !== "function") {
utils.settle(
resolve,
reject,
makeResponse(handler.response, config),
return passThroughRequest(mockAdapter, config);
} else {
return utils.settle(
config,
handler.response,
getEffectiveDelay(mockAdapter, handler)
);
} else {
const result = handler.response(config);
// TODO throw a sane exception when return value is incorrect
if (typeof result.then !== "function") {
utils.settle(
resolve,
reject,
makeResponse(result, config),
getEffectiveDelay(mockAdapter, handler)
);
} else {
result.then(
function (result) {
if (result.config && result.status) {
utils.settle(
resolve,
reject,
makeResponse(
[result.status, result.data, result.headers],
result.config
),
0
);
} else {
utils.settle(
resolve,
reject,
makeResponse(result, config),
getEffectiveDelay(mockAdapter, handler)
);
}
},
function (error) {
if (mockAdapter.delayResponse > 0) {
setTimeout(function () {
reject(error);
}, getEffectiveDelay(mockAdapter, handler));
} else {
reject(error);
}
}
);
}
}
} else {
// handler not found
switch (mockAdapter.onNoMatch) {
case "passthrough":
passThroughRequest(mockAdapter, resolve, reject, config);
break;
return passThroughRequest(mockAdapter, config);
case "throwException":
throw utils.createCouldNotFindMockError(config);
default:
utils.settle(
resolve,
reject,
{
status: 404,
config: config,
},
return utils.settle(
config,
{ status: 404 },
mockAdapter.delayResponse
);
}
Expand Down
4 changes: 1 addition & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ const VERBS = [

function adapter() {
return (config) => {
return new Promise((resolve, reject) => {
handleRequest(this, resolve, reject, config);
});
return handleRequest(this, config);
};
}

Expand Down
84 changes: 57 additions & 27 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,24 +100,57 @@ function purgeIfReplyOnce(mock, handler) {
}
}

function settle(resolve, reject, response, delay) {
if (delay > 0) {
setTimeout(settle, delay, resolve, reject, response);
return;
function transformRequest(data) {
if (
isArrayBuffer(data) ||
isBuffer(data) ||
isStream(data) ||
isBlob(data)
) {
return data;
}

// Object and Array: returns a deep copy
if (isObjectOrArray(data)) {
return JSON.parse(JSON.stringify(data));
}

// for primitives like string, undefined, null, number
return data;
}

async function makeResponse(result, config) {
if (typeof result === "function") result = await result(config);

const status = result.status || result[0];
const data = transformRequest(result.data || result[1]);
const headers = result.headers || result[2];
if (result.config) config = result.config;

return {
status,
data,
headers,
config,
request: { responseURL: config.url }
};
}

async function settle(config, response, delay) {
if (delay > 0) await new Promise(resolve => setTimeout(resolve, delay));

const result = await makeResponse(response, config);

if (
!response.config.validateStatus ||
response.config.validateStatus(response.status)
!result.config.validateStatus ||
result.config.validateStatus(result.status)
) {
resolve(response);
return result;
} else {
reject(
createAxiosError(
`Request failed with status code ${response.status}`,
response.config,
response
)
throw createAxiosError(
`Request failed with status code ${result.status}`,
result.config,
result
);
}
}
Expand Down Expand Up @@ -177,18 +210,15 @@ function createCouldNotFindMockError(config) {
}

module.exports = {
find: find,
findHandler: findHandler,
purgeIfReplyOnce: purgeIfReplyOnce,
settle: settle,
isStream: isStream,
isArrayBuffer: isArrayBuffer,
isFunction: isFunction,
isObjectOrArray: isObjectOrArray,
isBuffer: isBuffer,
isBlob: isBlob,
isBodyOrParametersMatching: isBodyOrParametersMatching,
isEqual: isEqual,
createAxiosError: createAxiosError,
createCouldNotFindMockError: createCouldNotFindMockError,
find,
findHandler,
purgeIfReplyOnce,
settle,
isObjectOrArray,
isBuffer,
isBlob,
isBodyOrParametersMatching,
isEqual,
createAxiosError,
createCouldNotFindMockError,
};

0 comments on commit 47db995

Please sign in to comment.