Validate placement, threshold and resolution

This commit is contained in:
Daniel García Aubert 2017-12-18 13:42:27 +01:00
parent e4ae3e235d
commit 0bca3d6f33
3 changed files with 226 additions and 0 deletions

View File

@ -1,8 +1,13 @@
const MapConfig = require('windshaft').model.MapConfig; const MapConfig = require('windshaft').model.MapConfig;
const Aggregation = require('./aggregation');
module.exports = class AggregationMapConfig extends MapConfig { module.exports = class AggregationMapConfig extends MapConfig {
constructor (config, datasource) { constructor (config, datasource) {
super(config, datasource); super(config, datasource);
this.validateResolution();
this.validatePlacement();
this.validateThreshold();
} }
isAggregationMapConfig () { isAggregationMapConfig () {
@ -31,4 +36,88 @@ module.exports = class AggregationMapConfig extends MapConfig {
return aggregation !== undefined && (typeof aggregation === 'object' || typeof aggregation === 'boolean'); return aggregation !== undefined && (typeof aggregation === 'object' || typeof aggregation === 'boolean');
} }
getAggregation (index) {
if (!this.hasLayerAggregation(index)) {
return;
}
const { aggregation } = this.getLayer(index).options;
if (typeof aggregation === 'boolean') {
return {};
}
return aggregation;
}
validateResolution () {
for (let index = 0; index < this.getLayers().length; index++) {
const aggregation = this.getAggregation(index);
if (aggregation === undefined || aggregation.resolution === undefined) {
continue;
}
const resolution = parseInt(aggregation.resolution, 10);
if (!Number.isFinite(resolution) || resolution <= 0) {
const error = new Error(`Invalid resolution, should be a number greather than 0`);
error.type = 'layer';
error.layer = {
id: this.getLayerId(index),
index: index,
type: this.layerType(index)
};
throw error;
}
}
}
validatePlacement () {
for (let index = 0; index < this.getLayers().length; index++) {
const aggregation = this.getAggregation(index);
if (aggregation === undefined || aggregation.placement === undefined) {
continue;
}
if (!Aggregation.PLACEMENTS.includes(aggregation.placement)) {
const error = new Error(`Invalid placement. Valid values: ${Aggregation.PLACEMENTS.join(', ')}`);
error.type = 'layer';
error.layer = {
id: this.getLayerId(index),
index: index,
type: this.layerType(index)
};
throw error;
}
}
}
validateThreshold () {
for (let index = 0; index < this.getLayers().length; index++) {
const aggregation = this.getAggregation(index);
if (aggregation === undefined || aggregation.threshold === undefined) {
continue;
}
const threshold = parseInt(aggregation.threshold, 10);
if (!Number.isFinite(threshold) || threshold <= 0) {
const error = new Error(`Invalid threshold, should be a number greather than 0`);
error.type = 'layer';
error.layer = {
id: this.getLayerId(index),
index: index,
type: this.layerType(index)
};
throw error;
}
}
}
}; };

View File

@ -5,6 +5,14 @@ module.exports = class Aggregation {
return 1e5; // 100K return 1e5; // 100K
} }
static get PLACEMENTS() {
return [
'centroid',
'point-grid',
'point-sample'
];
}
constructor (mapconfig, query, { constructor (mapconfig, query, {
resolution = 1, resolution = 1,
threshold = Aggregation.THRESHOLD, threshold = Aggregation.THRESHOLD,

View File

@ -686,6 +686,135 @@ describe('aggregation', function () {
done(); done();
}); });
}); });
it('should fail with bad resolution', function (done) {
this.mapConfig = createVectorMapConfig([
{
id: 'wadus',
type: 'cartodb',
options: {
sql: POINTS_SQL_1,
aggregation: {
resolution: 'wadus',
}
}
}
]);
this.testClient = new TestClient(this.mapConfig);
const options = {
response: {
status: 400
}
};
this.testClient.getLayergroup(options, (err, body) => {
if (err) {
return done(err);
}
assert.deepEqual(body, {
errors: [ 'Invalid resolution, should be a number greather than 0' ],
errors_with_context:[{
type: 'layer',
message: 'Invalid resolution, should be a number greather than 0',
layer: {
"id": "wadus",
"index": 0,
"type": "mapnik"
}
}]
});
done();
});
});
it('should fail with bad placement', function (done) {
this.mapConfig = createVectorMapConfig([
{
type: 'cartodb',
options: {
sql: POINTS_SQL_1,
aggregation: {
placement: 'wadus',
}
}
}
]);
this.testClient = new TestClient(this.mapConfig);
const options = {
response: {
status: 400
}
};
this.testClient.getLayergroup(options, (err, body) => {
if (err) {
return done(err);
}
assert.deepEqual(body, {
errors: [ 'Invalid placement. Valid values: centroid, point-grid, point-sample'],
errors_with_context:[{
type: 'layer',
message: 'Invalid placement. Valid values: centroid, point-grid, point-sample',
layer: {
id: "layer0",
index: 0,
type: "mapnik",
}
}]
});
done();
});
});
it('should fail with bad threshold', function (done) {
this.mapConfig = createVectorMapConfig([
{
type: 'cartodb',
options: {
sql: POINTS_SQL_1,
aggregation: {
threshold: 'wadus',
}
}
}
]);
this.testClient = new TestClient(this.mapConfig);
const options = {
response: {
status: 400
}
};
this.testClient.getLayergroup(options, (err, body) => {
if (err) {
return done(err);
}
assert.deepEqual(body, {
errors: [ 'Invalid threshold, should be a number greather than 0' ],
errors_with_context:[{
type: 'layer',
message: 'Invalid threshold, should be a number greather than 0',
layer: {
"id": "layer0",
"index": 0,
"type": "mapnik"
}
}]
});
done();
});
});
}); });
}); });
}); });