mockaton 0.9.5 → 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/Api.js CHANGED
@@ -97,7 +97,7 @@ async function bulkUpdateBrokersByCommentTag(req, response) {
97
97
  async function updateBrokerTransform(req, response) {
98
98
  try {
99
99
  const body = await parseJSON(req)
100
- const broker = mockBrokersCollection.getBroker(body[DF.method], body[DF.urlMask])
100
+ const broker = mockBrokersCollection.getBrokerByFilename(body[DF.file])
101
101
  broker.updateTransform(body[DF.file])
102
102
  sendOK(response)
103
103
  }
package/ApiConstants.js CHANGED
@@ -15,7 +15,5 @@ export const DF = { // Dashboard Fields (XHR)
15
15
  delayed: 'delayed',
16
16
  file: 'file',
17
17
  currentCookieKey: 'current_cookie_key',
18
- isForDashboard: 'mock_request_payload',
19
- method: 'method',
20
- urlMask: 'url_mask'
18
+ isForDashboard: 'mock_request_payload'
21
19
  }
package/Dashboard.js CHANGED
@@ -257,15 +257,13 @@ function Transforms({ brokersByMethod }) {
257
257
  r('tr', null,
258
258
  r('td', null, r(PreviewLink, { method: broker.method, urlMask })),
259
259
  r('td', null, r(TransformSelector, {
260
- urlMask,
261
- method: broker.method,
262
260
  items: ['', ...broker.transforms],
263
261
  selected: broker.currentTransform
264
262
  })))
265
263
  )))
266
264
  }
267
265
 
