cartodb-4.42/lib/assets/test/spec/builder/editor/layers/layer-content-view.spec.js
2024-04-06 05:25:13 +00:00

828 lines
28 KiB
JavaScript

var _ = require('underscore');
var $ = require('jquery');
var Backbone = require('backbone');
var AnalysisDefinitionNodeSourceModel = require('builder/data/analysis-definition-node-source-model');
var AnalysisFormsCollection = require('builder/editor/layers/layer-content-views/analyses/analysis-forms-collection');
var LayerDefinitionsCollection = require('builder/data/layer-definitions-collection');
var LayerDefinitionModel = require('builder/data/layer-definition-model');
var LayerContentView = require('builder/editor/layers/layer-content-view');
var ConfigModel = require('builder/data/config-model');
var UserModel = require('builder/data/user-model');
var EditorModel = require('builder/data/editor-model');
var UserNotifications = require('builder/data/user-notifications');
var AnalysesService = require('builder/editor/layers/layer-content-views/analyses/analyses-service');
var FactoryModals = require('../../factories/modals');
var Router = require('builder/routes/router');
describe('editor/layers/layer-content-view/layer-content-view', function () {
var view;
var analysisDefinitionNodeModel;
var editorModel;
var layerDefinitionModel;
var dashboardCanvasEl;
var handleRouteSpy;
var analysesTabName = 'analyses';
var dataTabName = 'data';
var createViewFn = function (options) {
dashboardCanvasEl = document.createElement('div');
dashboardCanvasEl.className = 'CDB-Dashboard-canvas';
document.body.appendChild(dashboardCanvasEl);
var canvas = document.createElement('div');
canvas.classList.add('CDB-Map-canvas');
dashboardCanvasEl.appendChild(canvas);
var configModel = new ConfigModel({
base_url: '/u/pepe',
user_name: 'pepe',
sql_api_protocol: 'http'
});
var userModel = new UserModel({}, {
configModel: configModel,
username: 'pepe'
});
var mapDefModel = new Backbone.Model({
legends: true
});
layerDefinitionModel = new LayerDefinitionModel({
id: 'l-1',
kind: 'carto',
options: {
source: 'a0',
letter: 'a',
table_name: 'foo'
}
}, {
parse: true,
configModel: configModel
});
var onboardings = new Backbone.Model();
onboardings.create = function () {};
onboardings.destroy = function () {};
analysisDefinitionNodeModel = new AnalysisDefinitionNodeSourceModel({
id: 'a1',
type: 'source',
table_name: 'foo'
}, {
configModel: configModel,
userModel: userModel,
collection: new Backbone.Collection()
});
analysisDefinitionNodeModel.querySchemaModel.attributes.query = 'SELECT * FROM foo';
var layerDefinitionsCollection = new LayerDefinitionsCollection(null, {
configModel: configModel,
userModel: userModel,
analysisDefinitionNodesCollection: new Backbone.Collection(),
mapId: 'map-123',
stateDefinitionModel: {}
});
layerDefinitionsCollection.add(layerDefinitionModel);
var widgetDefinitionsCollection = new Backbone.Collection();
widgetDefinitionsCollection.isThereTimeSeries = function () {
return false;
};
widgetDefinitionsCollection.isThereOtherWidgets = function () {
return false;
};
spyOn(layerDefinitionModel, 'getAnalysisDefinitionNodeModel').and.returnValue(analysisDefinitionNodeModel);
spyOn(layerDefinitionModel, 'findAnalysisDefinitionNodeModel').and.returnValue(analysisDefinitionNodeModel);
spyOn(Router, 'goToLayerList');
spyOn(Router, 'navigate');
handleRouteSpy = spyOn(LayerContentView.prototype, '_handleRoute');
var onboardingNotification = new UserNotifications({}, {
key: 'builder',
configModel: configModel
});
var visDefinitionModel = new Backbone.Model();
var stackLayoutModel = jasmine.createSpyObj('stackLayoutModel', ['prevStep', 'goToStep']);
AnalysesService.init({
onboardings: onboardings,
layerDefinitionsCollection: layerDefinitionsCollection,
modals: FactoryModals.createModalService(),
userModel: userModel,
configModel: configModel
});
editorModel = new EditorModel({ edition: false });
var viewOptions = {
mapDefinitionModel: mapDefModel,
layerDefinitionModel: layerDefinitionModel,
analysisDefinitionsCollection: new Backbone.Collection(),
analysisDefinitionNodesCollection: new Backbone.Collection(),
layerDefinitionsCollection: layerDefinitionsCollection,
legendDefinitionsCollection: new Backbone.Collection(),
widgetDefinitionsCollection: widgetDefinitionsCollection,
userModel: userModel,
modals: FactoryModals.createModalService(),
onboardings: onboardings,
analysis: {},
userActions: {},
vis: {},
stackLayoutModel: stackLayoutModel,
configModel: configModel,
editorModel: editorModel,
mapModeModel: jasmine.createSpyObj('mapModeModel', ['enterDrawingFeatureMode']),
stateDefinitionModel: {},
onboardingNotification: onboardingNotification,
visDefinitionModel: visDefinitionModel
};
return new LayerContentView(_.extend(viewOptions, options));
};
describe('.initialize', function () {
beforeEach(function () {
spyOn(LayerContentView.prototype, '_updateViewState').and.callThrough();
spyOn(LayerContentView.prototype, '_initViewState').and.callThrough();
spyOn(LayerContentView.prototype, '_initBinds').and.callThrough();
spyOn(AnalysesService, 'setLayerId').and.callThrough();
view = createViewFn();
});
it('should initialize correctly', function () {
expect(view.model._querySchemaModel).toBeDefined();
expect(view.model._queryGeometryModel).toBeDefined();
expect(view.model._queryRowsCollection).toBeDefined();
expect(LayerContentView.prototype._updateViewState).toHaveBeenCalled();
expect(LayerContentView.prototype._initViewState).toHaveBeenCalled();
expect(LayerContentView.prototype._initBinds).toHaveBeenCalled();
expect(AnalysesService.setLayerId).toHaveBeenCalled();
});
});
describe('.render', function () {
beforeEach(function () {
view = createViewFn();
spyOn(view, '_renderHeaderView').and.callThrough();
spyOn(view, '_renderLayerTabPaneView').and.callThrough();
});
it('should render correctly', function () {
view.render();
expect(_.size(view._subviews)).toBe(3); // [Header, Geometry Toolips]
expect(view.$('.Editor-HeaderInfo-titleText').text()).toContain('foo');
});
it('should have no leaks', function () {
expect(view).toHaveNoLeaks();
});
describe('when all query objects are loaded', function () {
beforeEach(function () {
view.render();
});
it('should render correctly', function () {
expect(_.size(view._subviews)).toBe(3); // [Header, TabPane, Geometry Toolips]
expect(view.$('.Editor-HeaderInfo-titleText').text()).toContain('foo');
expect(view.$('.CDB-NavMenu .CDB-NavMenu-item').length).toBe(5);
expect(view.$('.js-editorPanelContent').length).toBe(1); // Onboarding
});
});
describe('when can be georeferenced', function () {
beforeEach(function () {
view._viewState.set('canBeGeoreferenced', true);
view.render();
});
it('should disable tabs', function () {
expect(view.$el.find('.CDB-NavMenu-item.is-disabled').length).toBe(3);
});
it('should select the analysis tab', function () {
expect(view._layerTabPaneView.getSelectedTabPaneName()).toBe(analysesTabName);
});
});
describe('when analysisDefinitionNodeModel has errors', function () {
beforeEach(function () {
spyOn(analysisDefinitionNodeModel, 'hasFailed').and.returnValue(true);
view.render();
});
it('should disable tabs properly', function () {
expect(view.$el.find('.CDB-NavMenu-item.is-disabled').length).toBe(3);
});
it('should select the analysis tab', function () {
expect(view._layerTabPaneView.getSelectedTabPaneName()).toBe(analysesTabName);
});
});
describe('when is empty', function () {
beforeEach(function () {
spyOn(analysisDefinitionNodeModel.querySchemaModel, 'isDone').and.returnValue(true);
spyOn(analysisDefinitionNodeModel.queryGeometryModel, 'isDone').and.returnValue(true);
spyOn(analysisDefinitionNodeModel.queryRowsCollection, 'isDone').and.returnValue(true);
spyOn(analysisDefinitionNodeModel, 'hasFailed').and.returnValue(false);
view._viewState.set({
isLayerEmpty: true
});
view.render();
});
it('should select the data tab', function () {
expect(view._layerTabPaneView.getSelectedTabPaneName()).toBe(dataTabName);
});
});
});
describe('._initViewState', function () {
beforeEach(function () {
view = createViewFn();
});
it('should initialize viewState', function () {
view._initViewState();
expect(view._viewState).toBeDefined();
expect(view._viewState.get('isLayerEmpty')).toEqual(false);
expect(view._viewState.get('canBeGeoreferenced')).toEqual(false);
expect(view._viewState.get('isLayerDone')).toEqual(false);
});
it('should call setViewState', function () {
spyOn(view, '_setViewState');
view._initViewState();
expect(view._setViewState).toHaveBeenCalled();
});
});
describe('._updateViewState', function () {
beforeEach(function () {
view = createViewFn();
spyOn(view, '_fetchAllQueryObjects').and.returnValue(Promise.resolve(true));
spyOn(view, '_setViewState').and.callThrough();
});
it('should call _setViewState if isDone', function () {
spyOn(view.model, 'isDone').and.returnValue(true);
view._updateViewState();
expect(view._setViewState).toHaveBeenCalled();
});
it('should call _setViewState after all queries have been fetched', function (done) {
spyOn(view.model, 'isDone').and.returnValue(false);
view._updateViewState();
setTimeout(function () {
expect(view._setViewState).toHaveBeenCalled();
done();
}, 0);
});
});
describe('._setViewState', function () {
beforeEach(function () {
view = createViewFn();
});
describe('set isLayerEmpty', function () {
it('should be setted to true if layer is empty', function (done) {
view.render();
spyOn(view, 'render');
spyOn(view._layerDefinitionModel, 'isEmptyAsync').and.returnValue(Promise.resolve(true));
spyOn(view._layerDefinitionModel, 'canBeGeoreferenced').and.returnValue(Promise.resolve(true));
view._setViewState();
setTimeout(function () {
expect(view._viewState.get('isLayerEmpty')).toEqual(true);
expect(view._viewState.get('canBeGeoreferenced')).toEqual(true);
done();
}, 0);
});
});
describe('set canBeGeoreferenced', function () {
it('should be setted to true if layer can not be georeferenced', function (done) {
view._viewState.set({
isLayerEmpty: true,
canBeGeoreferenced: false
});
view.render();
spyOn(view._layerDefinitionModel, 'isEmptyAsync').and.returnValue(Promise.resolve(true));
spyOn(view._layerDefinitionModel, 'canBeGeoreferenced').and.returnValue(Promise.resolve(true));
view._setViewState();
setTimeout(function () {
expect(view._viewState.get('canBeGeoreferenced')).toEqual(true);
done();
}, 0);
});
it('should be setted to false if layer can be georeferenced', function (done) {
view._viewState.set({
isLayerEmpty: true,
canBeGeoreferenced: true
});
view.render();
spyOn(view._layerDefinitionModel, 'isEmptyAsync').and.returnValue(Promise.resolve(true));
spyOn(view._layerDefinitionModel, 'canBeGeoreferenced').and.returnValue(Promise.resolve(false));
view._setViewState();
setTimeout(function () {
expect(view._viewState.get('canBeGeoreferenced')).toEqual(false);
done();
}, 0);
});
});
describe('set isLayerDone', function () {
// isLayerDone can be false when entering and the UI should respond to that
it('should set isLayerDone when entering the function and again when the promise resolves', function (done) {
view._viewState.set('isLayerDone', true, { silent: true });
spyOn(view._layerDefinitionModel, 'isEmptyAsync').and.returnValue(Promise.resolve(true));
spyOn(view._layerDefinitionModel, 'canBeGeoreferenced').and.returnValue(Promise.resolve(false));
spyOn(view._layerDefinitionModel, 'isDone').and.returnValue(false);
view._setViewState();
expect(view._viewState.get('isLayerDone')).toBe(false);
view._layerDefinitionModel.isDone.and.returnValue(true);
setTimeout(function () {
expect(view._viewState.get('isLayerDone')).toEqual(true);
done();
}, 0);
});
});
});
describe('._renderLayerTabPaneView', function () {
it('should disable all tabs but data is layer is empty', function () {
view = createViewFn();
view._viewState.set({
isLayerEmpty: true,
isLayerDone: true
}, { silent: true });
view._renderLayerTabPaneView();
var tabs = view.$('nav > ul > li');
expect(tabs[0].classList.contains('is-disabled')).toBe(false);
expect(tabs[1].classList.contains('is-disabled')).toBe(true);
expect(tabs[2].classList.contains('is-disabled')).toBe(true);
expect(tabs[3].classList.contains('is-disabled')).toBe(true);
expect(tabs[4].classList.contains('is-disabled')).toBe(true);
});
it('should enable all tabs but data is layer is not empty', function () {
view = createViewFn();
view._viewState.set({
isLayerEmpty: false,
isLayerDone: true
}, { silent: true });
view._renderLayerTabPaneView();
var tabs = view.$('nav > ul > li');
expect(tabs[0].classList.contains('is-disabled')).toBe(false);
expect(tabs[1].classList.contains('is-disabled')).toBe(false);
expect(tabs[2].classList.contains('is-disabled')).toBe(false);
expect(tabs[3].classList.contains('is-disabled')).toBe(false);
expect(tabs[4].classList.contains('is-disabled')).toBe(false);
});
});
describe('._onClickBack', function () {
beforeEach(function () {
view = createViewFn();
view.render();
});
it('should call goToLayerList in Router', function () {
view.$('.js-back').click();
expect(Router.goToLayerList).toHaveBeenCalled();
});
it('should set editorModel edition to false', function () {
editorModel.set('edition', true, { silent: true });
view.$('.js-back').click();
expect(editorModel.get('edition')).toBe(false);
});
});
describe('.handleRoute', function () {
beforeEach(function () {
view = createViewFn();
view.render();
});
it('should create editOverlay', function () {
handleRouteSpy.and.callThrough();
var routeModel = new Backbone.Model({
currentRoute: ['add_feature_']
});
view._handleRoute(routeModel);
expect($(dashboardCanvasEl).find('.js-editOverlay').length).toBe(1);
});
});
describe('._renderContextButtons', function () {
var analysisDefNodeModel;
var layerDefinitionModel;
var queryGeometryModel;
var needsGeoSpy;
var isEmptySpy;
function hasTipsy (subviews) {
var newGeomItems = _.filter(subviews, function (elem) {
return elem.el.classList.contains('js-newGeometryView');
});
if (newGeomItems.length === 0) return false;
return newGeomItems.reduce(function (hasTipsy, btn) {
return btn.tipsy && hasTipsy;
}, true);
}
beforeEach(function () {
view = createViewFn();
view.render();
analysisDefNodeModel = view._getAnalysisDefinitionNodeModel();
layerDefinitionModel = view._layerDefinitionModel;
queryGeometryModel = view._getQueryGeometryModel();
spyOn(analysisDefNodeModel, 'isReadOnly');
needsGeoSpy = spyOn(view._layerDefinitionModel, 'canBeGeoreferenced');
isEmptySpy = spyOn(view._layerDefinitionModel, 'isEmptyAsync');
view._renderContextButtons();
});
afterEach(function () {
view._destroyContextButtons();
});
it('shouldn\'t disable tabs', function () {
needsGeoSpy.and.returnValue(Promise.resolve(false));
isEmptySpy.and.returnValue(Promise.resolve(false));
view.render();
expect(view.$el.find('.CDB-NavMenu-item.is-disabled').length).toBe(0);
});
it('should not create editOverlay tip view', function () {
expect($(dashboardCanvasEl).find('js-editOverlay').length).toBe(0);
});
it('should navigate when click on new geometry', function () {
queryGeometryModel.set('simple_geom', 'point');
analysisDefNodeModel.isReadOnly.and.returnValue(false);
layerDefinitionModel.set('visible', true);
view._renderContextButtons();
$(dashboardCanvasEl).find('.js-newGeometry').trigger('click');
expect(Router.navigate).toHaveBeenCalled();
});
it('should render context switch toggler properly', function () {
expect($(dashboardCanvasEl).find('.Editor-contextSwitcher.js-mapTableView').length).toBe(1);
});
it('should render geometry buttons properly', function () {
expect($(dashboardCanvasEl).find('.Editor-contextSwitcherItem.js-newGeometryItem').length).toBe(3);
});
it('should disable edit geometry buttons when node is read only and visible', function () {
analysisDefNodeModel.isReadOnly.and.returnValue(true);
layerDefinitionModel.set('visible', true);
expect($(dashboardCanvasEl).find('.Editor-contextSwitcherItem.js-newGeometryItem.is-disabled').length).toBe(3);
});
it('should disable edit geometry buttons when node is read only and not visible', function () {
analysisDefNodeModel.isReadOnly.and.returnValue(true);
layerDefinitionModel.set('visible', false);
expect($(dashboardCanvasEl).find('.Editor-contextSwitcherItem.js-newGeometryItem.is-disabled').length).toBe(3);
});
it('should disable edit geometry buttons when node is neither visible nor read only', function () {
analysisDefNodeModel.isReadOnly.and.returnValue(false);
layerDefinitionModel.set('visible', false);
expect($(dashboardCanvasEl).find('.Editor-contextSwitcherItem.js-newGeometryItem.is-disabled').length).toBe(3);
});
it('should not disable edit geometry buttons when node is visible and not read only', function () {
analysisDefNodeModel.isReadOnly.and.returnValue(false);
layerDefinitionModel.set('visible', true);
expect($(dashboardCanvasEl).find('.Editor-contextSwitcherItem.js-newGeometryItem.is-disabled').length).toBe(0);
});
it('should add tipsy subview when not visible or read only', function () {
view.clearSubViews();
analysisDefNodeModel.isReadOnly.and.returnValue(true);
layerDefinitionModel.set('visible', false);
expect(hasTipsy(view._subviews)).toBe(true);
});
it('should not add tipsy subview when not visible or read only', function () {
view.clearSubViews();
analysisDefNodeModel.isReadOnly.and.returnValue(false);
layerDefinitionModel.set('visible', true);
expect(hasTipsy(view._subviews)).toBe(false);
});
it('should display only one button per geometry', function () {
queryGeometryModel.set('simple_geom', 'polygon');
view._renderContextButtons();
expect($(dashboardCanvasEl).find('.Editor-contextSwitcherItem.js-newGeometryItem').length).toBe(1);
});
it('should show the button for the simple_geom type', function () {
queryGeometryModel.set('simple_geom', 'point');
view._renderContextButtons();
expect($(dashboardCanvasEl).find('.js-newGeometry[data-feature-type="point"]').length).toBe(1);
queryGeometryModel.set('simple_geom', 'line');
view._renderContextButtons();
expect($(dashboardCanvasEl).find('.js-newGeometry[data-feature-type="line"]').length).toBe(1);
queryGeometryModel.set('simple_geom', 'polygon');
view._renderContextButtons();
expect($(dashboardCanvasEl).find('.js-newGeometry[data-feature-type="polygon"]').length).toBe(1);
});
});
describe('._initBinds', function () {
function buildResponse (geom) {
return {
status: 200,
contentType: 'application/json; charset=utf-8',
responseText: '{"rows":[{"the_geom":"' + geom + '"}],"time":0.005,"fields":{"the_geom":{"type":"string"}},"total_rows":1}'
};
}
beforeEach(function () {
view = createViewFn();
jasmine.Ajax.install();
});
afterEach(function () {
jasmine.Ajax.uninstall();
});
it('should call _renderContextButtons and set default style properties if there is a change in simple_geom to a valid value', function () {
var queryGeometryModel = view._getQueryGeometryModel();
queryGeometryModel.set('status', 'unfetched');
queryGeometryModel.set('simple_geom', 'point');
queryGeometryModel.set('query', 'SELECT TOP 10 FROM fake_table;');
spyOn(view, '_renderContextButtons');
jasmine.Ajax.stubRequest(/sql/)
.andReturn(buildResponse('polygon'));
view._initBinds();
queryGeometryModel.set('simple_geom', 'polygon');
expect(view._renderContextButtons).toHaveBeenCalled();
});
it('should call _renderContextButtons and not set default style properties if there is a change in simple_geom to nothing', function () {
var queryGeometryModel = view._getQueryGeometryModel();
queryGeometryModel.set('status', 'unfetched');
queryGeometryModel.set('simple_geom', 'point');
queryGeometryModel.set('query', 'SELECT TOP 10 FROM fake_table;');
spyOn(view, '_renderContextButtons');
jasmine.Ajax.stubRequest(/sql/)
.andReturn(buildResponse(''));
view._initBinds();
queryGeometryModel.set('simple_geom', '');
expect(view._renderContextButtons).toHaveBeenCalled();
});
it('should call _onTogglerChanged if togglerModel:active changes', function () {
spyOn(view, '_onTogglerChanged');
view._initBinds();
view._togglerModel.trigger('change:active');
expect(view._onTogglerChanged).toHaveBeenCalled();
});
it('should call handleRoute if routeModel:currentRoute changes', function () {
var routeModel = Router.getRouteModel();
routeModel.trigger('change:currentRoute', routeModel);
expect(view._handleRoute).toHaveBeenCalled();
});
it('should call render if analysisDefinitionNodeModel:error changes', function () {
spyOn(view, 'render');
view._initBinds();
analysisDefinitionNodeModel.trigger('change:error');
expect(view.render).toHaveBeenCalled();
});
it('should call _updateViewState on change model state', function () {
spyOn(view, 'render');
spyOn(view, '_updateViewState');
view._initBinds();
view.model.set('state', 'fake');
expect(view._updateViewState).toHaveBeenCalled();
});
it('should call _updateViewState on change layerDefinitionModel source', function () {
spyOn(view, 'render');
spyOn(view, '_updateViewState');
view._initBinds();
view._layerDefinitionModel.set('source', 'fake');
expect(view._updateViewState).toHaveBeenCalled();
});
}); // end of '._initBinds'
describe('._onTogglerChanged', function () {
beforeEach(function () {
view = createViewFn();
view.render();
});
it('should set context correctly', function () {
expect(view.model.get('context')).toEqual('map');
view._togglerModel.set('active', true, { silent: true });
view._onTogglerChanged();
expect(view.model.get('context')).toEqual('table');
view._togglerModel.set('active', false, { silent: true });
view._onTogglerChanged();
expect(view.model.get('context')).toEqual('map');
});
it('should call _initTable if context is table', function () {
spyOn(view, '_initTable');
view._togglerModel.set('active', true, { silent: true });
view._onTogglerChanged();
expect(view._initTable).toHaveBeenCalled();
});
it('should call _destroyTable if context is map', function () {
spyOn(view, '_destroyTable');
view._togglerModel.set('active', false, { silent: true });
view._onTogglerChanged();
expect(view._destroyTable).toHaveBeenCalled();
});
});
describe('._isContextTable', function () {
beforeEach(function () {
view = createViewFn();
view.render();
});
it('should return true if model context is table', function () {
expect(view._isContextTable()).toBe(false);
view.model.set('context', 'table', { silent: true });
expect(view._isContextTable()).toBe(true);
});
});
describe('when rendering analysis tab', function () {
var addBindingsAndRender = function () {
spyOn(analysisDefinitionNodeModel.querySchemaModel, 'isDone').and.returnValue(true);
spyOn(analysisDefinitionNodeModel.queryGeometryModel, 'isDone').and.returnValue(true);
spyOn(analysisDefinitionNodeModel.queryRowsCollection, 'isDone').and.returnValue(true);
view.render();
};
describe('when analysis payload is a string and its in the formsCollection', function () {
it('should use the analysis payload as selectedNodeId', function () {
var analysisPayload = 'a1';
spyOn(AnalysisFormsCollection.prototype, 'get').and.returnValue(analysisPayload);
view = createViewFn({
selectedTabItem: 'analyses',
analysisPayload: analysisPayload
});
addBindingsAndRender();
var analysesContentView = _.find(view._layerTabPaneView._subviews, function (view) {
return view.className === 'Editor-content';
});
expect(analysesContentView._selectedNodeId).toEqual(analysisPayload);
});
});
describe('when analysis payload is an object', function () {
it('should use the analysis payload id key as selectedNodeId', function () {
var analysisPayload = {
id: 'a2'
};
view = createViewFn({
selectedTabItem: 'analyses',
analysisPayload: analysisPayload
});
addBindingsAndRender();
var analysesContentView = _.find(view._layerTabPaneView._subviews, function (view) {
return view.className === 'Editor-content';
});
expect(analysesContentView._selectedNodeId).toEqual(analysisPayload.id);
});
});
describe('when analysis payload is null', function () {
describe('when last node exists', function () {
it('should redirect to the last node id', function () {
var lastAnalysisNode = new Backbone.Model({
id: 'a1'
});
spyOn(AnalysisFormsCollection.prototype, 'at').and.returnValue(lastAnalysisNode);
spyOn(Router, 'goToAnalysisNode');
view = createViewFn({
selectedTabItem: 'analyses',
analysisPayload: null
});
addBindingsAndRender();
expect(Router.goToAnalysisNode).toHaveBeenCalledWith(
layerDefinitionModel.get('id'),
lastAnalysisNode.get('id'),
{ trigger: false, replace: true }
);
});
});
describe('when there is no nodes left', function () {
it('should redirect to the analysis tab', function () {
spyOn(Router, 'goToAnalysisTab');
view = createViewFn({
selectedTabItem: 'analyses',
analysisPayload: null
});
addBindingsAndRender();
expect(Router.goToAnalysisTab).toHaveBeenCalledWith(
layerDefinitionModel.get('id'),
{ trigger: false, replace: true }
);
});
});
});
});
afterEach(function () {
dashboardCanvasEl.parentNode && dashboardCanvasEl.parentNode.removeChild(dashboardCanvasEl);
view.clean();
});
});