e690170689
- layers is an array and it's not empty - layers has at least options
526 lines
16 KiB
JavaScript
526 lines
16 KiB
JavaScript
var assert = require('assert')
|
|
//, _ = require('underscore')
|
|
, RedisPool = require('redis-mpool')
|
|
, TemplateMaps = require('../../../lib/cartodb/template_maps.js')
|
|
, test_helper = require('../../support/test_helper')
|
|
, Step = require('step')
|
|
, _ = require('underscore')
|
|
, tests = module.exports = {};
|
|
|
|
suite('template_maps', function() {
|
|
|
|
// configure redis pool instance to use in tests
|
|
var redis_pool = RedisPool(global.environment.redis);
|
|
|
|
var wadusLayer = {
|
|
options: {
|
|
sql: 'select 1 cartodb_id, null::geometry the_geom_webmercator',
|
|
cartocss: '#layer { marker-fill:blue; }',
|
|
cartocss_version: '2.3.0'
|
|
}
|
|
};
|
|
|
|
var validTemplate = {
|
|
version:'0.0.1',
|
|
name: 'first',
|
|
auth: {},
|
|
layergroup: {
|
|
layers: [
|
|
wadusLayer
|
|
]
|
|
}
|
|
};
|
|
var owner = 'me';
|
|
|
|
test('does not accept template with unsupported version', function(done) {
|
|
var tmap = new TemplateMaps(redis_pool);
|
|
assert.ok(tmap);
|
|
var tpl = { version:'6.6.6',
|
|
name:'k', auth: {}, layergroup: {layers:[wadusLayer]} };
|
|
Step(
|
|
function() {
|
|
tmap.addTemplate('me', tpl, this);
|
|
},
|
|
function checkFailed(err) {
|
|
assert.ok(err);
|
|
assert.ok(err.message.match(/unsupported.*version/i), err);
|
|
return null;
|
|
},
|
|
function finish(err) {
|
|
done(err);
|
|
}
|
|
);
|
|
});
|
|
|
|
test('does not accept template with missing name', function(done) {
|
|
var tmap = new TemplateMaps(redis_pool);
|
|
assert.ok(tmap);
|
|
var tpl = { version:'0.0.1',
|
|
auth: {}, layergroup: {layers:[wadusLayer]} };
|
|
Step(
|
|
function() {
|
|
tmap.addTemplate('me', tpl, this);
|
|
},
|
|
function checkFailed(err) {
|
|
assert.ok(err);
|
|
assert.ok(err.message.match(/missing.*name/i), err);
|
|
return null;
|
|
},
|
|
function finish(err) {
|
|
done(err);
|
|
}
|
|
);
|
|
});
|
|
|
|
test('does not accept template with invalid name', function(done) {
|
|
var tmap = new TemplateMaps(redis_pool);
|
|
assert.ok(tmap);
|
|
var tpl = { version:'0.0.1',
|
|
auth: {}, layergroup: {layers:[wadusLayer]} };
|
|
var invalidnames = [ "ab|", "a b", "a@b", "1ab", "_x", "", " x", "x " ];
|
|
var testNext = function() {
|
|
if ( ! invalidnames.length ) { done(); return; }
|
|
var n = invalidnames.pop();
|
|
tpl.name = n;
|
|
tmap.addTemplate('me', tpl, function(err) {
|
|
if ( ! err ) {
|
|
done(new Error("Unexpected success with invalid name '" + n + "'"));
|
|
}
|
|
else if ( ! err.message.match(/template.*name/i) ) {
|
|
done(new Error("Unexpected error message with invalid name '" + n
|
|
+ "': " + err));
|
|
}
|
|
else {
|
|
testNext();
|
|
}
|
|
});
|
|
};
|
|
testNext();
|
|
});
|
|
|
|
test('does not accept template with invalid placeholder name', function(done) {
|
|
var tmap = new TemplateMaps(redis_pool);
|
|
assert.ok(tmap);
|
|
var tpl = { version:'0.0.1',
|
|
name: "valid", placeholders: {},
|
|
auth: {}, layergroup: {layers:[wadusLayer]} };
|
|
var invalidnames = [ "ab|", "a b", "a@b", "1ab", "_x", "", " x", "x " ];
|
|
var testNext = function() {
|
|
if ( ! invalidnames.length ) { done(); return; }
|
|
var n = invalidnames.pop();
|
|
tpl.placeholders = {};
|
|
tpl.placeholders[n] = { type:'number', default:1 };
|
|
tmap.addTemplate('me', tpl, function(err) {
|
|
if ( ! err ) {
|
|
done(new Error("Unexpected success with invalid name '" + n + "'"));
|
|
}
|
|
else if ( ! err.message.match(/invalid.*name/i) ) {
|
|
done(new Error("Unexpected error message with invalid name '" + n
|
|
+ "': " + err));
|
|
}
|
|
else {
|
|
testNext();
|
|
}
|
|
});
|
|
};
|
|
testNext();
|
|
});
|
|
|
|
test('does not accept template with missing placeholder default', function(done) {
|
|
var tmap = new TemplateMaps(redis_pool);
|
|
assert.ok(tmap);
|
|
var tpl = { version:'0.0.1',
|
|
name: "valid", placeholders: { v: {} },
|
|
auth: {}, layergroup: {layers:[wadusLayer]} };
|
|
tmap.addTemplate('me', tpl, function(err) {
|
|
if ( ! err ) {
|
|
done(new Error("Unexpected success with missing placeholder default"));
|
|
}
|
|
else if ( ! err.message.match(/missing default/i) ) {
|
|
done(new Error("Unexpected error message with missing placeholder default: "
|
|
+ err));
|
|
}
|
|
else {
|
|
done();
|
|
}
|
|
});
|
|
});
|
|
|
|
test('does not accept template with missing placeholder type', function(done) {
|
|
var tmap = new TemplateMaps(redis_pool);
|
|
assert.ok(tmap);
|
|
var tpl = { version:'0.0.1',
|
|
name: "valid", placeholders: { v: { default:1 } },
|
|
auth: {}, layergroup: {layers:[wadusLayer]} };
|
|
tmap.addTemplate('me', tpl, function(err) {
|
|
if ( ! err ) {
|
|
done(new Error("Unexpected success with missing placeholder type"));
|
|
}
|
|
else if ( ! err.message.match(/missing type/i) ) {
|
|
done(new Error("Unexpected error message with missing placeholder default: "
|
|
+ err));
|
|
}
|
|
else {
|
|
done();
|
|
}
|
|
});
|
|
});
|
|
|
|
// See http://github.com/CartoDB/Windshaft-cartodb/issues/128
|
|
test('does not accept template with invalid token auth (undefined tokens)',
|
|
function(done) {
|
|
var tmap = new TemplateMaps(redis_pool);
|
|
assert.ok(tmap);
|
|
var tpl = { version:'0.0.1',
|
|
name: "invalid_auth1", placeholders: { },
|
|
auth: { method: 'token' }, layergroup: {layers:[wadusLayer]} };
|
|
tmap.addTemplate('me', tpl, function(err) {
|
|
if ( ! err ) {
|
|
done(new Error("Unexpected success with invalid token auth (undefined tokens)"));
|
|
}
|
|
else if ( ! err.message.match(/invalid 'token' authentication/i) ) {
|
|
done(new Error("Unexpected error message with invalid token auth (undefined tokens): "
|
|
+ err));
|
|
}
|
|
else {
|
|
done();
|
|
}
|
|
});
|
|
});
|
|
|
|
test('add, get and delete a valid template', function(done) {
|
|
var tmap = new TemplateMaps(redis_pool);
|
|
assert.ok(tmap);
|
|
var expected_failure = false;
|
|
var tpl_id;
|
|
var tpl = { version:'0.0.1',
|
|
name: 'first', auth: {}, layergroup: {layers:[wadusLayer]} };
|
|
Step(
|
|
function() {
|
|
tmap.addTemplate('me', tpl, this);
|
|
},
|
|
function addOmonimousTemplate(err, id) {
|
|
if ( err ) throw err;
|
|
tpl_id = id;
|
|
assert.equal(tpl_id, 'first');
|
|
expected_failure = true;
|
|
// should fail, as it already exists
|
|
tmap.addTemplate('me', tpl, this);
|
|
},
|
|
function getTemplate(err) {
|
|
if ( ! expected_failure && err ) throw err;
|
|
assert.ok(err);
|
|
assert.ok(err.message.match(/already exists/i), err);
|
|
tmap.getTemplate('me', tpl_id, this);
|
|
},
|
|
function delTemplate(err, got_tpl) {
|
|
if ( err ) throw err;
|
|
assert.deepEqual(got_tpl, _.extend({}, tpl, {auth: {method: 'open'}, placeholders: {}}));
|
|
tmap.delTemplate('me', tpl_id, this);
|
|
},
|
|
function finish(err) {
|
|
done(err);
|
|
}
|
|
);
|
|
});
|
|
|
|
test('add multiple templates, list them', function(done) {
|
|
var tmap = new TemplateMaps(redis_pool);
|
|
assert.ok(tmap);
|
|
var expected_failure = false;
|
|
var tpl1 = { version:'0.0.1', name: 'first', auth: {}, layergroup: {layers:[wadusLayer]} };
|
|
var tpl1_id;
|
|
var tpl2 = { version:'0.0.1', name: 'second', auth: {}, layergroup: {layers:[wadusLayer]} };
|
|
var tpl2_id;
|
|
Step(
|
|
function addTemplate1() {
|
|
tmap.addTemplate('me', tpl1, this);
|
|
},
|
|
function addTemplate2(err, id) {
|
|
if ( err ) throw err;
|
|
tpl1_id = id;
|
|
tmap.addTemplate('me', tpl2, this);
|
|
},
|
|
function listTemplates(err, id) {
|
|
if ( err ) throw err;
|
|
tpl2_id = id;
|
|
tmap.listTemplates('me', this);
|
|
},
|
|
function checkTemplates(err, ids) {
|
|
if ( err ) throw err;
|
|
assert.equal(ids.length, 2);
|
|
assert.ok(ids.indexOf(tpl1_id) != -1, ids.join(','));
|
|
assert.ok(ids.indexOf(tpl2_id) != -1, ids.join(','));
|
|
return null;
|
|
},
|
|
function delTemplate1(err) {
|
|
if ( tpl1_id ) {
|
|
var next = this;
|
|
tmap.delTemplate('me', tpl1_id, function(e) {
|
|
if ( err || e ) next(new Error(err + '; ' + e));
|
|
else next();
|
|
});
|
|
} else {
|
|
if ( err ) throw err;
|
|
return null;
|
|
}
|
|
},
|
|
function delTemplate2(err) {
|
|
if ( tpl2_id ) {
|
|
var next = this;
|
|
tmap.delTemplate('me', tpl2_id, function(e) {
|
|
if ( err || e ) next(new Error(err + '; ' + e));
|
|
else next();
|
|
});
|
|
} else {
|
|
if ( err ) throw err;
|
|
return null;
|
|
}
|
|
},
|
|
function finish(err) {
|
|
done(err);
|
|
}
|
|
);
|
|
});
|
|
|
|
test('update templates', function(done) {
|
|
var tmap = new TemplateMaps(redis_pool);
|
|
assert.ok(tmap);
|
|
var expected_failure = false;
|
|
var owner = 'me';
|
|
var tpl = { version:'0.0.1',
|
|
name: 'first',
|
|
auth: { method: 'open' },
|
|
layergroup: {layers:[wadusLayer]}
|
|
};
|
|
var tpl_id;
|
|
Step(
|
|
function addTemplate() {
|
|
tmap.addTemplate(owner, tpl, this);
|
|
},
|
|
// Updating template name should fail
|
|
function updateTemplateName(err, id) {
|
|
if ( err ) throw err;
|
|
tpl_id = id;
|
|
expected_failure = true;
|
|
tpl.name = 'second';
|
|
tmap.updTemplate(owner, tpl_id, tpl, this);
|
|
},
|
|
function updateTemplateAuth(err) {
|
|
if ( err && ! expected_failure) throw err;
|
|
expected_failure = false;
|
|
assert.ok(err);
|
|
tpl.name = 'first';
|
|
tpl.auth.method = 'token';
|
|
tpl.auth.valid_tokens = [ 'tok1' ];
|
|
tmap.updTemplate(owner, tpl_id, tpl, this);
|
|
},
|
|
function updateTemplateWithInvalid(err) {
|
|
if ( err ) throw err;
|
|
tpl.version = '999.999.999';
|
|
expected_failure = true;
|
|
tmap.updTemplate(owner, tpl_id, tpl, this);
|
|
},
|
|
function updateUnexistentTemplate(err) {
|
|
if ( err && ! expected_failure) throw err;
|
|
expected_failure = false;
|
|
assert.ok(err);
|
|
assert.ok(err.message.match(/unsupported.*version/i), err);
|
|
tpl.version = '0.0.1';
|
|
expected_failure = true;
|
|
tmap.updTemplate(owner, 'unexistent', tpl, this);
|
|
},
|
|
function delTemplate(err) {
|
|
if ( err && ! expected_failure) throw err;
|
|
expected_failure = false;
|
|
assert.ok(err);
|
|
assert.ok(err.message.match(/cannot update name/i), err);
|
|
tmap.delTemplate(owner, tpl_id, this);
|
|
},
|
|
function finish(err) {
|
|
done(err);
|
|
}
|
|
);
|
|
});
|
|
|
|
test('instanciate templates', function() {
|
|
var tmap = new TemplateMaps(redis_pool);
|
|
assert.ok(tmap);
|
|
|
|
var tpl1 = {
|
|
version: '0.0.1',
|
|
name: 'acceptance1',
|
|
auth: { method: 'open' },
|
|
placeholders: {
|
|
fill: { type: "css_color", default: "red" },
|
|
color: { type: "css_color", default: "#a0fF9A" },
|
|
name: { type: "sql_literal", default: "test" },
|
|
zoom: { type: "number", default: "0" },
|
|
test_number: { type: "number", default: 23 },
|
|
},
|
|
layergroup: {
|
|
version: '1.0.0',
|
|
global_cartocss_version: '2.0.2',
|
|
layers: [
|
|
{ options: {
|
|
sql: "select '<%=name %>' || id, g from t",
|
|
cartocss: '#layer { marker-fill:<%= fill %>; marker-width: <%=test_number %>; }'
|
|
} },
|
|
{ options: {
|
|
sql: "select fun('<%= name%>') g from x",
|
|
cartocss: '#layer { line-color:<%= color %>; marker-fill:<%= color %>; }'
|
|
} },
|
|
{ options: {
|
|
sql: "select g from x",
|
|
cartocss: '#layer[zoom=<%=zoom%>] { }'
|
|
} }
|
|
]
|
|
}
|
|
};
|
|
|
|
var inst = tmap.instance(tpl1, {});
|
|
|
|
var lyr = inst.layers[0].options;
|
|
assert.equal(lyr.sql, "select 'test' || id, g from t");
|
|
assert.equal(lyr.cartocss, '#layer { marker-fill:red; marker-width: 23; }');
|
|
|
|
lyr = inst.layers[1].options;
|
|
assert.equal(lyr.sql, "select fun('test') g from x");
|
|
assert.equal(lyr.cartocss, '#layer { line-color:#a0fF9A; marker-fill:#a0fF9A; }');
|
|
|
|
inst = tmap.instance(tpl1, {color:'yellow', name:"it's dangerous"});
|
|
|
|
lyr = inst.layers[0].options;
|
|
assert.equal(lyr.sql, "select 'it''s dangerous' || id, g from t");
|
|
assert.equal(lyr.cartocss, '#layer { marker-fill:red; marker-width: 23; }');
|
|
|
|
lyr = inst.layers[1].options;
|
|
assert.equal(lyr.sql, "select fun('it''s dangerous') g from x");
|
|
assert.equal(lyr.cartocss, '#layer { line-color:yellow; marker-fill:yellow; }');
|
|
|
|
// Invalid css_color
|
|
var err = null;
|
|
try { inst = tmap.instance(tpl1, {color:'##ff00ff'}); }
|
|
catch (e) { err = e; }
|
|
assert.ok(err);
|
|
assert.ok(err.message.match(/invalid css_color/i), err);
|
|
|
|
// Invalid css_color 2 (too few digits)
|
|
var err = null;
|
|
try { inst = tmap.instance(tpl1, {color:'#ff'}); }
|
|
catch (e) { err = e; }
|
|
assert.ok(err);
|
|
assert.ok(err.message.match(/invalid css_color/i), err);
|
|
|
|
// Invalid css_color 3 (too many digits)
|
|
var err = null;
|
|
try { inst = tmap.instance(tpl1, {color:'#1234567'}); }
|
|
catch (e) { err = e; }
|
|
assert.ok(err);
|
|
assert.ok(err.message.match(/invalid css_color/i), err);
|
|
|
|
// Invalid number
|
|
var err = null;
|
|
try { inst = tmap.instance(tpl1, {zoom:'#'}); }
|
|
catch (e) { err = e; }
|
|
assert.ok(err);
|
|
assert.ok(err.message.match(/invalid number/i), err);
|
|
|
|
// Invalid number 2
|
|
var err = null;
|
|
try { inst = tmap.instance(tpl1, {zoom:'23e'}); }
|
|
catch (e) { err = e; }
|
|
assert.ok(err);
|
|
assert.ok(err.message.match(/invalid number/i), err);
|
|
|
|
// Valid number
|
|
var err = null;
|
|
try { inst = tmap.instance(tpl1, {zoom:'-.23e10'}); }
|
|
catch (e) { err = e; }
|
|
assert.ok(!err);
|
|
});
|
|
|
|
// Can set a limit on the number of user templates
|
|
test('can limit number of user templates', function(done) {
|
|
var tmap = new TemplateMaps(redis_pool, {
|
|
max_user_templates: 2
|
|
});
|
|
assert.ok(tmap);
|
|
var tpl = { version:'0.0.1', auth: {}, layergroup: {layers:[wadusLayer]} };
|
|
var expectErr = false;
|
|
var idMe = [];
|
|
var idYou = [];
|
|
Step(
|
|
function oneForMe() {
|
|
tpl.name = 'oneForMe';
|
|
tmap.addTemplate('me', tpl, this);
|
|
},
|
|
function twoForMe(err, id) {
|
|
if ( err ) throw err;
|
|
assert.ok(id);
|
|
idMe.push(id);
|
|
tpl.name = 'twoForMe';
|
|
tmap.addTemplate('me', tpl, this);
|
|
},
|
|
function threeForMe(err, id) {
|
|
if ( err ) throw err;
|
|
assert.ok(id);
|
|
idMe.push(id);
|
|
tpl.name = 'threeForMe';
|
|
expectErr = true;
|
|
tmap.addTemplate('me', tpl, this);
|
|
},
|
|
function errForMe(err, id) {
|
|
if ( err && ! expectErr ) throw err;
|
|
expectErr = false;
|
|
assert.ok(err);
|
|
assert.ok(err.message.match(/limit.*template/), err);
|
|
return null;
|
|
},
|
|
function delOneMe(err) {
|
|
if ( err ) throw err;
|
|
tmap.delTemplate('me', idMe.shift(), this);
|
|
},
|
|
function threeForMeRetry(err) {
|
|
if ( err ) throw err;
|
|
tpl.name = 'threeForMe';
|
|
tmap.addTemplate('me', tpl, this);
|
|
},
|
|
function oneForYou(err, id) {
|
|
if ( err ) throw err;
|
|
assert.ok(id);
|
|
idMe.push(id);
|
|
tpl.name = 'oneForYou';
|
|
tmap.addTemplate('you', tpl, this);
|
|
},
|
|
function twoForYou(err, id) {
|
|
if ( err ) throw err;
|
|
assert.ok(id);
|
|
idYou.push(id);
|
|
tpl.name = 'twoForYou';
|
|
tmap.addTemplate('you', tpl, this);
|
|
},
|
|
function threeForYou(err, id) {
|
|
if ( err ) throw err;
|
|
assert.ok(id);
|
|
idYou.push(id);
|
|
tpl.name = 'threeForYou';
|
|
expectErr = true;
|
|
tmap.addTemplate('you', tpl, this);
|
|
},
|
|
function errForYou(err, id) {
|
|
if ( err && ! expectErr ) throw err;
|
|
expectErr = false;
|
|
assert.ok(err);
|
|
assert.ok(err.message.match(/limit.*template/), err);
|
|
return null;
|
|
},
|
|
function finish(err) {
|
|
// TODO: delete all templates
|
|
done(err);
|
|
}
|
|
);
|
|
});
|
|
|
|
});
|