require('../helper'); var app = require(global.settings.app_root + '/app/app')(); var assert = require('../support/assert'); var querystring = require('querystring'); var _ = require('underscore'); // allow lots of emitters to be set to silence warning app.setMaxListeners(0); describe('X-Cache-Channel header', function() { function createGetRequest(sqlQuery) { var query = querystring.stringify({ q: sqlQuery, api_key: 1234 }); return { url: '/api/v1/sql?' + query, headers: { host: 'vizzuality.cartodb.com' }, method: 'GET' }; } var RESPONSE_OK = { statusCode: 200 }; function xCacheChannelHeaderHasTables(xCacheChannel, expectedTablesNames) { var databaseAndTables = xCacheChannel.split(':'); var databaseName = databaseAndTables[0]; assert.equal(databaseName, 'cartodb_test_user_1_db'); var headerTableNames = databaseAndTables[1].split(','); assert.equal(headerTableNames.length, expectedTablesNames.length); var tablesDiff = _.difference(expectedTablesNames, headerTableNames); assert.equal(tablesDiff.length, 0, 'X-Cache-Channel header missing tables: ' + tablesDiff.join(',')); } function tableNamesInCacheChannelHeader(expectedTableNames, done) { return function(res) { xCacheChannelHeaderHasTables(res.headers['x-cache-channel'], expectedTableNames); done(); }; } it('supports joins', function(done) { var sql = "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)"; assert.response(app, createGetRequest(sql), RESPONSE_OK, tableNamesInCacheChannelHeader([ 'public.private_table', 'public.untitle_table_4' ], done)); }); it('supports multistatements', function(done) { var sql = "SELECT * FROM untitle_table_4; SELECT * FROM private_table"; assert.response(app, createGetRequest(sql), RESPONSE_OK, tableNamesInCacheChannelHeader([ 'public.private_table', 'public.untitle_table_4' ], done)); }); it('supports explicit transactions', function(done) { var sql = "BEGIN; SELECT * FROM untitle_table_4; COMMIT; BEGIN; SELECT * FROM private_table; COMMIT;"; assert.response(app, createGetRequest(sql), RESPONSE_OK, tableNamesInCacheChannelHeader([ 'public.private_table', 'public.untitle_table_4' ], done)); }); it('survives partial transactions', function(done) { var sql = "BEGIN; SELECT * FROM untitle_table_4"; assert.response(app, createGetRequest(sql), RESPONSE_OK, tableNamesInCacheChannelHeader([ 'public.untitle_table_4' ], done)); }); it('should not add header for functions', function(done) { var sql = "SELECT format('%s', 'wadus')"; assert.response(app, createGetRequest(sql), RESPONSE_OK, function(res) { assert.ok(!res.headers.hasOwnProperty('x-cache-channel'), res.headers['x-cache-channel']); done(); }); }); it('should not add header for CDB_QueryTables', function(done) { var sql = "SELECT CDB_QueryTablesText('select * from untitle_table_4')"; assert.response(app, createGetRequest(sql), RESPONSE_OK, function(res) { assert.ok(!res.headers.hasOwnProperty('x-cache-channel'), res.headers['x-cache-channel']); done(); }); }); it('should not add header for non table results', function(done) { var sql = "SELECT 'wadus'::text"; assert.response(app, createGetRequest(sql), RESPONSE_OK, function(res) { assert.ok(!res.headers.hasOwnProperty('x-cache-channel'), res.headers['x-cache-channel']); done(); }); }); });