@hurenkam/hue-services 0.6.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.
- package/.github/workflows/node.js.yml +31 -0
- package/.nyc_output/ecb1b16f-015c-458b-96d5-32cb9569c1e8.json +1 -0
- package/.nyc_output/processinfo/ecb1b16f-015c-458b-96d5-32cb9569c1e8.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -0
- package/.vscode/settings.json +15 -0
- package/.vscode/sftp.json +11 -0
- package/LICENSE +201 -0
- package/README.md +340 -0
- package/Todo.txt +18 -0
- package/coverage/BaseNode.js.html +379 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +101 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +161 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov-report/src/RestApi.js.html +499 -0
- package/coverage/lcov-report/src/all.js.html +208 -0
- package/coverage/lcov-report/src/clip/ClipApi.js.html +1096 -0
- package/coverage/lcov-report/src/clip/Resource.js.html +481 -0
- package/coverage/lcov-report/src/clip/index.html +131 -0
- package/coverage/lcov-report/src/debug.js.html +253 -0
- package/coverage/lcov-report/src/files.js.html +118 -0
- package/coverage/lcov-report/src/index.html +161 -0
- package/coverage/lcov-report/src/nodes/BaseNode.js.html +381 -0
- package/coverage/lcov-report/src/nodes/BridgeConfigNode.js.html +817 -0
- package/coverage/lcov-report/src/nodes/ButtonNode.js.html +241 -0
- package/coverage/lcov-report/src/nodes/DevicePowerNode.js.html +199 -0
- package/coverage/lcov-report/src/nodes/GroupedLightNode.js.html +226 -0
- package/coverage/lcov-report/src/nodes/LightLevelNode.js.html +205 -0
- package/coverage/lcov-report/src/nodes/LightNode.js.html +226 -0
- package/coverage/lcov-report/src/nodes/MotionNode.js.html +205 -0
- package/coverage/lcov-report/src/nodes/RelativeRotaryNode.js.html +253 -0
- package/coverage/lcov-report/src/nodes/ResourceNode.js.html +388 -0
- package/coverage/lcov-report/src/nodes/SceneNode.js.html +124 -0
- package/coverage/lcov-report/src/nodes/ServiceNode.js.html +124 -0
- package/coverage/lcov-report/src/nodes/TemperatureNode.js.html +205 -0
- package/coverage/lcov-report/src/nodes/ZigbeeConnectivityNode.js.html +199 -0
- package/coverage/lcov-report/src/nodes/index.html +311 -0
- package/coverage/lcov-report/src/ui/BaseUI.js.html +484 -0
- package/coverage/lcov-report/src/ui/BridgeConfigUI.js.html +475 -0
- package/coverage/lcov-report/src/ui/ButtonUI.js.html +166 -0
- package/coverage/lcov-report/src/ui/DevicePowerUI.js.html +166 -0
- package/coverage/lcov-report/src/ui/GroupedLightUI.js.html +178 -0
- package/coverage/lcov-report/src/ui/LightLevelUI.js.html +166 -0
- package/coverage/lcov-report/src/ui/LightUI.js.html +178 -0
- package/coverage/lcov-report/src/ui/MotionUI.js.html +166 -0
- package/coverage/lcov-report/src/ui/RelativeRotaryUI.js.html +166 -0
- package/coverage/lcov-report/src/ui/ResourceUI.js.html +511 -0
- package/coverage/lcov-report/src/ui/SceneUI.js.html +160 -0
- package/coverage/lcov-report/src/ui/ServiceUI.js.html +868 -0
- package/coverage/lcov-report/src/ui/TemperatureUI.js.html +166 -0
- package/coverage/lcov-report/src/ui/ZigbeeConnectivityUI.js.html +166 -0
- package/coverage/lcov-report/src/ui/index.html +311 -0
- package/coverage/lcov.info +2217 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/coverage/src/RestApi.js.html +499 -0
- package/coverage/src/all.js.html +208 -0
- package/coverage/src/clip/ClipApi.js.html +1183 -0
- package/coverage/src/clip/Resource.js.html +481 -0
- package/coverage/src/clip/index.html +131 -0
- package/coverage/src/debug.js.html +253 -0
- package/coverage/src/files.js.html +118 -0
- package/coverage/src/index.html +116 -0
- package/coverage/src/nodes/BaseNode.js.html +379 -0
- package/coverage/src/nodes/BridgeConfigNode.js.html +517 -0
- package/coverage/src/nodes/ButtonNode.js.html +238 -0
- package/coverage/src/nodes/DevicePowerNode.js.html +196 -0
- package/coverage/src/nodes/GroupedLightNode.js.html +223 -0
- package/coverage/src/nodes/LightLevelNode.js.html +202 -0
- package/coverage/src/nodes/LightNode.js.html +223 -0
- package/coverage/src/nodes/MotionNode.js.html +202 -0
- package/coverage/src/nodes/RelativeRotaryNode.js.html +250 -0
- package/coverage/src/nodes/ResourceNode.js.html +373 -0
- package/coverage/src/nodes/SceneNode.js.html +124 -0
- package/coverage/src/nodes/ServiceNode.js.html +124 -0
- package/coverage/src/nodes/TemperatureNode.js.html +202 -0
- package/coverage/src/nodes/ZigbeeConnectivityNode.js.html +199 -0
- package/coverage/src/nodes/index.html +311 -0
- package/coverage/src/ui/BaseUI.js.html +484 -0
- package/coverage/src/ui/BridgeConfigUI.js.html +475 -0
- package/coverage/src/ui/ButtonUI.js.html +166 -0
- package/coverage/src/ui/DevicePowerUI.js.html +166 -0
- package/coverage/src/ui/GroupedLightUI.js.html +178 -0
- package/coverage/src/ui/LightLevelUI.js.html +166 -0
- package/coverage/src/ui/LightUI.js.html +178 -0
- package/coverage/src/ui/MotionUI.js.html +166 -0
- package/coverage/src/ui/RelativeRotaryUI.js.html +166 -0
- package/coverage/src/ui/ResourceUI.js.html +511 -0
- package/coverage/src/ui/SceneUI.js.html +160 -0
- package/coverage/src/ui/ServiceUI.js.html +868 -0
- package/coverage/src/ui/TemperatureUI.js.html +166 -0
- package/coverage/src/ui/ZigbeeConnectivityUI.js.html +166 -0
- package/coverage/src/ui/index.html +311 -0
- package/examples/flows.json +959 -0
- package/package.json +53 -0
- package/screenshots/Screenshot from 2022-11-29 00-29-23.png +0 -0
- package/screenshots/Screenshot from 2022-11-29 00-30-16.png +0 -0
- package/screenshots/Screenshot from 2022-11-29 00-30-58.png +0 -0
- package/screenshots/Screenshot from 2022-11-29 00-31-29.png +0 -0
- package/src/RestApi.js +138 -0
- package/src/all.html +52 -0
- package/src/all.js +42 -0
- package/src/clip/ClipApi.js +367 -0
- package/src/clip/Resource.js +132 -0
- package/src/debug.js +56 -0
- package/src/files.js +12 -0
- package/src/hue.js +98 -0
- package/src/nodes/BaseNode.js +98 -0
- package/src/nodes/BridgeConfigNode.js +144 -0
- package/src/nodes/ButtonNode.js +51 -0
- package/src/nodes/DevicePowerNode.js +37 -0
- package/src/nodes/GroupedLightNode.js +46 -0
- package/src/nodes/LightLevelNode.js +39 -0
- package/src/nodes/LightNode.js +46 -0
- package/src/nodes/MotionNode.js +39 -0
- package/src/nodes/RelativeRotaryNode.js +55 -0
- package/src/nodes/ResourceNode.js +95 -0
- package/src/nodes/SceneNode.js +13 -0
- package/src/nodes/ServiceNode.js +13 -0
- package/src/nodes/TemperatureNode.js +39 -0
- package/src/nodes/ZigbeeConnectivityNode.js +38 -0
- package/src/ui/BaseUI.js +133 -0
- package/src/ui/BridgeConfigUI.js +130 -0
- package/src/ui/ButtonUI.js +27 -0
- package/src/ui/DevicePowerUI.js +27 -0
- package/src/ui/GroupedLightUI.js +31 -0
- package/src/ui/LightLevelUI.js +27 -0
- package/src/ui/LightUI.js +31 -0
- package/src/ui/MotionUI.js +27 -0
- package/src/ui/RelativeRotaryUI.js +27 -0
- package/src/ui/ResourceUI.js +142 -0
- package/src/ui/SceneUI.js +25 -0
- package/src/ui/ServiceUI.js +261 -0
- package/src/ui/TemperatureUI.js +27 -0
- package/src/ui/ZigbeeConnectivityUI.js +27 -0
- package/test/BaseNode_spec.js +246 -0
- package/test/BaseUI_spec.js +17 -0
- package/test/BridgeConfigNode_spec.js +184 -0
- package/test/ButtonNode_spec.js +178 -0
- package/test/ClipApi_spec.js +769 -0
- package/test/DevicePowerNode_spec.js +186 -0
- package/test/GroupedLightNode_spec.js +218 -0
- package/test/LightLevelNode_spec.js +154 -0
- package/test/LightNode_spec.js +218 -0
- package/test/MotionNode_spec.js +186 -0
- package/test/RelativeRotataryNode_spec.js +325 -0
- package/test/ResourceNode_spec.js +308 -0
- package/test/Resource_spec.js +392 -0
- package/test/SceneNode_spec.js +33 -0
- package/test/ServiceNode_spec.js +33 -0
- package/test/TemperatureNode_spec.js +153 -0
- package/test/ZigbeeConnectivityNode_spec.js +186 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
const helper = require("node-red-node-test-helper");
|
|
2
|
+
const assert = require('assert');
|
|
3
|
+
const sinon = require('sinon');
|
|
4
|
+
const BaseNode = require("../src/nodes/BaseNode");
|
|
5
|
+
|
|
6
|
+
const testnodes = function(RED) {
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
const BaseNode = require('../src/nodes/BaseNode');
|
|
10
|
+
BaseNode.nodeAPI = RED;
|
|
11
|
+
|
|
12
|
+
RED.nodes.registerType("BaseNode",BaseNode);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe('Base Node', function () {
|
|
16
|
+
beforeEach(()=>{
|
|
17
|
+
sandbox = sinon.createSandbox();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterEach(function () {
|
|
21
|
+
helper.unload();
|
|
22
|
+
sandbox.restore();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should store config.name property', function (done) {
|
|
26
|
+
|
|
27
|
+
var flow = [{
|
|
28
|
+
id: "n1",
|
|
29
|
+
type: "BaseNode",
|
|
30
|
+
name: "base node",
|
|
31
|
+
}];
|
|
32
|
+
|
|
33
|
+
helper.load(testnodes, flow, function () {
|
|
34
|
+
var n1 = helper.getNode("n1");
|
|
35
|
+
n1.should.have.property('config');
|
|
36
|
+
|
|
37
|
+
var config = n1.config;
|
|
38
|
+
config.should.have.property('name', 'base node');
|
|
39
|
+
done();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should call onInput(msg) when a message is presented on the input', function (done) {
|
|
44
|
+
var flow = [{
|
|
45
|
+
id: "n1",
|
|
46
|
+
type: "BaseNode",
|
|
47
|
+
name: "base node",
|
|
48
|
+
}];
|
|
49
|
+
|
|
50
|
+
var payload = { on: { on: true }};
|
|
51
|
+
var msg = { payload: payload };
|
|
52
|
+
|
|
53
|
+
const fake = sandbox.fake((msg) => {
|
|
54
|
+
msg.should.have.property('payload',payload);
|
|
55
|
+
done();
|
|
56
|
+
});
|
|
57
|
+
sandbox.replace(BaseNode.prototype,'onInput',fake);
|
|
58
|
+
|
|
59
|
+
helper.load(testnodes, flow, function () {
|
|
60
|
+
var n1 = helper.getNode("n1");
|
|
61
|
+
n1.receive(msg);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should call getStatusFill() when updateStatus() method is called', function (done) {
|
|
66
|
+
var flow = [{
|
|
67
|
+
id: "n1",
|
|
68
|
+
type: "BaseNode",
|
|
69
|
+
name: "base node",
|
|
70
|
+
}];
|
|
71
|
+
|
|
72
|
+
const fake = sandbox.fake(() => {
|
|
73
|
+
done();
|
|
74
|
+
});
|
|
75
|
+
sandbox.replace(BaseNode.prototype,'getStatusFill',fake);
|
|
76
|
+
|
|
77
|
+
helper.load(testnodes, flow, function () {
|
|
78
|
+
var n1 = helper.getNode("n1");
|
|
79
|
+
n1.updateStatus();
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should call getStatusText() when updateStatus() is called', function (done) {
|
|
84
|
+
var flow = [{
|
|
85
|
+
id: "n1",
|
|
86
|
+
type: "BaseNode",
|
|
87
|
+
name: "base node",
|
|
88
|
+
}];
|
|
89
|
+
|
|
90
|
+
const fake = sandbox.fake(() => {
|
|
91
|
+
done();
|
|
92
|
+
});
|
|
93
|
+
sandbox.replace(BaseNode.prototype,'getStatusText',fake);
|
|
94
|
+
|
|
95
|
+
helper.load(testnodes, flow, function () {
|
|
96
|
+
var n1 = helper.getNode("n1");
|
|
97
|
+
n1.updateStatus();
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should call getStatusShape() when updateStatus() is called', function (done) {
|
|
102
|
+
var flow = [{
|
|
103
|
+
id: "n1",
|
|
104
|
+
type: "BaseNode",
|
|
105
|
+
name: "base node",
|
|
106
|
+
}];
|
|
107
|
+
|
|
108
|
+
const fake = sandbox.fake(() => {
|
|
109
|
+
done();
|
|
110
|
+
});
|
|
111
|
+
sandbox.replace(BaseNode.prototype,'getStatusShape',fake);
|
|
112
|
+
|
|
113
|
+
helper.load(testnodes, flow, function () {
|
|
114
|
+
var n1 = helper.getNode("n1");
|
|
115
|
+
n1.updateStatus();
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('should call status() with default status when updateStatus() is called', function (done) {
|
|
120
|
+
var flow = [{
|
|
121
|
+
id: "n1",
|
|
122
|
+
type: "BaseNode",
|
|
123
|
+
name: "base node",
|
|
124
|
+
}];
|
|
125
|
+
|
|
126
|
+
const fakeShape = sandbox.fake(() => null);
|
|
127
|
+
const fakeText = sandbox.fake(() => null);
|
|
128
|
+
const fakeFill = sandbox.fake(() => null);
|
|
129
|
+
const fakeStatus = sandbox.fake(() => { done(); });
|
|
130
|
+
sandbox.replace(BaseNode.prototype,'getStatusShape',fakeShape);
|
|
131
|
+
sandbox.replace(BaseNode.prototype,'getStatusText',fakeText);
|
|
132
|
+
sandbox.replace(BaseNode.prototype,'getStatusFill',fakeFill);
|
|
133
|
+
sandbox.replace(BaseNode.prototype,'status',fakeStatus);
|
|
134
|
+
|
|
135
|
+
helper.load(testnodes, flow, function () {
|
|
136
|
+
var n1 = helper.getNode("n1");
|
|
137
|
+
n1.updateStatus();
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should call status() with correct status when updateStatus() is called', function (done) {
|
|
142
|
+
var flow = [{
|
|
143
|
+
id: "n1",
|
|
144
|
+
type: "BaseNode",
|
|
145
|
+
name: "base node",
|
|
146
|
+
}];
|
|
147
|
+
|
|
148
|
+
const fakeShape = sandbox.fake(() => { return "ring" });
|
|
149
|
+
const fakeText = sandbox.fake(() => { return "text" });
|
|
150
|
+
const fakeFill = sandbox.fake(() => { return "green" });
|
|
151
|
+
const fakeStatus = sandbox.fake((status) => {
|
|
152
|
+
status.should.have.property('shape','ring');
|
|
153
|
+
status.should.have.property('text','text');
|
|
154
|
+
status.should.have.property('fill','green');
|
|
155
|
+
done();
|
|
156
|
+
});
|
|
157
|
+
sandbox.replace(BaseNode.prototype,'getStatusShape',fakeShape);
|
|
158
|
+
sandbox.replace(BaseNode.prototype,'getStatusText',fakeText);
|
|
159
|
+
sandbox.replace(BaseNode.prototype,'getStatusFill',fakeFill);
|
|
160
|
+
sandbox.replace(BaseNode.prototype,'status',fakeStatus);
|
|
161
|
+
|
|
162
|
+
helper.load(testnodes, flow, function () {
|
|
163
|
+
var n1 = helper.getNode("n1");
|
|
164
|
+
n1.updateStatus();
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should default shape to "dot" when updateStatus() is called and fill is defined', function (done) {
|
|
169
|
+
var flow = [{
|
|
170
|
+
id: "n1",
|
|
171
|
+
type: "BaseNode",
|
|
172
|
+
name: "base node",
|
|
173
|
+
}];
|
|
174
|
+
|
|
175
|
+
const fakeShape = sandbox.fake(() => { return null });
|
|
176
|
+
const fakeText = sandbox.fake(() => { return null });
|
|
177
|
+
const fakeFill = sandbox.fake(() => { return "green" });
|
|
178
|
+
const fakeStatus = sandbox.fake((status) => {
|
|
179
|
+
status.should.have.property('shape','dot');
|
|
180
|
+
done();
|
|
181
|
+
});
|
|
182
|
+
sandbox.replace(BaseNode.prototype,'getStatusShape',fakeShape);
|
|
183
|
+
sandbox.replace(BaseNode.prototype,'getStatusText',fakeText);
|
|
184
|
+
sandbox.replace(BaseNode.prototype,'getStatusFill',fakeFill);
|
|
185
|
+
sandbox.replace(BaseNode.prototype,'status',fakeStatus);
|
|
186
|
+
|
|
187
|
+
helper.load(testnodes, flow, function () {
|
|
188
|
+
var n1 = helper.getNode("n1");
|
|
189
|
+
n1.updateStatus();
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('should default fill to "grey" when updateStatus() is called and shape is defined', function (done) {
|
|
194
|
+
var flow = [{
|
|
195
|
+
id: "n1",
|
|
196
|
+
type: "BaseNode",
|
|
197
|
+
name: "base node",
|
|
198
|
+
}];
|
|
199
|
+
|
|
200
|
+
const fakeShape = sandbox.fake(() => { return "dot" });
|
|
201
|
+
const fakeText = sandbox.fake(() => { return null });
|
|
202
|
+
const fakeFill = sandbox.fake(() => { return null });
|
|
203
|
+
const fakeStatus = sandbox.fake((status) => {
|
|
204
|
+
status.should.have.property('fill','grey');
|
|
205
|
+
done();
|
|
206
|
+
});
|
|
207
|
+
sandbox.replace(BaseNode.prototype,'getStatusShape',fakeShape);
|
|
208
|
+
sandbox.replace(BaseNode.prototype,'getStatusText',fakeText);
|
|
209
|
+
sandbox.replace(BaseNode.prototype,'getStatusFill',fakeFill);
|
|
210
|
+
sandbox.replace(BaseNode.prototype,'status',fakeStatus);
|
|
211
|
+
|
|
212
|
+
helper.load(testnodes, flow, function () {
|
|
213
|
+
var n1 = helper.getNode("n1");
|
|
214
|
+
n1.updateStatus();
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('should return name if logid() is called and config.name is set', function (done) {
|
|
219
|
+
var name = "base node";
|
|
220
|
+
var flow = [{
|
|
221
|
+
id: "n1",
|
|
222
|
+
type: "BaseNode",
|
|
223
|
+
name: name,
|
|
224
|
+
}];
|
|
225
|
+
|
|
226
|
+
helper.load(testnodes, flow, function () {
|
|
227
|
+
var n1 = helper.getNode("n1");
|
|
228
|
+
assert.equal(n1.logid(),name);
|
|
229
|
+
done();
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it('should return id if logid() is called and config.name is not set', function (done) {
|
|
234
|
+
var id = "n1";
|
|
235
|
+
var flow = [{
|
|
236
|
+
id: id,
|
|
237
|
+
type: "BaseNode",
|
|
238
|
+
}];
|
|
239
|
+
|
|
240
|
+
helper.load(testnodes, flow, function () {
|
|
241
|
+
var n1 = helper.getNode(id);
|
|
242
|
+
assert.equal(n1.logid(),id);
|
|
243
|
+
done();
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//const BaseUI = require("../src/ui/BaseUI.js");
|
|
2
|
+
//import {BaseUI} from "../src/ui/BaseUI"
|
|
3
|
+
|
|
4
|
+
describe('Base UI', function () {
|
|
5
|
+
beforeEach(()=>{
|
|
6
|
+
sandbox = sinon.createSandbox();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
afterEach(function () {
|
|
10
|
+
sandbox.restore();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should store config.name property', function (done) {
|
|
14
|
+
//var ui = new BaseUI("label","category");
|
|
15
|
+
done();
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
var helper = require("node-red-node-test-helper");
|
|
2
|
+
const assert = require('assert');
|
|
3
|
+
const sinon = require('sinon');
|
|
4
|
+
const axios = require('axios');
|
|
5
|
+
|
|
6
|
+
var testnodes = function(RED) {
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
const BaseNode = require('../src/nodes/BaseNode');
|
|
10
|
+
BaseNode.nodeAPI = RED;
|
|
11
|
+
|
|
12
|
+
RED.nodes.registerType("BridgeConfigNode",BridgeConfigNode);
|
|
13
|
+
}
|
|
14
|
+
const BridgeConfigNode = require('../src/nodes/BridgeConfigNode');
|
|
15
|
+
const ClipApi = require('../src/clip/ClipApi');
|
|
16
|
+
|
|
17
|
+
describe('Bridge Config Node (instance)', function () {
|
|
18
|
+
beforeEach(()=>{
|
|
19
|
+
sandbox = sinon.createSandbox();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
afterEach(function () {
|
|
23
|
+
sandbox.restore();
|
|
24
|
+
helper.unload();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should be loaded', function (done) {
|
|
28
|
+
const fakeClip = sandbox.fake(() => { return {
|
|
29
|
+
name: "clip",
|
|
30
|
+
destructor: function() {}
|
|
31
|
+
} });
|
|
32
|
+
sandbox.replace(BridgeConfigNode.prototype,'_constructClip',fakeClip);
|
|
33
|
+
|
|
34
|
+
var flow = [{
|
|
35
|
+
id: "n1",
|
|
36
|
+
type: "BridgeConfigNode",
|
|
37
|
+
name: "bridge config node",
|
|
38
|
+
}];
|
|
39
|
+
|
|
40
|
+
helper.load(testnodes, flow, function () {
|
|
41
|
+
var n1 = helper.getNode("n1");
|
|
42
|
+
var config = n1.config;
|
|
43
|
+
config.should.have.property('name', 'bridge config node');
|
|
44
|
+
var clip = n1.clip();
|
|
45
|
+
clip.should.have.property('name','clip');
|
|
46
|
+
var bridges = BridgeConfigNode.bridges();
|
|
47
|
+
bridges['n1'].should.have.property('id','n1');
|
|
48
|
+
done();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('catch errors when executing on("close")', function (done) {
|
|
53
|
+
const fakeClip = sandbox.fake(() => { return {
|
|
54
|
+
name: "clip",
|
|
55
|
+
destructor: function() {}
|
|
56
|
+
} });
|
|
57
|
+
sandbox.replace(BridgeConfigNode.prototype,'_constructClip',fakeClip);
|
|
58
|
+
const fakeDestructor = sandbox.fake(() => { throw "Exception"; })
|
|
59
|
+
sandbox.replace(BridgeConfigNode.prototype,'destructor',fakeDestructor);
|
|
60
|
+
|
|
61
|
+
var flow = [{
|
|
62
|
+
id: "n1",
|
|
63
|
+
type: "BridgeConfigNode",
|
|
64
|
+
name: "bridge config node",
|
|
65
|
+
}];
|
|
66
|
+
|
|
67
|
+
helper.load(testnodes, flow, function () {
|
|
68
|
+
var n1 = helper.getNode("n1");
|
|
69
|
+
n1.close();
|
|
70
|
+
done();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should call clip.requestStartup when requestStartup() is called', function (done) {
|
|
75
|
+
const fakeClip = sandbox.fake(() => { return {
|
|
76
|
+
name: "clip",
|
|
77
|
+
destructor: function() {},
|
|
78
|
+
requestStartup: function() { done(); }
|
|
79
|
+
} });
|
|
80
|
+
sandbox.replace(BridgeConfigNode.prototype,'_constructClip',fakeClip);
|
|
81
|
+
|
|
82
|
+
var flow = [{
|
|
83
|
+
id: "n1",
|
|
84
|
+
type: "BridgeConfigNode",
|
|
85
|
+
name: "bridge config node",
|
|
86
|
+
}];
|
|
87
|
+
|
|
88
|
+
helper.load(testnodes, flow, function () {
|
|
89
|
+
var n1 = helper.getNode("n1");
|
|
90
|
+
n1.requestStartup("resource");
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should not attempt to call clip.requestStartup when clip is null', function (done) {
|
|
95
|
+
const fakeClip = sandbox.fake(() => { return null; } );
|
|
96
|
+
sandbox.replace(BridgeConfigNode.prototype,'_constructClip',fakeClip);
|
|
97
|
+
|
|
98
|
+
var flow = [{
|
|
99
|
+
id: "n1",
|
|
100
|
+
type: "BridgeConfigNode",
|
|
101
|
+
name: "bridge config node",
|
|
102
|
+
}];
|
|
103
|
+
|
|
104
|
+
helper.load(testnodes, flow, function () {
|
|
105
|
+
var n1 = helper.getNode("n1");
|
|
106
|
+
n1.requestStartup("resource");
|
|
107
|
+
done();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should construct Clip instance', function (done) {
|
|
112
|
+
sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
|
|
113
|
+
sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
|
|
114
|
+
sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(done);
|
|
115
|
+
|
|
116
|
+
var flow = [{
|
|
117
|
+
id: "n1",
|
|
118
|
+
type: "BridgeConfigNode",
|
|
119
|
+
name: "bridge config node",
|
|
120
|
+
}];
|
|
121
|
+
|
|
122
|
+
helper.load(testnodes, flow, function () {
|
|
123
|
+
var n1 = helper.getNode("n1");
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
describe('Bridge Config Node (static)', function () {
|
|
129
|
+
beforeEach(()=>{
|
|
130
|
+
sandbox = sinon.createSandbox();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
afterEach(function () {
|
|
134
|
+
sandbox.restore();
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('should discover bridges', function (done) {
|
|
138
|
+
var count = 0;
|
|
139
|
+
sandbox.stub(BridgeConfigNode,'_axios').callsFake(function() {
|
|
140
|
+
if (count > 0) {
|
|
141
|
+
count++;
|
|
142
|
+
//console.log("fake bridge query");
|
|
143
|
+
return Promise.resolve({ data: {}});
|
|
144
|
+
} else {
|
|
145
|
+
//console.log("fake meethue query");
|
|
146
|
+
return Promise.resolve({ data: [{ "internalipaddress": "ip" }]});
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
BridgeConfigNode.DiscoverBridges();
|
|
151
|
+
done();
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('should acquire application key', function (done) {
|
|
155
|
+
sandbox.stub(BridgeConfigNode,'_axios').callsFake(function() {
|
|
156
|
+
return Promise.resolve({ data : [
|
|
157
|
+
{ success: "username" }
|
|
158
|
+
]});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
BridgeConfigNode.AcquireApplicationKey("ip");
|
|
162
|
+
done();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should acquire application key, but returns error', function (done) {
|
|
166
|
+
sandbox.stub(BridgeConfigNode,'_axios').callsFake(function() {
|
|
167
|
+
return Promise.resolve({ data : [
|
|
168
|
+
{ error: "some error" }
|
|
169
|
+
]});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
BridgeConfigNode.AcquireApplicationKey("ip");
|
|
173
|
+
done();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('should acquire application key, but throws exception', function (done) {
|
|
177
|
+
sandbox.stub(BridgeConfigNode,'_axios').callsFake(function() {
|
|
178
|
+
return Promise.reject("trigger exception");
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
BridgeConfigNode.AcquireApplicationKey("ip");
|
|
182
|
+
done();
|
|
183
|
+
});
|
|
184
|
+
});
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
const helper = require("node-red-node-test-helper");
|
|
2
|
+
const assert = require('assert');
|
|
3
|
+
const sinon = require('sinon');
|
|
4
|
+
|
|
5
|
+
const testnodes = function(RED) {
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
const BaseNode = require('../src/nodes/BaseNode');
|
|
9
|
+
BaseNode.nodeAPI = RED;
|
|
10
|
+
|
|
11
|
+
RED.nodes.registerType("ButtonNode",ButtonNode);
|
|
12
|
+
}
|
|
13
|
+
const ButtonNode = require('../src/nodes/ButtonNode')
|
|
14
|
+
|
|
15
|
+
describe('ButtonNode', function () {
|
|
16
|
+
beforeEach(()=>{
|
|
17
|
+
sandbox = sinon.createSandbox();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterEach(function () {
|
|
21
|
+
sandbox.restore();
|
|
22
|
+
helper.unload();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should load', function (done) {
|
|
26
|
+
|
|
27
|
+
var flow = [{
|
|
28
|
+
id: "n1",
|
|
29
|
+
type: "ButtonNode",
|
|
30
|
+
name: "button node",
|
|
31
|
+
}];
|
|
32
|
+
|
|
33
|
+
helper.load(testnodes, flow, function () {
|
|
34
|
+
var n1 = helper.getNode("n1");
|
|
35
|
+
n1.should.have.property('config');
|
|
36
|
+
|
|
37
|
+
var config = n1.config;
|
|
38
|
+
config.should.have.property('name', 'button node');
|
|
39
|
+
done();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should call updateStatus() twice with 3s delay when onUpdate(event) is called', function (done) {
|
|
44
|
+
var statuscount = 0;
|
|
45
|
+
const fakeStatus = sandbox.fake(() => {
|
|
46
|
+
if (statuscount++ > 0) {
|
|
47
|
+
done()
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
sandbox.replace(ButtonNode.prototype,'updateStatus',fakeStatus);
|
|
51
|
+
|
|
52
|
+
var flow = [{
|
|
53
|
+
id: "n1",
|
|
54
|
+
type: "ButtonNode",
|
|
55
|
+
name: "button node",
|
|
56
|
+
}];
|
|
57
|
+
|
|
58
|
+
helper.load(testnodes, flow, function () {
|
|
59
|
+
var n1 = helper.getNode("n1");
|
|
60
|
+
n1.onUpdate({
|
|
61
|
+
name: "event"
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should call status() with "blue/dot/last_event" and "grey/dot/last_event"', function (done) {
|
|
67
|
+
var statuscount = 0;
|
|
68
|
+
const fakeStatus = sandbox.fake(() => {
|
|
69
|
+
var args = fakeStatus.firstArg;
|
|
70
|
+
if (statuscount++ == 0) {
|
|
71
|
+
assert.equal(args.fill,"blue");
|
|
72
|
+
assert.equal(args.shape,"dot");
|
|
73
|
+
assert.equal(args.text,"last_event");
|
|
74
|
+
} else {
|
|
75
|
+
assert.equal(args.fill,"grey");
|
|
76
|
+
assert.equal(args.shape,"dot");
|
|
77
|
+
assert.equal(args.text,"last_event");
|
|
78
|
+
done()
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
sandbox.replace(ButtonNode.prototype,'status',fakeStatus);
|
|
82
|
+
const fakeResource = sandbox.fake(() => {
|
|
83
|
+
return {
|
|
84
|
+
data: function() {
|
|
85
|
+
return { button: { last_event: "last_event" } }
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
sandbox.replace(ButtonNode.prototype,'resource',fakeResource);
|
|
90
|
+
|
|
91
|
+
var flow = [{
|
|
92
|
+
id: "n1",
|
|
93
|
+
type: "ButtonNode",
|
|
94
|
+
name: "button node",
|
|
95
|
+
}];
|
|
96
|
+
|
|
97
|
+
helper.load(testnodes, flow, function () {
|
|
98
|
+
var n1 = helper.getNode("n1");
|
|
99
|
+
n1.onUpdate({
|
|
100
|
+
button: { last_event: "last_event" }
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should call status() with "blue/dot/" and "grey/dot/" when resource==null', function (done) {
|
|
106
|
+
var statuscount = 0;
|
|
107
|
+
const fakeStatus = sandbox.fake(() => {
|
|
108
|
+
var args = fakeStatus.firstArg;
|
|
109
|
+
if (statuscount++ == 0) {
|
|
110
|
+
assert.equal(args.fill,"blue");
|
|
111
|
+
assert.equal(args.shape,"dot");
|
|
112
|
+
assert.equal(args.text,"");
|
|
113
|
+
} else {
|
|
114
|
+
assert.equal(args.fill,"grey");
|
|
115
|
+
assert.equal(args.shape,"dot");
|
|
116
|
+
assert.equal(args.text,"");
|
|
117
|
+
done()
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
sandbox.replace(ButtonNode.prototype,'status',fakeStatus);
|
|
121
|
+
const fakeResource = sandbox.fake(() => {
|
|
122
|
+
return null
|
|
123
|
+
});
|
|
124
|
+
sandbox.replace(ButtonNode.prototype,'resource',fakeResource);
|
|
125
|
+
|
|
126
|
+
var flow = [{
|
|
127
|
+
id: "n1",
|
|
128
|
+
type: "ButtonNode",
|
|
129
|
+
name: "button node",
|
|
130
|
+
}];
|
|
131
|
+
|
|
132
|
+
helper.load(testnodes, flow, function () {
|
|
133
|
+
var n1 = helper.getNode("n1");
|
|
134
|
+
n1.onUpdate({
|
|
135
|
+
button: { last_event: "last_event" }
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should call status() with "blue/dot/" and "grey/dot/" when last_event==null', function (done) {
|
|
141
|
+
var statuscount = 0;
|
|
142
|
+
const fakeStatus = sandbox.fake(() => {
|
|
143
|
+
var args = fakeStatus.firstArg;
|
|
144
|
+
if (statuscount++ == 0) {
|
|
145
|
+
assert.equal(args.fill,"blue");
|
|
146
|
+
assert.equal(args.shape,"dot");
|
|
147
|
+
assert.equal(args.text,"");
|
|
148
|
+
} else {
|
|
149
|
+
assert.equal(args.fill,"grey");
|
|
150
|
+
assert.equal(args.shape,"dot");
|
|
151
|
+
assert.equal(args.text,"");
|
|
152
|
+
done()
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
sandbox.replace(ButtonNode.prototype,'status',fakeStatus);
|
|
156
|
+
const fakeResource = sandbox.fake(() => {
|
|
157
|
+
return {
|
|
158
|
+
data: function() {
|
|
159
|
+
return { button: { last_event: null } }
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
sandbox.replace(ButtonNode.prototype,'resource',fakeResource);
|
|
164
|
+
|
|
165
|
+
var flow = [{
|
|
166
|
+
id: "n1",
|
|
167
|
+
type: "ButtonNode",
|
|
168
|
+
name: "button node",
|
|
169
|
+
}];
|
|
170
|
+
|
|
171
|
+
helper.load(testnodes, flow, function () {
|
|
172
|
+
var n1 = helper.getNode("n1");
|
|
173
|
+
n1.onUpdate({
|
|
174
|
+
button: { last_event: "last_event" }
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
});
|