UNPKG

iotagent-node-lib

Version:

IoT Agent library to interface with NGSI Context Broker

1,362 lines (1,357 loc) 181 kB
/* * Copyright 2023 Telefonica Investigación y Desarrollo, S.A.U * * This file is part of iotagent-json * * iotagent-json is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * iotagent-json is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public * License along with iotagent-json. * If not, seehttp://www.gnu.org/licenses/. * * For those usages not covered by the GNU Affero General Public License * please contact with::[contacto@tid.es] * * Modified by: Miguel Angel Pedraza */ /* eslint-disable no-unused-vars*/ /* eslint-disable no-unused-expressions*/ const config = require('./config-test.js'); var chai = require('chai'); var chaiMatchPattern = require('chai-match-pattern'); chai.use(chaiMatchPattern); var _ = chaiMatchPattern.getLodashModule(); chai.config.truncateThreshold = 0; const globalEnv = { service: 'smartgondor', servicePath: '/gardens', apikey: '123456', entity_type: 'TestType', entity_name: 'TestType:TestDevice', deviceId: 'TestDevice' }; const testCases = [ // 0000 - BASIC TESTS { describeName: '0010 - Simple group without attributes', provision: { url: 'http://localhost:' + config.iota.server.port + '/iot/services', method: 'POST', json: { services: [ { resource: '/iot/json', apikey: globalEnv.apikey, entity_type: globalEnv.entity_type, commands: [], lazy: [], attributes: [], static_attributes: [] } ] }, headers: { 'fiware-service': globalEnv.service, 'fiware-servicepath': globalEnv.servicePath } }, should: [ { // loglevel: 'debug', shouldName: 'A - WHEN sending measures through http IT should send measures to Context Broker preserving value types', config: { type: 'single' }, measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { a: false, b: 10, c: 'text', d: 10.5, e: [1, 2], f: { a: 1, b: 2 } } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, a: { value: false, type: 'Text' }, b: { value: 10, type: 'Text' }, c: { type: 'Text', value: 'text' }, d: { type: 'Text', value: 10.5 }, e: { type: 'Text', value: [1, 2] }, f: { type: 'Text', value: { a: 1, b: 2 } } } }, { transport: 'MQTT', shouldName: 'B - WHEN sending measures through mqtt IT should send measures to Context Broker preserving value types', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { a: false, b: 10, c: 'text', d: 10.5, e: [1, 2], f: { a: 1, b: 2 } } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, a: { value: false, type: 'Text' }, b: { value: 10, type: 'Text' }, c: { type: 'Text', value: 'text' }, d: { type: 'Text', value: 10.5 }, e: { type: 'Text', value: [1, 2] }, f: { type: 'Text', value: { a: 1, b: 2 } } } } ] }, { describeName: '0020 - Simple group with active attributes', provision: { url: 'http://localhost:' + config.iota.server.port + '/iot/services', method: 'POST', json: { services: [ { resource: '/iot/json', apikey: globalEnv.apikey, entity_type: globalEnv.entity_type, commands: [], lazy: [], attributes: [ { object_id: 'a', name: 'attr_a', type: 'Boolean' }, { object_id: 'b', name: 'attr_b', type: 'Integer' }, { object_id: 'c', name: 'attr_c', type: 'Text' }, { object_id: 'd', name: 'attr_d', type: 'Float' }, { object_id: 'e', name: 'attr_e', type: 'Array' }, { object_id: 'f', name: 'attr_f', type: 'Object' } ], static_attributes: [] } ] }, headers: { 'fiware-service': globalEnv.service, 'fiware-servicepath': globalEnv.servicePath } }, should: [ { shouldName: 'A - WHEN sending defined object_ids (measures) through http IT should send measures to Context Broker preserving value types and name mappings', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { a: false, b: 10, c: 'text', d: 10.5, e: [1, 2], f: { a: 1, b: 2 } } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, attr_a: { value: false, type: 'Boolean' }, attr_b: { value: 10, type: 'Integer' }, attr_c: { type: 'Text', value: 'text' }, attr_d: { type: 'Float', value: 10.5 }, attr_e: { type: 'Array', value: [1, 2] }, attr_f: { type: 'Object', value: { a: 1, b: 2 } } } }, { shouldName: 'B - WHEN sending defined object_ids (measures) through mqtt IT should send measures to Context Broker preserving value types and name mappings', transport: 'MQTT', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { a: false, b: 10, c: 'text', d: 10.5, e: [1, 2], f: { a: 1, b: 2 } } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, attr_a: { value: false, type: 'Boolean' }, attr_b: { value: 10, type: 'Integer' }, attr_c: { type: 'Text', value: 'text' }, attr_d: { type: 'Float', value: 10.5 }, attr_e: { type: 'Array', value: [1, 2] }, attr_f: { type: 'Object', value: { a: 1, b: 2 } } } }, { shouldName: 'C - WHEN sending undefined object_ids (measures) through http IT should send measures to Context Broker preserving value types', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { u: false, v: 10, w: 'text', y: 10.5, x: [1, 2], z: { a: 1, b: 2 } } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, u: { value: false, type: 'Text' }, v: { value: 10, type: 'Text' }, w: { type: 'Text', value: 'text' }, y: { type: 'Text', value: 10.5 }, x: { type: 'Text', value: [1, 2] }, z: { type: 'Text', value: { a: 1, b: 2 } } } }, { shouldName: 'D - WHEN sending undefined object_ids (measures) through mqtt IT should send measures to Context Broker preserving value types', transport: 'MQTT', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { u: false, v: 10, w: 'text', y: 10.5, x: [1, 2], z: { a: 1, b: 2 } } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, u: { value: false, type: 'Text' }, v: { value: 10, type: 'Text' }, w: { type: 'Text', value: 'text' }, y: { type: 'Text', value: 10.5 }, x: { type: 'Text', value: [1, 2] }, z: { type: 'Text', value: { a: 1, b: 2 } } } } ] }, { describeName: '0021 - Simple group with active attributes with metadata', provision: { url: 'http://localhost:' + config.iota.server.port + '/iot/services', method: 'POST', json: { services: [ { resource: '/iot/json', apikey: globalEnv.apikey, entity_type: globalEnv.entity_type, commands: [], lazy: [], attributes: [ { object_id: 'a', name: 'attr_a', type: 'Boolean', metadata: { accuracy: { value: 0.8, type: 'Float' } } } ], static_attributes: [] } ] }, headers: { 'fiware-service': globalEnv.service, 'fiware-servicepath': globalEnv.servicePath } }, should: [ { shouldName: 'A - WHEN sending defined object_ids (measures) through http IT should send measures to Context Broker preserving value types, name mappings and metadatas', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { a: false } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, attr_a: { value: false, type: 'Boolean', metadata: { accuracy: { value: 0.8, type: 'Float' } } } } } ] }, { describeName: '0021b - Simple group with active attributes with special names in object_id', provision: { url: 'http://localhost:' + config.iota.server.port + '/iot/services', method: 'POST', json: { services: [ { resource: '/iot/json', apikey: globalEnv.apikey, entity_type: globalEnv.entity_type, commands: [], lazy: [], attributes: [ { object_id: 'a', name: 'attr_a', type: 'Boolean', metadata: { accuracy: { value: 0.8, type: 'Float' } } }, { object_id: '.1.0.0.1', name: 'psBatteryVoltage', type: 'Number' } ], static_attributes: [] } ] }, headers: { 'fiware-service': globalEnv.service, 'fiware-servicepath': globalEnv.servicePath } }, should: [ { shouldName: 'A - WHEN sending defined object_ids with special format names (measures) through http IT should send measures to Context Broker preserving value types, name mappings and metadatas', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { a: false, '.1.0.0.1': 23.5 } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, attr_a: { value: false, type: 'Boolean', metadata: { accuracy: { value: 0.8, type: 'Float' } } }, psBatteryVoltage: { type: 'Number', value: 23.5 } } } ] }, { describeName: '0021c - Simple group with active attributes with special names in object_id', provision: { url: 'http://localhost:' + config.iota.server.port + '/iot/services', method: 'POST', json: { services: [ { resource: '/iot/json', apikey: globalEnv.apikey, entity_type: globalEnv.entity_type, commands: [], lazy: [], attributes: [ { name: 'mainDoorEvent', type: 'Boolean' }, { name: 'psSMDUHPower14', type: 'Text', object_id: '.1.3.6.1.4.1.6302.2.1.2.17.1.1.15.1702' }, { name: 'psSMDUHPower17', type: 'Number', object_id: '.1.3.6.1.4.1.6302.2.1.2.17.1.1.18.1702' } ], static_attributes: [] } ] }, headers: { 'fiware-service': globalEnv.service, 'fiware-servicepath': globalEnv.servicePath } }, should: [ { shouldName: 'A - WHEN sending defined object_ids with special format names in attributes through http IT should send measures to Context Broker preserving value types, name mappings and metadatas', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { '.1.3.6.1.4.1.6302.2.1.2.17.1.1.18.1702': 3, mainDoorEvent: 1, psSMDUHPower14: 2 } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, mainDoorEvent: { type: 'Boolean', value: 1 }, psSMDUHPower17: { type: 'Number', value: 3 }, psSMDUHPower14: { type: 'Text', value: 2 } } } ] }, { describeName: '0022 - Simple group with active attributes and multimeasures', provision: { url: 'http://localhost:' + config.iota.server.port + '/iot/services', method: 'POST', json: { services: [ { resource: '/iot/json', apikey: globalEnv.apikey, entity_type: globalEnv.entity_type, commands: [], lazy: [], attributes: [ { object_id: 'a', name: 'attr_a', type: 'Number' } ], static_attributes: [] } ] }, headers: { 'fiware-service': globalEnv.service, 'fiware-servicepath': globalEnv.servicePath } }, should: [ { shouldName: 'A - WHEN sending defined object_ids (measures) through http IT should send measures to Context Broker preserving value types and name mappings', type: 'multimeasure', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: [ { a: 0 }, { a: 1 }, { a: 2 }, { a: 3 }, { a: 4 }, { a: 5 }, { a: 6 } ] }, expectation: { actionType: 'append', entities: [ { attr_a: { type: 'Number', value: 0 }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 1 }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 2 }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 3 }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 4 }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 5 }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 6 }, id: globalEnv.entity_name, type: globalEnv.entity_type } ] } }, { shouldName: 'A - WHEN sending defined object_ids (measures) through http IT should send measures with TimeInstant to Context Broker preserving value types and name mappings and order', type: 'multimeasure', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: [ { a: 0, TimeInstant: '2024-04-10T10:00:00Z' }, { a: 1, TimeInstant: '2024-04-10T10:05:00Z' }, { a: 2, TimeInstant: '2024-04-10T10:10:00Z' }, { a: 3, TimeInstant: '2024-04-10T10:15:00Z' }, { a: 4, TimeInstant: '2024-04-10T10:20:00Z' }, { a: 5, TimeInstant: '2024-04-10T10:25:00Z' }, { a: 6, TimeInstant: '2024-04-10T10:30:00Z' } ] }, expectation: { actionType: 'append', entities: [ { attr_a: { type: 'Number', value: 0 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:00:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 1 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:05:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 2 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:10:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 3 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:15:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 4 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:20:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 5 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:25:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 6 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:30:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type } ] } }, { shouldName: 'A - WHEN sending defined object_ids (measures) through http IT should send measures with TimeInstant to Context Broker preserving value types and name mappings and sorted by TimeInstant', type: 'multimeasure', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: [ { a: 0, TimeInstant: '2024-04-10T10:15:00Z' }, { a: 1, TimeInstant: '2024-04-10T10:05:00Z' }, { a: 2, TimeInstant: '2024-04-10T10:20:00Z' }, { a: 3, TimeInstant: '2024-04-10T10:00:00Z' }, { a: 4, TimeInstant: '2024-04-10T10:10:00Z' }, { a: 5, TimeInstant: '2024-04-10T10:30:00Z' }, { a: 6, TimeInstant: '2024-04-10T10:25:00Z' } ] }, expectation: { actionType: 'append', entities: [ { attr_a: { type: 'Number', value: 3 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:00:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 1 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:05:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 4 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:10:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 0 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:15:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 2 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:20:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 6 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:25:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type }, { attr_a: { type: 'Number', value: 5 }, TimeInstant: { type: 'DateTime', value: '2024-04-10T10:30:00Z' }, id: globalEnv.entity_name, type: globalEnv.entity_type } ] } } ] }, // 0100 - JEXL TESTS { describeName: '0100 - Simple group with active attribute + JEXL expression boolean (!)', provision: { url: 'http://localhost:' + config.iota.server.port + '/iot/services', method: 'POST', json: { services: [ { resource: '/iot/json', apikey: globalEnv.apikey, entity_type: globalEnv.entity_type, commands: [], lazy: [], attributes: [ { object_id: 'a', name: 'attr_a', type: 'Boolean', expression: '!a' } ], static_attributes: [] } ] }, headers: { 'fiware-service': globalEnv.service, 'fiware-servicepath': globalEnv.servicePath } }, should: [ { shouldName: 'A - WHEN sending a boolean value (false) through http IT should send to Context Broker the value true ', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { a: false } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, attr_a: { value: true, type: 'Boolean' } } }, { shouldName: 'B - WHEN sending a numeric value (3) through http IT should send to Context Broker the value false ', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { a: 3 } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, attr_a: { value: false, type: 'Boolean' } } }, { shouldName: 'C - WHEN sending a text value (abcd) through http IT should send to Context Broker the value false ', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { a: 'abcd' } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, attr_a: { value: false, type: 'Boolean' } } }, { shouldName: 'D - WHEN not sending the object ID (undefined) required by the expression through http IT should send to Context Broker the value true ', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { b: 1 } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, attr_a: { value: true, type: 'Boolean' }, b: { value: 1, type: 'Text' } } } ] }, { describeName: '0110 - Simple group with active attribute + JEXL expression numeric (+3)', provision: { url: 'http://localhost:' + config.iota.server.port + '/iot/services', method: 'POST', json: { services: [ { resource: '/iot/json', apikey: globalEnv.apikey, entity_type: globalEnv.entity_type, commands: [], lazy: [], attributes: [ { object_id: 'a', name: 'attr_a', type: 'Number', expression: 'a+3' } ], static_attributes: [] } ] }, headers: { 'fiware-service': globalEnv.service, 'fiware-servicepath': globalEnv.servicePath } }, should: [ { shouldName: 'A - WHEN sending a boolean value (true) through http IT should send to Context Broker the value 4 ', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { a: true } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, attr_a: { value: 4, type: 'Number' } } }, { shouldName: 'B - WHEN sending a boolean value (false) through http IT should send to Context Broker the value 3 ', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { a: false } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, attr_a: { value: 3, type: 'Number' } } }, { shouldName: 'C - WHEN sending a numeric value (-7) through http IT should send to Context Broker the value -4 ', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { a: -7 } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, attr_a: { value: -4, type: 'Number' } } }, { shouldName: 'D - WHEN sending a text value (abcd) through http IT should send to Context Broker the value abcd3', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { a: 'abcd' } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, attr_a: { value: 'abcd3', type: 'Number' } } }, { shouldName: 'E - WHEN not sending the object ID (undefined) required by the expression through http IT should not send that attribute to Context Broker', type: 'single', measure: { url: 'http://localhost:' + config.http.port + '/iot/json', method: 'POST', qs: { i: globalEnv.deviceId, k: globalEnv.apikey }, json: { b: 1 } }, expectation: { id: globalEnv.entity_name, type: globalEnv.entity_type, b: { value: 1, type: 'Text' } } } ] }, { describeName: '0120 - Simple group with active attribute + JEXL expression numeric (*3)', provision: { url: 'http://localhost:' + config.iota.server.port + '/iot/services', method: 'POST', json: { services: [ { resource: '/iot/json', apikey: globalEnv.apikey, entity_type: globalEnv.entity_type, commands: [], lazy: [],