Migrate to express 4.x series
- Remove express logger - Error handler responds with application/[json|javascript] - Fix all tests relying on res.headers - assert.response based on request module
This commit is contained in:
parent
8487008ee0
commit
abc2f130c9
3
app.js
3
app.js
@ -81,7 +81,8 @@ if ( ! global.settings.base_url ) {
|
||||
var version = require("./package").version;
|
||||
|
||||
var server = require('./app/server')();
|
||||
server.listen(global.settings.node_port, global.settings.node_host, function() {
|
||||
var listener = server.listen(global.settings.node_port, global.settings.node_host);
|
||||
listener.on('listening', function() {
|
||||
console.info('Using configuration file "%s"', configurationFile);
|
||||
console.log(
|
||||
"CartoDB SQL API %s listening on %s:%s PID=%d (%s)",
|
||||
|
@ -15,6 +15,7 @@
|
||||
//
|
||||
|
||||
var express = require('express');
|
||||
var bodyParser = require('body-parser');
|
||||
var os = require('os');
|
||||
var Profiler = require('step-profiler');
|
||||
var StatsD = require('node-statsd').StatsD;
|
||||
@ -50,7 +51,7 @@ require('./utils/date_to_json');
|
||||
// jshint maxcomplexity:12
|
||||
function App() {
|
||||
|
||||
var app = express.createServer();
|
||||
var app = express();
|
||||
|
||||
var redisConfig = {
|
||||
host: global.settings.redis_host,
|
||||
@ -102,16 +103,6 @@ function App() {
|
||||
}
|
||||
};
|
||||
app.use(global.log4js.connectLogger(global.log4js.getLogger(), _.defaults(loggerOpts, {level:'info'})));
|
||||
} else {
|
||||
// Express logger uses tokens as described here: http://www.senchalabs.org/connect/logger.html
|
||||
express.logger.token('sql', function(req) {
|
||||
return app.getSqlQueryFromRequestBody(req);
|
||||
});
|
||||
app.use(express.logger({
|
||||
buffer: true,
|
||||
format: global.settings.log_format ||
|
||||
':remote-addr :method :req[Host]:url :status :response-time ms -> :res[Content-Type]'
|
||||
}));
|
||||
}
|
||||
|
||||
// Initialize statsD client if requested
|
||||
@ -172,9 +163,12 @@ function App() {
|
||||
});
|
||||
}
|
||||
|
||||
app.use(express.bodyParser());
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({ extended: true }));
|
||||
app.enable('jsonp callback');
|
||||
app.set("trust proxy", true);
|
||||
app.disable('x-powered-by');
|
||||
app.disable('etag');
|
||||
|
||||
// basic routing
|
||||
|
||||
|
@ -25,14 +25,22 @@ module.exports = function handleException(err, res) {
|
||||
// Force inline content disposition
|
||||
res.header("Content-Disposition", 'inline');
|
||||
|
||||
if ( res.req && res.req.profiler ) {
|
||||
res.req.profiler.done('finish');
|
||||
res.header('X-SQLAPI-Profiler', res.req.profiler.toJSONString());
|
||||
var req = res.req;
|
||||
|
||||
if (req && req.profiler ) {
|
||||
req.profiler.done('finish');
|
||||
res.header('X-SQLAPI-Profiler', req.profiler.toJSONString());
|
||||
}
|
||||
|
||||
res.send(msg, getStatusError(pgErrorHandler, res.req));
|
||||
res.header('Content-Type', 'application/json; charset=utf-8');
|
||||
res.status(getStatusError(pgErrorHandler, req));
|
||||
if (req.query && req.query.callback) {
|
||||
res.jsonp(msg);
|
||||
} else {
|
||||
res.json(msg);
|
||||
}
|
||||
|
||||
if ( res.req && res.req.profiler ) {
|
||||
if (req && req.profiler) {
|
||||
res.req.profiler.sendStats();
|
||||
}
|
||||
};
|
||||
|
@ -17,11 +17,12 @@
|
||||
"Sandro Santilli <strk@vizzuality.com>"
|
||||
],
|
||||
"dependencies": {
|
||||
"body-parser": "~1.14.2",
|
||||
"cartodb-psql": "~0.6.0",
|
||||
"cartodb-query-tables": "0.2.0",
|
||||
"cartodb-redis": "0.13.1",
|
||||
"debug": "2.2.0",
|
||||
"express": "~2.5.11",
|
||||
"express": "~4.13.3",
|
||||
"log4js": "cartodb/log4js-node#cdb",
|
||||
"lru-cache": "~2.5.0",
|
||||
"node-statsd": "~0.0.7",
|
||||
|
@ -848,9 +848,9 @@ it('GET /api/v1/sql with SQL parameter and no format, ensuring content-dispositi
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var ct = res.header('Content-Type');
|
||||
var ct = res.headers['content-type'];
|
||||
assert.ok(/json/.test(ct), 'Default format is not JSON: ' + ct);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^inline/.test(cd), 'Default format is not disposed inline: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.json/gi.test(cd), 'Unexpected JSON filename: ' + cd);
|
||||
done();
|
||||
@ -865,9 +865,9 @@ it('POST /api/v1/sql with SQL parameter and no format, ensuring content-disposit
|
||||
method: 'POST'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var ct = res.header('Content-Type');
|
||||
var ct = res.headers['content-type'];
|
||||
assert.ok(/json/.test(ct), 'Default format is not JSON: ' + ct);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^inline/.test(cd), 'Default format is not disposed inline: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.json/gi.test(cd), 'Unexpected JSON filename: ' + cd);
|
||||
done();
|
||||
@ -881,9 +881,9 @@ it('GET /api/v1/sql with SQL parameter and no format, but a filename', function(
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var ct = res.header('Content-Type');
|
||||
var ct = res.headers['content-type'];
|
||||
assert.ok(/json/.test(ct), 'Default format is not JSON: ' + ct);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'Format with filename is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=x.json/gi.test(cd), 'Unexpected JSON filename: ' + cd);
|
||||
done();
|
||||
@ -959,7 +959,7 @@ it('GET /api/v1/sql ensure cross domain set on errors', function(done){
|
||||
},{
|
||||
status: 400
|
||||
}, function(err, res){
|
||||
var cd = res.header('Access-Control-Allow-Origin');
|
||||
var cd = res.headers['access-control-allow-origin'];
|
||||
assert.deepEqual(res.headers['content-type'], 'application/json; charset=utf-8');
|
||||
assert.deepEqual(res.headers['content-disposition'], 'inline');
|
||||
assert.equal(cd, '*');
|
||||
|
@ -18,10 +18,10 @@ it('CSV format', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'CSV is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.csv/gi.test(cd));
|
||||
var ct = res.header('Content-Type');
|
||||
var ct = res.headers['content-type'];
|
||||
assert.equal(true, /header=present/.test(ct), "CSV doesn't advertise header presence: " + ct);
|
||||
|
||||
var rows = res.body.split(/\r\n/);
|
||||
@ -59,10 +59,10 @@ it('CSV format from POST', function(done){
|
||||
method: 'POST'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'CSV is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.csv/gi.test(cd));
|
||||
var ct = res.header('Content-Type');
|
||||
var ct = res.headers['content-type'];
|
||||
assert.equal(true, /header=present/.test(ct), "CSV doesn't advertise header presence: " + ct);
|
||||
done();
|
||||
});
|
||||
@ -75,10 +75,10 @@ it('CSV format, custom filename', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'CSV is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=mycsv.csv/gi.test(cd), cd);
|
||||
var ct = res.header('Content-Type');
|
||||
var ct = res.headers['content-type'];
|
||||
assert.equal(true, /header=present/.test(ct), "CSV doesn't advertise header presence: " + ct);
|
||||
var row0 = res.body.substring(0, res.body.search(/[\n\r]/)).split(',');
|
||||
var checkFields = { name: true, cartodb_id: true, the_geom: true, the_geom_webmercator: true };
|
||||
|
@ -25,7 +25,7 @@ it('GET /api/v1/sql with SQL parameter, ensuring content-disposition set to geoj
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'GEOJSON is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.geojson/gi.test(cd));
|
||||
done();
|
||||
@ -40,7 +40,7 @@ it('POST /api/v1/sql with SQL parameter, ensuring content-disposition set to geo
|
||||
method: 'POST'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'GEOJSON is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.geojson/gi.test(cd));
|
||||
done();
|
||||
@ -54,7 +54,7 @@ it('uses the last format parameter when multiple are used', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /filename=cartodb-query.geojson/gi.test(cd));
|
||||
done();
|
||||
});
|
||||
@ -67,7 +67,7 @@ it('uses custom filename', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /filename=x.geojson/gi.test(cd), cd);
|
||||
done();
|
||||
});
|
||||
@ -157,7 +157,7 @@ it('null geometries in geojson output', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'GEOJSON is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.geojson/gi.test(cd));
|
||||
var gjson = JSON.parse(res.body);
|
||||
|
@ -112,7 +112,7 @@ it('KML format, unauthenticated', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'KML is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.kml/gi.test(cd), 'Unexpected KML filename: ' + cd);
|
||||
var row0 = res.body;
|
||||
@ -136,7 +136,7 @@ it('KML format, unauthenticated, POST', function(done){
|
||||
method: 'POST'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'KML is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.kml/gi.test(cd), 'Unexpected KML filename: ' + cd);
|
||||
done();
|
||||
@ -154,7 +154,7 @@ it('KML format, bigger than 81920 bytes', function(done){
|
||||
method: 'POST'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'KML is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.kml/gi.test(cd), 'Unexpected KML filename: ' + cd);
|
||||
assert.ok(res.body.length > 81920, 'KML smaller than expected: ' + res.body.length);
|
||||
@ -169,7 +169,7 @@ it('KML format, skipfields', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'KML is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.kml/gi.test(cd), 'Unexpected KML filename: ' + cd);
|
||||
var row0 = res.body;
|
||||
@ -192,7 +192,7 @@ it('KML format, unauthenticated, custom filename', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'KML is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=kmltest.kml/gi.test(cd), 'Unexpected KML filename: ' + cd);
|
||||
var name = extractFolderName(res.body);
|
||||
@ -208,7 +208,7 @@ it('KML format, authenticated', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /filename=cartodb-query.kml/gi.test(cd), 'Unexpected KML filename: ' + cd);
|
||||
done();
|
||||
});
|
||||
|
@ -20,7 +20,7 @@ it('SHP format, unauthenticated', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'SHP is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.zip/gi.test(cd));
|
||||
var tmpfile = '/tmp/myshape.zip';
|
||||
@ -47,7 +47,7 @@ it('SHP format, unauthenticated, POST', function(done){
|
||||
method: 'POST'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'SHP is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.zip/gi.test(cd), 'Unexpected SHP filename: ' + cd);
|
||||
done();
|
||||
@ -65,7 +65,7 @@ it('SHP format, big size, POST', function(done){
|
||||
method: 'POST'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'SHP is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.zip/gi.test(cd), 'Unexpected SHP filename: ' + cd);
|
||||
assert.ok(res.body.length > 81920, 'SHP smaller than expected: ' + res.body.length);
|
||||
@ -81,7 +81,7 @@ it('SHP format, unauthenticated, with custom filename', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'SHP is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=myshape.zip/gi.test(cd));
|
||||
var tmpfile = '/tmp/myshape.zip';
|
||||
@ -108,7 +108,7 @@ it('SHP format, unauthenticated, with custom, dangerous filename', function(done
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var fname = "b_______a";
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'SHP is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=b_______a.zip/gi.test(cd), 'Unexpected SHP filename: ' + cd);
|
||||
var tmpfile = '/tmp/myshape.zip';
|
||||
@ -134,7 +134,7 @@ it('SHP format, authenticated', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /filename=cartodb-query.zip/gi.test(cd));
|
||||
var tmpfile = '/tmp/myshape.zip';
|
||||
var writeErr = fs.writeFileSync(tmpfile, res.body, 'binary');
|
||||
@ -260,7 +260,7 @@ it('SHP format, concurrently', function(done){
|
||||
var concurrency = 1;
|
||||
var waiting = concurrency;
|
||||
function validate(err, res){
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'SHP is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.zip/gi.test(cd));
|
||||
var tmpfile = '/tmp/myshape.zip';
|
||||
@ -309,7 +309,7 @@ it('point with null first', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /filename=cartodb-query.zip/gi.test(cd));
|
||||
var tmpfile = '/tmp/myshape.zip';
|
||||
var writeErr = fs.writeFileSync(tmpfile, res.body, 'binary');
|
||||
|
@ -17,9 +17,9 @@ it('GET /api/v1/sql with SVG format', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.ok(/filename=cartodb-query.svg/gi.test(cd), cd);
|
||||
assert.equal(res.header('Content-Type'), 'image/svg+xml; charset=utf-8');
|
||||
assert.equal(res.headers['content-type'], 'image/svg+xml; charset=utf-8');
|
||||
assert.ok( res.body.indexOf('<path d="M 0 768 L 1024 0" />') > 0, res.body );
|
||||
// TODO: test viewBox
|
||||
done();
|
||||
@ -38,10 +38,10 @@ it('POST /api/v1/sql with SVG format', function(done){
|
||||
method: 'POST'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'SVG is not disposed as attachment: ' + cd);
|
||||
assert.ok(/filename=cartodb-query.svg/gi.test(cd), cd);
|
||||
assert.equal(res.header('Content-Type'), 'image/svg+xml; charset=utf-8');
|
||||
assert.equal(res.headers['content-type'], 'image/svg+xml; charset=utf-8');
|
||||
assert.ok( res.body.indexOf('<path d="M 0 768 L 1024 0" />') > 0, res.body );
|
||||
// TODO: test viewBox
|
||||
done();
|
||||
@ -60,9 +60,9 @@ it('GET /api/v1/sql with SVG format and custom filename', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.ok(/filename=mysvg.svg/gi.test(cd), cd);
|
||||
assert.equal(res.header('Content-Type'), 'image/svg+xml; charset=utf-8');
|
||||
assert.equal(res.headers['content-type'], 'image/svg+xml; charset=utf-8');
|
||||
assert.ok( res.body.indexOf('<path d="M 0 768 L 1024 0" />') > 0, res.body );
|
||||
// TODO: test viewBox
|
||||
done();
|
||||
@ -80,9 +80,9 @@ it('GET /api/v1/sql with SVG format and centered point', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.ok(/filename=cartodb-query.svg/gi.test(cd), cd);
|
||||
assert.equal(res.header('Content-Type'), 'image/svg+xml; charset=utf-8');
|
||||
assert.equal(res.headers['content-type'], 'image/svg+xml; charset=utf-8');
|
||||
assert.ok( res.body.indexOf('cx="0" cy="0"') > 0, res.body );
|
||||
// TODO: test viewBox
|
||||
// TODO: test radius
|
||||
@ -102,9 +102,9 @@ it('GET /api/v1/sql with SVG format and trimmed decimals', function(done){
|
||||
method: 'GET'
|
||||
},{ }, function(err, res){
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.ok(/filename=cartodb-query.svg/gi.test(cd), cd);
|
||||
assert.equal(res.header('Content-Type'), 'image/svg+xml; charset=utf-8');
|
||||
assert.equal(res.headers['content-type'], 'image/svg+xml; charset=utf-8');
|
||||
assert.ok( res.body.indexOf('<path d="M 0 768 L 1024 0 500.12 167.01" />') > 0, res.body );
|
||||
// TODO: test viewBox
|
||||
|
||||
@ -115,10 +115,10 @@ it('GET /api/v1/sql with SVG format and trimmed decimals', function(done){
|
||||
method: 'GET'
|
||||
},{}, function(err, res) {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'SVG is not disposed as attachment: ' + cd);
|
||||
assert.ok(/filename=cartodb-query.svg/gi.test(cd), cd);
|
||||
assert.equal(res.header('Content-Type'), 'image/svg+xml; charset=utf-8');
|
||||
assert.equal(res.headers['content-type'], 'image/svg+xml; charset=utf-8');
|
||||
assert.ok( res.body.indexOf('<path d="M 0 768 L 1024 0 500.123 167.012" />') > 0, res.body );
|
||||
// TODO: test viewBox
|
||||
done();
|
||||
|
@ -35,7 +35,7 @@ it('GET two polygons sharing an edge as topojson', function(done){
|
||||
status: 200
|
||||
},
|
||||
function(err, res) {
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'TOPOJSON is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.topojson/gi.test(cd));
|
||||
var topojson = JSON.parse(res.body);
|
||||
@ -140,7 +140,7 @@ it('null geometries', function(done){
|
||||
status: 200
|
||||
},
|
||||
function(err, res) {
|
||||
var cd = res.header('Content-Disposition');
|
||||
var cd = res.headers['content-disposition'];
|
||||
assert.equal(true, /^attachment/.test(cd), 'TOPOJSON is not disposed as attachment: ' + cd);
|
||||
assert.equal(true, /filename=cartodb-query.topojson/gi.test(cd));
|
||||
var topojson = JSON.parse(res.body);
|
||||
|
@ -1,6 +1,7 @@
|
||||
var http = require('http');
|
||||
|
||||
var assert = module.exports = exports = require('assert');
|
||||
var request = require('request');
|
||||
|
||||
/**
|
||||
* Assert response from `server` with
|
||||
@ -11,7 +12,7 @@ var assert = module.exports = exports = require('assert');
|
||||
* @param {Object|Function} res
|
||||
* @param {String|Function|Object} msg
|
||||
*/
|
||||
assert.response = function(server, req, res, msg){
|
||||
assert.responseOld = function(server, req, res, msg){
|
||||
var port = 5555;
|
||||
function check(){
|
||||
try {
|
||||
@ -171,6 +172,101 @@ assert.response = function(server, req, res, msg){
|
||||
}
|
||||
};
|
||||
|
||||
assert.response = function(server, req, res, callback) {
|
||||
if (!callback) {
|
||||
callback = res;
|
||||
res = {};
|
||||
}
|
||||
|
||||
var port = 5555,
|
||||
host = '127.0.0.1';
|
||||
|
||||
var listeningAttempts = 0;
|
||||
var listener;
|
||||
function listen() {
|
||||
if (listeningAttempts > 25) {
|
||||
return callback(new Error('Tried too many ports'));
|
||||
}
|
||||
listener = server.listen(port, host);
|
||||
listener.on('error', function() {
|
||||
port++;
|
||||
listeningAttempts++;
|
||||
listen();
|
||||
});
|
||||
listener.on('listening', onServerListening);
|
||||
}
|
||||
|
||||
listen();
|
||||
|
||||
// jshint maxcomplexity:10
|
||||
function onServerListening() {
|
||||
var status = res.status || res.statusCode;
|
||||
var requestParams = {
|
||||
url: 'http://' + host + ':' + port + req.url,
|
||||
method: req.method || 'GET',
|
||||
headers: req.headers || {},
|
||||
timeout: req.timeout || 0,
|
||||
encoding: req.encoding || 'utf8'
|
||||
};
|
||||
|
||||
if (req.body || req.data) {
|
||||
requestParams.body = req.body || req.data;
|
||||
}
|
||||
|
||||
request(requestParams, function assert$response$requestHandler(error, response, body) {
|
||||
listener.close(function() {
|
||||
if (error) {
|
||||
return callback(error);
|
||||
}
|
||||
|
||||
response = response || {};
|
||||
response.body = response.body || body;
|
||||
|
||||
// Assert response body
|
||||
if (res.body) {
|
||||
var eql = res.body instanceof RegExp ? res.body.test(response.body) : res.body === response.body;
|
||||
assert.ok(
|
||||
eql,
|
||||
colorize('[red]{Invalid response body.}\n' +
|
||||
' Expected: [green]{' + res.body + '}\n' +
|
||||
' Got: [red]{' + response.body + '}')
|
||||
);
|
||||
}
|
||||
|
||||
// Assert response status
|
||||
if (typeof status === 'number') {
|
||||
assert.equal(response.statusCode, status,
|
||||
colorize('[red]{Invalid response status code.}\n' +
|
||||
' Expected: [green]{' + status + '}\n' +
|
||||
' Got: [red]{' + response.statusCode + '}\n' +
|
||||
' Body: ' + response.body)
|
||||
);
|
||||
}
|
||||
|
||||
// Assert response headers
|
||||
if (res.headers) {
|
||||
var keys = Object.keys(res.headers);
|
||||
for (var i = 0, len = keys.length; i < len; ++i) {
|
||||
var name = keys[i],
|
||||
actual = response.headers[name.toLowerCase()],
|
||||
expected = res.headers[name],
|
||||
headerEql = expected instanceof RegExp ? expected.test(actual) : expected === actual;
|
||||
assert.ok(headerEql,
|
||||
colorize('Invalid response header [bold]{' + name + '}.\n' +
|
||||
' Expected: [green]{' + expected + '}\n' +
|
||||
' Got: [red]{' + actual + '}')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Callback
|
||||
callback(null, response);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Colorize the given string using ansi-escape sequences.
|
||||
* Disabled when --boring is set.
|
||||
|
Loading…
Reference in New Issue
Block a user