domsuite
Version:
Browser testing/automation utilities with async/await
98 lines (97 loc) • 3.31 kB
JavaScript
// lib/fetch-server.js
import * as sinon from "sinon";
import { isFunction } from "lodash-unified";
var FetchServer = class {
constructor(handlers, { debug = false, errorCallback = null, sort = false } = {}) {
this.handlers = handlers;
this.debug = debug;
this.errorCallback = errorCallback;
this.sort = sort;
}
handle(url, params) {
const routes = Object.entries(this.handlers);
if (this.sort) {
routes.sort(([aRoute], [bRoute]) => {
if (bRoute.length === aRoute.length) {
return bRoute.toLowerCase() < aRoute.toLowerCase() ? 1 : -1;
} else {
return bRoute.length - aRoute.length;
}
});
}
for (const [route, handler] of routes) {
if (url.includes(route)) {
if (params && params.body) {
try {
params = JSON.parse(params.body);
} catch (err) {
params = params.body;
}
}
let response = isFunction(handler) ? handler(url, params) : handler;
if (!response.then) {
const responseOptions = {
status: 200,
headers: {
"Content-Type": `application/json`
}
};
response = Promise.resolve(new Response(JSON.stringify(response), responseOptions));
}
this.debugLog({ url, params, response });
return response;
}
}
throw new Error(`Unexpected fetch: ${url} params: ${JSON.stringify(params)}`);
}
start() {
const fakeFetch = (url, params) => {
try {
return this.handle(url, params);
} catch (err) {
isFunction(this.errorCallback) && this.errorCallback(err);
throw err;
}
};
this.restore();
if (typeof window !== `undefined` && window.fetch && !Object.hasOwnProperty.call(window.fetch, `restore`)) {
sinon.stub(window, `fetch`).callsFake(fakeFetch);
}
if (typeof global !== `undefined` && global.fetch && !Object.hasOwnProperty.call(global.fetch, `restore`)) {
sinon.stub(global, `fetch`).callsFake(fakeFetch);
}
}
static restore() {
if (typeof window !== `undefined` && window.fetch && Object.hasOwnProperty.call(window.fetch, `restore`)) {
window.fetch.restore();
}
if (typeof global !== `undefined` && global.fetch && Object.hasOwnProperty.call(global.fetch, `restore`)) {
global.fetch.restore();
}
}
restore() {
FetchServer.restore();
}
debugLog({ url, params, response }) {
if (this.debug) {
const responseObjectPromise = response.then((r) => r.clone());
const responseBodyPromise = responseObjectPromise.then((clonedResponse) => clonedResponse.json());
Promise.all([responseObjectPromise, responseBodyPromise]).then(([response2, responseBody]) => {
console.groupCollapsed(`[fetch-server] ${url}`);
console.groupCollapsed(`Params`);
console.log(JSON.stringify(params, null, 2));
console.groupEnd();
console.groupCollapsed(`Response`);
console.log(JSON.stringify(response2, null, 2));
console.groupEnd();
console.group(`Response Body`);
console.log(JSON.stringify(responseBody, null, 2));
console.groupEnd();
console.groupEnd();
});
}
}
};
export {
FetchServer
};