mockaton 6.4.6 → 6.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-dashboard.png +0 -0
- package/README.md +16 -10
- package/package.json +1 -1
- package/src/MockDispatcher.js +21 -31
package/README-dashboard.png
CHANGED
|
Binary file
|
package/README.md
CHANGED
|
@@ -12,35 +12,41 @@ my-mocks-dir/api/user/[user-id].GET.200.json
|
|
|
12
12
|
[This browser extension](https://github.com/ericfortis/devtools-ext-tar-http-requests)
|
|
13
13
|
can be used for downloading a TAR of your XHR requests following that convention.
|
|
14
14
|
|
|
15
|
-
## What do I use
|
|
15
|
+
## What do I use it for?
|
|
16
16
|
- I’m a frontend dev, so I don’t have to spin up and maintain hefty or complex backends.
|
|
17
|
-
- For a deterministic and comprehensive state.
|
|
18
|
-
state variants
|
|
17
|
+
- For a deterministic and comprehensive backend state. For example, having all the possible
|
|
18
|
+
state variants of a particular collection helps for spotting inadvertent bugs. And having those
|
|
19
|
+
assorted responses are not easy to trigger from the backend.
|
|
19
20
|
- Testing empty responses.
|
|
20
21
|
- Testing spinners by delaying responses.
|
|
21
|
-
-
|
|
22
|
+
- Testing errors such as _Bad Request_ and _Internal Server Error_.
|
|
22
23
|
- Triggering notifications and alerts.
|
|
23
|
-
-
|
|
24
|
+
- Prototyping before the backend API is developed.
|
|
25
|
+
- Setting up tests.
|
|
26
|
+
- If you commit the mocks in the repo, when bisecting a bug, you don’t
|
|
24
27
|
have to sync the frontend with many backend repos.
|
|
25
28
|
- Similarly, I can check out long-lived branches that have old API contracts.
|
|
26
|
-
- Prototyping before the backend API is developed.
|
|
27
29
|
- As API documentation.
|
|
28
|
-
- Setting up tests.
|
|
29
30
|
|
|
30
31
|
## Alternatives
|
|
31
32
|
- Chrome DevTools allows for [overriding responses](https://developer.chrome.com/docs/devtools/overrides)
|
|
32
33
|
- Reverse Proxies such as [Burp](https://portswigger.net/burp) are also handy for overriding responses.
|
|
33
|
-
- [
|
|
34
|
+
- Storybook’s [MSW](https://storybook.js.org/addons/msw-storybook-addon)
|
|
34
35
|
|
|
35
36
|
### Caveats
|
|
36
|
-
- Syncing the mocks
|
|
37
|
+
- Syncing the mocks, but the browser extension mentioned above helps.
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
## Getting Started
|
|
40
41
|
The best way to learn _Mockaton_ is by checking out this repo and
|
|
41
42
|
exploring its [sample-mocks/](./sample-mocks) directory. Then, run
|
|
42
|
-
[`./_usage_example.js`](./_usage_example.js) and you’ll see
|
|
43
|
+
[`./_usage_example.js`](./_usage_example.js) and you’ll see the dashboard.
|
|
44
|
+
|
|
45
|
+
You can edit mock files without resetting Mockaton. The _Reset_
|
|
46
|
+
button is for when you add, remove, or rename a mock file.
|
|
43
47
|
|
|
48
|
+
The dropdown lets you pick a mock variant, details in the next section. Next to it is a
|
|
49
|
+
_Delay_ toggler, and a button for sending _500 - Internal Server Error_ on that endpoint.
|
|
44
50
|
|
|
45
51
|
<img src="./README-dashboard.png" style="max-width:820px"/>
|
|
46
52
|
|
package/package.json
CHANGED
package/src/MockDispatcher.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { join } from 'node:path'
|
|
2
|
-
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { readFileSync as read } from 'node:fs'
|
|
3
3
|
|
|
4
4
|
import { proxy } from './ProxyRelay.js'
|
|
5
5
|
import { cookie } from './cookie.js'
|
|
@@ -11,34 +11,40 @@ import { sendInternalServerError, sendNotFound, sendBadRequest } from './utils/h
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
export async function dispatchMock(req, response) {
|
|
14
|
-
const broker = mockBrokerCollection.getBrokerForUrl(req.method, req.url)
|
|
15
|
-
if (!broker) {
|
|
16
|
-
if (Config.proxyFallback)
|
|
17
|
-
await proxy(req, response)
|
|
18
|
-
else
|
|
19
|
-
sendNotFound(response)
|
|
20
|
-
return
|
|
21
|
-
}
|
|
22
|
-
|
|
23
14
|
try {
|
|
15
|
+
const broker = mockBrokerCollection.getBrokerForUrl(req.method, req.url)
|
|
16
|
+
if (!broker) {
|
|
17
|
+
if (Config.proxyFallback)
|
|
18
|
+
await proxy(req, response)
|
|
19
|
+
else
|
|
20
|
+
sendNotFound(response)
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
24
|
const { file, status, delay } = broker
|
|
25
25
|
console.log(decodeURIComponent(req.url), ' → ', file)
|
|
26
|
+
const filePath = join(Config.mocksDir, file)
|
|
26
27
|
|
|
27
|
-
let
|
|
28
|
+
let mockBody
|
|
28
29
|
if (file.endsWith('.js')) {
|
|
29
30
|
response.setHeader('Content-Type', mimeFor('.json'))
|
|
30
|
-
|
|
31
|
+
const jsExport = (await import(filePath + '?' + Date.now())).default // date for cache busting
|
|
32
|
+
mockBody = typeof jsExport === 'function'
|
|
33
|
+
? await jsExport(req, response)
|
|
34
|
+
: JSON.stringify(jsExport, null, 2)
|
|
31
35
|
}
|
|
32
36
|
else {
|
|
33
37
|
response.setHeader('Content-Type', mimeFor(file))
|
|
34
|
-
|
|
38
|
+
mockBody = broker.isTemp500
|
|
39
|
+
? ''
|
|
40
|
+
: read(filePath)
|
|
35
41
|
}
|
|
36
|
-
|
|
42
|
+
|
|
37
43
|
if (cookie.getCurrent())
|
|
38
44
|
response.setHeader('Set-Cookie', cookie.getCurrent())
|
|
39
45
|
|
|
40
46
|
response.writeHead(status, Config.extraHeaders)
|
|
41
|
-
setTimeout(() => response.end(
|
|
47
|
+
setTimeout(() => response.end(mockBody), delay)
|
|
42
48
|
}
|
|
43
49
|
catch (error) {
|
|
44
50
|
if (error instanceof JsonBodyParserError)
|
|
@@ -49,19 +55,3 @@ export async function dispatchMock(req, response) {
|
|
|
49
55
|
sendInternalServerError(response, error)
|
|
50
56
|
}
|
|
51
57
|
}
|
|
52
|
-
|
|
53
|
-
async function jsMockText(file, req, response) {
|
|
54
|
-
const jsExport = await importDefault(file)
|
|
55
|
-
return typeof jsExport === 'function'
|
|
56
|
-
? await jsExport(req, response)
|
|
57
|
-
: JSON.stringify(jsExport, null, 2)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function readMock(file) {
|
|
61
|
-
return readFileSync(join(Config.mocksDir, file))
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async function importDefault(file) {
|
|
65
|
-
// The date param is just for cache busting
|
|
66
|
-
return (await import(join(Config.mocksDir, file) + '?' + Date.now())).default
|
|
67
|
-
}
|