helia-coord 1.1.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.
Files changed (57) hide show
  1. package/.on-save.json +8 -0
  2. package/PEDIGREE.md +3 -0
  3. package/README.md +3 -0
  4. package/config/bootstrap-circuit-relays.js +48 -0
  5. package/examples/start-external.js +56 -0
  6. package/index.js +129 -0
  7. package/lib/adapters/bch-adapter.js +94 -0
  8. package/lib/adapters/encryption-adapter.js +123 -0
  9. package/lib/adapters/gist.js +42 -0
  10. package/lib/adapters/index.js +66 -0
  11. package/lib/adapters/ipfs-adapter.js +263 -0
  12. package/lib/adapters/logs-adapter.js +44 -0
  13. package/lib/adapters/pubsub-adapter/README.md +86 -0
  14. package/lib/adapters/pubsub-adapter/about-adapter.js +117 -0
  15. package/lib/adapters/pubsub-adapter/index.js +275 -0
  16. package/lib/adapters/pubsub-adapter/messaging.js +389 -0
  17. package/lib/adapters/pubsub-adapter/msg-router.js +58 -0
  18. package/lib/adapters/pubsub-adapter/resend-msg.js +58 -0
  19. package/lib/controllers/index.js +24 -0
  20. package/lib/controllers/timer-controller.js +417 -0
  21. package/lib/entities/this-node-entity.js +102 -0
  22. package/lib/use-cases/index.js +36 -0
  23. package/lib/use-cases/peer-use-cases.js +146 -0
  24. package/lib/use-cases/pubsub-use-cases.js +56 -0
  25. package/lib/use-cases/relay-use-cases.js +479 -0
  26. package/lib/use-cases/schema.js +158 -0
  27. package/lib/use-cases/this-node-use-cases.js +443 -0
  28. package/lib/util/utils.js +12 -0
  29. package/package.json +52 -0
  30. package/test/mocks/adapter-mock.js +119 -0
  31. package/test/mocks/circuit-relay-mocks.js +67 -0
  32. package/test/mocks/ipfs-mock.js +46 -0
  33. package/test/mocks/peers-mock.js +75 -0
  34. package/test/mocks/pubsub-mocks.js +37 -0
  35. package/test/mocks/thisnode-mocks.js +82 -0
  36. package/test/mocks/use-case-mocks.js +24 -0
  37. package/test/unit/adapters/bch-adapter-unit.js +96 -0
  38. package/test/unit/adapters/encryption-adapter-unit.js +129 -0
  39. package/test/unit/adapters/gist.unit.adapters.js +58 -0
  40. package/test/unit/adapters/index-adapters-unit.js +79 -0
  41. package/test/unit/adapters/ipfs-adapter-unit.js +215 -0
  42. package/test/unit/adapters/logs-adapter-unit.js +55 -0
  43. package/test/unit/adapters/pubsub/about-adapter-unit.js +129 -0
  44. package/test/unit/adapters/pubsub/messaging-adapter-unit.js +576 -0
  45. package/test/unit/adapters/pubsub/pubsub-adapter-unit.js +367 -0
  46. package/test/unit/adapters/pubsub/resend-msg-adapter-unit.js +58 -0
  47. package/test/unit/controllers/controllers-index-unit.js +30 -0
  48. package/test/unit/controllers/timer-controller-unit.js +261 -0
  49. package/test/unit/entities/this-node.unit.entity.js +157 -0
  50. package/test/unit/index-unit.js +160 -0
  51. package/test/unit/use-cases/peer.unit.use-cases.js +186 -0
  52. package/test/unit/use-cases/pubsub.unit.use-cases.js +114 -0
  53. package/test/unit/use-cases/relay-use-cases-unit.js +658 -0
  54. package/test/unit/use-cases/schema-use-case-unit.js +101 -0
  55. package/test/unit/use-cases/this-node-use-cases-unit.js +427 -0
  56. package/test/unit/use-cases/use-cases-index-unit.js +47 -0
  57. package/test/unit/util/utils-unit.js +31 -0
