iotagent-node-lib 4.5.0 → 4.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 (84) hide show
  1. package/README.md +67 -272
  2. package/doc/README.md +1 -1
  3. package/doc/admin.md +3 -15
  4. package/doc/api.md +469 -134
  5. package/doc/deprecated.md +4 -0
  6. package/doc/devel/architecture.md +5 -135
  7. package/doc/devel/development.md +224 -12
  8. package/doc/getting-started.md +114 -53
  9. package/doc/roadmap.md +5 -5
  10. package/docker/Mosquitto/Dockerfile +2 -2
  11. package/docker/Mosquitto/README.md +14 -11
  12. package/lib/constants.js +3 -0
  13. package/lib/fiware-iotagent-lib.js +12 -15
  14. package/lib/jexlTranformsMap.js +3 -1
  15. package/lib/model/dbConn.js +1 -4
  16. package/lib/services/common/alarmManagement.js +3 -0
  17. package/lib/services/groups/groupService.js +1 -1
  18. package/lib/services/ngsi/entities-NGSI-LD.js +320 -570
  19. package/lib/services/ngsi/entities-NGSI-v2.js +36 -1
  20. package/lib/services/ngsi/ngsiService.js +3 -1
  21. package/lib/services/northBound/deviceGroupAdministrationServer.js +42 -6
  22. package/lib/services/northBound/deviceProvisioningServer.js +0 -1
  23. package/lib/services/northBound/northboundServer.js +2 -0
  24. package/lib/services/stats/statsRegistry.js +128 -101
  25. package/lib/templates/createDevice.json +0 -24
  26. package/lib/templates/createDeviceLax.json +0 -23
  27. package/lib/templates/deviceGroup.json +1 -25
  28. package/lib/templates/updateDevice.json +0 -24
  29. package/lib/templates/updateDeviceLax.json +0 -23
  30. package/package.json +2 -2
  31. package/scripts/legacy_expression_tool/README.md +0 -1
  32. package/test/functional/README.md +22 -17
  33. package/test/functional/functional-tests-runner.js +9 -4
  34. package/test/functional/functional-tests.js +4 -4
  35. package/test/functional/testCases.js +245 -4
  36. package/test/unit/examples/deviceProvisioningRequests/provisionFullDevice.json +1 -13
  37. package/test/unit/examples/groupProvisioningRequests/multipleConfigGroupsCreation.json +44 -0
  38. package/test/unit/examples/groupProvisioningRequests/provisionDuplicateConfigGroup.json +35 -0
  39. package/test/unit/examples/groupProvisioningRequests/provisionFullConfigGroup.json +36 -0
  40. package/test/unit/examples/groupProvisioningRequests/provisionFullConfigGroupAlternate.json +36 -0
  41. package/test/unit/general/deviceService-test.js +102 -0
  42. package/test/unit/general/statistics-service_test.js +1 -74
  43. package/test/unit/mongodb/mongodb-configGroup-registry-test.js +452 -0
  44. package/test/unit/mongodb/mongodb-connectionoptions-test.js +2 -3
  45. package/test/unit/mongodb/mongodb-group-registry-test.js +34 -33
  46. package/test/unit/mongodb/mongodb-service-registry-test.js +477 -0
  47. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin1a.json +4 -4
  48. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin2.json +22 -22
  49. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin29.json +4 -4
  50. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin32.json +14 -15
  51. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin1.json +23 -23
  52. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin15.json +0 -5
  53. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin4.json +11 -16
  54. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin5.json +23 -28
  55. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin6.json +8 -13
  56. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin7.json +0 -5
  57. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin8.json +24 -29
  58. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin2.json +12 -17
  59. package/test/unit/ngsi-ld/examples/contextRequests/updateContextStaticLinkedAttributes.json +12 -10
  60. package/test/unit/ngsi-ld/expressions/jexlBasedTransformations-test.js +0 -102
  61. package/test/unit/ngsi-ld/plugins/multientity-plugin_test.js +4 -5
  62. package/test/unit/ngsi-ld/provisioning/listProvisionedDevices-test.js +0 -4
  63. package/test/unit/ngsiv2/general/deviceService-test.js +94 -1
  64. package/test/unit/ngsiv2/general/iotam-autoregistration-test.js +195 -0
  65. package/test/unit/ngsiv2/provisioning/device-group-api-test.js +259 -0
  66. package/test/unit/ngsiv2/provisioning/device-provisioning-configGroup-api_test.js +1189 -0
  67. package/test/unit/ngsiv2/provisioning/listProvisionedDevices-test.js +0 -4
  68. package/test/unit/statsRegistry/openmetrics-test.js +167 -0
  69. package/lib/templates/queryContext.json +0 -25
  70. package/test/unit/examples/deviceProvisioningRequests/provisionBidirectionalDevice.json +0 -35
  71. package/test/unit/examples/deviceProvisioningRequests/provisionDeviceBidirectionalGroup.json +0 -17
  72. package/test/unit/examples/groupProvisioningRequests/bidirectionalGroup.json +0 -31
  73. package/test/unit/general/statistics-persistence_test.js +0 -121
  74. package/test/unit/ngsi-ld/examples/contextRequests/createBidirectionalDevice.json +0 -17
  75. package/test/unit/ngsi-ld/examples/contextRequests/updateContextProcessTimestamp.json +0 -12
  76. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotification.json +0 -13
  77. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json +0 -21
  78. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +0 -17
  79. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json +0 -23
  80. package/test/unit/ngsi-ld/plugins/timestamp-processing-plugin_test.js +0 -132
  81. package/test/unit/ngsiv2/examples/contextRequests/createBidirectionalDevice.json +0 -8
  82. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotification.json +0 -13
  83. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +0 -19
  84. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json +0 -24
