Repository: ambari Updated Branches: refs/heads/trunk 275e8986b -> e67c5ea50
AMBARI-9105. Ambari shows empty popup when underlying call fails (alexantonenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e67c5ea5 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e67c5ea5 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e67c5ea5 Branch: refs/heads/trunk Commit: e67c5ea50c0ac1a71855b1f0e3af8dbb39a9c793 Parents: 275e898 Author: Alex Antonenko <[email protected]> Authored: Tue Jan 13 17:26:44 2015 +0200 Committer: Alex Antonenko <[email protected]> Committed: Tue Jan 13 18:45:50 2015 +0200 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 1 + .../app/controllers/wizard/step8_controller.js | 143 ++++++++++--- ambari-web/app/messages.js | 4 +- ambari-web/app/utils/ajax/ajax.js | 14 +- ambari-web/app/views.js | 1 + .../common/ajax_default_error_popup_body.js | 74 +++++++ .../test/controllers/wizard/step8_test.js | 213 ++++++++++++++++++- .../ajax_default_error_popup_body_test.js | 85 ++++++++ 8 files changed, 497 insertions(+), 38 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/e67c5ea5/ambari-web/app/assets/test/tests.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js index 218e71f..203b9c9 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -153,6 +153,7 @@ var files = ['test/init_model_test', 'test/utils/ui_effects_test', 'test/utils/updater_test', 'test/views/common/chart/linear_time_test', + 'test/views/common/ajax_default_error_popup_body_test', 'test/views/common/filter_combo_cleanable_test', 'test/views/common/filter_view_test', 'test/views/common/table_view_test', http://git-wip-us.apache.org/repos/asf/ambari/blob/e67c5ea5/ambari-web/app/controllers/wizard/step8_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step8_controller.js b/ambari-web/app/controllers/wizard/step8_controller.js index 33e8b4d..b582866 100644 --- a/ambari-web/app/controllers/wizard/step8_controller.js +++ b/ambari-web/app/controllers/wizard/step8_controller.js @@ -169,6 +169,26 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz clusterNames: [], /** + * Number of completed cluster delete requests + * @type {number} + */ + clusterDeleteRequestsCompleted: 0, + + /** + * Indicates if all cluster delete requests are completed + * @type {boolean} + */ + isAllClusterDeleteRequestsCompleted: function () { + return this.get('clusterDeleteRequestsCompleted') == this.get('clusterNames.length'); + }.property('clusterDeleteRequestsCompleted'), + + /** + * Error popup body views for clusters that couldn't be deleted + * @type {App.AjaxDefaultErrorPopupBodyView[]} + */ + clusterDeleteErrorViews: [], + + /** * Clear current step data * @method clearStep */ @@ -181,6 +201,8 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz this.set('ajaxQueueLength', 0); this.set('ajaxRequestsQueue', App.ajaxQueue.create()); this.set('ajaxRequestsQueue.finishedCallback', this.ajaxQueueFinished); + this.get('clusterDeleteErrorViews').clear(); + this.set('clusterDeleteRequestsCompleted', 0); }, /** @@ -881,8 +903,12 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz */ submitProceed: function () { var self = this; - this.set('isSubmitDisabled', true); - this.set('isBackBtnDisabled', true); + this.setProperties({ + isSubmitDisabled: true, + isBackBtnDisabled: true, + clusterDeleteRequestsCompleted: 0 + }); + this.get('clusterDeleteErrorViews').clear(); if (this.get('content.controllerName') == 'addHostController') { App.router.get('addHostController').setLowerStepsDisable(4); } @@ -924,7 +950,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz if (self.get('content.controllerName') == 'installerController' && (!App.get('testMode')) && clusterNames.length) { self.deleteClusters(clusterNames); } else { - self.deleteClustersCallback(null, null, {isLast: true}); + self.startDeploy(); } }); }, @@ -972,6 +998,7 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz * @method deleteClusters */ deleteClusters: function (clusterNames) { + this.get('clusterDeleteErrorViews').clear(); clusterNames.forEach(function (clusterName, index) { App.ajax.send({ name: 'common.delete.cluster', @@ -980,39 +1007,103 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz name: clusterName, isLast: index == clusterNames.length - 1 }, - success: 'deleteClustersCallback', - error: 'deleteClustersCallback' + success: 'deleteClusterSuccessCallback', + error: 'deleteClusterErrorCallback' }); }, this); }, - deleteClustersCallback: function (response, request, data) { - if (data.isLast) { - this.createCluster(); - this.createSelectedServices(); - if (this.get('content.controllerName') !== 'addHostController') { - if (this.get('wizardController').getDBProperty('fileNamesToUpdate') && this.get('wizardController').getDBProperty('fileNamesToUpdate').length) { - this.updateConfigurations(this.get('wizardController').getDBProperty('fileNamesToUpdate')); - } - this.createConfigurations(); - this.applyConfigurationsToCluster(this.get('serviceConfigTags')); - } - this.createComponents(); - this.registerHostsToCluster(); - this.createConfigurationGroups(); - this.createMasterHostComponents(); - this.createSlaveAndClientsHostComponents(); - if (this.get('content.controllerName') === 'addServiceController') { - this.createAdditionalClientComponents(); + /** + * Method to execute after successful cluster deletion + * @method deleteClusterSuccessCallback + */ + deleteClusterSuccessCallback: function () { + this.incrementProperty('clusterDeleteRequestsCompleted'); + if (this.get('isAllClusterDeleteRequestsCompleted')) { + if (this.get('clusterDeleteErrorViews.length')) { + this.showDeleteClustersErrorPopup(); + } else { + this.startDeploy(); } - this.createAdditionalHostComponents(); + } + }, - this.set('ajaxQueueLength', this.get('ajaxRequestsQueue.queue.length')); - this.get('ajaxRequestsQueue').start(); + /** + * Method to execute after failed cluster deletion + * @param {object} request + * @param {string} ajaxOptions + * @param {string} error + * @param {object} opt + * @method deleteClusterErrorCallback + */ + deleteClusterErrorCallback: function (request, ajaxOptions, error, opt) { + this.incrementProperty('clusterDeleteRequestsCompleted'); + try { + var json = $.parseJSON(request.responseText); + var message = json.message; + } catch (err) { + } + this.get('clusterDeleteErrorViews').pushObject(App.AjaxDefaultErrorPopupBodyView.create({ + url: opt.url, + type: opt.type, + status: request.status, + message: message + })); + if (this.get('isAllClusterDeleteRequestsCompleted')) { + this.showDeleteClustersErrorPopup(); } }, + /** + * Show error popup if cluster deletion failed + * @method showDeleteClustersErrorPopup + */ + showDeleteClustersErrorPopup: function () { + var self = this; + this.setProperties({ + isSubmitDisabled: false, + isBackBtnDisabled: false + }); + App.ModalPopup.show({ + header: Em.I18n.t('common.error'), + secondary: false, + onPrimary: function () { + this.hide(); + }, + bodyClass: Em.ContainerView.extend({ + childViews: self.get('clusterDeleteErrorViews') + }) + }); + }, + + /** + * Start deploy process + * @method startDeploy + */ + startDeploy: function () { + this.createCluster(); + this.createSelectedServices(); + if (this.get('content.controllerName') !== 'addHostController') { + if (this.get('wizardController').getDBProperty('fileNamesToUpdate') && this.get('wizardController').getDBProperty('fileNamesToUpdate').length) { + this.updateConfigurations(this.get('wizardController').getDBProperty('fileNamesToUpdate')); + } + this.createConfigurations(); + this.applyConfigurationsToCluster(this.get('serviceConfigTags')); + } + this.createComponents(); + this.registerHostsToCluster(); + this.createConfigurationGroups(); + this.createMasterHostComponents(); + this.createSlaveAndClientsHostComponents(); + if (this.get('content.controllerName') === 'addServiceController') { + this.createAdditionalClientComponents(); + } + this.createAdditionalHostComponents(); + + this.set('ajaxQueueLength', this.get('ajaxRequestsQueue.queue.length')); + this.get('ajaxRequestsQueue').start(); + }, /** * ******************************************************************* http://git-wip-us.apache.org/repos/asf/ambari/blob/e67c5ea5/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index 42384bc..b1e0ea8 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -2445,5 +2445,7 @@ Em.I18n.translations = { 'config.group.save.confirmation.manage.button': 'Manage Hosts', 'config.group.description.default': 'New configuration group created on {0}', - 'utils.ajax.errorMessage': 'Error message' + 'utils.ajax.errorMessage': 'Error message', + 'utils.ajax.defaultErrorPopupBody.message': 'received on {0} method for API: {1}', + 'utils.ajax.defaultErrorPopupBody.statusCode': '{0} status code' }; http://git-wip-us.apache.org/repos/asf/ambari/blob/e67c5ea5/ambari-web/app/utils/ajax/ajax.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js index 1756a99..e4a0960 100644 --- a/ambari-web/app/utils/ajax/ajax.js +++ b/ambari-web/app/utils/ajax/ajax.js @@ -2308,7 +2308,6 @@ var ajax = Em.Object.extend({ defaultErrorHandler: function (jqXHR, url, method, showStatus) { method = method || 'GET'; var self = this; - var api = " received on " + method + " method for API: " + url; try { var json = $.parseJSON(jqXHR.responseText); var message = json.message; @@ -2317,7 +2316,6 @@ var ajax = Em.Object.extend({ if (!showStatus) { showStatus = 500; } - var statusCode = jqXHR.status + " status code"; if (jqXHR.status === showStatus && !this.get('modalPopup')) { this.set('modalPopup', App.ModalPopup.show({ header: Em.I18n.t('common.error'), @@ -2326,13 +2324,11 @@ var ajax = Em.Object.extend({ this.hide(); self.set('modalPopup', null); }, - bodyClass: Ember.View.extend({ - classNames: ['api-error'], - templateName: require('templates/utils/ajax'), - api: api, - statusCode: statusCode, - message: message, - showMessage: !!message + bodyClass: App.AjaxDefaultErrorPopupBodyView.extend({ + type: method, + url: url, + status: jqXHR.status, + message: message }) })); } http://git-wip-us.apache.org/repos/asf/ambari/blob/e67c5ea5/ambari-web/app/views.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js index 1873b22..9971914 100644 --- a/ambari-web/app/views.js +++ b/ambari-web/app/views.js @@ -20,6 +20,7 @@ // load all views here require('views/application'); +require('views/common/ajax_default_error_popup_body'); require('views/common/chart'); require('views/common/chart/pie'); require('views/common/chart/linear'); http://git-wip-us.apache.org/repos/asf/ambari/blob/e67c5ea5/ambari-web/app/views/common/ajax_default_error_popup_body.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/ajax_default_error_popup_body.js b/ambari-web/app/views/common/ajax_default_error_popup_body.js new file mode 100644 index 0000000..616e69e --- /dev/null +++ b/ambari-web/app/views/common/ajax_default_error_popup_body.js @@ -0,0 +1,74 @@ +/** + * 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'); + +App.AjaxDefaultErrorPopupBodyView = Em.View.extend({ + + classNames: ['api-error'], + templateName: require('templates/utils/ajax'), + + /** + * HTTP request URL + * @type {string} + */ + url: '', + + /** + * HTTP request type + * @type {string} + */ + type: '', + + /** + * HTTP response status code + * @type {number} + */ + status: 0, + + /** + * Received error message + * @type {string} + */ + message: '', + + /** + * Status code string + * @type {string} + */ + statusCode: function () { + return Em.I18n.t('utils.ajax.defaultErrorPopupBody.statusCode').format(this.get('status')); + }.property('status'), + + /** + * Indicates if error message should be displayed + * @type {boolean} + */ + showMessage: function () { + return !!this.get('message'); + }.property('message'), + + /** + * HTTP response error description + * @type {string} + */ + api: function () { + return Em.I18n.t('utils.ajax.defaultErrorPopupBody.message').format(this.get('type'), this.get('url')); + }.property('type', 'url') + +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/e67c5ea5/ambari-web/test/controllers/wizard/step8_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/wizard/step8_test.js b/ambari-web/test/controllers/wizard/step8_test.js index e6b022b..0f3923d 100644 --- a/ambari-web/test/controllers/wizard/step8_test.js +++ b/ambari-web/test/controllers/wizard/step8_test.js @@ -833,16 +833,29 @@ describe('App.WizardStep8Controller', function () { }); describe('#deleteClusters', function() { - it('should call App.ajax.send for each provided clusterName', function() { + + beforeEach(function () { sinon.stub(App.ajax, 'send', Em.K); + }); + + afterEach(function () { + App.ajax.send.restore(); + }); + + it('should call App.ajax.send for each provided clusterName', function() { var clusterNames = ['h1', 'h2', 'h3']; installerStep8Controller.deleteClusters(clusterNames); expect(App.ajax.send.callCount).to.equal(clusterNames.length); clusterNames.forEach(function(n, i) { expect(App.ajax.send.getCall(i).args[0].data).to.eql({name: n, isLast: i == clusterNames.length - 1}); }); - App.ajax.send.restore(); }); + + it('should clear cluster delete error popup body views', function () { + installerStep8Controller.deleteClusters([]); + expect(installerStep8Controller.get('clusterDeleteErrorViews')).to.eql([]); + }); + }); describe('#createSelectedServicesData', function() { @@ -1551,4 +1564,200 @@ describe('App.WizardStep8Controller', function () { }); }); + describe('#isAllClusterDeleteRequestsCompleted', function () { + it('should depend on completed cluster delete requests number', function () { + installerStep8Controller.setProperties({ + clusterDeleteRequestsCompleted: 0, + clusterNames: ['c0'] + }); + expect(installerStep8Controller.get('isAllClusterDeleteRequestsCompleted')).to.be.false; + installerStep8Controller.incrementProperty('clusterDeleteRequestsCompleted'); + expect(installerStep8Controller.get('isAllClusterDeleteRequestsCompleted')).to.be.true; + }); + }); + + describe('#deleteClusterSuccessCallback', function () { + + beforeEach(function () { + sinon.stub(installerStep8Controller, 'showDeleteClustersErrorPopup', Em.K); + sinon.stub(installerStep8Controller, 'startDeploy', Em.K); + installerStep8Controller.setProperties({ + clusterDeleteRequestsCompleted: 0, + clusterNames: ['c0', 'c1'], + clusterDeleteErrorViews: [] + }); + installerStep8Controller.deleteClusterSuccessCallback(); + }); + + afterEach(function () { + installerStep8Controller.showDeleteClustersErrorPopup.restore(); + installerStep8Controller.startDeploy.restore(); + }); + + it('no failed requests', function () { + expect(installerStep8Controller.get('clusterDeleteRequestsCompleted')).to.equal(1); + expect(installerStep8Controller.showDeleteClustersErrorPopup.called).to.be.false; + expect(installerStep8Controller.startDeploy.called).to.be.false; + installerStep8Controller.deleteClusterSuccessCallback(); + expect(installerStep8Controller.get('clusterDeleteRequestsCompleted')).to.equal(2); + expect(installerStep8Controller.showDeleteClustersErrorPopup.called).to.be.false; + expect(installerStep8Controller.startDeploy.calledOnce).to.be.true; + }); + + it('one request failed', function () { + installerStep8Controller.deleteClusterErrorCallback({}, null, null, {}); + expect(installerStep8Controller.get('clusterDeleteRequestsCompleted')).to.equal(2); + expect(installerStep8Controller.showDeleteClustersErrorPopup.calledOnce).to.be.true; + expect(installerStep8Controller.startDeploy.called).to.be.false; + }); + + }); + + describe('#deleteClusterErrorCallback', function () { + + var request = { + status: 500, + responseText: '{"message":"Internal Server Error"}' + }, + ajaxOptions = 'error', + error = 'Internal Server Error', + opt = { + url: 'api/v1/clusters/c0', + type: 'DELETE' + }; + + beforeEach(function () { + installerStep8Controller.setProperties({ + clusterDeleteRequestsCompleted: 0, + clusterNames: ['c0', 'c1'], + clusterDeleteErrorViews: [] + }); + sinon.stub(installerStep8Controller, 'showDeleteClustersErrorPopup', Em.K); + installerStep8Controller.deleteClusterErrorCallback(request, ajaxOptions, error, opt); + }); + + afterEach(function () { + installerStep8Controller.showDeleteClustersErrorPopup.restore(); + }); + + it('should show error popup only if all requests are completed', function () { + expect(installerStep8Controller.get('clusterDeleteRequestsCompleted')).to.equal(1); + expect(installerStep8Controller.showDeleteClustersErrorPopup.called).to.be.false; + installerStep8Controller.deleteClusterErrorCallback(request, ajaxOptions, error, opt); + expect(installerStep8Controller.get('clusterDeleteRequestsCompleted')).to.equal(2); + expect(installerStep8Controller.showDeleteClustersErrorPopup.calledOnce).to.be.true; + }); + + it('should create error popup body view', function () { + expect(installerStep8Controller.get('clusterDeleteErrorViews')).to.have.length(1); + expect(installerStep8Controller.get('clusterDeleteErrorViews.firstObject.url')).to.equal('api/v1/clusters/c0'); + expect(installerStep8Controller.get('clusterDeleteErrorViews.firstObject.type')).to.equal('DELETE'); + expect(installerStep8Controller.get('clusterDeleteErrorViews.firstObject.status')).to.equal(500); + expect(installerStep8Controller.get('clusterDeleteErrorViews.firstObject.message')).to.equal('Internal Server Error'); + }); + + }); + + describe('#showDeleteClustersErrorPopup', function () { + + beforeEach(function () { + installerStep8Controller.setProperties({ + isSubmitDisabled: true, + isBackBtnDisabled: true + }); + sinon.stub(App.ModalPopup, 'show', Em.K); + installerStep8Controller.showDeleteClustersErrorPopup(); + }); + + afterEach(function () { + App.ModalPopup.show.restore(); + }); + + it('should show error popup and unlock navigation', function () { + expect(installerStep8Controller.get('isSubmitDisabled')).to.be.false; + expect(installerStep8Controller.get('isBackBtnDisabled')).to.be.false; + expect(App.ModalPopup.show.calledOnce).to.be.true; + }); + + }); + + describe('#startDeploy', function () { + + var stubbedNames = ['createCluster', 'createSelectedServices', 'updateConfigurations', 'createConfigurations', + 'applyConfigurationsToCluster', 'createComponents', 'registerHostsToCluster', 'createConfigurationGroups', + 'createMasterHostComponents', 'createSlaveAndClientsHostComponents', 'createAdditionalClientComponents', + 'createAdditionalHostComponents'], + cases = [ + { + controllerName: 'installerController', + notExecuted: ['createAdditionalClientComponents', 'updateConfigurations'], + fileNamesToUpdate: [], + title: 'Installer, no configs to update' + }, + { + controllerName: 'installerController', + notExecuted: ['createAdditionalClientComponents'], + fileNamesToUpdate: [''], + title: 'Installer, some configs to be updated' + }, + { + controllerName: 'addHostController', + notExecuted: ['updateConfigurations', 'createConfigurations', 'applyConfigurationsToCluster', 'createAdditionalClientComponents'], + title: 'Add Host Wizard' + }, + { + controllerName: 'addServiceController', + notExecuted: ['updateConfigurations'], + fileNamesToUpdate: [], + title: 'Add Service Wizard, no configs to update' + }, + { + controllerName: 'addServiceController', + notExecuted: [], + fileNamesToUpdate: [''], + title: 'Add Service Wizard, some configs to be updated' + } + ]; + + beforeEach(function () { + stubbedNames.forEach(function (name) { + sinon.stub(installerStep8Controller, name, Em.K); + }); + installerStep8Controller.setProperties({ + serviceConfigTags: [], + content: { + controllerName: null + } + }); + }); + + afterEach(function () { + stubbedNames.forEach(function (name) { + installerStep8Controller[name].restore(); + }); + installerStep8Controller.get.restore(); + }); + + cases.forEach(function (item) { + it(item.title, function () { + sinon.stub(installerStep8Controller, 'get') + .withArgs('ajaxRequestsQueue').returns({ + start: Em.K + }) + .withArgs('ajaxRequestsQueue.queue.length').returns(1) + .withArgs('wizardController').returns({ + getDBProperty: function () { + return item.fileNamesToUpdate; + } + }) + .withArgs('content.controllerName').returns(item.controllerName); + installerStep8Controller.startDeploy(); + stubbedNames.forEach(function (name) { + expect(installerStep8Controller[name].called).to.equal(!item.notExecuted.contains(name)); + }); + }); + }); + + }); + }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/e67c5ea5/ambari-web/test/views/common/ajax_default_error_popup_body_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/ajax_default_error_popup_body_test.js b/ambari-web/test/views/common/ajax_default_error_popup_body_test.js new file mode 100644 index 0000000..5575fe8 --- /dev/null +++ b/ambari-web/test/views/common/ajax_default_error_popup_body_test.js @@ -0,0 +1,85 @@ +/** + * 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'); +require('views/common/ajax_default_error_popup_body'); + +describe('App.AjaxDefaultErrorPopupBodyView', function () { + + describe('#statusCode', function () { + + var view = App.AjaxDefaultErrorPopupBodyView.create(); + + it('should format status code', function () { + view.set('status', 404); + expect(view.get('statusCode')).to.equal(Em.I18n.t('utils.ajax.defaultErrorPopupBody.statusCode').format(404)); + }); + + }); + + describe('#showMessage', function () { + + var view = App.AjaxDefaultErrorPopupBodyView.create(), + title = 'should be {0}', + cases = [ + { + message: 'error', + showMessage: true + }, + { + message: '', + showMessage: false + }, + { + message: null, + showMessage: false + }, + { + message: undefined, + showMessage: false + }, + { + message: 0, + showMessage: false + } + ]; + + cases.forEach(function (item) { + it(title.format(item.showMessage), function () { + view.set('message', item.message); + expect(view.get('showMessage')).to.equal(item.showMessage); + }); + }); + + }); + + describe('#api', function () { + + var view = App.AjaxDefaultErrorPopupBodyView.create(); + + it('should format string with request type and URL', function () { + view.setProperties({ + type: 'GET', + url: 'api/v1/clusters' + }); + expect(view.get('api')).to.equal(Em.I18n.t('utils.ajax.defaultErrorPopupBody.message').format('GET', 'api/v1/clusters')); + }); + + }); + +});
