mockaton 0.9.6 → 0.9.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/MockBroker.js +9 -12
- package/MockDispatcher.js +29 -30
- package/README-dashboard-dropdown.png +0 -0
- package/README-dashboard.png +0 -0
- package/README-mocks-with-comments.png +0 -0
- package/README.md +16 -24
- package/Route.js +6 -8
- package/Tests.js +35 -31
- package/mockBrokersCollection.js +2 -3
- package/package.json +1 -1
- package/sample-mocks/api/user/.GET.500.txt +7 -0
- package/sample-mocks/api/user/.GET.501.txt +0 -7
- /package/sample-mocks/api/user/{edit-name.PATCH.501.txt → edit-name.PATCH.500.txt} +0 -0
- /package/sample-mocks/api/user/{friends.GET.501.txt → friends.GET.500.txt} +0 -0
- /package/sample-mocks/api/user/{logout.POST.501.txt → logout.POST.500.txt} +0 -0
- /package/sample-mocks/api/user/{videos.GET.501.txt → videos.GET.500.txt} +0 -0
- /package/sample-mocks/api/video/{[id].GET.501.txt → [id].GET.500.txt} +0 -0
- /package/sample-mocks/api/video/{list.GET.501.txt → list.GET.500.txt} +0 -0
- /package/sample-mocks/api/video/stat/[stat-id]/{[video-id].GET.501.txt → [video-id].GET.500.txt} +0 -0
- /package/sample-mocks/api/video/stat/[stat-id]/{all-videos?limit=[limit].GET.501.txt → all-videos?limit=[limit].GET.500.txt} +0 -0
- /package/sample-mocks/api/video/{upload.POST.501.txt → upload.POST.500.txt} +0 -0
package/MockBroker.js
CHANGED
|
@@ -20,7 +20,7 @@ export class MockBroker {
|
|
|
20
20
|
this.mocks = [] // *.json,txt
|
|
21
21
|
this.currentMock = {
|
|
22
22
|
file: '',
|
|
23
|
-
status
|
|
23
|
+
get status() { return Route.parseFilename(this.file).status },
|
|
24
24
|
delay: 0
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -36,10 +36,8 @@ export class MockBroker {
|
|
|
36
36
|
else if (file.endsWith('.mjs'))
|
|
37
37
|
this.transforms.push(file)
|
|
38
38
|
else {
|
|
39
|
-
if (!this.mocks.length)
|
|
39
|
+
if (!this.mocks.length)
|
|
40
40
|
this.currentMock.file = file // The first mock file option for a particular route becomes the default
|
|
41
|
-
this.currentMock.status = Route.parseFilename(file).status
|
|
42
|
-
}
|
|
43
41
|
this.mocks.push(file)
|
|
44
42
|
}
|
|
45
43
|
}
|
|
@@ -52,7 +50,6 @@ export class MockBroker {
|
|
|
52
50
|
|
|
53
51
|
updateFile(filename) {
|
|
54
52
|
this.currentMock.file = filename
|
|
55
|
-
this.currentMock.status = Route.parseFilename(filename).status
|
|
56
53
|
}
|
|
57
54
|
|
|
58
55
|
updateDelay(delayed) {
|
|
@@ -83,24 +80,24 @@ export class MockBroker {
|
|
|
83
80
|
return comments
|
|
84
81
|
}
|
|
85
82
|
|
|
86
|
-
|
|
87
|
-
if (!this.#
|
|
88
|
-
this.#
|
|
83
|
+
ensureItHas500() {
|
|
84
|
+
if (!this.#has500())
|
|
85
|
+
this.#write500()
|
|
89
86
|
}
|
|
90
87
|
|
|
91
|
-
#
|
|
88
|
+
#has500() {
|
|
92
89
|
return this.mocks.some(mock =>
|
|
93
|
-
Route.parseFilename(mock).status ===
|
|
90
|
+
Route.parseFilename(mock).status === 500)
|
|
94
91
|
}
|
|
95
92
|
|
|
96
|
-
#
|
|
93
|
+
#write500() {
|
|
97
94
|
// TODO handle route with transforms but without mocks
|
|
98
95
|
const { urlMask, method } = Route.parseFilename(this.mocks[0])
|
|
99
96
|
let mask = urlMask
|
|
100
97
|
const t = join(Config.mocksDir, urlMask)
|
|
101
98
|
if (existsSync(t) && lstatSync(t).isDirectory())
|
|
102
99
|
mask = urlMask + '/'
|
|
103
|
-
const file = `${mask}.${method}.
|
|
100
|
+
const file = `${mask}.${method}.500.txt`
|
|
104
101
|
writeFileSync(join(Config.mocksDir, file), '')
|
|
105
102
|
this.register(file)
|
|
106
103
|
}
|
package/MockDispatcher.js
CHANGED
|
@@ -10,46 +10,45 @@ import { parseJSON, JsonBodyParserError } from './utils/http-request.js'
|
|
|
10
10
|
import { sendInternalServerError, sendNotFound, sendFile, sendBadRequest } from './utils/http-response.js'
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
function serveDocumentation(req, response) {
|
|
14
|
-
sendFile(response, join(Config.mocksDir, decodeURIComponent(req.url)))
|
|
15
|
-
}
|
|
16
|
-
|
|
17
13
|
export async function dispatchMock(req, response) {
|
|
14
|
+
/* Serve Documentation */
|
|
18
15
|
if (req.method === 'GET' && req.url.endsWith('.md')) {
|
|
19
|
-
|
|
16
|
+
sendFile(response, join(Config.mocksDir, decodeURIComponent(req.url)))
|
|
20
17
|
return
|
|
21
18
|
}
|
|
22
19
|
|
|
23
20
|
const mockBroker = MockBrokerCollection.findMatchingBroker(req.method, req.url)
|
|
24
|
-
if (!mockBroker)
|
|
21
|
+
if (!mockBroker) {
|
|
25
22
|
sendNotFound(response)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
const { file, status, delay, currentTransform } = mockBroker
|
|
28
|
+
console.log('\n', req.url, '->\n ', file)
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
response.statusCode = status
|
|
31
|
+
response.setHeader('content-type', mimeFor(file))
|
|
32
|
+
if (cookie.getCurrent())
|
|
33
|
+
response.setHeader('set-cookie', cookie.getCurrent())
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
setTimeout(() => response.end(mockAsText), delay)
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
console.error(error)
|
|
46
|
-
if (error instanceof JsonBodyParserError)
|
|
47
|
-
sendBadRequest(response)
|
|
48
|
-
else if (error.code === 'ENOENT')
|
|
49
|
-
sendNotFound(response) // file has been deleted
|
|
50
|
-
else
|
|
51
|
-
sendInternalServerError(response)
|
|
35
|
+
let mockAsText = readMock(file)
|
|
36
|
+
if (mockBroker.currentTransform) {
|
|
37
|
+
const body = await requestBodyForTransform(req, mockAsText)
|
|
38
|
+
const transformFunc = await importTransformFunc(currentTransform)
|
|
39
|
+
mockAsText = transformFunc(mockAsText, body, Config)
|
|
52
40
|
}
|
|
41
|
+
setTimeout(() => response.end(mockAsText), delay)
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
console.error(error)
|
|
45
|
+
if (error instanceof JsonBodyParserError)
|
|
46
|
+
sendBadRequest(response)
|
|
47
|
+
else if (error.code === 'ENOENT')
|
|
48
|
+
sendNotFound(response) // file has been deleted
|
|
49
|
+
else
|
|
50
|
+
sendInternalServerError(response)
|
|
51
|
+
}
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
const nonSafeMethods = ['PATCH', 'POST', 'PUT', 'DELETE', 'CONNECT']
|
|
Binary file
|
package/README-dashboard.png
CHANGED
|
Binary file
|
|
Binary file
|
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Mockaton
|
|
2
2
|
_Mockaton_ is a mock server for developing and testing frontends.
|
|
3
3
|
|
|
4
|
-
It scans `Config.mocksDir` for files following a specific
|
|
5
|
-
|
|
4
|
+
It scans `Config.mocksDir` for files following a specific
|
|
5
|
+
file name convention, which is similar to the URL paths. For
|
|
6
|
+
example, the following file will be served for `/api/user/1234`
|
|
6
7
|
```
|
|
7
8
|
api/
|
|
8
9
|
api/user/
|
|
@@ -22,12 +23,12 @@ Each route can have many mocks, which could either be:
|
|
|
22
23
|
Those alternatives can be manually selected in the dashboard
|
|
23
24
|
UI, or programmatically, for instance, for setting up tests.
|
|
24
25
|
|
|
25
|
-
About the mock
|
|
26
|
+
About the default mock file, the first file in **alphabetical order** wins.
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
## Getting Started
|
|
29
30
|
The best way to learn _Mockaton_ is by checking out this repo and
|
|
30
|
-
exploring its [sample-mocks/](./sample-mocks) directory. Then run
|
|
31
|
+
exploring its [sample-mocks/](./sample-mocks) directory. Then, run
|
|
31
32
|
[`./_usage_example.js`](./_usage_example.js) and you’ll see this dashboard:
|
|
32
33
|
|
|
33
34
|

|
|
@@ -38,8 +39,8 @@ The **sample-mocks/** directory has three mock alternatives for serving
|
|
|
38
39
|
`/api/user/friends`:
|
|
39
40
|
- _200 - OK_
|
|
40
41
|
- _204 - No Content_ with an empty list of friends
|
|
41
|
-
-
|
|
42
|
-
- BTW,
|
|
42
|
+
- _500 - Internal Server Error_
|
|
43
|
+
- BTW, 500 mocks get autogenerated for routes that have no 500’s.
|
|
43
44
|
|
|
44
45
|

|
|
45
46
|
|
|
@@ -48,7 +49,7 @@ Comments are anything within parentheses, including them.
|
|
|
48
49
|

|
|
49
50
|
|
|
50
51
|
## Delay 🕓
|
|
51
|
-
The clock icon next to the mock selector
|
|
52
|
+
The clock icon next to the mock selector is a checkbox for delaying a
|
|
52
53
|
particular response. They are handy for testing spinners.
|
|
53
54
|
|
|
54
55
|
The milliseconds for the delay is globally configurable via `Config.delay = 1200`
|
|
@@ -136,13 +137,13 @@ api/foo.GET.200.json
|
|
|
136
137
|
```
|
|
137
138
|
api/video?limit=[limit].GET.200.json
|
|
138
139
|
```
|
|
139
|
-
The query string behaves like comments in the sense it’s
|
|
140
|
-
|
|
140
|
+
The query string behaves like comments in the sense it’s only used for documenting
|
|
141
|
+
the URL API contract. In other words, the query string is ignored when routing to it.
|
|
141
142
|
|
|
142
|
-
|
|
143
|
-
|
|
143
|
+
BTW, in Windows, filenames containing "?" are [not
|
|
144
|
+
permitted](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file),
|
|
145
|
+
but since that’s part of the query string, it’s ignored anyway.
|
|
144
146
|
|
|
145
|
-
https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file
|
|
146
147
|
|
|
147
148
|
|
|
148
149
|
### Default (index-like) file
|
|
@@ -194,15 +195,6 @@ PATCH /mockaton/edit
|
|
|
194
195
|
---
|
|
195
196
|
|
|
196
197
|
### `/mockaton/bulk-select` Select all mocks that have a particular comment
|
|
197
|
-
Many mocks can be changed at once. We do that by searching the
|
|
198
|
-
comments on the filename. For example, `api/foo(demo-a).GET.200.json`
|
|
199
|
-
|
|
200
|
-
Non-matching mocks are ignored. For instance, if for a
|
|
201
|
-
particular API there is only `demo-a` and `demo-b`, changing to
|
|
202
|
-
`demo-c` will preserve the last one that was successfully set.
|
|
203
|
-
|
|
204
|
-
Similarly, if there’s no demo mock at all for
|
|
205
|
-
a route, the first dev mock (a-z) will be served.
|
|
206
198
|
|
|
207
199
|
```
|
|
208
200
|
PATCH /mockaton/bulk-select
|
|
@@ -220,7 +212,8 @@ PATCH /mockaton/reset
|
|
|
220
212
|
---
|
|
221
213
|
|
|
222
214
|
### `/mockaton/cookies` Select a cookie
|
|
223
|
-
In `Config.cookies`, each key is
|
|
215
|
+
In `Config.cookies`, each key is the label used
|
|
216
|
+
for changing it. Only one cookie can be set.
|
|
224
217
|
```
|
|
225
218
|
PATCH /mockaton/cookies
|
|
226
219
|
{
|
|
@@ -229,8 +222,7 @@ PATCH /mockaton/cookies
|
|
|
229
222
|
```
|
|
230
223
|
|
|
231
224
|
### `/mockaton/cookies` List Cookies
|
|
232
|
-
Sends a list of the
|
|
233
|
-
along with a flag indicated if it’s the selected.
|
|
225
|
+
Sends a list of the available cookies along with a flag indicated if it’s the selected.
|
|
234
226
|
```
|
|
235
227
|
GET /mockaton/cookies
|
|
236
228
|
```
|
package/Route.js
CHANGED
|
@@ -45,20 +45,18 @@ export class Route {
|
|
|
45
45
|
static parseFilename(file) {
|
|
46
46
|
const tokens = file.replace(Route.reComments, '').split('.')
|
|
47
47
|
|
|
48
|
-
let error = ''
|
|
49
48
|
if (tokens.length < 4)
|
|
50
|
-
error
|
|
51
|
-
|
|
52
|
-
const method = tokens.at(-3)
|
|
53
|
-
if (!httpMethods.includes(method))
|
|
54
|
-
error = `Unrecognized HTTP Method: "${method}"`
|
|
49
|
+
return { error: 'Invalid Filename Convention' }
|
|
55
50
|
|
|
56
51
|
const status = Number(tokens.at(-2))
|
|
57
52
|
if (!responseStatusIsValid(status))
|
|
58
|
-
error
|
|
53
|
+
return { error: `Invalid HTTP Response Status: "${status}"` }
|
|
54
|
+
|
|
55
|
+
const method = tokens.at(-3)
|
|
56
|
+
if (!httpMethods.includes(method))
|
|
57
|
+
return { error: `Unrecognized HTTP Method: "${method}"` }
|
|
59
58
|
|
|
60
59
|
return {
|
|
61
|
-
error,
|
|
62
60
|
urlMask: '/' + removeTrailingSlash(tokens.at(-4)),
|
|
63
61
|
method,
|
|
64
62
|
status
|
package/Tests.js
CHANGED
|
@@ -90,15 +90,10 @@ const fixtures = [
|
|
|
90
90
|
for (const [, file, body] of fixtures)
|
|
91
91
|
write(file, file.endsWith('.json') ? JSON.stringify(body) : body)
|
|
92
92
|
|
|
93
|
-
write('api/.GET.
|
|
93
|
+
write('api/.GET.500.txt', 'keeps non-autogenerated 500')
|
|
94
94
|
write('api/alternative(comment-2).GET.200.json', JSON.stringify({ comment: 2 }))
|
|
95
95
|
write('api/my-route(comment-2).GET.200.json', JSON.stringify({ comment: 2 }))
|
|
96
96
|
|
|
97
|
-
// These files ensure the server doesn’t crash. We don’t test their console.error
|
|
98
|
-
write('api/bad-filename.200.json', 'missing method')
|
|
99
|
-
write('api/bad-filename.GET.200', 'missing extension')
|
|
100
|
-
write('api/bad-filename.GET.json', 'missing response status')
|
|
101
|
-
|
|
102
97
|
writeStatic('index.html', '<h1>Static</h1>')
|
|
103
98
|
writeStatic('assets/app.js', 'const app = 1')
|
|
104
99
|
writeStatic('another-entry/index.html', '<h1>Another</h1>')
|
|
@@ -125,14 +120,14 @@ async function runTests() {
|
|
|
125
120
|
'/api/alternative',
|
|
126
121
|
'api/alternative(comment-1).GET.200.json')
|
|
127
122
|
|
|
128
|
-
await
|
|
123
|
+
await testAutogenerates500(
|
|
129
124
|
'/api/company-e/123?limit=9',
|
|
130
|
-
'api/company-e/[id]?limit=[limit].GET.
|
|
125
|
+
'api/company-e/[id]?limit=[limit].GET.500.txt')
|
|
131
126
|
|
|
132
|
-
await
|
|
127
|
+
await testPreservesExiting500(
|
|
133
128
|
'/api',
|
|
134
|
-
'api/.GET.
|
|
135
|
-
'keeps non-autogenerated
|
|
129
|
+
'api/.GET.500.txt',
|
|
130
|
+
'keeps non-autogenerated 500')
|
|
136
131
|
|
|
137
132
|
await reset()
|
|
138
133
|
await testItUpdatesTheCurrentSelectedMock(
|
|
@@ -148,12 +143,10 @@ async function runTests() {
|
|
|
148
143
|
'(this is the actual comment)',
|
|
149
144
|
'(another comment)'
|
|
150
145
|
])
|
|
151
|
-
await testItBulkSelectsByComment('(comment-2)',
|
|
152
|
-
[
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
]
|
|
156
|
-
)
|
|
146
|
+
await testItBulkSelectsByComment('(comment-2)', [
|
|
147
|
+
['/api/alternative', 'api/alternative(comment-2).GET.200.json', { comment: 2 }],
|
|
148
|
+
['/api/my-route', 'api/my-route(comment-2).GET.200.json', { comment: 2 }]
|
|
149
|
+
])
|
|
157
150
|
|
|
158
151
|
await reset()
|
|
159
152
|
for (const [url, file, body] of fixtures)
|
|
@@ -161,9 +154,8 @@ async function runTests() {
|
|
|
161
154
|
|
|
162
155
|
await testItUpdatesUserRole()
|
|
163
156
|
await testTransforms()
|
|
164
|
-
|
|
165
157
|
await testStaticFileServing()
|
|
166
|
-
|
|
158
|
+
await testInvalidFilenamesAreIgnored()
|
|
167
159
|
server.close()
|
|
168
160
|
}
|
|
169
161
|
|
|
@@ -223,29 +215,29 @@ async function testItUpdatesDelayAndFile(url, file) {
|
|
|
223
215
|
}
|
|
224
216
|
|
|
225
217
|
|
|
226
|
-
async function
|
|
218
|
+
async function testAutogenerates500(url, file) {
|
|
227
219
|
await request(DP.edit, {
|
|
228
220
|
method: 'PATCH',
|
|
229
221
|
body: JSON.stringify({ [DF.file]: file })
|
|
230
222
|
})
|
|
231
223
|
const res = await request(url)
|
|
232
224
|
const body = await res.text()
|
|
233
|
-
await describe('autogenerated
|
|
225
|
+
await describe('autogenerated 500', () => {
|
|
234
226
|
it('body is empty', () => equal(body, ''))
|
|
235
|
-
it('status is:
|
|
227
|
+
it('status is: 500', () => equal(res.status, 500))
|
|
236
228
|
})
|
|
237
229
|
}
|
|
238
230
|
|
|
239
|
-
async function
|
|
231
|
+
async function testPreservesExiting500(url, file, expectedBody) {
|
|
240
232
|
await request(DP.edit, {
|
|
241
233
|
method: 'PATCH',
|
|
242
234
|
body: JSON.stringify({ [DF.file]: file })
|
|
243
235
|
})
|
|
244
236
|
const res = await request(url)
|
|
245
237
|
const body = await res.text()
|
|
246
|
-
await describe('preserves existing
|
|
238
|
+
await describe('preserves existing 500', () => {
|
|
247
239
|
it('body is empty', () => equal(body, expectedBody))
|
|
248
|
-
it('status is:
|
|
240
|
+
it('status is: 500', () => equal(res.status, 500))
|
|
249
241
|
})
|
|
250
242
|
}
|
|
251
243
|
|
|
@@ -259,9 +251,7 @@ async function testExtractsAllComments(expected) {
|
|
|
259
251
|
async function testItBulkSelectsByComment(comment, tests) {
|
|
260
252
|
await request(DP.bulkSelect, {
|
|
261
253
|
method: 'PATCH',
|
|
262
|
-
body: JSON.stringify({
|
|
263
|
-
[DF.comment]: comment
|
|
264
|
-
})
|
|
254
|
+
body: JSON.stringify({ [DF.comment]: comment })
|
|
265
255
|
})
|
|
266
256
|
for (const [url, file, body] of tests)
|
|
267
257
|
await testMockDispatching(url, file, body)
|
|
@@ -305,9 +295,7 @@ export default function (mock, reqBody, config) {
|
|
|
305
295
|
await reset() // for registering the files
|
|
306
296
|
await request(DP.transform, {
|
|
307
297
|
method: 'PATCH',
|
|
308
|
-
body: JSON.stringify({
|
|
309
|
-
[DF.file]: 'api/transform.POST.200.mjs'
|
|
310
|
-
})
|
|
298
|
+
body: JSON.stringify({ [DF.file]: 'api/transform.POST.200.mjs' })
|
|
311
299
|
})
|
|
312
300
|
await testMockDispatching('/api/transform',
|
|
313
301
|
'api/transform.POST.200.json',
|
|
@@ -342,6 +330,22 @@ async function testStaticFileServing() {
|
|
|
342
330
|
})
|
|
343
331
|
}
|
|
344
332
|
|
|
333
|
+
async function testInvalidFilenamesAreIgnored() {
|
|
334
|
+
await it('Invalid filenames get skipped, so they don’t crash the server', async (t) => {
|
|
335
|
+
const consoleErrorSpy = t.mock.method(console, 'error')
|
|
336
|
+
consoleErrorSpy.mock.mockImplementation(() => {}) // so they don’t render in the test report
|
|
337
|
+
|
|
338
|
+
// An extension is needed for testing because of `Config.allowedExt`
|
|
339
|
+
write('api/_INVALID_FILENAME_CONVENTION_.json', '')
|
|
340
|
+
write('api/bad-filename.GET._INVALID_STATUS_.json', '')
|
|
341
|
+
write('api/bad-filename._INVALID_METHOD_.200.json', '')
|
|
342
|
+
await reset()
|
|
343
|
+
equal(consoleErrorSpy.mock.calls[0].arguments[0], 'Invalid Filename Convention')
|
|
344
|
+
equal(consoleErrorSpy.mock.calls[1].arguments[0], 'Invalid HTTP Response Status: "NaN"')
|
|
345
|
+
equal(consoleErrorSpy.mock.calls[2].arguments[0], 'Unrecognized HTTP Method: "_INVALID_METHOD_"')
|
|
346
|
+
})
|
|
347
|
+
}
|
|
348
|
+
|
|
345
349
|
|
|
346
350
|
// Utils
|
|
347
351
|
|
package/mockBrokersCollection.js
CHANGED
|
@@ -35,14 +35,13 @@ export function init() {
|
|
|
35
35
|
collection[method][urlMask].register(file)
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
forEachBroker(broker => broker.
|
|
38
|
+
forEachBroker(broker => broker.ensureItHas500())
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
export const getAll = () => collection
|
|
42
|
-
export const getBroker = (method, urlMask) => collection[method][urlMask]
|
|
43
42
|
export const getBrokerByFilename = file => {
|
|
44
43
|
const { method, urlMask } = Route.parseFilename(file)
|
|
45
|
-
return
|
|
44
|
+
return collection[method][urlMask]
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
This is a plain text response for (/api/user).
|
|
2
|
+
|
|
3
|
+
In this case, it’s for mocking up a 500 - Internal Server Error.
|
|
4
|
+
|
|
5
|
+
This file could have been empty, or some JSON if it had a `.json` extension.
|
|
6
|
+
|
|
7
|
+
By the way, on initialization an 500 is auto-generated for routes that don’t have a 500.
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
This is a plain text response for (/api/user).
|
|
2
|
-
|
|
3
|
-
In this case, it’s for mocking up a 501 - Internal Server Error.
|
|
4
|
-
|
|
5
|
-
This file could have been empty, or some JSON if it had a `.json` extension.
|
|
6
|
-
|
|
7
|
-
By the way, on initialization an 501 is auto-generated for routes that don’t have a 501.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/sample-mocks/api/video/stat/[stat-id]/{[video-id].GET.501.txt → [video-id].GET.500.txt}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|