mockaton 0.10.7 → 0.10.9

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/Tests.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { tmpdir } from 'node:os'
4
4
  import { dirname } from 'node:path'
5
+ import { promisify } from 'node:util'
5
6
  import { describe, it } from 'node:test'
6
7
  import { createServer } from 'node:http'
7
8
  import { equal, deepEqual, match } from 'node:assert/strict'
@@ -99,25 +100,20 @@ writeStatic('index.html', '<h1>Static</h1>')
99
100
  writeStatic('assets/app.js', 'const app = 1')
100
101
  writeStatic('another-entry/index.html', '<h1>Another</h1>')
101
102
 
102
- let server
103
- const fallbackServer = createServer((_, response) => {
104
- response.end('From_Fallback_Server')
105
- }).listen(0, 'localhost', function () {
106
- server = Mockaton({
107
- mocksDir: tmpDir,
108
- staticDir: staticTmpDir,
109
- skipOpen: true,
110
- cookies: {
111
- userA: 'CookieA',
112
- userB: 'CookieB'
113
- },
114
- proxyFallback: `http://localhost:${fallbackServer.address().port}`
115
- })
116
- server.on('listening', runTests)
103
+ const server = Mockaton({
104
+ mocksDir: tmpDir,
105
+ staticDir: staticTmpDir,
106
+ skipOpen: true,
107
+ cookies: {
108
+ userA: 'CookieA',
109
+ userB: 'CookieB'
110
+ }
117
111
  })
112
+ server.on('listening', runTests)
118
113
 
119
114
  async function runTests() {
120
115
  await testItRendersDashboard()
116
+ await test404()
121
117
 
122
118
  for (const [url, file, body] of fixtures)
123
119
  await testMockDispatching(url, file, body)
@@ -163,9 +159,8 @@ async function runTests() {
163
159
  await testTransforms()
164
160
  await testStaticFileServing()
165
161
  await testInvalidFilenamesAreIgnored()
166
- await testRouteWithoutMocksRelaysGetsProxied()
162
+ await testEnableFallbackSoRoutesWithoutMocksGetRelayed()
167
163
  server.close()
168
- fallbackServer.close()
169
164
  }
170
165
 
171
166
  async function reset() {
@@ -179,6 +174,17 @@ async function testItRendersDashboard() {
179
174
  it('Renders HTML', () => match(body, new RegExp('<!DOCTYPE html>'))))
180
175
  }
181
176
 
177
+ async function test404() {
178
+ await it('Sends 404 when there is no mock', async () => {
179
+ const res = await request('/api/non-existing')
180
+ equal(res.status, 404)
181
+ })
182
+ await it('Sends 404 when there’s no mock at all for a method', async () => {
183
+ const res = await request('/api/non-existing-too', { method: 'DELETE' })
184
+ equal(res.status, 404)
185
+ })
186
+ }
187
+
182
188
  async function testMockDispatching(url, file, expectedBody, reqBody = void 0) {
183
189
  const { urlMask, method, status } = Route.parseFilename(file)
184
190
  const mime = mimeFor(file)
@@ -346,7 +352,7 @@ async function testInvalidFilenamesAreIgnored() {
346
352
  await it('Invalid filenames get skipped, so they don’t crash the server', async (t) => {
347
353
  const consoleErrorSpy = t.mock.method(console, 'error')
348
354
  consoleErrorSpy.mock.mockImplementation(() => {}) // so they don’t render in the test report
349
-
355
+
350
356
  // An extension is needed for testing because of `Config.allowedExt`
351
357
  write('api/_INVALID_FILENAME_CONVENTION_.json', '')
352
358
  write('api/bad-filename.GET._INVALID_STATUS_.json', '')
@@ -358,10 +364,24 @@ async function testInvalidFilenamesAreIgnored() {
358
364
  })
359
365
  }
360
366
 
361
- async function testRouteWithoutMocksRelaysGetsProxied() {
362
- await it('Fallback relay', async () => {
363
- const res = await request('/non-existing-mock')
364
- equal(await res.text(), 'From_Fallback_Server')
367
+ async function testEnableFallbackSoRoutesWithoutMocksGetRelayed() {
368
+ await describe('Fallback', async () => {
369
+ const fallbackServer = createServer((_, response) => {
370
+ response.statusCode = 423
371
+ response.end('From_Fallback_Server')
372
+ })
373
+ await promisify(fallbackServer.listen).bind(fallbackServer, 3330, '127.0.0.1')()
374
+
375
+ await request(API.fallback, { // Enable fallback
376
+ method: 'PATCH',
377
+ body: JSON.stringify(`http://localhost:${fallbackServer.address().port}`)
378
+ })
379
+ await it('Relays to fallback server', async () => {
380
+ const res = await request('/non-existing-mock')
381
+ equal(res.status, 423)
382
+ equal(await res.text(), 'From_Fallback_Server')
383
+ fallbackServer.close()
384
+ })
365
385
  })
366
386
  }
367
387
 
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.10.7",
5
+ "version": "0.10.9",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
8
8
  "license": "MIT",
package/src/Api.js CHANGED
@@ -28,7 +28,8 @@ export const apiPatchRequests = new Map([
28
28
  [API.edit, updateBroker],
29
29
  [API.reset, reinitialize],
30
30
  [API.cookies, selectCookie],
31
- [API.transform, updateBrokerTransform]
31
+ [API.transform, updateBrokerTransform],
32
+ [API.fallback, updateProxyFallback]
32
33
  ])
33
34
 
34
35
  function serveDashboard(_, response) {
@@ -105,3 +106,14 @@ async function updateBrokerTransform(req, response) {
105
106
  sendBadRequest(response)
106
107
  }
107
108
  }
109
+
110
+ async function updateProxyFallback(req, response) {
111
+ try {
112
+ Config.proxyFallback = await parseJSON(req)
113
+ sendOK(response)
114
+ }
115
+ catch (error) {
116
+ console.error(error)
117
+ sendBadRequest(response)
118
+ }
119
+ }
@@ -7,7 +7,8 @@ export const API = {
7
7
  mocks: MOUNT + '/mocks',
8
8
  reset: MOUNT + '/reset',
9
9
  transform: MOUNT + '/transform',
10
- cookies: MOUNT + '/cookies'
10
+ cookies: MOUNT + '/cookies',
11
+ fallback: MOUNT + '/fallback'
11
12
  }
12
13
 
13
14
  export const DF = { // Dashboard Fields (XHR)
@@ -23,7 +23,7 @@ export async function dispatchMock(req, response) {
23
23
  if (Config.proxyFallback)
24
24
  await proxy(req, response)
25
25
  else
26
- sendNotFound(response) // TODO unit TESTME
26
+ sendNotFound(response)
27
27
  return
28
28
  }
29
29
 
@@ -61,6 +61,8 @@ export const getBrokerByFilename = file => {
61
61
  // BTW, `urlMasks` always start with "/", so there’s no need to
62
62
  // worry about the primacy of array-like keys when iterating.
63
63
  export function getBrokerForUrl(method, url) {
64
+ if (!collection[method])
65
+ return
64
66
  const brokers = Object.values(collection[method])
65
67
  for (let i = brokers.length - 1; i >= 0; i--)
66
68
  if (brokers[i].urlMaskMatches(url))