@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.
Files changed (162) hide show
  1. package/.github/workflows/node.js.yml +31 -0
  2. package/.nyc_output/ecb1b16f-015c-458b-96d5-32cb9569c1e8.json +1 -0
  3. package/.nyc_output/processinfo/ecb1b16f-015c-458b-96d5-32cb9569c1e8.json +1 -0
  4. package/.nyc_output/processinfo/index.json +1 -0
  5. package/.vscode/settings.json +15 -0
  6. package/.vscode/sftp.json +11 -0
  7. package/LICENSE +201 -0
  8. package/README.md +340 -0
  9. package/Todo.txt +18 -0
  10. package/coverage/BaseNode.js.html +379 -0
  11. package/coverage/base.css +224 -0
  12. package/coverage/block-navigation.js +87 -0
  13. package/coverage/favicon.png +0 -0
  14. package/coverage/index.html +101 -0
  15. package/coverage/lcov-report/base.css +224 -0
  16. package/coverage/lcov-report/block-navigation.js +87 -0
  17. package/coverage/lcov-report/favicon.png +0 -0
  18. package/coverage/lcov-report/index.html +161 -0
  19. package/coverage/lcov-report/prettify.css +1 -0
  20. package/coverage/lcov-report/prettify.js +2 -0
  21. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  22. package/coverage/lcov-report/sorter.js +196 -0
  23. package/coverage/lcov-report/src/RestApi.js.html +499 -0
  24. package/coverage/lcov-report/src/all.js.html +208 -0
  25. package/coverage/lcov-report/src/clip/ClipApi.js.html +1096 -0
  26. package/coverage/lcov-report/src/clip/Resource.js.html +481 -0
  27. package/coverage/lcov-report/src/clip/index.html +131 -0
  28. package/coverage/lcov-report/src/debug.js.html +253 -0
  29. package/coverage/lcov-report/src/files.js.html +118 -0
  30. package/coverage/lcov-report/src/index.html +161 -0
  31. package/coverage/lcov-report/src/nodes/BaseNode.js.html +381 -0
  32. package/coverage/lcov-report/src/nodes/BridgeConfigNode.js.html +817 -0
  33. package/coverage/lcov-report/src/nodes/ButtonNode.js.html +241 -0
  34. package/coverage/lcov-report/src/nodes/DevicePowerNode.js.html +199 -0
  35. package/coverage/lcov-report/src/nodes/GroupedLightNode.js.html +226 -0
  36. package/coverage/lcov-report/src/nodes/LightLevelNode.js.html +205 -0
  37. package/coverage/lcov-report/src/nodes/LightNode.js.html +226 -0
  38. package/coverage/lcov-report/src/nodes/MotionNode.js.html +205 -0
  39. package/coverage/lcov-report/src/nodes/RelativeRotaryNode.js.html +253 -0
  40. package/coverage/lcov-report/src/nodes/ResourceNode.js.html +388 -0
  41. package/coverage/lcov-report/src/nodes/SceneNode.js.html +124 -0
  42. package/coverage/lcov-report/src/nodes/ServiceNode.js.html +124 -0
  43. package/coverage/lcov-report/src/nodes/TemperatureNode.js.html +205 -0
  44. package/coverage/lcov-report/src/nodes/ZigbeeConnectivityNode.js.html +199 -0
  45. package/coverage/lcov-report/src/nodes/index.html +311 -0
  46. package/coverage/lcov-report/src/ui/BaseUI.js.html +484 -0
  47. package/coverage/lcov-report/src/ui/BridgeConfigUI.js.html +475 -0
  48. package/coverage/lcov-report/src/ui/ButtonUI.js.html +166 -0
  49. package/coverage/lcov-report/src/ui/DevicePowerUI.js.html +166 -0
  50. package/coverage/lcov-report/src/ui/GroupedLightUI.js.html +178 -0
  51. package/coverage/lcov-report/src/ui/LightLevelUI.js.html +166 -0
  52. package/coverage/lcov-report/src/ui/LightUI.js.html +178 -0
  53. package/coverage/lcov-report/src/ui/MotionUI.js.html +166 -0
  54. package/coverage/lcov-report/src/ui/RelativeRotaryUI.js.html +166 -0
  55. package/coverage/lcov-report/src/ui/ResourceUI.js.html +511 -0
  56. package/coverage/lcov-report/src/ui/SceneUI.js.html +160 -0
  57. package/coverage/lcov-report/src/ui/ServiceUI.js.html +868 -0
  58. package/coverage/lcov-report/src/ui/TemperatureUI.js.html +166 -0
  59. package/coverage/lcov-report/src/ui/ZigbeeConnectivityUI.js.html +166 -0
  60. package/coverage/lcov-report/src/ui/index.html +311 -0
  61. package/coverage/lcov.info +2217 -0
  62. package/coverage/prettify.css +1 -0
  63. package/coverage/prettify.js +2 -0
  64. package/coverage/sort-arrow-sprite.png +0 -0
  65. package/coverage/sorter.js +196 -0
  66. package/coverage/src/RestApi.js.html +499 -0
  67. package/coverage/src/all.js.html +208 -0
  68. package/coverage/src/clip/ClipApi.js.html +1183 -0
  69. package/coverage/src/clip/Resource.js.html +481 -0
  70. package/coverage/src/clip/index.html +131 -0
  71. package/coverage/src/debug.js.html +253 -0
  72. package/coverage/src/files.js.html +118 -0
  73. package/coverage/src/index.html +116 -0
  74. package/coverage/src/nodes/BaseNode.js.html +379 -0
  75. package/coverage/src/nodes/BridgeConfigNode.js.html +517 -0
  76. package/coverage/src/nodes/ButtonNode.js.html +238 -0
  77. package/coverage/src/nodes/DevicePowerNode.js.html +196 -0
  78. package/coverage/src/nodes/GroupedLightNode.js.html +223 -0
  79. package/coverage/src/nodes/LightLevelNode.js.html +202 -0
  80. package/coverage/src/nodes/LightNode.js.html +223 -0
  81. package/coverage/src/nodes/MotionNode.js.html +202 -0
  82. package/coverage/src/nodes/RelativeRotaryNode.js.html +250 -0
  83. package/coverage/src/nodes/ResourceNode.js.html +373 -0
  84. package/coverage/src/nodes/SceneNode.js.html +124 -0
  85. package/coverage/src/nodes/ServiceNode.js.html +124 -0
  86. package/coverage/src/nodes/TemperatureNode.js.html +202 -0
  87. package/coverage/src/nodes/ZigbeeConnectivityNode.js.html +199 -0
  88. package/coverage/src/nodes/index.html +311 -0
  89. package/coverage/src/ui/BaseUI.js.html +484 -0
  90. package/coverage/src/ui/BridgeConfigUI.js.html +475 -0
  91. package/coverage/src/ui/ButtonUI.js.html +166 -0
  92. package/coverage/src/ui/DevicePowerUI.js.html +166 -0
  93. package/coverage/src/ui/GroupedLightUI.js.html +178 -0
  94. package/coverage/src/ui/LightLevelUI.js.html +166 -0
  95. package/coverage/src/ui/LightUI.js.html +178 -0
  96. package/coverage/src/ui/MotionUI.js.html +166 -0
  97. package/coverage/src/ui/RelativeRotaryUI.js.html +166 -0
  98. package/coverage/src/ui/ResourceUI.js.html +511 -0
  99. package/coverage/src/ui/SceneUI.js.html +160 -0
  100. package/coverage/src/ui/ServiceUI.js.html +868 -0
  101. package/coverage/src/ui/TemperatureUI.js.html +166 -0
  102. package/coverage/src/ui/ZigbeeConnectivityUI.js.html +166 -0
  103. package/coverage/src/ui/index.html +311 -0
  104. package/examples/flows.json +959 -0
  105. package/package.json +53 -0
  106. package/screenshots/Screenshot from 2022-11-29 00-29-23.png +0 -0
  107. package/screenshots/Screenshot from 2022-11-29 00-30-16.png +0 -0
  108. package/screenshots/Screenshot from 2022-11-29 00-30-58.png +0 -0
  109. package/screenshots/Screenshot from 2022-11-29 00-31-29.png +0 -0
  110. package/src/RestApi.js +138 -0
  111. package/src/all.html +52 -0
  112. package/src/all.js +42 -0
  113. package/src/clip/ClipApi.js +367 -0
  114. package/src/clip/Resource.js +132 -0
  115. package/src/debug.js +56 -0
  116. package/src/files.js +12 -0
  117. package/src/hue.js +98 -0
  118. package/src/nodes/BaseNode.js +98 -0
  119. package/src/nodes/BridgeConfigNode.js +144 -0
  120. package/src/nodes/ButtonNode.js +51 -0
  121. package/src/nodes/DevicePowerNode.js +37 -0
  122. package/src/nodes/GroupedLightNode.js +46 -0
  123. package/src/nodes/LightLevelNode.js +39 -0
  124. package/src/nodes/LightNode.js +46 -0
  125. package/src/nodes/MotionNode.js +39 -0
  126. package/src/nodes/RelativeRotaryNode.js +55 -0
  127. package/src/nodes/ResourceNode.js +95 -0
  128. package/src/nodes/SceneNode.js +13 -0
  129. package/src/nodes/ServiceNode.js +13 -0
  130. package/src/nodes/TemperatureNode.js +39 -0
  131. package/src/nodes/ZigbeeConnectivityNode.js +38 -0
  132. package/src/ui/BaseUI.js +133 -0
  133. package/src/ui/BridgeConfigUI.js +130 -0
  134. package/src/ui/ButtonUI.js +27 -0
  135. package/src/ui/DevicePowerUI.js +27 -0
  136. package/src/ui/GroupedLightUI.js +31 -0
  137. package/src/ui/LightLevelUI.js +27 -0
  138. package/src/ui/LightUI.js +31 -0
  139. package/src/ui/MotionUI.js +27 -0
  140. package/src/ui/RelativeRotaryUI.js +27 -0
  141. package/src/ui/ResourceUI.js +142 -0
  142. package/src/ui/SceneUI.js +25 -0
  143. package/src/ui/ServiceUI.js +261 -0
  144. package/src/ui/TemperatureUI.js +27 -0
  145. package/src/ui/ZigbeeConnectivityUI.js +27 -0
  146. package/test/BaseNode_spec.js +246 -0
  147. package/test/BaseUI_spec.js +17 -0
  148. package/test/BridgeConfigNode_spec.js +184 -0
  149. package/test/ButtonNode_spec.js +178 -0
  150. package/test/ClipApi_spec.js +769 -0
  151. package/test/DevicePowerNode_spec.js +186 -0
  152. package/test/GroupedLightNode_spec.js +218 -0
  153. package/test/LightLevelNode_spec.js +154 -0
  154. package/test/LightNode_spec.js +218 -0
  155. package/test/MotionNode_spec.js +186 -0
  156. package/test/RelativeRotataryNode_spec.js +325 -0
  157. package/test/ResourceNode_spec.js +308 -0
  158. package/test/Resource_spec.js +392 -0
  159. package/test/SceneNode_spec.js +33 -0
  160. package/test/ServiceNode_spec.js +33 -0
  161. package/test/TemperatureNode_spec.js +153 -0
  162. package/test/ZigbeeConnectivityNode_spec.js +186 -0
