Browse Source

AMBARI-14515. Improve Ambari UI UT (p.3) (onechiporenko)

Oleg Nechiporenko 9 years ago
parent
commit
a487e5018d
31 changed files with 2202 additions and 1023 deletions
  1. 40 7
      ambari-web/test/app_test.js
  2. 114 46
      ambari-web/test/controllers/global/cluster_controller_test.js
  3. 7 6
      ambari-web/test/controllers/global/update_controller_test.js
  4. 157 51
      ambari-web/test/controllers/installer_test.js
  5. 84 27
      ambari-web/test/controllers/main/admin/highAvailability/progress_popup_controller_test.js
  6. 31 7
      ambari-web/test/controllers/main/admin/highAvailability/resourceManager/step3_controller_test.js
  7. 105 61
      ambari-web/test/controllers/main/admin/highAvailability_controller_test.js
  8. 20 10
      ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js
  9. 17 6
      ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
  10. 15 7
      ambari-web/test/controllers/main/admin/kerberos/step6_controller_test.js
  11. 69 33
      ambari-web/test/controllers/main/admin/kerberos_test.js
  12. 275 115
      ambari-web/test/controllers/main/admin/stack_and_upgrade_controller_test.js
  13. 47 16
      ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js
  14. 20 11
      ambari-web/test/controllers/main/alerts/manage_alert_notifications_controller_test.js
  15. 79 30
      ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_test.js
  16. 10 12
      ambari-web/test/controllers/main/charts/heatmap_test.js
  17. 5 15
      ambari-web/test/controllers/main/dashboard/config_history_controller_test.js
  18. 11 5
      ambari-web/test/controllers/main/host/configs_service_test.js
  19. 405 251
      ambari-web/test/controllers/main/host/details_test.js
  20. 79 30
      ambari-web/test/controllers/main/service/add_controller_test.js
  21. 65 29
      ambari-web/test/controllers/main/service/info/config_test.js
  22. 95 46
      ambari-web/test/controllers/main/service/item_test.js
  23. 103 34
      ambari-web/test/controllers/main/service/manage_config_groups_controller_test.js
  24. 7 21
      ambari-web/test/controllers/main/service/reassign/step1_controller_test.js
  25. 23 9
      ambari-web/test/controllers/main/service/reassign/step4_controller_test.js
  26. 14 2
      ambari-web/test/controllers/main/service/reassign_controller_test.js
  27. 216 86
      ambari-web/test/controllers/main/service/widgets/create/step2_controller_test.js
  28. 49 29
      ambari-web/test/controllers/main/service_test.js
  29. 3 2
      ambari-web/test/controllers/main/views_controller_test.js
  30. 13 5
      ambari-web/test/controllers/main_test.js
  31. 24 14
      ambari-web/test/router_test.js

+ 40 - 7
ambari-web/test/app_test.js

