Merge branch 'master' into cartogl

This commit is contained in:
Javier Goizueta
2018-04-04 12:21:43 +02:00
62 changed files with 2186 additions and 1737 deletions
+5 -1
View File
@@ -1272,6 +1272,8 @@ describe(suiteName, function() {
it("cache control for layergroup default value", function(done) {
global.environment.varnish.layergroupTtl = null;
var server = new CartodbWindshaft(serverOptions);
assert.response(server, layergroupTtlRequest, layergroupTtlResponseExpectation,
function(res) {
assert.equal(res.headers['cache-control'], 'public,max-age=86400,must-revalidate');
@@ -1287,6 +1289,8 @@ describe(suiteName, function() {
var layergroupTtl = 300;
global.environment.varnish.layergroupTtl = layergroupTtl;
var server = new CartodbWindshaft(serverOptions);
assert.response(server, layergroupTtlRequest, layergroupTtlResponseExpectation,
function(res) {
assert.equal(res.headers['cache-control'], 'public,max-age=' + layergroupTtl + ',must-revalidate');
@@ -1336,7 +1340,7 @@ describe(suiteName, function() {
status: 403
},
function(res) {
assert.ok(res.body.match(/permission denied for relation test_table_private_1/));
assert.ok(res.body.match(/permission denied for .+?test_table_private_1/));
done();
}
);
+1 -1
View File
@@ -659,7 +659,7 @@ describe('named_layers', function() {
}
var parsedBody = JSON.parse(response.body);
assert.ok(parsedBody.errors[0].match(/permission denied for relation test_table_private_1/));
assert.ok(parsedBody.errors[0].match(/permission denied for .+?test_table_private_1/));
return null;
},
+153 -127
View File
@@ -1,10 +1,9 @@
var testHelper = require('../../support/test_helper');
var assert = require('../../support/assert');
var step = require('step');
var assert = require('../../support/assert');
var step = require('step');
var cartodbServer = require('../../../lib/cartodb/server');
var PortedServerOptions = require('./support/ported_server_options');
var LayergroupToken = require('../../../lib/cartodb/models/layergroup-token');
describe('attributes', function() {
@@ -47,132 +46,147 @@ describe('attributes', function() {
});
it("can only be fetched from layer having an attributes spec", function(done) {
var expected_token;
step(
function do_post()
{
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
data: JSON.stringify(test_mapconfig_1)
}, {}, function(res, err) { next(err, res); });
},
function checkPost(err, res) {
assert.ifError(err);
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
// CORS headers should be sent with response
// from layergroup creation via POST
checkCORSHeaders(res);
var parsedBody = JSON.parse(res.body);
if ( expected_token ) {
assert.deepEqual(parsedBody, {layergroupid: expected_token, layercount: 2});
} else {
expected_token = parsedBody.layergroupid;
}
return null;
},
function do_get_attr_0(err)
{
assert.ifError(err);
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/attributes/1',
method: 'GET'
}, {}, function(res, err) { next(err, res); });
},
function check_error_0(err, res) {
assert.ifError(err);
assert.equal(
res.statusCode,
400,
res.statusCode + ( res.statusCode !== 200 ? (': ' + res.body) : '' )
);
var parsed = JSON.parse(res.body);
assert.equal(parsed.errors[0], "Layer 0 has no exposed attributes");
return null;
},
function do_get_attr_1(err)
{
assert.ifError(err);
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/1/attributes/1',
method: 'GET'
}, {}, function(res, err) { next(err, res); });
},
function check_attr_1(err, res) {
assert.ifError(err);
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
var parsed = JSON.parse(res.body);
assert.deepEqual(parsed, {"n":6});
return null;
},
function do_get_attr_1_404(err)
{
assert.ifError(err);
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/1/attributes/-666',
method: 'GET'
}, {}, function(res, err) { next(err, res); });
},
function check_attr_1_404(err, res) {
assert.ifError(err);
assert.equal(res.statusCode, 404, res.statusCode + ': ' + res.body);
var parsed = JSON.parse(res.body);
assert.ok(parsed.errors);
var msg = parsed.errors[0];
assert.equal(msg, "Multiple features (0) identified by 'i' = -666 in layer 1");
return null;
},
function finish(err) {
keysToDelete['map_cfg|' + LayergroupToken.parse(expected_token).token] = 0;
keysToDelete['user:localhost:mapviews:global'] = 5;
done(err);
var expected_token;
step(
function do_post()
{
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(test_mapconfig_1)
}, {}, function(res, err) { next(err, res); });
},
function checkPost(err, res) {
assert.ifError(err);
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
// CORS headers should be sent with response
// from layergroup creation via POST
checkCORSHeaders(res);
var parsedBody = JSON.parse(res.body);
if ( expected_token ) {
assert.deepEqual(parsedBody, {layergroupid: expected_token, layercount: 2});
} else {
expected_token = parsedBody.layergroupid;
}
);
});
return null;
},
function do_get_attr_0(err)
{
assert.ifError(err);
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/attributes/1',
method: 'GET',
headers: {
host: 'localhost'
},
}, {}, function(res, err) { next(err, res); });
},
function check_error_0(err, res) {
assert.ifError(err);
assert.equal(
res.statusCode,
400,
res.statusCode + ( res.statusCode !== 200 ? (': ' + res.body) : '' )
);
var parsed = JSON.parse(res.body);
assert.equal(parsed.errors[0], "Layer 0 has no exposed attributes");
return null;
},
function do_get_attr_1(err)
{
assert.ifError(err);
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/1/attributes/1',
method: 'GET',
headers: {
host: 'localhost'
}
}, {}, function(res, err) { next(err, res); });
},
function check_attr_1(err, res) {
assert.ifError(err);
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
var parsed = JSON.parse(res.body);
assert.deepEqual(parsed, {"n":6});
return null;
},
function do_get_attr_1_404(err)
{
assert.ifError(err);
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/1/attributes/-666',
method: 'GET',
headers: {
host: 'localhost'
}
}, {}, function(res, err) { next(err, res); });
},
function check_attr_1_404(err, res) {
assert.ifError(err);
assert.equal(res.statusCode, 404, res.statusCode + ': ' + res.body);
var parsed = JSON.parse(res.body);
assert.ok(parsed.errors);
var msg = parsed.errors[0];
assert.equal(msg, "Multiple features (0) identified by 'i' = -666 in layer 1");
return null;
},
function finish(err) {
keysToDelete['map_cfg|' + LayergroupToken.parse(expected_token).token] = 0;
keysToDelete['user:localhost:mapviews:global'] = 5;
done(err);
}
);
});
// See https://github.com/CartoDB/Windshaft/issues/131
it("are checked at map creation time", function(done) {
// clone the mapconfig test
var mapconfig = JSON.parse(JSON.stringify(test_mapconfig_1));
// append unexistant attribute name
mapconfig.layers[1].options.sql = 'SELECT * FROM test_table';
mapconfig.layers[1].options.attributes.id = 'unexistant';
mapconfig.layers[1].options.attributes.columns = ['cartodb_id'];
// clone the mapconfig test
var mapconfig = JSON.parse(JSON.stringify(test_mapconfig_1));
// append unexistant attribute name
mapconfig.layers[1].options.sql = 'SELECT * FROM test_table';
mapconfig.layers[1].options.attributes.id = 'unexistant';
mapconfig.layers[1].options.attributes.columns = ['cartodb_id'];
step(
function do_post()
{
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
data: JSON.stringify(mapconfig)
}, {}, function(res, err) { next(err, res); });
},
function checkPost(err, res) {
assert.ifError(err);
assert.equal(res.statusCode, 404, res.statusCode + ': ' + (res.statusCode===200?'...':res.body));
var parsed = JSON.parse(res.body);
assert.ok(parsed.errors);
assert.equal(parsed.errors.length, 1);
var msg = parsed.errors[0];
assert.equal(msg, 'column "unexistant" does not exist');
return null;
},
function finish(err) {
done(err);
}
);
});
step(
function do_post()
{
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(mapconfig)
}, {}, function(res, err) { next(err, res); });
},
function checkPost(err, res) {
assert.ifError(err);
assert.equal(res.statusCode, 404, res.statusCode + ': ' + (res.statusCode===200?'...':res.body));
var parsed = JSON.parse(res.body);
assert.ok(parsed.errors);
assert.equal(parsed.errors.length, 1);
var msg = parsed.errors[0];
assert.equal(msg, 'column "unexistant" does not exist');
return null;
},
function finish(err) {
done(err);
}
);
});
it("can be used with jsonp", function(done) {
@@ -184,7 +198,10 @@ describe('attributes', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(test_mapconfig_1)
}, {}, function(res, err) { next(err, res); });
},
@@ -209,7 +226,10 @@ describe('attributes', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token +
'/0/attributes/1?callback=test',
method: 'GET'
method: 'GET',
headers: {
host: 'localhost'
}
}, {}, function(res, err) { next(err, res); });
},
function check_error_0(err, res) {
@@ -232,7 +252,10 @@ describe('attributes', function() {
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/1/attributes/1',
method: 'GET'
method: 'GET',
headers: {
host: 'localhost'
}
}, {}, function(res, err) { next(err, res); });
},
function check_attr_1(err, res) {
@@ -270,7 +293,10 @@ describe('attributes', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(mapconfig)
}, {}, function(res, err) { next(err, res); });
},
+64 -96
View File
@@ -44,7 +44,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json; charset=utf-8' },
headers: { host: 'localhost', 'Content-Type': 'application/json; charset=utf-8' },
data: JSON.stringify(layergroup)
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
@@ -85,7 +85,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
@@ -101,7 +101,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/0/0.png',
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "image/png");
@@ -154,7 +155,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
@@ -177,7 +178,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/0/0.png',
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "image/png");
@@ -194,7 +196,8 @@ describe('multilayer', function() {
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/0/0/0.grid.json',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "application/json; charset=utf-8");
@@ -212,7 +215,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token +
'/1/0/0/0.grid.json?interactivity=cartodb_id',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "application/json; charset=utf-8");
@@ -266,7 +270,7 @@ describe('multilayer', function() {
config: JSON.stringify(layergroup)
}),
method: 'GET',
headers: {'Content-Type': 'application/json' }
headers: { host: 'localhost', 'Content-Type': 'application/json' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
// CORS headers should be sent with response
@@ -289,7 +293,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/0/0.png',
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "image/png");
@@ -307,7 +312,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token +
'/0/0/0/0.grid.json?interactivity=cartodb_id',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "application/json; charset=utf-8");
@@ -325,7 +331,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token +
'/1/0/0/0.grid.json?interactivity=cartodb_id',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "application/json; charset=utf-8");
@@ -380,7 +387,7 @@ describe('multilayer', function() {
callback: 'jsonp_test'
}),
method: 'GET',
headers: {'Content-Type': 'application/json' }
headers: { host: 'localhost', 'Content-Type': 'application/json' }
}, {}, function(res, err) { next(err, res); });
},
function do_check_token(err, res) {
@@ -413,7 +420,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/0/0.png',
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "image/png");
@@ -431,7 +439,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token +
'/0/0/0/0.grid.json?interactivity=cartodb_id',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "application/json; charset=utf-8");
@@ -449,7 +458,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token +
'/1/0/0/0.grid.json?interactivity=cartodb_id',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "application/json; charset=utf-8");
@@ -510,7 +520,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res, err) {
next(err, res);
@@ -530,7 +540,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/0/0.png',
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "image/png");
@@ -548,7 +559,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token +
'/0/0/0/0.grid.json?interactivity=cartodb_id',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "application/json; charset=utf-8");
@@ -566,7 +578,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token +
'/1/0/0/0.grid.json?interactivity=cartodb_id',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "application/json; charset=utf-8");
@@ -583,7 +596,8 @@ describe('multilayer', function() {
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/1/attributes/4',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res, err) {
next(err, res);
});
@@ -602,7 +616,8 @@ describe('multilayer', function() {
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/2/0/0/0.json.torque',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res, err) { next(err, res); });
},
function do_check_torque2(err, res) {
@@ -624,7 +639,8 @@ describe('multilayer', function() {
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/1/0/0/0.json.torque',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res, err) { next(err, res); });
},
function do_check_torque1(err, res) {
@@ -684,7 +700,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup1)
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
@@ -700,7 +716,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup2)
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
@@ -717,7 +733,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + token1 + '/0/0/0.png',
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "image/png");
@@ -734,7 +751,8 @@ describe('multilayer', function() {
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + token1 + '/0/0/0/0.grid.json?interactivity=cartodb_id',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "application/json; charset=utf-8");
@@ -752,7 +770,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + token2 + '/0/0/0.png',
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "image/png");
@@ -769,7 +788,8 @@ describe('multilayer', function() {
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + token2 + '/0/0/0/0.grid.json?interactivity=cartodb_id',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "application/json; charset=utf-8");
@@ -826,7 +846,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res) {
try {
@@ -848,7 +868,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/0/0.png',
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "image/png");
@@ -893,7 +914,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {host: 'localhost', 'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
@@ -922,7 +943,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {host: 'localhost', 'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
@@ -957,7 +978,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {host: 'localhost', 'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: _.template(tpl, {font:'bogus'})
}, function(res) { next(null, res); });
},
@@ -977,7 +998,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {host: 'localhost', 'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: _.template(tpl, {font:available_system_fonts[0]})
}, function(res) { next(null, res); });
},
@@ -1040,7 +1061,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res) {
try {
@@ -1061,7 +1082,8 @@ describe('multilayer', function() {
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/0/0/0.grid.json',
method: 'GET'
method: 'GET',
headers: { host: 'localhost' }
}, {}, function(res) {
next(null, res);
});
@@ -1093,63 +1115,8 @@ describe('multilayer', function() {
);
});
// See http://github.com/CartoDB/Windshaft/issues/157
it("req2params is called only once for a multilayer post", function(done) {
var layergroup = {
version: '1.0.1',
layers: [
{ options: {
sql: 'select cartodb_id, ST_Translate(the_geom, 50, 0) as the_geom from test_table limit 2',
cartocss: '#layer { marker-fill:red; marker-width:32; marker-allow-overlap:true; }',
cartocss_version: '2.0.1',
interactivity: [ 'cartodb_id' ],
geom_column: 'the_geom'
} },
{ options: {
sql: 'select cartodb_id, ST_Translate(the_geom, -50, 0) as the_geom from test_table limit 2 offset 2',
cartocss: '#layer { marker-fill:blue; marker-allow-overlap:true; }',
cartocss_version: '2.0.2',
interactivity: [ 'cartodb_id' ],
geom_column: 'the_geom'
} }
]
};
var expected_token;
step(
function do_post()
{
global.req2params_calls = 0;
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res, err) { next(err,res); });
},
function check_post(err, res) {
assert.ifError(err);
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
var parsedBody = JSON.parse(res.body);
expected_token = LayergroupToken.parse(parsedBody.layergroupid).token;
assert.equal(global.req2params_calls, 1);
return null;
},
function finish(err) {
if (err) {
return done(err);
}
var keysToDelete = {'user:localhost:mapviews:global': 5};
keysToDelete['map_cfg|' + expected_token] = 0;
testHelper.deleteRedisKeys(keysToDelete, done);
}
);
});
// See https://github.com/CartoDB/Windshaft/issues/163
it("has different token for different database", function(done) {
it.skip("has different token for different database", function(done) {
var layergroup = {
version: '1.0.1',
layers: [
@@ -1170,7 +1137,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res, err) { next(err,res); });
},
@@ -1187,7 +1154,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test2/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'cartodb250user', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res, err) { next(err,res); });
},
@@ -1233,7 +1200,7 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res, err) { next(err,res); });
},
@@ -1251,7 +1218,8 @@ describe('multilayer', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + token1 + '/0/0/0.png',
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: { host: 'localhost' }
}, {}, function(res) {
assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['content-type'], "image/png");
@@ -24,7 +24,10 @@ describe('multilayer error cases', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded' }
headers: {
host: 'localhost',
'Content-Type': 'application/x-www-form-urlencoded'
}
}, {}, function(res) {
assert.equal(res.statusCode, 400, res.body);
var parsedBody = JSON.parse(res.body);
@@ -37,7 +40,10 @@ describe('multilayer error cases', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' }
headers: {
host: 'localhost',
'Content-Type': 'application/json'
}
}, {}, function(res) {
assert.equal(res.statusCode, 400, res.body);
var parsedBody = JSON.parse(res.body);
@@ -50,7 +56,10 @@ describe('multilayer error cases', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup?callback=test',
method: 'POST',
headers: {'Content-Type': 'application/json' }
headers: {
host: 'localhost',
'Content-Type': 'application/json'
}
}, {}, function(res) {
assert.equal(res.statusCode, 200);
assert.equal(
@@ -65,27 +74,30 @@ describe('multilayer error cases', function() {
});
it("layergroup with no cartocss_version", function(done) {
var layergroup = {
version: '1.0.0',
layers: [
{ options: {
sql: 'select cartodb_id, ST_Translate(the_geom, 50, 0) as the_geom from test_table limit 2',
cartocss: '#layer { marker-fill:red; marker-width:32; marker-allow-overlap:true; }',
geom_column: 'the_geom'
} }
]
};
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res) {
assert.equal(res.statusCode, 400, res.body);
var parsedBody = JSON.parse(res.body);
assert.deepEqual(parsedBody.errors, ["Missing cartocss_version for layer 0 options"]);
done();
});
var layergroup = {
version: '1.0.0',
layers: [
{ options: {
sql: 'select cartodb_id, ST_Translate(the_geom, 50, 0) as the_geom from test_table limit 2',
cartocss: '#layer { marker-fill:red; marker-width:32; marker-allow-overlap:true; }',
geom_column: 'the_geom'
} }
]
};
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(layergroup)
}, {}, function(res) {
assert.equal(res.statusCode, 400, res.body);
var parsedBody = JSON.parse(res.body);
assert.deepEqual(parsedBody.errors, ["Missing cartocss_version for layer 0 options"]);
done();
});
});
it("sql/cartocss combination errors", function(done) {
@@ -98,17 +110,18 @@ describe('multilayer error cases', function() {
geom_column: 'the_geom'
}}]
};
ServerOptions.afterLayergroupCreateCalls = 0;
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(layergroup)
}, {}, function(res) {
try {
assert.equal(res.statusCode, 400, res.statusCode + ': ' + res.body);
// See http://github.com/CartoDB/Windshaft/issues/159
assert.equal(ServerOptions.afterLayergroupCreateCalls, 0);
var parsed = JSON.parse(res.body);
assert.ok(parsed);
assert.equal(parsed.errors.length, 1);
@@ -149,12 +162,9 @@ describe('multilayer error cases', function() {
}}
]
};
ServerOptions.afterLayergroupCreateCalls = 0;
this.client = new TestClient(layergroup);
this.client.getLayergroup({ response: { status: 400 } }, function(err, parsed) {
assert.ok(!err, err);
// See http://github.com/CartoDB/Windshaft/issues/159
assert.equal(ServerOptions.afterLayergroupCreateCalls, 0);
assert.ok(parsed);
assert.equal(parsed.errors.length, 1);
var error = parsed.errors[0];
@@ -186,7 +196,10 @@ describe('multilayer error cases', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(layergroup)
}, {}, function(res) {
try {
@@ -222,7 +235,10 @@ describe('multilayer error cases', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(layergroup)
}, {}, function(res) {
try {
@@ -264,7 +280,10 @@ describe('multilayer error cases', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(layergroup)
}, {}, function(res) {
assert.equal(res.statusCode, 400, res.body);
@@ -367,7 +386,10 @@ describe('multilayer error cases', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/deadbeef/0/0/0/0.grid.json',
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: {
host: 'localhost'
}
}, {}, function(res, err) { next(err, res); });
},
function checkResponse(err, res) {
@@ -23,13 +23,12 @@ describe('multilayer interactivity and layers order', function() {
layers: testScenario.layers
};
PortedServerOptions.afterLayergroupCreateCalls = 0;
assert.response(server,
{
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(layergroup)
@@ -49,8 +48,6 @@ describe('multilayer interactivity and layers order', function() {
'\n\tLayer types: ' + layergroup.layers.map(layerType).join(', ')
);
// assert.equal(PortedServerOptions.afterLayergroupCreateCalls, 1);
var layergroupResponse = JSON.parse(response.body);
assert.ok(layergroupResponse);
+4 -2
View File
@@ -41,7 +41,7 @@ describe('raster', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(mapconfig)
}, {}, function(res, err) { next(err, res); });
},
@@ -66,7 +66,8 @@ describe('raster', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/0/0.png',
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: { host: 'localhost' }
}, {}, function(res, err) { next(err, res); });
},
function check_response(err, res) {
@@ -124,6 +125,7 @@ describe('raster', function() {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(mapconfig)
-15
View File
@@ -8,21 +8,6 @@ describe('regressions', function() {
testHelper.rmdirRecursiveSync(global.environment.millstone.cache_basedir);
});
// See https://github.com/Vizzuality/Windshaft/issues/65
it("#65 catching non-Error exception doesn't kill the backend", function(done) {
var mapConfig = testClient.defaultTableMapConfig('test_table');
testClient.withLayergroup(mapConfig, function(err, requestTile, finish) {
var options = {
statusCode: 400,
contentType: 'application/json; charset=utf-8'
};
requestTile('/0/0/0.png?testUnexpectedError=1', options, function(err, res) {
assert.deepEqual(JSON.parse(res.body).errors, ["test unexpected error"]);
finish(done);
});
});
});
// Test that you cannot write to the database from a tile request
//
// See http://github.com/CartoDB/Windshaft/issues/130
+5 -1
View File
@@ -38,6 +38,7 @@ describe('retina support', function() {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(retinaSampleMapConfig)
@@ -67,7 +68,10 @@ describe('retina support', function() {
{
url: '/database/windshaft_test/layergroup/' + layergroupId + '/0/0/0' + scaleFactor + '.png',
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: {
host: 'localhost'
}
},
responseHead,
assertFn
+18 -11
View File
@@ -59,7 +59,7 @@ describe('server_gettile', function() {
assert.ok(xwc > 0);
assert.ok(xwc >= lastXwc);
requestTile(tileUrl + '?cache_buster=wadus', function (err, res) {
requestTile(tileUrl, { cache_buster: 'wadus' }, function (err, res) {
var xwc = res.headers['x-windshaft-cache'];
assert.ok(!xwc);
@@ -99,18 +99,25 @@ describe('server_gettile', function() {
}
testClient.withLayergroup(mapConfig, validateLayergroup, function(err, requestTile, finish) {
requestTile(tileUrl, function(err, res) {
assert.ok(res.headers.hasOwnProperty('x-windshaft-cache'), "Did not hit renderer cache on second time");
assert.ok(res.headers['x-windshaft-cache'] >= 0);
var xwc = res.headers['x-windshaft-cache'];
assert.ok(!xwc);
assert.imageBufferIsSimilarToFile(res.body, imageFixture, IMAGE_EQUALS_TOLERANCE_PER_MIL,
function(err) {
finish(function(finishErr) {
done(err || finishErr);
});
}
);
requestTile(tileUrl, function (err, res) {
assert.ok(
res.headers.hasOwnProperty('x-windshaft-cache'),
"Did not hit renderer cache on second time"
);
assert.ok(res.headers['x-windshaft-cache'] >= 0);
assert.imageBufferIsSimilarToFile(res.body, imageFixture, IMAGE_EQUALS_TOLERANCE_PER_MIL,
function(err) {
finish(function(finishErr) {
done(err || finishErr);
});
}
);
});
});
});
});
+5 -2
View File
@@ -62,6 +62,7 @@ describe('server_png8_format', function() {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(layergroup)
@@ -81,7 +82,10 @@ describe('server_png8_format', function() {
var requestPayload = {
url: '/database/windshaft_test/layergroup/' + layergroupId + tilePartialUrl,
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: {
host: 'localhost'
}
};
var requestHeaders = {
@@ -179,4 +183,3 @@ describe('server_png8_format', function() {
});
});
});
@@ -1,7 +1,6 @@
var _ = require('underscore');
var serverOptions = require('../../../../lib/cartodb/server_options');
var mapnik = require('windshaft').mapnik;
var LayergroupToken = require('../../../../lib/cartodb/models/layergroup-token');
var OverviewsQueryRewriter = require('../../../../lib/cartodb/utils/overviews_query_rewriter');
var overviewsQueryRewriter = new OverviewsQueryRewriter({
zoom_level: 'CDB_ZoomFromScale(!scale_denominator!)'
@@ -47,48 +46,5 @@ module.exports = _.extend({}, serverOptions, {
enable_cors: global.environment.enable_cors,
unbuffered_logging: true, // for smoother teardown from tests
log_format: null, // do not log anything
afterLayergroupCreateCalls: 0,
useProfiler: true,
req2params: function(req, res, callback){
if ( req.query.testUnexpectedError ) {
return callback('test unexpected error');
}
// this is in case you want to test sql parameters eg ...png?sql=select * from my_table limit 10
req.params = _.extend({}, req.params);
if (req.params.token) {
req.params.token = LayergroupToken.parse(req.params.token).token;
}
_.extend(req.params, req.query);
req.params.user = 'localhost';
res.locals.user = 'localhost';
req.params.dbhost = global.environment.postgres.host;
req.params.dbport = req.params.dbport || global.environment.postgres.port;
req.params.dbuser = 'test_windshaft_publicuser';
if (req.params.dbname !== 'windshaft_test2') {
req.params.dbuser = 'test_windshaft_cartodb_user_1';
}
req.params.dbname = 'test_windshaft_cartodb_user_1_db';
// add all params to res.locals
res.locals = _.extend({}, req.params);
// increment number of calls counter
global.req2params_calls = global.req2params_calls ? global.req2params_calls + 1 : 1;
// send the finished req object on
callback(null,req);
},
afterLayergroupCreate: function(req, cfg, res, callback) {
res.layercount = cfg.layers.length;
// config.afterLayergroupCreateCalls++;
callback(null);
}
useProfiler: true
});
+26 -5
View File
@@ -72,7 +72,7 @@ function createLayergroup(layergroupConfig, options, callback) {
});
},
function validateLayergroup(err, res) {
assert.ok(!err, 'Failed to request layergroup');
assert.ifError(err);
var parsedBody;
var layergroupid;
@@ -129,6 +129,7 @@ function layergroupRequest(layergroupConfig, method, callbackName, extraParams)
var request = {
url: '/database/windshaft_test/layergroup',
headers: {
host: 'localhost',
'Content-Type': 'application/json'
}
};
@@ -337,6 +338,7 @@ function getGeneric(layergroupConfig, url, expectedResponse, callback) {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {
host: 'localhost',
'Content-Type': 'application/json'
},
data: JSON.stringify(layergroupConfig)
@@ -372,7 +374,10 @@ function getGeneric(layergroupConfig, url, expectedResponse, callback) {
var request = {
url: finalUrl,
method: 'GET'
method: 'GET',
headers: {
host: 'localhost'
}
};
if (contentType === pngContentType) {
@@ -449,12 +454,28 @@ function withLayergroup(layergroupConfig, options, callback) {
};
}
var baseUrlTpl = '/database/windshaft_test/layergroup/<%= layergroupid %>';
var finalUrl = _.template(baseUrlTpl, { layergroupid: layergroupid }) + layergroupUrl;
const signerTpl = function ({ signer }) {
return `${signer ? `:${signer}@` : ''}`;
};
const cacheTpl = function ({ cache_buster, cacheBuster }) {
return `${cache_buster ? `:${cache_buster}` : `:${cacheBuster}`}`;
};
const urlTpl = function ({layergroupid, cache_buster = null, tile }) {
const { signer, token , cacheBuster } = LayergroupToken.parse(layergroupid);
const base = '/database/windshaft_test/layergroup/';
return `${base}${signerTpl({signer})}${token}${cacheTpl({cache_buster, cacheBuster})}${tile}`;
};
const finalUrl = urlTpl({ layergroupid, cache_buster: options.cache_buster, tile: layergroupUrl });
var request = {
url: finalUrl,
method: 'GET'
method: 'GET',
headers: {
host: 'localhost'
}
};
if (options.contentType === pngContentType) {
+32 -14
View File
@@ -48,7 +48,7 @@ describe('torque', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res) { next(null, res); });
},
@@ -71,7 +71,7 @@ describe('torque', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res) { next(null, res); });
},
@@ -94,7 +94,7 @@ describe('torque', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res) { next(null, res); });
},
@@ -136,7 +136,7 @@ describe('torque', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res) { next(null, res); });
},
@@ -179,7 +179,7 @@ describe('torque', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(mapconfig)
}, {}, function(res, err) { next(err, res); });
},
@@ -218,7 +218,10 @@ describe('torque', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/0/0.png',
method: 'GET',
encoding: 'binary'
encoding: 'binary',
headers: {
host: 'localhost'
}
}, {}, function(res, err) { next(err, res); });
},
function check_mapnik_error_1(err, res) {
@@ -235,7 +238,10 @@ describe('torque', function() {
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/0/0/0.grid.json',
method: 'GET'
method: 'GET',
headers: {
host: 'localhost'
}
}, {}, function(res, err) { next(err, res); });
},
function check_mapnik_error_2(err, res) {
@@ -252,7 +258,10 @@ describe('torque', function() {
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/0/0/0.json.torque',
method: 'GET'
method: 'GET',
headers: {
host: 'localhost'
}
}, {}, function(res, err) { next(err, res); });
},
function check_torque0_response(err, res) {
@@ -270,7 +279,10 @@ describe('torque', function() {
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/0/0/0.torque.json',
method: 'GET'
method: 'GET',
headers: {
host: 'localhost'
}
}, {}, function(res, err) { next(err, res); });
},
function check_torque0_response_1(err, res) {
@@ -315,7 +327,7 @@ describe('torque', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(mapconfig)
}, {}, function(res, err) { next(err, res); });
},
@@ -354,19 +366,25 @@ describe('torque', function() {
]
};
let defautlPort = global.environment.postgres.port;
step(
function do_post()
{
var next = this;
global.environment.postgres.port = 54777;
assert.response(server, {
url: '/database/windshaft_test/layergroup?dbport=54777',
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(mapconfig)
}, {}, function(res, err) { next(err, res); });
},
function checkPost(err, res) {
assert.ifError(err);
global.environment.postgres.port = defautlPort;
assert.equal(res.statusCode, 500, res.statusCode + ': ' + res.body);
var parsed = JSON.parse(res.body);
assert.ok(parsed.errors, parsed);
@@ -407,9 +425,9 @@ describe('torque', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(layergroup)
}, {}, function(res) { next(null, res); });
}, {}, function (res) { next(null, res); });
},
function checkResponse(err, res) {
assert.ifError(err);
+15 -6
View File
@@ -237,7 +237,7 @@ describe('torque boundary points', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(boundaryPointsMapConfig)
}, {}, function (res, err) {
@@ -250,7 +250,10 @@ describe('torque boundary points', function() {
var partialUrl = tileRequest.z + '/' + tileRequest.x + '/' + tileRequest.y;
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + expected_token + '/0/' + partialUrl + '.json.torque',
method: 'GET'
method: 'GET',
headers: {
host: 'localhost'
}
}, {}, function (res, err) {
assert.ok(!err, 'Failed to get json');
@@ -351,7 +354,7 @@ describe('torque boundary points', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(londonPointMapConfig)
}, {}, function (res, err) {
assert.ok(!err, 'Failed to create layergroup');
@@ -363,7 +366,10 @@ describe('torque boundary points', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + layergroupId + '/0/2/1/1.json.torque',
method: 'GET'
method: 'GET',
headers: {
host: 'localhost'
}
}, {}, function (res, err) {
assert.ok(!err, 'Failed to request torque.json');
@@ -414,7 +420,7 @@ describe('torque boundary points', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup',
method: 'POST',
headers: {'Content-Type': 'application/json' },
headers: { host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(londonPointMapConfig)
}, {}, function (res, err) {
assert.ok(!err, 'Failed to create layergroup');
@@ -426,7 +432,10 @@ describe('torque boundary points', function() {
assert.response(server, {
url: '/database/windshaft_test/layergroup/' + layergroupId + '/0/13/4255/2765.json.torque',
method: 'GET'
method: 'GET',
headers: {
host: 'localhost'
}
}, {}, function (res, err) {
assert.ok(!err, 'Failed to request torque.json');
+133 -33
View File
@@ -15,6 +15,7 @@ let redisClient;
let testClient;
let keysToDelete = ['user:localhost:mapviews:global'];
const user = 'localhost';
let layergroupid;
const query = `
SELECT
@@ -68,13 +69,13 @@ const createMapConfig = ({
});
function setLimit(count, period, burst) {
function setLimit(count, period, burst, endpoint = RATE_LIMIT_ENDPOINTS_GROUPS.ANONYMOUS) {
redisClient.SELECT(8, err => {
if (err) {
return;
}
const key = `limits:rate:store:${user}:maps:${RATE_LIMIT_ENDPOINTS_GROUPS.ANONYMOUS}`;
const key = `limits:rate:store:${user}:maps:${endpoint}`;
redisClient.rpush(key, burst);
redisClient.rpush(key, count);
redisClient.rpush(key, period);
@@ -87,8 +88,12 @@ function getReqAndRes() {
req: {},
res: {
headers: {},
set(headers) {
this.headers = headers;
set(headers, value) {
if(typeof headers === 'object') {
this.headers = headers;
} else {
this.headers[headers] = value;
}
},
locals: {
user: 'localhost'
@@ -97,18 +102,21 @@ function getReqAndRes() {
};
}
function assertGetLayergroupRequest (status, limit, remaining, reset, retry, done = null) {
const response = {
function assertGetLayergroupRequest (status, limit, remaining, reset, retry, done) {
let response = {
status,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Carto-Rate-Limit-Limit': limit,
'Carto-Rate-Limit-Remaining': remaining,
'Carto-Rate-Limit-Reset': reset,
'Retry-After': retry
'Carto-Rate-Limit-Reset': reset
}
};
if(retry) {
response.headers['Retry-After'] = retry;
}
testClient.getLayergroup({ response }, err => {
assert.ifError(err);
if (done) {
@@ -117,21 +125,26 @@ function assertGetLayergroupRequest (status, limit, remaining, reset, retry, don
});
}
function assertRateLimitRequest (status, limit, remaining, reset, retry, done = null) {
function assertRateLimitRequest (status, limit, remaining, reset, retry, done) {
const { req, res } = getReqAndRes();
rateLimit(req, res, function (err) {
assert.deepEqual(res.headers, {
let expectedHeaders = {
"Carto-Rate-Limit-Limit": limit,
"Carto-Rate-Limit-Remaining": remaining,
"Carto-Rate-Limit-Reset": reset,
"Retry-After": retry
});
"Carto-Rate-Limit-Reset": reset
};
if(retry) {
expectedHeaders['Retry-After'] = retry;
}
assert.deepEqual(res.headers, expectedHeaders);
if(status === 200) {
assert.ifError(err);
} else {
assert.ok(err);
assert.equal(err.message, 'You are over the limits.');
assert.equal(err.message, 'You are over platform\'s limits. Please contact us to know more details');
assert.equal(err.http_status, 429);
assert.equal(err.type, 'limit');
assert.equal(err.subtype, 'rate-limit');
@@ -178,7 +191,7 @@ describe('rate limit', function() {
const burst = 1;
setLimit(count, period, burst);
assertGetLayergroupRequest(200, '2', '1', '1', '-1', done);
assertGetLayergroupRequest(200, '2', '1', '1', null, done);
});
it("1 req/sec: 2 req/seg should be limited", function(done) {
@@ -187,12 +200,12 @@ describe('rate limit', function() {
const burst = 1;
setLimit(count, period, burst);
assertGetLayergroupRequest(200, '2', '1', '1', '-1');
setTimeout( () => assertGetLayergroupRequest(200, '2', '0', '1', '-1'), 250);
setTimeout( () => assertGetLayergroupRequest(429, '2', '0', '1', '0'), 500);
setTimeout( () => assertGetLayergroupRequest(429, '2', '0', '1', '0'), 750);
setTimeout( () => assertGetLayergroupRequest(429, '2', '0', '1', '0'), 950);
setTimeout( () => assertGetLayergroupRequest(200, '2', '0', '1', '-1', done), 1050);
assertGetLayergroupRequest(200, '2', '1', '1');
setTimeout( () => assertGetLayergroupRequest(200, '2', '0', '1'), 250);
setTimeout( () => assertGetLayergroupRequest(429, '2', '0', '1', '1'), 500);
setTimeout( () => assertGetLayergroupRequest(429, '2', '0', '1', '1'), 750);
setTimeout( () => assertGetLayergroupRequest(429, '2', '0', '1', '1'), 950);
setTimeout( () => assertGetLayergroupRequest(200, '2', '0', '1', null, done), 1050);
});
});
@@ -234,12 +247,12 @@ describe('rate limit middleware', function () {
});
it("1 req/sec: 2 req/seg should be limited", function (done) {
assertRateLimitRequest(200, 1, 0, 1, -1);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 0), 250);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 0), 500);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 0), 750);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 0), 950);
setTimeout( () => assertRateLimitRequest(200, 1, 0, 1, -1, done), 1050);
assertRateLimitRequest(200, 1, 0, 1);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 1), 250);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 1), 500);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 1), 750);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 1), 950);
setTimeout( () => assertRateLimitRequest(200, 1, 0, 1, null, done), 1050);
});
it("1 req/sec: 2 req/seg should be limited, removing SHA script from Redis", function (done) {
@@ -248,13 +261,100 @@ describe('rate limit middleware', function () {
'SCRIPT',
['FLUSH'],
function () {
assertRateLimitRequest(200, 1, 0, 1, -1);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 0), 500);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 0), 500);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 0), 750);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 0), 950);
setTimeout( () => assertRateLimitRequest(200, 1, 0, 1, -1, done), 1050);
assertRateLimitRequest(200, 1, 0, 1);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 1), 500);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 1), 500);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 1), 750);
setTimeout( () => assertRateLimitRequest(429, 1, 0, 0, 1), 950);
setTimeout( () => assertRateLimitRequest(200, 1, 0, 1, null, done), 1050);
}
);
});
});
describe('rate limit and vector tiles', function () {
before(function(done) {
global.environment.enabledFeatures.rateLimitsEnabled = true;
global.environment.enabledFeatures.rateLimitsByEndpoint.tile = true;
redisClient = redis.createClient(global.environment.redis.port);
const count = 1;
const period = 1;
const burst = 0;
setLimit(count, period, burst, RATE_LIMIT_ENDPOINTS_GROUPS.TILE);
testClient = new TestClient(createMapConfig(), 1234);
testClient.getLayergroup({status: 200}, (err, res) => {
assert.ifError(err);
layergroupid = res.layergroupid;
done();
});
});
after(function() {
global.environment.enabledFeatures.rateLimitsEnabled = false;
global.environment.enabledFeatures.rateLimitsByEndpoint.tile = false;
});
afterEach(function(done) {
keysToDelete.forEach( key => {
redisClient.del(key);
});
redisClient.SELECT(0, () => {
redisClient.del('user:localhost:mapviews:global');
redisClient.SELECT(5, () => {
redisClient.del('user:localhost:mapviews:global');
done();
});
});
});
it('mvt rate limited', function (done) {
const tileParams = (status, limit, remaining, reset, retry, contentType) => {
let headers = {
"Content-Type": contentType,
"Carto-Rate-Limit-Limit": limit,
"Carto-Rate-Limit-Remaining": remaining,
"Carto-Rate-Limit-Reset": reset
};
if (retry) {
headers['Retry-After'] = retry;
}
return {
layergroupid: layergroupid,
format: 'mvt',
response: {status, headers}
};
};
testClient.getTile(0, 0, 0, tileParams(204, '1', '0', '1'), (err) => {
assert.ifError(err);
testClient.getTile(
0,
0,
0,
tileParams(429, '1', '0', '0', '1', 'application/x-protobuf'),
(err, res, tile) => {
assert.ifError(err);
var tileJSON = tile.toJSON();
assert.equal(Array.isArray(tileJSON), true);
assert.equal(tileJSON.length, 2);
assert.equal(tileJSON[0].name, 'errorTileSquareLayer');
assert.equal(tileJSON[1].name, 'errorTileStripesLayer');
done();
}
);
});
});
});
+1 -1
View File
@@ -88,7 +88,7 @@ describe('turbo-carto regressions', function() {
var turboCartoError = layergroup.errors_with_context[0];
assert.ok(turboCartoError);
assert.equal(turboCartoError.type, 'layer');
assert.ok(turboCartoError.message.match(/permission\sdenied\sfor\srelation\stest_table_private_1/));
assert.ok(turboCartoError.message.match(/permission\sdenied\sfor\s.+?test_table_private_1/));
done();
});
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+7 -21
View File
@@ -7,11 +7,10 @@ var PgConnection = require('../../../lib/cartodb/backends/pg_connection');
var AuthApi = require('../../../lib/cartodb/api/auth_api');
var TemplateMaps = require('../../../lib/cartodb/backends/template_maps');
const cleanUpQueryParamsMiddleware = require('../../../lib/cartodb/middleware/context/clean-up-query-params');
const authorizeMiddleware = require('../../../lib/cartodb/middleware/context/authorize');
const dbConnSetupMiddleware = require('../../../lib/cartodb/middleware/context/db-conn-setup');
const credentialsMiddleware = require('../../../lib/cartodb/middleware/context/credentials');
const localsMiddleware = require('../../../lib/cartodb/middleware/context/locals');
const cleanUpQueryParamsMiddleware = require('../../../lib/cartodb/middleware/clean-up-query-params');
const authorizeMiddleware = require('../../../lib/cartodb/middleware/authorize');
const dbConnSetupMiddleware = require('../../../lib/cartodb/middleware/db-conn-setup');
const credentialsMiddleware = require('../../../lib/cartodb/middleware/credentials');
var windshaft = require('windshaft');
@@ -66,18 +65,6 @@ describe('prepare-context', function() {
return res;
}
it('res.locals are created', function(done) {
const locals = localsMiddleware();
let req = {};
let res = {};
locals(prepareRequest(req), prepareResponse(res), function(err) {
if ( err ) { done(err); return; }
assert.ok(res.hasOwnProperty('locals'), 'response has locals');
done();
});
});
it('cleans up request', function(done){
var req = {headers: { host:'localhost' }, query: {dbuser:'hacker',dbname:'secret'}};
var res = {};
@@ -178,10 +165,9 @@ describe('prepare-context', function() {
return done(err);
}
var query = res.locals;
assert.deepEqual(config, query.config);
assert.equal('test', query.api_key);
assert.equal(undefined, query.non_included);
assert.deepEqual(config, req.query.config);
assert.equal('test', req.query.api_key);
assert.equal(undefined, req.query.non_included);
done();
});
});