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,658 @@
1
+ /*
2
+ Unit tests for the Circuit Relays use case.
3
+ */
4
+
5
+ // npm libraries
6
+ import { assert } from 'chai'
7
+ import sinon from 'sinon'
8
+
9
+ // Local libraries
10
+ import RelayUseCases from '../../../lib/use-cases/relay-use-cases.js'
11
+ import ThisNodeUseCases from '../../../lib/use-cases/this-node-use-cases.js'
12
+ import AdapterMock from '../../mocks/adapter-mock.js'
13
+ import mockData from '../../mocks/peers-mock.js'
14
+ import relayMockData from '../../mocks/circuit-relay-mocks.js'
15
+
16
+ const adapters = new AdapterMock()
17
+
18
+ describe('#relay-Use-Cases', () => {
19
+ let uut
20
+ let sandbox
21
+ let thisNode
22
+
23
+ beforeEach(async () => {
24
+ // Restore the sandbox before each test.
25
+ sandbox = sinon.createSandbox()
26
+
27
+ const thisNodeUseCases = new ThisNodeUseCases({
28
+ adapters,
29
+ statusLog: () => {
30
+ }
31
+ })
32
+ thisNode = await thisNodeUseCases.createSelf({ type: 'node.js' })
33
+
34
+ uut = new RelayUseCases({
35
+ adapters,
36
+ statusLog: () => {
37
+ }
38
+ })
39
+ })
40
+
41
+ afterEach(() => sandbox.restore())
42
+
43
+ describe('#constructor', () => {
44
+ it('should throw an error if adapters is not included', () => {
45
+ try {
46
+ uut = new RelayUseCases()
47
+
48
+ assert.fail('Unexpected code path')
49
+ } catch (err) {
50
+ assert.include(
51
+ err.message,
52
+ 'Must inject instance of adapters when instantiating Relay Use Cases library.'
53
+ )
54
+ }
55
+ })
56
+ })
57
+
58
+ describe('#initializeRelays', () => {
59
+ it('should initialize the node.js circuit relays', async () => {
60
+ const result = await uut.initializeRelays(thisNode)
61
+
62
+ // assert.isOk(true, 'Not throwing an error is a pass')
63
+ assert.equal(result, true)
64
+ })
65
+
66
+ it('should initialize the browser circuit relays', async () => {
67
+ thisNode.type = 'browser'
68
+
69
+ const result = await uut.initializeRelays(thisNode)
70
+
71
+ // assert.isOk(true, 'Not throwing an error is a pass')
72
+ assert.equal(result, true)
73
+ })
74
+
75
+ it('should catch and throw an error', async () => {
76
+ try {
77
+ // Force an error
78
+ sandbox
79
+ .stub(uut.adapters.ipfs, 'connectToPeer')
80
+ .rejects(new Error('test error'))
81
+
82
+ await uut.initializeRelays(thisNode)
83
+
84
+ assert.fail('Unexpected code path')
85
+ } catch (err) {
86
+ // console.log(err)
87
+ assert.include(err.message, 'test error')
88
+ }
89
+ })
90
+ })
91
+
92
+ describe('#getCRGist', () => {
93
+ it('should load list from GitHub and connect to node.js circuit relays', async () => {
94
+ // Mock dependencies
95
+ const data = {
96
+ browser: [],
97
+ node: [{
98
+ ipfsId: '123'
99
+ }]
100
+ }
101
+ sandbox.stub(uut.adapters.gist, 'getCRList').resolves(data)
102
+ sandbox.stub(uut, 'removeDuplicates').resolves()
103
+
104
+ const result = await uut.getCRGist(thisNode)
105
+
106
+ assert.equal(result, true)
107
+ })
108
+
109
+ it('should load list from GitHub and connect to browser circuit relays', async () => {
110
+ thisNode.type = 'browser'
111
+
112
+ // Force desired code path.
113
+ thisNode.relayData.push({
114
+ ipfsId: 'fake-id'
115
+ })
116
+
117
+ // Mock dependencies
118
+ const data = {
119
+ browser: [{
120
+ ipfsId: 'fake-id'
121
+ }],
122
+ node: []
123
+ }
124
+ sandbox.stub(uut.adapters.gist, 'getCRList').resolves(data)
125
+ sandbox.stub(uut, 'removeDuplicates').resolves()
126
+
127
+ const result = await uut.getCRGist(thisNode)
128
+
129
+ assert.equal(result, true)
130
+ })
131
+
132
+ it('should catch and throw errors', async () => {
133
+ try {
134
+ // Force desired code path.
135
+ sandbox.stub(uut.adapters.gist, 'getCRList').rejects(new Error('test error'))
136
+
137
+ await uut.getCRGist()
138
+
139
+ assert.fail('Unexpected result')
140
+ } catch (err) {
141
+ assert.include(err.message, 'test error')
142
+ }
143
+ })
144
+ })
145
+
146
+ describe('#connectToCRs', () => {
147
+ it('should connect to array of circuit relays', async () => {
148
+ await uut.connectToCRs(thisNode)
149
+
150
+ assert.equal(true, true, 'Not throwing an error is a success')
151
+ })
152
+
153
+ it('Should try to connect to circuit relays', async () => {
154
+ // Force circuit relay to be used.
155
+ thisNode.relayData = mockData.mockRelayData
156
+
157
+ // Mock dependencies
158
+ sandbox.stub(uut.adapters.ipfs, 'getPeers').resolves(mockData.swarmPeers)
159
+ sandbox.stub(uut, 'sortRelays').returns(thisNode.relayData)
160
+
161
+ // uut.state.relays = crMockData.circuitRelays
162
+ await uut.connectToCRs(thisNode)
163
+
164
+ assert.equal(true, true, 'Not throwing an error is a success')
165
+ })
166
+
167
+ it('Should skip relays that are already connected', async () => {
168
+ // Force circuit relay to be used.
169
+ thisNode.relayData = mockData.mockRelayData
170
+
171
+ // Force mock ciruit relay to appear as being already connected.
172
+ thisNode.relayData[0].multiaddr = mockData.swarmPeers[0].peer
173
+
174
+ // Mock dependencies
175
+ sandbox.stub(uut.adapters.ipfs, 'getPeers').resolves(mockData.swarmPeers)
176
+ sandbox.stub(uut, 'sortRelays').returns(thisNode.relayData)
177
+
178
+ // uut.state.relays = crMockData.circuitRelays
179
+ await uut.connectToCRs(thisNode)
180
+
181
+ assert.equal(true, true, 'Not throwing an error is a success')
182
+ })
183
+
184
+ it('Should try to connect to circuit relays', async () => {
185
+ // Force circuit relay to be used.
186
+ thisNode.relayData = mockData.mockRelayData
187
+
188
+ // Mock dependencies
189
+ sandbox.stub(uut.adapters.ipfs, 'getPeers').resolves(mockData.swarmPeers2)
190
+ sandbox.stub(uut.adapters.ipfs, 'connectToPeer').resolves(true)
191
+ sandbox.stub(uut, 'sortRelays').returns(thisNode.relayData)
192
+
193
+ // uut.state.relays = crMockData.circuitRelays
194
+ await uut.connectToCRs(thisNode)
195
+
196
+ assert.equal(true, true, 'Not throwing an error is a success')
197
+ })
198
+
199
+ it('should return false when error occurs.', async () => {
200
+ // Force desired code path
201
+ sandbox.stub(uut, 'sortRelays').throws(new Error('test error'))
202
+
203
+ const result = await uut.connectToCRs(thisNode)
204
+
205
+ assert.equal(result, false)
206
+ })
207
+ })
208
+
209
+ describe('#addRelay', () => {
210
+ it('should return true if peer is already in relayData array', async () => {
211
+ // Mock test data
212
+ const ipfsId = 'testId'
213
+ const thisNode = {
214
+ relayData: [{ ipfsId }]
215
+ }
216
+
217
+ const result = await uut.addRelay(ipfsId, thisNode)
218
+
219
+ assert.equal(result, true)
220
+ })
221
+
222
+ it('should connect to a peers multiaddr', async () => {
223
+ // Mock test data
224
+ const ipfsId = 'testId'
225
+ const thisNode = {
226
+ relayData: [],
227
+ peerData: [
228
+ {
229
+ data: {
230
+ ipfsId,
231
+ ipfsMultiaddrs: ['/ip4/addr1'],
232
+ isCircuitRelay: true
233
+ }
234
+ }
235
+ ]
236
+ }
237
+
238
+ // Mock dependencies
239
+ sandbox.stub(uut.adapters.ipfs, 'connectToPeer').resolves(true)
240
+ sandbox
241
+ .stub(uut.adapters.ipfs, 'getPeers')
242
+ .resolves([{ peer: ipfsId, addr: '/ip4/addr1' }])
243
+
244
+ const result = await uut.addRelay(ipfsId, thisNode)
245
+
246
+ // console.log('thisNode: ', thisNode)
247
+
248
+ // Function should return true.
249
+ assert.equal(result, true)
250
+
251
+ // relayData array should be updated
252
+ assert.isArray(thisNode.relayData) // Its an array.
253
+ assert.equal(thisNode.relayData.length, 1) // Should be one element
254
+
255
+ // Assert expected properties of the object.
256
+ assert.property(thisNode.relayData[0], 'multiaddr')
257
+ assert.property(thisNode.relayData[0], 'connected')
258
+ assert.property(thisNode.relayData[0], 'updatedAt')
259
+ assert.property(thisNode.relayData[0], 'ipfsId')
260
+ assert.property(thisNode.relayData[0], 'isBootstrap')
261
+ assert.property(thisNode.relayData[0], 'metrics')
262
+
263
+ // Assert expected values.
264
+ assert.equal(thisNode.relayData[0].multiaddr, '/ip4/addr1/p2p/testId')
265
+ assert.equal(thisNode.relayData[0].connected, true)
266
+ assert.equal(thisNode.relayData[0].ipfsId, 'testId')
267
+ assert.equal(thisNode.relayData[0].isBootstrap, false)
268
+ assert.isArray(thisNode.relayData[0].metrics.aboutLatency)
269
+ })
270
+
271
+ it('should return false if thisNode can not connect to peer', async () => {
272
+ // Mock test data
273
+ const ipfsId = 'testId'
274
+ const thisNode = {
275
+ relayData: [],
276
+ peerData: [
277
+ {
278
+ data: {
279
+ ipfsId,
280
+ ipfsMultiaddrs: ['addr1']
281
+ }
282
+ }
283
+ ]
284
+ }
285
+
286
+ // Mock dependencies
287
+ sandbox.stub(uut.adapters.ipfs, 'connectToPeer').resolves(false)
288
+
289
+ const result = await uut.addRelay(ipfsId, thisNode)
290
+
291
+ assert.equal(result, false)
292
+ })
293
+
294
+ it('should not connect to peer with p2p-circuit in multiaddr', async () => {
295
+ // Mock test data
296
+ const ipfsId = 'testId'
297
+ const thisNode = {
298
+ relayData: [],
299
+ peerData: [
300
+ {
301
+ data: {
302
+ ipfsId,
303
+ ipfsMultiaddrs: ['addr1/p2p-circuit/addr2']
304
+ }
305
+ }
306
+ ]
307
+ }
308
+
309
+ // Mock dependencies
310
+ sandbox.stub(uut.adapters.ipfs, 'connectToPeer').resolves(true)
311
+ sandbox.stub(uut.adapters.ipfs, 'disconnectFromPeer').resolves()
312
+ sandbox
313
+ .stub(uut.adapters.ipfs, 'getPeers')
314
+ .resolves([{ peer: ipfsId, addr: 'addr1/p2p-circuit/addr2' }])
315
+
316
+ const result = await uut.addRelay(ipfsId, thisNode)
317
+
318
+ assert.equal(result, false)
319
+ })
320
+
321
+ it('should return false on error', async () => {
322
+ const result = await uut.addRelay()
323
+
324
+ assert.equal(result, false)
325
+ })
326
+
327
+ it('should skip multiaddrs with anti-patterns', async () => {
328
+ // Mock test data
329
+ const ipfsId = 'testId'
330
+ const thisNode = {
331
+ relayData: [],
332
+ peerData: [
333
+ {
334
+ data: {
335
+ ipfsId,
336
+ ipfsMultiaddrs: ['/ip4/addr1'],
337
+ isCircuitRelay: true
338
+ }
339
+ }
340
+ ]
341
+ }
342
+
343
+ // Mock dependencies
344
+ sandbox.stub(uut.adapters.ipfs, 'connectToPeer').resolves(true)
345
+ sandbox
346
+ .stub(uut.adapters.ipfs, 'getPeers')
347
+ .resolves([{ peer: ipfsId, addr: '/p2p-circuit' }])
348
+
349
+ const result = await uut.addRelay(ipfsId, thisNode)
350
+
351
+ // console.log(`thisNode: ${JSON.stringify(thisNode, null, 2)}`)
352
+
353
+ // Function should return false.
354
+ assert.equal(result, false)
355
+ })
356
+
357
+ it('should not connect to peer with p2p-circuit in multiaddr', async () => {
358
+ // Mock test data
359
+ const ipfsId = 'testId'
360
+ const thisNode = {
361
+ relayData: [],
362
+ peerData: [
363
+ {
364
+ data: {
365
+ ipfsId,
366
+ ipfsMultiaddrs: ['addr1/p2p-circuit/addr2']
367
+ }
368
+ }
369
+ ]
370
+ }
371
+
372
+ // Mock dependencies
373
+ sandbox.stub(uut.adapters.ipfs, 'connectToPeer').resolves(true)
374
+ sandbox.stub(uut.adapters.ipfs, 'disconnectFromPeer').resolves()
375
+ sandbox
376
+ .stub(uut.adapters.ipfs, 'getPeers')
377
+ .resolves([{ peer: ipfsId, addr: 'addr1/p2p-circuit/addr2' }])
378
+
379
+ const result = await uut.addRelay(ipfsId, thisNode)
380
+
381
+ assert.equal(result, false)
382
+ })
383
+
384
+ it('should report connection failure and return false', async () => {
385
+ // Mock test data
386
+ const ipfsId = 'testId'
387
+ const thisNode = {
388
+ relayData: [],
389
+ peerData: [
390
+ {
391
+ data: {
392
+ ipfsId,
393
+ ipfsMultiaddrs: ['/ip4/addr1'],
394
+ isCircuitRelay: true
395
+ }
396
+ }
397
+ ]
398
+ }
399
+
400
+ // Force desired code path.
401
+ sandbox.stub(uut.adapters.ipfs, 'connectToPeer').resolves(false)
402
+
403
+ const result = await uut.addRelay(ipfsId, thisNode)
404
+
405
+ // console.log('thisNode: ', thisNode)
406
+
407
+ // Function should return true.
408
+ assert.equal(result, false)
409
+ })
410
+
411
+ it('should detect and add optional connection data to multiaddr', async () => {
412
+ // Mock test data
413
+ const ipfsId = 'testId'
414
+ const thisNode = {
415
+ relayData: [],
416
+ peerData: [
417
+ {
418
+ data: {
419
+ ipfsId,
420
+ ipfsMultiaddrs: ['/ip4/addr1'],
421
+ isCircuitRelay: true,
422
+ circuitRelayInfo: {
423
+ ip4: '555.555.555.555',
424
+ crDomain: '666.666.666.666'
425
+ }
426
+ }
427
+ }
428
+ ]
429
+ }
430
+
431
+ // Mock dependencies
432
+ sandbox.stub(uut.adapters.ipfs, 'connectToPeer').resolves(true)
433
+ sandbox
434
+ .stub(uut.adapters.ipfs, 'getPeers')
435
+ .resolves([{ peer: ipfsId, addr: '/ip4/addr1' }])
436
+
437
+ const result = await uut.addRelay(ipfsId, thisNode)
438
+
439
+ // console.log(`thisNode: ${JSON.stringify(thisNode, null, 2)}`)
440
+
441
+ // Function should return true.
442
+ assert.equal(result, true)
443
+
444
+ // Assert the expected circuit relay multiaddrs have been added.
445
+ const ip4Exists = thisNode.peerData[0].data.ipfsMultiaddrs.filter(x => x.includes('555.555'))
446
+ assert.equal(ip4Exists.length, 1)
447
+ const dnsExists = thisNode.peerData[0].data.ipfsMultiaddrs.filter(x => x.includes('666.666'))
448
+ assert.equal(dnsExists.length, 1)
449
+ })
450
+ })
451
+
452
+ describe('#measureRelays', () => {
453
+ it('should catch and throw errors', async () => {
454
+ try {
455
+ await uut.measureRelays()
456
+
457
+ assert.fail('Unexpected code path')
458
+ } catch (err) {
459
+ // console.log(err)
460
+ assert.include(err.message, 'Cannot read')
461
+ }
462
+ })
463
+
464
+ it('should skip bootstrap relays', async () => {
465
+ // Mock test data
466
+ const thisNode = {
467
+ relayData: [
468
+ {
469
+ isBootstrap: true,
470
+ metrics: {
471
+ aboutLatency: []
472
+ }
473
+ }
474
+ ],
475
+ peerData: []
476
+ }
477
+
478
+ await uut.measureRelays(thisNode)
479
+ // console.log('thisNode: ', thisNode)
480
+
481
+ // Assert that the latecy metrics are unchanged.
482
+ assert.equal(thisNode.relayData[0].metrics.aboutLatency.length, 0)
483
+ })
484
+
485
+ it('should give disconnected relays the worst latency score', async () => {
486
+ // Mock test data
487
+ const thisNode = {
488
+ relayData: [
489
+ {
490
+ ipfsId: 'testId',
491
+ isBootstrap: false,
492
+ connected: false,
493
+ metrics: {
494
+ aboutLatency: []
495
+ }
496
+ }
497
+ ],
498
+ peerData: [
499
+ {
500
+ data: {
501
+ ipfsId: 'testId',
502
+ isCircuitRelay: true
503
+ }
504
+ }
505
+ ]
506
+ }
507
+
508
+ await uut.measureRelays(thisNode)
509
+ // console.log('thisNode: ', thisNode)
510
+
511
+ assert.equal(thisNode.relayData[0].metrics.aboutLatency[0], 10000)
512
+ })
513
+
514
+ it('should score the latency of a relay peer', async () => {
515
+ // Mock test data
516
+ const thisNode = {
517
+ relayData: [
518
+ {
519
+ ipfsId: 'testId',
520
+ isBootstrap: false,
521
+ connected: true,
522
+ metrics: {
523
+ aboutLatency: []
524
+ }
525
+ }
526
+ ],
527
+ peerData: [
528
+ {
529
+ data: {
530
+ ipfsId: 'testId',
531
+ isCircuitRelay: true
532
+ }
533
+ }
534
+ ]
535
+ }
536
+
537
+ // Mock dependencies
538
+ sandbox.stub(uut.adapters.bch.bchjs.Util, 'sleep').resolves()
539
+ sandbox.stub(uut.adapters.pubsub.about, 'queryAbout').resolves(true)
540
+
541
+ await uut.measureRelays(thisNode)
542
+ // console.log(
543
+ // 'thisNode.relayData[0].metrics.aboutLatency: ',
544
+ // thisNode.relayData[0].metrics.aboutLatency
545
+ // )
546
+
547
+ assert.isNumber(thisNode.relayData[0].metrics.aboutLatency[0])
548
+ })
549
+
550
+ it('should replace oldest data with new data', async () => {
551
+ // Mock test data
552
+ const thisNode = {
553
+ relayData: [
554
+ {
555
+ ipfsId: 'testId',
556
+ isBootstrap: false,
557
+ connected: true,
558
+ metrics: {
559
+ aboutLatency: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
560
+ }
561
+ }
562
+ ],
563
+ peerData: [
564
+ {
565
+ data: {
566
+ ipfsId: 'testId',
567
+ isCircuitRelay: true
568
+ }
569
+ }
570
+ ]
571
+ }
572
+
573
+ // Mock dependencies
574
+ sandbox.stub(uut.adapters.bch.bchjs.Util, 'sleep').resolves()
575
+
576
+ await uut.measureRelays(thisNode)
577
+ // console.log(
578
+ // 'thisNode.relayData[0].metrics.aboutLatency: ',
579
+ // thisNode.relayData[0].metrics.aboutLatency
580
+ // )
581
+
582
+ // First element of '1' should have been shifted out and replaced by '2'
583
+ assert.equal(thisNode.relayData[0].metrics.aboutLatency[0], 2)
584
+ })
585
+ })
586
+
587
+ describe('#sortRelays', () => {
588
+ it('should sort an array of relay data', () => {
589
+ const relayData = [
590
+ { metrics: { aboutLatency: [5, 6, 7] } },
591
+ { metrics: { aboutLatency: [7, 8, 9] } },
592
+ { metrics: { aboutLatency: [6, 7, 8] } }
593
+ ]
594
+
595
+ const result = uut.sortRelays(relayData)
596
+ // console.log('result: ', result)
597
+
598
+ assert.equal(result[0].latencyScore, 6)
599
+ assert.equal(result[2].latencyScore, 8)
600
+ })
601
+
602
+ it('should give highest score to Boostrap nodes', () => {
603
+ const relayData = [{ isBootstrap: true }]
604
+
605
+ const result = uut.sortRelays(relayData)
606
+ // console.log('result: ', result)
607
+
608
+ assert.equal(result[0].latencyScore, 10000)
609
+ })
610
+
611
+ it('should give highest score to empty metrics array', () => {
612
+ const relayData = [{ metrics: { aboutLatency: [] } }]
613
+
614
+ const result = uut.sortRelays(relayData)
615
+ // console.log('result: ', result)
616
+
617
+ assert.equal(result[0].latencyScore, 10000)
618
+ })
619
+
620
+ it('should catch and throw errors', () => {
621
+ try {
622
+ uut.sortRelays()
623
+
624
+ assert.fail('Unexpected code path')
625
+ } catch (err) {
626
+ // console.log(err)
627
+ assert.include(err.message, 'Cannot read')
628
+ }
629
+ })
630
+ })
631
+
632
+ describe('#removeDuplicates', () => {
633
+ it('should remove duplicate entries', () => {
634
+ // Mock test data
635
+ const thisNode = {
636
+ relayData: relayMockData.duplicateRelays
637
+ }
638
+
639
+ const result = uut.removeDuplicates(thisNode)
640
+
641
+ // console.log('thisNode.relayData: ', thisNode.relayData)
642
+
643
+ assert.equal(result, true)
644
+ assert.equal(thisNode.relayData.length, 3)
645
+ })
646
+
647
+ it('should catch and throw errors', () => {
648
+ try {
649
+ uut.removeDuplicates()
650
+
651
+ assert.fail('Unexpected code path')
652
+ } catch (err) {
653
+ // console.log(err)
654
+ assert.include(err.message, 'Cannot read')
655
+ }
656
+ })
657
+ })
658
+ })