Initial commit
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
var adapter = require('../../../../src/windshaft-integration/legends/rule-to-bubble-legend-adapter');
|
||||
|
||||
describe('src/windshaft-integration/legends/rule-to-bubble-legend-adapter', function () {
|
||||
beforeEach(function () {
|
||||
this.rule = {
|
||||
'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
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
describe('.canAdapt', function () {
|
||||
it('should return true if prop is valid', function () {
|
||||
expect(adapter.canAdapt(this.rule)).toBeTruthy();
|
||||
|
||||
// lines
|
||||
this.rule.prop = 'line-width';
|
||||
expect(adapter.canAdapt(this.rule)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return false if prop is not valid', function () {
|
||||
this.rule.prop = 'marker-fill';
|
||||
expect(adapter.canAdapt(this.rule)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.adapt', function () {
|
||||
it('should return attrs', function () {
|
||||
var attrs = adapter.adapt([this.rule]);
|
||||
expect(attrs).toEqual({
|
||||
values: [
|
||||
10,
|
||||
1000,
|
||||
2000,
|
||||
3000,
|
||||
4000,
|
||||
5000
|
||||
],
|
||||
sizes: [
|
||||
10,
|
||||
14,
|
||||
20,
|
||||
26,
|
||||
32
|
||||
],
|
||||
avg: 3500
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,94 @@
|
||||
var adapter = require('../../../../src/windshaft-integration/legends/rule-to-category-legend-adapter');
|
||||
|
||||
describe('src/windshaft-integration/legends/rule-to-category-legend-adapter', function () {
|
||||
beforeEach(function () {
|
||||
this.rule = {
|
||||
'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
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
describe('.canAdapt', function () {
|
||||
it('should return true if prop is valid', function () {
|
||||
expect(adapter.canAdapt(this.rule)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return false if prop is not valid', function () {
|
||||
this.rule.prop = 'marker-width';
|
||||
expect(adapter.canAdapt(this.rule)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.adapt', function () {
|
||||
it('should return attrs', function () {
|
||||
var attrs = adapter.adapt([this.rule]);
|
||||
expect(attrs).toEqual({
|
||||
categories: [
|
||||
{ title: 'Category 1', icon: '', color: '#AAAAAA' },
|
||||
{ title: 'Category 2', icon: '', color: '#BBBBBB' }
|
||||
],
|
||||
default: {
|
||||
icon: '',
|
||||
color: '#CCCCCC'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should include and empty default property if there is no bucket with a default filter', function () {
|
||||
this.rule.buckets = [
|
||||
{
|
||||
'filter': {
|
||||
'type': 'category',
|
||||
'name': 'Category 1'
|
||||
},
|
||||
'value': '#AAAAAA'
|
||||
},
|
||||
{
|
||||
'filter': {
|
||||
'type': 'category',
|
||||
'name': 'Category 2'
|
||||
},
|
||||
'value': '#BBBBBB'
|
||||
}
|
||||
];
|
||||
|
||||
var attrs = adapter.adapt([this.rule]);
|
||||
expect(attrs).toEqual({
|
||||
categories: [
|
||||
{ title: 'Category 1', icon: '', color: '#AAAAAA' },
|
||||
{ title: 'Category 2', icon: '', color: '#BBBBBB' }
|
||||
],
|
||||
default: {
|
||||
icon: '',
|
||||
color: ''
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,97 @@
|
||||
var adapter = require('../../../../src/windshaft-integration/legends/rule-to-choropleth-legend-adapter');
|
||||
|
||||
describe('src/windshaft-integration/legends/rule-to-choropleth-legend-adapter', function () {
|
||||
beforeEach(function () {
|
||||
this.rule = {
|
||||
'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
|
||||
}
|
||||
};
|
||||
this.one_bucket_rule = {
|
||||
'selector': '#layer',
|
||||
'prop': 'polygon-fill',
|
||||
'mapping': '>',
|
||||
'buckets': [
|
||||
{
|
||||
'filter': {
|
||||
'type': 'range',
|
||||
'start': 100,
|
||||
'end': 100
|
||||
},
|
||||
'value': '#AAAAAA'
|
||||
}
|
||||
],
|
||||
'stats': {
|
||||
'filter_avg': 100
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
describe('.canAdapt', function () {
|
||||
it('should return true if prop is valid', function () {
|
||||
expect(adapter.canAdapt(this.rule)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return false if prop is not valid', function () {
|
||||
this.rule.prop = 'marker-width';
|
||||
expect(adapter.canAdapt(this.rule)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.adapt', function () {
|
||||
it('should return attrs', function () {
|
||||
var attrs = adapter.adapt([this.rule]);
|
||||
expect(attrs).toEqual({
|
||||
colors: [
|
||||
{ label: '0', value: '#AAAAAA' },
|
||||
{ label: '', value: '#BBBBBB' },
|
||||
{ label: '3000', value: '#CCCCCC' }
|
||||
],
|
||||
avg: 1975,
|
||||
max: 3000,
|
||||
min: 0
|
||||
});
|
||||
});
|
||||
it('should return two buckets in case we receive just one', function () {
|
||||
var attrs = adapter.adapt([this.one_bucket_rule]);
|
||||
expect(attrs).toEqual({
|
||||
colors: [
|
||||
{ label: '100', value: '#AAAAAA' },
|
||||
{ label: '100', value: '#AAAAAA' }
|
||||
],
|
||||
avg: 100,
|
||||
max: 100,
|
||||
min: 100
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,733 @@
|
||||
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];
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user