mockaton 12.7.1 → 13.0.0

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.
@@ -11,14 +11,15 @@ export class MockBroker {
11
11
  this.file = '' // selected mock filename
12
12
  this.mocks = [] // filenames
13
13
  this.status = -1
14
+ this.isStatic = false // doesn’t follow filename convention
14
15
  this.delayed = false
15
16
  this.proxied = false
16
- this.auto500 = false
17
+ this.autoStatus = 0
17
18
  this.urlMaskMatches = new UrlMatcher(file).urlMaskMatches
18
19
  this.register(file)
19
20
  }
20
21
 
21
- #is500 = file => parseFilename(file).status === 500
22
+ #isStatus = (file, status) => parseFilename(file).status === status
22
23
 
23
24
  #sortMocks() {
24
25
  this.mocks.sort()
@@ -27,7 +28,7 @@ export class MockBroker {
27
28
  }
28
29
 
29
30
  register(file) {
30
- if (this.auto500 && this.#is500(file))
31
+ if (this.autoStatus && this.#isStatus(file, this.autoStatus))
31
32
  this.selectFile(file)
32
33
  this.mocks.push(file)
33
34
  this.#sortMocks()
@@ -44,27 +45,29 @@ export class MockBroker {
44
45
  hasMock = file => this.mocks.includes(file)
45
46
 
46
47
  selectFile(filename) {
48
+ const { status, isStatic } = parseFilename(filename)
47
49
  this.file = filename
50
+ this.status = status
51
+ this.isStatic = isStatic
48
52
  this.proxied = false
49
- this.auto500 = false
50
- this.status = parseFilename(filename).status
53
+ this.autoStatus = 0
51
54
  }
52
55
 
53
56
  selectDefaultFile() {
54
57
  this.selectFile(this.mocks[0])
55
58
  }
56
59
 
57
- toggle500() {
58
- const shouldUnset = this.auto500 || this.status === 500
60
+ toggleStatus(status) {
61
+ const shouldUnset = this.autoStatus === status || (!this.autoStatus && this.status === status)
59
62
  if (shouldUnset)
60
63
  this.selectDefaultFile()
61
64
  else {
62
- const f500 = this.mocks.find(this.#is500)
63
- if (f500)
64
- this.selectFile(f500)
65
+ const fStatus = this.mocks.find(f => parseFilename(f).status === status)
66
+ if (fStatus)
67
+ this.selectFile(fStatus)
65
68
  else {
66
- this.auto500 = true
67
- this.status = 500
69
+ this.autoStatus = status
70
+ this.status = status
68
71
  }
69
72
  }
70
73
  this.proxied = false
@@ -75,7 +78,7 @@ export class MockBroker {
75
78
  }
76
79
 
77
80
  setProxied(proxied) {
78
- this.auto500 = false
81
+ this.autoStatus = 0
79
82
  this.proxied = proxied
80
83
  }
81
84
 
@@ -4,6 +4,7 @@ import { logger } from './utils/logger.js'
4
4
 
5
5
  import { proxy } from './ProxyRelay.js'
6
6
  import { cookie } from './cookie.js'
7
+ import { parseFilename } from '../client/Filename.js'
7
8
  import { echoFilePlugin } from './MockDispatcherPlugins.js'
8
9
  import { brokerByRoute } from './mockBrokersCollection.js'
9
10
  import { config, calcDelay } from './config.js'
@@ -29,12 +30,25 @@ export async function dispatchMock(req, response) {
29
30
  if (cookie.getCurrent())
30
31
  response.setHeader('Set-Cookie', cookie.getCurrent())
31
32
 
32
- response.statusCode = broker.auto500
33
- ? 500
33
+ const { isStatic } = parseFilename(broker.file)
34
+
35
+ if (isStatic && req.headers.range && !broker.autoStatus) {
36
+ setTimeout(async () => {
37
+ await response.partialContent(req.headers.range, join(config.mocksDir, broker.file))
38
+ }, Number(broker.delayed && calcDelay()))
39
+ logger.accessMock(req.url, broker.file)
40
+ return
41
+ }
42
+
43
+ response.statusCode = broker.autoStatus
44
+ ? broker.autoStatus
34
45
  : broker.status
35
- const { mime, body } = broker.auto500
46
+
47
+ const { mime, body } = broker.autoStatus
36
48
  ? { mime: '', body: '' }
37
- : await applyPlugins(join(config.mocksDir, broker.file), req, response)
49
+ : isStatic
50
+ ? echoFilePlugin(join(config.mocksDir, broker.file))
51
+ : await applyPlugins(join(config.mocksDir, broker.file), req, response)
38
52
 
39
53
  response.setHeader('Content-Type', mime)
40
54
  response.setHeader('Content-Length', length(body))
@@ -15,25 +15,21 @@ import { config, setup } from './config.js'
15
15
  import { apiPatchReqs, apiGetReqs } from './Api.js'
16
16
 
17
17
  import { dispatchMock } from './MockDispatcher.js'
18
- import { dispatchStatic } from './StaticDispatcher.js'
19
18
 
20
- import * as staticCollection from './staticCollection.js'
21
19
  import * as mockBrokerCollection from './mockBrokersCollection.js'
22
20
 
23
21
  import { watchDevSPA } from './WatcherDevClient.js'
24
- import { watchMocksDir, watchStaticDir } from './Watcher.js'
22
+ import { watchMocksDir } from './Watcher.js'
25
23
 
26
24
 
27
25
  export function Mockaton(options) {
28
26
  return new Promise((resolve, reject) => {
29
27
  setup(options)
30
28
  mockBrokerCollection.init()
31
- staticCollection.init()
32
29
 
33
30
  if (config.watcherEnabled) {
34
31
  register('./cacheBustResolver.js', import.meta.url)
35
32
  watchMocksDir()
36
- watchStaticDir()
37
33
  }
38
34
  if (config.hotReload)
39
35
  watchDevSPA()
@@ -84,9 +80,6 @@ async function onRequest(req, response) {
84
80
  else if (method === 'GET' && apiGetReqs.has(pathname))
85
81
  apiGetReqs.get(pathname)(req, response)
86
82
 
87
- else if (method === 'GET' && staticCollection.brokerByRoute(pathname))
88
- await dispatchStatic(req, response)
89
-
90
83
  else
91
84
  await dispatchMock(req, response)
92
85
  }
@@ -6,9 +6,7 @@ export default {
6
6
  userB: jwtCookie('CookieB', { email: 'john@example.test' }),
7
7
  },
8
8
  extraHeaders: ['custom_header_name', 'custom_header_val'],
9
- extraMimes: {
10
- ['custom_extension']: 'custom_mime'
11
- },
9
+ extraMimes: { ['custom_extension']: 'custom_mime' },
12
10
  logLevel: 'verbose',
13
11
  corsOrigins: ['https://example.test'],
14
12
  corsExposedHeaders: ['Content-Encoding'],
@@ -7,7 +7,7 @@ import { mkdtempSync } from 'node:fs'
7
7
  import { randomUUID } from 'node:crypto'
8
8
  import { equal, deepEqual, match } from 'node:assert/strict'
9
9
  import { describe, test, before, beforeEach, after } from 'node:test'
10
- import { writeFile, unlink, mkdir, readFile, rename } from 'node:fs/promises'
10
+ import { writeFile, unlink, mkdir, readFile, rename, readdir } from 'node:fs/promises'
11
11
 
12
12
  import { mimeFor } from './utils/mime.js'
13
13
  import { parseFilename } from '../client/Filename.js'
@@ -17,14 +17,12 @@ import CONFIG from './Mockaton.test.config.js'
17
17
 
18
18
 
19
19
  const mocksDir = mkdtempSync(join(tmpdir(), 'mocks'))
20
- const staticDir = mkdtempSync(join(tmpdir(), 'static'))
21
20
 
22
21
  const stdout = []
23
22
  const stderr = []
24
23
  const proc = spawn(join(import.meta.dirname, 'cli.js'), [
24
+ mocksDir,
25
25
  '--config', join(import.meta.dirname, 'Mockaton.test.config.js'),
26
- '--mocks-dir', mocksDir,
27
- '--static-dir', staticDir,
28
26
  '--no-open'
29
27
  ])
30
28
 
@@ -42,13 +40,13 @@ const serverAddr = await new Promise((resolve, reject) => {
42
40
  after(() => proc.kill('SIGUSR2'))
43
41
 
44
42
 
43
+ const rmFromMocksDir = f => unlink(join(mocksDir, f))
44
+ const listFromMocksDir = d => readdir(join(mocksDir, d))
45
45
  const readFromMocksDir = f => readFile(join(mocksDir, f), 'utf8')
46
46
 
47
47
  const makeDirInMocks = dir => mkdir(join(mocksDir, dir), { recursive: true })
48
- const makeDirInStaticMocks = dir => mkdir(join(staticDir, dir), { recursive: true })
49
48
 
50
49
  const renameInMocksDir = (src, target) => rename(join(mocksDir, src), join(mocksDir, target))
51
- const renameInStaticMocksDir = (src, target) => rename(join(staticDir, src), join(staticDir, target))
52
50
 
53
51
 
54
52
  const api = new Commander(serverAddr)
@@ -126,7 +124,7 @@ class Fixture extends BaseFixture {
126
124
  class FixtureStatic extends BaseFixture {
127
125
  constructor(file, body = '') {
128
126
  super(file, body)
129
- this.dir = staticDir
127
+ this.dir = mocksDir
130
128
  this.urlMask = '/' + file
131
129
  this.method = 'GET'
132
130
  }
@@ -147,26 +145,24 @@ describe('Windows', () => {
147
145
 
148
146
  describe('Rejects malicious URLs', () => {
149
147
  [
150
- ['double-encoded', `/${encodeURIComponent(encodeURIComponent('/'))}user`, 400],
151
- ['encoded null byte', '/user%00/admin', 400],
152
- ['invalid percent-encoding', '/user%ZZ', 400],
153
- ['encoded CRLF sequence', '/user%0d%0aSet-Cookie:%20x=1', 400],
154
- ['overlong/illegal UTF-8 sequence', '/user%C0%AF', 400],
155
- ['double-double-encoding trick', '/%25252Fuser', 400],
156
- ['zero-width/invisible char', '/user%E2%80%8Binfo', 404],
157
- ['encoded path traversal', '/user/..%2Fadmin', 404],
158
- ['raw path traversal', '/../user', 404],
159
-
160
- ['very long path', '/'.repeat(2048 + 1), 414]
148
+ ['double-encoded', 400, `/${encodeURIComponent(encodeURIComponent('/'))}user`],
149
+ ['encoded null byte', 400, '/user%00/admin'],
150
+ ['invalid percent-encoding', 400, '/user%ZZ'],
151
+ ['encoded CRLF sequence', 400, '/user%0d%0aSet-Cookie:%20x=1'],
152
+ ['overlong/illegal UTF-8 sequence', 400, '/user%C0%AF'],
153
+ ['double-double-encoding trick', 400, '/%25252Fuser'],
154
+ ['zero-width/invisible char', 404, '/user%E2%80%8Binfo'],
155
+ ['encoded path traversal', 404, '/user/..%2Fadmin'],
156
+ ['raw path traversal', 404, '/../user'],
157
+ ['very long path', 414, '/'.repeat(2048 + 1)]
161
158
  ]
162
- .map(([title, url, status]) =>
163
- test(title, async () =>
164
- equal((await request(url)).status, status)))
159
+ .forEach(([title, status, url]) => test(title, async () =>
160
+ equal((await request(url)).status, status)))
165
161
  })
166
162
 
167
163
 
168
- describe('Warnings', () => {
169
- test('rejects invalid filenames', async () => {
164
+ describe('Filename Convention', () => {
165
+ test('registers invalid filenames as GET 200', async () => {
170
166
  const fx0 = new Fixture('bar.GET._INVALID_STATUS_.json')
171
167
  const fx1 = new Fixture('foo._INVALID_METHOD_.202.json')
172
168
  const fx2 = new Fixture('missing-method-and-status.json')
@@ -175,10 +171,10 @@ describe('Warnings', () => {
175
171
  await fx2.write()
176
172
  await api.reset()
177
173
 
178
- const log = stderr.join('')
179
- match(log, /Invalid HTTP Response Status: "NaN"/)
180
- match(log, /Unrecognized HTTP Method: "_INVALID_METHOD_"/)
181
- match(log, /Invalid Filename Convention/)
174
+ const s = await fetchState()
175
+ equal(s.brokersByMethod.GET['/bar.GET._INVALID_STATUS_.json'].file, 'bar.GET._INVALID_STATUS_.json')
176
+ equal(s.brokersByMethod.GET['/foo._INVALID_METHOD_.202.json'].file, 'foo._INVALID_METHOD_.202.json')
177
+ equal(s.brokersByMethod.GET['/missing-method-and-status.json'].file, 'missing-method-and-status.json')
182
178
 
183
179
  await fx0.unlink()
184
180
  await fx1.unlink()
@@ -369,15 +365,17 @@ describe('Proxy Fallback', () => {
369
365
  describe('Fallback', () => {
370
366
  let fallbackServer
371
367
  const CUSTOM_COOKIES = ['cookieX=x', 'cookieY=y']
372
- const BODY_PAYLOAD = 'text_req_body'
368
+ const BODY_PAYLOAD = { a: 'b' }
369
+ const expectedBody = JSON.stringify(BODY_PAYLOAD, null, ' ') // config.formatCollectedJSON=true
370
+
373
371
  before(async () => {
374
372
  fallbackServer = createServer(async (req, response) => {
375
373
  response.writeHead(423, {
376
374
  'custom_header': 'my_custom_header',
377
- 'content-type': mimeFor('.txt'),
375
+ 'content-type': mimeFor('.json'),
378
376
  'set-cookie': CUSTOM_COOKIES
379
377
  })
380
- response.end(BODY_PAYLOAD)
378
+ response.end(JSON.stringify(BODY_PAYLOAD))
381
379
  })
382
380
  await promisify(fallbackServer.listen).bind(fallbackServer, 0, '127.0.0.1')()
383
381
  await api.setProxyFallback(`http://localhost:${fallbackServer.address().port}`)
@@ -386,15 +384,31 @@ describe('Proxy Fallback', () => {
386
384
 
387
385
  after(() => fallbackServer.close())
388
386
 
389
- test('Relays to fallback server and saves the mock', async () => {
390
- const r = await request(`/non-existing-mock/${randomUUID()}`, { method: 'POST' })
391
- equal(r.status, 423)
392
- equal(r.headers.get('custom_header'), 'my_custom_header')
393
- equal(r.headers.get('set-cookie'), CUSTOM_COOKIES.join(', '))
394
- equal(await r.text(), BODY_PAYLOAD)
387
+ test('Relays to fallback server and saves the mock (we req twice, so the second one gets a unique comment)', async () => {
388
+ const r1 = await request(`/non-existing-mock/${randomUUID()}`, { method: 'POST' })
389
+ const r2 = await request(`/non-existing-mock/${randomUUID()}`, { method: 'POST' })
390
+
391
+ equal(r1.status, 423)
392
+ equal(r2.status, 423)
393
+
394
+ equal(r1.headers.get('custom_header'), 'my_custom_header')
395
+ equal(r2.headers.get('custom_header'), 'my_custom_header')
396
+
397
+ equal(r1.headers.get('set-cookie'), CUSTOM_COOKIES.join(', '))
398
+ equal(r2.headers.get('set-cookie'), CUSTOM_COOKIES.join(', '))
399
+
400
+ deepEqual(await r2.json(), BODY_PAYLOAD)
401
+ deepEqual(await r1.json(), BODY_PAYLOAD)
395
402
 
396
- const savedBody = await readFromMocksDir('non-existing-mock/[id].POST.423.txt')
397
- equal(savedBody, BODY_PAYLOAD)
403
+ const savedMocks = await listFromMocksDir('non-existing-mock')
404
+ equal(savedMocks.length, 2)
405
+
406
+ equal(await readFromMocksDir('non-existing-mock/[id].POST.423.json'), expectedBody)
407
+ for (const m of savedMocks) {
408
+ const f = join('non-existing-mock', m)
409
+ equal(await readFromMocksDir(f), expectedBody)
410
+ await rmFromMocksDir(f)
411
+ }
398
412
  })
399
413
  })
400
414
 
@@ -479,20 +493,20 @@ describe('Proxy Fallback', () => {
479
493
  equal((await r.json()).proxied, false)
480
494
  })
481
495
 
482
- test('unsets auto500', async () => {
496
+ test('unsets autoStatus', async () => {
483
497
  const fx = new Fixture('unset-500-on-proxy.GET.200.txt')
484
498
  await fx.sync()
485
499
  await api.setProxyFallback('https://example.test')
486
500
 
487
- const r0 = await api.toggle500(fx.method, fx.urlMask)
501
+ const r0 = await api.toggleStatus(500, fx.method, fx.urlMask)
488
502
  const b0 = await r0.json()
489
503
  equal(b0.proxied, false)
490
- equal(b0.auto500, true)
504
+ equal(b0.autoStatus, 500)
491
505
 
492
506
  const r1 = await api.setRouteIsProxied(fx.method, fx.urlMask, true)
493
507
  const b1 = await r1.json()
494
508
  equal(b1.proxied, true)
495
- equal(b1.auto500, false)
509
+ equal(b1.autoStatus, 0)
496
510
 
497
511
  await fx.unlink()
498
512
  await api.setProxyFallback('')
@@ -535,14 +549,6 @@ describe('404', () => {
535
549
  await fx.unlink()
536
550
  })
537
551
 
538
- test('404s ignored static files', async () => {
539
- const fx = new FixtureStatic('static-ignored.js~')
540
- await fx.write()
541
- await api.reset()
542
- const r = await fx.request()
543
- equal(r.status, 404)
544
- await fx.unlink()
545
- })
546
552
  })
547
553
 
548
554
 
@@ -642,7 +648,7 @@ describe('Static Files', () => {
642
648
  await fxsIndex.write()
643
649
  await fxsAsset.write()
644
650
  await api.reset()
645
- }) // the last test deletes them
651
+ })
646
652
 
647
653
  describe('Static File Serving', () => {
648
654
  test('Defaults to index.html', async () => {
@@ -660,64 +666,10 @@ describe('Static Files', () => {
660
666
  })
661
667
  })
662
668
 
663
- test('Static File List', async () => {
664
- const { staticBrokers } = await fetchState()
665
- deepEqual(Object.keys(staticBrokers), [
666
- fxsAsset.urlMask,
667
- fxsIndex.urlMask
668
- ])
669
- })
670
-
671
- describe('Set Static Route is Delayed', () => {
672
- test('422 for non-existing route', async () => {
673
- const r = await api.setStaticRouteIsDelayed('/non-existing', true)
674
- equal(r.status, 422)
675
- equal(await r.text(), `Static route does not exist: /non-existing`)
676
- })
677
-
678
- test('422 for invalid delayed value', async () => {
679
- const r = await api.setStaticRouteIsDelayed(fxsIndex.urlMask, 'not-a-boolean')
680
- equal(await r.text(), 'Expected boolean for "delayed"')
681
- })
682
-
683
- test('200', async () => {
684
- await api.setStaticRouteIsDelayed(fxsIndex.urlMask, true)
685
- const { staticBrokers } = await fetchState()
686
- equal(staticBrokers[fxsIndex.urlMask].delayed, true)
687
- })
688
- })
689
-
690
- describe('Set Static Route Status Code', () => {
691
- test('422 for non-existing route', async () => {
692
- const r = await api.setStaticRouteStatus('/non-existing', 200)
693
- equal(r.status, 422)
694
- equal(await r.text(), `Static route does not exist: /non-existing`)
695
- })
696
-
697
- test('422 for invalid delayed value', async () => {
698
- const r = await api.setStaticRouteStatus(fxsIndex.urlMask, 'not-200-or-404')
699
- equal(r.status, 422)
700
- equal(await r.text(), 'Expected 200 or 404 status code')
701
- })
702
-
703
- test('sets 404 and 200', async () => {
704
- await api.setStaticRouteStatus(fxsIndex.urlMask, 404)
705
- const r0 = await fxsIndex.request()
706
- equal(r0.status, 404)
707
-
708
- await api.setStaticRouteStatus(fxsIndex.urlMask, 200)
709
- const r1 = await fxsIndex.request()
710
- equal(r1.status, 200)
711
- })
712
-
713
- test('404s on a registered route but its file has been deleted', async () => {
714
- // Possible: (1) due to watcher delay. (2) or, when not-watching and deleting.
715
- const fx = new FixtureStatic('to-be-deleted.js')
716
- await fx.sync()
717
- await fx.unlink()
718
- const r = await fx.request()
719
- equal(r.status, 404)
720
- })
669
+ test('are part of the normal mocks list', async () => {
670
+ const s = await fetchState()
671
+ equal(s.brokersByMethod.GET[fxsAsset.urlMask].file, fxsAsset.file)
672
+ equal(s.brokersByMethod.GET[fxsIndex.urlMask].file, fxsIndex.file)
721
673
  })
722
674
 
723
675
  describe('Static Partial Content', () => {
@@ -741,27 +693,27 @@ describe('Static Files', () => {
741
693
  await fxsIndex.unlink()
742
694
  await fxsAsset.unlink()
743
695
  await api.reset()
744
- const { staticBrokers } = await fetchState()
745
- equal(staticBrokers[fxsIndex.urlMask], undefined)
746
- equal(staticBrokers[fxsAsset.urlMask], undefined)
696
+ const s = await fetchState()
697
+ equal(s.brokersByMethod.GET?.[fxsIndex.urlMask], undefined)
698
+ equal(s.brokersByMethod.GET?.[fxsAsset.urlMask], undefined)
747
699
  })
748
700
  })
749
701
 
750
702
 
751
- describe('500', () => {
703
+ describe('Auto Status', () => {
752
704
  test('toggling ON 500 on a route without 500 auto-generates one', async () => {
753
705
  const fx = new Fixture('toggling-500-without-500.GET.200.json')
754
706
  await fx.sync()
755
707
  equal((await fx.request()).status, fx.status)
756
708
 
757
- const bp0 = await api.toggle500(fx.method, fx.urlMask)
709
+ const bp0 = await api.toggleStatus(500, fx.method, fx.urlMask)
758
710
  const b0 = await bp0.json()
759
- equal(b0.auto500, true)
711
+ equal(b0.autoStatus, 500)
760
712
  equal(b0.status, 500)
761
713
  equal((await fx.request()).status, 500)
762
714
 
763
- const r1 = await api.toggle500(fx.method, fx.urlMask)
764
- equal((await r1.json()).auto500, false)
715
+ const r1 = await api.toggleStatus(500, fx.method, fx.urlMask)
716
+ equal((await r1.json()).autoStatus, 0)
765
717
  equal((await fx.request()).status, fx.status)
766
718
  })
767
719
 
@@ -772,15 +724,15 @@ describe('500', () => {
772
724
  await fx500.write()
773
725
  await api.reset()
774
726
 
775
- const bp0 = await api.toggle500(fx200.method, fx200.urlMask)
727
+ const bp0 = await api.toggleStatus(500, fx200.method, fx200.urlMask)
776
728
  const b0 = await bp0.json()
777
- equal(b0.auto500, false)
729
+ equal(b0.autoStatus, 0)
778
730
  equal(b0.status, 500)
779
731
  equal(await (await fx200.request()).text(), fx500.body)
780
732
 
781
- const bp1 = await api.toggle500(fx200.method, fx200.urlMask)
733
+ const bp1 = await api.toggleStatus(500, fx200.method, fx200.urlMask)
782
734
  const b1 = await bp1.json()
783
- equal(b0.auto500, false)
735
+ equal(b0.autoStatus, 0)
784
736
  equal(b1.status, 200)
785
737
  equal(await (await fx200.request()).text(), fx200.body)
786
738
 
@@ -793,11 +745,29 @@ describe('500', () => {
793
745
  await fx.sync()
794
746
  await api.setProxyFallback('https://example.test')
795
747
  await api.setRouteIsProxied(fx.method, fx.urlMask, true)
796
- await api.toggle500(fx.method, fx.urlMask)
748
+ await api.toggleStatus(500, fx.method, fx.urlMask)
797
749
  equal((await fx.fetchBroker()).proxied, false)
798
750
  await fx.unlink()
799
751
  await api.setProxyFallback('')
800
752
  })
753
+
754
+ test('toggling ON 404 for static routes', async () => {
755
+ const fx = new FixtureStatic('static-404.txt')
756
+ await fx.sync()
757
+ equal((await fx.request()).status, 200)
758
+
759
+ const bp0 = await api.toggleStatus(404, fx.method, fx.urlMask)
760
+ const b0 = await bp0.json()
761
+ equal(b0.autoStatus, 404)
762
+ equal(b0.status, 404)
763
+ equal((await fx.request()).status, 404)
764
+
765
+ const r1 = await api.toggleStatus(404, fx.method, fx.urlMask)
766
+ equal((await r1.json()).autoStatus, 0)
767
+ equal((await fx.request()).status, 200)
768
+
769
+ await fx.unlink()
770
+ })
801
771
  })
802
772
 
803
773
 
@@ -1090,16 +1060,16 @@ describe('Registering Mocks', () => {
1090
1060
  equal(b, undefined)
1091
1061
  })
1092
1062
 
1093
- test('registering a 500 unsets auto500', async () => {
1063
+ test('registering a 500 unsets autoStatus', async () => {
1094
1064
  const fx200 = new Fixture('reg-error.GET.200.txt')
1095
1065
  const fx500 = new Fixture('reg-error.GET.500.txt')
1096
1066
  await fx200.register()
1097
- await api.toggle500(fx200.method, fx200.urlMask)
1067
+ await api.toggleStatus(500, fx200.method, fx200.urlMask)
1098
1068
  const b0 = await fx200.fetchBroker()
1099
- equal(b0.auto500, true)
1069
+ equal(b0.autoStatus, 500)
1100
1070
  await fx500.register()
1101
1071
  const b1 = await fx200.fetchBroker()
1102
- equal(b1.auto500, false)
1072
+ equal(b1.autoStatus, 0)
1103
1073
  deepEqual(b1.mocks, [
1104
1074
  fx200.file,
1105
1075
  fx500.file
@@ -1142,76 +1112,10 @@ describe('Registering Mocks', () => {
1142
1112
  })
1143
1113
 
1144
1114
 
1145
- describe('Registering Static Mocks', () => {
1146
- test('when watcher is off, newly added mocks do not get registered', async () => {
1147
- await api.setWatchMocks(false)
1148
- const fx = new FixtureStatic('non-auto-registered-file.txt')
1149
- await fx.write()
1150
- await sleep()
1151
- const { staticBrokers } = await fetchState()
1152
- equal(staticBrokers['/' + fx.file], undefined)
1153
- await fx.unlink()
1154
- })
1155
-
1156
- const fx = new FixtureStatic('static-register.txt', 'static-body')
1157
- test('registers static', async () => {
1158
- await api.setWatchMocks(true)
1159
- await fx.register()
1160
- const { staticBrokers } = await fetchState()
1161
- deepEqual(staticBrokers, {
1162
- ['/' + fx.file]: {
1163
- route: '/' + fx.file,
1164
- status: 200,
1165
- delayed: false
1166
- }
1167
- })
1168
- const response = await fx.request()
1169
- equal(response.status, 200)
1170
- equal(await response.text(), fx.body)
1171
- })
1172
-
1173
- test('unregisters static', async () => {
1174
- await fx.unregister()
1175
- const { staticBrokers } = await fetchState()
1176
- deepEqual(staticBrokers, {})
1177
- })
1178
-
1179
- describe('getSyncVersion', () => {
1180
- const fx0 = new FixtureStatic('reg0/static0.txt')
1181
- let version
1182
- before(async () => {
1183
- await makeDirInStaticMocks('reg0')
1184
- await fx0.sync()
1185
- version = await resolveOnNextSyncVersion(-1)
1186
- })
1187
-
1188
- const fx = new FixtureStatic('static1.txt')
1189
- test('responds when a file is added', async () => {
1190
- const prom = resolveOnNextSyncVersion(version)
1191
- await fx.write()
1192
- equal(await prom, version + 1)
1193
- })
1194
-
1195
- test('responds when a file is deleted', async () => {
1196
- const prom = resolveOnNextSyncVersion(version + 1)
1197
- await fx.unlink()
1198
- equal(await prom, version + 2)
1199
- })
1200
-
1201
- test('responds when dir is renamed', async () => {
1202
- const p0 = resolveOnNextSyncVersion(version + 2)
1203
- await renameInStaticMocksDir('reg0', 'reg1')
1204
- equal(await p0, version + 3)
1205
-
1206
- const s = await fetchState()
1207
- equal(s.staticBrokers['/reg1/static0.txt'].route, '/reg1/static0.txt')
1208
- })
1209
- })
1210
- })
1211
1115
 
1212
1116
 
1213
- async function sleep(ms = 100) {
1214
- await new Promise(resolve => setTimeout(resolve, ms))
1117
+ function sleep(ms = 100) {
1118
+ return new Promise(resolve => setTimeout(resolve, ms))
1215
1119
  }
1216
1120
 
1217
1121