Files
cartodb/lib/assets/javascripts/cdb/test/spec/geo/leaflet/leaflet.spec.js
zhongjin a96ef233c9 cdb
2020-06-15 12:07:54 +08:00

517 lines
16 KiB
JavaScript

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();
});
});