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 2016/06/30 07:25:39 UTC
ambari git commit: AMBARI-17474 Configs validation: UI does not show
warning if a slider value is more than maximum. (ababiichuk)
Repository: ambari
Updated Branches:
refs/heads/trunk c86672cb7 -> b618d22bd
AMBARI-17474 Configs validation: UI does not show warning if a slider value is more than maximum. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b618d22b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b618d22b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b618d22b
Branch: refs/heads/trunk
Commit: b618d22bd27ee24cad8855c5e8b6160307aa8ad9
Parents: c86672c
Author: ababiichuk <ab...@hortonworks.com>
Authored: Wed Jun 29 18:24:56 2016 +0300
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Thu Jun 30 10:20:02 2016 +0300
----------------------------------------------------------------------
ambari-web/app/mixins/common/serverValidator.js | 302 +++++++++----------
.../config_recommendation_popup.hbs | 78 ++---
ambari-web/app/views.js | 2 +
.../config_validation_failed_popup.js | 46 +++
.../config_validation_popup.js | 54 ++++
.../test/mixins/common/serverValidator_test.js | 254 +++++++++-------
6 files changed, 412 insertions(+), 324 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/b618d22b/ambari-web/app/mixins/common/serverValidator.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/serverValidator.js b/ambari-web/app/mixins/common/serverValidator.js
index e8774b0..428b0cd 100644
--- a/ambari-web/app/mixins/common/serverValidator.js
+++ b/ambari-web/app/mixins/common/serverValidator.js
@@ -31,26 +31,6 @@ App.ServerValidatorMixin = Em.Mixin.create({
}.property('wizardController.name'),
/**
- * @type {boolean} set true if at least one config has error
- */
- configValidationError: false,
-
- /**
- * @type {boolean} set true if at least one config has warning
- */
- configValidationWarning: false,
-
- /**
- * @type {boolean} set true if at least one config has warning
- */
- configValidationFailed: false,
-
- /**
- * @type {object[]} contains additional message about validation errors
- */
- configValidationGlobalMessage: [],
-
- /**
* recommendation configs loaded from server
* (used only during install)
* @type {Object}
@@ -65,6 +45,24 @@ App.ServerValidatorMixin = Em.Mixin.create({
clusterEnvConfigs: [],
/**
+ * Collection of all config validation errors
+ *
+ * @type {Object[]}
+ */
+ configErrorList: [],
+
+ /**
+ * Map with allowed error types
+ *
+ * @type {Object}
+ */
+ errorTypes: {
+ ERROR: 'ERROR',
+ WARN: 'WARN',
+ GENERAL: 'GENERAL'
+ },
+
+ /**
* by default loads data from model otherwise must be overridden as computed property
* refer to \assets\data\stacks\HDP-2.1\recommendations_configs.json to learn structure
* (shouldn't contain configurations filed)
@@ -103,25 +101,23 @@ App.ServerValidatorMixin = Em.Mixin.create({
stepConfigs: null,
serverSideValidation: function () {
- var deferred = $.Deferred();
- this.set('configValidationFailed', false);
- this.set('configValidationGlobalMessage', []);
- if (this.get('configValidationFailed')) {
- this.warnUser(deferred);
- } else {
- this.runServerSideValidation(deferred);
- }
- return deferred;
- },
+ var deferred = $.Deferred(),
+ self = this,
+ primary = function() { deferred.resolve(); },
+ secondary = function() { deferred.reject('invalid_configs'); };
+ this.set('configErrorList', []);
- getAllHostsWithComponents: function() {
- return App.ajax.send({
- sender: this,
- name: 'common.hosts.all',
- data: {
- urlParams: 'fields=HostRoles/component_name,HostRoles/host_name'
+ this.runServerSideValidation().done(function() {
+ if (self.get('configErrorList.length')) {
+ App.showConfigValidationPopup(self.get('configErrorList'), primary, secondary);
+ } else {
+ deferred.resolve();
}
+ }).fail(function() {
+ App.showConfigValidationFailedPopup(primary, secondary);
});
+
+ return deferred.promise();
},
/**
@@ -129,14 +125,15 @@ App.ServerValidatorMixin = Em.Mixin.create({
* send request to validate configs
* @returns {*}
*/
- runServerSideValidation: function (deferred) {
+ runServerSideValidation: function () {
var self = this;
var recommendations = this.get('hostGroups');
var stepConfigs = this.get('stepConfigs');
+ var dfd = $.Deferred();
- return this.getBlueprintConfigurations().done(function(blueprintConfigurations){
+ this.getBlueprintConfigurations().done(function(blueprintConfigurations) {
recommendations.blueprint.configurations = blueprintConfigurations;
- return App.ajax.send({
+ App.ajax.send({
name: 'config.validations',
sender: self,
data: {
@@ -148,10 +145,11 @@ App.ServerValidatorMixin = Em.Mixin.create({
},
success: 'validationSuccess',
error: 'validationError'
- }).complete(function () {
- self.warnUser(deferred);
+ }).complete(function() {
+ dfd.resolve();
});
});
+ return dfd.promise();
},
/**
@@ -206,144 +204,116 @@ App.ServerValidatorMixin = Em.Mixin.create({
},
/**
- * @method validationSuccess
- * success callback after getting response from server
- * go through the step configs and set warn and error messages
+ * Creates config validation error object
+ *
+ * @param type - error type, see <code>errorTypes<code>
+ * @param property - config property object
+ * @param messages - array of messages
+ * @returns {{type: String, isError: boolean, isWarn: boolean, isGeneral: boolean, messages: Array}}
+ */
+ createErrorMessage: function (type, property, messages) {
+ var errorTypes = this.get('errorTypes');
+ var error = {
+ type: type,
+ isError: type === errorTypes.ERROR,
+ isWarn: type === errorTypes.WARN,
+ isGeneral: type === errorTypes.GENERAL,
+ messages: Em.makeArray(messages)
+ };
+
+ Em.assert('Unknown config error type ' + type, error.isError || error.isWarn || error.isGeneral);
+ if (property) {
+ error.serviceName = App.StackService.find(Em.get(property, 'serviceName')).get('displayName');
+ error.propertyName = Em.get(property, 'name');
+ error.filename = Em.get(property, 'filename');
+ error.value = Em.get(property, 'value');
+ error.description = Em.get(property, 'description');
+ }
+ return error;
+ },
+
+
+ /**
+ * Parse data from server to
+ * <code>configErrorsMap<code> and
+ * <code>generalErrors<code>
+ *
* @param data
+ * @returns {{configErrorsMap: {}, generalErrors: Array}}
*/
- validationSuccess: function(data) {
- var self = this;
- var checkedProperties = [];
- var globalWarning = [];
- self.set('configValidationError', false);
- self.set('configValidationWarning', false);
+ parseValidation: function(data) {
+ var configErrorsMap = {}, generalErrors = [];
+
data.resources.forEach(function(r) {
r.items.forEach(function(item){
if (item.type == "configuration") {
- self.get('stepConfigs').forEach(function(service) {
- service.get('configs').forEach(function(property) {
- if ((property.get('filename') == item['config-type'] + '.xml') && (property.get('name') == item['config-name'])) {
- if (item.level == "ERROR") {
- self.set('configValidationError', true);
- property.set('validationErrors', property.get('validationErrors').concat(item.message).slice());
- } else if (item.level == "WARN") {
- self.set('configValidationWarning', true);
- property.set('validationWarnings', property.get('validationWarnings').concat(item.message).slice());
- }
- // store property data to detect WARN or ERROR messages for missed property
- if (["ERROR", "WARN"].contains(item.level)) checkedProperties.push(item['config-type'] + '/' + item['config-name']);
- }
- });
- });
- // check if error or warn message detected for property that absent in step configs
- if (["ERROR", "WARN"].contains(item.level) && !checkedProperties.contains(item['config-type'] + '/' + item['config-name'])) {
- var message = {
- propertyName: item['config-name'],
- filename: item['config-type'],
- validationWarnings: [item.message]
- };
- if (item['config-type'] === "" && item['config-name'] === "") {
- //service-independent validation
- message.isGeneral = true;
+ var configId = (item['config-name'] && item['config-type']) && App.config.configId(item['config-name'], item['config-type']);
+ if (configId) {
+ if (configErrorsMap[configId]) {
+ configErrorsMap[configId].messages.push(item.message);
} else {
- message.serviceName = App.StackService.find().filter(function(service) {
- return !!service.get('configTypes')[item['config-type']];
- })[0].get('displayName');
+ configErrorsMap[configId] = {
+ type: item.level,
+ messages: [item.message]
+ }
}
- self.set(item.level == 'WARN' ? 'configValidationWarning' : 'configValidationError', true);
- globalWarning.push(message);
+ } else {
+ generalErrors.push({
+ type: this.get('errorTypes').GENERAL,
+ messages: [item.message]
+ });
}
}
- });
- });
- self.set('configValidationGlobalMessage', globalWarning);
- },
+ }, this);
+ }, this);
- validationError: function (jqXHR, ajaxOptions, error, opt) {
- this.set('configValidationFailed', true);
+ return {
+ configErrorsMap: configErrorsMap,
+ generalErrors: generalErrors
+ }
},
+ /**
+ * Generates list of all config errors that should be displayed in popup
+ *
+ * @param configErrorsMap
+ * @param generalErrors
+ * @returns {Array}
+ */
+ collectAllIssues: function(configErrorsMap, generalErrors) {
+ var errorTypes = this.get('errorTypes');
+ var configErrorList = [];
+
+ this.get('stepConfigs').forEach(function(service) {
+ service.get('configs').forEach(function(property) {
+ if (property.get('isVisible') && !property.get('hiddenBySection')) {
+ var serverIssue = configErrorsMap[property.get('id')];
+ if (serverIssue) {
+ configErrorList.push(this.createErrorMessage(serverIssue.type, property, serverIssue.messages));
+ } else if (property.get('warnMessage')) {
+ configErrorList.push(this.createErrorMessage(errorTypes.WARN, property, [property.get('warnMessage')]));
+ }
+ }
+ }, this);
+ }, this);
+
+ generalErrors.forEach(function(serverIssue) {
+ configErrorList.push(this.createErrorMessage(errorTypes.GENERAL, null, serverIssue.messages));
+ }, this);
+
+ return configErrorList;
+ },
/**
- * warn user if some errors or warning were
- * in setting up configs otherwise go to the nex operation
- * @param deferred
- * @returns {*}
+ * @method validationSuccess
+ * success callback after getting response from server
+ * go through the step configs and set warn and error messages
+ * @param data
*/
- warnUser: function(deferred) {
- var self = this;
- if (this.get('configValidationFailed')) {
- return App.ModalPopup.show({
- header: Em.I18n.t('installer.step7.popup.validation.failed.header'),
- primary: Em.I18n.t('common.proceedAnyway'),
- primaryClass: 'btn-danger',
- marginBottom: 200,
- onPrimary: function () {
- this.hide();
- deferred.resolve();
- },
- onSecondary: function () {
- this.hide();
- deferred.reject("invalid_configs"); // message used to differentiate types of rejections.
- },
- onClose: function () {
- this.hide();
- deferred.reject("invalid_configs"); // message used to differentiate types of rejections.
- },
- body: Em.I18n.t('installer.step7.popup.validation.request.failed.body')
- });
- } else if (this.get('configValidationWarning') || this.get('configValidationError')) {
- // Motivation: for server-side validation warnings allow user to continue wizard
- var stepConfigs = self.get('name') === 'mainServiceInfoConfigsController'
- ? [self.get('selectedService')]
- : self.get('stepConfigs');
- var configsWithErrors = stepConfigs.some(function (step) {
- return step.get('configs').some(function(c) {
- return c.get('isVisible') && !c.get('hiddenBySection') && (c.get('hasValidationWarnings') || c.get('hasValidationErrors'));
- });
- });
- if (configsWithErrors) {
- return App.ModalPopup.show({
- header: Em.I18n.t('installer.step7.popup.validation.warning.header'),
- classNames: ['sixty-percent-width-modal','modal-full-width'],
- primary: Em.I18n.t('common.proceedAnyway'),
- primaryClass: 'btn-danger',
- marginBottom: 200,
- onPrimary: function () {
- this.hide();
- deferred.resolve();
- },
- onSecondary: function () {
- this.hide();
- deferred.reject("invalid_configs"); // message used to differentiate types of rejections.
- },
- onClose: function () {
- this.hide();
- deferred.reject("invalid_configs"); // message used to differentiate types of rejections.
- },
- hide: function() {
- stepConfigs.forEach(function(serviceConfig) {
- serviceConfig.get('configs').invoke('setProperties', {
- validationErrors: [].slice(),
- validationWarnings: [].slice()
- });
- });
- this._super();
- },
- bodyClass: Em.View.extend({
- controller: self,
- templateName: require('templates/common/modal_popups/config_recommendation_popup'),
- serviceConfigs: stepConfigs,
- messageBody: Em.I18n.t(self.get('configValidationError')
- ? 'installer.step7.popup.validation.error.body'
- : 'installer.step7.popup.validation.warning.body')
- })
- });
- } else {
- deferred.resolve();
- }
- } else {
- deferred.resolve();
- }
- }
+ validationSuccess: function(data) {
+ var parsed = this.parseValidation(data);
+ this.set('configErrorList', this.collectAllIssues(parsed.configErrorsMap, parsed.generalErrors));
+ },
+
+ validationError: Em.K
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/b618d22b/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs b/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs
index bb629ff..8100dff 100644
--- a/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs
+++ b/ambari-web/app/templates/common/modal_popups/config_recommendation_popup.hbs
@@ -29,63 +29,33 @@
</tr>
</thead>
<tbody>
- {{#each service in view.serviceConfigs}}
- {{#each property in service.configs}}
- {{#if property.isVisible}}
- {{#unless property.hiddenBySection}}
- {{#if property.hasValidationErrors}}
- {{#each error in property.validationErrors}}
- <tr class="error">
- <td>{{t common.error}}</td>
- <td>{{property.serviceName}}</td>
- <td>{{property.name}}</td>
- <td>{{property.value}}</td>
- <td>
- <div class="property-message">{{error}}</div>
- <div class="property-description">{{property.description}}</div>
- </td>
- </tr>
- {{/each}}
- {{/if}}
- {{/unless}}
+ {{#each error in view.configErrors}}
+ <tr {{bindAttr class="error.isError:error:warning"}}>
+ <td>
+ {{#if error.isError}}
+ {{t common.error}}
+ {{else}}
+ {{t common.warning}}
{{/if}}
- {{/each}}
- {{/each}}
- {{#each service in view.serviceConfigs}}
- {{#each property in service.configs}}
- {{#if property.isVisible}}
- {{#unless property.hiddenBySection}}
- {{#if property.hasValidationWarnings}}
- {{#each warning in property.validationWarnings}}
- <tr class="warning">
- <td>{{t common.warning}}</td>
- <td>{{property.serviceName}}</td>
- <td>{{property.name}}</td>
- <td>{{property.value}}</td>
- <td>
- <div class="property-message">{{warning}}</div>
- <div class="property-description">{{property.description}}</div>
- </td>
- </tr>
- {{/each}}
- {{/if}}
- {{/unless}}
- {{/if}}
- {{/each}}
- {{/each}}
- {{#each message in configValidationGlobalMessage}}
- {{#if message.isGeneral}}
- <tr>
- <td colspan="4">{{message.warnMessage}}</td>
- </tr>
+ </td>
+
+ {{#if error.isGeneral}}
+ {{#each message in error.messages}}
+ <td colspan="4">{{error.message}}</td>
+ {{/each}}
{{else}}
- <tr>
- <td>{{message.serviceName}}</td>
- <td>{{message.propertyName}}</td>
- <td colspan="2">{{message.warnMessage}} {{t in}} {{message.filename}}</td>
- </tr>
+ <td>{{error.serviceName}}</td>
+ <td>{{error.propertyName}}</td>
+ <td>{{error.value}}</td>
+ <td>
+ {{#each message in error.messages}}
+ <div class="property-message">{{message}}</div>
+ {{/each}}
+ <div class="property-description">{{error.description}}</div>
+ </td>
{{/if}}
- {{/each}}
+ </tr>
+ {{/each}}
</tbody>
</table>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/b618d22b/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index 7127420..ab79b98 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -42,6 +42,8 @@ require('views/common/modal_popups/select_groups_popup');
require('views/common/modal_popups/logs_popup');
require('views/common/modal_popups/log_file_search_popup');
require('views/common/modal_popups/log_tail_popup');
+require('views/common/modal_popups/config_validation/config_validation_failed_popup');
+require('views/common/modal_popups/config_validation/config_validation_popup');
require('views/common/editable_list');
require('views/common/host_progress_popup_body_view');
require('views/common/rolling_restart_view');
http://git-wip-us.apache.org/repos/asf/ambari/blob/b618d22b/ambari-web/app/views/common/modal_popups/config_validation/config_validation_failed_popup.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/modal_popups/config_validation/config_validation_failed_popup.js b/ambari-web/app/views/common/modal_popups/config_validation/config_validation_failed_popup.js
new file mode 100644
index 0000000..20639b4
--- /dev/null
+++ b/ambari-web/app/views/common/modal_popups/config_validation/config_validation_failed_popup.js
@@ -0,0 +1,46 @@
+/**
+ * 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');
+
+/**
+ * Show alert popup
+ *
+ * @return {*}
+ */
+App.showConfigValidationFailedPopup = function (primary, secondary) {
+ return App.ModalPopup.show({
+ header: Em.I18n.t('installer.step7.popup.validation.failed.header'),
+ primary: Em.I18n.t('common.proceedAnyway'),
+ primaryClass: 'btn-danger',
+ marginBottom: 200,
+ onPrimary: function () {
+ this._super();
+ primary();
+ },
+ onSecondary: function () {
+ this._super();
+ secondary();
+ },
+ onClose: function () {
+ this._super();
+ secondary();
+ },
+ body: Em.I18n.t('installer.step7.popup.validation.request.failed.body')
+ });
+};
http://git-wip-us.apache.org/repos/asf/ambari/blob/b618d22b/ambari-web/app/views/common/modal_popups/config_validation/config_validation_popup.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/modal_popups/config_validation/config_validation_popup.js b/ambari-web/app/views/common/modal_popups/config_validation/config_validation_popup.js
new file mode 100644
index 0000000..98e1ce5
--- /dev/null
+++ b/ambari-web/app/views/common/modal_popups/config_validation/config_validation_popup.js
@@ -0,0 +1,54 @@
+/**
+ * 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');
+
+/**
+ * Show alert popup
+ *
+ * @return {*}
+ */
+App.showConfigValidationPopup = function (configErrors, primary, secondary) {
+ return App.ModalPopup.show({
+ header: Em.I18n.t('installer.step7.popup.validation.warning.header'),
+ classNames: ['sixty-percent-width-modal','modal-full-width'],
+ primary: Em.I18n.t('common.proceedAnyway'),
+ primaryClass: 'btn-danger',
+ marginBottom: 200,
+ onPrimary: function () {
+ this._super();
+ primary();
+ },
+ onSecondary: function () {
+ this._super();
+ secondary();
+ },
+ onClose: function () {
+ this._super();
+ secondary();
+ },
+ bodyClass: Em.View.extend({
+ templateName: require('templates/common/modal_popups/config_recommendation_popup'),
+ configErrors: configErrors,
+ configValidationError: Em.computed.someBy('configErrors', 'isError', true),
+ messageBody: Em.I18n.t(this.get('configValidationError')
+ ? 'installer.step7.popup.validation.error.body'
+ : 'installer.step7.popup.validation.warning.body')
+ })
+ });
+};
http://git-wip-us.apache.org/repos/asf/ambari/blob/b618d22b/ambari-web/test/mixins/common/serverValidator_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mixins/common/serverValidator_test.js b/ambari-web/test/mixins/common/serverValidator_test.js
index 39e71a0..4a22e28 100644
--- a/ambari-web/test/mixins/common/serverValidator_test.js
+++ b/ambari-web/test/mixins/common/serverValidator_test.js
@@ -18,123 +18,169 @@
var App = require('app');
-describe('App.ServerValidatorMixin', function() {
+describe('App.ServerValidatorMixin', function () {
var mixinObject = Em.Object.extend(App.ServerValidatorMixin, {});
- describe('#validationSuccess', function() {
- var instanceObject;
- var genRespItem = function(name, filename, level, message) {
- return {
- type: 'configuration',
- 'config-name': name,
- 'config-type': filename,
- level: level,
- message: message
- };
- };
- var genResponse = function(items) {
- return {
- items: items.map(function(item) { return genRespItem.apply(undefined, item); })
- };
+ var instanceObject;
+ beforeEach(function () {
+ instanceObject = mixinObject.create();
+ });
+ describe('#collectAllIssues', function () {
+ var result = [];
+ var stepConfigs = [
+ Em.Object.create({
+ serviceName: 'service1',
+ configs: [
+ Em.Object.create({
+ id: 'c1_f1',
+ name: 'c1',
+ filename: 'f1',
+ isVisible: true,
+ hiddenBySection: false
+ }),
+ Em.Object.create({
+ id: 'c2_f2',
+ name: 'c2',
+ filename: 'f2',
+ isVisible: true,
+ hiddenBySection: false
+ }),
+ Em.Object.create({
+ id: 'c3_f3',
+ name: 'c3',
+ filename: 'f3',
+ isVisible: true,
+ hiddenBySection: false,
+ warnMessage: 'warn3'
+ }),
+ Em.Object.create({
+ id: 'c4_f4',
+ name: 'c4',
+ filename: 'f4',
+ isVisible: false,
+ hiddenBySection: false
+ })
+ ]
+ })
+ ];
+
+ var response = {
+ configErrorsMap: {
+ 'c1_f1': {
+ type: 'WARN',
+ messages: ['warn1']
+ },
+ 'c2_f2': {
+ type: 'ERROR',
+ messages: ['error2']
+ },
+ 'c4_f4': {
+ type: 'ERROR',
+ messages: ['error4']
+ }
+ },
+ generalErrors: [{
+ type: 'GENERAL',
+ messages: ['general issue']
+ }]
};
- var genConfigs = function(configs) {
- return Em.Object.create({
- configs: configs.map(function(item) {
- return Em.Object.create({ name: item[0], filename: item[1], validationErrors: [], validationWarnings: []});
- })
- });
+
+ beforeEach(function () {
+ instanceObject.set('stepConfigs', stepConfigs);
+ result = instanceObject.collectAllIssues(response.configErrorsMap, response.generalErrors);
+ });
+
+ it('should add server warnings', function () {
+ var error = result.find(function(r) { return r.propertyName === 'c1' && r.filename === 'f1'; });
+ expect(error.type).to.equal('WARN');
+ expect(error.messages).to.eql(['warn1']);
+ });
+
+ it('should add server errors', function () {
+ var error = result.find(function(r) { return r.propertyName === 'c2' && r.filename === 'f2'; });
+ expect(error.type).to.equal('ERROR');
+ expect(error.messages).to.eql(['error2']);
+ });
+
+ it('should add ui warning', function () {
+ var error = result.find(function(r) { return r.propertyName === 'c3' && r.filename === 'f3'; });
+ expect(error.type).to.equal('WARN');
+ expect(error.messages).to.eql(['warn3']);
+ });
+
+ it('should add general issues', function () {
+ var error = result.findProperty('type', 'GENERAL');
+ expect(error.messages).to.eql(['general issue']);
+ });
+
+ it('should ignore issues for hidden configs', function () {
+ var error = result.find(function(r) { return r.propertyName === 'c4' && r.filename === 'f4'; });
+ expect(error).to.be.undefined;
+ });
+ });
+
+ describe('#createErrorMessage', function() {
+ var property = {
+ name: 'p1',
+ filename: 'f1',
+ value: 'v1',
+ description: 'd1'
};
- var tests = [
- {
- stepConfigs: Em.A([
- genConfigs([
- ['prop1', 'some-site.xml']
- ])
- ]),
- resources: [
- genResponse([
- ['prop1', 'some-site', 'WARN', 'Some warn'],
- ['prop2', 'some-site', 'ERROR', 'Value should be set']
- ])
- ],
- expected: [
- { prop: 'configValidationError', value: true },
- { prop: 'configValidationWarning', value: true },
- { prop: 'configValidationGlobalMessage.length', value: 1 },
- { prop: 'configValidationGlobalMessage[0].serviceName', value: 'Some Service' },
- { prop: 'configValidationGlobalMessage[0].propertyName', value: 'prop2' }
- ],
- message: 'validation failed on absent property from step configs. global message should be showed.'
- },
- {
- stepConfigs: Em.A([
- genConfigs([
- ['prop1', 'some-site.xml'],
- ['prop2', 'some-site.xml']
- ])
- ]),
- resources: [
- genResponse([
- ['prop1', 'some-site', 'WARN', 'Some warn']
- ])
- ],
- expected: [
- { prop: 'configValidationError', value: false },
- { prop: 'configValidationWarning', value: true },
- { prop: 'configValidationGlobalMessage.length', value: 0}
- ],
- message: 'all properties present in step configs. validation failed. Present WARN and ERROR level messages.'
- },
- {
- stepConfigs: Em.A([
- genConfigs([
- ['prop1', 'some-site.xml'],
- ['prop2', 'some-site.xml']
- ])
- ]),
- resources: [
- {
- items: []
- }
- ],
- expected: [
- { prop: 'configValidationFailed', value: false },
- { prop: 'configValidationError', value: false },
- { prop: 'configValidationWarning', value: false },
- { prop: 'configValidationGlobalMessage.length', value: 0}
- ],
- message: 'validation success. no errors flags should be set.'
- }
- ];
-
beforeEach(function() {
- instanceObject = mixinObject.create({});
- sinon.stub(App.StackService, 'find').returns([
- Em.Object.create({
- displayName: 'Some Service',
- configTypes: { 'some-site': {} }
- })
- ]);
+ sinon.stub(App.StackService, 'find', function() {
+ return Em.Object.create({
+ displayName: 'sName'
+ });
+ });
});
afterEach(function() {
App.StackService.find.restore();
});
-
- tests.forEach(function(test) {
- describe(test.message, function() {
- beforeEach(function () {
- instanceObject.set('stepConfigs', test.stepConfigs);
- instanceObject.validationSuccess({resources: test.resources});
- });
+ it('creates warn object', function() {
+ expect(instanceObject.createErrorMessage('WARN', property, ['msg1'])).to.eql({
+ type: 'WARN',
+ isError: false,
+ isWarn: true,
+ isGeneral: false,
+ messages: ['msg1'],
+ propertyName: 'p1',
+ filename: 'f1',
+ value: 'v1',
+ description: 'd1',
+ serviceName: 'sName'
+ });
+ });
- test.expected.forEach(function(e) {
- it(e.prop + ': ' + e.value, function () {
- expect(instanceObject).to.have.deep.property(e.prop, e.value);
- });
- });
+ it('creates error object', function() {
+ expect(instanceObject.createErrorMessage('ERROR', property, ['msg2'])).to.eql({
+ type: 'ERROR',
+ isError: true,
+ isWarn: false,
+ isGeneral: false,
+ messages: ['msg2'],
+ propertyName: 'p1',
+ filename: 'f1',
+ value: 'v1',
+ description: 'd1',
+ serviceName: 'sName'
+ });
+ });
+
+ it('creates general issue object', function() {
+ expect(instanceObject.createErrorMessage('GENERAL', null, ['msg3'])).to.eql({
+ type: 'GENERAL',
+ isError: false,
+ isWarn: false,
+ isGeneral: true,
+ messages: ['msg3']
});
});
+
+ it('creates general issue object', function() {
+ expect(instanceObject.createErrorMessage.bind(instanceObject, 'WRONG TYPE', null, ['msg3']))
+ .to.throw(Error, 'Unknown config error type WRONG TYPE');
+ });
});
});