@@ -0,0 +1,1189 @@
1
+ /*
2
+ * Copyright 2024 Telefonica Investigación y Desarrollo, S.A.U
3
+ *
4
+ * This file is part of fiware-iotagent-lib
5
+ *
6
+ * fiware-iotagent-lib is free software: you can redistribute it and/or
7
+ * modify it under the terms of the GNU Affero General Public License as
8
+ * published by the Free Software Foundation, either version 3 of the License,
9
+ * or (at your option) any later version.
10
+ *
11
+ * fiware-iotagent-lib is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
+ * See the GNU Affero General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Affero General Public
17
+ * License along with fiware-iotagent-lib.
18
+ * If not, see http://www.gnu.org/licenses/.
19
+ *
20
+ * For those usages not covered by the GNU Affero General Public License
21
+ * please contact with::[contacto@tid.es]
22
+ *
23
+ * Modified by: Daniel Calvo - ATOS Research & Innovation
24
+ */
25
+
26
+ /* eslint-disable no-unused-vars */
27
+
28
+ const iotAgentLib = require('../../../../lib/fiware-iotagent-lib');
29
+ const utils = require('../../../tools/utils');
30
+ const should = require('should');
31
+ const nock = require('nock');
32
+
33
+ const request = utils.request;
34
+ const moment = require('moment');
35
+ let contextBrokerMock;
36
+ const iotAgentConfig = {
37
+ logLevel: 'FATAL',
38
+ contextBroker: {
39
+ host: '192.168.1.1',
40
+ port: '1026',
41
+ ngsiVersion: 'v2'
42
+ },
43
+ server: {
44
+ port: 4041,
45
+ host: 'localhost',
46
+ baseRoot: '/'
47
+ },
48
+ types: {},
49
+ service: 'smartgondor',
50
+ subservice: 'gardens',
51
+ providerUrl: 'http://smartgondor.com',
52
+ explicitAttrs: false
53
+ };
54
+
55
+ describe('NGSI-v2 - Device provisioning API: Provision devices', function () {
56
+ beforeEach(function (done) {
57
+ nock.cleanAll();
58
+
59
+ iotAgentLib.activate(iotAgentConfig, function () {
60
+ contextBrokerMock = nock('http://192.168.1.1:1026')
61
+ .matchHeader('fiware-service', 'smartgondor')
62
+ .matchHeader('fiware-servicepath', '/gardens')
63
+ .post(
64
+ '/v2/registrations',
65
+ utils.readExampleFile(
66
+ './test/unit/ngsiv2/examples/contextAvailabilityRequests/registerProvisionedDevice.json'
67
+ )
68
+ )
69
+ .reply(201, null, { Location: '/v2/registrations/6319a7f5254b05844116584d' });
70
+
71
+ // This mock does not check the payload since the aim of the test is not to verify
72
+ // device provisioning functionality. Appropriate verification is done in tests under
73
+ // provisioning folder
74
+ contextBrokerMock
75
+ .matchHeader('fiware-service', 'smartgondor')
76
+ .matchHeader('fiware-servicepath', '/gardens')
77
+ .post('/v2/entities?options=upsert')
78
+ .reply(204);
79
+
80
+ iotAgentLib.clearAll(done);
81
+ });
82
+ });
83
+
84
+ afterEach(function (done) {
85
+ nock.cleanAll();
86
+ iotAgentLib.setProvisioningHandler();
87
+ iotAgentLib.deactivate(done);
88
+ });
89
+
90
+ describe('When a device provisioning request with all the required data arrives to the IoT Agent', function () {
91
+ beforeEach(function () {
92
+ nock.cleanAll();
93
+ contextBrokerMock = nock('http://192.168.1.1:1026')
94
+ .matchHeader('fiware-service', 'smartgondor')
95
+ .matchHeader('fiware-servicepath', '/gardens')
96
+ .post(
97
+ '/v2/registrations',
98
+ utils.readExampleFile(
99
+ './test/unit/ngsiv2/examples/contextAvailabilityRequests/registerProvisionedDevice.json'
100
+ )
101
+ )
102
+ .reply(201, null, { Location: '/v2/registrations/6319a7f5254b05844116584d' });
103
+ });
104
+
105
+ const options = {
106
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
107
+ method: 'POST',
108
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionNewDevice.json'),
109
+ headers: {
110
+ 'fiware-service': 'smartgondor',
111
+ 'fiware-servicepath': '/gardens'
112
+ }
113
+ };
114
+
115
+ it('should add the device to the devices list', function (done) {
116
+ request(options, function (error, response, body) {
117
+ should.not.exist(error);
118
+ response.statusCode.should.equal(201);
119
+
120
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
121
+ results.devices.length.should.equal(1);
122
+ done();
123
+ });
124
+ });
125
+ });
126
+
127
+ it('should call the device provisioning handler if present', function (done) {
128
+ let handlerCalled = false;
129
+
130
+ iotAgentLib.setProvisioningHandler(function (device, callback) {
131
+ handlerCalled = true;
132
+ callback(null, device);
133
+ });
134
+
135
+ request(options, function (error, response, body) {
136
+ handlerCalled.should.equal(true);
137
+ done();
138
+ });
139
+ });
140
+
141
+ it('should store the device with the provided entity id, name and type', function (done) {
142
+ request(options, function (error, response, body) {
143
+ response.statusCode.should.equal(201);
144
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
145
+ results.devices[0].id.should.equal('Light1');
146
+ results.devices[0].name.should.equal('TheFirstLight');
147
+ results.devices[0].type.should.equal('TheLightType');
148
+ done();
149
+ });
150
+ });
151
+ });
152
+ it('should store the device with the per device information', function (done) {
153
+ request(options, function (error, response, body) {
154
+ response.statusCode.should.equal(201);
155
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
156
+ should.exist(results.devices[0].timezone);
157
+ results.devices[0].timezone.should.equal('America/Santiago');
158
+ should.exist(results.devices[0].endpoint);
159
+ results.devices[0].endpoint.should.equal('http://fakedEndpoint:1234');
160
+ should.exist(results.devices[0].transport);
161
+ results.devices[0].transport.should.equal('MQTT');
162
+ should.exist(results.devices[0].lazy);
163
+ results.devices[0].lazy.length.should.equal(1);
164
+ results.devices[0].lazy[0].name.should.equal('luminance');
165
+ should.exist(results.devices[0].staticAttributes);
166
+ results.devices[0].commands.length.should.equal(1);
167
+ results.devices[0].commands[0].name.should.equal('commandAttr');
168
+ should.exist(results.devices[0].staticAttributes);
169
+ results.devices[0].staticAttributes.length.should.equal(1);
170
+ results.devices[0].staticAttributes[0].name.should.equal('hardcodedAttr');
171
+ should.exist(results.devices[0].active);
172
+ results.devices[0].active.length.should.equal(1);
173
+ results.devices[0].active[0].name.should.equal('attr_name');
174
+ should.exist(results.devices[0].internalAttributes);
175
+ results.devices[0].internalAttributes.length.should.equal(1);
176
+ results.devices[0].internalAttributes[0].customField.should.equal('customValue');
177
+ done();
178
+ });
179
+ });
180
+ });
181
+
182
+ it('should store fill the device ID in case only the name is provided', function (done) {
183
+ /* jshint camelcase:false */
184
+ request(options, function (error, response, body) {
185
+ response.statusCode.should.equal(201);
186
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
187
+ results.devices[0].lazy[0].object_id.should.equal('luminance');
188
+ results.devices[0].commands[0].object_id.should.equal('commandAttr');
189
+ results.devices[0].active[0].object_id.should.equal('attr_name');
190
+ done();
191
+ });
192
+ });
193
+ });
194
+
195
+ it('should store service and subservice info from the headers along with the device data', function (done) {
196
+ request(options, function (error, response, body) {
197
+ response.statusCode.should.equal(201);
198
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
199
+ should.exist(results.devices[0].service);
200
+ results.devices[0].service.should.equal('smartgondor');
201
+ should.exist(results.devices[0].subservice);
202
+ results.devices[0].subservice.should.equal('/gardens');
203
+ done();
204
+ });
205
+ });
206
+ });
207
+
208
+ it('should not create the initial entity in the Context Broker', function (done) {
209
+ request(options, function (error, response, body) {
210
+ response.statusCode.should.equal(201);
211
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
212
+ contextBrokerMock.done();
213
+ done();
214
+ });
215
+ });
216
+ });
217
+ });
218
+ describe('When a device provisioning request with a TimeInstant attribute arrives to the IoTA', function () {
219
+ const options = {
220
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
221
+ method: 'POST',
222
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionTimeInstant.json'),
223
+ headers: {
224
+ 'fiware-service': 'smartgondor',
225
+ 'fiware-servicepath': '/gardens'
226
+ }
227
+ };
228
+
229
+ beforeEach(function (done) {
230
+ iotAgentLib.deactivate(function () {
231
+ iotAgentConfig.timestamp = true;
232
+ iotAgentLib.activate(iotAgentConfig, done);
233
+ });
234
+ });
235
+
236
+ afterEach(function () {
237
+ iotAgentConfig.timestamp = false;
238
+ });
239
+
240
+ beforeEach(function (done) {
241
+ nock.cleanAll();
242
+ done();
243
+ });
244
+
245
+ it('should send the appropriate requests to the Context Broker', function (done) {
246
+ request(options, function (error, response, body) {
247
+ contextBrokerMock.done();
248
+ done();
249
+ });
250
+ });
251
+ });
252
+
253
+ describe('When a device provisioning request with a timestamp provision attribute arrives to the IoTA', function () {
254
+ const options = {
255
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
256
+ method: 'POST',
257
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionTimeInstant2.json'),
258
+ headers: {
259
+ 'fiware-service': 'smartgondor',
260
+ 'fiware-servicepath': '/gardens'
261
+ }
262
+ };
263
+
264
+ beforeEach(function (done) {
265
+ iotAgentLib.deactivate(function () {
266
+ iotAgentConfig.timestamp = false;
267
+ iotAgentLib.activate(iotAgentConfig, done);
268
+ });
269
+ });
270
+
271
+ afterEach(function () {
272
+ iotAgentConfig.timestamp = false;
273
+ });
274
+
275
+ beforeEach(function (done) {
276
+ nock.cleanAll();
277
+ done();
278
+ });
279
+
280
+ it('should send the appropriate requests to the Context Broker', function (done) {
281
+ request(options, function (error, response, body) {
282
+ contextBrokerMock.done();
283
+ done();
284
+ });
285
+ });
286
+ });
287
+
288
+ describe('When a device provisioning request with explicitAttrs provision attribute arrives to the IoTA', function () {
289
+ const options = {
290
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
291
+ method: 'POST',
292
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionExplicitAttrs.json'),
293
+ headers: {
294
+ 'fiware-service': 'smartgondor',
295
+ 'fiware-servicepath': '/gardens'
296
+ }
297
+ };
298
+
299
+ beforeEach(function (done) {
300
+ iotAgentLib.deactivate(function () {
301
+ iotAgentConfig.explicitAttrs = false;
302
+ iotAgentLib.activate(iotAgentConfig, done);
303
+ });
304
+ });
305
+
306
+ afterEach(function () {
307
+ iotAgentConfig.explicitAttrs = false;
308
+ });
309
+
310
+ beforeEach(function (done) {
311
+ nock.cleanAll();
312
+ done();
313
+ });
314
+
315
+ it('should send the appropriate requests to the Context Broker', function (done) {
316
+ request(options, function (error, response, body) {
317
+ contextBrokerMock.done();
318
+ done();
319
+ });
320
+ });
321
+ it('should store the device with explicitAttrs:true device information', function (done) {
322
+ request(options, function (error, response, body) {
323
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
324
+ should.exist(results.devices[0].explicitAttrs);
325
+ results.devices[0].explicitAttrs.should.equal(true);
326
+ done();
327
+ });
328
+ });
329
+ });
330
+ });
331
+
332
+ describe(
333
+ 'When a device provisioning request without explicitAttrs provision attribute arrives to the IoTA' +
334
+ ' and explicitAttrs is not configured at group level',
335
+ function () {
336
+ const options = {
337
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
338
+ method: 'POST',
339
+ json: utils.readExampleFile(
340
+ './test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice.json'
341
+ ),
342
+ headers: {
343
+ 'fiware-service': 'smartgondor',
344
+ 'fiware-servicepath': '/gardens'
345
+ }
346
+ };
347
+
348
+ beforeEach(function (done) {
349
+ iotAgentLib.deactivate(function () {
350
+ iotAgentConfig.explicitAttrs = false;
351
+ iotAgentLib.activate(iotAgentConfig, done);
352
+ });
353
+ });
354
+
355
+ afterEach(function () {
356
+ iotAgentConfig.explicitAttrs = false;
357
+ });
358
+
359
+ beforeEach(function (done) {
360
+ nock.cleanAll();
361
+ done();
362
+ });
363
+
364
+ it('should send the appropriate requests to the Context Broker', function (done) {
365
+ request(options, function (error, response, body) {
366
+ contextBrokerMock.done();
367
+ done();
368
+ });
369
+ });
370
+ it('should store the device without explicitAttrs', function (done) {
371
+ request(options, function (error, response, body) {
372
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
373
+ should.not.exist(results.devices[0].explicitAttrs);
374
+ done();
375
+ });
376
+ });
377
+ });
378
+ }
379
+ );
380
+
381
+ describe(
382
+ 'When a device provisioning request without explicitAttrs provision attribute arrives to the IoTA' +
383
+ ' and explicitAttrs is configured at group level',
384
+ function () {
385
+ const options = {
386
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
387
+ method: 'POST',
388
+ json: utils.readExampleFile(
389
+ './test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice.json'
390
+ ),
391
+ headers: {
392
+ 'fiware-service': 'smartgondor',
393
+ 'fiware-servicepath': '/gardens'
394
+ }
395
+ };
396
+ const groupCreation = {
397
+ url: 'http://localhost:4041/iot/groups',
398
+ method: 'POST',
399
+ json: {
400
+ groups: [
401
+ {
402
+ resource: '/Thing',
403
+ apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
404
+ /*jshint camelcase: false */
405
+ entity_type: 'MicroLights',
406
+ cbroker: 'http://192.168.1.1:1026',
407
+ explicitAttrs: true
408
+ }
409
+ ]
410
+ },
411
+ headers: {
412
+ 'fiware-service': 'smartgondor',
413
+ 'fiware-servicepath': '/gardens'
414
+ }
415
+ };
416
+
417
+ beforeEach(function (done) {
418
+ nock.cleanAll();
419
+ contextBrokerMock = nock('http://192.168.1.1:1026')
420
+ .matchHeader('fiware-service', 'smartgondor')
421
+ .matchHeader('fiware-servicepath', '/gardens')
422
+ .post(
423
+ '/v2/entities?options=upsert',
424
+ utils.readExampleFile(
425
+ './test/unit/ngsiv2/examples/contextRequests/createMinimumProvisionedDevice.json'
426
+ )
427
+ )
428
+ .reply(204);
429
+
430
+ done();
431
+ });
432
+
433
+ it('should store the device without explicitAttrs value', function (done) {
434
+ request(groupCreation, function (error, response, body) {
435
+ request(options, function (error, response, body) {
436
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
437
+ should.not.exist(results.devices[0].explicitAttrs);
438
+ done();
439
+ });
440
+ });
441
+ });
442
+ });
443
+ }
444
+ );
445
+
446
+ describe(
447
+ 'When a device provisioning request without static attributes arrives to the IoTA' +
448
+ ' and static attribute is configured at group level',
449
+ function () {
450
+ const options = {
451
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
452
+ method: 'POST',
453
+ json: utils.readExampleFile(
454
+ './test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice.json'
455
+ ),
456
+ headers: {
457
+ 'fiware-service': 'smartgondor',
458
+ 'fiware-servicepath': '/gardens'
459
+ }
460
+ };
461
+ const groupCreation = {
462
+ url: 'http://localhost:4041/iot/groups',
463
+ method: 'POST',
464
+ json: {
465
+ groups: [
466
+ {
467
+ resource: '/Thing',
468
+ apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
469
+ /*jshint camelcase: false */
470
+ entity_type: 'MicroLights',
471
+ cbroker: 'http://192.168.1.1:1026',
472
+ explicitAttrs: true,
473
+ static_attributes: [
474
+ {
475
+ name: 'bootstrapServer',
476
+ type: 'Address',
477
+ value: '127.0.0.1'
478
+ }
479
+ ]
480
+ }
481
+ ]
482
+ },
483
+ headers: {
484
+ 'fiware-service': 'smartgondor',
485
+ 'fiware-servicepath': '/gardens'
486
+ }
487
+ };
488
+
489
+ beforeEach(function (done) {
490
+ nock.cleanAll();
491
+ contextBrokerMock = nock('http://192.168.1.1:1026')
492
+ .matchHeader('fiware-service', 'smartgondor')
493
+ .matchHeader('fiware-servicepath', '/gardens')
494
+ .post(
495
+ '/v2/entities?options=upsert',
496
+ utils.readExampleFile(
497
+ './test/unit/ngsiv2/examples/' +
498
+ 'contextRequests/createStaticAttributesProvisionDevice.json'
499
+ )
500
+ )
501
+ .reply(204);
502
+
503
+ done();
504
+ });
505
+
506
+ it('should not store the device with static attributes provided in configuration', function (done) {
507
+ request(groupCreation, function (error, response, body) {
508
+ request(options, function (error, response, body) {
509
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
510
+ should.exist(results.devices[0].staticAttributes);
511
+ results.devices[0].staticAttributes.length.should.equal(0);
512
+ done();
513
+ });
514
+ });
515
+ });
516
+ });
517
+ }
518
+ );
519
+ describe(
520
+ 'When a device provisioning request with static attributes arrives to the IoTA' +
521
+ ' and static attribute is not configured at group level',
522
+ function () {
523
+ const options = {
524
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
525
+ method: 'POST',
526
+ json: utils.readExampleFile(
527
+ './test/unit/examples/deviceProvisioningRequests/provisionStaticAttrsDevice.json'
528
+ ),
529
+ headers: {
530
+ 'fiware-service': 'smartgondor',
531
+ 'fiware-servicepath': '/gardens'
532
+ }
533
+ };
534
+ const groupCreation = {
535
+ url: 'http://localhost:4041/iot/groups',
536
+ method: 'POST',
537
+ json: {
538
+ groups: [
539
+ {
540
+ resource: '/Thing',
541
+ apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
542
+ /*jshint camelcase: false */
543
+ entity_type: 'MicroLights',
544
+ cbroker: 'http://192.168.1.1:1026',
545
+ explicitAttrs: true
546
+ }
547
+ ]
548
+ },
549
+ headers: {
550
+ 'fiware-service': 'smartgondor',
551
+ 'fiware-servicepath': '/gardens'
552
+ }
553
+ };
554
+
555
+ beforeEach(function (done) {
556
+ nock.cleanAll();
557
+ contextBrokerMock = nock('http://192.168.1.1:1026')
558
+ .matchHeader('fiware-service', 'smartgondor')
559
+ .matchHeader('fiware-servicepath', '/gardens')
560
+ .post(
561
+ '/v2/entities?options=upsert',
562
+ utils.readExampleFile(
563
+ './test/unit/ngsiv2/examples/' +
564
+ 'contextRequests/createStaticAttributesProvisionDevice.json'
565
+ )
566
+ )
567
+ .reply(204);
568
+
569
+ done();
570
+ });
571
+
572
+ it('should store the device with static attributes provided in device', function (done) {
573
+ request(groupCreation, function (error, response, body) {
574
+ request(options, function (error, response, body) {
575
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
576
+ should.exist(results.devices[0].staticAttributes);
577
+ results.devices[0].staticAttributes[0].name.should.equal('bootstrapServer');
578
+ done();
579
+ });
580
+ });
581
+ });
582
+ });
583
+ }
584
+ );
585
+
586
+ describe(
587
+ 'When a device provisioning request with static attributes arrives to the IoTA' +
588
+ ' and static attribute is also configured at group level',
589
+ function () {
590
+ const options = {
591
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
592
+ method: 'POST',
593
+ json: utils.readExampleFile(
594
+ './test/unit/examples/deviceProvisioningRequests/provisionStaticAttrsDevice2.json'
595
+ ),
596
+ headers: {
597
+ 'fiware-service': 'smartgondor',
598
+ 'fiware-servicepath': '/gardens'
599
+ }
600
+ };
601
+ const groupCreation = {
602
+ url: 'http://localhost:4041/iot/groups',
603
+ method: 'POST',
604
+ json: {
605
+ groups: [
606
+ {
607
+ resource: '/Thing',
608
+ apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
609
+ /*jshint camelcase: false */
610
+ entity_type: 'MicroLights',
611
+ cbroker: 'http://192.168.1.1:1026',
612
+ explicitAttrs: true,
613
+ static_attributes: [
614
+ {
615
+ name: 'bootstrapServer',
616
+ type: 'Address',
617
+ value: '127.0.0.1'
618
+ }
619
+ ]
620
+ }
621
+ ]
622
+ },
623
+ headers: {
624
+ 'fiware-service': 'smartgondor',
625
+ 'fiware-servicepath': '/gardens'
626
+ }
627
+ };
628
+
629
+ beforeEach(function (done) {
630
+ nock.cleanAll();
631
+ contextBrokerMock = nock('http://192.168.1.1:1026')
632
+ .matchHeader('fiware-service', 'smartgondor')
633
+ .matchHeader('fiware-servicepath', '/gardens')
634
+ .post(
635
+ '/v2/entities?options=upsert',
636
+ utils.readExampleFile(
637
+ './test/unit/ngsiv2/examples/' +
638
+ 'contextRequests/createStaticAttributesProvisionDevice2.json'
639
+ )
640
+ )
641
+ .reply(204);
642
+
643
+ done();
644
+ });
645
+
646
+ it('should store the device with static attributes provided in configuration as well as device', function (done) {
647
+ request(groupCreation, function (error, response, body) {
648
+ request(options, function (error, response, body) {
649
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
650
+ should.exist(results.devices[0].staticAttributes);
651
+ results.devices[0].staticAttributes.length.should.equal(1);
652
+ done();
653
+ });
654
+ });
655
+ });
656
+ });
657
+ }
658
+ );
659
+
660
+ describe(
661
+ 'When a device provisioning request with static attributes arrives to the IoTA' +
662
+ ' and same static attribute is also configured at group level',
663
+ function () {
664
+ const options = {
665
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
666
+ method: 'POST',
667
+ json: utils.readExampleFile(
668
+ './test/unit/examples/deviceProvisioningRequests/provisionStaticAttrsDevice3.json'
669
+ ),
670
+ headers: {
671
+ 'fiware-service': 'smartgondor',
672
+ 'fiware-servicepath': '/gardens'
673
+ }
674
+ };
675
+ const groupCreation = {
676
+ url: 'http://localhost:4041/iot/groups',
677
+ method: 'POST',
678
+ json: {
679
+ groups: [
680
+ {
681
+ resource: '/Thing',
682
+ apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
683
+ /*jshint camelcase: false */
684
+ entity_type: 'MicroLights',
685
+ cbroker: 'http://192.168.1.1:1026',
686
+ explicitAttrs: true,
687
+ static_attributes: [
688
+ {
689
+ name: 'bootstrapServer',
690
+ type: 'Address',
691
+ value: '127.0.0.1'
692
+ }
693
+ ]
694
+ }
695
+ ]
696
+ },
697
+ headers: {
698
+ 'fiware-service': 'smartgondor',
699
+ 'fiware-servicepath': '/gardens'
700
+ }
701
+ };
702
+
703
+ beforeEach(function (done) {
704
+ nock.cleanAll();
705
+ contextBrokerMock = nock('http://192.168.1.1:1026')
706
+ .matchHeader('fiware-service', 'smartgondor')
707
+ .matchHeader('fiware-servicepath', '/gardens')
708
+ .post(
709
+ '/v2/entities?options=upsert',
710
+ utils.readExampleFile(
711
+ './test/unit/ngsiv2/examples/' +
712
+ 'contextRequests/createStaticAttributesProvisionDevice3.json'
713
+ )
714
+ )
715
+ .reply(204);
716
+
717
+ done();
718
+ });
719
+
720
+ it('should store the device with static attributes provided in device', function (done) {
721
+ request(groupCreation, function (error, response, body) {
722
+ request(options, function (error, response, body) {
723
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
724
+ should.exist(results.devices[0].staticAttributes);
725
+ results.devices[0].staticAttributes[0].value.should.equal('127.0.0.2');
726
+ done();
727
+ });
728
+ });
729
+ });
730
+ });
731
+ }
732
+ );
733
+
734
+ describe('When a device provisioning request with a autoprovision attribute arrives to the IoTA', function () {
735
+ const options = {
736
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
737
+ method: 'POST',
738
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionAutoprovision.json'),
739
+ headers: {
740
+ 'fiware-service': 'smartgondor',
741
+ 'fiware-servicepath': '/gardens'
742
+ }
743
+ };
744
+
745
+ beforeEach(function (done) {
746
+ iotAgentLib.deactivate(function () {
747
+ iotAgentLib.activate(iotAgentConfig, done);
748
+ });
749
+ });
750
+
751
+ afterEach(function () {});
752
+
753
+ beforeEach(function (done) {
754
+ nock.cleanAll();
755
+ done();
756
+ });
757
+
758
+ it('should send the appropriate requests to the Context Broker', function (done) {
759
+ request(options, function (error, response, body) {
760
+ done();
761
+ });
762
+ });
763
+ });
764
+
765
+ describe('When a device provisioning request arrives to the IoTAand timestamp is enabled in configuration', function () {
766
+ const options = {
767
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
768
+ method: 'POST',
769
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice.json'),
770
+ headers: {
771
+ 'fiware-service': 'smartgondor',
772
+ 'fiware-servicepath': '/gardens'
773
+ }
774
+ };
775
+
776
+ beforeEach(function (done) {
777
+ iotAgentLib.deactivate(function () {
778
+ iotAgentConfig.timestamp = true;
779
+ iotAgentLib.activate(iotAgentConfig, done);
780
+ });
781
+ });
782
+
783
+ afterEach(function () {
784
+ iotAgentConfig.timestamp = false;
785
+ });
786
+
787
+ beforeEach(function (done) {
788
+ nock.cleanAll();
789
+
790
+ done();
791
+ });
792
+
793
+ it('should send the any request to the Context Broker', function (done) {
794
+ request(options, function (error, response, body) {
795
+ done();
796
+ });
797
+ });
798
+ });
799
+
800
+ describe('When a device provisioning request with the minimum required data arrives to the IoT Agent', function () {
801
+ const options = {
802
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
803
+ method: 'POST',
804
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice.json'),
805
+ headers: {
806
+ 'fiware-service': 'smartgondor',
807
+ 'fiware-servicepath': '/gardens'
808
+ }
809
+ };
810
+
811
+ beforeEach(function (done) {
812
+ nock.cleanAll();
813
+ done();
814
+ });
815
+
816
+ it('should send the any request to the Context Broker', function (done) {
817
+ request(options, function (error, response, body) {
818
+ done();
819
+ });
820
+ });
821
+
822
+ it('should add the device to the devices list', function (done) {
823
+ request(options, function (error, response, body) {
824
+ should.not.exist(error);
825
+ response.statusCode.should.equal(201);
826
+
827
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
828
+ results.devices.length.should.equal(1);
829
+ done();
830
+ });
831
+ });
832
+ });
833
+
834
+ it('should store the device with the provided entity id, name and type', function (done) {
835
+ request(options, function (error, response, body) {
836
+ response.statusCode.should.equal(201);
837
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
838
+ results.devices[0].id.should.equal('MicroLight1');
839
+ results.devices[0].name.should.equal('FirstMicroLight');
840
+ results.devices[0].type.should.equal('MicroLights');
841
+ done();
842
+ });
843
+ });
844
+ });
845
+ });
846
+
847
+ describe('When a device provisioning request with geo:point attributes arrives', function () {
848
+ const options = {
849
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
850
+ method: 'POST',
851
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionGeopointDevice.json'),
852
+ headers: {
853
+ 'fiware-service': 'smartgondor',
854
+ 'fiware-servicepath': '/gardens'
855
+ }
856
+ };
857
+
858
+ beforeEach(function (done) {
859
+ nock.cleanAll();
860
+ done();
861
+ });
862
+
863
+ it('should send any initial values to the Context Broker', function (done) {
864
+ request(options, function (error, response, body) {
865
+ done();
866
+ });
867
+ });
868
+ });
869
+
870
+ describe('When a device provisioning request with DateTime attributes arrives', function () {
871
+ const options = {
872
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
873
+ method: 'POST',
874
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionDatetimeDevice.json'),
875
+ headers: {
876
+ 'fiware-service': 'smartgondor',
877
+ 'fiware-servicepath': '/gardens'
878
+ }
879
+ };
880
+
881
+ beforeEach(function (done) {
882
+ nock.cleanAll();
883
+ done();
884
+ });
885
+
886
+ it('should send any initial values to the Context Broker', function (done) {
887
+ request(options, function (error, response, body) {
888
+ done();
889
+ });
890
+ });
891
+ });
892
+
893
+ describe('When two devices with the same ID but different services arrive to the agent', function () {
894
+ const options1 = {
895
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
896
+ method: 'POST',
897
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice.json'),
898
+ headers: {
899
+ 'fiware-service': 'smartgondor',
900
+ 'fiware-servicepath': '/gardens'
901
+ }
902
+ };
903
+ const options2 = {
904
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
905
+ method: 'POST',
906
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice.json'),
907
+ headers: {
908
+ 'fiware-service': 'smartMordor',
909
+ 'fiware-servicepath': '/electricity'
910
+ }
911
+ };
912
+
913
+ beforeEach(function (done) {
914
+ nock.cleanAll();
915
+ contextBrokerMock = nock('http://192.168.1.1:1026')
916
+ .post(
917
+ '/v2/entities?options=upsert',
918
+ utils.readExampleFile(
919
+ './test/unit/ngsiv2/examples/contextRequests/createMinimumProvisionedDevice.json'
920
+ )
921
+ )
922
+ .reply(204);
923
+
924
+ contextBrokerMock
925
+ .post(
926
+ '/v2/entities?options=upsert',
927
+ utils.readExampleFile(
928
+ './test/unit/ngsiv2/examples/contextRequests/createMinimumProvisionedDevice.json'
929
+ )
930
+ )
931
+ .reply(204);
932
+
933
+ done();
934
+ });
935
+
936
+ it('should accept both creations', function (done) {
937
+ request(options1, function (error, response, body) {
938
+ response.statusCode.should.equal(201);
939
+
940
+ request(options2, function (error, response, body) {
941
+ response.statusCode.should.equal(201);
942
+ done();
943
+ });
944
+ });
945
+ });
946
+
947
+ it('should show the new device in each list', function (done) {
948
+ request(options1, function (error, response, body) {
949
+ request(options2, function (error, response, body) {
950
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
951
+ results.devices.length.should.equal(1);
952
+ results.devices[0].id.should.equal('MicroLight1');
953
+
954
+ iotAgentLib.listDevices('smartMordor', '/electricity', function (error, results) {
955
+ results.devices.length.should.equal(1);
956
+ results.devices[0].id.should.equal('MicroLight1');
957
+ done();
958
+ });
959
+ });
960
+ });
961
+ });
962
+ });
963
+ });
964
+
965
+ describe('When there is a connection error with a String code connecting the CB', function () {
966
+ const options = {
967
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
968
+ method: 'POST',
969
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice.json'),
970
+ headers: {
971
+ 'fiware-service': 'smartgondor',
972
+ 'fiware-servicepath': '/gardens'
973
+ }
974
+ };
975
+
976
+ beforeEach(function (done) {
977
+ nock.cleanAll();
978
+
979
+ contextBrokerMock = nock('http://192.168.1.1:1026')
980
+ .matchHeader('fiware-service', 'smartgondor')
981
+ .matchHeader('fiware-servicepath', '/gardens')
982
+ .post('/v2/registrations')
983
+ .reply(201, null, { Location: '/v2/registrations/6319a7f5254b05844116584d' });
984
+ done();
985
+ });
986
+
987
+ it('should return a valid return code', function (done) {
988
+ request(options, function (error, response, body) {
989
+ should.not.exist(error);
990
+ response.statusCode.should.equal(201);
991
+
992
+ done();
993
+ });
994
+ });
995
+ });
996
+
997
+ describe('When there is a connection error with a Number code connecting the CB', function () {
998
+ const options = {
999
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
1000
+ method: 'POST',
1001
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice.json'),
1002
+ headers: {
1003
+ 'fiware-service': 'smartgondor',
1004
+ 'fiware-servicepath': '/gardens'
1005
+ }
1006
+ };
1007
+
1008
+ beforeEach(function (done) {
1009
+ nock.cleanAll();
1010
+
1011
+ contextBrokerMock = nock('http://192.168.1.1:1026')
1012
+ .matchHeader('fiware-service', 'smartgondor')
1013
+ .matchHeader('fiware-servicepath', '/gardens')
1014
+ .post('/v2/registrations')
1015
+ .reply(201, null, { Location: '/v2/registrations/6319a7f5254b05844116584d' });
1016
+
1017
+ done();
1018
+ });
1019
+
1020
+ it('should return a valid return code (three character number)', function (done) {
1021
+ request(options, function (error, response, body) {
1022
+ should.not.exist(error);
1023
+ response.statusCode.should.equal(201);
1024
+
1025
+ done();
1026
+ });
1027
+ });
1028
+ });
1029
+
1030
+ describe('When a device provisioning request with missing data arrives to the IoT Agent', function () {
1031
+ const options = {
1032
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
1033
+ method: 'POST',
1034
+ headers: {
1035
+ 'fiware-service': 'smartgondor',
1036
+ 'fiware-servicepath': '/gardens'
1037
+ },
1038
+ json: utils.readExampleFile(
1039
+ './test/unit/examples/deviceProvisioningRequests/provisionDeviceMissingParameters.json'
1040
+ )
1041
+ };
1042
+
1043
+ it('should raise a MISSING_ATTRIBUTES error, indicating the missing attributes', function (done) {
1044
+ request(options, function (error, response, body) {
1045
+ should.exist(body);
1046
+ response.statusCode.should.equal(400);
1047
+ body.name.should.equal('MISSING_ATTRIBUTES');
1048
+ body.message.should.match(/.*device_id.*/);
1049
+ done();
1050
+ });
1051
+ });
1052
+ });
1053
+ describe('When two device provisioning requests with the same service and Device ID arrive', function () {
1054
+ const options = {
1055
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
1056
+ method: 'POST',
1057
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionNewDevice.json'),
1058
+ headers: {
1059
+ 'fiware-service': 'smartgondor',
1060
+ 'fiware-servicepath': '/gardens'
1061
+ }
1062
+ };
1063
+
1064
+ beforeEach(function (done) {
1065
+ contextBrokerMock = nock('http://192.168.1.1:1026')
1066
+ .matchHeader('fiware-service', 'smartgondor')
1067
+ .matchHeader('fiware-servicepath', '/gardens')
1068
+ .post('/v2/registrations')
1069
+ .reply(201, null, { Location: '/v2/registrations/6319a7f5254b05844116584d' });
1070
+
1071
+ // This mock does not check the payload since the aim of the test is not to verify
1072
+ // device provisioning functionality. Appropriate verification is done in tests under
1073
+ // provisioning folder
1074
+ contextBrokerMock
1075
+ .matchHeader('fiware-service', 'smartgondor')
1076
+ .matchHeader('fiware-servicepath', '/gardens')
1077
+ .post('/v2/entities?options=upsert')
1078
+ .reply(204);
1079
+
1080
+ done();
1081
+ });
1082
+
1083
+ it('should raise a DUPLICATE_ID error, indicating the ID was already in use', function (done) {
1084
+ request(options, function (error, response, body) {
1085
+ request(options, function (error, response, body) {
1086
+ should.exist(body);
1087
+ response.statusCode.should.equal(409);
1088
+ body.name.should.equal('DUPLICATE_DEVICE_ID');
1089
+ done();
1090
+ });
1091
+ });
1092
+ });
1093
+ });
1094
+ describe('When a device provisioning request is malformed', function () {
1095
+ const options = {
1096
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
1097
+ method: 'POST',
1098
+ json: utils.readExampleFile(
1099
+ './test/unit/examples/deviceProvisioningRequests/provisionNewDeviceMalformed1.json'
1100
+ ),
1101
+ headers: {
1102
+ 'fiware-service': 'smartgondor',
1103
+ 'fiware-servicepath': '/gardens'
1104
+ }
1105
+ };
1106
+
1107
+ it('should raise a WRONG_SYNTAX exception', function (done) {
1108
+ request(options, function (error, response, body) {
1109
+ request(options, function (error, response, body) {
1110
+ should.exist(body);
1111
+ response.statusCode.should.equal(400);
1112
+ body.name.should.equal('WRONG_SYNTAX');
1113
+ done();
1114
+ });
1115
+ });
1116
+ });
1117
+ });
1118
+ describe('When an agent is activated with a different base root', function () {
1119
+ const options = {
1120
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/newBaseRoot/iot/devices',
1121
+ method: 'POST',
1122
+ headers: {
1123
+ 'fiware-service': 'smartgondor',
1124
+ 'fiware-servicepath': '/gardens'
1125
+ },
1126
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionNewDevice.json')
1127
+ };
1128
+
1129
+ beforeEach(function (done) {
1130
+ iotAgentLib.deactivate(function () {
1131
+ iotAgentConfig.server.baseRoot = '/newBaseRoot';
1132
+ iotAgentLib.activate(iotAgentConfig, done);
1133
+ });
1134
+ });
1135
+
1136
+ afterEach(function () {
1137
+ iotAgentConfig.server.baseRoot = '/';
1138
+ });
1139
+
1140
+ it('should listen to requests in the new root', function (done) {
1141
+ request(options, function (error, response, body) {
1142
+ should.not.exist(error);
1143
+ response.statusCode.should.equal(201);
1144
+
1145
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
1146
+ results.devices.length.should.equal(1);
1147
+ done();
1148
+ });
1149
+ });
1150
+ });
1151
+ });
1152
+ describe('When a device provisioning request without the mandatory headers arrives to the Agent', function () {
1153
+ const options = {
1154
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
1155
+ method: 'POST',
1156
+ headers: {},
1157
+ json: utils.readExampleFile(
1158
+ './test/unit/examples/deviceProvisioningRequests/provisionDeviceMissingParameters.json'
1159
+ )
1160
+ };
1161
+
1162
+ it('should raise a MISSING_HEADERS error, indicating the missing attributes', function (done) {
1163
+ request(options, function (error, response, body) {
1164
+ should.exist(body);
1165
+ response.statusCode.should.equal(400);
1166
+ body.name.should.equal('MISSING_HEADERS');
1167
+ done();
1168
+ });
1169
+ });
1170
+ });
1171
+ describe('When a device delete request arrives to the Agent for a not existing device', function () {
1172
+ const options = {
1173
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices/Light84',
1174
+ headers: {
1175
+ 'fiware-service': 'smartgondor',
1176
+ 'fiware-servicepath': '/gardens'
1177
+ },
1178
+ method: 'DELETE'
1179
+ };
1180
+
1181
+ it('should return a 404 error', function (done) {
1182
+ request(options, function (error, response, body) {
1183
+ should.not.exist(error);
1184
+ response.statusCode.should.equal(404);
1185
+ done();
1186
+ });
1187
+ });
1188
+ });
1189
+ });