AMBARI-14648 Cover with unit tests recommendations flow 2. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ac1fbc23 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ac1fbc23 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ac1fbc23 Branch: refs/heads/branch-dev-patch-upgrade Commit: ac1fbc23d2d9d759cf24e61ba7c5fdf0be434ea4 Parents: a717275 Author: ababiichuk <[email protected]> Authored: Wed Jan 13 16:02:30 2016 +0200 Committer: ababiichuk <[email protected]> Committed: Wed Jan 13 17:07:37 2016 +0200 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 1 + .../configs/config_recommendation_parser.js | 153 ++++--- ambari-web/app/utils/config.js | 25 +- .../config_recommendation_parser_test.js | 458 +++++++++++++++++++ ambari-web/test/utils/config_test.js | 2 +- 5 files changed, 583 insertions(+), 56 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/ac1fbc23/ambari-web/app/assets/test/tests.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js index 031a939..d6b0de8 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -137,6 +137,7 @@ var files = [ 'test/mappers/configs/themes_mapper_test', 'test/mixins/common/configs/enhanced_configs_test', 'test/mixins/common/configs/config_recommendations_test', + 'test/mixins/common/configs/config_recommendation_parser_test', 'test/mixins/common/configs/configs_saver_test', 'test/mixins/common/configs/toggle_isrequired_test', 'test/mixins/common/chart/storm_linear_time_test', http://git-wip-us.apache.org/repos/asf/ambari/blob/ac1fbc23/ambari-web/app/mixins/common/configs/config_recommendation_parser.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins/common/configs/config_recommendation_parser.js b/ambari-web/app/mixins/common/configs/config_recommendation_parser.js index 800e145..51d0b44 100644 --- a/ambari-web/app/mixins/common/configs/config_recommendation_parser.js +++ b/ambari-web/app/mixins/common/configs/config_recommendation_parser.js @@ -37,33 +37,43 @@ App.ConfigRecommendationParser = Em.Mixin.create(App.ConfigRecommendations, { */ parseRecommendations: function(recommendationObject, configs, parentProperties, configGroup, updateCallback, removeCallback, updateBoundariesCallback) { + + App.assertObject(recommendationObject); + App.assertArray(configs); + App.assertFunction(updateCallback); + App.assertFunction(removeCallback); + App.assertFunction(updateBoundariesCallback); + var propertiesToDelete = []; configs.forEach(function (config) { var name = Em.get(config, 'name'), fileName = Em.get(config, 'filename'), - site = App.config.getConfigTagFromFileName(fileName); - if (recommendationObject[site]) { - var properties = recommendationObject[site].properties, - property_attributes = recommendationObject[site].property_attributes; - if (properties) { - var recommendedValue = App.config.formatValue(properties[name]); + recommendations = recommendationObject[App.config.getConfigTagFromFileName(fileName)]; + + if (recommendations) { + + if (recommendations.properties) { + var recommendedValue = App.config.formatValue(recommendations.properties[name]); if (!Em.isNone(recommendedValue)) { /** update config **/ updateCallback(config, recommendedValue, parentProperties, configGroup); - delete recommendationObject[site].properties[name]; + delete recommendations.properties[name]; } } - if (property_attributes) { - var propertyAttributes = property_attributes[name]; - var stackProperty = App.configsCollection.getConfigByName(name, fileName); - for (var attr in propertyAttributes) { - if (attr == 'delete' && this.allowUpdateProperty(parentProperties, name, fileName)) { - propertiesToDelete.push(config); - } else if (stackProperty) { - /** update config boundaries **/ - updateBoundariesCallback(stackProperty, attr, propertyAttributes[attr], configGroup); - } - } + + if (recommendations.property_attributes) { + var propertyAttributes = recommendations.property_attributes[name]; + if (propertyAttributes) { + var stackProperty = App.configsCollection.getConfigByName(name, fileName); + for (var attr in propertyAttributes) { + if (attr == 'delete' && this.allowUpdateProperty(parentProperties, name, fileName)) { + propertiesToDelete.push(config); + } else if (stackProperty) { + /** update config boundaries **/ + updateBoundariesCallback(stackProperty, attr, propertyAttributes[attr], configGroup); + } + } + } } } }, this); @@ -98,6 +108,8 @@ App.ConfigRecommendationParser = Em.Mixin.create(App.ConfigRecommendations, { * @param {Object[]} parentProperties */ addByRecommendations: function (recommendationObject, parentProperties) { + App.assertObject(recommendationObject); + for (var site in recommendationObject) { var properties = recommendationObject[site].properties; if (properties && Object.keys(properties).length) { @@ -105,11 +117,13 @@ App.ConfigRecommendationParser = Em.Mixin.create(App.ConfigRecommendations, { if (stepConfig) { for (var propertyName in properties) { if (this.allowUpdateProperty(parentProperties, propertyName, site)) { - this._addConfigByRecommendation(configs, propertyName, site, properties[propertyName], parentProperties); + configs.pushObject(this._createNewProperty(propertyName, site, stepConfig.get('serviceName'), properties[propertyName], parentProperties)); } } - var mergedConfigs = configs.concat(stepConfig.get('configs')); - stepConfig.set('configs', mergedConfigs); + if (configs.length) { + var mergedConfigs = configs.concat(stepConfig.get('configs')); + stepConfig.set('configs', mergedConfigs); + } } } } @@ -118,13 +132,15 @@ App.ConfigRecommendationParser = Em.Mixin.create(App.ConfigRecommendations, { /** * Update config based on recommendations * - * @param config - * @param recommendedValue - * @param parentProperties + * @param {recommendation} config + * @param {String} recommendedValue + * @param {String[]} [parentProperties] + * @returns {recommendation} * @protected */ _updateConfigByRecommendation: function (config, recommendedValue, parentProperties) { - Em.assert('config should be defined', config); + App.assertObject(config); + Em.set(config, 'recommendedValue', recommendedValue); if (this.allowUpdateProperty(parentProperties, Em.get(config, 'name'), Em.get(config, 'filename'))) { Em.set(config, 'value', recommendedValue); @@ -133,43 +149,53 @@ App.ConfigRecommendationParser = Em.Mixin.create(App.ConfigRecommendations, { if (this.updateInitialOnRecommendations(Em.get(config, 'serviceName'))) { Em.set(config, 'initialValue', recommendedValue); } + return config; }, /** * Add config based on recommendations * - * @param configs * @param name * @param fileName + * @param serviceName * @param recommendedValue * @param parentProperties * @protected */ - _addConfigByRecommendation: function (configs, name, fileName, recommendedValue, parentProperties) { - fileName = App.config.getOriginalFileName(fileName); - var stackConfig = App.configsCollection.getConfigByName(name, fileName), - service = App.config.get('serviceByConfigTypeMap')[App.config.getConfigTagFromFileName(fileName)]; - if (service) { - var serviceName = stackConfig ? stackConfig.serviceName : service && service.get('serviceName'), - popupProperty = this.getRecommendation(name, fileName), - initialValue = popupProperty ? popupProperty.value : null; - - var coreObject = { - "value": recommendedValue, - "recommendedValue": recommendedValue, - "initialValue": this.updateInitialOnRecommendations(serviceName) ? recommendedValue : initialValue, - "savedValue": !this.useInitialValue(serviceName) && !Em.isNone(initialValue) ? initialValue : null - }; - var addedProperty = stackConfig || App.config.createDefaultConfig(name, serviceName, fileName, false); - Em.setProperties(addedProperty, coreObject); - var addedPropertyObject = App.ServiceConfigProperty.create(addedProperty); - configs.pushObject(addedPropertyObject); - addedPropertyObject.validate(); - - this.applyRecommendation(name, fileName, "Default", - recommendedValue, null, parentProperties); - } - }, + _createNewProperty: function (name, fileName, serviceName, recommendedValue, parentProperties) { + App.assertExists(name, 'name'); + App.assertExists(fileName, 'fileName'); + App.assertExists(serviceName, 'serviceName'); + + var coreObject = this._getCoreProperties(serviceName, recommendedValue, this._getInitialFromRecommendations(name, fileName)), + newConfig = App.config.getDefaultConfig(name, fileName, serviceName, coreObject), + addedPropertyObject = App.ServiceConfigProperty.create(newConfig); + + addedPropertyObject.validate(); + + this.applyRecommendation(name, fileName, "Default", + recommendedValue, null, parentProperties); + + return addedPropertyObject; + }, + + /** + * + * @param serviceName + * @param recommendedValue + * @param initialValue + * @returns {{value: *, recommendedValue: *, initialValue: *, savedValue: *}} + * @private + */ + _getCoreProperties: function(serviceName, recommendedValue, initialValue) { + return { + "value": recommendedValue, + "recommendedValue": recommendedValue, + "initialValue": this.updateInitialOnRecommendations(serviceName) ? recommendedValue : initialValue, + "savedValue": !this.useInitialValue(serviceName) ? initialValue : null + } + }, + /** * Remove config based on recommendations @@ -180,7 +206,9 @@ App.ConfigRecommendationParser = Em.Mixin.create(App.ConfigRecommendations, { * @protected */ _removeConfigByRecommendation: function (config, configsCollection, parentProperties) { - Em.assert('config and configsCollection should be defined', config && configsCollection); + App.assertObject(config); + App.assertArray(configsCollection); + configsCollection.removeObject(config); this.applyRecommendation(Em.get(config, 'name'), Em.get(config, 'filename'), Em.get(config, 'group.name'), @@ -196,9 +224,30 @@ App.ConfigRecommendationParser = Em.Mixin.create(App.ConfigRecommendations, { * @protected */ _updateBoundaries: function(stackProperty, attr, value) { + App.assertObject(stackProperty); + if (!Em.get(stackProperty, 'valueAttributes')) { + stackProperty.valueAttributes = {}; + } Em.set(stackProperty.valueAttributes, attr, value); + return stackProperty; }, + /** + * Get initial config value that was before recommendations was applied + * + * @param name + * @param fileName + * @returns {*} + * @protected + */ + _getInitialFromRecommendations: function(name, fileName) { + try { + return this.getRecommendation(name, fileName).initialValue; + } catch(e) { + return null; + } + }, + /** * Get default config value * <code>savedValue<code> for installed services http://git-wip-us.apache.org/repos/asf/ambari/blob/ac1fbc23/ambari-web/app/utils/config.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js index 263baa2..d18c937 100644 --- a/ambari-web/app/utils/config.js +++ b/ambari-web/app/utils/config.js @@ -245,8 +245,7 @@ App.config = Em.Object.create({ var properties = siteConfig.properties || {}; for (var index in properties) { - var advancedConfig = App.configsCollection.getConfigByName(index, siteConfig.type); - var serviceConfigObj = advancedConfig || this.createDefaultConfig(index, serviceName, filename, false); + var serviceConfigObj = this.getDefaultConfig(index, serviceName, filename); this.restrictSecureProperties(serviceConfigObj); if (serviceConfigObj.isRequiredByAgent !== false) { @@ -278,6 +277,26 @@ App.config = Em.Object.create({ }, /** + * Get config from configsCollections or + * generate new default config in collection does not contain + * such config + * + * @param name + * @param serviceName + * @param fileName + * @param coreObject + * @returns {*|Object} + */ + getDefaultConfig: function(name, serviceName, fileName, coreObject) { + var cfg = App.configsCollection.getConfigByName(name, fileName) || + App.config.createDefaultConfig(name, serviceName, fileName, false, coreObject); + if (Em.typeOf(coreObject) === 'object') { + Em.setProperties(cfg, coreObject); + } + return cfg; + }, + + /** * This method sets default values for config property * These property values has the lowest priority and can be overridden be stack/UI * config property but is used when such properties are absent in stack/UI configs @@ -293,7 +312,7 @@ App.config = Em.Object.create({ /** core properties **/ id: this.configId(name, fileName), name: name, - filename: fileName, + filename: this.getOriginalFileName(fileName), value: '', savedValue: null, isFinal: false, http://git-wip-us.apache.org/repos/asf/ambari/blob/ac1fbc23/ambari-web/test/mixins/common/configs/config_recommendation_parser_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/mixins/common/configs/config_recommendation_parser_test.js b/ambari-web/test/mixins/common/configs/config_recommendation_parser_test.js new file mode 100644 index 0000000..f406336 --- /dev/null +++ b/ambari-web/test/mixins/common/configs/config_recommendation_parser_test.js @@ -0,0 +1,458 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var App = require('app'); + +describe('App.ConfigRecommendationParser', function() { + var mixinObject = Em.Controller.extend(App.ConfigRecommendationParser, {}); + var instanceObject = mixinObject.create({}); + + var recommendationObject = { + 'fileName1': { + 'properties': { + 'p1': 'v1' + }, + 'property_attributes': { + 'p2': { + 'delete': true + }, + 'p3': { + 'maximum': 100, + 'minimum': 1 + } + } + } + }; + var configs = [ + Em.Object.create({ + name: 'p1', + filename: 'fileName1' + }), + Em.Object.create({ + name: 'p2', + filename: 'fileName1' + }), + Em.Object.create({ + name: 'p3', + filename: 'fileName1' + }) + ]; + + beforeEach(function() { + instanceObject.set('stepConfigs', []); + }); + + + describe('#parseRecommendations', function() { + + describe('#recommendartion parsed', function() { + beforeEach(function() { + instanceObject.reopen({ + updateCallback: Em.K, + removeCallback: Em.K, + updateBoundariesCallback: Em.K + }); + + sinon.stub(App.configsCollection, 'getConfigByName', function(name, fileName) { + return { name: name, filename: fileName }; + }); + + sinon.spy(instanceObject, 'updateCallback'); + sinon.spy(instanceObject, 'removeCallback'); + sinon.spy(instanceObject, 'updateBoundariesCallback'); + + instanceObject.parseRecommendations(recommendationObject, configs, null, null, + instanceObject.updateCallback, instanceObject.removeCallback, instanceObject.updateBoundariesCallback); + }); + + afterEach(function() { + App.configsCollection.getConfigByName.restore(); + + instanceObject.updateCallback.restore(); + instanceObject.removeCallback.restore(); + instanceObject.updateBoundariesCallback.restore(); + }); + + it('updateCallback', function() { + expect(instanceObject.updateCallback.calledWith(configs[0], 'v1', null, null)).to.be.true; + }); + + it('removeCallback', function() { + expect(instanceObject.removeCallback.calledWith(configs[1], configs, null, null)).to.be.true; + }); + + it('updateBoundariesCallback maximum', function() { + expect(instanceObject.updateBoundariesCallback.calledWith({ name: 'p3', filename: 'fileName1' }, + 'maximum', 100, null)).to.be.true; + }); + + it('updateBoundariesCallback minimum', function() { + expect(instanceObject.updateBoundariesCallback.calledWith({ name: 'p3', filename: 'fileName1' }, + 'minimum', 1, null)).to.be.true; + }); + }); + + it('#recommendation parsing failed', function() { + expect(instanceObject.parseRecommendations.bind(instanceObject, null)).to.throw(App.ObjectTypeError); + }); + + it('#recommendation parsing failed', function() { + expect(instanceObject.parseRecommendations.bind(instanceObject, {}, null)).to.throw(App.ArrayTypeError); + }); + + it('#recommendation parsing failed', function() { + expect(instanceObject.parseRecommendations.bind(instanceObject, {}, [Em.Object.create({name: 'cfg1'})])).to.throw(App.FunctionTypeError); + }); + }); + + describe('#addByRecommendations', function(){ + var recommendationObject = { + 'file-name': { + 'properties': { + 'p1': 'v1' + } + } + }; + var stepConfig = App.ServiceConfig.create({ + serviceName: 'serviceName1', + configs: [] + }); + var cases = [ + { + m: 'allowUpdateProperty true', + allowUpdateProperty: true + }, + { + m: 'allowUpdateProperty false', + allowUpdateProperty: false + } + ]; + cases.forEach(function (c) { + describe('non error case', function() { + beforeEach(function() { + sinon.stub(App.config, 'getStepConfigForProperty').returns(stepConfig); + sinon.stub(instanceObject, 'allowUpdateProperty').returns(c.allowUpdateProperty); + sinon.stub(instanceObject, '_createNewProperty').returns(App.ServiceConfigProperty.create({ + 'name': 'p1', + 'filename': 'file-name' + })); + instanceObject.addByRecommendations(recommendationObject, []); + }); + + afterEach(function() { + App.config.getStepConfigForProperty.restore(); + instanceObject.allowUpdateProperty.restore(); + instanceObject._createNewProperty.restore(); + }); + + if (c.allowUpdateProperty) { + it ('adds new property', function() { + expect(instanceObject._createNewProperty.calledWith('p1', 'file-name', 'serviceName1', 'v1', [])).to.be.true; + + expect(stepConfig.get('configs.0')).to.eql(App.ServiceConfigProperty.create({ + 'name': 'p1', + 'filename': 'file-name' + })); + }); + + } else { + it('does not add property error', function() { + expect(instanceObject._createNewProperty.called).to.be.false; + }); + } + }); + }); + + it('throws error', function() { + expect(instanceObject.addByRecommendations.bind(instanceObject, null)).to.throw(App.ObjectTypeError); + }); + }); + + describe('#_updateConfigByRecommendation', function() { + var cases = [ + { + 'allowUpdateProperty': true, + 'updateInitialOnRecommendations': true, + 'm': 'allowUpdateProperty and update init on recommendation', + 'result': { + 'recommendedValue': 'recommendedValue', + 'value': 'recommendedValue', + 'initialValue': 'recommendedValue' + } + }, + { + 'allowUpdateProperty': true, + 'updateInitialOnRecommendations': false, + 'm': 'allowUpdateProperty and do not update init on recommendation', + 'result': { + 'recommendedValue': 'recommendedValue', + 'value': 'recommendedValue', + 'initialValue': null + } + }, + { + 'allowUpdateProperty': false, + 'updateInitialOnRecommendations': false, + 'm': 'do not allowUpdateProperty and do not update init on recommendation', + 'result': { + 'recommendedValue': 'recommendedValue', + 'value': null, + 'initialValue': null + } + } + ]; + + cases.forEach(function(c) { + describe('update recommendation', function() { + beforeEach(function() { + sinon.spy(instanceObject, 'applyRecommendation'); + sinon.stub(instanceObject, 'allowUpdateProperty').returns(c.allowUpdateProperty); + sinon.stub(instanceObject, 'updateInitialOnRecommendations').returns(c.updateInitialOnRecommendations); + }); + afterEach(function() { + instanceObject.allowUpdateProperty.restore(); + instanceObject.updateInitialOnRecommendations.restore(); + instanceObject.applyRecommendation.restore(); + }); + + it(c.m, function() { + expect(instanceObject._updateConfigByRecommendation({ + 'recommendedValue': null, + 'value': null, + 'initialValue': null + }, 'recommendedValue')).to.eql(c.result); + }); + + if(c.allowUpdateProperty) { + it('runs applyRecommendation', function() { + instanceObject._updateConfigByRecommendation({}, 'recommendedValue'); + expect(instanceObject.applyRecommendation.calledOnce).to.be.true; + }); + } + }); + }); + + it('throws error for configs', function() { + expect(instanceObject._updateConfigByRecommendation.bind(instanceObject, null)).to.throw(App.ObjectTypeError); + }); + }); + + describe('#_createNewProperty', function() { + beforeEach(function() { + sinon.spy(instanceObject, 'applyRecommendation'); + sinon.stub(instanceObject, '_getCoreProperties').returns({ + 'value': 'recommendedValue', + 'recommendedValue': 'recommendedValue', + 'initialValue': 'initialValue', + 'savedValue': null + }); + sinon.stub(App.config, 'getDefaultConfig', function(name, serviceName, fileName, coreObject) { + coreObject.name = name; + coreObject.filename = fileName; + coreObject.serviceName = serviceName; + return coreObject; + }); + }); + afterEach(function() { + instanceObject.applyRecommendation.restore(); + instanceObject._getCoreProperties.restore(); + App.config.getDefaultConfig.restore(); + }); + + it('adds new config', function() { + expect(instanceObject._createNewProperty('name', 'serviceName', 'fileName', 'recommendedValue', null)).to.eql(App.ServiceConfigProperty.create({ + 'value': 'recommendedValue', + 'recommendedValue': 'recommendedValue', + 'initialValue': 'initialValue', + 'savedValue': null, + 'name': 'name', + 'filename': 'fileName', + 'serviceName': 'serviceName' + })); + + expect(instanceObject.applyRecommendation.calledOnce).to.be.true; + }); + + it('throws error for name/fileName/serviceName', function() { + expect(instanceObject._createNewProperty.bind(instanceObject)).to.throw(App.NotNullTypeError); + expect(instanceObject._createNewProperty.bind(instanceObject, 'name')).to.throw(App.NotNullTypeError); + }); + }); + + describe('#_removeConfigByRecommendation', function() { + beforeEach(function() { + sinon.spy(instanceObject, 'applyRecommendation'); + }); + afterEach(function() { + instanceObject.applyRecommendation.restore(); + }); + + it('removes config', function() { + var configCollection = [ + {'name': 'cfg1'}, + {'name': 'cfg2'} + ]; + instanceObject._removeConfigByRecommendation(configCollection[0], configCollection); + expect(configCollection[0]).to.eql({'name': 'cfg2'}); + expect(instanceObject.applyRecommendation.calledOnce).to.be.true; + }); + + it('throws error', function() { + expect(instanceObject._removeConfigByRecommendation.bind(instanceObject, null)).to.throw(App.ObjectTypeError); + }); + + it('throws error', function() { + expect(instanceObject._removeConfigByRecommendation.bind(instanceObject, {}, null)).to.throw(App.ArrayTypeError); + }); + }); + + describe('#_updateBoundaries', function() { + it('sets appropriate attribute', function() { + expect(instanceObject._updateBoundaries({}, 'attr1', 'v1')).to.eql({ valueAttributes: {'attr1': 'v1'}}); + }); + + it('throws error', function() { + expect(instanceObject._updateBoundaries.bind(instanceObject, null, 'attr1', 'v1')).to.throw(App.ObjectTypeError); + }); + }); + + describe('#_getCoreProperties', function() { + var cases = [ + { + 'useInitialValue': true, + 'updateInitialOnRecommendations': true, + 'm': 'use init and update init on recommendation', + 'result': { + 'value': 'recommendedValue', + 'recommendedValue': 'recommendedValue', + 'initialValue': 'recommendedValue', + 'savedValue': null + } + }, + { + 'useInitialValue': true, + 'updateInitialOnRecommendations': false, + 'm': 'use init and do not update init on recommendation', + 'result': { + 'value': 'recommendedValue', + 'recommendedValue': 'recommendedValue', + 'initialValue': 'initValue', + 'savedValue': null + } + }, + { + 'useInitialValue': false, + 'updateInitialOnRecommendations': false, + 'm': 'do not use init and do not update init on recommendation', + 'result': { + 'value': 'recommendedValue', + 'recommendedValue': 'recommendedValue', + 'initialValue': 'initValue', + 'savedValue': 'initValue' + } + } + ]; + cases.forEach(function(c) { + describe('get core object for different cases', function() { + beforeEach(function() { + sinon.stub(instanceObject, 'useInitialValue').returns(c.useInitialValue); + sinon.stub(instanceObject, 'updateInitialOnRecommendations').returns(c.updateInitialOnRecommendations); + }); + afterEach(function() { + instanceObject.useInitialValue.restore(); + instanceObject.updateInitialOnRecommendations.restore(); + }); + it(c.m, function() { + expect(instanceObject._getCoreProperties('serviceName', 'recommendedValue', 'initValue')).to.eql(c.result); + }) + }) + }); + }); + + describe('#_getInitialFromRecommendations', function() { + beforeEach(function() { + instanceObject.set('recommendations', [ + { + propertyName: 'p1', + propertyFileName: 'f1', + configGroup: 'Default', + initialValue: 'initValue' + } + ]) + }); + + it('get init value from recommendations', function() { + expect(instanceObject._getInitialFromRecommendations('p1','f1')).to.equal('initValue'); + }); + + it('recommendation does not exist', function() { + expect(instanceObject._getInitialFromRecommendations('p2','f2')).to.equal(null); + }); + }); + + describe('#_getInitialValue', function() { + beforeEach(function() { + sinon.stub(instanceObject, 'useInitialValue', function(serviceName) { + return serviceName !== 'serviceNameInstalled' + }) + }); + afterEach(function() { + instanceObject.useInitialValue.restore(); + }); + + it('use initialValue', function() { + expect(instanceObject._getInitialValue({ + serviceName: 'serviceNameNotInstalled', + initialValue: 'initV', + savedValue: 'savedV' + })).to.equal('initV'); + }); + + it('use savedValue', function() { + expect(instanceObject._getInitialValue({ + serviceName: 'serviceNameInstalled', + initialValue: 'initV', + savedValue: 'savedV' + })).to.equal('savedV'); + }); + + it('wrong params', function() { + expect(instanceObject._getInitialValue()).to.be.null; + }); + }); + + describe('#updateInitialOnRecommendations', function() { + it('default value for updateInitialOnRecommendations is true', function() { + expect(instanceObject.updateInitialOnRecommendations()).to.be.false; + }) + }); + + describe('#useInitialValue', function() { + it('default value for useInitialValue is false', function() { + expect(instanceObject.useInitialValue()).to.be.false; + }) + }); + + describe('#allowUpdateProperty', function() { + it('default value for allowUpdateProperty is true', function() { + expect(instanceObject.allowUpdateProperty()).to.be.true; + }) + }); +}); + + http://git-wip-us.apache.org/repos/asf/ambari/blob/ac1fbc23/ambari-web/test/utils/config_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/utils/config_test.js b/ambari-web/test/utils/config_test.js index 13e0fa5..b58bfa3 100644 --- a/ambari-web/test/utils/config_test.js +++ b/ambari-web/test/utils/config_test.js @@ -951,7 +951,7 @@ describe('App.config', function () { /** core properties **/ id: "pName__pFileName", name: 'pName', - filename: 'pFileName', + filename: 'pFileName.xml', value: '', savedValue: null, isFinal: false,