@@ -103,12 +103,22 @@ describe('App', function () {
     ];
 
     testCases.forEach(function (test) {
-      it(test.title, function () {
-        sinon.stub(App.Service, 'find', function () {
-          return test.service;
+      describe(test.title, function () {
+
+        beforeEach(function () {
+          sinon.stub(App.Service, 'find', function () {
+            return test.service;
+          });
+        });
+
+        afterEach(function () {
+          App.Service.find.restore();
         });
-        expect(App.get('falconServerURL')).to.equal(test.result);
-        App.Service.find.restore();
+
+        it('App.falconServerURL is ' + test.result, function () {
+          expect(App.get('falconServerURL')).to.equal(test.result);
+        });
+
       });
     });
   });
@@ -219,19 +229,42 @@ describe('App', function () {
       })
     ];
 
-    it('distribute services by categories', function () {
+    beforeEach(function () {
       sinon.stub(App.StackService, 'find', function () {
         return stackServices;
       });
+    });
+
+    afterEach(function () {
+      App.StackService.find.restore();
+    });
 
+    it('App.services.all', function () {
       expect(App.get('services.all')).to.eql(['S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7']);
+    });
+
+    it('App.services.clientOnly', function () {
       expect(App.get('services.clientOnly')).to.eql(['S1']);
+    });
+
+    it('App.services.hasClient', function () {
       expect(App.get('services.hasClient')).to.eql(['S2']);
+    });
+
+    it('App.services.hasMaster', function () {
       expect(App.get('services.hasMaster')).to.eql(['S3']);
+    });
+
+    it('App.services.hasSlave', function () {
       expect(App.get('services.hasSlave')).to.eql(['S4']);
+    });
+
+    it('App.services.noConfigTypes', function () {
       expect(App.get('services.noConfigTypes')).to.eql(['S5']);
+    });
+
+    it('App.services.monitoring', function () {
       expect(App.get('services.monitoring')).to.eql(['S6']);
-      App.StackService.find.restore();
     });
   });
 

+ 114 - 46
ambari-web/test/controllers/global/cluster_controller_test.js

@@ -202,6 +202,7 @@ describe('App.clusterController', function () {
   });
 
   describe("#createKerberosAdminSession()", function() {
+
     beforeEach(function () {
       sinon.stub(App.ajax, 'send', function() {
         return {success: Em.K}
@@ -209,21 +210,24 @@ describe('App.clusterController', function () {
       sinon.stub(credentialUtils, 'createOrUpdateCredentials', function() {
         return $.Deferred().resolve().promise();
       });
+      this.stub = sinon.stub(App, 'get');
+      this.stub.withArgs('clusterName').returns('test');
     });
+
     afterEach(function () {
       App.ajax.send.restore();
       credentialUtils.createOrUpdateCredentials.restore();
+      App.get.restore();
     });
+
     it("KDC Store supports disabled, credentials updated via kdc session call", function() {
-      sinon.stub(App, 'get')
-        .withArgs('supports.storeKDCCredentials').returns(false)
-        .withArgs('clusterName').returns('test');
+      this.stub.withArgs('supports.storeKDCCredentials').returns(false);
       controller.createKerberosAdminSession({
         principal: 'admin',
         key: 'pass',
         type: 'persistent'
       }, {});
-      App.get.restore();
+
       expect(App.ajax.send.getCall(0).args[0]).to.eql({
         name: 'common.cluster.update',
         sender: controller,
@@ -238,15 +242,12 @@ describe('App.clusterController', function () {
       });
     });
     it("KDC Store supports enabled, credentials updated via credentials storage call", function() {
-      sinon.stub(App, 'get')
-        .withArgs('supports.storeKDCCredentials').returns(true)
-        .withArgs('clusterName').returns('test');
+      this.stub.withArgs('supports.storeKDCCredentials').returns(true);
       controller.createKerberosAdminSession({
         principal: 'admin',
         key: 'pass',
         type: 'persistent'
       }, {});
-      App.get.restore();
       expect(App.ajax.send.called).to.be.eql(false);
       expect(credentialUtils.createOrUpdateCredentials.getCall(0).args).to.eql([
         'test', 'kdc.admin.credential', {
@@ -292,20 +293,36 @@ describe('App.clusterController', function () {
       App.get.restore();
     });
 
-    it('should check detailed repo version for HDP 2.2', function () {
-      sinon.stub(App, 'get').withArgs('currentStackName').returns('HDP').withArgs('currentStackVersionNumber').returns('2.2');
-      controller.checkDetailedRepoVersion();
-      expect(App.ajax.send.calledOnce).to.be.true;
+    describe('should check detailed repo version for HDP 2.2', function () {
+
+      beforeEach(function () {
+        sinon.stub(App, 'get').withArgs('currentStackName').returns('HDP').withArgs('currentStackVersionNumber').returns('2.2');
+      });
+
+      it('request is sent', function () {
+        controller.checkDetailedRepoVersion();
+        expect(App.ajax.send.calledOnce).to.be.true;
+      });
     });
 
     cases.forEach(function (item) {
-      it(item.title, function () {
-        sinon.stub(App, 'get', function (key) {
-          return item[key] || Em.get(App, key);
+      describe(item.title, function () {
+
+        beforeEach(function () {
+          sinon.stub(App, 'get', function (key) {
+            return item[key] || Em.get(App, key);
+          });
+          controller.checkDetailedRepoVersion();
         });
-        controller.checkDetailedRepoVersion();
-        expect(App.ajax.send.called).to.be.false;
-        expect(App.get('isStormMetricsSupported')).to.equal(item.isStormMetricsSupported);
+
+        it('request is not sent', function () {
+          expect(App.ajax.send.called).to.be.false;
+        });
+
+        it('App.isStormMetricsSupported is ' + item.isStormMetricsSupported, function () {
+          expect(App.get('isStormMetricsSupported')).to.equal(item.isStormMetricsSupported);
+        });
+
       });
     });
 
@@ -438,14 +455,18 @@ describe('App.clusterController', function () {
 
   describe("#restoreUpgradeState()", function() {
     var data = {upgradeData: {}};
-    var mock = {done: function(callback) {
-      callback(data.upgradeData);
-    }};
+    var mock = {
+      done: function (callback) {
+        callback(data.upgradeData);
+      }
+    };
     var upgradeController = Em.Object.create({
       restoreLastUpgrade: Em.K,
       initDBProperties: Em.K,
       loadUpgradeData: Em.K,
-      loadStackVersionsToModel: function(){return {done: Em.K};}
+      loadStackVersionsToModel: function () {
+        return {done: Em.K};
+      }
     });
 
     beforeEach(function () {
@@ -458,6 +479,7 @@ describe('App.clusterController', function () {
       sinon.spy(upgradeController, 'loadUpgradeData');
       sinon.spy(upgradeController, 'loadStackVersionsToModel');
     });
+
     afterEach(function () {
       mock.done.restore();
       controller.getAllUpgrades.restore();
@@ -468,31 +490,77 @@ describe('App.clusterController', function () {
       upgradeController.loadUpgradeData.restore();
       upgradeController.loadStackVersionsToModel.restore();
     });
-    it("has upgrade request", function() {
-      data.upgradeData = {items: [
-        {
-          Upgrade: {
-            request_id: 1
+
+    describe("has upgrade request", function() {
+
+      beforeEach(function () {
+        data.upgradeData = {items: [
+          {
+            Upgrade: {
+              request_id: 1
+            }
           }
-        }
-      ]};
-      controller.restoreUpgradeState();
-      expect(controller.getAllUpgrades.calledOnce).to.be.true;
-      expect(App.get('upgradeState')).to.equal('PENDING');
-      expect(upgradeController.restoreLastUpgrade.calledWith(data.upgradeData.items[0])).to.be.true;
-      expect(upgradeController.loadStackVersionsToModel.calledWith(true)).to.be.true;
-      expect(upgradeController.initDBProperties.called).to.be.false;
-      expect(upgradeController.loadUpgradeData.called).to.be.false;
-    });
-    it("does not have upgrade request", function() {
-      data.upgradeData = {items: []};
-      controller.restoreUpgradeState();
-      expect(controller.getAllUpgrades.calledOnce).to.be.true;
-      expect(App.get('upgradeState')).to.equal('PENDING');
-      expect(upgradeController.restoreLastUpgrade.called).to.be.false;
-      expect(upgradeController.loadStackVersionsToModel.calledWith(true)).to.be.true;
-      expect(upgradeController.initDBProperties.calledOnce).to.be.true;
-      expect(upgradeController.loadUpgradeData.calledWith(true)).to.be.true;
+        ]};
+        controller.restoreUpgradeState();
+      });
+
+      it('getAllUpgrades is called once', function () {
+        expect(controller.getAllUpgrades.calledOnce).to.be.true;
+      });
+
+      it('upgradeState is PENDING', function () {
+        expect(App.get('upgradeState')).to.equal('PENDING');
+      });
+
+      it('restoreLastUpgrade is called with valid arguments', function () {
+        expect(upgradeController.restoreLastUpgrade.calledWith(data.upgradeData.items[0])).to.be.true;
+      });
+
+      it('loadStackVersionsToModel is called with valid arguments', function () {
+        expect(upgradeController.loadStackVersionsToModel.calledWith(true)).to.be.true;
+      });
+
+      it('initDBProperties is not called', function () {
+        expect(upgradeController.initDBProperties.called).to.be.false;
+      });
+
+      it('loadUpgradeData is not called', function () {
+        expect(upgradeController.loadUpgradeData.called).to.be.false;
+      });
+
+    });
+
+    describe("does not have upgrade request", function() {
+
+      beforeEach(function () {
+        data.upgradeData = {items: []};
+        controller.restoreUpgradeState();
+      });
+
+      it('getAllUpgrades is called once', function () {
+        expect(controller.getAllUpgrades.calledOnce).to.be.true;
+      });
+
+      it('upgradeState is PENDING', function () {
+        expect(App.get('upgradeState')).to.equal('PENDING');
+      });
+
+      it('restoreLastUpgrade is not called', function () {
+        expect(upgradeController.restoreLastUpgrade.called).to.be.false;
+      });
+
+      it('loadStackVersionsToModel is called with valid arguments', function () {
+        expect(upgradeController.loadStackVersionsToModel.calledWith(true)).to.be.true;
+      });
+
+      it('initDBProperties is called once', function () {
+        expect(upgradeController.initDBProperties.calledOnce).to.be.true;
+      });
+
+      it('loadUpgradeData is called with valid arguments', function () {
+        expect(upgradeController.loadUpgradeData.calledWith(true)).to.be.true;
+      });
+
     });
   });
 });

+ 7 - 6
ambari-web/test/controllers/global/update_controller_test.js

@@ -34,18 +34,19 @@ describe('App.UpdateController', function () {
 
   describe('#getUrl()', function () {
 
-    it('testMode = true', function () {
-      App.set('testMode', true);
-      expect(controller.getUrl('test', '/real')).to.equal('test');
+    beforeEach(function () {
+      sinon.stub(App, 'get').withArgs('testMode').returns(false);
+    });
+
+    afterEach(function () {
+      App.get.restore();
     });
 
     it('testMode = false', function () {
-      App.set('testMode', false);
       expect(controller.getUrl('test', '/real')).to.equal('/api/v1/clusters//real');
     });
 
-    it('testMode = false', function () {
-      App.set('testMode', false);
+    it('testMode = false (2)', function () {
       controller.set('clusterName', 'mycluster');
       expect(controller.getUrl('test', '/real')).to.equal('/api/v1/clusters/mycluster/real');
     });

+ 157 - 51
ambari-web/test/controllers/installer_test.js

@@ -462,17 +462,25 @@ describe('App.InstallerController', function () {
   });
 
   describe('#loadMap', function() {
-    it ('Should load cluster', function() {
+
+    describe('Should load cluster', function() {
       var loadCluster = false;
       var checker = {
         load: function() {
           loadCluster = true;
         }
       };
-      installerController.loadMap['0'][0].callback.call(checker);
-      expect(loadCluster).to.be.true;
+
+      beforeEach(function () {
+        installerController.loadMap['0'][0].callback.call(checker);
+      });
+
+      it('cluster info is loaded', function () {
+        expect(loadCluster).to.be.true;
+      });
     });
-    it ('Should load stacks', function() {
+
+    describe('Should load stacks', function() {
       var loadStacks = false;
       var checker = {
         loadStacks: function() {
@@ -483,52 +491,84 @@ describe('App.InstallerController', function () {
           };
         }
       };
-      installerController.loadMap['1'][0].callback.call(checker);
-      expect(loadStacks).to.be.true;
+
+      beforeEach(function () {
+        installerController.loadMap['1'][0].callback.call(checker);
+      });
+
+      it('stack info is loaded', function () {
+        expect(loadStacks).to.be.true;
+      });
     });
-    it ('Should load stacks async', function() {
+
+    describe ('Should load stacks async', function() {
       var loadStacksVersions = false;
       var checker = {
         loadStacksVersions: function() {
           loadStacksVersions = true;
         }
       };
-      installerController.loadMap['1'][1].callback.call(checker, true).then(function(data){
-        expect(data).to.be.true;
+
+      it('stack versions are loaded', function () {
+        installerController.loadMap['1'][1].callback.call(checker, true).then(function(data){
+          expect(data).to.be.true;
+        });
+        expect(loadStacksVersions).to.be.false;
       });
-      expect(loadStacksVersions).to.be.false;
     });
-    it ('Should load installOptions', function() {
-      var loadStacks = false;
+
+    describe('Should load installOptions', function() {
+      var installOptions = false;
       var checker = {
         load: function() {
-          loadStacks = true;
+          installOptions = true;
         }
       };
-      installerController.loadMap['2'][0].callback.call(checker);
-      expect(loadStacks).to.be.true;
+
+      beforeEach(function () {
+        installerController.loadMap['2'][0].callback.call(checker);
+      });
+
+      it('install option are loaded', function () {
+        expect(installOptions).to.be.true;
+      });
     });
-    it ('Should load loadConfirmedHosts', function() {
+
+    describe('Should load loadConfirmedHosts', function() {
       var loadConfirmedHosts = false;
       var checker = {
         loadConfirmedHosts: function() {
           loadConfirmedHosts = true;
         }
       };
-      installerController.loadMap['3'][0].callback.call(checker);
-      expect(loadConfirmedHosts).to.be.true;
+
+      beforeEach(function () {
+        installerController.loadMap['3'][0].callback.call(checker);
+      });
+
+      it('confirmed hosts are loaded', function () {
+        expect(loadConfirmedHosts).to.be.true;
+      });
     });
-    it ('Should load loadServices', function() {
+
+    describe('Should load loadServices', function() {
       var loadServices = false;
       var checker = {
         loadServices: function() {
           loadServices = true;
         }
       };
-      installerController.loadMap['4'][0].callback.call(checker);
-      expect(loadServices).to.be.true;
+
+      beforeEach(function () {
+        installerController.loadMap['4'][0].callback.call(checker);
+      });
+
+      it('services are loaded', function () {
+        expect(loadServices).to.be.true;
+      });
     });
-    it ('Should load loadServices', function() {
+
+    describe('Should load loadServices (2)', function() {
       var setSkipSlavesStep = false;
       var loadMasterComponentHosts = false;
       var loadConfirmedHosts = false;
@@ -548,14 +588,30 @@ describe('App.InstallerController', function () {
           loadRecommendations = true;
         }
       };
-      installerController.loadMap['5'][0].callback.call(checker);
-      expect(loadConfirmedHosts).to.be.true;
-      expect(setSkipSlavesStep).to.be.true;
-      expect(loadMasterComponentHosts).to.be.true;
-      expect(loadRecommendations).to.be.true;
+
+      beforeEach(function () {
+        installerController.loadMap['5'][0].callback.call(checker);
+      });
+
+      it('confirmed hosts are loaded', function() {
+        expect(loadConfirmedHosts).to.be.true;
+      });
+
+      it('`skipSlavesStep` is loaded', function() {
+        expect(setSkipSlavesStep).to.be.true;
+      });
+
+      it('master components hosts are loaded', function() {
+        expect(loadMasterComponentHosts).to.be.true;
+      });
+
+      it('recommendations are loaded', function() {
+        expect(loadRecommendations).to.be.true;
+      });
 
     });
-    it ('Should load serviceConfigGroups', function() {
+
+    describe ('Should load serviceConfigGroups', function() {
       var loadServiceConfigGroups = false;
       var loadServiceConfigProperties = false;
       var loadCurrentHostGroups = false;
@@ -579,14 +635,34 @@ describe('App.InstallerController', function () {
           loadConfigThemes = true;
         }
       };
-      installerController.loadMap['7'][0].callback.call(checker);
-      expect(loadServiceConfigGroups).to.be.true;
-      expect(loadServiceConfigProperties).to.be.true;
-      expect(loadCurrentHostGroups).to.be.true;
-      expect(loadRecommendationsConfigs).to.be.true;
-      expect(loadConfigThemes).to.be.true;
+
+      beforeEach(function () {
+        installerController.loadMap['7'][0].callback.call(checker);
+      });
+
+      it('config groups are loaded', function () {
+        expect(loadServiceConfigGroups).to.be.true;
+      });
+
+      it('config properties are loaded', function () {
+        expect(loadServiceConfigProperties).to.be.true;
+      });
+
+      it('current host groups are loaded', function () {
+        expect(loadCurrentHostGroups).to.be.true;
+      });
+
+      it('recommendations are loaded', function () {
+        expect(loadRecommendationsConfigs).to.be.true;
+      });
+
+      it('config themes are loaded', function () {
+        expect(loadConfigThemes).to.be.true;
+      });
+
     });
-    it ('Should load clients', function() {
+
+    describe('Should load clients', function() {
       var loadSlaveComponentHosts = false;
       var loadClients = false;
       var loadRecommendations = false;
@@ -602,11 +678,25 @@ describe('App.InstallerController', function () {
           loadRecommendations = true;
         }
       };
-      installerController.loadMap['6'][0].callback.call(checker);
-      expect(loadSlaveComponentHosts).to.be.true;
-      expect(loadClients).to.be.true;
-      expect(loadRecommendations).to.be.true;
+
+      beforeEach(function () {
+        installerController.loadMap['6'][0].callback.call(checker);
+      });
+
+      it('slave components hosts are loaded', function () {
+        expect(loadSlaveComponentHosts).to.be.true;
+      });
+
+      it('clients are loaded', function () {
+        expect(loadClients).to.be.true;
+      });
+
+      it('recommendations are loaded', function () {
+        expect(loadRecommendations).to.be.true;
+      });
+
     });
+
   });
 
   describe('#removeHosts', function() {
@@ -1121,18 +1211,34 @@ describe('App.InstallerController', function () {
     ];
 
     tests.forEach(function(test) {
-      it(test.m, function() {
-        sinon.stub(App.Stack, 'find').returns(test.stacks);
-        sinon.stub(App.router, 'get').withArgs('clusterController.isCustomJDK').returns(test.isCustomJDK)
-          .withArgs('clusterController.ambariProperties').returns(test.ambariProperties);
-        sinon.stub(App, 'showConfirmationPopup', Em.K);
-        var successCallback = sinon.spy();
-        installerController.validateJDKVersion(successCallback);
-        expect(successCallback.called).to.be.eql(test.successCallbackCalled);
-        expect(App.showConfirmationPopup.called).to.be.eql(test.popupCalled);
-        App.router.get.restore();
-        App.Stack.find.restore();
-        App.showConfirmationPopup.restore();
+
+      describe(test.m, function() {
+
+        var successCallback;
+
+        beforeEach(function ()  {
+          sinon.stub(App.Stack, 'find').returns(test.stacks);
+          sinon.stub(App.router, 'get').withArgs('clusterController.isCustomJDK').returns(test.isCustomJDK)
+            .withArgs('clusterController.ambariProperties').returns(test.ambariProperties);
+          sinon.stub(App, 'showConfirmationPopup', Em.K);
+          successCallback = sinon.spy();
+          installerController.validateJDKVersion(successCallback);
+        });
+
+        afterEach(function () {
+          App.router.get.restore();
+          App.Stack.find.restore();
+          App.showConfirmationPopup.restore();
+        });
+
+        it('successCallback is ' + (test.successCallbackCalled ? '' : 'not') + ' called', function () {
+          expect(successCallback.called).to.be.equal(test.successCallbackCalled);
+        });
+
+        it('App.showConfirmationPopup. is ' + (test.popupCalled ? '' : 'not') + ' called', function () {
+          expect(App.showConfirmationPopup.called).to.be.equal(test.popupCalled);
+        });
+
       });
     });
   });

+ 84 - 27
ambari-web/test/controllers/main/admin/highAvailability/progress_popup_controller_test.js

@@ -44,13 +44,32 @@ describe('App.HighAvailabilityProgressPopupController', function () {
       App.updater.immediateRun.restore();
     });
 
-    it('should start task polling', function () {
-      controller.startTaskPolling(1, 2);
-      expect(controller.get('isTaskPolling')).to.be.true;
-      expect(controller.get('taskInfo.id'), 2);
-      expect(controller.get('taskInfo.requestId'), 1);
-      expect(App.updater.run.calledOnce).to.be.true;
-      expect(App.updater.immediateRun.calledOnce).to.be.true;
+    describe('should start task polling', function () {
+
+      beforeEach(function () {
+        controller.startTaskPolling(1, 2);
+      });
+
+      it('isTaskPolling = true', function () {
+        expect(controller.get('isTaskPolling')).to.be.true;
+      });
+
+      it('taskInfo.id = 2', function () {
+        expect(controller.get('taskInfo.id'), 2);
+      });
+
+      it('taskInfo.requestId = 1', function () {
+        expect(controller.get('taskInfo.requestId'), 1);
+      });
+
+      it('App.updater.run is called once', function () {
+        expect(App.updater.run.calledOnce).to.be.true;
+      });
+
+      it('App.updater.immediateRun is called once', function () {
+        expect(App.updater.immediateRun.calledOnce).to.be.true;
+      });
+
     });
 
   });
@@ -125,17 +144,36 @@ describe('App.HighAvailabilityProgressPopupController', function () {
 
     cases.forEach(function (item) {
       var message = title.format(item.isTaskPolling ? '' : 'not ', item.status);
-      it(message, function () {
-        controller.updateTaskSuccessCallback({
-          Tasks: $.extend(tasks, {
-            status: item.status
-          })
+      describe(message, function () {
+
+        beforeEach(function () {
+          controller.updateTaskSuccessCallback({
+            Tasks: $.extend(tasks, {
+              status: item.status
+            })
+          });
         });
-        expect(controller.get('taskInfo.stderr')).to.equal('error');
-        expect(controller.get('taskInfo.stdout')).to.equal('output');
-        expect(controller.get('taskInfo.outputLog')).to.equal('output-log.txt');
-        expect(controller.get('taskInfo.errorLog')).to.equal('error-log.txt');
-        expect(controller.get('isTaskPolling')).to.equal(item.isTaskPolling);
+
+        it('stderr is valid', function () {
+          expect(controller.get('taskInfo.stderr')).to.equal('error');
+        });
+
+        it('stdout is valid', function () {
+          expect(controller.get('taskInfo.stdout')).to.equal('output');
+        });
+
+        it('outputLog is valid', function () {
+          expect(controller.get('taskInfo.outputLog')).to.equal('output-log.txt');
+        });
+
+        it('errorLog is valid', function () {
+          expect(controller.get('taskInfo.errorLog')).to.equal('error-log.txt');
+        });
+
+        it('isTaskPolling is valid', function () {
+          expect(controller.get('isTaskPolling')).to.equal(item.isTaskPolling);
+        });
+
       });
     });
 
@@ -171,17 +209,36 @@ describe('App.HighAvailabilityProgressPopupController', function () {
     });
 
     cases.forEach(function (item) {
-      it(item.title, function () {
-        controller.setProperties({
-          requestIds: [1, 2],
-          stageId: item.stageId
+      describe(item.title, function () {
+
+        beforeEach(function () {
+          controller.setProperties({
+            requestIds: [1, 2],
+            stageId: item.stageId
+          });
+          controller.getHosts();
+        });
+
+        it('two requests are sent', function () {
+          expect(App.ajax.send.calledTwice).to.be.true;
         });
-        controller.getHosts();
-        expect(App.ajax.send.calledTwice).to.be.true;
-        expect(App.ajax.send.firstCall.args[0].name).to.equal(item.name);
-        expect(App.ajax.send.secondCall.args[0].name).to.equal(item.name);
-        expect(App.ajax.send.firstCall.args[0].data.stageId).to.eql(item.stageIdPassed);
-        expect(App.ajax.send.secondCall.args[0].data.stageId).to.eql(item.stageIdPassed);
+
+        it('1st call name is valid', function () {
+          expect(App.ajax.send.firstCall.args[0].name).to.equal(item.name);
+        });
+
+        it('2nd call name is valid', function () {
+          expect(App.ajax.send.secondCall.args[0].name).to.equal(item.name);
+        });
+
+        it('1st stageId is valid', function () {
+          expect(App.ajax.send.firstCall.args[0].data.stageId).to.eql(item.stageIdPassed);
+        });
+
+        it('2nd stageId is valid', function () {
+          expect(App.ajax.send.secondCall.args[0].data.stageId).to.eql(item.stageIdPassed);
+        });
+
       });
     });
 

+ 31 - 7
ambari-web/test/controllers/main/admin/highAvailability/resourceManager/step3_controller_test.js

@@ -295,35 +295,59 @@ describe('App.RMHighAvailabilityWizardStep3Controller', function () {
           })
         ];
       });
+      controller.setDynamicConfigValues(configs, data);
     });
 
     afterEach(function () {
       App.HostComponent.find.restore();
     });
 
-    it('setting new RM properties values', function () {
-      controller.setDynamicConfigValues(configs, data);
+    it('yarn.resourcemanager.hostname.rm1 value', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.hostname.rm1').get('value')).to.equal('h0');
+    });
+    it('yarn.resourcemanager.hostname.rm1 recommendedValue', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.hostname.rm1').get('recommendedValue')).to.equal('h0');
+    });
+    it('yarn.resourcemanager.hostname.rm2 value', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.hostname.rm2').get('value')).to.equal('h1');
+    });
+    it('yarn.resourcemanager.hostname.rm2 recommendedValue', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.hostname.rm2').get('recommendedValue')).to.equal('h1');
-
+    });
+    it('yarn.resourcemanager.webapp.address.rm1 value', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.address.rm1').get('value')).to.equal('h0:1234');
+    });
+    it('yarn.resourcemanager.webapp.address.rm1 recommendedValue', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.address.rm1').get('recommendedValue')).to.equal('h0:1234');
+    });
+    it('yarn.resourcemanager.webapp.address.rm2 value', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.address.rm2').get('value')).to.equal('h1:1234');
+    });
+    it('yarn.resourcemanager.webapp.address.rm2 recommendedValue', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.address.rm2').get('recommendedValue')).to.equal('h1:1234');
-
+    });
+    it('yarn.resourcemanager.webapp.https.address.rm1 value', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm1').get('value')).to.equal('h0:4321');
+    });
+    it('yarn.resourcemanager.webapp.https.address.rm1 recommendedValue', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm1').get('recommendedValue')).to.equal('h0:4321');
+    });
+    it('yarn.resourcemanager.webapp.https.address.rm2 value', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm2').get('value')).to.equal('h1:4321');
+    });
+    it('yarn.resourcemanager.webapp.https.address.rm2 recommendedValue', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm2').get('recommendedValue')).to.equal('h1:4321');
-
+    });
+    it('yarn.resourcemanager.zk-address value', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.zk-address').get('value')).to.equal('h2:2222,h3:2222');
+    });
+    it('yarn.resourcemanager.zk-address recommendedValue', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.zk-address').get('recommendedValue')).to.equal('h2:2222,h3:2222');
     });
-
-    it('Setting new HAWQ RM properties values', function () {
+    it('yarn.resourcemanager.ha value', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.ha').get('value')).to.equal('h0:8032,h1:8032');
+    });
+    it('yarn.resourcemanager.ha recommendedValud', function () {
       expect(configs.configs.findProperty('name', 'yarn.resourcemanager.scheduler.ha').get('recommendedValue')).to.equal('h0:8030,h1:8030');
     });
 

+ 105 - 61
ambari-web/test/controllers/main/admin/highAvailability_controller_test.js

@@ -38,40 +38,51 @@ describe('App.MainAdminHighAvailabilityController', function () {
       });
       sinon.spy(controller, "showErrorPopup");
     });
+
     afterEach(function () {
       App.router.transitionTo.restore();
       controller.showErrorPopup.restore();
       App.HostComponent.find.restore();
+      App.router.get.restore();
     });
 
-    it('NAMENODE in INSTALLED state', function () {
-      hostComponents = [
-        Em.Object.create({
-          componentName: 'NAMENODE',
-          workStatus: 'INSTALLED'
-        }),
-        Em.Object.create({
-          componentName: 'ZOOKEEPER_SERVER',
-          workStatus: 'INSTALLED'
-        }),
-        Em.Object.create({
-          componentName: 'ZOOKEEPER_SERVER',
-          workStatus: 'INSTALLED'
-        }),
-        Em.Object.create({
-          componentName: 'ZOOKEEPER_SERVER',
-          workStatus: 'INSTALLED'
-        })
-      ];
+    describe('NAMENODE in INSTALLED state', function () {
+      beforeEach(function () {
+        hostComponents = [
+          Em.Object.create({
+            componentName: 'NAMENODE',
+            workStatus: 'INSTALLED'
+          }),
+          Em.Object.create({
+            componentName: 'ZOOKEEPER_SERVER',
+            workStatus: 'INSTALLED'
+          }),
+          Em.Object.create({
+            componentName: 'ZOOKEEPER_SERVER',
+            workStatus: 'INSTALLED'
+          }),
+          Em.Object.create({
+            componentName: 'ZOOKEEPER_SERVER',
+            workStatus: 'INSTALLED'
+          })
+        ];
+        sinon.stub(App.router, 'get', function() {
+          return 3;
+        });
+        this.result = controller.enableHighAvailability();
+      });
 
-      sinon.stub(App.router, 'get', function(){
-        return 3;
+      it('enableHighAvailability result is false', function () {
+        expect(this.result).to.be.false;
       });
-      expect(controller.enableHighAvailability()).to.be.false;
-      expect(controller.showErrorPopup.calledOnce).to.be.true;
-      App.router.get.restore();
+
+      it('showErrorPopup is called once', function () {
+        expect(controller.showErrorPopup.calledOnce).to.be.true;
+      });
+
     });
-    it('Cluster has less than 3 ZOOKEPER_SERVER components', function () {
+
+    describe('Cluster has less than 3 ZOOKEPER_SERVER components', function () {
       hostComponents = [
         Em.Object.create({
           componentName: 'NAMENODE',
@@ -79,14 +90,24 @@ describe('App.MainAdminHighAvailabilityController', function () {
         })
       ];
 
-      sinon.stub(App.router, 'get', function(){
-        return 3;
+      beforeEach(function () {
+        sinon.stub(App.router, 'get', function(){
+          return 3;
+        });
+        this.result = controller.enableHighAvailability();
       });
-      expect(controller.enableHighAvailability()).to.be.false;
-      expect(controller.showErrorPopup.called).to.be.true;
-      App.router.get.restore();
+
+      it('enableHighAvailability result is false', function () {
+        expect(this.result).to.be.false;
+      });
+
+      it('showErrorPopup is called', function () {
+        expect(controller.showErrorPopup.called).to.be.true;
+      });
+
     });
-    it('total hosts number less than 3', function () {
+
+    describe('total hosts number less than 3', function () {
       hostComponents = [
         Em.Object.create({
           componentName: 'NAMENODE',
@@ -105,39 +126,62 @@ describe('App.MainAdminHighAvailabilityController', function () {
           workStatus: 'INSTALLED'
         })
       ];
-      sinon.stub(App.router, 'get', function () {
-        return 1;
+
+      beforeEach(function () {
+        sinon.stub(App.router, 'get', function () {
+          return 1;
+        });
+        this.result = controller.enableHighAvailability();
       });
-      expect(controller.enableHighAvailability()).to.be.false;
-      expect(controller.showErrorPopup.calledOnce).to.be.true;
-      App.router.get.restore();
+
+      it('enableHighAvailability result is false', function () {
+        expect(this.result).to.be.false;
+      });
+
+      it('showErrorPopup is called once', function () {
+        expect(controller.showErrorPopup.calledOnce).to.be.true;
+      });
+
     });
-    it('All checks passed', function () {
-      hostComponents = [
-        Em.Object.create({
-          componentName: 'NAMENODE',
-          workStatus: 'STARTED'
-        }),
-        Em.Object.create({
-          componentName: 'ZOOKEEPER_SERVER',
-          workStatus: 'INSTALLED'
-        }),
-        Em.Object.create({
-          componentName: 'ZOOKEEPER_SERVER',
-          workStatus: 'INSTALLED'
-        }),
-        Em.Object.create({
-          componentName: 'ZOOKEEPER_SERVER',
-          workStatus: 'INSTALLED'
-        })
-      ];
-      sinon.stub(App.router, 'get', function(){
-        return 3;
+
+    describe('All checks passed', function () {
+      beforeEach(function () {
+        hostComponents = [
+          Em.Object.create({
+            componentName: 'NAMENODE',
+            workStatus: 'STARTED'
+          }),
+          Em.Object.create({
+            componentName: 'ZOOKEEPER_SERVER',
+            workStatus: 'INSTALLED'
+          }),
+          Em.Object.create({
+            componentName: 'ZOOKEEPER_SERVER',
+            workStatus: 'INSTALLED'
+          }),
+          Em.Object.create({
+            componentName: 'ZOOKEEPER_SERVER',
+            workStatus: 'INSTALLED'
+          })
+        ];
+        sinon.stub(App.router, 'get', function() {
+          return 3;
+        });
+        this.result = controller.enableHighAvailability();
       });
-      expect(controller.enableHighAvailability()).to.be.true;
-      expect(App.router.transitionTo.calledWith('main.services.enableHighAvailability')).to.be.true;
-      expect(controller.showErrorPopup.calledOnce).to.be.false;
-      App.router.get.restore();
+
+      it('enableHighAvailability result is true', function () {
+        expect(this.result).to.be.true;
+      });
+
+      it('user is moved to enable HA', function () {
+        expect(App.router.transitionTo.calledWith('main.services.enableHighAvailability')).to.be.true;
+      });
+
+      it('showErrorPopup is not called', function () {
+        expect(controller.showErrorPopup.calledOnce).to.be.false;
+      });
+
     });
   });
 

+ 20 - 10
ambari-web/test/controllers/main/admin/kerberos/step2_controller_test.js

@@ -79,17 +79,27 @@ describe('App.KerberosWizardStep2Controller', function() {
     ];
 
     tests.forEach(function(test) {
-      it('Should trim values for properties ' + Em.keys(test.e).join(','), function() {
-        sinon.stub(App.StackService, 'find').returns([Em.Object.create({serviceName: 'KERBEROS'})]);
-        controller.set('stepConfigs', [
-          App.ServiceConfig.create({
-            configs: test.stepConfigs.map(function(item) { return _createProperty(item[0], item[1], item[2]); })
-          })
-        ]);
-        var result = controller.createKerberosSiteObj('some-site', 'random-tag');
-        App.StackService.find.restore();
+      describe('Should trim values for properties ' + Em.keys(test.e).join(','), function() {
+        var result;
+
+        beforeEach(function () {
+          sinon.stub(App.StackService, 'find').returns([Em.Object.create({serviceName: 'KERBEROS'})]);
+          controller.set('stepConfigs', [
+            App.ServiceConfig.create({
+              configs: test.stepConfigs.map(function(item) { return _createProperty(item[0], item[1], item[2]); })
+            })
+          ]);
+          result = controller.createKerberosSiteObj('some-site', 'random-tag');
+        });
+
+        afterEach(function () {
+          App.StackService.find.restore();
+        });
+
         Em.keys(test.e).forEach(function(propertyName) {
-          expect(result.properties[propertyName]).to.be.eql(test.e[propertyName]);
+          it(propertyName, function () {
+            expect(result.properties[propertyName]).to.be.eql(test.e[propertyName]);
+          });
         });
       });
     });

+ 17 - 6
ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js

@@ -319,12 +319,23 @@ describe('App.KerberosWizardStep4Controller', function() {
       ];
 
       tests.forEach(function(test) {
-        it('Security {0} configure identities step should be {1}'.format(!!test.securityEnabled ? 'enabled' : 'disabled', !!test.stepSkipped ? 'skipped' : 'not skipped'), function() {
-          sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(test.securityEnabled);
-          this.wizardController.checkSecurityStatus();
-          App.get.restore();
-          controller.loadStep();
-          expect(App.router.send.calledWith('next')).to.be.eql(test.stepSkipped);
+        var message = 'Security {0} configure identities step should be {1}'.format(!!test.securityEnabled ? 'enabled' : 'disabled', !!test.stepSkipped ? 'skipped' : 'not skipped');
+        describe(message, function() {
+
+          beforeEach(function () {
+            sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(test.securityEnabled);
+            this.wizardController.checkSecurityStatus();
+            controller.loadStep();
+          });
+
+          afterEach(function () {
+            App.get.restore();
+          });
+
+          it('`send` is ' + (test.stepSkipped ? '' : 'not') + ' called with `next`', function () {
+            expect(App.router.send.calledWith('next')).to.be.eql(test.stepSkipped);
+          });
+
         });
       }, this);
 

+ 15 - 7
ambari-web/test/controllers/main/admin/kerberos/step6_controller_test.js

@@ -37,13 +37,21 @@ describe('App.KerberosWizardStep6Controller', function() {
     ];
 
     tests.forEach(function(test) {
-      it('YARN installed: {0}, ATS supported: {1} list of commands should be {2}'.format(test.yarnInstalled, test.doesATSSupportKerberos, test.commands.toString()), function () {
-        var controller = App.KerberosWizardStep6Controller.create({ commands: ['stopServices'] });
-        sinon.stub(App, 'get').withArgs('doesATSSupportKerberos').returns(test.doesATSSupportKerberos);
-        sinon.stub(App.Service, 'find').returns(test.yarnInstalled ? [Em.Object.create({serviceName: 'YARN'})] : []);
-        sinon.stub(App.HostComponent, 'find').returns(test.ATSInstalled ? [Em.Object.create({componentName: 'APP_TIMELINE_SERVER'})] : []);
-        controller.checkComponentsRemoval();
-        expect(controller.get('commands').toArray()).to.eql(test.commands);
+      var message = 'YARN installed: {0}, ATS supported: {1} list of commands should be {2}'.format(test.yarnInstalled, test.doesATSSupportKerberos, test.commands.toString());
+      describe(message, function () {
+        var controller;
+        beforeEach(function () {
+          controller = App.KerberosWizardStep6Controller.create({ commands: ['stopServices'] });
+          sinon.stub(App, 'get').withArgs('doesATSSupportKerberos').returns(test.doesATSSupportKerberos);
+          sinon.stub(App.Service, 'find').returns(test.yarnInstalled ? [Em.Object.create({serviceName: 'YARN'})] : []);
+          sinon.stub(App.HostComponent, 'find').returns(test.ATSInstalled ? [Em.Object.create({componentName: 'APP_TIMELINE_SERVER'})] : []);
+          controller.checkComponentsRemoval();
+        });
+
+        it('commands are valid', function () {
+          expect(controller.get('commands').toArray()).to.eql(test.commands);
+        });
+
       });
     });
   });

+ 69 - 33
ambari-web/test/controllers/main/admin/kerberos_test.js

@@ -61,20 +61,30 @@ describe('App.MainAdminKerberosController', function() {
       });
     });
 
-    it('should take displayType from predefinedSiteProperties', function () {
-      sinon.stub(App.configsCollection, 'getAll').returns([
-        {
-          name: 'hadoop.security.auth_to_local',
-          displayType: 'multiLine'
-        }
-      ]);
-      expect(controller.prepareConfigProperties([
-        Em.Object.create({
-          name: 'hadoop.security.auth_to_local',
-          serviceName: 'HDFS'
-        })
-      ])[0].get('displayType')).to.equal('multiLine');
-      App.configsCollection.getAll.restore();
+    describe('should take displayType from predefinedSiteProperties', function () {
+
+      beforeEach(function () {
+        sinon.stub(App.configsCollection, 'getAll').returns([
+          {
+            name: 'hadoop.security.auth_to_local',
+            displayType: 'multiLine'
+          }
+        ]);
+      });
+
+      afterEach(function () {
+        App.configsCollection.getAll.restore();
+      });
+
+      it('displayType is valid', function () {
+        expect(controller.prepareConfigProperties([
+          Em.Object.create({
+            name: 'hadoop.security.auth_to_local',
+            serviceName: 'HDFS'
+          })
+        ])[0].get('displayType')).to.equal('multiLine');
+      });
+
     });
   });
 
@@ -227,17 +237,31 @@ describe('App.MainAdminKerberosController', function() {
         result: true
       }
     ].forEach(function (test) {
-          it(test.m, function () {
-            sinon.stub(App, 'get').returns(test.isKerberosEnabled);
-            controller.set('securityEnabled', test.securityEnabled);
-            controller.set('kdc_type', test.kdc_type);
-            controller.getKDCSessionState(mock.callback);
+          describe(test.m, function () {
+
+            beforeEach(function () {
+              sinon.stub(App, 'get').returns(test.isKerberosEnabled);
+              controller.set('securityEnabled', test.securityEnabled);
+              controller.set('kdc_type', test.kdc_type);
+              controller.getKDCSessionState(mock.callback);
+            });
+
+
             if (test.result) {
-              expect(mock.callback.calledOnce).to.be.false;
-              expect(App.ajax.send.calledOnce).to.be.true;
-            } else {
-              expect(mock.callback.calledOnce).to.be.true;
-              expect(App.ajax.send.calledOnce).to.be.false;
+              it('callback is not called', function () {
+                expect(mock.callback.calledOnce).to.be.false;
+              });
+              it('1 request is sent', function () {
+                expect(App.ajax.send.calledOnce).to.be.true;
+              });
+            }
+            else {
+              it('callback is called once', function () {
+                expect(mock.callback.calledOnce).to.be.true;
+              });
+              it('no request is sent', function () {
+                expect(App.ajax.send.calledOnce).to.be.false;
+              });
             }
           });
         });
@@ -281,17 +305,29 @@ describe('App.MainAdminKerberosController', function() {
         result: true
       }
     ].forEach(function (test) {
-          it(test.m, function () {
-            sinon.stub(App, 'get').returns(test.isKerberosEnabled);
-            controller.set('securityEnabled', test.securityEnabled);
-            controller.set('kdc_type', test.kdc_type);
-            controller.getSecurityType(mock.callback);
+          describe(test.m, function () {
+
+            beforeEach(function () {
+              sinon.stub(App, 'get').returns(test.isKerberosEnabled);
+              controller.set('securityEnabled', test.securityEnabled);
+              controller.set('kdc_type', test.kdc_type);
+              controller.getSecurityType(mock.callback);
+            });
+
             if (test.result) {
-              expect(mock.callback.calledOnce).to.be.false;
-              expect(App.ajax.send.calledOnce).to.be.true;
+              it('callback os not called', function () {
+                expect(mock.callback.calledOnce).to.be.false;
+              });
+              it('1 request is sent', function () {
+                expect(App.ajax.send.calledOnce).to.be.true;
+              });
             } else {
-              expect(mock.callback.calledOnce).to.be.true;
-              expect(App.ajax.send.calledOnce).to.be.false;
+              it('callback is called once', function () {
+                expect(mock.callback.calledOnce).to.be.true;
+              });
+              it('no request is sent', function () {
+                expect(App.ajax.send.calledOnce).to.be.false;
+              });
             }
           });
         });

+ 275 - 115
ambari-web/test/controllers/main/admin/stack_and_upgrade_controller_test.js

@@ -523,15 +523,11 @@ describe('App.MainAdminStackAndUpgradeController', function() {
   });
 
   describe("#upgrade()", function() {
-    before(function () {
+    var callArgs;
+
+    beforeEach(function () {
       sinon.stub(App.ajax, 'send', Em.K);
       sinon.stub(controller, 'setDBProperty', Em.K);
-    });
-    after(function () {
-      App.ajax.send.restore();
-      controller.setDBProperty.restore();
-    });
-    it("make ajax call", function() {
       controller.set('currentVersion', {
         repository_version: '2.2'
       });
@@ -539,12 +535,30 @@ describe('App.MainAdminStackAndUpgradeController', function() {
         value: '2.2',
         label: 'HDP-2.2'
       });
-      var callArgs = App.ajax.send.getCall(0).args[0];
+      callArgs = App.ajax.send.getCall(0).args[0];
+    });
+
+    afterEach(function () {
+      App.ajax.send.restore();
+      controller.setDBProperty.restore();
+    });
+
+    it("request-data is valid", function() {
       expect(callArgs.data).to.eql({"value": '2.2', "label": 'HDP-2.2'});
-      expect(callArgs.name).to.eql('admin.upgrade.start');
+    });
+    it('request-name is valid', function () {
+      expect(callArgs.name).to.equal('admin.upgrade.start');
+    });
+    it('request-sender is valid', function () {
       expect(callArgs.sender).to.eql(controller);
-      expect(callArgs.success).to.eql('upgradeSuccessCallback');
+    });
+    it('callback is valid', function () {
+      expect(callArgs.success).to.equal('upgradeSuccessCallback');
+    });
+    it('callback is called', function () {
       expect(callArgs.callback).to.be.called;
+    });
+    it('setDBProperty is called with valid data', function () {
       expect(controller.setDBProperty.calledWith('currentVersion', {
         repository_version: '2.2'
       })).to.be.true;
@@ -552,19 +566,12 @@ describe('App.MainAdminStackAndUpgradeController', function() {
   });
 
   describe("#upgradeSuccessCallback()", function() {
-    before(function () {
+
+    beforeEach(function () {
       sinon.stub(App.clusterStatus, 'setClusterStatus', Em.K);
       sinon.stub(controller, 'openUpgradeDialog', Em.K);
       sinon.stub(controller, 'setDBProperties', Em.K);
       sinon.stub(controller, 'load', Em.K);
-    });
-    after(function () {
-      App.clusterStatus.setClusterStatus.restore();
-      controller.openUpgradeDialog.restore();
-      controller.setDBProperties.restore();
-      controller.load.restore();
-    });
-    it("open upgrade dialog", function() {
       var data = {
         resources: [
           {
@@ -575,11 +582,31 @@ describe('App.MainAdminStackAndUpgradeController', function() {
         ]
       };
       controller.upgradeSuccessCallback(data, {}, {label: 'HDP-2.2.1', isDowngrade: true});
+    });
+
+    afterEach(function () {
+      App.clusterStatus.setClusterStatus.restore();
+      controller.openUpgradeDialog.restore();
+      controller.setDBProperties.restore();
+      controller.load.restore();
+    });
+
+    it('load is called ocne', function() {
       expect(controller.load.calledOnce).to.be.true;
+    });
+    it('upgradeVersion is HDP-2.2.1', function() {
       expect(controller.get('upgradeVersion')).to.equal('HDP-2.2.1');
+    });
+    it('upgradeData is null', function() {
       expect(controller.get('upgradeData')).to.be.null;
+    });
+    it('isDowngrade is true', function() {
       expect(controller.get('isDowngrade')).to.be.true;
+    });
+    it('App.clusterStatus.setClusterStatus is called once', function() {
       expect(App.clusterStatus.setClusterStatus.calledOnce).to.be.true;
+    });
+    it('controller.openUpgradeDialog is called once', function() {
       expect(controller.openUpgradeDialog.calledOnce).to.be.true;
     });
   });
@@ -678,22 +705,46 @@ describe('App.MainAdminStackAndUpgradeController', function() {
         groups = controller.get('upgradeData.upgradeGroups');
       });
 
-      it("checking 1st group", function() {
-        expect(groups[0].get('status')).to.equal('COMPLETED');
-        expect(groups[0].get('progress_percent')).to.equal(100);
-        expect(groups[0].get('completed_task_count')).to.equal(3);
-        expect(groups[0].get('upgradeItems')[0].get('status')).to.equal('COMPLETED');
-        expect(groups[0].get('upgradeItems')[0].get('progress_percent')).to.equal(100);
-        expect(groups[0].get('hasExpandableItems')).to.be.true;
+      describe("checking 1st group", function() {
+        it('status is COMPLETED', function () {
+          expect(groups[0].get('status')).to.equal('COMPLETED');
+        });
+        it('progress_percent is 100', function () {
+          expect(groups[0].get('progress_percent')).to.equal(100);
+        });
+        it('completed_task_count = 3', function () {
+          expect(groups[0].get('completed_task_count')).to.equal(3);
+        });
+        it('upgradeItems.0.status is COMPLETED', function () {
+          expect(groups[0].get('upgradeItems')[0].get('status')).to.equal('COMPLETED');
+        });
+        it('upgradeItems.0.progress_percent is 100', function () {
+          expect(groups[0].get('upgradeItems')[0].get('progress_percent')).to.equal(100);
+        });
+        it('hasExpandableItems is true', function () {
+          expect(groups[0].get('hasExpandableItems')).to.be.true;
+        });
       });
 
-      it('checking 2nd group', function () {
-        expect(groups[1].get('status')).to.equal('ABORTED');
-        expect(groups[1].get('progress_percent')).to.equal(50);
-        expect(groups[1].get('completed_task_count')).to.equal(1);
-        expect(groups[1].get('upgradeItems').mapProperty('status')).to.eql(['ABORTED', 'PENDING']);
-        expect(groups[1].get('upgradeItems').mapProperty('progress_percent')).to.eql([99, 0]);
-        expect(groups[1].get('hasExpandableItems')).to.be.false;
+      describe('checking 2nd group', function () {
+        it('status is ABORTED', function () {
+          expect(groups[1].get('status')).to.equal('ABORTED');
+        });
+        it('progress_percent is 50', function () {
+          expect(groups[1].get('progress_percent')).to.equal(50);
+        });
+        it('completed_task_count = 1', function () {
+          expect(groups[1].get('completed_task_count')).to.equal(1);
+        });
+        it('upgradeItems.[].status = ["ABORTED", "PENDING"]', function () {
+          expect(groups[1].get('upgradeItems').mapProperty('status')).to.eql(['ABORTED', 'PENDING']);
+        });
+        it('upgradeItems.[].progress_percent = [99, 0]', function () {
+          expect(groups[1].get('upgradeItems').mapProperty('progress_percent')).to.eql([99, 0]);
+        });
+        it('hasExpandableItems is false', function () {
+          expect(groups[1].get('hasExpandableItems')).to.be.false;
+        });
       });
 
     });
@@ -802,14 +853,17 @@ describe('App.MainAdminStackAndUpgradeController', function() {
   });
 
   describe("#confirmDowngrade()", function() {
+
     before(function () {
       sinon.spy(App, 'showConfirmationPopup');
       sinon.stub(controller, 'downgrade', Em.K);
     });
+
     after(function () {
       App.showConfirmationPopup.restore();
       controller.downgrade.restore();
     });
+
     it("show confirmation popup", function() {
       controller.set('currentVersion', Em.Object.create({
         repository_version: '2.2',
@@ -826,8 +880,9 @@ describe('App.MainAdminStackAndUpgradeController', function() {
   });
 
   describe("#upgradeOptions()", function() {
-    before(function () {
-      sinon.spy(App, 'ModalPopup');
+    var version = Em.Object.create({displayName: 'HDP-2.2'});
+    beforeEach(function () {
+      sinon.spy(App.ModalPopup, 'show');
       sinon.spy(App, 'showConfirmationFeedBackPopup');
       sinon.stub(controller, 'getSupportedUpgradeTypes').returns({
         done: function (callback) {
@@ -846,38 +901,77 @@ describe('App.MainAdminStackAndUpgradeController', function() {
           status: 'CURRENT'
         })
       ]);
-    });
-    beforeEach(function () {
       controller.get('runningCheckRequests').clear();
     });
-    after(function () {
-      App.ModalPopup.restore();
+
+    afterEach(function () {
+      App.ModalPopup.show.restore();
       App.showConfirmationFeedBackPopup.restore();
       controller.runPreUpgradeCheck.restore();
       controller.getSupportedUpgradeTypes.restore();
       controller.get('upgradeMethods').setEach('selected', false);
       App.RepositoryVersion.find.restore();
     });
-    it("show confirmation popup", function() {
-      var version = Em.Object.create({displayName: 'HDP-2.2'});
-      controller.set('isDowngrade', false);
-      var popup = controller.upgradeOptions(false, version);
-      expect(App.ModalPopup.calledOnce).to.be.true;
-      expect(controller.get('upgradeMethods').everyProperty('isCheckRequestInProgress')).to.be.true;
-      expect(controller.get('upgradeMethods').someProperty('selected')).to.be.false;
-      controller.get('upgradeMethods')[0].set('selected', true);
-      var confirmPopup = popup.onPrimary();
-      expect(App.showConfirmationFeedBackPopup.calledOnce).to.be.true;
-      confirmPopup.onPrimary();
-      expect(controller.runPreUpgradeCheck.calledWith(version)).to.be.true;
-      expect( controller.get('runningCheckRequests')).to.have.length(1);
-    });
-    it("NOT show confirmation popup on Downgrade", function() {
-      var version = Em.Object.create({displayName: 'HDP-2.2'});
-      controller.set('isDowngrade', true);
-      controller.upgradeOptions(false, version);
-      expect(App.ModalPopup.calledOnce).to.be.false;
-      expect( controller.get('runningCheckRequests')).to.have.length(1);
+
+    describe("show confirmation popup", function() {
+
+      beforeEach(function () {
+        controller.set('isDowngrade', false);
+        this.popup = controller.upgradeOptions(false, version);
+      });
+
+      it('popup is shown', function () {
+        expect(App.ModalPopup.show.calledOnce).to.be.true;
+      });
+
+      it('all upgradeMethods have isCheckRequestInProgress = true', function () {
+        expect(controller.get('upgradeMethods').everyProperty('isCheckRequestInProgress')).to.be.true;
+      });
+
+      it('upgradeMethods no one is selected', function () {
+        expect(controller.get('upgradeMethods').someProperty('selected')).to.be.false;
+      });
+
+      describe('#popup.onPrimary', function () {
+
+        beforeEach(function () {
+          controller.get('upgradeMethods')[0].set('selected', true);
+          this.confirmPopup = this.popup.onPrimary();
+        });
+
+        it('showConfirmationFeedBackPopup is called once', function () {
+          expect(App.showConfirmationFeedBackPopup.calledOnce).to.be.true;
+        });
+
+        describe('#confirmPopup.onPrimary', function () {
+          beforeEach(function () {
+            this.confirmPopup.onPrimary();
+          });
+
+          it('runPreUpgradeCheck is called with correct version', function () {
+            expect(controller.runPreUpgradeCheck.calledWith(version)).to.be.true;
+          });
+
+          it('runningCheckRequests has 1 item', function () {
+            expect(controller.get('runningCheckRequests')).to.have.length(1);
+          });
+
+        });
+
+      });
+
+    });
+
+    describe("NOT show confirmation popup on Downgrade", function() {
+      beforeEach(function () {
+        controller.set('isDowngrade', true);
+        controller.upgradeOptions(false, version);
+      });
+
+      it('runningCheckRequests has 1 item', function () {
+        expect( controller.get('runningCheckRequests')).to.have.length(1);
+      });
+
     });
   });
 
@@ -896,7 +990,7 @@ describe('App.MainAdminStackAndUpgradeController', function() {
   });
 
   describe("#downgrade()", function() {
-    before(function () {
+    beforeEach(function () {
       sinon.stub(App.ajax, 'send', Em.K);
       sinon.stub(controller, 'abortUpgrade');
       sinon.stub(App.RepositoryVersion, 'find').returns([
@@ -905,20 +999,25 @@ describe('App.MainAdminStackAndUpgradeController', function() {
           repositoryVersion: '2.3'
         })
       ]);
-    });
-    after(function () {
-      App.ajax.send.restore();
-      controller.abortUpgrade.restore();
-      App.RepositoryVersion.find.restore();
-    });
-    it("make ajax call", function() {
       controller.set('upgradeVersion', 'HDP-2.3');
       controller.set('upgradeType', 'NON_ROLLING');
       controller.downgrade(Em.Object.create({
         repository_version: '2.2',
         repository_name: 'HDP-2.2'
       }), {context: 'context'});
+      this.callArgs = App.ajax.send.getCall(0).args[0];
+    });
+
+    afterEach(function () {
+      App.ajax.send.restore();
+      controller.abortUpgrade.restore();
+      App.RepositoryVersion.find.restore();
+    });
+
+    it('abortUpgrade is called once', function() {
       expect(controller.abortUpgrade.calledOnce).to.be.true;
+    });
+    it('request-data is valid', function () {
       expect(App.ajax.send.getCall(0).args[0].data).to.eql({
         from: '2.3',
         value: '2.2',
@@ -926,11 +1025,18 @@ describe('App.MainAdminStackAndUpgradeController', function() {
         isDowngrade: true,
         upgradeType: "NON_ROLLING"
       });
-      var callArgs = App.ajax.send.getCall(0).args[0];
-      expect(callArgs.name).to.eql('admin.downgrade.start');
-      expect(callArgs.sender).to.eql(controller);
-      expect(callArgs.success).to.eql('upgradeSuccessCallback');
-      expect(callArgs.callback).to.be.called;
+    });
+    it('request-name is valid', function () {
+      expect(this.callArgs.name).to.eql('admin.downgrade.start');
+    });
+    it('request-sender is valid', function () {
+      expect(this.callArgs.sender).to.eql(controller);
+    });
+    it('callback is valid', function () {
+      expect(this.callArgs.success).to.eql('upgradeSuccessCallback');
+    });
+    it('callback is called', function () {
+      expect(this.callArgs.callback).to.be.called;
     });
   });
 
@@ -1001,28 +1107,39 @@ describe('App.MainAdminStackAndUpgradeController', function() {
   });
 
   describe("#setUpgradeItemStatus()", function () {
-    before(function () {
+    var item;
+    beforeEach(function () {
       sinon.stub(App.ajax, 'send', function () {
         return {
           done: Em.clb
         }
       });
-    });
-    after(function () {
-      App.ajax.send.restore();
-    });
-    it("valid request is sent", function () {
-      var item = Em.Object.create({
+      item = Em.Object.create({
         request_id: 1,
         stage_id: 1,
         group_id: 1
       });
       controller.setUpgradeItemStatus(item, 'PENDING');
-      var callArgs = App.ajax.send.getCall(0).args[0];
-      expect(callArgs.data).to.eql({upgradeId: 1, itemId: 1, groupId: 1, status: 'PENDING'});
-      expect(callArgs.name).to.eql('admin.upgrade.upgradeItem.setState');
-      expect(callArgs.sender).to.eql(controller);
-      expect(callArgs.callback).to.be.called;
+      this.callArgs = App.ajax.send.getCall(0).args[0];
+    });
+
+    afterEach(function () {
+      App.ajax.send.restore();
+    });
+
+    it('request-data is valid', function () {
+      expect(this.callArgs.data).to.eql({upgradeId: 1, itemId: 1, groupId: 1, status: 'PENDING'});
+    });
+    it('request-name is valid', function () {
+      expect(this.callArgs.name).to.eql('admin.upgrade.upgradeItem.setState');
+    });
+    it('request-sendeer is valid', function () {
+      expect(this.callArgs.sender).to.eql(controller);
+    });
+    it('callback is called', function () {
+      expect(this.callArgs.callback).to.be.called;
+    });
+    it('item.status is PENDING', function () {
       expect(item.get('status')).to.equal('PENDING');
     });
   });
@@ -1238,17 +1355,24 @@ describe('App.MainAdminStackAndUpgradeController', function() {
     });
 
     cases.forEach(function (item) {
-      it(item.title, function () {
-        sinon.stub(App.RepositoryVersion, 'find').returns([
-          Em.Object.create({
-            status: 'CURRENT',
-            stackVersionType: item.stackVersionType
-          })
-        ]);
-        controller.set('currentVersion', {
-          repository_version: item.repoVersion
+      describe(item.title, function () {
+
+        beforeEach(function () {
+          sinon.stub(App.RepositoryVersion, 'find').returns([
+            Em.Object.create({
+              status: 'CURRENT',
+              stackVersionType: item.stackVersionType
+            })
+          ]);
+          controller.set('currentVersion', {
+            repository_version: item.repoVersion
+          });
         });
-        expect(App.get('isStormMetricsSupported')).to.equal(item.isStormMetricsSupported);
+
+        it('isStormMetricsSupported is ' + (item.isStormMetricsSupported ? '' : 'not') + ' supported', function () {
+          expect(App.get('isStormMetricsSupported')).to.equal(item.isStormMetricsSupported);
+        });
+
       });
     });
 
@@ -1259,25 +1383,42 @@ describe('App.MainAdminStackAndUpgradeController', function() {
     beforeEach(function() {
       sinon.stub($, 'ajax', Em.K);
       controller.set('isFinalizeItem', true);
+      this.stub = sinon.stub(App, 'get');
     });
 
     afterEach(function () {
       $.ajax.restore();
+      this.stub.restore();
     });
 
-    it('should do ajax-request', function () {
-      sinon.stub(App, 'get').withArgs('upgradeState').returns('HOLDING');
-      controller.updateFinalize();
-      App.get.restore();
-      expect($.ajax.calledOnce).to.be.true;
+    describe('should do ajax-request', function () {
+
+      beforeEach(function () {
+        this.stub.withArgs('upgradeState').returns('HOLDING');
+        controller.updateFinalize();
+      });
+
+      it('request is sent', function () {
+        expect($.ajax.calledOnce).to.be.true;
+      });
+
     });
 
-    it('shouldn\'t do ajax-request', function () {
-      sinon.stub(App, 'get').withArgs('upgradeState').returns('HOLDING_TIMEDOUT');
-      controller.updateFinalize();
-      App.get.restore();
-      expect(controller.get('isFinalizeItem')).to.be.false;
-      expect($.ajax.calledOnce).to.be.false;
+    describe('shouldn\'t do ajax-request', function () {
+
+      beforeEach(function () {
+        this.stub.withArgs('upgradeState').returns('HOLDING_TIMEDOUT');
+        controller.updateFinalize();
+      });
+
+      it('request is not sent', function () {
+        expect($.ajax.called).to.be.false;
+      });
+
+      it('isFinalizeItem is false', function () {
+        expect(controller.get('isFinalizeItem')).to.be.false;
+      });
+
     });
 
   });
@@ -1900,19 +2041,38 @@ describe('App.MainAdminStackAndUpgradeController', function() {
     });
 
     cases.forEach(function (item) {
-      it(item.title, function () {
-        var runningCheckRequests = controller.get('runningCheckRequests');
-        appGetMock.returns(item.supportsPreUpgradeCheck);
-        controller.runPreUpgradeCheckOnly({
-          type: item.type
+      describe(item.title, function () {
+        var runningCheckRequests;
+        beforeEach(function () {
+          runningCheckRequests = controller.get('runningCheckRequests');
+          appGetMock.returns(item.supportsPreUpgradeCheck);
+          controller.runPreUpgradeCheckOnly({
+            type: item.type
+          });
         });
-        expect(upgradeMethods.findProperty('type', 'ROLLING').getProperties('isCheckComplete', 'isCheckRequestInProgress', 'action')).to.eql(item.ru);
-        expect(upgradeMethods.findProperty('type', 'NON_ROLLING').getProperties('isCheckComplete', 'isCheckRequestInProgress', 'action')).to.eql(item.eu);
-        expect(App.ajax.send.callCount).to.equal(item.ajaxCallCount);
-        expect(runningCheckRequests).to.have.length(item.runningCheckRequestsLength);
+
+        it('ROLLING properties', function () {
+          expect(upgradeMethods.findProperty('type', 'ROLLING').getProperties('isCheckComplete', 'isCheckRequestInProgress', 'action')).to.eql(item.ru);
+        });
+
+        it('NON_ROLLING properties', function () {
+          expect(upgradeMethods.findProperty('type', 'NON_ROLLING').getProperties('isCheckComplete', 'isCheckRequestInProgress', 'action')).to.eql(item.eu);
+        });
+
+        it(item.ajaxCallCount + ' requests sent', function () {
+          expect(App.ajax.send.callCount).to.equal(item.ajaxCallCount);
+        });
+
+        it('runningCheckRequests length is ' + item.runningCheckRequestsLength, function () {
+          expect(runningCheckRequests).to.have.length(item.runningCheckRequestsLength);
+        });
+
         if (item.runningCheckRequestsLength) {
-          expect(runningCheckRequests[0].type).to.equal(item.type);
+          it('runningCheckRequests.type is ' + item.type, function () {
+            expect(runningCheckRequests[0].type).to.equal(item.type);
+          });
         }
+
       });
     });
 

+ 47 - 16
ambari-web/test/controllers/main/alerts/definitions_configs_controller_test.js

@@ -474,8 +474,7 @@ describe('App.MainAlertDefinitionConfigsController', function () {
 
   describe('#changeType()', function () {
 
-    it('should disable and enable appropriate configs', function () {
-
+    beforeEach(function () {
       controller.set('allServices', ['service1', 'service2']);
       controller.set('allScopes', ['scope1', 'scope2']);
 
@@ -484,25 +483,57 @@ describe('App.MainAlertDefinitionConfigsController', function () {
         Em.Object.create({name: 'component', isDisabled: false}),
         Em.Object.create({name: 'scope', isDisabled: false})
       ]);
+    });
 
-      controller.changeType('Host Alert Definition');
+    describe('Host Alert Definition', function () {
 
-      expect(controller.get('configs').everyProperty('isDisabled', true)).to.be.true;
-      expect(controller.get('configs').findProperty('name', 'service').get('options')).to.eql(['Ambari']);
-      expect(controller.get('configs').findProperty('name', 'service').get('value')).to.equal('Ambari');
-      expect(controller.get('configs').findProperty('name', 'component').get('value')).to.equal('Ambari Agent');
-      expect(controller.get('configs').findProperty('name', 'scope').get('options')).to.eql(['Host']);
-      expect(controller.get('configs').findProperty('name', 'scope').get('value')).to.equal('Host');
+      beforeEach(function () {
+        controller.changeType('Host Alert Definition');
+      });
 
-      controller.changeType('alert_type_service');
+      it('all configs are disabled', function () {
+        expect(controller.get('configs').everyProperty('isDisabled', true)).to.be.true;
+      });
+      it('service.options = ["Ambari"]', function () {
+        expect(controller.get('configs').findProperty('name', 'service').get('options')).to.eql(['Ambari']);
+      });
+      it('service.value = "Ambari"', function () {
+        expect(controller.get('configs').findProperty('name', 'service').get('value')).to.equal('Ambari');
+      });
+      it('component.value = "Ambari Agent"', function () {
+        expect(controller.get('configs').findProperty('name', 'component').get('value')).to.equal('Ambari Agent');
+      });
+      it('scope.options = ["Host"]', function () {
+        expect(controller.get('configs').findProperty('name', 'scope').get('options')).to.eql(['Host']);
+      });
+      it('isDisabled.value = "Host"', function () {
+        expect(controller.get('configs').findProperty('name', 'scope').get('value')).to.equal('Host');
+      });
+    });
 
-      expect(controller.get('configs').everyProperty('isDisabled', false)).to.be.true;
-      expect(controller.get('configs').findProperty('name', 'service').get('options')).to.eql(['service1', 'service2']);
-      expect(controller.get('configs').findProperty('name', 'service').get('value')).to.equal('service1');
-      expect(controller.get('configs').findProperty('name', 'component').get('value')).to.equal('No component');
-      expect(controller.get('configs').findProperty('name', 'scope').get('options')).to.eql(['scope1', 'scope2']);
-      expect(controller.get('configs').findProperty('name', 'scope').get('value')).to.equal('scope1');
+    describe('alert_type_service', function () {
 
+      beforeEach(function () {
+        controller.changeType('alert_type_service');
+      });
+      it('all configs are not disabled', function () {
+        expect(controller.get('configs').everyProperty('isDisabled', false)).to.be.true;
+      });
+      it('service.options = ["service1", "service2"]', function () {
+        expect(controller.get('configs').findProperty('name', 'service').get('options')).to.eql(['service1', 'service2']);
+      });
+      it('service.value = "service1"', function () {
+        expect(controller.get('configs').findProperty('name', 'service').get('value')).to.equal('service1');
+      });
+      it('component.value = "No component"', function () {
+        expect(controller.get('configs').findProperty('name', 'component').get('value')).to.equal('No component');
+      });
+      it('scope.options = ["scope1", "scope2"]', function () {
+        expect(controller.get('configs').findProperty('name', 'scope').get('options')).to.eql(['scope1', 'scope2']);
+      });
+      it('scope.value = "scope1"', function () {
+        expect(controller.get('configs').findProperty('name', 'scope').get('value')).to.equal('scope1');
+      });
     });
 
   });

+ 20 - 11
ambari-web/test/controllers/main/alerts/manage_alert_notifications_controller_test.js

@@ -585,20 +585,20 @@ describe('App.ManageAlertNotificationsController', function () {
           expect(view.get('parentView.hasErrors')).to.be.true;
         });
 
-        it('should check inputFields.name.value', function () {
+        it('should check inputFields.name.value (2)', function () {
           view.set('controller.inputFields.name.errorMsg', 'error');
           view.set('controller.inputFields.name.value', 'test');
           expect(view.get('controller.inputFields.name.errorMsg')).to.equal('');
         });
 
-        it('should check inputFields.name.value', function () {
+        it('should check inputFields.name.value (3)', function () {
           view.set('isEdit', true);
           view.set('controller.inputFields.name.value', '');
           expect(view.get('controller.inputFields.name.errorMsg')).to.equal(Em.I18n.t('alerts.actions.manage_alert_notifications_popup.error.name.empty'));
           expect(view.get('parentView.hasErrors')).to.be.true;
         });
 
-        it('should check inputFields.name.value', function () {
+        it('should check inputFields.name.value (4)', function () {
           view.set('isEdit', true);
           view.set('controller.inputFields.name.errorMsg', 'error');
           view.set('controller.inputFields.name.value', 'test');
@@ -620,7 +620,7 @@ describe('App.ManageAlertNotificationsController', function () {
 
         });
 
-        it('should check inputFields.retypeSMTPPassword.value', function () {
+        it('should check inputFields.retypeSMTPPassword.value (2)', function () {
 
           view.set('parentView.hasErrors', true);
           view.set('controller.inputFields.retypeSMTPPassword.errorMsg', 'error');
@@ -883,24 +883,33 @@ describe('App.ManageAlertNotificationsController', function () {
   });
 
   describe('#deleteAlertNotificationSuccessCallback()', function () {
+    var mockSelectedAlertNotification;
 
-    it("should call loadAlertNotifications, selectedAlertNotification.deleteRecord and set null to selectedAlertNotification", function () {
-
-      var mockSelectedAlertNotification = {
+    beforeEach(function () {
+      mockSelectedAlertNotification = {
         deleteRecord: Em.K
       };
       controller.set('selectedAlertNotification', mockSelectedAlertNotification);
       sinon.stub(controller, 'loadAlertNotifications', Em.K);
       sinon.spy(mockSelectedAlertNotification, 'deleteRecord');
-
       controller.deleteAlertNotificationSuccessCallback();
+    });
+
+    afterEach(function () {
+      controller.loadAlertNotifications.restore();
+      mockSelectedAlertNotification.deleteRecord.restore();
+    });
 
+    it("should call loadAlertNotifications", function () {
       expect(controller.loadAlertNotifications.calledOnce).to.be.true;
+    });
+
+    it("should call selectedAlertNotification.deleteRecord", function () {
       expect(mockSelectedAlertNotification.deleteRecord.calledOnce).to.be.true;
-      expect(controller.get('selectedAlertNotification')).to.equal(null);
+    });
 
-      controller.loadAlertNotifications.restore();
-      mockSelectedAlertNotification.deleteRecord.restore();
+    it("should set null to selectedAlertNotification", function () {
+      expect(controller.get('selectedAlertNotification')).to.equal(null);
     });
 
   });

+ 79 - 30
ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_test.js

@@ -77,38 +77,70 @@ describe('MainChartHeatmapMetric', function () {
   });
 
   describe('#generateSlot()', function () {
+
     beforeEach(function () {
       sinon.stub(mainChartHeatmapMetric, 'formatLegendNumber').returns('val');
       sinon.stub(date, 'timingFormat').returns('time');
     });
+
     afterEach(function () {
       mainChartHeatmapMetric.formatLegendNumber.restore();
       date.timingFormat.restore();
     });
-    it('label suffix is empty', function () {
-      expect(mainChartHeatmapMetric.generateSlot(0, 1, '', {r: 0, g: 0, b: 0})).to.eql(Em.Object.create({
-        "from": "val",
-        "to": "val",
-        "label": "val - val",
-        "cssStyle": "background-color:rgb(0,0,0)"
-      }));
-
-      expect(mainChartHeatmapMetric.formatLegendNumber.getCall(0).args).to.eql([0]);
-      expect(mainChartHeatmapMetric.formatLegendNumber.getCall(1).args).to.eql([1]);
+
+    describe('label suffix is empty', function () {
+
+      beforeEach(function () {
+        this.result = mainChartHeatmapMetric.generateSlot(0, 1, '', {r: 0, g: 0, b: 0});
+      });
+
+      it('generateSlot result is valid', function () {
+        expect(this.result).to.eql(Em.Object.create({
+          "from": "val",
+          "to": "val",
+          "label": "val - val",
+          "cssStyle": "background-color:rgb(0,0,0)"
+        }));
+      });
+
+      it('formatLegendNumber 1st call with valid arguments', function () {
+        expect(mainChartHeatmapMetric.formatLegendNumber.getCall(0).args).to.eql([0]);
+      });
+
+      it('formatLegendNumber 2nd call with valid arguments', function () {
+        expect(mainChartHeatmapMetric.formatLegendNumber.getCall(1).args).to.eql([1]);
+      });
     });
-    it('label suffix is "ms"', function () {
-      expect(mainChartHeatmapMetric.generateSlot(0, 1, 'ms', {r: 0, g: 0, b: 0})).to.eql(Em.Object.create({
-        "from": "val",
-        "to": "val",
-        "label": "time - time",
-        "cssStyle": "background-color:rgb(0,0,0)"
-      }));
-
-      expect(mainChartHeatmapMetric.formatLegendNumber.getCall(0).args).to.eql([0]);
-      expect(mainChartHeatmapMetric.formatLegendNumber.getCall(1).args).to.eql([1]);
-      expect(date.timingFormat.getCall(0).args).to.eql(['val', 'zeroValid']);
-      expect(date.timingFormat.getCall(1).args).to.eql(['val', 'zeroValid']);
+
+    describe('label suffix is "ms"', function () {
+
+      beforeEach(function () {
+        this.result = mainChartHeatmapMetric.generateSlot(0, 1, 'ms', {r: 0, g: 0, b: 0});
+      });
+
+      it('generateSlot result is valid', function () {
+        expect(this.result).to.eql(Em.Object.create({
+          "from": "val",
+          "to": "val",
+          "label": "time - time",
+          "cssStyle": "background-color:rgb(0,0,0)"
+        }));
+      });
+      it('formatLegendNumber 1st call with valid arguments', function () {
+        expect(mainChartHeatmapMetric.formatLegendNumber.getCall(0).args).to.eql([0]);
+      });
+      it('formatLegendNumber 2nd call with valid arguments', function () {
+        expect(mainChartHeatmapMetric.formatLegendNumber.getCall(1).args).to.eql([1]);
+      });
+      it('timingFormat 1st call with valid arguments', function () {
+        expect(date.timingFormat.getCall(0).args).to.eql(['val', 'zeroValid']);
+      });
+      it('timingFormat 2nd call with valid arguments', function () {
+        expect(date.timingFormat.getCall(1).args).to.eql(['val', 'zeroValid']);
+      });
+
     });
+
   });
 
   describe('#getHatchStyle()', function () {
@@ -159,6 +191,15 @@ describe('MainChartHeatmapMetric', function () {
   });
 
   describe('#hostToSlotMap', function () {
+
+    beforeEach(function () {
+      this.stub = sinon.stub(mainChartHeatmapMetric, 'calculateSlot');
+    });
+
+    afterEach(function () {
+      this.stub.restore();
+    });
+
     it('hostToValueMap is null', function () {
       mainChartHeatmapMetric.set('hostToValueMap', null);
       mainChartHeatmapMetric.set('hostNames', []);
@@ -174,20 +215,18 @@ describe('MainChartHeatmapMetric', function () {
     it('slot greater than -1', function () {
       mainChartHeatmapMetric.set('hostToValueMap', {});
       mainChartHeatmapMetric.set('hostNames', ['host1']);
-      sinon.stub(mainChartHeatmapMetric, 'calculateSlot').returns(0);
+      this.stub.returns(0);
       mainChartHeatmapMetric.propertyDidChange('hostToSlotMap');
       expect(mainChartHeatmapMetric.get('hostToSlotMap')).to.eql({'host1': 0});
       expect(mainChartHeatmapMetric.calculateSlot.calledWith({}, 'host1')).to.be.true;
-      mainChartHeatmapMetric.calculateSlot.restore();
     });
     it('slot equal to -1', function () {
       mainChartHeatmapMetric.set('hostToValueMap', {});
       mainChartHeatmapMetric.set('hostNames', ['host1']);
-      sinon.stub(mainChartHeatmapMetric, 'calculateSlot').returns('-1');
+      this.stub.returns('-1');
       mainChartHeatmapMetric.propertyDidChange('hostToSlotMap');
       expect(mainChartHeatmapMetric.get('hostToSlotMap')).to.be.empty;
       expect(mainChartHeatmapMetric.calculateSlot.calledWith({}, 'host1')).to.be.true;
-      mainChartHeatmapMetric.calculateSlot.restore();
     });
   });
 
@@ -272,10 +311,20 @@ describe('MainChartHeatmapMetric', function () {
     ];
 
     testCases.forEach(function (test) {
-      it(test.title, function () {
-        sinon.stub(mainChartHeatmapMetric, 'get').withArgs('slotDefinitions').returns(test.data.slotDefinitions);
-        expect(mainChartHeatmapMetric.calculateSlot(test.data.hostToValueMap, test.data.hostName)).to.equal(test.result);
-        mainChartHeatmapMetric.get.restore();
+      describe(test.title, function () {
+
+        beforeEach(function () {
+          sinon.stub(mainChartHeatmapMetric, 'get').withArgs('slotDefinitions').returns(test.data.slotDefinitions);
+        });
+
+        afterEach(function () {
+          mainChartHeatmapMetric.get.restore();
+        });
+
+        it('calculateSlot result is valid', function () {
+          expect(mainChartHeatmapMetric.calculateSlot(test.data.hostToValueMap, test.data.hostName)).to.equal(test.result);
+        });
+
       });
     });
   });

+ 10 - 12
ambari-web/test/controllers/main/charts/heatmap_test.js

@@ -53,11 +53,11 @@ describe('MainChartsHeatmapController', function () {
       controller.set("inputMaximum", 'qwerty');
       expect(controller.get('selectedMetric.maximumValue')).to.equal(100);
     });
-    it('should not set maximumValue if inputMaximum consists not only of digits', function () {
+    it('should not set maximumValue if inputMaximum consists not only of digits (2)', function () {
       controller.set("inputMaximum", '100%');
       expect(controller.get('selectedMetric.maximumValue')).to.equal(100);
     });
-    it('should set maximumValue if inputMaximum consists only of digits', function () {
+    it('should set maximumValue if inputMaximum consists only of digits (2)', function () {
       controller.set("inputMaximum", 1000);
       expect(controller.get('selectedMetric.maximumValue')).to.equal(1000);
     })
@@ -361,16 +361,14 @@ describe('MainChartsHeatmapController', function () {
   });
 
   describe("#toList()", function() {
-    it("", function() {
-      var rackMap = {'r1': {
-        name: 'r1',
-        rackId: 'r1',
-        hosts: [{rack: 'r1'}, {rack: 'r1'}]
-      }};
-      expect(controller.toList(rackMap)).to.eql([Em.Object.create({
-        name: 'r1',
-        rackId: 'r1',
-        hosts: [{rack: 'r1'}, {rack: 'r1'}],
+    var rackMap = {'r1': {
+      name: 'r1',
+      rackId: 'r1',
+      hosts: [{rack: 'r1'}, {rack: 'r1'}]
+    }};
+
+    it('toList result is valid', function() {
+      expect(controller.toList(rackMap)).to.eql([Em.Object.create(rackMap.r1, {
         isLoaded: false,
         index: 0
       })]);

+ 5 - 15
ambari-web/test/controllers/main/dashboard/config_history_controller_test.js

@@ -113,30 +113,20 @@ describe('MainConfigHistoryController', function () {
           }
         }
       });
+      sinon.stub(App, 'get', function(k) {
+        if ('testMode' === k) return false;
+        return Em.get(App, k);
+      });
     });
     afterEach(function () {
       App.router.get.restore();
       App.get.restore();
     });
-    it('testMode is true', function () {
-      sinon.stub(App, 'get', function(k) {
-        if ('testMode' === k) return true;
-        return Em.get(App, k);
-      });
-      expect(controller.getUrl()).to.equal('/data/configurations/service_versions.json');
-    });
     it('query params is empty', function () {
-      sinon.stub(App, 'get', function(k) {
-        if ('testMode' === k) return false;
-        return Em.get(App, k);
-      });
+
       expect(controller.getUrl()).to.equal('/api/v1/clusters/mycluster/configurations/service_config_versions?fields=service_config_version,user,group_id,group_name,is_current,createtime,service_name,hosts,service_config_version_note,is_cluster_compatible,stack_id&minimal_response=true');
     });
     it('query params is correct', function () {
-      sinon.stub(App, 'get', function(k) {
-        if ('testMode' === k) return false;
-        return Em.get(App, k);
-      });
       expect(controller.getUrl({})).to.equal('/api/v1/clusters/mycluster/configurations/service_config_versions?params&fields=service_config_version,user,group_id,group_name,is_current,createtime,service_name,hosts,service_config_version_note,is_cluster_compatible,stack_id&minimal_response=true');
     });
   });

+ 11 - 5
ambari-web/test/controllers/main/host/configs_service_test.js

@@ -118,17 +118,23 @@ describe('App.MainHostServiceConfigsController', function () {
 	});
 
 	describe("#renderServiceConfigs()", function () {
+
+    beforeEach(function () {
+      sinon.stub(controller, 'filterServiceConfigs', function () {
+        this._super = Em.K;
+      });
+    });
+
+    afterEach(function () {
+      controller.filterServiceConfigs.restore();
+    });
+
 		it("should call filterServiceConfigs", function () {
 			var serviceConfigs = {
 				configCategories: 'val'
 			};
-			sinon.stub(controller, 'filterServiceConfigs', function () {
-				this._super = Em.K;
-			});
 			controller.renderServiceConfigs(serviceConfigs);
-
 			expect(controller.filterServiceConfigs.calledWith('val')).to.be.true;
-			controller.filterServiceConfigs.restore();
 		});
 	});
 

+ 405 - 251
ambari-web/test/controllers/main/host/details_test.js

@@ -50,32 +50,51 @@ describe('App.MainHostDetailsController', function () {
   App.TestAliases.testAsComputedFilterBy(getController(), 'serviceNonClientActiveComponents', 'serviceActiveComponents', 'isClient', false);
 
   describe('#routeHome()', function () {
-    it('transiotion to dashboard', function () {
+
+    beforeEach(function () {
       sinon.stub(App.router, 'transitionTo', Em.K);
+    });
+
+    afterEach(function () {
+      App.router.transitionTo.restore();
+    });
+
+    it('transition to dashboard', function () {
       controller.routeHome();
       expect(App.router.transitionTo.calledWith('main.dashboard.index')).to.be.true;
-      App.router.transitionTo.restore();
     });
   });
 
   describe('#startComponent()', function () {
-    it('call sendComponentCommand', function () {
-      var event = {
-        context: Em.Object.create({
-          displayName: 'comp'
-        })
-      };
+
+    var event = {
+      context: Em.Object.create({
+        displayName: 'comp'
+      })
+    };
+
+    beforeEach(function () {
       sinon.stub(App, 'showConfirmationPopup', function (callback) {
         callback();
       });
       sinon.stub(controller, 'sendComponentCommand');
       controller.startComponent(event);
+    });
+
+    afterEach(function () {
+      App.showConfirmationPopup.restore();
+      controller.sendComponentCommand.restore();
+    });
+
+    it('configmation popup is shown', function () {
       expect(App.showConfirmationPopup.calledOnce).to.be.true;
+    });
+
+    it('call sendComponentCommand', function () {
       expect(controller.sendComponentCommand.calledWith(Em.Object.create({
         displayName: 'comp'
       })), Em.I18n.t('requestInfo.startHostComponent') + " comp", App.HostComponentStatus.started).to.be.true;
-      App.showConfirmationPopup.restore();
-      controller.sendComponentCommand.restore();
+
     });
   });
 
@@ -181,65 +200,45 @@ describe('App.MainHostDetailsController', function () {
   });
 
   describe('#sendComponentCommandSuccessCallback()', function () {
+
+    var params = {
+      component: Em.Object.create({}),
+      HostRoles: {
+        state: App.HostComponentStatus.stopped
+      }
+    };
+
     beforeEach(function () {
       sinon.stub(controller, 'mimicWorkStatusChange', Em.K);
       sinon.stub(controller, 'showBackgroundOperationsPopup', Em.K);
+      sinon.stub(App, 'get').withArgs('testMode').returns(false);
+      controller.sendComponentCommandSuccessCallback({}, {}, params);
     });
+
     afterEach(function () {
       controller.showBackgroundOperationsPopup.restore();
       controller.mimicWorkStatusChange.restore();
+      App.get.restore();
     });
-    it('testMode, starting component', function () {
-      var params = {
-        component: Em.Object.create({}),
-        HostRoles: {
-          state: App.HostComponentStatus.started
-        }
-      };
-
-      App.set('testMode', true);
-      controller.sendComponentCommandSuccessCallback({}, {}, params);
-      expect(controller.mimicWorkStatusChange.calledWith(Em.Object.create({
-        workStatus: App.HostComponentStatus.starting
-      }), App.HostComponentStatus.starting, App.HostComponentStatus.started)).to.be.true;
-      expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
-    });
-    it('testMode, stopping component', function () {
-      var params = {
-        component: Em.Object.create({}),
-        HostRoles: {
-          state: App.HostComponentStatus.stopped
-        }
-      };
-
-      App.set('testMode', true);
-      controller.sendComponentCommandSuccessCallback({}, {}, params);
-      expect(controller.mimicWorkStatusChange.calledWith(Em.Object.create({
-        workStatus: App.HostComponentStatus.stopping
-      }), App.HostComponentStatus.stopping, App.HostComponentStatus.stopped)).to.be.true;
-      expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
-    });
-    it('testMode, stopping component', function () {
-      var params = {
-        component: Em.Object.create({}),
-        HostRoles: {
-          state: App.HostComponentStatus.stopped
-        }
-      };
 
-      App.set('testMode', false);
-      controller.sendComponentCommandSuccessCallback({}, {}, params);
+    it('mimicWorkStatusChange is not called', function () {
       expect(controller.mimicWorkStatusChange.called).to.be.false;
+    });
+    it('showBackgroundOperationsPopup is called once', function () {
       expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
     });
   });
 
   describe('#ajaxErrorCallback()', function () {
-    it('call mainServiceItemController.ajaxErrorCallback', function () {
+    beforeEach(function () {
       sinon.stub(controller, 'ajaxErrorCallback', Em.K);
+    });
+    afterEach(function () {
+      controller.ajaxErrorCallback.restore();
+    });
+    it('call mainServiceItemController.ajaxErrorCallback', function () {
       controller.ajaxErrorCallback('request', 'ajaxOptions', 'error', 'opt', 'params');
       expect(controller.ajaxErrorCallback.calledWith('request', 'ajaxOptions', 'error', 'opt', 'params')).to.be.true;
-      controller.ajaxErrorCallback.restore();
     });
   });
 
@@ -252,6 +251,7 @@ describe('App.MainHostDetailsController', function () {
     var bgController = {
       showPopup: Em.K
     };
+
     beforeEach(function () {
       var stub = sinon.stub(App.router, 'get');
       stub.withArgs('userSettingsController').returns({
@@ -262,25 +262,28 @@ describe('App.MainHostDetailsController', function () {
       stub.withArgs('backgroundOperationsController').returns(bgController);
       sinon.spy(bgController, 'showPopup');
       sinon.spy(mock, 'done');
+      this.callback = sinon.stub();
     });
+
     afterEach(function () {
       bgController.showPopup.restore();
       mock.done.restore();
       App.router.get.restore();
     });
+
     it('initValue is true, callback is undefined', function () {
       mock.initValue = true;
       controller.showBackgroundOperationsPopup();
       expect(mock.done.calledOnce).to.be.true;
       expect(bgController.showPopup.calledOnce).to.be.true;
     });
+
     it('initValue is false, callback is defined', function () {
       mock.initValue = false;
-      var callback = sinon.stub();
-      controller.showBackgroundOperationsPopup(callback);
+      controller.showBackgroundOperationsPopup(this.callback);
       expect(mock.done.calledOnce).to.be.true;
       expect(bgController.showPopup.calledOnce).to.be.false;
-      expect(callback.calledOnce).to.be.true;
+      expect(this.callback.calledOnce).to.be.true;
     });
   });
 
@@ -901,6 +904,7 @@ describe('App.MainHostDetailsController', function () {
       App.Service.find().clear();
       expect(controller.constructConfigUrlParams(data)).to.eql([]);
     });
+
     it('isHaEnabled = true', function () {
       App.store.load(App.Service, {
         id: 'HDFS',
@@ -916,6 +920,7 @@ describe('App.MainHostDetailsController', function () {
       });
       App.set('currentStackVersion', 'HDP-2.0.1');
     });
+
     it('HBASE is installed', function () {
       App.store.load(App.Service, {
         id: 'HBASE',
@@ -926,6 +931,7 @@ describe('App.MainHostDetailsController', function () {
       expect(controller.constructConfigUrlParams(data)).to.eql(['(type=hbase-site&tag=1)']);
       App.Service.find().clear();
     });
+
     it('HIVE is installed', function () {
       App.store.load(App.Service, {
         id: 'HIVE',
@@ -935,6 +941,7 @@ describe('App.MainHostDetailsController', function () {
       expect(controller.constructConfigUrlParams(data)).to.eql(['(type=webhcat-site&tag=1)', '(type=hive-site&tag=1)']);
       App.Service.find().clear();
     });
+
     it('STORM is installed', function () {
       App.store.load(App.Service, {
         id: 'STORM',
@@ -944,6 +951,7 @@ describe('App.MainHostDetailsController', function () {
       expect(controller.constructConfigUrlParams(data)).to.eql(['(type=storm-site&tag=1)']);
       App.Service.find().clear();
     });
+
     it('YARN for 2.2 stack is installed', function () {
       App.set('currentStackVersion', 'HDP-2.2.0');
       App.store.load(App.Service, {
@@ -955,11 +963,20 @@ describe('App.MainHostDetailsController', function () {
       App.set('currentStackVersion', 'HDP-2.0.1');
       App.Service.find().clear();
     });
-    it('isRMHaEnabled true', function () {
-      sinon.stub(App, 'get').withArgs('isRMHaEnabled').returns(true);
-      var data = {Clusters: {desired_configs: {'yarn-site': {tag: 1}, 'zoo.cfg': {tag: 1}}}};
-      expect(controller.constructConfigUrlParams(data)).to.eql(['(type=yarn-site&tag=1)', '(type=zoo.cfg&tag=1)']);
-      App.get.restore();
+
+    describe('isRMHaEnabled true', function () {
+      beforeEach(function () {
+        sinon.stub(App, 'get').withArgs('isRMHaEnabled').returns(true);
+      });
+      afterEach(function () {
+        App.get.restore();
+      });
+
+      it('params are valid', function () {
+        var data = {Clusters: {desired_configs: {'yarn-site': {tag: 1}, 'zoo.cfg': {tag: 1}}}};
+        expect(controller.constructConfigUrlParams(data)).to.eql(['(type=yarn-site&tag=1)', '(type=zoo.cfg&tag=1)']);
+      });
+
     });
   });
 
@@ -1056,20 +1073,33 @@ describe('App.MainHostDetailsController', function () {
     });
 
     yarnCases.forEach(function (item) {
-      it(item.title, function () {
+      describe(item.title, function () {
         var servicesMock = item.isYARNInstalled ? [
           {
             serviceName: 'YARN'
           }
         ] : [];
-        sinon.stub(App, 'get').withArgs('isHadoop22Stack').returns(item.isHadoop22Stack).
-          withArgs('isRMHaEnabled').returns(item.isRMHaEnabled);
-        sinon.stub(App.Service, 'find').returns(servicesMock);
-        controller.saveZkConfigs(yarnData);
-        expect(controller.saveConfigsBatch.firstCall.args[0].someProperty('properties.yarn-site')).to.equal(item.shouldYarnSiteBeModified);
-        expect(controller.saveConfigsBatch.firstCall.args[0].someProperty('properties_attributes.yarn-site')).to.equal(item.shouldYarnSiteBeModified);
-        App.get.restore();
-        App.Service.find.restore();
+
+        beforeEach(function () {
+          sinon.stub(App, 'get').withArgs('isHadoop22Stack').returns(item.isHadoop22Stack).
+            withArgs('isRMHaEnabled').returns(item.isRMHaEnabled);
+          sinon.stub(App.Service, 'find').returns(servicesMock);
+          controller.saveZkConfigs(yarnData);
+        });
+
+        afterEach(function () {
+          App.get.restore();
+          App.Service.find.restore();
+        });
+
+        it('some properties.yarn-site = true (' + item.shouldYarnSiteBeModified + ')', function () {
+          expect(controller.saveConfigsBatch.firstCall.args[0].someProperty('properties.yarn-site')).to.equal(item.shouldYarnSiteBeModified);
+        });
+
+        it('some properties_attributes.yarn-site = true (' + item.shouldYarnSiteBeModified + ')', function () {
+          expect(controller.saveConfigsBatch.firstCall.args[0].someProperty('properties_attributes.yarn-site')).to.equal(item.shouldYarnSiteBeModified);
+        });
+
       });
     });
 
@@ -1346,24 +1376,38 @@ describe('App.MainHostDetailsController', function () {
     ];
 
     tests.forEach(function(test) {
-      it(test.m, function() {
-        if (test.appGetterStubs) {
-          Em.keys(test.appGetterStubs).forEach(function(key) {
-            sinon.stub(App, 'get').withArgs(key).returns(test.appGetterStubs[key]);
-          });
-        }
-        if (test.ctrlStubs) {
-          var stub = sinon.stub(controller, 'get');
-          Em.keys(test.ctrlStubs).forEach(function(key) {
-            stub.withArgs(key).returns(test.ctrlStubs[key]);
-          });
-        }
-        sinon.stub(App.HostComponent, 'find').returns(test.hostComponentModel);
-        controller.updateZkConfigs(test.configs);
-        expect(test.configs).to.be.eql(test.e.configs);
-        if (test.ctrlStubs) controller.get.restore();
-        if (test.appGetterStubs) App.get.restore();
-        App.HostComponent.find.restore();
+      describe(test.m, function() {
+
+        beforeEach(function() {
+          if (test.appGetterStubs) {
+            Em.keys(test.appGetterStubs).forEach(function(key) {
+              sinon.stub(App, 'get').withArgs(key).returns(test.appGetterStubs[key]);
+            });
+          }
+          if (test.ctrlStubs) {
+            var stub = sinon.stub(controller, 'get');
+            Em.keys(test.ctrlStubs).forEach(function(key) {
+              stub.withArgs(key).returns(test.ctrlStubs[key]);
+            });
+          }
+          sinon.stub(App.HostComponent, 'find').returns(test.hostComponentModel);
+          controller.updateZkConfigs(test.configs);
+        });
+
+        afterEach(function () {
+          if (test.ctrlStubs) {
+            controller.get.restore();
+          }
+          if (test.appGetterStubs) {
+            App.get.restore();
+          }
+          App.HostComponent.find.restore();
+        });
+
+        it('configs are mapped correctly', function () {
+          expect(test.configs).to.be.eql(test.e.configs);
+        });
+
       });
     });
   });
@@ -1445,12 +1489,23 @@ describe('App.MainHostDetailsController', function () {
       controller.runDecommission('host1', 'YARN');
       expect(controller.doDecommission.calledWith('host1', 'YARN', "RESOURCEMANAGER", "NODEMANAGER")).to.be.true;
     });
-    it('HBASE service', function () {
-      sinon.stub(controller, 'warnBeforeDecommission', Em.K);
-      controller.runDecommission('host1', 'HBASE');
-      expect(controller.warnBeforeDecommission.calledWith('host1')).to.be.true;
-      controller.warnBeforeDecommission.restore();
+
+    describe('HBASE service', function () {
+
+      beforeEach(function () {
+        sinon.stub(controller, 'warnBeforeDecommission', Em.K);
+      });
+
+      afterEach(function () {
+        controller.warnBeforeDecommission.restore();
+      });
+      it('warnBeforeDecommission is called with valid arguments', function () {
+        controller.runDecommission('host1', 'HBASE');
+        expect(controller.warnBeforeDecommission.calledWith('host1')).to.be.true;
+      });
+
     });
+
   });
 
   describe('#runRecommission()', function () {
@@ -1934,14 +1989,27 @@ describe('App.MainHostDetailsController', function () {
       toDecommissionComponents: []
     };
 
+    beforeEach(function () {
+      this.stub = sinon.stub(App.HostComponent, 'find').returns([{
+        id: 'TASKTRACKER_host1',
+        componentName: 'TASKTRACKER'
+      }]);;
+    });
+
+    afterEach(function () {
+      this.stub.restore();
+    });
+
     it('content.hostComponents is null', function () {
       controller.set('content', {hostComponents: null});
       expect(controller.getHostComponentsInfo()).to.eql(result);
     });
+
     it('content.hostComponents is empty', function () {
       controller.set('content', {hostComponents: []});
       expect(controller.getHostComponentsInfo()).to.eql(result);
     });
+
     it('content.hostComponents has ZOOKEEPER_SERVER', function () {
       App.HostComponent.find().clear();
       controller.set('content', {
@@ -1953,15 +2021,8 @@ describe('App.MainHostDetailsController', function () {
       });
       expect(controller.getHostComponentsInfo().zkServerInstalled).to.be.true;
     });
+
     it('content.hostComponents has last component', function () {
-      sinon.stub(App.HostComponent, 'find', function () {
-        return [
-          {
-            id: 'TASKTRACKER_host1',
-            componentName: 'TASKTRACKER'
-          }
-        ];
-      });
       controller.set('content', {
         hostComponents: [Em.Object.create({
           componentName: 'TASKTRACKER',
@@ -1971,17 +2032,9 @@ describe('App.MainHostDetailsController', function () {
         })]
       });
       expect(controller.getHostComponentsInfo().lastComponents).to.eql(['TaskTracker']);
-      App.HostComponent.find.restore();
     });
+
     it('content.hostComponents has master non-deletable component', function () {
-      sinon.stub(App.HostComponent, 'find', function () {
-        return [
-          {
-            id: 'TASKTRACKER_host1',
-            componentName: 'TASKTRACKER'
-          }
-        ];
-      });
       controller.set('content', {
         hostComponents: [Em.Object.create({
           componentName: 'TASKTRACKER',
@@ -1993,17 +2046,9 @@ describe('App.MainHostDetailsController', function () {
       });
       expect(controller.getHostComponentsInfo().masterComponents).to.eql(['ZK1']);
       expect(controller.getHostComponentsInfo().nonDeletableComponents).to.eql(['ZK1']);
-      App.HostComponent.find.restore();
     });
+
     it('content.hostComponents has running component', function () {
-      sinon.stub(App.HostComponent, 'find', function () {
-        return [
-          {
-            id: 'TASKTRACKER_host1',
-            componentName: 'TASKTRACKER'
-          }
-        ];
-      });
       controller.set('content', {
         hostComponents: [Em.Object.create({
           componentName: 'TASKTRACKER',
@@ -2013,17 +2058,9 @@ describe('App.MainHostDetailsController', function () {
         })]
       });
       expect(controller.getHostComponentsInfo().runningComponents).to.eql(['ZK1']);
-      App.HostComponent.find.restore();
     });
+
     it('content.hostComponents has non-deletable component', function () {
-      sinon.stub(App.HostComponent, 'find', function () {
-        return [
-          {
-            id: 'TASKTRACKER_host1',
-            componentName: 'TASKTRACKER'
-          }
-        ];
-      });
       controller.set('content', {
         hostComponents: [Em.Object.create({
           componentName: 'TASKTRACKER',
@@ -2033,17 +2070,9 @@ describe('App.MainHostDetailsController', function () {
         })]
       });
       expect(controller.getHostComponentsInfo().nonDeletableComponents).to.eql(['ZK1']);
-      App.HostComponent.find.restore();
     });
+
     it('content.hostComponents has component with UNKNOWN state', function () {
-      sinon.stub(App.HostComponent, 'find', function () {
-        return [
-          {
-            id: 'TASKTRACKER_host1',
-            componentName: 'TASKTRACKER'
-          }
-        ];
-      });
       controller.set('content', {
         hostComponents: [Em.Object.create({
           componentName: 'TASKTRACKER',
@@ -2053,8 +2082,8 @@ describe('App.MainHostDetailsController', function () {
         })]
       });
       expect(controller.getHostComponentsInfo().unknownComponents).to.eql(['ZK1']);
-      App.HostComponent.find.restore();
     });
+
   });
 
   describe('#validateAndDeleteHost()', function () {
@@ -2171,16 +2200,22 @@ describe('App.MainHostDetailsController', function () {
   });
 
   describe('#confirmDeleteHost()', function () {
-    it('Popup should be displayed', function () {
+
+    beforeEach(function () {
       sinon.spy(App.ModalPopup, "show");
       sinon.stub(controller, 'doDeleteHost');
+    });
+
+    afterEach(function () {
+      App.ModalPopup.show.restore();
+      controller.doDeleteHost.restore();
+    });
 
+    it('Popup should be displayed', function () {
       var popup = controller.confirmDeleteHost({toDecommissionComponents:[]});
       expect(App.ModalPopup.show.calledOnce).to.be.true;
       popup.onPrimary();
       expect(controller.doDeleteHost.calledOnce).to.be.true;
-      App.ModalPopup.show.restore();
-      controller.doDeleteHost.restore();
     });
   });
 
@@ -2550,11 +2585,18 @@ describe('App.MainHostDetailsController', function () {
   });
 
   describe('#refreshComponentConfigsSuccessCallback()', function () {
-    it('call showBackgroundOperationsPopup', function () {
+
+    beforeEach(function () {
       sinon.stub(controller, 'showBackgroundOperationsPopup', Em.K);
+    });
+
+    afterEach(function () {
+      controller.showBackgroundOperationsPopup.restore();
+    });
+
+    it('call showBackgroundOperationsPopup', function () {
       controller.refreshComponentConfigsSuccessCallback();
       expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
-      controller.showBackgroundOperationsPopup.restore();
     });
   });
 
@@ -2562,24 +2604,25 @@ describe('App.MainHostDetailsController', function () {
     beforeEach(function () {
       sinon.stub(controller, 'removeObserver');
       sinon.stub(controller, 'loadConfigs');
-      sinon.stub(controller, 'isServiceMetricsLoaded', function (callback) {
-        callback();
-      });
+      sinon.stub(controller, 'isServiceMetricsLoaded', Em.clb);
+      this.stub = sinon.stub(App.router, 'get');
     });
     afterEach(function () {
       controller.loadConfigs.restore();
       controller.removeObserver.restore();
       controller.isServiceMetricsLoaded.restore();
-      App.router.get.restore();
+      this.stub.restore();
     });
+
     it('No operations of ZOOKEEPER_SERVER', function () {
-      sinon.stub(App.router, 'get').withArgs('backgroundOperationsController.services').returns([]);
+      this.stub.withArgs('backgroundOperationsController.services').returns([]);
       controller.checkZkConfigs();
       expect(controller.removeObserver.called).to.be.false;
       expect(controller.loadConfigs.called).to.be.false;
     });
+
     it('Operation of ZOOKEEPER_SERVER running', function () {
-      sinon.stub(App.router, 'get').withArgs('backgroundOperationsController.services').returns([Em.Object.create({
+      this.stub.withArgs('backgroundOperationsController.services').returns([Em.Object.create({
         id: 1,
         isRunning: true
       })]);
@@ -2588,17 +2631,28 @@ describe('App.MainHostDetailsController', function () {
       expect(controller.removeObserver.called).to.be.false;
       expect(controller.loadConfigs.called).to.be.false;
     });
-    it('Operation of ZOOKEEPER_SERVER finished', function () {
-      sinon.stub(App.router, 'get').withArgs('backgroundOperationsController.services').returns([Em.Object.create({
-        id: 1
-      })]);
-      var clock = sinon.useFakeTimers();
-      controller.set('zkRequestId', 1);
-      controller.checkZkConfigs();
-      expect(controller.removeObserver.calledWith('App.router.backgroundOperationsController.serviceTimestamp', controller, controller.checkZkConfigs)).to.be.true;
-      clock.tick(App.get('componentsUpdateInterval'));
-      expect(controller.loadConfigs.calledOnce).to.be.true;
-      clock.restore();
+
+    describe('Operation of ZOOKEEPER_SERVER finished', function () {
+
+      beforeEach(function () {
+        this.stub.withArgs('backgroundOperationsController.services').returns([Em.Object.create({
+          id: 1
+        })]);
+        this.clock = sinon.useFakeTimers();
+        controller.set('zkRequestId', 1);
+        controller.checkZkConfigs();
+      });
+
+      afterEach(function () {
+        this.clock.restore();
+      });
+
+      it('loadConfigs is called after `componentsUpdateInterval`', function () {
+        expect(controller.removeObserver.calledWith('App.router.backgroundOperationsController.serviceTimestamp', controller, controller.checkZkConfigs)).to.be.true;
+        this.clock.tick(App.get('componentsUpdateInterval'));
+        expect(controller.loadConfigs.calledOnce).to.be.true;
+      });
+
     });
   });
 
@@ -2613,21 +2667,15 @@ describe('App.MainHostDetailsController', function () {
     beforeEach(function () {
       sinon.stub(controller, 'showBackgroundOperationsPopup', Em.K);
       sinon.stub(controller, 'mimicWorkStatusChange', Em.K);
+      sinon.stub(App, 'get').withArgs('testMode').returns(false);
     });
     afterEach(function () {
       controller.mimicWorkStatusChange.restore();
       controller.showBackgroundOperationsPopup.restore();
+      App.get.restore();
     });
-    it('testMode is true', function () {
-      App.set('testMode', true);
 
-      controller.installComponentSuccessCallback({}, {}, {component: "COMP"});
-      expect(controller.mimicWorkStatusChange.calledWith("COMP", App.HostComponentStatus.installing, App.HostComponentStatus.stopped)).to.be.true;
-      expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
-    });
     it('testMode is false', function () {
-      App.set('testMode', false);
-
       controller.installComponentSuccessCallback({}, {}, {component: "COMP"});
       expect(controller.mimicWorkStatusChange.called).to.be.false;
       expect(controller.showBackgroundOperationsPopup.calledOnce).to.be.true;
@@ -2635,21 +2683,35 @@ describe('App.MainHostDetailsController', function () {
   });
 
   describe('#showHbaseActiveWarning()', function () {
-    it('popup should be displayed', function () {
+
+    beforeEach(function () {
       sinon.spy(App.ModalPopup, "show");
-      var popup = controller.showHbaseActiveWarning(Em.Object.create({service: {}}));
-      expect(App.ModalPopup.show.calledOnce).to.be.true;
+    });
+
+    afterEach(function () {
       App.ModalPopup.show.restore();
     });
+
+    it('popup should be displayed', function () {
+      controller.showHbaseActiveWarning(Em.Object.create({service: {}}));
+      expect(App.ModalPopup.show.calledOnce).to.be.true;
+    });
   });
 
   describe('#updateHost()', function () {
-    it('popup should be displayed', function () {
+
+    beforeEach(function () {
       sinon.stub(batchUtils, "infoPassiveState", Em.K);
+    });
+
+    afterEach(function () {
+      batchUtils.infoPassiveState.restore();
+    });
+
+    it('popup should be displayed', function () {
       controller.updateHost({}, {}, {passive_state: 'state'});
       expect(controller.get('content.passiveState')).to.equal('state');
       expect(batchUtils.infoPassiveState.calledWith('state')).to.be.true;
-      batchUtils.infoPassiveState.restore();
     });
   });
 
@@ -2671,16 +2733,24 @@ describe('App.MainHostDetailsController', function () {
   });
 
   describe('#updateHostComponent()', function () {
-    it('popup should be displayed', function () {
+
+    var params = {
+      component: Em.Object.create(),
+      passive_state: 'state'
+    };
+
+    beforeEach(function () {
       sinon.stub(batchUtils, "infoPassiveState", Em.K);
-      var params = {
-        component: Em.Object.create(),
-        passive_state: 'state'
-      };
+    });
+
+    afterEach(function () {
+      batchUtils.infoPassiveState.restore();
+    });
+
+    it('popup should be displayed', function () {
       controller.updateHostComponent({}, {}, params);
       expect(params.component.get('passiveState')).to.equal('state');
       expect(batchUtils.infoPassiveState.calledWith('state')).to.be.true;
-      batchUtils.infoPassiveState.restore();
     });
   });
 
@@ -2833,40 +2903,69 @@ describe('App.MainHostDetailsController', function () {
     });
 
     cases.forEach(function (item) {
-      it(item.title, function () {
-        sinon.stub(controller, 'checkComponentDependencies', function (componentName, params) {
-          return item.dependencies[componentName];
+      describe(item.title, function () {
+
+        beforeEach(function () {
+          sinon.stub(controller, 'checkComponentDependencies', function (componentName, params) {
+            return item.dependencies[componentName];
+          });
+          controller.installClients({
+            context: item.context
+          });
+        });
+
+        it('getSecurityType is ' + (item.getKDCSessionStateCalled ? '' : 'not') + ' called', function() {
+          expect(App.get('router.mainAdminKerberosController').getSecurityType.calledOnce).to.equal(item.getKDCSessionStateCalled);
+        });
+
+        it('getKDCSessionState is ' + (item.getKDCSessionStateCalled ? '' : 'not') + ' called', function() {
+          expect(App.get('router.mainAdminKerberosController').getKDCSessionState.calledOnce).to.equal(item.getKDCSessionStateCalled);
+        });
+
+        it('sendComponentCommand is ' + (item.sendComponentCommandCalled ? '' : 'not') + ' called', function() {
+          expect(controller.sendComponentCommand.calledOnce).to.equal(item.sendComponentCommandCalled);
         });
-        controller.installClients({
-          context: item.context
+
+        it('showAlertPopup is ' + (item.showAlertPopupCalled ? '' : 'not') + ' called', function() {
+          expect(App.showAlertPopup.calledOnce).to.equal(item.showAlertPopupCalled);
         });
-        expect(App.get('router.mainAdminKerberosController').getSecurityType.calledOnce).to.equal(item.getKDCSessionStateCalled);
-        expect(App.get('router.mainAdminKerberosController').getKDCSessionState.calledOnce).to.equal(item.getKDCSessionStateCalled);
-        expect(controller.sendComponentCommand.calledOnce).to.equal(item.sendComponentCommandCalled);
-        expect(App.showAlertPopup.calledOnce).to.equal(item.showAlertPopupCalled);
+
       });
     });
   });
 
   describe("#executeCustomCommandSuccessCallback()", function () {
-    it("BO popup should be shown", function () {
-      var mock = {
-        showPopup: Em.K
-      };
-      sinon.stub(App.router, 'get').returns(mock);
-      sinon.spy(mock, 'showPopup');
-      var data = {
+
+    var data;
+    var mock;
+
+    beforeEach(function () {
+      data = {
         Requests: {
           id: 1
         }
       };
+      mock = {
+        showPopup: Em.K
+      };
+      sinon.stub(App.router, 'get').returns(mock);
+      sinon.spy(mock, 'showPopup');
       controller.executeCustomCommandSuccessCallback(data, {}, {});
+    });
 
-      expect(App.router.get.calledWith('backgroundOperationsController')).to.be.true;
-      expect(mock.showPopup.calledOnce).to.be.true;
+    afterEach(function () {
       App.router.get.restore();
       mock.showPopup.restore();
     });
+
+    it('App.router.get is called with `backgroundOperationsController`', function () {
+      expect(App.router.get.calledWith('backgroundOperationsController')).to.be.true;
+    });
+
+    it('showPopup is called once', function () {
+      expect(mock.showPopup.calledOnce).to.be.true;
+    });
+
   });
 
   describe("#executeCustomCommandErrorCallback()", function () {
@@ -2893,7 +2992,7 @@ describe('App.MainHostDetailsController', function () {
       expect(App.showAlertPopup.calledWith(Em.I18n.t('services.service.actions.run.executeCustomCommand.error'), Em.I18n.t('services.service.actions.run.executeCustomCommand.error'))).to.be.true;
       expect($.parseJSON.called).to.be.false;
     });
-    it("data empty", function () {
+    it("data empty (2)", function () {
       var data = {
         responseText: "test"
       };
@@ -2936,8 +3035,9 @@ describe('App.MainHostDetailsController', function () {
   });
 
   describe("#deleteHostSuccessCallback", function () {
-    it("call updateHost", function () {
-      var mock = {
+    var mock;
+    beforeEach(function () {
+      mock = {
         updateHost: function (callback) {
           callback();
         },
@@ -2948,18 +3048,11 @@ describe('App.MainHostDetailsController', function () {
       sinon.spy(mock, 'getAllHostNames');
       sinon.stub(controller, 'loadConfigs', Em.K);
       sinon.stub(App.router, 'transitionTo', Em.K);
-      sinon.stub(controller, 'isServiceMetricsLoaded', function (callback) {
-        callback();
-      });
-
+      sinon.stub(controller, 'isServiceMetricsLoaded', Em.clb);
       controller.deleteHostSuccessCallback();
-      expect(App.router.get.calledWith('updateController')).to.be.true;
-      expect(mock.updateHost.calledOnce).to.be.true;
-      expect(controller.loadConfigs.called).to.be.false;
-      expect(App.router.transitionTo.calledWith('hosts.index')).to.be.true;
-      expect(App.router.get.calledWith('clusterController')).to.be.true;
-      expect(mock.getAllHostNames.calledOnce).to.be.true;
+    });
 
+    afterEach(function () {
       App.router.get.restore();
       mock.updateHost.restore();
       mock.getAllHostNames.restore();
@@ -2967,25 +3060,51 @@ describe('App.MainHostDetailsController', function () {
       controller.isServiceMetricsLoaded.restore();
       App.router.transitionTo.restore();
     });
+
+    it('updateController is used', function () {
+      expect(App.router.get.calledWith('updateController')).to.be.true;
+    });
+    it('updateHost is called once', function () {
+      expect(mock.updateHost.calledOnce).to.be.true;
+    });
+    it('loadConfigs is not called', function () {
+      expect(controller.loadConfigs.called).to.be.false;
+    });
+    it('user is moved to the hosts', function () {
+      expect(App.router.transitionTo.calledWith('hosts.index')).to.be.true;
+    });
+    it('clusterController is used', function () {
+      expect(App.router.get.calledWith('clusterController')).to.be.true;
+    });
+    it('getAllHostNames is called once', function () {
+      expect(mock.getAllHostNames.calledOnce).to.be.true;
+    });
   });
 
   describe("#deleteHostErrorCallback", function () {
-    it("call defaultErrorHandler", function () {
+
+    beforeEach(function () {
       sinon.stub(controller, 'loadConfigs', Em.K);
       sinon.stub(App.ajax, 'defaultErrorHandler', Em.K);
-      sinon.stub(controller, 'isServiceMetricsLoaded', function (callback) {
-        callback();
-      });
+      sinon.stub(controller, 'isServiceMetricsLoaded', Em.clb);
       controller.deleteHostErrorCallback({
         status: 'status',
         statusText: "statusText"
       }, 'textStatus', 'errorThrown', {url: 'url'});
-      expect(controller.loadConfigs.calledOnce).to.be.true;
-      expect(App.ajax.defaultErrorHandler.calledOnce).to.be.true;
+    });
+
+    afterEach(function () {
       App.ajax.defaultErrorHandler.restore();
       controller.loadConfigs.restore();
       controller.isServiceMetricsLoaded.restore();
     });
+
+    it('loadConfigs is called once', function () {
+      expect(controller.loadConfigs.calledOnce).to.be.true;
+    });
+    it('defaultErrorHandler is called once', function () {
+      expect(App.ajax.defaultErrorHandler.calledOnce).to.be.true;
+    });
   });
 
   describe('#installVersionConfirmation()', function () {
@@ -3157,19 +3276,33 @@ describe('App.MainHostDetailsController', function () {
     });
 
     cases.forEach(function (item) {
-      it(item.title, function () {
-        Em.keys(item.input).forEach(function (key) {
-          controller.set(key, item.input[key]);
+      describe(item.title, function () {
+
+        beforeEach(function () {
+          Em.keys(item.input).forEach(function (key) {
+            controller.set(key, item.input[key]);
+          });
+          this.hostsMap = controller.getHiveHosts().toArray();
+          this.expectedHosts = this.hostsMap.filter(function(hostInfo) {
+            return ['WEBHCAT_SERVER', 'HIVE_METASTORE'].contains(hostInfo.component) && hostInfo.isInstalled === true;
+          }).mapProperty('hostName').uniq();
+        });
+
+        it(JSON.stringify(item.hiveHosts) + ' are in the list', function () {
+          expect(this.expectedHosts).to.include.same.members(item.hiveHosts);
+        });
+        it('hiveMetastoreHost is empty', function () {
+          expect(controller.get('hiveMetastoreHost')).to.be.empty;
+        });
+        it('webhcatServerHost is empty', function () {
+          expect(controller.get('webhcatServerHost')).to.be.empty;
+        });
+        it('fromDeleteHost is false', function () {
+          expect(controller.get('fromDeleteHost')).to.be.false;
+        });
+        it('deleteHiveMetaStore is false', function () {
+          expect(controller.get('deleteHiveMetaStore')).to.be.false;
         });
-        var hostsMap = controller.getHiveHosts().toArray();
-        var expectedHosts = hostsMap.filter(function(hostInfo) {
-          return ['WEBHCAT_SERVER', 'HIVE_METASTORE'].contains(hostInfo.component) && hostInfo.isInstalled === true;
-        }).mapProperty('hostName').uniq();
-        expect(expectedHosts).to.include.same.members(item.hiveHosts);
-        expect(controller.get('hiveMetastoreHost')).to.be.empty;
-        expect(controller.get('webhcatServerHost')).to.be.empty;
-        expect(controller.get('fromDeleteHost')).to.be.false;
-        expect(controller.get('deleteHiveMetaStore')).to.be.false;
       });
     });
 
@@ -3225,9 +3358,8 @@ describe('App.MainHostDetailsController', function () {
     });
 
     cases.forEach(function (item) {
-      it(item.title, function () {
-        controller.set('rangerKMSServerHost', item.hostToInstall);
-        sinon.stub(controller, 'getRangerKMSServerHosts').returns(item.kmsHosts);
+      describe(item.title, function () {
+
         var data = {
           items: [
             {
@@ -3244,8 +3376,16 @@ describe('App.MainHostDetailsController', function () {
             }
           ]
         };
-        controller.onLoadRangerConfigs(data);
-        expect(controller.saveConfigsBatch.calledWith(item.result, 'RANGER_KMS_SERVER', item.hostToInstall)).to.be.true;
+
+        beforeEach(function () {
+          controller.set('rangerKMSServerHost', item.hostToInstall);
+          sinon.stub(controller, 'getRangerKMSServerHosts').returns(item.kmsHosts);
+          controller.onLoadRangerConfigs(data);
+        });
+
+        it('saveConfigsBatch is called with valid arguments', function () {
+          expect(controller.saveConfigsBatch.calledWith(item.result, 'RANGER_KMS_SERVER', item.hostToInstall)).to.be.true;
+        });
       });
     });
 
@@ -3757,26 +3897,40 @@ describe('App.MainHostDetailsController', function () {
     ];
 
     tests.forEach(function(test) {
-      it(test.m.format(inlineComponentHostInfo(test.hostComponentModel), test.ctrlStubs ? JSON.stringify(test.ctrlStubs) : 'None'), function() {
-        if (test.appGetterStubs) {
-          Em.keys(test.appGetterStubs).forEach(function(key) {
-            sinon.stub(App, 'get').withArgs(key).returns(test.appGetterStubs[key]);
-          });
-        }
-        if (test.ctrlStubs) {
-          var stub = sinon.stub(controller, 'get');
-          Em.keys(test.ctrlStubs).forEach(function(key) {
-            stub.withArgs(key).returns(test.ctrlStubs[key]);
-          });
-        }
-        sinon.stub(App.HostComponent, 'find').returns(test.hostComponentModel);
-        controller.onLoadHiveConfigs(test.configs);
-        var configs = controller.saveConfigsBatch.args[0];
-        var properties = configs[0];
-        expect(properties).to.be.eql(test.e.configs);
-        if (test.ctrlStubs) controller.get.restore();
-        if (test.appGetterStubs) App.get.restore();
-        App.HostComponent.find.restore();
+      describe(test.m.format(inlineComponentHostInfo(test.hostComponentModel), test.ctrlStubs ? JSON.stringify(test.ctrlStubs) : 'None'), function() {
+
+        beforeEach(function () {
+          if (test.appGetterStubs) {
+            Em.keys(test.appGetterStubs).forEach(function(key) {
+              sinon.stub(App, 'get').withArgs(key).returns(test.appGetterStubs[key]);
+            });
+          }
+          if (test.ctrlStubs) {
+            var stub = sinon.stub(controller, 'get');
+            Em.keys(test.ctrlStubs).forEach(function(key) {
+              stub.withArgs(key).returns(test.ctrlStubs[key]);
+            });
+          }
+          sinon.stub(App.HostComponent, 'find').returns(test.hostComponentModel);
+        });
+
+        afterEach(function () {
+          if (test.ctrlStubs) {
+            controller.get.restore();
+          }
+          if (test.appGetterStubs) {
+            App.get.restore();
+          }
+          App.HostComponent.find.restore();
+        });
+
+        it('saveConfigsBatch is called with correct configs', function () {
+          controller.onLoadHiveConfigs(test.configs);
+          var configs = controller.saveConfigsBatch.args[0];
+          var properties = configs[0];
+          expect(properties).to.be.eql(test.e.configs);
+        });
+
       });
     });
   });

+ 79 - 30
ambari-web/test/controllers/main/service/add_controller_test.js

@@ -150,16 +150,31 @@ describe('App.AddServiceController', function() {
 
     var message = '{0} installed, {1} selected. Installed list should be {2} and selected - {3}';
     tests.forEach(function(test) {
+
       var installed = test.appService.mapProperty('serviceName');
       var selected = test.stepCtrlContent.get('content').filterProperty('isSelected', true)
         .filterProperty('isInstalled', false).mapProperty('serviceName');
-      it(message.format(installed, selected, test.e.installed, test.e.selected), function() {
-        sinon.stub(App.Service, 'find').returns(test.appService);
-        addServiceController.saveServices(test.stepCtrlContent);
-        App.Service.find.restore();
-        var savedServices = addServiceController.setDBProperty.withArgs('services').args[0][1];
-        expect(savedServices.selectedServices).to.have.members(test.e.selected);
-        expect(savedServices.installedServices).to.have.members(test.e.installed);
+
+      describe(message.format(installed, selected, test.e.installed, test.e.selected), function() {
+
+        beforeEach(function () {
+          sinon.stub(App.Service, 'find').returns(test.appService);
+          addServiceController.saveServices(test.stepCtrlContent);
+          this.savedServices = addServiceController.setDBProperty.withArgs('services').args[0][1];
+        });
+
+        afterEach(function () {
+          App.Service.find.restore();
+        });
+
+        it(JSON.stringify(test.e.selected) + ' are in the selectedServices', function () {
+          expect(this.savedServices.selectedServices).to.have.members(test.e.selected);
+        });
+
+        it(JSON.stringify(test.e.installed) + ' are in the installedServices', function () {
+          expect(this.savedServices.installedServices).to.have.members(test.e.installed);
+        });
+
       });
     });
   });
@@ -193,10 +208,16 @@ describe('App.AddServiceController', function() {
     });
 
     cases.forEach(function (item) {
-      it(item.title, function () {
-        sinon.stub(addServiceController, 'getDBProperty').withArgs('hosts').returns(item.hosts);
-        addServiceController.loadHosts();
-        expect(App.ajax.send.calledOnce).to.equal(item.isAjaxRequestSent);
+      describe(item.title, function () {
+
+        beforeEach(function () {
+          sinon.stub(addServiceController, 'getDBProperty').withArgs('hosts').returns(item.hosts);
+          addServiceController.loadHosts();
+        });
+
+        it('request is ' + (item.isAjaxRequestSent ? '' : 'not') + ' sent', function () {
+          expect(App.ajax.send.calledOnce).to.equal(item.isAjaxRequestSent);
+        });
       });
     });
 
@@ -407,22 +428,40 @@ describe('App.AddServiceController', function() {
     ];
 
     tests.forEach(function(test) {
-      it(test.m, function() {
-        this.mockStackService.returns(test.appStackService);
-        this.mockService.returns(test.appService);
-        this.mockGetDBProperty.withArgs('services').returns(test.servicesFromDB);
-        this.controller.set('serviceToInstall', test.serviceToInstall);
-        this.controller.loadServices();
-        if (!test.servicesFromDB) {
-          // verify saving to local db on first enter to the wizard
-          expect(mock.db.selectedServices).to.be.eql(test.e.selectedServices);
-          expect(mock.db.installedServices).to.be.eql(test.e.installedServices);
-        } else {
+      describe(test.m, function() {
+
+        beforeEach(function () {
+          this.mockStackService.returns(test.appStackService);
+          this.mockService.returns(test.appService);
+          this.mockGetDBProperty.withArgs('services').returns(test.servicesFromDB);
+          this.controller.set('serviceToInstall', test.serviceToInstall);
+          this.controller.loadServices();
+        });
+
+        if (test.servicesFromDB) {
           // verify values for App.StackService
-          expect(test.appStackService.filterProperty('isSelected', true).mapProperty('serviceName')).to.be.eql(test.e.selectedServices);
-          expect(test.appStackService.filterProperty('isInstalled', true).mapProperty('serviceName')).to.be.eql(test.e.installedServices);
+          it(JSON.stringify(test.e.selectedServices) + ' are selected', function () {
+            expect(test.appStackService.filterProperty('isSelected', true).mapProperty('serviceName')).to.be.eql(test.e.selectedServices);
+          });
+          it(JSON.stringify(test.e.installedServices) + ' are installed', function () {
+            expect(test.appStackService.filterProperty('isInstalled', true).mapProperty('serviceName')).to.be.eql(test.e.installedServices);
+          });
+        }
+        else {
+          // verify saving to local db on first enter to the wizard
+          it('selectedServices are saced', function () {
+            expect(mock.db.selectedServices).to.be.eql(test.e.selectedServices);
+          });
+          it('installedServices are saved', function () {
+            expect(mock.db.installedServices).to.be.eql(test.e.installedServices);
+          });
+
         }
-        expect(this.controller.get('serviceToInstall')).to.be.null;
+
+        it('serviceToInstall is null', function () {
+          expect(this.controller.get('serviceToInstall')).to.be.null;
+        });
+
       });
     }, this);
   });
@@ -461,11 +500,21 @@ describe('App.AddServiceController', function() {
     });
 
     cases.forEach(function (item) {
-      it(item.title, function () {
-        sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(item.securityEnabled);
-        addServiceController.checkSecurityStatus();
-        expect(addServiceController.get('skipConfigureIdentitiesStep')).to.equal(item.skipConfigureIdentitiesStep);
-        expect(addServiceController.get('isStepDisabled').findProperty('step', 5).get('value')).to.equal(item.isStep5Disabled);
+      describe(item.title, function () {
+
+        beforeEach(function () {
+          sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(item.securityEnabled);
+          addServiceController.checkSecurityStatus();
+        });
+
+        it('skipConfigureIdentitiesStep is ' + item.skipConfigureIdentitiesStep, function () {
+          expect(addServiceController.get('skipConfigureIdentitiesStep')).to.equal(item.skipConfigureIdentitiesStep);
+        });
+
+        it('step 5 is ' + (item.isStep5Disabled ? 'disabved' : 'enabled'), function () {
+          expect(addServiceController.get('isStepDisabled').findProperty('step', 5).get('value')).to.equal(item.isStep5Disabled);
+        });
+
       });
     });
 

+ 65 - 29
ambari-web/test/controllers/main/service/info/config_test.js

@@ -134,6 +134,7 @@ describe("App.MainServiceInfoConfigsController", function () {
         return "hash"
       });
     });
+
     afterEach(function () {
       mainServiceInfoConfigsController.get.restore();
       mainServiceInfoConfigsController.restartServicePopup.restore();
@@ -142,24 +143,45 @@ describe("App.MainServiceInfoConfigsController", function () {
 
     tests.forEach(function (t) {
       t.results.forEach(function (r) {
-        it(t.m + " " + r.method + " " + r.field, function () {
-          if (t.callback) {
-            t.callback = sinon.stub();
-          }
-          if (t.transitionCallback) {
-            t.transitionCallback = sinon.stub();
-          }
-          mainServiceInfoConfigsController.showSavePopup(t.transitionCallback, t.callback)[t.action]();
+        describe(t.m + " " + r.method + " " + r.field, function () {
+
+          beforeEach(function () {
+            if (t.callback) {
+              t.callback = sinon.stub();
+            }
+            if (t.transitionCallback) {
+              t.transitionCallback = sinon.stub();
+            }
+            mainServiceInfoConfigsController.showSavePopup(t.transitionCallback, t.callback)[t.action]();
+          });
+
+
           if (r.method) {
             if (r.method === 'callback') {
-              expect(t.callback.calledOnce).to.equal(r.called);
-            } else if (r.method === 'transitionCallback') {
-              expect(t.transitionCallback.calledOnce).to.equal(r.called);
-            } else {
-              expect(mainServiceInfoConfigsController[r.method].calledOnce).to.equal(r.called);
+              it('callback is ' + (r.called ? '' : 'not') + ' called once', function () {
+                expect(t.callback.calledOnce).to.equal(r.called);
+              });
+            }
+            else {
+              if (r.method === 'transitionCallback') {
+                it('transitionCallback is ' + (r.called ? '' : 'not') + ' called once', function () {
+                  expect(t.transitionCallback.calledOnce).to.equal(r.called);
+                });
+              }
+              else {
+                it(r.method + ' is ' + (r.called ? '' : 'not') + ' called once', function () {
+                  expect(mainServiceInfoConfigsController[r.method].calledOnce).to.equal(r.called);
+                });
+              }
+            }
+          }
+          else {
+            if (r.field) {
+              it(r.field + ' is equal to ' + r.value, function () {
+                expect(mainServiceInfoConfigsController.get(r.field)).to.equal(r.value);
+              });
+
             }
-          } else if (r.field) {
-            expect(mainServiceInfoConfigsController.get(r.field)).to.equal(r.value);
           }
         }, this);
       });
@@ -324,17 +346,21 @@ describe("App.MainServiceInfoConfigsController", function () {
   });
 
   describe("#restartAllStaleConfigComponents", function () {
+
     beforeEach(function () {
       sinon.stub(batchUtils, "restartAllServiceHostComponents", Em.K);
     });
+
     afterEach(function () {
       batchUtils.restartAllServiceHostComponents.restore();
     });
+
     it("trigger restartAllServiceHostComponents", function () {
       mainServiceInfoConfigsController.restartAllStaleConfigComponents().onPrimary();
       expect(batchUtils.restartAllServiceHostComponents.calledOnce).to.equal(true);
     });
-    it("trigger check last check point warning before triggering restartAllServiceHostComponents", function () {
+
+    describe("trigger check last check point warning before triggering restartAllServiceHostComponents", function () {
       var mainConfigsControllerHdfsStarted = App.MainServiceInfoConfigsController.create({
         content: {
           serviceName: "HDFS",
@@ -349,20 +375,30 @@ describe("App.MainServiceInfoConfigsController", function () {
         }
       });
       var mainServiceItemController = App.MainServiceItemController.create({});
-      sinon.stub(mainServiceItemController, 'checkNnLastCheckpointTime', function() {
-        return true;
+
+      beforeEach(function () {
+        sinon.stub(mainServiceItemController, 'checkNnLastCheckpointTime', function() {
+          return true;
+        });
+        sinon.stub(App.router, 'get', function(k) {
+          if ('mainServiceItemController' === k) {
+            return mainServiceItemController;
+          }
+          return Em.get(App.router, k);
+        });
+        mainConfigsControllerHdfsStarted.restartAllStaleConfigComponents();
       });
-      sinon.stub(App.router, 'get', function(k) {
-        if ('mainServiceItemController' === k) {
-          return mainServiceItemController;
-        }
-        return Em.get(App.router, k);
+
+      afterEach(function () {
+        mainServiceItemController.checkNnLastCheckpointTime.restore();
+        App.router.get.restore();
+      });
+
+      it('checkNnLastCheckpointTime is called once', function () {
+        expect(mainServiceItemController.checkNnLastCheckpointTime.calledOnce).to.equal(true);
       });
 
-      mainConfigsControllerHdfsStarted.restartAllStaleConfigComponents();
-      expect(mainServiceItemController.checkNnLastCheckpointTime.calledOnce).to.equal(true);
-      mainServiceItemController.checkNnLastCheckpointTime.restore();
-      App.router.get.restore();
+
     });
   });
 
@@ -713,10 +749,10 @@ describe("App.MainServiceInfoConfigsController", function () {
     it("expect that serviceConfig.compareConfigs will be getComparisonConfig", function() {
       expect(mainServiceInfoConfigsController.setCompareDefaultGroupConfig({isUserProperty: true}, {})).to.eql({compareConfigs: ["compConfig"], isUserProperty: true, isComparison: true, hasCompareDiffs: true});
     });
-    it("expect that serviceConfig.compareConfigs will be getComparisonConfig", function() {
+    it("expect that serviceConfig.compareConfigs will be getComparisonConfig (2)", function() {
       expect(mainServiceInfoConfigsController.setCompareDefaultGroupConfig({isReconfigurable: true}, {})).to.eql({compareConfigs: ["compConfig"], isReconfigurable: true, isComparison: true, hasCompareDiffs: true});
     });
-    it("expect that serviceConfig.compareConfigs will be getComparisonConfig", function() {
+    it("expect that serviceConfig.compareConfigs will be getComparisonConfig (3)", function() {
       expect(mainServiceInfoConfigsController.setCompareDefaultGroupConfig({isReconfigurable: true, isMock: true}, {})).to.eql({compareConfigs: ["compConfig"], isReconfigurable: true, isMock: true, isComparison: true, hasCompareDiffs: true});
     });
     it("property was created during upgrade and have no comparison, compare with 'Undefined' value should be created", function() {

+ 95 - 46
ambari-web/test/controllers/main/service/item_test.js

@@ -107,15 +107,27 @@ describe('App.MainServiceItemController', function () {
     ];
 
     tests.forEach(function (test) {
-      it(test.m, function () {
-        sinon.stub(App.router, 'get', function(k) {
-          if ('backgroundOperationsController.services' === k) return test.backgroundOperationsController.services;
-          return Em.get(App.router, k);
+      describe(test.m, function () {
+
+        var mainServiceItemController;
+
+        beforeEach(function () {
+          sinon.stub(App.router, 'get', function(k) {
+            if ('backgroundOperationsController.services' === k) return test.backgroundOperationsController.services;
+            return Em.get(App.router, k);
+          });
+          mainServiceItemController = App.MainServiceItemController.create({content: {serviceName: test.serviceController.serviceName}});
+          mainServiceItemController.setStartStopState();
+        });
+
+        afterEach(function () {
+          App.router.get.restore();
+        });
+
+        it('isPending is ' + test.isPending, function () {
+          expect(mainServiceItemController.get('isPending')).to.equal(test.isPending);
         });
-        var mainServiceItemController = App.MainServiceItemController.create({content: {serviceName: test.serviceController.serviceName}});
-        mainServiceItemController.setStartStopState();
-        App.router.get.restore();
-        expect(mainServiceItemController.get('isPending')).to.equal(test.isPending);
+
       });
     })
   });
@@ -141,34 +153,41 @@ describe('App.MainServiceItemController', function () {
     ];
 
     tests.forEach(function (test) {
-      var reassignMasterController = App.ReassignMasterController.create({currentStep: ''});
+      describe(test.m, function () {
 
-      beforeEach(function () {
-        sinon.stub(reassignMasterController, 'saveComponentToReassign', Em.K);
-        sinon.stub(reassignMasterController, 'setCurrentStep', Em.K);
-      });
+        var reassignMasterController = App.ReassignMasterController.create({currentStep: ''});
 
-      afterEach(function () {
-        reassignMasterController.saveComponentToReassign.restore();
-        reassignMasterController.setCurrentStep.restore();
-      });
+        beforeEach(function () {
+          sinon.stub(reassignMasterController, 'saveComponentToReassign', Em.K);
+          sinon.stub(reassignMasterController, 'setCurrentStep', Em.K);
+          sinon.stub(App.router, 'transitionTo', Em.K);
+          var mainServiceItemController = App.MainServiceItemController.create({});
+          sinon.stub(App.HostComponent, 'find', function() {
+            return test.host_components
+          });
+          sinon.stub(App.router, 'get', function(k) {
+            if ('reassignMasterController' === k) return reassignMasterController;
+            return Em.get(App.router, k);
+          });
+          mainServiceItemController.reassignMaster(test.componentName);
+        });
 
-      it(test.m, function () {
-        sinon.stub(App.router, 'transitionTo', Em.K);
-        var mainServiceItemController = App.MainServiceItemController.create({});
-        sinon.stub(App.HostComponent, 'find', function() {
-          return test.host_components
+        afterEach(function () {
+          reassignMasterController.saveComponentToReassign.restore();
+          reassignMasterController.setCurrentStep.restore();
+          App.HostComponent.find.restore();
+          App.router.transitionTo.restore();
+          App.router.get.restore();
         });
-        sinon.stub(App.router, 'get', function(k) {
-          if ('reassignMasterController' === k) return reassignMasterController;
-          return Em.get(App.router, k);
+
+        it('saveComponentToReassign is ' + (test.result ? '' : 'not') + ' called once', function () {
+          expect(reassignMasterController.saveComponentToReassign.calledOnce).to.equal(test.result);
         });
-        mainServiceItemController.reassignMaster(test.componentName);
-        expect(reassignMasterController.saveComponentToReassign.calledOnce).to.equal(test.result);
-        expect(reassignMasterController.setCurrentStep.calledOnce).to.equal(test.result);
-        App.HostComponent.find.restore();
-        App.router.transitionTo.restore();
-        App.router.get.restore();
+
+        it('setCurrentStep is ' + (test.result ? '' : 'not') + ' called once', function () {
+          expect(reassignMasterController.setCurrentStep.calledOnce).to.equal(test.result);
+        });
+
       });
     }, this);
   });
@@ -966,7 +985,8 @@ describe('App.MainServiceItemController', function () {
   });
 
   describe("#runRebalancer", function () {
-    it("run rebalancer", function () {
+
+    beforeEach(function () {
       sinon.stub(App.router, 'get', function(k) {
         if ('applicationController' === k) {
           return Em.Object.create({
@@ -977,15 +997,22 @@ describe('App.MainServiceItemController', function () {
         }
         return Em.get(App.router, k);
       });
+    });
+
+    afterEach(function () {
+      App.router.get.restore();
+    });
+
+    it("run rebalancer", function () {
       var mainServiceItemController = App.MainServiceItemController.create({content: {runRebalancer: false}});
       mainServiceItemController.runRebalancer().onPrimary();
       expect(mainServiceItemController.get("content.runRebalancer")).to.equal(true);
-      App.router.get.restore();
     });
   });
 
   describe("#runCompaction", function () {
-    it("run compaction", function () {
+
+    beforeEach(function () {
       sinon.stub(App.router, 'get', function(k) {
         if ('applicationController' === k) {
           return Em.Object.create({
@@ -996,10 +1023,16 @@ describe('App.MainServiceItemController', function () {
         }
         return Em.get(App.router, k);
       });
+    });
+
+    afterEach(function () {
+      App.router.get.restore();
+    });
+
+    it("run compaction", function () {
       var mainServiceItemController = App.MainServiceItemController.create({content: {runCompaction: false}});
       mainServiceItemController.runCompaction().onPrimary();
       expect(mainServiceItemController.get("content.runCompaction")).to.equal(true);
-      App.router.get.restore();
     });
   });
 
@@ -1049,19 +1082,35 @@ describe('App.MainServiceItemController', function () {
 
       var mainServiceItemController = App.MainServiceItemController.create({content: {serviceName: test.data.serviceName,
         displayName: test.data.displayName}});
-      beforeEach(function () {
-        mainServiceItemController.set("runSmokeTestErrorCallBack", Em.K);
-        mainServiceItemController.set("runSmokeTestSuccessCallBack", Em.K);
-      });
+      describe('send request to run smoke test for ' + test.data.serviceName, function () {
 
-      it('send request to run smoke test for ' + test.data.serviceName, function () {
-        mainServiceItemController.runSmokeTestPrimary(test.data.query);
-        expect($.ajax.calledOnce).to.equal(true);
+        beforeEach(function () {
+          mainServiceItemController.set("runSmokeTestErrorCallBack", Em.K);
+          mainServiceItemController.set("runSmokeTestSuccessCallBack", Em.K);
+          mainServiceItemController.runSmokeTestPrimary(test.data.query);
+          this.data = JSON.parse($.ajax.args[0][0].data);
+        });
+
+        it('ajax request is sent', function () {
+          expect($.ajax.calledOnce).to.equal(true);
+        });
+
+        it('RequestInfo.context is valid', function () {
+          expect(this.data.RequestInfo.context).to.equal(test.RequestInfo.context);
+        });
+
+        it('RequestInfo.command is valid', function () {
+          expect(this.data.RequestInfo.command).to.equal(test.RequestInfo.command);
+        });
+
+        it('Requests/resource_filter.0.serviceName is valid', function () {
+          expect(this.data["Requests/resource_filters"][0].serviceName).to.equal(test["Requests/resource_filters"][0].serviceName);
+        });
+
+        it('RequestInfo.operation_level is valid', function () {
+          expect(this.data.RequestInfo.operation_level).to.be.deep.equal(test.RequestInfo.operation_level);
+        });
 
-        expect(JSON.parse($.ajax.args[0][0].data).RequestInfo.context).to.equal(test.RequestInfo.context);
-        expect(JSON.parse($.ajax.args[0][0].data).RequestInfo.command).to.equal(test.RequestInfo.command);
-        expect(JSON.parse($.ajax.args[0][0].data)["Requests/resource_filters"][0].serviceName).to.equal(test["Requests/resource_filters"][0].serviceName);
-        expect(JSON.parse($.ajax.args[0][0].data).RequestInfo.operation_level).to.be.deep.equal(test.RequestInfo.operation_level);
       });
     });
   });

+ 103 - 34
ambari-web/test/controllers/main/service/manage_config_groups_controller_test.js

@@ -213,6 +213,7 @@ describe('App.ManageConfigGroupsController', function() {
       });
 
       describe("#onPrimaryWizard()", function () {
+
         var ctrl = Em.Object.create({
           selectedService: Em.Object.create({
             selected: false
@@ -220,6 +221,7 @@ describe('App.ManageConfigGroupsController', function() {
           selectedServiceObserver: Em.K,
           setGroupsToDelete: Em.K
         });
+
         beforeEach(function () {
           sinon.spy(ctrl, 'selectedServiceObserver');
           sinon.spy(ctrl, 'setGroupsToDelete');
@@ -227,6 +229,7 @@ describe('App.ManageConfigGroupsController', function() {
           sinon.stub(popup, 'updateConfigGroupOnServicePage', Em.K);
           sinon.stub(popup, 'hide', Em.K);
         });
+
         afterEach(function () {
           ctrl.setGroupsToDelete.restore();
           ctrl.selectedServiceObserver.restore();
@@ -234,44 +237,110 @@ describe('App.ManageConfigGroupsController', function() {
           popup.updateConfigGroupOnServicePage.restore();
           popup.hide.restore();
         });
-        it("groups deleted on 7th step", function () {
-          ctrl.set('name', 'wizardStep7Controller');
-          popup.onPrimaryWizard(ctrl, {toDelete: [1]});
-          expect(ctrl.selectedServiceObserver.calledOnce).to.be.true;
-          expect(ctrl.setGroupsToDelete.calledWith([1])).to.be.true;
-          expect(manageConfigGroupsController.persistConfigGroups.calledOnce).to.be.true;
-          expect(popup.updateConfigGroupOnServicePage.calledOnce).to.be.true;
-          expect(popup.hide.calledOnce).to.be.true;
+
+        describe("groups deleted on 7th step", function () {
+
+          beforeEach(function () {
+            ctrl.set('name', 'wizardStep7Controller');
+            popup.onPrimaryWizard(ctrl, {toDelete: [1]});
+          });
+
+          it('selectedServiceObserver is called once', function () {
+            expect(ctrl.selectedServiceObserver.calledOnce).to.be.true;
+          });
+          it('setGroupsToDelete is called with [1]', function () {
+            expect(ctrl.setGroupsToDelete.calledWith([1])).to.be.true;
+          });
+          it('persistConfigGroups is called once', function () {
+            expect(manageConfigGroupsController.persistConfigGroups.calledOnce).to.be.true;
+          });
+          it('updateConfigGroupOnServicePage is called once', function () {
+            expect(popup.updateConfigGroupOnServicePage.calledOnce).to.be.true;
+          });
+          it('hide is called once', function () {
+            expect(popup.hide.calledOnce).to.be.true;
+          });
         });
-        it("wizard not on 7th step", function () {
-          ctrl.set('name', '');
-          popup.onPrimaryWizard(ctrl, {});
-          expect(ctrl.selectedServiceObserver.calledOnce).to.be.true;
-          expect(ctrl.setGroupsToDelete.called).to.be.false;
-          expect(manageConfigGroupsController.persistConfigGroups.called).to.be.false;
-          expect(popup.updateConfigGroupOnServicePage.called).to.be.false;
-          expect(popup.hide.calledOnce).to.be.true;
+
+        describe("wizard not on 7th step", function () {
+
+          beforeEach(function () {
+            ctrl.set('name', '');
+            popup.onPrimaryWizard(ctrl, {});
+          });
+
+          it('selectedServiceObserver is called once', function () {
+            expect(ctrl.selectedServiceObserver.calledOnce).to.be.true;
+          });
+
+          it('setGroupsToDelete is not called', function () {
+            expect(ctrl.setGroupsToDelete.called).to.be.false;
+          });
+
+          it('persistConfigGroups is not called', function () {
+            expect(manageConfigGroupsController.persistConfigGroups.called).to.be.false;
+          });
+
+          it('updateConfigGroupOnServicePage is not called', function () {
+            expect(popup.updateConfigGroupOnServicePage.called).to.be.false;
+          });
+
+          it('hide is called once', function () {
+            expect(popup.hide.calledOnce).to.be.true;
+          });
         });
-        it("wizard on 7th step, service selected", function () {
-          ctrl.set('name', 'wizardStep7Controller');
-          ctrl.set('selectedService.selected', true);
-          popup.onPrimaryWizard(ctrl, {toDelete: [1]});
-          expect(ctrl.selectedServiceObserver.calledOnce).to.be.true;
-          expect(ctrl.setGroupsToDelete.called).to.be.false;
-          expect(manageConfigGroupsController.persistConfigGroups.calledOnce).to.be.true;
-          expect(popup.updateConfigGroupOnServicePage.calledOnce).to.be.true;
-          expect(popup.hide.calledOnce).to.be.true;
+
+        describe("wizard on 7th step, service selected", function () {
+
+          beforeEach(function () {
+            ctrl.set('name', 'wizardStep7Controller');
+            ctrl.set('selectedService.selected', true);
+            popup.onPrimaryWizard(ctrl, {toDelete: [1]});
+          });
+
+          it('selectedServiceObserver is called once', function () {
+            expect(ctrl.selectedServiceObserver.calledOnce).to.be.true;
+          });
+          it('setGroupsToDelete is not called', function () {
+            expect(ctrl.setGroupsToDelete.called).to.be.false;
+          });
+          it('persistConfigGroups is called once', function () {
+            expect(manageConfigGroupsController.persistConfigGroups.calledOnce).to.be.true;
+          });
+          it('updateConfigGroupOnServicePage is called once', function () {
+            expect(popup.updateConfigGroupOnServicePage.calledOnce).to.be.true;
+          });
+          it('hide is called once', function () {
+            expect(popup.hide.calledOnce).to.be.true;
+          });
         });
-        it("wizard on 7th step, no groups to delete", function () {
-          ctrl.set('name', 'wizardStep7Controller');
-          ctrl.set('selectedService.selected', false);
-          popup.onPrimaryWizard(ctrl, {toDelete: []});
-          expect(ctrl.selectedServiceObserver.calledOnce).to.be.true;
-          expect(ctrl.setGroupsToDelete.called).to.be.false;
-          expect(manageConfigGroupsController.persistConfigGroups.calledOnce).to.be.true;
-          expect(popup.updateConfigGroupOnServicePage.calledOnce).to.be.true;
-          expect(popup.hide.calledOnce).to.be.true;
+
+        describe("wizard on 7th step, no groups to delete", function () {
+
+          beforeEach(function () {
+            ctrl.set('name', 'wizardStep7Controller');
+            ctrl.set('selectedService.selected', false);
+            popup.onPrimaryWizard(ctrl, {toDelete: []});
+          });
+
+          it('selectedServiceObserver is called once', function () {
+            expect(ctrl.selectedServiceObserver.calledOnce).to.be.true;
+          });
+          it('setGroupsToDelete is not called', function () {
+            expect(ctrl.setGroupsToDelete.called).to.be.false;
+          });
+          it('persistConfigGroups is called once', function () {
+            expect(manageConfigGroupsController.persistConfigGroups.calledOnce).to.be.true;
+          });
+          it('updateConfigGroupOnServicePage is called once', function () {
+            expect(popup.updateConfigGroupOnServicePage.calledOnce).to.be.true;
+          });
+          it('hide is called once', function () {
+            expect(popup.hide.calledOnce).to.be.true;
+          });
+
         });
+
       });
     });
 

+ 7 - 21
ambari-web/test/controllers/main/service/reassign/step1_controller_test.js

@@ -35,10 +35,12 @@ describe('App.ReassignMasterWizardStep1Controller', function () {
   describe('#loadConfigTags', function() {
     beforeEach(function() {
       sinon.stub(App.ajax, 'send', Em.K);
+      this.stub = sinon.stub(App.router, 'get');
     });
 
     afterEach(function() {
       App.ajax.send.restore();
+      this.stub.restore();
     });
 
     it('tests loadConfigTags', function() {
@@ -48,47 +50,31 @@ describe('App.ReassignMasterWizardStep1Controller', function () {
     });
 
     it('tests saveDatabaseType with type', function() {
-      sinon.stub(App.router, 'get', function() {
-        return { saveDatabaseType: Em.K};
-      });
+      this.stub.returns({ saveDatabaseType: Em.K});
 
       controller.saveDatabaseType(true);
       expect(App.router.get.calledOnce).to.be.true;
-
-      App.router.get.restore();
     });
 
     it('tests saveDatabaseType without type', function() {
-      sinon.stub(App.router, 'get', function() {
-        return { saveDatabaseType: Em.K};
-      });
+      this.stub.returns({ saveDatabaseType: Em.K});
 
       controller.saveDatabaseType(false);
       expect(App.router.get.called).to.be.false;
-
-      App.router.get.restore();
     });
 
-    it('tests saveServiceProperties with propertie', function() {
-      sinon.stub(App.router, 'get', function() {
-        return { saveServiceProperties: Em.K};
-      });
+    it('tests saveServiceProperties with properties', function() {
+      this.stub.returns({ saveServiceProperties: Em.K});
 
       controller.saveServiceProperties(true);
       expect(App.router.get.calledOnce).to.be.true;
-
-      App.router.get.restore();
     });
 
     it('tests saveServiceProperties without properties', function() {
-      sinon.stub(App.router, 'get', function() {
-        return { saveServiceProperties: Em.K};
-      });
+      this.stub.returns({ saveServiceProperties: Em.K});
 
       controller.saveServiceProperties(false);
       expect(App.router.get.called).to.be.false;
-
-      App.router.get.restore();
     });
 
     it('tests getDatabaseHost', function() {

+ 23 - 9
ambari-web/test/controllers/main/service/reassign/step4_controller_test.js

@@ -130,13 +130,21 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
       App.router.get.restore();
     });
 
-    it('tests database connection', function() {
-      sinon.stub(controller, 'prepareDBCheckAction', Em.K);
+    describe('tests database connection', function() {
 
-      controller.testDBConnection();
-      expect(controller.prepareDBCheckAction.calledOnce).to.be.true;
+      beforeEach(function () {
+        sinon.stub(controller, 'prepareDBCheckAction', Em.K);
+      });
+
+      afterEach(function () {
+        controller.prepareDBCheckAction.restore();
+      });
+
+      it('prepareDBCheckAction is called once', function() {
+        controller.testDBConnection();
+        expect(controller.prepareDBCheckAction.calledOnce).to.be.true;
+      });
 
-      controller.prepareDBCheckAction.restore();
     });
 
     it('tests prepareDBCheckAction', function() {
@@ -770,36 +778,42 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
 
   describe('#setSecureConfigs()', function () {
 
+    beforeEach(function () {
+      this.stub = sinon.stub(App, 'get');
+    });
+
     afterEach(function () {
       Em.tryInvoke(App.get, 'restore');
     });
 
     it('undefined component and security disabled', function () {
       var secureConfigs = [];
-      sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(false);
+      this.stub.withArgs('isKerberosEnabled').returns(false);
       controller.set('secureConfigsMap', []);
       expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
       expect(secureConfigs).to.eql([]);
     });
+
     it('component exist and security disabled', function () {
       var secureConfigs = [];
-      sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(false);
+      this.stub.withArgs('isKerberosEnabled').returns(false);
       controller.set('secureConfigsMap', [{
         componentName: 'COMP1'
       }]);
       expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
       expect(secureConfigs).to.eql([]);
     });
+
     it('undefined component and security enabled', function () {
       var secureConfigs = [];
-      sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(true);
+      this.stub.withArgs('isKerberosEnabled').returns(true);
       controller.set('secureConfigsMap', []);
       expect(controller.setSecureConfigs(secureConfigs, {}, 'COMP1')).to.be.false;
       expect(secureConfigs).to.eql([]);
     });
     it('component exist and security enabled', function () {
       var secureConfigs = [];
-      sinon.stub(App, 'get').withArgs('isKerberosEnabled').returns(true);
+      this.stub.withArgs('isKerberosEnabled').returns(true);
       var configs = {'s1': {
         'k1': 'kValue',
         'p1': 'pValue'

+ 14 - 2
ambari-web/test/controllers/main/service/reassign_controller_test.js

@@ -101,6 +101,7 @@ describe('App.ReassignMasterController', function () {
     beforeEach(function () {
       sinon.stub(App.db, 'setMasterComponentHosts', Em.K);
       sinon.stub(reassignMasterController, 'setDBProperty', Em.K);
+      reassignMasterController.saveMasterComponentHosts(stepController);
     });
 
     afterEach(function () {
@@ -108,12 +109,23 @@ describe('App.ReassignMasterController', function () {
       reassignMasterController.setDBProperty.restore();
     });
 
-    it('should save master component hosts', function () {
-      reassignMasterController.saveMasterComponentHosts(stepController);
+    it('setMasterComponentHosts is called once', function () {
       expect(App.db.setMasterComponentHosts.calledOnce).to.be.true;
+    });
+
+    it('setDBProperty is called once', function () {
       expect(reassignMasterController.setDBProperty.calledOnce).to.be.true;
+    });
+
+    it('setMasterComponentHosts is called with valid arguments', function () {
       expect(App.db.setMasterComponentHosts.calledWith(masterComponentHosts)).to.be.true;
+    });
+
+    it('setDBProperty is called with valid arguments', function () {
       expect(reassignMasterController.setDBProperty.calledWith('masterComponentHosts', masterComponentHosts)).to.be.true;
+    });
+
+    it('masterComponentHosts are equal to ' + JSON.stringify(masterComponentHosts), function () {
       expect(reassignMasterController.get('content.masterComponentHosts')).to.eql(masterComponentHosts);
     });
 

+ 216 - 86
ambari-web/test/controllers/main/service/widgets/create/step2_controller_test.js

@@ -282,115 +282,245 @@ describe('App.WidgetWizardStep2Controller', function () {
   });
 
   describe("#initWidgetData()", function () {
-    it("new data", function () {
-      controller.set('expressions', []);
-      controller.set('dataSets', []);
-      controller.get('content').setProperties({
-        widgetProperties: {a: 1},
-        widgetValues: [1],
-        widgetMetrics: [2]
+
+    describe("new data", function () {
+
+      beforeEach(function () {
+        controller.set('expressions', []);
+        controller.set('dataSets', []);
+        controller.get('content').setProperties({
+          widgetProperties: {a: 1},
+          widgetValues: [1],
+          widgetMetrics: [2]
+        });
+
+        controller.initWidgetData();
+      });
+
+      it('widgetProperties is {a: 1}', function () {
+        expect(controller.get('widgetProperties')).to.eql({a: 1});
+      });
+
+      it('widgetValues is []', function () {
+        expect(controller.get('widgetValues')).to.eql([]);
+      });
+
+      it('widgetMetrics is []', function () {
+        expect(controller.get('widgetMetrics')).to.eql([]);
+      });
+
+      it('expressions is not empty', function () {
+        expect(controller.get('expressions')).to.not.be.empty;
       });
 
-      controller.initWidgetData();
+      it('dataSets is not empty', function () {
+        expect(controller.get('dataSets')).to.not.be.empty;
+      });
 
-      expect(controller.get('widgetProperties')).to.eql({a: 1});
-      expect(controller.get('widgetValues')).to.eql([]);
-      expect(controller.get('widgetMetrics')).to.eql([]);
-      expect(controller.get('expressions')).to.not.be.empty;
-      expect(controller.get('dataSets')).to.not.be.empty;
     });
-    it("previously edited", function () {
-      controller.set('expressions', [{}]);
-      controller.set('dataSets', [{}]);
-      controller.get('content').setProperties({
-        widgetProperties: {a: 1},
-        widgetValues: [1],
-        widgetMetrics: [2]
+
+    describe("previously edited", function () {
+
+      beforeEach(function () {
+        controller.set('expressions', [{}]);
+        controller.set('dataSets', [{}]);
+        controller.get('content').setProperties({
+          widgetProperties: {a: 1},
+          widgetValues: [1],
+          widgetMetrics: [2]
+        });
+
+        controller.initWidgetData();
       });
 
-      controller.initWidgetData();
+      it('widgetProperties is {a: 1}', function () {
+        expect(controller.get('widgetProperties')).to.eql({a: 1});
+      });
+      it('widgetValues is [1]', function () {
+        expect(controller.get('widgetValues')).to.eql([1]);
+      });
+      it('widgetMetrics is  [2]', function () {
+        expect(controller.get('widgetMetrics')).to.eql([2]);
+      });
+      it('expressions is not empty', function () {
+        expect(controller.get('expressions')).to.not.be.empty;
+      });
+      it('dataSets is not empty', function () {
+        expect(controller.get('dataSets')).to.not.be.empty;
+      });
 
-      expect(controller.get('widgetProperties')).to.eql({a: 1});
-      expect(controller.get('widgetValues')).to.eql([1]);
-      expect(controller.get('widgetMetrics')).to.eql([2]);
-      expect(controller.get('expressions')).to.not.be.empty;
-      expect(controller.get('dataSets')).to.not.be.empty;
     });
   });
 
   describe("#updateExpressions()", function () {
+
     beforeEach(function () {
       sinon.stub(controller, 'parseExpression').returns({values: [1], metrics: [1]});
       sinon.stub(controller, 'parseTemplateExpression').returns({values: [1], metrics: [1]});
       sinon.stub(controller, 'parseGraphDataset').returns({values: [1], metrics: [1]});
     });
+
     afterEach(function () {
       controller.parseExpression.restore();
       controller.parseTemplateExpression.restore();
       controller.parseGraphDataset.restore();
     });
-    it("empty expressions", function () {
-      controller.set('expressions', []);
-      controller.updateExpressions();
-      expect(controller.parseExpression.called).to.be.false;
-      expect(controller.parseTemplateExpression.called).to.be.false;
-      expect(controller.parseGraphDataset.called).to.be.false;
-      expect(controller.get('widgetValues')).to.be.empty;
-      expect(controller.get('widgetMetrics')).to.be.empty;
+
+    describe("empty expressions", function () {
+
+      beforeEach(function () {
+        controller.set('expressions', []);
+        controller.updateExpressions();
+      });
+
+      it('parseExpression is not called', function () {
+        expect(controller.parseExpression.called).to.be.false;
+      });
+      it('parseTemplateExpression is not called', function () {
+        expect(controller.parseTemplateExpression.called).to.be.false;
+      });
+      it('parseGraphDataset is not called', function () {
+        expect(controller.parseGraphDataset.called).to.be.false;
+      });
+      it('widgetValues is empty', function () {
+        expect(controller.get('widgetValues')).to.be.empty;
+      });
+      it('widgetMetrics is empty', function () {
+        expect(controller.get('widgetMetrics')).to.be.empty;
+      });
     });
-    it("empty dataSets", function () {
-      controller.set('dataSets', []);
-      controller.updateExpressions();
-      expect(controller.parseExpression.called).to.be.false;
-      expect(controller.parseTemplateExpression.called).to.be.false;
-      expect(controller.parseGraphDataset.called).to.be.false;
-      expect(controller.get('widgetValues')).to.be.empty;
-      expect(controller.get('widgetMetrics')).to.be.empty;
-    });
-    it("GAUGE widget", function () {
-      controller.set('expressions', [{}]);
-      controller.set('content.widgetType', 'GAUGE');
-      controller.set('dataSets', [{}]);
-      //controller.updateExpressions();
-      expect(controller.parseExpression.calledOnce).to.be.true;
-      expect(controller.parseTemplateExpression.called).to.be.false;
-      expect(controller.parseGraphDataset.called).to.be.false;
-      expect(controller.get('widgetValues')).to.not.be.empty;
-      expect(controller.get('widgetMetrics')).to.not.be.empty;
-    });
-    it("NUMBER widget", function () {
-      controller.set('expressions', [{}]);
-      controller.set('content.widgetType', 'NUMBER');
-      controller.set('dataSets', [{}]);
-      //controller.updateExpressions();
-      expect(controller.parseExpression.calledOnce).to.be.true;
-      expect(controller.parseTemplateExpression.called).to.be.false;
-      expect(controller.parseGraphDataset.called).to.be.false;
-      expect(controller.get('widgetValues')).to.not.be.empty;
-      expect(controller.get('widgetMetrics')).to.not.be.empty;
-    });
-    it("TEMPLATE widget", function () {
-      controller.set('expressions', [{}]);
-      controller.set('content.widgetType', 'TEMPLATE');
-      controller.set('dataSets', [{}]);
-      //controller.updateExpressions();
-      expect(controller.parseExpression.called).to.be.false;
-      expect(controller.parseTemplateExpression.calledOnce).to.be.true;
-      expect(controller.parseGraphDataset.called).to.be.false;
-      expect(controller.get('widgetValues')).to.not.be.empty;
-      expect(controller.get('widgetMetrics')).to.not.be.empty;
-    });
-    it("GRAPH widget", function () {
-      controller.set('expressions', [{}]);
-      controller.set('content.widgetType', 'GRAPH');
-      controller.set('dataSets', [{}]);
-      //controller.updateExpressions();
-      expect(controller.parseExpression.called).to.be.false;
-      expect(controller.parseTemplateExpression.called).to.be.false;
-      expect(controller.parseGraphDataset.calledOnce).to.be.true;
-      expect(controller.get('widgetValues')).to.not.be.empty;
-      expect(controller.get('widgetMetrics')).to.not.be.empty;
+
+    describe("empty dataSets", function () {
+
+      beforeEach(function () {
+        controller.set('dataSets', []);
+        controller.updateExpressions();
+      });
+
+      it('parseExpression is not called', function () {
+        expect(controller.parseExpression.called).to.be.false;
+      });
+      it('parseTemplateExpression is not called', function () {
+        expect(controller.parseTemplateExpression.called).to.be.false;
+      });
+      it('parseGraphDataset is not called', function () {
+        expect(controller.parseGraphDataset.called).to.be.false;
+      });
+      it('widgetValues is empty', function () {
+        expect(controller.get('widgetValues')).to.be.empty;
+      });
+      it('widgetMetrics is empty', function () {
+        expect(controller.get('widgetMetrics')).to.be.empty;
+      });
+    });
+
+    describe("GAUGE widget", function () {
+
+      beforeEach(function () {
+        controller.set('expressions', [{}]);
+        controller.set('content.widgetType', 'GAUGE');
+        controller.set('dataSets', [{}]);
+        //controller.updateExpressions();
+      });
+
+
+      it('parseExpression is called once', function () {
+        expect(controller.parseExpression.calledOnce).to.be.true;
+      });
+      it('parseTemplateExpression is not called', function () {
+        expect(controller.parseTemplateExpression.called).to.be.false;
+      });
+      it('parseGraphDataset is not called', function () {
+        expect(controller.parseGraphDataset.called).to.be.false;
+      });
+      it('widgetValues is not empty', function () {
+        expect(controller.get('widgetValues')).to.not.be.empty;
+      });
+      it('widgetMetrics is not empty', function () {
+        expect(controller.get('widgetMetrics')).to.not.be.empty;
+      });
+    });
+
+    describe("NUMBER widget", function () {
+
+      beforeEach(function () {
+        controller.set('expressions', [{}]);
+        controller.set('content.widgetType', 'NUMBER');
+        controller.set('dataSets', [{}]);
+        //controller.updateExpressions();
+      });
+
+
+      it('parseExpression is called once', function () {
+        expect(controller.parseExpression.calledOnce).to.be.true;
+      });
+      it('parseTemplateExpression is not called', function () {
+        expect(controller.parseTemplateExpression.called).to.be.false;
+      });
+      it('parseGraphDataset is not called', function () {
+        expect(controller.parseGraphDataset.called).to.be.false;
+      });
+      it('widgetValues is not empty', function () {
+        expect(controller.get('widgetValues')).to.not.be.empty;
+      });
+      it('widgetMetrics is not empty', function () {
+        expect(controller.get('widgetMetrics')).to.not.be.empty;
+      });
+    });
+
+    describe("TEMPLATE widget", function () {
+
+      beforeEach(function () {
+        controller.set('expressions', [{}]);
+        controller.set('content.widgetType', 'TEMPLATE');
+        controller.set('dataSets', [{}]);
+        //controller.updateExpressions();
+      });
+
+
+      it('parseExpression is not called', function () {
+        expect(controller.parseExpression.called).to.be.false;
+      });
+      it('parseTemplateExpression is called once', function () {
+        expect(controller.parseTemplateExpression.calledOnce).to.be.true;
+      });
+      it('parseGraphDataset is not called', function () {
+        expect(controller.parseGraphDataset.called).to.be.false;
+      });
+      it('widgetValues is not empty', function () {
+        expect(controller.get('widgetValues')).to.not.be.empty;
+      });
+      it('widgetMetrics is not empty', function () {
+        expect(controller.get('widgetMetrics')).to.not.be.empty;
+      });
     });
+
+    describe("GRAPH widget", function () {
+
+      beforeEach(function () {
+        controller.set('expressions', [{}]);
+        controller.set('content.widgetType', 'GRAPH');
+        controller.set('dataSets', [{}]);
+        //controller.updateExpressions();
+      });
+
+      it('parseExpression is not called', function () {
+        expect(controller.parseExpression.called).to.be.false;
+      });
+      it('parseTemplateExpression is not called', function () {
+        expect(controller.parseTemplateExpression.called).to.be.false;
+      });
+      it('parseGraphDataset is called once', function () {
+        expect(controller.parseGraphDataset.calledOnce).to.be.true;
+      });
+      it('widgetValues is not empty', function () {
+        expect(controller.get('widgetValues')).to.not.be.empty;
+      });
+      it('widgetMetrics is not empty', function () {
+        expect(controller.get('widgetMetrics')).to.not.be.empty;
+      });
+    });
+
   });
 
   describe("#parseGraphDataset()", function () {

+ 49 - 29
ambari-web/test/controllers/main/service_test.js

@@ -124,18 +124,28 @@ describe('App.MainServiceController', function () {
         e: null
       }
     ]).forEach(function(test) {
-        it(test.m, function() {
-          sinon.stub(App.router, 'get', function(k) {
-            if ('clusterController.isClusterDataLoaded' === k) return test.isLoaded;
-            return Em.get(App.router, k);
+        describe(test.m, function() {
+
+          beforeEach(function () {
+            sinon.stub(App.router, 'get', function(k) {
+              if ('clusterController.isClusterDataLoaded' === k) return test.isLoaded;
+              return Em.get(App.router, k);
+            });
+            sinon.stub(App.Cluster, 'find', function() {
+              return [test.e];
+            });
           });
-          sinon.stub(App.Cluster, 'find', function() {
-            return [test.e];
+
+          afterEach(function () {
+            App.router.get.restore();
+            App.Cluster.find.restore();
+          });
+
+          it('cluster is valid', function () {
+            var c = mainServiceController.get('cluster');
+            expect(c).to.eql(test.e);
           });
-          var c = mainServiceController.get('cluster');
-          App.router.get.restore();
-          App.Cluster.find.restore();
-          expect(c).to.eql(test.e);
+
         });
       });
 
@@ -220,28 +230,38 @@ describe('App.MainServiceController', function () {
       expect(Em.I18n.t.calledWith('services.service.stop.confirmButton')).to.be.ok;
     });
 
-    it ("should check last checkpoint for NN before confirming stop", function() {
-      var mainServiceItemController = App.MainServiceItemController.create({});
-      sinon.stub(mainServiceItemController, 'checkNnLastCheckpointTime', function() {
-        return true;
+    describe("should check last checkpoint for NN before confirming stop", function() {
+      var mainServiceItemController;
+      beforeEach(function() {
+        mainServiceItemController = App.MainServiceItemController.create({});
+        sinon.stub(mainServiceItemController, 'checkNnLastCheckpointTime', function() {
+          return true;
+        });
+        sinon.stub(App.router, 'get', function(k) {
+          if ('mainServiceItemController' === k) {
+            return mainServiceItemController;
+          }
+          return Em.get(App.router, k);
+        });
+        sinon.stub(App.Service, 'find', function() {
+          return [{
+            serviceName: "HDFS",
+            workStatus: "STARTED"
+          }];
+        });
       });
-      sinon.stub(App.router, 'get', function(k) {
-        if ('mainServiceItemController' === k) {
-          return mainServiceItemController;
-        }
-        return Em.get(App.router, k);
+
+      afterEach(function () {
+        mainServiceItemController.checkNnLastCheckpointTime.restore();
+        App.router.get.restore();
+        App.Service.find.restore();
       });
-      sinon.stub(App.Service, 'find', function() {
-        return [{
-          serviceName: "HDFS",
-          workStatus: "STARTED"
-        }];
+
+      it('checkNnLastCheckpointTime is called once', function () {
+        mainServiceController.startStopAllService(event, "INSTALLED");
+        expect(mainServiceItemController.checkNnLastCheckpointTime.calledOnce).to.equal(true);
       });
-      mainServiceController.startStopAllService(event, "INSTALLED");
-      expect(mainServiceItemController.checkNnLastCheckpointTime.calledOnce).to.equal(true);
-      mainServiceItemController.checkNnLastCheckpointTime.restore();
-      App.router.get.restore();
-      App.Service.find.restore();
+
     });
 
     it ("should confirm start if state is not INSTALLED", function() {

+ 3 - 2
ambari-web/test/controllers/main/views_controller_test.js

@@ -29,6 +29,7 @@ describe('MainViewsController', function () {
   describe('#loadAmbariViews()', function () {
     beforeEach(function () {
       sinon.stub(App.ajax, 'send', Em.K);
+      this.stub = sinon.stub(App.router, 'get');
     });
     afterEach(function () {
       App.router.get.restore();
@@ -36,13 +37,13 @@ describe('MainViewsController', function () {
     });
 
     it('should load views if the user is logged in', function () {
-      sinon.stub(App.router, 'get').withArgs('loggedIn').returns(true);
+      this.stub.withArgs('loggedIn').returns(true);
       mainViewsController.loadAmbariViews();
       expect(App.ajax.send.calledOnce).to.be.true;
     });
 
     it('should not load views if the user is not logged in', function () {
-      sinon.stub(App.router, 'get').withArgs('loggedIn').returns(false);
+      this.stub.withArgs('loggedIn').returns(false);
       mainViewsController.loadAmbariViews();
       expect(App.ajax.send.notCalled).to.be.true;
     })

+ 13 - 5
ambari-web/test/controllers/main_test.js

@@ -79,25 +79,33 @@ describe('App.MainController', function () {
   });
 
   describe('#dataLoading', function() {
+
+    beforeEach(function () {
+      this.stub = sinon.stub(App.router, 'get');
+    });
+
+    afterEach(function () {
+      this.stub.restore();
+    });
+
     it ('Should resolve promise', function() {
-      sinon.stub(App.router, 'get').returns(true);
+      this.stub.returns(true);
       var deffer = mainController.dataLoading();
-      App.router.get.restore();
       deffer.then(function(val){
         expect(val).to.be.undefined;
       });
     });
-    it ('Should resolve promise', function() {
-      sinon.stub(App.router, 'get').returns(false);
+    it ('Should resolve promise (2)', function(done) {
+      this.stub.returns(false);
       
       setTimeout(function() {
         mainController.set('isClusterDataLoaded', true);
       },150);
 
       var deffer = mainController.dataLoading();
-      App.router.get.restore();
       deffer.then(function(val){
         expect(val).to.be.undefined;
+        done();
       });
     });
   });

+ 24 - 14
ambari-web/test/router_test.js

@@ -496,22 +496,32 @@ describe('App.Router', function () {
         m: 'jwtProviderUrl is present, current location is local login url, no redirect'
       }
     ].forEach(function(test) {
-      it(test.m, function() {
-        var mockCurrentUrl = 'http://localhost:3333/#/some/hash';
-        router.set('location.lastSetURL', test.lastSetURL);
-        sinon.stub(App.ajax, 'send', function() {
-          if (!test.isResolved) {
-            router.onAuthenticationError(test.responseData);
-          }
-          return {
-            complete: function() {}
-          };
+      describe(test.m, function() {
+        var mockCurrentUrl;
+        beforeEach(function () {
+          mockCurrentUrl = 'http://localhost:3333/#/some/hash';
+          router.set('location.lastSetURL', test.lastSetURL);
+          sinon.stub(App.ajax, 'send', function() {
+            if (!test.isResolved) {
+              router.onAuthenticationError(test.responseData);
+            }
+            return {
+              complete: function() {}
+            };
+          });
+          this.mockGetCurrentLocationUrl.returns(mockCurrentUrl);
+          router.getAuthenticated();
+        });
+
+        it('redirectByURL is ' + (test.redirectCalled ? '' : 'not') + ' called', function () {
+          expect(router.redirectByURL.calledOnce).to.be.eql(test.redirectCalled);
         });
-        this.mockGetCurrentLocationUrl.returns(mockCurrentUrl);
-        router.getAuthenticated();
-        expect(router.redirectByURL.calledOnce).to.be.eql(test.redirectCalled);
+
+
         if (test.redirectCalled) {
-          expect(router.redirectByURL.args[0][0]).to.be.eql(JSON.parse(test.responseData.responseText).jwtProviderUrl + encodeURIComponent(mockCurrentUrl));
+          it('redirectByURL is correct', function () {
+            expect(router.redirectByURL.args[0][0]).to.be.eql(JSON.parse(test.responseData.responseText).jwtProviderUrl + encodeURIComponent(mockCurrentUrl));
+          });
         }
       });
     });