|
|
|
@ -13,27 +13,21 @@
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
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')()
|
|
|
|
|
, assert = require('assert')
|
|
|
|
|
, querystring = require('querystring')
|
|
|
|
|
, _ = require('underscore')
|
|
|
|
|
, zipfile = require('zipfile')
|
|
|
|
|
, fs = require('fs')
|
|
|
|
|
, libxmljs = require('libxmljs')
|
|
|
|
|
, Step = require('step')
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
suite('app.test', function() {
|
|
|
|
|
describe('app.test', function() {
|
|
|
|
|
|
|
|
|
|
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_cache_control_persist = 'public,max-age=31536000';
|
|
|
|
|
|
|
|
|
|
test('GET /api/v1/version', function(done){
|
|
|
|
|
it('GET /api/v1/version', function(done){
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: '/api/v1/version',
|
|
|
|
|
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, {
|
|
|
|
|
url: '/api/v1/sql',
|
|
|
|
|
method: 'GET'
|
|
|
|
@ -62,7 +56,7 @@ test('GET /api/v1/sql', function(done){
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Test base_url setting
|
|
|
|
|
test('GET /api/whatever/sql', function(done){
|
|
|
|
|
it('GET /api/whatever/sql', function(done){
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: '/api/whatever/sql?q=SELECT%201',
|
|
|
|
|
headers: {host: 'vizzuality.cartodb.com'},
|
|
|
|
@ -75,7 +69,7 @@ test('GET /api/whatever/sql', function(done){
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Test CORS headers with GET
|
|
|
|
|
test('GET /api/whatever/sql', function(done){
|
|
|
|
|
it('GET /api/whatever/sql', function(done){
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: '/api/whatever/sql?q=SELECT%201',
|
|
|
|
|
headers: {host: 'vizzuality.cartodb.com'},
|
|
|
|
@ -83,14 +77,16 @@ test('GET /api/whatever/sql', function(done){
|
|
|
|
|
},{
|
|
|
|
|
}, function(res) {
|
|
|
|
|
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'], '*');
|
|
|
|
|
done();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Test that OPTIONS does not run queries
|
|
|
|
|
test('OPTIONS /api/x/sql', function(done){
|
|
|
|
|
it('OPTIONS /api/x/sql', function(done){
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: '/api/x/sql?q=syntax%20error',
|
|
|
|
|
headers: {host: 'vizzuality.cartodb.com'},
|
|
|
|
@ -98,7 +94,9 @@ test('OPTIONS /api/x/sql', function(done){
|
|
|
|
|
},{}, function(res) {
|
|
|
|
|
assert.equal(res.statusCode, 200, 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'], '*');
|
|
|
|
|
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, {
|
|
|
|
|
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db',
|
|
|
|
|
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, {
|
|
|
|
|
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'},
|
|
|
|
@ -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, {
|
|
|
|
|
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4',
|
|
|
|
|
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, {
|
|
|
|
|
url: '/user/vizzuality/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4',
|
|
|
|
|
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
|
|
|
|
|
test('SELECT from user-specific database', function(done){
|
|
|
|
|
it('SELECT from user-specific database', function(done){
|
|
|
|
|
var backupDBHost = global.settings.db_host;
|
|
|
|
|
global.settings.db_host = '6.6.6.6';
|
|
|
|
|
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
|
|
|
|
|
test('SELECT with user-specific password', function(done){
|
|
|
|
|
it('SELECT with user-specific password', function(done){
|
|
|
|
|
var backupDBUserPass = global.settings.db_user_pass;
|
|
|
|
|
global.settings.db_user_pass = '<%= user_password %>';
|
|
|
|
|
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){
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
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("paging doesn't break x-cache-channel",
|
|
|
|
|
it("paging doesn't break x-cache-channel",
|
|
|
|
|
function(done){
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: '/api/v1/sql?' + querystring.stringify({
|
|
|
|
@ -242,13 +240,14 @@ function(done){
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 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 pr = [ [2,3], [0,4] ]; // page and rows
|
|
|
|
|
var methods = [ 'GET', 'POST' ];
|
|
|
|
|
var authorized = 0;
|
|
|
|
|
var testing = 0;
|
|
|
|
|
var method = 0;
|
|
|
|
|
// jshint maxcomplexity:7
|
|
|
|
|
var testNext = function() {
|
|
|
|
|
if ( testing >= pr.length ) {
|
|
|
|
|
if ( method+1 >= methods.length ) {
|
|
|
|
@ -266,9 +265,8 @@ test("paging", function(done){
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var prcur = pr[testing++];
|
|
|
|
|
console.log("Test " + testing + "/" + pr.length
|
|
|
|
|
+ " method " + methods[method] + " "
|
|
|
|
|
+ ( authorized ? "authenticated" : "" ) );
|
|
|
|
|
console.log("Test " + testing + "/" + pr.length + " method " + methods[method] + " " +
|
|
|
|
|
( authorized ? "authenticated" : "" ) );
|
|
|
|
|
var page = prcur[0];
|
|
|
|
|
var nrows = prcur[1];
|
|
|
|
|
var data_obj = {
|
|
|
|
@ -276,13 +274,15 @@ test("paging", function(done){
|
|
|
|
|
rows_per_page: nrows,
|
|
|
|
|
page: page
|
|
|
|
|
};
|
|
|
|
|
if ( authorized ) data_obj['api_key'] = '1234';
|
|
|
|
|
if ( authorized ) {
|
|
|
|
|
data_obj.api_key = '1234';
|
|
|
|
|
}
|
|
|
|
|
var data = querystring.stringify(data_obj);
|
|
|
|
|
var req = {
|
|
|
|
|
url: '/api/v1/sql',
|
|
|
|
|
headers: {host: 'vizzuality.cartodb.com'}
|
|
|
|
|
};
|
|
|
|
|
if ( methods[method] == 'GET' ) {
|
|
|
|
|
if ( methods[method] === 'GET' ) {
|
|
|
|
|
req.method = 'GET';
|
|
|
|
|
req.url += '?' + data;
|
|
|
|
|
} else {
|
|
|
|
@ -306,7 +306,7 @@ test("paging", function(done){
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 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" +
|
|
|
|
|
"SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(v)";
|
|
|
|
|
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, {
|
|
|
|
|
url: '/api/v1/sql',
|
|
|
|
|
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, {
|
|
|
|
|
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'},
|
|
|
|
|
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, {
|
|
|
|
|
url: "/api/v1/sql?q=DROP%20TABLE%20untitle_table_4&database=cartodb_test_user_1_db",
|
|
|
|
|
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, {
|
|
|
|
|
url: "/api/v1/sql?q=INSERT%20INTO%20untitle_table_4%20(id)%20VALUES%20(1)",
|
|
|
|
|
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
|
|
|
|
|
//
|
|
|
|
|
// 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, {
|
|
|
|
|
// view prepare_db.sh to see where to set api_key
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&"
|
|
|
|
|
+ querystring.stringify({q:
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
|
|
|
|
|
"INSERT INTO private_table(name) VALUES('noret1') UNION VALUES('noret2')"
|
|
|
|
|
}),
|
|
|
|
|
headers: {host: 'vizzuality.localhost.lan:8080' },
|
|
|
|
@ -417,11 +417,10 @@ test('INSERT returns affected rows', function(done){
|
|
|
|
|
// Check results from UPDATE
|
|
|
|
|
//
|
|
|
|
|
// 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, {
|
|
|
|
|
// view prepare_db.sh to see where to set api_key
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&"
|
|
|
|
|
+ querystring.stringify({q:
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
|
|
|
|
|
"UPDATE private_table SET name = upper(name) WHERE name in ('noret1', 'noret2')"
|
|
|
|
|
}),
|
|
|
|
|
headers: {host: 'vizzuality.localhost.lan:8080' },
|
|
|
|
@ -443,11 +442,10 @@ test('UPDATE returns affected rows', function(done){
|
|
|
|
|
// Check results from DELETE
|
|
|
|
|
//
|
|
|
|
|
// 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, {
|
|
|
|
|
// view prepare_db.sh to see where to set api_key
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&"
|
|
|
|
|
+ querystring.stringify({q:
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
|
|
|
|
|
"DELETE FROM private_table WHERE name in ('NORET1', 'NORET2')"
|
|
|
|
|
}),
|
|
|
|
|
headers: {host: 'vizzuality.localhost.lan:8080' },
|
|
|
|
@ -469,11 +467,10 @@ test('DELETE returns affected rows', function(done){
|
|
|
|
|
// Check results from INSERT .. RETURNING
|
|
|
|
|
//
|
|
|
|
|
// 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, {
|
|
|
|
|
// view prepare_db.sh to see where to set api_key
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&"
|
|
|
|
|
+ querystring.stringify({q:
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
|
|
|
|
|
"INSERT INTO private_table(name) VALUES('test') RETURNING upper(name), reverse(name)"
|
|
|
|
|
}),
|
|
|
|
|
headers: {host: 'vizzuality.localhost.lan:8080' },
|
|
|
|
@ -494,11 +491,10 @@ test('INSERT with RETURNING returns all results', function(done){
|
|
|
|
|
// Check results from UPDATE .. RETURNING
|
|
|
|
|
//
|
|
|
|
|
// 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, {
|
|
|
|
|
// view prepare_db.sh to see where to set api_key
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&"
|
|
|
|
|
+ querystring.stringify({q:
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
|
|
|
|
|
"UPDATE private_table SET name = 'tost' WHERE name = 'test' RETURNING upper(name), reverse(name)"
|
|
|
|
|
}),
|
|
|
|
|
headers: {host: 'vizzuality.localhost.lan:8080' },
|
|
|
|
@ -519,11 +515,10 @@ test('UPDATE with RETURNING returns all results', function(done){
|
|
|
|
|
// Check results from DELETE .. RETURNING
|
|
|
|
|
//
|
|
|
|
|
// 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, {
|
|
|
|
|
// view prepare_db.sh to see where to set api_key
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&"
|
|
|
|
|
+ querystring.stringify({q:
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
|
|
|
|
|
"DELETE FROM private_table WHERE name = 'tost' RETURNING name"
|
|
|
|
|
}),
|
|
|
|
|
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, {
|
|
|
|
|
url: "/api/v1/sql?q=DROP%20TABLE%20untitle_table_4",
|
|
|
|
|
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
|
|
|
|
|
//
|
|
|
|
|
// 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, {
|
|
|
|
|
// view prepare_db.sh to see where to set api_key
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&"
|
|
|
|
|
+ querystring.stringify({q:
|
|
|
|
|
url: "/api/v1/sql?api_key=1234&" + querystring.stringify({q:
|
|
|
|
|
"SELECT min(updated_at) FROM private_table"
|
|
|
|
|
}),
|
|
|
|
|
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, {
|
|
|
|
|
url: "/api/v1/sql?" + querystring.stringify({
|
|
|
|
|
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
|
|
|
|
|
test('SELECT INTO with paging ', function(done){
|
|
|
|
|
it('SELECT INTO with paging ', function(done){
|
|
|
|
|
var esc_tabname = 'test ""select into""'; // escaped ident
|
|
|
|
|
Step(
|
|
|
|
|
step(
|
|
|
|
|
function select_into() {
|
|
|
|
|
var next = this;
|
|
|
|
|
assert.response(app, {
|
|
|
|
@ -610,7 +604,7 @@ test('SELECT INTO with paging ', function(done){
|
|
|
|
|
},{}, function(res) { next(null, 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);
|
|
|
|
|
var next = this;
|
|
|
|
|
assert.response(app, {
|
|
|
|
@ -624,7 +618,7 @@ test('SELECT INTO with paging ', function(done){
|
|
|
|
|
},{}, function(res) { next(null, res); });
|
|
|
|
|
},
|
|
|
|
|
function check_res_drop_table(err, res) {
|
|
|
|
|
if ( err ) throw err;
|
|
|
|
|
assert.ifError(err);
|
|
|
|
|
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
|
|
|
|
|
var out = JSON.parse(res.body);
|
|
|
|
|
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 check_drop(err, res) {
|
|
|
|
|
if ( err ) throw err;
|
|
|
|
|
assert.ifError(err);
|
|
|
|
|
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
|
|
|
|
|
return null;
|
|
|
|
|
},
|
|
|
|
|
function finish(err) {
|
|
|
|
|
done(err)
|
|
|
|
|
done(err);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Test effects of COPY
|
|
|
|
|
// 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, {
|
|
|
|
|
url: "/api/v1/sql?" + querystring.stringify({
|
|
|
|
|
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, {
|
|
|
|
|
url: "/api/v1/sql?" + querystring.stringify({
|
|
|
|
|
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, {
|
|
|
|
|
url: "/api/v1/sql?" + querystring.stringify({
|
|
|
|
|
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, {
|
|
|
|
|
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
|
|
|
|
|
}),
|
|
|
|
|
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, {
|
|
|
|
|
url: "/api/v1/sql?" + querystring.stringify({
|
|
|
|
|
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);
|
|
|
|
|
var pbody = JSON.parse(res.body);
|
|
|
|
|
assert.equal(pbody.total_rows, 1);
|
|
|
|
|
assert.equal(pbody.rows[0]['count'], 0);
|
|
|
|
|
assert.equal(pbody.rows[0].count, 0);
|
|
|
|
|
done();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('REINDEX TABLE with GET and auth', function(done){
|
|
|
|
|
it('REINDEX TABLE with GET and auth', function(done){
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: "/api/v1/sql?" + querystring.stringify({
|
|
|
|
|
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, {
|
|
|
|
|
url: "/api/v1/sql?" + querystring.stringify({
|
|
|
|
|
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, {
|
|
|
|
|
url: "/api/v1/sql?" + querystring.stringify({
|
|
|
|
|
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, {
|
|
|
|
|
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&format=unknown',
|
|
|
|
|
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, {
|
|
|
|
|
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4',
|
|
|
|
|
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, {
|
|
|
|
|
url: '/api/v1/sql',
|
|
|
|
|
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, {
|
|
|
|
|
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&filename=x',
|
|
|
|
|
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, {
|
|
|
|
|
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4',
|
|
|
|
|
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, {
|
|
|
|
|
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&skipfields=the_geom_webmercator,cartodb_id,unexistant',
|
|
|
|
|
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, {
|
|
|
|
|
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'},
|
|
|
|
|
method: 'GET'
|
|
|
|
|
},{ }, 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, {
|
|
|
|
|
url: '/api/v1/sql?q=SELECT%20*gadfgadfg%20FROM%20untitle_table_4',
|
|
|
|
|
headers: {host: 'vizzuality.cartodb.com'},
|
|
|
|
@ -1013,7 +1009,7 @@ var systemQueriesSuitesToTest = [
|
|
|
|
|
|
|
|
|
|
function testSystemQueries(description, queries, statusErrorCode, apiKey) {
|
|
|
|
|
queries.forEach(function(query) {
|
|
|
|
|
test('[' + description + '] query: ' + query, function(done) {
|
|
|
|
|
it('[' + description + '] query: ' + query, function(done) {
|
|
|
|
|
var queryStringParams = {q: query};
|
|
|
|
|
if (!!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, {
|
|
|
|
|
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&format=geojson',
|
|
|
|
|
headers: {host: 'vizzualinot.cartodb.com'},
|
|
|
|
|
method: 'GET'
|
|
|
|
|
}, {}, 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-disposition'], 'inline');
|
|
|
|
|
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();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 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, {
|
|
|
|
|
url: '/api/v1/sql?' + querystring.stringify({q:
|
|
|
|
|
'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
|
|
|
|
|
test('numeric arrays are rendered as such', function(done){
|
|
|
|
|
it('numeric arrays are rendered as such', function(done){
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: "/api/v1/sql?"
|
|
|
|
|
+ querystring.stringify({q:
|
|
|
|
|
url: "/api/v1/sql?" + querystring.stringify({q:
|
|
|
|
|
"SELECT ARRAY[8.7,4.3]::numeric[] as x"
|
|
|
|
|
}),
|
|
|
|
|
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
|
|
|
|
|
test('field names and types are exposed', function(done){
|
|
|
|
|
it('field names and types are exposed', function(done){
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: '/api/v1/sql?' + querystring.stringify({
|
|
|
|
|
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
|
|
|
|
|
test('schema response takes skipfields into account', function(done){
|
|
|
|
|
it('schema response takes skipfields into account', function(done){
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: '/api/v1/sql?' + querystring.stringify({
|
|
|
|
|
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
|
|
|
|
|
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, {
|
|
|
|
|
url: '/api/v1/sql?' + querystring.stringify({
|
|
|
|
|
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
|
|
|
|
|
// test again (new mocha run) with a different TZ
|
|
|
|
|
//
|
|
|
|
|
test('timezone info in JSON output', function(done){
|
|
|
|
|
Step(
|
|
|
|
|
it('timezone info in JSON output', function(done){
|
|
|
|
|
step(
|
|
|
|
|
function testEuropeRomeExplicit() {
|
|
|
|
|
var next = this;
|
|
|
|
|
assert.response(app, {
|
|
|
|
@ -1213,7 +1211,7 @@ test('timezone info in JSON output', function(done){
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
function testEuropeRomeImplicit(err) {
|
|
|
|
|
if ( err ) throw err;
|
|
|
|
|
assert.ifError(err);
|
|
|
|
|
var next = this;
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: '/api/v1/sql?' + querystring.stringify({
|
|
|
|
@ -1233,7 +1231,7 @@ test('timezone info in JSON output', function(done){
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
function testUTCExplicit(err) {
|
|
|
|
|
if ( err ) throw err;
|
|
|
|
|
assert.ifError(err);
|
|
|
|
|
var next = this;
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: '/api/v1/sql?' + querystring.stringify({
|
|
|
|
@ -1253,7 +1251,7 @@ test('timezone info in JSON output', function(done){
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
function testUTCImplicit(err) {
|
|
|
|
|
if ( err ) throw err;
|
|
|
|
|
assert.ifError(err);
|
|
|
|
|
var next = this;
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: '/api/v1/sql?' + querystring.stringify({
|
|
|
|
@ -1280,13 +1278,15 @@ test('timezone info in JSON output', function(done){
|
|
|
|
|
|
|
|
|
|
// WARNING and NOTICE in JSON output
|
|
|
|
|
// See https://github.com/CartoDB/CartoDB-SQL-API/issues/104
|
|
|
|
|
test('notice and warning info in JSON output', function(done){
|
|
|
|
|
Step(
|
|
|
|
|
it('notice and warning info in JSON output', function(done){
|
|
|
|
|
step(
|
|
|
|
|
function addRaiseFunction() {
|
|
|
|
|
var next = this;
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
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'
|
|
|
|
|
}),
|
|
|
|
|
headers: {host: 'vizzuality.cartodb.com'},
|
|
|
|
@ -1300,7 +1300,7 @@ test('notice and warning info in JSON output', function(done){
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
function raiseNotice(err) {
|
|
|
|
|
if ( err ) throw err;
|
|
|
|
|
assert.ifError(err);
|
|
|
|
|
var next = this;
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: '/api/v1/sql?' + querystring.stringify({
|
|
|
|
@ -1321,7 +1321,7 @@ test('notice and warning info in JSON output', function(done){
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
function raiseWarning(err) {
|
|
|
|
|
if ( err ) throw err;
|
|
|
|
|
assert.ifError(err);
|
|
|
|
|
var next = this;
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
url: '/api/v1/sql?' + querystring.stringify({
|
|
|
|
@ -1342,11 +1342,12 @@ test('notice and warning info in JSON output', function(done){
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
function raiseBothWarningAndNotice(err) {
|
|
|
|
|
if ( err ) throw err;
|
|
|
|
|
assert.ifError(err);
|
|
|
|
|
var next = this;
|
|
|
|
|
assert.response(app, {
|
|
|
|
|
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'},
|
|
|
|
|
method: 'GET'
|
|
|
|
@ -1377,7 +1378,7 @@ test('notice and warning info in JSON output', function(done){
|
|
|
|
|
},{ }, function(res) {
|
|
|
|
|
try {
|
|
|
|
|
assert.equal(res.statusCode, 200, res.body);
|
|
|
|
|
var parsedBody = JSON.parse(res.body);
|
|
|
|
|
JSON.parse(res.body);
|
|
|
|
|
} catch (e) { err = new Error(err + ',' + e); }
|
|
|
|
|
next(err);
|
|
|
|
|
});
|
|
|
|
@ -1391,7 +1392,7 @@ test('notice and warning info in JSON output', function(done){
|
|
|
|
|
/**
|
|
|
|
|
* 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, {
|
|
|
|
|
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db',
|
|
|
|
|
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['cache-control'], expected_cache_control);
|
|
|
|
|
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();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
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, {
|
|
|
|
|
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&callback=foo_jsonp',
|
|
|
|
|
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, {
|
|
|
|
|
url: "/api/v1/sql?q=DROP%20TABLE%20untitle_table_4&callback=foo_jsonp",
|
|
|
|
|
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) {
|
|
|
|
|
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
|
|
|
|
|
var didRunJsonCallback = false;
|
|
|
|
|
// jshint ignore:start
|
|
|
|
|
function foo_jsonp(body) {
|
|
|
|
|
assert.deepEqual(body, {"error":["must be owner of relation untitle_table_4"]});
|
|
|
|
|
didRunJsonCallback = true;
|
|
|
|
|
}
|
|
|
|
|
eval(res.body);
|
|
|
|
|
// jshint ignore:end
|
|
|
|
|
assert.ok(didRunJsonCallback);
|
|
|
|
|
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, {
|
|
|
|
|
url: "/api/v1/sql?q=select%20pg_sleep(2.1)%20as%20sleep",
|
|
|
|
|
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(
|
|
|
|
|
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;
|
|
|
|
|
global.settings.db_max_row_size = 4;
|
|
|
|
|