diff --git a/README.md b/README.md
index bd2cf5d..46f57dd 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,7 @@ There are few packages those help the developers to mock the backend requests wh
| Property | Description | Required | Default |
| ---------- | :------------------------------------------------------------------------------------------ | :------- | :------ |
-| `url` | Supports both **named parameters** (`/:foo/:bar`) and **query parameters**.(`/foo?bar=true`) | Y | - |
+| `url` | Supports both **named parameters** (`/:foo/:bar`) and **query parameters** (`/foo?bar=true`) in [path-to-regexp](https://github.com/pillarjs/path-to-regexp/blob/master/Readme.md) format. | Y | - |
| `method` | Supports `GET`, `POST`, `PUT`, `PATCH` and `DELETE` methods. | - | `GET` |
| `status` | All possible HTTP status codes. | - | `200` |
| `response` | JSON format or function.
Response function is a function that contains request object as a parameter. See the **Custom Response** section for example. | Y | - |
@@ -155,7 +155,7 @@ Default.parameters = {
if (searchParams.id == 1) {
return {
data: 'Custom data for id 1',
- };
+ };
} else if (body.name === 'mock') {
return {
data: 'Custom data for name mock',
diff --git a/index.d.ts b/index.d.ts
index ffd8f5f..7d629ba 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -1,3 +1,21 @@
-declare const withMock: (storyFn: any) => any;
+declare const withMock: (options: RequestInfo[]) => any;
export default withMock;
+
+export interface RequestInfo {
+ url: string;
+ response: object | ((request: ResponseRequestParam) => object);
+ /** @default GET */
+ method?: string;
+ /** @default 200 */
+ status?: number;
+ /** @default 0 */
+ delay?: number;
+}
+
+export interface ResponseRequestParam {
+ method: string;
+ url: url;
+ body: RequestInit['body'];
+ searchParams?: Record;
+}
diff --git a/src/index.js b/src/index.js
index ec087d3..45aea16 100644
--- a/src/index.js
+++ b/src/index.js
@@ -7,9 +7,9 @@ export default makeDecorator({
parameterName: 'mockData',
// This means don't run this decorator if the notes decorator is not set
skipIfNoParametersOrOptions: true,
- wrapper: (getStory, context, { parameters }) => {
+ wrapper: (getStory, context, { options = [], parameters = [] }) => {
const channel = addons.getChannel();
- faker.makeInitialRequestMap(parameters);
+ faker.makeInitialRequestMap(options.concat(parameters));
// Our simple API above simply sets the notes parameter to a string,
// which we send to the channel
diff --git a/src/utils/array.js b/src/utils/array.js
deleted file mode 100644
index a366eef..0000000
--- a/src/utils/array.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export function arrayEquals(a, b) {
- return (
- Array.isArray(a) &&
- Array.isArray(b) &&
- a.length === b.length &&
- a.every((val, index) => val === b[index])
- );
-}
diff --git a/src/utils/faker.js b/src/utils/faker.js
index f75fe75..2566407 100644
--- a/src/utils/faker.js
+++ b/src/utils/faker.js
@@ -8,7 +8,6 @@ import {
getResponseHeaderMap,
defaultResponseHeaders,
} from './headers';
-import { arrayEquals } from './array';
import { getNormalizedUrl } from './url';
let global =
@@ -34,9 +33,9 @@ export class Faker {
getRequests = () => Object.values(this.requestMap);
- getKey = (url = '', searchParamKeys = [], method = 'GET') =>
+ getKey = (url = '', method = 'GET') =>
url && method
- ? [url, ...searchParamKeys, method.toLowerCase()].join('_')
+ ? [url, method.toLowerCase()].join('_')
: '';
makeInitialRequestMap = (requests) => {
@@ -51,12 +50,9 @@ export class Faker {
};
add = (request) => {
- const { path, searchParamKeys } = getNormalizedUrl(request.url);
- const key = this.getKey(path, searchParamKeys, request.method);
+ const key = this.getKey(request.url, request.method);
this.requestMap[key] = {
...request,
- path,
- searchParamKeys,
method: request.method || 'GET',
status: request.status || 200,
delay: request.delay || 0,
@@ -66,8 +62,7 @@ export class Faker {
update = (item, fieldKey, value) => {
const { url, method } = item;
- const { path, searchParamKeys } = getNormalizedUrl(url);
- const itemKey = this.getKey(path, searchParamKeys, method);
+ const itemKey = this.getKey(url, method);
if (
// eslint-disable-next-line no-prototype-builtins
@@ -80,17 +75,17 @@ export class Faker {
};
matchMock = (url, method = 'GET') => {
- const { path, searchParamKeys } = getNormalizedUrl(url);
+ const { fullUrl } = getNormalizedUrl(url);
for (let key in this.requestMap) {
const { url: requestUrl, method: requestMethod } =
this.requestMap[key];
- const { path: requestPath, searchParamKeys: requestSearchKeys } =
+ const { fullUrlEscaped } =
getNormalizedUrl(requestUrl);
+
if (
- match(requestPath)(path) &&
+ match(fullUrlEscaped)(fullUrl) &&
method == requestMethod &&
- arrayEquals(searchParamKeys, requestSearchKeys) &&
!this.requestMap[key].skip
) {
return this.requestMap[key];
diff --git a/src/utils/faker.test.js b/src/utils/faker.test.js
index 27db021..3e6566b 100644
--- a/src/utils/faker.test.js
+++ b/src/utils/faker.test.js
@@ -8,14 +8,10 @@ describe('Faker', () => {
const actual = faker.getKey('', [], '');
expect(actual).toEqual('');
});
- it('should return a string binding url and method with underscore if searchParamKeys is empty', () => {
- const actual = faker.getKey('google.com', [], 'GET');
+ it('should return a string binding url and method with underscore', () => {
+ const actual = faker.getKey('google.com', 'GET');
expect(actual).toEqual('google.com_get');
});
- it('should return a string binding url, search params keys, and method with underscore', () => {
- const actual = faker.getKey('google.com', ['all', 'only'], 'GET');
- expect(actual).toEqual('google.com_all_only_get');
- });
});
describe('makeInitialRequestMap', () => {
const faker = new Faker();
@@ -69,6 +65,13 @@ describe('Faker', () => {
response: {},
delay: 0,
},
+ {
+ url: 'http://request.com?a=1&b=2',
+ method: 'GET',
+ status: 200,
+ response: {},
+ delay: 0,
+ },
];
faker.makeInitialRequestMap(requests);
@@ -88,6 +91,12 @@ describe('Faker', () => {
expect(actual.method).toEqual(requests[2].method);
expect(actual.skip).toEqual(false);
});
+ it('should return request if url matches with the query parameters', () => {
+ const actual = faker.matchMock('http://request.com?a=1&b=2', 'GET');
+ expect(actual.url).toEqual(requests[3].url);
+ expect(actual.method).toEqual(requests[3].method);
+ expect(actual.skip).toEqual(false);
+ });
});
describe('restore', () => {
diff --git a/src/utils/url.js b/src/utils/url.js
index 9a6fe38..2f538dd 100644
--- a/src/utils/url.js
+++ b/src/utils/url.js
@@ -14,8 +14,13 @@ export const getNormalizedUrl = (rawUrl = '') => {
searchParamKeys.push(key);
}
}
+
+ const searchEscaped = url.search ? '\\' + url.search : '';
+
return {
path: url.host + url.pathname,
searchParamKeys,
+ fullUrl: url.host + url.pathname + url.search,
+ fullUrlEscaped: url.host + url.pathname + searchEscaped,
};
};