UNPKG

45.1 kBtext/coffeescriptView Raw
1_ = require 'lodash'
2shmock = require 'shmock'
3
4ConfigurationGenerator = require '../src/configuration-generator'
5ConfigurationUtilities = require '../src/configuration-utilities'
6
7sampleFlow = require './data/sample-flow.json'
8nodeRegistry = require './data/node-registry'
9
10describe 'ConfigurationGenerator', ->
11 beforeEach ->
12 @meshblu = shmock()
13 @meshblu.post('/search/devices').reply 200, []
14
15 @meshbluJSON =
16 server: 'localhost'
17 host: "this-is-silly-and-probably-broken"
18 port: @meshblu.address().port
19 uuid: 'brave-user'
20 token: 'who-fears-no-breaking-changes'
21
22 beforeEach ->
23 @registry = shmock()
24 @registry.get('/registry').reply 200, nodeRegistry
25 @registryUrl = "http://localhost:#{@registry.address().port}/registry"
26
27 afterEach (done) ->
28 @meshblu.close done
29
30 beforeEach ->
31 @request = get: sinon.stub()
32 @channelConfig =
33 update: sinon.stub()
34 get: sinon.stub()
35
36 describe '->configure', ->
37 beforeEach ->
38 options = {@meshbluJSON, @registryUrl}
39
40 dependencies =
41 request: @request
42 channelConfig: @channelConfig
43
44 @sut = new ConfigurationGenerator options, dependencies
45 sinon.stub @sut, '_generateNonce'
46 sinon.stub @sut, '_generateInstanceId'
47 sinon.stub @sut, '_generateTransactionGroupId'
48 sinon.stub @sut, '_generateFlowMetricId'
49
50 @sut._generateNonce.returns 'i-am-a-nonce'
51
52 describe 'when called', ->
53 beforeEach (done) ->
54 githubConfig = require './data/github-channel.json'
55 @channelConfig.update.yields null
56 @channelConfig.get.withArgs('channel:github').returns githubConfig
57 @sut._generateFlowMetricId.onCall(0).returns '000000-fake-metric-uuid-9999'
58
59 @sut._generateInstanceId.onCall(0).returns 'maybe-the-debug-node'
60 @sut._generateInstanceId.onCall(1).returns 'node-trigger-instance'
61 @sut._generateInstanceId.onCall(2).returns 'node-debug-instance'
62 @sut._generateInstanceId.onCall(3).returns 'node-interval-instance'
63 @sut._generateInstanceId.onCall(4).returns 'node-device-instance'
64 @sut._generateInstanceId.onCall(5).returns 'node-channel-instance'
65 @sut._generateInstanceId.onCall(6).returns 'node-component-unregister-instance'
66 @sut._generateInstanceId.onCall(7).returns 'node-get-key-instance'
67 @sut._generateInstanceId.onCall(8).returns 'node-set-key-instance'
68 @sut._generateInstanceId.onCall(9).returns 'node-flow-metric-instance'
69
70 options =
71 flowData: sampleFlow
72 flowToken: 'some-token'
73 deploymentUuid: 'the-deployment-uuid'
74
75 @sut.configure options, (@error, @flowConfig, @flowStopConfig) => done()
76
77 it 'should call channelConfig.update', ->
78 expect(@channelConfig.update).to.have.been.called
79
80 it 'should return a flow configuration with keys for all the nodes in the flow', ->
81 expect(_.keys @flowConfig).to.contain.deep.members [
82 '8a8da890-55d6-11e5-bd83-1349dc09f6d6'
83 '8e74a6c0-55d6-11e5-bd83-1349dc09f6d6'
84 '2cf457d0-57eb-11e5-99ea-11ac2aafbb8d'
85 'f607eed0-631b-11e5-9887-75e2edd7c9c8'
86 '9d8e9920-663b-11e5-82a3-c3248b467ade'
87 '40842d14-a536-4d07-9174-fc463c53a5a7'
88 '2528d3e8-6993-4184-8049-9c4025a57145'
89 '000000-fake-metric-uuid-9999'
90 'node-trigger-instance'
91 'node-debug-instance'
92 'node-interval-instance'
93 'node-device-instance'
94 'node-channel-instance'
95 'node-component-unregister-instance'
96 'node-flow-metric-instance'
97 'node-get-key-instance'
98 'node-set-key-instance'
99 'engine-data'
100 'engine-debug'
101 'engine-input'
102 'engine-output'
103 'engine-pulse'
104 'router'
105 'engine-start'
106 'engine-stop'
107 'subscribe-devices'
108 ]
109
110 it 'should return a flow configuration with keys for all the nodes in the flow', ->
111 expect(_.keys @flowStopConfig).to.contain.deep.members [
112 '8a8da890-55d6-11e5-bd83-1349dc09f6d6'
113 '8e74a6c0-55d6-11e5-bd83-1349dc09f6d6'
114 '2cf457d0-57eb-11e5-99ea-11ac2aafbb8d'
115 'f607eed0-631b-11e5-9887-75e2edd7c9c8'
116 '9d8e9920-663b-11e5-82a3-c3248b467ade'
117 '40842d14-a536-4d07-9174-fc463c53a5a7'
118 '2528d3e8-6993-4184-8049-9c4025a57145'
119 '000000-fake-metric-uuid-9999'
120 'node-component-unregister-instance'
121 'node-trigger-instance'
122 'node-debug-instance'
123 'node-interval-instance'
124 'node-device-instance'
125 'node-channel-instance'
126 'node-flow-metric-instance'
127 'node-get-key-instance'
128 'node-set-key-instance'
129 'engine-data'
130 'engine-debug'
131 'engine-input'
132 'engine-output'
133 'engine-pulse'
134 'router'
135 'engine-start'
136 'engine-stop'
137 'subscribe-devices'
138 ]
139
140
141 it 'should set the uuid and token of meshblu-output and merge meshbluJSON', ->
142 expect(@flowConfig['engine-output'].config).containSubset
143 uuid: sampleFlow.flowId
144 token: 'some-token'
145 server: 'localhost'
146
147 it 'should set engine-debug', ->
148
149 expect(_.keys(@flowConfig['engine-debug'].config)).contain.members [
150 'node-debug-instance'
151 'node-component-unregister-instance'
152 'node-interval-instance'
153 'node-trigger-instance'
154 'node-device-instance'
155 'node-channel-instance'
156 'node-flow-metric-instance'
157 'node-get-key-instance'
158 'node-set-key-instance'
159 ]
160
161 it 'should set engine-data', ->
162 expect(_.keys(@flowConfig['engine-data'].config)).contain.members [
163 'node-debug-instance'
164 'node-component-unregister-instance'
165 'node-interval-instance'
166 'node-trigger-instance'
167 'node-device-instance'
168 'node-channel-instance'
169 'node-flow-metric-instance'
170 'node-get-key-instance'
171 'node-set-key-instance'
172 ]
173
174 it 'should set engine-pulse', ->
175 expect(_.keys @flowConfig['engine-pulse'].config).contain.members [
176 'node-debug-instance'
177 'node-component-unregister-instance'
178 'node-interval-instance'
179 'node-trigger-instance'
180 'node-device-instance'
181 'node-channel-instance'
182 'node-flow-metric-instance'
183 'node-get-key-instance'
184 'node-set-key-instance'
185 ]
186
187 it 'should set engine-input', ->
188 expect(_.keys @flowConfig['engine-input'].config).contain.members [
189 '37f0a74a-2f17-11e4-9617-a6c5e4d22fb7'
190 '37f0a966-2f17-11e4-9617-a6c5e4d22fb7'
191 'c0e0955e-6ab4-4182-8d56-1c8c35a5106d'
192 ]
193
194 it 'should set subscribe-devices', ->
195 expect(@flowConfig['subscribe-devices'].config).containSubset
196 'broadcast.sent': [
197 'c0e0955e-6ab4-4182-8d56-1c8c35a5106d'
198 ]
199
200 it 'should set node-flow-metric-instance', ->
201 expect(@flowConfig['node-flow-metric-instance'].config).containSubset
202 id: '000000-fake-metric-uuid-9999'
203 category: 'flow-metrics'
204 deviceId: 'f952aacb-5156-4072-bcae-f830334376b1'
205 deploymentUuid: 'the-deployment-uuid'
206 flowUuid: sampleFlow.flowId
207 nanocyte:
208 nonce: 'i-am-a-nonce'
209
210 it 'should set node-get-key-instance', ->
211 expect(@flowConfig['node-get-key-instance'].config).containSubset
212 id: '40842d14-a536-4d07-9174-fc463c53a5a7'
213 bodyEncoding: 'json'
214 category: "operation"
215 headerKeys: [
216 "Content-Type"
217 "Authorization"
218 ]
219 headerValues: [
220 'application/json'
221 'Bearer ZGQzZDc4N2EtNzgzMy00NTgxLTkyODctM2FkMmM1YTEyNzNhOnNvbWUtdG9rZW4='
222 ]
223 method: 'GET'
224 nanocyte:
225 nonce: 'i-am-a-nonce'
226 type: 'operation:get-key'
227 url: 'http://this-is-silly-and-probably-broken/v2/devices/dd3d787a-7833-4581-9287-3ad2c5a1273a'
228
229 it 'should set node-set-key-instance', ->
230 expect(@flowConfig['node-set-key-instance'].config).containSubset
231 id: '2528d3e8-6993-4184-8049-9c4025a57145'
232 bodyEncoding: 'json'
233 category: "operation"
234 headerKeys: [
235 "Content-Type"
236 "Authorization"
237 ]
238 headerValues: [
239 'application/json'
240 'Bearer ZGQzZDc4N2EtNzgzMy00NTgxLTkyODctM2FkMmM1YTEyNzNhOnNvbWUtdG9rZW4='
241 ]
242 bodyKeys: [ 'data.{{msg.key}}' ]
243 bodyValues: [ '{{msg.value}}' ]
244 method: 'PATCH'
245 nanocyte:
246 nonce: 'i-am-a-nonce'
247 type: 'operation:set-key'
248 url: 'http://this-is-silly-and-probably-broken/v2/devices/dd3d787a-7833-4581-9287-3ad2c5a1273a'
249
250 it 'should set node-trigger-instance', ->
251 nodeConfigs = _.map @flowConfig, (node) => return node.config
252 expect(nodeConfigs).contain {
253 "id": "8a8da890-55d6-11e5-bd83-1349dc09f6d6",
254 "resourceType": "flow-node",
255 "payloadType": "date",
256 "once": false,
257 "name": "Trigger",
258 "class": "trigger",
259 "helpText": "Send a static message. Can also be triggered from other flows",
260 "category": "operation",
261 "uuid": "37f0a74a-2f17-11e4-9617-a6c5e4d22fb7",
262 "type": "operation:trigger",
263 "defaults": {
264 "payloadType": "date",
265 "once": false
266 },
267 nanocyte: {
268 nonce: 'i-am-a-nonce'
269 }
270 "input": 0,
271 "output": 1,
272 "formTemplatePath": "/pages/node_forms/button_form.html",
273 "logo": "https://ds78apnml6was.cloudfront.net/operation/trigger.svg",
274 "inputLocations": [],
275 "outputLocations": [],
276 "x": 609.9398803710938,
277 "y": 517.0806884765625,
278 "needsConfiguration": false,
279 "needsSetup": false
280 }
281
282 it 'should only set engine-stop on the stopConfig router', ->
283 links =
284 'engine-stop':
285 linkedTo: ['node-component-unregister-instance']
286 type: 'engine-stop'
287 'engine-output':
288 type: 'engine-output'
289 linkedTo: []
290 'node-component-unregister-instance':
291 linkedTo: []
292 type: 'node-component-unregister'
293
294 expect(@flowStopConfig.router.config).containSubset links
295
296 xit 'should set the flow links on the router', ->
297 links =
298 '2cf457d0-57eb-11e5-99ea-11ac2aafbb8d':
299 type: 'engine-input'
300 linkedTo: ['node-interval-instance']
301 '8a8da890-55d6-11e5-bd83-1349dc09f6d6':
302 type: 'engine-input'
303 linkedTo: ['node-trigger-instance']
304 'f607eed0-631b-11e5-9887-75e2edd7c9c8':
305 type: "engine-input"
306 linkedTo: ['node-device-instance']
307 'node-trigger-instance':
308 type: 'nanocyte-node-trigger'
309 linkedTo: ['node-debug-instance', 'engine-pulse']
310 'node-debug-instance':
311 type: 'nanocyte-node-debug'
312 linkedTo: ['engine-debug']
313 'node-interval-instance':
314 type: 'nanocyte-node-interval'
315 linkedTo: ['node-debug-instance', 'engine-pulse']
316 'node-device-instance':
317 type: 'nanocyte-component-pass-through'
318 linkedTo: ['engine-pulse']
319 'node-channel-instance':
320 linkedTo: ['engine-pulse']
321 type: 'nanocyte-component-channel'
322 'node-get-key-instance':
323 linkedTo: [ 'node-debug-instance', 'engine-pulse' ]
324 type: 'nanocyte-component-http-formatter'
325 'node-set-key-instance':
326 linkedTo: [ 'node-debug-instance', 'engine-pulse' ]
327 type: 'nanocyte-component-http-formatter'
328 'node-flow-metric-instance':
329 linkedTo: ['engine-output', 'engine-pulse']
330 type: 'nanocyte-component-flow-metrics-start'
331 'engine-start':
332 linkedTo: ['node-flow-metric-instance']
333 type: 'engine-start'
334 'engine-stop':
335 linkedTo: ['node-component-unregister-instance']
336 type: 'engine-stop'
337 'engine-output':
338 type: 'engine-output'
339 linkedTo: []
340 'engine-data':
341 type: 'engine-data'
342 linkedTo: []
343 'engine-debug':
344 type: 'engine-debug'
345 linkedTo: []
346 'engine-pulse':
347 type: 'engine-pulse'
348 linkedTo: []
349 'node-component-unregister-instance':
350 linkedTo: []
351 type: 'node-component-unregister'
352
353 expect(@flowConfig.router.config).containSubset links
354
355 it 'should configure the debug node with the proper config', ->
356 origNodeConfig = _.findWhere sampleFlow.nodes, id: '8e74a6c0-55d6-11e5-bd83-1349dc09f6d6'
357 expect(@flowConfig['8e74a6c0-55d6-11e5-bd83-1349dc09f6d6'].config).containSubset origNodeConfig
358
359 it 'should configure the debug node with default data', ->
360 expect(@flowConfig['8e74a6c0-55d6-11e5-bd83-1349dc09f6d6'].data).containSubset {}
361
362 it 'should set node-channel-instance', ->
363 expect(@flowConfig['node-channel-instance'].config).containSubset {
364 "id": "9d8e9920-663b-11e5-82a3-c3248b467ade",
365 "channelApiMatch": require './data/github-channel.json'
366 "resourceType": "flow-node",
367 "channelid": "532a258a50411e5802cb8053",
368 "channelActivationId": "55fc50d1aed35f0f0009b9c3",
369 "uuid": "e56842b0-5e2e-11e5-8abf-b33a470ad64b",
370 "name": "Github",
371 "type": "channel:github",
372 "category": "channel",
373 "online": true,
374 "useStaticMessage": true,
375 "nanocyte": {
376 "nonce": "i-am-a-nonce"
377 },
378 "nodeType": {
379 "_id": "53c9b839f400e177dca325c8",
380 "category": "channel",
381 "categories": [
382 "Social"
383 ],
384 "description": "",
385 "documentation": "https://developer.github.com/v3/",
386 "helpText": "GitHub is a web-based Git repository hosting service, that is the best place to share code with friends, co-workers, classmates, and complete strangers. Also offers distributed revision control and source code management functionalities to fork projects, send pull requests, and monitor development.",
387 "enabled": true,
388 "name": "Github",
389 "skynet": {
390 "type": "channel",
391 "subtype": "Github"
392 },
393 "channelid": "532a258a50411e5802cb8053",
394 "type": "channel:github"
395 },
396 "class": "channel-github",
397 "defaults": {
398 "channelid": "532a258a50411e5802cb8053",
399 "channelActivationId": "55fc50d1aed35f0f0009b9c3",
400 "uuid": "e56842b0-5e2e-11e5-8abf-b33a470ad64b",
401 "name": "Github",
402 "type": "channel:github",
403 "category": "channel",
404 "online": true,
405 "useStaticMessage": true,
406 "nodeType": {
407 "_id": "53c9b839f400e177dca325c8",
408 "category": "channel",
409 "categories": [
410 "Social"
411 ],
412 "description": "",
413 "documentation": "https://developer.github.com/v3/",
414 "helpText": "GitHub is a web-based Git repository hosting service, that is the best place to share code with friends, co-workers, classmates, and complete strangers. Also offers distributed revision control and source code management functionalities to fork projects, send pull requests, and monitor development.",
415 "enabled": true,
416 "name": "Github",
417 "skynet": {
418 "type": "channel",
419 "subtype": "Github"
420 },
421 "channelid": "532a258a50411e5802cb8053",
422 "type": "channel:github"
423 }
424 },
425 "input": 1,
426 "output": 1,
427 "helpText": "GitHub is a web-based Git repository hosting service, that is the best place to share code with friends, co-workers, classmates, and complete strangers. Also offers distributed revision control and source code management functionalities to fork projects, send pull requests, and monitor development.",
428 "formTemplatePath": "/pages/node_forms/channel_form.html",
429 "logo": "https://ds78apnml6was.cloudfront.net/channel/github.svg",
430 "inputLocations": [],
431 "outputLocations": [],
432 "x": 239.47897338867188,
433 "y": 228.071044921875,
434 "headerParams": {},
435 "urlParams": {},
436 "queryParams": {},
437 "bodyParams": {},
438 "url": "https://:hostname/setup/api/settings/authorized-keys",
439 "method": "POST",
440 "needsConfiguration": false,
441 "needsSetup": false,
442 "bodyFormat": "json"
443 }
444
445 describe '-> _buildLinks', ->
446 beforeEach ->
447 @sut = new ConfigurationGenerator {}, {request: @request, channelConfig: {}}
448 sinon.stub @sut, '_generateInstanceId'
449 sinon.stub @sut, '_generateTransactionGroupId'
450
451 describe 'when one node is linked to another', ->
452 beforeEach ->
453 links = [
454 from: 'some-node-uuid'
455 to: 'some-other-node-uuid'
456 ]
457
458 flowConfig =
459 'some-node-uuid':
460 config:
461 id: 'some-node-uuid'
462 category: 'some-thing'
463 'some-other-node-uuid':
464 config:
465 id: 'some-other-node-uuid'
466 category: 'some-other-thing'
467
468 nodeRegistry =
469 'some-thing':
470 type: 'nanocyte-node-fluff'
471 composedOf:
472 'fluff-1':
473 type: 'nanocyte-node-fluff'
474 linkedToNext: true
475 'some-other-thing':
476 type: 'nanocyte-node-fluff'
477 composedOf:
478 'fluff-1':
479 type: 'nanocyte-node-fluff'
480 linkedToPrev: true
481
482 @sut._generateInstanceId.onCall(0).returns 'some-node-instance-uuid'
483 @sut._generateInstanceId.onCall(1).returns 'some-other-node-instance-uuid'
484 @result = @sut._buildLinks links, @sut._generateInstances(links, flowConfig, nodeRegistry, {})
485
486 it 'should set the flow links on the router', ->
487 links =
488 'some-node-instance-uuid':
489 type: 'nanocyte-node-fluff'
490 linkedTo: ['some-other-node-instance-uuid', 'engine-pulse']
491 'some-other-node-instance-uuid':
492 type: 'nanocyte-node-fluff'
493 linkedTo: []
494 'engine-output':
495 type: 'engine-output'
496 linkedTo: []
497 'engine-data':
498 type: 'engine-data'
499 linkedTo: []
500 'engine-debug':
501 type: 'engine-debug'
502 linkedTo: []
503 'engine-pulse':
504 type: 'engine-pulse'
505 linkedTo: []
506
507 expect(@result).containSubset links
508
509 describe 'when a different node is linked to another', ->
510 beforeEach ->
511 links = [
512 from: 'some-other-node-uuid'
513 to: 'yet-some-other-node-uuid'
514 ]
515
516 flowConfig =
517 'some-other-node-uuid':
518 config:
519 category: 'some-node'
520 id: 'some-other-node-uuid'
521 'yet-some-other-node-uuid':
522 config:
523 category: 'nanocyte-node-tuff'
524 id: 'some-other-node-uuid'
525
526 nodeRegistry =
527 'some-node':
528 composedOf:
529 'tuff-2':
530 type: 'nanocyte-node-tuff'
531 linkedToNext: true
532 'nanocyte-node-tuff':
533 composedOf:
534 'tuff-2':
535 type: 'nanocyte-node-tuff'
536 linkedToPrev: true
537
538 @sut._generateInstanceId.onCall(0).returns 'some-other-node-instance-uuid'
539 @sut._generateInstanceId.onCall(1).returns 'yet-some-other-node-instance-uuid'
540 @result = @sut._buildLinks links, @sut._generateInstances(links, flowConfig, nodeRegistry, {})
541
542 it 'should set the flow links on the router', ->
543 links =
544 'some-other-node-instance-uuid':
545 type: 'nanocyte-node-tuff'
546 linkedTo: ['yet-some-other-node-instance-uuid', 'engine-pulse']
547 'yet-some-other-node-instance-uuid':
548 type: 'nanocyte-node-tuff'
549 linkedTo: []
550 'engine-output':
551 type: 'engine-output'
552 linkedTo: []
553 'engine-data':
554 type: 'engine-data'
555 linkedTo: []
556 'engine-debug':
557 type: 'engine-debug'
558 linkedTo: []
559 'engine-pulse':
560 type: 'engine-pulse'
561 linkedTo: []
562
563 expect(@result).containSubset links
564
565 describe 'when one node is linked to two nodes', ->
566 beforeEach ->
567 links = [
568 from: 'some-node-uuid'
569 to: 'some-other-node-uuid'
570 ,
571 from: 'some-node-uuid'
572 to: 'another-node-uuid'
573 ]
574
575 flowConfig =
576 'some-node-uuid':
577 config:
578 id: 'some-node-uuid'
579 category: 'some-thing'
580 'some-other-node-uuid':
581 config:
582 id: 'some-other-node-uuid'
583 category: 'some-other-thing'
584 'another-node-uuid':
585 config:
586 id: 'another-node-uuid'
587 category: 'another-thing'
588
589 nodeRegistry =
590 'some-thing':
591 type: 'nanocyte-node-fluff'
592 composedOf:
593 'fluff-1':
594 type: 'nanocyte-node-fluff'
595 linkedToNext: true
596 'some-other-thing':
597 type: 'nanocyte-node-fluff'
598 composedOf:
599 'fluff-1':
600 type: 'nanocyte-node-fluff'
601 linkedToPrev: true
602 'another-thing':
603 type: 'nanocyte-node-fluff'
604 composedOf:
605 'fluff-1':
606 type: 'nanocyte-node-fluff'
607 linkedToPrev: true
608
609
610 @sut._generateInstanceId.onCall(0).returns 'some-node-instance-uuid'
611 @sut._generateInstanceId.onCall(1).returns 'some-other-node-instance-uuid'
612 @sut._generateInstanceId.onCall(2).returns 'another-node-instance-uuid'
613 @result = @sut._buildLinks links, @sut._generateInstances(links, flowConfig, nodeRegistry, {})
614
615 it 'should set the flow links on the router', ->
616 links =
617 'some-node-instance-uuid':
618 type: 'nanocyte-node-fluff'
619 linkedTo: ['some-other-node-instance-uuid', 'another-node-instance-uuid', 'engine-pulse']
620 'some-other-node-instance-uuid':
621 linkedTo: []
622 type: 'nanocyte-node-fluff'
623 'another-node-instance-uuid':
624 linkedTo: []
625 type: 'nanocyte-node-fluff'
626 'engine-output':
627 type: 'engine-output'
628 linkedTo: []
629 'engine-data':
630 type: 'engine-data'
631 linkedTo: []
632 'engine-debug':
633 type: 'engine-debug'
634 linkedTo: []
635 'engine-pulse':
636 type: 'engine-pulse'
637 linkedTo: []
638
639 expect(@result).containSubset links
640
641 describe 'when two nodes are linked to two nodes', ->
642 beforeEach ->
643 links = [
644 from: 'some-node-uuid'
645 to: 'some-other-node-uuid'
646 ,
647 from: 'some-node-uuid'
648 to: 'another-node-uuid'
649 ,
650 from: 'some-different-node-uuid'
651 to: 'some-other-node-uuid'
652 ,
653 from: 'some-different-node-uuid'
654 to: 'another-node-uuid'
655 ]
656
657 flowConfig =
658 'some-node-uuid':
659 config:
660 id: 'some-node-uuid'
661 category: 'some-thing'
662 'some-other-node-uuid':
663 config:
664 id: 'some-other-node-uuid'
665 category: 'some-other-thing'
666 'some-different-node-uuid':
667 config:
668 id: 'some-different-node-uuid'
669 category: 'different-thing'
670 'another-node-uuid':
671 config:
672 id: 'another-node-uuid'
673 category: 'another-thing'
674
675 nodeRegistry =
676 'some-thing':
677 type: 'nanocyte-node-fluff'
678 composedOf:
679 'fluffy-1':
680 type: 'nanocyte-node-fluff'
681 linkedToNext: true
682 'some-other-thing':
683 type: 'nanocyte-node-stuff'
684 composedOf:
685 'stuffy-1':
686 type: 'nanocyte-node-stuff'
687 linkedToPrev: true
688 'different-thing':
689 type: 'nanocyte-node-ruff'
690 composedOf:
691 'ruffy-1':
692 type: 'nanocyte-node-ruff'
693 linkedToNext: true
694 'another-thing':
695 type: 'nanocyte-node-buff'
696 composedOf:
697 'buffy-1':
698 type: 'nanocyte-node-buff'
699 linkedToPrev: true
700
701 @sut._generateInstanceId.onCall(0).returns 'some-node-instance-uuid'
702 @sut._generateInstanceId.onCall(1).returns 'some-other-node-instance-uuid'
703 @sut._generateInstanceId.onCall(2).returns 'some-different-node-instance-uuid'
704 @sut._generateInstanceId.onCall(3).returns 'another-node-instance-uuid'
705 @result = @sut._buildLinks links, @sut._generateInstances(links, flowConfig, nodeRegistry, {})
706
707 it 'should set the flow links on the router', ->
708 links =
709 'some-node-instance-uuid':
710 type: 'nanocyte-node-fluff'
711 linkedTo: ['some-other-node-instance-uuid', 'another-node-instance-uuid', 'engine-pulse']
712 'some-other-node-instance-uuid':
713 type: 'nanocyte-node-stuff'
714 linkedTo: []
715 'some-different-node-instance-uuid':
716 type: 'nanocyte-node-ruff'
717 linkedTo: ['some-other-node-instance-uuid', 'another-node-instance-uuid', 'engine-pulse']
718 'another-node-instance-uuid':
719 linkedTo: []
720 type: 'nanocyte-node-buff'
721 'engine-output':
722 type: 'engine-output'
723 linkedTo: []
724 'engine-data':
725 type: 'engine-data'
726 linkedTo: []
727 'engine-debug':
728 type: 'engine-debug'
729 linkedTo: []
730 'engine-pulse':
731 type: 'engine-pulse'
732 linkedTo: []
733
734 expect(@result).containSubset links
735
736 describe 'when one node is linked to a virtual node', ->
737 beforeEach ->
738 links = []
739
740 flowConfig =
741 'some-node-uuid':
742 config:
743 id: 'some-node-uuid'
744 category: 'something'
745
746 nodeRegistry =
747 'something':
748 type: 'nanocyte-node-debug'
749 composedOf:
750 'debug-1':
751 linkedToOutput: true
752 type: 'nanocyte-node-debug'
753
754 @sut._generateInstanceId.onCall(0).returns 'some-node-instance-uuid'
755 @result = @sut._buildLinks links, @sut._generateInstances(links, flowConfig, nodeRegistry, {})
756
757 it 'should set the flow links on the router', ->
758 links =
759 'some-node-instance-uuid':
760 type: 'nanocyte-node-debug'
761 linkedTo: ['engine-output', 'engine-pulse']
762 'engine-output':
763 type: 'engine-output'
764 linkedTo: []
765 'engine-data':
766 type: 'engine-data'
767 linkedTo: []
768 'engine-debug':
769 type: 'engine-debug'
770 linkedTo: []
771 'engine-pulse':
772 type: 'engine-pulse'
773 linkedTo: []
774
775 expect(@result).containSubset links
776
777 describe 'when debug is set to true', ->
778 beforeEach ->
779 links = []
780
781 flowConfig =
782 'some-node-uuid':
783 config:
784 id: 'some-node-uuid'
785 debug: true
786 category: 'something'
787
788 nodeRegistry =
789 'something':
790 type: 'nanocyte-node-bar'
791 composedOf:
792 'bar-1':
793 type: 'nanocyte-node-bar'
794
795 @sut._generateInstanceId.onCall(0).returns 'some-node-instance-uuid'
796 @result = @sut._buildLinks links, @sut._generateInstances(links, flowConfig, nodeRegistry, {})
797
798 xit 'should set the flow links on the router', ->
799 links =
800 'some-node-instance-uuid':
801 type: 'nanocyte-node-bar'
802 linkedTo: ['engine-debug']
803 'engine-output':
804 type: 'engine-output'
805 linkedTo: []
806 'engine-data':
807 type: 'engine-data'
808 linkedTo: []
809 'engine-debug':
810 type: 'engine-debug'
811 linkedTo: []
812 'engine-pulse':
813 type: 'engine-pulse'
814 linkedTo: []
815
816 expect(@result).containSubset links
817
818 describe 'when linkedToOutput', ->
819 beforeEach ->
820 links = []
821
822 flowConfig =
823 'some-node-uuid':
824 config:
825 id: 'some-node-uuid'
826 category: 'something'
827
828 nodeRegistry =
829 'something':
830 type: 'nanocyte-node-bar'
831 composedOf:
832 'bar-1':
833 type: 'nanocyte-node-bar'
834 linkedToOutput: true
835
836 @sut._generateInstanceId.onCall(0).returns 'some-node-instance-uuid'
837 @result = @sut._buildLinks links, @sut._generateInstances(links, flowConfig, nodeRegistry, {})
838
839 it 'should set the flow links on the router', ->
840 links =
841 'some-node-instance-uuid':
842 type: 'nanocyte-node-bar'
843 linkedTo: ['engine-output', 'engine-pulse']
844 'engine-output':
845 type: 'engine-output'
846 linkedTo: []
847 'engine-data':
848 type: 'engine-data'
849 linkedTo: []
850 'engine-debug':
851 type: 'engine-debug'
852 linkedTo: []
853 'engine-pulse':
854 type: 'engine-pulse'
855 linkedTo: []
856
857 expect(@result).containSubset links
858
859 describe 'when linkedToPulse', ->
860 beforeEach ->
861 links = []
862
863 flowConfig =
864 'some-node-uuid':
865 config:
866 id: 'some-node-uuid'
867 category: 'something'
868
869 nodeRegistry =
870 'something':
871 type: 'nanocyte-node-bar'
872 composedOf:
873 'bar-1':
874 type: 'nanocyte-node-bar'
875 linkedToPulse: true
876
877 @sut._generateInstanceId.onCall(0).returns 'some-node-instance-uuid'
878 @result = @sut._buildLinks links, @sut._generateInstances(links, flowConfig, nodeRegistry, {})
879
880 it 'should set the flow links on the router', ->
881 links =
882 'some-node-instance-uuid':
883 type: 'nanocyte-node-bar'
884 linkedTo: ['engine-pulse']
885 'engine-output':
886 type: 'engine-output'
887 linkedTo: []
888 'engine-data':
889 type: 'engine-data'
890 linkedTo: []
891 'engine-debug':
892 type: 'engine-debug'
893 linkedTo: []
894 'engine-pulse':
895 type: 'engine-pulse'
896 linkedTo: []
897
898 expect(@result).containSubset links
899
900 describe 'when linkedToData', ->
901 beforeEach ->
902 links = []
903
904 flowConfig =
905 'some-node-uuid':
906 config:
907 id: 'some-node-uuid'
908 category: 'something'
909
910 nodeRegistry =
911 'something':
912 type: 'nanocyte-node-save-me'
913 composedOf:
914 'save-me-1':
915 type: 'nanocyte-node-save-me'
916 linkedToData: true
917
918
919 @sut._generateTransactionGroupId.onCall(0).returns 'some-node-uuid'
920 @sut._generateInstanceId.onCall(0).returns 'some-node-instance-uuid'
921
922 @result = @sut._buildLinks links, @sut._generateInstances(links, flowConfig, nodeRegistry, {})
923
924 it 'should set the flow links on the router', ->
925 links =
926 'some-node-instance-uuid':
927 type: 'nanocyte-node-save-me'
928 transactionGroupId: 'some-node-uuid'
929 linkedTo: ['engine-data']
930 'engine-output':
931 type: 'engine-output'
932 linkedTo: []
933 'engine-data':
934 type: 'engine-data'
935 linkedTo: []
936 'engine-debug':
937 type: 'engine-debug'
938 linkedTo: []
939 'engine-pulse':
940 type: 'engine-pulse'
941 linkedTo: []
942
943 expect(@result).containSubset links
944
945 describe 'when linkedToNext', ->
946 beforeEach ->
947 links = [
948 from: 'some-trigger-uuid'
949 to: 'some-throttle-uuid'
950 ,
951 from: 'some-throttle-uuid'
952 to: 'some-debug-uuid'
953 ]
954
955 flowConfig =
956 'some-trigger-uuid':
957 config:
958 id: 'some-trigger-uuid'
959 category: 'trigger'
960 'some-throttle-uuid':
961 config:
962 id: 'some-throttle-uuid'
963 category: 'throttle'
964 'some-debug-uuid':
965 config:
966 id: 'some-debug-uuid'
967 debug: true
968 category: 'debug'
969
970 nodeRegistry =
971 'trigger':
972 type: 'nanocyte-node-trigger'
973 composedOf:
974 'trigger-1':
975 type: 'nanocyte-node-trigger'
976 linkedToInput: true
977 linkedToNext: true
978 'throttle':
979 type: 'nanocyte-node-throttle'
980 composedOf:
981 'throttle-push-1':
982 type: 'nanocyte-node-throttle-push'
983 linkedToData: true
984 linkedToPrev: true
985 'throttle-pop-1':
986 type: 'nanocyte-node-throttle-pop'
987 linkedTo: ['throttle-emit-1']
988 linkedToInput: true
989 linkedToData: true
990 'throttle-emit-1':
991 type: 'nanocyte-node-throttle-emit'
992 linkedToInput: true
993 linkedToNext: true
994 'debug':
995 type: 'nanocyte-node-debug'
996 composedOf:
997 'debug-1':
998 type: 'nanocyte-node-debug'
999 linkedToPrev: true
1000
1001 @sut._generateTransactionGroupId.onCall(0).returns 'some-throttle-uuid'
1002
1003 @sut._generateInstanceId.onCall(0).returns 'trigger-instance-uuid'
1004 @sut._generateInstanceId.onCall(1).returns 'throttle-push-instance-uuid'
1005 @sut._generateInstanceId.onCall(2).returns 'throttle-pop-instance-uuid'
1006 @sut._generateInstanceId.onCall(3).returns 'throttle-emit-instance-uuid'
1007 @sut._generateInstanceId.onCall(4).returns 'debug-instance-uuid'
1008
1009 @result = @sut._buildLinks links, @sut._generateInstances(links, flowConfig, nodeRegistry, {})
1010
1011 xit 'should set the flow links on the router', ->
1012 links =
1013 'some-trigger-uuid':
1014 type: 'engine-input'
1015 linkedTo: ['trigger-instance-uuid']
1016 'trigger-instance-uuid':
1017 type: 'nanocyte-node-trigger'
1018 linkedTo: ['throttle-push-instance-uuid', 'engine-pulse']
1019 'some-throttle-uuid':
1020 type: 'engine-input'
1021 linkedTo: ['throttle-pop-instance-uuid', 'throttle-emit-instance-uuid']
1022 'throttle-push-instance-uuid':
1023 type: 'nanocyte-node-throttle-push'
1024 transactionGroupId: 'some-throttle-uuid'
1025 linkedTo: ['engine-data']
1026 'throttle-pop-instance-uuid':
1027 type: 'nanocyte-node-throttle-pop'
1028 transactionGroupId: 'some-throttle-uuid'
1029 linkedTo: ['throttle-emit-instance-uuid', 'engine-data']
1030 'throttle-emit-instance-uuid':
1031 type: 'nanocyte-node-throttle-emit'
1032 transactionGroupId: 'some-throttle-uuid'
1033 linkedTo: ['debug-instance-uuid', 'engine-pulse']
1034 'debug-instance-uuid':
1035 type: 'nanocyte-node-debug'
1036 linkedTo: ['engine-debug']
1037 'engine-output':
1038 type: 'engine-output'
1039 linkedTo: []
1040 'engine-data':
1041 type: 'engine-data'
1042 linkedTo: []
1043 'engine-debug':
1044 type: 'engine-debug'
1045 linkedTo: []
1046 'engine-pulse':
1047 type: 'engine-pulse'
1048 linkedTo: []
1049
1050 expect(@result).containSubset links
1051
1052 describe 'when linkedToStart and linkedToStop', ->
1053 beforeEach ->
1054 links = [
1055 from: 'some-interval-uuid'
1056 to: 'some-debug-uuid'
1057 ]
1058
1059 flowConfig =
1060 'some-interval-uuid':
1061 config:
1062 id: 'some-interval-uuid'
1063 category: 'interval'
1064
1065 'some-debug-uuid':
1066 config:
1067 id: 'some-debug-uuid'
1068 debug: true
1069 category: 'debug'
1070
1071 nodeRegistry =
1072 'interval':
1073 type: 'nanocyte-node-interval'
1074 composedOf:
1075 'interval-1':
1076 type: 'nanocyte-node-interval'
1077 linkedToNext: true
1078 linkedToInput: true
1079 'interval-start':
1080 type: 'nanocyte-node-interval-start'
1081 linkedFromStart: true
1082 'interval-stop':
1083 type: 'nanocyte-node-interval-stop'
1084 linkedFromStop: true
1085 'debug':
1086 composedOf:
1087 'debug-1':
1088 type: 'nanocyte-node-debug'
1089 linkedToPrev: true
1090
1091 @sut._generateInstanceId.onCall(0).returns 'interval-instance-uuid'
1092 @sut._generateInstanceId.onCall(1).returns 'interval-start-instance-uuid'
1093 @sut._generateInstanceId.onCall(2).returns 'interval-stop-instance-uuid'
1094 @sut._generateInstanceId.onCall(3).returns 'debug-instance-uuid'
1095
1096 @result = @sut._buildLinks links, @sut._generateInstances(links, flowConfig, nodeRegistry, {})
1097
1098 xit 'should set the flow links on the router', ->
1099 links =
1100 'engine-start':
1101 type: 'engine-start'
1102 linkedTo: ['interval-start-instance-uuid']
1103 'engine-stop':
1104 type: 'engine-stop'
1105 linkedTo: ['interval-stop-instance-uuid']
1106 'some-interval-uuid':
1107 type: 'engine-input'
1108 linkedTo: ['interval-instance-uuid']
1109 'interval-instance-uuid':
1110 type: 'nanocyte-node-interval'
1111 linkedTo: ['debug-instance-uuid','engine-pulse']
1112 'interval-start-instance-uuid':
1113 type: 'nanocyte-node-interval-start'
1114 linkedTo: []
1115 'interval-stop-instance-uuid':
1116 type: 'nanocyte-node-interval-stop'
1117 linkedTo: []
1118 'debug-instance-uuid':
1119 linkedTo: ["engine-debug"]
1120 type: "nanocyte-node-debug"
1121 'engine-output':
1122 type: 'engine-output'
1123 linkedTo: []
1124 'engine-data':
1125 type: 'engine-data'
1126 linkedTo: []
1127 'engine-debug':
1128 type: 'engine-debug'
1129 linkedTo: []
1130 'engine-pulse':
1131 type: 'engine-pulse'
1132 linkedTo: []
1133
1134 expect(@result).containSubset links
1135
1136 describe '-> _buildNodeMap', ->
1137 beforeEach ->
1138 @sut = new ConfigurationGenerator {}, {channelConfig: {}}
1139 sinon.stub @sut, '_generateInstanceId'
1140
1141 describe 'when one node is linked to another', ->
1142 beforeEach ->
1143 links = [
1144 from: 'some-node-uuid'
1145 to: 'some-other-node-uuid'
1146 ]
1147
1148 flowConfig =
1149 'some-node-uuid':
1150 config:
1151 id: 'some-node-uuid'
1152 category: 'nanocyte-node-cruft'
1153 'some-other-node-uuid':
1154 config:
1155 id: 'some-other-node-uuid'
1156 category: 'nanocyte-node-fluff'
1157
1158 nodeRegistry =
1159 'nanocyte-node-cruft':
1160 composedOf:
1161 'cruft-1':
1162 type: 'nanocyte-node-cruft'
1163 linkedToNext: true
1164 'nanocyte-node-fluff':
1165 composedOf:
1166 'fluff-1':
1167 type: 'nanocyte-node-fluff'
1168 linkedToPrev: true
1169
1170 @sut._generateInstanceId.onCall(0).returns 'some-node-instance-uuid'
1171 @sut._generateInstanceId.onCall(1).returns 'some-other-node-instance-uuid'
1172 @result = @sut._buildNodeMap @sut._generateInstances(links, flowConfig, nodeRegistry, {})
1173
1174 it 'should build the node map', ->
1175 nodeMap =
1176 'some-node-instance-uuid':
1177 nodeId: 'some-node-uuid'
1178 'some-other-node-instance-uuid':
1179 nodeId: 'some-other-node-uuid'
1180 expect(@result).containSubset nodeMap
1181
1182 describe '-> _buildMeshblutoNodeMap', ->
1183 describe 'when two of the same input node', ->
1184 beforeEach ->
1185 flow =
1186 'device-instance-1-uuid':
1187 config:
1188 uuid: 'device-uuid'
1189 'device-instance-2-uuid':
1190 config:
1191 uuid: 'device-uuid'
1192
1193 instanceMap =
1194 'device-instance-1':
1195 nodeUuid: 'device-instance-1-uuid'
1196 linkedToInput: true
1197 'device-instance-2':
1198 nodeUuid: 'device-instance-2-uuid'
1199 linkedToInput: true
1200
1201 @sut = new ConfigurationGenerator {}, {channelConfig: {}}
1202 sinon.stub @sut, '_generateInstanceId'
1203 @result = @sut._buildMeshblutoNodeMap flow, instanceMap
1204
1205 it 'should send back a map linking both devices to the same uuid', ->
1206 expect(@result['device-uuid']).to.deep.contain.same.members [
1207 {nodeId: 'device-instance-1-uuid'}
1208 {nodeId: 'device-instance-2-uuid'}
1209 ]
1210
1211 describe '-> _buildMeshblutoNodeMap', ->
1212 describe 'when the input node has an alias', ->
1213 beforeEach ->
1214 flow =
1215 'device-instance-1-uuid':
1216 config:
1217 uuid: 'device-uuid'
1218 alias: 'some-device-alias'
1219
1220 instanceMap =
1221 'device-instance-1':
1222 nodeUuid: 'device-instance-1-uuid'
1223 linkedToInput: true
1224
1225 @sut = new ConfigurationGenerator {}, {channelConfig: {}}
1226 sinon.stub @sut, '_generateInstanceId'
1227 @result = @sut._buildMeshblutoNodeMap flow, instanceMap
1228
1229 it 'should send back a map linking the device to the uuid and alias', ->
1230 expect(@result['device-uuid']).to.deep.contain.same.members [
1231 {nodeId: 'device-instance-1-uuid', alias: 'some-device-alias'}
1232 ]
1233
1234 describe '-> _legacyConversion', ->
1235 beforeEach ->
1236 dependencies =
1237 request: @request
1238 channelConfig: @channelConfig
1239
1240 @sut = new ConfigurationGenerator {}, dependencies
1241 sinon.stub @sut, '_generateInstanceId'
1242
1243 describe 'describe when given a debounce', ->
1244 beforeEach ->
1245 @result = @sut._legacyConversion
1246 type: 'operation:debounce'
1247 interval: 1000
1248
1249 it 'should convert interval to timeout', ->
1250 expect(@result).containSubset(
1251 type: 'operation:debounce', timeout: 1000
1252 )
1253
1254 describe 'describe when given another debounce interval', ->
1255 beforeEach ->
1256 @result = @sut._legacyConversion
1257 type: 'operation:debounce'
1258 interval: 9000
1259
1260 it 'should convert interval to timeout', ->
1261 expect(@result).containSubset(
1262 type: 'operation:debounce', timeout: 9000
1263 )
1264
1265 describe 'describe when given another debounce interval', ->
1266 beforeEach ->
1267 @result = @sut._legacyConversion
1268 type: 'operation:debounce'
1269 interval: 9000
1270 randomProperty: 'wow'
1271
1272 it 'should convert interval to timeout', ->
1273 expect(@result).containSubset(
1274 type: 'operation:debounce', timeout: 9000, randomProperty: 'wow'
1275 )
1276
1277 describe 'describe when given a throttle', ->
1278 beforeEach ->
1279 @result = @sut._legacyConversion
1280 type: 'operation:throttle'
1281 interval: 18
1282
1283 it 'should convert interval to repeat', ->
1284 expect(@result).containSubset(
1285 type: 'operation:throttle', repeat: 18
1286 )
1287
1288 describe 'describe when given a different throttle', ->
1289 beforeEach ->
1290 @result = @sut._legacyConversion
1291 type: 'operation:throttle'
1292 interval: 999
1293
1294 it 'should convert interval to repeat', ->
1295 expect(@result).containSubset(
1296 type: 'operation:throttle', repeat: 999
1297 )
1298
1299 describe 'describe when given a something that has an interval', ->
1300 beforeEach ->
1301 @result = @sut._legacyConversion
1302 type: 'operation:eject!'
1303 interval: 'whatevs'
1304
1305 it 'should convert interval to repeat', ->
1306 expect(@result).containSubset(
1307 type: 'operation:eject!', interval: 'whatevs'
1308 )