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,367 @@
1
+ /*
2
+ Unit tests for pubsub-adapter.js library.
3
+ */
4
+
5
+ // npm libraries
6
+ import { assert } from 'chai'
7
+ import sinon from 'sinon'
8
+ import SlpWallet from 'minimal-slp-wallet'
9
+ import cloneDeep from 'lodash.clonedeep'
10
+
11
+ // local libraries
12
+ import Pubsub from '../../../../lib/adapters/pubsub-adapter/index.js'
13
+ import ipfsLib from '../../../mocks/ipfs-mock.js'
14
+ import mockDataLib from '../../../mocks/pubsub-mocks.js'
15
+ import IPFSAdapter from '../../../../lib/adapters/ipfs-adapter.js'
16
+ import thisNodeMock from '../../../mocks/thisnode-mocks.js'
17
+ import EncryptionAdapter from '../../../../lib/adapters/encryption-adapter.js'
18
+ import BchAdapter from '../../../../lib/adapters/bch-adapter.js'
19
+ import { BroadcastRouter, PrivateChannelRouter } from '../../../../lib/adapters/pubsub-adapter/msg-router.js'
20
+
21
+ describe('#Adapter - Pubsub', () => {
22
+ let sandbox
23
+ let uut
24
+ let ipfs, ipfsAdapter, encryption
25
+ let thisNode
26
+ let mockData
27
+
28
+ const log = {
29
+ statusLog: () => {
30
+ }
31
+ }
32
+
33
+ beforeEach(async () => {
34
+ // Restore the sandbox before each test.
35
+ sandbox = sinon.createSandbox()
36
+
37
+ ipfs = cloneDeep(ipfsLib)
38
+ thisNode = cloneDeep(thisNodeMock)
39
+ mockData = cloneDeep(mockDataLib)
40
+
41
+ // Instantiate the IPFS adapter
42
+ ipfsAdapter = new IPFSAdapter({ ipfs, log })
43
+
44
+ // Instantiate the Encryption adapater
45
+ const wallet = new SlpWallet()
46
+ await wallet.walletInfoPromise
47
+ const bch = new BchAdapter({ wallet })
48
+ encryption = new EncryptionAdapter({ bch })
49
+
50
+ // Instantiate the library under test. Must instantiate dependencies first.
51
+ uut = new Pubsub({ ipfsAdapter, log, encryption, privateLog: {} })
52
+ })
53
+
54
+ afterEach(() => sandbox.restore())
55
+
56
+ describe('#constructor', () => {
57
+ it('should throw an error if IPFS adapter not specified', () => {
58
+ try {
59
+ uut = new Pubsub()
60
+
61
+ assert.fail('Unexpected result')
62
+ } catch (err) {
63
+ assert.include(
64
+ err.message,
65
+ 'Instance of IPFS adapter required when instantiating Pubsub Adapter.'
66
+ )
67
+ }
68
+ })
69
+
70
+ it('should throw an error if status log handler not specified', () => {
71
+ try {
72
+ uut = new Pubsub({ ipfsAdapter })
73
+
74
+ assert.fail('Unexpected result')
75
+ } catch (err) {
76
+ assert.include(
77
+ err.message,
78
+ 'A status log handler function required when instantitating Pubsub Adapter'
79
+ )
80
+ }
81
+ })
82
+
83
+ it('should throw an error if encryption library is not included', () => {
84
+ try {
85
+ uut = new Pubsub({ ipfsAdapter, log })
86
+
87
+ assert.fail('Unexpected result')
88
+ } catch (err) {
89
+ assert.include(
90
+ err.message,
91
+ 'An instance of the encryption Adapter must be passed when instantiating the Pubsub Adapter library.'
92
+ )
93
+ }
94
+ })
95
+
96
+ it('should throw an error if privateLog is not included', () => {
97
+ try {
98
+ uut = new Pubsub({ ipfsAdapter, log, encryption })
99
+
100
+ assert.fail('Unexpected result')
101
+ } catch (err) {
102
+ assert.include(
103
+ err.message,
104
+ 'A private log handler must be passed when instantiating the Pubsub Adapter library.'
105
+ )
106
+ }
107
+ })
108
+ })
109
+
110
+ describe('#parsePubsubMessage', () => {
111
+ it('should parse a pubsub message', async () => {
112
+ const handler = () => {}
113
+
114
+ const result = await uut.parsePubsubMessage(mockData.mockMsg, handler, thisNode)
115
+
116
+ // assert.equal(true, true, 'Not throwing an error is a pass')
117
+ assert.equal(result, true)
118
+ })
119
+
120
+ it('should quietly exit if message is from thisNode', async () => {
121
+ const handler = () => {
122
+ }
123
+
124
+ mockData.mockMsg.from = '12D3KooWE6tkdArVpCHG9QN61G1cE7eCq2Q7i4bNx6CJFTDprk9f'
125
+
126
+ const result = await uut.parsePubsubMessage(mockData.mockMsg, handler, thisNode)
127
+
128
+ // assert.equal(true, true, 'Not throwing an error is a pass')
129
+ assert.equal(result, true)
130
+ })
131
+
132
+ // This is a top-level function. It should not throw errors, but log
133
+ // the error message.
134
+ it('should catch and handle errors', async () => {
135
+ const result = await uut.parsePubsubMessage()
136
+
137
+ // assert.isOk(true, 'Not throwing an error is a pass')
138
+ assert.equal(result, false)
139
+ })
140
+
141
+ it('should parse a message for an external IPFS node', async () => {
142
+ const handler = () => {
143
+ }
144
+
145
+ uut.nodeType = 'external'
146
+
147
+ const result = await uut.parsePubsubMessage(mockData.mockMsg, handler, thisNode)
148
+
149
+ // assert.equal(true, true, 'Not throwing an error is a pass')
150
+ assert.equal(result, true)
151
+ })
152
+
153
+ it('should throw an error if data can not be parsd', async () => {
154
+ const handler = () => {}
155
+
156
+ // Force desired code path
157
+ mockData.mockMsg.data = Buffer.from('54234', 'hex')
158
+
159
+ const result = await uut.parsePubsubMessage(mockData.mockMsg, handler, thisNode)
160
+ // console.log('result: ', result)
161
+
162
+ assert.equal(result, false)
163
+ })
164
+ })
165
+
166
+ describe('#captureMetrics', () => {
167
+ it('should capture an about REQUEST', async () => {
168
+ // Mock dependencies
169
+ sandbox.stub(uut.encryption, 'encryptMsg').resolves('encrypted-payload')
170
+ sandbox.stub(uut.messaging, 'sendMsg').resolves()
171
+
172
+ const decryptedStr = mockData.aboutRequest
173
+ const from = 'fake-id'
174
+
175
+ const result = await uut.captureMetrics(decryptedStr, from, thisNode)
176
+ // console.log(result)
177
+
178
+ assert.equal(result, true)
179
+ })
180
+
181
+ it('should capture an about RESPONSE', async () => {
182
+ const decryptedStr = mockData.aboutResponse
183
+ const from = 'fake-id'
184
+
185
+ const result = await uut.captureMetrics(decryptedStr, from, thisNode)
186
+ // console.log(result)
187
+
188
+ // Should return the decrypted response data.
189
+ assert.property(result, 'ipfsId')
190
+ })
191
+
192
+ it('should return false for message not an /about request or response', async () => {
193
+ const decryptedStr = mockData.badId
194
+ const from = 'fake-id'
195
+
196
+ const result = await uut.captureMetrics(decryptedStr, from, thisNode)
197
+ // console.log(result)
198
+
199
+ assert.equal(result, false)
200
+ })
201
+
202
+ it('should return false on an error', async () => {
203
+ const result = await uut.captureMetrics()
204
+ // console.log(result)
205
+
206
+ assert.equal(result, false)
207
+ })
208
+ })
209
+
210
+ describe('#handleNewMessage', () => {
211
+ it('should return false if incoming message is an /about request or response', async () => {
212
+ // Mock dependencies
213
+ sandbox.stub(uut, 'captureMetrics').resolves(true)
214
+
215
+ const result = await uut.handleNewMessage(mockData.msgObj, thisNode)
216
+ // console.log(result)
217
+
218
+ assert.equal(result, false)
219
+ })
220
+
221
+ it('return true if incoming message is NOT an /about request or response', async () => {
222
+ // Mock dependencies
223
+ sandbox.stub(uut, 'captureMetrics').resolves(false)
224
+ uut.privateLog = () => {
225
+ }
226
+
227
+ const result = await uut.handleNewMessage(mockData.msgObj, thisNode)
228
+ // console.log(result)
229
+
230
+ assert.equal(result, true)
231
+ })
232
+
233
+ it('should catch and throw errors', async () => {
234
+ try {
235
+ await uut.handleNewMessage()
236
+
237
+ assert.fail('Unexpected result')
238
+ } catch (err) {
239
+ // console.log(err)
240
+ assert.include(
241
+ err.message,
242
+ 'Cannot read'
243
+ )
244
+ }
245
+ })
246
+ })
247
+
248
+ describe('#subscribeToPubsubChannel', () => {
249
+ // This tests the ability to subscribe to general broadcast channels like
250
+ // the psf-ipfs-coordination-002 channel.
251
+ it('should subscribe to a broadcast pubsub channel', async () => {
252
+ // Mock dependencies
253
+ sandbox.stub(uut.ipfs.ipfs.pubsub, 'subscribe').resolves()
254
+
255
+ const chanName = 'test'
256
+ const handler = () => {
257
+ }
258
+
259
+ const result = await uut.subscribeToPubsubChannel(chanName, handler, thisNode)
260
+
261
+ // assert.equal(true, true, 'Not throwing an error is a pass')
262
+ assert.equal(result, true)
263
+ })
264
+
265
+ // This tests the ability to subscribe to private, encrypted channels, like
266
+ // the one this node uses to receive messages from other nodes.
267
+ it('should subscribe to a private pubsub channel', async () => {
268
+ // Mock dependencies
269
+ sandbox.stub(uut.ipfs.ipfs.pubsub, 'subscribe').resolves()
270
+
271
+ const chanName = thisNode.ipfsId
272
+ const handler = () => {
273
+ }
274
+
275
+ const result = await uut.subscribeToPubsubChannel(chanName, handler, thisNode)
276
+
277
+ // assert.equal(true, true, 'Not throwing an error is a pass')
278
+ assert.equal(result, true)
279
+ })
280
+
281
+ it('should catch and throw errors', async () => {
282
+ try {
283
+ await uut.subscribeToPubsubChannel()
284
+
285
+ assert.fail('Unexpected code path')
286
+ } catch (err) {
287
+ // console.log('err: ', err)
288
+ assert.include(err.message, 'Cannot read')
289
+ }
290
+ })
291
+ })
292
+
293
+ describe('#BroadcastRouter', () => {
294
+ it('should route a broadcast message and return true', async () => {
295
+ // Mock dependencies
296
+ // sandbox.stub(uut.ipfs.ipfs.pubsub, 'subscribe').resolves()
297
+
298
+ // const chanName = 'test'
299
+ const handler = () => {}
300
+ const parsePubsubMessage = async () => {}
301
+
302
+ // Instantiate the Broadcast message router library
303
+ const bRouterOptions = {
304
+ handler,
305
+ thisNode,
306
+ parsePubsubMessage
307
+ }
308
+ const broadcastRouter = new BroadcastRouter(bRouterOptions)
309
+
310
+ const result = await broadcastRouter.route({})
311
+
312
+ assert.equal(result, true)
313
+ })
314
+
315
+ it('should catch and handle errors, and return false', async () => {
316
+ // Force and error
317
+ const handler = () => {}
318
+ const parsePubsubMessage = async () => {
319
+ throw new Error('test error')
320
+ }
321
+
322
+ // Instantiate the Broadcast message router library
323
+ const bRouterOptions = {
324
+ handler,
325
+ thisNode,
326
+ parsePubsubMessage
327
+ }
328
+ const broadcastRouter = new BroadcastRouter(bRouterOptions)
329
+
330
+ const result = await broadcastRouter.route({})
331
+
332
+ assert.equal(result, false)
333
+ })
334
+ })
335
+
336
+ describe('#PrivateChannelRouter', () => {
337
+ it('should route a private message and return true', async () => {
338
+ // Instantiate the Broadcast message router library
339
+ const pRouterOptions = {
340
+ thisNode,
341
+ messaging: uut.messaging,
342
+ handleNewMessage: async () => {}
343
+ }
344
+ const privateRouter = new PrivateChannelRouter(pRouterOptions)
345
+
346
+ const result = await privateRouter.route({})
347
+
348
+ assert.equal(result, true)
349
+ })
350
+
351
+ it('should catch and handle errors, and return false', async () => {
352
+ sandbox.stub(uut.messaging, 'handleIncomingData').resolves({})
353
+
354
+ // Instantiate the Private message router library
355
+ const pRouterOptions = {
356
+ thisNode,
357
+ messaging: uut.messaging,
358
+ handleNewMessage: async () => { throw new Error('test error') }
359
+ }
360
+ const privateRouter = new PrivateChannelRouter(pRouterOptions)
361
+
362
+ const result = await privateRouter.route({})
363
+
364
+ assert.equal(result, false)
365
+ })
366
+ })
367
+ })
@@ -0,0 +1,58 @@
1
+ /*
2
+ Unit tests for the about adapter library.
3
+ */
4
+
5
+ // npm libraries
6
+ import { assert } from 'chai'
7
+ import sinon from 'sinon'
8
+ import cloneDeep from 'lodash.clonedeep'
9
+
10
+ // local libraries
11
+ import ResendMsg from '../../../../lib/adapters/pubsub-adapter/resend-msg.js'
12
+ import ipfsLib from '../../../mocks/ipfs-mock.js'
13
+ import IPFSAdapter from '../../../../lib/adapters/ipfs-adapter.js'
14
+ import SlpWallet from 'minimal-slp-wallet'
15
+ import BchAdapter from '../../../../lib/adapters/bch-adapter.js'
16
+ import EncryptionAdapter from '../../../../lib/adapters/encryption-adapter.js'
17
+ import Messaging from '../../../../lib/adapters/pubsub-adapter/messaging.js'
18
+
19
+ describe('#ResendMsg-adapter', () => {
20
+ let uut
21
+ let sandbox
22
+ let ipfs, ipfsAdapter
23
+
24
+ const log = {
25
+ statusLog: () => {}
26
+ }
27
+
28
+ beforeEach(async () => {
29
+ // Restore the sandbox before each test.
30
+ sandbox = sinon.createSandbox()
31
+
32
+ // Instantiate the IPFS adapter
33
+ ipfs = cloneDeep(ipfsLib)
34
+ ipfsAdapter = new IPFSAdapter({ ipfs, log })
35
+
36
+ // Instantiate the Encryption adapater
37
+ const wallet = new SlpWallet()
38
+ await wallet.walletInfoPromise
39
+ const bch = new BchAdapter({ wallet })
40
+ const encryption = new EncryptionAdapter({ bch })
41
+
42
+ const msgLib = new Messaging({ ipfsAdapter, log, encryption })
43
+ const msgObj = false
44
+
45
+ // Instantiate the library under test. Must instantiate dependencies first.
46
+ uut = new ResendMsg({ msgObj, msgLib })
47
+ })
48
+
49
+ afterEach(() => sandbox.restore())
50
+
51
+ describe('#resend', () => {
52
+ it('should return 0 if message object is empty', async () => {
53
+ const result = await uut.resend()
54
+
55
+ assert.equal(result, 0)
56
+ })
57
+ })
58
+ })
@@ -0,0 +1,30 @@
1
+ /*
2
+ Unit tests for the main Controllers index.js file.
3
+ */
4
+
5
+ // npm libraries
6
+ import { assert } from 'chai'
7
+
8
+ // Local libraries
9
+ import Controllers from '../../../lib/controllers/index.js'
10
+
11
+ describe('#index.js-Controllers', () => {
12
+ let uut
13
+
14
+ describe('#constructor', () => {
15
+ it('should throw an error if adapters is not included', () => {
16
+ try {
17
+ uut = new Controllers()
18
+
19
+ assert.fail('Unexpected code path')
20
+
21
+ console.log(uut)
22
+ } catch (err) {
23
+ assert.include(
24
+ err.message,
25
+ 'Instance of adapters required when instantiating Controllers'
26
+ )
27
+ }
28
+ })
29
+ })
30
+ })