237 lines
7.6 KiB
JavaScript
237 lines
7.6 KiB
JavaScript
|
var $ = require('jquery');
|
||
|
var Backbone = require('backbone');
|
||
|
var UserActions = require('builder/data/user-actions');
|
||
|
var LayerDefinitionModel = require('builder/data/layer-definition-model');
|
||
|
var EditorWidgetsView = require('builder/editor/widgets/widgets-view');
|
||
|
var WidgetDefinitionModel = require('builder/data/widget-definition-model');
|
||
|
var Router = require('builder/routes/router');
|
||
|
var FactoryModals = require('../../factories/modals');
|
||
|
|
||
|
var STATES = {
|
||
|
loading: 'loading',
|
||
|
ready: 'ready'
|
||
|
};
|
||
|
|
||
|
describe('editor/widgets/widgets-view', function () {
|
||
|
var analysisDefinitionNodeModel;
|
||
|
|
||
|
function createLayerDefinitionsCollection (layerDefinitionModel) {
|
||
|
var layerDefinitionsCollection = new Backbone.Collection([layerDefinitionModel]);
|
||
|
|
||
|
layerDefinitionsCollection.loadAllQueryGeometryModels = function (callback) {
|
||
|
callback();
|
||
|
};
|
||
|
|
||
|
layerDefinitionsCollection.isThereAnyGeometryData = function () {
|
||
|
return Promise.resolve(true);
|
||
|
};
|
||
|
|
||
|
return layerDefinitionsCollection;
|
||
|
}
|
||
|
|
||
|
beforeEach(function () {
|
||
|
spyOn(Router, 'navigate');
|
||
|
|
||
|
this.model = new LayerDefinitionModel({
|
||
|
id: 'l-100',
|
||
|
options: {
|
||
|
type: 'CartoDB'
|
||
|
}
|
||
|
}, {
|
||
|
parse: true,
|
||
|
configModel: {}
|
||
|
});
|
||
|
|
||
|
analysisDefinitionNodeModel = new Backbone.Model({ type: 'source' });
|
||
|
analysisDefinitionNodeModel.querySchemaModel = new Backbone.Model();
|
||
|
analysisDefinitionNodeModel.querySchemaModel.hasGeometryData = function () {
|
||
|
return true;
|
||
|
};
|
||
|
analysisDefinitionNodeModel.isSourceType = function () {
|
||
|
return true;
|
||
|
};
|
||
|
analysisDefinitionNodeModel.getColor = function () {
|
||
|
return '#fabada';
|
||
|
};
|
||
|
this.model.findAnalysisDefinitionNodeModel = function () {
|
||
|
return analysisDefinitionNodeModel;
|
||
|
};
|
||
|
|
||
|
spyOn(this.model, 'getAnalysisDefinitionNodeModel').and.returnValue(analysisDefinitionNodeModel);
|
||
|
|
||
|
this.widgetDefinitionsCollection = new Backbone.Collection();
|
||
|
this.analysisDefinitionNodesCollection = new Backbone.Collection();
|
||
|
this.layerDefinitionsCollection = createLayerDefinitionsCollection(this.model);
|
||
|
|
||
|
this.userActions = UserActions({
|
||
|
userModel: {},
|
||
|
analysisDefinitionsCollection: {},
|
||
|
analysisDefinitionNodesCollection: {},
|
||
|
layerDefinitionsCollection: {},
|
||
|
widgetDefinitionsCollection: {}
|
||
|
});
|
||
|
this.promise = $.Deferred();
|
||
|
spyOn(this.userActions, 'saveWidget').and.returnValue(this.promise);
|
||
|
|
||
|
this.view = new EditorWidgetsView({
|
||
|
modals: FactoryModals.createModalService(),
|
||
|
userActions: this.userActions,
|
||
|
userModel: {},
|
||
|
configModel: {},
|
||
|
analysisDefinitionNodesCollection: this.analysisDefinitionNodesCollection,
|
||
|
widgetDefinitionsCollection: this.widgetDefinitionsCollection,
|
||
|
layerDefinitionsCollection: this.layerDefinitionsCollection,
|
||
|
stackLayoutModel: jasmine.createSpyObj('stackLayoutModel', ['nextStep'])
|
||
|
});
|
||
|
|
||
|
this.view.render();
|
||
|
});
|
||
|
|
||
|
describe('_initialize', function () {
|
||
|
it('should initialize a viewModel with a state', function () {
|
||
|
expect(this.view.viewModel).toBeDefined();
|
||
|
expect(this.view.viewModel.get('state')).toBeDefined();
|
||
|
});
|
||
|
|
||
|
describe('._initViewState', function () {
|
||
|
it('should initialze a viewState that indicates if there is geometry data', function () {
|
||
|
expect(this.view._viewState).toBeDefined();
|
||
|
expect(this.view._viewState.get('anyGeometryData')).toBeDefined();
|
||
|
});
|
||
|
|
||
|
it('should call _setViewState', function () {
|
||
|
spyOn(this.view, '_setViewState');
|
||
|
|
||
|
this.view._initViewState();
|
||
|
expect(this.view._setViewState).toHaveBeenCalled();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('._setViewState', function () {
|
||
|
it('should update _viewState and set if there is geometry data', function (done) {
|
||
|
this.view._viewState.set('anyGeometryData', false);
|
||
|
spyOn(this.layerDefinitionsCollection, 'isThereAnyGeometryData').and.returnValue(Promise.resolve(true));
|
||
|
|
||
|
this.view._setViewState();
|
||
|
|
||
|
setTimeout(function () {
|
||
|
expect(this.view._viewState.get('anyGeometryData')).toEqual(true);
|
||
|
done();
|
||
|
}.bind(this), 0);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('render', function () {
|
||
|
it('should render loading view if state is loading', function () {
|
||
|
this.view.viewModel.set({state: STATES.loading});
|
||
|
this.view.render();
|
||
|
expect(this.view.$('.FormPlaceholder-widget').length).toBe(4);
|
||
|
});
|
||
|
|
||
|
it('should not render no geometry view when _anyGeometryData is true', function () {
|
||
|
this.view.render();
|
||
|
|
||
|
expect(this.view.$el.text()).not.toContain('editor.widgets.no-geometry-data');
|
||
|
});
|
||
|
|
||
|
it('should render no geometry view if no data when no geometry data', function () {
|
||
|
this.view._viewState.set('anyGeometryData', false);
|
||
|
this.view.render();
|
||
|
|
||
|
expect(this.view.$el.text()).toContain('editor.widgets.no-geometry-data');
|
||
|
});
|
||
|
|
||
|
it('should render if widgets collection add one or more widgets', function () {
|
||
|
spyOn(this.view, 'render');
|
||
|
|
||
|
this.view._initBinds();
|
||
|
this.widgetDefinitionsCollection.trigger('successAdd');
|
||
|
|
||
|
expect(this.view.render).toHaveBeenCalled();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('sortable', function () {
|
||
|
beforeEach(function () {
|
||
|
this.widgetDefModel1 = new WidgetDefinitionModel({
|
||
|
id: 'widget-1',
|
||
|
type: 'formula',
|
||
|
title: 'formula example',
|
||
|
layer_id: 'l-100',
|
||
|
column: 'areas',
|
||
|
operation: 'avg',
|
||
|
order: 1
|
||
|
}, {
|
||
|
configModel: {},
|
||
|
mapId: 'm-123'
|
||
|
});
|
||
|
this.widgetDefModel2 = new WidgetDefinitionModel({
|
||
|
id: 'widget-2',
|
||
|
type: 'histogram',
|
||
|
title: 'histogram example',
|
||
|
layer_id: 'l-100',
|
||
|
column: 'population',
|
||
|
order: 0
|
||
|
}, {
|
||
|
configModel: {},
|
||
|
mapId: 'm-123'
|
||
|
});
|
||
|
this.widgetDefinitionsCollection.add(this.widgetDefModel1);
|
||
|
this.widgetDefinitionsCollection.add(this.widgetDefModel2);
|
||
|
});
|
||
|
|
||
|
it('should be initialized when view is rendered', function () {
|
||
|
spyOn(this.view, '_initSortable').and.callThrough();
|
||
|
this.view.render();
|
||
|
expect(this.view._initSortable).toHaveBeenCalled();
|
||
|
expect(this.view.$('.js-widgets').data('ui-sortable')).not.toBeUndefined();
|
||
|
});
|
||
|
|
||
|
it('should be show the widgets in the right order', function () {
|
||
|
this.view.render();
|
||
|
expect(this.view.$('.js-widgets li:nth-child(1) .js-title').text()).toBe('histogram example');
|
||
|
expect(this.view.$('.js-widgets li:nth-child(2) .js-title').text()).toBe('formula example');
|
||
|
});
|
||
|
|
||
|
it('should update the order of the models when sort has finished', function () {
|
||
|
this.view.render();
|
||
|
expect(this.widgetDefModel2.get('order')).toBe(0);
|
||
|
expect(this.widgetDefModel1.get('order')).toBe(1);
|
||
|
|
||
|
// Impossible to fake sortable behaviour so...
|
||
|
this.view.$('.js-widgetItem:eq(1)').insertBefore(this.view.$('.js-widgetItem:eq(0)'));
|
||
|
this.view._onSortableFinish();
|
||
|
|
||
|
// End of fake sortable
|
||
|
expect(this.widgetDefModel1.get('order')).toBe(0);
|
||
|
expect(this.widgetDefModel2.get('order')).toBe(1);
|
||
|
expect(this.userActions.saveWidget).toHaveBeenCalled();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('when adding a widget definition', function () {
|
||
|
var widgetDefModel;
|
||
|
|
||
|
beforeEach(function () {
|
||
|
widgetDefModel = new WidgetDefinitionModel({
|
||
|
id: 'widget-3',
|
||
|
type: 'formula',
|
||
|
title: 'AVG districts homes',
|
||
|
layer_id: 'l-100',
|
||
|
column: 'areas',
|
||
|
operation: 'avg'
|
||
|
}, {
|
||
|
configModel: {},
|
||
|
mapId: 'm-123'
|
||
|
});
|
||
|
this.widgetDefinitionsCollection.add(widgetDefModel);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should have no leaks', function () {
|
||
|
this.view.render();
|
||
|
expect(this.view).toHaveNoLeaks();
|
||
|
});
|
||
|
});
|