734 lines
29 KiB
JavaScript
734 lines
29 KiB
JavaScript
|
var _ = require('underscore');
|
||
|
var CartoDBLayer = require('../../../src/geo/map/cartodb-layer');
|
||
|
var TorqueLayer = require('../../../src/geo/map/torque-layer');
|
||
|
var LayersCollection = require('../../../src/geo/map/layers');
|
||
|
var Backbone = require('backbone');
|
||
|
var ModelUpdater = require('../../../src/windshaft-integration/model-updater');
|
||
|
var WindshaftError = require('../../../src/windshaft/error');
|
||
|
var ResponseWrapper = require('../../../src/windshaft/response');
|
||
|
var CartoDBLayerGroup = require('../../../src/geo/cartodb-layer-group');
|
||
|
var Dataview = require('../../../src/dataviews/dataview-model-base');
|
||
|
var AnalysisModel = require('../../../src/analysis/analysis-model');
|
||
|
var MapModel = require('../../../src/geo/map');
|
||
|
var createEngine = require('../fixtures/engine.fixture.js');
|
||
|
var BoundingBoxFilter = require('../../../src/windshaft/filters/bounding-box');
|
||
|
var MapModelBoundingBoxAdapter = require('../../../src/geo/adapters/map-model-bounding-box-adapter');
|
||
|
|
||
|
describe('src//model-updater', function () {
|
||
|
var boundingBoxFilter;
|
||
|
var engineMock;
|
||
|
var serverResponse;
|
||
|
var windshaftSettings;
|
||
|
|
||
|
beforeEach(function () {
|
||
|
engineMock = createEngine();
|
||
|
|
||
|
windshaftSettings = {
|
||
|
urlTemplate: 'http://{user}.cartodb.com:80',
|
||
|
userName: 'cartojs-test'
|
||
|
};
|
||
|
|
||
|
serverResponse = new ResponseWrapper(windshaftSettings, {
|
||
|
'layergroupid': '9d7bf465e45113123bf9949c2a4f0395:0',
|
||
|
'metadata': {
|
||
|
'layers': [],
|
||
|
'dataviews': {},
|
||
|
'analyses': []
|
||
|
}
|
||
|
});
|
||
|
|
||
|
spyOn(serverResponse, 'getBaseURL').and.callFake(function (subdomain) {
|
||
|
return 'http://' + (subdomain ? subdomain + '.' : '') + 'documentation.carto.com';
|
||
|
});
|
||
|
spyOn(serverResponse, 'getLayerIndexesByType').and.returnValue([0]);
|
||
|
spyOn(serverResponse, 'getSupportedSubdomains').and.returnValue(['']);
|
||
|
|
||
|
this.layersCollection = new LayersCollection();
|
||
|
|
||
|
this.layerGroupModel = new CartoDBLayerGroup({}, {
|
||
|
layersCollection: this.layersCollection
|
||
|
});
|
||
|
this.dataviewsCollection = new Backbone.Collection();
|
||
|
|
||
|
var mapModel = new MapModel({
|
||
|
bounds: [[40.2813, -3.90592], [40.5611, -3.47532]]
|
||
|
}, {
|
||
|
layersFactory: {},
|
||
|
layersCollection: this.LayersCollection
|
||
|
});
|
||
|
boundingBoxFilter = new BoundingBoxFilter(new MapModelBoundingBoxAdapter(mapModel));
|
||
|
|
||
|
this.modelUpdater = new ModelUpdater({
|
||
|
layerGroupModel: this.layerGroupModel,
|
||
|
layersCollection: this.layersCollection,
|
||
|
dataviewsCollection: this.dataviewsCollection
|
||
|
});
|
||
|
|
||
|
// _getProtocol uses window.location.protocol internally, and that returns "file:"
|
||
|
// when running the test suite using the jasmine test runner, so we need to fake it
|
||
|
spyOn(this.modelUpdater, '_getProtocol').and.returnValue('http');
|
||
|
});
|
||
|
|
||
|
describe('.updateModels', function () {
|
||
|
beforeEach(function () {
|
||
|
serverResponse.getBaseURL.and.returnValue('http://{s}.documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0');
|
||
|
});
|
||
|
|
||
|
describe('layerGroupModel', function () {
|
||
|
beforeEach(function () {
|
||
|
var analysis = new AnalysisModel({ id: 'a1', type: 'source', query: 'SELECT * FROM table' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
var layer1 = new CartoDBLayer({ source: analysis }, { engine: engineMock });
|
||
|
var layer2 = new CartoDBLayer({ source: analysis }, { engine: engineMock });
|
||
|
|
||
|
this.layersCollection.reset([layer1, layer2]);
|
||
|
|
||
|
serverResponse.getLayerIndexesByType.and.callFake(function (layerType) {
|
||
|
if (layerType === 'mapnik') {
|
||
|
return ([1, 2]);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should set indexOfLayersInWindshaft', function () {
|
||
|
this.modelUpdater.updateModels(serverResponse);
|
||
|
expect(this.layerGroupModel.get('indexOfLayersInWindshaft')).toEqual([1, 2]);
|
||
|
});
|
||
|
|
||
|
var testCases = [{
|
||
|
name: 'with subdomains',
|
||
|
baseURL: 'http://{s}.documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0',
|
||
|
supportedSubdomains: ['0', '1', '2', '3'],
|
||
|
expectedTileURLTemplate: 'http://{s}.documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/1,2/{z}/{x}/{y}.png',
|
||
|
expectedGridURLTemplatesWithSubdomains: {
|
||
|
0: [
|
||
|
'http://0.documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/1/{z}/{x}/{y}.grid.json',
|
||
|
'http://1.documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/1/{z}/{x}/{y}.grid.json',
|
||
|
'http://2.documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/1/{z}/{x}/{y}.grid.json',
|
||
|
'http://3.documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/1/{z}/{x}/{y}.grid.json'
|
||
|
],
|
||
|
1: [
|
||
|
'http://0.documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/2/{z}/{x}/{y}.grid.json',
|
||
|
'http://1.documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/2/{z}/{x}/{y}.grid.json',
|
||
|
'http://2.documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/2/{z}/{x}/{y}.grid.json',
|
||
|
'http://3.documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/2/{z}/{x}/{y}.grid.json'
|
||
|
]
|
||
|
},
|
||
|
expectedAttributesBaseURL: {
|
||
|
0: /http:\/\/[0-3]\.documentation\.carto\.com\/api\/v1\/map\/90e64f1b9145961af7ba36d71b887dd2:0\/1\/attributes/,
|
||
|
1: /http:\/\/[0-3]\.documentation\.carto\.com\/api\/v1\/map\/90e64f1b9145961af7ba36d71b887dd2:0\/2\/attributes/
|
||
|
}
|
||
|
}, {
|
||
|
name: 'with no subdomains',
|
||
|
baseURL: 'http://documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0',
|
||
|
supportedSubdomains: [],
|
||
|
expectedTileURLTemplate: 'http://documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/1,2/{z}/{x}/{y}.png',
|
||
|
expectedGridURLTemplatesWithSubdomains: {
|
||
|
0: [
|
||
|
'http://documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/1/{z}/{x}/{y}.grid.json'
|
||
|
],
|
||
|
1: [
|
||
|
'http://documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/2/{z}/{x}/{y}.grid.json'
|
||
|
]
|
||
|
},
|
||
|
expectedAttributesBaseURL: {
|
||
|
0: /http:\/\/documentation\.carto\.com\/api\/v1\/map\/90e64f1b9145961af7ba36d71b887dd2:0\/1\/attributes/,
|
||
|
1: /http:\/\/documentation\.carto\.com\/api\/v1\/map\/90e64f1b9145961af7ba36d71b887dd2:0\/2\/attributes/
|
||
|
}
|
||
|
}];
|
||
|
|
||
|
_.each(testCases, function (testCase) {
|
||
|
describe(testCase.name, function () {
|
||
|
beforeEach(function () {
|
||
|
serverResponse.getBaseURL.and.returnValue(testCase.baseURL);
|
||
|
serverResponse.getSupportedSubdomains.and.returnValue(testCase.supportedSubdomains);
|
||
|
this.modelUpdater.updateModels(serverResponse);
|
||
|
});
|
||
|
|
||
|
describe('tile urls', function () {
|
||
|
it('should generate tile URLs', function () {
|
||
|
expect(this.layerGroupModel.getTileURLTemplate()).toEqual(testCase.expectedTileURLTemplate);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('grid urls', function () {
|
||
|
it('should generate grid URLs', function () {
|
||
|
expect(this.layerGroupModel.getGridURLTemplatesWithSubdomains(0)).toEqual(testCase.expectedGridURLTemplatesWithSubdomains[0]);
|
||
|
expect(this.layerGroupModel.getGridURLTemplatesWithSubdomains(1)).toEqual(testCase.expectedGridURLTemplatesWithSubdomains[1]);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('attribute urls', function () {
|
||
|
it('should generate attribute URLs', function () {
|
||
|
expect(this.layerGroupModel.getAttributesBaseURL(0)).toMatch(testCase.expectedAttributesBaseURL[0]);
|
||
|
expect(this.layerGroupModel.getAttributesBaseURL(1)).toMatch(testCase.expectedAttributesBaseURL[1]);
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('layer models', function () {
|
||
|
it('should mark CartoDB and torque layer models as ok', function () {
|
||
|
var analysis = new AnalysisModel({ id: 'a1', type: 'source', query: 'SELECT * FROM table' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
|
||
|
var layer0 = new Backbone.Model({ type: 'Tiled' });
|
||
|
var layer1 = new CartoDBLayer({ source: analysis }, { engine: engineMock });
|
||
|
var layer2 = new TorqueLayer({ source: analysis }, { engine: engineMock });
|
||
|
|
||
|
spyOn(layer1, 'setOk');
|
||
|
spyOn(layer2, 'setOk');
|
||
|
|
||
|
this.layersCollection.reset([layer0, layer1, layer2]);
|
||
|
this.modelUpdater.updateModels(serverResponse);
|
||
|
|
||
|
expect(layer1.setOk).toHaveBeenCalled();
|
||
|
expect(layer2.setOk).toHaveBeenCalled();
|
||
|
});
|
||
|
|
||
|
it('should set tileURLTemplates attribute of torque layer models', function () {
|
||
|
var analysis = new AnalysisModel({ id: 'a1', type: 'source', query: 'SELECT * FROM table' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
|
||
|
var layer0 = new Backbone.Model({ type: 'Tiled' });
|
||
|
var layer1 = new CartoDBLayer({ source: analysis }, { engine: engineMock });
|
||
|
var layer2 = new TorqueLayer({ source: analysis }, { engine: engineMock });
|
||
|
this.layersCollection.reset([layer0, layer1, layer2]);
|
||
|
|
||
|
this.modelUpdater.updateModels(serverResponse);
|
||
|
|
||
|
expect(layer2.get('tileURLTemplates')).toEqual([
|
||
|
'http://{s}.documentation.carto.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/0/{z}/{x}/{y}.json.torque'
|
||
|
]);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('legend models', function () {
|
||
|
it('should "mark" all legend models as success', function () {
|
||
|
var analysis = new AnalysisModel({ id: 'a1', type: 'source', query: 'SELECT * FROM table' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
var layer = new CartoDBLayer({ source: analysis }, { engine: engineMock });
|
||
|
|
||
|
this.layersCollection.reset([layer]);
|
||
|
this.modelUpdater.updateModels(serverResponse, 'sourceId', 'forceFetch');
|
||
|
|
||
|
expect(layer.legends.choropleth.isSuccess()).toBeTruthy();
|
||
|
expect(layer.legends.bubble.isSuccess()).toBeTruthy();
|
||
|
expect(layer.legends.category.isSuccess()).toBeTruthy();
|
||
|
});
|
||
|
|
||
|
it('should update model for choropleth legends', function () {
|
||
|
var analysis = new AnalysisModel({ id: 'a1', type: 'source', query: 'SELECT * FROM table' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
|
||
|
serverResponse = new ResponseWrapper(windshaftSettings, {
|
||
|
'layergroupid': '9d7bf465e45113123bf9949c2a4f0395:0',
|
||
|
'metadata': {
|
||
|
layers: [
|
||
|
{
|
||
|
type: 'mapnik',
|
||
|
id: '923b7812-2d56-41c6-ac15-3ce430db090f',
|
||
|
meta: {
|
||
|
stats: [],
|
||
|
cartocss: 'cartocss',
|
||
|
'cartocss_meta': {
|
||
|
rules: [
|
||
|
{
|
||
|
'selector': '#layer',
|
||
|
'prop': 'polygon-fill',
|
||
|
'mapping': '>',
|
||
|
'buckets': [
|
||
|
{
|
||
|
'filter': {
|
||
|
'type': 'range',
|
||
|
'start': 0,
|
||
|
'end': 1000
|
||
|
},
|
||
|
'value': '#AAAAAA'
|
||
|
},
|
||
|
{
|
||
|
'filter': {
|
||
|
'type': 'range',
|
||
|
'start': 1000,
|
||
|
'end': 2000
|
||
|
},
|
||
|
'value': '#BBBBBB'
|
||
|
},
|
||
|
{
|
||
|
'filter': {
|
||
|
'type': 'range',
|
||
|
'start': 2000,
|
||
|
'end': 3000
|
||
|
},
|
||
|
'value': '#CCCCCC'
|
||
|
}
|
||
|
],
|
||
|
'stats': {
|
||
|
'filter_avg': 1975
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
});
|
||
|
|
||
|
var layer = new CartoDBLayer({ source: analysis }, { engine: engineMock });
|
||
|
|
||
|
this.layersCollection.reset([layer]);
|
||
|
|
||
|
this.modelUpdater.updateModels(serverResponse, 'sourceId', 'forceFetch');
|
||
|
|
||
|
expect(layer.legends.choropleth.get('colors')).toEqual([
|
||
|
{ label: '0', value: '#AAAAAA' },
|
||
|
{ label: '', value: '#BBBBBB' },
|
||
|
{ label: '3000', value: '#CCCCCC' }
|
||
|
]);
|
||
|
expect(layer.legends.choropleth.isSuccess()).toBeTruthy();
|
||
|
});
|
||
|
|
||
|
it('should update model for category legends', function () {
|
||
|
var analysis = new AnalysisModel({ id: 'a1', type: 'source', query: 'SELECT * FROM table' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
|
||
|
serverResponse = new ResponseWrapper(windshaftSettings, {
|
||
|
'layergroupid': '9d7bf465e45113123bf9949c2a4f0395:0',
|
||
|
'metadata': {
|
||
|
layers: [
|
||
|
{
|
||
|
'type': 'mapnik',
|
||
|
'id': '923b7812-2d56-41c6-ac15-b090f3ce430d',
|
||
|
'meta': {
|
||
|
'stats': [],
|
||
|
'cartocss': 'cartocss',
|
||
|
'cartocss_meta': {
|
||
|
'rules': [
|
||
|
{
|
||
|
'selector': '#layer',
|
||
|
'prop': 'marker-fill',
|
||
|
'mapping': '=',
|
||
|
'buckets': [
|
||
|
{
|
||
|
'filter': {
|
||
|
'type': 'category',
|
||
|
'name': 'Category 1'
|
||
|
},
|
||
|
'value': '#AAAAAA'
|
||
|
},
|
||
|
{
|
||
|
'filter': {
|
||
|
'type': 'category',
|
||
|
'name': 'Category 2'
|
||
|
},
|
||
|
'value': '#BBBBBB'
|
||
|
},
|
||
|
{
|
||
|
'filter': {
|
||
|
'type': 'default'
|
||
|
},
|
||
|
'value': '#CCCCCC'
|
||
|
}
|
||
|
],
|
||
|
'stats': {
|
||
|
'filter_avg': 3500
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
});
|
||
|
|
||
|
var layer = new CartoDBLayer({ source: analysis }, { engine: engineMock });
|
||
|
|
||
|
this.layersCollection.reset([layer]);
|
||
|
|
||
|
this.modelUpdater.updateModels(serverResponse, 'sourceId', 'forceFetch');
|
||
|
|
||
|
expect(layer.legends.category.get('categories')).toEqual([
|
||
|
{ title: 'Category 1', icon: '', color: '#AAAAAA' },
|
||
|
{ title: 'Category 2', icon: '', color: '#BBBBBB' }
|
||
|
]);
|
||
|
expect(layer.legends.choropleth.isSuccess()).toBeTruthy();
|
||
|
});
|
||
|
|
||
|
it('should update model for bubble legends', function () {
|
||
|
var analysis = new AnalysisModel({ id: 'a1', type: 'source', query: 'SELECT * FROM table' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
|
||
|
serverResponse = new ResponseWrapper(windshaftSettings, {
|
||
|
'layergroupid': '9d7bf465e45113123bf9949c2a4f0395:0',
|
||
|
'metadata': {
|
||
|
layers: [
|
||
|
{
|
||
|
'type': 'mapnik',
|
||
|
'id': '923b7812-2d56-41c6-ac15-b090f3ce430d',
|
||
|
'meta': {
|
||
|
'stats': [],
|
||
|
'cartocss': 'cartocss',
|
||
|
'cartocss_meta': {
|
||
|
'rules': [
|
||
|
{
|
||
|
'selector': '#layer',
|
||
|
'prop': 'marker-width',
|
||
|
'mapping': '>',
|
||
|
'buckets': [
|
||
|
{
|
||
|
'filter': {
|
||
|
'type': 'range',
|
||
|
'start': 10,
|
||
|
'end': 1000
|
||
|
},
|
||
|
'value': 10
|
||
|
},
|
||
|
{
|
||
|
'filter': {
|
||
|
'type': 'range',
|
||
|
'start': 1000,
|
||
|
'end': 2000
|
||
|
},
|
||
|
'value': 14
|
||
|
},
|
||
|
{
|
||
|
'filter': {
|
||
|
'type': 'range',
|
||
|
'start': 2000,
|
||
|
'end': 3000
|
||
|
},
|
||
|
'value': 20
|
||
|
},
|
||
|
{
|
||
|
'filter': {
|
||
|
'type': 'range',
|
||
|
'start': 3000,
|
||
|
'end': 4000
|
||
|
},
|
||
|
'value': 26
|
||
|
},
|
||
|
{
|
||
|
'filter': {
|
||
|
'type': 'range',
|
||
|
'start': 4000,
|
||
|
'end': 5000
|
||
|
},
|
||
|
'value': 32
|
||
|
}
|
||
|
],
|
||
|
'stats': {
|
||
|
'filter_avg': 3500
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
});
|
||
|
|
||
|
var layer = new CartoDBLayer({ source: analysis }, { engine: engineMock });
|
||
|
|
||
|
this.layersCollection.reset([layer]);
|
||
|
|
||
|
this.modelUpdater.updateModels(serverResponse, 'sourceId', 'forceFetch');
|
||
|
|
||
|
expect(layer.legends.bubble.get('values')).toEqual([
|
||
|
10, 1000, 2000, 3000, 4000, 5000
|
||
|
]);
|
||
|
expect(layer.legends.bubble.get('sizes')).toEqual([
|
||
|
10, 14, 20, 26, 32
|
||
|
]);
|
||
|
expect(layer.legends.bubble.get('avg')).toEqual(3500);
|
||
|
expect(layer.legends.bubble.isSuccess()).toBeTruthy();
|
||
|
});
|
||
|
|
||
|
it('should set legend state to "error" if adapter fails to generate attrs from rule', function () {
|
||
|
var analysis = new AnalysisModel({ id: 'a1', type: 'source', query: 'SELECT * FROM table' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
|
||
|
serverResponse = new ResponseWrapper(windshaftSettings, {
|
||
|
'layergroupid': '9d7bf465e45113123bf9949c2a4f0395:0',
|
||
|
'metadata': {
|
||
|
layers: [
|
||
|
{
|
||
|
'type': 'mapnik',
|
||
|
'id': '923b7812-2d56-41c6-ac15-b090f3ce430d',
|
||
|
'meta': {
|
||
|
'stats': [],
|
||
|
'cartocss': 'cartocss',
|
||
|
'cartocss_meta': {
|
||
|
'rules': [
|
||
|
{
|
||
|
'prop': 'marker-width',
|
||
|
'mapping': '>'
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
});
|
||
|
|
||
|
var layer = new CartoDBLayer({ source: analysis }, { engine: engineMock });
|
||
|
|
||
|
this.layersCollection.reset([layer]);
|
||
|
|
||
|
this.modelUpdater.updateModels(serverResponse, 'sourceId', 'forceFetch');
|
||
|
|
||
|
expect(layer.legends.bubble.isError()).toBeTruthy();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('dataview models', function () {
|
||
|
it('should update dataview models', function () {
|
||
|
var dataview1 = new Dataview({
|
||
|
id: 'a1',
|
||
|
source: new AnalysisModel({}, { engine: engineMock, camshaftReference: camshaftReferenceMock })
|
||
|
}, {
|
||
|
bboxFilter: boundingBoxFilter,
|
||
|
engine: engineMock
|
||
|
});
|
||
|
var dataview2 = new Dataview({
|
||
|
id: 'a2',
|
||
|
source: new AnalysisModel({}, { engine: engineMock, camshaftReference: camshaftReferenceMock })
|
||
|
}, {
|
||
|
bboxFilter: boundingBoxFilter,
|
||
|
engine: engineMock
|
||
|
});
|
||
|
this.dataviewsCollection.reset([dataview1, dataview2]);
|
||
|
|
||
|
serverResponse.getDataviewMetadata = function (dataviewId) {
|
||
|
if (dataviewId === 'a1') {
|
||
|
return {
|
||
|
url: {
|
||
|
http: 'http://example1.com',
|
||
|
https: 'https://example1.com'
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
if (dataviewId === 'a2') {
|
||
|
return {
|
||
|
url: {
|
||
|
http: 'http://example2.com',
|
||
|
https: 'https://example2.com'
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
};
|
||
|
|
||
|
spyOn(dataview1, 'set').and.callThrough();
|
||
|
|
||
|
this.modelUpdater.updateModels(serverResponse, 'sourceId', 'forceFetch');
|
||
|
|
||
|
expect(dataview1.set).toHaveBeenCalledWith({
|
||
|
url: 'http://example1.com'
|
||
|
}, {
|
||
|
sourceId: 'sourceId',
|
||
|
forceFetch: 'forceFetch'
|
||
|
});
|
||
|
|
||
|
expect(dataview1.get('url')).toEqual('http://example1.com');
|
||
|
expect(dataview2.get('url')).toEqual('http://example2.com');
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('analysis models', function () {
|
||
|
it('should update analysis models and set analysis state to "ok"', function () {
|
||
|
var analysis1 = new AnalysisModel({ id: 'a1', type: 'source', query: 'SELECT * FROM table' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
var analysis2 = new AnalysisModel({ id: 'a2', type: 'source', query: 'SELECT * FROM table' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
var layer = new CartoDBLayer({ source: analysis1 }, { engine: engineMock });
|
||
|
var dataview = new Dataview({ id: 'a1', source: analysis2 }, { bboxFilter: boundingBoxFilter, engine: engineMock });
|
||
|
|
||
|
spyOn(analysis1, 'setOk');
|
||
|
spyOn(analysis2, 'setOk');
|
||
|
spyOn(serverResponse, 'getAnalysisNodeMetadata').and.callFake(function (analysisId) {
|
||
|
return { status: 'status_' + analysisId, query: 'query_' + analysisId, url: { http: 'url_' + analysisId } };
|
||
|
});
|
||
|
|
||
|
this.layersCollection.reset([layer]);
|
||
|
this.dataviewsCollection.reset([dataview]);
|
||
|
this.modelUpdater.updateModels(serverResponse);
|
||
|
|
||
|
expect(analysis1.get('status')).toEqual('status_a1');
|
||
|
expect(analysis1.get('query')).toEqual('query_a1');
|
||
|
expect(analysis1.get('url')).toEqual('url_a1');
|
||
|
expect(analysis1.setOk).toHaveBeenCalled();
|
||
|
expect(analysis2.get('status')).toEqual('status_a2');
|
||
|
expect(analysis2.get('query')).toEqual('query_a2');
|
||
|
expect(analysis2.get('url')).toEqual('url_a2');
|
||
|
expect(analysis2.setOk).toHaveBeenCalled();
|
||
|
});
|
||
|
|
||
|
it('should update analysis models and set status to "failed"', function () {
|
||
|
var analysis1 = new AnalysisModel({ id: 'a1', type: 'source', query: 'SELECT * FROM table' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
var analysis2 = new AnalysisModel({ id: 'a2', type: 'source', query: 'SELECT * FROM table' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
var layer = new CartoDBLayer({ source: analysis1 }, { engine: engineMock });
|
||
|
var dataview = new Dataview({ id: 'a1', source: analysis2 }, { bboxFilter: boundingBoxFilter, engine: engineMock });
|
||
|
|
||
|
spyOn(serverResponse, 'getAnalysisNodeMetadata').and.callFake(function (analysisId) {
|
||
|
return { error_message: 'fake_error_message', status: 'failed', query: 'query_' + analysisId, url: { http: 'url_' + analysisId } };
|
||
|
});
|
||
|
|
||
|
this.layersCollection.reset([layer]);
|
||
|
this.dataviewsCollection.reset([dataview]);
|
||
|
this.modelUpdater.updateModels(serverResponse);
|
||
|
|
||
|
expect(analysis1.get('status')).toEqual('failed');
|
||
|
expect(analysis1.get('error')).toEqual({ message: 'fake_error_message' });
|
||
|
expect(analysis2.get('status')).toEqual('failed');
|
||
|
expect(analysis2.get('error')).toEqual({ message: 'fake_error_message' });
|
||
|
});
|
||
|
|
||
|
it('should not update attributes that are original params (eg: query)', function () {
|
||
|
var analysis1 = new AnalysisModel({ id: 'a1', type: 'source', query: 'original_query' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
var layer = new CartoDBLayer({ source: analysis1 }, { engine: engineMock });
|
||
|
|
||
|
spyOn(analysis1, 'getParamNames').and.returnValue(['query']);
|
||
|
spyOn(serverResponse, 'getAnalysisNodeMetadata').and.callFake(function (analysisId) {
|
||
|
return { status: 'new_status', query: 'query_' + analysisId, url: { http: 'new_url' } };
|
||
|
});
|
||
|
|
||
|
this.layersCollection.reset([layer]);
|
||
|
this.dataviewsCollection.reset([]);
|
||
|
this.modelUpdater.updateModels(serverResponse);
|
||
|
|
||
|
expect(analysis1.get('status')).toEqual('new_status');
|
||
|
expect(analysis1.get('query')).toEqual('original_query');
|
||
|
expect(analysis1.get('url')).toEqual('new_url');
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('.setErrors', function () {
|
||
|
it('should set analysis status to "error"', function () {
|
||
|
var analysisModel = new AnalysisModel({ id: 'a1', type: 'source', query: 'SELECT * FROM table' }, { engine: engineMock, camshaftReference: camshaftReferenceMock });
|
||
|
var layer = new CartoDBLayer({ source: analysisModel }, { engine: engineMock });
|
||
|
|
||
|
spyOn(analysisModel, 'setError');
|
||
|
|
||
|
this.layersCollection.reset([layer]);
|
||
|
this.dataviewsCollection.reset([]);
|
||
|
|
||
|
this.modelUpdater.setErrors([
|
||
|
new WindshaftError({
|
||
|
type: 'analysis',
|
||
|
message: 'fake_error_mesagge"',
|
||
|
analysis: {
|
||
|
id: 'fake_analysis_id',
|
||
|
node_id: 'a1',
|
||
|
context: {
|
||
|
something: 'fake_error_context'
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
]);
|
||
|
|
||
|
expect(analysisModel.setError).toHaveBeenCalled();
|
||
|
var error = analysisModel.setError.calls.argsFor(0)[0];
|
||
|
expect(error.analysisId).toEqual('a1');
|
||
|
expect(error.message).toEqual('fake_error_mesagge"');
|
||
|
expect(error.context).toEqual({ something: 'fake_error_context' });
|
||
|
});
|
||
|
|
||
|
it('should "mark" layer as erroroneus', function () {
|
||
|
var layer = new Backbone.Model({
|
||
|
id: 'LAYER_ID'
|
||
|
});
|
||
|
layer.setError = jasmine.createSpy('setError');
|
||
|
|
||
|
this.layersCollection.reset([layer]);
|
||
|
|
||
|
this.modelUpdater.setErrors([
|
||
|
new WindshaftError({
|
||
|
type: 'layer',
|
||
|
subtype: 'turbo-carto',
|
||
|
message: 'turbo-carto: something went wrong',
|
||
|
layer: {
|
||
|
index: 0,
|
||
|
id: 'LAYER_ID',
|
||
|
type: 'cartodb',
|
||
|
context: {
|
||
|
selector: '#layer',
|
||
|
source: {
|
||
|
start: {
|
||
|
line: 1,
|
||
|
column: 10
|
||
|
},
|
||
|
end: {
|
||
|
line: 1,
|
||
|
column: 61
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
})
|
||
|
]);
|
||
|
|
||
|
expect(layer.setError).toHaveBeenCalled();
|
||
|
var error = layer.setError.calls.argsFor(0)[0];
|
||
|
|
||
|
expect(error.type).toEqual('layer');
|
||
|
expect(error.subtype).toEqual('turbo-carto');
|
||
|
expect(error.layerId).toEqual('LAYER_ID');
|
||
|
expect(error.message).toEqual('turbo-carto: something went wrong');
|
||
|
expect(error.context).toEqual({
|
||
|
selector: '#layer',
|
||
|
source: {
|
||
|
start: {
|
||
|
line: 1,
|
||
|
column: 10
|
||
|
},
|
||
|
end: {
|
||
|
line: 1,
|
||
|
column: 61
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should "mark" legend models as erroroneus', function () {
|
||
|
var layer1 = new CartoDBLayer({}, { engine: engineMock });
|
||
|
var layer2 = new CartoDBLayer({}, { engine: engineMock });
|
||
|
|
||
|
expect(layer1.legends.bubble.isError()).toBeFalsy();
|
||
|
expect(layer1.legends.category.isError()).toBeFalsy();
|
||
|
expect(layer1.legends.choropleth.isError()).toBeFalsy();
|
||
|
|
||
|
expect(layer2.legends.bubble.isError()).toBeFalsy();
|
||
|
expect(layer2.legends.category.isError()).toBeFalsy();
|
||
|
expect(layer2.legends.choropleth.isError()).toBeFalsy();
|
||
|
|
||
|
this.layersCollection.reset([layer1, layer2]);
|
||
|
|
||
|
this.modelUpdater.setErrors();
|
||
|
|
||
|
expect(layer1.legends.bubble.isError()).toBeTruthy();
|
||
|
expect(layer1.legends.category.isError()).toBeTruthy();
|
||
|
expect(layer1.legends.choropleth.isError()).toBeTruthy();
|
||
|
|
||
|
expect(layer2.legends.bubble.isError()).toBeTruthy();
|
||
|
expect(layer2.legends.category.isError()).toBeTruthy();
|
||
|
expect(layer2.legends.choropleth.isError()).toBeTruthy();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
var camshaftReferenceMock = {
|
||
|
getSourceNamesForAnalysisType: function (analysisType) {
|
||
|
var map = {
|
||
|
'analysis-type-1': ['source1', 'source2'],
|
||
|
'trade-area': ['source'],
|
||
|
'estimated-population': ['source'],
|
||
|
'sql-function': ['source', 'target']
|
||
|
};
|
||
|
return map[analysisType];
|
||
|
},
|
||
|
getParamNamesForAnalysisType: function (analysisType) {
|
||
|
var map = {
|
||
|
'analysis-type-1': ['attribute1', 'attribute2'],
|
||
|
'trade-area': ['kind', 'time'],
|
||
|
'estimated-population': ['columnName']
|
||
|
};
|
||
|
|
||
|
return map[analysisType];
|
||
|
}
|
||
|
};
|