diff --git a/app/controllers/app.js b/app/controllers/app.js index 5a2c3b97..e7206fbe 100755 --- a/app/controllers/app.js +++ b/app/controllers/app.js @@ -41,6 +41,10 @@ app.get('/api/v1/cachestatus', function(req, res) { handleCacheStatus(req, res) // request handlers function handleQuery(req, res) { + var supportedFormats = ['json', 'geojson', 'csv', 'svg']; + var svg_width = 1024.0; + var svg_height = 768.0; + // extract input var body = (req.body) ? req.body : {}; var sql = req.query.q || body.q; // HTTP GET and POST store in different vars @@ -48,24 +52,27 @@ function handleQuery(req, res) { var database = req.query.database; // TODO: Depricate var limit = parseInt(req.query.rows_per_page); var offset = parseInt(req.query.page); - var format = _.isArray(req.query.format) ? req.query.format[req.query.format.length-1] : req.query.format; + var format = _.isArray(req.query.format) ? _.last(req.query.format) : req.query.format; var dp = req.query.dp; // decimal point digits (defaults to 6) var gn = "the_geom"; // TODO: read from configuration file - var svg_width = 1024.0; - var svg_height = 768.0; // sanitize and apply defaults to input dp = (dp === "" || _.isUndefined(dp)) ? '6' : dp; - format = (format === "" || _.isUndefined(format)) ? null : format.toLowerCase(); + format = (format === "" || _.isUndefined(format)) ? 'json' : format.toLowerCase(); sql = (sql === "" || _.isUndefined(sql)) ? null : sql; database = (database === "" || _.isUndefined(database)) ? null : database; limit = (_.isNumber(limit)) ? limit : null; offset = (_.isNumber(offset)) ? offset * limit : null; + // setup step run var start = new Date().getTime(); try { + + if ( -1 === supportedFormats.indexOf(format) ) + throw new Error("Invalid format: " + format); + if (!_.isString(sql)) throw new Error("You must indicate a sql query"); // initialise MD5 key of sql for cache lookups @@ -132,7 +139,7 @@ function handleQuery(req, res) { // TODO: refactor formats to external object if (format === 'geojson'){ sql = ['SELECT *, ST_AsGeoJSON(the_geom,',dp,') as the_geom FROM (', sql, ') as foo'].join(""); - } else if (format === 'svg'){ + } else if (format === 'svg') { var svg_ratio = svg_width/svg_height; sql = 'WITH source AS ( ' + sql + '), extent AS ( ' + ' SELECT ST_Extent(' + gn + ') AS e FROM source ' diff --git a/test/acceptance/app.test.js b/test/acceptance/app.test.js index 8379b9d9..7b488d38 100644 --- a/test/acceptance/app.test.js +++ b/test/acceptance/app.test.js @@ -274,7 +274,7 @@ test('GET /api/v1/sql with SQL parameter and geojson format, ensuring content-di }); }); -test('the last format parameter is used, when multiple are used', function(done){ +test('uses the last format parameter when multiple are used', function(done){ assert.response(app, { url: '/api/v1/sql?format=csv&q=SELECT%20*%20FROM%20untitle_table_4&format=geojson', headers: {host: 'vizzuality.cartodb.com'}, @@ -287,6 +287,18 @@ test('the last format parameter is used, when multiple are used', function(done) }); }); +test('sends a 400 when an unsupported format is requested', function(done){ + assert.response(app, { + url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&format=unknown', + headers: {host: 'vizzuality.cartodb.com'}, + method: 'GET' + },{ }, function(res){ + assert.equal(res.statusCode, 400, res.body); + assert.deepEqual(JSON.parse(res.body), {"error":[ "Invalid format: unknown" ]}); + done(); + }); +}); + test('GET /api/v1/sql with SVG format', function(done){ var query = querystring.stringify({ q: "SELECT 1 as cartodb_id, ST_MakeLine(ST_MakePoint(10, 10), ST_MakePoint(1034, 778)) AS the_geom ",