diff --git a/.travis.yml b/.travis.yml index f8dbc70..dbdeb2e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,9 +21,7 @@ jobs: node_js: 10 before_install: - - docker pull telefonicaiot/fiware-orion - docker run --name mongodb -d mongo:3.4 - - docker run --name orion -d --link mongodb:mongodb -p 10026:1026 telefonicaiot/fiware-orion -dbhost mongodb before_script: - npm run lint diff --git a/CHANGES_NEXT_RELEASE b/CHANGES_NEXT_RELEASE index ecb657c..9c86b2b 100644 --- a/CHANGES_NEXT_RELEASE +++ b/CHANGES_NEXT_RELEASE @@ -5,4 +5,5 @@ - Fix or disable eslint errors - Set Nodejs 10 as minimum version in packages.json (effectively removing Nodev8 from supported versions) - Allow to configure id field in received callbacks from Sigfox +- Use nock lib to mock exchanges with a context broker during tests (and avoid depending on a running one) diff --git a/package.json b/package.json index 7a29eff..fc67820 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "logops": "2.1.0" }, "devDependencies": { + "nock":"14.4.0", "coveralls": "~3.0.2", "husky": "~1.1.0", "eslint": "~5.16.0", diff --git a/test/examples/deviceProvisioning/expectedDataUpdatePluginRequest.json b/test/examples/deviceProvisioning/expectedDataUpdatePluginRequest.json new file mode 100644 index 0000000..5812b30 --- /dev/null +++ b/test/examples/deviceProvisioning/expectedDataUpdatePluginRequest.json @@ -0,0 +1,42 @@ +{ + "contextElements": [ + { + "type": "SIGFOX", + "isPattern": "false", + "id": "sigApp3", + "attributes": [ + { + "name": "time", + "type": "String", + "value": "1430909015" + }, + { + "name": "statin", + "type": "String", + "value": "0A5F" + }, + { + "name": "lng", + "type": "String", + "value": "-4" + }, + { + "name": "lat", + "type": "String", + "value": "41" + }, + { + "name": "campo1", + "type": "Integer", + "value": "valor1" + }, + { + "name": "campo2", + "type": "Integer", + "value": 64 + } + ] + } + ], + "updateAction": "UPDATE" +} diff --git a/test/examples/deviceProvisioning/expectedDataUpdateRequest.json b/test/examples/deviceProvisioning/expectedDataUpdateRequest.json new file mode 100644 index 0000000..523bca8 --- /dev/null +++ b/test/examples/deviceProvisioning/expectedDataUpdateRequest.json @@ -0,0 +1,57 @@ +{ + "contextElements": [ + { + "type": "SIGFOX", + "isPattern": "false", + "id": "sigApp2", + "attributes": [ + { + "name": "time", + "type": "String", + "value": "1430909015" + }, + { + "name": "statin", + "type": "String", + "value": "0A5F" + }, + { + "name": "lng", + "type": "String", + "value": "-4" + }, + { + "name": "lat", + "type": "String", + "value": "41" + }, + { + "name": "theCounter", + "type": "Integer", + "value": 2 + }, + { + "name": "theParam1", + "type": "Integer", + "value": 0 + }, + { + "name": "param2", + "type": "Integer", + "value": 0 + }, + { + "name": "tempDegreesCelsius", + "type": "Integer", + "value": 35 + }, + { + "name": "voltage", + "type": "Integer", + "value": 3183 + } + ] + } + ], + "updateAction": "UPDATE" +} \ No newline at end of file diff --git a/test/examples/deviceProvisioning/expectedProvisioningPluginRequest.json b/test/examples/deviceProvisioning/expectedProvisioningPluginRequest.json new file mode 100644 index 0000000..cf0326f --- /dev/null +++ b/test/examples/deviceProvisioning/expectedProvisioningPluginRequest.json @@ -0,0 +1,42 @@ +{ + "contextElements": [ + { + "type": "SIGFOX", + "isPattern": "false", + "id": "sigApp3", + "attributes": [ + { + "name": "time", + "type": "String", + "value": " " + }, + { + "name": "statin", + "type": "String", + "value": " " + }, + { + "name": "lng", + "type": "String", + "value": " " + }, + { + "name": "lat", + "type": "String", + "value": " " + }, + { + "name": "campo1", + "type": "Integer", + "value": " " + }, + { + "name": "campo2", + "type": "Integer", + "value": " " + } + ] + } + ], + "updateAction": "APPEND" +} \ No newline at end of file diff --git a/test/examples/deviceProvisioning/expectedProvisioningRequest.json b/test/examples/deviceProvisioning/expectedProvisioningRequest.json new file mode 100644 index 0000000..b15f268 --- /dev/null +++ b/test/examples/deviceProvisioning/expectedProvisioningRequest.json @@ -0,0 +1,57 @@ +{ + "contextElements": [ + { + "type": "SIGFOX", + "isPattern": "false", + "id": "sigApp2", + "attributes": [ + { + "name": "time", + "type": "String", + "value": " " + }, + { + "name": "statin", + "type": "String", + "value": " " + }, + { + "name": "lng", + "type": "String", + "value": " " + }, + { + "name": "lat", + "type": "String", + "value": " " + }, + { + "name": "theCounter", + "type": "Integer", + "value": " " + }, + { + "name": "theParam1", + "type": "Integer", + "value": " " + }, + { + "name": "param2", + "type": "Integer", + "value": " " + }, + { + "name": "tempDegreesCelsius", + "type": "Integer", + "value": " " + }, + { + "name": "voltage", + "type": "Integer", + "value": " " + } + ] + } + ], + "updateAction": "APPEND" +} \ No newline at end of file diff --git a/test/examples/ngsi-communication/expectedDeviceRegisterRequest.json b/test/examples/ngsi-communication/expectedDeviceRegisterRequest.json new file mode 100644 index 0000000..c1d285f --- /dev/null +++ b/test/examples/ngsi-communication/expectedDeviceRegisterRequest.json @@ -0,0 +1,57 @@ +{ + "contextElements": [ + { + "type": "SIGFOX", + "isPattern": "false", + "id": "SIGFOX:sigApp1", + "attributes": [ + { + "name": "time", + "type": "String", + "value": " " + }, + { + "name": "statin", + "type": "String", + "value": " " + }, + { + "name": "lng", + "type": "String", + "value": " " + }, + { + "name": "lat", + "type": "String", + "value": " " + }, + { + "name": "counter", + "type": "Integer", + "value": " " + }, + { + "name": "param1", + "type": "Integer", + "value": " " + }, + { + "name": "param2", + "type": "Integer", + "value": " " + }, + { + "name": "tempDegreesCelsius", + "type": "Integer", + "value": " " + }, + { + "name": "voltage", + "type": "Integer", + "value": " " + } + ] + } + ], + "updateAction": "APPEND" +} \ No newline at end of file diff --git a/test/examples/ngsi-communication/expectedDeviceUpdateDataRequest.json b/test/examples/ngsi-communication/expectedDeviceUpdateDataRequest.json new file mode 100644 index 0000000..b55604e --- /dev/null +++ b/test/examples/ngsi-communication/expectedDeviceUpdateDataRequest.json @@ -0,0 +1,57 @@ +{ + "contextElements": [ + { + "type": "SIGFOX", + "isPattern": "false", + "id": "SIGFOX:sigApp1", + "attributes": [ + { + "name": "time", + "type": "String", + "value": "1430909015" + }, + { + "name": "statin", + "type": "String", + "value": "0A5F" + }, + { + "name": "lng", + "type": "String", + "value": "-4" + }, + { + "name": "lat", + "type": "String", + "value": "41" + }, + { + "name": "counter", + "type": "Integer", + "value": 2 + }, + { + "name": "param1", + "type": "Integer", + "value": 0 + }, + { + "name": "param2", + "type": "Integer", + "value": 0 + }, + { + "name": "tempDegreesCelsius", + "type": "Integer", + "value": 35 + }, + { + "name": "voltage", + "type": "Integer", + "value": 3183 + } + ] + } + ], + "updateAction": "UPDATE" +} diff --git a/test/tools/ngsiUtils.js b/test/tools/ngsiUtils.js deleted file mode 100644 index 8207012..0000000 --- a/test/tools/ngsiUtils.js +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2015 Telefonica Investigación y Desarrollo, S.A.U - * - * This file is part of sigfox-iotagent - * - * sigfox-iotagent 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. - * - * sigfox-iotagent 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 sigfox-iotagent. - * If not, seehttp://www.gnu.org/licenses/. - * - * For those usages not covered by the GNU Affero General Public License - * please contact with::[daniel.moranjimenez at telefonica.com] - */ - -const request = require('request'); - -/** - * Updates the information in a Context Broker entity. - * - * @param {String} host Host where the Context Broker is installed. - * @param {Number} port Port where the Context Broker is listening. - * @param {String} service Service the entity belongs to. - * @param {String} subservice Subservice of the service where the entity was created. - * @param {String} name Id of the entity to query. - * @param {String} type Type of the entity to query. - * @param {Array} attributes List of attributes to retrieve, along with their types and values. - */ -function updateEntity(host, port, service, subservice, name, type, attributes, callback) { - const options = { - url: 'http://' + host + ':' + port + '/v1/updateContext', - method: 'POST', - headers: { - 'fiware-service': service, - 'fiware-servicepath': subservice - }, - json: { - contextElements: [ - { - type, - id: name, - isPattern: 'false', - attributes - } - ], - updateAction: 'UPDATE' - } - }; - - request(options, callback); -} - -/** - * Query the information for a Context Broker entity. - * - * @param {String} host Host where the Context Broker is installed. - * @param {Number} port Port where the Context Broker is listening. - * @param {String} service Service the entity belongs to. - * @param {String} subservice Subservice of the service where the entity was created. - * @param {String} id Id of the entity to query. - * @param {String} type Type of the entity to query. - * @param {Array} attributes List of attributes to retrieve. - */ -function queryEntity(host, port, service, subservice, id, type, attributes, callback) { - const options = { - url: 'http://' + host + ':' + port + '/v1/queryContext', - method: 'POST', - headers: { - 'fiware-service': service, - 'fiware-servicepath': subservice - }, - json: { - entities: [ - { - type, - id, - isPattern: 'false' - } - ], - attributes - } - }; - - request(options, callback); -} - -/** - * Get the context providers for a list of attributes of an entity. - * - * @param {String} host Host where the Context Broker is installed. - * @param {Number} port Port where the Context Broker is listening. - * @param {String} service Service the entity belongs to. - * @param {String} subservice Subservice of the service where the entity was created. - * @param {String} id Id of the entity to query. - * @param {String} type Type of the entity to query. - * @param {Array} attributes List of attributes to retrieve. - */ -function discoverContextAvailability(host, port, service, subservice, id, type, attributes, callback) { - const options = { - url: 'http://' + host + ':' + port + '/v1/registry/discoverContextAvailability ', - method: 'POST', - headers: { - 'fiware-service': service, - 'fiware-servicepath': subservice - }, - json: { - entities: [ - { - type, - id, - isPattern: 'false' - } - ], - attributes - } - }; - - request(options, callback); -} - -function createClient(host, port, service, subservice) { - /*jshint validthis:true */ - - return { - query: queryEntity.bind(null, host, port, service, subservice), - update: updateEntity.bind(null, host, port, service, subservice), - discover: discoverContextAvailability.bind(null, host, port, service, subservice) - }; -} - -exports.updateEntity = updateEntity; -exports.queryEntity = queryEntity; -exports.discoverContext = discoverContextAvailability; -exports.create = createClient; diff --git a/test/unit/deviceProvisioning-test.js b/test/unit/deviceProvisioning-test.js index 8025484..c901c85 100644 --- a/test/unit/deviceProvisioning-test.js +++ b/test/unit/deviceProvisioning-test.js @@ -28,19 +28,13 @@ const iotAgent = require('../../lib/iotagentCore'); const _ = require('underscore'); const mappings = require('../../lib/mappings'); const request = require('request'); -const ngsiTestUtils = require('../tools/ngsiUtils'); const mongoUtils = require('../tools/mongoDBUtils'); const utils = require('../tools/utils'); const async = require('async'); const apply = async.apply; const config = require('../testConfig'); const should = require('should'); -const ngsiClient = ngsiTestUtils.create( - config.iota.contextBroker.host, - config.iota.contextBroker.port, - 'dumbMordor', - '/deserts' -); +const nock = require('nock'); describe('Device and configuration provisioning', function() { beforeEach(function(done) { @@ -97,6 +91,20 @@ describe('Device and configuration provisioning', function() { } }; + nock('http://' + config.iota.contextBroker.host + ':' + config.iota.contextBroker.port) + .post( + '/v1/updateContext', + utils.readExampleFile('./test/examples/deviceProvisioning/expectedProvisioningRequest.json') + ) + .reply(200, {}); + + nock('http://' + config.iota.contextBroker.host + ':' + config.iota.contextBroker.port) + .post( + '/ngsi-ld/v1/entityOperations/upsert/', + utils.readExampleFile('./test/examples/deviceProvisioning/expectedDataUpdateRequest.json') + ) + .reply(200, {}); + it('should use the provided provisioning', function(done) { request(provisioningOpts, function(error, response, body) { should.not.exist(error); @@ -105,18 +113,7 @@ describe('Device and configuration provisioning', function() { should.not.exist(error); response.statusCode.should.equal(200); - ngsiClient.query('sigApp2', 'SIGFOX', [], function(error, response, body) { - should.not.exist(error); - should.exist(body); - should.not.exist(body.errorCode); - - const attributes = body.contextResponses[0].contextElement.attributes; - - _.contains(_.pluck(attributes, 'name'), 'theCounter').should.equal(true); - _.contains(_.pluck(attributes, 'name'), 'theParam1').should.equal(true); - - done(); - }); + done(); }); }); }); diff --git a/test/unit/ngsi-communication-test.js b/test/unit/ngsi-communication-test.js index de878fe..b45ff44 100644 --- a/test/unit/ngsi-communication-test.js +++ b/test/unit/ngsi-communication-test.js @@ -32,6 +32,8 @@ const async = require('async'); const apply = async.apply; const config = require('../testConfig'); const should = require('should'); +const nock = require('nock'), +const utils = require('../tools/utils'), const sigfoxDevice = { id: 'sigApp1', type: 'SIGFOX', @@ -81,6 +83,13 @@ const sigfoxDevice = { describe('Context Broker communication', function() { beforeEach(function(done) { + nock('http://' + config.iota.contextBroker.host + ':' + config.iota.contextBroker.port) + .post( + '/v1/updateContext', + utils.readExampleFile('./test/examples/ngsi-communication/expectedDeviceRegisterRequest.json') + ) + .reply(200, {}); + iotAgent.start(config, function() { async.series( [ @@ -118,6 +127,13 @@ describe('Context Broker communication', function() { } }; + nock('http://' + config.iota.contextBroker.host + ':' + config.iota.contextBroker.port) + .post( + '/v1/updateContext', + utils.readExampleFile('./test/examples/ngsi-communication/expectedDeviceUpdateDataRequest.json') + ) + .reply(200, {}); + it('should answer with a 200 OK', function(done) { request(options, function(error, response, body) { should.not.exist(error); diff --git a/test/unit/plugin-config-test.js b/test/unit/plugin-config-test.js index a3c8090..9e1b23e 100644 --- a/test/unit/plugin-config-test.js +++ b/test/unit/plugin-config-test.js @@ -27,19 +27,13 @@ const iotAgent = require('../../lib/iotagentCore'); const _ = require('underscore'); const mappings = require('../../lib/mappings'); const request = require('request'); -const ngsiTestUtils = require('../tools/ngsiUtils'); const utils = require('../tools/utils'); const mongoUtils = require('../tools/mongoDBUtils'); const async = require('async'); const apply = async.apply; const config = require('../testConfig'); const should = require('should'); -const ngsiClient = ngsiTestUtils.create( - config.iota.contextBroker.host, - config.iota.contextBroker.port, - 'dumbMordor', - '/deserts' -); +const nock = require('nock'); describe('Plugin configuration test', function() { beforeEach(function(done) { @@ -77,6 +71,20 @@ describe('Plugin configuration test', function() { } }; + nock('http://' + config.iota.contextBroker.host + ':' + config.iota.contextBroker.port) + .post( + '/v1/updateContext', + utils.readExampleFile('./test/examples/deviceProvisioning/expectedProvisioningPluginRequest.json') + ) + .reply(200, {}); + + nock('http://' + config.iota.contextBroker.host + ':' + config.iota.contextBroker.port) + .post( + '/v1/updateContext', + utils.readExampleFile('./test/examples/deviceProvisioning/expectedDataUpdatePluginRequest.json') + ) + .reply(200, {}); + it('should use the plugin to parse the device responses', function(done) { request(provisioningOpts, function(error, response, body) { should.not.exist(error); @@ -85,18 +93,7 @@ describe('Plugin configuration test', function() { should.not.exist(error); response.statusCode.should.equal(200); - ngsiClient.query('sigApp3', 'SIGFOX', [], function(error, response, body) { - should.not.exist(error); - should.exist(body); - should.not.exist(body.errorCode); - - const attributes = body.contextResponses[0].contextElement.attributes; - - _.contains(_.pluck(attributes, 'name'), 'campo1').should.equal(true); - _.contains(_.pluck(attributes, 'name'), 'campo2').should.equal(true); - - done(); - }); + done(); }); }); });