UNPKG

jest-mock-axios

Version:
370 lines (364 loc) 10.5 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); // lib/mock-axios.ts import { jest } from "@jest/globals"; import { SynchronousPromise } from "synchronous-promise"; // lib/cancel/Cancel.ts var Cancel = class { constructor(message = "Cancel") { this.message = message; } toString() { return this.message; } }; Cancel.prototype.__CANCEL__ = true; var Cancel_default = Cancel; // lib/cancel/CancelToken.ts var CancelToken = class _CancelToken { static source() { let cancel; const token = new _CancelToken((c) => cancel = c); return { cancel, token }; } constructor(executor) { const token = this; this.promise = new Promise((resolve) => { token.resolvePromise = resolve; }); executor(function cancel(message) { if (token.reason || !token.resolvePromise) { return; } token.reason = new Cancel(message); token.resolvePromise(token.reason); }); } throwIfRequested() { if (this.reason) { throw this.reason; } } }; // lib/mock-axios.ts var _pending_requests = []; var _responseInterceptors = []; var _requestInterceptors = []; var _requestHandler; var processInterceptors = (data, stack, type) => { return stack.map(({ [type]: interceptor }) => interceptor).filter((interceptor) => !!interceptor).reduce((_result, next) => { return next(_result); }, data); }; var _newReq = (config = {}, actualConfig = {}) => { if (typeof config === "string") { actualConfig.url = config; config = actualConfig; } const method = config.method || "get"; const url = config.url; const data = config.data; const promise = SynchronousPromise.unresolved(); if (config.cancelToken) { config.cancelToken.promise.then((cancel) => { if (_pending_requests.find((x) => x.promise === promise)) { MockAxios.mockError(cancel, promise); } }); } const requestConfig = processInterceptors({ config, data, method, promise, url }, _requestInterceptors, "onFulfilled"); _pending_requests.push(requestConfig); if (typeof _requestHandler === "function") { _requestHandler(requestConfig); } return promise; }; var _helperReq = (method, url, data, config) => { const conf = data && config ? config : {}; return _newReq(__spreadProps(__spreadValues({}, conf), { data, method, url })); }; var _helperReqNoData = (method, url, config) => { return _helperReq(method, url, {}, config); }; var MockAxios = jest.fn(_newReq); MockAxios.get = jest.fn(_helperReqNoData.bind(null, "get")); MockAxios.post = jest.fn(_helperReq.bind(null, "post")); MockAxios.put = jest.fn(_helperReq.bind(null, "put")); MockAxios.patch = jest.fn(_helperReq.bind(null, "patch")); MockAxios.delete = jest.fn(_helperReqNoData.bind(null, "delete")); MockAxios.request = jest.fn(_newReq); MockAxios.all = jest.fn((values) => Promise.all(values)); MockAxios.head = jest.fn(_helperReqNoData.bind(null, "head")); MockAxios.options = jest.fn(_helperReqNoData.bind(null, "options")); MockAxios.create = jest.fn(() => MockAxios); MockAxios.interceptors = { request: { // @ts-ignore use: jest.fn((onFulfilled, onRejected) => { return _requestInterceptors.push({ onFulfilled, onRejected }); }), // @ts-ignore eject: jest.fn((position) => { _requestInterceptors.splice(position - 1, 1); }), // @ts-ignore clear: jest.fn(() => { _requestInterceptors.length = 0; }) }, response: { // @ts-ignore use: jest.fn((onFulfilled, onRejected) => { return _responseInterceptors.push({ onFulfilled, onRejected }); }), // @ts-ignore eject: jest.fn((position) => { _responseInterceptors.splice(position - 1, 1); }), // @ts-ignore clear: jest.fn(() => { _responseInterceptors.length = 0; }) } }; MockAxios.defaults = { headers: { common: [], get: {}, post: {}, delete: {}, put: {}, patch: {}, head: {} } }; MockAxios.popPromise = (promise) => { if (promise) { for (let ix = 0; ix < _pending_requests.length; ix++) { const req = _pending_requests[ix]; if (req.promise === promise) { _pending_requests.splice(ix, 1); return req.promise; } } } else { const req = _pending_requests.shift(); return req ? req.promise : void 0; } }; MockAxios.popRequest = (request) => { if (request) { const ix = _pending_requests.indexOf(request); if (ix === -1) { return void 0; } _pending_requests.splice(ix, 1); return request; } else { return _pending_requests.shift(); } }; var popQueueItem = (queueItem = null) => { const request = MockAxios.popRequest( queueItem ); if (request) { return request.promise; } else { return MockAxios.popPromise(queueItem); } }; MockAxios.mockResponse = (response, queueItem = null, silentMode = false) => { response = Object.assign( { config: {}, data: {}, headers: {}, status: 200, statusText: "OK" }, response ); let promise = popQueueItem(queueItem); if (!promise && !silentMode) { throw new Error("No request to respond to!"); } else if (!promise) { return; } for (const interceptor of _responseInterceptors) { promise = promise.then(interceptor.onFulfilled, interceptor.onRejected); } promise.resolve(response); }; MockAxios.mockResponseFor = (criteria, response, silentMode = false) => { if (typeof criteria === "string") { criteria = { url: criteria }; } const queueItem = MockAxios.getReqMatching(criteria); if (!queueItem && !silentMode) { throw new Error("No request to respond to!"); } else if (!queueItem) { return; } MockAxios.mockResponse(response, queueItem, silentMode); }; MockAxios.mockError = (error = {}, queueItem = null, silentMode = false) => { let promise = popQueueItem(queueItem); if (!promise && !silentMode) { throw new Error("No request to respond to!"); } else if (!promise) { return; } if (error && typeof error === "object" && error.isAxiosError === void 0) { error.isAxiosError = true; } for (const interceptor of _responseInterceptors) { promise = promise.then(interceptor.onFulfilled, interceptor.onRejected); ; } promise.reject(error); }; MockAxios.isAxiosError = (payload) => typeof payload === "object" && payload.isAxiosError === true; MockAxios.lastReqGet = () => { return _pending_requests[_pending_requests.length - 1]; }; MockAxios.lastPromiseGet = () => { const req = MockAxios.lastReqGet(); return req ? req.promise : void 0; }; var _findReqByPredicate = (predicate) => { return _pending_requests.slice().reverse().find(predicate); }; var deepEqual = (x, y) => { if (x === null || x === void 0 || y === null || y === void 0) { return x === y; } if (x.constructor !== y.constructor) { return false; } if (x instanceof Function) { return x === y; } if (x instanceof RegExp) { return x === y; } if (x === y || x.valueOf() === y.valueOf()) { return true; } if (Array.isArray(x) && x.length !== y.length) { return false; } if (x instanceof Date) { return false; } if (!(x instanceof Object)) { return false; } if (!(y instanceof Object)) { return false; } var p = Object.keys(x); return Object.keys(y).every(function(i) { return p.indexOf(i) !== -1; }) && p.every(function(i) { return deepEqual(x[i], y[i]); }); }; var _checkCriteria = (item, criteria) => { if (criteria.method !== void 0 && criteria.method.toLowerCase() !== item.method.toLowerCase()) { return false; } if (criteria.url !== void 0 && criteria.url !== item.url) { return false; } if (criteria.params !== void 0) { if (item.config === void 0 || !item.config.params || typeof item.config.params !== "object") { return false; } const paramsMatching = Object.entries(criteria.params).every(([key, value]) => deepEqual(item.config.params[key], value)); if (!paramsMatching) { return false; } } return true; }; MockAxios.getReqMatching = (criteria) => { return _findReqByPredicate((x) => _checkCriteria(x, criteria)); }; MockAxios.getReqByUrl = (url) => { return MockAxios.getReqMatching({ url }); }; MockAxios.getReqByMatchUrl = (url) => { return _findReqByPredicate((x) => url.test(x.url)); }; MockAxios.getReqByRegex = (opts) => { return _findReqByPredicate((x) => Object.entries(opts).every(([key, value]) => value.test(JSON.stringify(x[key])))); }; MockAxios.queue = () => { return _pending_requests; }; MockAxios.reset = () => { _pending_requests.splice(0, _pending_requests.length); MockAxios.get.mockClear(); MockAxios.post.mockClear(); MockAxios.put.mockClear(); MockAxios.patch.mockClear(); MockAxios.delete.mockClear(); MockAxios.head.mockClear(); MockAxios.options.mockClear(); MockAxios.request.mockClear(); MockAxios.all.mockClear(); MockAxios.interceptors.request.clear(); MockAxios.interceptors.response.clear(); }; MockAxios.useRequestHandler = (handler) => { _requestHandler = handler; }; MockAxios.Cancel = Cancel_default; MockAxios.CancelToken = CancelToken; MockAxios.isCancel = (u) => { return !!(u && u.__CANCEL__); }; var mock_axios_default = MockAxios; // lib/index.ts var lib_default = mock_axios_default; export { lib_default as default }; /** * TypeScript version of Axios mock for unit testing with [Jest](https://facebook.github.io/jest/). * This file is based on https://gist.github.com/tux4/36006a1859323f779ab0 * * @author knee-cola <nikola.derezic@gmail.com> * @license @license MIT License, http://www.opensource.org/licenses/MIT */