Validate placement, threshold and resolution
This commit is contained in:
parent
e4ae3e235d
commit
0bca3d6f33
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user