diff --git a/doc/manuals/aggregated-data-retrieval.md b/doc/manuals/aggregated-data-retrieval.md index f13ff15..e7ba416 100644 --- a/doc/manuals/aggregated-data-retrieval.md +++ b/doc/manuals/aggregated-data-retrieval.md @@ -20,7 +20,7 @@ The requests for aggregated time series context information can use the followin - **aggrMethod**: The aggregation method. The STH component supports the following aggregation methods: `max` (maximum value), `min` (minimum value), `sum` (sum of all the samples) and `sum2` (sum of the square value of all the samples) for numeric attribute values and `occur` for attributes values of type string. It accepts multiple values - separated by comma (min,max) to get multiple aggregation method values. Additionally, `aggrMethod=all` can be used + separated by comma (eg. `aggrMethod=min,max`) to get multiple aggregation method values. Additionally, `aggrMethod=all` can be used to get all the aggregation method values. Combining the information provided by these aggregated methods with the number of samples, it is possible to calculate probabilistic values such as the average value, the variance as well as the standard deviation. It is a mandatory parameter. diff --git a/lib/server/sthServer.js b/lib/server/sthServer.js index d436651..21b66cd 100644 --- a/lib/server/sthServer.js +++ b/lib/server/sthServer.js @@ -63,9 +63,9 @@ function doStartServer(host, port, callback) { reply({ error: 'BadRequest', description: error.output.payload.message }).code(400); } - const list = ['min', 'max', 'sum', 'sum2', 'occur', 'all']; - const joinedList = '(' + list.join('|') + ')'; - const regex = new RegExp('^' + joinedList + '(,' + joinedList + ')*$'); + const aggList = ['min', 'max', 'sum', 'sum2', 'occur', 'all']; + const joinedAggList = '(' + aggList.join('|') + ')'; + const aggRegex = new RegExp('^' + joinedAggList + '(,' + joinedAggList + ')*$'); const config = { validate: { @@ -78,7 +78,7 @@ function doStartServer(host, port, callback) { // prettier-ignore hOffset: joi.number().integer().greater(-1).optional(), // prettier-ignore - aggrMethod: joi.string().regex(regex).optional(), + aggrMethod: joi.string().regex(aggRegex).optional(), // prettier-ignore aggrPeriod: joi.string().required().valid( 'month', 'day', 'hour', 'minute', 'second').optional(), diff --git a/test/unit/sthTestUtils.js b/test/unit/sthTestUtils.js index 960f0a5..99b3f98 100644 --- a/test/unit/sthTestUtils.js +++ b/test/unit/sthTestUtils.js @@ -1794,6 +1794,47 @@ function status200Test(ngsiVersion, options, done) { } } +/** + * Bad Request 400 status test case + * @param ngsiVersion NGSI version to use. Anything different from 2 (included undefined) means v1 + * @param {Object} options Options to generate the URL + * @param {Function} done Callback + */ +function status400Test(ngsiVersion, options, done) { + if (ngsiVersion === 2) { + request( + { + uri: getURL(sthTestConfig.API_OPERATION.READ_V2, options), + method: 'GET', + headers: { + 'Fiware-Service': sthConfig.DEFAULT_SERVICE, + 'Fiware-ServicePath': sthConfig.DEFAULT_SERVICE_PATH + } + }, + function(err, response, body) { + expect(response.statusCode).to.equal(400); + done(); + } + ); + } else { + // FIXME: remove the else branch when NGSIv1 becomes obsolete + request( + { + uri: getURL(sthTestConfig.API_OPERATION.READ, options), + method: 'GET', + headers: { + 'Fiware-Service': sthConfig.DEFAULT_SERVICE, + 'Fiware-ServicePath': sthConfig.DEFAULT_SERVICE_PATH + } + }, + function(err, response, body) { + expect(response.statusCode).to.equal(400); + done(); + } + ); + } +} + /** * Test to check that in case of updating a numeric attribute value aggregated data: * - If the value of the attribute is the same, it is only aggregated once @@ -2579,6 +2620,7 @@ module.exports = { cleanDatabaseSuite, eventNotificationSuite, status200Test, + status400Test, numericAggregatedDataUpdatedTest, textualAggregatedDataUpdatedTest, aggregatedDataNonExistentTest, diff --git a/test/unit/sth_test.js b/test/unit/sth_test.js index 13c39d7..feadc0e 100644 --- a/test/unit/sth_test.js +++ b/test/unit/sth_test.js @@ -340,6 +340,22 @@ describe('sth tests', function() { }) ); + it( + 'should respond with 400 - Bad Request if aggrMethod is not from [min,max,sum,sum2,occur,all]', + sthTestUtils.status400Test.bind(null, 2, { + aggrMethod: 'foo', + aggrPeriod: 'second' + }) + ); + + it( + 'should respond with 400 - Bad Request if aggrMethod are multiple and not from [min,max,sum,sum2,occur,all]', + sthTestUtils.status400Test.bind(null, 2, { + aggrMethod: 'foo,all', + aggrPeriod: 'second' + }) + ); + it( 'should respond with 200 - OK if aggrMethod and aggrPeriod query params - NGSIv1', sthTestUtils.status200Test.bind(null, 1, { @@ -363,6 +379,22 @@ describe('sth tests', function() { aggrPeriod: 'second' }) ); + + it( + 'should respond with 400 - Bad Request if aggrMethod is not from [min,max,sum,sum2,occur,all] - NGSIv1', + sthTestUtils.status400Test.bind(null, 1, { + aggrMethod: 'foo', + aggrPeriod: 'second' + }) + ); + + it( + 'should respond with 400 - Bad Request if aggrMethod are multiple and not from [min,max,sum,sum2,occur,all] - NGSIv1', + sthTestUtils.status400Test.bind(null, 1, { + aggrMethod: 'foo,all', + aggrPeriod: 'second' + }) + ); }); function eachEventTestSuiteContainer(attrName, attrType, includeTimeInstantMetadata) {