@@ -0,0 +1,101 @@
1
+ /*
2
+ Unit tests for the schema.js library.
3
+ */
4
+
5
+ // npm libraries
6
+ import { assert } from 'chai'
7
+ import sinon from 'sinon'
8
+
9
+ // local libraries
10
+ import Schema from '../../../lib/use-cases/schema.js'
11
+
12
+ describe('#schema', () => {
13
+ let sandbox
14
+ let uut
15
+
16
+ beforeEach(() => {
17
+ // Restore the sandbox before each test.
18
+ sandbox = sinon.createSandbox()
19
+
20
+ const schemaConfig = {
21
+ ipfsId: 'myIpfsId',
22
+ type: 'node.js',
23
+ ipfsMultiaddrs: ['addr1', 'addr2']
24
+ }
25
+ uut = new Schema(schemaConfig)
26
+ })
27
+
28
+ afterEach(() => sandbox.restore())
29
+
30
+ describe('#announcement', () => {
31
+ it('should return an announcement object', () => {
32
+ const result = uut.announcement()
33
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
34
+
35
+ // Assert that expected properties exist.
36
+ assert.property(result, 'apiName')
37
+ assert.property(result, 'apiVersion')
38
+ assert.property(result, 'apiInfo')
39
+ assert.property(result, 'ipfsId')
40
+ assert.property(result, 'type')
41
+ assert.property(result, 'ipfsMultiaddrs')
42
+ assert.property(result, 'circuitRelays')
43
+ assert.property(result, 'isCircuitRelay')
44
+ assert.property(result, 'cryptoAddresses')
45
+ assert.property(result, 'encryptPubKey')
46
+ assert.property(result, 'orbitdb')
47
+
48
+ // Assert that properties have the expected type.
49
+ assert.isArray(result.ipfsMultiaddrs)
50
+ assert.isArray(result.circuitRelays)
51
+ assert.isArray(result.cryptoAddresses)
52
+
53
+ // Assert expected values.
54
+ assert.equal(result.isCircuitRelay, false)
55
+ assert.equal(result.apiName, 'ipfs-coord-announce')
56
+ assert.equal(result.type, 'node.js')
57
+ })
58
+
59
+ it('should update orbitdbId in state when different', () => {
60
+ const announceObj = {
61
+ orbitdbId: '567'
62
+ }
63
+
64
+ const result = uut.announcement(announceObj)
65
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
66
+
67
+ assert.property(result, 'orbitdb')
68
+ assert.equal(result.orbitdb, '567')
69
+ })
70
+ })
71
+
72
+ describe('#chat', () => {
73
+ it('should return a chat object', () => {
74
+ const msgObj = {
75
+ message: 'Some arbitrary text.',
76
+ handle: 'Testy Tester'
77
+ }
78
+
79
+ const result = uut.chat(msgObj)
80
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
81
+
82
+ // Assert that expected properties exist.
83
+ assert.property(result, 'apiName')
84
+ assert.property(result, 'apiVersion')
85
+ assert.property(result, 'apiInfo')
86
+ assert.property(result, 'cryptoAddresses')
87
+ assert.property(result, 'encryptPubKey')
88
+ assert.property(result, 'data')
89
+ assert.property(result.data, 'message')
90
+ assert.property(result.data, 'handle')
91
+ assert.property(result, 'ipfsId')
92
+
93
+ // Assert that properties have the expected type.
94
+ assert.isArray(result.cryptoAddresses)
95
+
96
+ // Assert expected values.
97
+ assert.equal(result.apiName, 'chat')
98
+ assert.equal(result.type, 'node.js')
99
+ })
100
+ })
101
+ })
@@ -0,0 +1,427 @@
1
+ /*
2
+ Unit tests for the this-node use case.
3
+ */
4
+
5
+ // npm libraries
6
+ import { assert } from 'chai'
7
+ import sinon from 'sinon'
8
+
9
+ // Local libraries
10
+ import ThisNodeUseCases from '../../../lib/use-cases/this-node-use-cases.js'
11
+ import AdapterMock from '../../mocks/adapter-mock.js'
12
+ import mockData from '../../mocks/peers-mock.js'
13
+ import UseCasesMock from '../../mocks/use-case-mocks.js'
14
+
15
+ const adapters = new AdapterMock()
16
+
17
+ describe('#thisNode-Use-Cases', () => {
18
+ let uut
19
+ let sandbox
20
+
21
+ beforeEach(() => {
22
+ // Restore the sandbox before each test.
23
+ sandbox = sinon.createSandbox()
24
+
25
+ uut = new ThisNodeUseCases({
26
+ adapters
27
+ })
28
+
29
+ const useCases = new UseCasesMock()
30
+ uut.updateUseCases(useCases)
31
+ })
32
+
33
+ afterEach(() => sandbox.restore())
34
+
35
+ describe('#constructor', () => {
36
+ it('should throw an error if adapters is not included', () => {
37
+ try {
38
+ uut = new ThisNodeUseCases()
39
+
40
+ assert.fail('Unexpected code path')
41
+ } catch (err) {
42
+ assert.include(
43
+ err.message,
44
+ 'Must inject instance of adapters when instantiating thisNode Use Cases library.'
45
+ )
46
+ }
47
+ })
48
+
49
+ // it('should throw an error if controllers are not included', () => {
50
+ // try {
51
+ // uut = new ThisNodeUseCases({ adapters: {} })
52
+ //
53
+ // assert.fail('Unexpected code path')
54
+ // } catch (err) {
55
+ // assert.include(
56
+ // err.message,
57
+ // 'Must inject instance of controllers when instantiating thisNode Use Cases library.'
58
+ // )
59
+ // }
60
+ // })
61
+
62
+ it('should instantiate the use cases library', () => {
63
+ uut = new ThisNodeUseCases({
64
+ adapters: {}
65
+ })
66
+
67
+ assert.property(uut, 'adapters')
68
+ })
69
+ })
70
+
71
+ describe('#createSelf', () => {
72
+ it('should create a thisNode entity', async () => {
73
+ uut = new ThisNodeUseCases({ adapters, statusLog: {} })
74
+
75
+ const result = await uut.createSelf({ type: 'node.js' })
76
+ // console.log('result: ', result)
77
+
78
+ assert.property(result, 'ipfsId')
79
+ assert.property(result, 'type')
80
+ })
81
+ })
82
+
83
+ describe('#addSubnetPeer', () => {
84
+ it('should track a new peer', async () => {
85
+ // Mock dependencies
86
+ sandbox.stub(uut, 'isFreshPeer').returns(true)
87
+
88
+ const announceObj = {
89
+ from: 'peerId',
90
+ data: {}
91
+ }
92
+
93
+ await uut.createSelf({ type: 'node.js' })
94
+ const result = await uut.addSubnetPeer(announceObj)
95
+ // console.log('result: ', result)
96
+
97
+ assert.equal(result, true)
98
+ })
99
+
100
+ it('should track a new Relay peer', async () => {
101
+ // Mock dependencies
102
+ sandbox.stub(uut, 'isFreshPeer').returns(true)
103
+ sandbox.stub(uut.useCases.relays, 'addRelay').resolves()
104
+
105
+ const announceObj = {
106
+ from: 'peerId',
107
+ data: {
108
+ isCircuitRelay: true
109
+ }
110
+ }
111
+
112
+ await uut.createSelf({ type: 'node.js' })
113
+ const result = await uut.addSubnetPeer(announceObj)
114
+ // console.log('result: ', result)
115
+
116
+ assert.equal(result, true)
117
+ })
118
+
119
+ it('should update an existing peer', async () => {
120
+ // Mock dependencies
121
+ sandbox.stub(uut, 'isFreshPeer').returns(true)
122
+
123
+ const announceObj = {
124
+ from: 'peerId',
125
+ data: {
126
+ orbitdb: 'orbitdbId'
127
+ }
128
+ }
129
+
130
+ await uut.createSelf({ type: 'node.js' })
131
+
132
+ // Add the new peer
133
+ await uut.addSubnetPeer(announceObj)
134
+
135
+ // Simulate a second announcement object.
136
+ const result = await uut.addSubnetPeer(announceObj)
137
+ // console.log('result: ', result)
138
+
139
+ assert.equal(result, true)
140
+
141
+ // peerData array should only have one peer.
142
+ assert.equal(uut.thisNode.peerData.length, 1)
143
+ })
144
+
145
+ it('should not update an existing peer if broadcast message is older the current one', async () => {
146
+ // Mock dependencies
147
+ sandbox.stub(uut, 'isFreshPeer').returns(true)
148
+
149
+ const announceObj1 = {
150
+ from: 'peerId',
151
+ data: {
152
+ orbitdb: 'orbitdbId',
153
+ broadcastedAt: new Date('10/07/2023')
154
+ }
155
+ }
156
+
157
+ const announceObj2 = {
158
+ from: 'peerId',
159
+ data: {
160
+ orbitdb: 'orbitdbId',
161
+ broadcastedAt: new Date('10/05/2023')
162
+ }
163
+ }
164
+
165
+ await uut.createSelf({ type: 'node.js' })
166
+
167
+ // Add the new peer
168
+ await uut.addSubnetPeer(announceObj1)
169
+
170
+ // Simulate a second announcement object.
171
+ const result = await uut.addSubnetPeer(announceObj2)
172
+ // console.log('result: ', result)
173
+
174
+ assert.equal(result, true)
175
+
176
+ // peerData array should only have one peer.
177
+ assert.equal(uut.thisNode.peerData.length, 1)
178
+ })
179
+
180
+ it('should catch and report an error', async () => {
181
+ try {
182
+ const announceObj = {
183
+ from: 'peerId'
184
+ }
185
+
186
+ await uut.addSubnetPeer(announceObj)
187
+
188
+ assert.isOk(true, 'Not throwing an error is a pass')
189
+ } catch (err) {
190
+ // console.log(err)
191
+ assert.fail('Unexpected code path')
192
+ }
193
+ })
194
+ })
195
+
196
+ describe('#refreshPeerConnections', () => {
197
+ it('should execute with no connected peers', async () => {
198
+ await uut.createSelf({ type: 'node.js' })
199
+
200
+ // Add a peer
201
+ await uut.addSubnetPeer(mockData.announceObj)
202
+
203
+ // Mock dependencies
204
+ sandbox.stub(uut.adapters.ipfs, 'getPeers').resolves(mockData.swarmPeers)
205
+
206
+ // Connect to that peer.
207
+ await uut.refreshPeerConnections()
208
+ })
209
+
210
+ it('should skip if peer is already connected', async () => {
211
+ await uut.createSelf({ type: 'node.js' })
212
+ // Add a peer that is already in the list of connected peers.
213
+ uut.thisNode.peerList = ['QmbyYXKbnAmMbMGo8LRBZ58jYs58anqUzY1m4jxDmhDsjd']
214
+
215
+ // Add a peer
216
+ await uut.addSubnetPeer(mockData.announceObj2)
217
+
218
+ // Mock dependencies
219
+ sandbox.stub(uut.adapters.ipfs, 'getPeers').resolves(mockData.swarmPeers)
220
+
221
+ // Connect to that peer.
222
+ const result = await uut.refreshPeerConnections()
223
+
224
+ assert.equal(result, true)
225
+ })
226
+
227
+ it('should refresh a connection', async () => {
228
+ await uut.createSelf({ type: 'node.js' })
229
+ // Add a peer that is not in the list of connected peers.
230
+ const ipfsId = 'QmbyYXKbnAmMbMGo8LRBZ58jYs58anqUzY1m4jxDmhDsje'
231
+ uut.thisNode.peerList = [ipfsId]
232
+ uut.thisNode.peerData = [{ from: ipfsId }]
233
+
234
+ // Add a peer
235
+ await uut.addSubnetPeer(mockData.announceObj)
236
+
237
+ // Force circuit relay to be used.
238
+ uut.thisNode.relayData = mockData.mockRelayData
239
+
240
+ // Mock dependencies
241
+ sandbox.stub(uut.adapters.ipfs, 'getPeers').resolves(mockData.swarmPeers)
242
+ sandbox.stub(uut.adapters.ipfs, 'connectToPeer').resolves(true)
243
+ sandbox.stub(uut, 'isFreshPeer').returns(true)
244
+
245
+ // Connect to that peer.
246
+ const result = await uut.refreshPeerConnections()
247
+
248
+ assert.equal(result, true)
249
+ })
250
+
251
+ it('should skip if peer is stale', async () => {
252
+ await uut.createSelf({ type: 'node.js' })
253
+ // Add a peer that is not in the list of connected peers.
254
+ const ipfsId = 'QmbyYXKbnAmMbMGo8LRBZ58jYs58anqUzY1m4jxDmhDsje'
255
+ uut.thisNode.peerList = [ipfsId]
256
+ uut.thisNode.peerData = [{ from: ipfsId }]
257
+
258
+ // Add a peer
259
+ await uut.addSubnetPeer(mockData.announceObj)
260
+
261
+ // Force circuit relay to be used.
262
+ uut.thisNode.relayData = mockData.mockRelayData
263
+
264
+ // Mock dependencies
265
+ sandbox.stub(uut.adapters.ipfs, 'getPeers').resolves(mockData.swarmPeers)
266
+ sandbox.stub(uut.adapters.ipfs, 'connectToPeer').resolves(true)
267
+ sandbox.stub(uut, 'isFreshPeer').returns(false)
268
+
269
+ // Connect to that peer.
270
+ const result = await uut.refreshPeerConnections()
271
+
272
+ assert.equal(result, true)
273
+ })
274
+
275
+ it('should catch and throw an error', async () => {
276
+ try {
277
+ await uut.createSelf({ type: 'node.js' })
278
+
279
+ // Add a peer
280
+ await uut.addSubnetPeer(mockData.announceObj)
281
+
282
+ // Force error
283
+ sandbox
284
+ .stub(uut.adapters.ipfs, 'getPeers')
285
+ .rejects(new Error('test error'))
286
+
287
+ // Connect to that peer.
288
+ await uut.refreshPeerConnections()
289
+
290
+ assert.fail('Unexpected code path')
291
+ } catch (err) {
292
+ // console.log('err: ', err)
293
+ assert.include(err.message, 'test error')
294
+ }
295
+ })
296
+ })
297
+
298
+ describe('#isFreshPeer', () => {
299
+ it('should return false if peer data has no broadcastedAt property', () => {
300
+ const announceObj = {
301
+ data: {}
302
+ }
303
+
304
+ const result = uut.isFreshPeer(announceObj)
305
+
306
+ assert.equal(result, false)
307
+ })
308
+
309
+ it('should return false if broadcast is older than 10 minutes', () => {
310
+ const now = new Date()
311
+ const fifteenMinutes = 15 * 60000
312
+ let fifteenMinutesAgo = now.getTime() - fifteenMinutes
313
+ fifteenMinutesAgo = new Date(fifteenMinutesAgo)
314
+
315
+ const announceObj = {
316
+ data: {
317
+ broadcastedAt: fifteenMinutesAgo.toISOString()
318
+ }
319
+ }
320
+
321
+ const result = uut.isFreshPeer(announceObj)
322
+
323
+ assert.equal(result, false)
324
+ })
325
+
326
+ it('should return true if broadcast is newer than 10 minutes', () => {
327
+ const now = new Date()
328
+ const fiveMinutes = 5 * 60000
329
+ let fiveMinutesAgo = now.getTime() - fiveMinutes
330
+ fiveMinutesAgo = new Date(fiveMinutesAgo)
331
+
332
+ const announceObj = {
333
+ data: {
334
+ broadcastedAt: fiveMinutesAgo.toISOString()
335
+ }
336
+ }
337
+
338
+ const result = uut.isFreshPeer(announceObj)
339
+
340
+ assert.equal(result, true)
341
+ })
342
+ })
343
+
344
+ describe('#enforceBlacklist', () => {
345
+ it('should disconnect from blacklisted peers', async () => {
346
+ await uut.createSelf({ type: 'node.js' })
347
+
348
+ // Set up test data
349
+ uut.thisNode.blacklistPeers = ['testId']
350
+ uut.thisNode.blacklistMultiaddrs = ['testId']
351
+
352
+ const result = await uut.enforceBlacklist()
353
+
354
+ assert.equal(result, true)
355
+ })
356
+
357
+ it('catch and throw an error', async () => {
358
+ try {
359
+ await uut.enforceBlacklist()
360
+
361
+ assert.fail('Unexpected code path')
362
+ } catch (err) {
363
+ // console.log(err)
364
+ assert.include(err.message, 'Cannot read')
365
+ }
366
+ })
367
+ })
368
+
369
+ describe('#enforceWhitelist', () => {
370
+ it('should disconnect from non-ipfs-coord peers', async () => {
371
+ await uut.createSelf({ type: 'node.js' })
372
+
373
+ // Mock dependencies
374
+ sandbox.stub(uut.adapters.ipfs, 'getPeers').resolves([{ peer: 'badId' }])
375
+ const spy1 = sandbox
376
+ .stub(uut.adapters.ipfs, 'disconnectFromPeer')
377
+ .resolves()
378
+
379
+ const result = await uut.enforceWhitelist()
380
+
381
+ // Assert that the method completed.
382
+ assert.equal(result, true)
383
+
384
+ // Assert that disconnectFromPeer() was called.
385
+ assert.equal(spy1.called, true)
386
+ })
387
+
388
+ it('should skip ipfs-coord peers', async () => {
389
+ await uut.createSelf({ type: 'node.js' })
390
+ uut.thisNode.peerData = [
391
+ {
392
+ from: 'goodId',
393
+ data: {
394
+ jsonLd: {
395
+ name: 'good-name'
396
+ }
397
+ }
398
+ }
399
+ ]
400
+
401
+ // Mock dependencies
402
+ sandbox.stub(uut.adapters.ipfs, 'getPeers').resolves([{ peer: 'goodId' }])
403
+ const spy1 = sandbox
404
+ .stub(uut.adapters.ipfs, 'disconnectFromPeer')
405
+ .resolves()
406
+
407
+ const result = await uut.enforceWhitelist()
408
+
409
+ // Assert that the method completed.
410
+ assert.equal(result, true)
411
+
412
+ // Assert that disconnectFromPeer() was not called.
413
+ assert.equal(spy1.called, false)
414
+ })
415
+
416
+ it('should catch and throw errors', async () => {
417
+ try {
418
+ await uut.enforceWhitelist()
419
+
420
+ assert.fail('Unexpected code path')
421
+ } catch (err) {
422
+ // console.log(err)
423
+ assert.include(err.message, 'Cannot read')
424
+ }
425
+ })
426
+ })
427
+ })
@@ -0,0 +1,47 @@
1
+ /*
2
+ Unit tests for Use Cases index.js file
3
+ */
4
+
5
+ // npm libraries
6
+ import { assert } from 'chai'
7
+
8
+ // Local libraries
9
+ import UseCases from '../../../lib/use-cases/index.js'
10
+
11
+ describe('#Use-Cases-index.js', () => {
12
+ let uut
13
+
14
+ describe('#constructor', () => {
15
+ it('should throw an error if adapters is not included', () => {
16
+ try {
17
+ uut = new UseCases()
18
+
19
+ assert.fail('Unexpected code path')
20
+ } catch (err) {
21
+ assert.include(
22
+ err.message,
23
+ 'Must inject instance of adapters when instantiating Use Cases library.'
24
+ )
25
+ }
26
+ })
27
+
28
+ // it('should throw an error if controllers are not included', () => {
29
+ // try {
30
+ // uut = new UseCases({ adapters: {} })
31
+ //
32
+ // assert.fail('Unexpected code path')
33
+ // } catch (err) {
34
+ // assert.include(
35
+ // err.message,
36
+ // 'Must inject instance of controllers when instantiating Use Cases library.'
37
+ // )
38
+ // }
39
+ // })
40
+
41
+ it('should instantiate the use cases library', () => {
42
+ uut = new UseCases({ adapters: {}, statusLog: {} })
43
+
44
+ assert.property(uut, 'adapters')
45
+ })
46
+ })
47
+ })
@@ -0,0 +1,31 @@
1
+ /*
2
+ */
3
+
4
+ // Global npm libraries
5
+ import { assert } from 'chai'
6
+ import sinon from 'sinon'
7
+
8
+ // Local libraries
9
+ import Util from '../../../lib/util/utils.js'
10
+
11
+ describe('#utils.js', () => {
12
+ let sandbox
13
+ let uut // Unit Under Test
14
+
15
+ beforeEach(async () => {
16
+ // Restore the sandbox before each test.
17
+ sandbox = sinon.createSandbox()
18
+
19
+ uut = new Util()
20
+ })
21
+
22
+ afterEach(() => sandbox.restore())
23
+
24
+ describe('#sleep', () => {
25
+ it('should sleep for 1 ms', async () => {
26
+ await uut.sleep(1)
27
+
28
+ assert.isOk(true)
29
+ })
30
+ })
31
+ })