Skip to content

Commit d50eb6d

Browse files
authored
feat: add possibility to set API base url on mockiavelli instance (#7) (#16)
1 parent 1bb05e8 commit d50eb6d

File tree

4 files changed

+192
-144
lines changed

4 files changed

+192
-144
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Main features
3535
- [One-time mocks](#one-time-mocks)
3636
- [Matching order](#matching-order)
3737
- [Matching priority](#matching-priority)
38+
- [Specifying API base url](#base-url)
3839
- [Cross-origin (cross-domain) API requests](#cors)
3940
- [Dynamic responses](#dynamic-responses)
4041
- [Not matched requests](#not-matched-requests)
@@ -279,6 +280,19 @@ mockiavelli.mockGET('/api/users', { status: 200 });
279280
// GET /api/users => 200
280281
```
281282

283+
### Specifying API base url <a name="base-url"/>
284+
285+
It is possible to initialize Mockiavelli instance with specified API base url.
286+
This API base url is added to every mocked request url.
287+
288+
```typescript
289+
const mockiavelli = await Mockiavelli.setup(page, { baseUrl: '/api/v1' });
290+
291+
mockiavelli.mockGET('/users', { status: 200 });
292+
293+
// GET /api/v1/users => 200
294+
```
295+
282296
### Cross-origin (cross-domain) API requests <a name="cors"/>
283297

284298
Mockiavelli has built-in support for cross-origin requests. If application and API are not on the same origin (domain) just provide the full request URL to `mockiavelli.mock<HTTP_METHOD>`
@@ -344,6 +358,7 @@ If request does not match any mocks, it will be responded with `404 Not Found`.
344358

345359
- `page` _(Page)_ instance of [Puppeteer Page](https://pptr.dev/#?product=Puppeteer&show=api-class-page) or [Playwright Page](https://github.com/microsoft/playwright/blob/master/docs/api.md#class-page)
346360
- `options` _(object)_ configuration options
361+
- `baseUrl: string` specify the API base url, which will be added to every mocked request url
347362
- `debug: boolean` turns debug mode with logging to console (default: `false`)
348363

349364
###### Example

jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ module.exports = {
2727
preset: 'ts-jest',
2828
testEnvironment: 'node',
2929
roots: ['test/unit'],
30+
clearMocks: true,
3031
},
3132
{
3233
displayName: 'int',

src/mockiavelli.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,18 @@ const interceptedTypes: BrowserRequestType[] = ['xhr', 'fetch'];
3030

3131
export interface MockiavelliOptions {
3232
debug: boolean;
33+
baseUrl: string;
3334
}
3435

3536
export class Mockiavelli {
37+
private readonly baseUrl: string = '';
3638
private mocks: Mock[] = [];
3739

3840
constructor(options: Partial<MockiavelliOptions> = {}) {
41+
if (options.baseUrl) {
42+
this.baseUrl = options.baseUrl;
43+
}
44+
3945
if (options.debug) {
4046
dbg.enable('mockiavelli:*');
4147
}
@@ -61,7 +67,11 @@ export class Mockiavelli {
6167
response: MockedResponse<TResponseBody>,
6268
options?: Partial<MockOptions>
6369
): Mock {
64-
const mock = new Mock(matcher, response, { ...options });
70+
const matcherWithBaseUrl = {
71+
...matcher,
72+
url: this.baseUrl + matcher.url,
73+
};
74+
const mock = new Mock(matcherWithBaseUrl, response, { ...options });
6575
addMockByPriority(this.mocks, mock);
6676
return mock;
6777
}

test/unit/mockiavelli.test.ts

Lines changed: 165 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jest.mock('../../src/controllers/BrowserControllerFactory', () => ({
1111

1212
describe('Mockiavelli', () => {
1313
describe('setup()', () => {
14-
it('returns a promise resolving to instance of Mockiavelli', async () => {
14+
test('returns a promise resolving to instance of Mockiavelli', async () => {
1515
const page = createMockPage();
1616
await expect(Mockiavelli.setup(page)).resolves.toBeInstanceOf(
1717
Mockiavelli
@@ -35,148 +35,170 @@ describe('Mockiavelli', () => {
3535
mockiavelli = new Mockiavelli();
3636
});
3737

38-
test('should create RestMock using GET method and filter as object', () => {
39-
mockiavelli.mockGET(filter, mockResponse);
40-
expect(Mock).toHaveBeenCalledWith(
41-
expect.objectContaining({ method: 'GET', ...filter }),
42-
mockResponse,
43-
expect.anything()
44-
);
45-
});
46-
47-
test('should create RestMock using GET method with filter and query as objects', () => {
48-
mockiavelli.mockGET(filterWithQuery, mockResponse);
49-
expect(Mock).toHaveBeenCalledWith(
50-
expect.objectContaining({
51-
method: 'GET',
52-
...filterWithQuery,
53-
}),
54-
mockResponse,
55-
expect.anything()
56-
);
57-
});
58-
59-
test('should create RestMock using GET method and filter as url string', () => {
60-
mockiavelli.mockGET(url, mockResponse);
61-
expect(Mock).toHaveBeenCalledWith(
62-
expect.objectContaining({ method: 'GET', ...filter }),
63-
mockResponse,
64-
expect.anything()
65-
);
66-
});
67-
68-
test('should create RestMock using POST method and filter as object', () => {
69-
mockiavelli.mockPOST(filter, mockResponse);
70-
expect(Mock).toHaveBeenCalledWith(
71-
expect.objectContaining({
72-
method: 'POST',
73-
...filter,
74-
}),
75-
mockResponse,
76-
expect.anything()
77-
);
78-
});
79-
80-
test('should create RestMock using POST method with filter and query as objects', () => {
81-
mockiavelli.mockPOST(filterWithQuery, mockResponse);
82-
expect(Mock).toHaveBeenCalledWith(
83-
expect.objectContaining({
84-
method: 'POST',
85-
...filterWithQuery,
86-
}),
87-
mockResponse,
88-
expect.anything()
89-
);
90-
});
91-
92-
test('should create RestMock using POST method and filter as url string', () => {
93-
mockiavelli.mockPOST(url, mockResponse);
94-
expect(Mock).toHaveBeenCalledWith(
95-
expect.objectContaining({
96-
method: 'POST',
97-
...filter,
98-
}),
99-
mockResponse,
100-
expect.anything()
101-
);
102-
});
103-
104-
test('should create RestMock using PUT method and filter as object', () => {
105-
mockiavelli.mockPUT(filter, mockResponse);
106-
expect(Mock).toHaveBeenCalledWith(
107-
expect.objectContaining({ method: 'PUT', ...filter }),
108-
mockResponse,
109-
expect.anything()
110-
);
111-
});
112-
113-
test('should create RestMock using PUT method with filter and query as objects', () => {
114-
mockiavelli.mockPUT(filterWithQuery, mockResponse);
115-
expect(Mock).toHaveBeenCalledWith(
116-
expect.objectContaining({
117-
method: 'PUT',
118-
...filterWithQuery,
119-
}),
120-
mockResponse,
121-
expect.anything()
122-
);
123-
});
124-
125-
test('should create RestMock using PUT method and filter as url string', () => {
126-
mockiavelli.mockPUT(url, mockResponse);
127-
expect(Mock).toHaveBeenCalledWith(
128-
expect.objectContaining({ method: 'PUT', ...filter }),
129-
mockResponse,
130-
expect.anything()
131-
);
132-
});
133-
134-
test('should create RestMock using DELETE method and filter as object', () => {
135-
mockiavelli.mockDELETE(filter, mockResponse);
136-
expect(Mock).toHaveBeenCalledWith(
137-
expect.objectContaining({
138-
method: 'DELETE',
139-
...filter,
140-
}),
141-
mockResponse,
142-
expect.anything()
143-
);
144-
});
145-
146-
test('should create RestMock using DELETE method with filter and query as objects', () => {
147-
mockiavelli.mockDELETE(filterWithQuery, mockResponse);
148-
expect(Mock).toHaveBeenCalledWith(
149-
expect.objectContaining({
150-
method: 'DELETE',
151-
...filterWithQuery,
152-
}),
153-
mockResponse,
154-
expect.anything()
155-
);
156-
});
157-
158-
test('should create RestMock using DELETE method and filter as url string', () => {
159-
mockiavelli.mockDELETE(url, mockResponse);
160-
expect(Mock).toHaveBeenCalledWith(
161-
expect.objectContaining({
162-
method: 'DELETE',
163-
...filter,
164-
}),
165-
mockResponse,
166-
expect.anything()
167-
);
168-
});
169-
170-
test('should create RestMock using PATCH method and filter as url string', () => {
171-
mockiavelli.mockPATCH(url, mockResponse);
172-
expect(Mock).toHaveBeenCalledWith(
173-
expect.objectContaining({
174-
method: 'PATCH',
175-
...filter,
176-
}),
177-
mockResponse,
178-
expect.anything()
179-
);
38+
describe('mock()', () => {
39+
test('should add API base url to request matcher', () => {
40+
const mockiavelli = new Mockiavelli({ baseUrl: '/api/foo' });
41+
mockiavelli.mock({ url: '/boo', method: 'GET' }, mockResponse);
42+
expect(Mock).toHaveBeenCalledWith(
43+
{ url: '/api/foo/boo', method: 'GET' },
44+
mockResponse,
45+
expect.anything()
46+
);
47+
});
48+
});
49+
50+
describe('mockGET()', () => {
51+
test('should create RestMock using GET method and filter as object', () => {
52+
mockiavelli.mockGET(filter, mockResponse);
53+
expect(Mock).toHaveBeenCalledWith(
54+
expect.objectContaining({ method: 'GET', ...filter }),
55+
mockResponse,
56+
expect.anything()
57+
);
58+
});
59+
60+
test('should create RestMock using GET method with filter and query as objects', () => {
61+
mockiavelli.mockGET(filterWithQuery, mockResponse);
62+
expect(Mock).toHaveBeenCalledWith(
63+
expect.objectContaining({
64+
method: 'GET',
65+
...filterWithQuery,
66+
}),
67+
mockResponse,
68+
expect.anything()
69+
);
70+
});
71+
72+
test('should create RestMock using GET method and filter as url string', () => {
73+
mockiavelli.mockGET(url, mockResponse);
74+
expect(Mock).toHaveBeenCalledWith(
75+
expect.objectContaining({ method: 'GET', ...filter }),
76+
mockResponse,
77+
expect.anything()
78+
);
79+
});
80+
});
81+
82+
describe('mockPOST()', () => {
83+
test('should create RestMock using POST method and filter as object', () => {
84+
mockiavelli.mockPOST(filter, mockResponse);
85+
expect(Mock).toHaveBeenCalledWith(
86+
expect.objectContaining({
87+
method: 'POST',
88+
...filter,
89+
}),
90+
mockResponse,
91+
expect.anything()
92+
);
93+
});
94+
95+
test('should create RestMock using POST method with filter and query as objects', () => {
96+
mockiavelli.mockPOST(filterWithQuery, mockResponse);
97+
expect(Mock).toHaveBeenCalledWith(
98+
expect.objectContaining({
99+
method: 'POST',
100+
...filterWithQuery,
101+
}),
102+
mockResponse,
103+
expect.anything()
104+
);
105+
});
106+
107+
test('should create RestMock using POST method and filter as url string', () => {
108+
mockiavelli.mockPOST(url, mockResponse);
109+
expect(Mock).toHaveBeenCalledWith(
110+
expect.objectContaining({
111+
method: 'POST',
112+
...filter,
113+
}),
114+
mockResponse,
115+
expect.anything()
116+
);
117+
});
118+
});
119+
120+
describe('mockPUT()', () => {
121+
test('should create RestMock using PUT method and filter as object', () => {
122+
mockiavelli.mockPUT(filter, mockResponse);
123+
expect(Mock).toHaveBeenCalledWith(
124+
expect.objectContaining({ method: 'PUT', ...filter }),
125+
mockResponse,
126+
expect.anything()
127+
);
128+
});
129+
130+
test('should create RestMock using PUT method with filter and query as objects', () => {
131+
mockiavelli.mockPUT(filterWithQuery, mockResponse);
132+
expect(Mock).toHaveBeenCalledWith(
133+
expect.objectContaining({
134+
method: 'PUT',
135+
...filterWithQuery,
136+
}),
137+
mockResponse,
138+
expect.anything()
139+
);
140+
});
141+
142+
test('should create RestMock using PUT method and filter as url string', () => {
143+
mockiavelli.mockPUT(url, mockResponse);
144+
expect(Mock).toHaveBeenCalledWith(
145+
expect.objectContaining({ method: 'PUT', ...filter }),
146+
mockResponse,
147+
expect.anything()
148+
);
149+
});
150+
});
151+
152+
describe('mockDELETE()', () => {
153+
test('should create RestMock using DELETE method and filter as object', () => {
154+
mockiavelli.mockDELETE(filter, mockResponse);
155+
expect(Mock).toHaveBeenCalledWith(
156+
expect.objectContaining({
157+
method: 'DELETE',
158+
...filter,
159+
}),
160+
mockResponse,
161+
expect.anything()
162+
);
163+
});
164+
165+
test('should create RestMock using DELETE method with filter and query as objects', () => {
166+
mockiavelli.mockDELETE(filterWithQuery, mockResponse);
167+
expect(Mock).toHaveBeenCalledWith(
168+
expect.objectContaining({
169+
method: 'DELETE',
170+
...filterWithQuery,
171+
}),
172+
mockResponse,
173+
expect.anything()
174+
);
175+
});
176+
177+
test('should create RestMock using DELETE method and filter as url string', () => {
178+
mockiavelli.mockDELETE(url, mockResponse);
179+
expect(Mock).toHaveBeenCalledWith(
180+
expect.objectContaining({
181+
method: 'DELETE',
182+
...filter,
183+
}),
184+
mockResponse,
185+
expect.anything()
186+
);
187+
});
188+
});
189+
190+
describe('mockPUT()', () => {
191+
test('should create RestMock using PATCH method and filter as url string', () => {
192+
mockiavelli.mockPATCH(url, mockResponse);
193+
expect(Mock).toHaveBeenCalledWith(
194+
expect.objectContaining({
195+
method: 'PATCH',
196+
...filter,
197+
}),
198+
mockResponse,
199+
expect.anything()
200+
);
201+
});
180202
});
181203
});
182204
});

0 commit comments

Comments
 (0)