From 87eaeb0074af13c07479d9fd7e71cf2adce45d30 Mon Sep 17 00:00:00 2001 From: Raul Ochoa Date: Fri, 30 Jan 2015 18:57:01 +0100 Subject: [PATCH] Some integration tests for different cases in named layers type --- Makefile | 1 + .../models/mapconfig_named_layers_adapter.js | 8 +- .../mapconfig_named_layers_adapter.js | 318 ++++++++++++++++++ 3 files changed, 323 insertions(+), 4 deletions(-) create mode 100644 test/integration/mapconfig_named_layers_adapter.js diff --git a/Makefile b/Makefile index c033aab0..32a48859 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,7 @@ check-local: config/environments/test.js ./run_tests.sh ${RUNTESTFLAGS} \ test/unit/cartodb/*.js \ test/unit/cartodb/cache/model/*.js \ + test/integration/*.js \ test/acceptance/*.js \ test/acceptance/cache/*.js diff --git a/lib/cartodb/models/mapconfig_named_layers_adapter.js b/lib/cartodb/models/mapconfig_named_layers_adapter.js index e75b771b..df5b843b 100644 --- a/lib/cartodb/models/mapconfig_named_layers_adapter.js +++ b/lib/cartodb/models/mapconfig_named_layers_adapter.js @@ -16,7 +16,7 @@ MapConfigNamedLayersAdapter.prototype.getLayers = function(username, layers, cal if (layer.type === 'named') { if (!layer.options.name) { - return callback(new Error('Missing Named Map name in layer options')); + return callback(new Error('Missing Named Map `name` in layer options')); } var templateName = layer.options.name; @@ -24,8 +24,8 @@ MapConfigNamedLayersAdapter.prototype.getLayers = function(username, layers, cal var templateAuthTokens = layer.options.auth_tokens; self.templateMaps.getTemplate(username, templateName, function(err, template) { - if (err) { - return callback(err); + if (err || !template) { + return callback(new Error("Template '" + templateName + "' of user '" + username + "' not found")); } if (self.templateMaps.isAuthorized(template, templateAuthTokens)) { @@ -46,7 +46,7 @@ MapConfigNamedLayersAdapter.prototype.getLayers = function(username, layers, cal return callback(err); } } else { - var unauthorizedError = new Error('Unauthorized template instantiation'); + var unauthorizedError = new Error("Unauthorized '" + templateName + "' template instantiation"); // unauthorizedError.http_status = 403; return callback(unauthorizedError); } diff --git a/test/integration/mapconfig_named_layers_adapter.js b/test/integration/mapconfig_named_layers_adapter.js new file mode 100644 index 00000000..9fd84781 --- /dev/null +++ b/test/integration/mapconfig_named_layers_adapter.js @@ -0,0 +1,318 @@ +var assert = require('assert'); +var RedisPool = require('redis-mpool'); +var TemplateMaps = require('../../lib/cartodb/template_maps.js'); +var MapConfigNamedLayersAdapter = require('../../lib/cartodb/models/mapconfig_named_layers_adapter'); + +var test_helper = require('../support/test_helper'); +var Step = require('step'); +var _ = require('underscore'); + +suite('mapconfig_named_layers_adapter', function() { + + // configure redis pool instance to use in tests + var redisPool = RedisPool(global.environment.redis); + + var templateMaps = new TemplateMaps(redisPool, { + max_user_templates: global.environment.maxUserTemplates + }); + + var mapConfigNamedLayersAdapter = new MapConfigNamedLayersAdapter(templateMaps); + + var wadusLayer = { + type: 'cartodb', + options: { + sql: 'select 1 cartodb_id, null::geometry the_geom_webmercator', + cartocss: '#layer { marker-fill: <%= color %>; }', + cartocss_version: '2.3.0' + } + }; + + var wadusMapnikLayer = { + type: 'mapnik', + options: { + sql: 'select 1 cartodb_id, null::geometry the_geom_webmercator', + cartocss: '#layer { polygon-fill: <%= polygon_color %>; }', + cartocss_version: '2.3.0' + } + }; + + var username = 'me'; + + var templateName = 'valid_template'; + var template = { + version: '0.0.1', + name: templateName, + auth: { + method: 'open' + }, + "placeholders": { + "color": { + "type": "css_color", + "default": "#cc3300" + } + }, + layergroup: { + layers: [ + wadusLayer + ] + } + }; + + var tokenAuthTemplateName = 'auth_valid_template'; + var tokenAuthTemplate = { + version: '0.0.1', + name: tokenAuthTemplateName, + auth: { + method: 'token', + valid_tokens: ['valid1', 'valid2'] + }, + layergroup: { + layers: [ + wadusLayer + ] + } + }; + + var multipleLayersTemplateName = 'multiple_valid_template'; + var multipleLayersTemplate = { + version: '0.0.1', + name: multipleLayersTemplateName, + auth: { + method: 'token', + valid_tokens: ['valid1', 'valid2'] + }, + "placeholders": { + "polygon_color": { + "type": "css_color", + "default": "green" + }, + "color": { + "type": "css_color", + "default": "red" + } + }, + layergroup: { + layers: [ + wadusMapnikLayer, + wadusLayer + ] + } + }; + + var namedMapLayer = { + type: 'named', + options: { + name: templateName, + config: {}, + auth_tokens: [] + } + }; + + var nestedNamedMapTemplateName = 'auth_valid_template'; + var nestedNamedMapTemplate = { + version: '0.0.1', + name: nestedNamedMapTemplateName, + auth: { + method: 'open' + }, + layergroup: { + layers: [ + namedMapLayer + ] + } + }; + + function makeNamedMapLayerConfig(options) { + return { + version: '1.3.0', + layers: [ + { + type: 'named', + options: options + } + ] + }; + } + + + suiteSetup(function(done) { + templateMaps.addTemplate(username, template, done); + }); + + test('should fail for named map layer with missing name', function(done) { + + + assert.response(server, + healthCheckRequest, + { + status: 200 + }, + function (res, err) { + assert.ok(!err); + + var parsed = JSON.parse(res.body); + + assert.ok(parsed.enabled); + assert.ok(parsed.ok); + + done(); + } + ); + + + + + var missingNamedMapLayerConfig = makeNamedMapLayerConfig({ + config: {} + }); + mapConfigNamedLayersAdapter.getLayers(username, missingNamedMapLayerConfig.layers, function(err, layers) { + assert.ok(err); + assert.ok(!layers); + assert.equal(err.message, 'Missing Named Map `name` in layer options'); + done(); + }); + }); + + test('should fail for non-existing template name', function(done) { + var missingTemplateName = 'wadus'; + var nonExistentNamedMapLayerConfig = makeNamedMapLayerConfig({ + name: missingTemplateName + }); + mapConfigNamedLayersAdapter.getLayers(username, nonExistentNamedMapLayerConfig.layers, function(err, layers) { + assert.ok(err); + assert.ok(!layers); + assert.equal(err.message, "Template '" + missingTemplateName + "' of user '" + username + "' not found"); + done(); + }); + }); + + test('should fail if not properly authorized', function(done) { + templateMaps.addTemplate(username, tokenAuthTemplate, function(err) { + if (err) { + return done(err); + } + + var nonAuthTokensNamedMapLayerConfig = makeNamedMapLayerConfig({ + name: tokenAuthTemplateName + }); + mapConfigNamedLayersAdapter.getLayers(username, nonAuthTokensNamedMapLayerConfig.layers, function(err, layers) { + assert.ok(err); + assert.ok(!layers); + assert.equal(err.message, "Unauthorized '" + tokenAuthTemplateName + "' template instantiation"); + + templateMaps.delTemplate(username, tokenAuthTemplateName, done); + }); + }); + }); + + test('should fail for nested named map layers', function(done) { + templateMaps.addTemplate(username, nestedNamedMapTemplate, function(err) { + if (err) { + return done(err); + } + + var nestedNamedMapLayerConfig = makeNamedMapLayerConfig({ + name: nestedNamedMapTemplateName + }); + mapConfigNamedLayersAdapter.getLayers(username, nestedNamedMapLayerConfig.layers, function(err, layers) { + assert.ok(err); + assert.ok(!layers); + assert.equal(err.message, 'Nested named layers are not allowed'); + + templateMaps.delTemplate(username, nestedNamedMapTemplateName, done); + }); + }); + }); + + test('should return an expanded list of layers for a named map layer', function(done) { + var validNamedMapMapLayerConfig = makeNamedMapLayerConfig({ + name: templateName + }); + mapConfigNamedLayersAdapter.getLayers(username, validNamedMapMapLayerConfig.layers, function(err, layers) { + assert.ok(!err); + assert.ok(layers.length, 1); + assert.ok(layers[0].type, 'cartodb'); + done(); + }); + }); + + test('should return on auth=token with valid tokens provided', function(done) { + templateMaps.addTemplate(username, tokenAuthTemplate, function(err) { + if (err) { + return done(err); + } + + var validAuthTokensNamedMapLayerConfig = makeNamedMapLayerConfig({ + name: tokenAuthTemplateName, + auth_tokens: ['valid1'] + }); + mapConfigNamedLayersAdapter.getLayers(username, validAuthTokensNamedMapLayerConfig.layers, function(err, layers) { + assert.ok(!err); + assert.equal(layers.length, 1); + + templateMaps.delTemplate(username, tokenAuthTemplateName, done); + }); + }); + }); + + test('should return an expanded list of layers for a named map layer, multiple layers version', function(done) { + templateMaps.addTemplate(username, multipleLayersTemplate, function(err) { + if (err) { + return done(err); + } + + var multipleLayersNamedMapLayerConfig = makeNamedMapLayerConfig({ + name: multipleLayersTemplateName, + auth_tokens: ['valid2'] + }); + mapConfigNamedLayersAdapter.getLayers(username, multipleLayersNamedMapLayerConfig.layers, function(err, layers) { + assert.ok(!err); + assert.equal(layers.length, 2); + + assert.equal(layers[0].type, 'mapnik'); + assert.equal(layers[0].options.cartocss, '#layer { polygon-fill: green; }'); + + assert.equal(layers[1].type, 'cartodb'); + assert.equal(layers[1].options.cartocss, '#layer { marker-fill: red; }'); + + templateMaps.delTemplate(username, multipleLayersTemplateName, done); + }); + }); + }); + + test('should replace template params with the given config', function(done) { + templateMaps.addTemplate(username, multipleLayersTemplate, function(err) { + if (err) { + return done(err); + } + + var color = '#cc3300', + polygonColor = '#ff9900'; + + var multipleLayersNamedMapLayerConfig = makeNamedMapLayerConfig({ + name: multipleLayersTemplateName, + config: { + polygon_color: polygonColor, + color: color + }, + auth_tokens: ['valid2'] + }); + mapConfigNamedLayersAdapter.getLayers(username, multipleLayersNamedMapLayerConfig.layers, function(err, layers) { + assert.ok(!err); + assert.equal(layers.length, 2); + + assert.equal(layers[0].type, 'mapnik'); + assert.equal(layers[0].options.cartocss, '#layer { polygon-fill: ' + polygonColor + '; }'); + + assert.equal(layers[1].type, 'cartodb'); + assert.equal(layers[1].options.cartocss, '#layer { marker-fill: ' + color + '; }'); + + templateMaps.delTemplate(username, multipleLayersTemplateName, done); + }); + }); + }); + + suiteTeardown(function(done) { + templateMaps.delTemplate(username, templateName, done); + }); +});