jshint fixes

This commit is contained in:
Raul Ochoa 2015-05-13 11:21:44 +02:00
parent 926fa3fd44
commit 9486643f0a
7 changed files with 184 additions and 199 deletions

View File

@ -1,40 +1,37 @@
require('../helper'); require('../helper');
require('../support/assert');
var app = require(global.settings.app_root + '/app/controllers/app')() var app = require(global.settings.app_root + '/app/controllers/app')();
, assert = require('assert') var assert = require('../support/assert');
, tests = module.exports = {}
, querystring = require('querystring');
suite('app.auth', function() { describe('app.auth', function() {
var scenarios = [ var scenarios = [
{ {
desc: 'valid api key should allow insert in protected tables', desc: 'valid api key should allow insert in protected tables',
url: "/api/v1/sql?api_key=1234&q=INSERT%20INTO%20private_table%20(name)%20VALUES%20('app_auth_test1')", url: "/api/v1/sql?api_key=1234&q=INSERT%20INTO%20private_table%20(name)%20VALUES%20('app_auth_test1')",
statusCode: 200 statusCode: 200
} },
,{ {
desc: 'valid api key should allow delete in protected tables', desc: 'valid api key should allow delete in protected tables',
url: "/api/v1/sql?api_key=1234&q=DELETE%20FROM%20private_table%20WHERE%20name%3d'app_auth_test1'", url: "/api/v1/sql?api_key=1234&q=DELETE%20FROM%20private_table%20WHERE%20name%3d'app_auth_test1'",
statusCode: 200 statusCode: 200
} },
,{ {
desc: 'invalid api key should NOT allow insert in protected tables', desc: 'invalid api key should NOT allow insert in protected tables',
url: "/api/v1/sql?api_key=RAMBO&q=INSERT%20INTO%20private_table%20(name)%20VALUES%20('RAMBO')", url: "/api/v1/sql?api_key=RAMBO&q=INSERT%20INTO%20private_table%20(name)%20VALUES%20('RAMBO')",
statusCode: 401 statusCode: 401
} },
,{ {
desc: 'invalid api key (old redis location) should NOT allow insert in protected tables', desc: 'invalid api key (old redis location) should NOT allow insert in protected tables',
url: "/api/v1/sql?api_key=1235&q=INSERT%20INTO%20private_table%20(name)%20VALUES%20('RAMBO')", url: "/api/v1/sql?api_key=1235&q=INSERT%20INTO%20private_table%20(name)%20VALUES%20('RAMBO')",
statusCode: 401 statusCode: 401
} },
,{ {
desc: 'no api key should NOT allow insert in protected tables', desc: 'no api key should NOT allow insert in protected tables',
url: "/api/v1/sql?q=INSERT%20INTO%20private_table%20(name)%20VALUES%20('RAMBO')", url: "/api/v1/sql?q=INSERT%20INTO%20private_table%20(name)%20VALUES%20('RAMBO')",
statusCode: 401 statusCode: 401
} },
,{ {
desc: 'no api key should NOT allow insert in public tables', desc: 'no api key should NOT allow insert in public tables',
url: "/api/v1/sql?q=INSERT%20INTO%20untitle_table_4%20(name)%20VALUES%20('RAMBO')", url: "/api/v1/sql?q=INSERT%20INTO%20untitle_table_4%20(name)%20VALUES%20('RAMBO')",
statusCode: 401 statusCode: 401
@ -42,7 +39,7 @@ suite('app.auth', function() {
]; ];
scenarios.forEach(function(scenario) { scenarios.forEach(function(scenario) {
test(scenario.desc, function(done) { it(scenario.desc, function(done) {
assert.response(app, { assert.response(app, {
// view prepare_db.sh to find public table name and structure // view prepare_db.sh to find public table name and structure
url: scenario.url, url: scenario.url,

View File

@ -13,27 +13,21 @@
* *
*/ */
require('../helper'); require('../helper');
require('../support/assert');
var app = require(global.settings.app_root + '/app/controllers/app')();
var assert = require('../support/assert');
var querystring = require('querystring');
var _ = require('underscore');
var step = require('step');
var app = require(global.settings.app_root + '/app/controllers/app')() describe('app.test', function() {
, assert = require('assert')
, querystring = require('querystring')
, _ = require('underscore')
, zipfile = require('zipfile')
, fs = require('fs')
, libxmljs = require('libxmljs')
, Step = require('step')
;
suite('app.test', function() {
var expected_cache_control = 'no-cache,max-age=31536000,must-revalidate,public'; var expected_cache_control = 'no-cache,max-age=31536000,must-revalidate,public';
var expected_rw_cache_control = 'no-cache,max-age=0,must-revalidate,public'; var expected_rw_cache_control = 'no-cache,max-age=0,must-revalidate,public';
var expected_cache_control_persist = 'public,max-age=31536000'; var expected_cache_control_persist = 'public,max-age=31536000';
test('GET /api/v1/version', function(done){ it('GET /api/v1/version', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/version', url: '/api/v1/version',
method: 'GET' method: 'GET'
@ -47,7 +41,7 @@ test('GET /api/v1/version', function(done){
}); });
}); });
test('GET /api/v1/sql', function(done){ it('GET /api/v1/sql', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql', url: '/api/v1/sql',
method: 'GET' method: 'GET'
@ -62,7 +56,7 @@ test('GET /api/v1/sql', function(done){
}); });
// Test base_url setting // Test base_url setting
test('GET /api/whatever/sql', function(done){ it('GET /api/whatever/sql', function(done){
assert.response(app, { assert.response(app, {
url: '/api/whatever/sql?q=SELECT%201', url: '/api/whatever/sql?q=SELECT%201',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -75,7 +69,7 @@ test('GET /api/whatever/sql', function(done){
}); });
// Test CORS headers with GET // Test CORS headers with GET
test('GET /api/whatever/sql', function(done){ it('GET /api/whatever/sql', function(done){
assert.response(app, { assert.response(app, {
url: '/api/whatever/sql?q=SELECT%201', url: '/api/whatever/sql?q=SELECT%201',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -83,14 +77,16 @@ test('GET /api/whatever/sql', function(done){
},{ },{
}, function(res) { }, function(res) {
assert.equal(res.statusCode, 200, res.body); assert.equal(res.statusCode, 200, res.body);
assert.equal(res.headers['access-control-allow-headers'], 'X-Requested-With, X-Prototype-Version, X-CSRF-Token'); assert.equal(
res.headers['access-control-allow-headers'], 'X-Requested-With, X-Prototype-Version, X-CSRF-Token'
);
assert.equal(res.headers['access-control-allow-origin'], '*'); assert.equal(res.headers['access-control-allow-origin'], '*');
done(); done();
}); });
}); });
// Test that OPTIONS does not run queries // Test that OPTIONS does not run queries
test('OPTIONS /api/x/sql', function(done){ it('OPTIONS /api/x/sql', function(done){
assert.response(app, { assert.response(app, {
url: '/api/x/sql?q=syntax%20error', url: '/api/x/sql?q=syntax%20error',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -98,7 +94,9 @@ test('OPTIONS /api/x/sql', function(done){
},{}, function(res) { },{}, function(res) {
assert.equal(res.statusCode, 200, res.body); assert.equal(res.statusCode, 200, res.body);
assert.equal(res.body, ''); assert.equal(res.body, '');
assert.equal(res.headers['access-control-allow-headers'], 'X-Requested-With, X-Prototype-Version, X-CSRF-Token'); assert.equal(
res.headers['access-control-allow-headers'], 'X-Requested-With, X-Prototype-Version, X-CSRF-Token'
);
assert.equal(res.headers['access-control-allow-origin'], '*'); assert.equal(res.headers['access-control-allow-origin'], '*');
done(); done();
}); });
@ -106,7 +104,7 @@ test('OPTIONS /api/x/sql', function(done){
test('GET /api/v1/sql with SQL parameter on SELECT only. No oAuth included ', function(done){ it('GET /api/v1/sql with SQL parameter on SELECT only. No oAuth included ', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db', url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -120,7 +118,7 @@ test('GET /api/v1/sql with SQL parameter on SELECT only. No oAuth included ', fu
}); });
}); });
test('cache_policy=persist', function(done){ it('cache_policy=persist', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db&cache_policy=persist', url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db&cache_policy=persist',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -136,7 +134,7 @@ test('cache_policy=persist', function(done){
}); });
}); });
test('GET /api/v1/sql with SQL parameter on SELECT only. no database param, just id using headers', function(done){ it('GET /api/v1/sql with SQL parameter on SELECT only. no database param, just id using headers', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4', url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -147,7 +145,7 @@ test('GET /api/v1/sql with SQL parameter on SELECT only. no database param, just
}); });
}); });
test('GET /user/vizzuality/api/v1/sql with SQL parameter on SELECT only', function(done){ it('GET /user/vizzuality/api/v1/sql with SQL parameter on SELECT only', function(done){
assert.response(app, { assert.response(app, {
url: '/user/vizzuality/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4', url: '/user/vizzuality/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4',
method: 'GET' method: 'GET'
@ -159,7 +157,7 @@ test('GET /user/vizzuality/api/v1/sql with SQL parameter on SELECT only', functi
// See https://github.com/CartoDB/CartoDB-SQL-API/issues/121 // See https://github.com/CartoDB/CartoDB-SQL-API/issues/121
test('SELECT from user-specific database', function(done){ it('SELECT from user-specific database', function(done){
var backupDBHost = global.settings.db_host; var backupDBHost = global.settings.db_host;
global.settings.db_host = '6.6.6.6'; global.settings.db_host = '6.6.6.6';
assert.response(app, { assert.response(app, {
@ -182,7 +180,7 @@ test('SELECT from user-specific database', function(done){
}); });
// See https://github.com/CartoDB/CartoDB-SQL-API/issues/120 // See https://github.com/CartoDB/CartoDB-SQL-API/issues/120
test('SELECT with user-specific password', function(done){ it('SELECT with user-specific password', function(done){
var backupDBUserPass = global.settings.db_user_pass; var backupDBUserPass = global.settings.db_user_pass;
global.settings.db_user_pass = '<%= user_password %>'; global.settings.db_user_pass = '<%= user_password %>';
assert.response(app, { assert.response(app, {
@ -204,7 +202,7 @@ test('SELECT with user-specific password', function(done){
}); });
}); });
test('GET /api/v1/sql with SQL parameter on SELECT only. no database param, just id using headers. Authenticated.', it('GET /api/v1/sql with SQL parameter on SELECT only. no database param, just id using headers. Authenticated.',
function(done){ function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20cartodb_id*2%20FROM%20untitle_table_4&api_key=1234', url: '/api/v1/sql?q=SELECT%20cartodb_id*2%20FROM%20untitle_table_4&api_key=1234',
@ -220,7 +218,7 @@ function(done){
}); });
// Test for https://github.com/Vizzuality/CartoDB-SQL-API/issues/85 // Test for https://github.com/Vizzuality/CartoDB-SQL-API/issues/85
test("paging doesn't break x-cache-channel", it("paging doesn't break x-cache-channel",
function(done){ function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?' + querystring.stringify({ url: '/api/v1/sql?' + querystring.stringify({
@ -242,13 +240,14 @@ function(done){
}); });
// Test page and rows_per_page params // Test page and rows_per_page params
test("paging", function(done){ it("paging", function(done){
var sql = 'SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(v)'; var sql = 'SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(v)';
var pr = [ [2,3], [0,4] ]; // page and rows var pr = [ [2,3], [0,4] ]; // page and rows
var methods = [ 'GET', 'POST' ]; var methods = [ 'GET', 'POST' ];
var authorized = 0; var authorized = 0;
var testing = 0; var testing = 0;
var method = 0; var method = 0;
// jshint maxcomplexity:7
var testNext = function() { var testNext = function() {
if ( testing >= pr.length ) { if ( testing >= pr.length ) {
if ( method+1 >= methods.length ) { if ( method+1 >= methods.length ) {
@ -266,9 +265,8 @@ test("paging", function(done){
} }
} }
var prcur = pr[testing++]; var prcur = pr[testing++];
console.log("Test " + testing + "/" + pr.length console.log("Test " + testing + "/" + pr.length + " method " + methods[method] + " " +
+ " method " + methods[method] + " " ( authorized ? "authenticated" : "" ) );
+ ( authorized ? "authenticated" : "" ) );
var page = prcur[0]; var page = prcur[0];
var nrows = prcur[1]; var nrows = prcur[1];
var data_obj = { var data_obj = {
@ -276,13 +274,15 @@ test("paging", function(done){
rows_per_page: nrows, rows_per_page: nrows,
page: page page: page
}; };
if ( authorized ) data_obj['api_key'] = '1234'; if ( authorized ) {
data_obj.api_key = '1234';
}
var data = querystring.stringify(data_obj); var data = querystring.stringify(data_obj);
var req = { var req = {
url: '/api/v1/sql', url: '/api/v1/sql',
headers: {host: 'vizzuality.cartodb.com'} headers: {host: 'vizzuality.cartodb.com'}
}; };
if ( methods[method] == 'GET' ) { if ( methods[method] === 'GET' ) {
req.method = 'GET'; req.method = 'GET';
req.url += '?' + data; req.url += '?' + data;
} else { } else {
@ -306,7 +306,7 @@ test("paging", function(done){
}); });
// Test paging with WITH queries // Test paging with WITH queries
test("paging starting with comment", function(done){ it("paging starting with comment", function(done){
var sql = "-- this is a comment\n" + var sql = "-- this is a comment\n" +
"SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(v)"; "SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(v)";
var nrows = 3; var nrows = 3;
@ -332,7 +332,7 @@ test("paging starting with comment", function(done){
}); });
}); });
test('POST /api/v1/sql with SQL parameter on SELECT only. no database param, just id using headers', function(done){ it('POST /api/v1/sql with SQL parameter on SELECT only. no database param, just id using headers', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql', url: '/api/v1/sql',
data: querystring.stringify({q: "SELECT * FROM untitle_table_4"}), data: querystring.stringify({q: "SELECT * FROM untitle_table_4"}),
@ -344,9 +344,10 @@ test('POST /api/v1/sql with SQL parameter on SELECT only. no database param, jus
}); });
}); });
test('GET /api/v1/sql with INSERT. oAuth not used, so public user - should fail', function(done){ it('GET /api/v1/sql with INSERT. oAuth not used, so public user - should fail', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?q=INSERT%20INTO%20untitle_table_4%20(cartodb_id)%20VALUES%20(1e4)&database=cartodb_test_user_1_db", url: "/api/v1/sql?q=INSERT%20INTO%20untitle_table_4%20(cartodb_id)%20VALUES%20(1e4)" +
"&database=cartodb_test_user_1_db",
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
method: 'GET' method: 'GET'
},{ },{
@ -361,7 +362,7 @@ test('GET /api/v1/sql with INSERT. oAuth not used, so public user - should fail'
}); });
}); });
test('GET /api/v1/sql with DROP TABLE. oAuth not used, so public user - should fail', function(done){ it('GET /api/v1/sql with DROP TABLE. oAuth not used, so public user - should fail', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?q=DROP%20TABLE%20untitle_table_4&database=cartodb_test_user_1_db", url: "/api/v1/sql?q=DROP%20TABLE%20untitle_table_4&database=cartodb_test_user_1_db",
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -378,7 +379,7 @@ test('GET /api/v1/sql with DROP TABLE. oAuth not used, so public user - should f
}); });
}); });
test('GET /api/v1/sql with INSERT. header based db - should fail', function(){ it('GET /api/v1/sql with INSERT. header based db - should fail', function(){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?q=INSERT%20INTO%20untitle_table_4%20(id)%20VALUES%20(1)", url: "/api/v1/sql?q=INSERT%20INTO%20untitle_table_4%20(id)%20VALUES%20(1)",
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -391,11 +392,10 @@ test('GET /api/v1/sql with INSERT. header based db - should fail', function(){
// Check results from INSERT // Check results from INSERT
// //
// See https://github.com/Vizzuality/CartoDB-SQL-API/issues/13 // See https://github.com/Vizzuality/CartoDB-SQL-API/issues/13
test('INSERT returns affected rows', function(done){ it('INSERT returns affected rows', function(done){
assert.response(app, { assert.response(app, {
// view prepare_db.sh to see where to set api_key // view prepare_db.sh to see where to set api_key
url: "/api/v1/sql?api_key=1234&" url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
+ querystring.stringify({q:
"INSERT INTO private_table(name) VALUES('noret1') UNION VALUES('noret2')" "INSERT INTO private_table(name) VALUES('noret1') UNION VALUES('noret2')"
}), }),
headers: {host: 'vizzuality.localhost.lan:8080' }, headers: {host: 'vizzuality.localhost.lan:8080' },
@ -417,11 +417,10 @@ test('INSERT returns affected rows', function(done){
// Check results from UPDATE // Check results from UPDATE
// //
// See https://github.com/Vizzuality/CartoDB-SQL-API/issues/13 // See https://github.com/Vizzuality/CartoDB-SQL-API/issues/13
test('UPDATE returns affected rows', function(done){ it('UPDATE returns affected rows', function(done){
assert.response(app, { assert.response(app, {
// view prepare_db.sh to see where to set api_key // view prepare_db.sh to see where to set api_key
url: "/api/v1/sql?api_key=1234&" url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
+ querystring.stringify({q:
"UPDATE private_table SET name = upper(name) WHERE name in ('noret1', 'noret2')" "UPDATE private_table SET name = upper(name) WHERE name in ('noret1', 'noret2')"
}), }),
headers: {host: 'vizzuality.localhost.lan:8080' }, headers: {host: 'vizzuality.localhost.lan:8080' },
@ -443,11 +442,10 @@ test('UPDATE returns affected rows', function(done){
// Check results from DELETE // Check results from DELETE
// //
// See https://github.com/Vizzuality/CartoDB-SQL-API/issues/13 // See https://github.com/Vizzuality/CartoDB-SQL-API/issues/13
test('DELETE returns affected rows', function(done){ it('DELETE returns affected rows', function(done){
assert.response(app, { assert.response(app, {
// view prepare_db.sh to see where to set api_key // view prepare_db.sh to see where to set api_key
url: "/api/v1/sql?api_key=1234&" url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
+ querystring.stringify({q:
"DELETE FROM private_table WHERE name in ('NORET1', 'NORET2')" "DELETE FROM private_table WHERE name in ('NORET1', 'NORET2')"
}), }),
headers: {host: 'vizzuality.localhost.lan:8080' }, headers: {host: 'vizzuality.localhost.lan:8080' },
@ -469,11 +467,10 @@ test('DELETE returns affected rows', function(done){
// Check results from INSERT .. RETURNING // Check results from INSERT .. RETURNING
// //
// See https://github.com/Vizzuality/CartoDB-SQL-API/issues/50 // See https://github.com/Vizzuality/CartoDB-SQL-API/issues/50
test('INSERT with RETURNING returns all results', function(done){ it('INSERT with RETURNING returns all results', function(done){
assert.response(app, { assert.response(app, {
// view prepare_db.sh to see where to set api_key // view prepare_db.sh to see where to set api_key
url: "/api/v1/sql?api_key=1234&" url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
+ querystring.stringify({q:
"INSERT INTO private_table(name) VALUES('test') RETURNING upper(name), reverse(name)" "INSERT INTO private_table(name) VALUES('test') RETURNING upper(name), reverse(name)"
}), }),
headers: {host: 'vizzuality.localhost.lan:8080' }, headers: {host: 'vizzuality.localhost.lan:8080' },
@ -494,11 +491,10 @@ test('INSERT with RETURNING returns all results', function(done){
// Check results from UPDATE .. RETURNING // Check results from UPDATE .. RETURNING
// //
// See https://github.com/Vizzuality/CartoDB-SQL-API/issues/50 // See https://github.com/Vizzuality/CartoDB-SQL-API/issues/50
test('UPDATE with RETURNING returns all results', function(done){ it('UPDATE with RETURNING returns all results', function(done){
assert.response(app, { assert.response(app, {
// view prepare_db.sh to see where to set api_key // view prepare_db.sh to see where to set api_key
url: "/api/v1/sql?api_key=1234&" url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
+ querystring.stringify({q:
"UPDATE private_table SET name = 'tost' WHERE name = 'test' RETURNING upper(name), reverse(name)" "UPDATE private_table SET name = 'tost' WHERE name = 'test' RETURNING upper(name), reverse(name)"
}), }),
headers: {host: 'vizzuality.localhost.lan:8080' }, headers: {host: 'vizzuality.localhost.lan:8080' },
@ -519,11 +515,10 @@ test('UPDATE with RETURNING returns all results', function(done){
// Check results from DELETE .. RETURNING // Check results from DELETE .. RETURNING
// //
// See https://github.com/Vizzuality/CartoDB-SQL-API/issues/50 // See https://github.com/Vizzuality/CartoDB-SQL-API/issues/50
test('DELETE with RETURNING returns all results', function(done){ it('DELETE with RETURNING returns all results', function(done){
assert.response(app, { assert.response(app, {
// view prepare_db.sh to see where to set api_key // view prepare_db.sh to see where to set api_key
url: "/api/v1/sql?api_key=1234&" url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
+ querystring.stringify({q:
"DELETE FROM private_table WHERE name = 'tost' RETURNING name" "DELETE FROM private_table WHERE name = 'tost' RETURNING name"
}), }),
headers: {host: 'vizzuality.localhost.lan:8080' }, headers: {host: 'vizzuality.localhost.lan:8080' },
@ -540,7 +535,7 @@ test('DELETE with RETURNING returns all results', function(done){
}); });
}); });
test('GET /api/v1/sql with SQL parameter on DROP TABLE. should fail', function(done){ it('GET /api/v1/sql with SQL parameter on DROP TABLE. should fail', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?q=DROP%20TABLE%20untitle_table_4", url: "/api/v1/sql?q=DROP%20TABLE%20untitle_table_4",
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -559,11 +554,10 @@ test('GET /api/v1/sql with SQL parameter on DROP TABLE. should fail', function(d
// Check X-Cache-Channel when querying "updated_at" fields // Check X-Cache-Channel when querying "updated_at" fields
// //
// See https://github.com/Vizzuality/CartoDB-SQL-API/issues/99 // See https://github.com/Vizzuality/CartoDB-SQL-API/issues/99
test('Field name is not confused with UPDATE operation', function(done){ it('Field name is not confused with UPDATE operation', function(done){
assert.response(app, { assert.response(app, {
// view prepare_db.sh to see where to set api_key // view prepare_db.sh to see where to set api_key
url: "/api/v1/sql?api_key=1234&" url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
+ querystring.stringify({q:
"SELECT min(updated_at) FROM private_table" "SELECT min(updated_at) FROM private_table"
}), }),
headers: {host: 'vizzuality.localhost.lan:8080' }, headers: {host: 'vizzuality.localhost.lan:8080' },
@ -575,7 +569,7 @@ test('Field name is not confused with UPDATE operation', function(done){
}); });
}); });
test('CREATE TABLE with GET and auth', function(done){ it('CREATE TABLE with GET and auth', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?" + querystring.stringify({ url: "/api/v1/sql?" + querystring.stringify({
q: 'CREATE TABLE test_table(a int)', q: 'CREATE TABLE test_table(a int)',
@ -594,9 +588,9 @@ test('CREATE TABLE with GET and auth', function(done){
}); });
// See http://github.com/CartoDB/CartoDB-SQL-API/issues/127 // See http://github.com/CartoDB/CartoDB-SQL-API/issues/127
test('SELECT INTO with paging ', function(done){ it('SELECT INTO with paging ', function(done){
var esc_tabname = 'test ""select into""'; // escaped ident var esc_tabname = 'test ""select into""'; // escaped ident
Step( step(
function select_into() { function select_into() {
var next = this; var next = this;
assert.response(app, { assert.response(app, {
@ -610,7 +604,7 @@ test('SELECT INTO with paging ', function(done){
},{}, function(res) { next(null, res); }); },{}, function(res) { next(null, res); });
}, },
function check_res_test_fake_into_1(err, res) { function check_res_test_fake_into_1(err, res) {
if ( err ) throw err; assert.ifError(err);
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body); assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
var next = this; var next = this;
assert.response(app, { assert.response(app, {
@ -624,7 +618,7 @@ test('SELECT INTO with paging ', function(done){
},{}, function(res) { next(null, res); }); },{}, function(res) { next(null, res); });
}, },
function check_res_drop_table(err, res) { function check_res_drop_table(err, res) {
if ( err ) throw err; assert.ifError(err);
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body); assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
var out = JSON.parse(res.body); var out = JSON.parse(res.body);
assert.equal(out.total_rows, 1); // windowing works assert.equal(out.total_rows, 1); // windowing works
@ -639,19 +633,19 @@ test('SELECT INTO with paging ', function(done){
},{}, function(res) { next(null, res); }); },{}, function(res) { next(null, res); });
}, },
function check_drop(err, res) { function check_drop(err, res) {
if ( err ) throw err; assert.ifError(err);
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body); assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
return null; return null;
}, },
function finish(err) { function finish(err) {
done(err) done(err);
} }
); );
}); });
// Test effects of COPY // Test effects of COPY
// See https://github.com/Vizzuality/cartodb-management/issues/1502 // See https://github.com/Vizzuality/cartodb-management/issues/1502
test('COPY TABLE with GET and auth', function(done){ it('COPY TABLE with GET and auth', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?" + querystring.stringify({ url: "/api/v1/sql?" + querystring.stringify({
q: 'COPY test_table FROM stdin;', q: 'COPY test_table FROM stdin;',
@ -669,7 +663,7 @@ test('COPY TABLE with GET and auth', function(done){
}); });
}); });
test('COPY TABLE with GET and auth', function(done){ it('COPY TABLE with GET and auth', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?" + querystring.stringify({ url: "/api/v1/sql?" + querystring.stringify({
q: "COPY test_table to '/tmp/x';", q: "COPY test_table to '/tmp/x';",
@ -690,7 +684,7 @@ test('COPY TABLE with GET and auth', function(done){
}); });
}); });
test('ALTER TABLE with GET and auth', function(done){ it('ALTER TABLE with GET and auth', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?" + querystring.stringify({ url: "/api/v1/sql?" + querystring.stringify({
q: 'ALTER TABLE test_table ADD b int', q: 'ALTER TABLE test_table ADD b int',
@ -708,10 +702,11 @@ test('ALTER TABLE with GET and auth', function(done){
}); });
}); });
test('multistatement insert, alter, select, begin, commit', function(done){ it('multistatement insert, alter, select, begin, commit', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?" + querystring.stringify({ url: "/api/v1/sql?" + querystring.stringify({
q: 'BEGIN; DELETE FROM test_table; COMMIT; BEGIN; INSERT INTO test_table(b) values (5); COMMIT; ALTER TABLE test_table ALTER b TYPE float USING b::float/2; SELECT b FROM test_table;', q: 'BEGIN; DELETE FROM test_table; COMMIT; BEGIN; INSERT INTO test_table(b) values (5); COMMIT; ' +
'ALTER TABLE test_table ALTER b TYPE float USING b::float/2; SELECT b FROM test_table;',
api_key: 1234 api_key: 1234
}), }),
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -725,7 +720,7 @@ test('multistatement insert, alter, select, begin, commit', function(done){
}); });
}); });
test('TRUNCATE TABLE with GET and auth', function(done){ it('TRUNCATE TABLE with GET and auth', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?" + querystring.stringify({ url: "/api/v1/sql?" + querystring.stringify({
q: 'TRUNCATE TABLE test_table', q: 'TRUNCATE TABLE test_table',
@ -752,13 +747,13 @@ test('TRUNCATE TABLE with GET and auth', function(done){
assert.equal(res.headers['cache-control'], expected_cache_control); assert.equal(res.headers['cache-control'], expected_cache_control);
var pbody = JSON.parse(res.body); var pbody = JSON.parse(res.body);
assert.equal(pbody.total_rows, 1); assert.equal(pbody.total_rows, 1);
assert.equal(pbody.rows[0]['count'], 0); assert.equal(pbody.rows[0].count, 0);
done(); done();
}); });
}); });
}); });
test('REINDEX TABLE with GET and auth', function(done){ it('REINDEX TABLE with GET and auth', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?" + querystring.stringify({ url: "/api/v1/sql?" + querystring.stringify({
q: ' ReINdEX TABLE test_table', q: ' ReINdEX TABLE test_table',
@ -776,7 +771,7 @@ test('REINDEX TABLE with GET and auth', function(done){
}); });
}); });
test('DROP TABLE with GET and auth', function(done){ it('DROP TABLE with GET and auth', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?" + querystring.stringify({ url: "/api/v1/sql?" + querystring.stringify({
q: 'DROP TABLE test_table', q: 'DROP TABLE test_table',
@ -812,7 +807,7 @@ test('CREATE FUNCTION with GET and auth', function(done){
}); });
}); });
test('DROP FUNCTION with GET and auth', function(done){ it('DROP FUNCTION with GET and auth', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?" + querystring.stringify({ url: "/api/v1/sql?" + querystring.stringify({
q: 'DROP FUNCTION create_func_test(a int)', q: 'DROP FUNCTION create_func_test(a int)',
@ -830,7 +825,7 @@ test('DROP FUNCTION with GET and auth', function(done){
}); });
}); });
test('sends a 400 when an unsupported format is requested', function(done){ it('sends a 400 when an unsupported format is requested', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&format=unknown', url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&format=unknown',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -844,7 +839,7 @@ test('sends a 400 when an unsupported format is requested', function(done){
}); });
}); });
test('GET /api/v1/sql with SQL parameter and no format, ensuring content-disposition set to json', function(done){ it('GET /api/v1/sql with SQL parameter and no format, ensuring content-disposition set to json', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4', url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -860,7 +855,7 @@ test('GET /api/v1/sql with SQL parameter and no format, ensuring content-disposi
}); });
}); });
test('POST /api/v1/sql with SQL parameter and no format, ensuring content-disposition set to json', function(done){ it('POST /api/v1/sql with SQL parameter and no format, ensuring content-disposition set to json', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql', url: '/api/v1/sql',
data: querystring.stringify({q: "SELECT * FROM untitle_table_4" }), data: querystring.stringify({q: "SELECT * FROM untitle_table_4" }),
@ -877,7 +872,7 @@ test('POST /api/v1/sql with SQL parameter and no format, ensuring content-dispos
}); });
}); });
test('GET /api/v1/sql with SQL parameter and no format, but a filename', function(done){ it('GET /api/v1/sql with SQL parameter and no format, but a filename', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&filename=x', url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&filename=x',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -893,7 +888,7 @@ test('GET /api/v1/sql with SQL parameter and no format, but a filename', functio
}); });
}); });
test('field named "the_geom_webmercator" is not skipped by default', function(done){ it('field named "the_geom_webmercator" is not skipped by default', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4', url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -913,7 +908,7 @@ test('field named "the_geom_webmercator" is not skipped by default', function(do
}); });
}); });
test('skipfields controls included fields', function(done){ it('skipfields controls included fields', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&skipfields=the_geom_webmercator,cartodb_id,unexistant', url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&skipfields=the_geom_webmercator,cartodb_id,unexistant',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -933,9 +928,10 @@ test('skipfields controls included fields', function(done){
}); });
}); });
test('multiple skipfields parameter do not kill the backend', function(done){ it('multiple skipfields parameter do not kill the backend', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&skipfields=unexistent,the_geom_webmercator&skipfields=cartodb_id,unexistant', url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&skipfields=unexistent,the_geom_webmercator' +
'&skipfields=cartodb_id,unexistant',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
method: 'GET' method: 'GET'
},{ }, function(res){ },{ }, function(res){
@ -953,7 +949,7 @@ test('multiple skipfields parameter do not kill the backend', function(done){
}); });
}); });
test('GET /api/v1/sql ensure cross domain set on errors', function(done){ it('GET /api/v1/sql ensure cross domain set on errors', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20*gadfgadfg%20FROM%20untitle_table_4', url: '/api/v1/sql?q=SELECT%20*gadfgadfg%20FROM%20untitle_table_4',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -1013,7 +1009,7 @@ var systemQueriesSuitesToTest = [
function testSystemQueries(description, queries, statusErrorCode, apiKey) { function testSystemQueries(description, queries, statusErrorCode, apiKey) {
queries.forEach(function(query) { queries.forEach(function(query) {
test('[' + description + '] query: ' + query, function(done) { it('[' + description + '] query: ' + query, function(done) {
var queryStringParams = {q: query}; var queryStringParams = {q: query};
if (!!apiKey) { if (!!apiKey) {
queryStringParams.api_key = apiKey; queryStringParams.api_key = apiKey;
@ -1031,23 +1027,26 @@ function testSystemQueries(description, queries, statusErrorCode, apiKey) {
}); });
} }
test('GET decent error if domain is incorrect', function(done){ it('GET decent error if domain is incorrect', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&format=geojson', url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&format=geojson',
headers: {host: 'vizzualinot.cartodb.com'}, headers: {host: 'vizzualinot.cartodb.com'},
method: 'GET' method: 'GET'
}, {}, function(res){ }, {}, function(res){
assert.equal(res.statusCode, 404, res.statusCode + ( res.statusCode != 200 ? ( ': ' + res.body ) : '')); assert.equal(res.statusCode, 404, res.statusCode + ( res.statusCode !== 200 ? ( ': ' + res.body ) : ''));
assert.deepEqual(res.headers['content-type'], 'application/json; charset=utf-8'); assert.deepEqual(res.headers['content-type'], 'application/json; charset=utf-8');
assert.deepEqual(res.headers['content-disposition'], 'inline'); assert.deepEqual(res.headers['content-disposition'], 'inline');
var result = JSON.parse(res.body); var result = JSON.parse(res.body);
assert.equal(result.error[0],"Sorry, we can't find CartoDB user 'vizzualinot'. Please check that you have entered the correct domain."); assert.equal(
result.error[0],
"Sorry, we can't find CartoDB user 'vizzualinot'. Please check that you have entered the correct domain."
);
done(); done();
}); });
}); });
// this test does not make sense with the current CDB_QueryTables implementation // this test does not make sense with the current CDB_QueryTables implementation
test('GET decent error if SQL is broken', function(done){ it('GET decent error if SQL is broken', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?' + querystring.stringify({q: url: '/api/v1/sql?' + querystring.stringify({q:
'SELECT star FROM this and that' 'SELECT star FROM this and that'
@ -1066,10 +1065,9 @@ test('GET decent error if SQL is broken', function(done){
}); });
// See https://github.com/Vizzuality/CartoDB-SQL-API/issues/88 // See https://github.com/Vizzuality/CartoDB-SQL-API/issues/88
test('numeric arrays are rendered as such', function(done){ it('numeric arrays are rendered as such', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?" url: "/api/v1/sql?" + querystring.stringify({q:
+ querystring.stringify({q:
"SELECT ARRAY[8.7,4.3]::numeric[] as x" "SELECT ARRAY[8.7,4.3]::numeric[] as x"
}), }),
headers: {host: 'vizzuality.localhost.lan:8080' }, headers: {host: 'vizzuality.localhost.lan:8080' },
@ -1090,7 +1088,7 @@ test('numeric arrays are rendered as such', function(done){
}); });
// See https://github.com/Vizzuality/CartoDB-SQL-API/issues/97 // See https://github.com/Vizzuality/CartoDB-SQL-API/issues/97
test('field names and types are exposed', function(done){ it('field names and types are exposed', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?' + querystring.stringify({ url: '/api/v1/sql?' + querystring.stringify({
q: "SELECT 1::int as a, 2::float8 as b, 3::varchar as c, " + q: "SELECT 1::int as a, 2::float8 as b, 3::varchar as c, " +
@ -1123,7 +1121,7 @@ test('field names and types are exposed', function(done){
}); });
// See https://github.com/CartoDB/CartoDB-SQL-API/issues/109 // See https://github.com/CartoDB/CartoDB-SQL-API/issues/109
test('schema response takes skipfields into account', function(done){ it('schema response takes skipfields into account', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?' + querystring.stringify({ url: '/api/v1/sql?' + querystring.stringify({
q: "SELECT 1 as a, 2 as b, 3 as c ", q: "SELECT 1 as a, 2 as b, 3 as c ",
@ -1143,7 +1141,7 @@ test('schema response takes skipfields into account', function(done){
}); });
// See https://github.com/Vizzuality/CartoDB-SQL-API/issues/100 // See https://github.com/Vizzuality/CartoDB-SQL-API/issues/100
test('numeric fields are rendered as numbers in JSON', function(done){ it('numeric fields are rendered as numbers in JSON', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?' + querystring.stringify({ url: '/api/v1/sql?' + querystring.stringify({
q: "WITH inp AS ( SELECT 1::int2 as a, 2::int4 as b, " + q: "WITH inp AS ( SELECT 1::int2 as a, 2::int4 as b, " +
@ -1191,8 +1189,8 @@ test('numeric fields are rendered as numbers in JSON', function(done){
// numbers, but it'd currently take running the // numbers, but it'd currently take running the
// test again (new mocha run) with a different TZ // test again (new mocha run) with a different TZ
// //
test('timezone info in JSON output', function(done){ it('timezone info in JSON output', function(done){
Step( step(
function testEuropeRomeExplicit() { function testEuropeRomeExplicit() {
var next = this; var next = this;
assert.response(app, { assert.response(app, {
@ -1213,7 +1211,7 @@ test('timezone info in JSON output', function(done){
}); });
}, },
function testEuropeRomeImplicit(err) { function testEuropeRomeImplicit(err) {
if ( err ) throw err; assert.ifError(err);
var next = this; var next = this;
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?' + querystring.stringify({ url: '/api/v1/sql?' + querystring.stringify({
@ -1233,7 +1231,7 @@ test('timezone info in JSON output', function(done){
}); });
}, },
function testUTCExplicit(err) { function testUTCExplicit(err) {
if ( err ) throw err; assert.ifError(err);
var next = this; var next = this;
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?' + querystring.stringify({ url: '/api/v1/sql?' + querystring.stringify({
@ -1253,7 +1251,7 @@ test('timezone info in JSON output', function(done){
}); });
}, },
function testUTCImplicit(err) { function testUTCImplicit(err) {
if ( err ) throw err; assert.ifError(err);
var next = this; var next = this;
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?' + querystring.stringify({ url: '/api/v1/sql?' + querystring.stringify({
@ -1280,13 +1278,15 @@ test('timezone info in JSON output', function(done){
// WARNING and NOTICE in JSON output // WARNING and NOTICE in JSON output
// See https://github.com/CartoDB/CartoDB-SQL-API/issues/104 // See https://github.com/CartoDB/CartoDB-SQL-API/issues/104
test('notice and warning info in JSON output', function(done){ it('notice and warning info in JSON output', function(done){
Step( step(
function addRaiseFunction() { function addRaiseFunction() {
var next = this; var next = this;
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?' + querystring.stringify({ url: '/api/v1/sql?' + querystring.stringify({
q: "create or replace function raise(lvl text, msg text) returns void as $$ begin if lvl = 'notice' then raise notice '%', msg; elsif lvl = 'warning' then raise warning '%', msg; else raise exception '%', msg; end if; end; $$ language plpgsql;", q: "create or replace function raise(lvl text, msg text) returns void as $$ begin if lvl = 'notice' " +
"then raise notice '%', msg; elsif lvl = 'warning' then raise warning '%', msg; " +
"else raise exception '%', msg; end if; end; $$ language plpgsql;",
api_key: '1234' api_key: '1234'
}), }),
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -1300,7 +1300,7 @@ test('notice and warning info in JSON output', function(done){
}); });
}, },
function raiseNotice(err) { function raiseNotice(err) {
if ( err ) throw err; assert.ifError(err);
var next = this; var next = this;
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?' + querystring.stringify({ url: '/api/v1/sql?' + querystring.stringify({
@ -1321,7 +1321,7 @@ test('notice and warning info in JSON output', function(done){
}); });
}, },
function raiseWarning(err) { function raiseWarning(err) {
if ( err ) throw err; assert.ifError(err);
var next = this; var next = this;
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?' + querystring.stringify({ url: '/api/v1/sql?' + querystring.stringify({
@ -1342,11 +1342,12 @@ test('notice and warning info in JSON output', function(done){
}); });
}, },
function raiseBothWarningAndNotice(err) { function raiseBothWarningAndNotice(err) {
if ( err ) throw err; assert.ifError(err);
var next = this; var next = this;
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?' + querystring.stringify({ url: '/api/v1/sql?' + querystring.stringify({
q: "SET client_min_messages TO 'notice'; select raise('warning', 'hello again warning'), raise('notice', 'hello again notice');" q: "SET client_min_messages TO 'notice'; select raise('warning', 'hello again warning'), " +
"raise('notice', 'hello again notice');"
}), }),
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
method: 'GET' method: 'GET'
@ -1377,7 +1378,7 @@ test('notice and warning info in JSON output', function(done){
},{ }, function(res) { },{ }, function(res) {
try { try {
assert.equal(res.statusCode, 200, res.body); assert.equal(res.statusCode, 200, res.body);
var parsedBody = JSON.parse(res.body); JSON.parse(res.body);
} catch (e) { err = new Error(err + ',' + e); } } catch (e) { err = new Error(err + ',' + e); }
next(err); next(err);
}); });
@ -1391,7 +1392,7 @@ test('notice and warning info in JSON output', function(done){
/** /**
* CORS * CORS
*/ */
test('GET /api/v1/sql with SQL parameter on SELECT only should return CORS headers ', function(done){ it('GET /api/v1/sql with SQL parameter on SELECT only should return CORS headers ', function(done){
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db', url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -1402,12 +1403,15 @@ test('GET /api/v1/sql with SQL parameter on SELECT only should return CORS heade
assert.equal(res.headers['x-cache-channel'], 'cartodb_test_user_1_db:public.untitle_table_4'); assert.equal(res.headers['x-cache-channel'], 'cartodb_test_user_1_db:public.untitle_table_4');
assert.equal(res.headers['cache-control'], expected_cache_control); assert.equal(res.headers['cache-control'], expected_cache_control);
assert.equal(res.headers['access-control-allow-origin'], '*'); assert.equal(res.headers['access-control-allow-origin'], '*');
assert.equal(res.headers['access-control-allow-headers'], "X-Requested-With, X-Prototype-Version, X-CSRF-Token"); assert.equal(
res.headers['access-control-allow-headers'],
"X-Requested-With, X-Prototype-Version, X-CSRF-Token"
);
done(); done();
}); });
}); });
test('GET with callback param returns wrapped result set with callback as jsonp', function(done) { it('GET with callback param returns wrapped result set with callback as jsonp', function(done) {
assert.response(app, { assert.response(app, {
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&callback=foo_jsonp', url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&callback=foo_jsonp',
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -1419,7 +1423,7 @@ test('GET with callback param returns wrapped result set with callback as jsonp'
}); });
}); });
test('GET with callback must return 200 status error even if it is an error', function(done){ it('GET with callback must return 200 status error even if it is an error', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?q=DROP%20TABLE%20untitle_table_4&callback=foo_jsonp", url: "/api/v1/sql?q=DROP%20TABLE%20untitle_table_4&callback=foo_jsonp",
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -1427,17 +1431,19 @@ test('GET with callback must return 200 status error even if it is an error', fu
},{}, function(res) { },{}, function(res) {
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body); assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
var didRunJsonCallback = false; var didRunJsonCallback = false;
// jshint ignore:start
function foo_jsonp(body) { function foo_jsonp(body) {
assert.deepEqual(body, {"error":["must be owner of relation untitle_table_4"]}); assert.deepEqual(body, {"error":["must be owner of relation untitle_table_4"]});
didRunJsonCallback = true; didRunJsonCallback = true;
} }
eval(res.body); eval(res.body);
// jshint ignore:end
assert.ok(didRunJsonCallback); assert.ok(didRunJsonCallback);
done(); done();
}); });
}); });
test('GET with slow query exceeding statement timeout returns proper error message', function(done){ it('GET with slow query exceeding statement timeout returns proper error message', function(done){
assert.response(app, { assert.response(app, {
url: "/api/v1/sql?q=select%20pg_sleep(2.1)%20as%20sleep", url: "/api/v1/sql?q=select%20pg_sleep(2.1)%20as%20sleep",
headers: {host: 'vizzuality.cartodb.com'}, headers: {host: 'vizzuality.cartodb.com'},
@ -1452,7 +1458,7 @@ test('GET with callback must return 200 status error even if it is an error', fu
}); });
}); });
test('stream response is closed on error and error message is part of the response', function(done){ it('stream response is closed on error and error message is part of the response', function(done){
assert.response( assert.response(
app, app,
{ {
@ -1475,7 +1481,7 @@ test('GET with callback must return 200 status error even if it is an error', fu
); );
}); });
test('too large rows get into error log', function(done){ it('too large rows get into error log', function(done){
var dbMaxRowSize = global.settings.db_max_row_size; var dbMaxRowSize = global.settings.db_max_row_size;
global.settings.db_max_row_size = 4; global.settings.db_max_row_size = 4;

View File

@ -1,13 +1,8 @@
require('../helper'); require('../helper');
require('../support/assert');
var assert = require('assert') var assert = require('../support/assert');
, App = require(global.settings.app_root + '/app/controllers/app') var step = require('step');
, querystring = require('querystring') var net = require('net');
, _ = require('underscore')
, Step = require('step')
, net = require('net')
;
var sql_server_port = 5540; var sql_server_port = 5540;
var sql_server = net.createServer(function(c) { var sql_server = net.createServer(function(c) {
@ -19,21 +14,21 @@ var sql_server = net.createServer(function(c) {
}); });
}); });
suite('backend crash', function() { describe('backend crash', function() {
suiteSetup(function(done){ before(function(done){
sql_server.listen(sql_server_port, done); sql_server.listen(sql_server_port, done);
}); });
// See https://github.com/CartoDB/CartoDB-SQL-API/issues/135 // See https://github.com/CartoDB/CartoDB-SQL-API/issues/135
test('does not hang server', function(done){ it('does not hang server', function(done){
//console.log("settings:"); console.dir(global.settings); //console.log("settings:"); console.dir(global.settings);
var db_host_backup = global.settings.db_host; var db_host_backup = global.settings.db_host;
var db_port_backup = global.settings.db_port; var db_port_backup = global.settings.db_port;
global.settings.db_host = 'localhost'; global.settings.db_host = 'localhost';
global.settings.db_port = sql_server_port; global.settings.db_port = sql_server_port;
var app = App(); var app = require(global.settings.app_root + '/app/controllers/app')();
Step( step(
function sendQuery() { function sendQuery() {
var next = this; var next = this;
assert.response(app, { assert.response(app, {
@ -45,7 +40,7 @@ test('does not hang server', function(done){
}); });
}, },
function checkResponse(err, res) { function checkResponse(err, res) {
if ( err ) throw err; assert.ifError(err);
assert.equal(res.statusCode, 500, res.statusCode + ': ' + res.body); assert.equal(res.statusCode, 500, res.statusCode + ': ' + res.body);
var parsed = JSON.parse(res.body); var parsed = JSON.parse(res.body);
assert.ok(parsed.error); assert.ok(parsed.error);
@ -64,7 +59,7 @@ test('does not hang server', function(done){
}); });
}, },
function checkResponse(err, res) { function checkResponse(err, res) {
if ( err ) throw err; assert.ifError(err);
assert.equal(res.statusCode, 500, res.statusCode + ': ' + res.body); assert.equal(res.statusCode, 500, res.statusCode + ': ' + res.body);
var parsed = JSON.parse(res.body); var parsed = JSON.parse(res.body);
assert.ok(parsed.error); assert.ok(parsed.error);
@ -80,7 +75,7 @@ test('does not hang server', function(done){
); );
}); });
suiteTeardown(function(done) { after(function(done) {
try { try {
sql_server.close(done); sql_server.close(done);
} catch (er) { } catch (er) {

View File

@ -1,14 +1,8 @@
require('../helper'); require('../helper');
require('../support/assert');
var assert = require('assert') var assert = require('../support/assert');
, App = require(global.settings.app_root + '/app/controllers/app') var step = require('step');
, querystring = require('querystring') var net = require('net');
, _ = require('underscore')
, Step = require('step')
, net = require('net')
, http = require('http')
;
var sql_server_data_handler; var sql_server_data_handler;
var sql_server_port = 5556; var sql_server_port = 5556;
@ -23,22 +17,22 @@ var sql_server = net.createServer(function(c) {
}); });
}); });
suite('frontend abort', function() { describe('frontend abort', function() {
suiteSetup(function(done){ before(function(done){
sql_server.listen(sql_server_port, done); sql_server.listen(sql_server_port, done);
}); });
// See https://github.com/CartoDB/CartoDB-SQL-API/issues/129 // See https://github.com/CartoDB/CartoDB-SQL-API/issues/129
test('aborts request', function(done){ it('aborts request', function(done){
//console.log("settings:"); console.dir(global.settings); //console.log("settings:"); console.dir(global.settings);
var db_host_backup = global.settings.db_host; var db_host_backup = global.settings.db_host;
var db_port_backup = global.settings.db_port; var db_port_backup = global.settings.db_port;
global.settings.db_host = 'localhost'; global.settings.db_host = 'localhost';
global.settings.db_port = sql_server_port; global.settings.db_port = sql_server_port;
var app = App(); var app = require(global.settings.app_root + '/app/controllers/app')();
var timeout; var timeout;
Step( step(
function sendQuery() { function sendQuery() {
var next = this; var next = this;
assert.response(app, { assert.response(app, {
@ -50,7 +44,7 @@ test('aborts request', function(done){
next(err, res); next(err, res);
}); });
}, },
function checkResponse(err, res) { function checkResponse(err/*, res*/) {
assert(err); // expect timeout assert(err); // expect timeout
assert.ok((''+err).match(/socket/), err); assert.ok((''+err).match(/socket/), err);
sql_server_data_handler = this; sql_server_data_handler = this;
@ -74,7 +68,7 @@ test('aborts request', function(done){
); );
}); });
suiteTeardown(function(done) { after(function(done) {
try { try {
sql_server.close(done); sql_server.close(done);
} catch (er) { } catch (er) {

View File

@ -1,12 +1,10 @@
require('../helper'); require('../helper');
require('../support/assert'); require('../support/assert');
var assert = require('assert'), var assert = require('assert');
App = require(global.settings.app_root + '/app/controllers/app'); var app = require(global.settings.app_root + '/app/controllers/app')();
var app = App(); describe('health checks', function() {
suite('health checks', function() {
beforeEach(function(done) { beforeEach(function(done) {
global.settings.health = { global.settings.health = {
@ -25,7 +23,7 @@ suite('health checks', function() {
} }
}; };
test('returns 200 and ok=true with disabled configuration', function(done) { it('returns 200 and ok=true with disabled configuration', function(done) {
global.settings.health.enabled = false; global.settings.health.enabled = false;
assert.response(app, assert.response(app,
@ -46,7 +44,7 @@ suite('health checks', function() {
); );
}); });
test('returns 200 and ok=true with enabled configuration', function(done) { it('returns 200 and ok=true with enabled configuration', function(done) {
assert.response(app, assert.response(app,
healthCheckRequest, healthCheckRequest,
{ {

View File

@ -13,25 +13,21 @@
* *
*/ */
require('../helper'); require('../helper');
require('../support/assert');
var assert = require('assert')
, App = require(global.settings.app_root + '/app/controllers/app')
, querystring = require('querystring')
, _ = require('underscore')
, Step = require('step')
;
suite('timeout', function() { var assert = require('../support/assert');
var step = require('step');
describe('timeout', function() {
// See https://github.com/CartoDB/CartoDB-SQL-API/issues/128 // See https://github.com/CartoDB/CartoDB-SQL-API/issues/128
test('after configured milliseconds', function(done){ it('after configured milliseconds', function(done){
var testTimeout = 10; var testTimeout = 10;
//console.log("settings:"); console.dir(global.settings); //console.log("settings:"); console.dir(global.settings);
var timeoutBackup = global.settings.node_socket_timeout; var timeoutBackup = global.settings.node_socket_timeout;
global.settings.node_socket_timeout = testTimeout; global.settings.node_socket_timeout = testTimeout;
var app = App(); var app = require(global.settings.app_root + '/app/controllers/app')();
Step( step(
function sendLongQuery() { function sendLongQuery() {
var next = this; var next = this;
assert.response(app, { assert.response(app, {
@ -42,7 +38,7 @@ test('after configured milliseconds', function(done){
next(err, res); next(err, res);
}); });
}, },
function checkResponse(err, res) { function checkResponse(err/*, res*/) {
assert.ok(err); assert.ok(err);
assert.ok(err.message.match(/hang up/), err); assert.ok(err.message.match(/hang up/), err);
return null; return null;

View File

@ -1,24 +1,23 @@
require('../helper'); require('../helper');
require('../support/assert');
var app = require(global.settings.app_root + '/app/controllers/app')() var app = require(global.settings.app_root + '/app/controllers/app')();
, assert = require('assert') var assert = require('../support/assert');
, querystring = require('querystring') var querystring = require('querystring');
, _ = require('underscore') var _ = require('underscore');
;
// allow lots of emitters to be set to silence warning // allow lots of emitters to be set to silence warning
app.setMaxListeners(0); app.setMaxListeners(0);
suite('x_cache_channel', function() { describe('x_cache_channel', function() {
assert.contains = function(ary, elem) { assert.contains = function(ary, elem) {
assert.ok(_.contains(ary,elem), 'missing "' + elem +'" from x-cache-channel: '+ ary); assert.ok(_.contains(ary,elem), 'missing "' + elem +'" from x-cache-channel: '+ ary);
}; };
test('supports joins', function(done) { it('supports joins', function(done) {
var query = querystring.stringify({ var query = querystring.stringify({
q: "SELECT a.name as an, b.name as bn FROM untitle_table_4 a left join private_table b ON (a.cartodb_id = b.cartodb_id)", q: "SELECT a.name as an, b.name as bn FROM untitle_table_4 a " +
"left join private_table b ON (a.cartodb_id = b.cartodb_id)",
api_key: 1234 api_key: 1234
}); });
assert.response(app, { assert.response(app, {
@ -38,7 +37,7 @@ test('supports joins', function(done) {
}); });
}); });
test('supports multistatements', function(done) { it('supports multistatements', function(done) {
var query = querystring.stringify({ var query = querystring.stringify({
q: "SELECT * FROM untitle_table_4; SELECT * FROM private_table", q: "SELECT * FROM untitle_table_4; SELECT * FROM private_table",
api_key: 1234 api_key: 1234
@ -60,7 +59,7 @@ test('supports multistatements', function(done) {
}); });
}); });
test('supports explicit transactions', function(done) { it('supports explicit transactions', function(done) {
var query = querystring.stringify({ var query = querystring.stringify({
q: "BEGIN; SELECT * FROM untitle_table_4; COMMIT; BEGIN; SELECT * FROM private_table; COMMIT;", q: "BEGIN; SELECT * FROM untitle_table_4; COMMIT; BEGIN; SELECT * FROM private_table; COMMIT;",
api_key: 1234 api_key: 1234
@ -82,7 +81,7 @@ test('supports explicit transactions', function(done) {
}); });
}); });
test('survives partial transactions', function(done) { it('survives partial transactions', function(done) {
var query = querystring.stringify({ var query = querystring.stringify({
q: "BEGIN; SELECT * FROM untitle_table_4", q: "BEGIN; SELECT * FROM untitle_table_4",
api_key: 1234 api_key: 1234