Repository: ambari
Updated Branches:
  refs/heads/trunk 739d35e38 -> b96edcf90


http://git-wip-us.apache.org/repos/asf/ambari/blob/b96edcf9/ambari-web/test/installer/step9_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/installer/step9_test.js 
b/ambari-web/test/installer/step9_test.js
index f96ee00..2469828 100644
--- a/ambari-web/test/installer/step9_test.js
+++ b/ambari-web/test/installer/step9_test.js
@@ -24,12 +24,14 @@ require('models/hosts');
 require('controllers/wizard/step9_controller');
 require('utils/helper');
 var modelSetup = require('test/init_model_test');
-
+var c, obj;
 describe('App.InstallerStep9Controller', function () {
-  beforeEach(function(){
+  beforeEach(function () {
     modelSetup.setupStackServiceComponent();
+    c = App.WizardStep9Controller.create();
+    obj = App.InstallerController.create();
   });
-  afterEach(function(){
+  afterEach(function () {
     modelSetup.cleanStackServiceComponent();
   });
 
@@ -739,6 +741,22 @@ describe('App.InstallerStep9Controller', function () {
       var result = controller.finishState();
       expect(result).to.equal(false);
     });
+    it('for INSTALLED status should call isServicesStarted', function () {
+      c.set('content', {cluster: {status: 'INSTALLED'}});
+      var polledData = {'{}': {}};
+      sinon.stub(c, 'isServicesStarted', Em.K);
+      c.finishState(polledData);
+      expect(c.isServicesStarted.calledWith(polledData)).to.equal(true);
+      c.isServicesStarted.restore();
+    });
+    it('for PENDING status should call isServicesInstalled', function () {
+      c.set('content', {cluster: {status: 'PENDING'}});
+      var polledData = {'{}': {}};
+      sinon.stub(c, 'isServicesInstalled', Em.K);
+      c.finishState(polledData);
+      expect(c.isServicesInstalled.calledWith(polledData)).to.equal(true);
+      c.isServicesInstalled.restore();
+    });
   });
 
   describe('#setLogTasksStatePerHost', function () {
@@ -937,11 +955,19 @@ describe('App.InstallerStep9Controller', function () {
         expect(controller.get('progress')).to.equal(test.e.progress);
       });
     });
+    it('shouldn\'t do nothing if polledData.Requests.id != requestId', 
function () {
+      c.set('content', {cluster: {requestId: 1}});
+      var polledData = {Requests: {id: 2}, tasks: []};
+      sinon.spy(c, 'finishState');
+      expect(c.parseHostInfo(polledData)).to.equal(false);
+      expect(c.finishState.called).to.equal(false);
+      c.finishState.restore();
+    });
   });
 
   describe('#isAllComponentsInstalledSuccessCallback', function () {
 
-    describe('', function() {
+    describe('', function () {
       var hosts = Em.A([
         Em.Object.create({name: 'host1', status: 'failed', expectedStatus: 
'heartbeat_lost'}),
         Em.Object.create({name: 'host2', status: 'info', expectedStatus: 
'heartbeat_lost'}),
@@ -1046,7 +1072,7 @@ describe('App.InstallerStep9Controller', function () {
 
     });
 
-    describe('', function() {
+    describe('', function () {
       var noHeartbeatLostData = {
         "items": [
           {
@@ -1076,9 +1102,10 @@ describe('App.InstallerStep9Controller', function () {
       // INSTALL FAILED -> INSTALL FAILED. No transition should happen when 
install all services request fails and then user hits refresh
       // Cluster is not expected to enter this function in other states: 
INSTALLED, START FAILED, STARTED
 
-      var statuses = Em.A(['INSTALL FAILED', 'INSTALLED','START FAILED', 
'STARTED']);  // Cluster in any of this states should have no effect on the 
state from this function
+      var statuses = Em.A(['INSTALL FAILED', 'INSTALLED', 'START FAILED', 
'STARTED']);  // Cluster in any of this states should have no effect on the 
state from this function
       statuses.forEach(function (priorStatus) {
-        var controller = App.WizardStep9Controller.create({hosts: hosts, 
content: {controllerName: 'installerController', cluster: {status: 
priorStatus}},togglePreviousSteps: function(){}});
+        var controller = App.WizardStep9Controller.create({hosts: hosts, 
content: {controllerName: 'installerController', cluster: {status: 
priorStatus}}, togglePreviousSteps: function () {
+        }});
         // Action
         
controller.isAllComponentsInstalledSuccessCallback(noHeartbeatLostData);
         // Validation for the cluster state.
@@ -1090,25 +1117,25 @@ describe('App.InstallerStep9Controller', function () {
     });
   });
 
-   // isServicesInstalled is called after every poll for "Install All 
Services" request.
-   // This function should result into a call to "Start All Services" request 
only if install request completed successfully.
+  // isServicesInstalled is called after every poll for "Install All Services" 
request.
+  // This function should result into a call to "Start All Services" request 
only if install request completed successfully.
   describe('#isServicesInstalled', function () {
 
-    var hostStateJsonData =  {
-      "items" : [
+    var hostStateJsonData = {
+      "items": [
         {
-          "Hosts" : {
-            "cluster_name" : "c1",
-            "host_name" : "ambari-1.c.apache.internal",
-            "host_state" : "HEALTHY"
+          "Hosts": {
+            "cluster_name": "c1",
+            "host_name": "ambari-1.c.apache.internal",
+            "host_state": "HEALTHY"
           },
-          "host_components" : [
+          "host_components": [
             {
-              "HostRoles" : {
-                "cluster_name" : "c1",
-                "component_name" : "GANGLIA_MONITOR",
-                "host_name" : "ambari-1.c.apache.internal",
-                "state" : "STARTED"
+              "HostRoles": {
+                "cluster_name": "c1",
+                "component_name": "GANGLIA_MONITOR",
+                "host_name": "ambari-1.c.apache.internal",
+                "state": "STARTED"
               }
             }
           ]
@@ -1116,38 +1143,40 @@ describe('App.InstallerStep9Controller', function () {
       ]
     };
     var hosts = Em.A([Em.Object.create({name: 'host1', progress: '33', status: 
'info'}),
-                      Em.Object.create({name: 'host2', progress: '33', status: 
'info'})]);
+      Em.Object.create({name: 'host2', progress: '33', status: 'info'})]);
     // polledData has all hosts with status completed to trigger transition 
from install->start request.
-    var polledData =  Em.A([Em.Object.create({Tasks: {name: 'host1', status: 
'COMPLETED'}}),
-                            Em.Object.create({Tasks: {name: 'host2', status: 
'COMPLETED'}})]);
+    var polledData = Em.A([Em.Object.create({Tasks: {name: 'host1', status: 
'COMPLETED'}}),
+      Em.Object.create({Tasks: {name: 'host2', status: 'COMPLETED'}})]);
     var controller = App.WizardStep9Controller.create({hosts: hosts, content: 
{controllerName: 'installerController',
-                                                       cluster: {status: 
'PENDING',name: 'c1'}},launchStartServices: function() {return true;}});
+      cluster: {status: 'PENDING', name: 'c1'}}, launchStartServices: function 
() {
+      return true;
+    }});
     var tests = Em.A([
       // controller has "status" value as "info" initially. If no errors are 
encountered then wizard stages
       // transition info->success, on error info->error, on warning 
info->warning
-      {status: 'info' , e:{startServicesCalled:true}, m:'If no failed tasks 
then start services request should be called'},
-      {status: 'failed', e:{startServicesCalled:false}, m: 'If install request 
has failed tasks then start services call should not be called'}
+      {status: 'info', e: {startServicesCalled: true}, m: 'If no failed tasks 
then start services request should be called'},
+      {status: 'failed', e: {startServicesCalled: false}, m: 'If install 
request has failed tasks then start services call should not be called'}
     ]);
 
-    beforeEach(function() {
+    beforeEach(function () {
       App.testMode = true;
       sinon.spy(controller, 'launchStartServices');
       sinon.stub($, 'ajax').yieldsTo('success', hostStateJsonData);
     });
 
-    afterEach(function() {
+    afterEach(function () {
       App.testMode = false;
       controller.launchStartServices.restore();
       $.ajax.restore();
     });
 
-    tests.forEach(function(test){
-      it(test.m, function() {
-        controller.set('status',test.status);
+    tests.forEach(function (test) {
+      it(test.m, function () {
+        controller.set('status', test.status);
         //Action
         controller.isServicesInstalled(polledData);
         //Validation
-         
expect(controller.launchStartServices.called).to.equal(test.e.startServicesCalled);
+        
expect(controller.launchStartServices.called).to.equal(test.e.startServicesCalled);
       });
     });
   });
@@ -1161,15 +1190,16 @@ describe('App.InstallerStep9Controller', function () {
     App.testMode = true;
     // override the actual function
     App.popup = {
-      setErrorPopup: function() {
+      setErrorPopup: function () {
         return true;
       }
     };
-    var hosts = Em.A([Em.Object.create({name: 'host1', progress: '33', status: 
'info'}),Em.Object.create({name: 'host2', progress: '33', status: 'info'})]);
-    var controller = App.WizardStep9Controller.create({hosts: hosts, content: 
{controllerName: 'installerController', cluster: {status: 'PENDING',name: 
'c1'}},togglePreviousSteps: function(){}});
+    var hosts = Em.A([Em.Object.create({name: 'host1', progress: '33', status: 
'info'}), Em.Object.create({name: 'host2', progress: '33', status: 'info'})]);
+    var controller = App.WizardStep9Controller.create({hosts: hosts, content: 
{controllerName: 'installerController', cluster: {status: 'PENDING', name: 
'c1'}}, togglePreviousSteps: function () {
+    }});
 
     //Action
-    controller.launchStartServicesErrorCallback({status:500, statusTesxt: 
'Server Error'}, {}, '', {});
+    controller.launchStartServicesErrorCallback({status: 500, statusTesxt: 
'Server Error'}, {}, '', {});
     it('Cluster Status should be INSTALL FAILED', function () {
       expect(controller.get('content.cluster.status')).to.equal('INSTALL 
FAILED');
     });
@@ -1180,7 +1210,7 @@ describe('App.InstallerStep9Controller', function () {
     });
 
     it('All Host progress bars on the screen should be finished (100%) with 
blue color', function () {
-      controller.get('hosts').forEach(function(host){
+      controller.get('hosts').forEach(function (host) {
         expect(host.get('progress')).to.equal('100');
         expect(host.get('status')).to.equal('info');
       });
@@ -1196,4 +1226,748 @@ describe('App.InstallerStep9Controller', function () {
 
   });
 
-});
+  describe('#submit', function () {
+    it('should call App.router.send', function () {
+      sinon.stub(App.router, 'send', Em.K);
+      c.submit();
+      expect(App.router.send.calledWith('next')).to.equal(true);
+      App.router.send.restore();
+    });
+  });
+
+  describe('#back', function () {
+    beforeEach(function () {
+      sinon.stub(App.router, 'send', Em.K);
+    });
+    afterEach(function () {
+      App.router.send.restore();
+    });
+    it('should call App.router.send', function () {
+      c.reopen({isSubmitDisabled: false});
+      c.back();
+      expect(App.router.send.calledWith('back')).to.equal(true);
+    });
+    it('shouldn\'t call App.router.send', function () {
+      c.reopen({isSubmitDisabled: true});
+      c.back();
+      expect(App.router.send.called).to.equal(false);
+    });
+  });
+
+  describe('#loadStep', function () {
+    beforeEach(function () {
+      sinon.stub(c, 'clearStep', Em.K);
+      sinon.stub(c, 'loadHosts', Em.K);
+    });
+    afterEach(function () {
+      c.clearStep.restore();
+      c.loadHosts.restore();
+    });
+    it('should call clearStep', function () {
+      c.loadStep();
+      expect(c.clearStep.calledOnce).to.equal(true);
+    });
+    it('should call loadHosts', function () {
+      c.loadStep();
+      expect(c.loadHosts.calledOnce).to.equal(true);
+    });
+  });
+
+  describe('#startPolling', function () {
+    beforeEach(function () {
+      sinon.stub(c, 'getLogsByRequestErrorCallback', Em.K);
+    });
+    afterEach(function () {
+      c.getLogsByRequestErrorCallback.restore();
+    });
+    it('should set isSubmitDisabled to true', function () {
+      c.set('isSubmitDisabled', false);
+      c.startPolling();
+      expect(c.get('isSubmitDisabled')).to.equal(true);
+    });
+    it('should call doPolling', function () {
+      sinon.stub(c, 'doPolling', Em.K);
+      c.startPolling();
+      expect(c.doPolling.calledOnce).to.equal(true);
+      c.doPolling.restore();
+    });
+  });
+
+  describe('#loadLogData', function () {
+    beforeEach(function () {
+      sinon.stub(c, 'getLogsByRequest', Em.K);
+      c.set('wizardController', Em.Object.create({
+        cluster: {oldRequestsId: []},
+        getDBProperty: function (name) {
+          return this.get(name);
+        }
+      }));
+    });
+    afterEach(function () {
+      c.getLogsByRequest.restore();
+    });
+    it('shouldn\'t call getLogsByRequest if no requestIds', function () {
+      c.set('wizardController.cluster.oldRequestsId', []);
+      c.loadLogData();
+      expect(c.getLogsByRequest.called).to.equal(false);
+    });
+    it('should call getLogsByRequest 3 times', function () {
+      c.set('wizardController.cluster.oldRequestsId', [1, 2, 3]);
+      c.loadLogData();
+      expect(c.getLogsByRequest.calledThrice).to.equal(true);
+    });
+    it('should set POLL_INTERVAL to 1 if testMode enabled', function () {
+      App.set('testMode', true);
+      c.set('wizardController.cluster.oldRequestsId', [1, 2, 3]);
+      c.loadLogData();
+      expect(c.get('POLL_INTERVAL')).to.equal(1);
+      App.set('testMode', false);
+    });
+  });
+
+  describe('#loadCurrentTaskLog', function () {
+    beforeEach(function () {
+      sinon.spy(App.ajax, 'send');
+    });
+    afterEach(function () {
+      App.ajax.send.restore();
+    });
+    it('shouldn\'t call App.ajax.send if no currentOpenTaskId', function () {
+      c.set('currentOpenTaskId', null);
+      c.loadCurrentTaskLog();
+      expect(App.ajax.send.called).to.equal(false);
+    });
+    it('should call App.ajax.send with provided data', function () {
+      sinon.stub(c, 'togglePreviousSteps', Em.K);
+      c.set('currentOpenTaskId', 1);
+      c.set('currentOpenTaskRequestId', 2);
+      c.set('content', {cluster: {name: 3}});
+      c.loadCurrentTaskLog();
+      expect(App.ajax.send.args[0][0].data).to.eql({taskId: 1, requestId: 2, 
clusterName: 3, sync: true});
+      c.togglePreviousSteps.restore();
+    });
+  });
+
+  describe('#loadCurrentTaskLogSuccessCallback', function () {
+    it('should increment logTasksChangesCounter', function () {
+      c.set('logTasksChangesCounter', 0);
+      c.loadCurrentTaskLogSuccessCallback();
+      expect(c.get('logTasksChangesCounter')).to.equal(1);
+    });
+    it('should update stdout, stderr', function () {
+      c.set('currentOpenTaskId', 1);
+      c.reopen({
+        hosts: [
+          Em.Object.create({
+            name: 'h1',
+            logTasks: [
+              {Tasks: {id: 1, stdout: '', stderr: ''}}
+            ]
+          })
+        ]
+      });
+      var data = {Tasks: {host_name: 'h1', id: 1, stderr: 'stderr', stdout: 
'stdout'}};
+      c.loadCurrentTaskLogSuccessCallback(data);
+      var t = c.get('hosts')[0].logTasks[0].Tasks;
+      expect(t.stdout).to.equal('stdout');
+      expect(t.stderr).to.equal('stderr');
+    });
+    it('shouldn\'t update stdout, stderr', function () {
+      c.set('currentOpenTaskId', 1);
+      c.reopen({
+        hosts: [
+          Em.Object.create({
+            name: 'h1',
+            logTasks: [
+              {Tasks: {id: 2, stdout: '', stderr: ''}}
+            ]
+          })
+        ]
+      });
+      var data = {Tasks: {host_name: 'h1', id: 1, stderr: 'stderr', stdout: 
'stdout'}};
+      c.loadCurrentTaskLogSuccessCallback(data);
+      var t = c.get('hosts')[0].logTasks[0].Tasks;
+      expect(t.stdout).to.equal('');
+      expect(t.stderr).to.equal('');
+    });
+    it('shouldn\'t update stdout, stderr (2)', function () {
+      c.set('currentOpenTaskId', 1);
+      c.reopen({
+        hosts: [
+          Em.Object.create({
+            name: 'h2',
+            logTasks: [
+              {Tasks: {id: 1, stdout: '', stderr: ''}}
+            ]
+          })
+        ]
+      });
+      var data = {Tasks: {host_name: 'h1', id: 1, stderr: 'stderr', stdout: 
'stdout'}};
+      c.loadCurrentTaskLogSuccessCallback(data);
+      var t = c.get('hosts')[0].logTasks[0].Tasks;
+      expect(t.stdout).to.equal('');
+      expect(t.stderr).to.equal('');
+    });
+  });
+
+  describe('#loadCurrentTaskLogErrorCallback', function () {
+    it('should set currentOpenTaskId to 0', function () {
+      c.set('currentOpenTaskId', 123);
+      c.loadCurrentTaskLogErrorCallback();
+      expect(c.get('currentOpenTaskId')).to.equal(0);
+    });
+  });
+
+  describe('#getLogsByRequest', function () {
+    beforeEach(function () {
+      sinon.spy(App.ajax, 'send');
+      sinon.stub(c, 'togglePreviousSteps', Em.K);
+    });
+    afterEach(function () {
+      App.ajax.send.restore();
+      c.togglePreviousSteps.restore();
+    });
+    it('should call App.ajax.send with provided data', function () {
+      var polling = 1;
+      var requestId = 2;
+      c.set('content', {cluster: {name: 3}});
+      c.set('numPolls', 4);
+      c.getLogsByRequest(polling, requestId);
+      expect(App.ajax.send.args[0][0].data).to.eql({polling: polling, 
requestId: requestId, cluster: 3, numPolls: 4});
+    });
+  });
+
+  describe('#doPolling', function () {
+    beforeEach(function () {
+      sinon.stub(c, 'getLogsByRequest', Em.K);
+      sinon.stub(c, 'togglePreviousSteps', Em.K);
+    });
+    afterEach(function () {
+      c.getLogsByRequest.restore();
+      c.togglePreviousSteps.restore();
+    });
+    it('should increment numPolls if testMode', function () {
+      App.set('testMode', true);
+      c.set('numPolls', 0);
+      c.doPolling();
+      expect(c.get('numPolls')).to.equal(1);
+      App.set('testMode', false);
+    });
+    it('should call getLogsByRequest', function () {
+      c.set('content', {cluster: {requestId: 1}});
+      c.doPolling();
+      expect(c.getLogsByRequest.calledWith(true, 1)).to.equal(true);
+    });
+  });
+
+  describe('#isAllComponentsInstalled', function () {
+    beforeEach(function () {
+      sinon.spy(App.ajax, 'send');
+      sinon.stub(c, 'togglePreviousSteps', Em.K);
+      sinon.stub(c, 'saveClusterStatus', Em.K);
+    });
+    afterEach(function () {
+      App.ajax.send.restore();
+      c.togglePreviousSteps.restore();
+      c.saveClusterStatus.restore();
+    });
+    it('shouldn\'t call App.ajax.send', function () {
+      c.set('content', {controllerName: 'addServiceController'});
+      c.isAllComponentsInstalled();
+      expect(App.ajax.send.called).to.equal(false);
+    });
+    it('shouldn\'t call App.ajax.send (2)', function () {
+      c.set('content', {controllerName: 'addHostController'});
+      c.isAllComponentsInstalled();
+      expect(App.ajax.send.called).to.equal(false);
+    });
+    it('should call App.ajax.send', function () {
+      c.set('content', {cluster: {name: 'n'}, controllerName: 
'installerController'});
+      c.isAllComponentsInstalled();
+      expect(App.ajax.send.args[0][0].data).to.eql({cluster: 'n'});
+    });
+  });
+
+  describe('#isAllComponentsInstalledErrorCallback', function () {
+    beforeEach(function () {
+      sinon.stub(c, 'saveClusterStatus', Em.K);
+      sinon.stub(c, 'togglePreviousSteps', Em.K);
+    });
+    afterEach(function () {
+      c.saveClusterStatus.restore();
+      c.togglePreviousSteps.restore();
+    });
+    it('should call saveClusterStatus', function () {
+      c.isAllComponentsInstalledErrorCallback({});
+      expect(c.saveClusterStatus.calledOnce).to.equal(true);
+    });
+  });
+
+  describe('#saveClusterStatus', function () {
+    beforeEach(function () {
+      sinon.stub(c, 'togglePreviousSteps', Em.K);
+    });
+    afterEach(function () {
+      c.togglePreviousSteps.restore();
+    });
+    it('in testMode should set content.cluster', function () {
+      var d = {n: 'n'};
+      c.set('content', {cluster: ''});
+      App.set('testMode', true);
+      c.saveClusterStatus(d);
+      expect(c.get('content.cluster')).to.eql(d);
+      App.set('testMode', false);
+    });
+    it('if testMode is false should use content.controller', function () {
+      var d = {n: 'n'},
+        obj = Em.Object.create({
+          saveClusterStatus: Em.K
+        });
+      sinon.stub(App.router, 'get', function () {
+        return obj;
+      });
+      sinon.spy(obj, 'saveClusterStatus');
+      c.set('content', {cluster: ''});
+      App.set('testMode', false);
+      c.saveClusterStatus(d);
+      expect(obj.saveClusterStatus.calledWith(d)).to.eql(true);
+      App.set('testMode', true);
+      obj.saveClusterStatus.restore();
+      App.router.get.restore();
+    });
+  });
+
+  describe('#saveInstalledHosts', function () {
+    beforeEach(function () {
+      sinon.stub(c, 'togglePreviousSteps', Em.K);
+    });
+    afterEach(function () {
+      c.togglePreviousSteps.restore();
+    });
+    it('if testMode is false should use content.controller', function () {
+      var d = {n: 'n'},
+        obj = Em.Object.create({
+          saveInstalledHosts: Em.K
+        });
+      sinon.stub(App.router, 'get', function () {
+        return obj;
+      });
+      sinon.spy(obj, 'saveInstalledHosts');
+      c.set('content', {cluster: ''});
+      App.set('testMode', false);
+      c.saveInstalledHosts(d);
+      expect(obj.saveInstalledHosts.calledWith(d)).to.eql(true);
+      App.set('testMode', true);
+      obj.saveInstalledHosts.restore();
+      App.router.get.restore();
+    });
+  });
+
+  describe('#getComponentMessage', function () {
+    var tests = Em.A([
+      {
+        clients: ['c1'],
+        m: 'One client',
+        e: 'c1'
+      },
+      {
+        clients: ['c1', 'c2'],
+        m: 'Two clients',
+        e: 'c1 and c2'
+      },
+      {
+        clients: ['c1', 'c2', 'c3'],
+        m: 'Three clients',
+        e: 'c1, c2 and c3'
+      },
+      {
+        clients: ['c1', 'c2', 'c3', 'c4'],
+        m: 'Four clients',
+        e: 'c1, c2, c3 and c4'
+      },
+      {
+        clients: ['c1', 'c2', 'c3', 'c4', 'c5'],
+        m: 'Five clients',
+        e: 'c1, c2, c3, c4 and c5'
+      }
+    ]);
+    tests.forEach(function (test) {
+      it(test.m, function () {
+        var label = c.getComponentMessage(test.clients);
+        expect(label).to.equal(test.e);
+      });
+    });
+  });
+
+  describe('#togglePreviousSteps', function () {
+    beforeEach(function () {
+      sinon.stub(obj, 'setStepsEnable', Em.K);
+      sinon.stub(obj, 'setLowerStepsDisable', Em.K);
+      sinon.stub(App.router, 'get', function () {
+        return obj;
+      });
+    });
+    afterEach(function () {
+      App.router.get.restore();
+      obj.setStepsEnable.restore();
+      obj.setLowerStepsDisable.restore();
+    });
+    it('shouldn\'t do nothing on testMode', function () {
+      App.set('testMode', true);
+      c.togglePreviousSteps();
+      expect(App.router.get.called).to.equal(false);
+      App.set('testMode', false);
+    });
+    Em.A([
+        {
+          status: 'INSTALL FAILED',
+          controllerName: 'installerController',
+          e: {
+            setStepsEnable: true,
+            setLowerStepsDisable: false
+          }
+        },
+        {
+          status: 'STARTED',
+          controllerName: 'installerController',
+          e: {
+            setStepsEnable: false,
+            setLowerStepsDisable: true
+          }
+        },
+        {
+          status: 'INSTALL FAILED',
+          controllerName: 'addServiceController',
+          e: {
+            setStepsEnable: false,
+            setLowerStepsDisable: true
+          }
+        },
+        {
+          status: 'STARTED',
+          controllerName: 'addServiceController',
+          e: {
+            setStepsEnable: false,
+            setLowerStepsDisable: true
+          }
+        }
+      ]).forEach(function (test) {
+        it(test.status + ' ' + test.controllerName, function () {
+          App.set('testMode', false);
+          c.reopen({content: {cluster: {status: test.status}, controllerName: 
test.controllerName}});
+          c.togglePreviousSteps();
+          
expect(App.router.get.calledWith('installerController')).to.equal(true);
+          if (test.e.setStepsEnable) {
+            expect(obj.setStepsEnable.calledOnce).to.equal(true);
+          }
+          else {
+            expect(obj.setStepsEnable.called).to.equal(false);
+          }
+          if (test.e.setLowerStepsDisable) {
+            expect(obj.setLowerStepsDisable.calledWith(9)).to.equal(true);
+          }
+          else {
+            expect(obj.setLowerStepsDisable.called).to.equal(false);
+          }
+        });
+      });
+  });
+
+  describe('#navigateStep', function () {
+    beforeEach(function () {
+      sinon.stub(c, 'togglePreviousSteps', Em.K);
+      sinon.stub(c, 'loadStep', Em.K);
+      sinon.stub(c, 'loadLogData', Em.K);
+      sinon.stub(c, 'startPolling', Em.K);
+    });
+    afterEach(function () {
+      c.togglePreviousSteps.restore();
+      c.loadStep.restore();
+      c.loadLogData.restore();
+      c.startPolling.restore();
+    });
+    it('should set custom data in testMode', function () {
+      App.set('testMode', true);
+      c.reopen({content: {cluster: {status: 'st', isCompleted: true, 
requestId: 0}}});
+      c.navigateStep();
+      expect(c.get('content.cluster.status')).to.equal('PENDING');
+      expect(c.get('content.cluster.isCompleted')).to.equal(false);
+      expect(c.get('content.cluster.requestId')).to.equal(1);
+      App.set('testMode', false);
+    });
+    it('isCompleted = true, requestId = 1', function () {
+      App.set('testMode', false);
+      c.reopen({content: {cluster: {isCompleted: true, requestId: 1}}});
+      c.navigateStep();
+      expect(c.loadStep.calledOnce).to.equal(true);
+      expect(c.loadLogData.calledWith(1)).to.equal(true);
+      expect(c.get('progress')).to.equal('100');
+    });
+    it('isCompleted = false, requestId = 1, status = INSTALL FAILED', function 
() {
+      App.set('testMode', false);
+      c.reopen({content: {cluster: {status: 'INSTALL FAILED', isCompleted: 
false, requestId: 1}}});
+      c.navigateStep();
+      expect(c.loadStep.calledOnce).to.equal(true);
+      expect(c.loadLogData.calledWith(1)).to.equal(true);
+    });
+    it('isCompleted = false, requestId = 1, status = START FAILED', function 
() {
+      App.set('testMode', false);
+      c.reopen({content: {cluster: {status: 'START FAILED', isCompleted: 
false, requestId: 1}}});
+      c.navigateStep();
+      expect(c.loadStep.calledOnce).to.equal(true);
+      expect(c.loadLogData.calledWith(1)).to.equal(true);
+    });
+    it('isCompleted = false, requestId = 1, status = OTHER', function () {
+      App.set('testMode', false);
+      c.reopen({content: {cluster: {status: 'STARTED', isCompleted: false, 
requestId: 1}}});
+      c.navigateStep();
+      expect(c.loadStep.calledOnce).to.equal(true);
+      expect(c.loadLogData.calledWith(1)).to.equal(true);
+      expect(c.startPolling.calledOnce).to.equal(true);
+    });
+  });
+
+  describe('#launchStartServices', function () {
+    beforeEach(function () {
+      sinon.spy(App.ajax, 'send');
+      sinon.stub(c, 'togglePreviousSteps', Em.K);
+      sinon.stub(c, 'saveClusterStatus', Em.K);
+      c.reopen({content: {}});
+    });
+    afterEach(function () {
+      App.ajax.send.restore();
+      c.togglePreviousSteps.restore();
+      c.saveClusterStatus.restore();
+    });
+    it('should set numPolls to 6 in testMode', function () {
+      App.set('testMode', true);
+      c.set('numPolls', 0);
+      c.launchStartServices();
+      expect(c.get('numPolls')).to.equal(6);
+      App.set('testMode', false);
+    });
+    Em.A([
+        {
+          controllerName: 'installerController',
+          clusterName: 'c1',
+          e: {
+            name: 'wizard.step9.installer.launch_start_services'
+          }
+        },
+        {
+          controllerName: 'addHostController',
+          clusterName: 'c1',
+          wizardController: Em.Object.create({
+            getDBProperty: function () {
+              return {h1: '', h2: ''};
+            }
+          }),
+          e: {
+            name: 'wizard.step9.add_host.launch_start_services',
+            data: 'host_name.in(h1,h2)'
+          }
+        }
+      ]).forEach(function (test) {
+        it(test.controllerName, function () {
+          c.reopen({content: {controllerName: test.controllerName, cluster: 
{name: test.clusterName}}});
+          if (test.wizardController) {
+            c.reopen({wizardController: test.wizardController});
+          }
+          c.launchStartServices();
+          var r = App.ajax.send.args[0][0];
+          expect(r.data.cluster).to.equal(test.clusterName);
+          expect(r.name).to.equal(test.e.name);
+          if (test.e.data) {
+            expect(r.data.data.contains(test.e.data)).to.equal(true);
+          }
+        });
+      });
+  });
+
+  describe('#isServicesStarted', function () {
+    beforeEach(function () {
+      sinon.stub(c, 'saveClusterStatus', Em.K);
+      sinon.stub(c, 'saveInstalledHosts', Em.K);
+    });
+    afterEach(function () {
+      c.saveClusterStatus.restore();
+      c.saveInstalledHosts.restore();
+    });
+    Em.A([
+        {
+          polledData: [
+            {Tasks: {status: 'PENDING'}}
+          ],
+          m: 'PENDING',
+          e: false
+        },
+        {
+          polledData: [
+            {Tasks: {status: 'QUEUED'}}
+          ],
+          m: 'QUEUED',
+          e: false
+        },
+        {
+          polledData: [
+            {Tasks: {status: 'IN_PROGRESS'}}
+          ],
+          m: 'IN_PROGRESS',
+          e: false
+        }
+      ]).forEach(function (test) {
+        it(test.m, function () {
+          var r = c.isServicesStarted(test.polledData);
+          expect(r).to.equal(test.e);
+        });
+      });
+    Em.A([
+        {
+          polledData: [
+            {Tasks: {status: 'SUCCESS'}}
+          ],
+          m: 'tasks ok, isSuccess true',
+          isSuccess: true,
+          e: {
+            status: 'STARTED',
+            hasInstallTime: true
+          }
+        },
+        {
+          polledData: [
+            {Tasks: {status: 'SUCCESS'}}
+          ],
+          m: 'tasks ok, isSuccess false',
+          isSuccess: false,
+          e: {
+            status: 'START FAILED',
+            hasInstallTime: false
+          }
+        }
+      ]).forEach(function (test) {
+        it(test.m, function () {
+          sinon.stub(c, 'isSuccess', function () {
+            return test.isSuccess;
+          });
+          c.reopen({content: {cluster: {requestId: 2}}});
+          var r = c.isServicesStarted(test.polledData);
+          var args = c.saveClusterStatus.args[0][0];
+          expect(r).to.equal(true);
+          expect(c.get('progress')).to.equal('100');
+          expect(args.status).to.equal(test.e.status);
+          expect(args.requestId).to.equal(2);
+          
expect(args.hasOwnProperty('installTime')).to.equal(test.e.hasInstallTime);
+          expect(args.isCompleted).to.equal(true);
+          expect(c.saveInstalledHosts.calledOnce).to.equal(true);
+          c.isSuccess.restore();
+        });
+      });
+  });
+
+  describe('#launchStartServicesSuccessCallback', function () {
+    beforeEach(function () {
+      sinon.stub(c, 'saveClusterStatus', Em.K);
+      sinon.stub(c, 'doPolling', Em.K);
+      sinon.stub(c, 'hostHasClientsOnly', Em.K);
+    });
+    afterEach(function () {
+      c.saveClusterStatus.restore();
+      c.doPolling.restore();
+      c.hostHasClientsOnly.restore();
+    });
+    it('should call doPolling if some data were received', function () {
+      c.launchStartServicesSuccessCallback({Requests: {id: 2}});
+      expect(c.doPolling.calledOnce).to.equal(true);
+    });
+    Em.A([
+        {
+          jsonData: {Requests: {id: 2}},
+          e: {
+            hostHasClientsOnly: false,
+            clusterStatus: {
+              status: 'INSTALLED',
+              requestId: 2,
+              isStartError: false,
+              isCompleted: false
+            }
+          }
+        },
+        {
+          jsonData: null,
+          e: {
+            hostHasClientsOnly: true,
+            clusterStatus: {
+              status: 'STARTED',
+              isStartError: false,
+              isCompleted: true
+            },
+            status: 'success',
+            progress: '100'
+          }
+        }
+      ]).forEach(function (test) {
+        it(test.m, function () {
+          c.launchStartServicesSuccessCallback(test.jsonData);
+          
expect(c.hostHasClientsOnly.calledWith(test.e.hostHasClientsOnly)).to.equal(true);
+          
expect(c.saveClusterStatus.calledWith(test.e.clusterStatus)).to.equal(true);
+          if (test.e.status) {
+            expect(c.get('status')).to.equal(test.e.status);
+          }
+          if (test.e.progress) {
+            expect(c.get('progress')).to.equal(test.e.progress);
+          }
+        });
+      });
+  });
+
+  describe('#getLogsByRequestSuccessCallback', function () {
+    beforeEach(function () {
+      sinon.stub(c, 'isAllComponentsInstalled', Em.K);
+      sinon.stub(window, 'setTimeout', Em.K);
+    });
+    afterEach(function () {
+      c.isAllComponentsInstalled.restore();
+      window.setTimeout.restore();
+    });
+    Em.A([
+        {
+          polling: false,
+          status: 'INSTALL FAILED',
+          m: 'should call isAllComponentsInstalled',
+          e: true
+        },
+        {
+          polling: false,
+          status: 'INSTALLED',
+          m: 'shouldn\'t call isAllComponentsInstalled',
+          e: false
+        },
+        {
+          polling: true,
+          status: 'INSTALL FAILED',
+          m: 'shouldn\'t call isAllComponentsInstalled (2)',
+          e: false
+        },
+        {
+          polling: true,
+          status: 'INSTALLED',
+          m: 'shouldn\'t call isAllComponentsInstalled (3)',
+          e: false
+        }
+      ]).forEach(function (test) {
+        it(test.m, function () {
+          sinon.stub(c, 'parseHostInfo', Em.K);
+          c.reopen({content: {cluster: {status: test.status}}});
+          c.getLogsByRequestSuccessCallback({}, {}, {polling: test.polling});
+          if (test.e) {
+            expect(c.isAllComponentsInstalled.calledOnce).to.equal(true);
+          }
+          else {
+            expect(c.isAllComponentsInstalled.called).to.equal(false);
+          }
+          c.parseHostInfo.restore();
+        });
+      });
+  });
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/b96edcf9/ambari-web/test/views/wizard/step9/hostLogPopupBody_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/wizard/step9/hostLogPopupBody_view_test.js 
b/ambari-web/test/views/wizard/step9/hostLogPopupBody_view_test.js
new file mode 100644
index 0000000..918d3d9
--- /dev/null
+++ b/ambari-web/test/views/wizard/step9/hostLogPopupBody_view_test.js
@@ -0,0 +1,145 @@
+/**
+ * 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/wizard/step9/hostLogPopupBody_view');
+var view;
+
+describe('App.WizardStep9HostLogPopupBodyView', function() {
+
+  beforeEach(function() {
+    view = App.WizardStep9HostLogPopupBodyView.create({
+      parentView: Em.Object.create({
+        host: Em.Object.create()
+      })
+    });
+  });
+
+  describe('#isHeartbeatLost', function() {
+    it('should depends on parentView.host.status', function() {
+      view.set('parentView.host.status', 'success');
+      expect(view.get('isHeartbeatLost')).to.equal(false);
+      view.set('parentView.host.status', 'heartbeat_lost');
+      expect(view.get('isHeartbeatLost')).to.equal(true);
+    });
+  });
+
+  describe('#isNoTasksScheduled', function() {
+    it('should be same to parentView.host.isNoTasksForInstall', function() {
+      view.set('parentView.host.isNoTasksForInstall', true);
+      expect(view.get('isNoTasksScheduled')).to.equal(true);
+      view.set('parentView.host.isNoTasksForInstall', false);
+      expect(view.get('isNoTasksScheduled')).to.equal(false);
+    });
+  });
+
+  describe('#visibleTasks', function() {
+    Em.A([
+        {
+          value: 'pending',
+          f: ['pending', 'queued']
+        },
+        {
+          value: 'in_progress',
+          f: ['in_progress']
+        },
+        {
+          value: 'failed',
+          f: ['failed']
+        },
+        {
+          value: 'completed',
+          f: ['completed']
+        },
+        {
+          value: 'aborted',
+          f: ['aborted']
+        },
+        {
+          value: 'timedout',
+          f: ['timedout']
+        },
+        {
+          value: 'all'
+        }
+      ]).forEach(function(test) {
+        it(test.value, function() {
+          view.reopen({
+            category: Em.Object.create({value: test.value}),
+            tasks: Em.A([
+              {status: 'pending', isVisible: false},
+              {status: 'queued', isVisible: false},
+              {status: 'in_progress', isVisible: false},
+              {status: 'failed', isVisible: false},
+              {status: 'completed', isVisible: false},
+              {status: 'aborted', isVisible: false},
+              {status: 'timedout', isVisible: false}
+            ])
+          });
+          view.visibleTasks();
+          var visibleTasks = view.get('tasks').filter(function(task) {
+            if (test.f) {
+              return test.f.contains(task.status);
+            }
+            return true;
+          });
+          expect(visibleTasks.everyProperty('isVisible', true)).to.equal(true);
+        });
+    });
+  });
+
+  describe('#backToTaskList', function() {
+    it('should call destroyClipBoard', function() {
+      sinon.stub(view, 'destroyClipBoard', Em.K);
+      view.backToTaskList();
+      expect(view.destroyClipBoard.calledOnce).to.equal(true);
+      view.destroyClipBoard.restore();
+    });
+    it('should set isLogWrapHidden to true', function() {
+      view.set('isLogWrapHidden', false);
+      view.backToTaskList();
+      expect(view.get('isLogWrapHidden')).to.equal(true);
+    });
+  });
+
+  describe('#getStartedTasks', function() {
+    it('should return tasks with some status', function() {
+      var logTasks = Em.A([
+        {Tasks: {}}, {Tasks: {status: 's'}}, {Tasks: {status: null}}, {Tasks: 
{status: 'v'}}
+      ]);
+      expect(view.getStartedTasks({logTasks: logTasks}).length).to.equal(2);
+    });
+  });
+
+  describe('#openedTask', function() {
+    it('should return currently open task', function() {
+      var task = Em.Object.create({id: 2});
+      view.reopen({
+        tasks: Em.A([
+          Em.Object.create({id: 1}),
+          Em.Object.create({id: 3}),
+          task,
+          Em.Object.create({id: 4})
+        ])
+      });
+      view.set('parentView.c', {currentOpenTaskId: 2});
+      expect(view.get('openedTask.id')).to.equal(2);
+    });
+  });
+
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/b96edcf9/ambari-web/test/views/wizard/step9_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/wizard/step9_view_test.js 
b/ambari-web/test/views/wizard/step9_view_test.js
index 9b98019..733c3f9 100644
--- a/ambari-web/test/views/wizard/step9_view_test.js
+++ b/ambari-web/test/views/wizard/step9_view_test.js
@@ -19,10 +19,16 @@
 var App = require('app');
 require('views/wizard/step9_view');
 
-
+var v;
 describe('App.WizardStep9View', function () {
+  beforeEach(function () {
+    v = App.WizardStep9View.create({
+      controller: App.WizardStep9Controller.create()
+    });
+  });
   var view = App.WizardStep9View.create({
-    onStatus: function () {},
+    onStatus: function () {
+    },
     content: [],
     pageContent: function () {
       return this.get('content');
@@ -186,7 +192,7 @@ describe('App.WizardStep9View', function () {
     }
   ];
 
-  describe('countCategoryHosts', function () {
+  describe('#countCategoryHosts', function () {
     testCases.forEach(function (test) {
       it(test.title, function () {
         view.set('content', test.content);
@@ -198,7 +204,7 @@ describe('App.WizardStep9View', function () {
     }, this);
   });
 
-  describe('filter', function () {
+  describe('#filter', function () {
     testCases.forEach(function (test) {
       describe(test.title, function () {
         view.get('categories').forEach(function (category) {
@@ -212,9 +218,219 @@ describe('App.WizardStep9View', function () {
       });
     }, this);
   });
+
+  describe('#isStepCompleted', function () {
+    it('should be true if progress is 100', function () {
+      v.set('controller.progress', '100');
+      expect(v.get('isStepCompleted')).to.equal(true);
+    });
+    it('should be false if progress isn\'t 100', function () {
+      v.set('controller.progress', '50');
+      expect(v.get('isStepCompleted')).to.equal(false);
+    });
+  });
+
+  describe('#content', function () {
+    it('should be equal to controller.hosts', function () {
+      sinon.stub(v, 'hostStatusObserver', Em.K);
+      var hosts = [
+        {},
+        {},
+        {}
+      ];
+      v.set('controller.hosts', hosts);
+      expect(v.get('content')).to.eql(hosts);
+      v.hostStatusObserver.restore();
+    });
+  });
+
+  describe('#categoryObject', function () {
+    it('label should contains value and hostsCount', function () {
+      var value = 'v',
+        hostsCount = 10,
+        o = v.get('categoryObject').create({value: value, hostsCount: 
hostsCount});
+      expect(o.get('label')).to.equal(value + ' (' + hostsCount + ')');
+    });
+    it('itemClass should depends on isActive', function () {
+      var o = v.get('categoryObject').create();
+      o.set('isActive', false);
+      expect(o.get('itemClass')).to.equal('');
+      o.set('isActive', true);
+      expect(o.get('itemClass')).to.equal('active');
+    });
+  });
+
+  describe('#isHostHeartbeatLost', function () {
+    Em.A([
+        {
+          hostsWithHeartbeatLost: [],
+          m: 'should be false if hostsWithHeartbeatLost is empty',
+          e: false
+        },
+        {
+          hostsWithHeartbeatLost: [
+            {},
+            {}
+          ],
+          m: 'should be true if hostsWithHeartbeatLost contains some values',
+          e: true
+        }
+      ]).forEach(function (test) {
+        it(test.m, function () {
+          v.set('controller.hostsWithHeartbeatLost', 
test.hostsWithHeartbeatLost);
+          expect(v.get('isHostHeartbeatLost')).to.equal(test.e);
+        })
+      });
+  });
+
+  describe('#barWidth', function () {
+    it('should depends on controller.progress', function () {
+      var w = '25';
+      v.set('controller.progress', w);
+      expect(v.get('barWidth')).to.equal('width: ' + w + '%;');
+    });
+  });
+
+  describe('#progressMessage', function () {
+    it('should depends on controller.progress', function () {
+      var w = '25';
+      v.set('controller.progress', w);
+      expect(v.get('progressMessage').contains(w)).to.equal(true);
+    });
+  });
+
+  describe('#showAllHosts', function () {
+    it('should set active to category with all hosts', function () {
+      v.get('categories').findProperty('hostStatus', 
'inProgress').set('isActive', true);
+      v.showAllHosts();
+      var allCategory = v.get('categories').findProperty('hostStatus', 'all');
+      expect(allCategory.get('isActive')).to.equal(true);
+      
expect(v.get('categories').without(allCategory).everyProperty('isActive', 
false)).to.equal(true);
+    });
+  });
+
+  describe('#didInsertElement', function () {
+    beforeEach(function () {
+      sinon.stub(v, 'onStatus', Em.K);
+      sinon.stub(v.get('controller'), 'navigateStep', Em.K);
+    });
+    afterEach(function () {
+      v.onStatus.restore();
+      v.get('controller').navigateStep.restore();
+    });
+    it('should call onStatus', function () {
+      v.didInsertElement();
+      expect(v.onStatus.calledOnce).to.equal(true);
+    });
+    it('should call navigateStep', function () {
+      v.didInsertElement();
+      expect(v.get('controller').navigateStep.calledOnce).to.equal(true);
+    });
+  });
+
+  describe('#selectCategory', function () {
+    it('should set isActive true to selected category', function () {
+      var event = {context: Em.Object.create({hostStatus: 'inProgress'})},
+        c = v.get('categories').findProperty('hostStatus', 'inProgress');
+      c.set('isActive', false);
+      v.selectCategory(event);
+      expect(c.get('isActive')).to.equal(true);
+    });
+  });
+
+  describe('#onStatus', function () {
+    Em.A([
+        {
+          status: 'success',
+          e: {
+            barColor: 'progress-success',
+            resultMsg: Em.I18n.t('installer.step9.status.success'),
+            resultMsgColor: 'alert-success'
+          }
+        },
+        {
+          status: 'info',
+          e: {
+            barColor: 'progress-info',
+            resultMsg: ''
+          }
+        },
+        {
+          status: 'warning',
+          e: {
+            barColor: 'progress-warning',
+            resultMsg: Em.I18n.t('installer.step9.status.warning'),
+            resultMsgColor: 'alert-warning'
+          }
+        },
+        {
+          status: 'failed',
+          e: {
+            barColor: 'progress-danger',
+            resultMsgColor: 'alert-error'
+          }
+        }
+      ]).forEach(function (test) {
+        it(test.status, function () {
+          v.set('controller.status', test.status);
+          v.onStatus();
+          Em.keys(test.e).forEach(function (k) {
+            expect(v.get(k)).to.equal(test.e[k]);
+          });
+        });
+      });
+    Em.A([
+        {
+          hostsWithHeartbeatLost: [
+            {},
+            {}
+          ],
+          startCallFailed: false,
+          m: 'heartbeat lost for 2 hosts',
+          resultMsg: 
Em.I18n.t('installer.step9.status.hosts.heartbeat_lost').format(2)
+        },
+        {
+          hostsWithHeartbeatLost: [],
+          startCallFailed: true,
+          m: 'heartbeat not lost, startCallFailed true',
+          resultMsg: Em.I18n.t('installer.step9.status.start.services.failed')
+        },
+        {
+          hostsWithHeartbeatLost: [],
+          startCallFailed: false,
+          m: 'heartbeat not lost, startCallFailed false',
+          resultMsg: Em.I18n.t('installer.step9.status.failed')
+        }
+      ]).forEach(function (test) {
+        it(test.m, function () {
+          v.set('controller.hostsWithHeartbeatLost', 
test.hostsWithHeartbeatLost);
+          v.set('controller.startCallFailed', test.startCallFailed);
+          v.set('controller.status', 'failed');
+          v.onStatus();
+          expect(v.get('resultMsg')).to.equal(test.resultMsg);
+        });
+      });
+  });
+
+  describe('#hostWithInstallFailed', function () {
+    it('popup property failedHosts should be equal to hostsWithHeartbeatLost', 
function () {
+      var hostsWithHeartbeatLost = [
+        {},
+        {}
+      ];
+      v.set('controller.hostsWithHeartbeatLost', hostsWithHeartbeatLost);
+      var body = v.hostWithInstallFailed().get('bodyClass').create();
+      expect(body.get('failedHosts')).to.eql(hostsWithHeartbeatLost);
+    });
+  });
+
 });
 
+var hv;
 describe('App.HostStatusView', function () {
+  beforeEach(function () {
+    hv = App.HostStatusView.create();
+  });
   var tests = [
     {
       p: 'isFailed',
@@ -316,15 +532,170 @@ describe('App.HostStatusView', function () {
       ]
     }
   ];
-  tests.forEach(function(test) {
-    describe(test.p, function() {
-      test.tests.forEach(function(t) {
+  tests.forEach(function (test) {
+    describe(test.p, function () {
+      test.tests.forEach(function (t) {
         var hostStatusView = App.HostStatusView.create();
-        it('obj.progress = ' + t.obj.progress + '; obj.status = ' + 
t.obj.status, function() {
+        it('obj.progress = ' + t.obj.progress + '; obj.status = ' + 
t.obj.status, function () {
           hostStatusView.set('obj', t.obj);
           expect(hostStatusView.get(test.p)).to.equal(t.e);
         });
       });
     });
   });
+
+  describe('#barWidth', function () {
+    it('should depends of obj.progress', function () {
+      hv.set('obj', {progress: '25'});
+      expect(hv.get('barWidth')).to.equal('width: 25%;');
+    });
+  });
+
+  describe('#didInsertElement', function () {
+    it('should call onStatus', function () {
+      sinon.stub(hv, 'onStatus', Em.K);
+      hv.didInsertElement();
+      expect(hv.onStatus.calledOnce).to.equal(true);
+      hv.onStatus.restore();
+    });
+  });
+
+  describe('#onStatus', function () {
+    Em.A([
+        {
+          obj: {
+            status: 'info'
+          },
+          e: {
+            barColor: 'progress-info'
+          }
+        },
+        {
+          obj: {
+            status: 'warning'
+          },
+          e: {
+            barColor: 'progress-warning'
+          }
+        },
+        {
+          obj: {
+            status: 'warning',
+            progress: '100'
+          },
+          e: {
+            barColor: 'progress-warning',
+            'obj.message': Em.I18n.t('installer.step9.host.status.warning')
+          }
+        },
+        {
+          obj: {
+            status: 'failed'
+          },
+          e: {
+            barColor: 'progress-danger'
+          }
+        },
+        {
+          obj: {
+            status: 'failed',
+            progress: '100'
+          },
+          e: {
+            barColor: 'progress-danger',
+            'obj.message': Em.I18n.t('installer.step9.host.status.failed')
+          }
+        },
+        {
+          obj: {
+            status: 'heartbeat_lost'
+          },
+          e: {
+            barColor: 'progress-danger'
+          }
+        },
+        {
+          obj: {
+            status: 'heartbeat_lost',
+            progress: '100'
+          },
+          e: {
+            barColor: 'progress-danger',
+            'obj.message': Em.I18n.t('installer.step9.host.heartbeat_lost')
+          }
+        }
+      ]).forEach(function (test) {
+        it(JSON.stringify(test.obj), function () {
+          hv.set('obj', test.obj);
+          hv.onStatus();
+          Em.keys(test.e).forEach(function (k) {
+            expect(hv.get(k)).to.equal(test.e[k]);
+          });
+        });
+      });
+    Em.A([
+        {
+          obj: {
+            status: 'success',
+            progress: '100'
+          },
+          progress: '35',
+          e: true
+        },
+        {
+          obj: {
+            status: 'success',
+            progress: '100'
+          },
+          progress: '34',
+          e: false
+        },
+        {
+          obj: {
+            status: 'success',
+            progress: '99'
+          },
+          progress: '35',
+          e: false
+        },
+        {
+          obj: {
+            status: 'failed',
+            progress: '100'
+          },
+          progress: '35',
+          e: false
+        }
+      ]).forEach(function (test) {
+        it(JSON.stringify(test.obj) + ' ' + test.progress, function() {
+          hv.set('barColor', '');
+          hv.set('obj', test.obj);
+          hv.set('obj.message', '');
+          hv.set('controller', {progress: test.progress});
+          hv.onStatus();
+          expect(hv.get('obj.message') === 
Em.I18n.t('installer.step9.host.status.success')).to.equal(test.e);
+          expect(hv.get('barColor') === 'progress-success').to.equal(test.e);
+        });
+      });
+  });
+
+  describe('#hostLogPopup', function() {
+    describe('#onClose', function() {
+      beforeEach(function() {
+        hv.set('controller', {currentOpenTaskId: 123});
+        hv.set('obj', Em.Object.create());
+      });
+      it('popup should clear currentOpenTaskId', function() {
+        hv.hostLogPopup().onClose();
+        expect(hv.get('controller.currentOpenTaskId')).to.equal(0);
+      });
+      it('onClose popup should hide popup', function() {
+        var p = hv.hostLogPopup();
+        sinon.spy(p, 'hide');
+        p.onClose();
+        expect(p.hide.calledOnce).to.equal(true);
+      });
+    });
+  });
+
 });

Reply via email to