var assert = require('../support/assert'); var tests = module.exports = {}; var _ = require('underscore'); var redis = require('redis'); var querystring = require('querystring'); var semver = require('semver'); var mapnik = require('mapnik'); var Step = require('step'); var http = require('http'); var url = require('url'); require(__dirname + '/../support/test_helper'); var windshaft_fixtures = __dirname + '/../../node_modules/windshaft/test/fixtures'; var CartodbWindshaft = require(__dirname + '/../../lib/cartodb/cartodb_windshaft'); var serverOptions = require(__dirname + '/../../lib/cartodb/server_options'); var server = new CartodbWindshaft(serverOptions); server.setMaxListeners(0); suite('multilayer', function() { var redis_client = redis.createClient(global.environment.redis.port); var sqlapi_server; suiteSetup(function(done){ sqlapi_server = http.createServer(function(req,res) { var query = url.parse(req.url, true).query; if ( query.q.match('SQLAPIERROR') ) { res.statusCode = 400; res.write(JSON.stringify({'error':'Some error occurred'})); } else { res.write(JSON.stringify({rows: [ { 'cdb_querytables': '{' + JSON.stringify(query) + '}' } ]})); } res.end(); }); sqlapi_server.listen(global.environment.sqlapi.port, done); }); test("layergroup with 2 layers, each with its style", function(done) { var layergroup = { version: '1.0.0', layers: [ { options: { sql: 'select cartodb_id, ST_Translate(the_geom_webmercator, 5e6, 0) as the_geom_webmercator from test_table limit 2', cartocss: '#layer { marker-fill:red; marker-width:32; marker-allow-overlap:true; }', cartocss_version: '2.0.1' } }, { options: { sql: 'select cartodb_id, ST_Translate(the_geom_webmercator, -5e6, 0) as the_geom_webmercator from test_table limit 2 offset 2', cartocss: '#layer { marker-fill:blue; marker-allow-overlap:true; }', cartocss_version: '2.0.2' } } ] }; var expected_token = "d442ca6d3ece793b9c16c02a1d1ea5f2"; Step( function do_post() { var next = this; assert.response(server, { url: '/tiles/layergroup', method: 'POST', headers: {host: 'localhost', 'Content-Type': 'application/json' }, data: JSON.stringify(layergroup) }, {}, function(res) { assert.equal(res.statusCode, 200, res.body); var parsedBody = JSON.parse(res.body); var expectedBody = { layergroupid: expected_token }; // TODO: check last modified //expectedBody.layercount = 2; if ( expected_token ) assert.deepEqual(parsedBody, expectedBody); else expected_token = parsedBody.layergroupid; next(null, res); }); }, function do_get_tile(err) { if ( err ) throw err; var next = this; assert.response(server, { url: '/tiles/layergroup/' + expected_token + '/0/0/0.png', method: 'GET', headers: {host: 'localhost' }, encoding: 'binary' }, {}, function(res) { assert.equal(res.statusCode, 200, res.body); assert.equal(res.headers['content-type'], "image/png"); // Check X-Cache-Channel var cc = res.headers['x-cache-channel']; assert.ok(cc); var dbname = 'cartodb_test_user_1_db' assert.equal(cc.substring(0, dbname.length), dbname); var jsonquery = cc.substring(dbname.length+1); var sentquery = JSON.parse(jsonquery); assert.equal(sentquery.q, 'SELECT CDB_QueryTables($windshaft$' + layergroup.layers[0].options.sql + ';' + layergroup.layers[1].options.sql + '$windshaft$)'); assert.imageEqualsFile(res.body, 'test/fixtures/test_table_0_0_0_multilayer1.png', 2, function(err, similarity) { next(err); }); }); }, function do_get_grid_layer0(err) { if ( err ) throw err; var next = this; assert.response(server, { url: '/tiles/layergroup/' + expected_token + '/layer0/0/0/0.grid.json?interactivity=cartodb_id', headers: {host: 'localhost' }, method: 'GET' }, {}, function(res) { assert.equal(res.statusCode, 200, res.body); assert.equal(res.headers['content-type'], "text/javascript; charset=utf-8; charset=utf-8"); assert.utfgridEqualsFile(res.body, 'test/fixtures/test_table_0_0_0_multilayer1.layer0.grid.json', 2, function(err, similarity) { next(err); }); }); }, function do_get_grid_layer1(err) { if ( err ) throw err; var next = this; assert.response(server, { url: '/tiles/layergroup/' + expected_token + '/layer1/0/0/0.grid.json?interactivity=cartodb_id', headers: {host: 'localhost' }, method: 'GET' }, {}, function(res) { assert.equal(res.statusCode, 200, res.body); assert.equal(res.headers['content-type'], "text/javascript; charset=utf-8; charset=utf-8"); assert.utfgridEqualsFile(res.body, 'test/fixtures/test_table_0_0_0_multilayer1.layer1.grid.json', 2, function(err, similarity) { next(err); }); }); }, function finish(err) { var errors = []; if ( err ) { errors.push(err.message); console.log("Error: " + err); } redis_client.keys("map_style|cartodb_test_user_1_db|~" + expected_token, function(err, matches) { if ( err ) errors.push(err.message); assert.equal(matches.length, 1, "Missing expected token " + expected_token + " from redis: " + matches); redis_client.del(matches, function(err) { if ( err ) errors.push(err.message); if ( errors.length ) done(new Error(errors)); else done(null); }); }); } ); }); suiteTeardown(function(done) { // This test will add map_style records, like // 'map_style|null|publicuser|my_table', redis_client.keys("map_style|*", function(err, matches) { _.each(matches, function(k) { redis_client.del(k); }); sqlapi_server.close(done); }); }); });