@@ -0,0 +1,769 @@
1
+ const ClipApi = require('../src/clip/ClipApi')
2
+ const sinon = require('sinon');
3
+ //const { assert } = require('chai');
4
+ const assert = require('assert');
5
+
6
+ describe('ClipApi', function () {
7
+ beforeEach(()=>{
8
+ sandbox = sinon.createSandbox();
9
+ });
10
+
11
+ afterEach(function () {
12
+ sandbox.restore();
13
+ });
14
+
15
+ it('should call _initRestApi() on construction', function (done) {
16
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => done());
17
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
18
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
19
+ var clip = new ClipApi();
20
+ clip.destructor();
21
+ });
22
+
23
+ it('should call _initEventStream on construction', function (done) {
24
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
25
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => done());
26
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
27
+ var clip = new ClipApi();
28
+ clip.destructor();
29
+ });
30
+
31
+ it('should call _requestResources on construction', function (done) {
32
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
33
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
34
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => done());
35
+ var clip = new ClipApi();
36
+ clip.destructor();
37
+ });
38
+
39
+ it('should return restApi value when _restApi() is called', function (done) {
40
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => "test");
41
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
42
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => done());
43
+ var clip = new ClipApi();
44
+ assert.equal(clip._restApi(),"test");
45
+ clip.destructor();
46
+ });
47
+
48
+ // =============================
49
+ // TODO:
50
+ // _initEventStream
51
+ // =============================
52
+
53
+ it('should call _processStreamEvent when _processStreamMessage is called and message is present', function (done) {
54
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
55
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
56
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
57
+ sandbox.stub(ClipApi.prototype,'_processStreamEvent').callsFake(() => done());
58
+
59
+ var clip = new ClipApi();
60
+ clip._processStreamMessage({
61
+ data: '[{"creationtime":"2022-12-06T00:19:58Z","data":[{"id":"34d36d20-6e6b-4f53-a56f-30ce325ece5f","id_v1":"/sensors/49","light":{"light_level":0,"light_level_valid":true},"owner":{"rid":"57f16acb-0939-40bd-9ed0-5641205e5a81","rtype":"device"},"type":"light_level"}],"id":"59f491f9-a9be-4e7a-b128-37cdb17b4ed0","type":"update"}]'
62
+ });
63
+ clip.destructor();
64
+ });
65
+
66
+ it('should call getResource(event.rid).onEvent(event) when _processStreamEvent is called and message is present', function (done) {
67
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
68
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
69
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
70
+ sandbox.stub(ClipApi.prototype,'_isResourceRegistered').callsFake(() => true);
71
+ sandbox.stub(ClipApi.prototype,'getResource').callsFake(() => {
72
+ return {
73
+ onEvent: function(event) {
74
+ done();
75
+ }
76
+ };
77
+ });
78
+
79
+ var clip = new ClipApi();
80
+ clip._processStreamEvent({
81
+ "id": "34d36d20-6e6b-4f53-a56f-30ce325ece5f",
82
+ "id_v1": "/sensors/49",
83
+ "light": {
84
+ "light_level": 0,
85
+ "light_level_valid": true
86
+ },
87
+ "owner": {
88
+ "rid": "57f16acb-0939-40bd-9ed0-5641205e5a81",
89
+ "rtype": "device"
90
+ },
91
+ "type": "light_level"
92
+ });
93
+ clip.destructor();
94
+ });
95
+
96
+ it('should not call getResource(event.rid).onEvent(event) if resource is not registered', function (done) {
97
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
98
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
99
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
100
+ sandbox.stub(ClipApi.prototype,'_isResourceRegistered').callsFake(() => false);
101
+ sandbox.stub(ClipApi.prototype,'getResource').callsFake(() => assert.fail('should not reach here') );
102
+
103
+ var clip = new ClipApi();
104
+ clip._processStreamEvent({
105
+ "id": "34d36d20-6e6b-4f53-a56f-30ce325ece5f",
106
+ "id_v1": "/sensors/49",
107
+ "light": {
108
+ "light_level": 0,
109
+ "light_level_valid": true
110
+ },
111
+ "owner": {
112
+ "rid": "57f16acb-0939-40bd-9ed0-5641205e5a81",
113
+ "rtype": "device"
114
+ },
115
+ "type": "light_level"
116
+ });
117
+ clip.destructor();
118
+ done();
119
+ });
120
+
121
+ it('should call _processResources and _restApi when _requestResources is called', function (done) {
122
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
123
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
124
+ sandbox.stub(ClipApi.prototype,'_processResources').callsFake(() => done());
125
+
126
+ sandbox.stub(ClipApi.prototype,'_restApi').callsFake(() => {
127
+ return {
128
+ get: function(url) {
129
+ return new Promise((resolve,reject) => {
130
+ assert.equal(url,"/clip/v2/resource")
131
+ resolve();
132
+ });
133
+ }
134
+ };
135
+ });
136
+
137
+ var clip = new ClipApi();
138
+ // _requestResources is called during construction.
139
+ clip.destructor();
140
+ });
141
+
142
+ it('should catch errors when _requestResources triggers an error condition while calling _restApi().get fails', function (done) {
143
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
144
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
145
+ sandbox.stub(ClipApi.prototype,'_processResources').callsFake(() => { throw "exception" });
146
+
147
+ sandbox.stub(ClipApi.prototype,'_restApi').callsFake(() => {
148
+ return {
149
+ get: function(url) {
150
+ return new Promise((resolve,reject) => {
151
+ assert.equal(url,"/clip/v2/resource")
152
+ reject();
153
+ });
154
+ }
155
+ };
156
+ });
157
+
158
+ var clip = new ClipApi();
159
+ // _requestResources is called during construction.
160
+ clip.destructor();
161
+ done();
162
+ });
163
+
164
+ it('should register resources when _processResources is called', function (done) {
165
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
166
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
167
+ sandbox.stub(ClipApi.prototype,'_isResourceRegistered').callsFake(() => false);
168
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
169
+ sandbox.stub(ClipApi.prototype,'_registerResource').callsFake((resource) => {
170
+ assert.equal(resource.id(),"button/1284f4e7-f0d6-4736-b93f-41df5456a989");
171
+ });
172
+
173
+ var clip = new ClipApi();
174
+ clip._processResources({
175
+ data: [
176
+ { type: "button", id: "1284f4e7-f0d6-4736-b93f-41df5456a989" }
177
+ ]
178
+ });
179
+ clip.destructor();
180
+ done();
181
+ });
182
+
183
+ it('should not register resources when _processResources is called but _isResourceRegistered returns true', function (done) {
184
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
185
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
186
+ sandbox.stub(ClipApi.prototype,'_isResourceRegistered').callsFake(() =>true);
187
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
188
+ sandbox.stub(ClipApi.prototype,'_registerResource').callsFake((resource) => {
189
+ throw "exceptions";
190
+ });
191
+
192
+ var clip = new ClipApi();
193
+ clip._processResources({
194
+ data: [
195
+ { type: "button", id: "1284f4e7-f0d6-4736-b93f-41df5456a989" }
196
+ ]
197
+ });
198
+ clip.destructor();
199
+ done();
200
+ });
201
+
202
+ it('should call _isResourceRegistered when _processResources is called with unknonw type', function (done) {
203
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
204
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
205
+ sandbox.stub(ClipApi.prototype,'_isResourceRegistered').callsFake(() =>true);
206
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
207
+ sandbox.stub(ClipApi.prototype,'_registerResource').callsFake((resource) => {
208
+ throw "exceptions";
209
+ });
210
+
211
+ var clip = new ClipApi();
212
+ clip._processResources({
213
+ data: [
214
+ { type: "unknown", id: "1284f4e7-f0d6-4736-b93f-41df5456a989" }
215
+ ]
216
+ });
217
+ clip.destructor();
218
+ done();
219
+ });
220
+
221
+ it('should call resource.start() when _processResources is called and registered resources are present in the Q', function (done) {
222
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
223
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
224
+ sandbox.stub(ClipApi.prototype,'_isResourceRegistered').callsFake(() =>true);
225
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
226
+ sandbox.stub(ClipApi.prototype,'_registerResource').callsFake((resource) => {
227
+ throw "exceptions";
228
+ });
229
+
230
+ var clip = new ClipApi();
231
+ clip.requestStartup({
232
+ rid: function() {
233
+ return "resource";
234
+ },
235
+ start: function() {
236
+ done();
237
+ }
238
+ });
239
+ clip._processResources({
240
+ data: [
241
+ { type: "unknown", id: "1284f4e7-f0d6-4736-b93f-41df5456a989" }
242
+ ]
243
+ });
244
+ clip.destructor();
245
+ });
246
+
247
+ it('should not have registered resources after startup', function (done) {
248
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
249
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
250
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
251
+
252
+ var clip = new ClipApi();
253
+ var result = clip._isResourceRegistered("1284f4e7-f0d6-4736-b93f-41df5456a989");
254
+ assert.equal(result,false);
255
+ clip.destructor();
256
+ done();
257
+ });
258
+
259
+ it('should return true when _isResourceRegistered is called for registered resource ids', function (done) {
260
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
261
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
262
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
263
+
264
+ var clip = new ClipApi();
265
+ clip._registerResource({
266
+ id: function() { return "1284f4e7-f0d6-4736-b93f-41df5456a989"; },
267
+ rid: function() { return "1284f4e7-f0d6-4736-b93f-41df5456a989"; }
268
+ });
269
+ var result = clip._isResourceRegistered("1284f4e7-f0d6-4736-b93f-41df5456a989");
270
+ assert.equal(result,true);
271
+ clip._unregisterResource({
272
+ id: function() { return "1284f4e7-f0d6-4736-b93f-41df5456a989"; },
273
+ rid: function() { return "1284f4e7-f0d6-4736-b93f-41df5456a989"; }
274
+ });
275
+ clip.destructor();
276
+ done();
277
+ });
278
+
279
+ it('should call resource.start() when a resource calls requestsStartup() after clip has started.', function (done) {
280
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
281
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
282
+ sandbox.stub(ClipApi.prototype,'_isResourceRegistered').callsFake(() =>true);
283
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
284
+ sandbox.stub(ClipApi.prototype,'_registerResource').callsFake((resource) => {
285
+ throw "exceptions";
286
+ });
287
+
288
+ var clip = new ClipApi();
289
+ clip._processResources({
290
+ data: [
291
+ { type: "unknown", id: "1284f4e7-f0d6-4736-b93f-41df5456a989" }
292
+ ]
293
+ });
294
+ clip.requestStartup({
295
+ rid: function() {
296
+ return "resource";
297
+ },
298
+ start: function() {
299
+ done();
300
+ }
301
+ });
302
+ clip.destructor();
303
+ });
304
+
305
+ it('should call eventSource.close() when _stopEventStream() is called.', function (done) {
306
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
307
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => {
308
+ return {
309
+ onmessage: "message",
310
+ close: function() {
311
+ done();
312
+ }
313
+ };
314
+ });
315
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
316
+ var clip = new ClipApi();
317
+ // _stopEventStream is called from destructor();
318
+ clip.destructor();
319
+ });
320
+
321
+ it('should return appropriate resource when getResource() is called with registered rid.', function (done) {
322
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
323
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
324
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
325
+ var clip = new ClipApi();
326
+ var resource = {
327
+ id: function() { return "id"; },
328
+ rid: function() { return "rid"; }
329
+ };
330
+ clip._registerResource(resource);
331
+ assert.equal(clip.getResource(resource.rid()),resource);
332
+ clip._unregisterResource(resource);
333
+ clip.destructor();
334
+ done();
335
+ });
336
+
337
+ it('should return null when getResource() is called with unregisterd rid.', function (done) {
338
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
339
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
340
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
341
+ var clip = new ClipApi();
342
+ assert.equal(clip.getResource("unregistered id"), null);
343
+ clip.destructor();
344
+ done();
345
+ });
346
+
347
+ it('should call _restApi().get() when get() is called.', function (done) {
348
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
349
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
350
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
351
+ sandbox.stub(ClipApi.prototype,'_restApi').callsFake(() => {
352
+ return {
353
+ get: function(url) {
354
+ assert.equal(url,"/clip/v2/resource/rtype/rid");
355
+ done();
356
+ }
357
+ }
358
+ });
359
+ var clip = new ClipApi();
360
+ clip.get("rtype","rid");
361
+ clip.destructor();
362
+ });
363
+
364
+ it('should call _restApi().put() when put() is called.', function (done) {
365
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
366
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
367
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
368
+ sandbox.stub(ClipApi.prototype,'_restApi').callsFake(() => {
369
+ return {
370
+ put: function(url,data) {
371
+ assert.equal(url,"/clip/v2/resource/rtype/rid");
372
+ assert.equal(data,"data");
373
+ done();
374
+ }
375
+ }
376
+ });
377
+ var clip = new ClipApi();
378
+ clip.put("rtype","rid","data");
379
+ clip.destructor();
380
+ });
381
+
382
+ it('should call _restApi().post() when post() is called.', function (done) {
383
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
384
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
385
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
386
+ sandbox.stub(ClipApi.prototype,'_restApi').callsFake(() => {
387
+ return {
388
+ post: function(url,data) {
389
+ assert.equal(url,"/clip/v2/resource/rtype/rid");
390
+ assert.equal(data,"data");
391
+ done();
392
+ }
393
+ }
394
+ });
395
+ var clip = new ClipApi();
396
+ clip.post("rtype","rid","data");
397
+ clip.destructor();
398
+ });
399
+
400
+ it('should call _restApi().delete() when delete() is called.', function (done) {
401
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
402
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
403
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
404
+ sandbox.stub(ClipApi.prototype,'_restApi').callsFake(() => {
405
+ return {
406
+ delete: function(url,data) {
407
+ assert.equal(url,"/clip/v2/resource/rtype/rid");
408
+ assert.equal(data,"data");
409
+ done();
410
+ }
411
+ }
412
+ });
413
+ var clip = new ClipApi();
414
+ clip.delete("rtype","rid","data");
415
+ clip.destructor();
416
+ });
417
+
418
+ it('should return matching types when getSortedResourceByTypeAndModel is called.', function (done) {
419
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
420
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
421
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
422
+
423
+ var resources = [
424
+ {
425
+ id: function() { return "my button"; },
426
+ rid: function() { return "bc7402c9-84fe-4b51-9ca3-0623995337e4"; },
427
+ rtype: function() { return "button"; },
428
+ data: function() { return { } }
429
+ },
430
+ {
431
+ id: function() { return "my light"; },
432
+ rid: function() { return "91848489-27e1-48ff-9e27-8746a0a92cd6"; },
433
+ rtype: function() { return "light"; },
434
+ data: function() { return { } }
435
+ },
436
+ {
437
+ id: function() { return "a light"; },
438
+ rid: function() { return "7df6f521-c78e-496e-8914-ef1b75737a81"; },
439
+ rtype: function() { return "light"; },
440
+ data: function() { return { } }
441
+ },
442
+ {
443
+ id: function() { return "my light"; },
444
+ rid: function() { return "96ef1ccd-e580-41e3-a5f2-d3aecd6ccd66"; },
445
+ rtype: function() { return "light"; },
446
+ data: function() { return { } }
447
+ },
448
+ {
449
+ id: function() { return "yet another light"; },
450
+ rid: function() { return "75f94a58-b34e-4f6a-b9f6-9ee3841ed42f"; },
451
+ rtype: function() { return "light"; },
452
+ data: function() { return { product_data: { model_id: "model" } } }
453
+ },
454
+ ];
455
+
456
+ var clip = new ClipApi();
457
+ resources.forEach(resource => {
458
+ clip._registerResource(resource);
459
+ });
460
+ var result1 = clip.getSortedResourcesByTypeAndModel("light");
461
+ assert.equal(result1.length,4);
462
+ var result2 = clip.getSortedResourcesByTypeAndModel("button");
463
+ assert.equal(result2.length,1);
464
+ var result3 = clip.getSortedResourcesByTypeAndModel("light",["model"]);
465
+ assert.equal(result3.length,1);
466
+ resources.forEach(resource => {
467
+ clip._unregisterResource(resource);
468
+ });
469
+ clip.destructor();
470
+ done();
471
+ });
472
+
473
+ it('should return matching types when getSortedResourceOptions is called.', function (done) {
474
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
475
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
476
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
477
+ sandbox.stub(ClipApi.prototype,'getSortedResourcesByTypeAndModel').callsFake(() => {
478
+ return [
479
+ {
480
+ rid: function() { return "e23ce504-d180-43e7-bd04-560cc6b92706"; },
481
+ name: function() { return "my light";},
482
+ rtype: function() { return "light"; }
483
+ },
484
+ {
485
+ rid: function() { return "61bfa38e-5c69-4c36-9c01-9b91e42c3b36"; },
486
+ name: function() { return "my light";},
487
+ rtype: function() { return "light"; }
488
+ },
489
+ {
490
+ rid: function() { return "e5a796b2-2f6a-4ea1-894e-34295d03c96a"; },
491
+ name: function() { return "a light";},
492
+ rtype: function() { return "light"; }
493
+ },
494
+ {
495
+ rid: function() { return "957c7833-d480-4b3b-ae59-603106443adc"; },
496
+ name: function() { return "some light";},
497
+ rtype: function() { return "light"; }
498
+ },
499
+ {
500
+ id: function() { return "0f062369-2151-42c7-8b6c-203f9c3141ee"; },
501
+ rid: function() { return "0f062369-2151-42c7-8b6c-203f9c3141ee"; },
502
+ name: function() { return null;},
503
+ rtype: function() { return "light"; }
504
+ }
505
+ ];
506
+ });
507
+
508
+ var clip = new ClipApi();
509
+ var result = clip.getSortedResourceOptions("light");
510
+ assert.equal(result.length,5);
511
+ clip.destructor();
512
+
513
+ done();
514
+ });
515
+
516
+ it('should return matching types when getSortedTypeOptions is called.', function (done) {
517
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
518
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
519
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
520
+
521
+ var resources = [
522
+ {
523
+ id: function() { return "041b26f5-cb27-40ea-955c-8436285823cd"; },
524
+ rid: function() { return "041b26f5-cb27-40ea-955c-8436285823cd"; },
525
+ rtype: function() { return "zigbee_connectivity"; },
526
+ owner: function() { return "owner"; }
527
+ },
528
+ {
529
+ id: function() { return "cfebc28a-ecae-4c68-86ba-ac69f33aa6e1"; },
530
+ rid: function() { return "cfebc28a-ecae-4c68-86ba-ac69f33aa6e1"; },
531
+ rtype: function() { return "zigbee_connectivity"; },
532
+ owner: function() { return "owner"; }
533
+ },
534
+ {
535
+ id: function() { return "6570a67a-b2de-4fb2-bc12-03d586536f71"; },
536
+ rid: function() { return "6570a67a-b2de-4fb2-bc12-03d586536f71"; },
537
+ rtype: function() { return "motion"; },
538
+ owner: function() { return "owner"; }
539
+ },
540
+ {
541
+ id: function() { return "72ff9667-88e5-4e84-ab7e-0fbe2f2b7f89"; },
542
+ rid: function() { return "72ff9667-88e5-4e84-ab7e-0fbe2f2b7f89"; },
543
+ rtype: function() { return "device_power"; },
544
+ owner: function() { return "owner"; }
545
+ },
546
+ {
547
+ id: function() { return "0fb708f6-dfea-4c7a-9f09-2d6f0d941eb1"; },
548
+ rid: function() { return "0fb708f6-dfea-4c7a-9f09-2d6f0d941eb1"; },
549
+ rtype: function() { return "temperature"; },
550
+ owner: function() { return "owner"; }
551
+ },
552
+ {
553
+ id: function() { return "31d66d0b-e75a-451f-97fd-76c8ca458c29"; },
554
+ rid: function() { return "31d66d0b-e75a-451f-97fd-76c8ca458c29"; },
555
+ rtype: function() { return "light_level"; },
556
+ owner: function() { return "owner"; }
557
+ },
558
+ {
559
+ id: function() { return "a1c0daf9-1c10-44b5-8258-b0f2d862ea91"; },
560
+ rid: function() { return "a1c0daf9-1c10-44b5-8258-b0f2d862ea91"; },
561
+ rtype: function() { return "light_level"; },
562
+ owner: function() { return null; }
563
+ },
564
+ ];
565
+
566
+ var clip = new ClipApi();
567
+ resources.forEach(resource => {
568
+ clip._registerResource(resource);
569
+ });
570
+ var result = clip.getSortedTypeOptions();
571
+ assert.equal(result.length,5);
572
+ resources.forEach(resource => {
573
+ clip._unregisterResource(resource);
574
+ });
575
+ clip.destructor();
576
+
577
+ done();
578
+ });
579
+
580
+ it('should return matching types when getSortedOwnerOptions is called.', function (done) {
581
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
582
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
583
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
584
+
585
+ var resources = [
586
+ {
587
+ id: function() { return "041b26f5-cb27-40ea-955c-8436285823cd"; },
588
+ rid: function() { return "041b26f5-cb27-40ea-955c-8436285823cd"; },
589
+ rtype: function() { return "device"; },
590
+ name: function() { return "name2"; },
591
+ services: function() { return [
592
+ {
593
+ id: function() { return "7ae38812-75e1-4393-bbeb-ab9db8726d2c"; },
594
+ rid: function() { return "7ae38812-75e1-4393-bbeb-ab9db8726d2c"; },
595
+ rtype: function() { return "device_power"; },
596
+ },
597
+ {
598
+ id: function() { return "bde386c8-fe79-4cad-9609-491e50d412f5"; },
599
+ rid: function() { return "bde386c8-fe79-4cad-9609-491e50d412f5"; },
600
+ rtype: function() { return "zigbee_connectivity"; },
601
+ }
602
+ ]; }
603
+ },
604
+ {
605
+ id: function() { return "84216428-9c3d-4c03-85b7-9e42adbbe975"; },
606
+ rid: function() { return "84216428-9c3d-4c03-85b7-9e42adbbe975"; },
607
+ rtype: function() { return "device"; },
608
+ name: function() { return "name1"; },
609
+ services: function() { return [
610
+ {
611
+ id: function() { return "c9aef6ff-1ba6-4d92-b9a9-4f87e95e90b0"; },
612
+ rid: function() { return "c9aef6ff-1ba6-4d92-b9a9-4f87e95e90b0"; },
613
+ rtype: function() { return "device_power"; },
614
+ },
615
+ {
616
+ id: function() { return "3731be73-36fb-4d04-8a57-086eb51f80c8"; },
617
+ rid: function() { return "3731be73-36fb-4d04-8a57-086eb51f80c8"; },
618
+ rtype: function() { return "zigbee_connectivity"; },
619
+ }
620
+ ]; }
621
+ },
622
+ {
623
+ id: function() { return "8d9341f8-63d5-46d6-8b41-7da87290b398"; },
624
+ rid: function() { return "8d9341f8-63d5-46d6-8b41-7da87290b398"; },
625
+ rtype: function() { return "device"; },
626
+ name: function() { return "name3"; },
627
+ services: function() { return [
628
+ {
629
+ id: function() { return "f85fae4c-5996-434d-8598-bfc4364de5d8"; },
630
+ rid: function() { return "f85fae4c-5996-434d-8598-bfc4364de5d8"; },
631
+ rtype: function() { return "device_power"; },
632
+ },
633
+ {
634
+ id: function() { return "7d3b7ed2-c619-4d62-8232-c738f35ca25e"; },
635
+ rid: function() { return "7d3b7ed2-c619-4d62-8232-c738f35ca25e"; },
636
+ rtype: function() { return "zigbee_connectivity"; },
637
+ }
638
+ ]; }
639
+ },
640
+ {
641
+ id: function() { return "9e66209b-f177-4411-8ab6-65277589f39c"; },
642
+ rid: function() { return "9e66209b-f177-4411-8ab6-65277589f39c"; },
643
+ rtype: function() { return "device"; },
644
+ name: function() { return "name1"; },
645
+ services: function() { return [
646
+ {
647
+ id: function() { return "6fd13b8c-1e60-4bb9-b43e-a2bd53ff328f"; },
648
+ rid: function() { return "6fd13b8c-1e60-4bb9-b43e-a2bd53ff328f"; },
649
+ rtype: function() { return "device_power"; },
650
+ },
651
+ {
652
+ id: function() { return "161df2c4-6f5d-4a70-809b-de33dfc1b094"; },
653
+ rid: function() { return "161df2c4-6f5d-4a70-809b-de33dfc1b094"; },
654
+ rtype: function() { return "zigbee_connectivity"; },
655
+ }
656
+ ]; }
657
+ },
658
+ {
659
+ id: function() { return "006a2033-c3ba-479d-9120-a31fe4682ce6"; },
660
+ rid: function() { return "006a2033-c3ba-479d-9120-a31fe4682ce6"; },
661
+ rtype: function() { return "device"; },
662
+ name: function() { return "name"; },
663
+ }
664
+ ];
665
+
666
+ var clip = new ClipApi();
667
+ resources.forEach(resource => {
668
+ clip._registerResource(resource);
669
+ });
670
+ var result = clip.getSortedOwnerOptions("zigbee_connectivity");
671
+ assert.equal(result.length,4);
672
+ resources.forEach(resource => {
673
+ clip._unregisterResource(resource);
674
+ });
675
+ clip.destructor();
676
+
677
+ done();
678
+ });
679
+
680
+ it('should return matching types when getSortedServiceOptions is called.', function (done) {
681
+ sandbox.stub(ClipApi.prototype,'_initRestApi').callsFake(() => null);
682
+ sandbox.stub(ClipApi.prototype,'_initEventStream').callsFake(() => null);
683
+ sandbox.stub(ClipApi.prototype,'_requestResources').callsFake(() => null);
684
+
685
+ var resources = [
686
+ {
687
+ id: function() { return "8d9341f8-63d5-46d6-8b41-7da87290b398"; },
688
+ rid: function() { return "8d9341f8-63d5-46d6-8b41-7da87290b398"; },
689
+ rtype: function() { return "device"; },
690
+ name: function() { return "name3"; },
691
+ services: function() { return [
692
+ {
693
+ id: function() { return "f85fae4c-5996-434d-8598-bfc4364de5d8"; },
694
+ rid: function() { return "f85fae4c-5996-434d-8598-bfc4364de5d8"; },
695
+ rtype: function() { return "device_power"; },
696
+ },
697
+ {
698
+ id: function() { return "7d3b7ed2-c619-4d62-8232-c738f35ca25e"; },
699
+ rid: function() { return "7d3b7ed2-c619-4d62-8232-c738f35ca25e"; },
700
+ rtype: function() { return "zigbee_connectivity"; },
701
+ }
702
+ ]; }
703
+ },
704
+ {
705
+ id: function() { return "9e66209b-f177-4411-8ab6-65277589f39c"; },
706
+ rid: function() { return "9e66209b-f177-4411-8ab6-65277589f39c"; },
707
+ rtype: function() { return "device"; },
708
+ name: function() { return "name1"; },
709
+ services: function() { return [
710
+ {
711
+ id: function() { return "6fd13b8c-1e60-4bb9-b43e-a2bd53ff328f"; },
712
+ rid: function() { return "6fd13b8c-1e60-4bb9-b43e-a2bd53ff328f"; },
713
+ rtype: function() { return "device_power"; },
714
+ typeName: function() { return "device_power"; },
715
+ },
716
+ {
717
+ id: function() { return "161df2c4-6f5d-4a70-809b-de33dfc1b094"; },
718
+ rid: function() { return "161df2c4-6f5d-4a70-809b-de33dfc1b094"; },
719
+ rtype: function() { return "zigbee_connectivity"; },
720
+ typeName: function() { return "zigbee_connectivity"; },
721
+ },
722
+ {
723
+ id: function() { return "0469dfdf-1ff4-445e-8186-8199f8e83d82"; },
724
+ rid: function() { return "0469dfdf-1ff4-445e-8186-8199f8e83d82"; },
725
+ rtype: function() { return "button"; },
726
+ typeName: function() { return "button1"; },
727
+ },
728
+ {
729
+ id: function() { return "button2"; },
730
+ rid: function() { return "636030af-eca9-4b19-90ff-39463f6182f3"; },
731
+ rtype: function() { return "button"; },
732
+ typeName: function() { return "button3"; },
733
+ },
734
+ {
735
+ id: function() { return "button2"; },
736
+ rid: function() { return "636030af-eca9-4b19-90ff-39463f6182f3"; },
737
+ rtype: function() { return "button"; },
738
+ typeName: function() { return "button2"; },
739
+ },
740
+ {
741
+ id: function() { return "button2"; },
742
+ rid: function() { return "636030af-eca9-4b19-90ff-39463f6182f3"; },
743
+ rtype: function() { return "button"; },
744
+ typeName: function() { return "button4"; },
745
+ },
746
+ {
747
+ id: function() { return "button2"; },
748
+ rid: function() { return "636030af-eca9-4b19-90ff-39463f6182f3"; },
749
+ rtype: function() { return "button"; },
750
+ typeName: function() { return "button4"; },
751
+ }
752
+ ]; }
753
+ }
754
+ ];
755
+
756
+ var clip = new ClipApi();
757
+ resources.forEach(resource => {
758
+ clip._registerResource(resource);
759
+ });
760
+ var result = clip.getSortedServiceOptions("9e66209b-f177-4411-8ab6-65277589f39c","button");
761
+ assert.equal(result.length,5);
762
+ resources.forEach(resource => {
763
+ clip._unregisterResource(resource);
764
+ });
765
+ clip.destructor();
766
+
767
+ done();
768
+ });
769
+ });