268
- function TransformSelector({ method, urlMask, items, selected }) {
266
+ function TransformSelector({ items, selected }) {
269
267
  const className = defaultIsSelected => cssClass(
270
268
  CSS.TransformSelector,
271
269
  !defaultIsSelected && CSS.bold)
@@ -273,16 +271,10 @@ function TransformSelector({ method, urlMask, items, selected }) {
273
271
  r('select', {
274
272
  className: className(selected === items[0]),
275
273
  autocomplete: 'off',
276
- 'data-urlMask': urlMask,
277
- 'data-method': method,
278
274
  onChange() {
279
275
  fetch(DP.transform, {
280
276
  method: 'PATCH',
281
- body: JSON.stringify({
282
- [DF.file]: this.value,
283
- [DF.urlMask]: this.getAttribute('data-urlMask'),
284
- [DF.method]: this.getAttribute('data-method')
285
- })
277
+ body: JSON.stringify({ [DF.file]: this.value })
286
278
  }).then(() => {
287
279
  this.closest('tr').querySelector('a').click()
288
280
  this.className = className(this.value === this.options[0].value)
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: 200,
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
- ensureItHas501() {
87
- if (!this.#has501())
88
- this.#write501()
83
+ ensureItHas500() {
84
+ if (!this.#has500())
85
+ this.#write500()
89
86
  }
90
87
 
91
- #has501() {
88
+ #has500() {
92
89
  return this.mocks.some(mock =>
93
- Route.parseFilename(mock).status === 501)
90
+ Route.parseFilename(mock).status === 500)
94
91
  }
95
92
 
96
- #write501() {
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}.501.txt`
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
- serveDocumentation(req, response)
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
- else
27
- try {
28
- const { file, status, delay, currentTransform } = mockBroker
29
- console.log(decodeURIComponent(req.url), '->', file)
23
+ return
24
+ }
25
+
26
+ try {
27
+ const { file, status, delay, currentTransform } = mockBroker
28
+ console.log('\n', req.url, '->\n ', file)
30
29
 
31
- response.statusCode = status
32
- response.setHeader('content-type', mimeFor(file))
33
- if (cookie.getCurrent())
34
- response.setHeader('set-cookie', cookie.getCurrent())
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
- let mockAsText = readMock(file)
37
- if (mockBroker.currentTransform) {
38
- const body = await requestBodyForTransform(req, mockAsText)
39
- const transformFunc = await importTransformFunc(currentTransform)
40
- mockAsText = transformFunc(mockAsText, body, Config)
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
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 file name convention, which is
5
- similar to the URLs. For example, the following file will be served for `/api/user/1234`
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,10 +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
 
26
+ About the default mock file, the first file in **alphabetical order** wins.
27
+
25
28
 
26
29
  ## Getting Started
27
30
  The best way to learn _Mockaton_ is by checking out this repo and
28
- exploring its [sample-mocks/](./sample-mocks) directory. Then run
31
+ exploring its [sample-mocks/](./sample-mocks) directory. Then, run
29
32
  [`./_usage_example.js`](./_usage_example.js) and you’ll see this dashboard:
30
33
 
31
34
  ![](./README-dashboard.png)
@@ -36,8 +39,8 @@ The **sample-mocks/** directory has three mock alternatives for serving
36
39
  `/api/user/friends`:
37
40
  - _200 - OK_
38
41
  - _204 - No Content_ with an empty list of friends
39
- - _501 - Internal Server Error_
40
- - BTW, 501 mocks get autogenerated for routes that have no 501’s.
42
+ - _500 - Internal Server Error_
43
+ - BTW, 500 mocks get autogenerated for routes that have no 500’s.
41
44
 
42
45
  ![](./README-dashboard-dropdown.png)
43
46
 
@@ -46,7 +49,7 @@ Comments are anything within parentheses, including them.
46
49
  ![](./README-mocks-with-comments.png)
47
50
 
48
51
  ## Delay 🕓
49
- The clock icon next to the mock selector dropdown is a checkbox for delaying a
52
+ The clock icon next to the mock selector is a checkbox for delaying a
50
53
  particular response. They are handy for testing spinners.
51
54
 
52
55
  The milliseconds for the delay is globally configurable via `Config.delay = 1200`
@@ -102,7 +105,7 @@ Config.cookies = {
102
105
  ```
103
106
 
104
107
  That `jwtCookie` has a hardcoded header and signature. In other
105
- words, it’s useful iff you care about its payload in frontend.
108
+ words, it’s useful iff you care about its payload in the frontend.
106
109
 
107
110
  ---
108
111
 
@@ -134,13 +137,13 @@ api/foo.GET.200.json
134
137
  ```
135
138
  api/video?limit=[limit].GET.200.json
136
139
  ```
137
- The query string behaves like comments in the sense it’s
138
- only used for documenting the URL API contract.
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.
139
142
 
140
- In other words, the query string is ignored when routing to it. BTW, in Windows,
141
- filenames containing "?" are not permitted, but they are ignored anyway.
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.
142
146
 
143
- https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file
144
147
 
145
148
 
146
149
  ### Default (index-like) file
@@ -153,28 +156,6 @@ api/foo/?bar=[bar].GET.200.json
153
156
  api/foo/(my comment).GET.200.json
154
157
  ```
155
158
 
156
-
157
- ---
158
- ## Mock Precedence
159
- The first file in **alphabetical order** wins when a particular route has many files.
160
-
161
- ### Why do we have many mocks per Route+Method?
162
- Each route has mocks for many status codes, and also different
163
- mocks (by having comments) for testing particular scenarios.
164
- For example, different 422 validation error messages.
165
-
166
- ---
167
-
168
- ## Reset the Dashboard UI after insert or delete
169
- When deleting the currently selected option, without refreshing the dashboard, the
170
- served mock will be an alternative mock if it exists. That is, the dashboard won't show
171
- a 404 after deleting the current mock if there’s another mock for that particular route.
172
-
173
- Similarly, inserting a file that goes first in alphabetical order will
174
- send a different mock from the one stated in the dashboard dropdown.
175
-
176
- ---
177
-
178
159
  ## Documenting Contracts (.md)
179
160
  This is handy for documenting request payload parameters. The dashboard will
180
161
  print the markdown document (as plain text) above the actual payload content.
@@ -183,15 +164,14 @@ Create a markdown file following the same filename convention.
183
164
  The status code can be any number. For example,
184
165
  ```text
185
166
  api/foo/[user-id].POST.201.md
167
+ api/foo/[user-id].POST.201.json
186
168
  ```
187
169
 
188
- ---
189
-
190
- ## Non-Deterministic Mocks (.mjs handlers)
170
+ ## Transforms (.mjs)
191
171
  Using the same filename convention, files ending
192
172
  with `.mjs` will process the mock before serving it.
193
173
 
194
- For example, this handler will uppercase the mock body.
174
+ For example, this handler will capitalize the mock body and increment a counter.
195
175
  ```js
196
176
  export default function capitalizeAllText(mockAsText, requestBody, Config) {
197
177
  Config.database.myCount ??= 0
@@ -200,43 +180,60 @@ export default function capitalizeAllText(mockAsText, requestBody, Config) {
200
180
  }
201
181
  ```
202
182
 
203
- In demo mode, transforms tagged with the string `demo` within a filename
204
- comment get activated. Mock sets tags e.g. `demo-a` have no effect. In
205
- other words, only one transform per route is supported in demo mode.
206
-
207
183
  ---
208
184
 
209
185
  ## API
210
186
 
211
- ### Changing a mock for one route
187
+ ### `/mockaton/edit` Select a mock for a route
212
188
  ```
213
- PATCH http://localhost:2345/mockaton/edit
189
+ PATCH /mockaton/edit
214
190
  {
215
191
  "file": "api/foo.200.GET.json"
216
192
  "delayed": true // optional
217
193
  }
218
194
  ```
195
+ ---
196
+
197
+ ### `/mockaton/bulk-select` Select all mocks that have a particular comment
219
198
 
220
- ### Bulk Selecting Mocks by Matching comments
221
199
  ```
222
- PATCH http://localhost:2345/mockaton/bulk-select
200
+ PATCH /mockaton/bulk-select
223
201
  {
224
202
  "comment": "demo-a"
225
203
  }
226
204
  ```
205
+ ---
227
206
 
228
- Many mocks can be changed at once. We do that by searching the
229
- comments on the filename. For example, `api/foo(demo-a).GET.200.json`
207
+ ### `/mockaton/reset` Reset
208
+ Re-Initialize the collection and its states (selected mocks and cookies, delays, etc.).
209
+ ```
210
+ PATCH /mockaton/reset
211
+ ```
212
+ ---
230
213
 
231
- Non-matching mocks are ignored. For instance, if for a
232
- particular API there is only `demo-a` and `demo-b`, changing to
233
- `demo-c` will preserve the last one that was successfully set.
214
+ ### `/mockaton/cookies` Select a cookie
215
+ In `Config.cookies`, each key is the label used
216
+ for changing it. Only one cookie can be set.
217
+ ```
218
+ PATCH /mockaton/cookies
219
+ {
220
+ "current_cookie_key": "My Normal User"
221
+ }
222
+ ```
234
223
 
235
- Similarly, if there’s no demo mock at all for
236
- a route, the first dev mock (a-z) will be served.
224
+ ### `/mockaton/cookies` List Cookies
225
+ Sends a list of the available cookies along with a flag indicated if it’s the selected.
226
+ ```
227
+ GET /mockaton/cookies
228
+ ```
237
229
 
230
+ ---
238
231
 
239
- ### Reset
232
+ ### `/mockaton/transform` Select a Transform
240
233
  ```
241
- PATCH http://localhost:2345/mockaton/reset
234
+ PATCH /mockaton/transform
235
+ {
236
+ "file": "api/video/list(concat newly uploaded).GET.200.mjs"
237
+ }
242
238
  ```
239
+ ---
package/Route.js CHANGED
@@ -16,7 +16,7 @@ export class Route {
16
16
  constructor(file) {
17
17
  const { urlMask, method } = Route.parseFilename(file)
18
18
  this.method = method
19
- this.#urlRegex = new RegExp(`^${disregardVariables(removeQueryStringAndFragment(urlMask))}/*$`)
19
+ this.#urlRegex = new RegExp('^' + disregardVariables(removeQueryStringAndFragment(urlMask)) + '/*$')
20
20
  }
21
21
 
22
22
  urlMaskMatches(url) {
@@ -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 = 'Invalid Filename Convention'
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 = `Invalid HTTP Response Status: "${status}"`
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.501.txt', 'keeps non-autogenerated 501')
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 testAutogenerates501(
123
+ await testAutogenerates500(
129
124
  '/api/company-e/123?limit=9',
130
- 'api/company-e/[id]?limit=[limit].GET.501.txt')
125
+ 'api/company-e/[id]?limit=[limit].GET.500.txt')
131
126
 
132
- await testPreservesExiting501(
127
+ await testPreservesExiting500(
133
128
  '/api',
134
- 'api/.GET.501.txt',
135
- 'keeps non-autogenerated 501')
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
- ['/api/alternative', 'api/alternative(comment-2).GET.200.json', { comment: 2 }],
154
- ['/api/my-route', 'api/my-route(comment-2).GET.200.json', { comment: 2 }]
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 testAutogenerates501(url, file) {
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 501', () => {
225
+ await describe('autogenerated 500', () => {
234
226
  it('body is empty', () => equal(body, ''))
235
- it('status is: 501', () => equal(res.status, 501))
227
+ it('status is: 500', () => equal(res.status, 500))
236
228
  })
237
229
  }
238
230
 
239
- async function testPreservesExiting501(url, file, expectedBody) {
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 501', () => {
238
+ await describe('preserves existing 500', () => {
247
239
  it('body is empty', () => equal(body, expectedBody))
248
- it('status is: 501', () => equal(res.status, 501))
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,11 +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.method]: 'POST',
310
- [DF.urlMask]: '/api/transform',
311
- [DF.file]: 'api/transform.POST.200.mjs'
312
- })
298
+ body: JSON.stringify({ [DF.file]: 'api/transform.POST.200.mjs' })
313
299
  })
314
300
  await testMockDispatching('/api/transform',
315
301
  'api/transform.POST.200.json',
@@ -344,6 +330,22 @@ async function testStaticFileServing() {
344
330
  })
345
331
  }
346
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
+
347
349
 
348
350
  // Utils
349
351
 
package/_usage_example.js CHANGED
@@ -8,8 +8,8 @@ Mockaton({
8
8
  mocksDir: resolve('sample-mocks'),
9
9
  staticDir: resolve('sample-static'),
10
10
  cookies: {
11
- 'Admin User': 'my-cookie=1;Path=/;SameSite=strict',
12
- 'Normal User': 'my-cookie=0;Path=/;SameSite=strict',
11
+ 'My Admin User': 'my-cookie=1;Path=/;SameSite=strict',
12
+ 'My Normal User': 'my-cookie=0;Path=/;SameSite=strict',
13
13
  'My JWT': jwtCookie('my-cookie', {
14
14
  email: 'john.doe@example.com',
15
15
  picture: 'https://cdn.auth0.com/avatars/jd.png'
@@ -35,14 +35,13 @@ export function init() {
35
35
  collection[method][urlMask].register(file)
36
36
  }
37
37
  }
38
- forEachBroker(broker => broker.ensureItHas501())
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 getBroker(method, urlMask)
44
+ return collection[method][urlMask]
46
45
  }
47
46
 
48
47
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "mockaton",
3
3
  "description": "A deterministic server-side for developing and testing frontend clients",
4
4
  "type": "module",
5
- "version": "0.9.5",
5
+ "version": "0.9.7",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
8
8
  "license": "MIT",
@@ -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.