var assert = require('../../support/assert'); var step = require('step'); var LayergroupToken = require('../../support/layergroup-token'); var testHelper = require('../../support/test_helper'); var CartodbWindshaft = require('../../../lib/cartodb/server'); var serverOptions = require('../../../lib/cartodb/server_options'); var server = new CartodbWindshaft(serverOptions); var mapnik = require('windshaft').mapnik; var IMAGE_TOLERANCE_PER_MIL = 10; describe('turbo-carto for named maps', function() { var keysToDelete; beforeEach(function() { keysToDelete = {}; }); afterEach(function(done) { testHelper.deleteRedisKeys(keysToDelete, done); }); var templateId = 'turbo-carto-template-1'; function template(table) { return { version: '0.0.1', name: templateId, auth: { method: 'open' }, placeholders: { color: { type: "css_color", default: "Reds" } }, layergroup: { version: '1.0.0', layers: [ { options: { sql: [ 'SELECT ' + table + '.*, _prices.price FROM ' + table + ' JOIN (' + ' SELECT 1 AS cartodb_id, 10.00 AS price', ' UNION', ' SELECT 2, 10.50', ' UNION', ' SELECT 3, 11.00', ' UNION', ' SELECT 4, 12.00', ' UNION', ' SELECT 5, 21.00', ') _prices ON _prices.cartodb_id = ' + table + '.cartodb_id' ].join('\n'), cartocss: [ '#layer {', ' marker-fill: ramp([price], colorbrewer(<%= color %>));', ' marker-allow-overlap:true;', '}' ].join('\n'), cartocss_version: '2.0.2' } } ] } }; } var templateParamsReds = { color: 'Reds' }; var templateParamsBlues = { color: 'Blues' }; var scenarios = [ { desc: 'with public tables', table: 'test_table' }, { desc: 'with private tables', table: 'test_table_private_1' } ]; scenarios.forEach(function(scenario) { it('should create a template with turbo-carto parsed properly: ' + scenario.desc, function (done) { step( function postTemplate() { var next = this; assert.response(server, { url: '/api/v1/map/named?api_key=1234', method: 'POST', headers: { host: 'localhost', 'Content-Type': 'application/json' }, data: JSON.stringify(template(scenario.table)) }, {}, function (res, err) { next(err, res); }); }, function checkTemplate(err, res) { assert.ifError(err); assert.equal(res.statusCode, 200); assert.deepEqual(JSON.parse(res.body), { template_id: templateId }); return null; }, function instantiateTemplateWithReds(err) { assert.ifError(err); var next = this; assert.response(server, { url: '/api/v1/map/named/' + templateId, method: 'POST', headers: { host: 'localhost', 'Content-Type': 'application/json' }, data: JSON.stringify(templateParamsReds) }, {}, function(res, err) { return next(err, res); }); }, function checkInstanciationWithReds(err, res) { assert.ifError(err); assert.equal(res.statusCode, 200); var parsedBody = JSON.parse(res.body); keysToDelete['map_cfg|' + LayergroupToken.parse(parsedBody.layergroupid).token] = 0; keysToDelete['user:localhost:mapviews:global'] = 5; assert.ok(parsedBody.layergroupid); assert.ok(parsedBody.last_updated); return parsedBody.layergroupid; }, function requestTileReds(err, layergroupId) { assert.ifError(err); var next = this; assert.response(server, { url: '/api/v1/map/' + layergroupId + '/0/0/0.png', method: 'GET', headers: { host: 'localhost' }, encoding: 'binary' }, {}, function(res, err) { next(err, res); }); }, function checkTileReds(err, res) { assert.ifError(err); var next = this; assert.equal(res.statusCode, 200); assert.equal(res.headers['content-type'], 'image/png'); var fixturePath = './test/fixtures/turbo-carto-named-maps-reds.png'; var image = mapnik.Image.fromBytes(new Buffer(res.body, 'binary')); assert.imageIsSimilarToFile(image, fixturePath, IMAGE_TOLERANCE_PER_MIL, next); }, function instantiateTemplateWithBlues(err) { assert.ifError(err); var next = this; assert.response(server, { url: '/api/v1/map/named/' + templateId, method: 'POST', headers: { host: 'localhost', 'Content-Type': 'application/json' }, data: JSON.stringify(templateParamsBlues) }, {}, function(res, err) { return next(err, res); }); }, function checkInstanciationWithBlues(err, res) { assert.ifError(err); assert.equal(res.statusCode, 200); var parsedBody = JSON.parse(res.body); keysToDelete['map_cfg|' + LayergroupToken.parse(parsedBody.layergroupid).token] = 0; keysToDelete['user:localhost:mapviews:global'] = 5; assert.ok(parsedBody.layergroupid); assert.ok(parsedBody.last_updated); return parsedBody.layergroupid; }, function requestTileBlues(err, layergroupId) { assert.ifError(err); var next = this; assert.response(server, { url: '/api/v1/map/' + layergroupId + '/0/0/0.png', method: 'GET', headers: { host: 'localhost' }, encoding: 'binary' }, {}, function(res, err) { next(err, res); }); }, function checkTileBlues(err, res) { assert.ifError(err); var next = this; assert.equal(res.statusCode, 200); assert.equal(res.headers['content-type'], 'image/png'); var fixturePath = './test/fixtures/turbo-carto-named-maps-blues.png'; var image = mapnik.Image.fromBytes(new Buffer(res.body, 'binary')); assert.imageIsSimilarToFile(image, fixturePath, IMAGE_TOLERANCE_PER_MIL, next); }, function deleteTemplate(err) { assert.ifError(err); var next = this; assert.response(server, { url: '/api/v1/map/named/' + templateId + '?api_key=1234', method: 'DELETE', headers: { host: 'localhost' } }, {}, function (res, err) { next(err, res); }); }, function checkDeleteTemplate(err, res) { assert.ifError(err); assert.equal(res.statusCode, 204); assert.ok(!res.body); return null; }, function finish(err) { done(err); } ); }); }); });