You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2017/02/01 17:30:57 UTC
ambari git commit: AMBARI-19821 Recommendations for non-editable
properties should be listed as 'Required Changes'. (ababiichuk)
Repository: ambari
Updated Branches:
refs/heads/branch-2.5 98baf6c04 -> 8423a3e55
AMBARI-19821 Recommendations for non-editable properties should be listed as 'Required Changes'. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/8423a3e5
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/8423a3e5
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/8423a3e5
Branch: refs/heads/branch-2.5
Commit: 8423a3e550f1b4d6ec5a49e0b894e645f74b76a5
Parents: 98baf6c
Author: ababiichuk <ab...@hortonworks.com>
Authored: Wed Feb 1 18:35:18 2017 +0200
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Wed Feb 1 19:40:23 2017 +0200
----------------------------------------------------------------------
ambari-web/app/messages.js | 7 +-
.../configs/config_recommendation_parser.js | 6 +-
.../common/configs/config_recommendations.js | 11 +-
...onfig_with_override_recommendation_parser.js | 4 +-
.../mixins/common/configs/enhanced_configs.js | 6 +-
.../modal_popups/dependent_configs_list.hbs | 49 +-
.../modal_popups/dependent_configs_table.hbs | 70 +++
.../dependent_configs_list_popup.js | 78 ++-
.../configs/config_recommendations_test.js | 600 ++++++++++---------
.../dependent_configs_list_popup_test.js | 4 +-
10 files changed, 464 insertions(+), 371 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/8423a3e5/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 9a41a63..33a8289 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -453,11 +453,16 @@ Em.I18n.translations = {
'popup.invalid.KDC.admin.password': 'Admin password',
'popup.dependent.configs.header': 'Dependent Configurations',
- 'popup.dependent.configs.title': 'Based on your configuration changes, Ambari is recommending the following dependent configuration changes. <br/> Ambari will update all checked configuration changes to the <b>Recommended Value</b>. Uncheck any configuration to retain the <b>Current Value</b>.',
+ 'popup.dependent.configs.title.recommendation': 'Based on your configuration changes, Ambari is recommending the following dependent configuration changes.',
+ 'popup.dependent.configs.title.values': 'Ambari will update all checked configuration changes to the <b>Recommended Value</b>. Uncheck any configuration to retain the <b>Current Value</b>.',
+ 'popup.dependent.configs.title.required': 'The following configuration changes are required and will be applied automatically.',
+ 'popup.dependent.configs.table.recommended': 'Recommended Changes',
+ 'popup.dependent.configs.table.required': 'Required Changes',
'popup.dependent.configs.table.saveProperty': 'Save property',
'popup.dependent.configs.table.initValue': 'Initial value',
'popup.dependent.configs.table.currentValue': 'Current Value',
'popup.dependent.configs.table.recommendedValue': 'Recommended Value',
+ 'popup.dependent.configs.table.newValue': 'New Value',
'popup.dependent.configs.table.not.defined': 'Not Defined',
http://git-wip-us.apache.org/repos/asf/ambari/blob/8423a3e5/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 b014ede..b8845a0 100644
--- a/ambari-web/app/mixins/common/configs/config_recommendation_parser.js
+++ b/ambari-web/app/mixins/common/configs/config_recommendation_parser.js
@@ -173,7 +173,7 @@ App.ConfigRecommendationParser = Em.Mixin.create(App.ConfigRecommendations, {
if (!Em.isNone(recommendedValue) && !Em.get(config, 'hiddenBySection')) {
Em.set(config, 'isVisible', true);
}
- this.applyRecommendation(Em.get(config, 'name'), Em.get(config, 'filename'), Em.get(config, 'group.name'), recommendedValue, this._getInitialValue(config), parentProperties);
+ this.applyRecommendation(Em.get(config, 'name'), Em.get(config, 'filename'), Em.get(config, 'group.name'), recommendedValue, this._getInitialValue(config), parentProperties, Em.get(config, 'isEditable'));
}
if (this.updateInitialOnRecommendations(Em.get(config, 'serviceName'))) {
Em.set(config, 'initialValue', recommendedValue);
@@ -202,7 +202,7 @@ App.ConfigRecommendationParser = Em.Mixin.create(App.ConfigRecommendations, {
addedPropertyObject = App.ServiceConfigProperty.create(newConfig);
this.applyRecommendation(name, fileName, "Default",
- recommendedValue, null, parentProperties);
+ recommendedValue, null, parentProperties, true);
return addedPropertyObject;
},
@@ -245,7 +245,7 @@ App.ConfigRecommendationParser = Em.Mixin.create(App.ConfigRecommendations, {
configsCollection.removeObject(config);
this.applyRecommendation(Em.get(config, 'name'), Em.get(config, 'filename'), Em.get(config, 'group.name'),
- null, this._getInitialValue(config), parentProperties);
+ null, this._getInitialValue(config), parentProperties, Em.get(config, 'isEditable'));
},
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/8423a3e5/ambari-web/app/mixins/common/configs/config_recommendations.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/config_recommendations.js b/ambari-web/app/mixins/common/configs/config_recommendations.js
index 7427a54..bccf3b7 100644
--- a/ambari-web/app/mixins/common/configs/config_recommendations.js
+++ b/ambari-web/app/mixins/common/configs/config_recommendations.js
@@ -54,16 +54,17 @@ App.ConfigRecommendations = Em.Mixin.create({
* @param {string} recommendedValue
* @param {string} initialValue
* @param {Object[]} parentProperties
+ * @param {boolean} isEditable
* @returns {recommendation}
*/
- applyRecommendation: function (name, fileName, configGroupName, recommendedValue, initialValue, parentProperties) {
+ applyRecommendation: function (name, fileName, configGroupName, recommendedValue, initialValue, parentProperties, isEditable) {
try {
var parentPropertyIds = this.formatParentProperties(parentProperties);
var recommendation = this.getRecommendation(name, fileName, configGroupName);
if (recommendation) {
return this.updateRecommendation(recommendation, recommendedValue, parentPropertyIds);
}
- return this.addRecommendation(name, fileName, configGroupName, recommendedValue, initialValue, parentPropertyIds);
+ return this.addRecommendation(name, fileName, configGroupName, recommendedValue, initialValue, parentPropertyIds, isEditable);
} catch(e) {
console.error(e.message);
}
@@ -90,9 +91,10 @@ App.ConfigRecommendations = Em.Mixin.create({
* @param {string} recommendedValue
* @param {string} initialValue
* @param {string[]} parentPropertyIds
+ * @param {boolean} isEditable
* @returns {recommendation}
*/
- addRecommendation: function (name, fileName, configGroupName, recommendedValue, initialValue, parentPropertyIds) {
+ addRecommendation: function (name, fileName, configGroupName, recommendedValue, initialValue, parentPropertyIds, isEditable) {
Em.assert('name and fileName should be defined', name && fileName);
var site = App.config.getConfigTagFromFileName(fileName);
var service = App.config.get('serviceByConfigTypeMap')[site];
@@ -113,7 +115,8 @@ App.ConfigRecommendations = Em.Mixin.create({
allowChangeGroup: false,//TODO groupName!= "Default" && (service.get('serviceName') != this.get('selectedService.serviceName'))
//TODO&& (App.ServiceConfigGroup.find().filterProperty('serviceName', service.get('serviceName')).length > 1), //TODO
serviceDisplayName: service.get('displayName'),
- recommendedValue: recommendedValue
+ recommendedValue: recommendedValue,
+ isEditable: isEditable !== false
};
this.get('recommendations').pushObject(recommendation);
return recommendation;
http://git-wip-us.apache.org/repos/asf/ambari/blob/8423a3e5/ambari-web/app/mixins/common/configs/config_with_override_recommendation_parser.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/config_with_override_recommendation_parser.js b/ambari-web/app/mixins/common/configs/config_with_override_recommendation_parser.js
index bb39451..4312170 100644
--- a/ambari-web/app/mixins/common/configs/config_with_override_recommendation_parser.js
+++ b/ambari-web/app/mixins/common/configs/config_with_override_recommendation_parser.js
@@ -94,7 +94,7 @@ App.ConfigWithOverrideRecommendationParser = Em.Mixin.create(App.ConfigRecommend
var override = App.config.createOverride(config, coreObject, configGroup);
this.applyRecommendation(Em.get(config, 'name'), Em.get(config, 'filename'), configGroup.get('name'),
- recommendedValue, this._getInitialValue(override), parentProperties);
+ recommendedValue, this._getInitialValue(override), parentProperties, Em.get(config, 'isEditable'));
},
/**
@@ -114,4 +114,4 @@ App.ConfigWithOverrideRecommendationParser = Em.Mixin.create(App.ConfigRecommend
}
Em.set(stackProperty.valueAttributes[configGroup.get('name')], attr, value);
}
-});
\ No newline at end of file
+});
http://git-wip-us.apache.org/repos/asf/ambari/blob/8423a3e5/ambari-web/app/mixins/common/configs/enhanced_configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/configs/enhanced_configs.js b/ambari-web/app/mixins/common/configs/enhanced_configs.js
index 882f69d..f7cc4cf 100644
--- a/ambari-web/app/mixins/common/configs/enhanced_configs.js
+++ b/ambari-web/app/mixins/common/configs/enhanced_configs.js
@@ -385,9 +385,11 @@ App.EnhancedConfigsMixin = Em.Mixin.create(App.ConfigWithOverrideRecommendationP
*/
showChangedDependentConfigs: function(event, callback, secondary) {
var self = this;
- var recommendations = event ? this.get('changedProperties') : this.get('recommendations');
+ var recommendations = event ? this.get('changedProperties') : this.get('recommendations'),
+ recommendedChanges = recommendations.filterProperty('isEditable'),
+ requiredChanges = recommendations.filterProperty('isEditable', false);
if (recommendations.length > 0) {
- App.showDependentConfigsPopup(recommendations, function() {
+ App.showDependentConfigsPopup(recommendedChanges, requiredChanges, function() {
self.onSaveRecommendedPopup(recommendations);
if (callback) callback();
}, secondary);
http://git-wip-us.apache.org/repos/asf/ambari/blob/8423a3e5/ambari-web/app/templates/common/modal_popups/dependent_configs_list.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/modal_popups/dependent_configs_list.hbs b/ambari-web/app/templates/common/modal_popups/dependent_configs_list.hbs
index 6a2d93b..3a03c07 100644
--- a/ambari-web/app/templates/common/modal_popups/dependent_configs_list.hbs
+++ b/ambari-web/app/templates/common/modal_popups/dependent_configs_list.hbs
@@ -16,48 +16,11 @@
* limitations under the License.
}}
-<div class="alert alert-warning">
- {{t popup.dependent.configs.title}}
-</div>
<span id="config-dependencies" class="limited-height-2">
- <table class="table table-striped">
- <thead>
- <tr>
- <th class="check-box-col">{{view view.toggleAll}}</th>
- <th>{{t common.property}}</th>
- <th>{{t common.service}}</th>
- <th>{{t common.configGroup}}</th>
- <th>{{t common.fileName}}</th>
- <th class="row-fliud">
- <div class="span6">
- {{t popup.dependent.configs.table.currentValue}}
- </div>
- <div class="span6">
- {{t popup.dependent.configs.table.recommendedValue}}
- </div>
- </th>
- </tr>
- </thead>
- <tbody>
- {{#each recommendation in view.parentView.recommendations}}
- <tr>
- <td class="check-box-col">{{view Em.Checkbox checkedBinding="recommendation.saveRecommended"}}</td>
- <td class="config-dependency-name">{{recommendation.propertyName}}</td>
- <td class="config-dependency-service">{{recommendation.serviceDisplayName}}</td>
- <td class="config-dependency-group">
- <span {{bindAttr class="recommendation.allowChangeGroup::not-active-link"}} ><a href="javascript:void(null);" class="black"
- {{action showSelectGroupPopup recommendation.serviceName target="App.router.mainServiceInfoConfigsController"}}>
- {{recommendation.configGroup}}
- </a></span>
- </td>
- <td class="config-dependency-filename">{{recommendation.propertyFileName}}</td>
- <td>
- <div>
- {{view App.ConfigDiffView configBinding="recommendation"}}
- </div>
- </td>
- </tr>
- {{/each}}
- </tbody>
- </table>
+ {{#if view.recommendations.length}}
+ {{view App.DependentConfigsTableView recommendationsBinding="view.recommendations"}}
+ {{/if}}
+ {{#if view.requiredChanges.length}}
+ {{view App.DependentConfigsTableView recommendationsBinding="view.requiredChanges" isEditable=false}}
+ {{/if}}
</span>
http://git-wip-us.apache.org/repos/asf/ambari/blob/8423a3e5/ambari-web/app/templates/common/modal_popups/dependent_configs_table.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/modal_popups/dependent_configs_table.hbs b/ambari-web/app/templates/common/modal_popups/dependent_configs_table.hbs
new file mode 100644
index 0000000..b6fff84
--- /dev/null
+++ b/ambari-web/app/templates/common/modal_popups/dependent_configs_table.hbs
@@ -0,0 +1,70 @@
+{{!
+* 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.
+}}
+
+<h4>{{view.title}}</h4>
+<div class="alert alert-warning">{{{view.message}}}</div>
+<table class="table table-striped">
+ <thead>
+ <tr>
+ {{#if view.isEditable}}
+ <th class="check-box-col">{{view view.parentView.toggleAll}}</th>
+ {{/if}}
+ <th>{{t common.property}}</th>
+ <th>{{t common.service}}</th>
+ <th>{{t common.configGroup}}</th>
+ <th>{{t common.fileName}}</th>
+ <th>
+ <div class="span6">
+ {{t popup.dependent.configs.table.currentValue}}
+ </div>
+ <div class="span6">
+ {{#if view.isEditable}}
+ {{t popup.dependent.configs.table.recommendedValue}}
+ {{else}}
+ {{t popup.dependent.configs.table.newValue}}
+ {{/if}}
+ </div>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#each recommendation in view.recommendations}}
+ <tr>
+ {{#if view.isEditable}}
+ <td class="check-box-col">{{view Em.Checkbox checkedBinding="recommendation.saveRecommended"}}</td>
+ {{/if}}
+ <td class="config-dependency-name">{{recommendation.propertyName}}</td>
+ <td class="config-dependency-service">{{recommendation.serviceDisplayName}}</td>
+ <td class="config-dependency-group">
+ <span {{bindAttr class="recommendation.allowChangeGroup::not-active-link"}} >
+ <a href="javascript:void(null);" class="black"
+ {{action showSelectGroupPopup recommendation.serviceName target="App.router.mainServiceInfoConfigsController"}}>
+ {{recommendation.configGroup}}
+ </a>
+ </span>
+ </td>
+ <td class="config-dependency-filename">{{recommendation.propertyFileName}}</td>
+ <td>
+ <div>
+ {{view App.ConfigDiffView configBinding="recommendation"}}
+ </div>
+ </td>
+ </tr>
+ {{/each}}
+ </tbody>
+</table>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/8423a3e5/ambari-web/app/views/common/modal_popups/dependent_configs_list_popup.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/modal_popups/dependent_configs_list_popup.js b/ambari-web/app/views/common/modal_popups/dependent_configs_list_popup.js
index bcd8b86..0b6a09d 100644
--- a/ambari-web/app/views/common/modal_popups/dependent_configs_list_popup.js
+++ b/ambari-web/app/views/common/modal_popups/dependent_configs_list_popup.js
@@ -18,50 +18,76 @@
var App = require('app');
+App.DependentConfigsTableView = Em.View.extend({
+ templateName: require('templates/common/modal_popups/dependent_configs_table'),
+ recommendations: [],
+ isEditable: true,
+ title: Em.computed.ifThenElse('isEditable', Em.I18n.t('popup.dependent.configs.table.recommended'), Em.I18n.t('popup.dependent.configs.table.required')),
+ message: function () {
+ var message = '';
+ if (this.get('isEditable')) {
+ if (this.get('parentView.isAfterRecommendation')) {
+ message += Em.I18n.t('popup.dependent.configs.title.recommendation') + '<br>';
+ }
+ message += Em.I18n.t('popup.dependent.configs.title.values');
+ } else {
+ message += Em.I18n.t('popup.dependent.configs.title.required');
+ }
+ return message;
+ }.property('isEditable')
+});
+
+App.DependentConfigsListView = Em.View.extend({
+ templateName: require('templates/common/modal_popups/dependent_configs_list'),
+ isAfterRecommendation: true,
+ recommendations: [],
+ requiredChanges: [],
+ toggleAll: Em.Checkbox.extend({
+ didInsertElement: function () {
+ this.updateCheckbox();
+ },
+ click: function () {
+ Em.run.next(this, 'updateSaveRecommended');
+ },
+ updateCheckboxObserver: function () {
+ Em.run.once(this, 'updateCheckbox');
+ }.observes('parentView.recommendations.@each.saveRecommended'),
+
+ updateCheckbox: function() {
+ this.set('checked', !(this.get('parentView.recommendations') || []).someProperty('saveRecommended', false));
+ },
+ updateSaveRecommended: function() {
+ this.get('parentView.recommendations').setEach('saveRecommended', this.get('checked'));
+ }
+ })
+});
+
/**
* Show confirmation popup
- * @param {[Object]} recommendations
+ * @param {[Object]} recommendedChanges
+ * @param {[Object]} requiredChanges
* @param {function} [primary=null]
* @param {function} [secondary=null]
* we use this parameter to defer saving configs before we make some decisions.
* @return {App.ModalPopup}
*/
-App.showDependentConfigsPopup = function (recommendations, primary, secondary) {
+App.showDependentConfigsPopup = function (recommendedChanges, requiredChanges, primary, secondary) {
return App.ModalPopup.show({
encodeBody: false,
header: Em.I18n.t('popup.dependent.configs.header'),
classNames: ['sixty-percent-width-modal','modal-full-width'],
- recommendations: recommendations,
secondaryClass: 'cancel-button',
- bodyClass: Em.View.extend({
- templateName: require('templates/common/modal_popups/dependent_configs_list'),
-
- toggleAll: Em.Checkbox.extend({
- didInsertElement: function () {
- this.updateCheckbox();
- },
- click: function () {
- Em.run.next(this, 'updateSaveRecommended');
- },
- updateCheckboxObserver: function () {
- Em.run.once(this, 'updateCheckbox');
- }.observes('parentView.parentView.recommendations.@each.saveRecommended'),
-
- updateCheckbox: function() {
- this.set('checked', !(this.get('parentView.parentView.recommendations') || []).someProperty('saveRecommended', false));
- },
- updateSaveRecommended: function() {
- this.get('parentView.parentView.recommendations').setEach('saveRecommended', this.get('checked'));
- }
- })
+ bodyClass: App.DependentConfigsListView.extend({
+ recommendations: recommendedChanges,
+ requiredChanges: requiredChanges
}),
saveChanges: function() {
- this.get('recommendations').forEach(function (c) {
+ recommendedChanges.forEach(function (c) {
Em.set(c, 'saveRecommendedDefault', Em.get(c, 'saveRecommended'));
})
},
discardChanges: function() {
- this.get('recommendations').forEach(function(c) {
+ recommendedChanges.forEach(function(c) {
Em.set(c, 'saveRecommended', Em.get(c, 'saveRecommendedDefault'));
});
},
http://git-wip-us.apache.org/repos/asf/ambari/blob/8423a3e5/ambari-web/test/mixins/common/configs/config_recommendations_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mixins/common/configs/config_recommendations_test.js b/ambari-web/test/mixins/common/configs/config_recommendations_test.js
index baa8ed6..a72f6d3 100644
--- a/ambari-web/test/mixins/common/configs/config_recommendations_test.js
+++ b/ambari-web/test/mixins/common/configs/config_recommendations_test.js
@@ -19,29 +19,29 @@
var App = require('app');
describe('App.ConfigRecommendations', function() {
- var mixinObject = Em.Controller.extend(App.ConfigRecommendations, {});
- var instanceObject = mixinObject.create({});
+ var mixinObject = Em.Controller.extend(App.ConfigRecommendations, {});
+ var instanceObject = mixinObject.create({});
- beforeEach(function() {
- instanceObject.set('recommendations', []);
- });
+ beforeEach(function() {
+ instanceObject.set('recommendations', []);
+ });
- describe('#applyRecommendation', function() {
+ describe('#applyRecommendation', function() {
beforeEach(function() {
sinon.stub(instanceObject, 'formatParentProperties', function(parentProperties) { return parentProperties} );
sinon.stub(App.config, 'get').withArgs('serviceByConfigTypeMap').returns({
'pFile': Em.Object.create({serviceName: 'sName', displayName: 'sDisplayName'})
});
- sinon.stub(Handlebars, 'SafeString');
+ sinon.stub(Handlebars, 'SafeString');
});
afterEach(function() {
instanceObject.formatParentProperties.restore();
App.config.get.restore();
- Handlebars.SafeString.restore();
+ Handlebars.SafeString.restore();
});
it('adds new recommendation', function() {
- var res = instanceObject.applyRecommendation('pName', 'pFile', 'pGroup', 'pRecommended', 'pInitial', ['p_id']);
+ var res = instanceObject.applyRecommendation('pName', 'pFile', 'pGroup', 'pRecommended', 'pInitial', ['p_id'], true);
expect(res).to.eql({
saveRecommended: true,
saveRecommendedDefault: true,
@@ -56,26 +56,27 @@ describe('App.ConfigRecommendations', function() {
allowChangeGroup: false,
serviceDisplayName: 'sDisplayName',
recommendedValue: 'pRecommended',
+ isEditable: true
});
expect(instanceObject.getRecommendation('pName', 'pFile', 'pGroup')).to.eql(res);
});
it('updates recommendation', function() {
- instanceObject.set('recommendations', [{
- saveRecommended: true,
- saveRecommendedDefault: true,
- propertyFileName: 'pFile',
- propertyName: 'pName',
- isDeleted: false,
- notDefined: false,
- configGroup: 'pGroup',
- initialValue: 'pInitial',
- parentConfigs: ['p_id'],
- serviceName: 'sName',
- allowChangeGroup: false,
- serviceDisplayName: 'sDisplayName',
- recommendedValue: 'pRecommended'
- }]);
+ instanceObject.set('recommendations', [{
+ saveRecommended: true,
+ saveRecommendedDefault: true,
+ propertyFileName: 'pFile',
+ propertyName: 'pName',
+ isDeleted: false,
+ notDefined: false,
+ configGroup: 'pGroup',
+ initialValue: 'pInitial',
+ parentConfigs: ['p_id'],
+ serviceName: 'sName',
+ allowChangeGroup: false,
+ serviceDisplayName: 'sDisplayName',
+ recommendedValue: 'pRecommended'
+ }]);
expect(instanceObject.applyRecommendation('pName', 'pFile', 'pGroup', 'pRecommended1', 'pInitial', ['p_id1'])).to.eql({
saveRecommended: true,
saveRecommendedDefault: true,
@@ -92,7 +93,7 @@ describe('App.ConfigRecommendations', function() {
recommendedValue: 'pRecommended1'
});
});
- });
+ });
describe('#formatParentProperties', function() {
beforeEach(function() {
@@ -111,152 +112,175 @@ describe('App.ConfigRecommendations', function() {
});
});
- describe('#addRecommendation', function() {
- var cases = [
- {
- title: 'add recommendation with full info',
- name: 'pName', file: 'pFile.xml', group: 'pGroup', recommended: 'pRecommended', initial: 'pInitial', parent: ['p_id'],
- service: Em.Object.create({serviceName: 'sName', displayName: 'sDisplayName'}),
- result: {
- saveRecommended: true,
- saveRecommendedDefault: true,
- propertyFileName: 'pFile',
- propertyName: 'pName',
- isDeleted: false,
- notDefined: false,
- configGroup: 'pGroup',
- initialValue: 'pInitial',
- parentConfigs: ['p_id'],
- serviceName: 'sName',
- allowChangeGroup: false,
- serviceDisplayName: 'sDisplayName',
- recommendedValue: 'pRecommended'
- }
- },
- {
- title: 'add recommendation with min info',
- name: 'pName', file: 'pFile.xml',
- service: Em.Object.create({serviceName: 'sName', displayName: 'sDisplayName'}),
- result: {
- saveRecommended: true,
- saveRecommendedDefault: true,
- propertyFileName: 'pFile',
- propertyName: 'pName',
- isDeleted: true,
- notDefined: true,
- configGroup: 'Default',
- initialValue: undefined,
- parentConfigs: [],
- serviceName: 'sName',
- allowChangeGroup: false,
- serviceDisplayName: 'sDisplayName',
- recommendedValue: undefined
- }
- }
- ];
- cases.forEach(function(c) {
- describe('successful add recommendation', function() {
- var recommendation;
- beforeEach(function() {
- instanceObject.set('recommendations', []);
- sinon.stub(App.config, 'get').withArgs('serviceByConfigTypeMap').returns({
- 'pFile': c.service
- });
- sinon.stub(Handlebars, 'SafeString');
- recommendation = instanceObject.addRecommendation(c.name, c.file, c.group, c.recommended, c.initial, c.parent);
- });
-
- afterEach(function() {
- App.config.get.restore();
- Handlebars.SafeString.restore();
- });
-
- it(c.title, function() {
- expect(recommendation).to.eql(c.result);
- });
-
- it(c.title + ' check recommendations collection', function() {
- expect(instanceObject.get('recommendations.0')).to.eql(c.result);
- });
- })
- });
-
- it('throw exception when name, fileName', function() {
- expect(instanceObject.addRecommendation.bind()).to.throw(Error, 'name and fileName should be defined');
- expect(instanceObject.addRecommendation.bind(null, 'fname')).to.throw(Error, 'name and fileName should be defined');
- expect(instanceObject.addRecommendation.bind('name', null)).to.throw(Error, 'name and fileName should be defined');
- });
- });
-
- describe('#removeRecommendationObject', function () {
- var recommendations = [
- {
- propertyName: 'p1',
- propertyFileName: 'f1'
- },
- {
- propertyName: 'p2',
- propertyFileName: 'f2'
- }
- ];
-
- beforeEach(function () {
- instanceObject.set('recommendations', recommendations);
- });
-
- it('remove recommendation', function () {
- instanceObject.removeRecommendationObject(recommendations[1]);
-
- expect(instanceObject.get('recommendations.length')).to.equal(1);
- expect(instanceObject.get('recommendations.0')).to.eql({
- propertyName: 'p1',
- propertyFileName: 'f1'
- });
- });
-
- it('remove recommendation that is not exist (don\'t do anything)', function () {
- instanceObject.removeRecommendationObject({propertyName: 'any', 'propertyFileName': 'aby'});
- expect(instanceObject.get('recommendations')).to.eql(recommendations);
- });
-
- it('throw error if recommendation is undefined ', function () {
- expect(instanceObject.removeRecommendationObject.bind()).to.throw(Error, 'recommendation should be defined object');
- expect(instanceObject.removeRecommendationObject.bind(null)).to.throw(Error, 'recommendation should be defined object');
- });
-
- it('throw error if recommendation is not an object ', function () {
- expect(instanceObject.removeRecommendationObject.bind('recommendation')).to.throw(Error, 'recommendation should be defined object');
- expect(instanceObject.removeRecommendationObject.bind(['recommendation'])).to.throw(Error, 'recommendation should be defined object');
- });
- });
-
- describe('#updateRecommendation', function () {
- it('update recommended value and parent properties', function () {
- expect(instanceObject.updateRecommendation({'recommendedValue': 'v2', parentConfigs: ['id1']}, 'v1', ['id2']))
- .to.eql({'recommendedValue': 'v1', parentConfigs: ['id2', 'id1']});
- });
-
- it('update recommended value and add parent properties', function () {
- expect(instanceObject.updateRecommendation({}, 'v1', ['id1'])).to.eql({'recommendedValue': 'v1', parentConfigs: ['id1']});
- });
-
- it('update recommended value', function () {
- expect(instanceObject.updateRecommendation({}, 'v1')).to.eql({'recommendedValue': 'v1'});
- expect(instanceObject.updateRecommendation({'recommendedValue': 'v1'}, 'v2')).to.eql({'recommendedValue': 'v2'});
- });
-
- it('throw error if recommendation is undefined ', function () {
- expect(instanceObject.updateRecommendation.bind()).to.throw(Error, 'recommendation should be defined object');
- expect(instanceObject.updateRecommendation.bind(null)).to.throw(Error, 'recommendation should be defined object');
- });
-
- it('throw error if recommendation is not an object ', function () {
- expect(instanceObject.updateRecommendation.bind('recommendation')).to.throw(Error, 'recommendation should be defined object');
- expect(instanceObject.updateRecommendation.bind(['recommendation'])).to.throw(Error, 'recommendation should be defined object');
- });
- });
-
- describe('#saveRecommendation', function() {
+ describe('#addRecommendation', function() {
+ var cases = [
+ {
+ title: 'add recommendation for editable property with full info',
+ name: 'pName', file: 'pFile.xml', group: 'pGroup', recommended: 'pRecommended', initial: 'pInitial', parent: ['p_id'], isEditable: true,
+ service: Em.Object.create({serviceName: 'sName', displayName: 'sDisplayName'}),
+ result: {
+ saveRecommended: true,
+ saveRecommendedDefault: true,
+ propertyFileName: 'pFile',
+ propertyName: 'pName',
+ isDeleted: false,
+ notDefined: false,
+ configGroup: 'pGroup',
+ initialValue: 'pInitial',
+ parentConfigs: ['p_id'],
+ serviceName: 'sName',
+ allowChangeGroup: false,
+ serviceDisplayName: 'sDisplayName',
+ recommendedValue: 'pRecommended',
+ isEditable: true
+ }
+ },
+ {
+ title: 'add recommendation for read-only property with full info',
+ name: 'pName', file: 'pFile.xml', group: 'pGroup', recommended: 'pRecommended', initial: 'pInitial', parent: ['p_id'], isEditable: false,
+ service: Em.Object.create({serviceName: 'sName', displayName: 'sDisplayName'}),
+ result: {
+ saveRecommended: true,
+ saveRecommendedDefault: true,
+ propertyFileName: 'pFile',
+ propertyName: 'pName',
+ isDeleted: false,
+ notDefined: false,
+ configGroup: 'pGroup',
+ initialValue: 'pInitial',
+ parentConfigs: ['p_id'],
+ serviceName: 'sName',
+ allowChangeGroup: false,
+ serviceDisplayName: 'sDisplayName',
+ recommendedValue: 'pRecommended',
+ isEditable: false
+ }
+ },
+ {
+ title: 'add recommendation with min info',
+ name: 'pName', file: 'pFile.xml',
+ service: Em.Object.create({serviceName: 'sName', displayName: 'sDisplayName'}),
+ result: {
+ saveRecommended: true,
+ saveRecommendedDefault: true,
+ propertyFileName: 'pFile',
+ propertyName: 'pName',
+ isDeleted: true,
+ notDefined: true,
+ configGroup: 'Default',
+ initialValue: undefined,
+ parentConfigs: [],
+ serviceName: 'sName',
+ allowChangeGroup: false,
+ serviceDisplayName: 'sDisplayName',
+ recommendedValue: undefined,
+ isEditable: true
+ }
+ }
+ ];
+ cases.forEach(function(c) {
+ describe('successful add recommendation', function() {
+ var recommendation;
+ beforeEach(function() {
+ instanceObject.set('recommendations', []);
+ sinon.stub(App.config, 'get').withArgs('serviceByConfigTypeMap').returns({
+ 'pFile': c.service
+ });
+ sinon.stub(Handlebars, 'SafeString');
+ recommendation = instanceObject.addRecommendation(c.name, c.file, c.group, c.recommended, c.initial, c.parent, c.isEditable);
+ });
+
+ afterEach(function() {
+ App.config.get.restore();
+ Handlebars.SafeString.restore();
+ });
+
+ it(c.title, function() {
+ expect(recommendation).to.eql(c.result);
+ });
+
+ it(c.title + ' check recommendations collection', function() {
+ expect(instanceObject.get('recommendations.0')).to.eql(c.result);
+ });
+ })
+ });
+
+ it('throw exception when name, fileName', function() {
+ expect(instanceObject.addRecommendation.bind()).to.throw(Error, 'name and fileName should be defined');
+ expect(instanceObject.addRecommendation.bind(null, 'fname')).to.throw(Error, 'name and fileName should be defined');
+ expect(instanceObject.addRecommendation.bind('name', null)).to.throw(Error, 'name and fileName should be defined');
+ });
+ });
+
+ describe('#removeRecommendationObject', function () {
+ var recommendations = [
+ {
+ propertyName: 'p1',
+ propertyFileName: 'f1'
+ },
+ {
+ propertyName: 'p2',
+ propertyFileName: 'f2'
+ }
+ ];
+
+ beforeEach(function () {
+ instanceObject.set('recommendations', recommendations);
+ });
+
+ it('remove recommendation', function () {
+ instanceObject.removeRecommendationObject(recommendations[1]);
+
+ expect(instanceObject.get('recommendations.length')).to.equal(1);
+ expect(instanceObject.get('recommendations.0')).to.eql({
+ propertyName: 'p1',
+ propertyFileName: 'f1'
+ });
+ });
+
+ it('remove recommendation that is not exist (don\'t do anything)', function () {
+ instanceObject.removeRecommendationObject({propertyName: 'any', 'propertyFileName': 'aby'});
+ expect(instanceObject.get('recommendations')).to.eql(recommendations);
+ });
+
+ it('throw error if recommendation is undefined ', function () {
+ expect(instanceObject.removeRecommendationObject.bind()).to.throw(Error, 'recommendation should be defined object');
+ expect(instanceObject.removeRecommendationObject.bind(null)).to.throw(Error, 'recommendation should be defined object');
+ });
+
+ it('throw error if recommendation is not an object ', function () {
+ expect(instanceObject.removeRecommendationObject.bind('recommendation')).to.throw(Error, 'recommendation should be defined object');
+ expect(instanceObject.removeRecommendationObject.bind(['recommendation'])).to.throw(Error, 'recommendation should be defined object');
+ });
+ });
+
+ describe('#updateRecommendation', function () {
+ it('update recommended value and parent properties', function () {
+ expect(instanceObject.updateRecommendation({'recommendedValue': 'v2', parentConfigs: ['id1']}, 'v1', ['id2']))
+ .to.eql({'recommendedValue': 'v1', parentConfigs: ['id2', 'id1']});
+ });
+
+ it('update recommended value and add parent properties', function () {
+ expect(instanceObject.updateRecommendation({}, 'v1', ['id1'])).to.eql({'recommendedValue': 'v1', parentConfigs: ['id1']});
+ });
+
+ it('update recommended value', function () {
+ expect(instanceObject.updateRecommendation({}, 'v1')).to.eql({'recommendedValue': 'v1'});
+ expect(instanceObject.updateRecommendation({'recommendedValue': 'v1'}, 'v2')).to.eql({'recommendedValue': 'v2'});
+ });
+
+ it('throw error if recommendation is undefined ', function () {
+ expect(instanceObject.updateRecommendation.bind()).to.throw(Error, 'recommendation should be defined object');
+ expect(instanceObject.updateRecommendation.bind(null)).to.throw(Error, 'recommendation should be defined object');
+ });
+
+ it('throw error if recommendation is not an object ', function () {
+ expect(instanceObject.updateRecommendation.bind('recommendation')).to.throw(Error, 'recommendation should be defined object');
+ expect(instanceObject.updateRecommendation.bind(['recommendation'])).to.throw(Error, 'recommendation should be defined object');
+ });
+ });
+
+ describe('#saveRecommendation', function() {
it('skip update since values are same', function() {
expect(instanceObject.saveRecommendation({saveRecommended: false, saveRecommendedDefault: false}, false)).to.be.false;
@@ -282,122 +306,122 @@ describe('App.ConfigRecommendations', function() {
expect(instanceObject.updateRecommendation.bind('recommendation')).to.throw(Error, 'recommendation should be defined object');
expect(instanceObject.updateRecommendation.bind(['recommendation'])).to.throw(Error, 'recommendation should be defined object');
});
- });
-
- describe('#getRecommendation', function () {
- var recommendations = [
- {
- propertyName: 'p1',
- propertyFileName: 'f1',
- configGroup: 'Default'
- },
- {
- propertyName: 'p2',
- propertyFileName: 'f2',
- configGroup: 'group1'
- },
- {
- propertyName: 'p1',
- propertyFileName: 'f1',
- configGroup: 'group1'
- }
- ];
-
- beforeEach(function () {
- instanceObject.set('recommendations', recommendations);
- });
-
- it('get recommendation for default group', function () {
- expect(instanceObject.getRecommendation('p1', 'f1')).to.eql(recommendations[0]);
- });
-
- it('get recommendation for default group (2)', function () {
- expect(instanceObject.getRecommendation('p1', 'f1', 'group1')).to.eql(recommendations[2]);
- });
-
- it('get recommendation for wrong group', function () {
- expect(instanceObject.getRecommendation('p2', 'f2', 'group2')).to.equal(null);
- });
-
- it('get undefined recommendation', function () {
- expect(instanceObject.getRecommendation('some', 'amy')).to.equal(null);
- });
-
- it('get throw error if undefined name or fileName passed', function () {
- expect(instanceObject.getRecommendation.bind()).to.throw(Error, 'name and fileName should be defined');
- expect(instanceObject.getRecommendation.bind('name')).to.throw(Error, 'name and fileName should be defined');
- expect(instanceObject.getRecommendation.bind(null, 'fileName')).to.throw(Error, 'name and fileName should be defined');
- });
- });
-
- describe('#cleanUpRecommendations', function() {
- var cases = [
- {
- title: 'remove recommendations with same init and recommended values',
- recommendations: [{
- initialValue: 'v1', recommendedValue: 'v1'
- }, {
- initialValue: 'v1', recommendedValue: 'v2'
- }],
- cleanUpRecommendations: [{
- initialValue: 'v1', recommendedValue: 'v2'
- }]
- },
- {
- title: 'remove recommendations with null init and recommended values',
- recommendations: [{
- initialValue: null, recommendedValue: null
- }, {
- recommendedValue: null
- }, {
- initialValue: null
- },{
- initialValue: null, recommendedValue: 'v1'
- }, {
- initialValue: 'v1', recommendedValue: null
- }],
- cleanUpRecommendations: [{
- initialValue: null, recommendedValue: 'v1'
- }, {
- initialValue: 'v1', recommendedValue: null
- }
- ]
- }
- ];
-
- cases.forEach(function(c) {
- describe(c.title, function() {
- beforeEach(function() {
- instanceObject.set('recommendations', c.recommendations);
- instanceObject.cleanUpRecommendations()
- });
- it('do clean up', function() {
- expect(instanceObject.get('recommendations')).to.eql(c.cleanUpRecommendations);
- });
- });
- });
- });
-
- describe('#clearRecommendationsByServiceName', function () {
- beforeEach(function () {
- instanceObject.set('recommendations', [{serviceName: 's1'}, {serviceName: 's2'}, {serviceName: 's3'}]);
- });
-
- it('remove with specific service names ', function () {
- instanceObject.clearRecommendationsByServiceName(['s2','s3']);
- expect(instanceObject.get('recommendations')).to.eql([{serviceName: 's1'}]);
- });
- });
-
- describe('#clearAllRecommendations', function () {
- beforeEach(function () {
- instanceObject.set('recommendations', [{anyObject: 'o1'}, {anyObject: 'o2'}]);
- });
-
- it('remove all recommendations', function () {
- instanceObject.clearAllRecommendations();
- expect(instanceObject.get('recommendations.length')).to.equal(0);
- });
- });
+ });
+
+ describe('#getRecommendation', function () {
+ var recommendations = [
+ {
+ propertyName: 'p1',
+ propertyFileName: 'f1',
+ configGroup: 'Default'
+ },
+ {
+ propertyName: 'p2',
+ propertyFileName: 'f2',
+ configGroup: 'group1'
+ },
+ {
+ propertyName: 'p1',
+ propertyFileName: 'f1',
+ configGroup: 'group1'
+ }
+ ];
+
+ beforeEach(function () {
+ instanceObject.set('recommendations', recommendations);
+ });
+
+ it('get recommendation for default group', function () {
+ expect(instanceObject.getRecommendation('p1', 'f1')).to.eql(recommendations[0]);
+ });
+
+ it('get recommendation for default group (2)', function () {
+ expect(instanceObject.getRecommendation('p1', 'f1', 'group1')).to.eql(recommendations[2]);
+ });
+
+ it('get recommendation for wrong group', function () {
+ expect(instanceObject.getRecommendation('p2', 'f2', 'group2')).to.equal(null);
+ });
+
+ it('get undefined recommendation', function () {
+ expect(instanceObject.getRecommendation('some', 'amy')).to.equal(null);
+ });
+
+ it('get throw error if undefined name or fileName passed', function () {
+ expect(instanceObject.getRecommendation.bind()).to.throw(Error, 'name and fileName should be defined');
+ expect(instanceObject.getRecommendation.bind('name')).to.throw(Error, 'name and fileName should be defined');
+ expect(instanceObject.getRecommendation.bind(null, 'fileName')).to.throw(Error, 'name and fileName should be defined');
+ });
+ });
+
+ describe('#cleanUpRecommendations', function() {
+ var cases = [
+ {
+ title: 'remove recommendations with same init and recommended values',
+ recommendations: [{
+ initialValue: 'v1', recommendedValue: 'v1'
+ }, {
+ initialValue: 'v1', recommendedValue: 'v2'
+ }],
+ cleanUpRecommendations: [{
+ initialValue: 'v1', recommendedValue: 'v2'
+ }]
+ },
+ {
+ title: 'remove recommendations with null init and recommended values',
+ recommendations: [{
+ initialValue: null, recommendedValue: null
+ }, {
+ recommendedValue: null
+ }, {
+ initialValue: null
+ },{
+ initialValue: null, recommendedValue: 'v1'
+ }, {
+ initialValue: 'v1', recommendedValue: null
+ }],
+ cleanUpRecommendations: [{
+ initialValue: null, recommendedValue: 'v1'
+ }, {
+ initialValue: 'v1', recommendedValue: null
+ }
+ ]
+ }
+ ];
+
+ cases.forEach(function(c) {
+ describe(c.title, function() {
+ beforeEach(function() {
+ instanceObject.set('recommendations', c.recommendations);
+ instanceObject.cleanUpRecommendations()
+ });
+ it('do clean up', function() {
+ expect(instanceObject.get('recommendations')).to.eql(c.cleanUpRecommendations);
+ });
+ });
+ });
+ });
+
+ describe('#clearRecommendationsByServiceName', function () {
+ beforeEach(function () {
+ instanceObject.set('recommendations', [{serviceName: 's1'}, {serviceName: 's2'}, {serviceName: 's3'}]);
+ });
+
+ it('remove with specific service names ', function () {
+ instanceObject.clearRecommendationsByServiceName(['s2','s3']);
+ expect(instanceObject.get('recommendations')).to.eql([{serviceName: 's1'}]);
+ });
+ });
+
+ describe('#clearAllRecommendations', function () {
+ beforeEach(function () {
+ instanceObject.set('recommendations', [{anyObject: 'o1'}, {anyObject: 'o2'}]);
+ });
+
+ it('remove all recommendations', function () {
+ instanceObject.clearAllRecommendations();
+ expect(instanceObject.get('recommendations.length')).to.equal(0);
+ });
+ });
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/8423a3e5/ambari-web/test/views/common/modal_popups/dependent_configs_list_popup_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/common/modal_popups/dependent_configs_list_popup_test.js b/ambari-web/test/views/common/modal_popups/dependent_configs_list_popup_test.js
index 9dc4bf6..44c38b3 100644
--- a/ambari-web/test/views/common/modal_popups/dependent_configs_list_popup_test.js
+++ b/ambari-web/test/views/common/modal_popups/dependent_configs_list_popup_test.js
@@ -40,7 +40,7 @@ describe('App.showDependentConfigsPopup', function () {
beforeEach(function () {
this.ff = function () {};
sinon.spy(this, 'ff');
- view = App.showDependentConfigsPopup([], Em.K, this.ff);
+ view = App.showDependentConfigsPopup([], [], Em.K, this.ff);
});
afterEach(function () {
@@ -54,4 +54,4 @@ describe('App.showDependentConfigsPopup', function () {
});
-});
\ No newline at end of file
+});