cartodb-4.42/lib/assets/test/spec/deep-insights/widgets/widget-model.spec.js
2024-04-06 05:25:13 +00:00

562 lines
17 KiB
JavaScript

var specHelper = require('../spec-helper');
var WidgetModel = require('../../../../javascripts/deep-insights/widgets/widget-model');
var Backbone = require('backbone');
var _ = require('underscore');
describe('widgets/widget-model', function () {
describe('dataview enabled', function () {
var dataviewModel;
var layerModel;
beforeEach(function () {
var vis = specHelper.createDefaultVis();
var source = vis.analysis.findNodeById('a0');
// Use a category dataview as example
dataviewModel = vis.dataviews.createCategoryModel({
column: 'col',
source: source
});
layerModel = new Backbone.Model({
id: 'first-layer',
type: 'torque',
visible: false
});
this.model = new WidgetModel(null, {
dataviewModel: dataviewModel,
layerModel: layerModel
});
});
it('should be enabled always although layer is not visible', function () {
expect(dataviewModel.get('enabled')).toBeTruthy();
});
it('should not change enable attribute although layer visibility changes', function () {
layerModel.set('visible', true);
expect(dataviewModel.get('enabled')).toBeTruthy();
layerModel.set('visible', false);
expect(dataviewModel.get('enabled')).toBeTruthy();
});
});
describe('when autostyle options is enabled', function () {
var dataviewModel;
var layerModel;
beforeEach(function () {
var vis = specHelper.createDefaultVis();
var source = vis.analysis.findNodeById('a0');
// Use a category dataview as example
dataviewModel = vis.dataviews.createCategoryModel({
column: 'col',
source: source
});
dataviewModel.remove = spyOn(dataviewModel, 'remove');
layerModel = new Backbone.Model({
id: 'first-layer',
type: 'torque',
visible: true
});
this.model = new WidgetModel(null, {
dataviewModel: dataviewModel,
layerModel: layerModel
}, {autoStyleEnabled: true});
});
describe('.update', function () {
beforeEach(function () {
this.widgetChangeSpy = jasmine.createSpy('widgetModel change');
this.model.on('change', this.widgetChangeSpy);
});
describe('when given empty object', function () {
beforeEach(function () {
this.result = this.model.update();
this.result = this.model.update({}) || this.result;
});
it('should return false since did not change anything', function () {
expect(this.result).toBe(false);
});
it('should not change anything', function () {
expect(this.widgetChangeSpy).not.toHaveBeenCalled();
expect(this.model.dataviewModel.changedAttributes()).toBe(false);
});
});
describe('when there are some attrsNames but no dataview attrs names defined', function () {
beforeEach(function () {
this.model.set({
attrsNames: ['title']
}, { silent: true });
this.result = this.model.update({
title: 'new title',
column: 'col',
aggregation: 'count',
invalid: 'attr, should not be set'
});
});
it('should return true since attrs were changed', function () {
expect(this.result).toBe(true);
});
it('should update widget', function () {
expect(this.widgetChangeSpy).toHaveBeenCalled();
});
it('should have changed the valid attrs and leave the rest', function () {
expect(this.model.hasChanged('title')).toBe(true);
});
it('should not change existing attrs', function () {
expect(this.model.hasChanged('collapsed')).toBe(false);
});
it('should not set any invalid attrs', function () {
expect(this.model.get('invalid')).toBeUndefined();
});
it('should not update dataviewModel', function () {
expect(this.model.dataviewModel.changedAttributes()).toBe(false);
});
});
describe('when there are both widget and dataview attrs names defined', function () {
beforeEach(function () {
this.model.set({
attrsNames: ['title']
}, { silent: true });
this.result = this.model.update({
title: 'new title',
column: 'other',
aggregation: 'sum',
foo: 'attr, should not be set'
});
});
it('should return true since attrs were changed', function () {
expect(this.result).toBe(true);
});
it('should update the widget', function () {
expect(this.model.changedAttributes()).toEqual({
title: 'new title'
});
});
it('should update the dataview model attrs', function () {
expect(this.model.dataviewModel.changedAttributes()).toEqual({
column: 'other',
aggregation: 'sum'
});
});
});
});
describe('.remove', function () {
beforeEach(function () {
this.removeSpy = jasmine.createSpy('remove');
spyOn(this.model, 'stopListening');
this.model.on('destroy', this.removeSpy);
this.model.remove();
});
it('should remove the model', function () {
expect(this.removeSpy).toHaveBeenCalledWith(this.model);
});
it('should remove dataviewModel', function () {
expect(this.model.dataviewModel.remove).toHaveBeenCalled();
});
it('should call stop listening to events', function () {
expect(this.model.stopListening).toHaveBeenCalled();
});
});
describe('getState', function () {
it('should only return states different from default', function () {
this.model.setState({
collapsed: true
});
expect(this.model.getState()).toEqual({collapsed: true});
});
});
describe('isAutoStyleEnabled', function () {
beforeEach(function () {
this.model.set('type', 'category');
});
it('should return true without style options', function () {
expect(this.model.isAutoStyleEnabled()).toBe(true);
});
it('should return true with empty object style options', function () {
this.model.set('style', {});
expect(this.model.isAutoStyleEnabled()).toBe(true);
});
it('should return true with style options', function () {
var style = {
auto_style: {
allowed: true
}
};
this.model.set('style', style);
expect(this.model.isAutoStyleEnabled()).toBe(true);
});
it('should return false with style options', function () {
var style = {
auto_style: {
allowed: false
}
};
this.model.set('style', style);
expect(this.model.isAutoStyleEnabled()).toBe(false);
});
it('should be false if type is not category or histogram', function () {
var model = new WidgetModel(null, {
dataviewModel: dataviewModel,
layerModel: layerModel,
type: 'time-series'
}, {autoStyleEnabled: true});
expect(model.isAutoStyleEnabled()).toBeFalsy();
});
});
describe('.getAutoStyle', function () {
it('should not provide any info if auto-style is not enabled', function () {
spyOn(this.model, 'isAutoStyleEnabled').and.returnValue(false);
var data = this.model.getAutoStyle();
expect(data).toEqual({});
});
it('should not provide any info if autoStyler is not defined', function () {
spyOn(this.model, 'isAutoStyleEnabled').and.returnValue(true);
this.model.autoStyler = undefined;
var data = this.model.getAutoStyle();
expect(data).toEqual({});
});
it('should return proper definition and cartocss when no style model present', function () {
var definition = 'a definition';
var cartocss = 'some cartocss';
spyOn(this.model, 'isAutoStyleEnabled').and.returnValue(true);
this.model.autoStyler = {
getDef: function () {
return definition;
}
};
layerModel.set('cartocss', cartocss);
var expectedData = {
definition: definition,
cartocss: cartocss
};
var data = this.model.getAutoStyle();
expect(_.isEqual(data, expectedData)).toBe(true);
});
it('should return proper definition and cartocss when auto_style property already present', function () {
var definition = 'a definition';
var cartocss = 'some cartocss';
var style = {
auto_style: {
definition: 'other definition',
cartocss: 'other cartocss',
anotherProperty: 'another property'
}
};
spyOn(this.model, 'isAutoStyleEnabled').and.returnValue(true);
this.model.set('style', style);
this.model.autoStyler = {
getDef: function () {
return definition;
}
};
layerModel.set('cartocss', cartocss);
var expectedData = {
definition: definition,
cartocss: cartocss,
anotherProperty: 'another property'
};
var data = this.model.getAutoStyle();
expect(_.isEqual(data, expectedData)).toBe(true);
});
});
describe('.hasColorsAutoStyle', function () {
it('should return false if autostyle or auto-style definition is empty', function () {
spyOn(this.model, 'getAutoStyle').and.returnValue({
cartocss: '#dummy {}',
definition: {}
});
expect(this.model.hasColorsAutoStyle()).toBe(false);
this.model.getAutoStyle.and.returnValue({});
expect(this.model.hasColorsAutoStyle()).toBe(false);
});
it('should return false if color or range doesn\'t exist', function () {
spyOn(this.model, 'getAutoStyle').and.returnValue({
cartocss: '#dummy {}',
definition: {
point: {}
}
});
expect(this.model.hasColorsAutoStyle()).toBe(false);
this.model.getAutoStyle.and.returnValue({
cartocss: '#dummy {}',
definition: {
point: {
color: {}
}
}
});
expect(this.model.hasColorsAutoStyle()).toBe(false);
});
it('should return false if there is no colors defined', function () {
spyOn(this.model, 'getAutoStyle').and.returnValue({
cartocss: '#dummy {}',
definition: {
point: {
color: {
range: []
}
}
}
});
expect(this.model.hasColorsAutoStyle()).toBe(false);
this.model.getAutoStyle.and.returnValue({
cartocss: '#dummy {}',
definition: {
point: {
color: {
range: {}
}
},
line: {
color: {
range: {}
}
},
polygon: {
color: {
range: {}
}
}
}
});
expect(this.model.hasColorsAutoStyle()).toBe(false);
});
it('should return true if autostyle return any color', function () {
spyOn(this.model, 'getAutoStyle').and.returnValue({
cartocss: '#dummy {}',
definition: {
point: {
color: {
range: ['#red']
}
}
}
});
expect(this.model.hasColorsAutoStyle()).toBe(true);
});
});
describe('.autoStyle', function () {
beforeEach(function () {
spyOn(this.model, 'isAutoStyleEnabled').and.returnValue(true);
this.model.autoStyler = {
getStyle: jasmine.createSpy('getStyle')
};
layerModel.set('initialStyle', 'foo');
layerModel.set('cartocss', 'wadus');
});
it('should generate autostyle styles when dataview has data', function () {
this.model.dataviewModel.set('data', [{
name: 'foo'
}, {
name: 'bar'
}]);
this.model.autoStyle();
expect(this.model.autoStyler.getStyle).toHaveBeenCalled();
expect(layerModel.get('initialStyle')).toBe('wadus');
});
it('should not generate autostyle styles when dataview has data', function () {
this.model.dataviewModel.set('data', []);
this.model.autoStyle();
expect(this.model.autoStyler.getStyle).not.toHaveBeenCalled();
expect(layerModel.get('initialStyle')).toBe('foo');
});
});
});
describe('when autostyle option is disabled', function () {
beforeEach(function () {
var vis = specHelper.createDefaultVis();
this.layerModel = vis.map.layers.first();
var source = vis.analysis.findNodeById('a0');
// Use a category dataview as example
this.dataviewModel = vis.dataviews.createCategoryModel({
column: 'col',
source: source
});
this.dataviewModel.remove = spyOn(this.dataviewModel, 'remove');
});
describe('isAutoStyleEnabled', function () {
it('should be true if without autostyle option', function () {
var model = new WidgetModel(null, {
dataviewModel: this.dataviewModel,
layerModel: this.layerModel
});
model.set('type', 'category');
expect(model.isAutoStyleEnabled()).toBe(true);
});
it('should be false if passed autostyle option as false', function () {
var model = new WidgetModel(null, {
dataviewModel: this.dataviewModel,
layerModel: this.layerModel
}, {autoStyleEnabled: false});
model.set('type', 'category');
expect(model.isAutoStyleEnabled()).toBe(false);
});
it('should be true if passed autostyle option as true', function () {
var model = new WidgetModel(null, {
dataviewModel: this.dataviewModel,
layerModel: this.layerModel
}, {autoStyleEnabled: true});
model.set('type', 'category');
expect(model.isAutoStyleEnabled()).toBe(true);
});
});
});
describe('.getWidgetColor', function () {
beforeEach(function () {
var vis = specHelper.createDefaultVis();
this.layerModel = vis.map.layers.first();
var source = vis.analysis.findNodeById('a0');
// Use a category dataview as example
this.dataviewModel = vis.dataviews.createCategoryModel({
column: 'col',
source: source
});
this.model = new WidgetModel(null, {
dataviewModel: this.dataviewModel,
layerModel: this.layerModel
}, {autoStyleEnabled: false});
});
describe('when widget_color_changed is true', function () {
it('should return color', function () {
var style = {
widget_style: {
definition: {
color: {
fixed: '#fabada'
}
},
widget_color_changed: true
}
};
this.model.set('style', style);
expect(this.model.getWidgetColor()).toBe('#fabada');
});
});
describe('when widget_color_changed is false', function () {
it('should not return color', function () {
var style = {
widget_style: {
definition: {
color: {
fixed: '#9DE0AD'
}
},
widget_color_changed: false
}
};
this.model.set('style', style);
expect(this.model.getWidgetColor()).toBe(false);
});
describe('and widget color value has changed', function () { // this is the case for existing widgets
it('should return color', function () {
var style = {
widget_style: {
definition: {
color: {
fixed: '#fabada',
opacity: 1
}
}
}
};
this.model.set('style', style);
expect(this.model.getWidgetColor()).toBe('#fabada');
});
});
});
});
describe('forceResize', function () {
beforeEach(function () {
this.model = new WidgetModel(null, {
dataviewModel: new Backbone.Model(),
layerModel: new Backbone.Model()
});
});
it('should trigger forceResize event if it is a time-series', function () {
spyOn(this.model, 'trigger');
this.model.set('type', 'time-series');
this.model.forceResize();
expect(this.model.trigger).toHaveBeenCalledWith('forceResize');
});
it('should not trigger force Resize event if it is not a time-series', function () {
spyOn(this.model, 'trigger');
this.model.set('type', 'category');
this.model.forceResize();
expect(this.model.trigger).not.toHaveBeenCalledWith('forceResize');
});
});
});