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 <[email protected]> Authored: Wed Jun 29 18:24:56 2016 +0300 Committer: ababiichuk <[email protected]> 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'); + }); }); });
