Merge branch 'master' into eslint
This commit is contained in:
@@ -657,6 +657,176 @@ describe('dataviews using tables with overviews', function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('agreggation validation', function (){
|
||||
const params = {
|
||||
response: {
|
||||
status: 400,
|
||||
headers: {
|
||||
'Content-Type': 'application/json; charset=utf-8'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function createMapConfig(options) {
|
||||
return {
|
||||
version: '1.8.0',
|
||||
analyses: [
|
||||
{ id: 'data-source',
|
||||
type: 'source',
|
||||
params: {
|
||||
query: 'select * from test_table_overviews'
|
||||
}
|
||||
}
|
||||
],
|
||||
dataviews: {
|
||||
test_invalid_aggregation: {
|
||||
type: 'aggregation',
|
||||
source: {id: 'data-source'},
|
||||
options: options
|
||||
}
|
||||
},
|
||||
layers: [
|
||||
{
|
||||
type: 'mapnik',
|
||||
options: {
|
||||
sql: 'select * from test_table_overviews',
|
||||
cartocss: '#layer { marker-fill: red; marker-width: 32; marker-allow-overlap: true; }',
|
||||
cartocss_version: '2.3.0',
|
||||
source: { id: 'data-source' }
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
it('should fail if missing column', function (done) {
|
||||
var options = {
|
||||
aggregation: "sum",
|
||||
aggregationColumn: "value"
|
||||
};
|
||||
var missingColumnMapConfig = createMapConfig(options);
|
||||
|
||||
var testClient = new TestClient(missingColumnMapConfig);
|
||||
testClient.getDataview('test_invalid_aggregation', params, function (err, dataview) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
assert.deepStrictEqual(dataview, {
|
||||
errors: ["Aggregation expects 'column' in dataview options"],
|
||||
errors_with_context: [{
|
||||
type: 'unknown',
|
||||
message: "Aggregation expects 'column' in dataview options"
|
||||
}]
|
||||
});
|
||||
|
||||
testClient.drain(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if no aggregation operation', function (done) {
|
||||
var options = {
|
||||
column: "value",
|
||||
aggregationColumn: "value"
|
||||
};
|
||||
var missingOperationMapConfig = createMapConfig(options);
|
||||
|
||||
var testClient = new TestClient(missingOperationMapConfig);
|
||||
testClient.getDataview('test_invalid_aggregation', params, function (err, dataview) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
assert.deepStrictEqual(dataview, {
|
||||
errors: ["Aggregation expects 'aggregation' operation in dataview options"],
|
||||
errors_with_context: [{
|
||||
type: 'unknown',
|
||||
message: "Aggregation expects 'aggregation' operation in dataview options"
|
||||
}]
|
||||
});
|
||||
|
||||
testClient.drain(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if fake operation', function (done) {
|
||||
var options = {
|
||||
column: "value",
|
||||
aggregation: "wadus",
|
||||
aggregationColumn: "value"
|
||||
};
|
||||
var wrongOperationMapConfig = createMapConfig(options);
|
||||
|
||||
var testClient = new TestClient(wrongOperationMapConfig);
|
||||
testClient.getDataview('test_invalid_aggregation', params, function (err, dataview) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
assert.deepStrictEqual(dataview, {
|
||||
errors: ["Aggregation does not support 'wadus' operation"],
|
||||
errors_with_context: [{
|
||||
type: 'unknown',
|
||||
message: "Aggregation does not support 'wadus' operation"
|
||||
}]
|
||||
});
|
||||
|
||||
testClient.drain(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if invalid operation for overview', function (done) {
|
||||
var options = {
|
||||
column: "value",
|
||||
aggregation: "avg",
|
||||
aggregationColumn: "value"
|
||||
};
|
||||
var wrongOperationMapConfig = createMapConfig(options);
|
||||
|
||||
var testClient = new TestClient(wrongOperationMapConfig);
|
||||
testClient.getDataview('test_invalid_aggregation', params, function (err, dataview) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
assert.deepStrictEqual(dataview, {
|
||||
errors: ["Aggregation does not support 'avg' operation in dataview overview options"],
|
||||
errors_with_context: [{
|
||||
type: 'unknown',
|
||||
message: "Aggregation does not support 'avg' operation in dataview overview options"
|
||||
}]
|
||||
});
|
||||
|
||||
testClient.drain(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if no aggregation column when needed', function (done) {
|
||||
var options = {
|
||||
column: "value",
|
||||
aggregation: "sum"
|
||||
};
|
||||
var missingOptionMapConfig = createMapConfig(options);
|
||||
|
||||
var testClient = new TestClient(missingOptionMapConfig);
|
||||
testClient.getDataview('test_invalid_aggregation', params, function (err, dataview) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
|
||||
assert.deepStrictEqual(dataview, {
|
||||
errors: ["Aggregation 'sum' is missing some options: aggregationColumn"],
|
||||
errors_with_context: [{
|
||||
type: 'unknown',
|
||||
message: "Aggregation 'sum' is missing some options: aggregationColumn"
|
||||
}]
|
||||
});
|
||||
|
||||
testClient.drain(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -251,12 +251,12 @@ describe('torque boundary points', function () {
|
||||
assert.ok(!err, 'Failed to create layergroup');
|
||||
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
var expected_token = parsedBody.layergroupid;
|
||||
layergroupIdToDelete = expected_token;
|
||||
var expectedToken = parsedBody.layergroupid;
|
||||
layergroupIdToDelete = expectedToken;
|
||||
|
||||
var partialUrl = tileRequest.z + '/' + tileRequest.x + '/' + tileRequest.y;
|
||||
assert.response(server, {
|
||||
url: '/api/v1/map/' + expected_token + '/0/' + partialUrl + '.json.torque',
|
||||
url: '/api/v1/map/' + expectedToken + '/0/' + partialUrl + '.json.torque',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
host: 'localhost'
|
||||
|
||||
@@ -52,7 +52,7 @@ describe('torque', function () {
|
||||
};
|
||||
|
||||
step(
|
||||
function do_post1 () {
|
||||
function doPost1 () {
|
||||
var next = this;
|
||||
assert.response(server, {
|
||||
url: '/api/v1/map',
|
||||
@@ -71,7 +71,7 @@ describe('torque', function () {
|
||||
"Missing required property '-torque-frame-count' in torque layer CartoCSS");
|
||||
return null;
|
||||
},
|
||||
function do_post2 (err) {
|
||||
function doPost2 (err) {
|
||||
assert.ifError(err);
|
||||
var next = this;
|
||||
var css = 'Map { -torque-frame-count: 2; }';
|
||||
@@ -93,7 +93,7 @@ describe('torque', function () {
|
||||
"Missing required property '-torque-resolution' in torque layer CartoCSS");
|
||||
return null;
|
||||
},
|
||||
function do_post3 (err) {
|
||||
function doPost3 (err) {
|
||||
assert.ifError(err);
|
||||
var next = this;
|
||||
var css = 'Map { -torque-frame-count: 2; -torque-resolution: 3; }';
|
||||
@@ -139,7 +139,7 @@ describe('torque', function () {
|
||||
]
|
||||
};
|
||||
step(
|
||||
function do_post1 () {
|
||||
function doPost1 () {
|
||||
var next = this;
|
||||
assert.response(server, {
|
||||
url: '/api/v1/map',
|
||||
@@ -181,9 +181,9 @@ describe('torque', function () {
|
||||
]
|
||||
};
|
||||
|
||||
var expected_token;
|
||||
var expectedToken;
|
||||
step(
|
||||
function do_post () {
|
||||
function doPost () {
|
||||
var next = this;
|
||||
assert.response(server, {
|
||||
url: '/api/v1/map',
|
||||
@@ -199,10 +199,10 @@ describe('torque', function () {
|
||||
// from layergroup creation via POST
|
||||
checkCORSHeaders(res);
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
if (expected_token) {
|
||||
assert.deepStrictEqual(parsedBody, { layergroupid: expected_token, layercount: 2 });
|
||||
if (expectedToken) {
|
||||
assert.deepStrictEqual(parsedBody, { layergroupid: expectedToken, layercount: 2 });
|
||||
} else {
|
||||
expected_token = parsedBody.layergroupid;
|
||||
expectedToken = parsedBody.layergroupid;
|
||||
}
|
||||
var meta = parsedBody.metadata;
|
||||
assert.ok(!_.isUndefined(meta),
|
||||
@@ -220,11 +220,11 @@ describe('torque', function () {
|
||||
});
|
||||
return null;
|
||||
},
|
||||
function do_get_tile (err) {
|
||||
function doGetTile (err) {
|
||||
assert.ifError(err);
|
||||
var next = this;
|
||||
assert.response(server, {
|
||||
url: '/api/v1/map/' + expected_token + '/0/0/0.png',
|
||||
url: '/api/v1/map/' + expectedToken + '/0/0/0.png',
|
||||
method: 'GET',
|
||||
encoding: 'binary',
|
||||
headers: {
|
||||
@@ -232,7 +232,7 @@ describe('torque', function () {
|
||||
}
|
||||
}, {}, function (res, err) { next(err, res); });
|
||||
},
|
||||
function check_mapnik_error_1 (err, res) {
|
||||
function checkMapnikError1 (err, res) {
|
||||
assert.ifError(err);
|
||||
assert.strictEqual(res.statusCode, 400, res.statusCode + (res.statusCode !== 200 ? (': ' + res.body) : ''));
|
||||
var parsed = JSON.parse(res.body);
|
||||
@@ -240,18 +240,18 @@ describe('torque', function () {
|
||||
assert.strictEqual(parsed.errors[0], "No 'mapnik' layers in MapConfig");
|
||||
return null;
|
||||
},
|
||||
function do_get_grid0 (err) {
|
||||
function doGetGrid0 (err) {
|
||||
assert.ifError(err);
|
||||
var next = this;
|
||||
assert.response(server, {
|
||||
url: '/api/v1/map/' + expected_token + '/0/0/0/0.grid.json',
|
||||
url: '/api/v1/map/' + expectedToken + '/0/0/0/0.grid.json',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
host: 'localhost'
|
||||
}
|
||||
}, {}, function (res, err) { next(err, res); });
|
||||
},
|
||||
function check_mapnik_error_2 (err, res) {
|
||||
function checkMapnikError2 (err, res) {
|
||||
assert.ifError(err);
|
||||
assert.strictEqual(res.statusCode, 400, res.statusCode + (res.statusCode !== 200 ? (': ' + res.body) : ''));
|
||||
var parsed = JSON.parse(res.body);
|
||||
@@ -259,48 +259,48 @@ describe('torque', function () {
|
||||
assert.strictEqual(parsed.errors[0], 'Unsupported format grid.json');
|
||||
return null;
|
||||
},
|
||||
function do_get_torque0 (err) {
|
||||
function doGetTorque0 (err) {
|
||||
assert.ifError(err);
|
||||
var next = this;
|
||||
assert.response(server, {
|
||||
url: '/api/v1/map/' + expected_token + '/0/0/0/0.json.torque',
|
||||
url: '/api/v1/map/' + expectedToken + '/0/0/0/0.json.torque',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
host: 'localhost'
|
||||
}
|
||||
}, {}, function (res, err) { next(err, res); });
|
||||
},
|
||||
function check_torque0_response (err, res) {
|
||||
function checkTorque0Response (err, res) {
|
||||
assert.ifError(err);
|
||||
assert.strictEqual(res.statusCode, 200, res.body);
|
||||
assert.strictEqual(res.headers['content-type'], 'application/json; charset=utf-8');
|
||||
var tile_content = [{ x__uint8: 43, y__uint8: 43, vals__uint8: [1, 1], dates__uint16: [0, 1] }];
|
||||
var tileContent = [{ x__uint8: 43, y__uint8: 43, vals__uint8: [1, 1], dates__uint16: [0, 1] }];
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.deepStrictEqual(tile_content, parsed);
|
||||
assert.deepStrictEqual(tileContent, parsed);
|
||||
return null;
|
||||
},
|
||||
function do_get_torque0_1 (err) {
|
||||
function doGetTorque01 (err) {
|
||||
assert.ifError(err);
|
||||
var next = this;
|
||||
assert.response(server, {
|
||||
url: '/api/v1/map/' + expected_token + '/0/0/0/0.torque.json',
|
||||
url: '/api/v1/map/' + expectedToken + '/0/0/0/0.torque.json',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
host: 'localhost'
|
||||
}
|
||||
}, {}, function (res, err) { next(err, res); });
|
||||
},
|
||||
function check_torque0_response_1 (err, res) {
|
||||
function checkTorque0Response1 (err, res) {
|
||||
assert.ifError(err);
|
||||
assert.strictEqual(res.statusCode, 200, res.body);
|
||||
assert.strictEqual(res.headers['content-type'], 'application/json; charset=utf-8');
|
||||
var tile_content = [{ x__uint8: 43, y__uint8: 43, vals__uint8: [1, 1], dates__uint16: [0, 1] }];
|
||||
var tileContent = [{ x__uint8: 43, y__uint8: 43, vals__uint8: [1, 1], dates__uint16: [0, 1] }];
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.deepStrictEqual(tile_content, parsed);
|
||||
assert.deepStrictEqual(tileContent, parsed);
|
||||
return null;
|
||||
},
|
||||
function finish (err) {
|
||||
keysToDelete['map_cfg|' + LayergroupToken.parse(expected_token).token] = 0;
|
||||
keysToDelete['map_cfg|' + LayergroupToken.parse(expectedToken).token] = 0;
|
||||
keysToDelete['user:localhost:mapviews:global'] = 5;
|
||||
done(err);
|
||||
}
|
||||
@@ -329,7 +329,7 @@ describe('torque', function () {
|
||||
]
|
||||
};
|
||||
step(
|
||||
function do_post () {
|
||||
function doPost () {
|
||||
var next = this;
|
||||
assert.response(server, {
|
||||
url: '/api/v1/map',
|
||||
@@ -377,7 +377,7 @@ describe('torque', function () {
|
||||
const defautlPort = global.environment.postgres.port;
|
||||
|
||||
step(
|
||||
function do_post () {
|
||||
function doPost () {
|
||||
var next = this;
|
||||
global.environment.postgres.port = 54777;
|
||||
assert.response(server, {
|
||||
|
||||
@@ -18,14 +18,13 @@ SET default_with_oids = false;
|
||||
-- public user role
|
||||
DROP USER IF EXISTS :PUBLICUSER;
|
||||
CREATE USER :PUBLICUSER WITH PASSWORD ':PUBLICPASS';
|
||||
GRANT USAGE ON SCHEMA cartodb TO :PUBLICUSER;
|
||||
GRANT ALL ON CDB_TableMetadata TO :PUBLICUSER;
|
||||
SELECT current_setting('search_path') AS my_path \gset
|
||||
ALTER ROLE :PUBLICUSER SET search_path = :my_path, cartodb;
|
||||
|
||||
-- db owner role
|
||||
DROP USER IF EXISTS :TESTUSER;
|
||||
CREATE USER :TESTUSER WITH PASSWORD ':TESTPASS';
|
||||
GRANT USAGE ON SCHEMA cartodb TO :TESTUSER;
|
||||
GRANT ALL ON CDB_TableMetadata TO :TESTUSER;
|
||||
ALTER ROLE :TESTUSER SET search_path = :my_path, cartodb;
|
||||
|
||||
-- regular user role 1
|
||||
DROP USER IF EXISTS test_windshaft_regular1;
|
||||
|
||||
Reference in New Issue
Block a user