Files
cartodb/lib/assets/test/spec/builder/editor/layers/edit-feature-content-view.spec.js
2020-06-15 10:58:47 +08:00

271 lines
8.8 KiB
JavaScript

var _ = require('underscore');
var Backbone = require('backbone');
var EditFeatureContentView = require('builder/editor/layers/edit-feature-content-view');
var MapModeModel = require('builder/map-mode-model');
var LayerDefinitionsCollection = require('builder/data/layer-definitions-collection');
var AnalysisDefinitionNodesCollection = require('builder/data/analysis-definition-nodes-collection');
var ConfigModel = require('builder/data/config-model');
var UserModel = require('builder/data/user-model');
var FeatureDefinitionModel = require('builder/data/feature-definition-model');
var EditorModel = require('builder/data/editor-model');
var ModalsService = require('builder/components/modals/modals-service-model');
var Stylehelper = require('builder/helpers/style');
var Router = require('builder/routes/router');
var QueryGeometryModelMock = function (simple_geom) {
var geom = simple_geom || '';
return {
hasValueAsync: function () {
return Promise.resolve(geom !== '');
},
resetFetch: function () {}
};
};
describe('editor/layers/edit-feature-content-view', function () {
beforeEach(function () {
spyOn(Router, 'navigate');
jasmine.Ajax.install();
jasmine.Ajax.stubRequest(new RegExp('^http(s)?://.*tables.*'))
.andReturn({ status: 200 });
this.configModel = new ConfigModel({
base_url: '/u/pepe'
});
this.userModel = new UserModel({}, {
configModel: this.configModel
});
var analysisDefinitionNodesCollection = new AnalysisDefinitionNodesCollection(null, {
configModel: this.configModel,
userModel: this.userModel
});
var layerDefinitionsCollection = new LayerDefinitionsCollection(null, {
configModel: this.configModel,
userModel: this.userModel,
analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
mapId: 'm-123',
stateDefinitionModel: {}
});
layerDefinitionsCollection.add({
id: 'l-1',
kind: 'carto',
options: {
table_name: 'foo'
}
});
this.layerDefinitionModel = layerDefinitionsCollection.at(0);
this.mapModeModel = new MapModeModel();
this.editorModel = new EditorModel();
this.mapStackLayoutModel = jasmine.createSpyObj('stackLayoutModel', ['prevStep', 'nextStep', 'goToStep']);
this.modals = new ModalsService();
this.rowCollection = {
resetFetch: jasmine.createSpy('resetFetch')
};
var featureDefinition = new FeatureDefinitionModel({}, {
configModel: this.configModel,
layerDefinitionModel: this.layerDefinitionModel,
userModel: this.userModel
});
this.mapModeModel.enterDrawingFeatureMode(featureDefinition);
this.view = new EditFeatureContentView({
layerDefinitionModel: this.layerDefinitionModel,
configModel: this.configModel,
stackLayoutModel: this.mapStackLayoutModel,
mapModeModel: this.mapModeModel,
editorModel: this.editorModel,
model: new Backbone.Model({
hasChanges: false,
isValidAttributes: true,
isValidGeometry: true
}),
modals: this.modals
});
spyOn(this.view, '_addRow').and.callThrough();
spyOn(this.view, '_renderInfo').and.callThrough();
this.view._rowsCollection = this.rowCollection;
this.view.render();
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
it('should get table details', function () {
expect(this.view._tableName).toBe('foo');
expect(this.view._url).toBe('/u/pepe/dataset/foo');
});
it('should render properly', function () {
expect(_.size(this.view._subviews)).toBe(2); // header, content
});
describe('when feature is new', function () {
it('should add row', function () {
expect(this.view._addRow).toHaveBeenCalled();
expect(this.view._renderInfo).toHaveBeenCalled();
});
});
describe('when feature already exists', function () {
var view;
beforeEach(function () {
var featureDefinition = new FeatureDefinitionModel({
cartodb_id: 1
}, {
configModel: this.configModel,
layerDefinitionModel: this.layerDefinitionModel,
userModel: this.userModel
});
featureDefinition.fetch();
this.mapModeModel.enterEditingFeatureMode(featureDefinition);
view = new EditFeatureContentView({
layerDefinitionModel: this.layerDefinitionModel,
configModel: this.configModel,
stackLayoutModel: this.mapStackLayoutModel,
mapModeModel: this.mapModeModel,
editorModel: this.editorModel,
model: new Backbone.Model({
hasChanges: false
}),
modals: this.modals
});
spyOn(view, '_addRow').and.callThrough();
spyOn(view, '_renderInfo').and.callThrough();
view.render();
});
it('should not add row', function () {
expect(view._addRow).not.toHaveBeenCalled();
expect(view._renderInfo).toHaveBeenCalled();
});
});
describe('._onDestroyFeatureSuccess', function () {
it('should call `_onUpdateFeature`', function () {
spyOn(this.view, '_onUpdateFeature').and.callThrough();
spyOn(Router, 'goToStyleTab').and.callThrough();
this.view.notification = {
set: function () {}
};
spyOn(this.view.notification, 'set');
this.view._onDestroyFeatureSuccess();
expect(this.view._onUpdateFeature).toHaveBeenCalledWith('destroy');
expect(this.view.notification.set).toHaveBeenCalled();
expect(this.rowCollection.resetFetch).toHaveBeenCalled();
expect(Router.goToStyleTab).toHaveBeenCalledWith(this.layerDefinitionModel.get('id'));
});
});
describe('._onSaveFeatureSuccess', function () {
it('should call `_onUpdateFeature`', function () {
spyOn(this.view, '_onUpdateFeature').and.callThrough();
spyOn(Router, 'editFeature');
this.view.notification = {
set: function () {}
};
spyOn(this.view.notification, 'set');
this.view._onSaveFeatureSuccess('save');
expect(this.view._onUpdateFeature).toHaveBeenCalled();
expect(this.view.notification.set).toHaveBeenCalled();
expect(this.rowCollection.resetFetch).not.toHaveBeenCalled();
expect(Router.editFeature).toHaveBeenCalled();
});
});
describe('._onUpdateFeature', function () {
it('should reset fetch if saving and current geometry model does not have value', function (done) {
var self = this;
this.view._queryGeometryModel = new QueryGeometryModelMock();
spyOn(this.view._queryGeometryModel, 'resetFetch');
this.view._onUpdateFeature('save');
setTimeout(function () {
expect(self.view._queryGeometryModel.resetFetch).toHaveBeenCalled();
expect(self.rowCollection.resetFetch).not.toHaveBeenCalled();
done();
}, 200);
});
it('should not reset fetch if saving and current geometry model has value', function (done) {
var self = this;
this.view._queryGeometryModel = new QueryGeometryModelMock('polygon');
spyOn(this.view._queryGeometryModel, 'resetFetch');
this.view._onUpdateFeature('save');
setTimeout(function () {
expect(self.view._queryGeometryModel.resetFetch).not.toHaveBeenCalled();
done();
}, 200);
});
it('should reset fetch if destroying', function (done) {
var self = this;
this.view._queryGeometryModel = new QueryGeometryModelMock();
spyOn(this.view._queryGeometryModel, 'resetFetch');
this.view._onUpdateFeature('destroy');
setTimeout(function () {
expect(self.view._queryGeometryModel.resetFetch).toHaveBeenCalled();
expect(self.rowCollection.resetFetch).toHaveBeenCalled();
done();
}, 200);
});
});
describe('when `cancelPreviousEditions` is triggered from _editorModel', function () {
it('should call clean method', function () {
spyOn(this.view, 'clean');
this.view._initBinds();
this.view._editorModel.trigger('cancelPreviousEditions');
expect(this.view.clean).toHaveBeenCalled();
});
});
describe('reload vis', function () {
beforeEach(function () {
spyOn(Stylehelper, 'getColorAttribute');
spyOn(Stylehelper, 'getSizeAttribute');
});
it('should reload vis if metadata changes and layer is styled but that attribute', function () {
Stylehelper.getColorAttribute.and.returnValue('foo');
Stylehelper.getSizeAttribute.and.returnValue(undefined);
this.view._featureModel.set('foo', 10);
expect(this.view._needReloadVis()).toBeTruthy();
});
it('should reload vis if metadata changes and layer is not styled but that attribute', function () {
Stylehelper.getColorAttribute.and.returnValue('bar');
Stylehelper.getSizeAttribute.and.returnValue(undefined);
this.view._featureModel.set('foo', 10);
expect(this.view._needReloadVis()).toBeFalsy();
});
});
it('should have no leaks', function () {
expect(this.view).toHaveNoLeaks();
});
});