Initial commit
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
var Backbone = require('backbone');
|
||||
var FactoryModals = require('../../../factories/modals');
|
||||
var EditorHelpers = require('builder/components/form-components/helpers/editor');
|
||||
|
||||
function dispatchDocumentEvent (type, opts) {
|
||||
var e = document.createEvent('HTMLEvents');
|
||||
e.initEvent(type, false, true);
|
||||
if (opts.which) {
|
||||
e.which = opts.which;
|
||||
}
|
||||
document.dispatchEvent(e, opts);
|
||||
}
|
||||
|
||||
describe('components/form-components/editors/base', function () {
|
||||
var view;
|
||||
|
||||
beforeEach(function () {
|
||||
view = new Backbone.Form.editors.Base();
|
||||
view.options = {
|
||||
validators: ['required']
|
||||
};
|
||||
|
||||
document.body.appendChild(view.el);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
var parent = view.el.parentNode;
|
||||
parent && parent.removeChild(view.el);
|
||||
view.remove();
|
||||
});
|
||||
|
||||
it('should take default validation', function () {
|
||||
EditorHelpers.setOptions(view, {
|
||||
schema: {
|
||||
min: 0,
|
||||
max: 10,
|
||||
step: 1,
|
||||
showSlider: true
|
||||
}
|
||||
});
|
||||
expect(view.options.validators.length).toBe(1);
|
||||
expect(view.options.validators[0]).toBe('required');
|
||||
});
|
||||
|
||||
it('should take opts validation plus the default one', function () {
|
||||
EditorHelpers.setOptions(view, {
|
||||
schema: {
|
||||
validators: [{
|
||||
type: 'regexp',
|
||||
regexp: /^[0-9]*\.?[0-9]*$/,
|
||||
message: 'Must be valid'
|
||||
}]
|
||||
}
|
||||
});
|
||||
expect(view.options.validators.length).toBe(2);
|
||||
expect(view.options.validators[0].type).toBe('regexp');
|
||||
expect(view.options.validators[1]).toBe('required');
|
||||
});
|
||||
|
||||
describe('document click and escape binding', function () {
|
||||
beforeEach(function () {
|
||||
this.modals = FactoryModals.createModalService();
|
||||
});
|
||||
|
||||
it('without modals set', function () {
|
||||
var cb = jasmine.createSpy('cb');
|
||||
view.applyClickOutsideBind(cb);
|
||||
|
||||
dispatchDocumentEvent('click', { target: 'body' });
|
||||
expect(cb).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('with some modal open', function () {
|
||||
var clickCB = jasmine.createSpy('clickCB');
|
||||
var escCB = jasmine.createSpy('escCB');
|
||||
|
||||
EditorHelpers.setOptions(view, {
|
||||
modals: this.modals
|
||||
});
|
||||
|
||||
view.applyClickOutsideBind(clickCB);
|
||||
view.applyESCBind(escCB);
|
||||
|
||||
this.modals.set('open', true);
|
||||
dispatchDocumentEvent('click', { target: 'body' });
|
||||
expect(clickCB).not.toHaveBeenCalled();
|
||||
|
||||
dispatchDocumentEvent('keydown', { which: 27 });
|
||||
expect(escCB).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('without any modal open', function () {
|
||||
var clickCB = jasmine.createSpy('clickCB');
|
||||
var escCB = jasmine.createSpy('escCB');
|
||||
|
||||
EditorHelpers.setOptions(view, {
|
||||
modals: this.modals
|
||||
});
|
||||
|
||||
view.applyClickOutsideBind(clickCB);
|
||||
view.applyESCBind(escCB);
|
||||
|
||||
this.modals.set('open', false);
|
||||
dispatchDocumentEvent('click', { target: 'body' });
|
||||
expect(clickCB).toHaveBeenCalled();
|
||||
|
||||
dispatchDocumentEvent('keydown', { which: 27 });
|
||||
expect(escCB).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
var Backbone = require('backbone');
|
||||
var _ = require('underscore');
|
||||
var AnalysisDefinitionNodeModel = require('builder/data/analysis-definition-node-model');
|
||||
var MeasurementModel = require('builder/data/data-observatory/measurement-model');
|
||||
|
||||
describe('components/form-components/editors/data-observatory-measurements/data-observatory-measurements-view', function () {
|
||||
var createViewFn = function (options) {
|
||||
var configModel = new Backbone.Model({
|
||||
base_url: '/u/foo',
|
||||
user_name: 'foo',
|
||||
sql_api_template: 'foo',
|
||||
api_key: 'foo'
|
||||
});
|
||||
|
||||
this.nodeDefModel = new AnalysisDefinitionNodeModel({
|
||||
id: 'a1',
|
||||
type: 'data-observatory-multiple-measures',
|
||||
final_column: 'foo',
|
||||
source: 'a0'
|
||||
}, {
|
||||
configModel: configModel,
|
||||
collection: new Backbone.Collection()
|
||||
});
|
||||
|
||||
this.querySchemaModel = new Backbone.Model({
|
||||
query: 'select * from wadus'
|
||||
});
|
||||
|
||||
this.nodeDefModel.querySchemaModel = this.querySchemaModel;
|
||||
|
||||
this.model = new Backbone.Model({
|
||||
measurements: 'us.census.acs.B01001002'
|
||||
});
|
||||
|
||||
this.measurementModel = new MeasurementModel({}, {
|
||||
configModel: configModel,
|
||||
nodeDefModel: this.nodeDefModel
|
||||
});
|
||||
|
||||
var defaultOptions = {
|
||||
key: 'measurements',
|
||||
model: this.model,
|
||||
configModel: configModel,
|
||||
nodeDefModel: this.nodeDefModel,
|
||||
measurementModel: this.measurementModel,
|
||||
region: 'wadus'
|
||||
};
|
||||
|
||||
this.view = new Backbone.Form.editors.DataObservatoryDropdown(_.extend(defaultOptions, options));
|
||||
this.view.render();
|
||||
this.dialog = this.view._dialogView;
|
||||
|
||||
spyOn(this.view.filtersCollection.SQL, 'execute').and.callFake(function (query, vars, params) {
|
||||
var payload = {
|
||||
rows: [
|
||||
{
|
||||
subsection_id: 'subsection/tags.age_gender',
|
||||
subsection_name: 'Age and Gender'
|
||||
},
|
||||
{
|
||||
subsection_id: 'subsection/us.census.acs.segments',
|
||||
subsection_name: 'US Population Segments'
|
||||
},
|
||||
{
|
||||
subsection_id: 'subsection/tags.housing',
|
||||
subsection_name: 'Housing'
|
||||
},
|
||||
{
|
||||
subsection_id: 'subsection/us.zillow.indexes',
|
||||
subsection_name: 'Zillow Home Value and Rental Indexes'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
params && params.success(payload);
|
||||
});
|
||||
|
||||
spyOn(this.view.measurementsCollection.SQL, 'execute').and.callFake(function (query, vars, params) {
|
||||
var payload = {
|
||||
rows: [
|
||||
{
|
||||
numer_id: 'us.zillow.AllHomes_Zhvi',
|
||||
numer_name: 'Zillow Home Value Index for All homes',
|
||||
numer_tags: '{"subsection/tags.housing": "Housing", "license/us.zillow.zillow-license": "Zillow Terms of Use for Aggregate Data"}'
|
||||
},
|
||||
{
|
||||
numer_id: 'us.census.acs.B19083001',
|
||||
numer_name: 'Gini Index',
|
||||
numer_tags: '{"subsection/tags.age_gender": "Age and Gender", "license/tags.no-restrictions": "Unrestricted"}'
|
||||
},
|
||||
{
|
||||
numer_id: 'us.census.acs.B01001002',
|
||||
numer_name: 'Male Population',
|
||||
numer_tags: '{"subsection/tags.age_gender": "Age and Gender", "license/tags.no-restrictions": "Unrestricted"}'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
params && params.success(payload);
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
this.createView = createViewFn.bind(this);
|
||||
});
|
||||
|
||||
it('should genereate an measurements and filters collections', function () {
|
||||
this.createView();
|
||||
|
||||
expect(this.view.measurementsCollection).toBeDefined();
|
||||
expect(this.view.filtersCollection).toBeDefined();
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('should render properly', function () {
|
||||
this.createView();
|
||||
|
||||
this.view.measurementsCollection.fetch();
|
||||
this.view.measurementsCollection.getItem('us.census.acs.B01001002').set({ selected: true });
|
||||
|
||||
expect(this.view.$('.js-button').length).toBe(1);
|
||||
expect(this.view.$('.js-button').text()).toContain('Male Population');
|
||||
expect(this.view.$('.js-button').attr('title')).toBe('Male Population');
|
||||
|
||||
this.view.measurementsCollection.getItem('us.census.acs.B19083001').set({ selected: true });
|
||||
expect(this.view.$('.js-button').text()).toContain('Gini Index');
|
||||
expect(this.view.$('.js-button').attr('title')).toBe('Gini Index');
|
||||
});
|
||||
|
||||
it('should render custom placeholder if provided and no selected', function () {
|
||||
this.createView({
|
||||
placeholder: 'wadus'
|
||||
});
|
||||
|
||||
this.model.set('measurements', '');
|
||||
this.view.render();
|
||||
|
||||
expect(this.view.$('.js-button').length).toBe(1);
|
||||
expect(this.view.$('.js-button').text()).toContain('wadus');
|
||||
});
|
||||
|
||||
it('should disable the component if option is true', function () {
|
||||
this.createView();
|
||||
this.view.options.disabled = true;
|
||||
this.view.render();
|
||||
|
||||
expect(this.view.$('.js-button').hasClass('is-disabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should add is-empty class if there is no value selected', function () {
|
||||
this.createView();
|
||||
|
||||
this.view.render();
|
||||
expect(this.view.$('.js-button').hasClass('is-empty')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getValue', function () {
|
||||
it('should return item selected if any', function () {
|
||||
this.createView();
|
||||
|
||||
this.view.measurementsCollection.fetch();
|
||||
this.view.measurementsCollection.getItem('us.zillow.AllHomes_Zhvi').set({ selected: true });
|
||||
var value = this.view.getValue();
|
||||
expect(value).toBe('us.zillow.AllHomes_Zhvi');
|
||||
});
|
||||
|
||||
it('should return value if no item selected', function () {
|
||||
this.createView();
|
||||
|
||||
this.measurementModel.set({
|
||||
val: 'us.census.acs.B01001002'
|
||||
});
|
||||
|
||||
var value = this.view.getValue();
|
||||
expect(value).toBe('us.census.acs.B01001002');
|
||||
});
|
||||
});
|
||||
|
||||
it('should change button value and hide dialog when a new item is selected', function () {
|
||||
this.createView();
|
||||
spyOn(this.dialog, 'hide');
|
||||
|
||||
this.view.measurementsCollection.fetch();
|
||||
this.view.measurementsCollection.getItem('us.zillow.AllHomes_Zhvi').set({ selected: true });
|
||||
|
||||
expect(this.view.$('.js-button').text()).toContain('Zillow Home Value Index for All homes');
|
||||
expect(this.view.$('.js-button').hasClass('is-empty')).toBeFalsy();
|
||||
expect(this.dialog.hide).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should open dialog if "button" is clicked', function () {
|
||||
this.createView();
|
||||
spyOn(this.dialog, 'toggle');
|
||||
this.view.$('.js-button').trigger('click');
|
||||
expect(this.dialog.toggle).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should destroy dialog when element is removed', function () {
|
||||
this.createView();
|
||||
spyOn(this.dialog, 'clean');
|
||||
this.view.remove();
|
||||
expect(this.dialog.clean).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
var Backbone = require('backbone');
|
||||
var DataObservatoryCountView = require('builder/components/form-components/editors/data-observatory-measurements//measurements-count-view');
|
||||
|
||||
describe('components/form-components/editors/data-observatory-measurements/measurements-count-view', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
query: null,
|
||||
items: 50,
|
||||
filtering: false
|
||||
});
|
||||
|
||||
this.view = new DataObservatoryCountView({
|
||||
model: this.model
|
||||
});
|
||||
});
|
||||
|
||||
it('should render top results if query is empty', function () {
|
||||
this.model.set({
|
||||
query: '',
|
||||
items: 0
|
||||
});
|
||||
|
||||
expect(this.view.$el.html()).toContain('analyses.data-observatory-measure.count.suggested');
|
||||
});
|
||||
|
||||
it('should render number of results if query is not empty', function () {
|
||||
this.view.model.set({
|
||||
query: 'foo',
|
||||
items: 35
|
||||
});
|
||||
|
||||
expect(this.view.$el.html()).toContain('analyses.data-observatory-measure.count.search');
|
||||
});
|
||||
|
||||
it('should render number of results if query is not empty', function () {
|
||||
this.view.model.set({
|
||||
query: 'foo',
|
||||
items: 15,
|
||||
filtering: true
|
||||
});
|
||||
|
||||
expect(this.view.$el.html()).toContain('analyses.data-observatory-measure.count.search');
|
||||
});
|
||||
|
||||
it('should not have any leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
});
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
var Backbone = require('backbone');
|
||||
var MeasurementsCollection = require('builder/data/data-observatory/measurements-collection');
|
||||
var FiltersCollection = require('builder/data/data-observatory/filters-collection');
|
||||
var AnalysisDefinitionNodeModel = require('builder/data/analysis-definition-node-model');
|
||||
var DataObservatoryListView = require('builder/components/form-components/editors/data-observatory-measurements/measurements-list-view');
|
||||
var MeasurementModel = require('builder/data/data-observatory/measurement-model');
|
||||
|
||||
describe('components/form-components/editors/data-observatory-measurements/measurements-list-view', function () {
|
||||
beforeEach(function () {
|
||||
var configModel = new Backbone.Model({
|
||||
base_url: '/u/foo',
|
||||
user_name: 'foo',
|
||||
sql_api_template: 'foo',
|
||||
api_key: 'foo'
|
||||
});
|
||||
|
||||
this.nodeDefModel = new AnalysisDefinitionNodeModel({
|
||||
id: 'a1',
|
||||
type: 'data-observatory-multiple-measures',
|
||||
final_column: 'foo',
|
||||
source: 'a0'
|
||||
}, {
|
||||
configModel: configModel,
|
||||
collection: new Backbone.Collection()
|
||||
});
|
||||
|
||||
this.querySchemaModel = new Backbone.Model({
|
||||
query: 'select * from wadus'
|
||||
});
|
||||
|
||||
this.nodeDefModel.querySchemaModel = this.querySchemaModel;
|
||||
|
||||
this.measurementsCollection = new MeasurementsCollection([], {
|
||||
configModel: configModel,
|
||||
nodeDefModel: this.nodeDefModel
|
||||
});
|
||||
|
||||
spyOn(this.measurementsCollection.SQL, 'execute').and.callFake(function (query, vars, params) {
|
||||
var payload = {
|
||||
rows: [
|
||||
{
|
||||
numer_id: 'us.zillow.AllHomes_Zhvi',
|
||||
numer_name: 'Zillow Home Value Index for All homes',
|
||||
numer_tags: '{"subsection/tags.housing": "Housing", "license/us.zillow.zillow-license": "Zillow Terms of Use for Aggregate Data"}'
|
||||
},
|
||||
{
|
||||
numer_id: 'us.census.acs.B19083001',
|
||||
numer_name: 'Gini Index',
|
||||
numer_tags: '{"subsection/tags.age_gender": "Age and Gender", "license/tags.no-restrictions": "Unrestricted"}'
|
||||
},
|
||||
{
|
||||
numer_id: 'us.census.acs.B01001002',
|
||||
numer_name: 'Male Population',
|
||||
numer_tags: '{"subsection/tags.age_gender": "Age and Gender", "license/tags.no-restrictions": "Unrestricted"}'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
params && params.success(payload);
|
||||
});
|
||||
|
||||
this.filtersCollection = new FiltersCollection([], {
|
||||
configModel: configModel,
|
||||
nodeDefModel: this.nodeDefModel
|
||||
});
|
||||
|
||||
spyOn(this.filtersCollection.SQL, 'execute').and.callFake(function (query, vars, params) {
|
||||
var payload = {
|
||||
rows: [
|
||||
{
|
||||
subsection_id: 'subsection/tags.age_gender',
|
||||
subsection_name: 'Age and Gender'
|
||||
},
|
||||
{
|
||||
subsection_id: 'subsection/us.census.acs.segments',
|
||||
subsection_name: 'US Population Segments'
|
||||
},
|
||||
{
|
||||
subsection_id: 'subsection/tags.housing',
|
||||
subsection_name: 'Housing'
|
||||
},
|
||||
{
|
||||
subsection_id: 'subsection/us.zillow.indexes',
|
||||
subsection_name: 'Zillow Home Value and Rental Indexes'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
params && params.success(payload);
|
||||
});
|
||||
|
||||
this.measurementsCollection.fetch();
|
||||
this.filtersCollection.fetch();
|
||||
|
||||
this.searchMeasurements = jasmine.createSpy('searchMeasurements');
|
||||
|
||||
this.measurementModel = new MeasurementModel({}, {
|
||||
configModel: configModel,
|
||||
nodeDefModel: this.nodeDefModel
|
||||
});
|
||||
|
||||
this.view = new DataObservatoryListView({
|
||||
measurementsCollection: this.measurementsCollection,
|
||||
filtersCollection: this.filtersCollection,
|
||||
searchMeasurements: this.searchMeasurements,
|
||||
measurementModel: this.measurementModel
|
||||
});
|
||||
|
||||
spyOn(this.view, '_createListView').and.callThrough();
|
||||
spyOn(this.view, '_createSearchView').and.callThrough();
|
||||
spyOn(this.view, '_createCountView').and.callThrough();
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should genereate an measurements and filters collections', function () {
|
||||
expect(this.view._measurementsCollection).toBeDefined();
|
||||
expect(this.view._filtersCollection).toBeDefined();
|
||||
expect(this.view._measurementsCollection.size()).toBe(3);
|
||||
expect(this.view._filtersCollection.size()).toBe(4);
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view._listView).toBeDefined();
|
||||
expect(this.view._createListView).toHaveBeenCalled();
|
||||
expect(this.view._createSearchView).toHaveBeenCalled();
|
||||
expect(this.view._createCountView).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should filter search queries', function () {
|
||||
this.view.model.set('query', 'pop');
|
||||
|
||||
expect(this.searchMeasurements).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should render filtered measurements', function () {
|
||||
this.measurementsCollection.SQL.execute = function (query, vars, params) {
|
||||
var payload = {
|
||||
rows: [
|
||||
{
|
||||
numer_id: 'us.census.acs.B19083001',
|
||||
numer_name: 'Gini Index',
|
||||
numer_tags: '{"subsection/tags.age_gender": "Age and Gender", "license/tags.no-restrictions": "Unrestricted"}'
|
||||
},
|
||||
{
|
||||
numer_id: 'us.census.acs.B01001002',
|
||||
numer_name: 'Male Population',
|
||||
numer_tags: '{"subsection/tags.age_gender": "Age and Gender", "license/tags.no-restrictions": "Unrestricted"}'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
params && params.success(payload);
|
||||
};
|
||||
|
||||
this.filtersCollection.setSelected('subsection/tags.age_gender');
|
||||
this.measurementsCollection.fetch();
|
||||
|
||||
this.view = new DataObservatoryListView({
|
||||
measurementsCollection: this.measurementsCollection,
|
||||
filtersCollection: this.filtersCollection,
|
||||
searchMeasurements: this.searchMeasurements,
|
||||
measurementModel: this.measurementModel
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
|
||||
expect(this.view.$('.js-listItem').length).toBe(2);
|
||||
expect(this.view.$('.js-listItem').eq(0).text()).toContain('Gini Index');
|
||||
expect(this.view.$('.js-listItem').eq(1).text()).toContain('Male Population');
|
||||
});
|
||||
|
||||
it('should trigger filter event', function () {
|
||||
spyOn(this.view, 'trigger');
|
||||
this.view.$('.js-filters').click();
|
||||
|
||||
expect(this.view.trigger).toHaveBeenCalledWith('filters');
|
||||
});
|
||||
|
||||
it('should not have any leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
});
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
var Backbone = require('backbone');
|
||||
var DataObservatorySearchView = require('builder/components/form-components/editors/data-observatory-measurements/measurements-search-view');
|
||||
var FiltersCollection = require('builder/data/data-observatory/filters-collection');
|
||||
var AnalysisDefinitionNodeModel = require('builder/data/analysis-definition-node-model');
|
||||
|
||||
describe('components/form-components/editors/data-observatory-measurements/measurements-search-view', function () {
|
||||
beforeEach(function () {
|
||||
var configModel = new Backbone.Model({
|
||||
base_url: '/u/foo',
|
||||
user_name: 'foo',
|
||||
sql_api_template: 'foo',
|
||||
api_key: 'foo'
|
||||
});
|
||||
|
||||
this.nodeDefModel = new AnalysisDefinitionNodeModel({
|
||||
id: 'a1',
|
||||
type: 'data-observatory-multiple-measures',
|
||||
final_column: 'foo',
|
||||
source: 'a0'
|
||||
}, {
|
||||
configModel: configModel,
|
||||
collection: new Backbone.Collection()
|
||||
});
|
||||
|
||||
this.querySchemaModel = new Backbone.Model({
|
||||
query: 'select * from wadus'
|
||||
});
|
||||
|
||||
this.nodeDefModel.querySchemaModel = this.querySchemaModel;
|
||||
|
||||
this.filtersCollection = new FiltersCollection([
|
||||
{
|
||||
subsection_id: 'subsection/tags.age_gender',
|
||||
subsection_name: 'Age and Gender'
|
||||
},
|
||||
{
|
||||
subsection_id: 'subsection/us.census.acs.segments',
|
||||
subsection_name: 'US Population Segments'
|
||||
},
|
||||
{
|
||||
subsection_id: 'subsection/tags.housing',
|
||||
subsection_name: 'Housing'
|
||||
},
|
||||
{
|
||||
subsection_id: 'subsection/us.zillow.indexes',
|
||||
subsection_name: 'Zillow Home Value and Rental Indexes'
|
||||
}
|
||||
], {
|
||||
configModel: configModel,
|
||||
nodeDefModel: this.nodeDefModel
|
||||
});
|
||||
|
||||
this.model = new Backbone.Model({
|
||||
query: '',
|
||||
items: 50,
|
||||
fetching: false
|
||||
});
|
||||
|
||||
this.view = new DataObservatorySearchView({
|
||||
model: this.model,
|
||||
filtersCollection: this.filtersCollection
|
||||
});
|
||||
});
|
||||
|
||||
it('should sanitize input', function () {
|
||||
this.view.$('.js-input-search').val('<script>');
|
||||
expect(this.model.get('query')).toBe('');
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('label with no filter selected', function () {
|
||||
this.view.render();
|
||||
|
||||
expect(this.view.$('.js-filters').text()).toContain('analyses.data-observatory-measure.filters.label');
|
||||
});
|
||||
|
||||
it('label with 1 filter selected', function () {
|
||||
this.filtersCollection.at(0).set({selected: true});
|
||||
this.view.render();
|
||||
|
||||
expect(this.view.$('.js-filters').text()).toContain('analyses.data-observatory-measure.filters.applied.single');
|
||||
});
|
||||
|
||||
it('label with more than one filter selected', function () {
|
||||
this.filtersCollection.at(0).set({selected: true});
|
||||
this.filtersCollection.at(2).set({selected: true});
|
||||
this.view.render();
|
||||
|
||||
expect(this.view.$('.js-filters').text()).toContain('analyses.data-observatory-measure.filters.applied.multiple');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have any leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
var Backbone = require('backbone');
|
||||
|
||||
describe('components/form-components/editors/datetime', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
dateee: '2016-12-01T12:00:00+00:00'
|
||||
});
|
||||
|
||||
this.view = new Backbone.Form.editors.DateTime({
|
||||
schema: {},
|
||||
key: 'dateee',
|
||||
model: this.model
|
||||
});
|
||||
});
|
||||
|
||||
describe('when date time is provided', function () {
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$('.js-input').length).toBe(1);
|
||||
expect(this.view.$('.js-input').html()).toBe('2016-12-01T12:00:00Z');
|
||||
expect(this.view.$('.js-datetimePicker').length).toBe(0);
|
||||
});
|
||||
|
||||
it('should open time picker when click over input and not change the time', function () {
|
||||
expect(this.view.$('.js-input').html()).toBe('2016-12-01T12:00:00Z');
|
||||
this.view.$('.js-input').click();
|
||||
expect(this.view.$('.js-datetimePicker').length).toBe(1);
|
||||
expect(this.view.$('.js-input').html()).toBe('2016-12-01T12:00:00Z');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when date time is NOT provided', function () {
|
||||
beforeEach(function () {
|
||||
this.view.value = '';
|
||||
this.model.set('dateee', '');
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should return null as value when datetime is not selected', function () {
|
||||
expect(this.view.getValue()).toBe(null);
|
||||
});
|
||||
|
||||
it('should render null when datetime is not selected', function () {
|
||||
expect(this.view.$('.js-input').length).toBe(1);
|
||||
expect(this.view.$('.js-input').html()).toBe('null');
|
||||
expect(this.view.$('.js-input').hasClass('is-empty')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should change input when it is clicked for showing time picker', function () {
|
||||
expect(this.view.$('.js-input').html()).toBe('null');
|
||||
this.view.$('.js-input').click();
|
||||
expect(this.view.$('.js-datetimePicker').length).toBe(1);
|
||||
expect(this.view.$('.js-input').html()).not.toBe('null');
|
||||
expect(this.view.$('.js-input').hasClass('is-empty')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
var Backbone = require('backbone');
|
||||
|
||||
describe('components/form-components/editors/enabler-editor', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
key: ''
|
||||
});
|
||||
this.view = new Backbone.Form.editors.EnablerEditor({
|
||||
key: 'key',
|
||||
model: this.model,
|
||||
label: 'hello',
|
||||
trackingClass: 'wadus',
|
||||
editor: {
|
||||
type: 'Select',
|
||||
options: ['hello', 'world']
|
||||
}
|
||||
});
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$('.js-check').length).toBe(1);
|
||||
expect(this.view.$('.js-editor').length).toBe(1);
|
||||
expect(this.view.$('.js-check').is(':checked')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should render as checked when value is not empty', function () {
|
||||
this.view._checkModel.set('enabled', true);
|
||||
this.view.render();
|
||||
expect(this.view.$('.js-check').is(':checked')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should render help tooltip', function () {
|
||||
this.view.options.help = 'HELP!';
|
||||
this.view.render();
|
||||
expect(this.view._helpTooltip).toBeDefined();
|
||||
expect(this.view.$('.js-help').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should change model value when editor component changes', function () {
|
||||
this.view._editorComponent.setValue('hello');
|
||||
this.view._editorComponent.trigger('change', this.view._editorComponent);
|
||||
expect(this.view.value).toBe('hello');
|
||||
});
|
||||
|
||||
it('should change model with empty value when check is disabled', function () {
|
||||
this.view._checkModel.set('enabled', true);
|
||||
this.view._editorComponent.setValue('hello');
|
||||
this.view._editorComponent.trigger('change', 'hello', this.view._editorComponent);
|
||||
expect(this.view._checkModel.get('enabled')).toBeTruthy();
|
||||
expect(this.view.value).toBe('hello');
|
||||
this.view._checkModel.set('enabled', false);
|
||||
expect(this.view._checkModel.get('enabled')).toBeFalsy();
|
||||
expect(this.view.$('.js-check').is(':checked')).toBeFalsy();
|
||||
expect(this.view.value).toBe('');
|
||||
});
|
||||
|
||||
it('should change model with default value when check is enabled', function () {
|
||||
this.view.options.defaultValue = 'world';
|
||||
this.view._checkModel.set('enabled', true);
|
||||
expect(this.view._editorComponent.getValue()).toBe('world');
|
||||
expect(this.view.value).toBe('world');
|
||||
});
|
||||
|
||||
it('should change model with empty value when default value is passed and check is disabled', function () {
|
||||
this.view.options.defaultValue = 'world';
|
||||
this.view._checkModel.set('enabled', true);
|
||||
this.view._checkModel.set('enabled', false);
|
||||
expect(this.view.value).toBe('');
|
||||
});
|
||||
|
||||
it('should accept disabled option', function () {
|
||||
this.view.options.isDisabled = true;
|
||||
this.view.render();
|
||||
expect(this.view.$('.js-check').is(':disabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should add the track class', function () {
|
||||
expect(this.view.$('.track-keySelect').length).toBe(1);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,84 @@
|
||||
var Backbone = require('backbone');
|
||||
|
||||
describe('components/form-components/editors/enabler', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
enabler: false
|
||||
});
|
||||
|
||||
this.view = new Backbone.Form.editors.Enabler({
|
||||
model: this.model,
|
||||
title: 'hello',
|
||||
key: 'enabler'
|
||||
});
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
beforeEach(function () {
|
||||
this.view.render();
|
||||
this.$input = function () {
|
||||
return this.view.$('.js-input');
|
||||
};
|
||||
});
|
||||
|
||||
it('should create the checkbox properly', function () {
|
||||
expect(this.$input().length).toBe(1);
|
||||
expect(this.$input().is(':checked')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should start checked from the beginning if key is true', function () {
|
||||
this.model.attributes.enabler = true;
|
||||
var view = new Backbone.Form.editors.Enabler({
|
||||
model: this.model,
|
||||
title: 'hello',
|
||||
key: 'enabler'
|
||||
});
|
||||
expect(view.$('.js-input').is(':checked')).toBeTruthy();
|
||||
view.remove();
|
||||
});
|
||||
|
||||
it('should disable checkbox if option is false', function () {
|
||||
this.view.options.disabled = true;
|
||||
this.view._initViews();
|
||||
expect(this.$input().is(':checked')).toBeFalsy();
|
||||
expect(this.$input().is(':disabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should add help and help tooltip', function () {
|
||||
this.view.options.help = 'help!';
|
||||
this.view._initViews();
|
||||
expect(this.view.$('.js-help').length).toBe(1);
|
||||
expect(this.view._helpTooltip).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should trigger event when input changes', function () {
|
||||
var bindSpy = jasmine.createSpy('callback');
|
||||
expect(this.model.get('enabler')).toBeFalsy();
|
||||
this.view.bind('change', bindSpy);
|
||||
this.view.$('.js-input').attr('checked', '').trigger('change');
|
||||
expect(this.model.get('enabler')).toBeTruthy();
|
||||
expect(bindSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set value properly', function () {
|
||||
this.view.setValue(true);
|
||||
expect(this.model.get('enabler')).toBeTruthy();
|
||||
expect(this.view.$('.js-input').is(':checked')).toBeTruthy();
|
||||
this.view.setValue(false);
|
||||
expect(this.model.get('enabler')).toBeFalsy();
|
||||
expect(this.view.$('.js-input').is(':checked')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should remove help tooltip if it is defined', function () {
|
||||
this.view.options.help = 'hello';
|
||||
this.view._initViews();
|
||||
spyOn(this.view, '_removeTooltip');
|
||||
this.view.remove();
|
||||
expect(this.view._removeTooltip).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
|
||||
var Backbone = require('backbone');
|
||||
var FillColorByValueView = require('builder/components/form-components/editors/fill-color/fill-color-by-value-view');
|
||||
|
||||
var FactoryModals = require('../../../../factories/modals');
|
||||
var getConfigModelFixture = require('fixtures/builder/config-model.fixture.js');
|
||||
var getUserModelFixture = require('fixtures/builder/user-model.fixture.js');
|
||||
var DialogConstants = require('builder/components/form-components/_constants/_dialogs');
|
||||
|
||||
describe('components/form-components/editors/fill-color/fill-color-by-value-view', function () {
|
||||
var view;
|
||||
|
||||
var CARTODB_ID = { val: 'cartodb_id', label: 'cartodb_id', type: 'number' };
|
||||
var A_NUMBER_COLUMN = { val: 'a_number', label: 'a_number', type: 'number' };
|
||||
var A_TEXT_COLUMN = { val: 'category', label: 'category', type: 'string' };
|
||||
var ALL_COLUMNS = [CARTODB_ID, A_NUMBER_COLUMN, A_TEXT_COLUMN];
|
||||
|
||||
function createView (options) {
|
||||
options = options || {
|
||||
model: new Backbone.Model({}),
|
||||
columns: ALL_COLUMNS,
|
||||
query: 'SELECT * from table',
|
||||
configModel: getConfigModelFixture(),
|
||||
userModel: getUserModelFixture(),
|
||||
editorAttrs: { help: '' },
|
||||
modals: FactoryModals.createModalService(),
|
||||
dialogMode: DialogConstants.Mode.FLOAT,
|
||||
valueColorInputModel: new Backbone.Model({}),
|
||||
popupConfig: {}
|
||||
};
|
||||
|
||||
return new FillColorByValueView(options);
|
||||
}
|
||||
|
||||
describe('render', function () {
|
||||
it('should have no leaks', function () {
|
||||
view = createView();
|
||||
|
||||
expect(view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
it('calls to _initViews', function () {
|
||||
view = createView();
|
||||
spyOn(view, '_initFillDialog');
|
||||
spyOn(view, '_initColorByValueInput');
|
||||
|
||||
view.render();
|
||||
|
||||
expect(view._initFillDialog).toHaveBeenCalled();
|
||||
expect(view._initColorByValueInput).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
var Backbone = require('backbone');
|
||||
var FillColorFixedView = require('builder/components/form-components/editors/fill-color/fill-color-fixed-view');
|
||||
var DialogConstants = require('builder/components/form-components/_constants/_dialogs');
|
||||
|
||||
describe('components/form-components/editors/fill-color/fill-color-fixed-view', function () {
|
||||
var view;
|
||||
|
||||
var CARTODB_ID = { val: 'cartodb_id', label: 'cartodb_id', type: 'number' };
|
||||
var A_NUMBER_COLUMN = { val: 'a_number', label: 'a_number', type: 'number' };
|
||||
var A_TEXT_COLUMN = { val: 'category', label: 'category', type: 'string' };
|
||||
var ALL_COLUMNS = [CARTODB_ID, A_NUMBER_COLUMN, A_TEXT_COLUMN];
|
||||
|
||||
function createView () {
|
||||
var fillColorFixedView = new FillColorFixedView({
|
||||
model: new Backbone.Model({
|
||||
fixed: 'red',
|
||||
opacity: 0.8
|
||||
}),
|
||||
columns: ALL_COLUMNS,
|
||||
editorAttrs: { help: '' },
|
||||
dialogMode: DialogConstants.Mode.FLOAT,
|
||||
popupConfig: {},
|
||||
fixedColorInputModel: new Backbone.Model({}),
|
||||
imageInputModel: new Backbone.Model({})
|
||||
});
|
||||
return fillColorFixedView;
|
||||
}
|
||||
|
||||
describe('render', function () {
|
||||
it('should have no leaks', function () {
|
||||
view = createView();
|
||||
|
||||
expect(view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
it('calls to _initViews', function () {
|
||||
view = createView();
|
||||
spyOn(view, '_initFillColorInput');
|
||||
spyOn(view, '_initFillImageInput');
|
||||
|
||||
view.render();
|
||||
|
||||
expect(view._initFillColorInput).toHaveBeenCalled();
|
||||
expect(view._initFillImageInput).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
var Backbone = require('backbone');
|
||||
|
||||
var FactoryModals = require('../../../../factories/modals');
|
||||
var getConfigModelFixture = require('fixtures/builder/config-model.fixture.js');
|
||||
var getUserModelFixture = require('fixtures/builder/user-model.fixture.js');
|
||||
var DialogConstants = require('builder/components/form-components/_constants/_dialogs');
|
||||
|
||||
var ColorByValueView = require('builder/components/form-components/editors/fill-color/fill-color-by-value-view');
|
||||
|
||||
describe('components/form-components/editors/fill-color/fill-color', function () {
|
||||
var color;
|
||||
|
||||
var CARTODB_ID = { val: 'cartodb_id', label: 'cartodb_id', type: 'number' };
|
||||
var A_NUMBER_COLUMN = { val: 'a_number', label: 'a_number', type: 'number' };
|
||||
var A_TEXT_COLUMN = { val: 'category', label: 'category', type: 'string' };
|
||||
var ALL_COLUMNS = [CARTODB_ID, A_NUMBER_COLUMN, A_TEXT_COLUMN];
|
||||
|
||||
function createFillColor (opts) {
|
||||
opts = opts || {};
|
||||
var modelOptions = {};
|
||||
if (opts.fillColor) {
|
||||
modelOptions.fillColor = opts.fillColor;
|
||||
}
|
||||
|
||||
var options = {
|
||||
model: new Backbone.Model(modelOptions),
|
||||
key: 'fillColor',
|
||||
options: ALL_COLUMNS,
|
||||
query: 'SELECT * from table',
|
||||
configModel: getConfigModelFixture(),
|
||||
userModel: getUserModelFixture(),
|
||||
editorAttrs: {
|
||||
geometryName: 'point',
|
||||
help: '',
|
||||
hidePanes: []
|
||||
},
|
||||
modals: FactoryModals.createModalService(),
|
||||
dialogMode: DialogConstants.Mode.FLOAT,
|
||||
valueColorInputModel: new Backbone.Model({}),
|
||||
popupConfig: {}
|
||||
};
|
||||
|
||||
if (opts.hidePanes) {
|
||||
options.editorAttrs.hidePanes = opts.hidePanes;
|
||||
}
|
||||
if (opts.columns) {
|
||||
options.options = opts.columns;
|
||||
}
|
||||
return new Backbone.Form.editors.FillColor(options);
|
||||
}
|
||||
|
||||
describe('render', function () {
|
||||
it('both fixed and by value if no options passed about it', function () {
|
||||
color = createFillColor();
|
||||
color.render();
|
||||
|
||||
expect(color.$('.js-menu').children().length).toBe(2);
|
||||
var labels = color.$('.js-menu > li label');
|
||||
expect(labels.length).toBe(2);
|
||||
expect(labels[0].textContent.trim()).toContain('form-components.editors.fill.input-number.solid');
|
||||
expect(labels[1].textContent.trim()).toContain('form-components.editors.fill.input-number.by-value');
|
||||
});
|
||||
|
||||
it('only fixed if hidePanes set with `value`', function () {
|
||||
color = createFillColor({
|
||||
hidePanes: ['value'],
|
||||
fillColor: {
|
||||
fixed: '#FF0000',
|
||||
opacity: 0.9
|
||||
}
|
||||
});
|
||||
color.render();
|
||||
|
||||
// Menu
|
||||
expect(color.$('.js-menu').children().length).toBe(1);
|
||||
var labels = color.$('.js-menu > li label');
|
||||
expect(labels.length).toBe(1);
|
||||
expect(labels[0].textContent.trim()).toContain('form-components.editors.fill.input-number.solid');
|
||||
|
||||
// Form content
|
||||
expect(color.$('.js-content .ColorBarContainer').length).toBe(1);
|
||||
expect(color.$('.js-content li.ColorBar')[0].style.backgroundColor).toContain('rgba(255, 0, 0, 0.9');
|
||||
});
|
||||
|
||||
it('only by value if hidePanes set with `fixed`', function () {
|
||||
spyOn(ColorByValueView.prototype, 'initialize');
|
||||
spyOn(ColorByValueView.prototype, 'render').and.returnValue('<div class="fake-by-value"></div>');
|
||||
color = createFillColor({
|
||||
hidePanes: ['fixed']
|
||||
});
|
||||
color.render();
|
||||
|
||||
// Menu
|
||||
expect(color.$('.js-menu').children().length).toBe(1);
|
||||
var labels = color.$('.js-menu > li label');
|
||||
expect(labels.length).toBe(1);
|
||||
expect(labels[0].textContent.trim()).toContain('form-components.editors.fill.input-number.by-value');
|
||||
|
||||
expect(ColorByValueView.prototype.render).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
color.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
var Backbone = require('backbone');
|
||||
var InputColorByValueView = require('builder/components/form-components/editors/fill-color/inputs/input-color-by-value');
|
||||
|
||||
var FactoryModals = require('../../../../../factories/modals');
|
||||
|
||||
var getConfigModelFixture = require('fixtures/builder/config-model.fixture.js');
|
||||
var getUserModelFixture = require('fixtures/builder/user-model.fixture.js');
|
||||
|
||||
describe('components/form-components/editors/fill-color/inputs/input-color-by-value', function () {
|
||||
var view;
|
||||
|
||||
var CARTODB_ID = { val: 'cartodb_id', label: 'cartodb_id', type: 'number' };
|
||||
var A_NUMBER_COLUMN = { val: 'a_number', label: 'a_number', type: 'number' };
|
||||
var A_TEXT_COLUMN = { val: 'category', label: 'category', type: 'string' };
|
||||
var ALL_COLUMNS = [CARTODB_ID, A_NUMBER_COLUMN, A_TEXT_COLUMN];
|
||||
|
||||
function createView (options) {
|
||||
options = options || {
|
||||
model: new Backbone.Model({
|
||||
range: []
|
||||
}),
|
||||
columns: ALL_COLUMNS,
|
||||
configModel: getConfigModelFixture(),
|
||||
userModel: getUserModelFixture(),
|
||||
modals: FactoryModals.createModalService(),
|
||||
query: 'SELECT * from a',
|
||||
editorAttrs: { help: '' }
|
||||
};
|
||||
|
||||
return new InputColorByValueView(options);
|
||||
}
|
||||
|
||||
describe('initialize', function () {
|
||||
it('model can be set without colors (first use)', function () {
|
||||
view = createView();
|
||||
|
||||
expect(view._getValue()).toBe(null);
|
||||
expect(view.model.get('range')).toEqual([]);
|
||||
});
|
||||
|
||||
it('model can be set with colors range & string field', function () {
|
||||
view = createView();
|
||||
|
||||
view.model.set('range', ['#5F4690', '#1D6996']);
|
||||
view.model.set('attribute', 'category');
|
||||
view.model.set('attribute_type', 'string');
|
||||
|
||||
expect(view._getValue()).not.toBe(null);
|
||||
expect(view._getColumn()).toBe(A_TEXT_COLUMN);
|
||||
});
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('renders a `select by column` if no attribute is set', function () {
|
||||
view = createView();
|
||||
view.render();
|
||||
|
||||
var htmlContent = view.$el.html();
|
||||
expect(htmlContent).toContain('form-components.editors.style.select-by-column');
|
||||
});
|
||||
|
||||
it('renders the name of the field & a colorbar if attribute and colors are set', function () {
|
||||
view = createView();
|
||||
view.model.set('range', ['#FF0000', '#0000FF']);
|
||||
view.model.set('attribute', 'category');
|
||||
view.model.set('attribute_type', 'string');
|
||||
|
||||
view.render();
|
||||
|
||||
var columnName = view.$el.find('.Editor-fillContainer--Column');
|
||||
expect(columnName.html()).toContain('category');
|
||||
|
||||
var colorbar = view.$el.find('.Editor-fillContainer--ColorBarContainer');
|
||||
expect(colorbar.html()).toContain('rgba(255, 0, 0, 1)');
|
||||
expect(colorbar.html()).toContain('rgba(0, 0, 255, 1)');
|
||||
});
|
||||
|
||||
it('creates an input-color-value-content-view', function () {
|
||||
view = createView();
|
||||
view._createContentView();
|
||||
|
||||
expect(view._inputColorValueContentView).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('events', function () {
|
||||
it('should hookup selectors with functions', function () {
|
||||
view = createView();
|
||||
expect(view.events['click']).toEqual('_onClick');
|
||||
});
|
||||
});
|
||||
});
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
var Backbone = require('backbone');
|
||||
var InputColorFixedView = require('builder/components/form-components/editors/fill-color/inputs/input-color-fixed');
|
||||
|
||||
describe('components/form-components/editors/fill-color/inputs/input-color-fixed', function () {
|
||||
var inputColor;
|
||||
|
||||
function createView () {
|
||||
inputColor = new InputColorFixedView({
|
||||
model: new Backbone.Model({
|
||||
type: 'color',
|
||||
fixed: '#FF0000',
|
||||
opacity: 0.90
|
||||
}),
|
||||
columns: {},
|
||||
editorAttrs: { help: '' }
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
createView();
|
||||
});
|
||||
|
||||
it('renders a colorbar', function () {
|
||||
inputColor.render();
|
||||
|
||||
expect(inputColor._getValue()).toContain('rgba(255, 0, 0, 0.9');
|
||||
expect(inputColor._getOpacity()).toBe(0.9);
|
||||
|
||||
var colorBarBackground = inputColor.$el.find('.ColorBar')[0].style.backgroundColor;
|
||||
expect(colorBarBackground).toContain('rgba(255, 0, 0, 0.9');
|
||||
});
|
||||
|
||||
it('can create a color picker to choose one', function () {
|
||||
inputColor._createContentView();
|
||||
expect(inputColor._colorPickerView).not.toBeNull();
|
||||
});
|
||||
});
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var InputImageView = require('builder/components/form-components/editors/fill-color/inputs/input-image');
|
||||
|
||||
var ImageLoaderView = require('builder/components/img-loader-view');
|
||||
var ConfigModel = require('builder/data/config-model');
|
||||
var FactoryModals = require('../../../../../factories/modals');
|
||||
|
||||
describe('components/form-components/editors/fill-color/inputs/input-image', function () {
|
||||
var NO_IMAGE_TEXT = 'form-components.editors.fill.input-color.img';
|
||||
var SQUARE_ICON_URL = 'https://s3.amazonaws.com/com.cartodb.users-assets.production/maki-icons/square-18.svg';
|
||||
|
||||
var inputImageView;
|
||||
var spyOnSvgRequest;
|
||||
|
||||
function createView () {
|
||||
inputImageView = new InputImageView({
|
||||
model: new Backbone.Model({
|
||||
type: 'image',
|
||||
image: null,
|
||||
kind: null
|
||||
}),
|
||||
userModel: { featureEnabled: function () { return true; } },
|
||||
configModel: new ConfigModel({ base_url: '/u/pepe' }),
|
||||
modals: FactoryModals.createModalService(),
|
||||
editorAttrs: { help: '' }
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
spyOnSvgRequest = spyOn(ImageLoaderView.prototype, '_loadSVG');
|
||||
createView();
|
||||
});
|
||||
|
||||
it('renders without an image', function () {
|
||||
inputImageView.render();
|
||||
|
||||
expect(inputImageView._getImageURL()).toBe('');
|
||||
|
||||
var htmlContent = inputImageView.$('.Editor-fillImage').html();
|
||||
expect(htmlContent).toContain(NO_IMAGE_TEXT);
|
||||
|
||||
var imgDiv = inputImageView.$('.js-image-container');
|
||||
expect(_.size(imgDiv)).toBe(0);
|
||||
});
|
||||
|
||||
it('renders an image if specified', function () {
|
||||
inputImageView.model.set('image', SQUARE_ICON_URL);
|
||||
inputImageView.render();
|
||||
|
||||
expect(inputImageView._getImageURL()).toBe(SQUARE_ICON_URL);
|
||||
|
||||
var htmlContent = inputImageView.$('.Editor-fillImage').html();
|
||||
expect(htmlContent).not.toContain(NO_IMAGE_TEXT);
|
||||
|
||||
var imgDiv = inputImageView.$('.js-image-container');
|
||||
expect(_.size(imgDiv)).toBe(1);
|
||||
|
||||
expect(spyOnSvgRequest).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('can create a color file view to select assets', function () {
|
||||
inputImageView._createContentView();
|
||||
expect(inputImageView._inputColorFileView).not.toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,287 @@
|
||||
var Backbone = require('backbone');
|
||||
var FactoryModals = require('../../../factories/modals');
|
||||
|
||||
describe('components/form-components/editors/fill', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
names: 'pepe',
|
||||
stroke: {
|
||||
size: {
|
||||
range: [1, 30],
|
||||
attribute: 'the_geom',
|
||||
quantification: 'Quantile'
|
||||
},
|
||||
color: {
|
||||
bins: 5,
|
||||
range: ['#FFFFFF', '#FABADA', '#00FF00', '#000000', '#999999'],
|
||||
attribute: 'column1',
|
||||
quantification: 'Jenks',
|
||||
opacity: 0.5
|
||||
}
|
||||
},
|
||||
fill: {
|
||||
color: {
|
||||
bins: 5,
|
||||
range: ['#FFFFFF', '#FABADA', '#00FF00', '#000000', '#999999'],
|
||||
attribute: 'column1',
|
||||
quantification: 'Jenks',
|
||||
opacity: 0.5
|
||||
},
|
||||
size: {
|
||||
range: [1, 30],
|
||||
attribute: 'the_geom',
|
||||
quantification: 'Quantile'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this._userModel = {
|
||||
featureEnabled: function () { return true; }
|
||||
};
|
||||
|
||||
this._schema = {
|
||||
configModel: {},
|
||||
query: 'SELECT * from table',
|
||||
options: [
|
||||
{ label: 'column1', type: 'number' },
|
||||
{ label: 'column2', type: 'number' },
|
||||
{ label: 'column3', type: 'number' }
|
||||
]
|
||||
};
|
||||
|
||||
this.modals = FactoryModals.createModalService();
|
||||
|
||||
this.view = new Backbone.Form.editors.Fill({
|
||||
key: 'stroke',
|
||||
userModel: this._userModel,
|
||||
modals: this.modals,
|
||||
schema: this._schema,
|
||||
model: this.model
|
||||
});
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$('.CDB-OptionInput-item').length).toBe(2);
|
||||
expect(this.view.$el.text()).toContain('1..30');
|
||||
});
|
||||
|
||||
it('should render the input fields', function () {
|
||||
expect(this.view.$('.CDB-OptionInput-item').length).toBe(2);
|
||||
});
|
||||
|
||||
it('should show the input fields correctly sorted', function () {
|
||||
expect(this.view.$('.CDB-OptionInput-item:first-child').text()).toContain('1..30');
|
||||
expect(this.view.$('.CDB-OptionInput-item:last-child').html()).toContain('rgba(255, 255, 255, 0.5),rgba(250, 186, 218, 0.5),rgba(0, 255, 0, 0.5),rgba(0, 0, 0, 0.5),rgba(153, 153, 153, 0.5)');
|
||||
});
|
||||
|
||||
it('should open a fill dialog on click', function () {
|
||||
expect(this.view.$('.Editor-boxModal').length).toBe(0);
|
||||
this.view.$('.CDB-OptionInput-item:first-child').click();
|
||||
expect(this.view.$('.Editor-boxModal').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should render the size dialog component ', function () {
|
||||
this.view.$('.CDB-OptionInput-item:first-child').click();
|
||||
expect(this.view.$('.CDB-NavMenu-item').length).toEqual(2);
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('form-components.editors.fill.input-number.fixed');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('form-components.editors.fill.input-number.by-value');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('form-components.editors.fill.quantification.methods.quantiles');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('the_geom');
|
||||
});
|
||||
|
||||
it('should render the color dialog component ', function () {
|
||||
this.view.$('.CDB-OptionInput-item:last-child').click();
|
||||
expect(this.view.$('.CDB-NavMenu-item').length).toEqual(2);
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('form-components.editors.fill.input-color.solid');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('form-components.editors.fill.input-color.value');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('5 form-components.editors.fill.input-ramp.buckets');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('column1');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('form-components.editors.fill.quantification.methods.jenks');
|
||||
});
|
||||
|
||||
describe('hide panes', function () {
|
||||
beforeEach(function () {
|
||||
this.view = new Backbone.Form.editors.Fill({
|
||||
key: 'fill',
|
||||
schema: {
|
||||
configModel: {},
|
||||
userModel: {
|
||||
featureEnabled: function () { return true; }
|
||||
},
|
||||
modals: this.modals,
|
||||
query: 'SELECT * FROM table',
|
||||
options: [
|
||||
{ label: 'column1', type: 'number' },
|
||||
{ label: 'column2', type: 'number' },
|
||||
{ label: 'column3', type: 'number' }
|
||||
],
|
||||
editorAttrs: {
|
||||
size: {
|
||||
hidePanes: ['fixed']
|
||||
},
|
||||
color: {
|
||||
hidePanes: ['fixed']
|
||||
}
|
||||
}
|
||||
},
|
||||
model: this.model
|
||||
});
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render the size dialog component ', function () {
|
||||
this.view.$('.CDB-OptionInput-item:first-child').click();
|
||||
expect(this.view.$('.CDB-NavMenu-item').length).toEqual(1);
|
||||
expect(this.view.$('.Editor-boxModal').text()).not.toContain('form-components.editors.fill.input-number.fixed');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('form-components.editors.fill.input-number.by-value');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('form-components.editors.fill.quantification.methods.quantiles');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('the_geom');
|
||||
});
|
||||
|
||||
it('should render the color dialog component', function () {
|
||||
this.view.$('.CDB-OptionInput-item:last-child').click();
|
||||
expect(this.view.$('.CDB-NavMenu-item').length).toEqual(1);
|
||||
expect(this.view.$('.Editor-boxModal').text()).not.toContain('form-components.editors.fill.input-color.solid');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('form-components.editors.fill.input-color.value');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('5 form-components.editors.fill.input-ramp.buckets');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('column1');
|
||||
expect(this.view.$('.Editor-boxModal').text()).toContain('form-components.editors.fill.quantification.methods.jenks');
|
||||
});
|
||||
|
||||
describe('setting an image', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
stroke: {
|
||||
size: {
|
||||
range: [1, 30],
|
||||
attribute: 'the_geom',
|
||||
quantification: 'Quantile'
|
||||
},
|
||||
color: {
|
||||
bins: 5,
|
||||
range: ['#FFFFFF', '#FABADA', '#00FF00', '#000000', '#999999'],
|
||||
attribute: 'column1',
|
||||
quantification: 'Jenks',
|
||||
opacity: 0.5
|
||||
}
|
||||
},
|
||||
fill: {
|
||||
color: {
|
||||
fixed: '#f1f1f1',
|
||||
opacity: 0.5
|
||||
},
|
||||
size: {
|
||||
fixed: 10
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.view = new Backbone.Form.editors.Fill({
|
||||
key: 'fill',
|
||||
userModel: this._userModel,
|
||||
modals: this.modals,
|
||||
schema: this._schema,
|
||||
model: this.model
|
||||
});
|
||||
|
||||
this.color = this.view._inputCollection.findWhere({ type: 'color' });
|
||||
this.size = this.view._inputCollection.findWhere({ type: 'size' });
|
||||
});
|
||||
|
||||
it('should adjust the min image size if it\'s too small', function () {
|
||||
this.color.set('image', 'test.png');
|
||||
|
||||
expect(this.size.get('fixed')).toBe(20);
|
||||
});
|
||||
|
||||
it('shouldn\'t adjust the image size if its big enough', function () {
|
||||
this.size.set({ fixed: 30 }, { silent: true });
|
||||
this.color.set('image', 'dog.png');
|
||||
|
||||
expect(this.size.get('fixed')).toBe(30);
|
||||
});
|
||||
|
||||
it('shouldn\'t adjust the image size if there was already an image set', function () {
|
||||
this.size.set({ fixed: 1 }, { silent: true });
|
||||
this.color.set({ image: 'duck.png' }, { silent: true });
|
||||
this.color.set('image', 'cat.png');
|
||||
|
||||
expect(this.size.get('fixed')).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setting images', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
stroke: {
|
||||
size: {
|
||||
range: [1, 30],
|
||||
attribute: 'the_geom',
|
||||
quantification: 'Quantile'
|
||||
},
|
||||
color: {
|
||||
bins: 5,
|
||||
range: ['#FFFFFF', '#FABADA', '#00FF00', '#000000', '#999999'],
|
||||
attribute: 'column1',
|
||||
quantification: 'Jenks',
|
||||
opacity: 0.5
|
||||
}
|
||||
},
|
||||
fill: {
|
||||
color: {
|
||||
fixed: '#f1f1f1',
|
||||
opacity: 0.5
|
||||
},
|
||||
size: {
|
||||
fixed: 10
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.view = new Backbone.Form.editors.Fill({
|
||||
key: 'fill',
|
||||
userModel: this._userModel,
|
||||
modals: this.modals,
|
||||
schema: this._schema,
|
||||
model: this.model
|
||||
});
|
||||
|
||||
this.color = this.view._inputCollection.findWhere({ type: 'color' });
|
||||
this.size = this.view._inputCollection.findWhere({ type: 'size' });
|
||||
});
|
||||
|
||||
it('should adjust the min image size if it\'s too small', function () {
|
||||
this.color.set('images', ['test.png']);
|
||||
|
||||
expect(this.size.get('fixed')).toBe(20);
|
||||
});
|
||||
|
||||
it('shouldn\'t adjust the image size if its big enough', function () {
|
||||
this.size.set({ fixed: 30 }, { silent: true });
|
||||
this.color.set('images', ['test.png']);
|
||||
|
||||
expect(this.size.get('fixed')).toBe(30);
|
||||
});
|
||||
|
||||
it('shouldn\'t adjust the image size if there was already an image set', function () {
|
||||
this.size.set({ fixed: 1 }, { silent: true });
|
||||
this.color.set({ images: ['duck.png', 'ping.jpg'] }, { silent: true });
|
||||
this.color.set('images', ['duck.png', 'ping.jpg', 'cat.gif']);
|
||||
|
||||
expect(this.size.get('fixed')).toBe(1);
|
||||
});
|
||||
|
||||
it('shouldn\'t adjust the image size when no image is set', function () {
|
||||
this.size.set({ fixed: 1 }, { silent: true });
|
||||
this.color.set('images', ['']);
|
||||
|
||||
expect(this.size.get('fixed')).toBe(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
var $ = require('jquery');
|
||||
var ColorPicker = require('builder/components/color-picker/color-picker');
|
||||
|
||||
var ESCAPE_KEY_CODE = 27;
|
||||
var simulateEscapeKeyPress = function () {
|
||||
var e = $.Event('keydown');
|
||||
e.keyCode = e.which = ESCAPE_KEY_CODE;
|
||||
$(document).trigger(e);
|
||||
};
|
||||
|
||||
describe('components/form-components/editors/fill/color-picker/color-picker', function () {
|
||||
describe('ESC key press', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(ColorPicker.prototype, '_onEscapePressed');
|
||||
|
||||
this.view = new ColorPicker({
|
||||
value: '#A6CEE3',
|
||||
opacity: 0.5
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should close', function () {
|
||||
simulateEscapeKeyPress();
|
||||
expect(ColorPicker.prototype._onEscapePressed).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe('with opacity', function () {
|
||||
beforeEach(function () {
|
||||
this.view = new ColorPicker({
|
||||
value: '#A6CEE3',
|
||||
opacity: 0.5
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should get render', function () {
|
||||
expect(this.view.$('.js-hex').val()).toBe('#A6CEE3');
|
||||
expect(this.view.$('.js-r').val()).toBe('166');
|
||||
expect(this.view.$('.js-g').val()).toBe('206');
|
||||
expect(this.view.$('.js-b').val()).toBe('227');
|
||||
expect(this.view.$('.js-a').val()).toBe('0.5');
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe('withouth opacity', function () {
|
||||
beforeEach(function () {
|
||||
this.view = new ColorPicker({
|
||||
value: '#A6CEE3',
|
||||
opacity: 0.5,
|
||||
disableOpacity: true
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should disable the opacity selector', function () {
|
||||
expect(this.view.$('.js-a').val()).toBe('0.5');
|
||||
expect(this.view.$('.js-a').hasClass('is-disabled')).toBe(true);
|
||||
expect(this.view.$('.js-colorPicker .js-alpha').hasClass('is-hidden')).toBe(true);
|
||||
});
|
||||
|
||||
it('should change the hex color directly', function () {
|
||||
this.view.$('.js-hex').val('#CCC');
|
||||
var e = $.Event('blur');
|
||||
e.which = 37;
|
||||
this.view.$('.js-hex').trigger(e);
|
||||
|
||||
expect(this.view.model.get('hex')).toBe('#cccccc');
|
||||
});
|
||||
|
||||
it('should change each color individually', function () {
|
||||
this.view.$('.js-r').val('10');
|
||||
this.view.$('.js-g').val('20');
|
||||
this.view.$('.js-b').val('30');
|
||||
var e = $.Event('blur');
|
||||
e.which = 37;
|
||||
this.view.$('.js-r').trigger(e);
|
||||
|
||||
expect(this.view.model.get('hex')).toBe('#0a141e');
|
||||
});
|
||||
|
||||
it('should change each the alpha', function () {
|
||||
this.view.$('.js-a').val('0.7');
|
||||
var e = $.Event('blur');
|
||||
e.which = 37;
|
||||
this.view.$('.js-a').trigger(e);
|
||||
|
||||
expect(this.view.model.get('opacity')).toBe(0.7);
|
||||
});
|
||||
|
||||
it('should show the errors', function () {
|
||||
this.view.$('.js-r').val('10');
|
||||
this.view.$('.js-g').val('20');
|
||||
this.view.$('.js-b').val('what?');
|
||||
var e = $.Event('blur');
|
||||
e.which = 37;
|
||||
this.view.$('.js-b').trigger(e);
|
||||
|
||||
expect(this.view.model.get('hex')).toBe('#A6CEE3');
|
||||
expect(this.view.$('.js-b').hasClass('has-error')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
var _ = require('underscore');
|
||||
var DialogModel = require('builder/components/dialog/dialog-model');
|
||||
var DialogView = require('builder/components/dialog/dialog-view');
|
||||
|
||||
describe('components/fill-dialog', function () {
|
||||
var view, model;
|
||||
|
||||
var createViewFn = function () {
|
||||
model = new DialogModel({});
|
||||
|
||||
var view = new DialogView(({
|
||||
model: model
|
||||
}));
|
||||
|
||||
return view;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
view = createViewFn();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
view.clean();
|
||||
});
|
||||
|
||||
xit('should get rendered', function () {
|
||||
// TODO
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
view.render();
|
||||
expect(view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
view.remove();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
view.render();
|
||||
expect(_.size(view._subviews)).toBe(2);
|
||||
});
|
||||
});
|
||||
+342
@@ -0,0 +1,342 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var InputColor = require('builder/components/input-color/input-color');
|
||||
var rampList = require('builder/components/input-color/input-quantitative-ramps/ramps');
|
||||
var ConfigModel = require('builder/data/config-model');
|
||||
var UserModel = require('builder/data/user-model');
|
||||
var FactoryModals = require('../../../../factories/modals');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color', function () {
|
||||
var svgResponse = {
|
||||
status: 200,
|
||||
contentType: 'image/svg+xml',
|
||||
responseText: '<svg xmlns:a="genius.com" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"><path></path></svg>'
|
||||
};
|
||||
var imgUrl = 'http://www.image.com/image.svg';
|
||||
var fixed = '#c0ffee';
|
||||
|
||||
beforeEach(function () {
|
||||
this.configModel = new ConfigModel({
|
||||
base_url: '/u/pepe'
|
||||
});
|
||||
|
||||
this.userModel = new UserModel({}, {
|
||||
configModel: this.configModel
|
||||
});
|
||||
|
||||
this.modals = FactoryModals.createModalService();
|
||||
|
||||
this.model = new Backbone.Model({
|
||||
bins: 5,
|
||||
range: ['#FFF', '#FABADA', '#00FF00', '#000', '#999999'],
|
||||
attribute: 'column1',
|
||||
quantification: 'jenks',
|
||||
opacity: 0.5
|
||||
});
|
||||
this.view = new InputColor(({
|
||||
model: this.model,
|
||||
userModel: this.userModel,
|
||||
configModel: this.configModel,
|
||||
query: 'SELECT * from table',
|
||||
columns: [
|
||||
{ label: 'column1', type: 'number' },
|
||||
{ label: 'column2', type: 'number' },
|
||||
{ label: 'column3', type: 'number' }
|
||||
]
|
||||
}));
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(_.size(this.view._subviews)).toBe(1);
|
||||
});
|
||||
|
||||
it('should get selected', function () {
|
||||
this.model.set('selected', true);
|
||||
expect(this.view.$el.hasClass('is-active')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should create a content view', function () {
|
||||
expect(this.view.model.get('createContentView')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should trigger a click event when clicked', function () {
|
||||
var clickEvent = false;
|
||||
this.view.bind('click', function () {
|
||||
clickEvent = true;
|
||||
});
|
||||
this.view.$el.click();
|
||||
expect(clickEvent).toBeTruthy();
|
||||
});
|
||||
|
||||
describe('range', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
bins: 5,
|
||||
range: ['#FFFFFF', '#FABADA', '#00FF00', '#000000', '#999999'],
|
||||
attribute: 'column1',
|
||||
quantification: 'Jenks',
|
||||
opacity: 0.50
|
||||
});
|
||||
this.view = new InputColor(({
|
||||
model: this.model,
|
||||
userModel: this.userModel,
|
||||
configModel: this.configModel,
|
||||
query: 'SELECT * from table',
|
||||
columns: [
|
||||
{ label: 'column1', type: 'number' },
|
||||
{ label: 'column2', type: 'number' },
|
||||
{ label: 'column3', type: 'number' }
|
||||
]
|
||||
}));
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$('.ColorBar').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should update when the value has changed', function () {
|
||||
this.model.set('range', ['#FFFFFF', '#FFFF00', '#0000FF']);
|
||||
expect(this.view.$('.ColorBar').length).toBe(1);
|
||||
expect(this.view.$('.ColorBar').attr('style')).toBeDefined();
|
||||
expect(this.view._getValue()).toEqual(['rgba(255, 255, 255, 0.5)', 'rgba(255, 255, 0, 0.5)', 'rgba(0, 0, 255, 0.5)']);
|
||||
});
|
||||
|
||||
it('should set opacity for each color', function () {
|
||||
this.model.set({
|
||||
range: ['#FABADA', '#00FFAA', '#0000FF'],
|
||||
opacity: 0.99
|
||||
});
|
||||
expect(this.view.$('.ColorBar').length).toBe(1);
|
||||
expect(this.view.$('.ColorBar').attr('style')).toBeDefined();
|
||||
expect(this.view._getValue()).toEqual(['rgba(250, 186, 218, 0.99)', 'rgba(0, 255, 170, 0.99)', 'rgba(0, 0, 255, 0.99)']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('image', function () {
|
||||
describe('without image enabled', function () {
|
||||
it('should not render the image', function () {
|
||||
this.view = new InputColor(({
|
||||
model: new Backbone.Model({
|
||||
opacity: 0.5,
|
||||
fixed: fixed,
|
||||
attribute: 'column1'
|
||||
}),
|
||||
userModel: {
|
||||
featureEnabled: function () {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
modals: this.modals,
|
||||
configModel: {},
|
||||
query: 'SELECT * from table',
|
||||
columns: [
|
||||
{ label: 'column1', type: 'string' }
|
||||
]
|
||||
}));
|
||||
|
||||
this.view.render();
|
||||
|
||||
expect(this.view.$('.Editor-fillImage').length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with image enabled', function () {
|
||||
describe('without image', function () {
|
||||
it('should render image link if category images are present', function () {
|
||||
this.view = new InputColor(({
|
||||
model: new Backbone.Model({
|
||||
opacity: 0.5,
|
||||
fixed: fixed,
|
||||
images: [imgUrl, imgUrl, imgUrl],
|
||||
attribute: 'column1'
|
||||
}),
|
||||
userModel: {
|
||||
featureEnabled: function () {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
modals: this.modals,
|
||||
configModel: {},
|
||||
editorAttrs: {
|
||||
imageEnabled: true
|
||||
},
|
||||
query: 'SELECT * from table',
|
||||
columns: [
|
||||
{ label: 'column1', type: 'string' }
|
||||
]
|
||||
}));
|
||||
|
||||
this.view.render();
|
||||
|
||||
expect(this.view.$('.Editor-fillImage').html()).toContain('form-components.editors.fill.input-color.img');
|
||||
});
|
||||
|
||||
it('should not render image link if category images are not present', function () {
|
||||
this.view = new InputColor(({
|
||||
model: new Backbone.Model({
|
||||
opacity: 0.5,
|
||||
fixed: fixed,
|
||||
attribute: 'column1'
|
||||
}),
|
||||
userModel: {
|
||||
featureEnabled: function () {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
modals: this.modals,
|
||||
configModel: {},
|
||||
editorAttrs: {
|
||||
imageEnabled: true
|
||||
},
|
||||
query: 'SELECT * from table',
|
||||
columns: [
|
||||
{ label: 'column1', type: 'string' }
|
||||
]
|
||||
}));
|
||||
|
||||
this.view.render();
|
||||
|
||||
expect(this.view.$('.Editor-fillImage').html()).not.toContain('Img');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with image', function () {
|
||||
var fixture;
|
||||
|
||||
beforeEach(function () {
|
||||
jasmine.Ajax.install();
|
||||
jasmine.Ajax.stubRequest(new RegExp('^http(s)?.*/image.svg'))
|
||||
.andReturn(svgResponse);
|
||||
|
||||
this.view = new InputColor(({
|
||||
model: new Backbone.Model({
|
||||
image: imgUrl,
|
||||
opacity: 0.5,
|
||||
fixed: fixed,
|
||||
attribute: 'column1'
|
||||
}),
|
||||
userModel: {
|
||||
featureEnabled: function () {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
modals: this.modals,
|
||||
configModel: {},
|
||||
editorAttrs: {
|
||||
imageEnabled: true
|
||||
},
|
||||
query: 'SELECT * from table',
|
||||
columns: [
|
||||
{ label: 'column1', type: 'string' }
|
||||
]
|
||||
}));
|
||||
|
||||
// For getting right values from the SVG element, it needs to be attached to the DOM
|
||||
fixture = document.createElement('div');
|
||||
fixture.id = 'fixture';
|
||||
document.getElementsByTagName('body')[0].appendChild(fixture);
|
||||
fixture.appendChild(this.view.$el[0]);
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
fixture.parentNode.removeChild(fixture);
|
||||
jasmine.Ajax.uninstall();
|
||||
});
|
||||
|
||||
it('should render the image', function () {
|
||||
expect(this.view.$('.Editor-fillImage').length).toBe(1);
|
||||
});
|
||||
|
||||
it('SVG should have been loaded', function () {
|
||||
var image = this.view.$('.js-image');
|
||||
|
||||
expect(image[0].tagName.toUpperCase()).toBe('SVG');
|
||||
expect(image.attr('xmlns:a')).toBeUndefined();
|
||||
expect(image.attr('class')).toContain('Editor-fillImageAsset');
|
||||
expect(image.attr('class')).toContain('js-image');
|
||||
var cssFill = image.css('fill').toLowerCase();
|
||||
var pathFill = image.find('path').css('fill').toLowerCase();
|
||||
expect(cssFill === 'rgb(192, 255, 238)' || cssFill === '#c0ffee').toBe(true);
|
||||
expect(pathFill === 'rgb(192, 255, 238)' || pathFill === '#c0ffee').toBe(true);
|
||||
});
|
||||
|
||||
it('._updateImageColor should change fill attribute', function () {
|
||||
// Trigger _updateImageColor via model change
|
||||
this.view.model.set('fixed', '#0FF1CE'); // rgb(15, 241, 206)
|
||||
|
||||
var image = this.view.$('.js-image');
|
||||
var cssFill = image.css('fill').toLowerCase();
|
||||
expect(cssFill === 'rgb(15, 241, 206)' || cssFill === '#0ff1ce').toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('migrate old range', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
bins: 5,
|
||||
range: 'inverted_green',
|
||||
attribute: 'column1',
|
||||
quantification: 'jenks',
|
||||
opacity: 0.5
|
||||
});
|
||||
this.view = new InputColor(({
|
||||
model: this.model,
|
||||
userModel: this.userModel,
|
||||
configModel: this.configModel,
|
||||
query: 'SELECT * from table',
|
||||
columns: [
|
||||
{ label: 'column1', type: 'number' },
|
||||
{ label: 'column2', type: 'number' },
|
||||
{ label: 'column3', type: 'number' }
|
||||
]
|
||||
}));
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should migrate the range', function () {
|
||||
expect(this.model.get('range')).toBe(rampList['inverted_green'][5]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with help', function () {
|
||||
beforeEach(function () {
|
||||
this.view = new InputColor(({
|
||||
model: this.model,
|
||||
userModel: this.userModel,
|
||||
configModel: this.configModel,
|
||||
query: 'SELECT * from table',
|
||||
columns: [
|
||||
{ label: 'column1', type: 'number' },
|
||||
{ label: 'column2', type: 'number' },
|
||||
{ label: 'column3', type: 'number' }
|
||||
],
|
||||
editorAttrs: {
|
||||
help: 'help'
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
describe('.render', function () {
|
||||
it('should render properly', function () {
|
||||
this.view.render();
|
||||
|
||||
expect(_.size(this.view._subviews)).toBe(2);
|
||||
expect(this.view.$('.js-help').attr('data-tooltip')).toContain('help');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have any leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
});
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
var Backbone = require('backbone');
|
||||
var AssetHeaderView = require('builder/components/input-color/assets-picker/asset-header-view');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/assets-picker/asset-header-view', function () {
|
||||
beforeEach(function () {
|
||||
this.assetsCollection = new Backbone.Collection([
|
||||
{ item: 1, state: '' },
|
||||
{ item: 2, state: '' },
|
||||
{ item: 3, state: '' }
|
||||
]);
|
||||
|
||||
this.view = new AssetHeaderView({
|
||||
title: 'Title',
|
||||
editable: true,
|
||||
assetsCollection: this.assetsCollection
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render', function () {
|
||||
expect(this.view.$el.text()).toContain('Title');
|
||||
});
|
||||
|
||||
describe('options', function () {
|
||||
beforeEach(function () {
|
||||
this.assetsCollection.at(0).set('state', 'selected');
|
||||
this.assetsCollection.at(1).set('state', 'selected');
|
||||
});
|
||||
|
||||
it('should show select all link when some items are selected', function () {
|
||||
expect(this.view.$el.find('.js-select-all').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should hide select all link when all items are selected', function () {
|
||||
this.assetsCollection.at(2).set('state', 'selected');
|
||||
expect(this.view.$el.find('.js-select-all').length).toBe(0);
|
||||
});
|
||||
|
||||
it('should show deselect all link if all the items are selected', function () {
|
||||
this.assetsCollection.at(2).set('state', 'selected');
|
||||
expect(this.view.$el.find('.js-deselect-all').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should show remove link when an item is selected', function () {
|
||||
expect(this.view.$el.find('.js-remove').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should hide remove link when no item is selected', function () {
|
||||
this.assetsCollection.at(0).set('state', '');
|
||||
this.assetsCollection.at(1).set('state', '');
|
||||
this.assetsCollection.at(2).set('state', '');
|
||||
expect(this.view.$el.find('.js-remove').length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('triggers', function () {
|
||||
beforeEach(function () {
|
||||
this.assetsCollection.at(0).set('state', 'selected');
|
||||
this.assetsCollection.at(1).set('state', 'selected');
|
||||
});
|
||||
|
||||
it('should trigger select-all event', function () {
|
||||
var selectAllTrigger;
|
||||
|
||||
this.view.bind('select-all', function () {
|
||||
selectAllTrigger = true;
|
||||
});
|
||||
|
||||
this.view.$el.find('.js-select-all').click();
|
||||
expect(selectAllTrigger).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should trigger remove event', function () {
|
||||
var removeTrigger;
|
||||
|
||||
this.view.bind('remove', function () {
|
||||
removeTrigger = true;
|
||||
});
|
||||
|
||||
this.view.$el.find('.js-remove').click();
|
||||
expect(removeTrigger).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should trigger events for each option', function () {
|
||||
var deselectTrigger;
|
||||
|
||||
this.assetsCollection.at(2).set('state', 'selected');
|
||||
|
||||
this.view.bind('deselect-all', function () {
|
||||
deselectTrigger = true;
|
||||
});
|
||||
|
||||
this.view.$el.find('.js-deselect-all').click();
|
||||
expect(deselectTrigger).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.clean();
|
||||
});
|
||||
});
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var CoreView = require('backbone/core-view');
|
||||
var AssetsListView = require('builder/components/input-color/assets-picker/assets-list-view');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/asset-picker/assets-list-view', function () {
|
||||
function createViewFn (options) {
|
||||
var icons = [
|
||||
{ name: 'icon1', icon: 'icon1' },
|
||||
{ name: 'icon2', icon: 'icon2' },
|
||||
{ name: 'icon3', icon: 'icon3' }
|
||||
];
|
||||
|
||||
this.view = new AssetsListView(_.extend({
|
||||
selectedAsset: new Backbone.Model(),
|
||||
title: 'Title',
|
||||
icons: icons,
|
||||
disclaimer: 'Disclaimer',
|
||||
folder: 'folder',
|
||||
kind: 'marker',
|
||||
size: '10'
|
||||
}, options));
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
this.createView = createViewFn.bind(this);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
|
||||
describe('.initialize', function () {
|
||||
it('should call ._setupAssets and get assets with default options if no options provided', function () {
|
||||
this.createView();
|
||||
|
||||
var itemNames = _.map(this.view._assetsCollection.models, function (model) {
|
||||
return model.attributes.name;
|
||||
});
|
||||
|
||||
expect(itemNames.length).toBe(3);
|
||||
expect(_.contains(itemNames, 'icon1'));
|
||||
expect(_.contains(itemNames, 'icon2'));
|
||||
expect(_.contains(itemNames, 'icon3'));
|
||||
});
|
||||
|
||||
it('should call ._setupAssets and get assets with provided options', function () {
|
||||
this.createView({
|
||||
folder: 'a folder',
|
||||
size: 48,
|
||||
host: 'a host',
|
||||
ext: 'an extension'
|
||||
});
|
||||
|
||||
_.each(this.view._assetsCollection.models, function (model) {
|
||||
expect(model.attributes.ext).toBe('an extension');
|
||||
expect(model.attributes.folder).toBe('a folder');
|
||||
expect(model.attributes.host).toBe('a host');
|
||||
expect(model.attributes.size).toBe(48);
|
||||
});
|
||||
});
|
||||
|
||||
it('should limit asset collection length if limit option is present', function () {
|
||||
this.createView({
|
||||
limit: 2
|
||||
});
|
||||
|
||||
var itemNames = _.map(this.view._assetsCollection.models, function (model) {
|
||||
return model.attributes.name;
|
||||
});
|
||||
|
||||
expect(itemNames.length).toBe(2);
|
||||
expect(_.contains(itemNames, 'icon1'));
|
||||
expect(_.contains(itemNames, 'icon2'));
|
||||
});
|
||||
|
||||
it('should add related models', function () {
|
||||
spyOn(CoreView.prototype, 'add_related_model').and.callThrough();
|
||||
this.createView();
|
||||
|
||||
expect(CoreView.prototype.add_related_model).toHaveBeenCalledWith(this.view._assetsCollection);
|
||||
});
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('should render icons according to the template', function () {
|
||||
this.createView();
|
||||
|
||||
this.view.render();
|
||||
|
||||
var expectedIcons = ['icon1', 'icon2', 'icon3'];
|
||||
_.each(expectedIcons, function (icon) {
|
||||
var $icon = this.view.$("img[alt='" + icon + "']");
|
||||
expect($icon.length).toBe(1);
|
||||
expect($icon.attr('crossorigin')).toBe('anonymous');
|
||||
expect($icon.attr('src').indexOf(icon)).not.toBe(0);
|
||||
}, this);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._selectItem', function () {
|
||||
it('should select given item and deselect the others', function () {
|
||||
var selectedAsset = new Backbone.Model();
|
||||
|
||||
this.createView({
|
||||
selectedAsset: selectedAsset
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
|
||||
var url = this.view.$('.AssetsList-item:nth-child(1) img').attr('src');
|
||||
this.view.$('.AssetsList-item:nth-child(1) .js-asset').click();
|
||||
|
||||
expect(selectedAsset.get('url')).toBe(url);
|
||||
expect(selectedAsset.get('kind')).toBe('marker');
|
||||
});
|
||||
});
|
||||
});
|
||||
+327
@@ -0,0 +1,327 @@
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
var ConfigModel = require('builder/data/config-model');
|
||||
var UserModel = require('builder/data/user-model');
|
||||
var AssetsView = require('builder/components/input-color/assets-picker/assets-view');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/assets-view', function () {
|
||||
var createCalls = [];
|
||||
var files = ['one', 'two'];
|
||||
|
||||
beforeEach(function () {
|
||||
spyOn($, 'ajax').and.callFake(function (req) {
|
||||
var d = $.Deferred();
|
||||
d.resolve();
|
||||
return d.promise();
|
||||
});
|
||||
|
||||
this.model = new Backbone.Model();
|
||||
|
||||
this._configModel = new ConfigModel({
|
||||
base_url: '/u/pepe'
|
||||
});
|
||||
|
||||
this._userModel = new UserModel({}, {
|
||||
configModel: this._configModel
|
||||
});
|
||||
|
||||
this.view = new AssetsView({
|
||||
model: this.model,
|
||||
modalModel: {
|
||||
destroy: function () {}
|
||||
},
|
||||
configModel: this._configModel,
|
||||
userModel: this._userModel
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
function mockCreate (callback) {
|
||||
this.view._userAssetCollection.create = function (options, callbacks) {
|
||||
var createCall = {
|
||||
kind: options.kind,
|
||||
type: options.type,
|
||||
url: options.url,
|
||||
filename: options.filename,
|
||||
callbacks: callbacks
|
||||
};
|
||||
|
||||
var model = this.add(options);
|
||||
|
||||
createCalls.push(createCall);
|
||||
|
||||
if (callback) {
|
||||
if (callback === 'error') {
|
||||
callbacks[callback].call(this, model, {
|
||||
responseText: '{"error": ["hi, I am an error"]}'
|
||||
});
|
||||
} else if (callback === 'success') {
|
||||
callbacks['complete'].call(this);
|
||||
callbacks[callback].call(this);
|
||||
} else {
|
||||
callbacks[callback].call(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
describe('render', function () {
|
||||
it('should render tabs', function () {
|
||||
expect(this.view.$el.text()).toBeDefined();
|
||||
expect(this.view.$el.text()).toContain('components.modals.add-asset.icons');
|
||||
expect(this.view.$el.text()).toContain('components.modals.add-asset.your-uploads');
|
||||
expect(this.view.$el.text()).toContain('components.modals.add-asset.upload-file');
|
||||
});
|
||||
|
||||
it('should render upload button', function () {
|
||||
expect(this.view.$('.js-add').length).toBe(1);
|
||||
expect(this.view.$('.js-add').hasClass('is-disabled')).toBeTruthy();
|
||||
expect(this.view._stateModel.get('modalEnabled')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should toggle the set button state', function () {
|
||||
this.view._stateModel.set('modalEnabled', true);
|
||||
expect(this.view.$('.js-add').hasClass('is-disabled')).toBeFalsy();
|
||||
this.view._stateModel.set('modalEnabled', false);
|
||||
expect(this.view.$('.js-add').hasClass('is-disabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should toggle the set button state when there\'s no image selected', function () {
|
||||
this.view._selectedAsset.set('url', 'batman.png');
|
||||
expect(this.view.$('.js-add').hasClass('is-disabled')).toBeFalsy();
|
||||
expect(this.view._stateModel.get('modalEnabled')).toBeTruthy();
|
||||
|
||||
this.view._selectedAsset.set('url', '');
|
||||
expect(this.view.$('.js-add').hasClass('is-disabled')).toBeTruthy();
|
||||
expect(this.view._stateModel.get('modalEnabled')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should render disclaimer', function () {
|
||||
expect(this.view.$el.text()).toContain('assets.maki-icons.disclaimer');
|
||||
});
|
||||
});
|
||||
|
||||
describe('._initSetButtonState', function () {
|
||||
beforeEach(function () {
|
||||
this._userModel.getOrganization = function () {
|
||||
return new Backbone.Model({ id: 1 });
|
||||
};
|
||||
|
||||
this._userModel.isInsideOrg = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
this.view = new AssetsView({
|
||||
model: this.model,
|
||||
modalModel: {
|
||||
destroy: function () {}
|
||||
},
|
||||
configModel: this._configModel,
|
||||
userModel: this._userModel
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should return nothing if there\'s no image selected', function () {
|
||||
this.view.model.set('image', null);
|
||||
expect(this.view._initSetButtonState()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should enable the button if a marker is set', function () {
|
||||
this.model.set({ image: 'hi.png', kind: 'marker' });
|
||||
this.view._initSetButtonState();
|
||||
|
||||
expect(this.view.$('.js-add').hasClass('is-disabled')).toBeFalsy();
|
||||
expect(this.view._stateModel.get('modalEnabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should enable the button if a user icon is set', function () {
|
||||
this.model.set({ image: 'hi.png', kind: 'custom-marker' });
|
||||
this.view._userAssetCollection.add({ public_url: 'hi.png' });
|
||||
|
||||
this.view._initSetButtonState();
|
||||
|
||||
expect(this.view.$('.js-add').hasClass('is-disabled')).toBeFalsy();
|
||||
expect(this.view._stateModel.get('modalEnabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should enable the button if an org icon is set', function () {
|
||||
this.model.set({ image: 'hi.png', kind: 'custom-marker' });
|
||||
this.view._organizationAssetCollection.add({ public_url: 'hi.png' });
|
||||
|
||||
this.view._initSetButtonState();
|
||||
|
||||
expect(this.view.$('.js-add').hasClass('is-disabled')).toBeFalsy();
|
||||
expect(this.view._stateModel.get('modalEnabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.clean();
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onFileSelected', function () {
|
||||
it('should create an icon model for each selected file', function () {
|
||||
mockCreate.call(this);
|
||||
spyOn(this.view, '_getSelectedFiles').and.returnValue(files);
|
||||
spyOn(this.view, '_beforeAssetUpload');
|
||||
spyOn(this.view, '_onAssetUploaded');
|
||||
spyOn(this.view, '_onAssetUploadError');
|
||||
spyOn(this.view, '_onAssetUploadComplete');
|
||||
|
||||
this.view._onFileSelected();
|
||||
|
||||
expect(createCalls.length).toBe(2);
|
||||
expect(createCalls[0].kind).toEqual('custom-marker');
|
||||
expect(createCalls[0].filename).toEqual(files[0]);
|
||||
expect(createCalls[0].type).toEqual('file');
|
||||
expect(createCalls[1].kind).toEqual('custom-marker');
|
||||
expect(createCalls[1].filename).toEqual(files[1]);
|
||||
expect(createCalls[1].type).toEqual('file');
|
||||
|
||||
// Assert that every request callback has been hooked up
|
||||
createCalls[0].callbacks['beforeSend']();
|
||||
expect(this.view._beforeAssetUpload).toHaveBeenCalled();
|
||||
createCalls[0].callbacks['success']();
|
||||
expect(this.view._onAssetUploaded).toHaveBeenCalled();
|
||||
createCalls[0].callbacks['error']();
|
||||
expect(this.view._onAssetUploadError).toHaveBeenCalled();
|
||||
createCalls[0].callbacks['complete']();
|
||||
expect(this.view._onAssetUploadComplete).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('._beforeAssetUpload', function () {
|
||||
it('should set loading state', function () {
|
||||
this.view._beforeAssetUpload();
|
||||
expect(this.view._stateModel.get('uploads')).toBe(1);
|
||||
expect(this.view._stateModel.get('status')).toBe('loading');
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onAssetUploaded', function () {
|
||||
it('should reset selection after a successfull upload', function () {
|
||||
mockCreate.call(this, 'success');
|
||||
spyOn(this.view, '_resetFileSelection');
|
||||
spyOn(this.view, '_getSelectedFiles').and.returnValue(files);
|
||||
|
||||
this.view.$('.js-fileInput').trigger('change');
|
||||
|
||||
expect(this.view._resetFileSelection).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should render the new uploaded file and go to the uploads tab', function () {
|
||||
mockCreate.call(this, 'success');
|
||||
spyOn(this.view, '_getSelectedFiles').and.returnValue(['file.png']);
|
||||
|
||||
this.view.$('.js-fileInput').trigger('change');
|
||||
expect(this.view.$('.AssetsList-item').length).toBe(2);
|
||||
expect(this.view._assetsTabPaneView.getSelectedTabPane().get('name')).toBe('your-uploads');
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onAssetUploadError', function () {
|
||||
beforeEach(function () {
|
||||
mockCreate.call(this, 'error');
|
||||
spyOn(this.view, '_getSelectedFiles').and.returnValue(files);
|
||||
spyOn(this.view, '_resetFileSelection');
|
||||
this.view.$('.js-fileInput').trigger('change');
|
||||
});
|
||||
|
||||
it('should reset selection', function () {
|
||||
expect(this.view._resetFileSelection).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should show the proper error message', function () {
|
||||
expect(this.view._stateModel.get('error_message')).toBe('hi, I am an error');
|
||||
expect(this.view._stateModel.get('status')).toBe('error');
|
||||
});
|
||||
|
||||
it('should remove the model from _userAssetCollection', function () {
|
||||
expect(this.view._userAssetCollection.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._uploadURL', function () {
|
||||
it('should create an upload', function () {
|
||||
var url = 'http://carto.com/img/pin.png';
|
||||
|
||||
mockCreate.call(this);
|
||||
spyOn(this.view, '_beforeAssetUpload');
|
||||
spyOn(this.view, '_onAssetUploaded');
|
||||
spyOn(this.view, '_onAssetUploadError');
|
||||
spyOn(this.view, '_onAssetUploadComplete');
|
||||
|
||||
this.view._uploadURL(url);
|
||||
|
||||
expect(createCalls.length).toBe(1);
|
||||
expect(createCalls[0].kind).toEqual('custom-marker');
|
||||
expect(createCalls[0].url).toEqual(url);
|
||||
expect(createCalls[0].type).toEqual('url');
|
||||
|
||||
// Assert that every request callback has been hooked up
|
||||
createCalls[0].callbacks['beforeSend']();
|
||||
expect(this.view._beforeAssetUpload).toHaveBeenCalled();
|
||||
createCalls[0].callbacks['success']();
|
||||
expect(this.view._onAssetUploaded).toHaveBeenCalled();
|
||||
createCalls[0].callbacks['error']();
|
||||
expect(this.view._onAssetUploadError).toHaveBeenCalled();
|
||||
createCalls[0].callbacks['complete']();
|
||||
expect(this.view._onAssetUploadComplete).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onAssetUploadComplete', function () {
|
||||
it('should go to the upload tab', function () {
|
||||
this.view._stateModel.set('uploads', 2);
|
||||
|
||||
mockCreate.call(this, 'complete');
|
||||
|
||||
spyOn(this.view, '_getSelectedFiles').and.returnValue(files);
|
||||
|
||||
this.view.$('.js-fileInput').trigger('change');
|
||||
|
||||
expect(this.view._stateModel.get('status')).toBe('show');
|
||||
expect(this.view._stateModel.get('uploads')).toBe(0);
|
||||
expect(this.view._assetsTabPaneView.getSelectedTabPaneName()).toBe('your-uploads');
|
||||
});
|
||||
});
|
||||
|
||||
describe('_onSetImage', function () {
|
||||
it('should kill event, trigger a `change` event and destroy modal', function () {
|
||||
var changeTriggered = false;
|
||||
var changeImage;
|
||||
|
||||
this.view._selectedAsset.set({
|
||||
url: 'batman.png',
|
||||
kind: 'marker'
|
||||
});
|
||||
|
||||
this.view.on('change', function (data) {
|
||||
changeTriggered = true;
|
||||
changeImage = data;
|
||||
});
|
||||
spyOn(this.view, 'killEvent');
|
||||
spyOn(this.view._modalModel, 'destroy');
|
||||
|
||||
this.view.$('.js-add').click();
|
||||
|
||||
expect(this.view.killEvent).toHaveBeenCalled();
|
||||
expect(changeTriggered).toBe(true);
|
||||
expect(changeImage.url).toBe('batman.png');
|
||||
expect(changeImage.kind).toBe('marker');
|
||||
expect(this.view._modalModel.destroy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
createCalls = [];
|
||||
this.view.clean();
|
||||
});
|
||||
});
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
var Backbone = require('backbone');
|
||||
var InputAssetPickerHeader = require('builder/components/input-color/assets-picker/input-asset-picker-header');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/assets-picker/input-asset-picker-header', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
index: 0,
|
||||
ramp: [{
|
||||
color: '#FF0000',
|
||||
title: 'hola',
|
||||
image: 'http://www.image.com/image.jpg'
|
||||
}]
|
||||
});
|
||||
|
||||
this.view = new InputAssetPickerHeader({
|
||||
index: 0,
|
||||
model: this.model
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('should render template', function () {
|
||||
expect(this.view.$el.html()).toContain('CDB-Box-modalHeader');
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getRampItem', function () {
|
||||
it('should return ramp item element', function () {
|
||||
var item = this.view._getRampItem();
|
||||
expect(item.color).toBe('#FF0000');
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onClickBack', function () {
|
||||
it('should trigger back function', function () {
|
||||
var isBack;
|
||||
|
||||
this.view.bind('back', function () {
|
||||
isBack = true;
|
||||
}, this);
|
||||
|
||||
this.view.$('.js-back').click();
|
||||
expect(isBack).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onGoToColorPicker', function () {
|
||||
it('should trigger goToColorPicker function', function () {
|
||||
var isInColorPicker;
|
||||
|
||||
this.view.bind('goToColorPicker', function () {
|
||||
isInColorPicker = true;
|
||||
}, this);
|
||||
|
||||
this.view.$('.js-colorPicker').click();
|
||||
expect(isInColorPicker).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.clean();
|
||||
});
|
||||
});
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
var InputAssetPickerView = require('builder/components/input-color/assets-picker/input-asset-picker-view');
|
||||
var UserModel = require('builder/data/user-model');
|
||||
var ConfigModel = require('builder/data/config-model');
|
||||
var FactoryModals = require('../../../../../../factories/modals');
|
||||
var Backbone = require('backbone');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/assets-picker/input-asset-picker-view', function () {
|
||||
beforeEach(function () {
|
||||
this.userModel = new UserModel({
|
||||
username: 'pepe'
|
||||
}, {
|
||||
configModel: 'c'
|
||||
});
|
||||
|
||||
this.configModel = new ConfigModel({
|
||||
base_url: '/u/pepe'
|
||||
});
|
||||
|
||||
this.model = new Backbone.Model({
|
||||
ramp: [{
|
||||
color: '#FABADA',
|
||||
title: 'hola',
|
||||
image: 'http://www.image.com/image.jpg'
|
||||
}]
|
||||
});
|
||||
|
||||
this.view = new InputAssetPickerView({
|
||||
index: 0,
|
||||
ramp: [{
|
||||
color: '#FABADA',
|
||||
title: 'hola',
|
||||
image: 'http://www.image.com/image.jpg'
|
||||
}],
|
||||
userModel: this.userModel,
|
||||
configModel: this.configModel,
|
||||
modals: FactoryModals.createModalService()
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('should render _headerView', function () {
|
||||
expect(this.view._headerView).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render _assetPicker', function () {
|
||||
expect(this.view._assetPicker).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('._getRampItem', function () {
|
||||
it('should return ramp item element', function () {
|
||||
var item = this.view._getRampItem();
|
||||
expect(item.color).toBe('#FABADA');
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onChangeImage', function () {
|
||||
it('should trigger change:image on view and model', function () {
|
||||
this.view._onChangeImage({ url: 'new_image' });
|
||||
|
||||
expect(this.view.options.ramp[0].image).toBe('new_image');
|
||||
expect(this.view.model.get('ramp')[0].image).toBe('new_image');
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onClickBack', function () {
|
||||
it('should trigger back function', function () {
|
||||
var isBack;
|
||||
|
||||
this.view._headerView.bind('back', function () {
|
||||
isBack = true;
|
||||
}, this);
|
||||
|
||||
this.view._headerView.$('.js-back').click();
|
||||
expect(isBack).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onGoToColorPicker', function () {
|
||||
it('should trigger goToColorPicker function', function () {
|
||||
var isInColorPicker;
|
||||
|
||||
this.view._headerView.bind('goToColorPicker', function () {
|
||||
isInColorPicker = true;
|
||||
}, this);
|
||||
|
||||
this.view._headerView.$('.js-colorPicker').click();
|
||||
expect(isInColorPicker).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.clean();
|
||||
});
|
||||
});
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
var ConfigModel = require('builder/data/config-model');
|
||||
var UserModel = require('builder/data/user-model');
|
||||
var AssetsCollection = require('builder/data/assets-collection');
|
||||
var OrganizationAssetsCollection = require('builder/data/organization-assets-collection');
|
||||
var OrganizationAssetsListView = require('builder/components/input-color/assets-picker/organization-assets-list-view');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/assets-picker/organization-assets-list-view', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
image: '/image.png'
|
||||
});
|
||||
this.selectedAsset = new Backbone.Model();
|
||||
|
||||
var configModel = new ConfigModel({
|
||||
base_url: '/u/pepe'
|
||||
});
|
||||
|
||||
var userModel = new UserModel({}, {
|
||||
configModel: configModel
|
||||
});
|
||||
|
||||
this._userAssetCollection = new AssetsCollection([{
|
||||
item: 1, state: ''
|
||||
}, {
|
||||
item: 2, state: ''
|
||||
}, {
|
||||
item: 3, state: ''
|
||||
}], {
|
||||
configModel: configModel,
|
||||
userModel: userModel
|
||||
});
|
||||
|
||||
this._organizationAssetCollection = new OrganizationAssetsCollection([{
|
||||
item: 1, state: ''
|
||||
}, {
|
||||
item: 2, state: ''
|
||||
}, {
|
||||
item: 3, state: ''
|
||||
}], {
|
||||
configModel: configModel,
|
||||
orgId: userModel
|
||||
});
|
||||
|
||||
this.view = new OrganizationAssetsListView({
|
||||
title: 'Title',
|
||||
model: this.model,
|
||||
userAssetCollection: this._userAssetCollection,
|
||||
organizationAssetCollection: this._organizationAssetCollection,
|
||||
selectedAsset: this.selectedAsset,
|
||||
userModel: userModel
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render the assets', function () {
|
||||
expect(this.view.$el.find('.js-asset').length).toBe(this._userAssetCollection.size());
|
||||
});
|
||||
|
||||
it('should select an asset and deselect all the user assets', function () {
|
||||
this._userAssetCollection.at(0).set('state', 'selected');
|
||||
|
||||
expect(this._organizationAssetCollection.where({ state: 'selected' }).length).toBe(0);
|
||||
expect(this._organizationAssetCollection.at(0).get('state')).toBe('');
|
||||
expect(this._userAssetCollection.where({ state: 'selected' }).length).toBe(1);
|
||||
expect(this._userAssetCollection.at(0).get('state')).toBe('selected');
|
||||
|
||||
$(this.view.$('.js-asset')[0]).click();
|
||||
|
||||
expect(this.view.$('.is-selected').length).toBe(1);
|
||||
expect(this._organizationAssetCollection.where({ state: 'selected' }).length).toBe(1);
|
||||
expect(this._organizationAssetCollection.at(0).get('state')).toBe('selected');
|
||||
expect(this._userAssetCollection.where({ state: 'selected' }).length).toBe(0);
|
||||
expect(this._userAssetCollection.at(0).get('state')).toBe('');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.clean();
|
||||
});
|
||||
});
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
var Backbone = require('backbone');
|
||||
var _ = require('underscore');
|
||||
var View = require('builder/components/input-color/assets-picker/static-asset-item-view');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/asset-picker/static-asset-item-view', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
state: ''
|
||||
});
|
||||
this.view = new View({ model: this.model });
|
||||
});
|
||||
|
||||
describe('initialize', function () {
|
||||
it('should bind change:state that toggles selected', function () {
|
||||
expect(_.indexOf(this.view.$el[0].classList, 'is-selected')).toBe(-1);
|
||||
|
||||
this.view.model.set('state', 'selected');
|
||||
|
||||
expect(_.indexOf(this.view.$el[0].classList, 'is-selected')).not.toBe(-1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onClick', function () {
|
||||
it('should kill event, trigger selected and change model state', function () {
|
||||
var selectedTriggered = false;
|
||||
var selectedPayload;
|
||||
this.view.on('selected', function (payload) {
|
||||
selectedTriggered = true;
|
||||
selectedPayload = payload;
|
||||
});
|
||||
var event = 'an event';
|
||||
spyOn(this.view, 'killEvent');
|
||||
|
||||
this.view._onClick(event);
|
||||
|
||||
expect(this.view.killEvent).toHaveBeenCalledWith(event);
|
||||
expect(selectedTriggered).toBe(true);
|
||||
expect(selectedPayload).toBe(this.model);
|
||||
expect(this.view.model.get('state')).toBe('selected');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
// render function is already tested in assets-list-view.spec.js render
|
||||
});
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
var Backbone = require('backbone');
|
||||
var ConfigModel = require('builder/data/config-model');
|
||||
var UserModel = require('builder/data/user-model');
|
||||
var UploadAssetsTab = require('builder/components/input-color/assets-picker/upload-assets-tab');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/assets-picker/upoad-assets-tab', function () {
|
||||
beforeEach(function () {
|
||||
var configModel = new ConfigModel({
|
||||
base_url: '/u/pepe'
|
||||
});
|
||||
|
||||
var userModel = new UserModel({}, {
|
||||
configModel: configModel
|
||||
});
|
||||
|
||||
this.view = new UploadAssetsTab({
|
||||
model: new Backbone.Model(),
|
||||
configModel: configModel,
|
||||
userModel: userModel
|
||||
});
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render', function () {
|
||||
expect(this.view.$el.text()).toContain('components.modals.assets-picker.upload-desc');
|
||||
expect(this.view.$el.text()).toContain('components.modals.assets-picker.submit');
|
||||
expect(this.view.$el.text()).toContain('components.modals.assets-picker.upload-file-url');
|
||||
});
|
||||
|
||||
describe('._onClickSubmit', function () {
|
||||
it('should trigger an event', function () {
|
||||
var uploadURLEvent;
|
||||
var uploadURLEventData;
|
||||
|
||||
this.view.bind('upload-url', function (data) {
|
||||
uploadURLEvent = true;
|
||||
uploadURLEventData = data;
|
||||
}, this);
|
||||
|
||||
var url = 'http://carto.com/pizza.png';
|
||||
this.view.$('.js-url').val(url);
|
||||
this.view.$('.js-submit').click();
|
||||
|
||||
expect(uploadURLEvent).toBeTruthy();
|
||||
expect(uploadURLEventData).toBe(url);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.clean();
|
||||
});
|
||||
});
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
var UserAssetsListView = require('builder/components/input-color/assets-picker/user-assets-list-view');
|
||||
var AssetsCollection = require('builder/data/assets-collection');
|
||||
var ConfigModel = require('builder/data/config-model');
|
||||
var UserModel = require('builder/data/user-model');
|
||||
var OrganizationAssetsCollection = require('builder/data/organization-assets-collection');
|
||||
var AssetModel = require('builder/data/asset-model');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/assets-picker/user-assets-list-view', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
image: '/image.png'
|
||||
});
|
||||
this.selectedAsset = new Backbone.Model();
|
||||
|
||||
this.configModel = new ConfigModel({
|
||||
base_url: '/u/pepe'
|
||||
});
|
||||
|
||||
this.userModel = new UserModel({}, {
|
||||
configModel: this.configModel
|
||||
});
|
||||
|
||||
var asset1 = new AssetModel({
|
||||
item: 1, state: '', public_url: 'one.jpg'
|
||||
});
|
||||
|
||||
var asset2 = new AssetModel({
|
||||
item: 2, state: '', public_url: 'two.png'
|
||||
});
|
||||
|
||||
var asset3 = new AssetModel({
|
||||
item: 3, state: '', public_url: 'three.gif'
|
||||
});
|
||||
|
||||
this._userAssetCollection = new AssetsCollection([asset1, asset2, asset3], {
|
||||
configModel: this.configModel,
|
||||
userModel: this.userModel
|
||||
});
|
||||
|
||||
this.view = new UserAssetsListView({
|
||||
title: 'Title',
|
||||
model: this.model,
|
||||
userAssetCollection: this._userAssetCollection,
|
||||
selectedAsset: this.selectedAsset,
|
||||
userModel: this.userModel
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render the assets', function () {
|
||||
expect(this.view.$el.find('.js-asset').length).toBe(this._userAssetCollection.size() + 1);
|
||||
});
|
||||
|
||||
it('should render the add button', function () {
|
||||
expect(this.view.$el.find('.AssetsList-item--text .js-asset').text().trim()).toBe('+');
|
||||
expect(this.view.$el.find('.AssetsList-item--text .js-asset').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should trigger an upload event when clicking the add button', function () {
|
||||
var triggered = false;
|
||||
|
||||
this.view.bind('init-upload', function () {
|
||||
triggered = true;
|
||||
}, this);
|
||||
|
||||
this.view.$el.find('.AssetsList-item--text .js-asset').click();
|
||||
expect(triggered).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should select an asset', function () {
|
||||
this._userAssetCollection.at(0).set('state', '');
|
||||
this._userAssetCollection.at(1).set('state', '');
|
||||
this._userAssetCollection.at(2).set('state', '');
|
||||
|
||||
expect(this._userAssetCollection.where({ state: 'selected' }).length).toBe(0);
|
||||
$(this.view.$('.js-asset')[1]).click();
|
||||
expect(this.view.$('.is-selected').length).toBe(1);
|
||||
expect(this._userAssetCollection.where({ state: 'selected' }).length).toBe(1);
|
||||
expect(this._userAssetCollection.at(0).get('state')).toBe('selected');
|
||||
});
|
||||
|
||||
it('should select all the assets', function () {
|
||||
this._userAssetCollection.at(0).set('state', 'selected');
|
||||
|
||||
this.view.$('.js-select-all').click();
|
||||
expect(this.view.$('.is-selected').length).toBe(3);
|
||||
expect(this._userAssetCollection.at(0).get('state')).toBe('selected');
|
||||
expect(this._userAssetCollection.at(1).get('state')).toBe('selected');
|
||||
expect(this._userAssetCollection.at(2).get('state')).toBe('selected');
|
||||
});
|
||||
|
||||
it('should deselect all the assets', function () {
|
||||
this._userAssetCollection.at(0).set('state', 'selected');
|
||||
this._userAssetCollection.at(1).set('state', 'selected');
|
||||
this._userAssetCollection.at(2).set('state', 'selected');
|
||||
|
||||
this.view.$('.js-deselect-all').click();
|
||||
expect(this._userAssetCollection.at(0).get('state')).toBe('');
|
||||
expect(this._userAssetCollection.at(1).get('state')).toBe('');
|
||||
expect(this._userAssetCollection.at(2).get('state')).toBe('');
|
||||
expect(this.view.$('.is-selected').length).toBe(0);
|
||||
});
|
||||
|
||||
describe('when user is inside organization', function () {
|
||||
var view;
|
||||
|
||||
beforeEach(function () {
|
||||
spyOn(this.userModel, 'isInsideOrg').and.returnValue(true);
|
||||
|
||||
this._organizationAssetCollection = new OrganizationAssetsCollection([{
|
||||
item: 1, state: ''
|
||||
}, {
|
||||
item: 2, state: ''
|
||||
}, {
|
||||
item: 3, state: ''
|
||||
}], {
|
||||
configModel: this.configModel,
|
||||
orgId: this.userModel
|
||||
});
|
||||
|
||||
view = new UserAssetsListView({
|
||||
title: 'Title',
|
||||
model: this.model,
|
||||
userAssetCollection: this._userAssetCollection,
|
||||
organizationAssetCollection: this._organizationAssetCollection,
|
||||
selectedAsset: this.selectedAsset,
|
||||
userModel: this.userModel
|
||||
});
|
||||
|
||||
view.render();
|
||||
});
|
||||
|
||||
it('should select an asset and deselect all the organization assets', function () {
|
||||
this._organizationAssetCollection.at(0).set('state', 'selected');
|
||||
|
||||
expect(this._userAssetCollection.where({ state: 'selected' }).length).toBe(0);
|
||||
expect(this._userAssetCollection.at(0).get('state')).toBe('');
|
||||
expect(this._organizationAssetCollection.where({ state: 'selected' }).length).toBe(1);
|
||||
expect(this._organizationAssetCollection.at(0).get('state')).toBe('selected');
|
||||
|
||||
$(view.$('.js-asset')[1]).click();
|
||||
|
||||
expect(this.view.$('.is-selected').length).toBe(1);
|
||||
expect(this._userAssetCollection.where({ state: 'selected' }).length).toBe(1);
|
||||
expect(this._userAssetCollection.at(0).get('state')).toBe('selected');
|
||||
expect(this._organizationAssetCollection.where({ state: 'selected' }).length).toBe(0);
|
||||
expect(this._organizationAssetCollection.at(0).get('state')).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
it('should remove selected assets', function () {
|
||||
this._userAssetCollection.at(0).set('state', 'selected');
|
||||
this._userAssetCollection.at(1).set('state', 'selected');
|
||||
this._userAssetCollection.at(2).set('state', '');
|
||||
|
||||
this.view.$('.js-remove').click();
|
||||
expect(this._userAssetCollection.size()).toBe(1);
|
||||
});
|
||||
|
||||
it('should unset the selected asset', function () {
|
||||
var self = this;
|
||||
|
||||
AssetModel.prototype.destroy = function () {
|
||||
self.view._onDestroyFinished({ status: 200 });
|
||||
};
|
||||
|
||||
this._userAssetCollection.at(0).set('state', 'selected');
|
||||
this._userAssetCollection.at(1).set('state', '');
|
||||
this._userAssetCollection.at(2).set('state', '');
|
||||
|
||||
expect(this.selectedAsset.get('url')).toBe('one.jpg');
|
||||
expect(this.selectedAsset.get('kind')).toBe('custom-marker');
|
||||
|
||||
this.view.$('.js-remove').click();
|
||||
expect(this.selectedAsset.get('url')).toBe(undefined);
|
||||
expect(this.selectedAsset.get('kind')).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.clean();
|
||||
});
|
||||
});
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var InputColorDialogContent = require('builder/components/input-color/input-color-dialog-content');
|
||||
var FactoryModals = require('../../../../../factories/modals');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/input-color-dialog-content', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
bins: 5,
|
||||
range: ['#FFF', '#FABADA', '#00FF00', '#000', '#999999'],
|
||||
attribute: 'column1',
|
||||
quantification: 'jenks',
|
||||
opacity: 0.5
|
||||
});
|
||||
this.view = new InputColorDialogContent(({
|
||||
configModel: {},
|
||||
userModel: {
|
||||
featureEnabled: function () { return true; }
|
||||
},
|
||||
modals: FactoryModals.createModalService(),
|
||||
query: 'SELECT * from table',
|
||||
columns: [
|
||||
{ label: 'column1', type: 'number' },
|
||||
{ label: 'column2', type: 'number' },
|
||||
{ label: 'column3', type: 'number' }
|
||||
],
|
||||
model: this.model,
|
||||
editorAttrs: {}
|
||||
}));
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render', function () {
|
||||
expect(_.size(this.view._subviews)).toBe(1);
|
||||
});
|
||||
|
||||
it('should generate two panes', function () {
|
||||
expect(this.view.$el.html()).toContain('form-components.editors.fill.input-color.solid');
|
||||
expect(this.view.$el.html()).toContain('form-components.editors.fill.input-color.value');
|
||||
});
|
||||
|
||||
it('should populate hideTabs attribute if it is received as option', function () {
|
||||
var view = new InputColorDialogContent(({
|
||||
configModel: {},
|
||||
userModel: {
|
||||
featureEnabled: function () { return true; }
|
||||
},
|
||||
modals: FactoryModals.createModalService(),
|
||||
query: 'SELECT * from table',
|
||||
columns: [
|
||||
{ label: 'column1', type: 'number' },
|
||||
{ label: 'column2', type: 'number' },
|
||||
{ label: 'column3', type: 'number' }
|
||||
],
|
||||
model: this.model,
|
||||
editorAttrs: {
|
||||
hideTabs: ['quantification']
|
||||
}
|
||||
}));
|
||||
expect(view._hideTabs).toEqual(['quantification']);
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
var Backbone = require('backbone');
|
||||
var ConfigModel = require('builder/data/config-model');
|
||||
var InputColorFileView = require('builder/components/input-color/input-color-file-view');
|
||||
var utils = require('builder/helpers/utils');
|
||||
var MakiIcons = require('builder/components/input-color/assets/maki-icons');
|
||||
var FactoryModals = require('../../../../../factories/modals');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/input-color-file-view', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
image: 'http://www.domain.com/image.png',
|
||||
fixed: '#ff0000',
|
||||
index: 0,
|
||||
ramp: [{
|
||||
color: '#c0ffee',
|
||||
title: 'hola',
|
||||
image: 'http://www.image.com/image.jpg'
|
||||
}]
|
||||
});
|
||||
|
||||
this._configModel = new ConfigModel({ base_url: '/u/pepe' });
|
||||
this.view = new InputColorFileView(({
|
||||
model: this.model,
|
||||
userModel: {
|
||||
featureEnabled: function () { return true; }
|
||||
},
|
||||
configModel: this._configModel,
|
||||
modals: FactoryModals.createModalService()
|
||||
}));
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$el.html()).toContain('form-components.editors.fill.image.recently-title');
|
||||
expect(this.view.$el.find('.js-asset').length).toBe(MakiIcons.icons.length + 1); // None + icons
|
||||
expect(utils.endsWith(this.view.$('img').attr('src'), '?req=markup')).toBe(true);
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
var $ = require('jquery');
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var ConfigModel = require('builder/data/config-model');
|
||||
var InputColorFixedContentView = require('builder/components/input-color/input-color-fixed-content-view');
|
||||
var FactoryModals = require('../../../../../factories/modals');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/input-color-fixed-content-view', function () {
|
||||
beforeEach(function () {
|
||||
spyOn($, 'ajax').and.callFake(function (req) {
|
||||
var container = document.createElement('div');
|
||||
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
svg.setAttribute('width', '200');
|
||||
svg.setAttribute('height', '200');
|
||||
svg.setAttribute('version', '1.1');
|
||||
svg.setAttribute('id', 'mysvg');
|
||||
container.appendChild(svg);
|
||||
|
||||
var d = $.Deferred();
|
||||
d.resolve(container);
|
||||
return d.promise();
|
||||
});
|
||||
|
||||
this._configModel = new ConfigModel({ base_url: '/u/pepe' });
|
||||
|
||||
this.model = new Backbone.Model({
|
||||
image: '',
|
||||
fixed: '#ff0000',
|
||||
opacity: 1
|
||||
});
|
||||
});
|
||||
|
||||
describe('with image enabled', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(InputColorFixedContentView.prototype, '_updateImageTabPane').and.callThrough();
|
||||
spyOn(InputColorFixedContentView.prototype, '_updateTextTabPane').and.callThrough();
|
||||
|
||||
this.view = new InputColorFixedContentView({
|
||||
model: this.model,
|
||||
editorAttrs: {
|
||||
imageEnabled: true,
|
||||
hidePanes: ['value']
|
||||
},
|
||||
userModel: {
|
||||
featureEnabled: function () { return true; }
|
||||
},
|
||||
configModel: this._configModel,
|
||||
modals: FactoryModals.createModalService()
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(_.size(this.view._subviews)).toBe(1);
|
||||
expect(this.view.$el.find('.CDB-NavMenu-item').length).toBe(2);
|
||||
expect(this.view._tabPaneView).toBeDefined();
|
||||
});
|
||||
|
||||
it('should update color', function () {
|
||||
expect(this.view.$('.Editor-boxModalHeader').html()).toContain('#ff0000');
|
||||
this.model.set('fixed', '#fabada');
|
||||
expect(InputColorFixedContentView.prototype._updateTextTabPane).toHaveBeenCalled();
|
||||
expect(InputColorFixedContentView.prototype._updateImageTabPane).toHaveBeenCalled();
|
||||
expect(this.view.$('.Editor-boxModalHeader').html()).toContain('#fabada');
|
||||
});
|
||||
|
||||
it('should update image', function () {
|
||||
expect(this.view.$('.Editor-boxModalHeader').text()).toContain('form-components.editors.fill.input-color.img');
|
||||
this.model.set('image', 'http://image.io/image1.svg');
|
||||
expect(InputColorFixedContentView.prototype._updateTextTabPane).not.toHaveBeenCalled();
|
||||
expect(InputColorFixedContentView.prototype._updateImageTabPane).toHaveBeenCalled();
|
||||
expect(this.view.$('.Editor-boxModalHeader').html()).toContain('<div class="Tab-paneLabelImageContainer js-image-container">');
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe('without image enabled', function () {
|
||||
beforeEach(function () {
|
||||
this.view = new InputColorFixedContentView({
|
||||
model: this.model,
|
||||
editorAttrs: {
|
||||
hidePanes: ['value']
|
||||
}
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(_.size(this.view._subviews)).toBe(0);
|
||||
expect(this.view.$el.find('.CDB-NavMenu-item').length).toBe(0);
|
||||
expect(this.view._tabPaneView).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
var InputColorPickerView = require('builder/components/input-color/input-color-picker/input-color-picker-view');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/input-color-picker/input-color-picker-view', function () {
|
||||
beforeEach(function () {
|
||||
this.view = new InputColorPickerView({ ramp: [ 303 ], opacity: 0.81 });
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
|
||||
describe('initialization', function () {
|
||||
it('should throw Error if no ramp provided', function () {
|
||||
var wrapper = function () {
|
||||
new InputColorPickerView({}); // eslint-disable-line no-new
|
||||
};
|
||||
|
||||
expect(wrapper).toThrowError('ramp is required');
|
||||
});
|
||||
|
||||
it('should throw Error if no opacity provided', function () {
|
||||
var wrapper = function () {
|
||||
new InputColorPickerView({ ramp: [] }); // eslint-disable-line no-new
|
||||
};
|
||||
|
||||
expect(wrapper).toThrowError('opacity is required');
|
||||
});
|
||||
|
||||
it('should create proper model and bindings', function () {
|
||||
var view = new InputColorPickerView({ ramp: [ 303 ], opacity: 0.81 });
|
||||
|
||||
expect(view.model.get('ramp')).toEqual([ 303 ]);
|
||||
expect(view.model.get('opacity')).toEqual(0.81);
|
||||
});
|
||||
|
||||
it('should have bindings for changes in model', function () {
|
||||
var view = new InputColorPickerView({ ramp: [ 303 ], opacity: 0.81 });
|
||||
expect(view.model._events['change:index'][0].callback).toEqual(jasmine.anything());
|
||||
expect(view.model._events['change:opacity'][0].callback).toEqual(jasmine.anything());
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onOpacityChanged', function () {
|
||||
it('should trigger change:opacity when opacity changes', function () {
|
||||
var view = new InputColorPickerView({ ramp: [ 303 ], opacity: 0.81 });
|
||||
var opacity = 0;
|
||||
function onOpacityChanged (value) {
|
||||
opacity = value;
|
||||
}
|
||||
view.bind('change:opacity', onOpacityChanged);
|
||||
|
||||
view.model.set('opacity', 0.5);
|
||||
|
||||
expect(opacity).toBe(0.5);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
});
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
var Backbone = require('backbone');
|
||||
var InputColorPickerHeader = require('builder/components/input-color/input-color-picker/input-color-picker-header');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/input-color-picker/input-color-picker-header', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
ramp: [{
|
||||
val: '#c0ffee',
|
||||
color: '#c0ffee'
|
||||
}, {
|
||||
val: '#bada55',
|
||||
color: '#bada55'
|
||||
}, {
|
||||
val: '#decade',
|
||||
color: '#decade'
|
||||
}],
|
||||
opacity: 0.45,
|
||||
index: 0
|
||||
});
|
||||
this.view = new InputColorPickerHeader({ model: this.model });
|
||||
});
|
||||
|
||||
describe('events', function () {
|
||||
it('should be properly hooked up', function () {
|
||||
expect(this.view.events['click .js-color']).toEqual('_onClickColor');
|
||||
expect(this.view.events['keyup .js-a']).toEqual('_onChangeOpacity');
|
||||
});
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('should create slider and opacity input with proper values', function () {
|
||||
this.view.render();
|
||||
|
||||
var $slider = this.view.$('.js-slider');
|
||||
var expectedOpacity = this.model.get('opacity');
|
||||
expect(+this.view.$('.js-a').val()).toBe(expectedOpacity);
|
||||
expect($slider.slider('instance')).toEqual(jasmine.anything());
|
||||
expect($slider.slider('option', 'max')).toBe(1);
|
||||
expect($slider.slider('option', 'min')).toBe(0);
|
||||
expect($slider.slider('option', 'step')).toBe(0.02);
|
||||
expect($slider.slider('option', 'orientation')).toEqual('horizontal');
|
||||
expect($slider.slider('option', 'disabled')).toBe(false);
|
||||
expect($slider.slider('option', 'range')).toEqual('min');
|
||||
expect($slider.slider('option', 'value')).toEqual(this.view._inverseSliderValue(expectedOpacity));
|
||||
expect($slider.slider('option', 'slide')).toEqual(jasmine.anything());
|
||||
});
|
||||
|
||||
it('should call _reRenderOpacity and not render anything else if opacity changes', function () {
|
||||
spyOn(this.view, '_reRenderOpacity');
|
||||
spyOn(this.view, 'clearSubViews');
|
||||
this.view.render({
|
||||
changed: {
|
||||
opacity: true
|
||||
}
|
||||
});
|
||||
|
||||
expect(this.view._reRenderOpacity).toHaveBeenCalled();
|
||||
expect(this.view.clearSubViews).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onSlideChange', function () {
|
||||
it('should set model opacity inverting the value', function () {
|
||||
var opacity = 0.23;
|
||||
var expectedOpacity = this.view._inverseSliderValue(opacity);
|
||||
|
||||
this.view._onSlideChange(null, { value: opacity });
|
||||
|
||||
expect(this.view.model.get('opacity')).toBe(expectedOpacity);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._inverseSliderValue', function () {
|
||||
it('should inverse the provided value', function () {
|
||||
expect(this.view._inverseSliderValue(0)).toBe(1);
|
||||
expect(this.view._inverseSliderValue(1)).toBe(0);
|
||||
expect(this.view._inverseSliderValue(0.4)).toBe(0.6);
|
||||
expect(this.view._inverseSliderValue(0.2345)).toBe(0.77);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onChangeOpacity', function () {
|
||||
var selector = '.js-a';
|
||||
var errorClass = 'has-error';
|
||||
|
||||
beforeEach(function () {
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should change model opacity and have no error if opacity is valid', function () {
|
||||
var opacity = 0.31;
|
||||
this.view.$(selector).val(opacity);
|
||||
|
||||
this.view._onChangeOpacity();
|
||||
|
||||
expect(this.view.$(selector).hasClass(errorClass)).toBe(false);
|
||||
expect(this.view.model.get('opacity')).toBe(opacity);
|
||||
});
|
||||
|
||||
it('should not change model opacity and have error if opacity is no valid', function () {
|
||||
var opacity = 'hip';
|
||||
this.view.$(selector).val(opacity);
|
||||
|
||||
this.view._onChangeOpacity();
|
||||
|
||||
expect(this.view.$(selector).hasClass(errorClass)).toBe(true);
|
||||
expect(this.view.model.get('opacity')).toBe(0.45); // the original opacity
|
||||
});
|
||||
});
|
||||
|
||||
describe('._isValidOpacity', function () {
|
||||
it('should return if the opacity input is valid', function () {
|
||||
expect(this.view._isValidOpacity('0')).toBe(true);
|
||||
expect(this.view._isValidOpacity('0.1')).toBe(true);
|
||||
expect(this.view._isValidOpacity('0.234')).toBe(true);
|
||||
expect(this.view._isValidOpacity('1')).toBe(true);
|
||||
expect(this.view._isValidOpacity('0.')).toBe(false);
|
||||
expect(this.view._isValidOpacity('.34')).toBe(false);
|
||||
expect(this.view._isValidOpacity('1.1')).toBe(false);
|
||||
expect(this.view._isValidOpacity('')).toBe(false);
|
||||
expect(this.view._isValidOpacity('-0.4')).toBe(false);
|
||||
expect(this.view._isValidOpacity('hello')).toBe(false);
|
||||
expect(this.view._isValidOpacity('0.f')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._reRenderOpacity', function () {
|
||||
beforeEach(function () {
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should update input when opacity changes', function () {
|
||||
this.view.$('.js-a').val(0.75);
|
||||
|
||||
this.view.model.set('opacity', 0.69);
|
||||
|
||||
expect(+this.view.$('.js-a').val()).toBe(0.69);
|
||||
});
|
||||
|
||||
it('should update slider value when opacity changes', function () {
|
||||
this.view.$('.js-slider').slider('value', 0.75);
|
||||
|
||||
this.view.model.set('opacity', 0.68);
|
||||
|
||||
expect(this.view.$('.js-slider').slider('value')).toBe(this.view._inverseSliderValue(0.68));
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
var CustomListItemModel = require('builder/components/custom-list/custom-list-item-model');
|
||||
var CategoriesListItemView = require('builder/components/input-color/input-qualitative-ramps/categories-list/list-item-view/categories-list-item-view');
|
||||
var inputColorCategoriesListItemTemplate = require('builder/components/input-color/input-qualitative-ramps/categories-list/list-item-view/categories-list-item.tpl');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/input-qualitative-ramps/categories-list/list-item-view/categories-list-item-view', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new CustomListItemModel({
|
||||
label: 'hello',
|
||||
val: '#FFF',
|
||||
image: 'https://s3.amazonaws.com/com.cartodb.users-assets.production/maki-icons/star-stroked-18.svg'
|
||||
});
|
||||
|
||||
this.view = new CategoriesListItemView(({
|
||||
model: this.model,
|
||||
typeLabel: 'column',
|
||||
template: inputColorCategoriesListItemTemplate,
|
||||
imageEnabled: true
|
||||
}));
|
||||
|
||||
spyOn(this.view, '_loadImages');
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$('.CDB-Text').length).toBe(1);
|
||||
expect(this.view.$('.CDB-Text').attr('title')).toBe('hello');
|
||||
expect(this.view.$('.js-colorPicker').attr('style')).toBe('background-color: #FFF;');
|
||||
expect(this.view.$('.js-image-container').length).toBe(1);
|
||||
});
|
||||
|
||||
describe('_onClick', function () {
|
||||
it('should set js-assetPicker class in model when image is clicked', function () {
|
||||
this.view.$('.js-image-container').click();
|
||||
expect(this.model.get('selectedClass')).toEqual(['js-assetPicker']);
|
||||
});
|
||||
|
||||
it('should set js-assetPicker class in model when IMG label is clicked', function () {
|
||||
this.model.unset('image');
|
||||
this.view.render();
|
||||
this.view.$('.js-assetPicker').click();
|
||||
expect(this.model.get('selectedClass')).toEqual(['js-assetPicker']);
|
||||
});
|
||||
|
||||
it('should not set js-assetPicker class in model when rest of the item is clicked', function () {
|
||||
this.model.unset('image');
|
||||
this.view.render();
|
||||
this.view.$el.click();
|
||||
expect(this.model.get('selectedClass')).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
+296
@@ -0,0 +1,296 @@
|
||||
var Backbone = require('backbone');
|
||||
var CategoriesListView = require('builder/components/input-color/input-qualitative-ramps/categories-list/list-view/input-categories-list-view');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/input-qualitative-ramps/categories-list/list-view/input-categories-list-view', function () {
|
||||
var view, model;
|
||||
var range = ['#000000', '#1D6996'];
|
||||
var rangeInRGB = ['rgb(0, 0, 0)', 'rgb(29, 105, 150)'];
|
||||
|
||||
describe('when the attribute is boolean', function () {
|
||||
beforeEach(function () {
|
||||
model = new Backbone.Model({
|
||||
type: 'color',
|
||||
attribute: 'fake_boolean_attribute',
|
||||
attribute_type: 'boolean',
|
||||
images: ['', ''],
|
||||
range: range,
|
||||
domain: [true, false],
|
||||
selected: true
|
||||
});
|
||||
|
||||
view = new CategoriesListView({
|
||||
maxValues: 10,
|
||||
model: model,
|
||||
imageEnabled: false
|
||||
});
|
||||
|
||||
view.render();
|
||||
});
|
||||
|
||||
describe('.render', function () {
|
||||
it('should have a back button', function () {
|
||||
expect(view.$('.js-back')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should back button should have the "Color schemes" label', function () {
|
||||
expect(view.$('.label').text().trim()).toEqual('Color Schemes');
|
||||
});
|
||||
|
||||
it('should be properly rendered', function () {
|
||||
// Different browsers may return CSS color values that are logically
|
||||
// but not textually equal, e.g., #FFF, #ffffff, and rgb(255,255,255)
|
||||
// http://api.jquery.com/css/
|
||||
expect(view.$('.js-color:eq(0)').css('background-color')).toEqual(rangeInRGB[0]);
|
||||
expect(view.$('.js-color:eq(1)').css('background-color')).toEqual(rangeInRGB[1]);
|
||||
expect(view.$('.js-color:eq(2)').css('background-color')).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('should be properly rendered when there are null values', function () {
|
||||
var colorRange = ['#5F4690', '#1D6996', '#FFFFFF'];
|
||||
var colorRangeInRGB = ['rgb(95, 70, 144)', 'rgb(29, 105, 150)', 'rgb(255, 255, 255)'];
|
||||
|
||||
var model = new Backbone.Model({
|
||||
type: 'color',
|
||||
attribute: 'fake_boolean_attribute',
|
||||
attribute_type: 'boolean',
|
||||
images: ['', ''],
|
||||
range: colorRange,
|
||||
domain: [true, false, null],
|
||||
selected: true
|
||||
});
|
||||
|
||||
var view = new CategoriesListView({
|
||||
maxValues: 10,
|
||||
model: model,
|
||||
imageEnabled: false
|
||||
});
|
||||
|
||||
view.render();
|
||||
expect(view.$('.js-color:eq(0)').css('background-color')).toEqual(colorRangeInRGB[0]);
|
||||
expect(view.$('.js-color:eq(1)').css('background-color')).toEqual(colorRangeInRGB[1]);
|
||||
expect(view.$('.js-color:eq(2)').css('background-color')).toEqual(colorRangeInRGB[2]);
|
||||
view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the attribute is numeric', function () {
|
||||
beforeEach(function () {
|
||||
model = new Backbone.Model({
|
||||
type: 'color',
|
||||
attribute: 'fake_numeric_attribute',
|
||||
attribute_type: 'numeric',
|
||||
images: ['', ''],
|
||||
range: range,
|
||||
domain: [1, 2],
|
||||
selected: true
|
||||
});
|
||||
|
||||
view = new CategoriesListView({
|
||||
maxValues: 10,
|
||||
model: model,
|
||||
imageEnabled: false
|
||||
});
|
||||
|
||||
view.render();
|
||||
});
|
||||
|
||||
describe('.render', function () {
|
||||
it('should have a back button', function () {
|
||||
expect(view.$('.js-back')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should back button should have the "Color schemes" label', function () {
|
||||
expect(view.$('.label').text().trim()).toEqual('Color Schemes');
|
||||
});
|
||||
|
||||
it('should be properly rendered', function () {
|
||||
// Different browsers may return CSS color values that are logically
|
||||
// but not textually equal, e.g., #FFF, #ffffff, and rgb(255,255,255)
|
||||
// http://api.jquery.com/css/
|
||||
expect(view.$('.js-color:eq(0)').css('background-color')).toEqual(rangeInRGB[0]);
|
||||
expect(view.$('.js-color:eq(1)').css('background-color')).toEqual(rangeInRGB[1]);
|
||||
expect(view.$('.js-color:eq(2)').css('background-color')).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('should be properly rendered when there are null values', function () {
|
||||
var colorRange = ['#5F4690', '#1D6996', '#FFFFFF'];
|
||||
var colorRangeInRGB = ['rgb(95, 70, 144)', 'rgb(29, 105, 150)', 'rgb(255, 255, 255)'];
|
||||
|
||||
var model = new Backbone.Model({
|
||||
type: 'color',
|
||||
attribute: 'fake_numeric_attribute',
|
||||
attribute_type: 'numeric',
|
||||
images: ['', ''],
|
||||
range: colorRange,
|
||||
domain: [1, 2, null],
|
||||
selected: true
|
||||
});
|
||||
|
||||
var view = new CategoriesListView({
|
||||
maxValues: 10,
|
||||
model: model,
|
||||
imageEnabled: false
|
||||
});
|
||||
|
||||
view.render();
|
||||
expect(view.$('.js-color:eq(0)').css('background-color')).toEqual(colorRangeInRGB[0]);
|
||||
expect(view.$('.js-color:eq(1)').css('background-color')).toEqual(colorRangeInRGB[1]);
|
||||
expect(view.$('.js-color:eq(2)').css('background-color')).toEqual(colorRangeInRGB[2]);
|
||||
view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the attribute is string', function () {
|
||||
beforeEach(function () {
|
||||
model = new Backbone.Model({
|
||||
type: 'color',
|
||||
attribute: 'fake_string_attribute',
|
||||
attribute_type: 'string',
|
||||
images: ['', ''],
|
||||
range: range,
|
||||
domain: ['string_attribute_1', 'string_attribute_2'],
|
||||
selected: true
|
||||
});
|
||||
|
||||
view = new CategoriesListView({
|
||||
maxValues: 10,
|
||||
model: model,
|
||||
imageEnabled: false
|
||||
});
|
||||
|
||||
view.render();
|
||||
});
|
||||
|
||||
describe('.render', function () {
|
||||
it('should have a back button', function () {
|
||||
expect(view.$('.js-back')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should back button should have the "Color schemes" label', function () {
|
||||
expect(view.$('.label').text().trim()).toEqual('Color Schemes');
|
||||
});
|
||||
|
||||
it('should be properly rendered', function () {
|
||||
// Different browsers may return CSS color values that are logically
|
||||
// but not textually equal, e.g., #FFF, #ffffff, and rgb(255,255,255)
|
||||
// http://api.jquery.com/css/
|
||||
expect(view.$('.js-color:eq(0)').css('background-color')).toEqual(rangeInRGB[0]);
|
||||
expect(view.$('.js-color:eq(1)').css('background-color')).toEqual(rangeInRGB[1]);
|
||||
expect(view.$('.js-color:eq(2)').css('background-color')).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('should be properly rendered when there are null values', function () {
|
||||
var colorRange = ['#5F4690', '#1D6996', '#FFFFFF'];
|
||||
var colorRangeInRGB = ['rgb(95, 70, 144)', 'rgb(29, 105, 150)', 'rgb(255, 255, 255)'];
|
||||
|
||||
var model = new Backbone.Model({
|
||||
type: 'color',
|
||||
attribute: 'fake_string_attribute',
|
||||
attribute_type: 'date',
|
||||
images: ['', ''],
|
||||
range: colorRange,
|
||||
domain: ['string_attribute_1', 'string_attribute_2', null],
|
||||
selected: true
|
||||
});
|
||||
|
||||
var view = new CategoriesListView({
|
||||
maxValues: 10,
|
||||
model: model,
|
||||
imageEnabled: false
|
||||
});
|
||||
|
||||
view.render();
|
||||
expect(view.$('.js-color:eq(0)').css('background-color')).toEqual(colorRangeInRGB[0]);
|
||||
expect(view.$('.js-color:eq(1)').css('background-color')).toEqual(colorRangeInRGB[1]);
|
||||
expect(view.$('.js-color:eq(2)').css('background-color')).toEqual(colorRangeInRGB[2]);
|
||||
view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the attribute is a date', function () {
|
||||
beforeEach(function () {
|
||||
model = new Backbone.Model({
|
||||
type: 'color',
|
||||
attribute: 'fake_date_attribute',
|
||||
attribute_type: 'date',
|
||||
images: ['', ''],
|
||||
range: range,
|
||||
domain: ['2018-01-01T00:00:00+00:00', '2018-01-02T00:00:00+00:00'],
|
||||
selected: true
|
||||
});
|
||||
|
||||
view = new CategoriesListView({
|
||||
maxValues: 10,
|
||||
model: model,
|
||||
imageEnabled: false
|
||||
});
|
||||
|
||||
view.render();
|
||||
});
|
||||
|
||||
describe('.render', function () {
|
||||
it('should have a back button', function () {
|
||||
expect(view.$('.js-back')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should back button should have the "Color schemes" label', function () {
|
||||
expect(view.$('.label').text().trim()).toEqual('Color Schemes');
|
||||
});
|
||||
|
||||
it('should be properly rendered', function () {
|
||||
// Different browsers may return CSS color values that are logically
|
||||
// but not textually equal, e.g., #FFF, #ffffff, and rgb(255,255,255)
|
||||
// http://api.jquery.com/css/
|
||||
expect(view.$('.js-color:eq(0)').css('background-color')).toEqual(rangeInRGB[0]);
|
||||
expect(view.$('.js-color:eq(1)').css('background-color')).toEqual(rangeInRGB[1]);
|
||||
expect(view.$('.js-color:eq(2)').css('background-color')).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('should be properly rendered when there are null values', function () {
|
||||
var colorRange = ['#5F4690', '#1D6996', '#FFFFFF'];
|
||||
var colorRangeInRGB = ['rgb(95, 70, 144)', 'rgb(29, 105, 150)', 'rgb(255, 255, 255)'];
|
||||
|
||||
var model = new Backbone.Model({
|
||||
type: 'color',
|
||||
attribute: 'fake_date_attribute',
|
||||
attribute_type: 'date',
|
||||
images: ['', ''],
|
||||
range: colorRange,
|
||||
domain: ['2018-01-01T00:00:00+00:00', '2018-01-02T00:00:00+00:00', null],
|
||||
selected: true
|
||||
});
|
||||
|
||||
var view = new CategoriesListView({
|
||||
maxValues: 10,
|
||||
model: model,
|
||||
imageEnabled: false
|
||||
});
|
||||
|
||||
view.render();
|
||||
expect(view.$('.js-color:eq(0)').css('background-color')).toEqual(colorRangeInRGB[0]);
|
||||
expect(view.$('.js-color:eq(1)').css('background-color')).toEqual(colorRangeInRGB[1]);
|
||||
expect(view.$('.js-color:eq(2)').css('background-color')).toEqual(colorRangeInRGB[2]);
|
||||
view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
view.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var InputCategoriesRampsListItemView = require('builder/components/input-color/input-qualitative-ramps/color-ramps-list/list-item-view/color-ramps-list-item-view');
|
||||
var InputCategoriesRampsListItemTemplate = require('builder/components/input-color/input-qualitative-ramps/color-ramps-list/list-item-view/color-ramps-list-item.tpl');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/input-qualitative-ramps/color-ramps-list/list-item-view/color-ramps-list-item-view', function () {
|
||||
var view, model;
|
||||
var colorRamp = ['#855C75', '#D9AF6B', '#AF6458', '#736F4C', '#526A83', '#625377', '#68855C', '#9C9C5E', '#A06177', '#8C785D', '#7C7C7C'];
|
||||
|
||||
var createViewFn = function (options) {
|
||||
if (!options) options = {};
|
||||
|
||||
model = new Backbone.Model({
|
||||
disabled: false,
|
||||
selected: _.isUndefined(options.selected) ? true : options.selected
|
||||
});
|
||||
|
||||
model.getName = function () {
|
||||
return colorRamp;
|
||||
};
|
||||
|
||||
model.getValue = function () {
|
||||
return colorRamp;
|
||||
};
|
||||
|
||||
var view = new InputCategoriesRampsListItemView({
|
||||
model: model,
|
||||
typeLabel: 'column',
|
||||
template: InputCategoriesRampsListItemTemplate
|
||||
});
|
||||
|
||||
return view;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
view = createViewFn();
|
||||
});
|
||||
|
||||
it('should have no leaks', function () {
|
||||
expect(view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
view.render();
|
||||
expect(view.$el.find('.js-listItemLink').hasClass('is-selected')).toBe(true);
|
||||
expect(view.$el.find('.js-listItemLink').hasClass('is-disabled')).toBe(false);
|
||||
expect(view.$el.find('.ColorBarContainer .ColorBar').length).toBe(colorRamp.length);
|
||||
});
|
||||
|
||||
it('should add "is-highlighted" when mouse is over the view', function () {
|
||||
view._onMouseEnter();
|
||||
expect(view.$el.hasClass('is-highlighted')).toBe(true);
|
||||
});
|
||||
|
||||
it('should add "is-highlighted" when mouse leaves the view', function () {
|
||||
view._onMouseEnter();
|
||||
expect(view.$el.hasClass('is-highlighted')).toBe(true);
|
||||
|
||||
view._onMouseLeave();
|
||||
expect(view.$el.hasClass('is-highlighted')).toBe(false);
|
||||
});
|
||||
|
||||
it('should trigger "customize" event if the view is clicked and is selected', function () {
|
||||
spyOn(view, 'trigger');
|
||||
view._onClick();
|
||||
|
||||
expect(view.trigger).toHaveBeenCalledWith('customEvent', 'customize', model.getValue(), view);
|
||||
});
|
||||
|
||||
it('should select the element if clicked and it wasn\'t selected', function () {
|
||||
var view = createViewFn({
|
||||
selected: false
|
||||
});
|
||||
|
||||
view._onClick();
|
||||
|
||||
expect(model.get('selected')).toBe(true);
|
||||
});
|
||||
});
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var InputCategoriesRampsListView = require('builder/components/input-color/input-qualitative-ramps/color-ramps-list/list-view/color-ramps-list-view');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/input-qualitative-ramps/color-ramps-list/list-view/color-ramps-list-view', function () {
|
||||
var view, model;
|
||||
var ramp = ['#5F4690', '#1D6996', '#38A6A5', '#0F8554', '#73AF48', '#EDAD08', '#E17C05', '#CC503E', '#94346E', '#6F4070', '#666666'];
|
||||
|
||||
var createViewFn = function (options) {
|
||||
if (!options) options = {};
|
||||
|
||||
model = new Backbone.Model({
|
||||
type: 'color',
|
||||
attribute: 'common_species',
|
||||
attribute_type: 'string',
|
||||
range: _.isUndefined(options.range) ? ramp : options.range,
|
||||
images: ['', '', '', '', '', '', '', '', '', '', ''],
|
||||
domain: ['Brisbane Box', 'Sycamore', 'New Zealand Xmas Tree', 'Swamp Myrtle', 'Hybrid Strawberry Tree', 'Laurel Fig', 'Victorian Box', 'Cherry Plum', 'Southern Magnolia', 'Brisbane Box'],
|
||||
selected: true
|
||||
});
|
||||
|
||||
var view = new InputCategoriesRampsListView({
|
||||
model: model,
|
||||
maxValues: 10,
|
||||
requiredNumberOfColors: 10
|
||||
});
|
||||
|
||||
return view;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
view = createViewFn();
|
||||
});
|
||||
|
||||
describe('.render', function () {
|
||||
beforeEach(function () {
|
||||
view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(view.$el.find('.js-rampsList').length).toBe(1);
|
||||
expect(view.$el.find('.js-list').children().length).not.toBeLessThan(1);
|
||||
});
|
||||
|
||||
it('should render the custom ramp if any', function () {
|
||||
var customRamp = ['#5F4690', '#1D6996', '#38A6A5', '#0F8554', '#73AF48', '#EDAD08', '#E17C05', '#CC503E', '#94346E', '#6F4070', '#999999'];
|
||||
view = createViewFn({
|
||||
range: customRamp
|
||||
});
|
||||
|
||||
view.render();
|
||||
|
||||
expect(view.$el.find('.js-customList').hasClass('is-customized')).toBe(true);
|
||||
expect(view.$el.find('.js-customList .ColorBarContainer').children().length).toBe(customRamp.length);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._selectRamp', function () {
|
||||
it('should select a ramp', function () {
|
||||
view.render();
|
||||
view._selectRamp(new Backbone.Model({
|
||||
val: ramp
|
||||
}));
|
||||
|
||||
var rampDOMElement = view.$('.js-listItem[data-val="' + ramp.join(',') + '"] .js-listItemLink');
|
||||
expect(rampDOMElement.hasClass('is-selected')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onSelectItem', function () {
|
||||
it('should set the selected ramp in the model and trigger an event', function () {
|
||||
spyOn(view, 'trigger');
|
||||
var item = new Backbone.Model({
|
||||
val: ramp
|
||||
});
|
||||
|
||||
view._onSelectItem(item);
|
||||
|
||||
expect(model.get('range')).toBe(ramp);
|
||||
expect(view.trigger).toHaveBeenCalledWith('ramp-selected', ramp, view);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._setupCollection', function () {
|
||||
it('should setup the collection with the provided qualitative ramps', function () {
|
||||
view = createViewFn();
|
||||
view._setupCollection();
|
||||
|
||||
expect(view.collection.length).toBe(6);
|
||||
});
|
||||
|
||||
it('should select mark the ramp as selected if is in the model', function () {
|
||||
view = createViewFn({
|
||||
range: ramp
|
||||
});
|
||||
view._setupCollection();
|
||||
|
||||
var selectedRamp = view.collection.find(function (model) {
|
||||
return model.get('val').join() === ramp.join();
|
||||
});
|
||||
|
||||
expect(selectedRamp.get('selected')).toBe(true);
|
||||
});
|
||||
|
||||
it('should select the selected ramp as custom if is not inside the collection', function () {
|
||||
var customRamp = ['#000000'];
|
||||
view = createViewFn({
|
||||
range: customRamp
|
||||
});
|
||||
|
||||
expect(view._customRamp.get('range')).toBe(customRamp);
|
||||
expect(view.collection.findWhere({ selected: true })).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onClickCustomize', function () {
|
||||
beforeEach(function () {
|
||||
view = createViewFn({
|
||||
range: ramp
|
||||
});
|
||||
view._setupCollection();
|
||||
});
|
||||
|
||||
it('should set the current selected ramp as custom', function () {
|
||||
var selectedRamp = view.collection.findWhere({ selected: true });
|
||||
view._onClickCustomize();
|
||||
expect(view._customRamp.get('range')).toBe(selectedRamp);
|
||||
});
|
||||
|
||||
it('should trigger a customize event', function () {
|
||||
spyOn(view, 'trigger');
|
||||
view._onClickCustomize();
|
||||
expect(view.trigger).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onClickClear', function () {
|
||||
it('should clear customRamp range', function () {
|
||||
var customRamp = ['#000000'];
|
||||
view = createViewFn({
|
||||
range: customRamp
|
||||
});
|
||||
expect(view._customRamp.get('range')).toBe(customRamp);
|
||||
|
||||
view._onClickClear();
|
||||
expect(view._customRamp.get('range')).toBe(null);
|
||||
});
|
||||
|
||||
it('should select the first ramp in the collection', function () {
|
||||
view.collection.getSelectedItem().set('selected', false);
|
||||
|
||||
view._onClickClear();
|
||||
expect(view.collection.at(0).get('selected')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onClickCustomRamp', function () {
|
||||
it('should change to customize view if custom ramp is applied', function () {
|
||||
var customRamp = ['#999999', '#FFF000'];
|
||||
view = createViewFn({
|
||||
range: customRamp
|
||||
});
|
||||
|
||||
spyOn(view, 'trigger');
|
||||
view._onClickCustomRamp();
|
||||
expect(view.trigger).toHaveBeenCalledWith('customize', view.collection.findWhere({ selected: true }), view);
|
||||
});
|
||||
});
|
||||
});
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
var Backbone = require('backbone');
|
||||
var InputColorCategories = require('builder/components/input-color/input-qualitative-ramps/main-view');
|
||||
var ConfigModel = require('builder/data/config-model');
|
||||
var UserModel = require('builder/data/user-model');
|
||||
var FactoryModals = require('../../../../../../factories/modals');
|
||||
var rampList = require('cartocolor');
|
||||
var cdb = require('internal-carto.js');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/input-qualitative-ramps/main-view', function () {
|
||||
beforeEach(function () {
|
||||
this.configModel = new ConfigModel({
|
||||
base_url: '/u/pepe',
|
||||
user_name: 'pepe'
|
||||
});
|
||||
|
||||
this.userModel = new UserModel({}, {
|
||||
configModel: this.configModel,
|
||||
feature_flags: []
|
||||
});
|
||||
|
||||
this.model = new Backbone.Model({
|
||||
domain: [0, '', 'Three'],
|
||||
range: ['#E7E1EF', '#C994C7', '#DD1C77'],
|
||||
images: ['', '', ''],
|
||||
attribute: 'column1',
|
||||
quantification: 'jenks'
|
||||
});
|
||||
|
||||
this.modals = FactoryModals.createModalService();
|
||||
|
||||
spyOn(cdb.SQL.prototype, 'execute').and.callFake(function (query, vars, params) {
|
||||
params && params.success();
|
||||
});
|
||||
|
||||
this.view = new InputColorCategories(({
|
||||
model: this.model,
|
||||
userModel: this.userModel,
|
||||
modals: this.modals,
|
||||
query: 'SELECT * FROM table',
|
||||
columns: [
|
||||
{ label: 'column1', type: 'string' },
|
||||
{ label: 'column2', type: 'string' },
|
||||
{ label: 'column3', type: 'number' }
|
||||
],
|
||||
configModel: this.configModel
|
||||
}));
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
describe('.render', function () {
|
||||
it('should have a back button', function () {
|
||||
expect(this.view.$('.js-prevStep')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should display the attribute name in the header', function () {
|
||||
expect(this.view.$('.js-label').text()).toEqual(this.model.get('attribute'));
|
||||
});
|
||||
|
||||
it('should display color ranges with 4 colors', function () {
|
||||
// 4 colors = 3 domain values colors + Others color
|
||||
var fistRange = this.view.$('.ColorBarContainer')[0];
|
||||
expect(fistRange.children.length).toEqual(4);
|
||||
});
|
||||
|
||||
it('should display a button to select a custom color set', function () {
|
||||
expect(this.view.$('.js-custom-color-set')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not render quantification if hideTabs is defined and quantification is one of the items', function () {
|
||||
this.view.render();
|
||||
expect(this.view.$el.html()).toContain('js-quantification');
|
||||
this.view._hideTabs = ['quantification'];
|
||||
this.view.render();
|
||||
expect(this.view.$el.html()).not.toContain('js-quantification');
|
||||
this.view._hideTabs = [];
|
||||
this.view.render();
|
||||
expect(this.view.$el.html()).toContain('js-quantification');
|
||||
});
|
||||
|
||||
it('should show the loader', function () {
|
||||
// Not providing any response, we will let the loader be showed forever
|
||||
cdb.SQL.prototype.execute.and.callFake(function (query, vars, params) { });
|
||||
|
||||
this.model.set('attribute', 'column2');
|
||||
expect(this.view.$('.js-loader').length).toBe(1);
|
||||
expect(this.view.$('.InputColorCategory-content.js-content').length).toBe(0);
|
||||
});
|
||||
|
||||
describe('._createColorPickerView', function () {
|
||||
it('should set picker view opacity to 1 when no opacity is provided', function () {
|
||||
this.view.model.set('opacity', undefined);
|
||||
|
||||
var pickerView = this.view._createColorPickerView();
|
||||
|
||||
expect(pickerView.model.get('opacity')).toBe(1);
|
||||
});
|
||||
|
||||
it('should set picker view opacity to the value provided', function () {
|
||||
var opacity = 0.83;
|
||||
this.view.model.set('opacity', opacity);
|
||||
|
||||
var pickerView = this.view._createColorPickerView();
|
||||
|
||||
expect(pickerView.model.get('opacity')).toBe(opacity);
|
||||
});
|
||||
|
||||
it('should subscribe to picker view change of opacity', function () {
|
||||
this.view.model.set('opacity', 0.83);
|
||||
var pickerView = this.view._createColorPickerView();
|
||||
|
||||
pickerView.model.set('opacity', 0.69);
|
||||
|
||||
expect(this.view.model.get('opacity')).toBe(0.69);
|
||||
});
|
||||
|
||||
it('should enable image edition if the item is not the latest', function () {
|
||||
this.view._index = 0;
|
||||
this.view.options.imageEnabled = true;
|
||||
|
||||
var pickerView = this.view._createColorPickerView();
|
||||
|
||||
expect(pickerView.options.imageEnabled).toBe(true);
|
||||
});
|
||||
|
||||
it('should disable image edition if the item is the latest', function () {
|
||||
var MAX_VALUES = 10; // Mirror the constant from input-color-categories.js
|
||||
this.view._index = MAX_VALUES;
|
||||
this.view.options.imageEnabled = true;
|
||||
|
||||
var pickerView = this.view._createColorPickerView();
|
||||
|
||||
expect(pickerView.options.imageEnabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._createRangeListView', function () {
|
||||
it('should not add the img selector to the latest item', function () {
|
||||
this.view.options.imageEnabled = true;
|
||||
|
||||
var rangeListView = this.view._createRangeListView();
|
||||
var list = rangeListView.render().$el.find('.CustomList-item');
|
||||
|
||||
expect(list.last().find('RampItem-img').length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('._updateRangeAndDomain', function () {
|
||||
var MAX_VALUES = 10; // Mirror the constant from input-color-categories.js
|
||||
|
||||
it('updates correctly the domain and range colors for the current categories', function () {
|
||||
var rows = JSON.parse('[{"nombre":"Almagro"},{"nombre":"Arapiles"},{"nombre":"Cortes"},{"nombre":"Embajadores"},{"nombre":"Gaztambide"},{"nombre":"Jerónimos"},{"nombre":"Justicia"},{"nombre":"Palacio"},{"nombre":"RiosRosas"},{"nombre":"Sol"},{"nombre":"Trafalgar"}]');
|
||||
this.view.model.set({ 'attribute': 'nombre' }, { silent: true });
|
||||
|
||||
this.view._updateRangeAndDomain(rows);
|
||||
|
||||
expect(this.view.model.get('domain').length).toBe(10);
|
||||
expect(this.view.model.get('range')[MAX_VALUES]).toBe(rampList.Prism[MAX_VALUES + 1][MAX_VALUES + 1]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
var Backbone = require('backbone');
|
||||
var InputColorRamps = require('builder/components/input-color/input-quantitative-ramps/main-view');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/input-quantitative-ramps/main-view', function () {
|
||||
describe('on model with a range', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
bins: 7,
|
||||
range: ['#F1EEF6', '#D4B9DA', '#C994C7', '#DF65B0', '#E7298A', '#CE1256', '#91003F'],
|
||||
attribute: 'column1',
|
||||
quantification: 'jenks'
|
||||
});
|
||||
|
||||
this.view = new InputColorRamps(({
|
||||
model: this.model
|
||||
}));
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$el.html()).toContain('column1');
|
||||
expect(this.view.$el.html()).toContain('7 form-components.editors.fill.input-ramp.buckets');
|
||||
expect(this.view.$el.html()).toContain('form-components.editors.fill.quantification.methods.jenks');
|
||||
});
|
||||
|
||||
it('should pick a similar ramp when changing bins', function () {
|
||||
this.model.set('bins', 5);
|
||||
expect(this.model.get('range').join(',').toLowerCase()).toBe('#f1eef6,#d7b5d8,#df65b0,#dd1c77,#980043');
|
||||
});
|
||||
|
||||
it('should refresh when the attribute is changed', function () {
|
||||
this.model.set('attribute', 'column2');
|
||||
expect(this.view.$el.html()).toContain('column2');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe('model without previous range', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
fixed: '#FF0000'
|
||||
});
|
||||
|
||||
this.view = new InputColorRamps(({
|
||||
model: this.model
|
||||
}));
|
||||
});
|
||||
|
||||
it('should initialize the model with default values', function () {
|
||||
expect(this.model.get('quantification')).toBe('quantiles');
|
||||
expect(this.model.get('bins')).toBe('5');
|
||||
expect(this.model.get('fixed')).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe('model with previous bins', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
bins: 12
|
||||
});
|
||||
|
||||
this.view = new InputColorRamps(({
|
||||
model: this.model
|
||||
}));
|
||||
});
|
||||
|
||||
it('should set a default number of bins based on the current ramp list', function () {
|
||||
expect(this.model.get('bins')).toBe('7');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe('model without valid range', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
range: ['#F1EEF6']
|
||||
});
|
||||
|
||||
this.view = new InputColorRamps(({
|
||||
model: this.model
|
||||
}));
|
||||
});
|
||||
|
||||
it('should set a default ramp list', function () {
|
||||
expect(this.model.get('bins')).toBe('5');
|
||||
expect(this.model.get('range').length).toBe(5);
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
var Backbone = require('backbone');
|
||||
var InputRampContentView = require('builder/components/input-color/input-quantitative-ramps/input-ramp-content-view');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/input-quantitative-ramps/input-ramp-content-view', function () {
|
||||
function createView (opacity) {
|
||||
this.model = new Backbone.Model({
|
||||
range: ['#c0ffee', '#bada55', '#decade'],
|
||||
opacity: opacity
|
||||
});
|
||||
return new InputRampContentView({ model: this.model });
|
||||
}
|
||||
|
||||
describe('._createColorPickerView', function () {
|
||||
it('should return picker view with default opacity if no one is provided', function () {
|
||||
var view = createView();
|
||||
var pickerView = view._createColorPickerView();
|
||||
|
||||
expect(pickerView.model.get('opacity')).toEqual(1);
|
||||
view.remove();
|
||||
});
|
||||
|
||||
it('should return picker view with the provided opacity', function () {
|
||||
var view = createView(0.43);
|
||||
var pickerView = view._createColorPickerView();
|
||||
|
||||
expect(pickerView.model.get('opacity')).toEqual(0.43);
|
||||
view.remove();
|
||||
});
|
||||
|
||||
it('should update own opacity when picker view updates its', function () {
|
||||
var view = createView(0.43);
|
||||
var pickerView = view._createColorPickerView();
|
||||
|
||||
pickerView.model.set('opacity', 0.84);
|
||||
|
||||
expect(view.model.get('opacity')).toEqual(0.84);
|
||||
view.remove();
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
var view = createView(0.43);
|
||||
expect(view).toHaveNoLeaks();
|
||||
view.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var InputRampListView = require('builder/components/input-color/input-quantitative-ramps/input-ramp-list-view');
|
||||
var rampList = require('cartocolor');
|
||||
|
||||
describe('components/form-components/editors/fill/input-color/input-quantitative-ramps/input-ramp-list-view', function () {
|
||||
describe('with a default ramp', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
bins: 7,
|
||||
range: ['#f6d2a9', '#f5b78e', '#f19c7c', '#ea8171', '#dd686c', '#ca5268', '#b13f64'],
|
||||
attribute: 'column1',
|
||||
quantification: 'jenks'
|
||||
});
|
||||
|
||||
this.view = new InputRampListView(({
|
||||
model: this.model
|
||||
}));
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$('.js-listItem').length).toBe(_.toArray(rampList).length);
|
||||
expect(this.view.$('.js-customList').text()).toContain('form-components.editors.fill.customize');
|
||||
});
|
||||
|
||||
it('should select ramp on click', function () {
|
||||
this.view.$('.js-listItem:eq(2) .js-listItemLink').click();
|
||||
var selectedRamp = _.toArray(rampList)[2];
|
||||
var ramp = selectedRamp[7];
|
||||
var tags = selectedRamp.tags;
|
||||
expect(tags).toContain('quantitative');
|
||||
expect(this.model.get('range').join(',').toLowerCase()).toBe('#f6d2a9,#f5b78e,#f19c7c,#ea8171,#dd686c,#ca5268,#b13f64');
|
||||
expect(this.view.$('.js-listItem:eq(2)').data('val')).toContain(ramp.join(','));
|
||||
expect(this.view.$('.js-listItem.is-selected').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should invert the ramp', function () {
|
||||
expect(this.view.collection.at(2).get('val').join(',').toLowerCase()).toBe('#f6d2a9,#f5b78e,#f19c7c,#ea8171,#dd686c,#ca5268,#b13f64');
|
||||
this.view.$('.js-listItem:eq(2) .js-listItemLink').click();
|
||||
this.view.$('.js-listItem:eq(2) .js-invert').click();
|
||||
|
||||
var firstRamp = _.toArray(rampList)[1];
|
||||
var selectedRamp = _.toArray(rampList)[2];
|
||||
var thirdRamp = _.toArray(rampList)[3];
|
||||
|
||||
var ramp = selectedRamp[7];
|
||||
var tags = selectedRamp.tags;
|
||||
|
||||
expect(tags).toContain('quantitative');
|
||||
expect(this.model.get('range').join(',').toLowerCase()).toBe('#b13f64,#ca5268,#dd686c,#ea8171,#f19c7c,#f5b78e,#f6d2a9');
|
||||
expect(this.view.collection.at(2).get('val').join(',').toLowerCase()).toBe('#b13f64,#ca5268,#dd686c,#ea8171,#f19c7c,#f5b78e,#f6d2a9');
|
||||
expect(this.view.$('.js-listItem:eq(1)').data('val')).toContain(firstRamp[7].join(','));
|
||||
expect(this.view.$('.js-listItem:eq(2)').data('val')).toContain(ramp.reverse().join(','));
|
||||
expect(this.view.$('.js-listItem:eq(3)').data('val')).toContain(thirdRamp[7].join(','));
|
||||
expect(this.view.$('.js-listItem.is-selected').length).toBe(1);
|
||||
expect(this.view.$('.js-listItem.is-inverted').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should update ramps on attribute type changes and select the first one', function () {
|
||||
spyOn(this.view, 'render').and.callThrough();
|
||||
|
||||
this.model.set('attribute_type', 'string');
|
||||
|
||||
expect(this.view.render).toHaveBeenCalled();
|
||||
expect(this.view.$('.js-listItem:eq(0)').data('val')).toContain(this.view.collection.at(0).get('val').join(','));
|
||||
expect(this.view.$('.js-listItem:eq(0)').hasClass('is-selected')).toBe(true);
|
||||
expect(this.view.$('.js-customize').text()).toBe('form-components.editors.fill.customize');
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe('with a custom ramp', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
bins: 3,
|
||||
range: ['#FABADA', '#FADFAD', '#BADBAD'],
|
||||
attribute: 'column1',
|
||||
quantification: 'jenks'
|
||||
});
|
||||
|
||||
this.view = new InputRampListView(({
|
||||
model: this.model
|
||||
}));
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$('.js-customRamp').hasClass('is-selected')).toBeTruthy();
|
||||
expect(this.view.$('.js-customRamp .ColorBar:eq(0)').css('background-color')).toBe('rgb(250, 186, 218)');
|
||||
expect(this.view.$('.js-customRamp .ColorBar:eq(1)').css('background-color')).toBe('rgb(250, 223, 173)');
|
||||
expect(this.view.$('.js-customRamp .ColorBar:eq(2)').css('background-color')).toBe('rgb(186, 219, 173)');
|
||||
});
|
||||
|
||||
it('should select the custom ramp', function () {
|
||||
this.view.$('.js-listItemLink:eq(0)').click();
|
||||
this.view.$('.js-customRamp').click();
|
||||
expect(this.view.$('.js-customRamp').hasClass('is-selected')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should start the customization process clicking on the customized ramp again', function () {
|
||||
var customizeEventTriggered = false;
|
||||
|
||||
this.view.$('.js-listItemLink:eq(0)').click();
|
||||
this.view.$('.js-customRamp').click();
|
||||
|
||||
this.view.bind('customize', function () {
|
||||
customizeEventTriggered = true;
|
||||
}, this);
|
||||
|
||||
this.view.$('.js-customRamp').click();
|
||||
expect(customizeEventTriggered).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should clear the custom ramp', function () {
|
||||
expect(this.view.$('.js-customRamp .ColorBar').length).toBe(3);
|
||||
this.view.$('.js-clear').click();
|
||||
expect(this.view.$('.js-customRamp .ColorBar').length).toBe(0);
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var InputNumber = require('builder/components/input-number/input-number');
|
||||
|
||||
describe('components/form-components/editors/fill/input-number', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
range: [1, 30],
|
||||
attribute: 'the_geom',
|
||||
quantification: 'Quantile'
|
||||
});
|
||||
this.view = new InputNumber(({
|
||||
model: this.model,
|
||||
columns: ['pepe', 'paco', 'juan']
|
||||
}));
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
|
||||
it('should get selected', function () {
|
||||
this.model.set('selected', true);
|
||||
expect(this.view.$el.hasClass('is-active')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should create a content view', function () {
|
||||
expect(this.view.model.get('createContentView')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should trigger a click event when clicked', function () {
|
||||
var clickEvent = false;
|
||||
this.view.bind('click', function () {
|
||||
clickEvent = true;
|
||||
});
|
||||
this.view.$el.click();
|
||||
expect(clickEvent).toBeTruthy();
|
||||
});
|
||||
|
||||
describe('fixed value', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
fixed: 128
|
||||
});
|
||||
this.view = new InputNumber(({
|
||||
model: this.model,
|
||||
columns: ['pepe', 'paco', 'juan']
|
||||
}));
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$el.text()).toContain('128');
|
||||
});
|
||||
|
||||
it('should update when the value is changed', function () {
|
||||
this.model.set('fixed', 50);
|
||||
expect(this.view.$el.text()).toContain('50');
|
||||
});
|
||||
});
|
||||
|
||||
describe('range', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
range: [1, 30],
|
||||
attribute: 'the_geom',
|
||||
quantification: 'Quantile'
|
||||
});
|
||||
this.view = new InputNumber(({
|
||||
model: this.model,
|
||||
columns: ['pepe', 'paco', 'juan']
|
||||
}));
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$el.text()).toContain('1..30');
|
||||
});
|
||||
|
||||
it('should update when the value is changed', function () {
|
||||
this.model.set('range', [1, 50]);
|
||||
expect(this.view.$el.text()).toContain('1..50');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with help', function () {
|
||||
beforeEach(function () {
|
||||
this.view = new InputNumber(({
|
||||
model: this.model,
|
||||
columns: ['pepe', 'paco', 'juan'],
|
||||
editorAttrs: {
|
||||
help: 'help'
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
describe('.render', function () {
|
||||
it('should render properly', function () {
|
||||
this.view.render();
|
||||
|
||||
expect(_.size(this.view._subviews)).toBe(1);
|
||||
expect(this.view.$('.js-help').attr('data-tooltip')).toContain('help');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
});
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
var cdb = require('internal-carto.js');
|
||||
var Backbone = require('backbone');
|
||||
var InputNumberContentView = require('builder/components/input-number/input-number-content-view');
|
||||
|
||||
describe('components/form-components/editors/fill/input-number/input-number-content-view', function () {
|
||||
describe('on model with a range', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
bins: 7,
|
||||
range: [1, 100],
|
||||
attribute: 'age',
|
||||
quantification: 'jenks',
|
||||
selected: true,
|
||||
type: 'size'
|
||||
});
|
||||
|
||||
this.min = 1;
|
||||
this.max = 45;
|
||||
|
||||
this.view = new InputNumberContentView({
|
||||
stackLayoutModel: new cdb.core.Model(),
|
||||
model: this.model,
|
||||
min: this.min,
|
||||
max: this.max
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should calculate the right range', function () {
|
||||
var range = this.view._calculateRangeFromFixed(13.5);
|
||||
expect(range).toEqual([4, 22]);
|
||||
});
|
||||
|
||||
it('should have calculated the right range', function () {
|
||||
expect(this.model.get('range')).toEqual([1, 100]);
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
it('should not overwrite the range when not necessary', function () {
|
||||
this.model.set('range', [10, 12]);
|
||||
this.view.render();
|
||||
expect(this.model.get('range')).toEqual([10, 12]);
|
||||
this.view.render();
|
||||
expect(this.model.get('range')).toEqual([10, 12]);
|
||||
});
|
||||
|
||||
it('should overwrite the range when necessary', function () {
|
||||
this.model.set('range', [10, 10]);
|
||||
this.view.render();
|
||||
expect(this.model.get('range')).not.toEqual([10, 10]);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
var Backbone = require('backbone');
|
||||
var InputNumberDialogContent = require('builder/components/input-number/input-number-dialog-content');
|
||||
|
||||
var COLUMNS = ['schmeckles', 'flurbos'];
|
||||
|
||||
describe('input-number-dialog-content', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
fixed: 42,
|
||||
attribute: 'wadus'
|
||||
});
|
||||
});
|
||||
it('should set the range to fixed, fixed if no defaultRange specified', function () {
|
||||
var view = new InputNumberDialogContent({
|
||||
columns: COLUMNS,
|
||||
model: this.model
|
||||
});
|
||||
|
||||
view._updateRangeValue();
|
||||
expect(this.model.get('range')).toEqual([42, 42]);
|
||||
});
|
||||
|
||||
it('should set the range to the defaultRange if specified', function () {
|
||||
var view = new InputNumberDialogContent({
|
||||
columns: COLUMNS,
|
||||
model: this.model,
|
||||
editorAttrs: {
|
||||
defaultRange: [19, 87]
|
||||
}
|
||||
});
|
||||
|
||||
view._updateRangeValue();
|
||||
expect(this.model.get('range')).toEqual([19, 87]);
|
||||
});
|
||||
});
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
var Backbone = require('backbone');
|
||||
var InputNumberValueContentView = require('builder/components/input-number/input-number-value-content-view');
|
||||
|
||||
describe('components/form-components/editors/fill/input-number/input-number-value-content-view', function () {
|
||||
describe('on model with a range', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
bins: 7,
|
||||
range: [1, 100],
|
||||
attribute: 'age',
|
||||
quantification: 'jenks',
|
||||
selected: true,
|
||||
type: 'size'
|
||||
});
|
||||
|
||||
var columns = [
|
||||
{ label: 'cartodb_id', type: 'number', val: 'cartodb_id' },
|
||||
{ label: 'the_geom', type: 'geometry', val: 'the_geom' },
|
||||
{ label: 'address', type: 'string', val: 'address' },
|
||||
{ label: 'age', type: 'number', val: 'age' }
|
||||
];
|
||||
|
||||
this.view = new InputNumberValueContentView({
|
||||
model: this.model,
|
||||
columns: columns,
|
||||
min: 0,
|
||||
max: 100
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$el.html()).toContain('age');
|
||||
expect(this.view.$el.html()).toContain('form-components.editors.fill.quantification.methods.jenks');
|
||||
expect(this.view.$el.html()).toContain('7 form-components.editors.fill.input-ramp.buckets');
|
||||
expect(this.view.$el.html()).toContain('Max');
|
||||
expect(this.view.$el.html()).toContain('Min');
|
||||
});
|
||||
|
||||
it('should render the quantification list', function () {
|
||||
this.view.$('.js-quantification').click();
|
||||
expect(this.view.$el.html()).toContain('form-components.editors.fill.quantification.title');
|
||||
expect(this.view.$('.js-listItem').length).toBe(4);
|
||||
});
|
||||
|
||||
it('should render the bins list', function () {
|
||||
this.view.$('.js-bins').click();
|
||||
expect(this.view.$el.html()).toContain('form-components.editors.fill.bins');
|
||||
expect(this.view.$('.js-listItem').length).toBe(6);
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe('on a model with a range but without a defined bins count', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
range: [1, 100],
|
||||
attribute: 'age',
|
||||
quantification: 'jenks',
|
||||
selected: true,
|
||||
type: 'size'
|
||||
});
|
||||
|
||||
var columns = [
|
||||
{ label: 'cartodb_id', type: 'number', val: 'cartodb_id' },
|
||||
{ label: 'the_geom', type: 'geometry', val: 'the_geom' },
|
||||
{ label: 'address', type: 'string', val: 'address' },
|
||||
{ label: 'age', type: 'number', val: 'age' }
|
||||
];
|
||||
|
||||
this.view = new InputNumberValueContentView({
|
||||
model: this.model,
|
||||
columns: columns,
|
||||
min: 0,
|
||||
max: 100
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should set the default bins count to 5', function () {
|
||||
expect(+this.model.get('bins')).toBe(5);
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$el.html()).toContain('age');
|
||||
expect(this.view.$el.html()).toContain('form-components.editors.fill.quantification.methods.jenks');
|
||||
expect(this.view.$el.html()).toContain('5 form-components.editors.fill.input-ramp.buckets');
|
||||
expect(this.view.$el.html()).toContain('Max');
|
||||
expect(this.view.$el.html()).toContain('Min');
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
var Backbone = require('backbone');
|
||||
var LazySearchCollection = require('builder/components/form-components/editors/lazy-select/lazy-search-collection');
|
||||
var AnalysisDefinitionNodeModel = require('builder/data/analysis-definition-node-model');
|
||||
|
||||
describe('components/form-components/editors/lazy-select/lazy-search-collection', function () {
|
||||
beforeEach(function () {
|
||||
var configModel = new Backbone.Model({
|
||||
base_url: '/u/foo',
|
||||
user_name: 'foo',
|
||||
sql_api_template: 'foo',
|
||||
api_key: 'foo'
|
||||
});
|
||||
|
||||
this.nodeDefModel = new AnalysisDefinitionNodeModel({
|
||||
id: 'a1',
|
||||
source: 'a0'
|
||||
}, {
|
||||
configModel: configModel,
|
||||
collection: new Backbone.Collection()
|
||||
});
|
||||
|
||||
this.querySchemaModel = new Backbone.Model({
|
||||
query: 'select * from wadus'
|
||||
});
|
||||
|
||||
this.nodeDefModel.querySchemaModel = this.querySchemaModel;
|
||||
|
||||
var model = new Backbone.Model({
|
||||
name: 'foo'
|
||||
});
|
||||
|
||||
this.collection = new LazySearchCollection([], {
|
||||
configModel: configModel,
|
||||
nodeDefModel: this.nodeDefModel,
|
||||
rowModel: model,
|
||||
column: 'name'
|
||||
});
|
||||
|
||||
spyOn(this.collection.SQL, 'execute').and.callFake(function (query, vars, params) {
|
||||
params && params.success({
|
||||
rows: [
|
||||
{
|
||||
name: 'foo'
|
||||
},
|
||||
{
|
||||
name: 'bar'
|
||||
},
|
||||
{
|
||||
name: 'carto'
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('initial state', function () {
|
||||
expect(this.collection.getState()).toBe('empty');
|
||||
});
|
||||
|
||||
it('fetch', function () {
|
||||
this.collection.fetch();
|
||||
|
||||
expect(this.collection.length).toBe(3);
|
||||
expect(this.collection.getState()).toBe('fetched');
|
||||
});
|
||||
|
||||
it('model', function () {
|
||||
this.collection.fetch();
|
||||
|
||||
var m = this.collection.at(0);
|
||||
expect(m.getValue()).toBe('foo');
|
||||
expect(m.getName()).toBe('foo');
|
||||
});
|
||||
|
||||
it('getSelected', function () {
|
||||
this.collection.fetch();
|
||||
|
||||
var m = this.collection.at(0);
|
||||
this.collection.setSelected(m.getValue());
|
||||
|
||||
var selected = this.collection.getSelectedItem();
|
||||
expect(selected.getValue()).toBe(m.getValue());
|
||||
});
|
||||
});
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
var _ = require('underscore');
|
||||
var AnalysisDefinitionNodeModel = require('builder/data/analysis-definition-node-model');
|
||||
|
||||
describe('components/form-components/editors/lazy-select', function () {
|
||||
var dispatchDocumentEvent = function (type, opts) {
|
||||
var e = document.createEvent('HTMLEvents');
|
||||
e.initEvent(type, false, true);
|
||||
if (opts.which) {
|
||||
e.which = opts.which;
|
||||
}
|
||||
document.dispatchEvent(e, opts);
|
||||
};
|
||||
|
||||
var createViewFn = function (options) {
|
||||
var model = new Backbone.Model({
|
||||
names: 'pepe',
|
||||
latitude: undefined
|
||||
});
|
||||
|
||||
var configModel = new Backbone.Model({
|
||||
base_url: '/u/foo',
|
||||
user_name: 'foo',
|
||||
sql_api_template: 'foo',
|
||||
api_key: 'foo'
|
||||
});
|
||||
|
||||
var nodeDefModel = new AnalysisDefinitionNodeModel({
|
||||
id: 'a1',
|
||||
source: 'a0'
|
||||
}, {
|
||||
configModel: configModel,
|
||||
collection: new Backbone.Collection()
|
||||
});
|
||||
|
||||
var querySchemaModel = new Backbone.Model({
|
||||
query: 'select * from wadus'
|
||||
});
|
||||
|
||||
nodeDefModel.querySchemaModel = querySchemaModel;
|
||||
|
||||
var defaultOptions = {
|
||||
key: 'names',
|
||||
schema: {
|
||||
options: [{
|
||||
columna: 'foo'
|
||||
}, {
|
||||
columna: 'bar'
|
||||
}, {
|
||||
columna: 'carto'
|
||||
}]
|
||||
},
|
||||
model: model,
|
||||
configModel: configModel,
|
||||
nodeDefModel: nodeDefModel,
|
||||
column: 'columna'
|
||||
};
|
||||
|
||||
var view = new Backbone.Form.editors.LazySelect(_.extend(defaultOptions, options));
|
||||
|
||||
view.render();
|
||||
|
||||
return view;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
this.createView = createViewFn.bind(this);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view && this.view.remove();
|
||||
});
|
||||
|
||||
it('should genereate an options collection', function () {
|
||||
this.view = this.createView();
|
||||
|
||||
expect(this.view.searchCollection).toBeDefined();
|
||||
expect(this.view.searchCollection.size()).toBe(3);
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('should render properly', function () {
|
||||
this.view = this.createView();
|
||||
|
||||
expect(this.view.$('.js-button').length).toBe(1);
|
||||
expect(this.view.$('.js-button').text()).toContain('pepe');
|
||||
});
|
||||
|
||||
it('should render custom placeholder if provided', function () {
|
||||
this.view = this.createView({
|
||||
placeholder: 'quinoa',
|
||||
keyAttr: 'latitude'
|
||||
});
|
||||
|
||||
expect(this.view.$('.js-button').length).toBe(1);
|
||||
expect(this.view.$('.js-button').text()).toContain('quinoa');
|
||||
});
|
||||
|
||||
it('should pass searchPlaceholder to CustomListView if present', function () {
|
||||
var text = 'Search Machine';
|
||||
this.view = this.createView({
|
||||
searchPlaceholder: text
|
||||
});
|
||||
|
||||
expect(this.view._listView.options.searchPlaceholder).toEqual(text);
|
||||
});
|
||||
|
||||
it('should disable the component if option is true', function () {
|
||||
this.view = this.createView();
|
||||
|
||||
this.view.options.disabled = true;
|
||||
this.view.render();
|
||||
expect(this.view.$('.js-button').hasClass('is-disabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should add is-empty class if there is no value selected', function () {
|
||||
this.view = this.createView();
|
||||
|
||||
this.view.model.set({names: ''});
|
||||
this.view.setValue('');
|
||||
|
||||
expect(this.view.$('.js-button').hasClass('is-empty')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('bindings', function () {
|
||||
beforeEach(function () {
|
||||
this.view = this.createView();
|
||||
spyOn(this.view._listView, 'hide');
|
||||
});
|
||||
|
||||
it('should close list view if ESC is pressed', function () {
|
||||
dispatchDocumentEvent('keydown', { which: 27 });
|
||||
expect(this.view._listView.hide).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should close list view if user clicks out the select', function () {
|
||||
dispatchDocumentEvent('click', { target: 'body' });
|
||||
expect(this.view._listView.hide).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
describe('on ENTER pressed', function () {
|
||||
beforeEach(function () {
|
||||
this.view = this.createView();
|
||||
spyOn(this.view._listView, 'toggle');
|
||||
this._event = $.Event('keydown');
|
||||
this._event.which = 13;
|
||||
});
|
||||
|
||||
it('should open custom list', function () {
|
||||
this.view.$('.js-button').trigger(this._event);
|
||||
expect(this.view._listView.toggle).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not open custom list if it is already visible', function () {
|
||||
this.view._listView.show();
|
||||
this.view.$('.js-button').trigger(this._event);
|
||||
expect(this.view._listView.toggle).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
it('should change button value and hide list when a new item is selected', function () {
|
||||
this.view = this.createView();
|
||||
spyOn(this.view._listView, 'hide');
|
||||
var mdl = this.view.searchCollection.where({ val: 'carto' });
|
||||
mdl[0].set('selected', true);
|
||||
expect(this.view.$('.js-button').text()).toContain('carto');
|
||||
expect(this.view.$('.js-button').hasClass('is-empty')).toBeFalsy();
|
||||
expect(this.view._listView.hide).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should open list view if "button" is clicked', function () {
|
||||
this.view = this.createView();
|
||||
spyOn(this.view._listView, 'toggle');
|
||||
this.view.$('.js-button').trigger('click');
|
||||
expect(this.view._listView.toggle).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('placeholder', function () {
|
||||
it('empty and no value', function () {
|
||||
this.view = this.createView({
|
||||
keyAttr: 'latitude',
|
||||
schema: {
|
||||
options: []
|
||||
}
|
||||
});
|
||||
|
||||
var placeholder = $.trim(this.view.$('.js-button').text());
|
||||
expect(placeholder).toBe('components.backbone-forms.select.empty');
|
||||
});
|
||||
|
||||
it('no value', function () {
|
||||
this.view = this.createView({
|
||||
keyAttr: 'latitude'
|
||||
});
|
||||
|
||||
var placeholder = $.trim(this.view.$('.js-button').text());
|
||||
expect(placeholder).toBe('components.backbone-forms.select.placeholder');
|
||||
});
|
||||
});
|
||||
});
|
||||
+278
@@ -0,0 +1,278 @@
|
||||
var Backbone = require('backbone');
|
||||
var _ = require('underscore');
|
||||
// Required for affected specs, because we use backbone-forms through a global namespace
|
||||
require('builder/components/form-components/editors/list/list-item');
|
||||
|
||||
describe('components/form-components/editors/list/list-item', function () {
|
||||
var view;
|
||||
var createViewFn = function (options) {
|
||||
var defaultOptions = {
|
||||
schema: {},
|
||||
list: {}
|
||||
};
|
||||
|
||||
return new Backbone.Form.editors.List.Item(_.extend(defaultOptions, options));
|
||||
};
|
||||
|
||||
describe('.render', function () {
|
||||
beforeEach(function () {
|
||||
view = createViewFn();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
spyOn(view, '_removeTooltip');
|
||||
spyOn(view, 'setElement').and.callThrough();
|
||||
view.render();
|
||||
|
||||
expect(view.$('[data-editor]').length).toBe(1);
|
||||
expect(view.setElement).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should render a custom template', function () {
|
||||
var customTemplate = '<div>My custom Template</div>';
|
||||
view = createViewFn({
|
||||
template: _.template(customTemplate)
|
||||
});
|
||||
view.render();
|
||||
|
||||
expect(view.el.outerHTML).toContain(customTemplate);
|
||||
});
|
||||
});
|
||||
|
||||
describe('legend-list-item template', function () {
|
||||
beforeEach(function () {
|
||||
view = createViewFn({
|
||||
template: _.template('<div><div data-editor></div><button class="js-remove-help" type="button" data-action="remove">Remove</button></div>')
|
||||
});
|
||||
});
|
||||
|
||||
describe('.render', function () {
|
||||
it('should render properly', function () {
|
||||
spyOn(view, '_removeTooltip');
|
||||
spyOn(view, 'setElement').and.callThrough();
|
||||
view.render();
|
||||
|
||||
expect(view._removeTooltip).toHaveBeenCalled();
|
||||
expect(view._tooltip).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('._removeTooltip', function () {
|
||||
it('should destroy tooltip', function () {
|
||||
view.render();
|
||||
spyOn(view._tooltip, 'clean');
|
||||
|
||||
view._removeTooltip();
|
||||
|
||||
expect(view._tooltip.clean).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('.getValue', function () {
|
||||
it('should call editor.getValue', function () {
|
||||
view.render();
|
||||
spyOn(view.editor, 'getValue');
|
||||
view.getValue();
|
||||
|
||||
expect(view.editor.getValue).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.setValue', function () {
|
||||
it('should call editor.setValue', function () {
|
||||
view = createViewFn();
|
||||
view.render();
|
||||
spyOn(view.editor, 'setValue');
|
||||
view.setValue('test');
|
||||
|
||||
expect(view.editor.setValue).toHaveBeenCalledWith('test');
|
||||
});
|
||||
});
|
||||
|
||||
describe('.focus', function () {
|
||||
it('should call editor.focus', function () {
|
||||
view = createViewFn();
|
||||
view.render();
|
||||
spyOn(view.editor, 'focus');
|
||||
view.focus();
|
||||
|
||||
expect(view.editor.focus).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.blur', function () {
|
||||
it('should call editor.blur', function () {
|
||||
view = createViewFn();
|
||||
view.render();
|
||||
spyOn(view.editor, 'blur');
|
||||
view.blur();
|
||||
|
||||
expect(view.editor.blur).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.validate', function () {
|
||||
it('should return null', function () {
|
||||
view = createViewFn();
|
||||
view.render();
|
||||
expect(view.validate()).toBeNull();
|
||||
});
|
||||
|
||||
describe('with validators', function () {
|
||||
beforeEach(function () {
|
||||
view = createViewFn({
|
||||
schema: {
|
||||
validators: ['test']
|
||||
}
|
||||
});
|
||||
view.render();
|
||||
});
|
||||
|
||||
describe('when validation fails', function () {
|
||||
var error = 'This is an error';
|
||||
beforeEach(function () {
|
||||
view.getValidator = function () {
|
||||
return function () {
|
||||
return error;
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
it('should call setError', function () {
|
||||
spyOn(view, 'setError');
|
||||
|
||||
view.validate();
|
||||
|
||||
expect(view.setError).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return the error', function () {
|
||||
expect(view.validate()).toEqual(error);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when validation succeds', function () {
|
||||
beforeEach(function () {
|
||||
view.getValidator = function () {
|
||||
return function () {
|
||||
return false;
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
it('should call clearError', function () {
|
||||
spyOn(view, 'clearError');
|
||||
|
||||
view.validate();
|
||||
|
||||
expect(view.clearError).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return null', function () {
|
||||
expect(view.validate()).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('.setError', function () {
|
||||
var error = 'This is an error';
|
||||
beforeEach(function () {
|
||||
view = createViewFn();
|
||||
view.render();
|
||||
view.setError({
|
||||
message: error
|
||||
});
|
||||
});
|
||||
|
||||
it('should add the error class to the element', function () {
|
||||
expect(view.$el.hasClass('error')).toBe(true);
|
||||
});
|
||||
|
||||
it('should set the error to the title attribute', function () {
|
||||
expect(view.$el.attr('title')).toEqual(error);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with custom error class', function () {
|
||||
var errorClass = 'myCustomError';
|
||||
var errorMessage = 'This is an error';
|
||||
|
||||
beforeEach(function () {
|
||||
view = createViewFn({
|
||||
errorClassName: errorClass
|
||||
});
|
||||
view.render();
|
||||
view.setError({
|
||||
message: errorMessage
|
||||
});
|
||||
});
|
||||
|
||||
describe('.setError', function () {
|
||||
it('should add the error class to the element', function () {
|
||||
expect(view.$el.hasClass(errorClass)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.clearError', function () {
|
||||
it('should remove the error class from the element', function () {
|
||||
expect(view.$el.hasClass(errorClass)).toBe(true);
|
||||
view.clearError();
|
||||
expect(view.$el.hasClass(errorClass)).toBe(false);
|
||||
});
|
||||
|
||||
it('should remove the error from the title attribute', function () {
|
||||
view.clearError();
|
||||
expect(view.$el.attr('title')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('.clearError', function () {
|
||||
beforeEach(function () {
|
||||
view = createViewFn();
|
||||
view.render();
|
||||
view.setError({
|
||||
message: 'error'
|
||||
});
|
||||
});
|
||||
|
||||
it('should add the error class to the element', function () {
|
||||
expect(view.$el.hasClass('error')).toBe(true);
|
||||
view.clearError();
|
||||
expect(view.$el.hasClass('error')).toBe(false);
|
||||
});
|
||||
|
||||
it('should set the error to the title attribute', function () {
|
||||
view.clearError();
|
||||
expect(view.$el.attr('title')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('.remove', function () {
|
||||
it('should call _removeTooltip', function () {
|
||||
spyOn(view, '_removeTooltip');
|
||||
view.remove();
|
||||
|
||||
expect(view._removeTooltip).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call editor.remove', function () {
|
||||
spyOn(view.editor, 'remove');
|
||||
view.remove();
|
||||
|
||||
expect(view.editor.remove).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should have no leaks', function () {
|
||||
view = createViewFn();
|
||||
view.render();
|
||||
expect(view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
view.remove();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,151 @@
|
||||
var Backbone = require('backbone');
|
||||
|
||||
describe('components/form-components/editors/list/list', function () {
|
||||
beforeEach(function () {
|
||||
this.validator = jasmine.createSpy('validator').and.returnValue({
|
||||
error: true,
|
||||
message: 'Foo'
|
||||
});
|
||||
|
||||
this.view = new Backbone.Form.editors.List({
|
||||
trackingClass: 'Foo-trackingClass',
|
||||
value: ['wadus', 'foodie'],
|
||||
schema: {
|
||||
validators: [ this.validator ]
|
||||
}
|
||||
});
|
||||
|
||||
spyOn(this.view, 'addItem').and.callThrough();
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('addItem', function () {
|
||||
var n = this.view.value.length;
|
||||
expect(this.view.addItem).toHaveBeenCalledTimes(n);
|
||||
});
|
||||
|
||||
it('tracking class', function () {
|
||||
var n = this.view.value.length;
|
||||
expect(this.view.$('.Foo-trackingClass').length).toBe(n);
|
||||
});
|
||||
});
|
||||
|
||||
describe('validation', function () {
|
||||
it('should happen on render', function () {
|
||||
var n = this.view.value.length;
|
||||
expect(this.view.errors.length).toBe(n);
|
||||
});
|
||||
|
||||
describe('add item button', function () {
|
||||
it('without validation error', function () {
|
||||
this.validator.and.returnValue(null);
|
||||
this.view.validate();
|
||||
|
||||
var button = this.view.$('[data-action="add"]');
|
||||
expect(button.hasClass('is-disabled')).toBe(false);
|
||||
});
|
||||
|
||||
it('with validation error', function () {
|
||||
this.validator.and.returnValue({
|
||||
error: true,
|
||||
message: 'Important error'
|
||||
});
|
||||
|
||||
this.view.validate();
|
||||
|
||||
var n = this.view.value.length;
|
||||
var button = this.view.$('[data-action="add"]');
|
||||
|
||||
expect(button.hasClass('is-disabled')).toBe(true);
|
||||
expect(this.view.errors.length).toBe(n);
|
||||
});
|
||||
|
||||
it('error presenter', function () {
|
||||
this.validator.and.returnValue({
|
||||
error: true,
|
||||
message: 'Foo'
|
||||
});
|
||||
|
||||
this.view.validate();
|
||||
var error = this.view._errorPresenter();
|
||||
expect(error).toBe('Foo');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('maxItems', function () {
|
||||
var view;
|
||||
|
||||
beforeEach(function () {
|
||||
spyOn(Backbone.Form.editors.List.prototype, '_setAddButtonState').and.callThrough();
|
||||
view = new Backbone.Form.editors.List({
|
||||
trackingClass: 'Foo-trackingClass',
|
||||
value: ['wadus', 'foodie'],
|
||||
schema: {
|
||||
maxItems: 4,
|
||||
validators: ['required']
|
||||
}
|
||||
});
|
||||
|
||||
view.render();
|
||||
});
|
||||
|
||||
it('should check if add-button has to be visible or not', function () {
|
||||
expect(Backbone.Form.editors.List.prototype._setAddButtonState).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should hide add-button when maxItems is reached', function () {
|
||||
Backbone.Form.editors.List.prototype._setAddButtonState.calls.reset();
|
||||
view._getAddButtonElement().click();
|
||||
expect(Backbone.Form.editors.List.prototype._setAddButtonState).toHaveBeenCalled();
|
||||
expect(view._getAddButtonElement().css('display')).not.toBe('none'); // 3 items, you can add a new one
|
||||
view._getAddButtonElement().click();
|
||||
expect(view._getAddButtonElement().css('display')).toBe('none');
|
||||
});
|
||||
|
||||
it('should show add-button when maxItems is not reached', function () {
|
||||
Backbone.Form.editors.List.prototype._setAddButtonState.calls.reset();
|
||||
view.removeItem(view.items[0]);
|
||||
expect(Backbone.Form.editors.List.prototype._setAddButtonState).toHaveBeenCalled();
|
||||
expect(view._getAddButtonElement().css('display')).not.toBe('none');
|
||||
});
|
||||
|
||||
it('should provide a custom error when maxItems is reached after validating it', function () {
|
||||
view.options.maxItems = 1;
|
||||
view.validate();
|
||||
expect(view.errors.length > 0).toBeTruthy();
|
||||
expect(view.errors[0]).toBe('form-components.editors.list.max-items');
|
||||
});
|
||||
});
|
||||
|
||||
describe('_canAddNewItems', function () {
|
||||
it('should be falsy if there is any validation error', function () {
|
||||
this.view.errors = ['error'];
|
||||
expect(this.view._canAddNewItems()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should be truthy if maxItems is not defined and no errors', function () {
|
||||
this.view.errors = [];
|
||||
delete this.view.options.maxItems; // JUst in case
|
||||
expect(this.view._canAddNewItems()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should be truthy if maxItems has not been reached and no errors', function () {
|
||||
this.view.errors = [];
|
||||
this.view.options.maxItems = 3;
|
||||
expect(this.view._canAddNewItems()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should be falsy if maxItems is defined and limit is reached', function () {
|
||||
this.view.errors = [];
|
||||
this.view.options.maxItems = 2;
|
||||
expect(this.view._canAddNewItems()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,256 @@
|
||||
var $ = require('jquery');
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
// Required for affected specs, because we use backbone-forms through a global namespace
|
||||
require('builder/components/form-components/editors/number/number.js');
|
||||
|
||||
var ARROW_UP_KEY = 38;
|
||||
var ARROW_DOWN_KEY = 40;
|
||||
|
||||
describe('components/form-components/editors/number', function () {
|
||||
var createViewFn = function (options) {
|
||||
var defaultOptions = {
|
||||
schema: {}
|
||||
};
|
||||
|
||||
var view = new Backbone.Form.editors.Number(_.extend(defaultOptions, options));
|
||||
view.render();
|
||||
return view;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
this.view = createViewFn();
|
||||
this.view.render();
|
||||
this.$input = this.view.$('.js-input');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.$input.length).toBe(1);
|
||||
expect(this.view.$('.js-slider').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should not create the horizontal slider if not desired', function () {
|
||||
var view = createViewFn({
|
||||
showSlider: false
|
||||
});
|
||||
view.render();
|
||||
expect(view.$('.js-slider').length).toBe(0);
|
||||
});
|
||||
|
||||
describe('max and min', function () {
|
||||
it('should get values by default', function () {
|
||||
expect(this.view.options.min).toBe(0);
|
||||
expect(this.view.options.max).toBe(10);
|
||||
});
|
||||
|
||||
it('should accept max and min accross validators', function () {
|
||||
var view = createViewFn({
|
||||
schema: {
|
||||
validators: ['required', {
|
||||
type: 'interval',
|
||||
min: 5,
|
||||
max: 30
|
||||
}]
|
||||
}
|
||||
});
|
||||
expect(view.options.min).toBe(5);
|
||||
expect(view.options.max).toBe(30);
|
||||
});
|
||||
});
|
||||
|
||||
describe('change value', function () {
|
||||
beforeEach(function () {
|
||||
this.onChanged = jasmine.createSpy('onChanged');
|
||||
this.view.bind('change', this.onChanged);
|
||||
});
|
||||
|
||||
describe('when slider changes', function () {
|
||||
beforeEach(function () {
|
||||
var $slider = this.view.$('.js-slider');
|
||||
$slider.slider('option', 'slide').call($slider, {}, { value: 5 });
|
||||
$slider.slider('option', 'stop').call($slider);
|
||||
});
|
||||
|
||||
it('should trigger change after debounce time', function (done) {
|
||||
var self = this;
|
||||
setTimeout(function () {
|
||||
expect(self.onChanged).toHaveBeenCalled();
|
||||
done();
|
||||
}, 334);
|
||||
});
|
||||
|
||||
it('should update input', function () {
|
||||
expect(this.$input.val()).toBe('5');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when input changes', function () {
|
||||
beforeEach(function () {
|
||||
this.$input.val(6).trigger('keyup');
|
||||
});
|
||||
|
||||
it('should trigger change', function (done) {
|
||||
var self = this;
|
||||
setTimeout(function () {
|
||||
expect(self.onChanged).toHaveBeenCalled();
|
||||
done();
|
||||
}, 334);
|
||||
});
|
||||
|
||||
it('should update input', function () {
|
||||
expect(this.view.$('.js-slider').slider('value')).toBe(6);
|
||||
});
|
||||
|
||||
describe('when pressing the UP key', function () {
|
||||
it('should increase the value', function () {
|
||||
this.view.setValue(7);
|
||||
|
||||
var event = $.Event('keydown');
|
||||
event.keyCode = event.which = ARROW_UP_KEY;
|
||||
|
||||
this.$input.trigger(event);
|
||||
this.$input.trigger(event);
|
||||
this.$input.trigger(event);
|
||||
|
||||
expect(this.$input.val()).toBe('10');
|
||||
});
|
||||
|
||||
it('should increase the value when pressing shift', function () {
|
||||
this.view.setValue(0);
|
||||
|
||||
var event = $.Event('keydown');
|
||||
event.keyCode = event.which = ARROW_UP_KEY;
|
||||
event.shiftKey = true;
|
||||
|
||||
this.$input.trigger(event);
|
||||
|
||||
expect(this.$input.val()).toBe('10');
|
||||
});
|
||||
|
||||
it('should not increase the value if it exceeds the max allowed', function () {
|
||||
this.view.setValue(10);
|
||||
|
||||
var event = $.Event('keydown');
|
||||
event.keyCode = event.which = ARROW_UP_KEY;
|
||||
|
||||
this.$input.trigger(event);
|
||||
this.$input.trigger(event);
|
||||
this.$input.trigger(event);
|
||||
|
||||
expect(this.$input.val()).toBe('10');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when pressing the DOWN key', function () {
|
||||
it('should decrease the value', function () {
|
||||
this.view.setValue(7);
|
||||
|
||||
var event = $.Event('keydown');
|
||||
event.keyCode = event.which = ARROW_DOWN_KEY;
|
||||
|
||||
this.$input.trigger(event);
|
||||
this.$input.trigger(event);
|
||||
this.$input.trigger(event);
|
||||
|
||||
expect(this.$input.val()).toBe('4');
|
||||
});
|
||||
|
||||
it('should decrease the value when pressing shift', function () {
|
||||
this.view.setValue(10);
|
||||
|
||||
var event = $.Event('keydown');
|
||||
event.keyCode = event.which = ARROW_DOWN_KEY;
|
||||
event.shiftKey = true;
|
||||
|
||||
this.$input.trigger(event);
|
||||
|
||||
expect(this.$input.val()).toBe('0');
|
||||
});
|
||||
|
||||
it('should not decrease the value if it exceeds the max allowed', function () {
|
||||
this.view.setValue(0);
|
||||
|
||||
var event = $.Event('keydown');
|
||||
event.keyCode = event.which = ARROW_DOWN_KEY;
|
||||
|
||||
this.$input.trigger(event);
|
||||
this.$input.trigger(event);
|
||||
this.$input.trigger(event);
|
||||
|
||||
expect(this.$input.val()).toBe('0');
|
||||
});
|
||||
|
||||
it('should work with negative min value', function () {
|
||||
var view = createViewFn({
|
||||
schema: {
|
||||
validators: ['required', {
|
||||
type: 'interval',
|
||||
min: -5,
|
||||
max: 10
|
||||
}]
|
||||
}
|
||||
});
|
||||
var $input = view.$('.js-input');
|
||||
view.setValue(0);
|
||||
|
||||
var event = $.Event('keydown');
|
||||
event.keyCode = event.which = ARROW_DOWN_KEY;
|
||||
|
||||
$input.trigger(event);
|
||||
$input.trigger(event);
|
||||
$input.trigger(event);
|
||||
|
||||
expect($input.val()).toBe('-3');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should destroy horizontal slider and tooltip when element is removed', function () {
|
||||
spyOn(this.view, '_destroySlider');
|
||||
spyOn(this.view, '_removeTooltip');
|
||||
|
||||
this.view.remove();
|
||||
|
||||
expect(this.view._destroySlider).toHaveBeenCalled();
|
||||
expect(this.view._removeTooltip).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('with help', function () {
|
||||
var view;
|
||||
|
||||
beforeEach(function () {
|
||||
view = createViewFn({
|
||||
editorAttrs: {
|
||||
help: 'help'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('.render', function () {
|
||||
it('should render properly', function () {
|
||||
view.render();
|
||||
|
||||
expect(view.$('.js-help').attr('data-tooltip')).toContain('help');
|
||||
});
|
||||
});
|
||||
|
||||
describe('._removeTooltip', function () {
|
||||
it('should destroy tooltip', function () {
|
||||
spyOn(view._helpTooltip, 'clean');
|
||||
|
||||
view._removeTooltip();
|
||||
|
||||
expect(view._helpTooltip.clean).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
});
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
var OperatorsListModel = require('builder/components/form-components/editors/operators/operators-list-model');
|
||||
|
||||
describe('components/form-components/operators/operators-list-model', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new OperatorsListModel({
|
||||
operator: 'count',
|
||||
attribute: ''
|
||||
});
|
||||
});
|
||||
|
||||
describe('.isValidOperator', function () {
|
||||
it('should be true when operator is count', function () {
|
||||
expect(this.model.isValidOperator()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should be valid when operator is different than count and there is an attribute', function () {
|
||||
this.model.attributes = {
|
||||
operator: 'sum',
|
||||
attribute: '$'
|
||||
};
|
||||
expect(this.model.isValidOperator()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should be unvalid when operator is different than count and there is no an attribute', function () {
|
||||
this.model.attributes = {
|
||||
operator: 'sum',
|
||||
attribute: ''
|
||||
};
|
||||
expect(this.model.isValidOperator()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should be unvalid when operator is empty and there is an attribute', function () {
|
||||
this.model.attributes = {
|
||||
operator: '',
|
||||
attribute: '$'
|
||||
};
|
||||
expect(this.model.isValidOperator()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
var _ = require('underscore');
|
||||
var $ = require('jquery');
|
||||
var OperatorsListView = require('builder/components/form-components/editors/operators/operators-list-view');
|
||||
var CustomListCollection = require('builder/components/form-components/editors/operators/operators-list-collection');
|
||||
|
||||
describe('components/form-components/operators/operators-list-view', function () {
|
||||
var view, collection;
|
||||
|
||||
var createViewFn = function () {
|
||||
collection = new CustomListCollection([
|
||||
{
|
||||
val: '$',
|
||||
type: 'number'
|
||||
}, {
|
||||
val: '€',
|
||||
type: 'number'
|
||||
}, {
|
||||
val: '¥',
|
||||
type: 'number'
|
||||
}
|
||||
]);
|
||||
|
||||
var view = new OperatorsListView({
|
||||
attribute: '',
|
||||
operator: 'count',
|
||||
collection: collection
|
||||
});
|
||||
|
||||
return view;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
spyOn(_, 'debounce').and.callFake(function (func) {
|
||||
return function () {
|
||||
func.apply(this, arguments);
|
||||
};
|
||||
});
|
||||
|
||||
view = createViewFn();
|
||||
view.render();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
view.clean();
|
||||
});
|
||||
|
||||
it('should generate an internal model with the options', function () {
|
||||
expect(view.model).toBeDefined();
|
||||
var attrs = view.model.attributes;
|
||||
expect(attrs.operator).toBe('count');
|
||||
expect(attrs.attribute).toBe('');
|
||||
});
|
||||
|
||||
it('should destroy list if hidden', function () {
|
||||
spyOn(view, '_destroyList');
|
||||
spyOn(view, 'remove');
|
||||
// To force a change
|
||||
view.model.unset('visible');
|
||||
view.model.set('visible', false);
|
||||
|
||||
expect(view._destroyList).toHaveBeenCalled();
|
||||
expect(view.remove).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('.render', function () {
|
||||
it('should render properly', function () {
|
||||
expect(view.$('.Editor-dropdownCalculations').length).toBe(1);
|
||||
expect(view.$('.Editor-dropdownCalculationsElement').length).toBe(5);
|
||||
expect(view.$('[name="operator"]').val()).toBe('count');
|
||||
expect($('.CDB-Box-modalOverlay').length).toBe(1);
|
||||
expect(_.size(view._subviews)).toBe(1);
|
||||
expect(view._hasList()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should render list when operator is different than count', function () {
|
||||
view.$('[value="avg"]').click().trigger('change');
|
||||
expect(view._hasList()).toBeTruthy();
|
||||
view.$('[value="count"]').click().trigger('change');
|
||||
expect(view._hasList()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('._onModelChange', function () {
|
||||
it('should trigger change when new value is selected and is valid', function () {
|
||||
spyOn(view, 'trigger');
|
||||
view.model.set({ operator: 'avg', attribute: '¥' });
|
||||
expect(view.trigger).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not trigger change when new value is selected and is not valid', function () {
|
||||
spyOn(view, 'trigger');
|
||||
view.model.set({ operator: 'avg', attribute: '' });
|
||||
expect(view.trigger).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should destroy list view when it is removed', function () {
|
||||
view.remove();
|
||||
expect(view._hasList()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
|
||||
var dispatchDocumentEvent = function (type, opts) {
|
||||
var e = document.createEvent('HTMLEvents');
|
||||
e.initEvent(type, false, true);
|
||||
if (opts.which) {
|
||||
e.which = opts.which;
|
||||
}
|
||||
document.dispatchEvent(e, opts);
|
||||
};
|
||||
|
||||
describe('components/form-components/operators/operators-view', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
currency: {
|
||||
operator: 'count',
|
||||
attribute: ''
|
||||
}
|
||||
});
|
||||
|
||||
this.view = new Backbone.Form.editors.Operators({
|
||||
key: 'currency',
|
||||
schema: {
|
||||
options: ['$', '€', '¥']
|
||||
},
|
||||
model: this.model
|
||||
});
|
||||
this.view.render();
|
||||
this.listView = this.view._operatorsListView;
|
||||
});
|
||||
|
||||
it('should genereate an options collection', function () {
|
||||
expect(this.view.collection).toBeDefined();
|
||||
expect(this.view.collection.size()).toBe(3);
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$('.js-operator').length).toBe(1);
|
||||
expect(this.view.$('.js-button').length).toBe(1);
|
||||
expect(this.view.$('.js-button').text().toLowerCase()).toContain('count');
|
||||
});
|
||||
|
||||
it('should disable the component if option is true', function () {
|
||||
this.view.options.disabled = true;
|
||||
spyOn(this.view, 'undelegateEvents').and.callThrough();
|
||||
this.view._initViews();
|
||||
expect(this.view.$('.js-button').hasClass('is-disabled')).toBeTruthy();
|
||||
expect(this.view.undelegateEvents).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should add is-empty class if there is no value selected', function () {
|
||||
this.model.set('currency', '');
|
||||
this.view._initViews();
|
||||
expect(this.view.$('.js-button').hasClass('is-empty')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('bindings', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(this.listView, 'hide');
|
||||
});
|
||||
|
||||
it('should close list view if ESC is pressed', function () {
|
||||
dispatchDocumentEvent('keydown', { which: 27 });
|
||||
expect(this.listView.hide).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should close list view if user clicks out the select', function () {
|
||||
dispatchDocumentEvent('click', { target: 'body' });
|
||||
expect(this.listView.hide).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('on ENTER pressed', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(this.listView, 'toggle');
|
||||
this._event = $.Event('keydown');
|
||||
this._event.which = 13;
|
||||
});
|
||||
|
||||
it('should open custom list', function () {
|
||||
this.view.$('.js-button').trigger(this._event);
|
||||
expect(this.listView.toggle).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not open custom list if it is already visible', function () {
|
||||
this.listView.show();
|
||||
this.view.$('.js-button').trigger(this._event);
|
||||
expect(this.listView.toggle).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should change button value when a new values are selected', function () {
|
||||
var values = {
|
||||
operator: 'sum',
|
||||
attribute: '¥'
|
||||
};
|
||||
this.listView.trigger('change', values);
|
||||
expect(this.view.$('.js-button').text().toLowerCase()).toContain('sum(¥)');
|
||||
expect(this.view.$('.js-button').hasClass('is-empty')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should open list view if "button" is clicked', function () {
|
||||
spyOn(this.listView, 'toggle');
|
||||
this.view.$('.js-button').trigger('click');
|
||||
expect(this.listView.toggle).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should destroy custom list and tooltip when element is removed', function () {
|
||||
spyOn(this.listView, 'clean');
|
||||
spyOn(this.view, '_removeTooltip');
|
||||
|
||||
this.view.remove();
|
||||
|
||||
expect(this.listView.clean).toHaveBeenCalled();
|
||||
expect(this.view._removeTooltip).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('with help', function () {
|
||||
beforeEach(function () {
|
||||
this.view = new Backbone.Form.editors.Operators({
|
||||
key: 'currency',
|
||||
schema: {
|
||||
options: ['$', '€', '¥']
|
||||
},
|
||||
model: this.model,
|
||||
editorAttrs: {
|
||||
help: 'help'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should render correctly', function () {
|
||||
this.view.render();
|
||||
expect(this.view.$('.js-help').attr('data-tooltip')).toContain('help');
|
||||
});
|
||||
|
||||
describe('._removeTooltip', function () {
|
||||
it('should destroy tooltip', function () {
|
||||
spyOn(this.view._helpTooltip, 'clean');
|
||||
|
||||
this.view._removeTooltip();
|
||||
|
||||
expect(this.view._helpTooltip.clean).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have any leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
this.listView.remove();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
var _ = require('underscore');
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
|
||||
var OPTIONS = [{
|
||||
type: 'jpg',
|
||||
label: '.jpg',
|
||||
className: 'firstClass'
|
||||
}, {
|
||||
type: 'png',
|
||||
label: '.png',
|
||||
className: 'secondClass'
|
||||
}];
|
||||
|
||||
describe('components/form-components/editors/radio', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({ what: true });
|
||||
|
||||
this.form = new Backbone.Form({
|
||||
model: this.model
|
||||
});
|
||||
|
||||
this.view = new Backbone.Form.editors.Radio({
|
||||
key: 'what',
|
||||
form: this.form,
|
||||
schema: {
|
||||
options: _.map(OPTIONS, function (d) {
|
||||
return {
|
||||
val: d.type,
|
||||
label: d.label,
|
||||
className: d.className
|
||||
};
|
||||
}, this)
|
||||
}
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render the radio buttons', function () {
|
||||
expect(this.view.$('.CDB-Radio').length).toBe(2);
|
||||
expect($(this.view.$('.CDB-Radio').get(0)).val('jpg')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should add the classes', function () {
|
||||
expect($(this.view.$('.CDB-Radio').get(0)).hasClass('firstClass')).toBeTruthy();
|
||||
expect($(this.view.$('.CDB-Radio').get(1)).hasClass('secondClass')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return the right value', function () {
|
||||
$(this.view.$('.CDB-Radio').get(0)).click();
|
||||
expect(this.view.getValue()).toBe('jpg');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var SelectListView = require('builder/components/form-components/editors/select/select-list-view');
|
||||
var ItemTemplate = require('builder/components/custom-list/custom-list-item.tpl');
|
||||
var CustomListItemView = require('builder/components/custom-list/custom-list-item-view');
|
||||
var CustomListCollection = require('builder/components/custom-list/custom-list-collection');
|
||||
|
||||
describe('components/form-components/editors/select-list-view', function () {
|
||||
var mouseOverAction;
|
||||
var mouseOutAction;
|
||||
|
||||
var createViewFn = function (options) {
|
||||
mouseOverAction = jasmine.createSpy('mouseOverAction');
|
||||
mouseOutAction = jasmine.createSpy('mouseOutAction');
|
||||
|
||||
var collection = new CustomListCollection();
|
||||
collection.stateModel = new Backbone.Model({
|
||||
state: 'fetching'
|
||||
});
|
||||
|
||||
collection.isAsync = function () { return true; };
|
||||
var defaultOptions = {
|
||||
itemTemplate: ItemTemplate,
|
||||
itemView: CustomListItemView,
|
||||
collection: collection,
|
||||
mouseOverAction: mouseOverAction,
|
||||
mouseOutAction: mouseOutAction
|
||||
};
|
||||
|
||||
var view = new SelectListView(_.extend(defaultOptions, options));
|
||||
|
||||
return view;
|
||||
};
|
||||
|
||||
describe('.render', function () {
|
||||
it('should render properly', function () {
|
||||
var view = createViewFn();
|
||||
spyOn(view, '_renderListSection');
|
||||
|
||||
view.render();
|
||||
|
||||
expect(view._renderListSection).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('mouseOverAction', function () {
|
||||
describe('._onMouseOver', function () {
|
||||
it('should trigger mouseOverAction', function () {
|
||||
var view = createViewFn();
|
||||
|
||||
view.render();
|
||||
view._onMouseOver();
|
||||
|
||||
expect(mouseOverAction).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mouseOutAction', function () {
|
||||
describe('._onMouseOut', function () {
|
||||
it('should trigger mouseOutAction', function () {
|
||||
var view = createViewFn();
|
||||
|
||||
view.render();
|
||||
view._onMouseOut();
|
||||
|
||||
expect(mouseOutAction).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should have no leaks', function () {
|
||||
var view = createViewFn();
|
||||
|
||||
expect(view).toHaveNoLeaks();
|
||||
});
|
||||
});
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
var Backbone = require('backbone');
|
||||
var _ = require('underscore');
|
||||
// Required for affected specs, because we use backbone-forms through a global namespace
|
||||
require('builder/components/form-components/editors/select/multi-select-view.js');
|
||||
|
||||
function viewFactory (model) {
|
||||
return new Backbone.Form.editors.MultiSelect({
|
||||
key: 'names',
|
||||
schema: {
|
||||
options: ['pepe', 'paco', 'juan', 'rm_rick', 'rm_morty', 'rm_summer', 'rm_jerry', 'rm_beth', 'rm_mr meeseeks']
|
||||
},
|
||||
model: model
|
||||
});
|
||||
}
|
||||
|
||||
describe('components/form-components/editors/select/multi-select-view', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
names: 'pepe'
|
||||
});
|
||||
|
||||
this.view = viewFactory(this.model);
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$('.js-button').length).toBe(1);
|
||||
expect(this.view.$('.js-button').text()).toContain('components.backbone-forms.select.selected');
|
||||
});
|
||||
});
|
||||
|
||||
it('should trigger change event on select item', function () {
|
||||
var onChange = jasmine.createSpy('onChange');
|
||||
spyOn(_, 'debounce').and.callFake(function () {
|
||||
return onChange;
|
||||
});
|
||||
|
||||
var aView = viewFactory(this.model);
|
||||
aView.render();
|
||||
|
||||
aView.on('change', onChange);
|
||||
aView.collection.at(1).set({selected: true});
|
||||
|
||||
expect(onChange).toHaveBeenCalled();
|
||||
aView.remove();
|
||||
});
|
||||
|
||||
describe('all/none buttons', function () {
|
||||
it('should use _.debounce to prevent multiple change events firing', function () {
|
||||
var mockbounce = spyOn(_, 'debounce').and.callThrough();
|
||||
var aView = viewFactory(this.model);
|
||||
aView._selectAll();
|
||||
|
||||
expect(mockbounce).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('selects and deselects all', function () {
|
||||
this.view._selectAll();
|
||||
expect(this.view.collection.every(function (model) {
|
||||
return model.get('selected');
|
||||
})).toBe(true);
|
||||
|
||||
this.view._deselectAll();
|
||||
expect(this.view.collection.every(function (model) {
|
||||
return !model.get('selected');
|
||||
})).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
var Backbone = require('backbone');
|
||||
var SelectListView = require('builder/components/form-components/editors/select/select-list-view');
|
||||
var itemListTemplate = require('builder/components/custom-list/custom-list-item.tpl');
|
||||
var CustomListCollection = require('builder/components/custom-list/custom-list-collection');
|
||||
var CustomListItemView = require('builder/components/custom-list/custom-list-item-view');
|
||||
|
||||
describe('components/form-components/editors/select/select-list-view', function () {
|
||||
var view;
|
||||
|
||||
var createViewFn = function (options) {
|
||||
var collection = new CustomListCollection([], {});
|
||||
|
||||
var itemView = new CustomListItemView({
|
||||
model: new Backbone.Model()
|
||||
});
|
||||
|
||||
var selectListView = new SelectListView({
|
||||
collection: collection,
|
||||
itemTemplate: itemListTemplate,
|
||||
itemView: itemView
|
||||
});
|
||||
|
||||
return selectListView;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
view = createViewFn();
|
||||
view.render();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
view.clean();
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
expect(view).toHaveNoLeaks();
|
||||
});
|
||||
|
||||
describe('_toggleVisibility', function () {
|
||||
it('should render the overlay when visibility changes to true', function () {
|
||||
view.show();
|
||||
|
||||
var dropdownOverlay = document.querySelector('.CDB-Box-modalOverlay');
|
||||
expect(dropdownOverlay).not.toBeNull();
|
||||
expect(window.getComputedStyle(dropdownOverlay).display).toBe('block');
|
||||
});
|
||||
|
||||
it('should remove the overlay when visibility changes to false', function () {
|
||||
view.show();
|
||||
view.hide();
|
||||
|
||||
var dropdownOverlay = document.querySelector('.CDB-Box-modalOverlay');
|
||||
expect(dropdownOverlay).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
var Backbone = require('backbone');
|
||||
var _ = require('underscore');
|
||||
|
||||
describe('components/form-components/editors/select', function () {
|
||||
var view;
|
||||
|
||||
var mouseOverAction;
|
||||
var mouseOutAction;
|
||||
|
||||
mouseOverAction = jasmine.createSpy('mouseOverAction');
|
||||
mouseOutAction = jasmine.createSpy('mouseOutAction');
|
||||
|
||||
var createViewFn = function (options) {
|
||||
var model = new Backbone.Model({
|
||||
names: 'pepe',
|
||||
latitude: undefined
|
||||
});
|
||||
|
||||
var defaultOptions = {
|
||||
key: 'names',
|
||||
schema: {
|
||||
options: ['pepe', 'paco', 'juan']
|
||||
},
|
||||
model: model,
|
||||
mouseOverAction: mouseOverAction,
|
||||
mouseOutAction: mouseOutAction,
|
||||
placeholder: 'gruntbuggly'
|
||||
};
|
||||
|
||||
view = new Backbone.Form.editors.SelectPlaceholder(_.extend(defaultOptions, options));
|
||||
|
||||
view.render();
|
||||
|
||||
return view;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
this.createView = createViewFn.bind(this);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
view && view.remove();
|
||||
});
|
||||
|
||||
it('should force is-empty if provided forcePlaceholder', function () {
|
||||
view = this.createView({
|
||||
forcePlaceholder: true
|
||||
});
|
||||
|
||||
var btn = view.$el.find('.js-button');
|
||||
|
||||
expect(btn.hasClass('is-empty')).toBe(true);
|
||||
expect(btn.text()).toContain('gruntbuggly');
|
||||
});
|
||||
|
||||
it('should force is-empty if provided forcePlaceholder', function () {
|
||||
view = this.createView({
|
||||
forcePlaceholder: false
|
||||
});
|
||||
|
||||
var btn = view.$el.find('.js-button');
|
||||
|
||||
expect(btn.hasClass('is-empty')).toBe(false);
|
||||
expect(btn.text()).not.toContain('gruntbuggly');
|
||||
expect(btn.text()).toContain('pepe');
|
||||
});
|
||||
});
|
||||
+292
@@ -0,0 +1,292 @@
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
var _ = require('underscore');
|
||||
var CustomListCollection = require('builder/components/custom-list/custom-list-collection');
|
||||
|
||||
describe('components/form-components/editors/select', function () {
|
||||
var view;
|
||||
var mouseOverAction;
|
||||
var mouseOutAction;
|
||||
|
||||
var dispatchDocumentEvent = function (type, opts) {
|
||||
var e = document.createEvent('HTMLEvents');
|
||||
e.initEvent(type, false, true);
|
||||
if (opts.which) {
|
||||
e.which = opts.which;
|
||||
}
|
||||
document.dispatchEvent(e, opts);
|
||||
};
|
||||
|
||||
mouseOverAction = jasmine.createSpy('mouseOverAction');
|
||||
mouseOutAction = jasmine.createSpy('mouseOutAction');
|
||||
|
||||
var createViewFn = function (options) {
|
||||
var model = new Backbone.Model({
|
||||
names: 'pepe',
|
||||
latitude: undefined
|
||||
});
|
||||
|
||||
var defaultOptions = {
|
||||
key: 'names',
|
||||
schema: {
|
||||
options: ['pepe', 'paco', 'juan']
|
||||
},
|
||||
model: model,
|
||||
mouseOverAction: mouseOverAction,
|
||||
mouseOutAction: mouseOutAction
|
||||
};
|
||||
|
||||
view = new Backbone.Form.editors.Select(_.extend(defaultOptions, options));
|
||||
|
||||
view.render();
|
||||
|
||||
return view;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
this.createView = createViewFn.bind(this);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
view && view.remove();
|
||||
});
|
||||
|
||||
it('should genereate an options collection', function () {
|
||||
view = this.createView();
|
||||
|
||||
expect(view.collection).toBeDefined();
|
||||
expect(view.collection.size()).toBe(3);
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('should render properly', function () {
|
||||
view = this.createView();
|
||||
|
||||
expect(view.$('.js-button').length).toBe(1);
|
||||
expect(view.$('.js-button').text()).toContain('pepe');
|
||||
});
|
||||
|
||||
it('should render custom placeholder if provided', function () {
|
||||
view = this.createView({
|
||||
placeholder: 'quinoa',
|
||||
keyAttr: 'latitude'
|
||||
});
|
||||
|
||||
expect(view.$('.js-button').length).toBe(1);
|
||||
expect(view.$('.js-button').text()).toContain('quinoa');
|
||||
});
|
||||
|
||||
it('should pass searchPlaceholder to CustomListView if present', function () {
|
||||
var text = 'Search Machine';
|
||||
view = this.createView({
|
||||
searchPlaceholder: text
|
||||
});
|
||||
|
||||
expect(view._listView.options.searchPlaceholder).toEqual(text);
|
||||
});
|
||||
|
||||
it('should disable the component if option is true', function () {
|
||||
view = this.createView();
|
||||
|
||||
view.options.disabled = true;
|
||||
view.render();
|
||||
expect(view.$('.js-button').hasClass('is-disabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should add is-empty class if there is no value selected', function () {
|
||||
view = this.createView();
|
||||
|
||||
view.model.set({names: ''});
|
||||
view.setValue('');
|
||||
|
||||
expect(view.$('.js-button').hasClass('is-empty')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('bindings', function () {
|
||||
beforeEach(function () {
|
||||
view = this.createView();
|
||||
spyOn(view._listView, 'hide');
|
||||
});
|
||||
|
||||
it('should close list view if ESC is pressed', function () {
|
||||
dispatchDocumentEvent('keydown', { which: 27 });
|
||||
expect(view._listView.hide).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('on ENTER pressed', function () {
|
||||
beforeEach(function () {
|
||||
view = this.createView();
|
||||
spyOn(view._listView, 'toggle');
|
||||
this._event = $.Event('keydown');
|
||||
this._event.which = 13;
|
||||
});
|
||||
|
||||
it('should open custom list', function () {
|
||||
view.$('.js-button').trigger(this._event);
|
||||
expect(view._listView.toggle).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not open custom list if it is already visible', function () {
|
||||
view._listView.show();
|
||||
view.$('.js-button').trigger(this._event);
|
||||
expect(view._listView.toggle).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should change button value and hide list when a new item is selected', function () {
|
||||
view = this.createView();
|
||||
spyOn(view._listView, 'hide');
|
||||
var mdl = view.collection.where({ val: 'juan' });
|
||||
mdl[0].set('selected', true);
|
||||
expect(view.$('.js-button').text()).toContain('juan');
|
||||
expect(view.$('.js-button').hasClass('is-empty')).toBeFalsy();
|
||||
expect(view._listView.hide).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should open list view if "button" is clicked', function () {
|
||||
view = this.createView();
|
||||
spyOn(view._listView, 'toggle');
|
||||
view.$('.js-button').trigger('click');
|
||||
expect(view._listView.toggle).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should destroy custom list, and tooltip when element is removed', function () {
|
||||
view = this.createView();
|
||||
spyOn(view._listView, 'clean');
|
||||
spyOn(view, '_removeTooltip');
|
||||
|
||||
view.remove();
|
||||
|
||||
expect(view._listView.clean).toHaveBeenCalled();
|
||||
expect(view._removeTooltip).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('placeholder', function () {
|
||||
it('empty and no value', function () {
|
||||
view = this.createView({
|
||||
keyAttr: 'latitude',
|
||||
schema: {
|
||||
options: []
|
||||
}
|
||||
});
|
||||
|
||||
var placeholder = $.trim(view.$('.js-button').text());
|
||||
expect(placeholder).toBe('components.backbone-forms.select.empty');
|
||||
});
|
||||
|
||||
it('disabled and no value', function () {
|
||||
view = this.createView({
|
||||
keyAttr: 'latitude',
|
||||
disabled: true
|
||||
});
|
||||
|
||||
var placeholder = $.trim(view.$('.js-button').text());
|
||||
expect(placeholder).toBe('components.backbone-forms.select.disabled-placeholder');
|
||||
});
|
||||
|
||||
it('no value', function () {
|
||||
view = this.createView({
|
||||
keyAttr: 'latitude'
|
||||
});
|
||||
|
||||
var placeholder = $.trim(view.$('.js-button').text());
|
||||
expect(placeholder).toBe('components.backbone-forms.select.placeholder');
|
||||
});
|
||||
});
|
||||
|
||||
describe('async collection', function () {
|
||||
beforeEach(function () {
|
||||
var collection = new CustomListCollection();
|
||||
collection.stateModel = new Backbone.Model({
|
||||
state: 'fetching'
|
||||
});
|
||||
|
||||
collection.isAsync = function () { return true; };
|
||||
|
||||
view = this.createView({
|
||||
schema: {
|
||||
collection: collection
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should show loading if collection is fetching', function () {
|
||||
expect(view.$('.js-button .CDB-LoaderIcon').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should show list once collection is fetched', function () {
|
||||
view.collection.reset([{
|
||||
label: 'pepe',
|
||||
val: 'pepe'
|
||||
}, {
|
||||
label: 'paco',
|
||||
val: 'paco'
|
||||
}, {
|
||||
label: 'juan',
|
||||
val: 'juan'
|
||||
}]);
|
||||
|
||||
view.collection.stateModel.set({
|
||||
state: 'fetched'
|
||||
});
|
||||
|
||||
expect(view.$('.CustomList--inner').length).toBe(1);
|
||||
expect(view.$('.js-button').text()).toContain('pepe');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with help', function () {
|
||||
beforeEach(function () {
|
||||
view = this.createView({
|
||||
editorAttrs: {
|
||||
help: 'help'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('.render', function () {
|
||||
it('should render properly', function () {
|
||||
expect(view.$('.js-help').attr('data-tooltip')).toContain('help');
|
||||
});
|
||||
});
|
||||
|
||||
describe('._removeTooltip', function () {
|
||||
it('should destroy tooltip', function () {
|
||||
spyOn(view._helpTooltip, 'clean');
|
||||
|
||||
view._removeTooltip();
|
||||
|
||||
expect(view._helpTooltip.clean).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mouseOverAction', function () {
|
||||
describe('._onMouseOver', function () {
|
||||
it('should trigger mouseOverAction', function () {
|
||||
view = this.createView();
|
||||
view._onMouseOver();
|
||||
|
||||
expect(mouseOverAction).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mouseOutAction', function () {
|
||||
describe('._onMouseOut', function () {
|
||||
it('should trigger mouseOutAction', function () {
|
||||
view = this.createView();
|
||||
view._onMouseOut();
|
||||
|
||||
expect(mouseOutAction).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
view = this.createView();
|
||||
expect(view).toHaveNoLeaks();
|
||||
});
|
||||
});
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
var Backbone = require('backbone');
|
||||
var View = require('builder/components/form-components/editors/size/size-by-value-content-view');
|
||||
|
||||
describe('components/form-components/editors/size/size-by-value-content-view', function () {
|
||||
var view;
|
||||
|
||||
function createView (model, opts) {
|
||||
model = model || new Backbone.Model({
|
||||
bins: 7,
|
||||
attribute: 'price',
|
||||
quantification: 'jenks'
|
||||
});
|
||||
|
||||
opts = opts || {};
|
||||
if (opts.fixed) {
|
||||
model.set('fixed', opts.fixed);
|
||||
}
|
||||
if (opts.range) {
|
||||
model.set('range', opts.range);
|
||||
}
|
||||
|
||||
var options = {
|
||||
model: model,
|
||||
min: 1,
|
||||
max: 50
|
||||
};
|
||||
|
||||
return new View(options);
|
||||
}
|
||||
|
||||
describe('render', function () {
|
||||
it('should render template and call _initForm', function () {
|
||||
view = createView();
|
||||
spyOn(view, '_initForm');
|
||||
|
||||
view.render();
|
||||
|
||||
expect(view.$('.js-back').length).toBe(1);
|
||||
expect(view.$('.test-quantification')[0].textContent.trim()).toContain('jenks');
|
||||
expect(view.$('.test-bins')[0].textContent.trim().indexOf('7')).toBe(0);
|
||||
expect(view.$('.test-attribute')[0].textContent.trim()).toEqual('price');
|
||||
expect(view._initForm).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('_initForm', function () {
|
||||
it('should calculate range and create formView', function () {
|
||||
view = createView();
|
||||
spyOn(view, '_getRangeOrCalculateItIfNeeded').and.returnValue(808);
|
||||
spyOn(view, '_createFormView').and.returnValue('a_formview');
|
||||
spyOn(view, '_renderFormView');
|
||||
|
||||
view._initForm();
|
||||
|
||||
expect(view._getRangeOrCalculateItIfNeeded).toHaveBeenCalled();
|
||||
expect(view._createFormView).toHaveBeenCalledWith(808);
|
||||
expect(view._renderFormView).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('_getRangeOrCalculateItIfNeeded', function () {
|
||||
it('should calculate range from fixed', function () {
|
||||
view = createView(null, { fixed: 18 });
|
||||
|
||||
var range = view._getRangeOrCalculateItIfNeeded();
|
||||
|
||||
expect(range[0]).toBe(6);
|
||||
expect(range[1]).toBe(29);
|
||||
expect(view.model.get('fixed')).not.toBeDefined();
|
||||
expect(view.model.get('range')).toBeDefined();
|
||||
expect(view.model.get('range')[0]).toBe(6);
|
||||
expect(view.model.get('range')[1]).toBe(29);
|
||||
});
|
||||
|
||||
it('should return range if exists', function () {
|
||||
view = createView(null, { range: [45, 57] });
|
||||
|
||||
var range = view._getRangeOrCalculateItIfNeeded();
|
||||
|
||||
expect(range[0]).toBe(45);
|
||||
expect(range[1]).toBe(57);
|
||||
});
|
||||
});
|
||||
|
||||
describe('_createFormView', function () {
|
||||
it('should create the form view', function () {
|
||||
view = createView();
|
||||
|
||||
var formView = view._createFormView([45, 47]);
|
||||
|
||||
expect(formView.model.get('min')).toBe(45);
|
||||
expect(formView.model.get('max')).toBe(47);
|
||||
expect(formView.model.schema).toEqual(jasmine.objectContaining({
|
||||
min: {
|
||||
type: 'Number',
|
||||
validators: [
|
||||
'required',
|
||||
{
|
||||
type: 'interval',
|
||||
min: 1,
|
||||
max: 50
|
||||
}
|
||||
]
|
||||
},
|
||||
max: {
|
||||
type: 'Number',
|
||||
validators: [
|
||||
'required',
|
||||
{
|
||||
type: 'interval',
|
||||
min: 1,
|
||||
max: 50
|
||||
}
|
||||
]
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
it('change bindings sets model and commits form', function () {
|
||||
view = createView(null, { range: [15, 35] });
|
||||
view.render();
|
||||
|
||||
var $input1 = view.$('.js-input').first();
|
||||
var $input2 = view.$('.js-input').last();
|
||||
$input1.val(10);
|
||||
$input2.val(40);
|
||||
view._formView.trigger('change');
|
||||
|
||||
expect(view.model.get('range')[0]).toEqual(10);
|
||||
expect(view.model.get('range')[1]).toEqual(40);
|
||||
});
|
||||
});
|
||||
|
||||
describe('events', function () {
|
||||
it('should hook up js-back with _onClickBack', function (done) {
|
||||
view = createView(null, { range: [15, 35] });
|
||||
view.render();
|
||||
view.on('back', function () {
|
||||
expect(true).toBe(true);
|
||||
done();
|
||||
});
|
||||
|
||||
view.$('.js-back').click();
|
||||
});
|
||||
|
||||
it('should hook up js-quantification with _onClickQuantification', function (done) {
|
||||
view = createView(null, { range: [15, 35] });
|
||||
view.render();
|
||||
view.on('selectQuantification', function () {
|
||||
expect(true).toBe(true);
|
||||
done();
|
||||
});
|
||||
|
||||
view.$('.js-quantification').click();
|
||||
});
|
||||
|
||||
it('should hook up js-bins with _onClickBins', function (done) {
|
||||
view = createView(null, { range: [15, 35] });
|
||||
view.render();
|
||||
view.on('selectBins', function () {
|
||||
expect(true).toBe(true);
|
||||
done();
|
||||
});
|
||||
|
||||
view.$('.js-bins').click();
|
||||
});
|
||||
});
|
||||
|
||||
describe('clean', function () {
|
||||
it('clean removes form', function () {
|
||||
view = createView();
|
||||
view.render();
|
||||
expect(view.$('form').length).toBe(1);
|
||||
|
||||
view.clean();
|
||||
|
||||
expect(view.$('form').length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
var Backbone = require('backbone');
|
||||
var _ = require('underscore');
|
||||
var SizeByValueView = require('builder/components/form-components/editors/size/size-by-value-view');
|
||||
var FillConstants = require('builder/components/form-components/_constants/_fill');
|
||||
|
||||
describe('components/form-components/editors/size/size-by-value-view', function () {
|
||||
var view;
|
||||
var defaultSettings = FillConstants.Settings.NUMBER;
|
||||
|
||||
function createView (options) {
|
||||
options = options || {
|
||||
model: new Backbone.Model({}),
|
||||
columns: {},
|
||||
popupConfig: {}
|
||||
};
|
||||
return new SizeByValueView(options);
|
||||
}
|
||||
|
||||
describe('initialize', function () {
|
||||
it('model is set with default options', function () {
|
||||
view = createView();
|
||||
|
||||
expect(view.model.get('quantification')).toEqual(defaultSettings.quantifications.items[defaultSettings.quantifications.defaultIndex]);
|
||||
expect(view.model.get('bins')).toBe(defaultSettings.bins.items[defaultSettings.bins.defaultIndex]);
|
||||
});
|
||||
|
||||
it('model is initialized with options', function () {
|
||||
view = createView({
|
||||
model: new Backbone.Model({
|
||||
quantification: 'jenks',
|
||||
bins: 7
|
||||
}),
|
||||
columns: {},
|
||||
popupConfig: {}
|
||||
});
|
||||
|
||||
expect(view.model.get('quantification')).toEqual('jenks');
|
||||
expect(view.model.get('bins')).toBe(7);
|
||||
});
|
||||
|
||||
it('model bins get limited by settings', function () {
|
||||
view = createView({
|
||||
model: new Backbone.Model({
|
||||
bins: _.last(defaultSettings.bins.items) + 1
|
||||
}),
|
||||
columns: {},
|
||||
popupConfig: {}
|
||||
});
|
||||
|
||||
expect(view.model.get('bins')).toBe(_.last(defaultSettings.bins.items));
|
||||
});
|
||||
|
||||
it('attribute change triggers render', function () {
|
||||
view = createView({
|
||||
model: new Backbone.Model({
|
||||
attribute: 'an_attribute'
|
||||
}),
|
||||
columns: {},
|
||||
popupConfig: {}
|
||||
});
|
||||
expect(view.el.children.length).toBe(0);
|
||||
|
||||
view.model.set('attribute', 'another_attribute');
|
||||
|
||||
expect(view.el.children.length).not.toBe(0);
|
||||
});
|
||||
|
||||
it('range change triggers render', function () {
|
||||
view = createView({
|
||||
model: new Backbone.Model({
|
||||
range: [0, 5]
|
||||
}),
|
||||
columns: {},
|
||||
popupConfig: {}
|
||||
});
|
||||
expect(view.el.children.length).toBe(0);
|
||||
|
||||
view.model.set('range', [3, 7]);
|
||||
|
||||
expect(view.el.children.length).not.toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('calls to _initViews', function () {
|
||||
view = createView();
|
||||
spyOn(view, '_initDialog');
|
||||
spyOn(view, '_initPopup');
|
||||
spyOn(view, '_initInputColumn');
|
||||
|
||||
view.render();
|
||||
|
||||
expect(view._initDialog).toHaveBeenCalled();
|
||||
expect(view._initPopup).toHaveBeenCalled();
|
||||
expect(view._initInputColumn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('renders the column info', function () {
|
||||
view = createView({
|
||||
model: new Backbone.Model({
|
||||
attribute: 'price',
|
||||
range: [3, 9]
|
||||
}),
|
||||
columns: {},
|
||||
popupConfig: {
|
||||
cid: 357,
|
||||
$el: 'an_element'
|
||||
}
|
||||
});
|
||||
|
||||
view.render();
|
||||
|
||||
expect(view.$('.by-column-name').text().trim()).toEqual('price');
|
||||
expect(view.$('.by-column-range').text().trim()).toEqual('3 - 9');
|
||||
});
|
||||
});
|
||||
|
||||
describe('_initDialog', function () {
|
||||
it('creates the dialog view and binds destroy', function () {
|
||||
view = createView();
|
||||
expect(view._dialogView).not.toBeDefined();
|
||||
|
||||
view._initDialog();
|
||||
|
||||
expect(view._dialogView).toBeDefined();
|
||||
|
||||
view._dialogView.model.trigger('destroy');
|
||||
|
||||
expect(view._dialogView).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('_initPopup', function () {
|
||||
it('popupmanager gets created', function () {
|
||||
view = createView({
|
||||
model: new Backbone.Model({}),
|
||||
columns: {},
|
||||
popupConfig: {
|
||||
cid: 357,
|
||||
$el: 'an_element'
|
||||
}
|
||||
});
|
||||
expect(view._popupManager).not.toBeDefined();
|
||||
|
||||
view._initDialog();
|
||||
view._initPopup();
|
||||
|
||||
expect(view._popupManager.id).toBe(357);
|
||||
expect(view._popupManager.reference).toEqual('an_element');
|
||||
expect(view._popupManager.popup).toBe(view._dialogView.$el);
|
||||
});
|
||||
});
|
||||
|
||||
describe('events', function () {
|
||||
it('should hookup selectors with functions', function () {
|
||||
view = createView();
|
||||
|
||||
expect(view.events['click .js-button']).toEqual('_showByValueDialog');
|
||||
expect(view.events['click .js-back']).toEqual('_onClickBack');
|
||||
});
|
||||
});
|
||||
});
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
var Backbone = require('backbone');
|
||||
var SizeFixedView = require('builder/components/form-components/editors/size/size-fixed-view');
|
||||
|
||||
describe('components/form-components/editors/size/size-fixed-view', function () {
|
||||
var sizeFixedView;
|
||||
|
||||
function createView (options) {
|
||||
sizeFixedView = new SizeFixedView({
|
||||
model: new Backbone.Model({
|
||||
fixed: 5
|
||||
}),
|
||||
min: 1,
|
||||
max: 15,
|
||||
step: 2
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
createView();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
sizeFixedView.clean();
|
||||
});
|
||||
|
||||
it('renders with the expected schema', function () {
|
||||
sizeFixedView.render();
|
||||
|
||||
// Schema
|
||||
var schema = sizeFixedView._formModel.schema.value;
|
||||
expect(schema).toBeDefined();
|
||||
expect(schema.type).toEqual('Number');
|
||||
expect(schema.title).toEqual('');
|
||||
expect(schema.validators.length).toBe(2);
|
||||
expect(schema.validators[0]).toEqual('required');
|
||||
expect(schema.validators[1]).toEqual(jasmine.objectContaining({
|
||||
type: 'interval',
|
||||
min: 1,
|
||||
max: 15,
|
||||
step: 2
|
||||
}));
|
||||
|
||||
// Render
|
||||
expect(sizeFixedView.$('form').length).toBe(1);
|
||||
var input = sizeFixedView.$('.js-input');
|
||||
expect(input[0].value).toEqual('5');
|
||||
});
|
||||
|
||||
it('change binding sets model and commit form', function () {
|
||||
sizeFixedView.render();
|
||||
|
||||
var $input = sizeFixedView.$('.js-input').first();
|
||||
$input.val(10);
|
||||
sizeFixedView._formView.trigger('change');
|
||||
|
||||
expect(sizeFixedView.model.get('fixed')).toEqual(10);
|
||||
});
|
||||
|
||||
it('clean removes form', function () {
|
||||
sizeFixedView.render();
|
||||
expect(sizeFixedView.$('form').length).toBe(1);
|
||||
|
||||
sizeFixedView.clean();
|
||||
|
||||
expect(sizeFixedView.$('form').length).toBe(0);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,95 @@
|
||||
var Backbone = require('backbone');
|
||||
var SizeByValueView = require('builder/components/form-components/editors/size/size-by-value-view');
|
||||
|
||||
describe('/components/form-components/editors/size/size', function () {
|
||||
var size;
|
||||
|
||||
function createSize (opts) {
|
||||
opts = opts || {};
|
||||
var modelOptions = {};
|
||||
if (opts.fillSize) {
|
||||
modelOptions.fillSize = {
|
||||
fixed: opts.fillSize
|
||||
};
|
||||
}
|
||||
|
||||
var options = {
|
||||
model: new Backbone.Model(modelOptions),
|
||||
key: 'fillSize',
|
||||
schema: {
|
||||
validators: [ 'required' ],
|
||||
editorAttrs: {
|
||||
geometryName: 'point',
|
||||
hidePanes: []
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (opts.hidePanes) {
|
||||
options.schema.editorAttrs.hidePanes = opts.hidePanes;
|
||||
}
|
||||
if (opts.columns) {
|
||||
options.schema.options = opts.columns;
|
||||
}
|
||||
return new Backbone.Form.editors.Size(options);
|
||||
}
|
||||
|
||||
describe('render', function () {
|
||||
afterEach(function () {
|
||||
size.remove();
|
||||
});
|
||||
|
||||
it('both fixed and value if no options passed about it', function () {
|
||||
size = createSize();
|
||||
|
||||
expect(size.$('.js-menu').children().length).toBe(2);
|
||||
var labels = size.$('.js-menu > li label');
|
||||
expect(labels.length).toBe(2);
|
||||
expect(labels[0].textContent.trim()).toContain('form-components.editors.fill.input-number.fixed');
|
||||
expect(labels[1].textContent.trim()).toContain('form-components.editors.fill.input-number.by-value');
|
||||
});
|
||||
|
||||
it('only fixed if hidePanes set with `value`', function () {
|
||||
size = createSize({
|
||||
hidePanes: ['value'],
|
||||
fillSize: 7
|
||||
});
|
||||
|
||||
// Menu
|
||||
expect(size.$('.js-menu').children().length).toBe(1);
|
||||
var labels = size.$('.js-menu > li label');
|
||||
expect(labels.length).toBe(1);
|
||||
expect(labels[0].textContent.trim()).toContain('form-components.editors.fill.input-number.fixed');
|
||||
|
||||
// Form content
|
||||
expect(size.$('.js-content form').length).toBe(1);
|
||||
expect(size.$('.js-content form .js-input').val()).toEqual('7');
|
||||
});
|
||||
|
||||
describe('by value', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(SizeByValueView.prototype, 'initialize');
|
||||
spyOn(SizeByValueView.prototype, 'removeDialog');
|
||||
spyOn(SizeByValueView.prototype, 'removePopupManager');
|
||||
spyOn(SizeByValueView.prototype, '_showByValueDialog');
|
||||
spyOn(SizeByValueView.prototype, 'render').and.returnValue('<div class="fake-by-value"></div>');
|
||||
});
|
||||
it('only by value if hidePanes set with `fixed`', function () {
|
||||
size = createSize({
|
||||
hidePanes: ['fixed']
|
||||
});
|
||||
|
||||
// Menu
|
||||
expect(size.$('.js-menu').children().length).toBe(1);
|
||||
var labels = size.$('.js-menu > li label');
|
||||
expect(labels.length).toBe(1);
|
||||
expect(labels[0].textContent.trim()).toContain('form-components.editors.fill.input-number.by-value');
|
||||
|
||||
// Form content
|
||||
expect(SizeByValueView.prototype.render).toHaveBeenCalled();
|
||||
|
||||
size.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,169 @@
|
||||
var $ = require('jquery');
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
|
||||
describe('components/form-components/editors/slider', function () {
|
||||
var labels = ['Huckepack', 'Naseweis', 'Packe', 'Pick', 'Puck', 'Purzelbaum', 'Rumpelbold'];
|
||||
var values = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
|
||||
|
||||
var createViewFn = function (options) {
|
||||
var defaultOptions = {
|
||||
labels: labels,
|
||||
schema: {}
|
||||
};
|
||||
|
||||
var view = new Backbone.Form.editors.Slider(_.extend(defaultOptions, options));
|
||||
view.render();
|
||||
return view;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
this.view = createViewFn();
|
||||
this.viewWithValues = createViewFn({
|
||||
values: values,
|
||||
value: 'f'
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
this.viewWithValues.render();
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$('.js-slider').length).toBe(1);
|
||||
expect(this.view.$('.js-tick').length).toBe(labels.length);
|
||||
expect(this.view.$('.js-label').text()).toBe('Huckepack');
|
||||
expect($(this.view.$('.js-tick').get(0)).hasClass('is-highlighted')).toBeTruthy();
|
||||
|
||||
expect(this.viewWithValues.$('.js-slider').length).toBe(1);
|
||||
expect(this.viewWithValues.$('.js-tick').length).toBe(labels.length);
|
||||
expect(this.viewWithValues.$('.js-label').text()).toBe('Purzelbaum');
|
||||
expect($(this.viewWithValues.$('.js-tick').get(5)).hasClass('is-highlighted')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display neither the ticks nor the slider when there is only one value', function (done) {
|
||||
var self = this;
|
||||
this.view._values = ['1'];
|
||||
|
||||
document.body.appendChild(this.view.el);
|
||||
this.view.render();
|
||||
|
||||
setTimeout(function () {
|
||||
expect(self.view.$('.js-slider').css('display')).toBe('none');
|
||||
expect(self.view.$('.js-ticks').css('display')).toBe('none');
|
||||
done();
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('data', function () {
|
||||
it('should get a value by default', function () {
|
||||
expect(this.view.$('.js-label').text()).toBe('Huckepack');
|
||||
expect(this.viewWithValues.$('.js-label').text()).toBe('Purzelbaum');
|
||||
});
|
||||
|
||||
describe('change value', function () {
|
||||
beforeEach(function () {
|
||||
this.onChanged = jasmine.createSpy('onChanged');
|
||||
this.view.bind('change', this.onChanged);
|
||||
this.viewWithValues.bind('change', this.onChanged);
|
||||
});
|
||||
|
||||
describe('when slider changes', function () {
|
||||
beforeEach(function () {
|
||||
var $slider = this.view.$('.js-slider');
|
||||
$slider.val(4).change();
|
||||
var $sliderWithValues = this.viewWithValues.$('.js-slider');
|
||||
$sliderWithValues.val(4).change();
|
||||
});
|
||||
|
||||
it('should trigger change', function () {
|
||||
expect(this.onChanged).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update label', function () {
|
||||
expect(this.view.$('.js-label').text()).toBe('Puck');
|
||||
expect(this.viewWithValues.$('.js-label').text()).toBe('Puck');
|
||||
});
|
||||
|
||||
it('should highlight tick', function () {
|
||||
expect($(this.view.$('.js-tick').get(4)).hasClass('is-highlighted')).toBeTruthy();
|
||||
expect($(this.viewWithValues.$('.js-tick').get(4)).hasClass('is-highlighted')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return value', function () {
|
||||
expect(this.view.getValue()).toBe(4);
|
||||
expect(this.viewWithValues.getValue()).toBe('e');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('initial selection', function () {
|
||||
it('initial value', function () {
|
||||
this.view = createViewFn({
|
||||
values: [1, 2, 3, 4],
|
||||
labels: ['a', 'b', 'c', 'd'],
|
||||
schema: {},
|
||||
value: 2
|
||||
});
|
||||
|
||||
expect(this.view.getValue()).toBe(2);
|
||||
});
|
||||
|
||||
it('should start selecting the lowest value by default', function () {
|
||||
this.view = createViewFn({
|
||||
values: [1, 2, 3, 4],
|
||||
labels: ['a', 'b', 'c', 'd'],
|
||||
schema: {}
|
||||
});
|
||||
|
||||
expect(this.view.getValue()).toBe(1);
|
||||
});
|
||||
|
||||
it('should accept option to start selecting the highest value', function () {
|
||||
this.view = createViewFn({
|
||||
values: [1, 2, 3, 4],
|
||||
labels: ['a', 'b', 'c', 'd'],
|
||||
initial: 'highest',
|
||||
schema: {}
|
||||
});
|
||||
|
||||
expect(this.view.getValue()).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('exceptions', function () {
|
||||
it('should throw exception when the values and labels differ', function () {
|
||||
var wrapper = function () {
|
||||
createViewFn({
|
||||
values: [1, 2, 3, 4],
|
||||
labels: ['a', 'b'],
|
||||
schema: {}
|
||||
});
|
||||
};
|
||||
expect(wrapper).toThrow();
|
||||
});
|
||||
|
||||
it('should throw exception when there are no labels', function () {
|
||||
var wrapper = function () {
|
||||
createViewFn({
|
||||
values: [1, 2, 3, 4],
|
||||
schema: {}
|
||||
});
|
||||
};
|
||||
expect(wrapper).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
it('should destroy horizontal slider when element is removed', function () {
|
||||
spyOn(this.view, '_destroySlider');
|
||||
this.view.remove();
|
||||
expect(this.view._destroySlider).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
this.viewWithValues.remove();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,154 @@
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
var dispatchDocumentEvent = function (type, opts) {
|
||||
var e = document.createEvent('HTMLEvents');
|
||||
e.initEvent(type, false, true);
|
||||
if (opts.which) {
|
||||
e.which = opts.which;
|
||||
}
|
||||
document.dispatchEvent(e, opts);
|
||||
};
|
||||
|
||||
describe('components/form-components/editors/suggest', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
names: 'carlos'
|
||||
});
|
||||
|
||||
this.view = new Backbone.Form.editors.Suggest({
|
||||
key: 'names',
|
||||
schema: {
|
||||
options: []
|
||||
},
|
||||
model: this.model,
|
||||
editorAttrs: {
|
||||
showSearch: true,
|
||||
allowFreeTextInput: true,
|
||||
collectionData: ['pepe', 'paco', 'juan']
|
||||
}
|
||||
});
|
||||
this.view.render();
|
||||
this.listView = this.view._listView;
|
||||
});
|
||||
|
||||
describe('when there are values not null', function () {
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$('.js-button').length).toBe(1);
|
||||
expect(this.view.$('.js-button').text()).toContain('carlos');
|
||||
});
|
||||
|
||||
it('should disable the component if option is true', function () {
|
||||
this.view.options.disabled = true;
|
||||
this.view.render();
|
||||
expect(this.view.$('.js-button').hasClass('is-disabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should add is-empty class if null value is selected', function () {
|
||||
this.model.set('names', '');
|
||||
this.view.collection.removeSelected();
|
||||
this.view.render();
|
||||
expect(this.view.$('.js-button').hasClass('is-empty')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when all column row values are null but selected value is not null', function () {
|
||||
// ColumnRowData only fetches 40 rows
|
||||
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
names: 'carlos'
|
||||
});
|
||||
|
||||
this.view = new Backbone.Form.editors.Suggest({
|
||||
key: 'names',
|
||||
schema: {
|
||||
options: []
|
||||
},
|
||||
model: this.model,
|
||||
editorAttrs: {
|
||||
showSearch: true,
|
||||
allowFreeTextInput: true,
|
||||
collectionData: [null, null, null]
|
||||
}
|
||||
});
|
||||
this.view.render();
|
||||
this.listView = this.view._listView;
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$('.js-button').length).toBe(1);
|
||||
expect(this.view.$('.js-button').text()).toContain('carlos');
|
||||
});
|
||||
|
||||
it('should add is-empty class if null value is selected', function () {
|
||||
this.model.set('names', '');
|
||||
this.view.collection.removeSelected();
|
||||
this.view.render();
|
||||
expect(this.view.$('.js-button').hasClass('is-empty')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when all column row values are null', function () {
|
||||
// TODO: replace Text editor
|
||||
});
|
||||
|
||||
describe('bindings', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(this.listView, 'hide');
|
||||
});
|
||||
|
||||
it('should close list view if ESC is pressed', function () {
|
||||
dispatchDocumentEvent('keydown', { which: 27 });
|
||||
expect(this.listView.hide).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should close list view if user clicks out the select', function () {
|
||||
dispatchDocumentEvent('click', { target: 'body' });
|
||||
expect(this.listView.hide).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('on ENTER pressed', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(this.listView, 'toggle');
|
||||
this._event = $.Event('keydown');
|
||||
this._event.which = 13;
|
||||
});
|
||||
|
||||
it('should open custom list', function () {
|
||||
this.view.$('.js-button').trigger(this._event);
|
||||
expect(this.listView.toggle).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not open custom list if it is already visible', function () {
|
||||
this.listView.show();
|
||||
this.view.$('.js-button').trigger(this._event);
|
||||
expect(this.listView.toggle).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should change button value and hide list when a new item is selected', function () {
|
||||
spyOn(this.listView, 'hide');
|
||||
var mdl = this.view.collection.where({ val: 'juan' });
|
||||
mdl[0].set('selected', true);
|
||||
expect(this.view.$('.js-button').text()).toContain('juan');
|
||||
expect(this.view.$('.js-button').hasClass('is-empty')).toBeFalsy();
|
||||
expect(this.listView.hide).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should open list view if "button" is clicked', function () {
|
||||
spyOn(this.listView, 'toggle');
|
||||
this.view.$('.js-button').trigger('click');
|
||||
expect(this.listView.toggle).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should destroy custom list when element is removed', function () {
|
||||
spyOn(this.view._listView, 'clean');
|
||||
this.view.remove();
|
||||
expect(this.view._listView.clean).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,54 @@
|
||||
var Backbone = require('backbone');
|
||||
|
||||
describe('components/form-components/editors/taglist', function () {
|
||||
beforeEach(function () {
|
||||
this.view = new Backbone.Form.editors.Taglist({
|
||||
key: 'foo',
|
||||
schema: {
|
||||
options: {
|
||||
tags: ['foo', 'bar', 'lol'],
|
||||
isEditable: true
|
||||
}
|
||||
}
|
||||
});
|
||||
this.view.render();
|
||||
this.view.$el.appendTo(document.body);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
var parent = this.view.el.parentNode;
|
||||
parent && parent.removeChild(this.view.el);
|
||||
this.view.remove();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
expect(this.view.$('.tagit-choice').length).toBe(3);
|
||||
expect(this.view.$('.tagit-new').length).toBe(1);
|
||||
expect(this.view.$('.tagit-choice').eq(0).text()).toContain('foo');
|
||||
expect(this.view.$('.tagit-choice').eq(1).text()).toContain('bar');
|
||||
expect(this.view.$('.tagit-choice').eq(2).text()).toContain('lol');
|
||||
});
|
||||
|
||||
it('should setValue', function () {
|
||||
this.view.setValue(['vamos', 'neno']);
|
||||
expect(this.view.$('.tagit-choice').length).toBe(2);
|
||||
expect(this.view.$('.tagit-choice').eq(0).text()).toContain('vamos');
|
||||
expect(this.view.$('.tagit-choice').eq(1).text()).toContain('neno');
|
||||
});
|
||||
|
||||
it('should getValue', function () {
|
||||
this.view.setValue(['vamos', 'neno']);
|
||||
expect(this.view.getValue().length).toBe(2);
|
||||
});
|
||||
|
||||
it('should blur and focus properly', function () {
|
||||
this.view.$('.tagit-new input').trigger('focus');
|
||||
expect(this.view.$el.hasClass('is-focus')).toBe(true);
|
||||
this.view.$('.tagit-new input').trigger('blur');
|
||||
expect(this.view.$el.hasClass('is-focus')).toBe(false);
|
||||
});
|
||||
|
||||
it('should not have any leaks', function () {
|
||||
expect(this.view).toHaveNoLeaks();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,143 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
|
||||
describe('components/form-components/editors/text', function () {
|
||||
var createViewFn = function (options) {
|
||||
var defaultOptions = {
|
||||
schema: {}
|
||||
};
|
||||
|
||||
var view = new Backbone.Form.editors.Text(_.extend(defaultOptions, options));
|
||||
view.render();
|
||||
|
||||
return view;
|
||||
};
|
||||
|
||||
it('should render properly', function () {
|
||||
var view = createViewFn();
|
||||
expect(view.$el.attr('type')).toBe('text');
|
||||
|
||||
view.remove();
|
||||
});
|
||||
|
||||
it('should be possible to create another text type', function () {
|
||||
var view = createViewFn({
|
||||
schema: {
|
||||
editorAttrs: {
|
||||
type: 'email'
|
||||
}
|
||||
}
|
||||
});
|
||||
expect(view.$el.attr('type')).toBe('email');
|
||||
|
||||
view.remove();
|
||||
});
|
||||
|
||||
it('should return the value', function () {
|
||||
var view = createViewFn({
|
||||
value: 'Hello',
|
||||
schema: {}
|
||||
});
|
||||
|
||||
expect(view.options.value).toBe('Hello');
|
||||
view.render();
|
||||
expect(view.getValue()).toBe('Hello');
|
||||
|
||||
view.remove();
|
||||
});
|
||||
|
||||
describe('change value', function () {
|
||||
beforeEach(function () {
|
||||
this.view = createViewFn();
|
||||
|
||||
this.onChanged = jasmine.createSpy('onChanged');
|
||||
this.view.bind('change', this.onChanged);
|
||||
});
|
||||
|
||||
describe('when input changes', function () {
|
||||
beforeEach(function () {
|
||||
this.view.$el
|
||||
.val(6)
|
||||
.trigger('keyup');
|
||||
});
|
||||
|
||||
it('should trigger change', function () {
|
||||
expect(this.onChanged).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update input', function () {
|
||||
expect(this.view.$el.val()).toBe('6');
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
|
||||
it('should render custom placeholder if provided', function () {
|
||||
var view = createViewFn({
|
||||
placeholder: 'wadus'
|
||||
});
|
||||
|
||||
expect(view.$el.prop('placeholder')).toContain('wadus');
|
||||
|
||||
view.remove();
|
||||
});
|
||||
|
||||
it('should be disabled if provided', function () {
|
||||
var view = createViewFn({
|
||||
disabled: true
|
||||
});
|
||||
|
||||
expect(view.$el.prop('readonly')).toBe(true);
|
||||
expect(view.$el.hasClass('is-disabled')).toBe(true);
|
||||
|
||||
view.remove();
|
||||
});
|
||||
|
||||
it('should destroy custom list, and tooltip when element is removed', function () {
|
||||
var view = createViewFn();
|
||||
spyOn(view, '_removeTooltip');
|
||||
|
||||
view.remove();
|
||||
|
||||
expect(view._removeTooltip).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('with help', function () {
|
||||
var view;
|
||||
|
||||
beforeEach(function () {
|
||||
view = createViewFn({
|
||||
editorAttrs: {
|
||||
help: 'help'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('.render', function () {
|
||||
it('should render properly', function () {
|
||||
view.render();
|
||||
|
||||
expect(view._help).toEqual('help');
|
||||
expect(view._helpTooltip).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('._removeTooltip', function () {
|
||||
it('should destroy tooltip', function () {
|
||||
spyOn(view._helpTooltip, 'clean');
|
||||
|
||||
view._removeTooltip();
|
||||
|
||||
expect(view._helpTooltip.clean).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not have leaks', function () {
|
||||
var view = createViewFn();
|
||||
expect(view).toHaveNoLeaks();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,78 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
|
||||
describe('components/form-components/editors/textarea', function () {
|
||||
var createViewFn = function (options) {
|
||||
var model = new Backbone.Model({
|
||||
street_address_column: ''
|
||||
});
|
||||
|
||||
var defaultOptions = {
|
||||
schema: {},
|
||||
model: model,
|
||||
key: 'street_address_column'
|
||||
};
|
||||
|
||||
var view = new Backbone.Form.editors.TextArea(_.extend(defaultOptions, options));
|
||||
view.render();
|
||||
return view;
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
this.createView = createViewFn.bind(this);
|
||||
});
|
||||
|
||||
it('set key variable', function () {
|
||||
var view = this.createView();
|
||||
expect(view.key).toBe('street_address_column');
|
||||
view.remove();
|
||||
});
|
||||
|
||||
it('should render properly', function () {
|
||||
var view = this.createView();
|
||||
expect(view.$el.prop('tagName').toLowerCase()).toBe('textarea');
|
||||
view.remove();
|
||||
});
|
||||
|
||||
it('should return the value', function () {
|
||||
var model = new Backbone.Model({
|
||||
street_address_column: 'Hello'
|
||||
});
|
||||
|
||||
var view = this.createView({
|
||||
model: model
|
||||
});
|
||||
|
||||
expect(view.getValue()).toBe('Hello');
|
||||
view.remove();
|
||||
});
|
||||
|
||||
describe('change value', function () {
|
||||
beforeEach(function () {
|
||||
this.view = this.createView();
|
||||
|
||||
this.onChanged = jasmine.createSpy('onChanged');
|
||||
this.view.bind('change', this.onChanged);
|
||||
});
|
||||
|
||||
describe('when input changes', function () {
|
||||
beforeEach(function () {
|
||||
this.view.$el
|
||||
.val(6)
|
||||
.trigger('keyup');
|
||||
});
|
||||
|
||||
it('should trigger change', function () {
|
||||
expect(this.onChanged).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update input', function () {
|
||||
expect(this.view.$el.val()).toBe('6');
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
var _ = require('underscore');
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
|
||||
var OPTIONS = [{
|
||||
type: 'normal',
|
||||
label: 'normal',
|
||||
selected: true
|
||||
}, {
|
||||
type: 'advance',
|
||||
label: 'advance',
|
||||
selected: false
|
||||
}];
|
||||
|
||||
describe('components/form-components/editors/toggle', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({ context: 'normal' });
|
||||
|
||||
this.form = new Backbone.Form({
|
||||
model: this.model
|
||||
});
|
||||
|
||||
this.view = new Backbone.Form.editors.Toggle({
|
||||
key: 'context',
|
||||
form: this.form,
|
||||
schema: {
|
||||
options: _.map(OPTIONS, function (d) {
|
||||
return {
|
||||
val: d.type,
|
||||
label: d.label,
|
||||
selected: d.selected
|
||||
};
|
||||
}, this)
|
||||
}
|
||||
});
|
||||
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
it('should render the toggle links for the options that are not selected', function () {
|
||||
expect(this.view.$('label').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should render the radios', function () {
|
||||
expect(this.view.$('input[type="radio"]').length).toBe(2);
|
||||
expect($(this.view.$('input[type="radio"]').get(0)).val()).toBe('normal');
|
||||
});
|
||||
|
||||
it('should return the right value', function () {
|
||||
// trigger click in the radius despite it is hidden,
|
||||
// actually you have to click the label in the UI
|
||||
$(this.view.$('input[type="radio"]').get(1)).click();
|
||||
expect(this.view.getValue()).toBe('advance');
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.remove();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,170 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var editorsWithoutTrackClass = ['Base', 'Object', 'NestedModel'];
|
||||
var editorsNotInCARTO = ['Checkbox', 'Checkboxes', 'Date'];
|
||||
var DialogConstants = require('builder/components/form-components/_constants/_dialogs');
|
||||
|
||||
var OPTIONS_BY_TYPE = {
|
||||
'EnablerEditor': {
|
||||
editor: {
|
||||
type: 'Text'
|
||||
}
|
||||
},
|
||||
'Slider': {
|
||||
labels: ['hello', 'hey']
|
||||
},
|
||||
'Size': {
|
||||
schema: {
|
||||
editorAttrs: {}
|
||||
}
|
||||
},
|
||||
'Fill': {
|
||||
model: new Backbone.Model({
|
||||
names: 'pepe',
|
||||
stroke: {
|
||||
size: {
|
||||
range: [1, 30],
|
||||
attribute: 'the_geom',
|
||||
quantification: 'Quantile'
|
||||
},
|
||||
color: {
|
||||
bins: 5,
|
||||
range: ['#FFFFFF', '#FABADA', '#00FF00', '#000000', '#999999'],
|
||||
attribute: 'column1',
|
||||
quantification: 'Jenks',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
}),
|
||||
schema: {
|
||||
configModel: {},
|
||||
query: 'SELECT * from table',
|
||||
options: [
|
||||
{ label: 'column1', type: 'number' },
|
||||
{ label: 'column2', type: 'number' },
|
||||
{ label: 'column3', type: 'number' }
|
||||
]
|
||||
}
|
||||
},
|
||||
'FillColor': {
|
||||
model: new Backbone.Model({
|
||||
names: 'pepe',
|
||||
key: 'color',
|
||||
size: {
|
||||
range: [1, 30],
|
||||
attribute: 'the_geom',
|
||||
quantification: 'Quantile',
|
||||
editorAttrs: {
|
||||
geometryName: 'point'
|
||||
}
|
||||
},
|
||||
fillColor: {
|
||||
bins: 5,
|
||||
fixed: '#FABADA',
|
||||
attribute: 'column1',
|
||||
quantification: 'Jenks',
|
||||
opacity: 0.5,
|
||||
editorAttrs: {
|
||||
geometryName: 'point'
|
||||
}
|
||||
},
|
||||
help: {
|
||||
color: {
|
||||
colorAttributes: {}
|
||||
}
|
||||
}
|
||||
}),
|
||||
schema: {
|
||||
configModel: {},
|
||||
userModel: {},
|
||||
editorAttrs: {},
|
||||
modals: {},
|
||||
dialogMode: DialogConstants.Mode.FLOAT,
|
||||
query: 'SELECT * from table',
|
||||
options: [
|
||||
{ label: 'column1', type: 'number' },
|
||||
{ label: 'column2', type: 'number' },
|
||||
{ label: 'column3', type: 'number' }
|
||||
]
|
||||
}
|
||||
},
|
||||
'TagList': {
|
||||
schema: {
|
||||
options: {
|
||||
tags: ['foo', 'bar', 'lol'],
|
||||
isEditable: true
|
||||
}
|
||||
}
|
||||
},
|
||||
'DataObservatoryDropdown': {
|
||||
measurementModel: {},
|
||||
measurements: [],
|
||||
filters: [],
|
||||
configModel: new Backbone.Model({
|
||||
base_url: '/u/foo',
|
||||
user_name: 'foo',
|
||||
sql_api_template: 'foo',
|
||||
api_key: 'foo'
|
||||
}),
|
||||
nodeDefModel: {},
|
||||
region: 'wadus'
|
||||
},
|
||||
'LazySelect': {
|
||||
configModel: new Backbone.Model({
|
||||
base_url: '/u/foo',
|
||||
user_name: 'foo',
|
||||
sql_api_template: 'foo',
|
||||
api_key: 'foo'
|
||||
}),
|
||||
nodeDefModel: {
|
||||
querySchemaModel: new Backbone.Model({
|
||||
query: ''
|
||||
})
|
||||
},
|
||||
column: 'foo',
|
||||
model: new Backbone.Model({
|
||||
foo: 'bar'
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
describe('components/form-components/editors/track-class', function () {
|
||||
describe('trackingClass for', function () {
|
||||
_.each(Backbone.Form.editors, function (_class, key) {
|
||||
if (_.contains(editorsWithoutTrackClass, key) || _.contains(editorsNotInCARTO, key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var options = _.extend(
|
||||
{
|
||||
key: 'color',
|
||||
schema: {
|
||||
options: []
|
||||
},
|
||||
model: new Backbone.Model({ color: 'a' })
|
||||
},
|
||||
OPTIONS_BY_TYPE[key] || {}
|
||||
);
|
||||
|
||||
describe(key, function () {
|
||||
it('should not add the class if it not is specified', function () {
|
||||
var view = new _class(options);
|
||||
expect(view.$el.hasClass('track-class-whatever')).toBeFalsy();
|
||||
expect(view.options.trackingClass).toBeUndefined();
|
||||
view.remove();
|
||||
});
|
||||
|
||||
it('should add the class if it is specified', function () {
|
||||
var view = new _class(
|
||||
_.extend(options, {
|
||||
trackingClass: 'track-class-whatever'
|
||||
})
|
||||
);
|
||||
|
||||
expect(view.$el.hasClass('track-class-whatever')).toBeTruthy();
|
||||
view.remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
var Backbone = require('backbone');
|
||||
var ValidatorClass = require('builder/components/form-components/validators/column-type');
|
||||
|
||||
var Validator = ValidatorClass({
|
||||
type: 'columnType',
|
||||
columnsCollection: new Backbone.Collection([
|
||||
{ name: 'cartodb_id', type: 'number' },
|
||||
{ name: 'title', type: 'string' },
|
||||
{ name: 'created_at', type: 'date' }
|
||||
]),
|
||||
columnType: 'number'
|
||||
});
|
||||
|
||||
var error = { type: 'columnType', message: 'components.backbone-forms.column-type-error' };
|
||||
|
||||
describe('components/form-components/validators/column-type', function () {
|
||||
it('returns an error if there is no column with that name or the column doesnt match the type', function () {
|
||||
expect(Validator('this_column_does_not_exist')).toEqual(error);
|
||||
expect(Validator('title')).toEqual(error);
|
||||
});
|
||||
|
||||
it('returns undefined if the column matches the type', function () {
|
||||
expect(Validator('cartodb_id')).toBe(undefined);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,83 @@
|
||||
var $ = require('jquery');
|
||||
var Backbone = require('backbone');
|
||||
require('backbone-forms');
|
||||
Backbone.$ = $;
|
||||
require('builder/components/form-components/field.js');
|
||||
|
||||
describe('components/form-components/field', function () {
|
||||
beforeEach(function () {
|
||||
this.model = new Backbone.Model({
|
||||
test: true
|
||||
});
|
||||
this.model.schema = {
|
||||
test: {
|
||||
type: 'Text'
|
||||
}
|
||||
};
|
||||
|
||||
this.form = new Backbone.Form({
|
||||
model: this.model
|
||||
});
|
||||
|
||||
this.view = this.form.fields.test;
|
||||
});
|
||||
|
||||
describe('render', function () {
|
||||
it('should add help tooltip when it is defined', function () {
|
||||
spyOn(this.view, '_createTooltip').and.callThrough();
|
||||
expect(this.view._helpTooltip).toBeUndefined();
|
||||
this.view.schema.help = 'hello';
|
||||
this.view.render();
|
||||
expect(this.view._createTooltip).toHaveBeenCalled();
|
||||
expect(this.view._helpTooltip).toBeDefined();
|
||||
});
|
||||
|
||||
it('should add a custom class for the field', function () {
|
||||
this.view.render();
|
||||
expect(this.view.$el.hasClass('Editor-formInner--Text')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('on error', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(this.view, '_createTooltip').and.callThrough();
|
||||
this.view.setError('oh error!');
|
||||
spyOn(this.view._errorTooltip, 'hideTipsy').and.callThrough();
|
||||
spyOn(this.view._errorTooltip, 'destroyTipsy').and.callThrough();
|
||||
});
|
||||
|
||||
it('should add error tooltip', function () {
|
||||
expect(this.view._createTooltip).toHaveBeenCalled();
|
||||
expect(this.view._errorTooltip).toBeDefined();
|
||||
});
|
||||
|
||||
it('should clean error tooltip when error is gone', function () {
|
||||
this.view.clearError();
|
||||
expect(this.view._errorTooltip.hideTipsy).toHaveBeenCalled();
|
||||
expect(this.view._errorTooltip.destroyTipsy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.view.clearError();
|
||||
});
|
||||
});
|
||||
|
||||
it('should provide more info with templateData function', function () {
|
||||
var templateData = this.view.templateData();
|
||||
expect('hasNestedForm' in templateData).toBeDefined();
|
||||
});
|
||||
|
||||
describe('remove', function () {
|
||||
it('should delete tooltip views', function () {
|
||||
spyOn(this.view, '_destroyHelpTooltip');
|
||||
spyOn(this.view, '_destroyErrorTooltip');
|
||||
this.view.remove();
|
||||
expect(this.view._destroyHelpTooltip).toHaveBeenCalled();
|
||||
expect(this.view._destroyErrorTooltip).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
this.form.remove();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user