cdb
This commit is contained in:
@@ -0,0 +1,573 @@
|
||||
describe('api.layers', function() {
|
||||
|
||||
describe('loadLayer leaflet', function() {
|
||||
loadLayerSpecs(function() {
|
||||
return L.map($('<div>')[0]).setView([0, 0], 3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadLayer gmaps', function() {
|
||||
loadLayerSpecs(function() {
|
||||
return new google.maps.Map($('<div>')[0],{
|
||||
zoom: 3,
|
||||
center: new google.maps.LatLng(0, 0),
|
||||
mapTypeId: google.maps.MapTypeId.ROADMAP
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('loadLayer unknow', function() {
|
||||
it("should return an error for unknow map types", function(done) {
|
||||
var map = {};
|
||||
var err = false;
|
||||
cartodb.createLayer(map, { kind: 'plain', options: {} }, function(l) {
|
||||
layer = l;
|
||||
}).error(function() {
|
||||
err = true;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(err).toEqual(true);
|
||||
done();
|
||||
}, 1000);
|
||||
})
|
||||
});
|
||||
|
||||
//
|
||||
// shared specs for each map
|
||||
//
|
||||
function loadLayerSpecs(mapFn) {
|
||||
|
||||
describe("(shared)", function() {
|
||||
var map;
|
||||
beforeEach(function() {
|
||||
map = mapFn();
|
||||
cartodb.torque = torque;
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
delete cartodb.torque;
|
||||
});
|
||||
|
||||
it("should fecth layer when user and pass are specified", function() {
|
||||
spyOn(cdb.core.Loader, 'get');
|
||||
cartodb.createLayer(map, {
|
||||
user: 'development',
|
||||
table: 'clubbing',
|
||||
host: 'localhost.lan:3000',
|
||||
protocol: 'http'
|
||||
});
|
||||
expect(cdb.core.Loader.get).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should fecth layer when a url is specified", function() {
|
||||
spyOn(cdb.core.Loader, 'get');
|
||||
cartodb.createLayer(map, 'http://test.com/layer.json');
|
||||
expect(cdb.core.Loader.get).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should not fecth layer when kind and options are specified", function() {
|
||||
spyOn(cdb.core.Loader, 'get');
|
||||
cartodb.createLayer(map, { kind: 'plain', options: {} });
|
||||
expect(cdb.core.Loader.get).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should create a layer", function(done) {
|
||||
var layer;
|
||||
|
||||
cartodb.createLayer(map, { kind: 'plain', options: {} }, function(l) {
|
||||
layer = l;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer).not.toEqual(undefined);
|
||||
expect(layer.type).toEqual('plain');
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it("should create a layer with type", function(done) {
|
||||
var layer;
|
||||
|
||||
cartodb.createLayer(map, { kind: 'cartodb', options: { tile_style: 'test', table_name: 'table', user_name: 'test'} }, function(l) {
|
||||
layer = l;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer.type).toEqual('cartodb');
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it("should create a layer with options", function(done) {
|
||||
var layer;
|
||||
cartodb.createLayer(map, { kind: 'cartodb', options: {tile_style: 'test', table_name: 'table', user_name: 'test'} }, {query: 'select test'}, function(l) {
|
||||
layer = l;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer.options.query).toEqual('select test');
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it("should use https when https == true", function(done) {
|
||||
var layer;
|
||||
|
||||
cartodb.createLayer(map, { kind: 'cartodb', options: {tile_style: 'test', table_name: 'table', user_name: 'test'} }, {https: true}, function(l) {
|
||||
layer = l;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer._host().indexOf('https')).toEqual(0);
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it("should not use https when https == false", function(done) {
|
||||
var layer;
|
||||
|
||||
cartodb.createLayer(map, { kind: 'cartodb', options: {tile_style: 'test', table_name: 'table', user_name: 'test'} }, {https: false}, function(l) {
|
||||
layer = l;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer._host().indexOf('https')).toEqual(-1);
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it("should not substitute mapnik tokens", function(done) {
|
||||
var layer;
|
||||
|
||||
cartodb.createLayer(map, { kind: 'cartodb', options: {tile_style: 'test', table_name: 'table', user_name: 'test'} }, {query: 'select !bbox!'}, function(l) {
|
||||
layer = l
|
||||
})
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer.getQuery()).toEqual('select !bbox!');
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it("should manage errors", function(done) {
|
||||
var s = sinon.spy();
|
||||
cartodb.createLayer(map, { options: {} }).on('error', s);
|
||||
|
||||
setTimeout(function() {
|
||||
expect(s.called).toEqual(true);
|
||||
done();
|
||||
}, 10);
|
||||
});
|
||||
|
||||
it("should call callback if the last argument is a function", function(done) {
|
||||
var layer;
|
||||
var s = sinon.spy();
|
||||
var s2 = sinon.spy();
|
||||
|
||||
cartodb.createLayer(map, { kind: 'plain', options: {} }, s);
|
||||
cartodb.createLayer(map, layer={ kind: 'plain', options: {} }, { rambo: 'thebest'} ,s2);
|
||||
|
||||
setTimeout(function() {
|
||||
expect(s.called).toEqual(true);
|
||||
expect(layer.options.rambo).toEqual('thebest');
|
||||
expect(s2.called).toEqual(true);
|
||||
done();
|
||||
}, 10);
|
||||
|
||||
});
|
||||
|
||||
it("should load vis.json", function(done) {
|
||||
var layer;
|
||||
var s = sinon.spy();
|
||||
cartodb.createLayer(map, {
|
||||
updated_at: 'jaja',
|
||||
layers: [
|
||||
{ type: 'tiled', options: {} },
|
||||
{
|
||||
type: 'layergroup',
|
||||
options: {
|
||||
layer_definition: {
|
||||
layers: []
|
||||
},
|
||||
extra_params: { cache_buster: 'cb' }
|
||||
}
|
||||
}
|
||||
]
|
||||
}, s).done(function(lyr) {
|
||||
layer = lyr;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(s.called).toEqual(true);
|
||||
expect(layer.model.attributes.extra_params.cache_buster).toEqual('cb');
|
||||
done();
|
||||
}, 10);
|
||||
});
|
||||
|
||||
it("should load specified layer", function(done) {
|
||||
var layer;
|
||||
var s = sinon.spy();
|
||||
cartodb.createLayer(map, {
|
||||
updated_at: 'jaja',
|
||||
layers: [
|
||||
null,
|
||||
{kind: 'cartodb', options: { user_name: 'test', table_name: 'test', tile_style: 'test'}, infowindow: null },
|
||||
{kind: 'torque', options: { user_name: 'test', table_name: 'test', tile_style: 'Map{ -torque-frame-count: 10; }#test { marker-width: 10; }'}, infowindow: null }
|
||||
]
|
||||
}, { layerIndex: 2 }, s).done(function(lyr) {
|
||||
layer = lyr;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(s.called).toEqual(true);
|
||||
// check it's a torque layer and not a cartodb one
|
||||
expect(layer.model.get('type')).toEqual('torque');
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it("should load the `namedmap` layer by default", function(done) {
|
||||
var layer;
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
updated_at: 'jaja',
|
||||
layers: [
|
||||
{ type: 'tiled', options: {} },
|
||||
{ type: 'tiled', options: {} },
|
||||
{
|
||||
type: 'namedmap',
|
||||
user_name: 'dev',
|
||||
options: {
|
||||
named_map: {
|
||||
name: 'testing',
|
||||
params: {
|
||||
color: 'red'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}).done(function(lyr) {
|
||||
layer = lyr;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer).toBeDefined();
|
||||
expect(layer.options.type).toEqual('namedmap');
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it("should load the `layergroup` layer by default", function(done) {
|
||||
var layer;
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
updated_at: 'jaja',
|
||||
layers: [
|
||||
{ type: 'tiled', options: {} },
|
||||
{ type: 'tiled', options: {} },
|
||||
{
|
||||
type: 'layergroup',
|
||||
options: {
|
||||
layer_definition: {
|
||||
layers: []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}).done(function(lyr) {
|
||||
layer = lyr;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer).toBeDefined();
|
||||
expect(layer.options.type).toEqual('layergroup');
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it("should load the `torque` layer by default", function(done) {
|
||||
var layer;
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
updated_at: 'jaja',
|
||||
layers: [
|
||||
{ type: 'tiled', options: {} },
|
||||
{ type: 'tiled', options: {} },
|
||||
{
|
||||
type: 'torque',
|
||||
options: {
|
||||
'torque-steps': 3
|
||||
}
|
||||
}
|
||||
]
|
||||
}).done(function(lyr) {
|
||||
layer = lyr;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer).toBeDefined();
|
||||
expect(layer.type).toEqual('torque');
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it("should add a torque layer", function(done) {
|
||||
var layer;
|
||||
var s = sinon.spy();
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
updated_at: 'jaja',
|
||||
layers: [
|
||||
null,
|
||||
{kind: 'cartodb', options: { user_name: 'test', table_name: 'test', tile_style: 'test'}, infowindow: null },
|
||||
{kind: 'torque', options: { user_name: 'test', table_name: 'test', tile_style: 'Map { -torque-frame-count: 10;} #test { marker-width: 10; }'}, infowindow: null }
|
||||
]
|
||||
}, { layerIndex: 2 }, s).done(function(lyr) {
|
||||
layer = lyr;
|
||||
}).addTo(map)
|
||||
|
||||
var wait = 500;
|
||||
if (!map.getContainer) wait = 2500;
|
||||
|
||||
setTimeout(function() {
|
||||
if (map.getContainer) expect($(map.getContainer()).find('.cartodb-timeslider').length).toBe(1)
|
||||
if (map.getDiv) expect($(map.getDiv()).find('.cartodb-timeslider').length).toBe(1)
|
||||
done()
|
||||
}, wait);
|
||||
});
|
||||
|
||||
it("should ask for https data when https is on at torque layer", function(done) {
|
||||
var layer;
|
||||
var s = sinon.spy();
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
updated_at: 'jaja',
|
||||
layers: [
|
||||
null,
|
||||
{kind: 'cartodb', options: { user_name: 'test', table_name: 'test', tile_style: 'test'}, infowindow: null },
|
||||
{kind: 'torque', options: { user_name: 'test', table_name: 'test', tile_style: 'Map { -torque-frame-count: 10;} #test { marker-width: 10; }'}, infowindow: null }
|
||||
]
|
||||
}, { layerIndex: 2, https: true }, s).done(function(lyr) {
|
||||
layer = lyr;
|
||||
|
||||
}).addTo(map)
|
||||
|
||||
var wait = 500;
|
||||
if (!map.getContainer) wait = 2500;
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer.provider.options.tiler_protocol).toBe("https");
|
||||
done()
|
||||
}, wait);
|
||||
});
|
||||
|
||||
it("should not add a torque layer timeslider if steps are not greater than 1", function(done) {
|
||||
var layer;
|
||||
var s = sinon.spy();
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
updated_at: 'jaja',
|
||||
layers: [
|
||||
null,
|
||||
{kind: 'cartodb', options: { user_name: 'test', table_name: 'test', tile_style: 'test'}, infowindow: null },
|
||||
{kind: 'torque', options: { user_name: 'test', table_name: 'test', tile_style: 'Map { -torque-frame-count: 1;} #test { marker-width: 10; }'}, infowindow: null }
|
||||
]
|
||||
}, { layerIndex: 2 }, s).done(function(lyr) {
|
||||
layer = lyr;
|
||||
}).addTo(map)
|
||||
|
||||
var wait = 500;
|
||||
if (!map.getContainer) wait = 2500;
|
||||
|
||||
setTimeout(function() {
|
||||
if (map.getContainer) expect($(map.getContainer()).find('.cartodb-timeslider').length).toBe(0)
|
||||
if (map.getDiv) expect($(map.getDiv()).find('.cartodb-timeslider').length).toBe(0)
|
||||
done()
|
||||
}, wait);
|
||||
});
|
||||
|
||||
it("should add cartodb logo with torque layer although it is not defined", function(done) {
|
||||
var layer;
|
||||
var s = sinon.spy();
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
updated_at: 'jaja',
|
||||
layers: [
|
||||
null,
|
||||
{kind: 'cartodb', options: { user_name: 'test', table_name: 'test', tile_style: 'test'}, infowindow: null },
|
||||
{kind: 'torque', options: { user_name: 'test', table_name: 'test', tile_style: 'Map{ -torque-frame-count: 10;}#test { marker-width: 10; }'}, infowindow: null }
|
||||
]
|
||||
}, { layerIndex: 2 }, s).done(function(lyr) {
|
||||
layer = lyr;
|
||||
}).addTo(map)
|
||||
|
||||
var wait = 500;
|
||||
if (!map.getContainer) wait = 2500;
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer.options.cartodb_logo).toEqual(undefined);
|
||||
if (map.getContainer) expect($(map.getContainer()).find('.cartodb-logo').length).toBe(1)
|
||||
if (map.getDiv) expect($(map.getDiv()).find('.cartodb-logo').length).toBe(1)
|
||||
done();
|
||||
}, wait);
|
||||
});
|
||||
|
||||
it("should create a named map", function(done) {
|
||||
var layer;
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
type: 'namedmap',
|
||||
user_name: 'dev',
|
||||
options: {
|
||||
named_map: {
|
||||
name: 'testing',
|
||||
params: {
|
||||
color: 'red'
|
||||
}
|
||||
}
|
||||
}
|
||||
}).done(function(lyr) {
|
||||
layer = lyr;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer).not.toEqual(undefined);
|
||||
expect(layer.toJSON()).toEqual({ color: 'red' });
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it("should use access_token", function(done) {
|
||||
cartodb.createLayer(map, {
|
||||
type: 'namedmap',
|
||||
user_name: 'dev',
|
||||
options: {
|
||||
named_map: {
|
||||
name: 'testing',
|
||||
params: {
|
||||
color: 'red'
|
||||
}
|
||||
}
|
||||
}
|
||||
}, { https: true, auth_token: 'at_rambo' }).done(function(layer) {
|
||||
spyOn(layer, 'createMap').and.returnValue({
|
||||
layergroupid: 'test',
|
||||
metadata: {
|
||||
layers: []
|
||||
}
|
||||
})
|
||||
layer.getTiles(function(tiles) {
|
||||
expect(tiles.tiles[0].indexOf("auth_token=at_rambo")).not.toEqual(-1);
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should create a layer from the list of sublayers", function(done) {
|
||||
var layer;
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
type: 'cartodb',
|
||||
sublayers: [{
|
||||
sql: 'select * from table',
|
||||
cartocss: 'test',
|
||||
interactivity: 'testi'
|
||||
}]
|
||||
}).done(function(lyr) {
|
||||
layer = lyr;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer).not.toEqual(undefined);
|
||||
expect(layer.toJSON()).toEqual({
|
||||
version: '1.3.0',
|
||||
stat_tag: 'API',
|
||||
layers: [{
|
||||
type: 'cartodb',
|
||||
options: {
|
||||
sql: 'select * from table',
|
||||
cartocss: 'test',
|
||||
cartocss_version: '2.1.0',
|
||||
interactivity: ['testi']
|
||||
}
|
||||
}]
|
||||
});
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it("should return a promise that responds to addTo", function(done) {
|
||||
var layer;
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
type: 'cartodb',
|
||||
sublayers: [{
|
||||
sql: 'select * from table',
|
||||
cartocss: 'test',
|
||||
interactivity: 'testi'
|
||||
}]
|
||||
})
|
||||
.addTo(map)
|
||||
.done(function(lyr) {
|
||||
layer = lyr;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer).not.toEqual(undefined);
|
||||
if(map.overlayMapTypes) {
|
||||
expect(layer).toBe(map.overlayMapTypes.getAt(0));
|
||||
} else {
|
||||
expect(layer).toBe(map._layers[L.stamp(layer)]);
|
||||
}
|
||||
done();
|
||||
}, 100);
|
||||
|
||||
});
|
||||
|
||||
it("should have several 'addTo' with zIndex set", function(done) {
|
||||
var layer0, layer1;
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
type: 'cartodb',
|
||||
sublayers: [{
|
||||
sql: 'select * from table',
|
||||
cartocss: 'test',
|
||||
interactivity: 'testi'
|
||||
}]
|
||||
})
|
||||
.addTo(map,0)
|
||||
.done(function(lyr) {
|
||||
layer0 = lyr;
|
||||
});
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
type: 'cartodb',
|
||||
sublayers: [{
|
||||
sql: 'select * from table2',
|
||||
cartocss: 'test2',
|
||||
interactivity: 'testii'
|
||||
}]
|
||||
})
|
||||
.addTo(map,1)
|
||||
.done(function(lyr) {
|
||||
layer1 = lyr;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
//Test only for Leaflet
|
||||
if(map.overlayMapTypes === undefined) {
|
||||
expect(layer0).not.toEqual(undefined);
|
||||
expect(layer0.options.zIndex).toEqual(0);
|
||||
expect(layer1).not.toEqual(undefined);
|
||||
expect(layer1.options.zIndex).toEqual(1);
|
||||
}
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,230 @@
|
||||
describe('api.layers.cartodb', function() {
|
||||
|
||||
describe('loadLayer leaflet', function() {
|
||||
loadLayerSpecs(function() {
|
||||
return L.map($('<div>')[0]).setView([0, 0], 3);
|
||||
}, function(map, layer) {
|
||||
map.addLayer(layer);
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadLayer gmaps', function() {
|
||||
loadLayerSpecs(function() {
|
||||
return new google.maps.Map($('<div>')[0],{
|
||||
zoom: 3,
|
||||
center: new google.maps.LatLng(0, 0),
|
||||
mapTypeId: google.maps.MapTypeId.ROADMAP
|
||||
});
|
||||
},
|
||||
function(map, layer) {
|
||||
map.overlayMapTypes.setAt(0, layer);
|
||||
});
|
||||
});
|
||||
|
||||
//
|
||||
// shared specs for each map
|
||||
//
|
||||
function loadLayerSpecs(mapFn, addFn) {
|
||||
var layer;
|
||||
var map;
|
||||
|
||||
beforeEach(function() {
|
||||
map = mapFn();
|
||||
});
|
||||
|
||||
it("has all the needed methods", function(done) {
|
||||
var methods = [
|
||||
'show',
|
||||
'hide',
|
||||
'setInteraction',
|
||||
'setQuery',
|
||||
'setCartoCSS',
|
||||
'isVisible',
|
||||
'setInteractivity',
|
||||
'setOpacity',
|
||||
'setOptions'
|
||||
];
|
||||
|
||||
cartodb.createLayer(map, { kind: 'cartodb', options: { table_name:'test', tile_style: 'test', user_name: 'test'} }, function(l) {
|
||||
layer = l;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
_.each(methods, function(m) {
|
||||
expect(layer[m]).not.toEqual(undefined);
|
||||
})
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
function get_url_options(u) {
|
||||
var o = u.split('?')[1].split('&');
|
||||
var opts = {};
|
||||
for(var i in o) {
|
||||
var tk = o[i].split('=');
|
||||
opts[tk[0]] = decodeURIComponent(tk[1]);
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
|
||||
|
||||
it("should add a infowindow", function(done) {
|
||||
//cdb.templates.add(new cdb.core.Template({
|
||||
//name: 'test',
|
||||
//}));
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
kind: 'cartodb',
|
||||
options: {
|
||||
table_name: 'test',
|
||||
user_name: 'test',
|
||||
tile_style: 'tesst'
|
||||
},
|
||||
infowindow: {
|
||||
template: '<div></div>',
|
||||
fields: [{name: 'test', title: true, order: 0}]
|
||||
}
|
||||
}, function(l) {
|
||||
addFn(map, l);
|
||||
layer = l;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer.infowindow).not.toEqual(undefined);
|
||||
expect(layer.infowindow.get('fields').length).toEqual(1);
|
||||
expect(layer.infowindow.get('fields')[0].name).toEqual('test');
|
||||
expect(layer.options.interactivity).toEqual('cartodb_id');
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it("should expose the legend", function(done) {
|
||||
var legend = {
|
||||
type: "custom",
|
||||
show_title: true,
|
||||
title: "wadus",
|
||||
template: "",
|
||||
items: [
|
||||
{
|
||||
name: "item1",
|
||||
visible: true,
|
||||
value: "#FFCC00",
|
||||
sync: true
|
||||
},
|
||||
{
|
||||
name: "item2",
|
||||
visible: true,
|
||||
value: "#3B007F",
|
||||
sync: true
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
kind: 'cartodb',
|
||||
options: {
|
||||
table_name: 'test',
|
||||
user_name: 'test',
|
||||
tile_style: 'tesst'
|
||||
},
|
||||
infowindow: {
|
||||
template: '<div></div>',
|
||||
fields: [{name: 'test', title: true, order: 0}]
|
||||
},
|
||||
legend: legend,
|
||||
visible: true
|
||||
}, function(l) {
|
||||
addFn(map, l);
|
||||
layer = l;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer.legend instanceof cdb.geo.ui.LegendModel).toBeTruthy();
|
||||
expect(layer.legend.get('visible')).toBeTruthy();
|
||||
expect(layer.legend.get('items')).toEqual(legend.items);
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it("should add interactivity if there is infowindow", function(done) {
|
||||
cartodb.createLayer(map, {
|
||||
kind: 'cartodb',
|
||||
options: {
|
||||
table_name: 'test',
|
||||
user_name: 'test',
|
||||
tile_style: 'test'
|
||||
},
|
||||
infowindow: {
|
||||
template: '<div></div>',
|
||||
fields: [{name: 'test', title: true, order: 0}]
|
||||
}
|
||||
}, {
|
||||
interactivity: 'myname,jaja'
|
||||
}, function(l) {
|
||||
addFn(map, l);
|
||||
layer = l;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer.infowindow).not.toEqual(undefined);
|
||||
expect(layer.options.interactivity).toEqual('myname,jaja,cartodb_id');
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it("should not add interactivity when interaction is false", function(done) {
|
||||
|
||||
cartodb.createLayer(map, {
|
||||
kind: 'cartodb',
|
||||
options: {
|
||||
table_name: 'test',
|
||||
user_name: 'test',
|
||||
tile_style: 'test'
|
||||
},
|
||||
infowindow: {
|
||||
template: '<div></div>',
|
||||
fields: [{name: 'test', title: true, order: 0}]
|
||||
}
|
||||
}, {
|
||||
interactivity: 'myname,jaja',
|
||||
interaction: false
|
||||
}, function(l) {
|
||||
addFn(map, l);
|
||||
layer = l;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layer.infowindow).not.toEqual(undefined);
|
||||
expect(layer.options.interactivity).toEqual('myname,jaja,cartodb_id');
|
||||
expect(layer.options.interaction).toEqual(false);
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it("should add to the map when done", function() {
|
||||
cartodb.createLayer(map, {
|
||||
kind: 'cartodb',
|
||||
options: {
|
||||
table_name: 'test',
|
||||
user_name: 'test',
|
||||
tile_style: 'test'
|
||||
},
|
||||
infowindow: {
|
||||
template: '<div></div>',
|
||||
fields: [{name: 'test', title: true, order: 0}]
|
||||
}
|
||||
}, {
|
||||
interactivity: 'myname,jaja',
|
||||
interaction: false
|
||||
}, function(l) {
|
||||
addFn(map, l);
|
||||
layer = l;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,429 @@
|
||||
|
||||
describe('SQL api client', function() {
|
||||
var USER = 'rambo';
|
||||
var TEST_DATA = { test: 'good' };
|
||||
var sql;
|
||||
var ajaxParams;
|
||||
var throwError = false;
|
||||
var jquery_ajax;
|
||||
var ajax;
|
||||
beforeEach(function() {
|
||||
ajaxParams = null;
|
||||
ajax = function(params) {
|
||||
ajaxParams = params;
|
||||
_.defer(function() {
|
||||
if(!throwError && params.success) params.success(TEST_DATA, 200);
|
||||
throwError && params.error && params.error({
|
||||
responseText: JSON.stringify({
|
||||
error: ['jaja']
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
sql = new cartodb.SQL({
|
||||
user: USER,
|
||||
protocol: 'https',
|
||||
ajax: ajax
|
||||
})
|
||||
|
||||
jquery_ajax = $.ajax;
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
$.ajax = jquery_ajax;
|
||||
});
|
||||
|
||||
it("should compile the url if not completeDomain passed", function() {
|
||||
expect(sql._host()).toEqual('https://rambo.carto.com/api/v2/sql');
|
||||
});
|
||||
|
||||
it("should compile the url if completeDomain passed", function() {
|
||||
var sqlBis = new cartodb.SQL({
|
||||
user: USER,
|
||||
protocol: 'https',
|
||||
completeDomain: 'http://troloroloro.com'
|
||||
})
|
||||
|
||||
expect(sqlBis._host()).toEqual('http://troloroloro.com/api/v2/sql');
|
||||
});
|
||||
|
||||
it("should execute a query", function() {
|
||||
sql.execute('select * from table');
|
||||
expect(ajaxParams.url).toEqual(
|
||||
'https://' + USER + '.carto.com/api/v2/sql?q=' + encodeURIComponent('select * from table')
|
||||
)
|
||||
expect(ajaxParams.type).toEqual('get');
|
||||
expect(ajaxParams.dataType).toEqual('json');
|
||||
expect(ajaxParams.crossDomain).toEqual(true);
|
||||
});
|
||||
|
||||
it("should parse template", function() {
|
||||
sql.execute('select * from {{table}}', {
|
||||
table: 'rambo'
|
||||
})
|
||||
expect(ajaxParams.url).toEqual(
|
||||
'https://' + USER + '.carto.com/api/v2/sql?q=' + encodeURIComponent('select * from rambo')
|
||||
)
|
||||
});
|
||||
|
||||
it("should execute a long query", function() {
|
||||
//Generating a giant query
|
||||
var long_sql = []
|
||||
var i = 2000;
|
||||
while (--i) long_sql.push("10000");
|
||||
var long_query = 'SELECT * ' + long_sql;
|
||||
|
||||
sql.execute(long_query);
|
||||
|
||||
expect(ajaxParams.url).toEqual(
|
||||
'https://' + USER + '.carto.com/api/v2/sql'
|
||||
)
|
||||
|
||||
expect(ajaxParams.data.q).toEqual(long_query);
|
||||
expect(ajaxParams.type).toEqual('post');
|
||||
expect(ajaxParams.dataType).toEqual('json');
|
||||
expect(ajaxParams.crossDomain).toEqual(true);
|
||||
});
|
||||
|
||||
it("should execute a long query with params", function() {
|
||||
s = new cartodb.SQL({
|
||||
user: 'rambo',
|
||||
format: 'geojson',
|
||||
protocol: 'http',
|
||||
host: 'charlies.com',
|
||||
api_key: 'testkey',
|
||||
rambo: 'test',
|
||||
ajax: ajax
|
||||
})
|
||||
|
||||
//Generating a giant query
|
||||
var long_sql = []
|
||||
var i = 2000;
|
||||
while (--i) long_sql.push("10000");
|
||||
var long_query = 'SELECT * ' + long_sql;
|
||||
|
||||
s.execute(long_query, null, {
|
||||
dp: 2
|
||||
})
|
||||
|
||||
expect(ajaxParams.url.indexOf('http://')).not.toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('rambo.charlies.com')).not.toEqual(-1);
|
||||
//Check that we don't have params in the URI
|
||||
expect(ajaxParams.url.indexOf('&format=geojson')).toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('&api_key=testkey')).toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('&dp=2')).toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('&rambo')).toEqual(-1);
|
||||
//Check that we have the params in the body
|
||||
expect(ajaxParams.data.q).toEqual(long_query);
|
||||
expect(ajaxParams.data.format).toEqual('geojson');
|
||||
expect(ajaxParams.data.api_key).toEqual('testkey');
|
||||
expect(ajaxParams.data.dp).toEqual(2);
|
||||
expect(ajaxParams.rambo).toEqual('test');
|
||||
});
|
||||
|
||||
it("should substitute mapnik tokens", function() {
|
||||
sql.execute('select !pixel_width! as w, !pixel_height! as h, !bbox! as b from {{table}}', {
|
||||
table: 't'
|
||||
})
|
||||
|
||||
var earth_circumference = 40075017;
|
||||
var tile_size = 256;
|
||||
var srid = 3857;
|
||||
var full_resolution = earth_circumference/tile_size;
|
||||
var shift = earth_circumference / 2.0;
|
||||
|
||||
var pw = full_resolution;
|
||||
var ph = pw;
|
||||
var bbox = 'ST_MakeEnvelope(' + (-shift) + ',' + (-shift) + ','
|
||||
+ shift + ',' + shift + ',' + srid + ')';
|
||||
|
||||
expect(ajaxParams.url).toEqual(
|
||||
'https://' + USER + '.carto.com/api/v2/sql?q=' + encodeURIComponent(
|
||||
'select ' + pw + ' as w, ' + ph + ' as h, '
|
||||
+ bbox + ' as b from t')
|
||||
)
|
||||
});
|
||||
|
||||
it("should call promise", function(done) {
|
||||
var data;
|
||||
var data_callback;
|
||||
|
||||
sql.execute('select * from bla', function(data) { data_callback = data }).done(function(d) {
|
||||
data = d;
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(data).toEqual(TEST_DATA);
|
||||
expect(data_callback).toEqual(TEST_DATA);
|
||||
done()
|
||||
}, 500); //Fix cartodb.js issue #336
|
||||
});
|
||||
it("should call promise on error", function(done) {
|
||||
throwError = true;
|
||||
var err = false;
|
||||
sql.execute('select * from bla').error(function(d) {
|
||||
err = true;
|
||||
});
|
||||
setTimeout(function() {
|
||||
expect(err).toEqual(true);
|
||||
done();
|
||||
},10);
|
||||
});
|
||||
|
||||
it("should include url params", function() {
|
||||
s = new cartodb.SQL({
|
||||
user: 'rambo',
|
||||
format: 'geojson',
|
||||
protocol: 'http',
|
||||
host: 'charlies.com',
|
||||
api_key: 'testkey',
|
||||
rambo: 'test',
|
||||
ajax: ajax
|
||||
})
|
||||
s.execute('select * from rambo', null, {
|
||||
dp: 2
|
||||
})
|
||||
expect(ajaxParams.url.indexOf('http://')).not.toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('rambo.charlies.com')).not.toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('&format=geojson')).not.toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('&api_key=testkey')).not.toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('&dp=2')).not.toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('&rambo')).toEqual(-1);
|
||||
});
|
||||
|
||||
it("should include extra url params", function() {
|
||||
s = new cartodb.SQL({
|
||||
user: 'rambo',
|
||||
format: 'geojson',
|
||||
protocol: 'http',
|
||||
host: 'charlies.com',
|
||||
api_key: 'testkey',
|
||||
rambo: 'test',
|
||||
ajax: ajax,
|
||||
extra_params: ['rambo']
|
||||
})
|
||||
s.execute('select * from rambo', null, {
|
||||
dp: 2
|
||||
})
|
||||
expect(ajaxParams.url.indexOf('http://')).not.toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('rambo.charlies.com')).not.toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('&format=geojson')).not.toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('&api_key=testkey')).not.toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('&dp=2')).not.toEqual(-1);
|
||||
expect(ajaxParams.url.indexOf('&rambo=test')).not.toEqual(-1);
|
||||
|
||||
s.execute('select * from rambo', null, {
|
||||
dp: 2,
|
||||
rambo: 'test2'
|
||||
})
|
||||
expect(ajaxParams.url.indexOf('&rambo=test2')).not.toEqual(-1);
|
||||
});
|
||||
|
||||
|
||||
it("should use jsonp if browser does not support cors", function() {
|
||||
$.support.cors = false;
|
||||
s = new cartodb.SQL({ user: 'jaja', ajax: ajax });
|
||||
expect(s.options.jsonp).toEqual(true);
|
||||
s.execute('select * from rambo', null, {
|
||||
dp: 2,
|
||||
jsonpCallback: 'test_callback',
|
||||
cache: false
|
||||
})
|
||||
expect(ajaxParams.dataType).toEqual('jsonp');
|
||||
expect(ajaxParams.crossDomain).toEqual(undefined);
|
||||
expect(ajaxParams.jsonp).toEqual(undefined);
|
||||
expect(ajaxParams.jsonpCallback).toEqual('test_callback');
|
||||
expect(ajaxParams.cache).toEqual(false);
|
||||
$.support.cors = true;
|
||||
});
|
||||
|
||||
it("should get bounds for query", function() {
|
||||
var sql = 'SELECT ST_XMin(ST_Extent(the_geom)) as minx,' +
|
||||
' ST_YMin(ST_Extent(the_geom)) as miny,'+
|
||||
' ST_XMax(ST_Extent(the_geom)) as maxx,' +
|
||||
' ST_YMax(ST_Extent(the_geom)) as maxy' +
|
||||
' from (select * from rambo where id=2) as subq';
|
||||
s = new cartodb.SQL({ user: 'jaja', ajax: ajax });
|
||||
s.getBounds('select * from rambo where id={{id}}', {id: 2});
|
||||
expect(ajaxParams.url.indexOf(encodeURIComponent(sql))).not.toEqual(-1);
|
||||
});
|
||||
|
||||
it("should get bounds for query with appostrophes", function() {
|
||||
s = new cartodb.SQL({ user: 'jaja', ajax: ajax });
|
||||
s.getBounds("select * from country where name={{ name }}", { name: "'Spain'"});
|
||||
expect(ajaxParams.url.indexOf("%26amp%3B%2339%3B")).toEqual(-1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('sql.table', function() {
|
||||
var USER = 'rambo';
|
||||
var sql;
|
||||
beforeEach(function() {
|
||||
ajaxParams = null;
|
||||
sql = new cartodb.SQL({
|
||||
user: USER,
|
||||
protocol: 'https'
|
||||
})
|
||||
});
|
||||
|
||||
it("sql", function() {
|
||||
var s = sql.table('test');
|
||||
expect(s.sql()).toEqual('select * from test');
|
||||
s.columns(['age', 'jeta'])
|
||||
expect(s.sql()).toEqual('select age,jeta from test');
|
||||
s.filter('age < 10')
|
||||
expect(s.sql()).toEqual('select age,jeta from test where age < 10');
|
||||
s.limit(15)
|
||||
expect(s.sql()).toEqual('select age,jeta from test where age < 10 limit 15');
|
||||
s.order_by('age')
|
||||
expect(s.sql()).toEqual('select age,jeta from test where age < 10 limit 15 order by age');
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
describe("column descriptions", function(){
|
||||
var USER = 'manolo';
|
||||
var sql;
|
||||
|
||||
beforeAll(function(){
|
||||
this.colDate = new Backbone.Model(JSON.parse('{"name":"object_postedtime","type":"date","geometry_type":"point","bbox":[[-28.92163128242129,-201.09375],[75.84516854027044,196.875]],"analyzed":true,"success":true,"stats":{"type":"date","start_time":"2015-02-19T15:13:16.000Z","end_time":"2015-02-22T04:34:05.000Z","range":220849000,"steps":1024,"null_ratio":0,"column":"object_postedtime"}}'));
|
||||
this.colFloat = new Backbone.Model(JSON.parse('{"name":"asdfd","type":"number","geometry_type":"point"}'));
|
||||
this.colString = new Backbone.Model(JSON.parse('{"name":"asdfd","type":"string","geometry_type":"point"}'));
|
||||
this.colGeom = new Backbone.Model(JSON.parse('{"name":"asdfd","type":"geometry","geometry_type":"point"}'));
|
||||
this.colBoolean = new Backbone.Model(JSON.parse('{"name":"asdfd","type":"boolean","geometry_type":"point"}'));
|
||||
this.query = "SELECT * FROM whatevs";
|
||||
sql = new cartodb.SQL({
|
||||
user: USER,
|
||||
protocol: 'https'
|
||||
});
|
||||
sql.execute = function(sql, callback){
|
||||
callback({});
|
||||
}
|
||||
});
|
||||
|
||||
it("should deduct correct describe method", function(){
|
||||
spyOn(sql, "describeDate");
|
||||
sql.describe(this.query, this.colDate, {type: this.colDate.get("type")}, function(){});
|
||||
expect(sql.describeDate).toHaveBeenCalled;
|
||||
|
||||
spyOn(sql, "describeFloat");
|
||||
sql.describe(this.query, this.colFloat, {type: this.colFloat.get("type")}, function(){});
|
||||
expect(sql.describeFloat).toHaveBeenCalled();
|
||||
|
||||
spyOn(sql, "describeString");
|
||||
sql.describe(this.query, this.colString, {type: this.colString.get("type")}, function(){});
|
||||
expect(sql.describeString).toHaveBeenCalled();
|
||||
|
||||
spyOn(sql, "describeGeom");
|
||||
sql.describe(this.query, this.colGeom, {type: this.colGeom.get("type")}, function(){});
|
||||
expect(sql.describeGeom).toHaveBeenCalled();
|
||||
|
||||
spyOn(sql, "describeBoolean");
|
||||
sql.describe(this.query, this.colBoolean, {type: this.colBoolean.get("type")}, function(){});
|
||||
expect(sql.describeBoolean).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe("string describer", function(){
|
||||
var description;
|
||||
beforeAll(function(done){
|
||||
sql.execute = function(sql, callback){
|
||||
var data = JSON.parse('{"rows":[{"uniq":462,"cnt":487,"null_count":1,"null_ratio":0.002053388090349076,"skew":0.043121149897330596,"array_agg":""}],"time":0.01,"fields":{"uniq":{"type":"number"},"cnt":{"type":"number"},"null_count":{"type":"number"},"null_ratio":{"type":"number"},"skew":{"type":"number"},"array_agg":{"type":"unknown(2287)"}},"total_rows":1}');
|
||||
callback(data);
|
||||
}
|
||||
var callback = function(stuff){
|
||||
description = stuff;
|
||||
done();
|
||||
}
|
||||
sql.describeString(sql, this.colString, callback); // THE COLS DON'T MATCH!!!
|
||||
});
|
||||
|
||||
it("should return correct properties", function(){
|
||||
expect(description.hist.constructor).toEqual(Array); // Right now it's an empty array because JSON.parse doesn't like our way of notating histograms
|
||||
expect(description.type).toEqual("string");
|
||||
expect(typeof description.null_count).toEqual("number");
|
||||
expect(typeof description.distinct).toEqual("number");
|
||||
expect(typeof description.null_ratio).toEqual("number");
|
||||
expect(typeof description.skew).toEqual("number");
|
||||
expect(typeof description.weight).toEqual("number");
|
||||
});
|
||||
});
|
||||
|
||||
describe("geometry describer", function(){
|
||||
var description;
|
||||
beforeAll(function(done){
|
||||
sql.execute = function(sql, callback){
|
||||
var data = {"rows":[{"bbox": '{"type":"Polygon","coordinates":[[[-179.9284,-65.2446],[-179.9284,81.8962],[179.9698,81.8962],[179.9698,-65.2446],[-179.9284,-65.2446]]]}',"geometry_type":"ST_Point","clusterrate":0.20359746623640493,"density":0.105333307745705}],"time":0.035,"fields":{"bbox":{"type":"string"},"geometry_type":{"type":"string"},"clusterrate":{"type":"number"},"density":{"type":"number"}},"total_rows":1};
|
||||
callback(data);
|
||||
}
|
||||
var callback = function(stuff){
|
||||
description = stuff;
|
||||
done();
|
||||
}
|
||||
sql.describeGeom(sql, this.colGeom, callback);
|
||||
});
|
||||
it("should return correct properties", function(){
|
||||
expect(description.type).toEqual("geom");
|
||||
expect(["ST_Point", "ST_Line", "ST_Polygon"].indexOf(description.geometry_type) > -1).toBe(true);
|
||||
expect(description.bbox.constructor).toEqual(Array);
|
||||
expect(typeof description.density).toEqual("number");
|
||||
expect(typeof description.cluster_rate).toEqual("number");
|
||||
})
|
||||
});
|
||||
|
||||
describe("number describer", function(){
|
||||
var description;
|
||||
beforeAll(function(done){
|
||||
sql.execute = function(sql, callback){
|
||||
var data = JSON.parse('{"rows":[{"hist":"{\\"(1,empty,69368)\\",\\"(25,empty,11063)\\"}","min":0,"max":4,"avg":0.3745819397993311,"cnt":89401,"uniq":5,"null_ratio":0,"stddev":0.000009057366328792043,"stddevmean":2.1617223091836313,"dist_type":"U","quantiles":[0,1,2,2,3,4,4],"equalint":[0,0,0,0,0,0,0],"jenks":[0,1,2,3,4],"headtails":[0,1,2,3,4],"cat_hist":"{\\"(1,empty,69368)\\",\\"(25,empty,11063)\\"}"}],"time":1.442,"fields":{"hist":{"type":"unknown(2287)"},"min":{"type":"number"},"max":{"type":"number"},"avg":{"type":"number"},"cnt":{"type":"number"},"uniq":{"type":"number"},"null_ratio":{"type":"number"},"stddev":{"type":"number"},"stddevmean":{"type":"number"},"dist_type":{"type":"string"},"quantiles":{"type":"number[]"},"equalint":{"type":"number[]"},"jenks":{"type":"number[]"},"headtails":{"type":"number[]"},"cat_hist":{"type":"unknown(2287)"}},"total_rows":1}');
|
||||
callback(data);
|
||||
}
|
||||
var callback = function(stuff){
|
||||
description = stuff;
|
||||
done();
|
||||
}
|
||||
sql.describeFloat(sql, this.colGeom, callback);
|
||||
});
|
||||
it("should return correct properties", function(){
|
||||
expect(description.type).toEqual("number");
|
||||
expect(["A", "U", "F", "J"].indexOf(description.dist_type) > -1).toBe(true);
|
||||
var numTypes = ["avg", "max", "min", "stddevmean", "weight", "stddev", "null_ratio", "count"];
|
||||
for(var i = 0; i < numTypes.length; i++){
|
||||
expect(typeof description[numTypes[i]]).toEqual("number");
|
||||
}
|
||||
var arrayTypes = ["quantiles", "equalint", "jenks", "headtails", "cat_hist", "hist"];
|
||||
for(var i = 0; i < arrayTypes.length; i++){
|
||||
expect(description[arrayTypes[i]].constructor).toEqual(Array);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
describe("boolean describer", function(){
|
||||
var description;
|
||||
beforeAll(function(done){
|
||||
sql.execute = function(sql, callback){
|
||||
var data = {"rows":[
|
||||
{"true_ratio":0.3377926421404682,"null_ratio":0,"uniq":2,"cnt":89401}
|
||||
],
|
||||
"time":0.251,
|
||||
"fields":{"true_ratio":{"type":"number"},"null_ratio":{"type":"number"},"uniq":{"type":"number"},"cnt":{"type":"number"}},
|
||||
"total_rows":1
|
||||
};
|
||||
callback(data);
|
||||
}
|
||||
var callback = function(stuff){
|
||||
description = stuff;
|
||||
done();
|
||||
}
|
||||
sql.describeBoolean(sql, this.colGeom, callback);
|
||||
});
|
||||
it("should return correct properties", function(){
|
||||
expect(description.type).toEqual("boolean");
|
||||
expect(typeof description.true_ratio).toEqual("number");
|
||||
expect(typeof description.distinct).toEqual("number");
|
||||
expect(typeof description.count).toEqual("number");
|
||||
expect(typeof description.null_ratio).toEqual("number");
|
||||
})
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
describe("config", function() {
|
||||
it("should contain links variables", function() {
|
||||
expect(cdb.config.get('cartodb_attributions')).toEqual("© <a href=\"https://carto.com/attributions\" target=\"_blank\">CARTO</a>");
|
||||
expect(cdb.config.get('cartodb_logo_link')).toEqual("http://www.carto.com");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,77 @@
|
||||
describe("decorators", function() {
|
||||
|
||||
describe("cbd.decorators.elder", function() {
|
||||
var getMocks = function() {
|
||||
this.plane = Backbone.Model.extend({
|
||||
speed: 0,
|
||||
heading: 12,
|
||||
accelerate: function() {this.speed += 10;},
|
||||
turn: function(direction) {
|
||||
if(direction === 'L') {
|
||||
this.heading === 1?
|
||||
this.heading = 12:
|
||||
this.heading--;
|
||||
} else {
|
||||
this.heading === 12?
|
||||
this.heading = 1:
|
||||
this.heading++;
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
this.spitfire = this.plane.extend({
|
||||
weapons: 2,
|
||||
turn: function(direction) {
|
||||
this.elder('turn', direction);
|
||||
this.elder('accelerate');
|
||||
},
|
||||
fire: function() {
|
||||
return 'ratatata x ' + this.weapons;
|
||||
}
|
||||
})
|
||||
|
||||
this.seafire = this.spitfire.extend({
|
||||
weapons: 4,
|
||||
accelerate: function() {
|
||||
this.elder('accelerate');
|
||||
this.speed += 2;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
cdb.decorators.elder(Backbone.Model);
|
||||
getMocks.apply(this);
|
||||
});
|
||||
|
||||
it("Should be able to add elder method ", function(done) {
|
||||
// If not, it fails running this test with PhantomJS :S
|
||||
setTimeout(function(){
|
||||
expect(Backbone.Model.prototype.elder).toBeTruthy();
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it("Should be able to call a method from a parent class", function() {
|
||||
var plane = new this.spitfire();
|
||||
plane.turn('L');
|
||||
expect(plane.heading).toEqual(11);
|
||||
expect(plane.speed).toEqual(10)
|
||||
});
|
||||
|
||||
it("Should be able to use parent using own properties without infinitelooping", function() {
|
||||
var plane = new this.seafire();
|
||||
var attack = plane.fire();
|
||||
expect(attack).toEqual('ratatata x 4');
|
||||
})
|
||||
|
||||
it("Should be able to use grandparent method when the parent is not defined", function(){
|
||||
var plane = new this.seafire();
|
||||
plane.accelerate();
|
||||
expect(plane.speed).toEqual(12);
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,594 @@
|
||||
describe("Image", function() {
|
||||
beforeEach(function() {
|
||||
var img = $('<img id="image" />');
|
||||
$("body").append(img);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
$("#image").remove();
|
||||
});
|
||||
|
||||
it("should allow to set the size", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var image = cartodb.Image(vizjson).size(640, 480);
|
||||
|
||||
image.getUrl(function() {
|
||||
expect(image.imageOptions["size"]).toEqual([640, 480]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should use the basemap defined in the vizjson", function(done) {
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/318ab654-c989-11e4-97c6-0e9d821ea90d/viz.json"
|
||||
var image = cartodb.Image(vizjson).size(640, 480);
|
||||
var basemapURLTemplate = 'https://{s}.base.maps.api.here.com/maptile/2.1/maptile/newest/normal.day/{z}/{x}/{y}/256/png8?lg=eng&token=A7tBPacePg9Mj_zghvKt9Q&app_id=KuYppsdXZznpffJsKT24';
|
||||
image.getUrl(function() {
|
||||
expect(image.imageOptions.basemap.options.urlTemplate).toEqual(basemapURLTemplate);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should generate the URL for a torque layer", function(done) {
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/3ec995a8-b6ae-11e4-849e-0e4fddd5de28/viz.json"
|
||||
|
||||
var image = cartodb.Image(vizjson);
|
||||
|
||||
var regexp = new RegExp("http://a.gusc.cartocdn.com/documentation/api/v1/map/static/bbox/(.*?)/-138\.6474609375,27\.761329874505233,-83\.408203125,51\.26191485308451/320/240\.pn");
|
||||
|
||||
image.getUrl(function(err, url) {
|
||||
expect(image.options.layers.layers.length).toEqual(2);
|
||||
expect(image.options.layers.layers[0].type).toEqual("http");
|
||||
expect(image.options.layers.layers[1].type).toEqual("torque");
|
||||
expect(url.match(regexp).length).toEqual(2);
|
||||
expect(url).toMatch(regexp);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should generate the right layer configuration for map with a layer of labels", function(done) {
|
||||
var oldLoaderGet = cdb.core.Loader.get;
|
||||
|
||||
var vizjson = {
|
||||
layers: [
|
||||
{
|
||||
type: 'tiled',
|
||||
options: {
|
||||
urlTemplate: 'urlTemplate'
|
||||
},
|
||||
visible: true
|
||||
},
|
||||
{
|
||||
type: 'tiled',
|
||||
options: {
|
||||
urlTemplate: 'urlTemplateLabels'
|
||||
},
|
||||
visible: true
|
||||
},
|
||||
{
|
||||
type: 'layergroup',
|
||||
options: {
|
||||
layer_definition: {
|
||||
layers: [{
|
||||
options: {},
|
||||
visible: true
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
center: "[52.5897007687178, 52.734375]",
|
||||
zoom: 2
|
||||
}
|
||||
cdb.core.Loader.get = function(a, callback) {
|
||||
callback(vizjson);
|
||||
}
|
||||
|
||||
var image = cartodb.Image("wadus.json");
|
||||
|
||||
image.getUrl(function(err, url) {
|
||||
expect(image.options.layers.layers.length).toEqual(3);
|
||||
expect(image.options.layers.layers[0].type).toEqual("http");
|
||||
expect(image.options.layers.layers[0].options.urlTemplate).toEqual("urlTemplate");
|
||||
expect(image.options.layers.layers[1].type).toEqual("cartodb");
|
||||
expect(image.options.layers.layers[2].type).toEqual("http");
|
||||
expect(image.options.layers.layers[2].options.urlTemplate).toEqual("urlTemplateLabels");
|
||||
done();
|
||||
});
|
||||
|
||||
cdb.core.Loader.get = oldLoaderGet;
|
||||
});
|
||||
|
||||
it("should generate the right layer configuration for a torque layer and a named map", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/e7b04b62-b901-11e4-b0d7-0e018d66dc29/viz.json";
|
||||
|
||||
var image = cartodb.Image(vizjson);
|
||||
|
||||
image.getUrl(function(err, url) {
|
||||
expect(image.options.layers.layers.length).toEqual(2);
|
||||
expect(image.options.layers.layers[0].type).toEqual("http");
|
||||
expect(image.options.layers.layers[1].type).toEqual("named");
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should generate the right layer configuration for a torque layer with a named map inside", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/6b447f26-c80b-11e4-8164-0e018d66dc29/viz.json";
|
||||
|
||||
var image = cartodb.Image(vizjson);
|
||||
|
||||
image.getUrl(function(err, url) {
|
||||
expect(image.options.layers.layers.length).toEqual(2);
|
||||
expect(image.options.layers.layers[0].type).toEqual("http");
|
||||
expect(image.options.layers.layers[1].type).toEqual("named");
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should allow to use a step for a torque layer", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/3ec995a8-b6ae-11e4-849e-0e4fddd5de28/viz.json"
|
||||
|
||||
var image = cartodb.Image(vizjson, { step: 10 });
|
||||
|
||||
var regexp = new RegExp("http://a.ashbu.cartocdn.com/documentation/api/v1/map/static/bbox/(.*?)/-138\.6474609375,27\.761329874505233,-83\.408203125,51\.26191485308451/320/240\.pn");
|
||||
|
||||
image.getUrl(function(err, url) {
|
||||
expect(image.options.userOptions.step).toEqual(10);
|
||||
expect(image.options.layers.layers[1].options.step).toEqual(10);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("shouldn't use hidden layers to generate the image", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/42e98b9a-bcce-11e4-9d68-0e9d821ea90d/viz.json";
|
||||
|
||||
var image = cartodb.Image(vizjson);
|
||||
|
||||
image.getUrl(function(err, url) {
|
||||
expect(image.options.layers.layers.length).toEqual(2);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should extract the cdn_url from the vizjson", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/e7b04b62-b901-11e4-b0d7-0e018d66dc29/viz.json";
|
||||
|
||||
var image = cartodb.Image(vizjson);
|
||||
|
||||
image.getUrl(function(err, url) {
|
||||
expect(image.options.cdn_url.http).toEqual("gusc.cartocdn.com");
|
||||
expect(image.options.cdn_url.https).toEqual("cartocdn-gusc.global.ssl.fastly.net");
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should allow to set the zoom", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var image = cartodb.Image(vizjson).zoom(4);
|
||||
|
||||
image.getUrl(function() {
|
||||
expect(image.imageOptions["zoom"]).toEqual(4);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should allow to set the center", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var image = cartodb.Image(vizjson).center([40, 30]);
|
||||
|
||||
image.getUrl(function() {
|
||||
expect(image.imageOptions["center"]).toEqual([40, 30]);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should allow to set the bounding box", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var regexp = new RegExp("http://a.gusc.cartocdn.com/documentation/api/v1/map/static/bbox/(.*?)/-31\.05,-155\.74,82\.58,261\.21/400/300\.png");
|
||||
|
||||
cartodb.Image(vizjson).bbox([-31.05, -155.74, 82.58, 261.21]).size(400,300).getUrl(function(error, url) {
|
||||
expect(error).toEqual(null);
|
||||
expect(url.match(regexp).length).toEqual(2);
|
||||
expect(url).toMatch(regexp);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should allow to override the bounding box", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var regexp = new RegExp("http://a.gusc.cartocdn.com/documentation/api/v1/map/static/center/(.*?)/52\.5897007687178/52\.734375/400/300\.png");
|
||||
|
||||
cartodb.Image(vizjson, { override_bbox: true }).size(400,300).getUrl(function(error, url) {
|
||||
expect(error).toEqual(null);
|
||||
expect(url.match(regexp).length).toEqual(2);
|
||||
expect(url).toMatch(regexp);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("shouldn't generate a bbox URL without a bouding box", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var regexp = new RegExp("http://a.gusc.cartocdn.com/documentation/api/v1/map/static/center/(.*?)/52\.5897007687178/52\.734375/400/300\.png");
|
||||
|
||||
cartodb.Image(vizjson).bbox([]).size(400,300).getUrl(function(error, url) {
|
||||
expect(error).toEqual(null);
|
||||
expect(url.match(regexp).length).toEqual(2);
|
||||
expect(url).toMatch(regexp);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should use the zoom defined in the vizjson", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var image = cartodb.Image(vizjson);
|
||||
|
||||
var regexp = new RegExp("http://a.gusc.cartocdn.com/documentation/api/v1/map/static/center/(.*?)/2/40/10/320/240\.png");
|
||||
|
||||
image.center([40,10]).getUrl(function(err, url) {
|
||||
expect(image.imageOptions.zoom).toEqual(2);
|
||||
expect(url.match(regexp).length).toEqual(2);
|
||||
expect(url).toMatch(regexp);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should allow to set the format", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var image = cartodb.Image(vizjson).format("jpg");
|
||||
|
||||
image.getUrl(function() {
|
||||
expect(image.imageOptions["format"]).toEqual("jpg");
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("shouldn't allow to set an invalid format", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var image = cartodb.Image(vizjson).format("pin");
|
||||
|
||||
image.getUrl(function() {
|
||||
expect(image.imageOptions["format"]).toEqual("png");
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should generate the image URL", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var regexp = new RegExp("http://a.gusc.cartocdn.com/documentation/api/v1/map/static/bbox/(.*?)320/240\.png");
|
||||
|
||||
cartodb.Image(vizjson).getUrl(function(error, url) {
|
||||
expect(error).toEqual(null);
|
||||
expect(url.match(regexp).length).toEqual(2);
|
||||
expect(url).toMatch(regexp);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should generate the image URL using custom params", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var regexp = new RegExp("http://a.gusc.cartocdn.com/documentation/api/v1/map/static/center/(.*?)/7/40/10/400/300\.png");
|
||||
|
||||
cartodb.Image(vizjson).center([40, 10]).zoom(7).size(400, 300).getUrl(function(error, url) {
|
||||
expect(error).toEqual(null);
|
||||
expect(url.match(regexp).length).toEqual(2);
|
||||
expect(url).toMatch(regexp);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should generate the image inside of an image element", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var img = document.getElementById('image');
|
||||
|
||||
cartodb.Image(vizjson).center([40, 10]).zoom(7).size(400, 300).into(img);
|
||||
|
||||
var regexp = new RegExp("http://a.gusc.cartocdn.com/documentation/api/v1/map/static/center/(.*?)/7/40/10/400/300\.png");
|
||||
|
||||
setTimeout(function() {
|
||||
expect($("#image").attr("src")).toMatch(regexp);
|
||||
done();
|
||||
}, 800);
|
||||
|
||||
});
|
||||
|
||||
it("should generate an image using a layer definition", function(done) {
|
||||
|
||||
var layer_definition = {
|
||||
user_name: "documentation",
|
||||
tiler_domain: "carto.com",
|
||||
tiler_port: "80",
|
||||
tiler_protocol: "http",
|
||||
layers: [{
|
||||
type: "http",
|
||||
options: {
|
||||
urlTemplate: "http://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
|
||||
subdomains: [ "a", "b", "c" ]
|
||||
}
|
||||
}, {
|
||||
type: "cartodb",
|
||||
options: {
|
||||
sql: "SELECT * FROM nyc_wifi",
|
||||
cartocss: "#ncy_wifi{ marker-fill-opacity: 0.8; marker-line-color: #FFFFFF; marker-line-width: 3; marker-line-opacity: .8; marker-placement: point; marker-type: ellipse; marker-width: 16; marker-fill: #6ac41c; marker-allow-overlap: true; }",
|
||||
cartocss_version: "2.1.1"
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
var regexp = new RegExp("http://a.gusc.cartocdn.com/documentation/api/v1/map/static/center/(.*?)/2/0/0/250/250\.png");
|
||||
|
||||
cartodb.Image(layer_definition).size(250, 250).zoom(2).getUrl(function(error, url) {
|
||||
expect(url.match(regexp).length).toEqual(2);
|
||||
expect(url).toMatch(regexp);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should use maps_api_template when provided", function() {
|
||||
var layer_definition = {
|
||||
user_name: "documentation",
|
||||
maps_api_template: 'https://carto.com/user/{user}/api/v1/maps',
|
||||
tiler_domain: "carto.com",
|
||||
tiler_port: "80",
|
||||
tiler_protocol: "http",
|
||||
layers: [{
|
||||
type: "http",
|
||||
options: {
|
||||
urlTemplate: "http://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
|
||||
subdomains: [ "a", "b", "c" ]
|
||||
}
|
||||
}, {
|
||||
type: "cartodb",
|
||||
options: {
|
||||
sql: "SELECT * FROM nyc_wifi",
|
||||
cartocss: "#ncy_wifi{ marker-fill-opacity: 0.8; marker-line-color: #FFFFFF; marker-line-width: 3; marker-line-opacity: .8; marker-placement: point; marker-type: ellipse; marker-width: 16; marker-fill: #6ac41c; marker-allow-overlap: true; }",
|
||||
cartocss_version: "2.1.1"
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
expect(cartodb.Image(layer_definition)._tilerHost()).toEqual(
|
||||
'https://carto.com/user/documentation/api/v1/maps'
|
||||
);
|
||||
});
|
||||
|
||||
it("should generate an image using a layer definition for a plain color", function(done) {
|
||||
|
||||
var layer_definition = {
|
||||
user_name: "documentation",
|
||||
tiler_domain: "carto.com",
|
||||
tiler_port: "80",
|
||||
tiler_protocol: "http",
|
||||
layers: [{
|
||||
type: "plain",
|
||||
options: {
|
||||
color: "lightblue"
|
||||
}
|
||||
}, {
|
||||
type: "cartodb",
|
||||
options: {
|
||||
sql: "SELECT * FROM nyc_wifi",
|
||||
cartocss: "#ncy_wifi{ marker-fill-opacity: 0.8; marker-line-color: #FFFFFF; marker-line-width: 3; marker-line-opacity: .8; marker-placement: point; marker-type: ellipse; marker-width: 16; marker-fill: #6ac41c; marker-allow-overlap: true; }",
|
||||
cartocss_version: "2.1.1"
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
var regexp = new RegExp("http://a.gusc.cartocdn.com/documentation/api/v1/map/static/center/(.*?)/2/0/0/250/250\.png");
|
||||
|
||||
cartodb.Image(layer_definition).size(250, 250).zoom(2).getUrl(function(error, url) {
|
||||
expect(url.match(regexp).length).toEqual(2);
|
||||
expect(url).toMatch(regexp);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should set the protocol and port depending on the URL (https)", function(done) {
|
||||
|
||||
var vizjson = "https://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var image = cartodb.Image(vizjson).size(400, 300);
|
||||
|
||||
var regexp = new RegExp("https://cartocdn-gusc.global.ssl.fastly.net/documentation/api/v1/map/static/bbox/(.*?)400/300\.png");
|
||||
|
||||
image.getUrl(function(err, url) {
|
||||
expect(url.match(regexp).length).toEqual(2);
|
||||
expect(url).toMatch(regexp);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should set the protocol and port depending on the URL (http)", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var image = cartodb.Image(vizjson).size(400, 300);
|
||||
|
||||
var regexp = new RegExp("http://a.gusc.cartocdn.com/documentation/api/v1/map/static/bbox/(.*?)400/300\.png");
|
||||
|
||||
image.getUrl(function(err, url) {
|
||||
expect(url.match(regexp).length).toEqual(2);
|
||||
expect(url).toMatch(regexp);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should set the protocol and port depending on the URL (http, no_cdn)", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/2b13c956-e7c1-11e2-806b-5404a6a683d5/viz.json"
|
||||
|
||||
var image = cartodb.Image(vizjson, { no_cdn: true }).size(400, 300);
|
||||
|
||||
var regexp = new RegExp("http://documentation.carto.com:80/api/v1/map/static/bbox/(.*?)400/300\.png");
|
||||
|
||||
image.getUrl(function(err, url) {
|
||||
expect(url.match(regexp).length).toEqual(2);
|
||||
expect(url).toMatch(regexp);
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("shouldn't send the urlTemplate if the vizjson doesn't contain it", function(done) {
|
||||
|
||||
var vizjson = "https://documentation.carto.com/api/v2/viz/75b90cd6-e9cf-11e2-8be0-5404a6a683d5/viz.json"
|
||||
|
||||
var image = cartodb.Image(vizjson).size(400, 300);
|
||||
|
||||
image.getUrl(function(err, url) {
|
||||
expect(image.options.layers.layers.length).toEqual(1);
|
||||
expect(image.options.layers.layers[0].type).toEqual("cartodb");
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should send the auth_tokens", function(done) {
|
||||
|
||||
var vizjson = "http://documentation.carto.com/api/v2/viz/e11db0aa-d77e-11e4-9039-0e853d047bba/viz.json"
|
||||
var json = {"id":"e11db0aa-d77e-11e4-9039-0e853d047bba","version":"0.1.0","title":"password_protected_map","likes":0,"description":null,"scrollwheel":false,"legends":true,"url":null,"map_provider":"leaflet","bounds":[[0.0,0.0],[0.0,0.0]],"center":"[30, 0]","zoom":3,"updated_at":"2015-03-31T08:21:18+00:00","layers":[{"options":{"visible":true,"type":"Tiled","urlTemplate":"http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png","subdomains":"1234","name":"Positron","className":"positron_rainbow","attribution":"\u00a9 <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors \u00a9 <a href=\"https://carto.com/attributions\">CartoDB</a>"},"infowindow":null,"tooltip":null,"id":"c850d654-ab61-441d-9860-b3c2e42424fb","order":0,"parent_id":null,"children":[],"type":"tiled"},{"type":"namedmap","order":1,"options":{"type":"namedmap","user_name":"documentation","tiler_protocol":"https","tiler_domain":"carto.com","tiler_port":"443","cdn_url":{"http":"api.cartocdn.com","https":"cartocdn.global.ssl.fastly.net"},"dynamic_cdn":false,"named_map":{"name":"tpl_e11db0aa_d77e_11e4_9039_0e853d047bba","stat_tag":"e11db0aa-d77e-11e4-9039-0e853d047bba","params":{"layer0":1},"layers":[{"layer_name":"untitled_table_5","interactivity":"cartodb_id","visible":true}]}}}],"overlays":[{"type":"logo","order":9,"options":{"display":true,"x":10,"y":40},"template":""},{"type":"loader","order":8,"options":{"display":true,"x":20,"y":150},"template":"<div class=\"loader\" original-title=\"\"></div>"},{"type":"zoom","order":6,"options":{"display":true,"x":20,"y":20},"template":"<a href=\"#zoom_in\" class=\"zoom_in\">+</a> <a href=\"#zoom_out\" class=\"zoom_out\">-</a>"},{"type":"search","order":3,"options":{"display":true,"x":60,"y":20},"template":""},{"type":"share","order":2,"options":{"display":true,"x":20,"y":20},"template":""}],"prev":null,"next":null,"transition_options":{"time":0}};
|
||||
|
||||
StaticImage.prototype.load = function(vizjson, options) {
|
||||
|
||||
this.queue = new Queue;
|
||||
|
||||
this.no_cdn = options.no_cdn;
|
||||
|
||||
this.auth_tokens = options.auth_tokens;
|
||||
|
||||
this.userOptions = options;
|
||||
|
||||
options = _.defaults({ vizjson: vizjson, temp_id: "s" + this._getUUID() }, this.defaults);
|
||||
|
||||
this.imageOptions = options;
|
||||
|
||||
this._onVisLoaded(json); // do the callback
|
||||
|
||||
};
|
||||
|
||||
var options = { auth_tokens: ["e900fe76cc3c1eed4fc018d027d82c8b0e59b2c484d1941954f34b4818a5d660"] };
|
||||
var image = cartodb.Image(vizjson, options).size(400, 300);
|
||||
|
||||
image.getUrl(function(err, url) {
|
||||
expect(image.options.layers.layers[1].options.auth_tokens.length > 0).toBe(true);
|
||||
expect(image.options.layers.layers[1].options.auth_tokens[0]).toBe("e900fe76cc3c1eed4fc018d027d82c8b0e59b2c484d1941954f34b4818a5d660");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should generate an image using a layer definition in a certain bbox", function(done) {
|
||||
jasmine.clock().install();
|
||||
var ajax = $.ajax;
|
||||
spyOn($, 'ajax');
|
||||
|
||||
var fakeServerResponse = {
|
||||
'layergroupid': '5e59b997e678d51096c9037faf9a84b7:1398886221740',
|
||||
'metadata': {
|
||||
'layers': [
|
||||
{
|
||||
'type': 'plain',
|
||||
'id': 'plain-layer0',
|
||||
'meta': {
|
||||
'stats': []
|
||||
}
|
||||
},
|
||||
{
|
||||
'type': 'mapnik',
|
||||
'id': 'layer0',
|
||||
'meta': {
|
||||
'stats': [],
|
||||
'cartocss': '#ncy_wifi{ marker-fill-opacity: 0.8; marker-line-color: #FFFFFF; marker-line-width: 3; marker-line-opacity: .8; marker-placement: point; marker-type: ellipse; marker-width: 16; marker-fill: #6ac41c; marker-allow-overlap: true; }'
|
||||
}
|
||||
}
|
||||
],
|
||||
'dataviews': {},
|
||||
'analyses': []
|
||||
},
|
||||
'cdn_url': {
|
||||
'http': 'ashbu.cartocdn.com',
|
||||
'https': 'cartocdn-ashbu.global.ssl.fastly.net'
|
||||
},
|
||||
'last_updated': '2014-04-30T19:30:21.740Z'
|
||||
};
|
||||
|
||||
var layer_definition = {
|
||||
user_name: "documentation",
|
||||
tiler_domain: "carto.com",
|
||||
tiler_port: "80",
|
||||
tiler_protocol: "http",
|
||||
layers: [{
|
||||
type: "http",
|
||||
options: {
|
||||
urlTemplate: "http://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
|
||||
subdomains: [ "a", "b", "c" ]
|
||||
}
|
||||
}, {
|
||||
type: "cartodb",
|
||||
options: {
|
||||
sql: "SELECT * FROM nyc_wifi",
|
||||
cartocss: "#ncy_wifi{ marker-fill-opacity: 0.8; marker-line-color: #FFFFFF; marker-line-width: 3; marker-line-opacity: .8; marker-placement: point; marker-type: ellipse; marker-width: 16; marker-fill: #6ac41c; marker-allow-overlap: true; }",
|
||||
cartocss_version: "2.1.1"
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
cartodb.Image(layer_definition).size(250, 250).bbox([[-87.82814025878906,41.88719899247721], [ -27.5936508178711,41.942765696654604]]).getUrl(function (error, url) {
|
||||
expect(url).toEqual('http://a.ashbu.cartocdn.com/documentation/api/v1/map/static/bbox/5e59b997e678d51096c9037faf9a84b7:1398886221740/-87.82814025878906,41.88719899247721,-27.5936508178711,41.942765696654604/250/250.png');
|
||||
done();
|
||||
});
|
||||
|
||||
// Wait for a timeout
|
||||
jasmine.clock().tick(101);
|
||||
|
||||
$.ajax.calls.argsFor(0)[0].success(fakeServerResponse);
|
||||
jasmine.clock().uninstall();
|
||||
$.ajax = ajax;
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
describe("log", function() {
|
||||
|
||||
it("should exist a global log", function() {
|
||||
expect(cdb.log).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should exist a global errorlist", function() {
|
||||
expect(cdb.errors).toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
describe("Log", function() {
|
||||
|
||||
it("should has error, log and debug", function() {
|
||||
var log = new cdb.core.Log({tag: 'test'});
|
||||
expect(log.error).toBeTruthy();
|
||||
expect(log.debug).toBeTruthy();
|
||||
expect(log.log).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should generate error when error is called", function() {
|
||||
cdb.config.ERROR_TRACK_ENABLED = true
|
||||
cdb.errors.reset([]);
|
||||
var log = new cdb.core.Log({tag: 'test'});
|
||||
log.error('this is an error');
|
||||
expect(cdb.errors.size()).toEqual(1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Error", function() {
|
||||
it("should set a browser info when created", function() {
|
||||
var err = new cdb.core.Error({});
|
||||
expect(err.get('browser')).toEqual(JSON.stringify($.browser));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,164 @@
|
||||
|
||||
describe("core.Model", function() {
|
||||
|
||||
var TestModel = cdb.core.Model.extend({
|
||||
url: 'irrelevant.json',
|
||||
initialize: function() {
|
||||
this.initCalled = true;
|
||||
this.elder('initialize');
|
||||
},
|
||||
save: function() {
|
||||
this.saveCalled = true;
|
||||
this.elder('save');
|
||||
},
|
||||
fetch: function() {
|
||||
this.fetchCalled = true;
|
||||
this.elder('fetch');
|
||||
},
|
||||
test_method: function() {}
|
||||
});
|
||||
|
||||
var model;
|
||||
|
||||
beforeEach(function() {
|
||||
this.server = sinon.fakeServer.create();
|
||||
this.server.respondWith("GET", "irrelevant.json",
|
||||
[200, { "Content-Type": "application/json" },
|
||||
'{ "response": true }']);
|
||||
this.server.respondWith("GET", "irrelevantError.json",
|
||||
[500, { "Content-Type": "application/json" },
|
||||
'{ "response": false }']);
|
||||
this.server.respondWith("POST", "irrelevant.json",
|
||||
[200, { "Content-Type": "application/json" },
|
||||
'{ "response": true }']);
|
||||
this.server.respondWith("POST", "irrelevantError.json",
|
||||
[500, { "Content-Type": "application/json" },
|
||||
'{ "response": false }']);
|
||||
var requests = this.requests = [];
|
||||
sinon.spy(cdb.core.Model.prototype, "initialize");
|
||||
model = new TestModel();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
this.server.restore();
|
||||
cdb.core.Model.prototype.initialize.restore();
|
||||
})
|
||||
|
||||
it("should call initialize", function() {
|
||||
expect(model.initCalled).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should call cdb.core.Model initialize method too", function() {
|
||||
expect(cdb.core.Model.prototype.initialize.calledOnce).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should attach save to the element context", function() {
|
||||
model.bind('irrelevantEvent', model.save);
|
||||
model.trigger('irrelevantEvent');
|
||||
expect(model.saveCalled).toBeTruthy;
|
||||
})
|
||||
|
||||
it("should attach fetch to the element context", function() {
|
||||
model.bind('irrelevantEvent', model.fetch);
|
||||
model.trigger('irrelevantEvent');
|
||||
expect(model.fetchCalled).toBeTruthy;
|
||||
})
|
||||
|
||||
it("should add the correct response from server", function() {
|
||||
model.sync = function(method, model, options) {
|
||||
options.success({ "response": true });
|
||||
}
|
||||
model.fetch();
|
||||
this.server.respond();
|
||||
expect(model.get('response')).toBeTruthy();
|
||||
})
|
||||
|
||||
it("should trigger 'loadModelStarted' event when fetch", function() {
|
||||
var triggered = false;
|
||||
model.bind('loadModelStarted', function() {
|
||||
triggered = true;
|
||||
})
|
||||
model.fetch();
|
||||
expect(triggered).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should trigger 'loadModelCompleted' event when fetched", function() {
|
||||
var triggered = false;
|
||||
model.sync = function(method, model, options) {
|
||||
var dfd = $.Deferred();
|
||||
options.success({ "response": true });
|
||||
dfd.resolve();
|
||||
return dfd.promise();
|
||||
}
|
||||
model.bind('loadModelCompleted', function() {
|
||||
triggered = true;
|
||||
})
|
||||
model.fetch();
|
||||
this.server.respond();
|
||||
expect(triggered).toBeTruthy();
|
||||
})
|
||||
|
||||
it("should trigger 'loadModelFailed' event when fetch fails", function() {
|
||||
var triggered = false;
|
||||
model.url = 'irrelevantError.json'
|
||||
model.bind('loadModelFailed', function() {
|
||||
triggered = true;
|
||||
})
|
||||
model.fetch();
|
||||
this.server.respond();
|
||||
expect(triggered).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should retrigger an event when launched on a descendant object", function(done) {
|
||||
var launched = false;
|
||||
model.child = new TestModel({});
|
||||
model.retrigger('cachopo', model.child);
|
||||
model.bind('cachopo', function() {
|
||||
launched = true;
|
||||
}),
|
||||
model.child.trigger('cachopo');
|
||||
setTimeout(function(){
|
||||
expect(launched).toBeTruthy();
|
||||
done();
|
||||
}, 25);
|
||||
});
|
||||
|
||||
it("should trigger 'saving' event when save", function() {
|
||||
var triggered = false;
|
||||
model.bind('saving', function() {
|
||||
triggered = true;
|
||||
})
|
||||
model.save();
|
||||
expect(triggered).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should trigger 'saved' event when saved", function() {
|
||||
var triggered = false;
|
||||
model.sync = function(method, model, options) {
|
||||
var dfd = $.Deferred();
|
||||
options.success({ "response": true });
|
||||
dfd.resolve();
|
||||
return dfd.promise();
|
||||
}
|
||||
model.bind('saved', function() {
|
||||
triggered = true;
|
||||
})
|
||||
model.save();
|
||||
this.server.respond();
|
||||
expect(triggered).toBeTruthy();
|
||||
})
|
||||
|
||||
it("should trigger 'errorSaving' event when save fails", function() {
|
||||
var triggered = false;
|
||||
model.url = 'irrelevantError.json'
|
||||
model.bind('errorSaving', function() {
|
||||
triggered = true;
|
||||
})
|
||||
model.save();
|
||||
this.server.respond();
|
||||
expect(triggered).toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
@@ -0,0 +1,84 @@
|
||||
describe("core.core.sanitize", function() {
|
||||
|
||||
describe('.html', function() {
|
||||
|
||||
describe('when given a HTML', function() {
|
||||
|
||||
it('should allow safe HTML', function() {
|
||||
expect(cdb.core.sanitize.html('test')).toEqual('test');
|
||||
expect(cdb.core.sanitize.html('<div>works</div>')).toEqual('<div>works</div>');
|
||||
});
|
||||
|
||||
it('should remove unsafe stuff', function() {
|
||||
expect(cdb.core.sanitize.html('<img src="fail.png" onerror="document.body.appendChild(document.createElement(\'script\')).src=\'http://localhost/xss.js\'" /> nono')).toEqual('<img src="fail.png"> nono');
|
||||
expect(cdb.core.sanitize.html('nono <scrip src="ext.js"></script>')).toEqual('nono ');
|
||||
});
|
||||
|
||||
it('should allow target attributes for links', function() {
|
||||
expect(cdb.core.sanitize.html('<a href="https://carto.com/" target="_blank">carto.com</a>')).toEqual('<a href="https://carto.com/" target="_blank">carto.com</a>');
|
||||
});
|
||||
|
||||
it('should remove iframe tag', function() {
|
||||
expect(cdb.core.sanitize.html('no <iframe src="" onload="document.body.appendChild(document.createElement(\'script\')).src=\'http://localhost/xss.js\'"/> no')).toEqual('no ');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when given an 2nd param with a function', function() {
|
||||
beforeEach(function() {
|
||||
this.optionalSanitizer = jasmine.createSpy('optionalSanitizer').and.returnValue('optional sanitizer result');
|
||||
});
|
||||
|
||||
it('should use that to sanitize instead', function() {
|
||||
expect(cdb.core.sanitize.html('<p>something</p>', this.optionalSanitizer)).toEqual('optional sanitizer result');
|
||||
expect(this.optionalSanitizer).toHaveBeenCalled();
|
||||
expect(this.optionalSanitizer).toHaveBeenCalledWith('<p>something</p>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when given a 2nd param with a non-undefined/function value', function() {
|
||||
it('should skip sanitize', function() {
|
||||
expect(cdb.core.sanitize.html('<script src="i-know-what-im-doing.js"></script>', false)).toEqual('<script src="i-know-what-im-doing.js"></script>');
|
||||
expect(cdb.core.sanitize.html('<script src="i-know-what-im-doing.js"></script>', null)).toEqual('<script src="i-know-what-im-doing.js"></script>');
|
||||
});
|
||||
});
|
||||
|
||||
describe('common XSS attacks', function() {
|
||||
|
||||
var attacks = [
|
||||
'<iframe><iframe src="/>"><p <a><img/src="x"/onerror="prompt(document.cookie)">',
|
||||
"<iframe srcdoc='<svg/onload=alert(document.cookie)>'>",
|
||||
"<img src=x onerror=alert(/XSS/)>",
|
||||
"<iframe src=j
	a
		v
			a
				s
					c
						r
							i
								p
									t
										:a
											l
												e
													r
														t
															%28
																1
																	%29></iframe>",
|
||||
'"><img src="C" onerror=alert(1)>',
|
||||
'"><img src="C" onerror=alert(document.cookie)>'
|
||||
];
|
||||
|
||||
it('should avoid `' + attacks[0] + '`', function() {
|
||||
expect(cdb.core.sanitize.html(attacks[0])).toEqual('');
|
||||
});
|
||||
|
||||
it('should avoid `' + attacks[1] + '`', function() {
|
||||
expect(cdb.core.sanitize.html(attacks[1])).toEqual('');
|
||||
});
|
||||
|
||||
it('should avoid `' + attacks[2] + '`', function() {
|
||||
expect(cdb.core.sanitize.html(attacks[2])).toEqual('<img src="x">');
|
||||
});
|
||||
|
||||
it('should avoid `' + attacks[3] + '`', function() {
|
||||
expect(cdb.core.sanitize.html(attacks[3])).toEqual('');
|
||||
});
|
||||
|
||||
it('should avoid `' + attacks[4] + '`', function() {
|
||||
expect(cdb.core.sanitize.html(attacks[4])).toEqual('"><img src="C">');
|
||||
});
|
||||
|
||||
it('should avoid `' + attacks[5] + '`', function() {
|
||||
expect(cdb.core.sanitize.html(attacks[5])).toEqual('"><img src="C">');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,50 @@
|
||||
describe("core.template", function() {
|
||||
|
||||
describe("cbd.core.Template", function() {
|
||||
var tmpl;
|
||||
beforeEach(function() {
|
||||
tmpl = new cdb.core.Template({
|
||||
template: "hi, my name is <%= name %>"
|
||||
});
|
||||
});
|
||||
|
||||
it("should render", function() {
|
||||
expect(tmpl.render({name: 'rambo'})).toEqual("hi, my name is rambo");
|
||||
});
|
||||
|
||||
it("should accept compiled templates", function() {
|
||||
tmpl = new cdb.core.Template({
|
||||
compiled: function(vars) { return 'hola ' + vars.name; }
|
||||
});
|
||||
expect(tmpl.render({name: 'rambo'})).toEqual("hola rambo");
|
||||
});
|
||||
|
||||
it("should render using mustache", function() {
|
||||
tmpl = new cdb.core.Template({
|
||||
template: "hi, my name is {{ name }}",
|
||||
type: 'mustache'
|
||||
});
|
||||
|
||||
expect(tmpl.render({name: 'rambo'})).toEqual("hi, my name is rambo");
|
||||
});
|
||||
});
|
||||
|
||||
describe("cbd.core.TemplateList", function() {
|
||||
var tmpl;
|
||||
beforeEach(function() {
|
||||
tmpl = new cdb.core.TemplateList();
|
||||
tmpl.reset([
|
||||
{name: 't1', template: "hi, my name is <%= name %>"},
|
||||
{name: 't2', template: "byee!! <%= name %>"}
|
||||
]);
|
||||
});
|
||||
|
||||
it("should get template by name", function() {
|
||||
expect(tmpl.getTemplate('t1')).toBeTruthy();
|
||||
expect(tmpl.getTemplate('t2')({name:'rambo'})).toEqual('byee!! rambo');
|
||||
expect(tmpl.getTemplate('nononon')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
describe("util", function() {
|
||||
it("should identify user agents properly", function() {
|
||||
var browser, ua;
|
||||
ua = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36";
|
||||
browser = cdb.core.util._inferBrowser(ua);
|
||||
expect(typeof browser.chrome).not.toEqual("undefined");
|
||||
|
||||
ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A";
|
||||
browser = cdb.core.util._inferBrowser(ua);
|
||||
expect(typeof browser.safari).not.toEqual("undefined");
|
||||
|
||||
ua = "Opera/9.80 (X11; Linux i686; Ubuntu/14.10) Presto/2.12.388 Version/12.16";
|
||||
browser = cdb.core.util._inferBrowser(ua);
|
||||
expect(typeof browser.opera).not.toEqual("undefined");
|
||||
|
||||
ua = "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko";
|
||||
browser = cdb.core.util._inferBrowser(ua);
|
||||
expect(typeof browser.ie).not.toEqual("undefined");
|
||||
|
||||
ua = "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0";
|
||||
browser = cdb.core.util._inferBrowser(ua);
|
||||
expect(typeof browser.firefox).not.toEqual("undefined");
|
||||
|
||||
ua = "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10136"
|
||||
browser = cdb.core.util._inferBrowser(ua);
|
||||
expect(typeof browser.edge).not.toEqual("undefined");
|
||||
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,163 @@
|
||||
|
||||
describe("core.view", function() {
|
||||
|
||||
var TestView = cdb.core.View.extend({
|
||||
initialize: function() {
|
||||
this.init_called = true;
|
||||
},
|
||||
test_method: function() {}
|
||||
});
|
||||
|
||||
var view;
|
||||
|
||||
beforeEach(function() {
|
||||
cdb.core.View.viewCount = 0;
|
||||
view = new TestView({ el: $('<div>')});
|
||||
|
||||
});
|
||||
|
||||
it("should call initialize", function() {
|
||||
expect(view.init_called).toEqual(true);
|
||||
});
|
||||
|
||||
it("should increment refCount", function() {
|
||||
expect(cdb.core.View.viewCount).toEqual(1);
|
||||
expect(cdb.core.View.views[view.cid]).toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
it("should decrement refCount", function() {
|
||||
view.clean();
|
||||
expect(cdb.core.View.viewCount).toEqual(0);
|
||||
expect(cdb.core.View.views[view.cid]).toBeFalsy();
|
||||
});
|
||||
|
||||
it("clean should remove view from dom", function() {
|
||||
var dom = $('<div>');
|
||||
dom.append(view.el);
|
||||
expect(dom.children().length).toEqual(1);
|
||||
view.clean();
|
||||
expect(dom.children().length).toEqual(0);
|
||||
});
|
||||
|
||||
it("clean should unbind all events", function() {
|
||||
view.bind('meh', function(){});
|
||||
expect(_.size(view._callbacks)).toEqual(1);
|
||||
view.clean();
|
||||
expect(view._callbacks).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should unlink the view model", function() {
|
||||
var called = false;
|
||||
var new_view = new TestView({ el: $('<div>'), model: new Backbone.Model() });
|
||||
|
||||
spyOn(new_view, 'test_method');
|
||||
new_view.model.bind('change', new_view.test_method, new_view);
|
||||
new_view.model.bind('change', function() { called= true;});
|
||||
|
||||
new_view.model.trigger('change');
|
||||
expect(called).toEqual(true);
|
||||
expect(new_view.test_method).toHaveBeenCalled();
|
||||
expect(new_view.test_method.calls.count()).toEqual(1);
|
||||
called = false;
|
||||
new_view.clean();
|
||||
//trigger again
|
||||
new_view.model.trigger('change');
|
||||
expect(called).toEqual(true);
|
||||
expect(new_view.test_method.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it("should unlink linked models", function() {
|
||||
var called = false;
|
||||
var model = new Backbone.Model();
|
||||
spyOn(view, 'test_method');
|
||||
model.bind('change', view.test_method, view);
|
||||
model.bind('change', function() { called= true;});
|
||||
view.add_related_model(model);
|
||||
|
||||
model.trigger('change');
|
||||
expect(called).toEqual(true);
|
||||
expect(view.test_method).toHaveBeenCalled();
|
||||
expect(view.test_method.calls.count()).toEqual(1);
|
||||
called = false;
|
||||
view.clean();
|
||||
expect(_.size(view._models)).toEqual(0);
|
||||
//trigger again
|
||||
model.trigger('change');
|
||||
expect(called).toEqual(true);
|
||||
expect(view.test_method.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it("should add and remove subview", function() {
|
||||
var v1 = new cdb.core.View();
|
||||
view.addView(v1);
|
||||
expect(view._subviews[v1.cid]).toEqual(v1);
|
||||
expect(v1._parent).toEqual(view);
|
||||
view.removeView(v1);
|
||||
expect(view._subviews[v1.cid]).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should remove and clean subviews", function() {
|
||||
var v1 = new cdb.core.View();
|
||||
spyOn(v1, 'clean');
|
||||
view.addView(v1);
|
||||
expect(view._subviews[v1.cid]).toEqual(v1);
|
||||
view.clean();
|
||||
expect(view._subviews[v1.cid]).toEqual(undefined);
|
||||
expect(v1.clean).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("subview shuould be removed from its parent", function() {
|
||||
var v1 = new cdb.core.View();
|
||||
view.addView(v1);
|
||||
expect(view._subviews[v1.cid]).toEqual(v1);
|
||||
v1.clean();
|
||||
expect(view._subviews[v1.cid]).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("extendEvents should extend events", function() {
|
||||
var V1 = cdb.core.View.extend({
|
||||
events: cdb.core.View.extendEvents({
|
||||
'click': 'hide'
|
||||
})
|
||||
});
|
||||
var v1 = new V1();
|
||||
expect(v1.el.style.display).not.toEqual('none');
|
||||
v1.$el.trigger('click');
|
||||
expect(v1.el.style.display).toEqual('none');
|
||||
});
|
||||
|
||||
it("should retrigger an event when launched on a descendant object", function(done) {
|
||||
var launched = false;
|
||||
view.child = new TestView({});
|
||||
view.retrigger('cachopo', view.child);
|
||||
view.bind('cachopo', function() {
|
||||
launched = true;
|
||||
}),
|
||||
view.child.trigger('cachopo');
|
||||
setTimeout(function(){
|
||||
expect(launched).toBeTruthy();
|
||||
done();
|
||||
}, 25);
|
||||
});
|
||||
|
||||
it("should kill an event", function() {
|
||||
var ev = {
|
||||
stopPropagation:function(){},
|
||||
preventDefault: function(){}
|
||||
};
|
||||
var ev2 = "thisisnotanevent";
|
||||
|
||||
spyOn(ev, "stopPropagation");
|
||||
spyOn(ev, "preventDefault");
|
||||
|
||||
view.killEvent(ev);
|
||||
view.killEvent(ev2);
|
||||
view.killEvent();
|
||||
|
||||
expect(ev.stopPropagation).toHaveBeenCalled()
|
||||
expect(ev.preventDefault).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
describe('common', function() {
|
||||
|
||||
var common;
|
||||
|
||||
beforeEach(function() {
|
||||
common = new CartoDBLayerCommon();
|
||||
common.options = {
|
||||
tiler_domain: "carto.com",
|
||||
tiler_port: "8081",
|
||||
tiler_protocol: "http",
|
||||
user_name: 'rambo',
|
||||
table_name: 'test'
|
||||
}
|
||||
});
|
||||
|
||||
it("when query_wrapper is present the query should be wrapped", function() {
|
||||
common.options = {
|
||||
table_name: 'test',
|
||||
tiler_domain: "carto.com",
|
||||
tiler_port: "8081",
|
||||
tiler_protocol: "http",
|
||||
tile_style: "TEST",
|
||||
query: 'select jaja',
|
||||
query_wrapper: 'select * from (<%=sql%>)',
|
||||
tile_style: '#test { polygon-fill: red; }',
|
||||
interactivity: 'jaja'
|
||||
}
|
||||
var t = common._getLayerDefinition();
|
||||
expect(t.sql).toEqual('select * from (select jaja)');
|
||||
expect(t.cartocss).toEqual('#layer0 { polygon-fill: red; }');
|
||||
expect(t.interactivity).toEqual('jaja');
|
||||
|
||||
common.options = {
|
||||
table_name: 'test',
|
||||
tiler_domain: "carto.com",
|
||||
tiler_port: "8081",
|
||||
tiler_protocol: "http",
|
||||
tile_style: "TEST",
|
||||
query: null,
|
||||
query_wrapper: 'select * from (<%=sql%>)'
|
||||
};
|
||||
t = common._getLayerDefinition();
|
||||
expect(t.sql).toEqual('select * from (select * from test)');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
describe("Geometry", function() {
|
||||
it("isPoint should return true when is a point", function() {
|
||||
var geojsonFeature = {
|
||||
"type": "Point",
|
||||
"coordinates": [-104.99404, 39.75621]
|
||||
};
|
||||
var g = new cdb.geo.Geometry({
|
||||
geojson: geojsonFeature
|
||||
});
|
||||
expect(g.isPoint()).toEqual(true);
|
||||
g.set('geojson', {type: 'Polygon'});
|
||||
expect(g.isPoint()).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
|
||||
describe('GoogleMapsMapView', function() {
|
||||
var mapView;
|
||||
var map;
|
||||
var spy;
|
||||
var container;
|
||||
beforeEach(function() {
|
||||
container = $('<div>').css('height', '200px');
|
||||
//$('body').append(container);
|
||||
map = new cdb.geo.Map();
|
||||
mapView = new cdb.geo.GoogleMapsMapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
layerURL = 'http://{s}.tiles.mapbox.com/v3/cartodb.map-1nh578vv/{z}/{x}/{y}.png';
|
||||
layer = new cdb.geo.TileLayer({ urlTemplate: layerURL });
|
||||
|
||||
spy = {
|
||||
zoomChanged: function(){},
|
||||
centerChanged: function(){},
|
||||
scrollWheelChanged: function(){}
|
||||
};
|
||||
|
||||
spyOn(spy, 'zoomChanged');
|
||||
spyOn(spy, 'centerChanged');
|
||||
spyOn(spy, 'scrollWheelChanged');
|
||||
|
||||
map.bind('change:zoom', spy.zoomChanged);
|
||||
map.bind('change:center', spy.centerChanged);
|
||||
map.bind('change:scrollwheel', spy.scrollWheelChanged);
|
||||
});
|
||||
|
||||
it("should change bounds when center is set", function() {
|
||||
var s = sinon.spy();
|
||||
spyOn(map, 'getViewBounds');
|
||||
map.bind('change:view_bounds_ne', s);
|
||||
map.set('center', [10, 10]);
|
||||
expect(s.called).toEqual(true);
|
||||
expect(map.getViewBounds).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should change center and zoom when bounds are changed", function(done) {
|
||||
var s = sinon.spy();
|
||||
mapView.getSize = function() { return {x: 200, y: 200}; }
|
||||
map.bind('change:center', s);
|
||||
spyOn(mapView, '_setCenter');
|
||||
mapView._bindModel();
|
||||
|
||||
map.set({
|
||||
'view_bounds_ne': [1, 1],
|
||||
'view_bounds_sw': [-0.3, -1.2]
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(mapView._setCenter).toHaveBeenCalled();
|
||||
done();
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
it("should allow to disable the scroll wheel", function() {
|
||||
map.disableScrollWheel();
|
||||
expect(spy.scrollWheelChanged).toHaveBeenCalled();
|
||||
expect(map.get("scrollwheel")).toEqual(false);
|
||||
});
|
||||
|
||||
it("should change zoom", function() {
|
||||
mapView._setZoom(null, 10);
|
||||
expect(spy.zoomChanged).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should allow adding a layer", function() {
|
||||
map.addLayer(layer);
|
||||
expect(map.layers.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should add layers on reset", function() {
|
||||
map.layers.reset([
|
||||
layer
|
||||
]);
|
||||
expect(map.layers.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should create a layer view when adds a model", function() {
|
||||
var spy = { c: function() {} };
|
||||
spyOn(spy, 'c');
|
||||
mapView.bind('newLayerView', spy.c);
|
||||
map.addLayer(layer);
|
||||
expect(map.layers.length).toEqual(1);
|
||||
expect(_.size(mapView.layers)).toEqual(1);
|
||||
expect(spy.c).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should allow removing a layer", function() {
|
||||
map.addLayer(layer);
|
||||
map.removeLayer(layer);
|
||||
expect(map.layers.length).toEqual(0);
|
||||
expect(_.size(mapView.layers)).toEqual(0);
|
||||
});
|
||||
|
||||
it("should allow removing a layer by index", function() {
|
||||
map.addLayer(layer);
|
||||
map.removeLayerAt(0);
|
||||
expect(map.layers.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("should allow removing a layer by Cid", function() {
|
||||
var cid = map.addLayer(layer);
|
||||
map.removeLayerByCid(cid);
|
||||
expect(map.layers.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("should create a TiledLayerView when the layer is Tiled", function() {
|
||||
var lyr = map.addLayer(layer);
|
||||
var layerView = mapView.getLayerByCid(lyr);
|
||||
expect(cdb.geo.GMapsTiledLayerView.prototype.isPrototypeOf(layerView)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should create a CartoDBLayer when the layer is cartodb", function() {
|
||||
layer = new cdb.geo.CartoDBLayer({
|
||||
table_name: 'test',
|
||||
user_name: 'testuser',
|
||||
tile_style: 'teststyle'
|
||||
});
|
||||
map.addLayer(new cdb.geo.PlainLayer({}));
|
||||
var lyr = map.addLayer(layer);
|
||||
var layerView = mapView.getLayerByCid(lyr);
|
||||
expect(cdb.geo.GMapsCartoDBLayerView.prototype.isPrototypeOf(layerView)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should create a CartoDBGroupLayer when the layer is layergroup", function() {
|
||||
layer = new cdb.geo.CartoDBGroupLayer({
|
||||
layer_definition: {
|
||||
version: '1.0.0',
|
||||
layers: [{
|
||||
type: 'cartodb',
|
||||
options: {
|
||||
sql: "select * from european_countries_export",
|
||||
cartocss: '#layer { polygon-fill: #000; polygon-opacity: 0.8;}',
|
||||
cartocss_version : '2.0.0',
|
||||
interactivity: ['test2', 'cartodb_id2']
|
||||
}
|
||||
}]
|
||||
}
|
||||
});
|
||||
map.addLayer(new cdb.geo.PlainLayer({}));
|
||||
var lyr = map.addLayer(layer);
|
||||
var layerView = mapView.getLayerByCid(lyr);
|
||||
expect(cdb.geo.GMapsCartoDBLayerGroupView.prototype.isPrototypeOf(layerView)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should create a cartodb logo when layer is cartodb", function(done) {
|
||||
layer = new cdb.geo.CartoDBLayer({ table_name: "INVENTADO", tile_style: 'test', user_name: 'test'});
|
||||
var lyr = map.addLayer(layer);
|
||||
var layerView = mapView.getLayerByCid(lyr);
|
||||
|
||||
setTimeout(function() {
|
||||
expect(container.find("div.cartodb-logo").length).toEqual(1);
|
||||
done();
|
||||
}, 3000);
|
||||
});
|
||||
|
||||
it("should create a PlaiLayer when the layer is cartodb", function() {
|
||||
layer = new cdb.geo.PlainLayer({});
|
||||
var lyr = map.addLayer(layer);
|
||||
var layerView = mapView.getLayerByCid(lyr);
|
||||
expect(layerView.__proto__.constructor).toEqual(cdb.geo.GMapsPlainLayerView);
|
||||
});
|
||||
|
||||
var geojsonFeature = {
|
||||
"type": "Point",
|
||||
"coordinates": [-104.99404, 39.75621]
|
||||
};
|
||||
|
||||
|
||||
var multipoly = {"type":"MultiPolygon","coordinates": [
|
||||
[
|
||||
[[40, 40], [20, 45], [45, 30], [40, 40]]
|
||||
],
|
||||
[
|
||||
[[20, 35], [45, 20], [30, 5], [10, 10], [10, 30], [20, 35]],
|
||||
[[30, 20], [20, 25], [20, 15], [30, 20]]
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
function testGeom(g) {
|
||||
var geo = new cdb.geo.Geometry({
|
||||
geojson: g
|
||||
});
|
||||
map.addGeometry(geo);
|
||||
expect(_.size(mapView.geometries)).toEqual(1);
|
||||
geo.destroy();
|
||||
expect(_.size(mapView.geometries)).toEqual(0);
|
||||
}
|
||||
|
||||
it("should add and remove a geometry", function() {
|
||||
testGeom(geojsonFeature);
|
||||
});
|
||||
|
||||
it("should add and remove a polygon", function() {
|
||||
testGeom(multipoly);
|
||||
});
|
||||
|
||||
it("should edit a geometry", function() {
|
||||
var geo = new cdb.geo.Geometry({
|
||||
geojson: geojsonFeature
|
||||
});
|
||||
map.addGeometry(geo);
|
||||
var v = mapView.geometries[geo.cid];
|
||||
v.trigger('dragend', null, [10, 20]);
|
||||
expect(geo.get('geojson')).toEqual({
|
||||
"type": "Point",
|
||||
"coordinates": [20, 10]
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
it("should convert to geojson", function() {
|
||||
var geo = new cdb.geo.Geometry({
|
||||
geojson: multipoly
|
||||
});
|
||||
map.addGeometry(geo);
|
||||
var v = mapView.geometries[geo.cid];
|
||||
var geojson = cdb.geo.gmaps.PathView.getGeoJSON(v.geom, 'MultiPolygon');
|
||||
expect(geojson).toEqual(multipoly);
|
||||
});
|
||||
|
||||
it("should swicth layer", function(done) {
|
||||
map.addLayer(layer);
|
||||
layer.set({'type': 'torque', 'cartocss': 'Map{ -torque-frame-count: 10; }'});
|
||||
setTimeout(function() {
|
||||
expect(mapView.layers[layer.cid] instanceof cdb.geo.GMapsTorqueLayerView).toEqual(true);
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
it("should disable gmaps dragging and double click zooming when the map has drag disabled", function() {
|
||||
var container = $('<div>').css({
|
||||
'height': '200px',
|
||||
'width': '200px'
|
||||
});
|
||||
var map = new cdb.geo.Map({
|
||||
drag: false
|
||||
});
|
||||
var mapView = new cdb.geo.GoogleMapsMapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
expect(mapView.map_googlemaps.get('draggable')).toBeFalsy();
|
||||
expect(mapView.map_googlemaps.get('disableDoubleClickZoom')).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,85 @@
|
||||
describe('Hide functionality', function() {
|
||||
var div, map, cdb_layer;
|
||||
|
||||
beforeEach(function() {
|
||||
div = document.createElement('div');
|
||||
div.setAttribute("id","map");
|
||||
div.style.height = "100px";
|
||||
div.style.width = "100px";
|
||||
|
||||
map = new google.maps.Map(div, {
|
||||
center: new google.maps.LatLng(51.505, -0.09),
|
||||
disableDefaultUI: false,
|
||||
zoom: 13,
|
||||
mapTypeId: google.maps.MapTypeId.ROADMAP,
|
||||
mapTypeControl: false
|
||||
});
|
||||
|
||||
cdb_layer = new cdb.geo.CartoDBLayerGMaps({
|
||||
map: map,
|
||||
user_name:"examples",
|
||||
tile_style: 'test',
|
||||
table_name: 'earthquakes',
|
||||
query: "SELECT * FROM {{table_name}}",
|
||||
tile_style: "#{{table_name}}{marker-fill:#E25B5B}",
|
||||
opacity:0.8,
|
||||
interactivity: "cartodb_id, magnitude",
|
||||
featureOver: function(ev,latlng,pos,data) {},
|
||||
featureOut: function() {},
|
||||
featureClick: function(ev,latlng,pos,data) {},
|
||||
debug: true
|
||||
});
|
||||
|
||||
map.overlayMapTypes.setAt(0, cdb_layer);
|
||||
|
||||
});
|
||||
|
||||
|
||||
it('if hides layers should work', function(done) {
|
||||
|
||||
setTimeout(function () {
|
||||
cdb_layer.hide();
|
||||
|
||||
setTimeout(function() {
|
||||
var $tile = $(div).find("img[gtilekey]").first()
|
||||
, opacity = cdb_layer.options.opacity
|
||||
, before_opacity = cdb_layer.options.previous_opacity;
|
||||
|
||||
expect(cdb_layer.visible).toBeFalsy();
|
||||
expect($tile.css("opacity")).toEqual('0');
|
||||
expect(opacity).toEqual(0);
|
||||
expect(before_opacity).not.toEqual(0);
|
||||
done();
|
||||
}, 500);
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it('If sets opacity to 0, layer should be visible', function(done) {
|
||||
setTimeout(function () {
|
||||
cdb_layer.setOpacity(0);
|
||||
expect(cdb_layer.options.visible).toBeTruthy();
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it('toggle layer from a visible state should work', function(done) {
|
||||
|
||||
setTimeout(function () {
|
||||
cdb_layer.hide();
|
||||
visibility = cdb_layer.toggle();
|
||||
|
||||
setTimeout(function() {
|
||||
var $tile = $(div).find("img[gtilekey]").first()
|
||||
, opacity = cdb_layer.options.opacity;
|
||||
|
||||
expect(visibility).toBeTruthy();
|
||||
expect(cdb_layer.visible).toBeTruthy();
|
||||
expect($tile.css("opacity")).toEqual('0.99');
|
||||
expect(opacity).toEqual(0.99);
|
||||
done();
|
||||
}, 500);
|
||||
|
||||
}, 500);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
describe('Interaction functionality', function() {
|
||||
var div, map, cdb_layer;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
div = document.createElement('div');
|
||||
div.setAttribute("id","map");
|
||||
div.style.height = "100px";
|
||||
div.style.width = "100px";
|
||||
|
||||
map = new google.maps.Map(div, {
|
||||
center: new google.maps.LatLng(51.505, -0.09),
|
||||
disableDefaultUI: false,
|
||||
zoom: 13,
|
||||
mapTypeId: google.maps.MapTypeId.ROADMAP,
|
||||
mapTypeControl: false
|
||||
});
|
||||
|
||||
cdb_layer = new cdb.geo.CartoDBLayerGMaps({
|
||||
map: map,
|
||||
user_name:"examples",
|
||||
table_name: 'country_colors',
|
||||
tile_style: 'test',
|
||||
opacity:0.8,
|
||||
interactivity: "cartodb_id",
|
||||
debug: true,
|
||||
interaction: true
|
||||
});
|
||||
|
||||
map.overlayMapTypes.setAt(0, cdb_layer);
|
||||
});
|
||||
|
||||
it('If there is no interaction defined, shouldn\'t work and failed', function() {
|
||||
// Fake a mouseover
|
||||
$(div).trigger('mouseover');
|
||||
expect(cdb_layer._manageOnEvents).toThrow();
|
||||
|
||||
// Fake a mouseout
|
||||
$(div).trigger('mouseout');
|
||||
expect(cdb_layer._manageOffEvents).toThrow();
|
||||
|
||||
// Fake a click
|
||||
$(div).trigger('click');
|
||||
expect(cdb_layer._manageOffEvents).toThrow();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,94 @@
|
||||
describe('Opacity interaction', function() {
|
||||
var div, map, cdb_layer;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
div = document.createElement('div');
|
||||
div.setAttribute("id","map");
|
||||
div.style.height = "100px";
|
||||
div.style.width = "100px";
|
||||
|
||||
map = new google.maps.Map(div, {
|
||||
center: new google.maps.LatLng(51.505, -0.09),
|
||||
disableDefaultUI: false,
|
||||
zoom: 13,
|
||||
mapTypeId: google.maps.MapTypeId.ROADMAP,
|
||||
mapTypeControl: false
|
||||
});
|
||||
|
||||
cdb_layer = new cdb.geo.CartoDBLayerGMaps({
|
||||
map: map,
|
||||
user_name:"examples",
|
||||
table_name: 'earthquakes',
|
||||
query: "SELECT * FROM {{table_name}}",
|
||||
tile_style: "#{{table_name}}{marker-fill:#E25B5B}",
|
||||
opacity: 0.8,
|
||||
interactivity: "cartodb_id, magnitude",
|
||||
featureOver: function(ev,latlng,pos,data) {},
|
||||
featureOut: function() {},
|
||||
featureClick: function(ev,latlng,pos,data) {},
|
||||
debug: true
|
||||
});
|
||||
map.overlayMapTypes.setAt(0, cdb_layer);
|
||||
|
||||
});
|
||||
|
||||
xit('Layer opacity should be 0.8', function() {
|
||||
|
||||
waits(500);
|
||||
|
||||
runs(function () {
|
||||
var $layer = $(div).find("img[gtilekey]").first()
|
||||
, opacity = cdb_layer.options.opacity;
|
||||
|
||||
expect(cdb_layer.options.visible).toBeTruthy();
|
||||
expect($layer.css("opacity")).toEqual('0.8');//opacity.toString());
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
xit('Opacity shouldn\'t change if it is not visible', function() {
|
||||
|
||||
waits(500);
|
||||
|
||||
runs(function() {
|
||||
cdb_layer.hide();
|
||||
cdb_layer.setOpacity(0.3);
|
||||
map.overlayMapTypes.setAt(0, cdb_layer);
|
||||
});
|
||||
|
||||
waits(500);
|
||||
|
||||
runs(function () {
|
||||
var $layer = $(div).find("img[gtilekey]").first()
|
||||
, opacity = cdb_layer.options.opacity
|
||||
, before_opacity = cdb_layer.options.previous_opacity;
|
||||
|
||||
expect(cdb_layer.options.visible).toBeFalsy();
|
||||
expect($layer.css("opacity")).toEqual('0.3');
|
||||
expect(before_opacity).toEqual(0.8);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// it('Opacity should change if layer is visible', function() {
|
||||
// cdb_layer.setOpacity(0.3);
|
||||
|
||||
// var $layer = $(div).find(".leaflet-layer")
|
||||
// , opacity = cdb_layer.options.opacity;
|
||||
|
||||
// expect(cdb_layer.options.visible).toBeTruthy();
|
||||
// expect($layer.css("opacity")).toEqual('0.3');
|
||||
// });
|
||||
|
||||
|
||||
// it('If sets opacity to 0, the layer is still visible', function() {
|
||||
// cdb_layer.setOpacity(0);
|
||||
|
||||
// var $layer = $(div).find(".leaflet-layer")
|
||||
// , opacity = cdb_layer.options.opacity;
|
||||
|
||||
// expect(cdb_layer.options.visible).toBeTruthy();
|
||||
// expect($layer.css("opacity")).toEqual('0');
|
||||
// });
|
||||
});
|
||||
@@ -0,0 +1,83 @@
|
||||
describe('Show functionality', function() {
|
||||
var div, map, cdb_layer;
|
||||
|
||||
beforeEach(function() {
|
||||
div = document.createElement('div');
|
||||
div.setAttribute("id","map");
|
||||
div.style.height = "100px";
|
||||
div.style.width = "100px";
|
||||
|
||||
map = new google.maps.Map(div, {
|
||||
center: new google.maps.LatLng(51.505, -0.09),
|
||||
disableDefaultUI: false,
|
||||
zoom: 13,
|
||||
mapTypeId: google.maps.MapTypeId.ROADMAP,
|
||||
mapTypeControl: false
|
||||
});
|
||||
|
||||
cdb_layer = new cdb.geo.CartoDBLayerGMaps({
|
||||
map: map,
|
||||
user_name:"examples",
|
||||
table_name: 'earthquakes',
|
||||
query: "SELECT * FROM {{table_name}}",
|
||||
tile_style: "#{{table_name}}{marker-fill:#E25B5B}",
|
||||
opacity:0.8,
|
||||
interactivity: "cartodb_id, magnitude",
|
||||
featureOver: function(ev,latlng,pos,data) {},
|
||||
featureOut: function() {},
|
||||
featureClick: function(ev,latlng,pos,data) {},
|
||||
debug: true
|
||||
});
|
||||
map.overlayMapTypes.setAt(0, cdb_layer);
|
||||
|
||||
});
|
||||
|
||||
|
||||
it('If layer is visible, show shouldn\'t do anything', function(done) {
|
||||
setTimeout(function () {
|
||||
expect(cdb_layer.show).toThrow();
|
||||
var opacity = cdb_layer.options.opacity;
|
||||
expect(cdb_layer.options.visible).toBeTruthy();
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it('Shows layer after hide it', function(done) {
|
||||
setTimeout(function () {
|
||||
cdb_layer.hide();
|
||||
cdb_layer.show();
|
||||
expect(cdb_layer.options.visible).toBeTruthy();
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it('If hides layer and set an opacity greater than 0, layer shouln\'t be visible', function(done) {
|
||||
setTimeout(function () {
|
||||
cdb_layer.hide();
|
||||
cdb_layer.setOpacity(0.2);
|
||||
expect(cdb_layer.visible).toBeFalsy();
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it('toggle layer from hidden state should work', function(done) {
|
||||
setTimeout(function () {
|
||||
cdb_layer.show();
|
||||
visibility = cdb_layer.toggle();
|
||||
|
||||
setTimeout(function() {
|
||||
var $tile = $(div).find("img[gtilekey]").first()
|
||||
, opacity = cdb_layer.options.opacity
|
||||
, before_opacity = cdb_layer.options.previous_opacity;
|
||||
|
||||
expect(cdb_layer.visible).toBeFalsy();
|
||||
expect(visibility).toBeFalsy();
|
||||
expect($tile.css("opacity")).toEqual('0');
|
||||
expect(opacity).toEqual(0);
|
||||
expect(before_opacity).not.toEqual(0);
|
||||
done();
|
||||
}, 500);
|
||||
|
||||
}, 500);
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,516 @@
|
||||
describe('LeafletMapView', function() {
|
||||
var mapView;
|
||||
var map;
|
||||
var spy;
|
||||
var container;
|
||||
beforeEach(function() {
|
||||
container = $('<div>').css({
|
||||
'height': '200px',
|
||||
'width': '200px'
|
||||
});
|
||||
map = new cdb.geo.Map();
|
||||
mapView = new cdb.geo.LeafletMapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
layerURL = 'http://{s}.tiles.mapbox.com/v3/cartodb.map-1nh578vv/{z}/{x}/{y}.png';
|
||||
layer = new cdb.geo.TileLayer({ urlTemplate: layerURL });
|
||||
|
||||
spy = {
|
||||
zoomChanged: function(){},
|
||||
keyboardChanged: function(){},
|
||||
centerChanged: function(){},
|
||||
changed: function() {}
|
||||
};
|
||||
|
||||
spyOn(spy, 'zoomChanged');
|
||||
spyOn(spy, 'keyboardChanged');
|
||||
spyOn(spy, 'centerChanged');
|
||||
spyOn(spy, 'changed');
|
||||
map.bind('change:zoom', spy.zoomChanged);
|
||||
map.bind('change:keyboard', spy.keyboardChanged);
|
||||
map.bind('change:center', spy.centerChanged);
|
||||
map.bind('change', spy.changed);
|
||||
});
|
||||
|
||||
it("should change bounds when center is set", function() {
|
||||
var s = sinon.spy();
|
||||
spyOn(map, 'getViewBounds');
|
||||
map.bind('change:view_bounds_ne', s);
|
||||
map.set('center', [10, 10]);
|
||||
expect(s.called).toEqual(true);
|
||||
expect(map.getViewBounds).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should change center and zoom when bounds are changed", function(done) {
|
||||
var s = sinon.spy();
|
||||
mapView.getSize = function() { return {x: 200, y: 200}; }
|
||||
map.bind('change:center', s);
|
||||
spyOn(mapView, '_setCenter');
|
||||
mapView._bindModel();
|
||||
|
||||
map.set({
|
||||
'view_bounds_ne': [1, 1],
|
||||
'view_bounds_sw': [-0.3, -1.2]
|
||||
})
|
||||
|
||||
setTimeout(function() {
|
||||
expect(mapView._setCenter).toHaveBeenCalled();
|
||||
done();
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
it("should allow adding a layer", function() {
|
||||
map.addLayer(layer);
|
||||
expect(map.layers.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should add layers on reset", function() {
|
||||
map.layers.reset([
|
||||
layer
|
||||
]);
|
||||
expect(map.layers.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should create a layer view when adds a model", function() {
|
||||
var spy = { c: function() {} };
|
||||
spyOn(spy, 'c');
|
||||
mapView.bind('newLayerView', spy.c);
|
||||
map.addLayer(layer);
|
||||
expect(map.layers.length).toEqual(1);
|
||||
expect(_.size(mapView.layers)).toEqual(1);
|
||||
expect(spy.c).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should allow removing a layer", function() {
|
||||
map.addLayer(layer);
|
||||
map.removeLayer(layer);
|
||||
expect(map.layers.length).toEqual(0);
|
||||
expect(_.size(mapView.layers)).toEqual(0);
|
||||
});
|
||||
|
||||
it("should allow removing a layer by index", function() {
|
||||
map.addLayer(layer);
|
||||
map.removeLayerAt(0);
|
||||
expect(map.layers.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("should allow removing a layer by Cid", function() {
|
||||
var cid = map.addLayer(layer);
|
||||
map.removeLayerByCid(cid);
|
||||
expect(map.layers.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("should create a TiledLayerView when the layer is Tiled", function() {
|
||||
var lyr = map.addLayer(layer);
|
||||
var layerView = mapView.getLayerByCid(lyr);
|
||||
expect(cdb.geo.LeafLetTiledLayerView.prototype.isPrototypeOf(layerView)).isPrototypeOf();
|
||||
});
|
||||
|
||||
it("should create a CartoDBLayer when the layer is cartodb", function() {
|
||||
layer = new cdb.geo.CartoDBLayer({
|
||||
table_name: 'test',
|
||||
user_name: 'test',
|
||||
tile_style: 'test'
|
||||
});
|
||||
var lyr = map.addLayer(layer);
|
||||
var layerView = mapView.getLayerByCid(lyr);
|
||||
expect(layerView.setQuery).not.toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should create a CartoDBLayerGroup when the layer is LayerGroup", function() {
|
||||
layer = new cdb.geo.CartoDBGroupLayer({
|
||||
layer_definition: {
|
||||
version: '1.0.0',
|
||||
layers: [{
|
||||
type: 'cartodb',
|
||||
options: {
|
||||
sql: 'select * from ne_10m_populated_places_simple',
|
||||
cartocss: '#layer { marker-fill: red; }',
|
||||
interactivity: ['test', 'cartodb_id']
|
||||
}
|
||||
}]
|
||||
}
|
||||
});
|
||||
var lyr = map.addLayer(layer);
|
||||
var layerView = mapView.getLayerByCid(lyr);
|
||||
expect(layerView.getLayerCount()).toEqual(1);
|
||||
});
|
||||
|
||||
it("should create the cartodb logo", function(done) {
|
||||
layer = new cdb.geo.CartoDBLayer({
|
||||
table_name: "INVENTADO",
|
||||
user_name: 'test',
|
||||
tile_style: 'test'
|
||||
});
|
||||
var lyr = map.addLayer(layer);
|
||||
var layerView = mapView.getLayerByCid(lyr);
|
||||
|
||||
setTimeout(function() {
|
||||
expect(container.find("div.cartodb-logo").length).toEqual(1);
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
it("should not add the cartodb logo when cartodb_logo = false", function(done) {
|
||||
layer = new cdb.geo.CartoDBLayer({
|
||||
table_name: "INVENTADO",
|
||||
user_name: 'test',
|
||||
tile_style: 'test',
|
||||
cartodb_logo: false
|
||||
});
|
||||
var lyr = map.addLayer(layer);
|
||||
var layerView = mapView.getLayerByCid(lyr);
|
||||
|
||||
setTimeout(function() {
|
||||
expect(container.find("div.cartodb-logo").length).toEqual(0);
|
||||
done();
|
||||
}, 1);
|
||||
});
|
||||
|
||||
it("should create a PlaiLayer when the layer is cartodb", function() {
|
||||
layer = new cdb.geo.PlainLayer({});
|
||||
var lyr = map.addLayer(layer);
|
||||
var layerView = mapView.getLayerByCid(lyr);
|
||||
expect(layerView.setQuery).not.toEqual(cdb.geo.LeafLetPlainLayerView);
|
||||
});
|
||||
|
||||
it("should insert layers in specified order", function() {
|
||||
var layer = new cdb.geo.CartoDBLayer({
|
||||
table_name: "INVENTADO",
|
||||
user_name: 'test',
|
||||
tile_style: 'test'
|
||||
});
|
||||
map.addLayer(layer);
|
||||
|
||||
spyOn(mapView.map_leaflet,'addLayer');
|
||||
var b = new cdb.geo.TileLayer({urlTemplate: 'test' });
|
||||
map.addLayer(b, {at: 0});
|
||||
|
||||
expect(mapView.getLayerByCid(layer.cid).options.zIndex).toEqual(1);
|
||||
expect(mapView.getLayerByCid(b.cid).options.zIndex).toEqual(0);
|
||||
//expect(mapView.map_leaflet.addLayer).toHaveBeenCalledWith(mapView.layers[layer.cid].leafletLayer, true);
|
||||
});
|
||||
|
||||
it("shoule remove all layers when map view is cleaned", function() {
|
||||
|
||||
var id1 = map.addLayer(new cdb.geo.CartoDBLayer({
|
||||
table_name: "INVENTADO",
|
||||
user_name: 'test',
|
||||
tile_style: 'test'
|
||||
}));
|
||||
var id2 = map.addLayer(new cdb.geo.CartoDBLayer({
|
||||
table_name: "INVENTADO",
|
||||
user_name: 'test',
|
||||
tile_style: 'test'
|
||||
}));
|
||||
|
||||
expect(_.size(mapView.layers)).toEqual(2);
|
||||
var layer = mapView.getLayerByCid(id1);
|
||||
var layer2 = mapView.getLayerByCid(id2);
|
||||
spyOn(layer, 'remove');
|
||||
spyOn(layer2, 'remove');
|
||||
mapView.clean();
|
||||
expect(_.size(mapView.layers)).toEqual(0);
|
||||
expect(layer.remove).toHaveBeenCalled();
|
||||
expect(layer2.remove).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should not all a layer when it can't be creadted", function() {
|
||||
var layer = new cdb.geo.TileLayer({type: 'rambo'});
|
||||
map.addLayer(layer);
|
||||
expect(_.size(mapView.layers)).toEqual(0);
|
||||
});
|
||||
|
||||
var geojsonFeature = {
|
||||
"type": "Point",
|
||||
"coordinates": [-104.99404, 39.75621]
|
||||
};
|
||||
|
||||
it("should add and remove a geometry", function() {
|
||||
var geo = new cdb.geo.Geometry({
|
||||
geojson: geojsonFeature
|
||||
});
|
||||
map.addGeometry(geo);
|
||||
expect(_.size(mapView.geometries)).toEqual(1);
|
||||
geo.destroy();
|
||||
expect(_.size(mapView.geometries)).toEqual(0);
|
||||
});
|
||||
|
||||
it("should edit a geometry", function() {
|
||||
var geo = new cdb.geo.Geometry({
|
||||
geojson: geojsonFeature
|
||||
});
|
||||
map.addGeometry(geo);
|
||||
var v = mapView.geometries[geo.cid];
|
||||
v.trigger('dragend', null, [10, 20]);
|
||||
expect(geo.get('geojson')).toEqual({
|
||||
"type": "Point",
|
||||
"coordinates": [20, 10]
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should save automatically when the zoom or center changes", function(done) {
|
||||
spyOn(map, 'save');
|
||||
mapView.setAutoSaveBounds();
|
||||
map.set('center', [1,2]);
|
||||
|
||||
setTimeout(function() {
|
||||
expect(map.save).toHaveBeenCalled();
|
||||
done();
|
||||
}, 1500);
|
||||
|
||||
});
|
||||
|
||||
it("should set z-order", function() {
|
||||
var layer1 = new cdb.geo.TileLayer({ urlTemplate:'test1'});
|
||||
var layer2 = new cdb.geo.TileLayer({ urlTemplate:'test2'});
|
||||
var layerView1 = mapView.getLayerByCid(map.addLayer(layer1));
|
||||
var layerView2 = mapView.getLayerByCid(map.addLayer(layer2, { at: 0 }));
|
||||
expect(layerView1.options.zIndex > layerView2.options.zIndex).toEqual(true);
|
||||
});
|
||||
|
||||
it("should switch layer", function() {
|
||||
map.addLayer(layer);
|
||||
layer.set('type', 'torque');
|
||||
expect(mapView.layers[layer.cid] instanceof L.TorqueLayer).toEqual(true);
|
||||
});
|
||||
|
||||
it("should reuse layer view", function() {
|
||||
var layer1 = new cdb.geo.TorqueLayer({ type: 'torque', sql: 'select * from table', cartocss: '#test {}' });
|
||||
map.addLayer(layer1);
|
||||
expect(mapView.layers[layer1.cid] instanceof L.TorqueLayer).toEqual(true);
|
||||
mapView.layers[layer1.cid].check = 'testing';
|
||||
var newLayer = layer1.clone();
|
||||
newLayer.set({ sql: 'select * from table', cartocss: '#test {}' });
|
||||
map.layers.reset([newLayer]);
|
||||
expect(mapView.layers[newLayer.cid] instanceof L.TorqueLayer).toEqual(true);
|
||||
expect(mapView.layers[newLayer.cid].model).toEqual(newLayer)
|
||||
expect(mapView.layers[newLayer.cid].check).toEqual('testing');
|
||||
});
|
||||
|
||||
// Test cases for gmaps substitutes since the support is deprecated.
|
||||
_({ // GMaps basemap base_type: expected substitute data
|
||||
//empty = defaults to gray_roadmap
|
||||
"": {
|
||||
tiles: {
|
||||
providedBy: "cartocdn",
|
||||
type: "light"
|
||||
},
|
||||
subdomains: ['a','b','c','d'],
|
||||
minZoom: 0,
|
||||
maxZoom: 18,
|
||||
attribution: 'Map designs by <a href="http://stamen.com/">Stamen</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, Provided by <a href="https://carto.com">CARTO</a>'
|
||||
},
|
||||
dark_roadmap: {
|
||||
tiles: {
|
||||
providedBy: "cartocdn",
|
||||
type: "dark"
|
||||
},
|
||||
subdomains: ['a','b','c','d'],
|
||||
minZoom: 0,
|
||||
maxZoom: 18,
|
||||
attribution: 'Map designs by <a href="http://stamen.com/">Stamen</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, Provided by <a href="https://carto.com">CARTO</a>'
|
||||
},
|
||||
roadmap: {
|
||||
tiles: {
|
||||
providedBy: "nokia",
|
||||
type: "normal.day"
|
||||
},
|
||||
subdomains: ['1','2','3','4'],
|
||||
minZoom: 0,
|
||||
maxZoom: 21,
|
||||
attribution: '©2012 Nokia <a href="http://here.net/services/terms" target="_blank">Terms of use</a>'
|
||||
},
|
||||
hybrid: {
|
||||
tiles: {
|
||||
providedBy: "nokia",
|
||||
type: "hybrid.day"
|
||||
},
|
||||
subdomains: ['1','2','3','4'],
|
||||
minZoom: 0,
|
||||
maxZoom: 21,
|
||||
attribution: '©2012 Nokia <a href="http://here.net/services/terms" target="_blank">Terms of use</a>'
|
||||
},
|
||||
terrain: {
|
||||
tiles: {
|
||||
providedBy: "nokia",
|
||||
type: "terrain.day"
|
||||
},
|
||||
subdomains: ['1','2','3','4'],
|
||||
minZoom: 0,
|
||||
maxZoom: 21,
|
||||
attribution: '©2012 Nokia <a href="http://here.net/services/terms" target="_blank">Terms of use</a>'
|
||||
},
|
||||
satellite: { // Nokia Satellite Day
|
||||
tiles: {
|
||||
providedBy: "nokia",
|
||||
type: "satellite.day"
|
||||
},
|
||||
subdomains: ['1','2','3','4'],
|
||||
minZoom: 0,
|
||||
maxZoom: 21,
|
||||
attribution: '©2012 Nokia <a href="http://here.net/services/terms" target="_blank">Terms of use</a>'
|
||||
}
|
||||
}).map(function(substitute, baseType) {
|
||||
var layerOpts;
|
||||
var testContext;
|
||||
|
||||
if (baseType) {
|
||||
layerOpts = { base_type: baseType};
|
||||
testContext = 'with basemap "'+ baseType +'"';
|
||||
} else {
|
||||
testContext = 'with default basemap "gray_roadmap"';
|
||||
}
|
||||
|
||||
describe("given a GMaps layer model "+ testContext, function () {
|
||||
var view;
|
||||
|
||||
beforeEach(function() {
|
||||
var layer = new cdb.geo.GMapsBaseLayer(layerOpts);
|
||||
view = mapView.createLayer(layer);
|
||||
});
|
||||
|
||||
it("should have a tileUrl based on substitute's template URL", function() {
|
||||
var tileUrl = view.getTileUrl({ x: 101, y: 202, z: 303 });
|
||||
|
||||
expect(tileUrl).toContain(substitute.tiles.providedBy);
|
||||
expect(tileUrl).toContain(substitute.tiles.type);
|
||||
});
|
||||
|
||||
it("should have substitute's attribution", function() {
|
||||
expect(view.options.attribution).toEqual(substitute.attribution);
|
||||
});
|
||||
|
||||
it("should have substitute's minZoom", function() {
|
||||
expect(view.options.minZoom).toEqual(substitute.minZoom);
|
||||
});
|
||||
|
||||
it("should have substitute's maxZoom", function() {
|
||||
expect(view.options.maxZoom).toEqual(substitute.maxZoom);
|
||||
});
|
||||
|
||||
it("shouldn't have any opacity since gmaps basemap didn't have any", function() {
|
||||
expect(view.options.opacity).toEqual(1);
|
||||
});
|
||||
|
||||
it("should match substitute's subdomains", function() {
|
||||
expect(view.options.subdomains).toEqual(substitute.subdomains);
|
||||
});
|
||||
|
||||
it("shouldn't have an errorTileUrl since gmaps didn't have any", function() {
|
||||
expect(view.options.errorTileUrl).toEqual('');
|
||||
});
|
||||
|
||||
it("shouldn't use osgeo's TMS setting", function() {
|
||||
expect(view.options.tms).toEqual(false);
|
||||
});
|
||||
|
||||
xit("should change keyboard", function() {
|
||||
mapView._setKeyboard(null, false);
|
||||
expect(spy.keyboardChanged).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('attributions', function() {
|
||||
|
||||
var container;
|
||||
|
||||
beforeEach(function() {
|
||||
container = $('<div>').css({
|
||||
'height': '200px',
|
||||
'width': '200px'
|
||||
});
|
||||
});
|
||||
|
||||
it('should render the right attributions', function() {
|
||||
var attributions = mapView.$el.find('.leaflet-control-attribution').text();
|
||||
expect(attributions).toEqual('© CARTO');
|
||||
|
||||
layer = new cdb.geo.CartoDBLayer({
|
||||
attribution: 'custom attribution'
|
||||
});
|
||||
map.addLayer(layer);
|
||||
|
||||
var attributions = mapView.$el.find('.leaflet-control-attribution').text();
|
||||
expect(attributions).toEqual('custom attribution, © CARTO');
|
||||
});
|
||||
|
||||
it('should respect the attribution of existing Leaflet layers', function() {
|
||||
var leafletMap = new L.Map(container[0], {
|
||||
center: [43, 0],
|
||||
zoom: 3
|
||||
});
|
||||
|
||||
// Add a tile layer with some attribution
|
||||
L.tileLayer('http://tile.stamen.com/toner/{z}/{x}/{y}.png', {
|
||||
attribution: 'Stamen'
|
||||
}).addTo(leafletMap);
|
||||
|
||||
mapView = new cdb.geo.LeafletMapView({
|
||||
el: container,
|
||||
map: map,
|
||||
map_object: leafletMap
|
||||
});
|
||||
|
||||
// Add a CartoDB layer with some custom attribution
|
||||
layer = new cdb.geo.CartoDBLayer({
|
||||
attribution: 'custom attribution'
|
||||
});
|
||||
map.addLayer(layer);
|
||||
|
||||
var attributions = mapView.$el.find('.leaflet-control-attribution').text();
|
||||
expect(attributions).toEqual('Leaflet | Stamen, custom attribution, © CARTO');
|
||||
});
|
||||
|
||||
it('should render attributions when the Leaflet map has attributionControl disabled', function() {
|
||||
var leafletMap = new L.Map(container[0], {
|
||||
center: [43, 0],
|
||||
zoom: 3,
|
||||
attributionControl: false
|
||||
});
|
||||
|
||||
// Add a tile layer with some attribution
|
||||
L.tileLayer('http://tile.stamen.com/toner/{z}/{x}/{y}.png', {
|
||||
attribution: 'Stamen'
|
||||
}).addTo(leafletMap);
|
||||
|
||||
mapView = new cdb.geo.LeafletMapView({
|
||||
el: container,
|
||||
map: map,
|
||||
map_object: leafletMap
|
||||
});
|
||||
|
||||
// Add a CartoDB layer with some custom attribution
|
||||
layer = new cdb.geo.CartoDBLayer({
|
||||
attribution: 'custom attribution'
|
||||
});
|
||||
map.addLayer(layer);
|
||||
|
||||
var attributions = mapView.$el.find('.leaflet-control-attribution').text();
|
||||
expect(attributions).toEqual('Stamen, custom attribution, © CARTO');
|
||||
});
|
||||
});
|
||||
|
||||
it("should disable leaflet dragging and double click zooming when the map has drag disabled", function() {
|
||||
var container = $('<div>').css({
|
||||
'height': '200px',
|
||||
'width': '200px'
|
||||
});
|
||||
var map = new cdb.geo.Map({
|
||||
drag: false
|
||||
});
|
||||
var mapView = new cdb.geo.LeafletMapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
expect(mapView.map_leaflet.dragging.enabled()).toBeFalsy();
|
||||
expect(mapView.map_leaflet.doubleClickZoom.enabled()).toBeFalsy();
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,330 @@
|
||||
|
||||
describe("geo.map", function() {
|
||||
|
||||
describe('cdb.geo.MapLayer', function() {
|
||||
var layer;
|
||||
|
||||
beforeEach(function() {
|
||||
layer = new cdb.geo.MapLayer();
|
||||
layer.url = function() {return true};
|
||||
layer.sync = function() {return true};
|
||||
});
|
||||
});
|
||||
|
||||
describe('GMapsBaseLayer', function() {
|
||||
it("should be type GMapsBase", function() {
|
||||
var layer = new cdb.geo.GMapsBaseLayer();
|
||||
expect(layer.get('type')).toEqual("GMapsBase");
|
||||
});
|
||||
});
|
||||
|
||||
describe('TileLayer', function() {
|
||||
it("should be type tiled", function() {
|
||||
var layer = new cdb.geo.TileLayer();
|
||||
expect(layer.get('type')).toEqual("Tiled");
|
||||
});
|
||||
});
|
||||
|
||||
describe('CartoDBLayer', function() {
|
||||
it("should be type CartoDB", function() {
|
||||
var layer = new cdb.geo.CartoDBLayer();
|
||||
expect(layer.get('type')).toEqual("CartoDB");
|
||||
});
|
||||
});
|
||||
|
||||
describe('CartoDBGroupLayer', function() {
|
||||
it("should be type layergroup", function() {
|
||||
var layer = new cdb.geo.CartoDBGroupLayer();
|
||||
expect(layer.get('type')).toEqual("layergroup");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Layers", function() {
|
||||
var layers;
|
||||
|
||||
beforeEach(function() {
|
||||
layers = new cdb.geo.Layers();
|
||||
});
|
||||
|
||||
it("should compare equal layers correctly", function() {
|
||||
var layer1 = new cdb.geo.PlainLayer({ name: 'Positron' });
|
||||
var layer2 = new cdb.geo.PlainLayer({});
|
||||
var layer3 = new cdb.geo.PlainLayer({});
|
||||
var layer4 = new cdb.geo.PlainLayer({});
|
||||
|
||||
expect(layer3.isEqual(layer4)).toBeTruthy();
|
||||
expect(layer1.isEqual(layer2)).not.toBeTruthy();
|
||||
|
||||
layers.add(layer4);
|
||||
layers.add(layer3);
|
||||
|
||||
expect(layer3.isEqual(layer4)).toBeTruthy();
|
||||
})
|
||||
|
||||
it("should compare TileLayers", function() {
|
||||
var layer1 = new cdb.geo.TileLayer({ urlTemplate: 'urlTemplate', name: 'layer1', other: 'something' });
|
||||
var layer2 = new cdb.geo.TileLayer({ urlTemplate: 'urlTemplate', name: 'layer2', other: 'else' });
|
||||
|
||||
expect(layer1.isEqual(layer2)).toBeFalsy();
|
||||
|
||||
layer2.set({ name: 'layer1' }, { silent: true});
|
||||
|
||||
expect(layer1.isEqual(layer2)).toBeTruthy();
|
||||
})
|
||||
|
||||
it("should re-assign order when new layers are added to the collection", function() {
|
||||
var baseLayer = new cdb.geo.TileLayer();
|
||||
var layer1 = new cdb.geo.CartoDBLayer();
|
||||
var layer2 = new cdb.geo.CartoDBLayer();
|
||||
var layer3 = new cdb.geo.CartoDBLayer();
|
||||
|
||||
// Sets the order to 0
|
||||
layers.add(baseLayer);
|
||||
|
||||
expect(baseLayer.get('order')).toEqual(0);
|
||||
|
||||
// Sets the order to 1
|
||||
layers.add(layer1);
|
||||
layers.add(layer2);
|
||||
|
||||
expect(baseLayer.get('order')).toEqual(0);
|
||||
expect(layer1.get('order')).toEqual(1);
|
||||
expect(layer2.get('order')).toEqual(2);
|
||||
|
||||
// Sets the order to 1 and re-orders the rest of the layers
|
||||
layers.add(layer3, { at: 1});
|
||||
|
||||
expect(baseLayer.get('order')).toEqual(0);
|
||||
expect(layer1.get('order')).toEqual(2);
|
||||
expect(layer2.get('order')).toEqual(3);
|
||||
expect(layer3.get('order')).toEqual(1);
|
||||
|
||||
var torqueLayer = new cdb.geo.TorqueLayer({});
|
||||
|
||||
// Torque layer should be at the top
|
||||
layers.add(torqueLayer);
|
||||
|
||||
expect(baseLayer.get('order')).toEqual(0);
|
||||
expect(layer1.get('order')).toEqual(2);
|
||||
expect(layer2.get('order')).toEqual(3);
|
||||
expect(layer3.get('order')).toEqual(1);
|
||||
expect(torqueLayer.get('order')).toEqual(4);
|
||||
|
||||
var tiledLayer = new cdb.geo.TileLayer({});
|
||||
|
||||
// Tiled layer should be at the top
|
||||
layers.add(tiledLayer);
|
||||
|
||||
expect(baseLayer.get('order')).toEqual(0);
|
||||
expect(layer1.get('order')).toEqual(2);
|
||||
expect(layer2.get('order')).toEqual(3);
|
||||
expect(layer3.get('order')).toEqual(1);
|
||||
expect(torqueLayer.get('order')).toEqual(4);
|
||||
expect(tiledLayer.get('order')).toEqual(5);
|
||||
|
||||
var layer4 = new cdb.geo.CartoDBLayer({});
|
||||
layers.add(layer4);
|
||||
|
||||
expect(baseLayer.get('order')).toEqual(0);
|
||||
expect(layer1.get('order')).toEqual(2);
|
||||
expect(layer2.get('order')).toEqual(3);
|
||||
expect(layer3.get('order')).toEqual(1);
|
||||
expect(layer4.get('order')).toEqual(4);
|
||||
expect(torqueLayer.get('order')).toEqual(5);
|
||||
expect(tiledLayer.get('order')).toEqual(6);
|
||||
});
|
||||
|
||||
it("should re-assign order when new layers are removed from the collection", function() {
|
||||
var baseLayer = new cdb.geo.TileLayer();
|
||||
var layer1 = new cdb.geo.CartoDBLayer();
|
||||
var layer2 = new cdb.geo.CartoDBLayer();
|
||||
var torqueLayer = new cdb.geo.TorqueLayer({});
|
||||
var labelsLayer = new cdb.geo.TileLayer();
|
||||
|
||||
// Sets the order to 0
|
||||
layers.add(baseLayer);
|
||||
layers.add(layer1);
|
||||
layers.add(layer2);
|
||||
layers.add(torqueLayer);
|
||||
layers.add(labelsLayer);
|
||||
|
||||
expect(baseLayer.get('order')).toEqual(0);
|
||||
expect(layer1.get('order')).toEqual(1);
|
||||
expect(layer2.get('order')).toEqual(2);
|
||||
expect(torqueLayer.get('order')).toEqual(3);
|
||||
expect(labelsLayer.get('order')).toEqual(4);
|
||||
|
||||
layers.remove(layer1);
|
||||
|
||||
expect(baseLayer.get('order')).toEqual(0);
|
||||
expect(layer2.get('order')).toEqual(1);
|
||||
expect(torqueLayer.get('order')).toEqual(2);
|
||||
expect(labelsLayer.get('order')).toEqual(3);
|
||||
|
||||
layers.remove(torqueLayer);
|
||||
|
||||
expect(baseLayer.get('order')).toEqual(0);
|
||||
expect(layer2.get('order')).toEqual(1);
|
||||
expect(labelsLayer.get('order')).toEqual(2);
|
||||
|
||||
layers.remove(labelsLayer);
|
||||
|
||||
expect(baseLayer.get('order')).toEqual(0);
|
||||
expect(layer2.get('order')).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Map", function() {
|
||||
var map;
|
||||
|
||||
beforeEach(function() {
|
||||
map = new cdb.geo.Map();
|
||||
});
|
||||
|
||||
it("should raise only one change event on setBounds", function() {
|
||||
var c = 0;
|
||||
map.bind('change:view_bounds_ne', function() {
|
||||
c++;
|
||||
});
|
||||
map.setBounds([[1,2],[1,2]]);
|
||||
expect(c).toEqual(1);
|
||||
});
|
||||
|
||||
it("should not change center or zoom when the bounds are not ok", function() {
|
||||
var c = 0;
|
||||
map.bind('change:center', function() {
|
||||
c++;
|
||||
});
|
||||
map.setBounds([[1,2],[1,2]]);
|
||||
expect(c).toEqual(0);
|
||||
});
|
||||
|
||||
it("should not change bounds when map size is 0", function() {
|
||||
map.set('zoom', 10);
|
||||
var bounds = [[43.100982876188546, 35.419921875], [60.23981116999893, 69.345703125]]
|
||||
map.fitBounds(bounds, {x: 0, y: 0});
|
||||
expect(map.get('zoom')).toEqual(10);
|
||||
});
|
||||
|
||||
it("should adjust zoom to layer", function() {
|
||||
expect(map.get('maxZoom')).toEqual(40);
|
||||
expect(map.get('minZoom')).toEqual(0);
|
||||
|
||||
var layer = new cdb.geo.PlainLayer({ minZoom: 5, maxZoom: 20 });
|
||||
map.layers.reset(layer);
|
||||
expect(map.get('maxZoom')).toEqual(20);
|
||||
expect(map.get('minZoom')).toEqual(5);
|
||||
|
||||
var layer = new cdb.geo.PlainLayer({ minZoom: "7", maxZoom: "31" });
|
||||
map.layers.reset(layer);
|
||||
expect(map.get('maxZoom')).toEqual(31);
|
||||
expect(map.get('minZoom')).toEqual(7);
|
||||
});
|
||||
|
||||
it("shouldn't set a NaN zoom", function() {
|
||||
var layer = new cdb.geo.PlainLayer({ minZoom: NaN, maxZoom: NaN });
|
||||
map.layers.reset(layer);
|
||||
expect(map.get('maxZoom')).toEqual(40);
|
||||
expect(map.get('minZoom')).toEqual(0);
|
||||
});
|
||||
|
||||
it('should update the attributions of the map when layers are reset/added/removed', function() {
|
||||
|
||||
map = new cdb.geo.Map();
|
||||
var DEFAULT_CARTO_ATTRIBUTION = '© <a href="https://carto.com/attributions" target="_blank">CARTO</a>';
|
||||
|
||||
// Map has the default CARTO attribution
|
||||
expect(map.get('attribution')).toEqual([
|
||||
cdb.core.sanitize.html("© <a href='https://carto.com/attributions' target='_blank'>CARTO</a>")
|
||||
]);
|
||||
|
||||
var layer1 = new cdb.geo.CartoDBLayer({ attribution: 'attribution1' });
|
||||
var layer2 = new cdb.geo.CartoDBLayer({ attribution: 'attribution1' });
|
||||
var layer3 = new cdb.geo.CartoDBLayer({ attribution: 'wadus' });
|
||||
var layer4 = new cdb.geo.CartoDBLayer({ attribution: '' });
|
||||
|
||||
map.layers.reset([ layer1, layer2, layer3, layer4 ]);
|
||||
|
||||
// Attributions have been updated removing duplicated and empty attributions
|
||||
expect(map.get('attribution')).toEqual([
|
||||
"attribution1",
|
||||
"wadus",
|
||||
DEFAULT_CARTO_ATTRIBUTION
|
||||
]);
|
||||
|
||||
var layer = new cdb.geo.CartoDBLayer({ attribution: 'attribution2' });
|
||||
|
||||
map.layers.add(layer);
|
||||
|
||||
// The attribution of the new layer has been appended before the default CARTO attribution
|
||||
expect(map.get('attribution')).toEqual([
|
||||
"attribution1",
|
||||
"wadus",
|
||||
"attribution2",
|
||||
DEFAULT_CARTO_ATTRIBUTION
|
||||
]);
|
||||
|
||||
layer.set('attribution', 'new attribution');
|
||||
|
||||
// The attribution of the layer has been updated in the map
|
||||
expect(map.get('attribution')).toEqual([
|
||||
"attribution1",
|
||||
"wadus",
|
||||
"new attribution",
|
||||
DEFAULT_CARTO_ATTRIBUTION
|
||||
]);
|
||||
|
||||
map.layers.remove(layer);
|
||||
|
||||
expect(map.get('attribution')).toEqual([
|
||||
"attribution1",
|
||||
"wadus",
|
||||
DEFAULT_CARTO_ATTRIBUTION
|
||||
]);
|
||||
|
||||
// Addind a layer with the default attribution
|
||||
var layer = new cdb.geo.CartoDBLayer();
|
||||
|
||||
map.layers.add(layer, { at: 0 });
|
||||
|
||||
// Default CARTO only appears once and it's the last one
|
||||
expect(map.get('attribution')).toEqual([
|
||||
"attribution1",
|
||||
"wadus",
|
||||
DEFAULT_CARTO_ATTRIBUTION
|
||||
]);
|
||||
})
|
||||
});
|
||||
|
||||
describe('MapView', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
this.container = $('<div>').css('height', '200px');
|
||||
|
||||
this.map = new cdb.geo.Map();
|
||||
this.mapView = new cdb.geo.MapView({
|
||||
el: this.container,
|
||||
map: this.map
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to add a infowindow', function() {
|
||||
var infow = new cdb.geo.ui.Infowindow({mapView: this.mapView, model: new Backbone.Model()});
|
||||
this.mapView.addInfowindow(infow);
|
||||
|
||||
expect(this.mapView._subviews[infow.cid]).toBeTruthy()
|
||||
expect(this.mapView._subviews[infow.cid] instanceof cdb.geo.ui.Infowindow).toBeTruthy()
|
||||
});
|
||||
|
||||
it('should be able to retrieve the infowindows', function() {
|
||||
var infow = new cdb.geo.ui.Infowindow({mapView: this.mapView, model: new Backbone.Model()});
|
||||
this.mapView._subviews['irrelevant'] = new Backbone.View();
|
||||
this.mapView.addInfowindow(infow);
|
||||
|
||||
var infowindows = this.mapView.getInfoWindows()
|
||||
|
||||
expect(infowindows.length).toEqual(1);
|
||||
expect(infowindows[0]).toEqual(infow);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,230 @@
|
||||
describe("cdb.geo.ui.Annotation", function() {
|
||||
|
||||
var data, view, map, mapView;
|
||||
|
||||
describe("Annotation unbinding", function() {
|
||||
|
||||
var spy;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
map = new cdb.geo.Map();
|
||||
|
||||
container = $('<div>').css('height', '200px');
|
||||
|
||||
mapView = new cdb.geo.GoogleMapsMapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
spy = spyOn(cdb.geo.ui.Annotation.prototype, '_place');
|
||||
|
||||
view = new cdb.geo.ui.Annotation({
|
||||
text: "You are <strong>here</strong>",
|
||||
latlng: [40, 2],
|
||||
mapView: mapView,
|
||||
minZoom: 0,
|
||||
maxZoom: 40,
|
||||
});
|
||||
|
||||
mapView.$el.append(view.render().$el);
|
||||
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
view.clean();
|
||||
container.remove();
|
||||
});
|
||||
|
||||
it("should unbind from the map", function(done) {
|
||||
|
||||
mapView.map.bind('change', spy, view);
|
||||
|
||||
view.clean();
|
||||
|
||||
mapView.map.set('center', [10, 10]);
|
||||
|
||||
setTimeout(function(){
|
||||
expect(spy.calls.count()).toEqual(1);
|
||||
done();
|
||||
}, 1000);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Annotation movement", function() {
|
||||
|
||||
var spy;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
map = new cdb.geo.Map();
|
||||
|
||||
container = $('<div>').css('height', '200px');
|
||||
|
||||
mapView = new cdb.geo.GoogleMapsMapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
spy = spyOn(cdb.geo.ui.Annotation.prototype, '_place');
|
||||
|
||||
view = new cdb.geo.ui.Annotation({
|
||||
text: "You are <strong>here</strong>",
|
||||
latlng: [40, 2],
|
||||
mapView: mapView,
|
||||
minZoom: 0,
|
||||
maxZoom: 40,
|
||||
});
|
||||
|
||||
mapView.$el.append(view.render().$el);
|
||||
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
view.clean();
|
||||
container.remove();
|
||||
});
|
||||
|
||||
it("should move when the map moves", function(done) {
|
||||
|
||||
mapView.map.bind('change', spy);
|
||||
mapView.map.set('center', [10, 10]);
|
||||
|
||||
setTimeout(function(){
|
||||
expect(spy.calls.count()).toEqual(2);
|
||||
done();
|
||||
}, 200);
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
describe("Annotation rendering", function() {
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
map = new cdb.geo.Map();
|
||||
|
||||
container = $('<div>').css('height', '200px');
|
||||
|
||||
mapView = new cdb.geo.GoogleMapsMapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
view = new cdb.geo.ui.Annotation({
|
||||
text: "This is <a href='http://www.carto.com'>a link</a> and this <a href='http://www.carto.com'>too</a>",
|
||||
latlng: [40, 2],
|
||||
mapView: mapView,
|
||||
minZoom: 0,
|
||||
maxZoom: 40,
|
||||
style: {
|
||||
textAlign: "left",
|
||||
zIndex: 1000,
|
||||
textAlign: "right",
|
||||
"font-size": "13",
|
||||
fontFamilyName: "Helvetica",
|
||||
"box-color": "#F84F40",
|
||||
boxOpacity: 0.7,
|
||||
boxPadding: 10,
|
||||
"line-width": 50
|
||||
}
|
||||
});
|
||||
|
||||
mapView.$el.append(view.render().$el);
|
||||
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
view.clean();
|
||||
container.remove();
|
||||
});
|
||||
|
||||
it("should render the right links", function(done) {
|
||||
setTimeout(function() {
|
||||
expect(view.$el.find(".text a:first-child").attr("target")).toEqual("_top");
|
||||
expect(view.$el.find(".text a:last-child").attr("target")).toEqual("_top");
|
||||
done();
|
||||
}, 700);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Annotation setters", function() {
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
map = new cdb.geo.Map();
|
||||
|
||||
container = $('<div>').css('height', '200px');
|
||||
|
||||
mapView = new cdb.geo.GoogleMapsMapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
view = new cdb.geo.ui.Annotation({
|
||||
text: "You are <strong>here</strong>",
|
||||
latlng: [40, 2],
|
||||
mapView: mapView,
|
||||
minZoom: 0,
|
||||
maxZoom: 40,
|
||||
style: {
|
||||
textAlign: "left",
|
||||
zIndex: 1000,
|
||||
textAlign: "right",
|
||||
"font-size": "13",
|
||||
fontFamilyName: "Helvetica",
|
||||
"box-color": "#F84F40",
|
||||
boxOpacity: 0.7,
|
||||
boxPadding: 10,
|
||||
"line-width": 50
|
||||
}
|
||||
});
|
||||
|
||||
mapView.$el.append(view.render().$el);
|
||||
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
view.clean();
|
||||
container.remove();
|
||||
});
|
||||
|
||||
it("should render", function(done) {
|
||||
setTimeout(function() {
|
||||
expect(view.$el.find(".text").html()).toEqual("You are <strong>here</strong>");
|
||||
expect(view.$el.css("background-color").indexOf('rgba(248, 79, 64')).toEqual(0);
|
||||
expect(view.$el.find(".stick").css("background-color")).toEqual('rgb(51, 51, 51)');
|
||||
expect(view.$el.find(".text").css("color")).toEqual('rgb(255, 255, 255)');
|
||||
done();
|
||||
}, 700);
|
||||
});
|
||||
|
||||
it("should allow to change the text", function() {
|
||||
expect(view.model.set("text", "Now you are here"));
|
||||
expect(view.$el.find(".text").html()).toEqual("Now you are here");
|
||||
});
|
||||
|
||||
it("should allow to change the text", function() {
|
||||
expect(view.setText("I'm here"));
|
||||
expect(view.$el.find(".text").text()).toEqual("I'm here");
|
||||
});
|
||||
|
||||
it("should allow to change the style", function() {
|
||||
expect(view.setStyle("color", "#000000"));
|
||||
expect(view.$el.find(".text").css("color")).toEqual('rgb(0, 0, 0)');
|
||||
});
|
||||
|
||||
it("should generate a standard name for a property", function() {
|
||||
expect(view._getStandardPropertyName("")).toEqual(undefined);
|
||||
expect(view._getStandardPropertyName("color")).toEqual("color");
|
||||
expect(view._getStandardPropertyName("font-size")).toEqual("fontSize");
|
||||
expect(view._getStandardPropertyName("font-family-name")).toEqual("fontFamilyName");
|
||||
expect(view._getStandardPropertyName("z-index")).toEqual("zIndex");
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,572 @@
|
||||
describe('Sublayers', function() {
|
||||
var layerDefinition, sublayer;
|
||||
|
||||
beforeEach(function() {
|
||||
var layer_definition = {
|
||||
version: '1.0.0',
|
||||
stat_tag: 'vis_id',
|
||||
layers: [
|
||||
{
|
||||
type: 'cartodb',
|
||||
options: {
|
||||
sql: 'select * from ne_10m_populated_places_simple',
|
||||
cartocss: '#layer { marker-fill: red; }',
|
||||
interactivity: ['test', 'cartodb_id']
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'cartodb',
|
||||
options: {
|
||||
sql: "select * from european_countries_export",
|
||||
cartocss: '#layer { polygon-fill: #000; polygon-opacity: 0.8;}',
|
||||
cartocss_version : '2.0.0',
|
||||
interactivity: [' test2 ', 'cartodb_id2']
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
_.extend(LayerDefinition.prototype, Backbone.Events);
|
||||
|
||||
layerDefinition = new LayerDefinition(layer_definition, {});
|
||||
|
||||
sublayer = layerDefinition.getSubLayer(0);
|
||||
});
|
||||
|
||||
describe('SubLayerFactory', function() {
|
||||
|
||||
it('should return a CartoDBSublayer', function() {
|
||||
var sublayer = SubLayerFactory.createSublayer('', layerDefinition, 0);
|
||||
expect(sublayer instanceof CartoDBSubLayer).toBeTruthy();
|
||||
|
||||
var sublayer = SubLayerFactory.createSublayer('mapnik', layerDefinition, 0);
|
||||
expect(sublayer instanceof CartoDBSubLayer).toBeTruthy();
|
||||
|
||||
var sublayer = SubLayerFactory.createSublayer('cartodb', layerDefinition, 0);
|
||||
expect(sublayer instanceof CartoDBSubLayer).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return an HttpSublayer', function() {
|
||||
var sublayer = SubLayerFactory.createSublayer('http', layerDefinition, 0);
|
||||
expect(sublayer instanceof HttpSubLayer).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should be case insensitive', function() {
|
||||
var sublayer = SubLayerFactory.createSublayer('cARToDB', layerDefinition, 0);
|
||||
expect(sublayer instanceof CartoDBSubLayer).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should throw an error if type is not supported', function() {
|
||||
expect(function() {
|
||||
SubLayerFactory.createSublayer('unsupported type');
|
||||
}).toThrow('Sublayer type not supported');
|
||||
})
|
||||
});
|
||||
|
||||
describe('SublayerBase', function() {
|
||||
|
||||
describe('.remove', function() {
|
||||
|
||||
it('should throw and error if layer was already removed', function() {
|
||||
sublayer.remove()
|
||||
|
||||
// Try to remove again
|
||||
expect(function() {
|
||||
sublayer.remove();
|
||||
}).toThrow('sublayer was removed');
|
||||
|
||||
});
|
||||
|
||||
it('should remove itself from the layer', function() {
|
||||
sublayer.remove()
|
||||
|
||||
expect(layerDefinition.getSubLayerCount()).toEqual(1);
|
||||
expect(layerDefinition.getSubLayer(0)).not.toEqual(sublayer);
|
||||
});
|
||||
|
||||
it('should unbind the interaction', function() {
|
||||
spyOn(sublayer, '_unbindInteraction');
|
||||
|
||||
sublayer.remove();
|
||||
|
||||
expect(sublayer._unbindInteraction).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should trigger a "remove" event', function(done) {
|
||||
var callback = function(subl) {
|
||||
expect(subl).toEqual(sublayer);
|
||||
done();
|
||||
};
|
||||
|
||||
sublayer.on('remove', callback);
|
||||
|
||||
sublayer.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.toggle', function() {
|
||||
|
||||
it('should show or hide the sublayer', function() {
|
||||
sublayer.set('hidden', false);
|
||||
|
||||
sublayer.toggle();
|
||||
|
||||
expect(sublayer.get('hidden')).toEqual(true);
|
||||
|
||||
sublayer.toggle();
|
||||
|
||||
expect(sublayer.get('hidden')).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.show', function() {
|
||||
|
||||
it('should show the layer', function() {
|
||||
sublayer.set('hidden', true);
|
||||
|
||||
sublayer.show();
|
||||
|
||||
expect(sublayer.get('hidden')).toBeUndefined();
|
||||
})
|
||||
});
|
||||
|
||||
describe('.hide', function() {
|
||||
|
||||
it('should hide the layer', function() {
|
||||
sublayer.set('hidden', false);
|
||||
|
||||
sublayer.hide();
|
||||
|
||||
expect(sublayer.get('hidden')).toEqual(true);
|
||||
})
|
||||
});
|
||||
|
||||
describe('.isVisible', function() {
|
||||
|
||||
it('should return true if sublayer is visible', function() {
|
||||
sublayer.set({'hidden': undefined});
|
||||
|
||||
expect(sublayer.isVisible()).toBeTruthy();
|
||||
|
||||
sublayer.set({'hidden': false});
|
||||
|
||||
expect(sublayer.isVisible()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return false if sublayer is hidden', function() {
|
||||
sublayer.set({'hidden': true});
|
||||
|
||||
expect(sublayer.isVisible()).toBeFalsy();
|
||||
});
|
||||
})
|
||||
|
||||
describe('.set', function() {
|
||||
|
||||
it('should throw an error if the sublayer was removed', function() {
|
||||
sublayer.remove();
|
||||
|
||||
expect(function() {
|
||||
sublayer.set({ wadus: true });
|
||||
}).toThrow('sublayer was removed');
|
||||
});
|
||||
|
||||
it('should set the attribute', function() {
|
||||
sublayer.set({ wadus: true });
|
||||
|
||||
expect(sublayer.get('wadus')).toEqual(true);
|
||||
});
|
||||
|
||||
it('should trigger a "change:visibility" event if the visibility has changed', function(done) {
|
||||
var callback = function(subl, hidden) {
|
||||
expect(subl).toEqual(sublayer);
|
||||
expect(hidden).toEqual(true);
|
||||
done();
|
||||
}
|
||||
|
||||
sublayer.on('change:visibility', callback);
|
||||
|
||||
sublayer.set({ hidden: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe('.unset', function() {
|
||||
|
||||
it('should delete an attribute', function() {
|
||||
sublayer.set({ wadus: true });
|
||||
expect(sublayer.get('wadus')).toEqual(true);
|
||||
|
||||
sublayer.unset('wadus');
|
||||
|
||||
expect(sublayer.get('wadus')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.get', function() {
|
||||
|
||||
it('should throw and error if layer was already removed', function() {
|
||||
sublayer.remove()
|
||||
|
||||
// Try to remove again
|
||||
expect(function() {
|
||||
sublayer.get('wadus');
|
||||
}).toThrow('sublayer was removed');
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('CartoDBSubLayer', function() {
|
||||
|
||||
describe('toJSON', function() {
|
||||
|
||||
it('should serialize the sublayer', function() {
|
||||
expect(sublayer.toJSON()).toEqual({
|
||||
type: 'cartodb',
|
||||
options: {
|
||||
sql: 'select * from ne_10m_populated_places_simple',
|
||||
cartocss: '#layer { marker-fill: red; }',
|
||||
cartocss_version: '2.1.0',
|
||||
interactivity: ['test', 'cartodb_id']
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should include the cartocss_version if present', function() {
|
||||
sublayer.set({
|
||||
cartocss_version: 'X.X.X',
|
||||
});
|
||||
|
||||
expect(sublayer.toJSON().options.cartocss_version).toEqual('X.X.X');
|
||||
}),
|
||||
|
||||
it('should set the default cartocss_version if not present', function() {
|
||||
expect(sublayer.toJSON().options.cartocss_version).toEqual('2.1.0');
|
||||
}),
|
||||
|
||||
it('should include attributes option if interactivity is present', function() {
|
||||
sublayer.set({
|
||||
interactivity: [],
|
||||
attributes: ['column1', 'column2']
|
||||
});
|
||||
|
||||
expect(sublayer.toJSON().options.attributes).toBeUndefined();
|
||||
|
||||
sublayer.set({
|
||||
interactivity: ['column1'],
|
||||
attributes: ['column1', 'column2']
|
||||
});
|
||||
|
||||
expect(sublayer.toJSON().options.attributes).toEqual({
|
||||
id: 'cartodb_id',
|
||||
columns: ['column1', 'column2']
|
||||
});
|
||||
});
|
||||
|
||||
it('should include attributes option when there are attributes', function() {
|
||||
sublayer.set({
|
||||
interactivity: ['column1'],
|
||||
attributes: undefined
|
||||
});
|
||||
|
||||
expect(sublayer.toJSON().options.attributes).toBeUndefined();
|
||||
})
|
||||
|
||||
it('should include geometry options if raster option is true', function() {
|
||||
sublayer.set({raster: true});
|
||||
|
||||
expect(sublayer.toJSON().options.geom_column).toEqual("the_raster_webmercator");
|
||||
expect(sublayer.toJSON().options.geom_type).toEqual("raster");
|
||||
expect(sublayer.toJSON().options.cartocss_version).toEqual('2.3.0');
|
||||
expect(sublayer.toJSON().options.raster_band).toEqual(0);
|
||||
});
|
||||
|
||||
it('should include geometry options with a given cartocss_version if raster option is true', function() {
|
||||
sublayer.set({
|
||||
raster: true,
|
||||
raster_band: 2,
|
||||
cartocss_version: '2.4.0'
|
||||
});
|
||||
|
||||
expect(sublayer.toJSON().options.geom_column).toEqual("the_raster_webmercator");
|
||||
expect(sublayer.toJSON().options.geom_type).toEqual("raster");
|
||||
expect(sublayer.toJSON().options.cartocss_version).toEqual('2.4.0');
|
||||
expect(sublayer.toJSON().options.raster_band).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isValid', function() {
|
||||
|
||||
it('should return true if the required options are present', function() {
|
||||
expect(sublayer.isValid()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return false if any of the required options are not present', function() {
|
||||
var cartocss = sublayer.get('cartocss');
|
||||
|
||||
sublayer.set({ cartocss: undefined });
|
||||
expect(sublayer.isValid()).toBeFalsy();
|
||||
|
||||
sublayer.set({
|
||||
sql: undefined,
|
||||
cartocss: cartocss,
|
||||
});
|
||||
|
||||
expect(sublayer.isValid()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('event binding', function() {
|
||||
|
||||
var events = [
|
||||
['featureOver'],
|
||||
['featureOut'],
|
||||
['featureClick'],
|
||||
['layermouseover', 'mouseover'],
|
||||
['layermouseout', 'mouseout']
|
||||
];
|
||||
|
||||
events.forEach(function(event) {
|
||||
var signal = event[0];
|
||||
var alias = event[1] || signal;
|
||||
|
||||
it("should respond to " + signal + " events on the layer if the position matches", function(done) {
|
||||
sublayer.on(alias, function(index) {
|
||||
expect(index).toEqual(0);
|
||||
done();
|
||||
});
|
||||
|
||||
layerDefinition.trigger(signal, 0);
|
||||
});
|
||||
|
||||
it("should NOT respond to " + signal + " events on the layer if the position doesn't match", function() {
|
||||
var callback = jasmine.createSpy('callback');
|
||||
|
||||
sublayer.on(alias, function(){
|
||||
callback();
|
||||
});
|
||||
|
||||
layerDefinition.trigger(signal, 1);
|
||||
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('.infowindow', function() {
|
||||
|
||||
it('should be a Backbone model with the infowindow', function() {
|
||||
var fields = [
|
||||
{
|
||||
position: 1,
|
||||
name: "city",
|
||||
title: true
|
||||
}
|
||||
];
|
||||
layerDefinition.layers[0].infowindow = {
|
||||
fields: fields
|
||||
}
|
||||
|
||||
// Force the initialization of the sublayer
|
||||
layerDefinition.layers[0].sub = undefined;
|
||||
|
||||
var sublayer = layerDefinition.getSubLayer(0);
|
||||
|
||||
expect(sublayer.infowindow instanceof Backbone.Model).toBeTruthy();
|
||||
expect(sublayer.infowindow.get('fields')).toEqual(fields);
|
||||
});
|
||||
|
||||
it('should update the infowindow in the layer definition if the infowindow changes', function() {
|
||||
sublayer.infowindow.set({fields: 'wadus'});
|
||||
|
||||
expect(sublayer._parent.getLayer(sublayer._position).infowindow).toEqual({
|
||||
fields: 'wadus'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('.setSQL', function() {
|
||||
|
||||
it('should set the SQL attribute', function() {
|
||||
sublayer.setSQL('wadus');
|
||||
|
||||
expect(sublayer.get('sql')).toEqual('wadus');
|
||||
expect(sublayer.getSQL()).toEqual('wadus');
|
||||
});
|
||||
});
|
||||
|
||||
describe('.setCartoCSS', function() {
|
||||
|
||||
it('should set the cartocss attribute', function() {
|
||||
sublayer.setCartoCSS('wadus');
|
||||
|
||||
expect(sublayer.get('cartocss')).toEqual('wadus');
|
||||
expect(sublayer.getCartoCSS()).toEqual('wadus');
|
||||
});
|
||||
});
|
||||
|
||||
describe('.setInteractivity', function() {
|
||||
|
||||
it('should set the interactivity attribute', function() {
|
||||
sublayer.setInteractivity('wadus');
|
||||
|
||||
expect(sublayer.get('interactivity')).toEqual('wadus');
|
||||
})
|
||||
});
|
||||
|
||||
describe('.getInteractivity', function() {
|
||||
|
||||
it('should return undefined when no interactivity is present', function() {
|
||||
sublayer.setInteractivity(undefined);
|
||||
|
||||
expect(sublayer.getInteractivity()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should convert string with fields to array', function() {
|
||||
sublayer.setInteractivity('field1, field2');
|
||||
|
||||
expect(sublayer.getInteractivity()).toEqual(['field1', 'field2']);
|
||||
});
|
||||
|
||||
it('should remove whitespaces from field names', function() {
|
||||
sublayer.setInteractivity([' field1 ', ' field2']);
|
||||
|
||||
expect(sublayer.getInteractivity()).toEqual(['field1', 'field2']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getAttributes', function() {
|
||||
|
||||
it('should return the attributes from the definition if present and remove whitespaces from columns', function() {
|
||||
sublayer.set({
|
||||
attributes: [' field1 ', 'field2']
|
||||
});
|
||||
|
||||
expect(sublayer.getAttributes()).toEqual(['field1', 'field2']);
|
||||
});
|
||||
|
||||
it('should return the attributes from the infowindow fields', function() {
|
||||
sublayer.infowindow.set('fields', [ { name: 'field1 '}, { name: ' field2 '}]);
|
||||
|
||||
expect(sublayer.getAttributes()).toEqual(['field1', 'field2']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.setInteraction', function() {
|
||||
|
||||
it('should set the interactivity attribute', function() {
|
||||
sublayer.setInteractivity('wadus');
|
||||
|
||||
expect(sublayer.get('interactivity')).toEqual('wadus');
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
describe('HttpSubLayer', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
var layer_definition = {
|
||||
version: '1.0.0',
|
||||
stat_tag: 'vis_id',
|
||||
layers: [
|
||||
{
|
||||
type: 'http',
|
||||
options: {
|
||||
urlTemplate: "http://{s}.example.com/{z}/{x}/{y}.png",
|
||||
subdomains: ['a', 'b', 'c'],
|
||||
tms: false
|
||||
},
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
layerDefinition = new LayerDefinition(layer_definition, {});
|
||||
|
||||
sublayer = layerDefinition.getSubLayer(0);
|
||||
});
|
||||
|
||||
describe('toJSON', function() {
|
||||
|
||||
it('should serialize the sublayer', function() {
|
||||
expect(sublayer.toJSON()).toEqual({
|
||||
type: 'http',
|
||||
options: {
|
||||
urlTemplate: "http://{s}.example.com/{z}/{x}/{y}.png",
|
||||
subdomains: ['a', 'b', 'c'],
|
||||
tms: false
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('should not include optional params if not present', function() {
|
||||
sublayer.set({
|
||||
subdomains: undefined,
|
||||
tms: undefined
|
||||
});
|
||||
|
||||
expect(sublayer.toJSON()).toEqual({
|
||||
type: 'http',
|
||||
options: {
|
||||
urlTemplate: "http://{s}.example.com/{z}/{x}/{y}.png"
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
describe('isValid', function() {
|
||||
|
||||
it('should return true if the required options are present', function() {
|
||||
expect(sublayer.isValid()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return false if any of the required options are not present', function() {
|
||||
sublayer.set({ urlTemplate: undefined });
|
||||
expect(sublayer.isValid()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('event binding', function() {
|
||||
|
||||
it("should NOT respond to events on the layer", function() {
|
||||
var callback = jasmine.createSpy('callback');
|
||||
|
||||
sublayer.on('featureOver', function(){
|
||||
callback();
|
||||
});
|
||||
|
||||
layerDefinition.trigger('featureOver', 0);
|
||||
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.setURLTemplate', function(){
|
||||
|
||||
it('should set the urlTemplate attribute', function() {
|
||||
sublayer.setURLTemplate('template');
|
||||
|
||||
expect(sublayer.get('urlTemplate')).toEqual('template');
|
||||
expect(sublayer.getURLTemplate()).toEqual('template');
|
||||
});
|
||||
});
|
||||
|
||||
describe('.setSubdomains', function() {
|
||||
|
||||
it('should set the subdomains attribute', function() {
|
||||
sublayer.setSubdomains('subdomains');
|
||||
|
||||
expect(sublayer.get('subdomains')).toEqual('subdomains');
|
||||
expect(sublayer.getSubdomains()).toEqual('subdomains');
|
||||
});
|
||||
});
|
||||
|
||||
describe('.setTms', function() {
|
||||
|
||||
it('should set the tmps attribute', function() {
|
||||
sublayer.setTms('tms');
|
||||
|
||||
expect(sublayer.get('tms')).toEqual('tms');
|
||||
expect(sublayer.getTms()).toEqual('tms');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,87 @@
|
||||
describe("common.geo.ui.Header", function() {
|
||||
|
||||
var header, template;
|
||||
|
||||
afterEach(function() {
|
||||
header.clean();
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
template = cdb.core.Template.compile(
|
||||
' \
|
||||
<div class="content">\
|
||||
<div class="title">{{{ title }}}</div>\
|
||||
<div class="description">{{{ description }}}</div>\
|
||||
</div>',
|
||||
'mustache'
|
||||
);
|
||||
|
||||
header = new cdb.geo.ui.Header({
|
||||
model: new cdb.core.Model({
|
||||
extra: {
|
||||
title: 'Title',
|
||||
description: 'Description <a href="http://test.es">Test</a>',
|
||||
show_title: true,
|
||||
show_descriptin: true
|
||||
}
|
||||
}),
|
||||
template: template
|
||||
});
|
||||
});
|
||||
|
||||
it("should render description links with target attribute included", function() {
|
||||
header.render();
|
||||
expect(header.$('.description a').attr('target')).toBe('_blank');
|
||||
|
||||
// Overwritting target attribute if exists
|
||||
var h1 = new cdb.geo.ui.Header({
|
||||
model: new cdb.core.Model({
|
||||
extra: {
|
||||
title: 'Title',
|
||||
description: "Description <a href='http://test.es' target='_parent'>Test</a>",
|
||||
show_title: true,
|
||||
show_descriptin: true
|
||||
}
|
||||
}),
|
||||
template: template
|
||||
});
|
||||
|
||||
h1.render();
|
||||
expect(h1.$('.description a').attr('target')).toBe('_blank');
|
||||
|
||||
// Working with simple and double quotes
|
||||
var h2 = new cdb.geo.ui.Header({
|
||||
model: new cdb.core.Model({
|
||||
extra: {
|
||||
title: 'Title',
|
||||
description: "Description <a href='http://test.es'>Test</a>",
|
||||
show_title: true,
|
||||
show_descriptin: true
|
||||
}
|
||||
}),
|
||||
template: template
|
||||
});
|
||||
|
||||
h2.render();
|
||||
expect(h2.$('.description a').attr('target')).toBe('_blank');
|
||||
|
||||
// Don't remove other attributes
|
||||
var h1 = new cdb.geo.ui.Header({
|
||||
model: new cdb.core.Model({
|
||||
extra: {
|
||||
title: 'Title',
|
||||
description: "Description <a href='http://test.es' target='_parent' name='naaaamed'>Test</a>",
|
||||
show_title: true,
|
||||
show_descriptin: true
|
||||
}
|
||||
}),
|
||||
template: template
|
||||
});
|
||||
|
||||
h1.render();
|
||||
expect(h1.$('.description a').attr('target')).toBe('_blank');
|
||||
expect(h1.$('.description a').attr('name')).toBe('naaaamed');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
describe('infobox', function() {
|
||||
var view;
|
||||
var layer;
|
||||
beforeEach(function() {
|
||||
layer = new Backbone.Model();
|
||||
view = new cdb.geo.ui.InfoBox({
|
||||
template: '#{{test}}#',
|
||||
position: 'top|right',
|
||||
pos_margin: 30,
|
||||
layer: layer
|
||||
});
|
||||
});
|
||||
|
||||
it("should render with template", function() {
|
||||
view.render({ test: 'jaja' });
|
||||
expect(view.$el.html()).toEqual('#jaja#');
|
||||
});
|
||||
|
||||
it("should render in position", function() {
|
||||
view.render({ test: 'jaja' });
|
||||
expect(view.$el.css('top')).toEqual('30px');
|
||||
expect(view.$el.css('right')).toEqual('30px');
|
||||
});
|
||||
|
||||
it("should render on layer hover", function() {
|
||||
layer.trigger('featureOver', null, null, null, {
|
||||
test: '1234'
|
||||
});
|
||||
expect(view.$el.html()).toEqual('#1234#');
|
||||
});
|
||||
|
||||
it("should disable/enable", function() {
|
||||
view.disable();
|
||||
layer.trigger('featureOver', null, null, null, {
|
||||
test: '1234'
|
||||
});
|
||||
expect(view.$el.html()).toEqual('');
|
||||
view.enable();
|
||||
layer.trigger('featureOver', null, null, null, {
|
||||
test: '1234'
|
||||
});
|
||||
expect(view.$el.html()).toEqual('#1234#');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,577 @@
|
||||
|
||||
describe("cdb.geo.ui.infowindow", function() {
|
||||
|
||||
describe("model", function() {
|
||||
var model;
|
||||
beforeEach(function() {
|
||||
model = new cdb.geo.ui.InfowindowModel();
|
||||
});
|
||||
|
||||
it("should allow adding an alternative name", function() {
|
||||
|
||||
model.addField('the_name');
|
||||
model.addField('the_description');
|
||||
|
||||
model.setAlternativeName('the_name', 'nombre');
|
||||
model.setAlternativeName('the_description', 'descripción');
|
||||
|
||||
n = model.getAlternativeName('the_name');
|
||||
d = model.getAlternativeName('the_description');
|
||||
|
||||
expect(n).toEqual("nombre");
|
||||
expect(d).toEqual("descripción");
|
||||
|
||||
});
|
||||
|
||||
it("should add a field", function() {
|
||||
expect(model.containsField('test')).toEqual(false);
|
||||
model.addField('test');
|
||||
model.addField('test2');
|
||||
expect(model.containsField('test')).toEqual(true);
|
||||
model.removeField('test');
|
||||
expect(model.containsField('test')).toEqual(false);
|
||||
expect(model.containsField('test2')).toEqual(true);
|
||||
model.clearFields();
|
||||
expect(model.containsField('test2')).toEqual(false);
|
||||
});
|
||||
|
||||
it("should add a field in order", function() {
|
||||
model.addField('test', 1);
|
||||
model.addField('test2', 0);
|
||||
expect(model.get('fields')[0].name).toEqual('test2');
|
||||
expect(model.get('fields')[1].name).toEqual('test');
|
||||
});
|
||||
|
||||
it("should allow modify field properties", function() {
|
||||
var spy = sinon.spy();
|
||||
model.addField('test');
|
||||
var t = model.getFieldProperty('test', 'title');
|
||||
expect(t).toEqual(true);
|
||||
model.bind('change:fields', spy);
|
||||
expect(spy.called).toEqual(false);
|
||||
model.setFieldProperty('test', 'title', false);
|
||||
t = model.getFieldProperty('test', 'title');
|
||||
expect(t).toEqual(false);
|
||||
expect(spy.called).toEqual(true);
|
||||
});
|
||||
|
||||
it("should save and restore fields", function() {
|
||||
model.addField('test', 1);
|
||||
model.addField('test2', 0);
|
||||
model.addField('test3', 3);
|
||||
model.saveFields();
|
||||
expect(model.get('old_fields')).toEqual(model.get('fields'));
|
||||
model.clearFields();
|
||||
model.restoreFields();
|
||||
expect(model.get('old_fields')).toEqual(undefined);
|
||||
expect(model.get('fields')[0].name).toEqual('test2');
|
||||
expect(model.get('fields')[1].name).toEqual('test');
|
||||
expect(model.get('fields')[2].name).toEqual('test3');
|
||||
});
|
||||
});
|
||||
|
||||
describe("view", function() {
|
||||
var model, view;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
var container = $('<div>').css('height', '200px');
|
||||
|
||||
map = new cdb.geo.Map();
|
||||
|
||||
mapView = new cdb.geo.MapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
model = new cdb.geo.ui.InfowindowModel({
|
||||
fields: [
|
||||
{ name: 'test1', position: 1, title: true},
|
||||
{ name: 'test2', position: 2, title: true}
|
||||
]
|
||||
});
|
||||
|
||||
view = new cdb.geo.ui.Infowindow({
|
||||
model: model,
|
||||
mapView: mapView
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should add render when template changes", function() {
|
||||
spyOn(view, 'render');
|
||||
model.set('template', 'jaja');
|
||||
expect(view.render).toHaveBeenCalled()
|
||||
});
|
||||
|
||||
it("should change width of the popup when width attribute changes", function() {
|
||||
spyOn(view, 'render');
|
||||
view.model.set({
|
||||
'template': '<div class="cartodb-popup"></div>',
|
||||
'width': 100
|
||||
});
|
||||
expect(view.$('.cartodb-popup').css('width')).toBe('100px');
|
||||
});
|
||||
|
||||
it("shouldn't change width of the popup when width attribute is undefined", function() {
|
||||
spyOn(view, 'render');
|
||||
view.model.set({
|
||||
'template': '<div class="cartodb-popup v2"></div>'
|
||||
})
|
||||
view.model.unset('width');
|
||||
expect(view.$('.cartodb-popup').css('width')).toBe(undefined);
|
||||
});
|
||||
|
||||
it("should change maxHeight of the popup when maxHeight attribute changes", function() {
|
||||
spyOn(view, 'render');
|
||||
view.model.set({
|
||||
'template': '<div class="cartodb-popup"><div class="cartodb-popup-content"></div></div>',
|
||||
'maxHeight': 100
|
||||
});
|
||||
expect(view.$('.cartodb-popup-content').css('max-height')).toBe('100px');
|
||||
});
|
||||
|
||||
it("should render without alternative_name set", function() {
|
||||
var template = '<div class="cartodb-popup">\
|
||||
<a href="#close" class="cartodb-popup-close-button close">x</a>\
|
||||
<div class="cartodb-popup-content-wrapper">\
|
||||
<div class="cartodb-popup-content">\
|
||||
<ul id="mylist"></ul>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="cartodb-popup-tip-container"></div>\
|
||||
</div>';
|
||||
|
||||
model.unset('alternative_names');
|
||||
model.set({
|
||||
content: {
|
||||
fields: [ { title:'test', value:true, position:0, index:0 } ]
|
||||
},
|
||||
template_name:'infowindow_light',
|
||||
template: template
|
||||
});
|
||||
|
||||
expect(view.render().$el.html().length).not.toBe(0);
|
||||
});
|
||||
|
||||
it("should convert value to string when it is a number", function() {
|
||||
model.set({
|
||||
content: {
|
||||
fields: [{
|
||||
title: 'jamon1', value: 0, index:0
|
||||
}, {
|
||||
title: 'jamon2', value: 1, index:1
|
||||
}]
|
||||
},
|
||||
template_name: 'jaja'
|
||||
}, {silent: true});
|
||||
|
||||
var render_fields = view._fieldsToString(model.attributes.content.fields, model.attributes.template_name);
|
||||
|
||||
expect(render_fields[0].value).toEqual("0");
|
||||
expect(render_fields[1].value).toEqual("1");
|
||||
});
|
||||
|
||||
it("should convert value to '' when it is undefined", function() {
|
||||
model.set({
|
||||
content: { fields: [{ title: 'jamon', value: undefined}] },
|
||||
template_name: 'jaja'
|
||||
}, {silent: true});
|
||||
|
||||
var render_fields = view._fieldsToString(model.attributes.content.fields, model.attributes.template_name);
|
||||
expect(render_fields[0].value).toEqual('');
|
||||
});
|
||||
|
||||
it("should convert value to '' when it is null", function() {
|
||||
model.set('content', { fields: [{ title: 'jamon', value: null}] }, {silent: true});
|
||||
|
||||
var render_fields = view._fieldsToString(model.attributes.content.fields, model.attributes.template_name);
|
||||
expect(render_fields[0].value).toEqual('');
|
||||
});
|
||||
|
||||
it("shouldn't convert the value if it is empty", function() {
|
||||
model.set('content', { fields: [{ title: 'jamon', value: ''}] }, {silent: true});
|
||||
|
||||
var render_fields = view._fieldsToString(model.attributes.content.fields, model.attributes.template_name);
|
||||
expect(render_fields[0].value).toEqual('');
|
||||
});
|
||||
|
||||
it("should leave a string as it is", function() {
|
||||
model.set('content', { fields: [{ title: 'jamon', value: "jamon is testing"}] }, {silent: true});
|
||||
|
||||
var render_fields = view._fieldsToString(model.attributes.content.fields, model.attributes.template_name);
|
||||
expect(render_fields[0].value).toEqual("jamon is testing");
|
||||
});
|
||||
|
||||
it("should convert value to string when it is a boolean", function() {
|
||||
model.set('content', { fields: [{ title: 'jamon1', value: false}, { title: 'jamon2', value: true}] }, {silent: true});
|
||||
|
||||
var render_fields = view._fieldsToString(model.attributes.content.fields, model.attributes.template_name);
|
||||
|
||||
expect(render_fields[0].value).toEqual("false");
|
||||
expect(render_fields[1].value).toEqual("true");
|
||||
});
|
||||
|
||||
it("should be null when there isn't any field", function() {
|
||||
spyOn(view, 'render');
|
||||
model.set('fields', []);
|
||||
expect(view.render).not.toHaveBeenCalled();
|
||||
expect(view.$el.html()).toEqual('');
|
||||
});
|
||||
});
|
||||
|
||||
describe("contentForFields", function() {
|
||||
|
||||
it('should return the title and value of each field', function() {
|
||||
var attributes = { field1: 'value1' };
|
||||
var fields = [{ name: 'field1', title: true }];
|
||||
var content = cdb.geo.ui.InfowindowModel.contentForFields(attributes, fields, {})
|
||||
|
||||
expect(content.fields.length).toEqual(1);
|
||||
expect(content.fields[0].title).toEqual('field1');
|
||||
expect(content.fields[0].value).toEqual('value1');
|
||||
});
|
||||
|
||||
it('should not return the title if not specified', function() {
|
||||
var attributes = { field1: 'value1' };
|
||||
var fields = [{ name: 'field1' }]; // Field doesn't have a title attribute
|
||||
var content = cdb.geo.ui.InfowindowModel.contentForFields(attributes, fields, {})
|
||||
|
||||
expect(content.fields.length).toEqual(1);
|
||||
expect(content.fields[0].title).toEqual(null);
|
||||
});
|
||||
|
||||
it('should return the index of each field', function() {
|
||||
var attributes = { field1: 'value1', field2: 'value2' };
|
||||
var fields = [{ name: 'field1' }, { name: 'field2' }];
|
||||
var content = cdb.geo.ui.InfowindowModel.contentForFields(attributes, fields, {})
|
||||
|
||||
expect(content.fields.length).toEqual(2);
|
||||
expect(content.fields[0].index).toEqual(0);
|
||||
expect(content.fields[1].index).toEqual(1);
|
||||
});
|
||||
|
||||
it('should return empty fields', function() {
|
||||
var attributes = { field1: 'value1' };
|
||||
var fields = [{ name: 'field1' }, { name: 'field2' }];
|
||||
var options = { empty_fields: true };
|
||||
var content = cdb.geo.ui.InfowindowModel.contentForFields(attributes, fields, options)
|
||||
|
||||
expect(content.fields.length).toEqual(2);
|
||||
expect(content.fields[0]).toEqual({
|
||||
title: null,
|
||||
value: 'value1',
|
||||
index: 0
|
||||
});
|
||||
expect(content.fields[1]).toEqual({
|
||||
title: null,
|
||||
value: undefined,
|
||||
index: 1
|
||||
});
|
||||
});
|
||||
|
||||
it('should not return empty fields', function() {
|
||||
var attributes = { field1: 'value1' };
|
||||
var fields = [{ name: 'field1' }, { name: 'field2' }];
|
||||
var options = { empty_fields: false };
|
||||
var content = cdb.geo.ui.InfowindowModel.contentForFields(attributes, fields, options)
|
||||
|
||||
expect(content.fields.length).toEqual(1);
|
||||
expect(content.fields[0]).toEqual({
|
||||
title: null,
|
||||
value: 'value1',
|
||||
index: 0
|
||||
});
|
||||
});
|
||||
|
||||
it('should not return fields with a null value', function() {
|
||||
var attributes = { field1: 'wadus', field2: null };
|
||||
var fields = [{ name: 'field1' }, { name: 'field2' }];
|
||||
var content = cdb.geo.ui.InfowindowModel.contentForFields(attributes, fields, {})
|
||||
|
||||
expect(content.fields.length).toEqual(1);
|
||||
expect(content.fields[0]).toEqual({
|
||||
title: null,
|
||||
value: 'wadus',
|
||||
index: 0
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the attributes as data', function() {
|
||||
var attributes = { field1: 'value1' };
|
||||
var fields = [{ name: 'field1' }];
|
||||
var content = cdb.geo.ui.InfowindowModel.contentForFields(attributes, fields, {})
|
||||
|
||||
expect(content.data).toEqual(attributes);
|
||||
});
|
||||
|
||||
it('should return an empty field when no data is available', function() {
|
||||
var attributes = {};
|
||||
var fields = [{ name: 'field1' }, { name: 'field2' }];
|
||||
var content = cdb.geo.ui.InfowindowModel.contentForFields(attributes, fields, {})
|
||||
|
||||
expect(content.fields.length).toEqual(1);
|
||||
expect(content.fields[0]).toEqual({
|
||||
title: null,
|
||||
value: 'No data available',
|
||||
index: 0,
|
||||
type: 'empty'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("loading state", function() {
|
||||
var model, view;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
var container = $('<div>').css('height', '200px');
|
||||
|
||||
map = new cdb.geo.Map();
|
||||
|
||||
mapView = new cdb.geo.MapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
model = new cdb.geo.ui.InfowindowModel({
|
||||
fields: [
|
||||
{ value: 'Loading content...', index: null, title: null, type: 'loading'}
|
||||
]
|
||||
});
|
||||
|
||||
view = new cdb.geo.ui.Infowindow({
|
||||
model: model,
|
||||
mapView: mapView
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should show loading state", function() {
|
||||
spyOn(view, '_startSpinner');
|
||||
model.set({
|
||||
'template': 'jaja',
|
||||
'content': {
|
||||
fields: [
|
||||
{ value: 'Loading content...', index: null, title: null, type: 'loading'}
|
||||
]
|
||||
}
|
||||
});
|
||||
expect(view._startSpinner).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should hide loading state", function() {
|
||||
model.set({
|
||||
'template': 'jaja',
|
||||
'content': {
|
||||
fields: [
|
||||
{ value: 'Loading content...', index: null, title: null, type: 'loading'}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
spyOn(view, '_stopSpinner');
|
||||
model.set({
|
||||
'template': 'jaja',
|
||||
'content': {
|
||||
fields: [
|
||||
{ value: 'Any kind of value', index: 0, title: 'TITLE'}
|
||||
]
|
||||
}
|
||||
});
|
||||
expect(view._stopSpinner).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("shouldn't show the loader if there are several fields", function() {
|
||||
spyOn(view, '_stopSpinner');
|
||||
spyOn(view, '_startSpinner');
|
||||
model.set({
|
||||
'template': 'jaja',
|
||||
'content': {
|
||||
fields: [
|
||||
{ value: 'Loading content...', index: null, title: null, type: 'loading'},
|
||||
{ value: 'Loading content...', index: null, title: null, type: 'loading'}
|
||||
]
|
||||
}
|
||||
});
|
||||
expect(view._stopSpinner).toHaveBeenCalled();
|
||||
expect(view._startSpinner).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("custom template", function() {
|
||||
var model, view;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
var container = $('<div>').css('height', '200px');
|
||||
|
||||
map = new cdb.geo.Map();
|
||||
|
||||
mapView = new cdb.geo.MapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
model = new cdb.geo.ui.InfowindowModel({
|
||||
template: '<div>{{ test1 }}</div>',
|
||||
fields: [
|
||||
{ title: 'test1', position: 1, value: "x" },
|
||||
{ title: 'test2', position: 2, value: "b" }
|
||||
]
|
||||
});
|
||||
|
||||
view = new cdb.geo.ui.Infowindow({
|
||||
model: model,
|
||||
mapView: mapView
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should compile the template when changes", function() {
|
||||
view.model.set('template', '<div>{{test1}}</div>');
|
||||
expect(view.template({ test1: 'new' })).toEqual('<div>new</div>');
|
||||
});
|
||||
|
||||
it("should render properly when there is only a field without title", function() {
|
||||
model.set({
|
||||
fields: [
|
||||
{ name: 'test1', position: 0, title: false },
|
||||
],
|
||||
content: {
|
||||
fields: [
|
||||
{ title: 'test1', position: 0, value: 'jamon' },
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
var new_view = new cdb.geo.ui.Infowindow({
|
||||
model: model,
|
||||
mapView: mapView
|
||||
});
|
||||
|
||||
expect(new_view.render().$el.html()).toBe('<div>jamon</div>');
|
||||
});
|
||||
|
||||
it("shouldn't sanitize the fields", function() {
|
||||
spyOn(view, '_sanitizeField');
|
||||
view.render();
|
||||
expect(view._sanitizeField).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should sanitize the template output by default', function() {
|
||||
view.model.set('template', 'no <iframe src="" onload="document.body.appendChild(document.createElement(\'script\')).src=\'http://localhost/xss.js\'"/> no');
|
||||
view.render();
|
||||
expect(view.$el.html()).toEqual('no ');
|
||||
});
|
||||
|
||||
it('should allow to override sanitization', function() {
|
||||
view.model.set({
|
||||
template: 'no <iframe src="" onload="document.body.appendChild(document.createElement(\'script\')).src=\'http://localhost/xss.js\'"/> no',
|
||||
sanitizeTemplate: false
|
||||
});
|
||||
view.render();
|
||||
expect(view.$el.html()).toEqual('no <iframe src="" onload="document.body.appendChild(document.createElement(\'script\')).src=\'http://localhost/xss.js\'"></iframe> no');
|
||||
|
||||
view.model.set('sanitizeTemplate', null);
|
||||
view.render();
|
||||
expect(view.$el.html()).toEqual('no <iframe src="" onload="document.body.appendChild(document.createElement(\'script\')).src=\'http://localhost/xss.js\'"></iframe> no');
|
||||
|
||||
customSanitizeSpy = jasmine.createSpy('sanitizeTemplateSpy').and.returnValue('<p>custom sanitizied result</p>');
|
||||
view.model.set('sanitizeTemplate', customSanitizeSpy);
|
||||
expect(customSanitizeSpy).toHaveBeenCalledWith('no <iframe src="" onload="document.body.appendChild(document.createElement(\'script\')).src=\'http://localhost/xss.js\'"/> no');
|
||||
view.render();
|
||||
expect(view.$el.html()).toEqual('<p>custom sanitizied result</p>');
|
||||
|
||||
view.model.set('sanitizeTemplate', undefined);
|
||||
view.render();
|
||||
expect(view.$el.html()).toEqual('no ');
|
||||
});
|
||||
});
|
||||
|
||||
describe("image template", function() {
|
||||
var model, view, container, fields, fieldsWithoutURL, url;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
url = "http://assets.javierarce.com/lion.png";
|
||||
|
||||
container = $('<div>').css('height', '200px');
|
||||
|
||||
fields = [
|
||||
{ title: 'test1', position: 1, value: url },
|
||||
{ title: 'test2', position: 2, value: "b"}
|
||||
];
|
||||
|
||||
fieldsWithoutURL = [
|
||||
{ title: 'test1', position: 1, value: "x" },
|
||||
{ title: 'test2', position: 2, value: "b"}
|
||||
];
|
||||
|
||||
map = new cdb.geo.Map();
|
||||
|
||||
mapView = new cdb.geo.MapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
model = new cdb.geo.ui.InfowindowModel({
|
||||
content: {
|
||||
fields: fields
|
||||
}
|
||||
});
|
||||
|
||||
view = new cdb.geo.ui.Infowindow({
|
||||
model: model,
|
||||
mapView: mapView
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should get the cover url", function() {
|
||||
expect(view._getCoverURL()).toEqual(url);
|
||||
});
|
||||
|
||||
it("should validate the cover url", function() {
|
||||
var url = view._getCoverURL();
|
||||
expect(view._isValidURL(url)).toEqual(true);
|
||||
});
|
||||
|
||||
it("should accept google chart URLS in the cover", function() {
|
||||
var url = "http://chart.googleapis.com/chart?chxl=0:|1990%2F92|2001%2F03|2011%2F13&chxr=1,0,75&chxs=0,676767,11.5,0.5,lt,676767&chxt=x,y&chs=279x210&cht=lc&chco=FF0000&chds=0,69&chd=t:9.5,12.8,15.1,14.6,12.9,10.2,9.5,8.2,7.4,6.2,6,6.5,7.1,7.5,7.9,8,8.2,7.9,7.5,6.9,6.3,5.6&chg=-1,0,0,4&chls=1&chma=0,0,0,25&chm=B,EFEFEF,0,0,0&chtt=Malnourishment+in+&chts=676767,14";
|
||||
expect(view._isValidURL(url)).toEqual(true);
|
||||
});
|
||||
|
||||
it("should detect if the infowindow has a cover", function() {
|
||||
model.set('template', '<div class="cartodb-popup header" data-cover="true"><div class="cover"></div></div>');
|
||||
expect(view._containsCover()).toEqual(true);
|
||||
});
|
||||
|
||||
it("should append the image", function() {
|
||||
model.set('template', '<div class="cartodb-popup header" data-cover="true"><div class="cover"></div></div>');
|
||||
expect(view.$el.find("img").length).toEqual(1);
|
||||
});
|
||||
|
||||
it("if the image is invalid it shouldn't append it", function() {
|
||||
model.set("content", { fields: fieldsWithoutURL });
|
||||
model.set('template', '<div class="cartodb-popup header" data-cover="true"><div class="cover"></div></div>');
|
||||
expect(view.$el.find("img").length).toEqual(0);
|
||||
});
|
||||
|
||||
it("if the them has a cover and the image is invalid it should hide it", function() {
|
||||
model.set("content", { fields: fieldsWithoutURL });
|
||||
model.set('template', '<div class="cartodb-popup header" data-cover="true"><div class="cover"><img src="{{ wadus }}"/></div></div>');
|
||||
expect(view.$el.find("img").css('display')).toEqual('none');
|
||||
});
|
||||
|
||||
it("if the theme doesn't have cover don't append the image", function() {
|
||||
model.set("content", { fields: fields });
|
||||
model.set('template', '<div class="cover"></div>');
|
||||
expect(view.$el.find("img").length).toEqual(0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,155 @@
|
||||
describe("cdb.geo.ui.LayerSelector", function() {
|
||||
|
||||
var layerSelector, layerSelector2, layerGroup;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
var map = new cdb.geo.Map();
|
||||
var map2 = new cdb.geo.Map();
|
||||
|
||||
// Layers
|
||||
var l1 = new cdb.geo.CartoDBLayer({ type: "Tiled", visible: true, urlTemplate: "https://maps.nlp.nokia.com/maptiler/v2/maptile/newest/normal.day/{z}/{x}/{y}/256/png8?lg=eng&token=foo&app_id=bar", name: "Nokia Day", className: "nokia_day", attribution: "©2012 Nokia <a href='http://here.net/services/terms' target='_blank'>Terms of use</a>", kind: "tiled", infowindow: null, id: 1226, order: 0 });
|
||||
var l2 = new cdb.geo.CartoDBLayer({ type: "CartoDB", attribution: "CartoDB <a href='https://carto.com/attributions' target='_blank'>attribution</a>", active: true, query: null, opacity: 0.99, interactivity: "cartodb_id", interaction: true, debug: false, tiler_domain: "localhost.lan", tiler_port: "8181", tiler_protocol: "http", sql_api_domain: "development.localhost.lan", sql_api_port: 8080, sql_api_protocol: "http", extra_params: { cache_policy: "persist", cache_buster: 1369995364392 }, cdn_url: "", maxZoom: 28, auto_bound: false, visible: true, sql_domain: "localhost.lan", sql_port: "8080", sql_protocol: "http", tile_style_history: [ "#untitled_table1 { // polygons [mapnik-geometry-type=polygons] { marker-fill: #FF6600; marker-opacity: 1; marker-width: 12; marker-line-color: white; marker-line-width: 3; marker-line-opacity: 0.9; marker-placement: point; marker-type: ellipse;marker-allow-overlap: true; } //lines [mapnik-geometry-type=linestring] { line-color: #FF6600; line-width: 2; line-opacity: 0.7; } //polygons [mapnik-geometry-type=polygon] { polygon-fill:#FF6600; polygon-opacity: 0.7; line-opacity:1; line-color: #FFFFFF; } }" ], style_version: "2.1.1", table_name: "points", user_name: "development", tile_style: "#untitled_table { // points [mapnik-geometry-type=point] { marker-fill: #FF6600; marker-opacity: 1; marker-width: 12; marker-line-color: white; marker-line-width: 3; marker-line-opacity: 0.9; marker-placement: point; marker-type: ellipse;marker-allow-overlap: true; } //lines [mapnik-geometry-type=linestring] { line-color: #FF6600; line-width: 2; line-opacity: 0.7; } //polygons [mapnik-geometry-type=polygon] { polygon-fill:#FF6600; polygon-opacity: 0.7; line-opacity:1; line-color: #FFFFFF; } }", use_server_style: true, query_history: [ ], sql_api_endpoint: "/api/v1/sql", no_cdn: true, order: 2, kind: "carto", template_name: "table/views/infowindow_light" , id: 231, order: 1 });
|
||||
var l3 = new cdb.geo.CartoDBLayer({ type: "CartoDB", attribution: "CartoDB <a href='https://carto.com/attributions' target='_blank'>attribution</a>", active: true, query: null, opacity: 0.99, interactivity: "cartodb_id", interaction: true, debug: false, tiler_domain: "localhost.lan", tiler_port: "8181", tiler_protocol: "http", sql_api_domain: "development.localhost.lan", sql_api_port: 8080, sql_api_protocol: "http", extra_params: { cache_policy: "persist", cache_buster: 1369995364392 }, cdn_url: "", maxZoom: 28, auto_bound: false, visible: true, sql_domain: "localhost.lan", sql_port: "8080", sql_protocol: "http", tile_style_history: [ "#untitled_table { // points [mapnik-geometry-type=point] { marker-fill: #FF6600; marker-opacity: 1; marker-width: 12; marker-line-color: white; marker-line-width: 3; marker-line-opacity: 0.9; marker-placement: point; marker-type: ellipse;marker-allow-overlap: true; } //lines [mapnik-geometry-type=linestring] { line-color: #FF6600; line-width: 2; line-opacity: 0.7; } //polygons [mapnik-geometry-type=polygon] { polygon-fill:#FF6600; polygon-opacity: 0.7; line-opacity:1; line-color: #FFFFFF; } }" ], style_version: "2.1.1", table_name: "polygons", user_name: "development", tile_style: "#untitled_table { // points [mapnik-geometry-type=point] { marker-fill: #FF6600; marker-opacity: 1; marker-width: 12; marker-line-color: white; marker-line-width: 3; marker-line-opacity: 0.9; marker-placement: point; marker-type: ellipse;marker-allow-overlap: true; } //lines [mapnik-geometry-type=linestring] { line-color: #FF6600; line-width: 2; line-opacity: 0.7; } //polygons [mapnik-geometry-type=polygon] { polygon-fill:#FF6600; polygon-opacity: 0.7; line-opacity:1; line-color: #FFFFFF; } }", use_server_style: true, query_history: [ ], sql_api_endpoint: "/api/v1/sql", no_cdn: true, order: 2, kind: "carto", template_name: "table/views/infowindow_light" , id: 1231, order: 2 });
|
||||
|
||||
layerGroup = new cdb.geo.CartoDBGroupLayer({
|
||||
layer_definition: {
|
||||
version: '1.0.0',
|
||||
layers: [{
|
||||
type: 'cartodb',
|
||||
options: {
|
||||
sql: "select * from european_countries_export",
|
||||
cartocss: '#layer { polygon-fill: #000; polygon-opacity: 0.8;}',
|
||||
cartocss_version : '2.0.0',
|
||||
layer_name: "european_countries_export",
|
||||
interactivity: ['created_at', 'cartodb_id']
|
||||
}
|
||||
},{
|
||||
type: 'cartodb',
|
||||
options: {
|
||||
sql: "select * from jamon_countries",
|
||||
cartocss: '#layer { polygon-fill: #000; polygon-opacity: 0.8;}',
|
||||
cartocss_version : '2.0.0',
|
||||
layer_name: "jamon_countries",
|
||||
interactivity: ['description', 'cartodb_id']
|
||||
}
|
||||
}]
|
||||
}
|
||||
});
|
||||
|
||||
map.layers = new cdb.geo.Layers([l1, l2, l3]);
|
||||
map2.layers = new cdb.geo.Layers([l1, layerGroup]);
|
||||
|
||||
|
||||
var mapView = new cdb.geo.LeafletMapView({
|
||||
el: $("<div>"),
|
||||
map: map
|
||||
});
|
||||
|
||||
var mapView2 = new cdb.geo.LeafletMapView({
|
||||
el: $("<div>"),
|
||||
map: map2
|
||||
});
|
||||
|
||||
layerSelector = new cdb.geo.ui.LayerSelector({
|
||||
mapView: mapView,
|
||||
template: cdb.core.Template.compile('<a href="#/change-visibility" class="layers">Visible layers<div class="count"></div></a>','underscore'),
|
||||
dropdown_template: cdb.core.Template.compile('<ul></ul><div class="tail"><span class="border"></span></div>','underscore')
|
||||
});
|
||||
|
||||
layerSelector2 = new cdb.geo.ui.LayerSelector({
|
||||
mapView: mapView2,
|
||||
template: cdb.core.Template.compile('<a href="#/change-visibility" class="layers">Visible layers<div class="count"></div></a>','underscore'),
|
||||
dropdown_template: cdb.core.Template.compile('<ul></ul><div class="tail"><span class="border"></span></div>','underscore')
|
||||
});
|
||||
});
|
||||
|
||||
describe("with CartoDB layers", function() {
|
||||
|
||||
it("should render properly", function() {
|
||||
layerSelector.render();
|
||||
expect(layerSelector.$('a.layers').size()).toBe(1);
|
||||
expect(layerSelector.$('a.layer').size()).toBe(2);
|
||||
expect(layerSelector.$('a.layer:eq(0)').text()).not.toBe("");
|
||||
expect(layerSelector.$('a.layer:eq(1)').text()).not.toBe("");
|
||||
expect(layerSelector.$('div.count').text()).toBe("2")
|
||||
});
|
||||
|
||||
it("should render the dropdown correctly", function() {
|
||||
layerSelector.render();
|
||||
expect(layerSelector.dropdown.$('li').size()).toBe(2);
|
||||
});
|
||||
|
||||
it("should store two layers", function() {
|
||||
layerSelector.render();
|
||||
expect(layerSelector.layers.length).toBe(2);
|
||||
});
|
||||
|
||||
it("should open the dropdown when clicks over it", function() {
|
||||
layerSelector.render();
|
||||
layerSelector.$('a.layers').click();
|
||||
expect(layerSelector.dropdown.$el.css('display')).toBe('block');
|
||||
});
|
||||
|
||||
it("should change the select status when the switch button is clicked and trigger and event", function() {
|
||||
layerSelector.render();
|
||||
|
||||
for(var key in layerSelector._subviews) break;
|
||||
var view = layerSelector._subviews[key];
|
||||
|
||||
view.$el.find(".switch").click();
|
||||
expect(view.model.get("visible")).toBeFalsy();
|
||||
|
||||
view.$el.find(".switch").click();
|
||||
expect(view.model.get("visible")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should trigger a switchChanged event when the switch button is clicked", function() {
|
||||
layerSelector.render();
|
||||
for(var key in layerSelector._subviews) break;
|
||||
var view = layerSelector._subviews[key];
|
||||
spyOn(view, 'trigger');
|
||||
view.$el.find(".switch").click();
|
||||
expect(view.trigger).toHaveBeenCalledWith('switchChanged');
|
||||
});
|
||||
|
||||
it("should toggle the enabled/disabled classes when the switch button is clicked", function() {
|
||||
layerSelector.render();
|
||||
for(var key in layerSelector._subviews) break;
|
||||
var view = layerSelector._subviews[key];
|
||||
|
||||
view.$el.find(".switch").click();
|
||||
expect(view.$el.find(".switch").hasClass("enabled")).toBeFalsy();
|
||||
expect(view.$el.find(".switch").hasClass("disabled")).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("with a CartoDB LayerGroup", function() {
|
||||
it("should render properly", function() {
|
||||
layerSelector2.render();
|
||||
expect(layerSelector2.$('a.layers').size()).toBe(1);
|
||||
expect(layerSelector2.$('a.layer').size()).toBe(2);
|
||||
expect(layerSelector2.$('a.layer:eq(0)').text()).not.toBe("");
|
||||
expect(layerSelector2.$('a.layer:eq(1)').text()).not.toBe("");
|
||||
expect(layerSelector2.$('div.count').text()).toBe("2")
|
||||
});
|
||||
|
||||
it("should store two layers", function() {
|
||||
layerSelector2.render();
|
||||
expect(layerSelector2.layers.length).toBe(2);
|
||||
});
|
||||
|
||||
it("should hide the layer when the switch button is clicked", function() {
|
||||
layerSelector2.render();
|
||||
var switcher = $(layerSelector2.$('li')[0]);
|
||||
switcher.find(".switch").click();
|
||||
var layerGroupView = layerSelector2.mapView.getLayerByCid(layerGroup.cid);
|
||||
|
||||
expect(layerGroupView.getSubLayer(0).get('hidden')).toEqual(true);
|
||||
expect(!layerGroupView.getSubLayer(1).get('hidden')).toEqual(true);
|
||||
expect(layerSelector2.$('div.count').text()).toBe("1")
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,953 @@
|
||||
describe("common.geo.ui.Legend", function() {
|
||||
|
||||
describe("Legend", function() {
|
||||
|
||||
var data, legend, map;
|
||||
|
||||
afterEach(function() {
|
||||
legend.clean();
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
map = new cdb.geo.Map();
|
||||
|
||||
data = [
|
||||
{ name: "Category 1", value: "#f1f1f1" },
|
||||
{ name: "Category 2", value: "red" },
|
||||
{ name: "Category 3", value: "#f1f1f1" },
|
||||
{ name: "Category 4", value: "#ccc" },
|
||||
];
|
||||
|
||||
legend = new cdb.geo.ui.Legend({
|
||||
data: data,
|
||||
map: map
|
||||
});
|
||||
|
||||
$("body").append(legend.render().$el);
|
||||
|
||||
});
|
||||
|
||||
it("should have a 'none' type set by default", function() {
|
||||
expect(legend.model.get("type")).toEqual("none");
|
||||
});
|
||||
|
||||
it("should use the provided model", function() {
|
||||
|
||||
var legend = new cdb.geo.ui.Legend({
|
||||
data: data,
|
||||
map: map
|
||||
});
|
||||
|
||||
expect(legend.model).toBeDefined();
|
||||
expect(legend.model.get("type")).toEqual("none");
|
||||
|
||||
});
|
||||
|
||||
it("should generate a model if no model is provided", function() {
|
||||
|
||||
expect(legend.model).toBeDefined();
|
||||
expect(legend.model.get("type")).toEqual("none");
|
||||
|
||||
});
|
||||
|
||||
it("should allow to change type", function() {
|
||||
legend.model.set({ type: "bubble" });
|
||||
expect(legend.model.get("type")).toEqual('bubble');
|
||||
});
|
||||
|
||||
it("should have a collection", function() {
|
||||
expect(legend.items instanceof cdb.geo.ui.LegendItems).toEqual(true);
|
||||
});
|
||||
|
||||
it("should populate the collection", function() {
|
||||
legend.model.set("type", "custom");
|
||||
expect(legend.model.items.length).toEqual(4);
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
expect(legend.model.items.at(i).get("name")).toEqual(data[i].name);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
it("should set the type of the legend in the element", function() {
|
||||
legend.model.set({ type: "bubble" });
|
||||
legend.render();
|
||||
expect(legend.$el.hasClass("bubble")).toEqual(true);
|
||||
});
|
||||
|
||||
it("should create the specific legend based on the type", function() {
|
||||
legend.model.set({ type: "bubble" });
|
||||
expect(legend.view instanceof cdb.geo.ui.BubbleLegend).toEqual(true);
|
||||
expect(legend.$el.hasClass("bubble")).toEqual(true);
|
||||
expect(legend.$el.hasClass("custom")).toEqual(false);
|
||||
});
|
||||
|
||||
it("shouldn't create the legend if the type is unknown", function() {
|
||||
legend.model.set({ type: "the_legend_of_santana" });
|
||||
expect(legend.view instanceof cdb.geo.ui.CustomLegend).toEqual(false);
|
||||
expect(legend.$el.hasClass("custom")).toEqual(false);
|
||||
});
|
||||
|
||||
it("should update the legend when the name of an item is changed", function() {
|
||||
legend.render();
|
||||
legend.model.set({ type: "custom" });
|
||||
expect(legend.$el.find("li:first-child").text().trim()).toEqual('Category 1');
|
||||
|
||||
legend.items.at(0).set("name", "New Category 1")
|
||||
expect(legend.$el.find("li:first-child").text().trim()).toEqual('New Category 1');
|
||||
});
|
||||
|
||||
it("should update the legend when the value of an item is changed", function() {
|
||||
legend.render();
|
||||
legend.model.set({ type: "custom" });
|
||||
expect(legend.$el.find("li:first-child .bullet").css("background-color")).toEqual('rgb(241, 241, 241)');
|
||||
|
||||
legend.items.at(0).set("value", "red")
|
||||
expect(legend.$el.find("li:first-child .bullet").css("background-color")).toEqual('rgb(255, 0, 0)');
|
||||
});
|
||||
|
||||
|
||||
it("should have a title defined", function() {
|
||||
expect(legend.model.get("title")).toBeDefined();
|
||||
});
|
||||
|
||||
it("should have a show_title defined", function() {
|
||||
legend.model.set({ type: "custom" });
|
||||
expect(legend.model.get("show_title")).toBeDefined();
|
||||
});
|
||||
|
||||
it("should show the legend", function() {
|
||||
legend.model.set({ type: "custom" });
|
||||
legend.show();
|
||||
expect(legend.$el.css('display')).toEqual('block');
|
||||
});
|
||||
it("shouldn't show the 'none' legend", function() {
|
||||
legend.show();
|
||||
expect(legend.$el.css('display')).toEqual('none');
|
||||
});
|
||||
|
||||
it("should hide the legend", function(done) {
|
||||
|
||||
legend.model.set({ type: "bubble" });
|
||||
|
||||
legend.show();
|
||||
legend.hide();
|
||||
|
||||
setTimeout(function () {
|
||||
expect(legend.$el.css('display')).toEqual('none');
|
||||
done();
|
||||
}, 300);
|
||||
|
||||
});
|
||||
|
||||
it("should show/hide the legend when the visible attribute changes", function() {
|
||||
legend.model.set({ type: "custom" });
|
||||
|
||||
legend.render();
|
||||
|
||||
expect(legend.$el.css('display')).toEqual('block');
|
||||
|
||||
legend.model.set({ visible: false });
|
||||
|
||||
expect(legend.$el.css('display')).toEqual('none');
|
||||
|
||||
legend.model.set({ visible: true });
|
||||
|
||||
expect(legend.$el.css('display')).toEqual('block');
|
||||
});
|
||||
|
||||
it("should render the title if title and show_title are set", function() {
|
||||
var title = "Hi, I'm a title";
|
||||
legend.model.set({ type: "custom", title: title, show_title: true });
|
||||
expect(legend.$el.find('.legend-title').text()).toEqual(title);
|
||||
|
||||
legend.model.set({ type: "bubble", title: title, show_title: true });
|
||||
expect(legend.$el.find('.legend-title').text()).toEqual(title);
|
||||
|
||||
legend.model.set({ type: "density", title: title, show_title: true });
|
||||
expect(legend.$el.find('.legend-title').text()).toEqual(title);
|
||||
|
||||
legend.model.set({ type: "intensity", title: title, show_title: true });
|
||||
expect(legend.$el.find('.legend-title').text()).toEqual(title);
|
||||
|
||||
legend.model.set({ type: "color", title: title, show_title: true });
|
||||
expect(legend.$el.find('.legend-title').text()).toEqual(title);
|
||||
|
||||
legend.model.set({ type: "category", title: title, show_title: true });
|
||||
expect(legend.$el.find('.legend-title').text()).toEqual(title);
|
||||
|
||||
legend.model.set({ type: "choropleth", title: title, show_title: true });
|
||||
expect(legend.$el.find('.legend-title').text()).toEqual(title);
|
||||
});
|
||||
|
||||
it("shouldn't render the title if show_title is not true", function() {
|
||||
var title = "Hi, I'm a title";
|
||||
legend.model.set({ type: "custom", title: title, show_title: false });
|
||||
expect(legend.$el.find('.legend-title').text()).not.toEqual(title);
|
||||
|
||||
legend.model.set({ type: "bubble", title: title, show_title: false });
|
||||
expect(legend.$el.find('.legend-title').text()).not.toEqual(title);
|
||||
|
||||
legend.model.set({ type: "density", title: title, show_title: false });
|
||||
expect(legend.$el.find('.legend-title').text()).not.toEqual(title);
|
||||
|
||||
legend.model.set({ type: "intensity", title: title, show_title: false });
|
||||
expect(legend.$el.find('.legend-title').text()).not.toEqual(title);
|
||||
|
||||
legend.model.set({ type: "color", title: title, show_title: false });
|
||||
expect(legend.$el.find('.legend-title').text()).not.toEqual(title);
|
||||
|
||||
legend.model.set({ type: "category", title: title, show_title: false });
|
||||
expect(legend.$el.find('.legend-title').text()).not.toEqual(title);
|
||||
|
||||
legend.model.set({ type: "choropleth", title: title, show_title: false });
|
||||
expect(legend.$el.find('.legend-title').text()).not.toEqual(title);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("StackedLegend", function() {
|
||||
|
||||
var data, legends, legendA, legendB, stackedLegend;
|
||||
|
||||
afterEach(function() {
|
||||
stackedLegend.clean();
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
data = [
|
||||
{ name: "Category 1", value: "#f1f1f1" },
|
||||
{ name: "Category 2", value: "red" },
|
||||
{ name: "Category 3", value: "#f1f1f1" },
|
||||
{ name: "Category 4", value: "#ccc" },
|
||||
];
|
||||
|
||||
legendA = new cdb.geo.ui.Legend({
|
||||
data: data
|
||||
});
|
||||
|
||||
legendB = new cdb.geo.ui.Legend({
|
||||
data: data
|
||||
});
|
||||
|
||||
legends = [ legendA, legendB ];
|
||||
|
||||
stackedLegend = new cdb.geo.ui.StackedLegend({
|
||||
legends: legends
|
||||
});
|
||||
|
||||
$("body").append(stackedLegend.render().$el);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("ColorLegend", function() {
|
||||
var legend;
|
||||
beforeEach(function() {
|
||||
var data = [
|
||||
{ name: true, value: "red" },
|
||||
{ name: false, value: "red" },
|
||||
{ name: "#f1f1f1", value: "red" },
|
||||
{ name: null, value: "red" },
|
||||
];
|
||||
|
||||
var model = new cdb.core.Model({
|
||||
type: "color",
|
||||
title: "title",
|
||||
show_title: false,
|
||||
});
|
||||
model.items = new Backbone.Collection(data)
|
||||
|
||||
legend = new cdb.geo.ui.ColorLegend({
|
||||
model: model
|
||||
});
|
||||
});
|
||||
|
||||
it("should render boolean values and nulls", function() {
|
||||
legend.render();
|
||||
var bullets = legend.$('li');
|
||||
expect(bullets.length).toEqual(4);
|
||||
expect($(bullets[0]).text()).toEqual(" true");
|
||||
expect($(bullets[1]).text()).toEqual(" false");
|
||||
expect($(bullets[2]).text()).toEqual(" #f1f1f1");
|
||||
expect($(bullets[3]).text()).toEqual(" null");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("Legend (public interface)", function() {
|
||||
|
||||
var custom_data;
|
||||
|
||||
afterEach(function() {
|
||||
$(".legend_playground").remove();
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
custom_data = [
|
||||
{ name: "Natural Parks", value: "#58A062" },
|
||||
{ name: "Villages", value: "https://carto.com/assets/logos/logos_full_cartodb_light.png", type: "image" },
|
||||
{ name: "Rivers", value: "#54BFDE" },
|
||||
{ name: "Fields", value: "#9BC562" },
|
||||
{ name: "Caves", value: "#FABB5C" }
|
||||
];
|
||||
|
||||
});
|
||||
|
||||
it("should allow to show/hide the title", function() {
|
||||
|
||||
var title = "Custom title";
|
||||
|
||||
var legend = new cdb.geo.ui.Legend.Custom({
|
||||
title: title,
|
||||
data: custom_data
|
||||
});
|
||||
|
||||
legend.render();
|
||||
legend.model.set("show_title", false);
|
||||
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual(null);
|
||||
|
||||
legend.model.set("show_title", true);
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual(title);
|
||||
|
||||
legend.hideTitle();
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual(null);
|
||||
|
||||
legend.showTitle();
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual(title);
|
||||
|
||||
});
|
||||
|
||||
it("should have a method to render the legend", function() {
|
||||
|
||||
$("body").append("<div class='legend_playground' />");
|
||||
|
||||
var legend = new cdb.geo.ui.Legend.Custom({
|
||||
title: "Custom title",
|
||||
data: custom_data
|
||||
});
|
||||
|
||||
legend.addTo(".legend_playground");
|
||||
expect($(".legend_playground .cartodb-legend").length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should render the title", function() {
|
||||
|
||||
var legend = new cdb.geo.ui.Legend.Custom({
|
||||
title: "Custom title",
|
||||
data: custom_data
|
||||
});
|
||||
|
||||
legend.render();
|
||||
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual("Custom title");
|
||||
|
||||
});
|
||||
|
||||
it("shouldn't render the title if it's not provided", function() {
|
||||
|
||||
var legend = new cdb.geo.ui.Legend.Custom({
|
||||
data: custom_data
|
||||
});
|
||||
|
||||
legend.render();
|
||||
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual(null);
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe("Custom Legend", function() {
|
||||
|
||||
var properties, legend;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
properties = { title: "Custom title", data: custom_data };
|
||||
legend = new cdb.geo.ui.Legend.Custom( properties );
|
||||
|
||||
legend.render();
|
||||
|
||||
});
|
||||
|
||||
it("should generate a legend", function() {
|
||||
expect(legend.model.get("type")).toEqual("custom");
|
||||
});
|
||||
|
||||
it("should show the items", function() {
|
||||
expect(legend.items.length).toEqual(custom_data.length);
|
||||
expect(legend.items.at(0).get("name")).toEqual(custom_data[0].name);
|
||||
expect(legend.items.at(0).get("value")).toEqual(custom_data[0].value);
|
||||
|
||||
expect(legend.$el.find("li:first-child").text().trim()).toEqual(custom_data[0].name);
|
||||
expect(legend.$el.find("li:first-child .bullet").css("background")).toEqual("rgb(88, 160, 98)");
|
||||
});
|
||||
|
||||
it("should show a title", function() {
|
||||
expect(legend.model.get("title")).toEqual(properties.title);
|
||||
expect(legend.$el.find(".legend-title").text()).toEqual(properties.title);
|
||||
});
|
||||
|
||||
it("should allow to change the title", function() {
|
||||
legend.setTitle("New title");
|
||||
expect(legend.model.get("show_title")).toEqual(true);
|
||||
expect(legend.$el.find(".legend-title").text().trim()).toEqual("New title");
|
||||
});
|
||||
|
||||
it("should allow to change the items", function() {
|
||||
|
||||
var new_data = [
|
||||
{ name: "One", value: "#F1F1F1" },
|
||||
{ name: "Too", value: "#FF00FF" }
|
||||
];
|
||||
|
||||
legend.setData(new_data);
|
||||
|
||||
expect(legend.items.length).toEqual(new_data.length);
|
||||
|
||||
expect(legend.items.at(0).get("name")).toEqual(new_data[0].name);
|
||||
expect(legend.items.at(0).get("value")).toEqual(new_data[0].value);
|
||||
|
||||
expect(legend.$el.find("li:first-child").text().trim()).toEqual(new_data[0].name);
|
||||
expect(legend.$el.find("li:first-child .bullet").css("background")).toEqual("rgb(241, 241, 241)");
|
||||
|
||||
expect(legend.$el.find("li:last-child").text().trim()).toEqual(new_data[1].name);
|
||||
expect(legend.$el.find("li:last-child .bullet").css("background")).toEqual("rgb(255, 0, 255)");
|
||||
});
|
||||
|
||||
it("should allow to specify a custom template for the items", function() {
|
||||
|
||||
var title = "Custom title";
|
||||
|
||||
var legend = new cdb.geo.ui.Legend.Custom({
|
||||
title: title,
|
||||
data: custom_data,
|
||||
itemTemplate: '<div class="myCustomClass" style="background:#f1f1f1;"></div><%= name %>: <%= value %>'
|
||||
});
|
||||
|
||||
legend.render();
|
||||
|
||||
expect(legend.$el.find("li:first-child").html()).toEqual('<div class="myCustomClass" style="background:#f1f1f1;"></div>Natural Parks: #58A062');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Category Legend", function() {
|
||||
|
||||
var properties, legend;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
properties = { title: "Category title", data: custom_data };
|
||||
legend = new cdb.geo.ui.Legend.Category( properties );
|
||||
legend.render();
|
||||
|
||||
});
|
||||
|
||||
it("should generate the legend", function() {
|
||||
expect(legend.model.get("type")).toEqual("category");
|
||||
});
|
||||
|
||||
it("should show the items", function() {
|
||||
expect(legend.items.length).toEqual(custom_data.length);
|
||||
expect(legend.items.at(0).get("name")).toEqual(custom_data[0].name);
|
||||
expect(legend.items.at(0).get("value")).toEqual(custom_data[0].value);
|
||||
|
||||
expect(legend.$el.find("li:first-child").text().trim()).toEqual(custom_data[0].name);
|
||||
expect(legend.$el.find("li:first-child .bullet").css("background")).toEqual("rgb(88, 160, 98)");
|
||||
|
||||
expect(legend.$el.find("li:nth-child(2)").text().trim()).toEqual(custom_data[1].name);
|
||||
expect(legend.$el.find("li:nth-child(2) .bullet").css("background")).toEqual("url(https://carto.com/assets/logos/logos_full_cartodb_light.png)");
|
||||
});
|
||||
|
||||
it("should show a title", function() {
|
||||
expect(legend.model.get("title")).toEqual(properties.title);
|
||||
expect(legend.$el.find(".legend-title").text().trim()).toEqual(properties.title);
|
||||
});
|
||||
|
||||
it("should allow to change the title", function() {
|
||||
legend.setTitle("New title");
|
||||
expect(legend.model.get("show_title")).toEqual(true);
|
||||
expect(legend.$el.find(".legend-title").text().trim()).toEqual("New title");
|
||||
});
|
||||
|
||||
it("shouldn't evaluate name 0 to null", function() {
|
||||
custom_data = [
|
||||
{ name: 0, value: "#58A062" },
|
||||
{ name: 2, value: "#54BFDE" },
|
||||
{ name: 3, value: "#9BC562" },
|
||||
{ name: 4, value: "#FABB5C" }
|
||||
];
|
||||
properties = { title: "Category title", data: custom_data };
|
||||
legend = new cdb.geo.ui.Legend.Category( properties );
|
||||
legend.render();
|
||||
expect(legend.$el.find("li:first-child").text().trim()).toEqual("" + custom_data[0].name);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Bubble Legend", function() {
|
||||
|
||||
var properties, legend;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
properties = { title: "Bubble legend", type: "bubble", color: "#FF0000", min: 1, max: 120 };
|
||||
legend = new cdb.geo.ui.Legend.Bubble( properties );
|
||||
|
||||
legend.render();
|
||||
|
||||
});
|
||||
|
||||
it("should generate the legend", function() {
|
||||
expect(legend.model.get("type")).toEqual(properties.type);
|
||||
});
|
||||
|
||||
it("should show a graph with the right color", function() {
|
||||
expect(legend.$el.find(".graph").css("background-color")).toEqual("rgb(255, 0, 0)");
|
||||
});
|
||||
|
||||
it("should show min and max values", function() {
|
||||
expect(legend.model.get("min")).toEqual(properties.min);
|
||||
expect(legend.model.get("max")).toEqual(properties.max);
|
||||
});
|
||||
|
||||
it("should show a title", function() {
|
||||
expect(legend.model.get("title")).toEqual(properties.title);
|
||||
expect(legend.$el.find(".legend-title").text().trim()).toEqual(properties.title);
|
||||
});
|
||||
|
||||
it("should allow to change the title", function() {
|
||||
legend.setTitle("New title");
|
||||
expect(legend.model.get("show_title")).toEqual(true);
|
||||
expect(legend.$el.find(".legend-title").text().trim()).toEqual("New title");
|
||||
});
|
||||
|
||||
it("should allow to show the title", function() {
|
||||
legend.hideTitle();
|
||||
legend.showTitle();
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual(properties.title);
|
||||
});
|
||||
|
||||
it("should allow to hide the title", function() {
|
||||
legend.hideTitle();
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual(null);
|
||||
});
|
||||
|
||||
it("should allow to change the color", function() {
|
||||
legend.setColor("#CCC");
|
||||
expect(legend.$el.find(".graph").css("background-color")).toEqual("rgb(204, 204, 204)");
|
||||
});
|
||||
|
||||
it("should allow to change the min value", function() {
|
||||
var value = "3";
|
||||
|
||||
legend.setMinValue(value)
|
||||
expect(legend.model.get("min")).toEqual(value);
|
||||
expect(legend.$el.find("ul li:nth-child(1)").text().trim()).toEqual(value);
|
||||
});
|
||||
|
||||
it("should allow to change the max value", function() {
|
||||
var value = "10000";
|
||||
|
||||
legend.setMaxValue(value)
|
||||
expect(legend.model.get("max")).toEqual(value);
|
||||
expect(legend.$el.find("ul li:nth-child(3)").text().trim()).toEqual(value);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Choropleth Legend", function() {
|
||||
|
||||
var properties, legend;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
properties = { title: "Choropleth title", type: "choropleth", colors: ["#DDD", "#FF000", "#F1F1F1"], left: "Left value", right: "Right value" };
|
||||
legend = new cdb.geo.ui.Legend.Choropleth(properties);
|
||||
legend.render();
|
||||
|
||||
});
|
||||
|
||||
it("should generate a legend", function() {
|
||||
expect(legend.model.get("type")).toEqual(properties.type);
|
||||
});
|
||||
|
||||
it("should show left and right values", function() {
|
||||
expect(legend.model.get("leftLabel")).toEqual(properties.left);
|
||||
expect(legend.model.get("rightLabel")).toEqual(properties.right);
|
||||
});
|
||||
|
||||
it("should show colors", function() {
|
||||
expect(legend.model.get("colors").length).toEqual(properties.colors.length);
|
||||
expect(legend.$el.find(".quartile").length).toEqual(properties.colors.length);
|
||||
});
|
||||
|
||||
it("should show a title", function() {
|
||||
expect(legend.model.get("title")).toEqual(properties.title);
|
||||
expect(legend.$el.find(".legend-title").text().trim()).toEqual(properties.title);
|
||||
});
|
||||
|
||||
it("should allow to change the title", function() {
|
||||
legend.setTitle("New title");
|
||||
expect(legend.model.get("show_title")).toEqual(true);
|
||||
expect(legend.$el.find(".legend-title").text().trim()).toEqual("New title");
|
||||
});
|
||||
|
||||
it("should allow to hide the title", function() {
|
||||
legend.hideTitle();
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual(null);
|
||||
});
|
||||
|
||||
it("should allow to show the title", function() {
|
||||
legend.hideTitle();
|
||||
legend.showTitle();
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual(properties.title);
|
||||
});
|
||||
|
||||
it("should allow change colors", function() {
|
||||
var newColors = ["red", "white", "blue"];
|
||||
|
||||
legend.setColors(newColors);
|
||||
expect(legend.model.get("colors").length).toEqual(newColors.length);
|
||||
expect(legend.$el.find(".quartile").length).toEqual(newColors.length);
|
||||
});
|
||||
|
||||
it("should allow change the left label", function() {
|
||||
var label = "New left label";
|
||||
|
||||
legend.setLeftLabel(label)
|
||||
expect(legend.model.get("leftLabel")).toEqual(label);
|
||||
expect(legend.$el.find("li:nth-child(1)").text().trim()).toEqual(label);
|
||||
});
|
||||
|
||||
it("should allow change the right label", function() {
|
||||
var label = "New right label";
|
||||
|
||||
legend.setRightLabel(label)
|
||||
expect(legend.model.get("rightLabel")).toEqual(label);
|
||||
expect(legend.$el.find("li:nth-child(2)").text().trim()).toEqual(label);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Density Legend", function() {
|
||||
|
||||
var properties, legend;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
properties = { title: "Density title", type: "density", colors: ["#DDD", "#FF000", "#F1F1F1"], left: "Left value", right: "Right value" };
|
||||
legend = new cdb.geo.ui.Legend.Density(properties);
|
||||
legend.render();
|
||||
|
||||
});
|
||||
|
||||
it("should generate a legend", function() {
|
||||
expect(legend.model.get("type")).toEqual(properties.type);
|
||||
});
|
||||
|
||||
it("should show left and right values", function() {
|
||||
expect(legend.model.get("leftLabel")).toEqual(properties.left);
|
||||
expect(legend.model.get("rightLabel")).toEqual(properties.right);
|
||||
});
|
||||
|
||||
it("should show colors", function() {
|
||||
expect(legend.model.get("colors").length).toEqual(properties.colors.length);
|
||||
expect(legend.$el.find(".quartile").length).toEqual(properties.colors.length);
|
||||
});
|
||||
|
||||
it("should show a title", function() {
|
||||
expect(legend.model.get("title")).toEqual(properties.title);
|
||||
expect(legend.$el.find(".legend-title").text().trim()).toEqual(properties.title);
|
||||
});
|
||||
|
||||
it("should allow to change the title", function() {
|
||||
legend.setTitle("New title");
|
||||
expect(legend.model.get("show_title")).toEqual(true);
|
||||
expect(legend.$el.find(".legend-title").text().trim()).toEqual("New title");
|
||||
});
|
||||
|
||||
it("should allow to hide the title", function() {
|
||||
legend.hideTitle();
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual(null);
|
||||
});
|
||||
|
||||
it("should allow to show the title", function() {
|
||||
legend.hideTitle();
|
||||
legend.showTitle();
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual(properties.title);
|
||||
});
|
||||
|
||||
it("should allow change colors", function() {
|
||||
var newColors = ["red", "white", "blue"];
|
||||
|
||||
legend.setColors(newColors);
|
||||
expect(legend.model.get("colors").length).toEqual(newColors.length);
|
||||
expect(legend.$el.find(".quartile").length).toEqual(newColors.length);
|
||||
});
|
||||
|
||||
it("should allow change the left label", function() {
|
||||
legend.setLeftLabel("Hello!")
|
||||
expect(legend.model.get("leftLabel")).toEqual("Hello!");
|
||||
expect(legend.$el.find("li:nth-child(1)").text().trim()).toEqual("Hello!");
|
||||
});
|
||||
|
||||
it("should allow change the right label", function() {
|
||||
legend.setRightLabel("Hi!")
|
||||
expect(legend.model.get("rightLabel")).toEqual("Hi!");
|
||||
expect(legend.$el.find("li:nth-child(2)").text().trim()).toEqual("Hi!");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Intensity Legend", function() {
|
||||
|
||||
var properties, legend;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
properties = { title: "Intensity legend", type: "intensity", color: "#FF0000", min: 1, max: 120 };
|
||||
legend = new cdb.geo.ui.Legend.Intensity( properties );
|
||||
|
||||
legend.render();
|
||||
|
||||
});
|
||||
|
||||
it("should generate the legend", function() {
|
||||
expect(legend.model.get("type")).toEqual(properties.type);
|
||||
});
|
||||
|
||||
it("should show a graph with the right color", function() {
|
||||
var gradient = "-webkit-linear-gradient(left, rgb(255, 0, 0) 0%, rgb(255, 0, 0) 100%)";
|
||||
expect(legend.$el.find(".graph").css("background")).toEqual(gradient);
|
||||
});
|
||||
|
||||
it("should show left and right values", function() {
|
||||
expect(legend.model.get("leftLabel")).toEqual(properties.left);
|
||||
expect(legend.model.get("rightLabel")).toEqual(properties.right);
|
||||
});
|
||||
|
||||
it("should show a title", function() {
|
||||
expect(legend.model.get("title")).toEqual(properties.title);
|
||||
expect(legend.$el.find(".legend-title").text().trim()).toEqual(properties.title);
|
||||
});
|
||||
|
||||
it("should allow to change the title", function() {
|
||||
legend.setTitle("New title");
|
||||
expect(legend.model.get("show_title")).toEqual(true);
|
||||
expect(legend.$el.find(".legend-title").text().trim()).toEqual("New title");
|
||||
});
|
||||
|
||||
it("should allow to show the title", function() {
|
||||
legend.hideTitle();
|
||||
legend.showTitle();
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual(properties.title);
|
||||
});
|
||||
|
||||
it("should allow to hide the title", function() {
|
||||
legend.hideTitle();
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual(null);
|
||||
});
|
||||
|
||||
it("should allow to change the color", function() {
|
||||
legend.setColor("#CCC");
|
||||
var gradient = "-webkit-linear-gradient(left, rgb(204, 204, 204) 0%, rgb(255, 255, 255) 100%)";
|
||||
expect(legend.$el.find(".graph").css("background")).toEqual(gradient);
|
||||
});
|
||||
|
||||
it("should allow change the left label", function() {
|
||||
var label = "New left label";
|
||||
|
||||
legend.setLeftLabel(label)
|
||||
expect(legend.model.get("leftLabel")).toEqual(label);
|
||||
expect(legend.$el.find("li:nth-child(1)").text().trim()).toEqual(label);
|
||||
});
|
||||
|
||||
it("should allow change the right label", function() {
|
||||
var label = "New right label";
|
||||
|
||||
legend.setRightLabel(label)
|
||||
expect(legend.model.get("rightLabel")).toEqual(label);
|
||||
expect(legend.$el.find("li:nth-child(2)").text().trim()).toEqual(label);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Stacked Legend (using data)", function() {
|
||||
|
||||
afterEach(function() {
|
||||
$(".legend_playground").remove();
|
||||
});
|
||||
|
||||
var stacked, properties, legendA, legendB, custom_data;
|
||||
|
||||
var custom_data = [
|
||||
{ name: "Natural Parks", value: "#58A062" },
|
||||
{ name: "Villages", value: "#F07971" },
|
||||
{ name: "Rivers", value: "#54BFDE" },
|
||||
{ name: "Fields", value: "#9BC562" },
|
||||
{ name: "Caves", value: "#FABB5C" }
|
||||
];
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
var legendA = { title: "Intensity legend", type: "intensity", color: "#FF0000", min: 1, max: 120 };
|
||||
var legendB = { title: "Custom title", type:"custom", data: custom_data };
|
||||
|
||||
stacked = new cdb.geo.ui.Legend.Stacked({ data: [legendA, legendB] });
|
||||
|
||||
stacked.render();
|
||||
|
||||
});
|
||||
|
||||
it("should have a method to render the stacked legend", function() {
|
||||
|
||||
$("body").append("<div class='legend_playground' />");
|
||||
|
||||
var legendA = { title: "Intensity legend", type: "intensity", color: "#FF0000", min: 1, max: 120 };
|
||||
var legendB = { title: "Custom title", type:"custom", data: custom_data };
|
||||
|
||||
var stacked = new cdb.geo.ui.Legend.Stacked({ data: [legendA, legendB] });
|
||||
|
||||
stacked.addTo(".legend_playground");
|
||||
expect($(".legend_playground .cartodb-legend-stack").length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should render", function() {
|
||||
expect(stacked.legends.length).toEqual(2);
|
||||
expect(stacked.$el.find(".cartodb-legend").length).toEqual(2);
|
||||
expect(stacked.$el.find(".cartodb-legend.intensity").length).toEqual(1);
|
||||
expect(stacked.$el.find(".cartodb-legend.custom").length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should allow to add a legend", function() {
|
||||
|
||||
var properties = { title: "Density title", type: "density", colors: ["#DDD", "#FF000", "#F1F1F1"], left: "Left value", right: "Right value" };
|
||||
|
||||
stacked.addLegend(properties);
|
||||
|
||||
expect(stacked.legends.length).toEqual(3);
|
||||
|
||||
expect(stacked.$el.find(".cartodb-legend").length).toEqual(3);
|
||||
expect(stacked.$el.find(".cartodb-legend.intensity").length).toEqual(1);
|
||||
expect(stacked.$el.find(".cartodb-legend.custom").length).toEqual(1);
|
||||
expect(stacked.$el.find(".cartodb-legend.density").length).toEqual(1);
|
||||
|
||||
});
|
||||
|
||||
it("should allow to remove a legend", function() {
|
||||
|
||||
stacked.removeLegendAt(0);
|
||||
|
||||
expect(stacked.legends.length).toEqual(1);
|
||||
|
||||
expect(stacked.$el.find(".cartodb-legend").length).toEqual(1);
|
||||
expect(stacked.$el.find(".cartodb-legend.intensity").length).toEqual(0);
|
||||
expect(stacked.$el.find(".cartodb-legend.custom").length).toEqual(1);
|
||||
|
||||
});
|
||||
|
||||
it("should allow to get a legend", function() {
|
||||
|
||||
var legend = stacked.getLegendAt(1);
|
||||
|
||||
expect(legend.model.get("title")).toEqual("Custom title");
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual("Custom title");
|
||||
|
||||
var legend = stacked.legends[0];
|
||||
|
||||
expect(legend.model.get("title")).toEqual("Intensity legend");
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual("Intensity legend");
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Stacked Legend (using legends)", function() {
|
||||
|
||||
var stacked, properties, legendA, legendB, custom_data;
|
||||
|
||||
var custom_data = [
|
||||
{ name: "Natural Parks", value: "#58A062" },
|
||||
{ name: "Villages", value: "#F07971" },
|
||||
{ name: "Rivers", value: "#54BFDE" },
|
||||
{ name: "Fields", value: "#9BC562" },
|
||||
{ name: "Caves", value: "#FABB5C" }
|
||||
];
|
||||
|
||||
var customLegend = new cdb.geo.ui.Legend.Custom({
|
||||
title: "Custom Legend",
|
||||
data: custom_data
|
||||
});
|
||||
|
||||
var intensityLegend = new cdb.geo.ui.Legend.Intensity({
|
||||
title: "Intensity Legend",
|
||||
left: "10", right: "20", color: "#f1f1f1"
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
stacked = new cdb.geo.ui.Legend.Stacked({ legends: [ customLegend, intensityLegend ] });
|
||||
stacked.render();
|
||||
|
||||
});
|
||||
|
||||
it("should render", function() {
|
||||
expect(stacked.legends.length).toEqual(2);
|
||||
expect(stacked.$el.find(".cartodb-legend").length).toEqual(2);
|
||||
expect(stacked.$el.find(".cartodb-legend.intensity").length).toEqual(1);
|
||||
expect(stacked.$el.find(".cartodb-legend.custom").length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should allow to add a legend", function() {
|
||||
|
||||
var properties = { title: "Density title", type: "density", colors: ["#DDD", "#FF000", "#F1F1F1"], left: "Left value", right: "Right value" };
|
||||
|
||||
stacked.addLegend(properties);
|
||||
|
||||
expect(stacked.legends.length).toEqual(3);
|
||||
|
||||
expect(stacked.$el.find(".cartodb-legend").length).toEqual(3);
|
||||
expect(stacked.$el.find(".cartodb-legend.intensity").length).toEqual(1);
|
||||
expect(stacked.$el.find(".cartodb-legend.custom").length).toEqual(1);
|
||||
expect(stacked.$el.find(".cartodb-legend.density").length).toEqual(1);
|
||||
|
||||
});
|
||||
|
||||
it("should allow to remove a legend", function() {
|
||||
|
||||
stacked.removeLegendAt(0);
|
||||
|
||||
expect(stacked.legends.length).toEqual(1);
|
||||
|
||||
expect(stacked.$el.find(".cartodb-legend").length).toEqual(1);
|
||||
expect(stacked.$el.find(".cartodb-legend.intensity").length).toEqual(1);
|
||||
expect(stacked.$el.find(".cartodb-legend.custom").length).toEqual(0);
|
||||
|
||||
});
|
||||
|
||||
it("should allow to get a legend", function() {
|
||||
|
||||
var legend = stacked.getLegendAt(0);
|
||||
|
||||
expect(legend.model.get("title")).toEqual("Custom Legend");
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual("Custom Legend");
|
||||
|
||||
var legend = stacked.legends[1];
|
||||
|
||||
expect(legend.model.get("title")).toEqual("Intensity Legend");
|
||||
expect(legend.$el.find(".legend-title").html()).toEqual("Intensity Legend");
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,861 @@
|
||||
describe("cdb.geo.ui.Mobile", function() {
|
||||
|
||||
var mobile, map, layerGroup, container, mapView, template, overlays, l1, l2, torque;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
map = new cdb.geo.Map();
|
||||
|
||||
torque = new cdb.geo.TorqueLayer({ type: "torque", visible: false, urlTemplate: "https://maps.nlp.nokia.com/maptiler/v2/maptile/newest/normal.day/{z}/{x}/{y}/256/png8?lg=eng&token=foo&app_id=bar", name: "Nokia Day", className: "nokia_day", attribution: "©2012 Nokia <a href='http://here.net/services/terms' target='_blank'>Terms of use</a>", kind: "tiled", infowindow: null, id: 1226, order: 0 });
|
||||
|
||||
l1 = new cdb.geo.CartoDBLayer({ type: "Tiled", visible: true, urlTemplate: "https://maps.nlp.nokia.com/maptiler/v2/maptile/newest/normal.day/{z}/{x}/{y}/256/png8?lg=eng&token=foo&app_id=bar", name: "Nokia Day", className: "nokia_day", attribution: "©2012 Nokia <a href='http://here.net/services/terms' target='_blank'>Terms of use</a>", kind: "tiled", infowindow: null, id: 1226, order: 0 });
|
||||
|
||||
l2 = new cdb.geo.CartoDBLayer({ type: "CartoDB", attribution: "© <a href='https://carto.com/attributions' target='_blank'>CARTO</a>", active: true, query: null, opacity: 0.99, interactivity: "cartodb_id", interaction: true, debug: false, tiler_domain: "localhost.lan", tiler_port: "8181", tiler_protocol: "http", sql_api_domain: "development.localhost.lan", sql_api_port: 8080, sql_api_protocol: "http", extra_params: { cache_policy: "persist", cache_buster: 1369995364392 }, cdn_url: "", maxZoom: 28, auto_bound: false, visible: true, sql_domain: "localhost.lan", sql_port: "8080", sql_protocol: "http", tile_style_history: [ "#untitled_table1 { // polygons [mapnik-geometry-type=polygons] { marker-fill: #FF6600; marker-opacity: 1; marker-width: 12; marker-line-color: white; marker-line-width: 3; marker-line-opacity: 0.9; marker-placement: point; marker-type: ellipse;marker-allow-overlap: true; } //lines [mapnik-geometry-type=linestring] { line-color: #FF6600; line-width: 2; line-opacity: 0.7; } //polygons [mapnik-geometry-type=polygon] { polygon-fill:#FF6600; polygon-opacity: 0.7; line-opacity:1; line-color: #FFFFFF; } }" ], style_version: "2.1.1", table_name: "points", user_name: "development", tile_style: "#untitled_table { // points [mapnik-geometry-type=point] { marker-fill: #FF6600; marker-opacity: 1; marker-width: 12; marker-line-color: white; marker-line-width: 3; marker-line-opacity: 0.9; marker-placement: point; marker-type: ellipse;marker-allow-overlap: true; } //lines [mapnik-geometry-type=linestring] { line-color: #FF6600; line-width: 2; line-opacity: 0.7; } //polygons [mapnik-geometry-type=polygon] { polygon-fill:#FF6600; polygon-opacity: 0.7; line-opacity:1; line-color: #FFFFFF; } }", use_server_style: true, query_history: [ ], sql_api_endpoint: "/api/v1/sql", no_cdn: true, order: 2, kind: "carto", template_name: "table/views/infowindow_light" , id: 231, order: 1 });
|
||||
|
||||
layerGroup = new cdb.geo.CartoDBGroupLayer({
|
||||
layer_definition: {
|
||||
version: '1.0.0',
|
||||
layers: [{
|
||||
type: 'cartodb',
|
||||
visible: false,
|
||||
options: {
|
||||
sql: "select * from european_countries_export",
|
||||
cartocss: '#layer { polygon-fill: #000; polygon-opacity: 0.8;}',
|
||||
cartocss_version : '2.0.0',
|
||||
layer_name: "european_countries_export",
|
||||
interactivity: ['created_at', 'cartodb_id']
|
||||
}
|
||||
},{
|
||||
type: 'cartodb',
|
||||
visible: false,
|
||||
options: {
|
||||
sql: "select * from jamon_countries",
|
||||
cartocss: '#layer { polygon-fill: #000; polygon-opacity: 0.8;}',
|
||||
cartocss_version : '2.0.0',
|
||||
layer_name: "jamon_countries",
|
||||
interactivity: ['description', 'cartodb_id']
|
||||
}
|
||||
},{
|
||||
type: 'cartodb',
|
||||
visible: true,
|
||||
options: {
|
||||
sql: "select * from jamon_countries",
|
||||
cartocss: '#layer { polygon-fill: #000; polygon-opacity: 0.8;}',
|
||||
cartocss_version : '2.0.0',
|
||||
layer_name: "layer_with_legend",
|
||||
interactivity: ['description', 'cartodb_id'],
|
||||
},
|
||||
legend: {
|
||||
type: "custom",
|
||||
title: "Little legend",
|
||||
show_title: true,
|
||||
data: [
|
||||
{ name: "Natural Parks", value: "#58A062" },
|
||||
{ name: "Villages", value: "#F07971" },
|
||||
{ name: "Rivers", value: "#54BFDE" },
|
||||
{ name: "Fields", value: "#9BC562" },
|
||||
{ name: "Caves", value: "#FABB5C" }
|
||||
]
|
||||
}
|
||||
}]
|
||||
}
|
||||
});
|
||||
|
||||
map.layers.reset([l1, layerGroup]);
|
||||
|
||||
template = cdb.core.Template.compile('\<div class="backdrop"></div>\
|
||||
<div class="cartodb-header">\
|
||||
<div class="content">\
|
||||
<a href="#" class="fullscreen"></a>\
|
||||
<a href="#" class="toggle"></a>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="aside">\
|
||||
<div class="layer-container">\
|
||||
<div class="scrollpane"><ul class="layers"></ul></div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="cartodb-attribution"></div>\
|
||||
<a href="#" class="cartodb-attribution-button"></a>\
|
||||
<div class="torque"></div>\
|
||||
', 'mustache');
|
||||
|
||||
container = $('<div>').css('height', '200px');
|
||||
|
||||
mapView = new cdb.geo.GoogleMapsMapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
overlays = [];
|
||||
|
||||
overlays.push({
|
||||
order: 2,
|
||||
type: "zoom",
|
||||
url: null
|
||||
});
|
||||
|
||||
overlays.push({
|
||||
options: {
|
||||
extra: {
|
||||
description: null,
|
||||
title: "Hello!",
|
||||
show_title: true,
|
||||
show_description: false
|
||||
},
|
||||
},
|
||||
order: 1,
|
||||
shareable: false,
|
||||
type: "header",
|
||||
url: null
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("with legends, with layer selector, without search", function() {
|
||||
|
||||
var mobile;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
mobile = new cdb.geo.ui.Mobile({
|
||||
template: template,
|
||||
mapView: mapView,
|
||||
overlays: overlays,
|
||||
torqueLayer: null,
|
||||
map: map,
|
||||
visibility_options: {
|
||||
search: false,
|
||||
legends: true,
|
||||
layer_selector: true
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should render properly", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".aside").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should render the title", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".title").text()).toBe("Hello!");
|
||||
});
|
||||
|
||||
it("shouldn't render the description", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".description").length).toBe(0);
|
||||
});
|
||||
|
||||
it("should render the layers", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-layers")).toBe(true);
|
||||
expect(mobile.$el.find(".layer-container > h3").text()).toBe("3 layers");
|
||||
expect(mobile.$el.find(".layers > li").length).toBe(3);
|
||||
|
||||
// There's one layer with legend
|
||||
expect(mobile.$el.find(".layers > li:nth-child(3) .cartodb-legend").length).toBe(1);
|
||||
|
||||
expect(mobile.$el.find(".layers > li:nth-child(1) h3").text()).toBe("european_countries_exp…");
|
||||
expect(mobile.$el.find(".layers > li:nth-child(2) h3").text()).toBe("jamon_countries");
|
||||
expect(mobile.$el.find(".layers > li:nth-child(3) h3").text()).toBe("layer_with_legend");
|
||||
});
|
||||
|
||||
it("shouldn't render the search", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-search")).toBe(false);
|
||||
expect(mobile.$el.find(".cartodb-searchbox").length).toBe(0);
|
||||
});
|
||||
|
||||
it("should render the attribution", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution-button").length).toBe(1);
|
||||
expect(mobile.$el.find(".cartodb-attribution").html()).toBe('<li>©2012 Nokia <a href="http://here.net/services/terms" target="_blank">Terms of use</a></li><li>© <a href="https://carto.com/attributions" target="_blank">CARTO</a></li>');
|
||||
});
|
||||
|
||||
it("should has the attribution hidden by default", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("");
|
||||
});
|
||||
|
||||
it("should show the zoom", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-zoom").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should show the toggle button", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-header .content .toggle").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should show the attribution", function() {
|
||||
mobile.render();
|
||||
mobile.$el.find(".cartodb-attribution-button").click();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("block");
|
||||
});
|
||||
|
||||
it("should render the legend", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".layers .cartodb-mobile-layer.has-legend .cartodb-legend .legend-title").text()).toBe("Little legend");
|
||||
expect(mobile.$el.find(".layers .cartodb-mobile-layer.has-legend").length).toBe(1);
|
||||
});
|
||||
|
||||
//it("should hide the attribution when clicking on the backdrop", function() {
|
||||
//mobile.render();
|
||||
//mobile.$el.find(".cartodb-attribution-button").click();
|
||||
//mobile.$el.find(".cartodb-attribution-button .backdrop").click();
|
||||
|
||||
//setTimeout(function() {
|
||||
//expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("");
|
||||
//}, 450);
|
||||
|
||||
//});
|
||||
|
||||
});
|
||||
|
||||
describe("without layer_selector, without legends, without search", function() {
|
||||
|
||||
var mobile;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
mobile = new cdb.geo.ui.Mobile({
|
||||
template: template,
|
||||
mapView: mapView,
|
||||
overlays: overlays,
|
||||
torqueLayer: null,
|
||||
map: map,
|
||||
visibility_options: {
|
||||
search:false,
|
||||
legends: false,
|
||||
layer_selector: false
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should render properly", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".aside").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should render the title", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".title").text()).toBe("Hello!");
|
||||
});
|
||||
|
||||
it("should set the right classes", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-header")).toBe(true);
|
||||
expect(mobile.$el.hasClass("with-layers")).toBe(false);
|
||||
expect(mobile.$el.hasClass("with-search")).toBe(false);
|
||||
});
|
||||
|
||||
it("shouldn't render the layers", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".layers > li").length).toBe(0);
|
||||
});
|
||||
|
||||
|
||||
it("should render the attribution", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution-button").length).toBe(1);
|
||||
expect(mobile.$el.find(".cartodb-attribution").html()).toBe('<li>©2012 Nokia <a href="http://here.net/services/terms" target="_blank">Terms of use</a></li><li>© <a href="https://carto.com/attributions" target="_blank">CARTO</a></li>');
|
||||
});
|
||||
|
||||
it("should has the attribution hidden by default", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("");
|
||||
});
|
||||
|
||||
it("should show the zoom", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-zoom").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should show the attribution", function() {
|
||||
mobile.render();
|
||||
mobile.$el.find(".cartodb-attribution-button").click();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("block");
|
||||
});
|
||||
|
||||
it("shouldn't render the legend", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".layers .cartodb-mobile-layer.has-legend").length).toBe(0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("with legends, without layer selector, without search", function() {
|
||||
|
||||
var mobile;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
mobile = new cdb.geo.ui.Mobile({
|
||||
template: template,
|
||||
mapView: mapView,
|
||||
overlays: overlays,
|
||||
torqueLayer: null,
|
||||
map: map,
|
||||
visibility_options: {
|
||||
search: false,
|
||||
legends: true,
|
||||
layer_selector: false
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should render properly", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".aside").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should render the title", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".title").text()).toBe("Hello!");
|
||||
});
|
||||
|
||||
it("should render only the layers with legends", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-layers")).toBe(true);
|
||||
expect(mobile.$el.find(".layers > li h3").length).toBe(0); // don't show titles
|
||||
expect(mobile.$el.find(".layers > li").length).toBe(1);
|
||||
expect(mobile.$el.find(".layer-container h3").text()).toBe("1 layer");
|
||||
});
|
||||
|
||||
it("shouldn't render the search", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-search")).toBe(false);
|
||||
expect(mobile.$el.find(".cartodb-searchbox").length).toBe(0);
|
||||
});
|
||||
|
||||
it("should render the attribution", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution-button").length).toBe(1);
|
||||
expect(mobile.$el.find(".cartodb-attribution").html()).toBe('<li>©2012 Nokia <a href="http://here.net/services/terms" target="_blank">Terms of use</a></li><li>© <a href="https://carto.com/attributions" target="_blank">CARTO</a></li>');
|
||||
});
|
||||
|
||||
it("should has the attribution hidden by default", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("");
|
||||
});
|
||||
|
||||
it("should show the zoom", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-zoom").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should show the toggle button", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-header .content .toggle").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should show the attribution", function() {
|
||||
mobile.render();
|
||||
mobile.$el.find(".cartodb-attribution-button").click();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("block");
|
||||
});
|
||||
|
||||
it("should render the legend", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".layers .cartodb-mobile-layer.has-legend .cartodb-legend .legend-title").text()).toBe("Little legend");
|
||||
expect(mobile.$el.find(".layers .cartodb-mobile-layer.has-legend").length).toBe(1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("with layer_selector, without legends, without search", function() {
|
||||
|
||||
var mobile;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
mobile = new cdb.geo.ui.Mobile({
|
||||
template: template,
|
||||
mapView: mapView,
|
||||
overlays: overlays,
|
||||
torqueLayer: null,
|
||||
map: map,
|
||||
visibility_options: {
|
||||
search: false,
|
||||
legends: false,
|
||||
layer_selector: true
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should render properly", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".aside").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should render the title", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".title").text()).toBe("Hello!");
|
||||
});
|
||||
|
||||
it("shouldn't render the search", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-search")).toBe(false);
|
||||
});
|
||||
|
||||
it("should render the layers", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-header")).toBe(true);
|
||||
expect(mobile.$el.hasClass("with-layers")).toBe(true);
|
||||
expect(mobile.$el.find(".layers > li").length).toBe(3);
|
||||
expect(mobile.$el.find(".layers > li:first-child").hasClass("has-toggle")).toBe(true);
|
||||
});
|
||||
|
||||
it("shouldn't render the legend", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".layers .cartodb-mobile-layer.has-legend").length).toBe(0);
|
||||
});
|
||||
|
||||
it("should render the attribution", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution-button").length).toBe(1);
|
||||
expect(mobile.$el.find(".cartodb-attribution").html()).toBe('<li>©2012 Nokia <a href="http://here.net/services/terms" target="_blank">Terms of use</a></li><li>© <a href="https://carto.com/attributions" target="_blank">CARTO</a></li>');
|
||||
});
|
||||
|
||||
it("should has the attribution hidden by default", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("");
|
||||
});
|
||||
|
||||
it("should show the zoom", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-zoom").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should show the attribution", function() {
|
||||
mobile.render();
|
||||
mobile.$el.find(".cartodb-attribution-button").click();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("block");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("with search, without layer_selector, without legends", function() {
|
||||
|
||||
var mobile;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
mobile = new cdb.geo.ui.Mobile({
|
||||
template: template,
|
||||
mapView: mapView,
|
||||
overlays: overlays,
|
||||
torqueLayer: null,
|
||||
map: map,
|
||||
visibility_options: {
|
||||
search:true,
|
||||
legends: false,
|
||||
layer_selector: false
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should render properly", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".aside").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should render the title", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".title").text()).toBe("Hello!");
|
||||
});
|
||||
|
||||
it("should render the search", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-search")).toBe(true);
|
||||
});
|
||||
|
||||
it("shouldn't render the layers", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-header")).toBe(true);
|
||||
expect(mobile.$el.hasClass("with-layers")).toBe(false);
|
||||
expect(mobile.$el.find(".layers > li").length).toBe(0);
|
||||
});
|
||||
|
||||
it("should render the attribution", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution-button").length).toBe(1);
|
||||
expect(mobile.$el.find(".cartodb-attribution").html()).toBe('<li>©2012 Nokia <a href="http://here.net/services/terms" target="_blank">Terms of use</a></li><li>© <a href="https://carto.com/attributions" target="_blank">CARTO</a></li>');
|
||||
});
|
||||
|
||||
it("should has the attribution hidden by default", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("");
|
||||
});
|
||||
|
||||
it("should show the zoom", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-zoom").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should show the attribution", function() {
|
||||
mobile.render();
|
||||
mobile.$el.find(".cartodb-attribution-button").click();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("block");
|
||||
});
|
||||
|
||||
it("shouldn't render the legend", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".layers .cartodb-mobile-layer.has-legend").length).toBe(0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("without anything", function() {
|
||||
|
||||
var mobile;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
mobile = new cdb.geo.ui.Mobile({
|
||||
template: template,
|
||||
mapView: mapView,
|
||||
overlays: [],
|
||||
torqueLayer: null,
|
||||
map: map,
|
||||
visibility_options: {
|
||||
legends: false,
|
||||
layer_selector: false
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should render properly", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".aside").length).toBe(1);
|
||||
});
|
||||
|
||||
it("shouldn't render the title", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".title").text()).toBe("");
|
||||
});
|
||||
|
||||
it("should set the right classes", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-header")).toBe(false);
|
||||
expect(mobile.$el.hasClass("with-layers")).toBe(false);
|
||||
expect(mobile.$el.hasClass("with-search")).toBe(false);
|
||||
});
|
||||
|
||||
it("shouldn't render the layers", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-layers")).toBe(false);
|
||||
expect(mobile.$el.find(".layers > li").length).toBe(0);
|
||||
});
|
||||
|
||||
|
||||
it("should render the attribution", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution-button").length).toBe(1);
|
||||
expect(mobile.$el.find(".cartodb-attribution").html()).toBe('<li>©2012 Nokia <a href="http://here.net/services/terms" target="_blank">Terms of use</a></li><li>© <a href="https://carto.com/attributions" target="_blank">CARTO</a></li>');
|
||||
});
|
||||
|
||||
it("should has the attribution hidden by default", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("");
|
||||
});
|
||||
|
||||
it("shouldn't show the zoom", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-zoom").length).toBe(0);
|
||||
});
|
||||
|
||||
it("should show the attribution", function() {
|
||||
mobile.render();
|
||||
mobile.$el.find(".cartodb-attribution-button").click();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("block");
|
||||
});
|
||||
|
||||
it("shouldn't render the legend", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".layers .cartodb-mobile-layer.has-legend").length).toBe(0);
|
||||
});
|
||||
|
||||
//it("should hide the attribution when clicking on the backdrop", function() {
|
||||
//mobile.render();
|
||||
//mobile.$el.find(".cartodb-attribution-button").click();
|
||||
//mobile.$el.find(".cartodb-attribution-button .backdrop").click();
|
||||
|
||||
//setTimeout(function() {
|
||||
//expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("");
|
||||
//}, 350);
|
||||
|
||||
//});
|
||||
|
||||
});
|
||||
|
||||
describe("with some disabled layers", function() {
|
||||
|
||||
var mobile, layerGroup2;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
layerGroup = new cdb.geo.CartoDBGroupLayer({
|
||||
layer_definition: {
|
||||
version: '1.0.0',
|
||||
layers: [{
|
||||
type: 'cartodb',
|
||||
options: {
|
||||
sql: "select * from european_countries_export",
|
||||
cartocss: '#layer { polygon-fill: #000; polygon-opacity: 0.8;}',
|
||||
cartocss_version : '2.0.0',
|
||||
layer_name: "european_countries_export",
|
||||
interactivity: ['created_at', 'cartodb_id']
|
||||
}
|
||||
},{
|
||||
type: 'cartodb',
|
||||
options: {
|
||||
sql: "select * from jamon_countries",
|
||||
cartocss: '#layer { polygon-fill: #000; polygon-opacity: 0.8;}',
|
||||
cartocss_version : '2.0.0',
|
||||
layer_name: "jamon_countries",
|
||||
interactivity: ['description', 'cartodb_id']
|
||||
}
|
||||
},{
|
||||
type: 'cartodb',
|
||||
options: {
|
||||
visible: false,
|
||||
sql: "select * from jamon_countries",
|
||||
cartocss: '#layer { polygon-fill: #000; polygon-opacity: 0.8;}',
|
||||
cartocss_version : '2.0.0',
|
||||
layer_name: "layer_with_legend",
|
||||
interactivity: ['description', 'cartodb_id'],
|
||||
},
|
||||
legend: {
|
||||
type: "custom",
|
||||
title: "Little legend",
|
||||
show_title: true,
|
||||
data: [
|
||||
{ name: "Natural Parks", value: "#58A062" },
|
||||
{ name: "Villages", value: "#F07971" },
|
||||
{ name: "Rivers", value: "#54BFDE" },
|
||||
{ name: "Fields", value: "#9BC562" },
|
||||
{ name: "Caves", value: "#FABB5C" }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
map.layers.reset([l1, layerGroup]);
|
||||
|
||||
|
||||
mapView = new cdb.geo.GoogleMapsMapView({
|
||||
el: container,
|
||||
map: map
|
||||
});
|
||||
|
||||
mobile = new cdb.geo.ui.Mobile({
|
||||
template: template,
|
||||
mapView: mapView,
|
||||
overlays: overlays,
|
||||
torqueLayer: null,
|
||||
map: map,
|
||||
visibility_options: {
|
||||
layer_selector: true
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should render properly", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".aside").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should render the title", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".title").text()).toBe("Hello!");
|
||||
});
|
||||
|
||||
it("should render the layers", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-layers")).toBe(true);
|
||||
expect(mobile.$el.find(".layer-container > h3").text()).toBe("3 layers");
|
||||
expect(mobile.$el.find(".layers > li").length).toBe(3);
|
||||
|
||||
// There's one hidden layer
|
||||
expect(mobile.$el.find(".layers > li:nth-child(3)").hasClass("hidden")).toBe(true);
|
||||
|
||||
expect(mobile.$el.find(".layers > li:nth-child(1) h3").text()).toBe("european_countries_exp…");
|
||||
expect(mobile.$el.find(".layers > li:nth-child(2) h3").text()).toBe("jamon_countries");
|
||||
expect(mobile.$el.find(".layers > li:nth-child(3) h3").text()).toBe("layer_with_legend");
|
||||
});
|
||||
|
||||
it("shouldn't render the search", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-search")).toBe(false);
|
||||
expect(mobile.$el.find(".cartodb-searchbox").length).toBe(0);
|
||||
});
|
||||
|
||||
it("should render the attribution", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution-button").length).toBe(1);
|
||||
expect(mobile.$el.find(".cartodb-attribution").html()).toBe('<li>©2012 Nokia <a href="http://here.net/services/terms" target="_blank">Terms of use</a></li><li>© <a href="https://carto.com/attributions" target="_blank">CARTO</a></li>');
|
||||
});
|
||||
|
||||
it("should has the attribution hidden by default", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("");
|
||||
});
|
||||
|
||||
it("should show the zoom", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-zoom").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should show the toggle button", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-header .content .toggle").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should show the attribution", function() {
|
||||
mobile.render();
|
||||
mobile.$el.find(".cartodb-attribution-button").click();
|
||||
expect(mobile.$el.find(".cartodb-attribution").css("display")).toBe("block");
|
||||
});
|
||||
|
||||
it("should render the legend", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".layers .cartodb-mobile-layer.has-legend .cartodb-legend .legend-title").text()).toBe("Little legend");
|
||||
expect(mobile.$el.find(".layers .cartodb-mobile-layer.has-legend").length).toBe(1);
|
||||
});
|
||||
|
||||
it("should hide the attribution when clicking on the backdrop", function(done) {
|
||||
mobile.render();
|
||||
mobile.$el.find(".cartodb-attribution-button").click();
|
||||
|
||||
setTimeout(function() {
|
||||
expect(mobile.$el.find(".backdrop").css("display")).toBe("block");
|
||||
|
||||
spyOn($.fn, 'fadeOut');
|
||||
|
||||
mobile.$el.find(".backdrop").click();
|
||||
|
||||
setTimeout(function() {
|
||||
// FadeOut tests are the hell!!
|
||||
expect($.fn.fadeOut).toHaveBeenCalled();
|
||||
expect($.fn.fadeOut.calls.count()).toBe(2);
|
||||
|
||||
var elements_class = ['backdrop', 'cartodb-attribution'];
|
||||
expect(
|
||||
_.every($.fn.fadeOut.calls.all(), function(item, pos) {
|
||||
return _.contains(elements_class, $(item.object).attr('class'))
|
||||
})
|
||||
).toBeTruthy();
|
||||
|
||||
done();
|
||||
}, 500);
|
||||
|
||||
}, 500);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("disabling the title and the description", function() {
|
||||
|
||||
var mobile;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
mobile = new cdb.geo.ui.Mobile({
|
||||
template: template,
|
||||
mapView: mapView,
|
||||
overlays: overlays,
|
||||
torqueLayer: null,
|
||||
map: map,
|
||||
visibility_options: {
|
||||
title: false,
|
||||
description: false,
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should render properly", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".aside").length).toBe(1);
|
||||
});
|
||||
|
||||
it("shoulnd't render the title", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".title").length).toBe(0);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("search overlay", function() {
|
||||
|
||||
var mobile;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
mobile = new cdb.geo.ui.Mobile({
|
||||
template: template,
|
||||
mapView: mapView,
|
||||
overlays: [{
|
||||
order: 3,
|
||||
type: "search",
|
||||
template: null
|
||||
}],
|
||||
torqueLayer: null,
|
||||
map: map,
|
||||
visibility_options: {
|
||||
layer_selector:false,
|
||||
legends:false,
|
||||
title: false,
|
||||
description: false,
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should render the search", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.hasClass("with-search")).toBe(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe("with a hidden torque layer", function() {
|
||||
|
||||
var mobile;
|
||||
|
||||
beforeEach(function() {
|
||||
|
||||
torque.options = { steps: 3 };
|
||||
torque.hidden = true;
|
||||
torque.getStep = function() {};
|
||||
|
||||
mobile = new cdb.geo.ui.Mobile({
|
||||
template: template,
|
||||
mapView: mapView,
|
||||
overlays: overlays,
|
||||
torqueLayer: torque,
|
||||
map: map
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("should hide the timeslider", function() {
|
||||
mobile.render();
|
||||
expect(mobile.$el.find(".cartodb-timeslider").length).toBe(1);
|
||||
expect(mobile.$el.find(".cartodb-timeslider").css("display")).toBe("none");
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,269 @@
|
||||
describe('cdb.geo.ui.Search', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
this.$el = $("<div>")
|
||||
.attr('id', 'map')
|
||||
.height(500)
|
||||
.width(500);
|
||||
$('body').append(this.$el);
|
||||
this.map = new cdb.geo.Map();
|
||||
var template = cdb.core.Template.compile(
|
||||
'\
|
||||
<form>\
|
||||
<span class="loader"></span>\
|
||||
<input type="text" class="text" value="" />\
|
||||
<input type="submit" class="submit" value="" />\
|
||||
</form>\
|
||||
',
|
||||
'mustache'
|
||||
);
|
||||
this.mapView = new cdb.geo.LeafletMapView({
|
||||
el: this.$el,
|
||||
map: this.map
|
||||
});
|
||||
|
||||
this.view = new cdb.geo.ui.Search({
|
||||
template: template,
|
||||
model: this.map,
|
||||
mapView: this.mapView
|
||||
});
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function() {
|
||||
expect(this.view.$('form').length).toBe(1);
|
||||
expect(this.view.$('input[type="text"]').length).toBe(1);
|
||||
expect(this.view.$('input[type="submit"]').length).toBe(1);
|
||||
expect(this.view.$('span.loader').length).toBe(1);
|
||||
});
|
||||
|
||||
describe('onSubmit', function() {
|
||||
beforeEach(function(){
|
||||
var self = this;
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0,
|
||||
boundingbox: {
|
||||
south: 6.0,
|
||||
north: 4.0,
|
||||
west: 6.0,
|
||||
east: 4.0
|
||||
},
|
||||
type: undefined
|
||||
};
|
||||
cdb.geo.geocoder[this.view.GEOCODER_SERVICE].geocode = function(address, callback) {
|
||||
callback([ self.result ]);
|
||||
};
|
||||
|
||||
this.view.$('input.text').val('Madrid, Spain');
|
||||
});
|
||||
|
||||
it('should search with geocoder when form is submit', function() {
|
||||
spyOn(cdb.geo.geocoder[this.view.GEOCODER_SERVICE], 'geocode');
|
||||
this.view.$('form').submit();
|
||||
expect(cdb.geo.geocoder[this.view.GEOCODER_SERVICE].geocode).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should change map center when geocoder returns any result', function() {
|
||||
var onBoundsChanged = jasmine.createSpy("onBoundsChange");
|
||||
this.map.bind('change:view_bounds_sw', onBoundsChanged, this.view);
|
||||
this.view.$('form').submit();
|
||||
expect(onBoundsChanged).toHaveBeenCalled();
|
||||
this.map.unbind('change:view_bounds_sw', onBoundsChanged, this.view);
|
||||
});
|
||||
|
||||
it('should center map to lat,lon when bbox is not defined', function() {
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0
|
||||
};
|
||||
this.view.$('form').submit();
|
||||
var center = this.map.get('center');
|
||||
expect(center[0]).toBe(43.0);
|
||||
expect(center[1]).toBe(-3.0);
|
||||
});
|
||||
|
||||
it('should center map whith bbox when it is defined', function() {
|
||||
this.view.$('form').submit();
|
||||
var ne = this.map.get('view_bounds_ne');
|
||||
var sw = this.map.get('view_bounds_sw');
|
||||
expect(ne[0].toFixed(0)).toBe('6');
|
||||
expect(ne[1].toFixed(0)).toBe('6');
|
||||
expect(sw[0].toFixed(0)).toBe('4');
|
||||
expect(sw[1].toFixed(0)).toBe('4');
|
||||
var center = this.map.get('center');
|
||||
expect(center[0]).not.toBe(43.0);
|
||||
expect(center[1]).not.toBe(-3.0);
|
||||
});
|
||||
|
||||
describe('result zoom', function() {
|
||||
|
||||
it('should zoom to 18 when search result is building type', function() {
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0,
|
||||
type: 'building'
|
||||
};
|
||||
this.view.$('form').submit();
|
||||
expect(this.map.get('zoom')).toBe(18);
|
||||
});
|
||||
|
||||
it('should zoom to 15 when search result is postal-area type', function() {
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0,
|
||||
type: 'postal-area'
|
||||
};
|
||||
this.view.$('form').submit();
|
||||
expect(this.map.get('zoom')).toBe(15);
|
||||
});
|
||||
|
||||
it('should zoom to 18 when search result is venue type', function() {
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0,
|
||||
type: 'venue'
|
||||
};
|
||||
this.view.$('form').submit();
|
||||
expect(this.map.get('zoom')).toBe(18);
|
||||
});
|
||||
|
||||
it('should zoom to 8 when search result is region type', function() {
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0,
|
||||
type: 'region'
|
||||
};
|
||||
this.view.$('form').submit();
|
||||
expect(this.map.get('zoom')).toBe(8);
|
||||
});
|
||||
|
||||
it('should zoom to 5 when search result is country type', function() {
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0,
|
||||
type: 'country'
|
||||
};
|
||||
this.view.$('form').submit();
|
||||
expect(this.map.get('zoom')).toBe(5);
|
||||
});
|
||||
|
||||
it('should zoom to 8 when search result is county type', function() {
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0,
|
||||
type: 'county'
|
||||
};
|
||||
this.view.$('form').submit();
|
||||
expect(this.map.get('zoom')).toBe(8);
|
||||
});
|
||||
|
||||
it('should zoom to 18 when search result is address type', function() {
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0,
|
||||
type: 'address'
|
||||
};
|
||||
this.view.$('form').submit();
|
||||
expect(this.map.get('zoom')).toBe(18);
|
||||
});
|
||||
|
||||
it('should zoom to 12 when search result is locality type', function() {
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0,
|
||||
type: 'locality'
|
||||
};
|
||||
this.view.$('form').submit();
|
||||
expect(this.map.get('zoom')).toBe(12);
|
||||
});
|
||||
|
||||
it('should zoom to 11 when search result is localadmin type', function() {
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0,
|
||||
type: 'localadmin'
|
||||
};
|
||||
this.view.$('form').submit();
|
||||
expect(this.map.get('zoom')).toBe(11);
|
||||
});
|
||||
|
||||
it('should zoom to 15 when search result is neighbourhood type', function() {
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0,
|
||||
type: 'neighbourhood'
|
||||
};
|
||||
this.view.$('form').submit();
|
||||
expect(this.map.get('zoom')).toBe(15);
|
||||
});
|
||||
|
||||
it('should zoom to 12 when search result is unknown type', function() {
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0,
|
||||
type: 'whatever'
|
||||
};
|
||||
this.view.$('form').submit();
|
||||
expect(this.map.get('zoom')).toBe(12);
|
||||
});
|
||||
});
|
||||
|
||||
describe('searchPin', function() {
|
||||
beforeEach(function() {
|
||||
this.view.options.searchPin = true;
|
||||
this.view.$('form').submit();
|
||||
});
|
||||
|
||||
it('should add a pin and an infowindow when search is completed', function() {
|
||||
expect(this.view._searchPin).toBeDefined();
|
||||
expect(this.view._searchInfowindow).toBeDefined();
|
||||
});
|
||||
|
||||
it('should place pin in the lat,lon if it is provided', function() {
|
||||
this.result = {
|
||||
lat: 43.0,
|
||||
lon: -3.0
|
||||
};
|
||||
var center = this.view._searchPin.model.get('geojson').coordinates;
|
||||
expect(center[0]).toBe(-3.0);
|
||||
expect(center[1]).toBe(43.0);
|
||||
});
|
||||
|
||||
it('should place pin in the middle of the bbox if lat,lon is not provided', function() {
|
||||
this.result = {
|
||||
boundingbox: {
|
||||
south: 6.0,
|
||||
north: 4.0,
|
||||
west: 6.0,
|
||||
east: 4.0
|
||||
}
|
||||
};
|
||||
this.view.$('form').submit();
|
||||
var center = this.view._searchPin.model.get('geojson').coordinates;
|
||||
expect(center[0]).toBe(5.0);
|
||||
expect(center[1]).toBe(5.0);
|
||||
});
|
||||
|
||||
it('should display address in the search infowindow', function() {
|
||||
expect(this.view._searchInfowindow.$('.cartodb-popup-content-wrapper p').text()).toBe('Madrid, Spain');
|
||||
});
|
||||
|
||||
it('should destroy/hide search pin when map is clicked', function(done) {
|
||||
expect(this.view._searchPin).toBeDefined();
|
||||
expect(this.view._searchInfowindow).toBeDefined();
|
||||
this.mapView.trigger('click');
|
||||
setTimeout(function() {
|
||||
expect(this.view._searchPin).toBeUndefined();
|
||||
expect(this.view._searchInfowindow).toBeUndefined();
|
||||
done();
|
||||
}, 1500);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
this.$el.remove();
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,107 @@
|
||||
describe('cdb.geo.ui.TimeSlider', function() {
|
||||
var view;
|
||||
var layer;
|
||||
|
||||
beforeEach(function() {
|
||||
layer = new Backbone.Model();
|
||||
view = new cdb.geo.ui.TimeSlider({
|
||||
layer: layer,
|
||||
width: "auto"
|
||||
});
|
||||
});
|
||||
|
||||
describe(".formatterForRange", function() {
|
||||
var formatter;
|
||||
|
||||
/**
|
||||
* @param {String} str (Optional) e.g. "2014-11-19T13:17:42Z" ATTENTION! This format must be used for Dates to be
|
||||
* created as expected when running the tests on PhantomJS, you can find the report here:
|
||||
* https://code.google.com/p/phantomjs/issues/detail?id=187 until the fix is included in the same version we use
|
||||
* we must use dates this way.
|
||||
* @return {Number} a Unix timestamp
|
||||
*/
|
||||
var time = function time(str) {
|
||||
return Date.parse(str)
|
||||
};
|
||||
|
||||
describe("given a range is within the same day", function() {
|
||||
beforeEach(function() {
|
||||
var start = time("2014-11-19T09:13:00Z");
|
||||
var end = time("2014-11-19T18:37:00Z");
|
||||
formatter = view.formatterForRange(start, end)
|
||||
});
|
||||
|
||||
it("should return a formatter function that renders the local time of given moment", function() {
|
||||
var moment = new Date("2014-11-19T15:04:00Z");
|
||||
expect(formatter(moment).match(/\d?\d:\d\d/g).length > 0).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("given a range is within the same year", function() {
|
||||
beforeEach(function() {
|
||||
var start = time("2014-11-19T12:00:00Z");
|
||||
var end = Date.parse("Dec 24, 2014 12:00 GMT+01");
|
||||
formatter = view.formatterForRange(start, end)
|
||||
});
|
||||
|
||||
it("should return a formatter function that renders the month/day/year (US format) of given moment", function() {
|
||||
var moment = new Date("2014-11-20T12:00:00Z");
|
||||
expect(formatter(moment)).toEqual("11/20/2014");
|
||||
});
|
||||
});
|
||||
|
||||
describe("given a range is more than a year", function() {
|
||||
beforeEach(function() {
|
||||
var start = time("2014-01-19T12:00:00Z");
|
||||
var end = time("2015-02-01T12:00:00Z");
|
||||
formatter = view.formatterForRange(start, end)
|
||||
});
|
||||
|
||||
it("should return a formatter function that renders the month and year of given moment", function() {
|
||||
var moment = new Date("2014-11-27T12:00:00Z");
|
||||
expect(formatter(moment)).toEqual("11/2014")
|
||||
});
|
||||
});
|
||||
|
||||
describe("given a step that spans more than 48 hours", function() {
|
||||
beforeEach(function() {
|
||||
var start = 1423699205000;
|
||||
var end = 1424649534000;
|
||||
view.torqueLayer.getTimeBounds = function(){return {start: start, end: end}};
|
||||
view.torqueLayer.options = {steps: 5};
|
||||
formatter = view.formatterForRange(start, end);
|
||||
});
|
||||
it("should return a formatter function that defines a two-date range", function() {
|
||||
var moment = new Date(1424269402400);
|
||||
expect(formatter(moment, view.torqueLayer)).toEqual("Feb 18 - Feb 20");
|
||||
});
|
||||
});
|
||||
|
||||
describe("given a step that spans more than 48 hours, but within a period of more than a year", function() {
|
||||
beforeEach(function() {
|
||||
var start = 1423699205000;
|
||||
var end = 1460419200000;
|
||||
view.torqueLayer.getTimeBounds = function(){return {start: start, end: end}};
|
||||
view.torqueLayer.options = {steps: 5};
|
||||
formatter = view.formatterForRange(start, end);
|
||||
});
|
||||
it("should return a formatter function that defines a two-date range", function() {
|
||||
var moment = new Date(1424269402400);
|
||||
expect(formatter(moment, view.torqueLayer).indexOf(" - ")).toEqual(-1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("given a range is less than a day but spanning two dates", function() {
|
||||
beforeEach(function() {
|
||||
var start = time("2014-11-19T23:33:00Z");
|
||||
var end = time("2014-11-20T09:42:00Z");
|
||||
formatter = view.formatterForRange(start, end)
|
||||
});
|
||||
|
||||
it("should return a formatter function that renders both date and local time", function() {
|
||||
var moment = new Date("2014-11-20T01:16:00Z");
|
||||
expect(formatter(moment).match(/\d?\d:\d\d/g).length > 0).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,198 @@
|
||||
describe('cdb.geo.Tooltip', function() {
|
||||
|
||||
var tooltip, layer, container, mapView;
|
||||
beforeEach(function() {
|
||||
container = $("<div id='map'>").css('height', '1000px');
|
||||
$('body').append(container)
|
||||
var map = new cdb.geo.Map();
|
||||
mapView = new cdb.geo.LeafletMapView({
|
||||
el: $('#map'),
|
||||
map: map
|
||||
});
|
||||
|
||||
layer = new Backbone.Model();
|
||||
tooltip = new cdb.geo.ui.Tooltip({
|
||||
template: '{{#fields}}{{{ value }}},{{/fields}}',
|
||||
layer: layer,
|
||||
mapView: mapView
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
$('#map').remove();
|
||||
});
|
||||
|
||||
it ("should render fields in specified order", function() {
|
||||
tooltip.setFields([{
|
||||
name:'test2'
|
||||
}, {
|
||||
name:'test1'
|
||||
}, {
|
||||
name: 'huracan'
|
||||
}]);
|
||||
tooltip.enable();
|
||||
layer.trigger('mouseover', new $.Event('e'), [0,0], [0, 0], {
|
||||
test1: 'test1',
|
||||
test2: 'test2',
|
||||
huracan: 'huracan'
|
||||
});
|
||||
expect(tooltip.$el.html()).toEqual('test2,test1,huracan,');
|
||||
tooltip.options.columns_order = null;
|
||||
layer.trigger('mouseover', new $.Event('e'), [0,0], [0, 0], {
|
||||
test1: 'test1',
|
||||
test2: 'test2',
|
||||
huracan: 'hurecan'
|
||||
});
|
||||
expect(tooltip.$el.html()).not.toEqual('test2,test1,huracan,');
|
||||
});
|
||||
|
||||
it("should not show the tooltip if there are no fields", function() {
|
||||
tooltip.setFields([]);
|
||||
tooltip.enable();
|
||||
|
||||
layer.trigger('mouseover', new $.Event('e'), [0, 0], [0, 0], {});
|
||||
|
||||
// Tooltip is hidden
|
||||
expect(tooltip.showing).toBeFalsy();
|
||||
});
|
||||
|
||||
it("should hide the tooltip if it was visible and there are no fields now", function() {
|
||||
tooltip.setFields([{
|
||||
name:'test2'
|
||||
}]);
|
||||
tooltip.enable();
|
||||
|
||||
// mouseover a layer whose tooltip has fields
|
||||
layer.trigger('mouseover', new $.Event('e'), [0, 0], [0, 0], { name: 'wadus' });
|
||||
|
||||
// Tooltip is visible
|
||||
expect(tooltip.showing).toBeTruthy();
|
||||
|
||||
tooltip.setFields([]);
|
||||
|
||||
// mouseover a layer whose tooltip doesn NOT has fields
|
||||
layer.trigger('mouseover', new $.Event('e'), [0, 0], [0, 0], {});
|
||||
|
||||
// Tooltip is hidden
|
||||
expect(tooltip.showing).toBeFalsy();
|
||||
})
|
||||
|
||||
it ("should use alternate_names ", function() {
|
||||
tooltip.setTemplate('{{#fields}}{{{ title }}},{{/fields}}');
|
||||
tooltip.setFields([{
|
||||
name:'test2',
|
||||
title: true
|
||||
}, {
|
||||
name:'test1',
|
||||
title: true
|
||||
}, {
|
||||
name: 'huracan',
|
||||
title: true
|
||||
}]);
|
||||
tooltip.options.alternative_names = {
|
||||
'test1': 'testnamed'
|
||||
};
|
||||
tooltip.enable();
|
||||
layer.trigger('mouseover', new $.Event('e'), [0,0], [0, 0], {
|
||||
test1: 'test1',
|
||||
test2: 'test2',
|
||||
huracan: 'huracan'
|
||||
});
|
||||
expect(tooltip.$el.html()).toEqual('test2,testnamed,huracan,');
|
||||
});
|
||||
|
||||
it ("should position the element correctly", function() {
|
||||
tooltip.$el.css('width', '200px');
|
||||
tooltip.$el.css('height', '20px');
|
||||
var data = { cartodb_id: 2, description: 'test' };
|
||||
|
||||
tooltip.options.position = 'bottom|right';
|
||||
tooltip.show({ x:10, y:10 }, data);
|
||||
expect(tooltip.$el.css('top')).toBe('10px');
|
||||
expect(tooltip.$el.css('left')).toBe('10px');
|
||||
|
||||
tooltip.options.position = 'top|left';
|
||||
tooltip.show({ x:210, y:40 }, data);
|
||||
expect(tooltip.$el.css('top')).toBe('20px');
|
||||
expect(tooltip.$el.css('left')).toBe('10px');
|
||||
|
||||
tooltip.options.position = 'middle|center';
|
||||
tooltip.show({ x:150, y:30 }, data);
|
||||
expect(tooltip.$el.css('top')).toBe('20px');
|
||||
expect(tooltip.$el.css('left')).toBe('50px');
|
||||
|
||||
// With offsets
|
||||
tooltip.options.position = 'middle|center';
|
||||
tooltip.options.vertical_offset = -10;
|
||||
tooltip.options.horizontal_offset = -10;
|
||||
tooltip.show({ x:150, y:30 }, data);
|
||||
expect(tooltip.$el.css('top')).toBe('10px');
|
||||
expect(tooltip.$el.css('left')).toBe('40px');
|
||||
});
|
||||
|
||||
describe('overflow positioning', function() {
|
||||
var data;
|
||||
|
||||
beforeEach(function() {
|
||||
data = { cartodb_id: 2, description: 'test' };
|
||||
$('#map').css('height', '100px');
|
||||
$('#map').css('width', '100px');
|
||||
tooltip.$el.css('height', '80px');
|
||||
tooltip.$el.css('width', '80px');
|
||||
mapView.invalidateSize();
|
||||
});
|
||||
|
||||
it('should position the element on top when bottom overflow occurs', function() {
|
||||
tooltip.options.position = 'bottom|right';
|
||||
|
||||
tooltip.show({ x:0, y:90 }, data);
|
||||
expect(tooltip.$el.css('top')).toBe('10px');
|
||||
});
|
||||
|
||||
it('should position the element on the bottom when top overflow occurs', function() {
|
||||
tooltip.options.position = 'top|right';
|
||||
|
||||
tooltip.show({ x:0, y:10 }, data);
|
||||
expect(tooltip.$el.css('top')).toBe('10px');
|
||||
});
|
||||
|
||||
it('should position the element on top/bottom when overflow vertically centered and overflow occurs', function() {
|
||||
tooltip.options.position = 'middle|right';
|
||||
|
||||
tooltip.show({ x:0, y:90 }, data);
|
||||
expect(tooltip.$el.css('top')).toBe('10px');
|
||||
|
||||
tooltip.options.position = 'middle|right';
|
||||
|
||||
tooltip.show({ x:0, y:10 }, data);
|
||||
expect(tooltip.$el.css('top')).toBe('10px');
|
||||
})
|
||||
|
||||
it('should position the element on the left when right overflow occurs', function() {
|
||||
tooltip.options.position = 'top|right';
|
||||
|
||||
tooltip.show({ x:90, y:10 }, data);
|
||||
expect(tooltip.$el.css('left')).toBe('10px');
|
||||
});
|
||||
|
||||
it('should position the element on the right when left overflow occurs', function() {
|
||||
tooltip.options.position = 'top|left';
|
||||
|
||||
tooltip.show({ x:10, y:10 }, data);
|
||||
expect(tooltip.$el.css('left')).toBe('10px');
|
||||
});
|
||||
|
||||
it('should position the element on the left/right when horizontally centered and overflow occurs', function() {
|
||||
tooltip.options.position = 'top|center';
|
||||
|
||||
tooltip.show({ x:10, y:10 }, data);
|
||||
expect(tooltip.$el.css('left')).toBe('10px');
|
||||
|
||||
tooltip.options.position = 'top|center';
|
||||
|
||||
tooltip.show({ x:90, y:10 }, data);
|
||||
expect(tooltip.$el.css('left')).toBe('10px');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
describe("common.ui.Dialog", function() {
|
||||
|
||||
var dialog;
|
||||
beforeEach(function() {
|
||||
dialog = new cdb.ui.common.Dialog({el: $('<div>')});
|
||||
dialog.ok = function() {};
|
||||
dialog.cancel = function() {};
|
||||
spyOn(dialog, 'ok');
|
||||
spyOn(dialog, 'cancel');
|
||||
});
|
||||
|
||||
it("should show element on open", function() {
|
||||
dialog.open();
|
||||
expect(dialog.$el.css('display')).toEqual('block');
|
||||
});
|
||||
|
||||
it("should hide element on close", function() {
|
||||
dialog.open();
|
||||
dialog.hide();
|
||||
expect(dialog.$el.css('display')).toEqual('none');
|
||||
});
|
||||
|
||||
it("should hide element on ok", function() {
|
||||
dialog.open();
|
||||
dialog._ok();
|
||||
expect(dialog.$el.css('display')).toEqual('none');
|
||||
});
|
||||
|
||||
it("should call cancel on _cancel", function() {
|
||||
dialog._ok();
|
||||
expect(dialog.ok).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should call ok on _ok", function() {
|
||||
dialog._cancel();
|
||||
expect(dialog.cancel).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should append it to body and be rendered", function() {
|
||||
var s = sinon.stub(dialog, 'render');
|
||||
s.returns(dialog);
|
||||
var r = dialog.appendToBody();
|
||||
expect(s.called).toEqual(true);
|
||||
expect(dialog.$el.parent()[0]).toEqual(document.body);
|
||||
expect(r).toEqual(dialog);
|
||||
});
|
||||
|
||||
it("should render title", function() {
|
||||
var dialog = new cdb.ui.common.Dialog({
|
||||
title: 'test',
|
||||
template_base: '<%= title %>'
|
||||
});
|
||||
expect(dialog.render().$el.html()).toEqual('test');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
describe('common.ui.Dropdown', function() {
|
||||
beforeEach(function() {
|
||||
this.$el = $('<div><button id="btn"></button></div>');
|
||||
this.view = new cdb.ui.common.Dropdown({
|
||||
el: $('<div>'),
|
||||
target: this.$el.find('#btn')
|
||||
});
|
||||
});
|
||||
|
||||
describe('.clean', function() {
|
||||
it('should unbind click handler on target', function() {
|
||||
this.targetClickSpy = jasmine.createSpy('click');
|
||||
this.$el.on('click', this.targetClickSpy);
|
||||
|
||||
// Event should not bubble up since there is a handler that prevents it
|
||||
this.$el.find('#btn').click();
|
||||
expect(this.targetClickSpy).not.toHaveBeenCalled();
|
||||
|
||||
// Verify click bubbles up as expected again
|
||||
this.view.clean();
|
||||
this.$el.find('#btn').click();
|
||||
expect(this.targetClickSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should unbind event handlers on document', function() {
|
||||
// spy on internal call, since spying on _keydown fn do not work for some reason
|
||||
spyOn(this.view, 'hide');
|
||||
var keyEsc = function() {
|
||||
var e = $.Event('keydown');
|
||||
e.keyCode = 27; // ESC
|
||||
$(document).trigger(e);
|
||||
};
|
||||
|
||||
// Should hide on ESC
|
||||
keyEsc();
|
||||
expect(this.view.hide).toHaveBeenCalled();
|
||||
|
||||
// Callback should not be triggered again
|
||||
this.view.clean();
|
||||
keyEsc();
|
||||
expect(this.view.hide.calls.count()).toEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
describe("common.ui.Notification", function() {
|
||||
|
||||
var notification;
|
||||
beforeEach(function() {
|
||||
notification = new cdb.ui.common.Notification({
|
||||
el: $('<div>'),
|
||||
template: 'template'
|
||||
});
|
||||
//spyOn(dialog, 'cancel');
|
||||
});
|
||||
|
||||
it("open should show the element", function(done) {
|
||||
expect(notification.$el.css('display')).toEqual('none');
|
||||
notification.open();
|
||||
setTimeout(function () {
|
||||
expect(notification.$el.css('display')).toEqual('block');
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
it("should be closed on timeout", function(done) {
|
||||
notification = new cdb.ui.common.Notification({
|
||||
el: $('<div>'),
|
||||
timeout: 250,
|
||||
template: 'template'
|
||||
});
|
||||
notification.open();
|
||||
|
||||
setTimeout(function () {
|
||||
expect(notification.$el.css('display')).toEqual('none');
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
@@ -0,0 +1,279 @@
|
||||
describe("common.ui.Table", function() {
|
||||
|
||||
var cols;
|
||||
var tableMetadata;
|
||||
describe("Row", function() {
|
||||
beforeEach(function() {
|
||||
});
|
||||
|
||||
// it("", function() {
|
||||
|
||||
// });
|
||||
});
|
||||
|
||||
describe("TableData", function() {
|
||||
beforeEach(function() {
|
||||
cols = new cdb.ui.common.TableData();
|
||||
cols.reset([
|
||||
{'id': 1, 'col1': 1, 'col2': 2, 'col3': 3},
|
||||
{'id': 2, 'col1': 4, 'col2': 5, 'col3': 6}
|
||||
]);
|
||||
});
|
||||
it("should return the value for cell", function() {
|
||||
expect(cols.getCell(0, 'col1')).toEqual(1);
|
||||
});
|
||||
|
||||
it("should return null for non existing cell", function() {
|
||||
expect(cols.getCell(10, 'col1')).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe("RowView", function() {
|
||||
it("should render in a row", function() {
|
||||
var row = new cdb.ui.common.Row({test0: 'a', test1: 'b'});
|
||||
var r = new cdb.ui.common.RowView({model: row});
|
||||
expect(r.render().$('td').length).toEqual(3); // two rows plus one blank row before them
|
||||
});
|
||||
|
||||
it("should render in order", function() {
|
||||
var row = new cdb.ui.common.Row({test0: 'a', test1: 'b'});
|
||||
var r = new cdb.ui.common.RowView({model: row, order: ['test1', 'test0']});
|
||||
r.render();
|
||||
expect($(r.$('td')[1]).html()).toEqual('b');
|
||||
expect($(r.$('td')[2]).html()).toEqual('a');
|
||||
|
||||
r = new cdb.ui.common.RowView({model: row, order: ['test0', 'test1']});
|
||||
r.render();
|
||||
expect($(r.$('td')[1]).html()).toEqual('a');
|
||||
expect($(r.$('td')[2]).html()).toEqual('b');
|
||||
});
|
||||
|
||||
it("should render row header", function() {
|
||||
var row = new cdb.ui.common.Row({test0: 'a', test1: 'b'});
|
||||
var r = new cdb.ui.common.RowView({
|
||||
model: row,
|
||||
row_header: true
|
||||
});
|
||||
r.render();
|
||||
expect(r.$('td').length).toEqual(3);
|
||||
});
|
||||
|
||||
it("should return cell x", function() {
|
||||
var row = new cdb.ui.common.Row({test0: 'a', test1: 'b'});
|
||||
var r = new cdb.ui.common.RowView({model: row});
|
||||
r.render();
|
||||
expect(r.getCell(2).html()).toEqual('b');
|
||||
});
|
||||
});
|
||||
|
||||
describe("Table", function() {
|
||||
var table;
|
||||
beforeEach(function() {
|
||||
cdb.ui.common.Row.url = 'test';
|
||||
cols = new cdb.ui.common.TableData();
|
||||
cols.url = 'test';
|
||||
|
||||
tableMetadata = new cdb.ui.common.TableProperties({
|
||||
schema: [
|
||||
['id', 'number'],
|
||||
['col1','number'],
|
||||
['col2','number'],
|
||||
['col3','number']
|
||||
]
|
||||
});
|
||||
cols.reset([
|
||||
{'id': 1, 'col1': 1, 'col2': 2, 'col3': 3},
|
||||
{'id': 2, 'col1': 4, 'col2': 5, 'col3': 6}
|
||||
]);
|
||||
|
||||
table = new cdb.ui.common.Table({
|
||||
dataModel: cols,
|
||||
model: tableMetadata
|
||||
});
|
||||
|
||||
this.server = sinon.fakeServer.create();
|
||||
|
||||
|
||||
});
|
||||
|
||||
it("should render a table", function() {
|
||||
expect(table.render().$el.is('table')).toEqual(true);
|
||||
});
|
||||
|
||||
it("should render a header", function() {
|
||||
expect(table.render().$('thead')).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should have 2 rows and the header", function() {
|
||||
expect(table.render().$('tr').length).toEqual(3);
|
||||
});
|
||||
|
||||
it("should have 6 cells and header", function() {
|
||||
expect(table.render().$('th').length).toEqual(5);
|
||||
expect(table.render().$('td').length).toEqual(2*5);
|
||||
});
|
||||
|
||||
it("each row has an id", function() {
|
||||
expect($(table.render().$('tr')[1]).attr('id')).toEqual('row_' + cols.at(0).id);
|
||||
});
|
||||
|
||||
it("should change value when model changes", function() {
|
||||
table.render();
|
||||
cols.at(0).set('col1', 10);
|
||||
expect(table.$('#cell_1_col1').html()).toEqual(cols.at(0).get('col1').toString());
|
||||
});
|
||||
|
||||
it("should rerender on data reset", function() {
|
||||
expect(table.render().$('tr').length).toEqual(3);
|
||||
cols.reset([
|
||||
{'id': 1, 'col1': 1, 'col2': 2, 'col3': 3}
|
||||
]);
|
||||
expect(table.$('tr').length).toEqual(2);
|
||||
});
|
||||
|
||||
it("should remove rows on remove", function() {
|
||||
table.render();
|
||||
cols.at(0).destroy();
|
||||
expect(table.$('tr').length).toEqual(2);
|
||||
expect(table.rowViews.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should add rows", function() {
|
||||
table.render();
|
||||
cols.add({'id': 4, 'col1': 1, 'col2': 2, 'col3': 3});
|
||||
expect(table.$('tr').length).toEqual(4);
|
||||
});
|
||||
|
||||
it("should add rows at index", function() {
|
||||
table.render();
|
||||
cols.add({'id': 10, 'col1': 11, 'col2': 12, 'col3': 13}, {at: 1});
|
||||
expect(table.$('tr').length).toEqual(4);
|
||||
var cell = table.getCell(1, 1);
|
||||
expect(cell.html()).toEqual('10');
|
||||
expect(cell.parent().attr('data-y')).toEqual('1');
|
||||
expect(table.getCell(1, 2).parent().attr('data-y')).toEqual('2');
|
||||
});
|
||||
|
||||
it("should update cell indexes when remove a column", function() {
|
||||
table.render();
|
||||
cols.add({'id': 10, 'col1': 11, 'col2': 12, 'col3': 13}, {at: 1});
|
||||
expect(table.$('tr').length).toEqual(4);
|
||||
cols.remove(cols.at(0));
|
||||
var cell = table.getCell(0, 1);
|
||||
expect(cell.parent().attr('data-y')).toEqual('1');
|
||||
/*
|
||||
var cell = table.getCell(0, 1);
|
||||
expect(cell.html()).toEqual('10');
|
||||
expect(cell.parent().attr('data-y')).toEqual('1');
|
||||
expect(table.getCell(0, 2).parent().attr('data-y')).toEqual('2');
|
||||
*/
|
||||
});
|
||||
|
||||
it("should remove rows", function() {
|
||||
table.render();
|
||||
cols.remove(cols.at(0));
|
||||
expect(table.$('tr').length).toEqual(2);
|
||||
});
|
||||
|
||||
it("should return cell x,y", function() {
|
||||
//$('#foo').trigger('click');
|
||||
var cell = table.render().getCell(1, 1);
|
||||
expect(cell.html()).toEqual('2');
|
||||
cell = table.getCell(2, 1);
|
||||
expect(cell.html()).toEqual('4');
|
||||
});
|
||||
|
||||
it("should trigger cell clicked on click and dblclick", function() {
|
||||
var cell = table.render().getCell(0, 1);
|
||||
spy = {
|
||||
click: function() {},
|
||||
dblClick: function() {}
|
||||
};
|
||||
spyOn(spy, 'click');
|
||||
spyOn(spy, 'dblClick');
|
||||
table.bind('cellClick', spy.click, spy);
|
||||
cell.trigger('click');
|
||||
expect(spy.click).toHaveBeenCalled();
|
||||
expect(spy.click.calls.mostRecent().args[1][0]).toEqual(cell[0]);
|
||||
expect(spy.click.calls.mostRecent().args[2]).toEqual(0);
|
||||
expect(spy.click.calls.mostRecent().args[3]).toEqual(1);
|
||||
|
||||
table.bind('cellDblClick', spy.dblClick, spy);
|
||||
cell.trigger('dblclick');
|
||||
expect(spy.dblClick).toHaveBeenCalled();
|
||||
expect(spy.dblClick.calls.mostRecent().args[1][0]).toEqual(cell[0]);
|
||||
expect(spy.dblClick.calls.mostRecent().args[2]).toEqual(0);
|
||||
expect(spy.dblClick.calls.mostRecent().args[3]).toEqual(1);
|
||||
|
||||
});
|
||||
|
||||
it("should render new data on change data source", function() {
|
||||
cols = new cdb.ui.common.TableData();
|
||||
table.setDataSource(cols);
|
||||
cols.reset([
|
||||
{'id': 100, 'col1': 1, 'col2': 2, 'col3': 3}
|
||||
]);
|
||||
cell = table.getCell(1, 0);
|
||||
expect(cell.html()).toEqual('100');
|
||||
});
|
||||
|
||||
it("should clear rows after a reset", function() {
|
||||
expect(table.render().$('tr').length).toEqual(3);
|
||||
cols.reset([]);
|
||||
expect(table.$('tr').length).toEqual(1); // only the header
|
||||
});
|
||||
|
||||
it("should call renderEmpty after an error", function() {
|
||||
spyOn(table, '_renderEmpty');
|
||||
cols.reset([], { silent: true });
|
||||
cols.trigger('error');
|
||||
expect(table._renderEmpty).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
||||
it("should render faster than light", function() {
|
||||
var NCOLUMNS = 100;
|
||||
var NROWS = 260;
|
||||
var schema = []
|
||||
var rows = [];
|
||||
|
||||
_(NCOLUMNS).times(function(n) {
|
||||
schema.push(['column_' + n, 'string']);
|
||||
});
|
||||
|
||||
_(NROWS).times(function(n) {
|
||||
var row = {}
|
||||
_(schema).each(function(c) {
|
||||
row[c[0]] = "testestestest"
|
||||
})
|
||||
rows.push(row);
|
||||
});
|
||||
|
||||
|
||||
tableMetadata = new cdb.ui.common.TableProperties({
|
||||
schema: schema
|
||||
});
|
||||
cols.reset(rows);
|
||||
|
||||
table = new cdb.ui.common.Table({
|
||||
dataModel: cols,
|
||||
model: tableMetadata
|
||||
});
|
||||
|
||||
var mean = 0;
|
||||
var count = 5;
|
||||
for(var i = 0; i < count; ++i) {
|
||||
var t0 = new Date().getTime();
|
||||
table.render();
|
||||
var t1 = new Date().getTime();
|
||||
mean += t1 - t0;
|
||||
}
|
||||
// God please, forgive me.
|
||||
expect(mean/count).toBeLessThan(10000);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
describe('core.ui.common.TabPane', function() {
|
||||
|
||||
var pane;
|
||||
|
||||
beforeEach(function() {
|
||||
pane = new cdb.ui.common.TabPane();
|
||||
});
|
||||
|
||||
it("getPreviousPane should return the last pane if the active pane is the first one", function() {
|
||||
|
||||
var // Let's create the views
|
||||
v1 = new cdb.core.View(),
|
||||
v2 = new cdb.core.View(),
|
||||
v3 = new cdb.core.View();
|
||||
|
||||
// Add some tabs
|
||||
pane.addTab('tab1', v1);
|
||||
pane.addTab('tab2', v2);
|
||||
pane.addTab('tab3', v3);
|
||||
|
||||
pane.active('tab1');
|
||||
|
||||
expect(pane.getPreviousPane()).toEqual(v3);
|
||||
|
||||
});
|
||||
it("getPreviousPane should return the previous pane", function() {
|
||||
|
||||
var // Let's create the views
|
||||
v1 = new cdb.core.View(),
|
||||
v2 = new cdb.core.View(),
|
||||
v3 = new cdb.core.View();
|
||||
|
||||
// Add some tabs
|
||||
pane.addTab('tab1', v1);
|
||||
pane.addTab('tab2', v2);
|
||||
pane.addTab('tab3', v3);
|
||||
|
||||
pane.active('tab2');
|
||||
|
||||
expect(pane.getPreviousPane()).toEqual(v1);
|
||||
|
||||
});
|
||||
|
||||
it("getNextPane should return the next pane", function() {
|
||||
|
||||
var // Let's create the views
|
||||
v1 = new cdb.core.View(),
|
||||
v2 = new cdb.core.View(),
|
||||
v3 = new cdb.core.View();
|
||||
|
||||
// Add some tabs
|
||||
pane.addTab('tab1', v1);
|
||||
pane.addTab('tab2', v2);
|
||||
pane.addTab('tab3', v3);
|
||||
|
||||
pane.active('tab1');
|
||||
|
||||
expect(pane.getNextPane()).toEqual(v2);
|
||||
|
||||
});
|
||||
|
||||
it("getNextPane should return the first pane if the last pane is active", function() {
|
||||
|
||||
var // Let's create the views
|
||||
v1 = new cdb.core.View(),
|
||||
v2 = new cdb.core.View(),
|
||||
v3 = new cdb.core.View();
|
||||
|
||||
// Add some tabs
|
||||
pane.addTab('tab1', v1);
|
||||
pane.addTab('tab2', v2);
|
||||
pane.addTab('tab3', v3);
|
||||
|
||||
pane.active('tab3');
|
||||
|
||||
expect(pane.getNextPane()).toEqual(v1);
|
||||
|
||||
});
|
||||
|
||||
it("getActive should return the desired pane", function() {
|
||||
|
||||
var // Let's create the views
|
||||
v1 = new cdb.core.View(),
|
||||
v2 = new cdb.core.View(),
|
||||
v3 = new cdb.core.View();
|
||||
|
||||
// Add some tabs
|
||||
pane.addTab('tab1', v1);
|
||||
pane.addTab('tab2', v2);
|
||||
pane.addTab('tab3', v3);
|
||||
|
||||
expect(pane.getPane('tab1')).toEqual(v1);
|
||||
expect(pane.getPane('tab3')).toEqual(v3);
|
||||
expect(pane.getPane('tab2')).toEqual(v2);
|
||||
|
||||
});
|
||||
|
||||
it("getActivePane should return the active pane", function() {
|
||||
|
||||
var // Let's create the views
|
||||
v1 = new cdb.core.View(),
|
||||
v2 = new cdb.core.View(),
|
||||
v3 = new cdb.core.View();
|
||||
|
||||
// Add some tabs
|
||||
pane.addTab('tab1', v1);
|
||||
pane.addTab('tab2', v2);
|
||||
pane.addTab('tab3', v3);
|
||||
|
||||
// Finally, activate one of them
|
||||
pane.active('tab2');
|
||||
|
||||
expect(pane.getActivePane()).toEqual(v2);
|
||||
|
||||
});
|
||||
|
||||
it("activating a tab should return the view", function() {
|
||||
|
||||
var // Let's create the views
|
||||
v1 = new cdb.core.View(),
|
||||
v2 = new cdb.core.View(),
|
||||
v3 = new cdb.core.View();
|
||||
|
||||
// Add some tabs
|
||||
pane.addTab('tab1', v1);
|
||||
pane.addTab('tab2', v2);
|
||||
pane.addTab('tab3', v3);
|
||||
|
||||
// Finally, activate one of them
|
||||
var activeView = pane.active('tab2');
|
||||
|
||||
expect(activeView).toEqual(v2);
|
||||
|
||||
});
|
||||
|
||||
it("should allow to add a pane", function() {
|
||||
|
||||
var v1 = new cdb.core.View();
|
||||
|
||||
spy = {
|
||||
tabAdded: function(){}
|
||||
};
|
||||
|
||||
spyOn(spy, 'tabAdded');
|
||||
|
||||
pane.bind('tabAdded', spy.tabAdded, spy);
|
||||
|
||||
pane.addTab('tab1', v1);
|
||||
|
||||
expect(pane._subviews[v1.cid]).toBeTruthy();
|
||||
expect(pane.activeTab).toEqual('tab1');
|
||||
expect(pane.$el.children()[0]).toEqual(v1.el);
|
||||
expect(spy.tabAdded).toHaveBeenCalledWith('tab1', v1);
|
||||
|
||||
});
|
||||
|
||||
it("should allow to remove a pane", function() {
|
||||
|
||||
var // Let's create the views
|
||||
v1 = new cdb.core.View(),
|
||||
v2 = new cdb.core.View();
|
||||
|
||||
// Add the views
|
||||
pane.addTab('tab1', v1);
|
||||
pane.addTab('tab2', v2);
|
||||
|
||||
pane.active('tab1');
|
||||
|
||||
pane.removeTab('tab1');
|
||||
|
||||
expect(pane._subviews[v1.cid]).toBeFalsy();
|
||||
expect(pane.activeTab).toEqual('tab2');
|
||||
|
||||
// There shold be only one children
|
||||
expect(pane.$el.children()[0]).toEqual(v2.el);
|
||||
expect(pane.$el.children().length).toEqual(1);
|
||||
|
||||
});
|
||||
|
||||
it("should remove all panels ", function() {
|
||||
var v1 = new cdb.core.View();
|
||||
var v2 = new cdb.core.View();
|
||||
spyOn(v1, 'clean');
|
||||
spyOn(v2, 'clean');
|
||||
pane.addTab('tab1', v1);
|
||||
pane.addTab('tab2', v2);
|
||||
pane.removeTabs();
|
||||
expect(_.keys(pane.tabs).length).toEqual(0);
|
||||
expect(v1.clean).toHaveBeenCalled()
|
||||
expect(v2.clean).toHaveBeenCalled()
|
||||
});
|
||||
|
||||
it("should trigger on activate", function() {
|
||||
|
||||
var // Let's create the views
|
||||
v1 = new cdb.core.View(),
|
||||
v2 = new cdb.core.View();
|
||||
|
||||
spy = {
|
||||
tabEnabled: function(){},
|
||||
tabDisabled: function(){}
|
||||
};
|
||||
|
||||
spyOn(spy, 'tabDisabled');
|
||||
spyOn(spy, 'tabEnabled');
|
||||
|
||||
pane.addTab('tab1', v1);
|
||||
pane.addTab('tab2', v2);
|
||||
|
||||
expect(pane.activeTab).toEqual('tab2');
|
||||
|
||||
pane.bind('tabEnabled', spy.tabEnabled, spy);
|
||||
pane.bind('tabDisabled', spy.tabDisabled, spy);
|
||||
|
||||
pane.active('tab1');
|
||||
|
||||
expect(spy.tabEnabled).toHaveBeenCalledWith('tab1', v1);
|
||||
expect(spy.tabDisabled).toHaveBeenCalledWith('tab2', v2);
|
||||
|
||||
expect(v1.el.style.display).toEqual('block');
|
||||
expect(v2.el.style.display).toEqual('none');
|
||||
|
||||
});
|
||||
|
||||
it("should call activated and deactivaed on tab if exists", function() {
|
||||
|
||||
var // Let's create the views
|
||||
v1 = new cdb.core.View(),
|
||||
v2 = new cdb.core.View();
|
||||
|
||||
v1.activated = function() {};
|
||||
v2.deactivated = function() {};
|
||||
|
||||
spyOn(spy, 'tabDisabled');
|
||||
spyOn(spy, 'tabEnabled');
|
||||
|
||||
pane.addTab('tab1', v1);
|
||||
pane.addTab('tab2', v2);
|
||||
var a = spyOn(v1, 'activated');
|
||||
var d = spyOn(v2, 'deactivated');
|
||||
pane.active('tab1');
|
||||
expect(a).toHaveBeenCalled();
|
||||
expect(d).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("each should call function for each tab", function() {
|
||||
var // Let's create the views
|
||||
v1 = new cdb.core.View(),
|
||||
v2 = new cdb.core.View();
|
||||
pane.addTab('tab1', v1);
|
||||
pane.addTab('tab2', v2);
|
||||
var t = [];
|
||||
pane.each(function(name, tab) {
|
||||
t.push([name, tab]);
|
||||
});
|
||||
|
||||
expect(t.length).toEqual(2);
|
||||
expect(t[0][0]).toEqual('tab1')
|
||||
expect(t[1][0]).toEqual('tab2')
|
||||
expect(t[0][1].cid).toEqual(v1.cid);
|
||||
expect(t[1][1].cid).toEqual(v2.cid);
|
||||
|
||||
});
|
||||
|
||||
|
||||
it("user after option inserting view after specified index", function() {
|
||||
var v1, v2, v3;
|
||||
v1 = new cdb.core.View(),
|
||||
v2 = new cdb.core.View();
|
||||
v3 = new cdb.core.View();
|
||||
pane.addTab('tab1', v1);
|
||||
pane.addTab('tab2', v2);
|
||||
pane.addTab('tab3', v3, { after: 0 });
|
||||
expect(pane.$el.children()[0]).toEqual(v1.el);
|
||||
expect(pane.$el.children()[1]).toEqual(v3.el);
|
||||
expect(pane.$el.children()[2]).toEqual(v2.el);
|
||||
});
|
||||
|
||||
it("clean should remove all tabs", function() {
|
||||
spyOn(pane, "removeTabs");
|
||||
pane.clean();
|
||||
expect(pane.removeTabs).toHaveBeenCalled();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
describe('vis.layers', function() {
|
||||
var vis;
|
||||
beforeEach(function() {
|
||||
vis = new cdb.vis.Vis({});
|
||||
});
|
||||
|
||||
describe('https/http', function() {
|
||||
|
||||
it("torque layer should not rewrite to http if vis is not forced to https", function() {
|
||||
var layer = cdb.vis.Layers.create('torque', vis, {
|
||||
type: 'torque',
|
||||
sql_api_port: 123,
|
||||
sql_api_domain: 'carto.com',
|
||||
sql_api_protocol: 'https'
|
||||
});
|
||||
expect(layer.get('sql_api_protocol')).toEqual('https');
|
||||
expect(layer.get('sql_api_port')).toEqual(123);
|
||||
});
|
||||
|
||||
it("torque layer should rewrite to https if the domain is not carto.com and is forced", function() {
|
||||
vis.https = true;
|
||||
var layer = cdb.vis.Layers.create('torque', vis, {
|
||||
type: 'torque',
|
||||
sql_api_port: 123,
|
||||
sql_api_domain: 'carto.com',
|
||||
sql_api_protocol: 'http'
|
||||
});
|
||||
expect(layer.get('sql_api_protocol')).toEqual('https');
|
||||
expect(layer.get('sql_api_port')).toEqual(443);
|
||||
});
|
||||
|
||||
it("basemaps with a true explicit https property should be forced to https", function() {
|
||||
vis.https = true;
|
||||
var layer = cdb.vis.Layers.create('tiled', vis, {
|
||||
type: 'Tiled',
|
||||
urlTemplate: "http://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png"
|
||||
});
|
||||
expect(layer.get('urlTemplate').indexOf('https')).not.toBe(-1);
|
||||
})
|
||||
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,658 @@
|
||||
|
||||
describe("Overlay", function() {
|
||||
|
||||
it("should register and create a type", function() {
|
||||
var _data;
|
||||
cdb.vis.Overlay.register('test', function(data) {
|
||||
_data = data;
|
||||
return new cdb.core.View();
|
||||
});
|
||||
|
||||
var opt = {a : 1, b:2, pos: [10, 20]};
|
||||
var v = cdb.vis.Overlay.create('test', null, opt);
|
||||
expect(_data).toEqual(opt);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("Vis", function() {
|
||||
|
||||
beforeEach(function(){
|
||||
|
||||
this.container = $('<div>').css('height', '200px');
|
||||
this.mapConfig = {
|
||||
updated_at: 'cachebuster',
|
||||
title: "irrelevant",
|
||||
url: "https://carto.com",
|
||||
center: [40.044, -101.95],
|
||||
bounding_box_sw: [20, -140],
|
||||
bounding_box_ne: [ 55, -50],
|
||||
zoom: 4,
|
||||
bounds: [
|
||||
[1, 2],
|
||||
[3, 4],
|
||||
]
|
||||
};
|
||||
|
||||
this.vis = new cdb.vis.Vis({el: this.container});
|
||||
this.vis.load(this.mapConfig);
|
||||
})
|
||||
|
||||
it("should insert default max and minZoom values when not provided", function() {
|
||||
expect(this.vis.mapView.map_leaflet.options.maxZoom).toEqual(20);
|
||||
expect(this.vis.mapView.map_leaflet.options.minZoom).toEqual(0);
|
||||
});
|
||||
|
||||
|
||||
it("should insert user max and minZoom values when provided", function() {
|
||||
this.container = $('<div>').css('height', '200px');
|
||||
this.mapConfig.maxZoom = 10;
|
||||
this.mapConfig.minZoom = 5;
|
||||
this.vis.load(this.mapConfig);
|
||||
|
||||
expect(this.vis.mapView.map_leaflet.options.maxZoom).toEqual(10);
|
||||
expect(this.vis.mapView.map_leaflet.options.minZoom).toEqual(5);
|
||||
})
|
||||
|
||||
|
||||
it("should insert the max boundaries when provided", function() {
|
||||
this.container = $('<div>').css('height', '200px');
|
||||
this.mapConfig.bounding_box_sw = [1,2];
|
||||
this.mapConfig.bounding_box_ne = [3,5];
|
||||
this.vis.load(this.mapConfig);
|
||||
|
||||
expect(this.vis.map.get('bounding_box_sw')).toEqual([1,2]);
|
||||
expect(this.vis.map.get('bounding_box_ne')).toEqual([3,5]);
|
||||
})
|
||||
|
||||
it("should parse center if values are correct", function() {
|
||||
this.container = $('<div>').css('height', '200px');
|
||||
var opts = {
|
||||
center_lat: 43.3,
|
||||
center_lon: "89"
|
||||
}
|
||||
this.vis.load(this.mapConfig, opts);
|
||||
|
||||
expect(this.mapConfig.center[0]).toEqual(43.3);
|
||||
expect(this.mapConfig.center[1]).toEqual(89.0);
|
||||
})
|
||||
|
||||
it("should not parse center if values are not correct", function() {
|
||||
this.container = $('<div>').css('height', '200px');
|
||||
var opts = {
|
||||
center_lat: 43.3,
|
||||
center_lon: "ham"
|
||||
}
|
||||
this.vis.load(this.mapConfig, opts);
|
||||
|
||||
expect(this.mapConfig.center[0]).not.toEqual(43.3);
|
||||
expect(this.mapConfig.center[1]).not.toEqual("ham");
|
||||
})
|
||||
|
||||
it("should parse bounds values if they are correct", function() {
|
||||
this.container = $('<div>').css('height', '200px');
|
||||
var opts = {
|
||||
sw_lat: 43.3,
|
||||
sw_lon: 12,
|
||||
ne_lat: 12,
|
||||
ne_lon: "0"
|
||||
}
|
||||
this.vis.load(this.mapConfig, opts);
|
||||
|
||||
expect(this.mapConfig.bounds[0][0]).toEqual(43.3);
|
||||
expect(this.mapConfig.bounds[0][1]).toEqual(12);
|
||||
expect(this.mapConfig.bounds[1][0]).toEqual(12);
|
||||
expect(this.mapConfig.bounds[1][1]).toEqual(0);
|
||||
})
|
||||
|
||||
it("should not parse bounds values if they are not correct", function() {
|
||||
this.container = $('<div>').css('height', '200px');
|
||||
var opts = {
|
||||
sw_lat: 43.3,
|
||||
sw_lon: 12,
|
||||
ne_lat: "jamon",
|
||||
ne_lon: "0"
|
||||
}
|
||||
this.vis.load(this.mapConfig, opts);
|
||||
|
||||
expect(this.mapConfig.bounds[0][0]).not.toEqual(43.3);
|
||||
expect(this.mapConfig.bounds[0][1]).not.toEqual(12);
|
||||
expect(this.mapConfig.bounds[1][0]).not.toEqual(12);
|
||||
expect(this.mapConfig.bounds[1][1]).not.toEqual(0);
|
||||
})
|
||||
|
||||
it("should create a google maps map when provider is google maps", function() {
|
||||
this.container = $('<div>').css('height', '200px');
|
||||
this.mapConfig.map_provider = "googlemaps";
|
||||
this.vis.load(this.mapConfig);
|
||||
expect(this.vis.mapView.map_googlemaps).not.toEqual(undefined);
|
||||
});
|
||||
|
||||
it("should not invalidate map if map height is 0", function(done) {
|
||||
var container = $('<div>').css('height', '0');
|
||||
var vis = new cdb.vis.Vis({el: container});
|
||||
this.mapConfig.map_provider = "googlemaps";
|
||||
|
||||
vis.load(this.mapConfig);
|
||||
|
||||
setTimeout(function () {
|
||||
spyOn(vis.mapView, 'invalidateSize');
|
||||
expect(vis.mapView.invalidateSize).not.toHaveBeenCalled();
|
||||
done();
|
||||
}, 4000);
|
||||
});
|
||||
|
||||
it("should bind resize changes when map height is 0", function() {
|
||||
var container = $('<div>').css('height', '0');
|
||||
var vis = new cdb.vis.Vis({el: container});
|
||||
spyOn(vis, '_onResize');
|
||||
|
||||
this.mapConfig.map_provider = "googlemaps";
|
||||
vis.load(this.mapConfig);
|
||||
$(window).trigger('resize');
|
||||
expect(vis._onResize).toHaveBeenCalled();
|
||||
expect(vis.mapConfig).toBeDefined();
|
||||
});
|
||||
|
||||
it("shouldn't bind resize changes when map height is greater than 0", function() {
|
||||
var container = $('<div>').css('height', '200px');
|
||||
var vis = new cdb.vis.Vis({el: container});
|
||||
spyOn(vis, '_onResize');
|
||||
|
||||
this.mapConfig.map_provider = "googlemaps";
|
||||
vis.load(this.mapConfig);
|
||||
$(window).trigger('resize');
|
||||
expect(vis._onResize).not.toHaveBeenCalled();
|
||||
expect(vis.center).not.toBeDefined();
|
||||
});
|
||||
|
||||
|
||||
it("should pass map to overlays", function() {
|
||||
var _map;
|
||||
cdb.vis.Overlay.register('jaja', function(data, vis){
|
||||
_map = vis.map
|
||||
return new cdb.core.View()
|
||||
})
|
||||
var vis = new cdb.vis.Vis({el: this.container});
|
||||
this.mapConfig.overlays = [ {type: 'jaja'}];
|
||||
vis.load(this.mapConfig);
|
||||
expect(_map).not.toEqual(undefined);
|
||||
});
|
||||
|
||||
it("when https is false all the urls should be transformed to http", function() {
|
||||
this.vis.https = false;
|
||||
this.mapConfig.layers = [{
|
||||
kind: 'tiled',
|
||||
options: {
|
||||
urlTemplate: 'https://dnv9my2eseobd.cloudfront.net/v3/{z}/{x}/{y}.png'
|
||||
}
|
||||
}]
|
||||
this.vis.load(this.mapConfig);
|
||||
expect(this.vis.map.layers.at(0).get('urlTemplate')).toEqual(
|
||||
'http://a.tiles.mapbox.com/v3/{z}/{x}/{y}.png'
|
||||
)
|
||||
});
|
||||
|
||||
it("should return the native map obj", function() {
|
||||
expect(this.vis.getNativeMap()).toEqual(this.vis.mapView.map_leaflet);
|
||||
})
|
||||
|
||||
it("load should call done", function(done) {
|
||||
this.mapConfig.layers = [{
|
||||
kind: 'tiled',
|
||||
options: {
|
||||
urlTemplate: 'https://dnv9my2eseobd.cloudfront.net/v3/{z}/{x}/{y}.png'
|
||||
}
|
||||
}]
|
||||
layers = null;
|
||||
|
||||
this.vis.load(this.mapConfig, { }).done(function(vis, lys){ layers = lys;});
|
||||
|
||||
setTimeout(function() {
|
||||
expect(layers.length).toEqual(1);
|
||||
done();
|
||||
}, 100);
|
||||
|
||||
});
|
||||
|
||||
it("should add header", function() {
|
||||
|
||||
this.mapConfig.title = "title";
|
||||
|
||||
this.vis.load(this.mapConfig, {
|
||||
title: true
|
||||
});
|
||||
expect(this.vis.$('.cartodb-header').length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should add layer selector", function() {
|
||||
this.vis.load(this.mapConfig, {
|
||||
title: true,
|
||||
layer_selector: true
|
||||
});
|
||||
expect(this.vis.$('.cartodb-layer-selector-box').length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should add share", function() {
|
||||
this.vis.load(this.mapConfig, {
|
||||
shareable: true
|
||||
});
|
||||
expect(this.vis.$('.cartodb-share').length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should add header without link in the title", function() {
|
||||
var mapConfig = _.clone(this.mapConfig);
|
||||
mapConfig.title = "title"
|
||||
mapConfig.url = null;
|
||||
|
||||
this.vis.load(mapConfig, {
|
||||
title: true
|
||||
});
|
||||
|
||||
expect(this.vis.$('.cartodb-header').length).toEqual(1);
|
||||
expect(this.vis.$('.cartodb-header h1 > a').length).toEqual(0);
|
||||
});
|
||||
|
||||
it("should add zoom", function() {
|
||||
this.mapConfig.overlays = [{ type: 'zoom', order: 7, options: { x: 20, y: 20 }, template: 'test' }];
|
||||
this.vis.load(this.mapConfig);
|
||||
expect(this.vis.$('.cartodb-zoom').length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should enable zoom if it's specified by zoomControl option", function() {
|
||||
this.mapConfig.overlays = [{ type: 'zoom', order: 7, options: { x: 20, y: 20 }, template: 'test' }];
|
||||
this.vis.load(this.mapConfig, {
|
||||
zoomControl: true
|
||||
});
|
||||
expect(this.vis.$('.cartodb-zoom').length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should disable zoom if it's specified by zoomControl option", function() {
|
||||
this.mapConfig.overlays = [{ type: 'zoom', order: 7, options: { x: 20, y: 20 }, template: 'test' }];
|
||||
this.vis.load(this.mapConfig, {
|
||||
zoomControl: false
|
||||
});
|
||||
expect(this.vis.$('.cartodb-zoom').length).toEqual(0);
|
||||
});
|
||||
|
||||
it("should add search", function() {
|
||||
this.mapConfig.overlays = [{ type: 'search' }];
|
||||
this.vis.load(this.mapConfig);
|
||||
expect(this.vis.$('.cartodb-searchbox').length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should enable search if it's specified by searchControl", function() {
|
||||
this.mapConfig.overlays = [{ type: 'search' }];
|
||||
this.vis.load(this.mapConfig, {
|
||||
searchControl: true
|
||||
});
|
||||
expect(this.vis.$('.cartodb-searchbox').length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should disable search if it's specified by searchControl", function() {
|
||||
this.mapConfig.overlays = [{ type: 'search' }];
|
||||
this.vis.load(this.mapConfig, {
|
||||
searchControl: false
|
||||
});
|
||||
expect(this.vis.$('.cartodb-searchbox').length).toEqual(0);
|
||||
});
|
||||
|
||||
it("should use zoom", function() {
|
||||
this.vis.load(this.mapConfig, {
|
||||
zoom: 10,
|
||||
bounds: [[24.206889622398023,-84.0234375],[76.9206135182968,169.1015625]]
|
||||
});
|
||||
expect(this.vis.map.getZoom()).toEqual(10);
|
||||
});
|
||||
|
||||
|
||||
it("should retrieve the overlays of a given type", function() {
|
||||
var v = this.vis.addOverlay({
|
||||
type: 'tooltip',
|
||||
template: 'test',
|
||||
layer: new L.CartoDBGroupLayer({
|
||||
layer_definition: {version: '1.0.0', layers: [] }
|
||||
})
|
||||
});
|
||||
var v1 = this.vis.addOverlay({
|
||||
type: 'tooltip',
|
||||
template: 'test',
|
||||
layer: new L.CartoDBGroupLayer({
|
||||
layer_definition: {version: '1.0.0', layers: [] }
|
||||
})
|
||||
});
|
||||
var v2 = this.vis.addOverlay({
|
||||
type: 'tooltip',
|
||||
template: 'test',
|
||||
layer: new L.CartoDBGroupLayer({
|
||||
layer_definition: {version: '1.0.0', layers: [] }
|
||||
})
|
||||
});
|
||||
|
||||
var tooltips = this.vis.getOverlaysByType('tooltip');
|
||||
expect(tooltips.length).toEqual(3);
|
||||
expect(tooltips[0]).toEqual(v);
|
||||
expect(tooltips[1]).toEqual(v1);
|
||||
expect(tooltips[2]).toEqual(v2);
|
||||
v.clean();
|
||||
v1.clean();
|
||||
v2.clean();
|
||||
expect(this.vis.getOverlaysByType("tooltip").length).toEqual(0);
|
||||
});
|
||||
|
||||
describe('addOverlay', function() {
|
||||
|
||||
it("should throw an error if no layers are available", function() {
|
||||
expect(function() {
|
||||
this.vis.addOverlay({
|
||||
type: 'tooltip',
|
||||
template: 'test'
|
||||
})
|
||||
}.bind(this)).toThrow(new Error("layer is null"));
|
||||
});
|
||||
|
||||
it("should add an overlay to the specified layer and enable interaction", function() {
|
||||
var layer = new L.CartoDBGroupLayer({
|
||||
layer_definition: {version: '1.0.0', layers: [] }
|
||||
});
|
||||
|
||||
var tooltip = this.vis.addOverlay({
|
||||
type: 'tooltip',
|
||||
template: 'test',
|
||||
layer: layer
|
||||
});
|
||||
|
||||
expect(tooltip.options.layer).toEqual(layer);
|
||||
expect(layer.interactionEnabled).toEqual([true]);
|
||||
});
|
||||
|
||||
it("should add an overlay to the first layer and enable interaction", function(done) {
|
||||
var layer;
|
||||
var vizjson = {
|
||||
layers: [
|
||||
{
|
||||
type: 'tiled',
|
||||
options: {
|
||||
urlTemplate: ''
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'layergroup',
|
||||
options: {
|
||||
layer_definition: {
|
||||
layers: []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
cartodb.createVis('map', vizjson, {})
|
||||
.done(function(vis, layers) {
|
||||
var tooltip = vis.addOverlay({
|
||||
type: 'tooltip',
|
||||
template: 'test'
|
||||
});
|
||||
var layer = vis.getLayers()[1];
|
||||
|
||||
expect(tooltip.options.layer).toEqual(layer);
|
||||
expect(layer.interactionEnabled).toEqual([true]);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it ("should load modules", function(done) {
|
||||
this.mapConfig.layers = [
|
||||
{kind: 'torque', options: { tile_style: 'test', user_name: 'test', table_name: 'test'}}
|
||||
];
|
||||
|
||||
this.vis.load(this.mapConfig);
|
||||
|
||||
setTimeout(function() {
|
||||
var scripts = document.getElementsByTagName('script'),
|
||||
torqueRe = /\/cartodb\.mod\.torque\.js/;
|
||||
var found = false;
|
||||
for (i = 0, len = scripts.length; i < len && !found; i++) {
|
||||
src = scripts[i].src;
|
||||
found = !!src.match(torqueRe);
|
||||
}
|
||||
expect(found).toEqual(true);
|
||||
done()
|
||||
}, 20);
|
||||
});
|
||||
|
||||
it ("should force GMaps", function() {
|
||||
this.mapConfig.map_provider = "leaflet";
|
||||
this.mapConfig.layers = [{
|
||||
kind: 'tiled',
|
||||
options: {
|
||||
urlTemplate: 'https://dnv9my2eseobd.cloudfront.net/v3/{z}/{x}/{y}.png'
|
||||
}
|
||||
}]
|
||||
|
||||
var opts = {
|
||||
gmaps_base_type: 'dark_roadmap'
|
||||
};
|
||||
|
||||
layers = null;
|
||||
|
||||
this.vis.load(this.mapConfig, opts);
|
||||
expect(this.vis.map.layers.at(0).get('type')).toEqual('GMapsBase');
|
||||
});
|
||||
|
||||
describe("dragging option", function() {
|
||||
|
||||
beforeEach(function() {
|
||||
var container = $('<div>').css('height', '200px');
|
||||
this.vis = new cdb.vis.Vis({el: container});
|
||||
});
|
||||
|
||||
it("should be enabled with zoom overlay, scrollwheel enabled and not under a mobile device", function() {
|
||||
spyOn(this.vis, 'isMobileDevice').and.returnValue(false);
|
||||
var mapConfig = createMapConfig({
|
||||
scrollwheel: true,
|
||||
zoom: true
|
||||
});
|
||||
this.vis.load(mapConfig);
|
||||
expect(this.vis.map.get('drag')).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should be enabled with zoom overlay, scrollwheel disabled and not under a mobile device", function() {
|
||||
spyOn(this.vis, 'isMobileDevice').and.returnValue(false);
|
||||
var mapConfig = createMapConfig({
|
||||
scrollwheel: false,
|
||||
zoom: true
|
||||
});
|
||||
this.vis.load(mapConfig);
|
||||
expect(this.vis.map.get('drag')).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should be enabled without zoom overlay, scrollwheel enabled and not under mobile device", function() {
|
||||
spyOn(this.vis, 'isMobileDevice').and.returnValue(false);
|
||||
var mapConfig = createMapConfig({
|
||||
scrollwheel: true,
|
||||
zoom: false
|
||||
});
|
||||
this.vis.load(mapConfig);
|
||||
expect(this.vis.map.get('drag')).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should be disabled without zoom overlay, scrollwheel disabled and not under mobile device", function() {
|
||||
spyOn(this.vis, 'isMobileDevice').and.returnValue(false);
|
||||
var mapConfig = createMapConfig({
|
||||
scrollwheel: false,
|
||||
zoom: false
|
||||
});
|
||||
this.vis.load(mapConfig);
|
||||
expect(this.vis.map.get('drag')).toBeFalsy();
|
||||
});
|
||||
|
||||
it("should be enabled without zoom, scrollwheel is enabled and under mobile device", function() {
|
||||
spyOn(this.vis, 'isMobileDevice').and.returnValue(true);
|
||||
var mapConfig = createMapConfig({
|
||||
scrollwheel: true,
|
||||
zoom: false
|
||||
});
|
||||
this.vis.load(mapConfig);
|
||||
expect(this.vis.map.get('drag')).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should be enabled without zoom, scrollwheel disabled and under mobile device", function() {
|
||||
spyOn(this.vis, 'isMobileDevice').and.returnValue(true);
|
||||
var mapConfig = createMapConfig({
|
||||
scrollwheel: false,
|
||||
zoom: false
|
||||
});
|
||||
this.vis.load(mapConfig);
|
||||
expect(this.vis.map.get('drag')).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should be enabled with zoom, scrollwheel disabled and under mobile device", function() {
|
||||
spyOn(this.vis, 'isMobileDevice').and.returnValue(true);
|
||||
var mapConfig = createMapConfig({
|
||||
scrollwheel: false,
|
||||
zoom: true
|
||||
});
|
||||
this.vis.load(mapConfig);
|
||||
expect(this.vis.map.get('drag')).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should be enabled if all parameters are enabled or present", function() {
|
||||
spyOn(this.vis, 'isMobileDevice').and.returnValue(true);
|
||||
var mapConfig = createMapConfig({
|
||||
scrollwheel: true,
|
||||
zoom: true
|
||||
});
|
||||
this.vis.load(mapConfig);
|
||||
expect(this.vis.map.get('drag')).toBeTruthy();
|
||||
});
|
||||
|
||||
function createMapConfig(obj) {
|
||||
var r = {
|
||||
updated_at: 'cachebuster',
|
||||
title: "irrelevant",
|
||||
url: "https://carto.com",
|
||||
center: [40.044, -101.95],
|
||||
bounding_box_sw: [20, -140],
|
||||
bounding_box_ne: [ 55, -50],
|
||||
zoom: 4,
|
||||
bounds: [[1, 2],[3, 4]],
|
||||
scrollwheel: false,
|
||||
overlays: []
|
||||
};
|
||||
if (obj.scrollwheel) {
|
||||
r.scrollwheel = true;
|
||||
}
|
||||
if (obj.zoom) {
|
||||
r.overlays = [
|
||||
{
|
||||
type: "zoom",
|
||||
order: 6,
|
||||
options: {
|
||||
x: 20,
|
||||
y: 20,
|
||||
display: true
|
||||
},
|
||||
template: ""
|
||||
}
|
||||
];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
describe("Legends", function() {
|
||||
|
||||
it('should only display legends for visible layers', function() {
|
||||
this.mapConfig.layers = [
|
||||
{
|
||||
kind: 'tiled',
|
||||
legend: {
|
||||
type: "custom",
|
||||
show_title: false,
|
||||
title: "",
|
||||
template: "",
|
||||
items: [
|
||||
{
|
||||
name: "visible legend item",
|
||||
visible: true,
|
||||
value: "#cccccc",
|
||||
sync: true
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
urlTemplate: 'https://dnv9my2eseobd.cloudfront.net/v3/{z}/{x}/{y}.png'
|
||||
}
|
||||
},
|
||||
{
|
||||
visible: false,
|
||||
kind: 'tiled',
|
||||
legend: {
|
||||
type: "custom",
|
||||
show_title: false,
|
||||
title: "",
|
||||
template: "",
|
||||
items: [
|
||||
{
|
||||
name: "invisible legend item",
|
||||
visible: true,
|
||||
value: "#cccccc",
|
||||
sync: true
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
urlTemplate: 'https://dnv9my2eseobd.cloudfront.net/v3/{z}/{x}/{y}.png'
|
||||
}
|
||||
}
|
||||
]
|
||||
this.vis.load(this.mapConfig);
|
||||
|
||||
expect(this.vis.legends.$('.cartodb-legend').length).toEqual(1);
|
||||
expect(this.vis.legends.$el.html()).toContain('visible legend item');
|
||||
expect(this.vis.legends.$el.html()).not.toContain('invisible legend item');
|
||||
})
|
||||
})
|
||||
|
||||
describe("Torque time slider", function() {
|
||||
|
||||
beforeEach(function() {
|
||||
// Load torque module
|
||||
cartodb.torque = torque;
|
||||
})
|
||||
|
||||
it ("should display the time slider if a torque layer is present", function(done) {
|
||||
this.mapConfig.layers = [
|
||||
{
|
||||
kind: 'torque',
|
||||
options: { user_name: 'test', table_name: 'test', tile_style: 'Map { -torque-frame-count: 10;} #test { marker-width: 10; }'}
|
||||
}
|
||||
];
|
||||
|
||||
this.vis.load(this.mapConfig).done(function(vis, layers){
|
||||
expect(vis.timeSlider).toBeDefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it ("should NOT display the time slider if a torque layer is not visible", function(done) {
|
||||
this.mapConfig.layers = [
|
||||
{
|
||||
kind: 'torque',
|
||||
visible: false,
|
||||
options: { user_name: 'test', table_name: 'test', tile_style: 'Map { -torque-frame-count: 10;} #test { marker-width: 10; }'}
|
||||
}
|
||||
];
|
||||
|
||||
this.vis.load(this.mapConfig).done(function(vis, layers){
|
||||
expect(vis.timeSlider).toBeUndefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
Reference in New Issue
Block a user