Return-Path: X-Original-To: apmail-ambari-commits-archive@www.apache.org Delivered-To: apmail-ambari-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 22B8C11312 for ; Wed, 23 Apr 2014 12:41:49 +0000 (UTC) Received: (qmail 88036 invoked by uid 500); 23 Apr 2014 12:41:48 -0000 Delivered-To: apmail-ambari-commits-archive@ambari.apache.org Received: (qmail 87761 invoked by uid 500); 23 Apr 2014 12:41:48 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 87601 invoked by uid 99); 23 Apr 2014 12:41:47 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 23 Apr 2014 12:41:47 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id CB4059483D2; Wed, 23 Apr 2014 12:41:46 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: onechiporenko@apache.org To: commits@ambari.apache.org Message-Id: <14fa279fc2564f8ab34bd422b0db7a14@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: git commit: AMBARI-5543. Unit tests for steps 6. (onechiporenko) Date: Wed, 23 Apr 2014 12:41:46 +0000 (UTC) Repository: ambari Updated Branches: refs/heads/trunk 9d0dea40b -> d9b91a7fc AMBARI-5543. Unit tests for steps 6. (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d9b91a7f Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d9b91a7f Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d9b91a7f Branch: refs/heads/trunk Commit: d9b91a7fc58424f9a9c66918771d404ba84abc62 Parents: 9d0dea4 Author: Oleg Nechiporenko Authored: Wed Apr 23 15:37:47 2014 +0300 Committer: Oleg Nechiporenko Committed: Wed Apr 23 15:41:37 2014 +0300 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 1 + .../app/controllers/wizard/step6_controller.js | 151 +- ambari-web/app/templates/wizard/step6.hbs | 70 +- ambari-web/app/views/wizard/step6_view.js | 71 +- ambari-web/test/installer/step6_test.js | 1310 ++++++++++++++++-- ambari-web/test/views/wizard/step6_view_test.js | 170 +++ 6 files changed, 1592 insertions(+), 181 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/d9b91a7f/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 c4738f0..6175b3f 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -138,6 +138,7 @@ require('test/views/wizard/step1_view_test'); require('test/views/wizard/step2_view_test'); require('test/views/wizard/step3_view_test'); require('test/views/wizard/step5_view_test'); +require('test/views/wizard/step6_view_test'); require('test/views/wizard/step9_view_test'); require('test/views/wizard/step10_view_test'); require('test/models/host_test'); http://git-wip-us.apache.org/repos/asf/ambari/blob/d9b91a7f/ambari-web/app/controllers/wizard/step6_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/wizard/step6_controller.js b/ambari-web/app/controllers/wizard/step6_controller.js index f8af7a6..e11c63e 100644 --- a/ambari-web/app/controllers/wizard/step6_controller.js +++ b/ambari-web/app/controllers/wizard/step6_controller.js @@ -33,7 +33,12 @@ var db = require('utils/db'); */ App.WizardStep6Controller = Em.Controller.extend({ + /** + * List of hosts + * @type {object[]} + */ hosts: [], + /** * List of components info about selecting/deselecting status for components. * @@ -41,33 +46,50 @@ App.WizardStep6Controller = Em.Controller.extend({ * @item {Em.Object} * @property name {String} - component name * @property label {String} - component display name - * @property allChecked {Boolean} - all checkboxes are checked - * @property noChecked {Boolean} - no checkboxes checked + * @property allChecked {bool} - all checkboxes are checked + * @property noChecked {bool} - no checkboxes checked */ headers: [], /** * true - assign ZK, HB * false - slaves and clients + * @type {bool} */ isMasters: false, - isLoaded: false, + /** + * @type {bool} + */ + isLoaded: false, + /** + * Check if addHostWizard used + * @type {bool} + */ isAddHostWizard: function () { return this.get('content.controllerName') === 'addHostController'; }.property('content.controllerName'), + /** + * Check if installerWizard used + * @type {bool} + */ isInstallerWizard: function () { return this.get('content.controllerName') === 'installerController'; }.property('content.controllerName'), - isAddServiceWizard: function() { + /** + * Check if addHerviceWizard used + * @type {bool} + */ + isAddServiceWizard: function () { return this.get('content.controllerName') === 'addServiceController'; }.property('content.controllerName'), /** - * verify condition that at least one checkbox of each component was checked + * Verify condition that at least one checkbox of each component was checked + * @method clearError */ clearError: function () { var self = this; @@ -114,6 +136,10 @@ App.WizardStep6Controller = Em.Controller.extend({ } }, + /** + * Clear Step6 data like hosts, headers etc + * @method clearStep + */ clearStep: function () { this.set('hosts', []); this.set('headers', []); @@ -123,24 +149,33 @@ App.WizardStep6Controller = Em.Controller.extend({ /** * Enable some service for all hosts - * @param event + * @param {object} event + * @method selectAllNodes */ selectAllNodes: function (event) { - this.setAllNodes(event.context.name, true); + var name = Em.get(event, 'context.name'); + if (name) { + this.setAllNodes(name, true); + } }, /** * Disable some services for all hosts - * @param event + * @param {object} event + * @method deselectAllNodes */ deselectAllNodes: function (event) { - this.setAllNodes(event.context.name, false); + var name = Em.get(event, 'context.name'); + if (name) { + this.setAllNodes(name, false); + } }, /** * Enable/disable some service for all hosts * @param {String} component - component name - * @param {Boolean} checked - true - enable, false - disable + * @param {bool} checked - true - enable, false - disable + * @method setAllNodes */ setAllNodes: function (component, checked) { this.get('hosts').forEach(function (host) { @@ -155,8 +190,9 @@ App.WizardStep6Controller = Em.Controller.extend({ /** * Return whether service was selected or not - * @param name serviceName - * @return {*} + * @param {string} name serviceName + * @return {bool} + * @method isServiceSelected */ isServiceSelected: function (name) { return !!(this.get('content.services').findProperty('serviceName', name) && @@ -165,30 +201,44 @@ App.WizardStep6Controller = Em.Controller.extend({ /** * Checkbox check callback + * Verify if all/none checkboxes for current component are checked * @param {String} component + * @method checkCallback */ checkCallback: function (component) { var header = this.get('headers').findProperty('name', component); - var hosts = this.get('hosts'); - var allTrue = true; - var allFalse = true; - hosts.forEach(function (host) { - host.get('checkboxes').forEach(function (checkbox) { - if (checkbox.get('component') === component && !checkbox.get('isInstalled')) { - allTrue &= checkbox.get('checked'); - allFalse &= !checkbox.get('checked'); - } + if (header) { + var hosts = this.get('hosts'); + var allTrue = true; + var allFalse = true; + hosts.forEach(function (host) { + host.get('checkboxes').forEach(function (checkbox) { + if (checkbox.get('component') === component && !checkbox.get('isInstalled')) { + allTrue = allTrue && checkbox.get('checked'); + allFalse = allFalse && !checkbox.get('checked'); + } + }); }); - }); - header.set('allChecked', allTrue); - header.set('noChecked', allFalse); + header.set('allChecked', allTrue); + header.set('noChecked', allFalse); + } this.clearError(); }, + /** + * Get displayName for component by componentName + * @param componentName + * @returns {string} + * @method getComponentDisplayName + */ getComponentDisplayName: function (componentName) { - return App.StackServiceComponent.find().findProperty('componentName', componentName).get('displayName') + return App.StackServiceComponent.find().findProperty('componentName', componentName).get('displayName'); }, + /** + * Init step6 data + * @method loadStep + */ loadStep: function () { var self = this; @@ -196,7 +246,7 @@ App.WizardStep6Controller = Em.Controller.extend({ console.log("WizardStep6Controller: Loading step6: Assign Slaves"); this.clearStep(); - var headers = []; + var headers = Em.A([]); if (this.get('isMasters')) { if (this.isServiceSelected('HBASE') && App.supports.multipleHBaseMasters) { @@ -214,7 +264,7 @@ App.WizardStep6Controller = Em.Controller.extend({ } else { if (this.isServiceSelected('HDFS')) { - headers.pushObject(Ember.Object.create({ + headers.pushObject(Em.Object.create({ name: 'DATANODE', label: self.getComponentDisplayName('DATANODE') })); @@ -249,7 +299,7 @@ App.WizardStep6Controller = Em.Controller.extend({ label: self.getComponentDisplayName('FLUME_HANDLER') })); } - headers.pushObject(Ember.Object.create({ + headers.pushObject(Em.Object.create({ name: 'CLIENT', label: App.format.role('CLIENT') })); @@ -276,14 +326,17 @@ App.WizardStep6Controller = Em.Controller.extend({ /** * Get active host names - * @return {Array} + * @return {string[]} + * @method getHostNames */ getHostNames: function () { var hostInfo = this.get('content.hosts'); var hostNames = []; for (var index in hostInfo) { - if (hostInfo[index].bootStatus === 'REGISTERED') { - hostNames.push(hostInfo[index].name); + if (hostInfo.hasOwnProperty(index)) { + if (hostInfo[index].bootStatus === 'REGISTERED') { + hostNames.push(hostInfo[index].name); + } } } return hostNames; @@ -291,12 +344,13 @@ App.WizardStep6Controller = Em.Controller.extend({ /** * Load all data needed for this module. Then it automatically renders in template + * @method render */ render: function () { - var hostsObj = []; - var masterHosts = []; - var headers = this.get('headers'); - var masterHostNames = this.get('content.masterComponentHosts').mapProperty('hostName').uniq(); + var hostsObj = [], + masterHosts = [], + headers = this.get('headers'), + masterHostNames = this.get('content.masterComponentHosts').mapProperty('hostName').uniq(); this.getHostNames().forEach(function (_hostName) { var hasMaster = masterHostNames.contains(_hostName); @@ -339,9 +393,10 @@ App.WizardStep6Controller = Em.Controller.extend({ }, /** - * + * Set checked values for slaves checkboxes * @param {Array} hostsObj * @return {Array} + * @method renderSlaves */ renderSlaves: function (hostsObj) { var self = this; @@ -389,10 +444,11 @@ App.WizardStep6Controller = Em.Controller.extend({ }, /** - * select checkboxes which correspond to master components + * Select checkboxes which correspond to master components * * @param {Array} hostsObj * @return {Array} + * @method selectMasterComponents */ selectMasterComponents: function (hostsObj) { var masterComponentHosts = this.get('content.masterComponentHosts'); @@ -414,8 +470,9 @@ App.WizardStep6Controller = Em.Controller.extend({ /** * Return list of master components for specified hostname - * @param hostName - * @return {*} + * @param {string} hostName + * @return {string[]} + * @method getMasterComponentsForHost */ getMasterComponentsForHost: function (hostName) { return this.get('content.masterComponentHosts').filterProperty('hostName', hostName).mapProperty('component'); @@ -424,7 +481,8 @@ App.WizardStep6Controller = Em.Controller.extend({ /** * Validate form. Return do we have errors or not - * @return {Boolean} + * @return {bool} + * @method validate */ validate: function () { @@ -433,19 +491,21 @@ App.WizardStep6Controller = Em.Controller.extend({ } else { if (this.get('isInstallerWizard')) { - return this.validateEachComponent() && this.validateEachHost(Em.I18n.t('installer.step6.error.mustSelectOneForSlaveHost')); + return this.validateEachComponent() && this.validateEachHost(Em.I18n.t('installer.step6.error.mustSelectOneForSlaveHost')); } else { - if(this.get('isAddServiceWizard')) { + if (this.get('isAddServiceWizard')) { return this.validateEachComponent(); } + return true; } } }, /** * Validate all components for each host. Return do we have errors or not - * @return {Boolean} + * @return {bool} + * @method validateEachHost */ validateEachHost: function (errorMsg) { @@ -459,7 +519,7 @@ App.WizardStep6Controller = Em.Controller.extend({ var checkboxes = hosts[i].get('checkboxes'); isError = false; headers.forEach(function (header) { - isError |= checkboxes.findProperty('title', header.get('label')).checked; + isError = isError || checkboxes.findProperty('title', header.get('label')).checked; }); isError = !isError; if (isError) { @@ -472,7 +532,8 @@ App.WizardStep6Controller = Em.Controller.extend({ /** * Validate a component for all hosts. Return do we have errors or not - * @return {Boolean} + * @return {bool} + * @method validateEachComponent */ validateEachComponent: function () { var isError = false; http://git-wip-us.apache.org/repos/asf/ambari/blob/d9b91a7f/ambari-web/app/templates/wizard/step6.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/wizard/step6.hbs b/ambari-web/app/templates/wizard/step6.hbs index 9a3ee05..12ae8c2 100644 --- a/ambari-web/app/templates/wizard/step6.hbs +++ b/ambari-web/app/templates/wizard/step6.hbs @@ -30,56 +30,56 @@ {{t common.host}} {{#each header in controller.headers}} - - {{t all}} | + + {{t all}} | - {{t none}} - + {{t none}} + {{/each}} - {{#if view.pageContent}} - {{#each host in view.pageContent}} - - {{#view App.WizardStep6HostView hostBinding="host" }} - {{host.hostName}} - {{#if host.hasMaster}} - - {{/if}} - {{/view}} - {{#each checkbox in host.checkboxes}} - + {{#if view.pageContent}} + {{#each host in view.pageContent}} + + {{#view App.WizardStep6HostView hostBinding="host" }} + {{host.hostName}} + {{#if host.hasMaster}} + + {{/if}} + {{/view}} + {{#each checkbox in host.checkboxes}} + - - {{/each}} - - {{/each}} - {{/if}} + + {{/each}} + + {{/each}} + {{/if}} -
-
-
- -
-
{{view.paginationInfo}}
-
- {{view view.paginationFirst}} - {{view view.paginationLeft}} - {{view view.paginationRight}} - {{view view.paginationLast}} -
-
+
+
+
+ +
+
{{view.paginationInfo}}
+
+ {{view view.paginationFirst}} + {{view view.paginationLeft}} + {{view view.paginationRight}} + {{view view.paginationLast}} +
+
← {{t common.back}} {{t common.next}} → http://git-wip-us.apache.org/repos/asf/ambari/blob/d9b91a7f/ambari-web/app/views/wizard/step6_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/wizard/step6_view.js b/ambari-web/app/views/wizard/step6_view.js index 6cf0b31..f5f8d73 100644 --- a/ambari-web/app/views/wizard/step6_view.js +++ b/ambari-web/app/views/wizard/step6_view.js @@ -25,16 +25,32 @@ App.WizardStep6View = App.TableView.extend({ title: '', + /** + * Numbe rof visible rows + * @type {string} + */ displayLength: "25", + /** + * List of hosts + * @type {object[]} + */ content: function () { return this.get('controller.hosts'); }.property('controller.hosts'), + /** + * Synonym to content in this App.TableView + * @type {object[]} + */ filteredContent: function () { return this.get('content'); }.property('content'), + /** + * Set label, title and do loadStep + * @method didInsertElement + */ didInsertElement: function () { var controller = this.get('controller'); if (controller.get('isMasters')) { @@ -49,6 +65,10 @@ App.WizardStep6View = App.TableView.extend({ controller.loadStep(); }, + /** + * Set label value + * @method setLabel + */ setLabel: function () { var label = Em.I18n.t('installer.step6.body'); var clients = this.get('controller.content.clients'); @@ -56,26 +76,30 @@ App.WizardStep6View = App.TableView.extend({ if (clients.length === 1) { label = label + ' ' + _client.display_name; } - else + else { if (_client !== clients[clients.length - 1]) { // [clients.length - 1] label = label + ' ' + _client.display_name; - if(_client !== clients[clients.length - 2]) { + if (_client !== clients[clients.length - 2]) { label = label + ','; } } else { label = label + ' ' + Em.I18n.t('and') + ' ' + _client.display_name + '.'; } + } }, this); this.set('label', label); }, + /** * Binding host property with dynamic name - * @type {*} + * @type {Ember.Checkbox} */ checkboxView: Em.Checkbox.extend({ + /** * Header object with host property name + * @type {object} */ checkbox: null, @@ -85,6 +109,10 @@ App.WizardStep6View = App.TableView.extend({ disabledBinding: 'checkbox.isInstalled', + /** + * Click-handler on checkbox + * @method click + */ click: function () { if ($.browser.mozilla) { this.toggleProperty('checkbox.checked'); @@ -96,24 +124,33 @@ App.WizardStep6View = App.TableView.extend({ App.WizardStep6HostView = Em.View.extend({ + /** + * Binded host object + * @type {object} + */ host: null, + tagName: 'td', + /** + * Create hover-labels for hostName with list of installed master-components + * @method didInsertElement + */ didInsertElement: function () { - if (!this.get('controller.isMasters')) { - var components = this.get('controller').getMasterComponentsForHost(this.get('host.hostName')); - if (components && components.length > 0) { - components = components.map(function(_component) { - return App.format.role(_component); - }); - components = components.join(" /\n"); - App.popover(this.$(), { - title: Em.I18n.t('installer.step6.wizardStep6Host.title').format(this.get('host.hostName')), - content: components, - placement: 'right', - trigger: 'hover' - }); - } + if(this.get('controller.isMasters')) return; + + var components = this.get('controller').getMasterComponentsForHost(this.get('host.hostName')); + if (components && components.length > 0) { + components = components.map(function (_component) { + return App.format.role(_component); + }); + components = components.join(" /\n"); + App.popover(this.$(), { + title: Em.I18n.t('installer.step6.wizardStep6Host.title').format(this.get('host.hostName')), + content: components, + placement: 'right', + trigger: 'hover' + }); } } }); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/d9b91a7f/ambari-web/test/installer/step6_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/installer/step6_test.js b/ambari-web/test/installer/step6_test.js index da64fc1..39ab248 100644 --- a/ambari-web/test/installer/step6_test.js +++ b/ambari-web/test/installer/step6_test.js @@ -18,101 +18,392 @@ var Ember = require('ember'); var App = require('app'); +require('utils/helper'); require('controllers/wizard/step6_controller'); - +var controller, + services = [ + Em.Object.create({ + serviceName: 'MAPREDUCE', + isSelected: true + }), + Em.Object.create({ + serviceName: 'YARN', + isSelected: true + }), + Em.Object.create({ + serviceName: 'HBASE', + isSelected: true + }), + Em.Object.create({ + serviceName: 'HDFS', + isSelected: true + }), + Em.Object.create({ + serviceName: 'STORM', + isSelected: true + }), + Em.Object.create({ + serviceName: 'FLUME', + isSelected: true + }) + ]; describe('App.WizardStep6Controller', function () { - var controller = App.WizardStep6Controller.create(); - controller.set('content', { - hosts: {}, - masterComponentHosts: {}, - services: [ - Em.Object.create({ - serviceName: 'MAPREDUCE', - isSelected: true - }), - Em.Object.create({ - serviceName: 'YARN', - isSelected: true - }), - Em.Object.create({ - serviceName: 'HBASE', - isSelected: true - }), - Em.Object.create({ - serviceName: 'HDFS', - isSelected: true - }) - ] - }); - controller.set('getComponentDisplayName',function () { - return true; - }); - - var HOSTS = Em.A([ 'host0', 'host1', 'host2', 'host3' ]); + beforeEach(function () { + controller = App.WizardStep6Controller.create(); + controller.set('content', { + hosts: {}, + masterComponentHosts: {}, + services: services + }); + sinon.stub(controller, 'getComponentDisplayName', function (c) { + return App.format.components[c]; + }); - var h = {}; - var m = []; - HOSTS.forEach(function (hostName) { - var obj = Em.Object.create({ - name: hostName, - hostName: hostName, - bootStatus: 'REGISTERED' + var h = {}, m = []; + Em.A(['host0', 'host1', 'host2', 'host3']).forEach(function (hostName) { + var obj = Em.Object.create({ + name: hostName, + hostName: hostName, + bootStatus: 'REGISTERED' + }); + h[hostName] = obj; + m.push(obj); }); - h[hostName] = obj; - m.push(obj); + + controller.set('content.hosts', h); + controller.set('content.masterComponentHosts', m); + controller.set('isMasters', false); + }); - controller.set('content.hosts', h); - controller.set('content.masterComponentHosts', m); - controller.set('isMasters', false); + afterEach(function () { + controller.getComponentDisplayName.restore(); + }); + describe('#loadStep', function () { + Em.A([ + { + isMasters: false, + services: [ + Em.Object.create({ + serviceName: 'MAPREDUCE', + isSelected: true + }) + ], + e: { + l: 2, + allChecked: false, + noChecked: true + } + }, + { + isMasters: false, + services: [ + Em.Object.create({ + serviceName: 'MAPREDUCE', + isSelected: true + }), + Em.Object.create({ + serviceName: 'YARN', + isSelected: true + }) + ], + e: { + l: 3, + allChecked: false, + noChecked: true + } + }, + { + isMasters: false, + services: [ + Em.Object.create({ + serviceName: 'MAPREDUCE', + isSelected: true + }), + Em.Object.create({ + serviceName: 'YARN', + isSelected: true + }), + Em.Object.create({ + serviceName: 'HBASE', + isSelected: true + }) + ], + e: { + l: 4, + allChecked: false, + noChecked: true + } + }, + { + isMasters: false, + services: [ + Em.Object.create({ + serviceName: 'MAPREDUCE', + isSelected: true + }), + Em.Object.create({ + serviceName: 'YARN', + isSelected: true + }), + Em.Object.create({ + serviceName: 'HBASE', + isSelected: true + }), + Em.Object.create({ + serviceName: 'HDFS', + isSelected: true + }) + ], + e: { + l: 5, + allChecked: false, + noChecked: true + } + }, + { + isMasters: false, + services: [ + Em.Object.create({ + serviceName: 'MAPREDUCE', + isSelected: true + }), + Em.Object.create({ + serviceName: 'YARN', + isSelected: true + }), + Em.Object.create({ + serviceName: 'HBASE', + isSelected: true + }), + Em.Object.create({ + serviceName: 'HDFS', + isSelected: true + }), + Em.Object.create({ + serviceName: 'STORM', + isSelected: true + }) + ], + e: { + l: 6, + allChecked: false, + noChecked: true + } + }, + { + isMasters: false, + services: [ + Em.Object.create({ + serviceName: 'MAPREDUCE', + isSelected: true + }), + Em.Object.create({ + serviceName: 'YARN', + isSelected: true + }), + Em.Object.create({ + serviceName: 'HBASE', + isSelected: true + }), + Em.Object.create({ + serviceName: 'HDFS', + isSelected: true + }), + Em.Object.create({ + serviceName: 'STORM', + isSelected: true + }), + Em.Object.create({ + serviceName: 'FLUME', + isSelected: true + }) + ], + e: { + l: 7, + allChecked: false, + noChecked: true + } + }, + { + isMasters: true, + multipleHBaseMasters: true, + services: [ + Em.Object.create({ + serviceName: 'HBASE', + isSelected: true + }) + ], + e: { + l: 1, + allChecked: false, + noChecked: true + } + }, + { + isMasters: true, + multipleHBaseMasters: false, + services: [ + Em.Object.create({ + serviceName: 'HBASE', + isSelected: true + }) + ], + e: { + l: 0, + allChecked: false, + noChecked: true + } + }, + { + isMasters: true, + services: [ + Em.Object.create({ + serviceName: 'ZOOKEEPER', + isSelected: true + }) + ], + e: { + l: 1, + allChecked: false, + noChecked: true + } + } + ]).forEach(function (test) { + it(test.isMasters.toString() + ' ' + test.services.mapProperty('serviceName').join(', '), function () { + if (test.hasOwnProperty('multipleHBaseMasters')) { + App.set('supports.multipleHBaseMasters', test.multipleHBaseMasters); + } + controller.set('content.services', test.services); + controller.set('isMasters', test.isMasters); + sinon.stub(controller, 'render', Em.K); + controller.loadStep(); + expect(controller.get('headers.length')).to.equal(test.e.l); + expect(controller.get('headers').everyProperty('allChecked', test.e.allChecked)).to.equal(true); + expect(controller.get('headers').everyProperty('noChecked', test.e.noChecked)).to.equal(true); + controller.clearStep(); + controller.render.restore(); + }); + }); - describe('#loadStep', function() { - controller.loadStep(); - it('Hosts are loaded', function() { - expect(controller.get('hosts').length).to.equal(HOSTS.length); - }); + Em.A([ + { + p: { + isMasters: true, + skipMasterStep: true + }, + e: true + }, + { + p: { + isMasters: false, + skipMasterStep: true + }, + e: false + }, + { + p: { + isMasters: true, + skipMasterStep: false + }, + e: false + }, + { + p: { + isMasters: false, + skipMasterStep: false + }, + e: false + } + ]).forEach(function (test) { + it('should skip this step if isMasters is ' + test.p.isMasters + ' and content.skipMasterStep is ' + test.p.skipMasterStep, function () { + controller.set('isMasters', test.p.isMasters); + controller.set('content.skipMasterStep', test.p.skipMasterStep); + sinon.stub(App.router, 'send', Em.K); + controller.loadStep(); + expect(App.router.send.calledWith('next')).to.equal(test.e); + App.router.send.restore(); + }); + }); + + Em.A([ + { + p: { + isMasters: true, + skipSlavesStep: true + }, + e: false + }, + { + p: { + isMasters: false, + skipSlavesStep: true + }, + e: true + }, + { + p: { + isMasters: true, + skipSlavesStep: false + }, + e: false + }, + { + p: { + isMasters: false, + skipSlavesStep: false + }, + e: false + } + ]).forEach(function (test) { + it('should skip this step if isMasters is ' + test.p.isMasters + ' and content.skipSlavesStep is ' + test.p.skipSlavesStep, function () { + controller.set('isMasters', test.p.isMasters); + controller.set('content.skipSlavesStep', test.p.skipSlavesStep); + sinon.stub(App.router, 'send', Em.K); + controller.loadStep(); + expect(App.router.send.calledWith('next')).to.equal(test.e); + App.router.send.restore(); + }); + }); - it('Headers are loaded', function() { - expect(controller.get('headers').length).not.to.equal(0); - }); }); - describe('#isAddHostWizard', function() { - it('true if content.controllerName is addHostController', function() { + describe('#isAddHostWizard', function () { + it('true if content.controllerName is addHostController', function () { controller.set('content.controllerName', 'addHostController'); expect(controller.get('isAddHostWizard')).to.equal(true); }); - it('false if content.controllerName is not addHostController', function() { + it('false if content.controllerName is not addHostController', function () { controller.set('content.controllerName', 'mainController'); expect(controller.get('isAddHostWizard')).to.equal(false); }); }); - describe('#isInstallerWizard', function() { - it('true if content.controllerName is addHostController', function() { + describe('#isInstallerWizard', function () { + it('true if content.controllerName is addHostController', function () { controller.set('content.controllerName', 'installerController'); expect(controller.get('isInstallerWizard')).to.equal(true); }); - it('false if content.controllerName is not addHostController', function() { + it('false if content.controllerName is not addHostController', function () { controller.set('content.controllerName', 'mainController'); expect(controller.get('isInstallerWizard')).to.equal(false); }); }); - describe('#isAddServiceWizard', function() { - it('true if content.controllerName is addServiceController', function() { + describe('#isAddServiceWizard', function () { + it('true if content.controllerName is addServiceController', function () { controller.set('content.controllerName', 'addServiceController'); expect(controller.get('isAddServiceWizard')).to.equal(true); }); - it('false if content.controllerName is not addServiceController', function() { + it('false if content.controllerName is not addServiceController', function () { controller.set('content.controllerName', 'mainController'); expect(controller.get('isAddServiceWizard')).to.equal(false); }); }); - describe('#setAllNodes', function() { + describe('#setAllNodes', function () { var test_config = Em.A([ { @@ -137,11 +428,12 @@ describe('App.WizardStep6Controller', function () { } ]); - test_config.forEach(function(test) { - it((test.state?'Select':'Deselect') + ' all ' + test.title, function() { + test_config.forEach(function (test) { + it((test.state ? 'Select' : 'Deselect') + ' all ' + test.title, function () { + controller.loadStep(); controller.setAllNodes(test.name, test.state); var hosts = controller.get('hosts'); - hosts.forEach(function(host) { + hosts.forEach(function (host) { var cb = host.get('checkboxes').filterProperty('isInstalled', false).findProperty('component', test.name); if (cb) { expect(cb.get('checked')).to.equal(test.state); @@ -153,36 +445,41 @@ describe('App.WizardStep6Controller', function () { }); - describe('#isServiceSelected', function() { - controller.get('content.services').forEach(function(service) { - it(service.serviceName + ' is selected', function() { - expect(controller.isServiceSelected(service.serviceName)).to.equal(true); + describe('#isServiceSelected', function () { + describe('selected', function () { + services.forEach(function (service) { + it(service.serviceName + ' is selected', function () { + expect(controller.isServiceSelected(service.serviceName)).to.equal(true); + }); }); }); var unselectedService = 'FAKESERVICE'; - it(unselectedService + ' is not selected', function() { + it(unselectedService + ' is not selected', function () { expect(controller.isServiceSelected(unselectedService)).to.equal(false); }); }); - describe('#validateEachComponent', function() { - it('Nothing checked', function() { - controller.get('hosts').forEach(function(host) { + describe('#validateEachComponent', function () { + beforeEach(function () { + controller.loadStep(); + }); + it('Nothing checked', function () { + controller.get('hosts').forEach(function (host) { host.get('checkboxes').setEach('checked', false); }); expect(controller.validateEachComponent('')).to.equal(false); }); - it('One slave is not selected for no one host', function() { - controller.get('hosts').forEach(function(host) { - host.get('checkboxes').forEach(function(checkbox, index) { + it('One slave is not selected for no one host', function () { + controller.get('hosts').forEach(function (host) { + host.get('checkboxes').forEach(function (checkbox, index) { checkbox.set('checked', index === 0); }); }); expect(controller.validateEachComponent('')).to.equal(false); }); - it('All checked', function() { - controller.get('hosts').forEach(function(host) { - host.get('checkboxes').forEach(function(checkbox) { + it('All checked', function () { + controller.get('hosts').forEach(function (host) { + host.get('checkboxes').forEach(function (checkbox) { checkbox.set('checked', true); }); }); @@ -190,25 +487,870 @@ describe('App.WizardStep6Controller', function () { }); }); - describe('#validateEachHost', function() { - it('Nothing checked', function() { - controller.get('hosts').forEach(function(host) { + describe('#validateEachHost', function () { + beforeEach(function () { + controller.loadStep(); + }); + it('Nothing checked', function () { + controller.get('hosts').forEach(function (host) { host.get('checkboxes').setEach('checked', false); }); expect(controller.validateEachHost('')).to.equal(false); }); - it('One host doesn\'t have assigned slaves', function() { - controller.get('hosts').forEach(function(host, index) { + it('One host doesn\'t have assigned slaves', function () { + controller.get('hosts').forEach(function (host, index) { host.get('checkboxes').setEach('checked', index === 0); }); expect(controller.validateEachHost('')).to.equal(false); }); - it('All checked', function() { - controller.get('hosts').forEach(function(host) { + it('All checked', function () { + controller.get('hosts').forEach(function (host) { host.get('checkboxes').setEach('checked', true); }); expect(controller.validateEachHost('')).to.equal(true); }); }); -}); + describe('#clearStep', function () { + beforeEach(function () { + sinon.stub(controller, 'clearError', Em.K); + }); + afterEach(function () { + controller.clearError.restore(); + }); + it('should call clearError', function () { + controller.clearStep(); + expect(controller.clearError.calledOnce).to.equal(true); + }); + it('should clear hosts', function () { + controller.set('hosts', [ + {}, + {} + ]); + controller.clearStep(); + expect(controller.get('hosts')).to.eql([]); + }); + it('should clear headers', function () { + controller.set('headers', [ + {}, + {} + ]); + controller.clearStep(); + expect(controller.get('headers')).to.eql([]); + }); + it('should set isLoaded to false', function () { + controller.set('isLoaded', true); + controller.clearStep(); + expect(controller.get('isLoaded')).to.equal(false); + }); + }); + + describe('#selectAllNodes', function () { + beforeEach(function () { + sinon.stub(controller, 'setAllNodes', Em.K); + }); + afterEach(function () { + controller.setAllNodes.restore(); + }); + it('should call setAllNodes', function () { + controller.selectAllNodes({context: {name: 'name'}}); + expect(controller.setAllNodes.calledWith('name', true)).to.equal(true); + }); + it('shouldn\'t call setAllNodes', function () { + controller.selectAllNodes(); + expect(controller.setAllNodes.called).to.equal(false); + }); + }); + + describe('#deselectAllNodes', function () { + beforeEach(function () { + sinon.stub(controller, 'setAllNodes', Em.K); + }); + afterEach(function () { + controller.setAllNodes.restore(); + }); + it('should call setAllNodes', function () { + controller.deselectAllNodes({context: {name: 'name'}}); + expect(controller.setAllNodes.calledWith('name', false)).to.equal(true); + }); + it('shouldn\'t call setAllNodes', function () { + controller.deselectAllNodes(); + expect(controller.setAllNodes.called).to.equal(false); + }); + }); + + describe('#checkCallback', function () { + beforeEach(function () { + sinon.stub(controller, 'clearError', Em.K); + }); + afterEach(function () { + controller.clearError.restore(); + }); + it('should call clearError', function () { + controller.checkCallback(''); + expect(controller.clearError.calledOnce).to.equal(true); + }); + Em.A([ + { + m: 'all checked, isInstalled false', + headers: Em.A([ + Em.Object.create({name: 'c1'}) + ]), + hosts: Em.A([ + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({ + component: 'c1', + isInstalled: false, + checked: true + }) + ]) + }) + ]), + component: 'c1', + e: { + allChecked: true, + noChecked: false + } + }, + { + m: 'all checked, isInstalled true', + headers: Em.A([ + Em.Object.create({name: 'c1'}) + ]), + hosts: Em.A([ + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({ + component: 'c1', + isInstalled: true, + checked: true + }) + ]) + }) + ]), + component: 'c1', + e: { + allChecked: true, + noChecked: true + } + }, + { + m: 'no one checked', + headers: Em.A([ + Em.Object.create({name: 'c1'}) + ]), + hosts: Em.A([ + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({ + component: 'c1', + isInstalled: false, + checked: false + }) + ]) + }) + ]), + component: 'c1', + e: { + allChecked: false, + noChecked: true + } + }, + { + m: 'some checked', + headers: Em.A([ + Em.Object.create({name: 'c1'}) + ]), + hosts: Em.A([ + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({ + component: 'c1', + isInstalled: false, + checked: true + }), + Em.Object.create({ + component: 'c1', + isInstalled: false, + checked: false + }) + ]) + }) + ]), + component: 'c1', + e: { + allChecked: false, + noChecked: false + } + }, + { + m: 'some checked, some isInstalled true', + headers: Em.A([ + Em.Object.create({name: 'c1'}) + ]), + hosts: Em.A([ + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({ + component: 'c1', + isInstalled: true, + checked: true + }), + Em.Object.create({ + component: 'c1', + isInstalled: true, + checked: true + }) + ]) + }) + ]), + component: 'c1', + e: { + allChecked: true, + noChecked: true + } + }, + { + m: 'some checked, some isInstalled true (2)', + headers: Em.A([ + Em.Object.create({name: 'c1'}) + ]), + hosts: Em.A([ + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({ + component: 'c1', + isInstalled: false, + checked: false + }), + Em.Object.create({ + component: 'c1', + isInstalled: true, + checked: true + }) + ]) + }) + ]), + component: 'c1', + e: { + allChecked: false, + noChecked: true + } + } + ]).forEach(function (test) { + it(test.m, function () { + controller.clearStep(); + controller.set('headers', test.headers); + controller.set('hosts', test.hosts); + controller.checkCallback(test.component); + var header = controller.get('headers').findProperty('name', test.component); + expect(header.get('allChecked')).to.equal(test.e.allChecked); + expect(header.get('noChecked')).to.equal(test.e.noChecked); + }); + }); + }); + + describe('#getHostNames', function () { + var tests = Em.A([ + { + hosts: { + h1: {bootStatus: 'REGISTERED', name: 'h1'}, + h2: {bootStatus: 'REGISTERED', name: 'h2'}, + h3: {bootStatus: 'REGISTERED', name: 'h3'} + }, + m: 'All REGISTERED', + e: ['h1', 'h2', 'h3'] + }, + { + hosts: { + h1: {bootStatus: 'REGISTERED', name: 'h1'}, + h2: {bootStatus: 'FAILED', name: 'h2'}, + h3: {bootStatus: 'REGISTERED', name: 'h3'} + }, + m: 'Some REGISTERED', + e: ['h1', 'h3'] + }, + { + hosts: { + h1: {bootStatus: 'FAILED', name: 'h1'}, + h2: {bootStatus: 'FAILED', name: 'h2'}, + h3: {bootStatus: 'FAILED', name: 'h3'} + }, + m: 'No one REGISTERED', + e: [] + }, + { + hosts: {}, + m: 'Empty hosts', + e: [] + } + ]); + tests.forEach(function (test) { + it(test.m, function () { + controller.set('content.hosts', test.hosts); + var r = controller.getHostNames(); + expect(r).to.eql(test.e); + }); + }); + }); + + describe('#validate', function () { + var tests = Em.A([ + { + controllerName: 'addHostController', + method: 'validateEachHost', + r: true, + e: true + }, + { + controllerName: 'addHostController', + method: 'validateEachHost', + r: false, + e: false + }, + { + controllerName: 'addServiceController', + method: 'validateEachComponent', + r: true, + e: true + }, + { + controllerName: 'addServiceController', + method: 'validateEachComponent', + r: false, + e: false + }, + { + controllerName: 'installerController', + method: 'validateEachComponent', + r: true, + e: true + }, + { + controllerName: 'installerController', + method: 'validateEachComponent', + r: false, + e: false + } + ]); + tests.forEach(function (test) { + it(test.controllerName + ' ' + test.method + ' returns ' + test.r.toString(), function () { + sinon.stub(controller, test.method, function () { + return test.r + }); + controller.set('content.controllerName', test.controllerName); + expect(controller.validate()).to.equal(test.e); + controller[test.method].restore(); + }); + }); + }); + + describe('#getMasterComponentsForHost', function () { + var tests = Em.A([ + { + masterComponentHosts: Em.A([ + {hostName: 'h1', component: 'c1'} + ]), + hostName: 'h1', + m: 'host exists', + e: ['c1'] + }, + { + masterComponentHosts: Em.A([ + {hostName: 'h1', component: 'c1'} + ]), + hostName: 'h2', + m: 'host donesn\'t exists', + e: [] + } + ]); + tests.forEach(function (test) { + it(test.m, function () { + controller.set('content.masterComponentHosts', test.masterComponentHosts); + var r = controller.getMasterComponentsForHost(test.hostName); + expect(r).to.eql(test.e); + }); + }); + }); + + describe('#selectMasterComponents', function () { + var tests = Em.A([ + { + masterComponentHosts: Em.A([ + { + hostName: 'h1', + component: 'c1' + } + ]), + hostsObj: [ + Em.Object.create({ + hostName: 'h1', + checkboxes: [ + Em.Object.create({ + component: 'c1', + checked: false + }) + ] + }) + ], + e: true, + m: 'host and component exist' + }, + { + masterComponentHosts: Em.A([ + { + hostName: 'h1', + component: 'c2' + } + ]), + hostsObj: [ + Em.Object.create({ + hostName: 'h1', + checkboxes: [ + Em.Object.create({ + component: 'c1', + checked: false + }) + ] + }) + ], + e: false, + m: 'host exists' + }, + { + masterComponentHosts: Em.A([ + { + hostName: 'h2', + component: 'c2' + } + ]), + hostsObj: [ + Em.Object.create({ + hostName: 'h1', + checkboxes: [ + Em.Object.create({ + component: 'c1', + checked: false + }) + ] + }) + ], + e: false, + m: 'host and component don\'t exist' + } + ]); + tests.forEach(function (test) { + it(test.m, function () { + controller.set('content.masterComponentHosts', test.masterComponentHosts); + var r = controller.selectMasterComponents(test.hostsObj); + expect(r.findProperty('hostName', 'h1').get('checkboxes').findProperty('component', 'c1').get('checked')).to.equal(test.e); + }); + }); + }); + + describe('#render', function () { + beforeEach(function () { + sinon.stub(controller, 'selectMasterComponents', Em.K); + sinon.stub(controller, 'renderSlaves', Em.K); + }); + afterEach(function () { + controller.selectMasterComponents.restore(); + controller.renderSlaves.restore(); + }); + it('should call selectMasterComponents if isMasters is true', function () { + controller.set('isMasters', true); + controller.render(); + expect(controller.selectMasterComponents.calledOnce).to.equal(true); + expect(controller.renderSlaves.called).to.equal(false); + }); + it('should call renderSlaves if isMasters is false', function () { + controller.set('isMasters', false); + controller.render(); + expect(controller.selectMasterComponents.called).to.equal(false); + expect(controller.renderSlaves.calledOnce).to.equal(true); + }); + it('should set isLoaded to true', function () { + controller.set('isLoaded', false); + controller.render(); + expect(controller.get('isLoaded')).to.equal(true); + }); + }); + + describe('#renderSlaves', function () { + Em.A([ + { + controllerName: 'addServiceController', + slaveComponents: [], + hostsObj: [ + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({isInstalled: false, title: 'client'}), + Em.Object.create({isInstalled: false, title: ''}), + Em.Object.create({isInstalled: false, title: ''}) + ]), + hasMaster: true + }) + ], + m: 'host with masters, empty slaveComponents, controllerName - addServiceController', + e: [ + [false, false, false] + ] + }, + { + controllerName: 'addServiceController', + slaveComponents: [], + hostsObj: [ + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({isInstalled: false, title: 'client'}), + Em.Object.create({isInstalled: false, title: ''}), + Em.Object.create({isInstalled: false, title: ''}) + ]), + hasMaster: false + }) + ], + m: 'host without masters, empty slaveComponents, controllerName - addServiceController', + e: [ + [false, true, true] + ] + }, + { + controllerName: 'addServiceController', + slaveComponents: [], + services: [ + Em.Object.create({serviceName: 'HDFS', isSelected: true}) + ], + hostsObj: [ + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({isInstalled: false, title: 'client'}), + Em.Object.create({isInstalled: false, title: 'DataNode', checked: true}), + Em.Object.create({isInstalled: false, title: ''}) + ]), + hasMaster: false + }) + ], + m: 'host without masters, empty slaveComponents, controllerName - addServiceController, one datanode checked', + e: [ + [true, true, true] + ] + }, + { + controllerName: 'addServiceController', + slaveComponents: [], + services: [ + Em.Object.create({serviceName: 'HDFS', isSelected: true}) + ], + hostsObj: [ + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({isInstalled: false, title: 'client'}), + Em.Object.create({isInstalled: false, title: 'DataNode', checked: false}), + Em.Object.create({isInstalled: false, title: ''}) + ]), + hasMaster: true + }) + ], + m: 'host with masters, empty slaveComponents, controllerName - addServiceController, one datanode not checked', + e: [ + [false, false, false] + ] + }, + { + controllerName: 'installerController', + slaveComponents: [], + services: [ + Em.Object.create({serviceName: 'HDFS', isSelected: true}) + ], + hostsObj: [ + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({isInstalled: false, title: 'client'}), + Em.Object.create({isInstalled: false, title: 'DataNode', checked: true}), + Em.Object.create({isInstalled: false, title: ''}) + ]), + hasMaster: true + }) + ], + m: 'host with masters, empty slaveComponents, controllerName - installerController, one datanode checked', + e: [ + [true, true, true] + ] + }, + { + controllerName: 'installerController', + slaveComponents: [], + services: [ + Em.Object.create({serviceName: 'HDFS', isSelected: true}) + ], + hostsObj: [ + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({isInstalled: false, title: 'client'}), + Em.Object.create({isInstalled: false, title: 'DataNode', checked: false}), + Em.Object.create({isInstalled: false, title: ''}) + ]), + hasMaster: true + }), + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({isInstalled: false, title: 'client'}), + Em.Object.create({isInstalled: false, title: 'DataNode', checked: true}), + Em.Object.create({isInstalled: false, title: ''}) + ]), + hasMaster: true + }) + ], + m: 'hosts with masters, empty slaveComponents, controllerName - installerController, one datanode checked', + e: [ + [false, false, false], + [true, true, true] + ] + }, + { + controllerName: 'installerController', + slaveComponents: [], + services: [ + Em.Object.create({serviceName: 'HDFS', isSelected: true}) + ], + hostsObj: [ + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({isInstalled: false, title: 'client'}), + Em.Object.create({isInstalled: false, title: 'DataNode', checked: false}), + Em.Object.create({isInstalled: false, title: ''}) + ]), + hasMaster: true + }), + Em.Object.create({ + checkboxes: Em.A([ + Em.Object.create({isInstalled: false, title: 'client'}), + Em.Object.create({isInstalled: false, title: 'DataNode', checked: true}), + Em.Object.create({isInstalled: false, title: ''}) + ]), + hasMaster: false + }) + ], + m: 'some hosts with masters, empty slaveComponents, controllerName - installerController, one datanode checked', + e: [ + [false, false, false], + [true, true, true] + ] + } + ]).forEach(function (test) { + it(test.m, function () { + controller.set('content.slaveComponents', test.slaveComponents); + controller.set('content.controllerName', test.controllerName); + if (test.services) { + controller.set('content.services', test.services); + } + controller.set('isMasters', false); + controller.loadStep(); + var r = controller.renderSlaves(test.hostsObj); + expect(r.map(function (i) { + return i.get('checkboxes').map(function (j) { + return j.get('checked'); + }); + })).to.eql(test.e); + }); + }); + + Em.A([ + { + slaveComponents: [ + {componentName: 'c1', hosts: [ + {hostName: 'h1', isInstalled: false}, + {hostName: 'h2', isInstalled: false} + ]}, + {componentName: 'c2', hosts: [ + {hostName: 'h1', isInstalled: false}, + {hostName: 'h2', isInstalled: false} + ]} + ], + headers: [ + Em.Object.create({name: 'c1', label: 'C1'}), + Em.Object.create({name: 'c2', label: 'C2'}) + ], + hostsObj: [ + Em.Object.create({ + hostName: 'h1', + checkboxes: [ + Em.Object.create({ + title: 'C1', + checked: false, + isInstalled: false + }), + Em.Object.create({ + title: 'C2', + checked: false, + isInstalled: false + }) + ] + }), + Em.Object.create({ + hostName: 'h2', + checkboxes: [ + Em.Object.create({ + title: 'C1', + checked: false, + isInstalled: false + }), + Em.Object.create({ + title: 'C2', + checked: false, + isInstalled: false + }) + ] + }) + ], + m: 'all Checked, nothing installed before', + e: { + checked: [ + [true, true], + [true, true] + ], + isInstalled: [ + [false, false], + [false, false] + ] + } + }, + { + slaveComponents: [ + {componentName: 'c1', hosts: [ + {hostName: 'h1', isInstalled: true}, + {hostName: 'h2', isInstalled: true} + ]}, + {componentName: 'c2', hosts: [ + {hostName: 'h1', isInstalled: true}, + {hostName: 'h2', isInstalled: true} + ]} + ], + headers: [ + Em.Object.create({name: 'c1', label: 'C1'}), + Em.Object.create({name: 'c2', label: 'C2'}) + ], + hostsObj: [ + Em.Object.create({ + hostName: 'h1', + checkboxes: [ + Em.Object.create({ + title: 'C1', + checked: false, + isInstalled: false + }), + Em.Object.create({ + title: 'C2', + checked: false, + isInstalled: false + }) + ] + }), + Em.Object.create({ + hostName: 'h2', + checkboxes: [ + Em.Object.create({ + title: 'C1', + checked: false, + isInstalled: false + }), + Em.Object.create({ + title: 'C2', + checked: false, + isInstalled: false + }) + ] + }) + ], + m: 'all Checked, all installed before', + e: { + checked: [ + [true, true], + [true, true] + ], + isInstalled: [ + [true, true], + [true, true] + ] + } + }, + { + slaveComponents: [ + {componentName: 'c1', hosts: [ + {hostName: 'h1', isInstalled: true} + ]}, + {componentName: 'c2', hosts: [ + {hostName: 'h2', isInstalled: true} + ]} + ], + headers: [ + Em.Object.create({name: 'c1', label: 'C1'}), + Em.Object.create({name: 'c2', label: 'C2'}) + ], + hostsObj: [ + Em.Object.create({ + hostName: 'h1', + checkboxes: [ + Em.Object.create({ + title: 'C1', + checked: false, + isInstalled: false + }), + Em.Object.create({ + title: 'C2', + checked: false, + isInstalled: false + }) + ] + }), + Em.Object.create({ + hostName: 'h2', + checkboxes: [ + Em.Object.create({ + title: 'C1', + checked: false, + isInstalled: false + }), + Em.Object.create({ + title: 'C2', + checked: false, + isInstalled: false + }) + ] + }) + ], + m: 'some Checked, some installed before', + e: { + checked: [ + [true, false], + [false, true] + ], + isInstalled: [ + [true, false], + [false, true] + ] + } + } + ]).forEach(function (test) { + it(test.m, function () { + controller.set('content.slaveComponentHosts', test.slaveComponents); + controller.set('headers', test.headers); + var r = controller.renderSlaves(test.hostsObj); + var checked = r.map(function (i) { + return i.get('checkboxes').map(function (j) { + return j.get('checked') + }) + }); + var isInstalled = r.map(function (i) { + return i.get('checkboxes').map(function (j) { + return j.get('isInstalled') + }) + }); + expect(checked).to.eql(test.e.checked); + expect(isInstalled).to.eql(test.e.isInstalled); + }); + }); + }); + +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/d9b91a7f/ambari-web/test/views/wizard/step6_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/wizard/step6_view_test.js b/ambari-web/test/views/wizard/step6_view_test.js new file mode 100644 index 0000000..85cccc1 --- /dev/null +++ b/ambari-web/test/views/wizard/step6_view_test.js @@ -0,0 +1,170 @@ +/** + * 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('utils/helper'); +require('utils/string_utils'); +require('views/wizard/step6_view'); +var view; + +describe('App.WizardStep6View', function() { + + beforeEach(function() { + view = App.WizardStep6View.create({ + controller: App.WizardStep6Controller.create() + }); + }); + + describe('#content', function() { + it('should be same to controller.hosts', function() { + view.set('content', []); + var d = [{}, {}]; + view.set('controller.hosts', d); + expect(view.get('content')).to.eql(d); + }); + }); + + describe('#filteredContent', function() { + it('should be same to content', function() { + view.set('content', []); + var d = [{}, {}]; + view.set('controller.hosts', d); + expect(view.get('filteredContent')).to.eql(d); + }); + }); + + describe('#didInsertElement', function() { + beforeEach(function() { + sinon.stub(view.get('controller'), 'loadStep', Em.K); + sinon.stub(App, 'tooltip', Em.K); + sinon.stub(view, 'setLabel', Em.K); + }); + afterEach(function() { + view.get('controller').loadStep.restore(); + App.tooltip.restore(); + view.setLabel.restore(); + }); + it('should call loadStep', function() { + view.didInsertElement(); + expect(view.get('controller').loadStep.calledOnce).to.equal(true); + }); + it('should create tooltip', function() { + view.didInsertElement(); + expect(App.tooltip.calledOnce).to.equal(true); + }); + it('should call setLabel if not controller.isMasters', function() { + view.set('controller.isMasters', false); + view.didInsertElement(); + expect(view.setLabel.calledOnce).to.equal(true); + }); + it('shouldn\'t call setLabel if controller.isMasters', function() { + view.set('controller.isMasters', true); + view.didInsertElement(); + expect(view.setLabel.called).to.equal(false); + }); + }); + + describe('#setLabel', function() { + var tests = Em.A([ + { + clients: [{display_name: 'c1'}], + m: 'One client', + e: 'c1' + }, + { + clients: [{display_name: 'c1'}, {display_name: 'c2'}], + m: 'Two clients', + e: 'c1 and c2.' + }, + { + clients: [{display_name: 'c1'}, {display_name: 'c2'}, {display_name: 'c3'}], + m: 'Three clients', + e: 'c1, c2 and c3.' + }, + { + clients: [{display_name: 'c1'}, {display_name: 'c2'}, {display_name: 'c3'}, {display_name: 'c4'}], + m: 'Four clients', + e: 'c1, c2, c3 and c4.' + }, + { + clients: [{display_name: 'c1'}, {display_name: 'c2'}, {display_name: 'c3'}, {display_name: 'c4'}, {display_name: 'c5'}], + m: 'Five clients', + e: 'c1, c2, c3, c4 and c5.' + } + ]); + tests.forEach(function(test) { + it(test.m, function() { + view.set('controller.content', {clients: test.clients}); + view.setLabel(); + expect(view.get('label').endsWith(test.e)).to.equal(true); + }); + }); + }); + + describe('#checkboxView', function() { + it('should call checkCallback', function() { + var v = view.get('checkboxView').create({ + controller: App.WizardStep6Controller.create() + }); + sinon.stub(v.get('controller'), 'checkCallback', Em.K); + v.click(); + expect(v.get('controller').checkCallback.calledOnce).to.equal(true); + v.get('controller').checkCallback.restore(); + }); + }); + +}); + +describe('App.WizardStep6HostView', function() { + + beforeEach(function() { + view = App.WizardStep6HostView.create({ + controller: App.WizardStep6Controller.create() + }); + }); + + describe('#didInsertElement', function() { + beforeEach(function() { + sinon.stub(App, 'popover', Em.K); + }); + afterEach(function() { + App.popover.restore(); + }); + it('should create popover if not controller.isMasters', function() { + sinon.stub(view.get('controller'), 'getMasterComponentsForHost', function() {return [{}, {}];}); + view.set('controller.isMasters', false); + view.didInsertElement(); + expect(App.popover.calledOnce).to.equal(true); + view.get('controller').getMasterComponentsForHost.restore(); + }); + it('shouldn\'t create popover if controller.isMasters', function() { + view.set('controller.isMasters', true); + view.didInsertElement(); + expect(App.popover.called).to.equal(false); + }); + it('shouldn\'t create popover if controller.getMasterComponentsForHost returns empty array', function() { + sinon.stub(view.get('controller'), 'getMasterComponentsForHost', function() {return [];}); + view.set('controller.isMasters', true); + view.didInsertElement(); + expect(App.popover.called).to.equal(false); + view.get('controller').getMasterComponentsForHost.restore(); + }); + }); + +}); \ No newline at end of file