Initial commit
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var ConfigModel = require('builder/data/config-model');
|
||||
var UserModel = require('builder/data/user-model');
|
||||
var AnalysisDefinitionNodesCollection = require('builder/data/analysis-definition-nodes-collection');
|
||||
var LayerDefinitionsCollection = require('builder/data/layer-definitions-collection');
|
||||
var AddWidgetsView = require('builder/components/modals/add-widgets/add-widgets-view');
|
||||
|
||||
describe('components/modals/add-widgets/add-widgets-view', function () {
|
||||
var LOADING_TITLE = 'loading-';
|
||||
var view;
|
||||
var configModel;
|
||||
var userModel;
|
||||
var analysisDefinitionNodesCollection;
|
||||
var layerDefinitionsCollection;
|
||||
var querySchemaModel0;
|
||||
var querySchemaModel1;
|
||||
var querySchemaModel2;
|
||||
var modalModel;
|
||||
|
||||
function createViewFn (options) {
|
||||
var defaultOptions;
|
||||
|
||||
configModel = new ConfigModel({
|
||||
base_url: '/u/pepe'
|
||||
});
|
||||
|
||||
userModel = new UserModel({}, {
|
||||
configModel: configModel
|
||||
});
|
||||
|
||||
analysisDefinitionNodesCollection = new AnalysisDefinitionNodesCollection(null, {
|
||||
configModel: configModel,
|
||||
userModel: userModel
|
||||
});
|
||||
|
||||
layerDefinitionsCollection = new LayerDefinitionsCollection(null, {
|
||||
configModel: configModel,
|
||||
userModel: userModel,
|
||||
analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
|
||||
mapId: 'map-123',
|
||||
stateDefinitionModel: {}
|
||||
});
|
||||
|
||||
analysisDefinitionNodesCollection.add({
|
||||
id: 'a0',
|
||||
type: 'source',
|
||||
query: 'SELECT * FROM table_name'
|
||||
});
|
||||
|
||||
analysisDefinitionNodesCollection.add({
|
||||
id: 'a1',
|
||||
type: 'buffer',
|
||||
radio: 300,
|
||||
source: 'a0'
|
||||
});
|
||||
|
||||
analysisDefinitionNodesCollection.add({
|
||||
id: 'a2',
|
||||
type: 'buffer',
|
||||
radio: 300,
|
||||
source: 'a1'
|
||||
});
|
||||
|
||||
querySchemaModel0 = analysisDefinitionNodesCollection.at(0).querySchemaModel;
|
||||
querySchemaModel1 = analysisDefinitionNodesCollection.at(1).querySchemaModel;
|
||||
querySchemaModel2 = analysisDefinitionNodesCollection.at(2).querySchemaModel;
|
||||
|
||||
querySchemaModel0.set({ status: 'fetched', query: 'SELECT * FROM table_name' });
|
||||
querySchemaModel1.set({ status: 'unavailable' });
|
||||
querySchemaModel2.set({ query: 'SELECT * FROM test' });
|
||||
querySchemaModel2.set({ status: 'fetching' });
|
||||
|
||||
spyOn(querySchemaModel0, 'fetch');
|
||||
spyOn(querySchemaModel1, 'fetch');
|
||||
spyOn(querySchemaModel2, 'fetch');
|
||||
|
||||
modalModel = new Backbone.Model();
|
||||
|
||||
defaultOptions = {
|
||||
modalModel: modalModel,
|
||||
userActions: {
|
||||
saveWidgetOption: function (widgetOptionModels) {
|
||||
return Promise.resolve(widgetOptionModels);
|
||||
},
|
||||
updateWidgetsOrder: function (widgetOptionModels) {
|
||||
return Promise.resolve(widgetOptionModels);
|
||||
},
|
||||
goToEditWidget: function () {}
|
||||
},
|
||||
analysisDefinitionNodesCollection: analysisDefinitionNodesCollection,
|
||||
layerDefinitionsCollection: layerDefinitionsCollection,
|
||||
widgetDefinitionsCollection: new Backbone.Collection()
|
||||
};
|
||||
|
||||
return new AddWidgetsView(_.extend(defaultOptions, options));
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
view = createViewFn();
|
||||
|
||||
view.render();
|
||||
});
|
||||
|
||||
it('should have no leaks', function () {
|
||||
expect(view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
it('should show loading msg until all are fetched', function () {
|
||||
expect(view.$('.js-body').html()).toContain(LOADING_TITLE);
|
||||
});
|
||||
|
||||
describe('when all layer tables are fetched', function () {
|
||||
beforeEach(function () {
|
||||
querySchemaModel2.set('status', 'fetched');
|
||||
});
|
||||
|
||||
it('should render the content view', function () {
|
||||
expect(view.$('.js-body').html()).not.toContain(LOADING_TITLE);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the user clicks on continue', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(view, '_hasFetchedAllQuerySchemas').and.returnValue(true);
|
||||
view.render();
|
||||
});
|
||||
|
||||
it('should call _saveSelectedWidgets if there are selected widgets', function () {
|
||||
var saveSelectedWidgetsSpy = spyOn(view, '_saveSelectedWidgets').and.callThrough();
|
||||
|
||||
view._optionsCollection.add(new Backbone.Model({
|
||||
id: '1',
|
||||
selected: true
|
||||
}));
|
||||
|
||||
view._onContinue();
|
||||
|
||||
expect(saveSelectedWidgetsSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not call _saveSelectedWidgets if there are not selected widgets', function () {
|
||||
var saveSelectedWidgetsSpy = spyOn(view, '_saveSelectedWidgets').and.returnValue(true);
|
||||
|
||||
view._optionsCollection.add(new Backbone.Model({
|
||||
id: '2',
|
||||
selected: false
|
||||
}));
|
||||
|
||||
view._onContinue();
|
||||
|
||||
expect(saveSelectedWidgetsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call user actions to update widgets if the _saveSelectedWidgets succeeds', function (done) {
|
||||
spyOn(view, '_saveSelectedWidgets').and.returnValue(Promise.resolve());
|
||||
spyOn(view._userActions, 'updateWidgetsOrder');
|
||||
spyOn(view._userActions, 'goToEditWidget');
|
||||
|
||||
view._optionsCollection.add(new Backbone.Model({
|
||||
id: '1',
|
||||
selected: true
|
||||
}));
|
||||
|
||||
view._onContinue();
|
||||
|
||||
setTimeout(function () {
|
||||
expect(view._userActions.updateWidgetsOrder).toHaveBeenCalled();
|
||||
expect(view._userActions.goToEditWidget).toHaveBeenCalled();
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('should call user actions to update widgets if the _saveSelectedWidgets fails', function (done) {
|
||||
spyOn(view, '_saveSelectedWidgets').and.returnValue(Promise.reject());
|
||||
spyOn(view._userActions, 'updateWidgetsOrder');
|
||||
spyOn(view._userActions, 'goToEditWidget');
|
||||
|
||||
view._optionsCollection.add(new Backbone.Model({
|
||||
id: '1',
|
||||
selected: true
|
||||
}));
|
||||
|
||||
view._onContinue();
|
||||
|
||||
setTimeout(function () {
|
||||
expect(view._userActions.updateWidgetsOrder).toHaveBeenCalled();
|
||||
expect(view._userActions.goToEditWidget).not.toHaveBeenCalled();
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the selected widgets are selected to be saved', function () {
|
||||
it('should call saveWidgetOption for each selectedOptionModel', function () {
|
||||
var saveWidgetOptionSpy = spyOn(view._userActions, 'saveWidgetOption').and.callThrough();
|
||||
|
||||
var widgetModel_1 = new Backbone.Model({
|
||||
id: '1',
|
||||
selected: true
|
||||
});
|
||||
|
||||
var widgetModel_2 = new Backbone.Model({
|
||||
id: '2',
|
||||
selected: true
|
||||
});
|
||||
|
||||
view._saveSelectedWidgets([widgetModel_1, widgetModel_2]);
|
||||
|
||||
expect(saveWidgetOptionSpy).toHaveBeenCalledWith(widgetModel_1);
|
||||
expect(saveWidgetOptionSpy).toHaveBeenCalledWith(widgetModel_2);
|
||||
});
|
||||
|
||||
it('should return an async response that succeeds if all the widgets can be saved', function (done) {
|
||||
var widgetModel_1 = new Backbone.Model({
|
||||
id: '1',
|
||||
selected: false
|
||||
});
|
||||
|
||||
var widgetModel_2 = new Backbone.Model({
|
||||
id: '2',
|
||||
selected: true
|
||||
});
|
||||
|
||||
view._saveSelectedWidgets([widgetModel_1, widgetModel_2])
|
||||
.then(function (response) {
|
||||
expect(response.length).toEqual(2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an async response that fails if one of the widgets can not be saved', function (done) {
|
||||
var errorResponse = 'Error';
|
||||
|
||||
view = createViewFn({userActions: {
|
||||
saveWidgetOption: function () {
|
||||
return Promise.reject(errorResponse);
|
||||
},
|
||||
updateWidgetsOrder: function () {
|
||||
return Promise.resolve({});
|
||||
},
|
||||
goToEditWidget: function () {}
|
||||
}});
|
||||
|
||||
view.render();
|
||||
|
||||
var widgetModel_1 = new Backbone.Model({
|
||||
id: '1',
|
||||
selected: false
|
||||
});
|
||||
|
||||
var widgetModel_2 = new Backbone.Model({
|
||||
id: '2',
|
||||
selected: true
|
||||
});
|
||||
|
||||
view._saveSelectedWidgets([widgetModel_1, widgetModel_2])
|
||||
.catch(function (response) {
|
||||
expect(response).toEqual(errorResponse);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
var Backbone = require('backbone');
|
||||
var BodyView = require('builder/components/modals/add-widgets/body-view');
|
||||
var WidgetOptionModel = require('builder/components/modals/add-widgets/widget-option-model');
|
||||
var widgetsTypes = require('builder/components/modals/add-widgets/widgets-types');
|
||||
|
||||
describe('components/modals/add-widgets/body-view', function () {
|
||||
beforeEach(function () {
|
||||
var layerDefinitionModel = new Backbone.Model();
|
||||
layerDefinitionModel.getColor = function () { return '#fabada'; };
|
||||
layerDefinitionModel.getName = function () { return 'layer'; };
|
||||
layerDefinitionModel.getTableName = function () { return 'table_name'; };
|
||||
|
||||
var analysisDefinitionNodeModel = new Backbone.Model({
|
||||
id: 'a1'
|
||||
});
|
||||
analysisDefinitionNodeModel.isSourceType = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
var tuples = [{
|
||||
columnModel: new Backbone.Model(),
|
||||
analysisDefinitionNodeModel: analysisDefinitionNodeModel,
|
||||
layerDefinitionModel: layerDefinitionModel
|
||||
}];
|
||||
this.optionsCollection = new Backbone.Collection([
|
||||
new WidgetOptionModel({
|
||||
type: 'category',
|
||||
layer_index: 0,
|
||||
tuples: tuples
|
||||
}),
|
||||
new WidgetOptionModel({
|
||||
type: 'histogram',
|
||||
layer_index: 0,
|
||||
tuples: tuples
|
||||
}),
|
||||
new WidgetOptionModel({
|
||||
type: 'formula',
|
||||
layer_index: 0,
|
||||
tuples: tuples
|
||||
}),
|
||||
new WidgetOptionModel({
|
||||
type: 'time-series',
|
||||
layer_index: 0,
|
||||
tuples: tuples
|
||||
})
|
||||
]);
|
||||
|
||||
this.view = new BodyView({
|
||||
optionsCollection: this.optionsCollection,
|
||||
widgetsTypes: widgetsTypes
|
||||
});
|
||||
this.view = this.view.render();
|
||||
});
|
||||
|
||||
it('should have no leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
it('should render fine', function () {
|
||||
expect(this.view).toBeDefined();
|
||||
});
|
||||
|
||||
it('should create tab pane items when there is at least one option of that type', function () {
|
||||
expect(this.view.$el.html()).toContain('formula');
|
||||
expect(this.view.$el.html()).toContain('category');
|
||||
expect(this.view.$el.html()).toContain('histogram');
|
||||
expect(this.view.$el.html()).toContain('time-series');
|
||||
});
|
||||
});
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var CategoryOptionModel = require('builder/components/modals/add-widgets/category/category-option-model');
|
||||
|
||||
describe('components/modals/add-widgets/category/category-option-model', function () {
|
||||
var model;
|
||||
var defaultOptions;
|
||||
var widgetDefinitionsCollection;
|
||||
var layerDefinitionModel;
|
||||
var analysisDefinitionNodeModel;
|
||||
var defaultTuples;
|
||||
var columnModel;
|
||||
|
||||
var createModelFn = function (options, optionsTuples) {
|
||||
widgetDefinitionsCollection = new Backbone.Collection({});
|
||||
|
||||
widgetDefinitionsCollection.addWidget = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
layerDefinitionModel = new Backbone.Model({
|
||||
id: 'layerDefinitionModel1',
|
||||
style: new Backbone.Model()
|
||||
});
|
||||
|
||||
columnModel = new Backbone.Model({
|
||||
name: 'line'
|
||||
});
|
||||
|
||||
analysisDefinitionNodeModel = new Backbone.Model({
|
||||
id: 'analysesDefinitionNodeModel1'
|
||||
});
|
||||
|
||||
defaultTuples = [{
|
||||
columnModel: columnModel,
|
||||
layerDefinitionModel: layerDefinitionModel,
|
||||
analysisDefinitionNodeModel: analysisDefinitionNodeModel
|
||||
}];
|
||||
|
||||
defaultOptions = {
|
||||
layer_index: '0',
|
||||
title: 'default-title',
|
||||
tuples: _.extend(defaultTuples, optionsTuples)
|
||||
};
|
||||
|
||||
return new CategoryOptionModel(_.extend(defaultOptions, options));
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
model = createModelFn();
|
||||
});
|
||||
|
||||
it('should have a "category" type by default', function () {
|
||||
expect(model.get('type')).toEqual('category');
|
||||
});
|
||||
|
||||
it('should return the result of the "addWidget" function from the given widgetDefinitionsCollection', function () {
|
||||
var addWidgetSpy = spyOn(widgetDefinitionsCollection, 'addWidget').and.returnValue(true);
|
||||
|
||||
model.save(widgetDefinitionsCollection);
|
||||
|
||||
expect(addWidgetSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
var _ = require('underscore');
|
||||
var ConfigModel = require('builder/data/config-model');
|
||||
var UserModel = require('builder/data/user-model');
|
||||
var AnalysisDefinitionNodesCollection = require('builder/data/analysis-definition-nodes-collection');
|
||||
var LayerDefinitionsCollection = require('builder/data/layer-definitions-collection');
|
||||
var createTuplesItems = require('builder/components/modals/add-widgets/create-tuples-items');
|
||||
|
||||
describe('components/modals/add-widgets/create-tuples-items', function () {
|
||||
beforeEach(function () {
|
||||
var configModel = new ConfigModel({
|
||||
base_url: '/u/pepe'
|
||||
});
|
||||
|
||||
var userModel = new UserModel({}, {
|
||||
configModel: configModel
|
||||
});
|
||||
|
||||
this.analysisDefinitionNodesCollection = new AnalysisDefinitionNodesCollection(null, {
|
||||
configModel: configModel,
|
||||
userModel: userModel
|
||||
});
|
||||
|
||||
this.analysisDefinitionNodesCollection.add({
|
||||
id: 'a0',
|
||||
type: 'source',
|
||||
query: 'SELECT * FROM table_name'
|
||||
});
|
||||
|
||||
this.analysisDefinitionNodesCollection.add({
|
||||
id: 'b0',
|
||||
type: 'source',
|
||||
query: 'SELECT * FROM table_name_two'
|
||||
});
|
||||
|
||||
this.analysisDefinitionNodesCollection.add({
|
||||
id: 'a1',
|
||||
type: 'buffer',
|
||||
radio: 300,
|
||||
source: 'a0'
|
||||
});
|
||||
|
||||
this.analysisDefinitionNodesCollection.add({
|
||||
id: 'b1',
|
||||
type: 'buffer',
|
||||
radio: 300,
|
||||
source: 'a1'
|
||||
});
|
||||
|
||||
this.analysisDefinitionNodesCollection.add({
|
||||
id: 'secondary_source', // created when selecting secondary nodes, so technically orphaned if not used later.
|
||||
type: 'source',
|
||||
query: 'SELECT * FROM secondary_source'
|
||||
});
|
||||
|
||||
this.layerDefinitionsCollection = new LayerDefinitionsCollection([
|
||||
{
|
||||
id: 'l0',
|
||||
kind: 'tiled'
|
||||
}, {
|
||||
id: 'l1',
|
||||
kind: 'carto',
|
||||
options: {
|
||||
table_name: 'foo_table'
|
||||
}
|
||||
}, {
|
||||
id: 'l2',
|
||||
kind: 'carto',
|
||||
options: {
|
||||
table_name: 'bar_table'
|
||||
}
|
||||
}
|
||||
], {
|
||||
configModel: configModel,
|
||||
userModel: userModel,
|
||||
analysisDefinitionNodesCollection: this.analysisDefinitionNodesCollection,
|
||||
mapId: 'm-123',
|
||||
stateDefinitionModel: {}
|
||||
});
|
||||
|
||||
var a1 = this.analysisDefinitionNodesCollection.get('a1');
|
||||
a1.querySchemaModel.columnsCollection.reset([
|
||||
{
|
||||
name: 'cartodb_id',
|
||||
type: 'number'
|
||||
}, {
|
||||
name: 'county_name',
|
||||
type: 'string'
|
||||
}, {
|
||||
name: 'the_geom',
|
||||
type: 'geom'
|
||||
}, {
|
||||
name: 'the_geom_webmercator',
|
||||
type: 'geom'
|
||||
}, {
|
||||
name: 'pop_count',
|
||||
type: 'number'
|
||||
}, {
|
||||
name: 'created_at',
|
||||
type: 'date'
|
||||
}, {
|
||||
name: 'updated_at',
|
||||
type: 'date'
|
||||
}
|
||||
]);
|
||||
|
||||
var b1 = this.analysisDefinitionNodesCollection.get('b1');
|
||||
b1.querySchemaModel.columnsCollection.reset([
|
||||
{
|
||||
name: 'cartodb_id',
|
||||
type: 'number'
|
||||
}, {
|
||||
name: 'pop_count',
|
||||
type: 'number'
|
||||
}
|
||||
]);
|
||||
|
||||
var secondary = this.analysisDefinitionNodesCollection.get('secondary_source');
|
||||
secondary.querySchemaModel.columnsCollection.reset([
|
||||
{
|
||||
name: 'only_for_secondary',
|
||||
type: 'number'
|
||||
}
|
||||
]);
|
||||
|
||||
a1.queryGeometryModel.isDone = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
a1.queryGeometryModel.set('simple_geom', true);
|
||||
|
||||
b1.queryGeometryModel.isDone = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
b1.queryGeometryModel.set('simple_geom', true);
|
||||
|
||||
this.tuplesItems = createTuplesItems(this.analysisDefinitionNodesCollection, this.layerDefinitionsCollection);
|
||||
});
|
||||
|
||||
it('should return an object', function () {
|
||||
expect(this.tuplesItems).toEqual(jasmine.any(Object));
|
||||
});
|
||||
|
||||
it('should contain an item for each column name+type match', function () {
|
||||
expect(this.tuplesItems['county_name-string'].length).toEqual(1);
|
||||
expect(this.tuplesItems['pop_count-number'].length).toEqual(2);
|
||||
});
|
||||
|
||||
it('should not add items for blacklisted columns', function () {
|
||||
var keys = _.keys(this.tuplesItems).toString();
|
||||
expect(keys).not.toContain('the_geom');
|
||||
expect(keys).not.toContain('the_geom_webmercator');
|
||||
expect(keys).not.toContain('created_at');
|
||||
expect(keys).not.toContain('updated_at');
|
||||
});
|
||||
|
||||
it('should not contain a tuple when no geometry data', function () {
|
||||
var b1 = this.analysisDefinitionNodesCollection.get('b1');
|
||||
|
||||
b1.queryGeometryModel.isDone = function () {
|
||||
return false;
|
||||
};
|
||||
|
||||
b1.queryGeometryModel.set('simple_geom', false);
|
||||
|
||||
this.tuplesItems = createTuplesItems(this.analysisDefinitionNodesCollection, this.layerDefinitionsCollection);
|
||||
|
||||
var tuples = this.tuplesItems['pop_count-number'];
|
||||
expect(tuples.length).toBe(1);
|
||||
expect(tuples[0].layerDefinitionModel.id).toEqual('l1');
|
||||
});
|
||||
|
||||
it('should contain a tuple of column+layer definition in each item', function () {
|
||||
var tuples = this.tuplesItems['pop_count-number'];
|
||||
|
||||
expect(tuples[0].columnModel).toBeDefined();
|
||||
expect(tuples[0].columnModel.get('name')).toEqual('pop_count');
|
||||
expect(tuples[0].layerDefinitionModel.id).toEqual('l1');
|
||||
|
||||
expect(tuples[1].columnModel).toBeDefined();
|
||||
expect(tuples[1].columnModel.get('name')).toEqual('pop_count');
|
||||
expect(tuples[1].layerDefinitionModel.id).toEqual('l2');
|
||||
});
|
||||
|
||||
it('should skip nodes that does not have an owning layer', function () {
|
||||
for (var columnName in this.tuplesItems) {
|
||||
var tuples = this.tuplesItems[columnName];
|
||||
tuples.forEach(function (tuple) {
|
||||
expect(tuple.columnModel).toBeDefined('a tuple for ' + columnName + ' is missing columnModel');
|
||||
expect(tuple.layerDefinitionModel).toBeDefined('a tuple for ' + columnName + ' is missing layerDefinitionModel');
|
||||
expect(tuple.analysisDefinitionNodeModel).toBeDefined('a tuple for ' + columnName + ' is missing analysisDefinitionModel');
|
||||
}, this);
|
||||
}
|
||||
});
|
||||
});
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var FormulaOptionModel = require('builder/components/modals/add-widgets/formula/formula-option-model');
|
||||
|
||||
describe('components/modals/add-widgets/formula/formula-option-model', function () {
|
||||
var model;
|
||||
var defaultOptions;
|
||||
var widgetDefinitionsCollection;
|
||||
var layerDefinitionModel;
|
||||
var analysisDefinitionNodeModel;
|
||||
var defaultTuples;
|
||||
var columnModel;
|
||||
|
||||
var createModelFn = function (options, optionsTuples) {
|
||||
widgetDefinitionsCollection = new Backbone.Collection({});
|
||||
|
||||
widgetDefinitionsCollection.addWidget = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
layerDefinitionModel = new Backbone.Model({
|
||||
id: 'layerDefinitionModel1',
|
||||
style: new Backbone.Model()
|
||||
});
|
||||
|
||||
columnModel = new Backbone.Model({
|
||||
name: 'line'
|
||||
});
|
||||
|
||||
analysisDefinitionNodeModel = new Backbone.Model({
|
||||
id: 'analysesDefinitionNodeModel1'
|
||||
});
|
||||
|
||||
defaultTuples = [{
|
||||
columnModel: columnModel,
|
||||
layerDefinitionModel: layerDefinitionModel,
|
||||
analysisDefinitionNodeModel: analysisDefinitionNodeModel
|
||||
}];
|
||||
|
||||
defaultOptions = {
|
||||
layer_index: '0',
|
||||
title: 'default-title',
|
||||
tuples: _.extend(defaultTuples, optionsTuples)
|
||||
};
|
||||
|
||||
return new FormulaOptionModel(_.extend(defaultOptions, options));
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
model = createModelFn();
|
||||
});
|
||||
|
||||
it('should have a "formula" type by default', function () {
|
||||
expect(model.get('type')).toEqual('formula');
|
||||
});
|
||||
|
||||
it('should return the result of the "addWidget" function from the given widgetDefinitionsCollection', function () {
|
||||
var addWidgetSpy = spyOn(widgetDefinitionsCollection, 'addWidget').and.returnValue(true);
|
||||
|
||||
model.save(widgetDefinitionsCollection);
|
||||
|
||||
expect(addWidgetSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var HistogramOptionModel = require('builder/components/modals/add-widgets/histogram/histogram-option-model');
|
||||
|
||||
describe('components/modals/add-widgets/histogram/histogram-option-model', function () {
|
||||
var model;
|
||||
var defaultOptions;
|
||||
var widgetDefinitionsCollection;
|
||||
var layerDefinitionModel;
|
||||
var analysisDefinitionNodeModel;
|
||||
var defaultTuples;
|
||||
var columnModel;
|
||||
|
||||
var createModelFn = function (options, optionsTuples) {
|
||||
widgetDefinitionsCollection = new Backbone.Collection({});
|
||||
|
||||
widgetDefinitionsCollection.addWidget = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
layerDefinitionModel = new Backbone.Model({
|
||||
id: 'layerDefinitionModel1',
|
||||
style: new Backbone.Model()
|
||||
});
|
||||
|
||||
columnModel = new Backbone.Model({
|
||||
name: 'line'
|
||||
});
|
||||
|
||||
analysisDefinitionNodeModel = new Backbone.Model({
|
||||
id: 'analysesDefinitionNodeModel1'
|
||||
});
|
||||
|
||||
defaultTuples = [{
|
||||
columnModel: columnModel,
|
||||
layerDefinitionModel: layerDefinitionModel,
|
||||
analysisDefinitionNodeModel: analysisDefinitionNodeModel
|
||||
}];
|
||||
|
||||
defaultOptions = {
|
||||
layer_index: '0',
|
||||
title: 'default-title',
|
||||
tuples: _.extend(defaultTuples, optionsTuples)
|
||||
};
|
||||
|
||||
return new HistogramOptionModel(_.extend(defaultOptions, options));
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
model = createModelFn();
|
||||
});
|
||||
|
||||
it('should have a "histogram" type by default', function () {
|
||||
expect(model.get('type')).toEqual('histogram');
|
||||
});
|
||||
|
||||
it('should return the result of the "addWidget" function from the given widgetDefinitionsCollection', function () {
|
||||
var addWidgetSpy = spyOn(widgetDefinitionsCollection, 'addWidget').and.returnValue(true);
|
||||
|
||||
model.save(widgetDefinitionsCollection);
|
||||
|
||||
expect(addWidgetSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
var LayerSelectorView = require('builder/components/modals/add-widgets/layer-selector-view');
|
||||
|
||||
describe('components/modals/add-widgets/layer-selector-view', function () {
|
||||
var $el;
|
||||
|
||||
beforeEach(function () {
|
||||
$el = $('<div class="js-WidgetList-item"></div>');
|
||||
|
||||
this.columnModel1 = new Backbone.Model({
|
||||
name: 'col',
|
||||
type: 'string'
|
||||
});
|
||||
this.analysisDefinitionModel1 = new Backbone.Model({ id: 'a1' });
|
||||
this.analysisDefinitionModel2 = new Backbone.Model({ id: 'a2' });
|
||||
this.analysisDefinitionModel1.isSourceType = this.analysisDefinitionModel2.isSourceType = function () {
|
||||
return true;
|
||||
};
|
||||
this.layerDefinitionModel1 = new Backbone.Model({
|
||||
table_name: 'foo'
|
||||
});
|
||||
this.columnModel2 = new Backbone.Model({
|
||||
name: 'col',
|
||||
type: 'string'
|
||||
});
|
||||
this.layerDefinitionModel2 = new Backbone.Model({
|
||||
table_name: 'bar'
|
||||
});
|
||||
this.layerDefinitionModel1.getColor = this.layerDefinitionModel2.getColor = function () {
|
||||
return '#fabada';
|
||||
};
|
||||
this.layerDefinitionModel1.getName = this.layerDefinitionModel2.getName = function () {
|
||||
return this.get('table_name');
|
||||
};
|
||||
this.layerDefinitionModel1.getTableName = this.layerDefinitionModel2.getTableName = function () {
|
||||
return this.get('table_name');
|
||||
};
|
||||
|
||||
this.model = new Backbone.Model({
|
||||
layer_index: 0,
|
||||
tuples: [{
|
||||
columnModel: this.columnModel1,
|
||||
layerDefinitionModel: this.layerDefinitionModel1,
|
||||
analysisDefinitionNodeModel: this.analysisDefinitionModel1
|
||||
}, {
|
||||
columnModel: this.columnModel2,
|
||||
layerDefinitionModel: this.layerDefinitionModel2,
|
||||
analysisDefinitionNodeModel: this.analysisDefinitionModel2
|
||||
}]
|
||||
});
|
||||
|
||||
this.view = new LayerSelectorView({
|
||||
model: this.model
|
||||
});
|
||||
this.view = this.view.render();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
$el.remove();
|
||||
});
|
||||
|
||||
it('should have no leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
it('should render table name and node id in the selected item', function () {
|
||||
expect(this.view).toBeDefined();
|
||||
expect(this.view.$el.html()).toContain('foo');
|
||||
expect(this.view.$el.html()).toContain('a1');
|
||||
});
|
||||
|
||||
it('should render table name and node id in the custom list items', function () {
|
||||
this.view._selectView._onButtonClick();
|
||||
var customList = this.view.$('.js-list').html();
|
||||
|
||||
expect(customList).toContain('foo');
|
||||
expect(customList).toContain('a1');
|
||||
expect(customList).toContain('bar');
|
||||
expect(customList).toContain('a2');
|
||||
});
|
||||
|
||||
it('should change the selected item', function () {
|
||||
expect(this.model.get('layer_index')).toEqual(0);
|
||||
});
|
||||
|
||||
it('should stop event propagation when element is clicked', function () {
|
||||
var eventMock = {
|
||||
stopPropagation: jasmine.createSpy()
|
||||
};
|
||||
|
||||
this.view._onClick(eventMock);
|
||||
|
||||
expect(eventMock.stopPropagation).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('when a new option is selected', function () {
|
||||
beforeEach(function () {
|
||||
this.view._selectView.setValue(1);
|
||||
this.view._selectView.trigger('change');
|
||||
});
|
||||
|
||||
it('should change the selected item', function () {
|
||||
expect(this.model.get('layer_index')).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onMouseOver', function () {
|
||||
it('should set highlighted to true', function () {
|
||||
expect(this.view._stateModel.get('highlighted')).toBe(false);
|
||||
|
||||
this.view._onMouseOver();
|
||||
|
||||
expect(this.view._stateModel.get('highlighted')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onMouseOut', function () {
|
||||
it('should set highlighted to false', function () {
|
||||
this.view._stateModel.set({ highlighted: true }, { silent: true });
|
||||
|
||||
this.view._onMouseOut();
|
||||
|
||||
expect(this.view._stateModel.get('highlighted')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._toggleHover', function () {
|
||||
it('should toggle highlighted', function () {
|
||||
$el.append(this.view.el);
|
||||
|
||||
this.view._stateModel.set('highlighted', true, { silent: true });
|
||||
this.view._toggleHover();
|
||||
|
||||
expect($el.hasClass('is-hover')).toBe(true);
|
||||
|
||||
this.view._stateModel.set('highlighted', false, { silent: true });
|
||||
this.view._toggleHover();
|
||||
|
||||
expect($el.hasClass('is-hover')).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var TimeSeriesOptionModel = require('builder/components/modals/add-widgets/time-series/time-series-option-model');
|
||||
|
||||
describe('components/modals/add-widgets/time-series/time-series-option-model', function () {
|
||||
var model;
|
||||
var defaultOptions;
|
||||
var widgetDefinitionsCollection;
|
||||
var layerDefinitionModel;
|
||||
var analysisDefinitionNodeModel;
|
||||
var defaultTuples;
|
||||
var columnModel;
|
||||
|
||||
var createModelFn = function (options, optionsTuples) {
|
||||
widgetDefinitionsCollection = new Backbone.Collection({});
|
||||
|
||||
widgetDefinitionsCollection.addWidget = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
layerDefinitionModel = new Backbone.Model({
|
||||
id: 'layerDefinitionModel1',
|
||||
style: new Backbone.Model()
|
||||
});
|
||||
|
||||
columnModel = new Backbone.Model({
|
||||
name: 'line'
|
||||
});
|
||||
|
||||
analysisDefinitionNodeModel = new Backbone.Model({
|
||||
id: 'analysesDefinitionNodeModel1'
|
||||
});
|
||||
|
||||
defaultTuples = [{
|
||||
columnModel: columnModel,
|
||||
layerDefinitionModel: layerDefinitionModel,
|
||||
analysisDefinitionNodeModel: analysisDefinitionNodeModel
|
||||
}];
|
||||
|
||||
defaultOptions = {
|
||||
layer_index: '0',
|
||||
title: 'default-title',
|
||||
tuples: _.extend(defaultTuples, optionsTuples)
|
||||
};
|
||||
|
||||
return new TimeSeriesOptionModel(_.extend(defaultOptions, options));
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
model = createModelFn();
|
||||
});
|
||||
|
||||
it('should have a "time-series" type by default', function () {
|
||||
expect(model.get('type')).toEqual('time-series');
|
||||
});
|
||||
|
||||
it('should return the result of the "addWidget" function from the given widgetDefinitionsCollection', function () {
|
||||
var addWidgetSpy = spyOn(widgetDefinitionsCollection, 'addWidget').and.returnValue(true);
|
||||
|
||||
model.save(widgetDefinitionsCollection);
|
||||
|
||||
expect(addWidgetSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var widgetsTypes = require('builder/components/modals/add-widgets/widgets-types');
|
||||
var TimeSeriesNoneOptionModel = require('builder/components/modals/add-widgets/time-series/time-series-none-option-model');
|
||||
|
||||
describe('components/modals/add-widgets/widgets-types', function () {
|
||||
describe('all items', function () {
|
||||
it('should have a type prop', function () {
|
||||
widgetsTypes.forEach(function (d) {
|
||||
expect(d.type).toMatch(/\w+/);
|
||||
});
|
||||
});
|
||||
|
||||
it('should have a createTabPaneItem method', function () {
|
||||
widgetsTypes.forEach(function (d) {
|
||||
expect(d.createTabPaneItem).toEqual(jasmine.any(Function));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('times-series', function () {
|
||||
beforeEach(function () {
|
||||
this.d = _.find(widgetsTypes, function (d) {
|
||||
return d.type === 'time-series';
|
||||
});
|
||||
});
|
||||
|
||||
describe('.createOptionModels', function () {
|
||||
it('should always create a none-option even if there are no tuples items', function () {
|
||||
var widgetDefinitionsCollection = new Backbone.Collection();
|
||||
var models = this.d.createOptionModels([], widgetDefinitionsCollection);
|
||||
expect(models.length).toEqual(1);
|
||||
expect(models[0]).toEqual(jasmine.any(TimeSeriesNoneOptionModel));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user