You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2015/10/01 14:58:42 UTC

[1/2] ambari git commit: AMBARI-13285 Cover Component Reassign wizard controllers with unit tests. (atkach)

Repository: ambari
Updated Branches:
  refs/heads/trunk 0fc2cd584 -> 4e5489bac


http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/test/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view_test.js b/ambari-web/test/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view_test.js
new file mode 100644
index 0000000..d7b3e95
--- /dev/null
+++ b/ambari-web/test/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view_test.js
@@ -0,0 +1,385 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+require('views/main/alerts/manage_alert_groups/select_definitions_popup_body_view');
+
+
+var view;
+
+describe('App.SelectDefinitionsPopupBodyView', function () {
+
+  beforeEach(function () {
+    view = App.SelectDefinitionsPopupBodyView.create({
+      parentView: Em.Object.create()
+    });
+  });
+
+  describe("#filteredContentObs()", function () {
+    beforeEach(function () {
+      sinon.stub(Em.run, 'once', Em.K);
+    });
+    afterEach(function () {
+      Em.run.once.restore();
+    });
+
+    it("Em.run.once should be called", function () {
+      view.filteredContentObs();
+      expect(Em.run.once.calledWith(view)).to.be.true;
+    });
+  });
+
+  describe("#filteredContentObsOnce()", function () {
+    beforeEach(function () {
+      sinon.stub(view, 'filterDefs', Em.K);
+    });
+    afterEach(function () {
+      view.filterDefs.restore();
+    });
+    it("filteredContent should be set", function () {
+      view.set('parentView.availableDefs', [
+        {
+          filtered: true
+        },
+        {
+          filtered: false
+        }
+      ]);
+      view.filteredContentObsOnce();
+      expect(view.get('filteredContent')).to.eql([{
+        filtered: true
+      }]);
+    });
+  });
+
+  describe("#didInsertElement()", function () {
+    beforeEach(function () {
+      sinon.stub(view, 'filterDefs', Em.K);
+      sinon.stub(view, 'filteredContentObsOnce', Em.K);
+    });
+    afterEach(function () {
+      view.filterDefs.restore();
+      view.filteredContentObsOnce.restore();
+    });
+    it("", function () {
+      view.set('initialDefs', [
+        Em.Object.create({filtered: true}),
+        Em.Object.create({filtered: false})
+      ]);
+      view.didInsertElement();
+      expect(view.get('parentView.availableDefs').mapProperty('filtered')).to.eql([true, true]);
+      expect(view.get('parentView.isLoaded')).to.be.true;
+      expect(view.filteredContentObsOnce.calledOnce).to.be.true;
+    });
+  });
+
+  describe("#filterDefs()", function () {
+    var testCases = [
+      {
+        title: 'should be filtered',
+        data: {
+          defs: [
+            Em.Object.create({
+              filtered: false
+            })
+          ],
+          filterComponent: null,
+          filterService: null,
+          showOnlySelectedDefs: false
+        },
+        result: [true]
+      },
+      {
+        title: 'should be filtered by serviceName',
+        data: {
+          defs: [
+            Em.Object.create({
+              filtered: false,
+              serviceName: 'S1'
+            })
+          ],
+          filterComponent: null,
+          filterService: Em.Object.create({serviceName: 'S1'}),
+          showOnlySelectedDefs: false
+        },
+        result: [true]
+      },
+      {
+        title: 'fail to be filtered by serviceName',
+        data: {
+          defs: [
+            Em.Object.create({
+              filtered: false,
+              serviceName: 'S1'
+            })
+          ],
+          filterComponent: null,
+          filterService: Em.Object.create({serviceName: 'S2'}),
+          showOnlySelectedDefs: false
+        },
+        result: [false]
+      },
+      {
+        title: 'should be filtered by componentName',
+        data: {
+          defs: [
+            Em.Object.create({
+              filtered: false,
+              componentName: 'C1'
+            })
+          ],
+          filterComponent: Em.Object.create({componentName: 'C1'}),
+          filterService: null,
+          showOnlySelectedDefs: false
+        },
+        result: [true]
+      },
+      {
+        title: 'fail to be filtered by componentName',
+        data: {
+          defs: [
+            Em.Object.create({
+              filtered: false,
+              componentName: 'C1'
+            })
+          ],
+          filterComponent: Em.Object.create({componentName: 'C2'}),
+          filterService: null,
+          showOnlySelectedDefs: false
+        },
+        result: [false]
+      },
+      {
+        title: 'should be filtered by showOnlySelectedDefs',
+        data: {
+          defs: [
+            Em.Object.create({
+              filtered: false,
+              selected: true
+            })
+          ],
+          filterComponent: null,
+          filterService: null,
+          showOnlySelectedDefs: true
+        },
+        result: [true]
+      },
+      {
+        title: 'fail to be filtered by showOnlySelectedDefs',
+        data: {
+          defs: [
+            Em.Object.create({
+              filtered: false,
+              selected: false
+            })
+          ],
+          filterComponent: null,
+          filterService: null,
+          showOnlySelectedDefs: true
+        },
+        result: [false]
+      },
+      {
+        title: 'should be filtered by all filters',
+        data: {
+          defs: [
+            Em.Object.create({
+              filtered: false,
+              componentName: 'C1',
+              serviceName: 'S1',
+              selected: true
+            })
+          ],
+          filterComponent: Em.Object.create({componentName: 'C1'}),
+          filterService: Em.Object.create({serviceName: 'S1'}),
+          showOnlySelectedDefs: true
+        },
+        result: [true]
+      }
+    ];
+    testCases.forEach(function (test) {
+      it(test.title, function () {
+        view.set('parentView.availableDefs', test.data.defs);
+        view.set('showOnlySelectedDefs', test.data.showOnlySelectedDefs);
+        view.set('filterComponent', test.data.filterComponent);
+        view.set('filterService', test.data.filterService);
+
+        view.filterDefs();
+        expect(view.get('parentView.availableDefs').mapProperty('filtered')).to.eql(test.result);
+        expect(view.get('startIndex')).to.equal(1);
+      });
+    });
+  });
+
+  describe("#defSelectMessage", function () {
+    beforeEach(function () {
+      sinon.stub(view, 'filterDefs', Em.K);
+    });
+    afterEach(function () {
+      view.filterDefs.restore();
+    });
+    it("", function () {
+      view.set('parentView.availableDefs', [
+        {selected: true},
+        {selected: false}
+      ]);
+      expect(view.get('defSelectMessage')).to.equal(Em.I18n.t('alerts.actions.manage_alert_groups_popup.selectDefsDialog.selectedDefsLink').format(1, 2));
+    });
+  });
+
+  describe("#selectFilterComponent()", function() {
+    beforeEach(function () {
+      sinon.stub(view, 'filterDefs', Em.K);
+    });
+    afterEach(function () {
+      view.filterDefs.restore();
+    });
+
+    it("event is null", function() {
+      view.set('filterComponent', null);
+      view.selectFilterComponent(null);
+      expect(view.get('filterComponent')).to.be.null;
+    });
+    it("componentName is empty", function() {
+      view.set('filterComponent', null);
+      view.selectFilterComponent({context: Em.Object.create({componentName: ""})});
+      expect(view.get('filterComponent')).to.be.null;
+    });
+    it("filterComponent is null", function() {
+      var context = Em.Object.create({componentName: "C1"});
+      view.set('filterComponent', null);
+      view.selectFilterComponent({context: context});
+      expect(view.get('filterComponent')).to.eql(context);
+      expect(view.get('filterComponent.selected')).to.be.true;
+    });
+    it("filterComponent exist", function() {
+      var context = Em.Object.create({componentName: "C1"});
+      var filterComponent = Em.Object.create();
+      view.set('filterComponent', filterComponent);
+      view.selectFilterComponent({context: context});
+      expect(view.get('filterComponent')).to.eql(context);
+      expect(view.get('filterComponent.selected')).to.be.true;
+      expect(filterComponent.get('selected')).to.be.false;
+    });
+    it("the same filterComponent selected", function() {
+      var context = Em.Object.create({componentName: "C1"});
+      var filterComponent = Em.Object.create({componentName: 'C1'});
+      view.set('filterComponent', filterComponent);
+      view.selectFilterComponent({context: context});
+      expect(view.get('filterComponent')).to.be.null;
+      expect(filterComponent.get('selected')).to.be.false;
+    });
+  });
+
+  describe("#selectFilterService()", function() {
+    beforeEach(function () {
+      sinon.stub(view, 'filterDefs', Em.K);
+    });
+    afterEach(function () {
+      view.filterDefs.restore();
+    });
+
+    it("event is null", function() {
+      view.set('filterService', null);
+      view.selectFilterService(null);
+      expect(view.get('filterService')).to.be.null;
+    });
+    it("serviceName is empty", function() {
+      view.set('filterService', null);
+      view.selectFilterService({context: Em.Object.create({serviceName: ""})});
+      expect(view.get('filterService')).to.be.null;
+    });
+    it("filterService is null", function() {
+      var context = Em.Object.create({serviceName: "C1"});
+      view.set('filterService', null);
+      view.selectFilterService({context: context});
+      expect(view.get('filterService')).to.eql(context);
+      expect(view.get('filterService.selected')).to.be.true;
+    });
+    it("filterService exist", function() {
+      var context = Em.Object.create({serviceName: "C1"});
+      var filterService = Em.Object.create();
+      view.set('filterService', filterService);
+      view.selectFilterService({context: context});
+      expect(view.get('filterService')).to.eql(context);
+      expect(view.get('filterService.selected')).to.be.true;
+      expect(filterService.get('selected')).to.be.false;
+    });
+    it("the same filterService selected", function() {
+      var context = Em.Object.create({serviceName: "C1"});
+      var filterService = Em.Object.create({serviceName: 'C1'});
+      view.set('filterService', filterService);
+      view.selectFilterService({context: context});
+      expect(view.get('filterService')).to.be.null;
+      expect(filterService.get('selected')).to.be.false;
+    });
+  });
+
+  describe("#toggleSelectAllDefs()", function() {
+    beforeEach(function () {
+      sinon.stub(view, 'filterDefs', Em.K);
+    });
+    afterEach(function () {
+      view.filterDefs.restore();
+    });
+
+    it("allDefsSelected is false", function() {
+      view.set('parentView.availableDefs', [
+        Em.Object.create({filtered: true, selected: true}),
+        Em.Object.create({filtered: false, selected: false})
+      ]);
+      view.set('allDefsSelected', false);
+      view.toggleSelectAllDefs();
+      expect(view.get('parentView.availableDefs').mapProperty('selected')).to.eql([false, false]);
+    });
+    it("allDefsSelected is true", function() {
+      view.set('parentView.availableDefs', [
+        Em.Object.create({filtered: false, selected: true}),
+        Em.Object.create({filtered: true, selected: false})
+      ]);
+      view.set('allDefsSelected', true);
+      view.toggleSelectAllDefs();
+      expect(view.get('parentView.availableDefs').mapProperty('selected')).to.eql([true, true]);
+    });
+  });
+
+  describe("#toggleShowSelectedDefs()", function() {
+    beforeEach(function () {
+      sinon.stub(view, 'filterDefs', Em.K);
+    });
+    afterEach(function () {
+      view.filterDefs.restore();
+    });
+
+    it("", function() {
+      view.set('showOnlySelectedDefs', true);
+      var filterComponent = Em.Object.create();
+      var filterService = Em.Object.create();
+      view.set('filterComponent', filterComponent);
+      view.set('filterService', filterService);
+
+      view.toggleShowSelectedDefs();
+
+      expect(filterComponent.get('selected')).to.be.false;
+      expect(filterService.get('selected')).to.be.false;
+      expect(view.get('filterComponent')).to.be.null;
+      expect(view.get('filterService')).to.be.null;
+      expect(view.get('showOnlySelectedDefs')).to.be.false;
+    });
+  });
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/test/views/main/host/details/host_component_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/host/details/host_component_view_test.js b/ambari-web/test/views/main/host/details/host_component_view_test.js
index 6f765de..75cf476 100644
--- a/ambari-web/test/views/main/host/details/host_component_view_test.js
+++ b/ambari-web/test/views/main/host/details/host_component_view_test.js
@@ -25,18 +25,7 @@ var hostComponentView;
 describe('App.HostComponentView', function() {
 
   beforeEach(function() {
-    sinon.stub(App.router, 'get', function (k) {
-      if (k === 'mainHostDetailsController.content') return Em.Object.create({
-        hostComponents: [
-          {
-            componentName: 'component'
-          }
-        ]
-      });
-      return Em.get(App.router, k);
-    });
     hostComponentView = App.HostComponentView.create({
-      componentCounter: 1,
       startBlinking: function(){},
       doBlinking: function(){},
       getDesiredAdminState: function(){return $.ajax({});},
@@ -47,10 +36,6 @@ describe('App.HostComponentView', function() {
     });
   });
 
-  afterEach(function () {
-    App.router.get.restore();
-  });
-
   describe('#disabled', function() {
 
     var tests = Em.A([
@@ -243,50 +228,33 @@ describe('App.HostComponentView', function() {
   describe('#isDeleteComponentDisabled', function() {
 
     beforeEach(function() {
-      sinon.stub(App.StackServiceComponent, 'find', function(component) {
-        var min = component == 'comp0' ? 0 : 1;
-        return Em.Object.create({minToInstall: min});
-      });
+      this.mock = sinon.stub(App.StackServiceComponent, 'find');
+      sinon.stub(App.HostComponent, 'getCount').returns(1);
     });
     afterEach(function() {
-      App.StackServiceComponent.find.restore();
+      this.mock.restore();
+      App.HostComponent.getCount.restore();
     });
 
-    var tests = ['INSTALLED', 'UNKNOWN', 'INSTALL_FAILED', 'UPGRADE_FAILED', 'INIT'];
-    var testE = false;
-    var defaultE = true;
-
-    App.HostComponentStatus.getStatusesList().forEach(function(status) {
-      it(status, function() {
-        App.store.load(App.StackServiceComponent, {
-          id: 1,
-          component_name: 'comp0'
-        });
-        hostComponentView.get('hostComponent').set('componentName', 'comp0');
-        hostComponentView.get('hostComponent').set('workStatus', status);
-        var e = tests.contains(status) ? testE : defaultE;
-        expect(hostComponentView.get('isDeleteComponentDisabled')).to.equal(e);
-      });
+    it('delete is disabled because min cardinality 1', function() {
+      this.mock.returns(Em.Object.create({minToInstall: 1}));
+      hostComponentView.get('hostComponent').set('componentName', 'C1');
+      hostComponentView.propertyDidChange('isDeleteComponentDisabled');
+      expect(hostComponentView.get('isDeleteComponentDisabled')).to.be.true;
     });
 
-    it('delete is disabled because min cardinality 1', function() {
-      App.store.load(App.StackServiceComponent, {
-        id: 2,
-        component_name: 'comp1'
-      });
-      hostComponentView.get('hostComponent').set('componentName', 'comp1');
-      hostComponentView.get('hostComponent').set('workStatus', 'INSTALLED');
-      expect(hostComponentView.get('isDeleteComponentDisabled')).to.equal(true);
+    it('delete is disabled because min cardinality 0 and status INSTALLED', function() {
+      this.mock.returns(Em.Object.create({minToInstall: 0}));
+      hostComponentView.get('hostComponent').set('workStatus', 'INIT');
+      hostComponentView.propertyDidChange('isDeleteComponentDisabled');
+      expect(hostComponentView.get('isDeleteComponentDisabled')).to.be.false;
     });
 
-    it('delete is enabled because min cardinality 0', function() {
-      App.store.load(App.StackServiceComponent, {
-        id: 2,
-        component_name: 'comp0'
-      });
-      hostComponentView.get('hostComponent').set('componentName', 'comp0');
-      hostComponentView.get('hostComponent').set('workStatus', 'INSTALLED');
-      expect(hostComponentView.get('isDeleteComponentDisabled')).to.equal(false);
+    it('delete is enabled because min cardinality 0 and status STARTED', function() {
+      this.mock.returns(Em.Object.create({minToInstall: 0}));
+      hostComponentView.get('hostComponent').set('workStatus', 'STARTED');
+      hostComponentView.propertyDidChange('isDeleteComponentDisabled');
+      expect(hostComponentView.get('isDeleteComponentDisabled')).to.be.true;
     });
   });
 
@@ -470,125 +438,6 @@ describe('App.HostComponentView', function() {
     });
   });
 
-  describe('#masterCustomCommands', function() {
-    var content = [
-      {
-        componentName: 'MASTER_COMPONENT',
-        hostName: '01'
-      }
-    ];
-
-    beforeEach(function () {
-      sinon.stub(App.HostComponentActionMap, 'getMap', function () {
-        return {
-          REFRESHQUEUES: {
-            action: 'refreshYarnQueues',
-            customCommand: 'REFRESHQUEUES',
-            context : Em.I18n.t('services.service.actions.run.yarnRefreshQueues.context'),
-            label: Em.I18n.t('services.service.actions.run.yarnRefreshQueues.menu'),
-            cssClass: 'icon-refresh',
-            disabled: false
-          }
-        }
-      });
-    });
-
-
-    //two components, one running, active one is stopped
-    it('Should not get custom commands for master component if component not running', function() {
-      sinon.stub(App.StackServiceComponent, 'find', function() {
-        return Em.Object.create({
-          componentName: 'MASTER_COMPONENT',
-          isSlave: false,
-          isMaster: true,
-          isStart: false,
-          customCommands: ['DECOMMISSION', 'REFRESHQUEUES']
-        });
-      });
-
-      hostComponentView.set('componentCounter', 2);
-
-      sinon.stub(hostComponentView, 'runningComponentCounter', function () {
-        return 1;
-      });
-
-      hostComponentView.set('content', content);
-      expect(hostComponentView.get('customCommands')).to.have.length(0);
-    });
-
-    //two components, none running
-    it('Should get custom commands for master component when all components are stopped', function() {
-      sinon.stub(App.StackServiceComponent, 'find', function() {
-        return Em.Object.create({
-          componentName: 'MASTER_COMPONENT',
-          isSlave: false,
-          isMaster: true,
-          isStart: false,
-          customCommands: ['DECOMMISSION', 'REFRESHQUEUES']
-        });
-      });
-
-      hostComponentView.set('componentCounter', 2);
-
-      sinon.stub(hostComponentView, 'runningComponentCounter', function () {
-        return 0;
-      });
-
-      hostComponentView.set('content', content);
-      expect(hostComponentView.get('customCommands')).to.have.length(1);
-    });
-
-    //two components, two running, only commission and decommission custom commands
-    it('Should not show COMMISSION and DECOMMISSION on master', function() {
-      sinon.stub(App.StackServiceComponent, 'find', function() {
-        return Em.Object.create({
-          componentName: 'MASTER_COMPONENT',
-          isSlave: false,
-          isMaster: true,
-          isStart: false,
-          customCommands: ['DECOMMISSION', 'RECOMMISSION']
-        });
-      });
-
-      hostComponentView.set('componentCounter', 2);
-
-      sinon.stub(hostComponentView, 'runningComponentCounter', function () {
-        return 2;
-      });
-
-      hostComponentView.set('content', content);
-      expect(hostComponentView.get('customCommands')).to.have.length(0);
-    });
-
-    //one component, one running, cardinality 1
-    it('Should show custom command for cardinality 1', function() {
-      sinon.stub(App.StackServiceComponent, 'find', function() {
-        return Em.Object.create({
-          isSlave: false,
-          cardinality: '1',
-          isMaster: true,
-          isStart: true,
-          customCommands: ['DECOMMISSION', 'REFRESHQUEUES']
-        });
-      });
-
-      hostComponentView.set('componentCounter', 1);
-
-      sinon.stub(hostComponentView, 'runningComponentCounter', function () {
-        return 1;
-      });
-
-      hostComponentView.set('content', content);
-      expect(hostComponentView.get('customCommands')).to.have.length(1);
-    });
-
-    afterEach(function() {
-      App.HostComponentActionMap.getMap.restore();
-      App.StackServiceComponent.find.restore();
-      hostComponentView.runningComponentCounter.restore();
-    });
-  });
-
   describe('#getCustomCommandLabel', function() {
 
     beforeEach(function () {
@@ -654,4 +503,147 @@ describe('App.HostComponentView', function() {
       })
     });
   });
+
+  describe("#isDeletableComponent", function() {
+    beforeEach(function(){
+      sinon.stub(App, 'get').returns(['C1']);
+    });
+    afterEach(function(){
+      App.get.restore();
+    });
+    it("component deletable", function() {
+      hostComponentView.set('content.componentName', 'C1');
+      hostComponentView.propertyDidChange('isDeletableComponent');
+      expect(hostComponentView.get('isDeletableComponent')).to.be.true;
+    });
+    it("component is not deletable", function() {
+      hostComponentView.set('content.componentName', 'C2');
+      hostComponentView.propertyDidChange('isDeletableComponent');
+      expect(hostComponentView.get('isDeletableComponent')).to.be.false;
+    });
+  });
+
+  describe("#isMoveComponentDisabled", function() {
+    beforeEach(function(){
+      sinon.stub(App.HostComponent, 'find').returns([
+        Em.Object.create({componentName: 'C1', hostName: 'host1'}),
+        Em.Object.create({componentName: 'C1', hostName: 'host2'}),
+        Em.Object.create({componentName: 'C2', hostName: 'host1'})
+      ]);
+    });
+    afterEach(function(){
+      App.HostComponent.find.restore();
+    });
+    it("component is not movable", function() {
+      App.set('allHostNames', ['host1', 'host2']);
+      hostComponentView.set('content.componentName', 'C1');
+      hostComponentView.propertyDidChange('isMoveComponentDisabled');
+      expect(hostComponentView.get('isMoveComponentDisabled')).to.be.true;
+    });
+    it("component movable", function() {
+      App.set('allHostNames', ['host1', 'host2']);
+      hostComponentView.set('content.componentName', 'C2');
+      hostComponentView.propertyDidChange('isMoveComponentDisabled');
+      expect(hostComponentView.get('isMoveComponentDisabled')).to.be.false;
+    });
+  });
+
+  describe("#runningComponentCounter()", function() {
+    beforeEach(function(){
+      sinon.stub(App.HostComponent, 'find').returns([
+        Em.Object.create({componentName: 'C1', workStatus: 'STARTED'}),
+        Em.Object.create({componentName: 'C2', workStatus: 'INSTALLED'})
+      ]);
+    });
+    afterEach(function(){
+      App.HostComponent.find.restore();
+    });
+    it("running components present", function() {
+      hostComponentView.set('content.componentName', 'C1');
+      expect(hostComponentView.runningComponentCounter()).to.equal(1);
+    });
+    it("running components absent", function() {
+      hostComponentView.set('content.componentName', 'C2');
+      expect(hostComponentView.runningComponentCounter()).to.equal(0);
+    });
+  });
+
+  describe("#isReassignable", function() {
+    beforeEach(function(){
+      sinon.stub(App, 'get').returns(['C1']);
+      this.mock = sinon.stub(App.router, 'get');
+    });
+    afterEach(function(){
+      App.get.restore();
+      this.mock.restore();
+    });
+    it("component reassignable and count is 2", function() {
+      this.mock.returns({TOTAL: 2});
+      hostComponentView.set('content.componentName', 'C1');
+      hostComponentView.propertyDidChange('isReassignable');
+      expect(hostComponentView.get('isReassignable')).to.be.true;
+    });
+    it("component reassignable and count is 1", function() {
+      this.mock.returns({TOTAL: 1});
+      hostComponentView.set('content.componentName', 'C1');
+      hostComponentView.propertyDidChange('isReassignable');
+      expect(hostComponentView.get('isReassignable')).to.be.false;
+    });
+    it("component is not reassignable", function() {
+      hostComponentView.set('content.componentName', 'C2');
+      hostComponentView.propertyDidChange('isReassignable');
+      expect(hostComponentView.get('isReassignable')).to.be.false;
+    });
+  });
+
+  describe("#isRestartableComponent", function() {
+    beforeEach(function(){
+      sinon.stub(App, 'get').returns(['C1']);
+    });
+    afterEach(function(){
+      App.get.restore();
+    });
+    it("component deletable", function() {
+      hostComponentView.set('content.componentName', 'C1');
+      hostComponentView.propertyDidChange('isRestartableComponent');
+      expect(hostComponentView.get('isRestartableComponent')).to.be.true;
+    });
+    it("component is not deletable", function() {
+      hostComponentView.set('content.componentName', 'C2');
+      hostComponentView.propertyDidChange('isRestartableComponent');
+      expect(hostComponentView.get('isRestartableComponent')).to.be.false;
+    });
+  });
+
+  describe("#isRefreshConfigsAllowed", function() {
+    beforeEach(function(){
+      sinon.stub(App, 'get').returns(['C1']);
+    });
+    afterEach(function(){
+      App.get.restore();
+    });
+    it("component deletable", function() {
+      hostComponentView.set('content.componentName', 'C1');
+      hostComponentView.propertyDidChange('isRefreshConfigsAllowed');
+      expect(hostComponentView.get('isRefreshConfigsAllowed')).to.be.true;
+    });
+    it("component is not deletable", function() {
+      hostComponentView.set('content.componentName', 'C2');
+      hostComponentView.propertyDidChange('isRefreshConfigsAllowed');
+      expect(hostComponentView.get('isRefreshConfigsAllowed')).to.be.false;
+    });
+  });
+
+  describe("#isRestartComponentDisabled", function() {
+    it("component is restartable", function() {
+      hostComponentView.get('hostComponent').set('workStatus', 'STARTED');
+      hostComponentView.propertyDidChange('isRestartComponentDisabled');
+      expect(hostComponentView.get('isRestartComponentDisabled')).to.be.false;
+    });
+    it("component is not restartable", function() {
+      hostComponentView.get('hostComponent').set('workStatus', 'INSTALLED');
+      hostComponentView.propertyDidChange('isRestartComponentDisabled');
+      expect(hostComponentView.get('isRestartComponentDisabled')).to.be.true;
+    });
+  });
 });


[2/2] ambari git commit: AMBARI-13285 Cover Component Reassign wizard controllers with unit tests. (atkach)

Posted by at...@apache.org.
AMBARI-13285 Cover Component Reassign wizard controllers with unit tests. (atkach)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4e5489ba
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4e5489ba
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4e5489ba

Branch: refs/heads/trunk
Commit: 4e5489bac15f92771eaaa86e548bc7b09dd1945f
Parents: 0fc2cd5
Author: Andrii Tkach <at...@hortonworks.com>
Authored: Thu Oct 1 14:47:36 2015 +0300
Committer: Andrii Tkach <at...@hortonworks.com>
Committed: Thu Oct 1 15:58:30 2015 +0300

----------------------------------------------------------------------
 ambari-web/app/assets/test/tests.js             |   5 +
 ambari-web/app/controllers/main/host/details.js |   5 +-
 .../main/host/host_alerts_controller.js         |   4 +-
 .../main/service/reassign/step1_controller.js   |  24 +-
 .../main/service/reassign/step4_controller.js   |  33 +-
 .../main/service/reassign/step6_controller.js   |  24 +-
 ambari-web/app/messages.js                      |   2 +
 ambari-web/app/models/service/flume.js          |   6 +-
 .../select_definitions_popup_body_view.js       |  66 ++--
 .../main/host/details/host_component_view.js    |  38 +-
 .../test/controllers/main/host/details_test.js  | 352 +++++++++++++++--
 .../main/host/host_alerts_controller_test.js    |  48 +++
 .../service/reassign/step1_controller_test.js   |  71 ++++
 .../service/reassign/step2_controller_test.js   |  47 +++
 .../service/reassign/step3_controller_test.js   |  51 +++
 .../service/reassign/step4_controller_test.js   | 362 ++++++++++++++++-
 .../service/reassign/step6_controller_test.js   |  58 +--
 .../service/reassign/step7_controller_test.js   |  76 +++-
 ambari-web/test/models/service/flume_test.js    |  21 +-
 .../add_alert_definition/step1_view_test.js     |  47 +++
 .../add_alert_definition/step3_view_test.js     |  41 ++
 .../select_definitions_popup_body_view_test.js  | 385 +++++++++++++++++++
 .../host/details/host_component_view_test.js    | 332 ++++++++--------
 23 files changed, 1743 insertions(+), 355 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/app/assets/test/tests.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js
index 318fcc6..8ace78c 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -76,6 +76,7 @@ var files = [
   'test/controllers/main/charts/heatmap_metrics/heatmap_metric_test',
   'test/controllers/main/alerts/manage_alert_groups_controller_test',
   'test/controllers/main/host/add_controller_test',
+  'test/controllers/main/host/host_alerts_controller_test',
   'test/controllers/main/host/configs_service_test',
   'test/controllers/main/host/details_test',
   'test/controllers/main/host/addHost/step4_controller_test',
@@ -84,6 +85,7 @@ var files = [
   'test/controllers/main/service/reassign_controller_test',
   'test/controllers/main/service/reassign/step1_controller_test',
   'test/controllers/main/service/reassign/step2_controller_test',
+  'test/controllers/main/service/reassign/step3_controller_test',
   'test/controllers/main/service/reassign/step4_controller_test',
   'test/controllers/main/service/reassign/step6_controller_test',
   'test/controllers/main/service/reassign/step7_controller_test',
@@ -205,6 +207,9 @@ var files = [
   'test/views/main/alerts/manage_alert_groups_view_test',
   'test/views/main/alerts/manage_alert_notifications_view_test',
   'test/views/main/alerts/definition_details_view_test',
+  'test/views/main/alerts/add_alert_definition/step1_view_test',
+  'test/views/main/alerts/add_alert_definition/step3_view_test',
+  'test/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view_test',
   'test/views/main/admin/stack_upgrade/upgrade_version_box_view_test',
   'test/views/main/admin/stack_upgrade/upgrade_group_view_test',
   'test/views/main/admin/stack_upgrade/upgrade_task_view_test',

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/app/controllers/main/host/details.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js
index 9bc8c11..0fbe448 100644
--- a/ambari-web/app/controllers/main/host/details.js
+++ b/ambari-web/app/controllers/main/host/details.js
@@ -430,10 +430,9 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
     if (data.componentName == 'ZOOKEEPER_SERVER') {
       this.set('fromDeleteZkServer', true);
       this.updateStormConfigs();
-      var callback =   function () {
+      self.isServiceMetricsLoaded(function () {
         self.loadConfigs();
-      };
-      self.isServiceMetricsLoaded(callback);
+      });
     } else if (data.componentName == 'HIVE_METASTORE') {
       this.set('deleteHiveMetaStore', true);
       this.loadConfigs('loadHiveConfigs');

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/app/controllers/main/host/host_alerts_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host/host_alerts_controller.js b/ambari-web/app/controllers/main/host/host_alerts_controller.js
index a44aa26..a864b28 100644
--- a/ambari-web/app/controllers/main/host/host_alerts_controller.js
+++ b/ambari-web/app/controllers/main/host/host_alerts_controller.js
@@ -39,9 +39,7 @@ App.MainHostAlertsController = Em.ArrayController.extend({
    * @method routeToAlertDefinition
    */
   routeToAlertDefinition: function (event) {
-    var alertDefinition = App.AlertDefinition.find().findProperty('id', event.context);
+    var alertDefinition = App.AlertDefinition.find(event.context);
     App.router.transitionTo('main.alerts.alertDetails', alertDefinition);
   }
-
-
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/app/controllers/main/service/reassign/step1_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/reassign/step1_controller.js b/ambari-web/app/controllers/main/service/reassign/step1_controller.js
index d8e9f76..9f30bb7 100644
--- a/ambari-web/app/controllers/main/service/reassign/step1_controller.js
+++ b/ambari-web/app/controllers/main/service/reassign/step1_controller.js
@@ -22,21 +22,13 @@ App.ReassignMasterWizardStep1Controller = Em.Controller.extend({
   name: 'reassignMasterWizardStep1Controller',
   databaseType: null,
 
-  dbProperty: function() {
-    var componentName = this.get('content.reassign.component_name');
-
-    var property = null;
-    switch(componentName) {
-      case 'HIVE_SERVER':
-      case 'HIVE_METASTORE':
-        property = 'javax.jdo.option.ConnectionDriverName';
-        break;
-      case 'OOZIE_SERVER':
-        property = 'oozie.service.JPAService.jdbc.driver';
-        break;
-    }
-
-    return property;
+  /**
+   * @type {object}
+   */
+  dbPropertyMap: {
+    'HIVE_SERVER': 'javax.jdo.option.ConnectionDriverName',
+    'HIVE_METASTORE': 'javax.jdo.option.ConnectionDriverName',
+    'OOZIE_SERVER': 'oozie.service.JPAService.jdbc.driver'
   },
 
   loadConfigsTags: function () {
@@ -98,7 +90,7 @@ App.ReassignMasterWizardStep1Controller = Em.Controller.extend({
 
     this.set('content.serviceProperties', properties);
 
-    databaseProperty = properties[ this.dbProperty() ];
+    databaseProperty = properties[ Em.getWithDefault(this.get('dbPropertyMap'), this.get('content.reassign.component_name'), null) ];
     databaseType = databaseProperty.match(/MySQL|PostgreS|Oracle|Derby|MSSQL|Anywhere/gi)[0];
     this.set('databaseType', databaseType);
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/app/controllers/main/service/reassign/step4_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/reassign/step4_controller.js b/ambari-web/app/controllers/main/service/reassign/step4_controller.js
index 44dfeff..148e922 100644
--- a/ambari-web/app/controllers/main/service/reassign/step4_controller.js
+++ b/ambari-web/app/controllers/main/service/reassign/step4_controller.js
@@ -79,6 +79,12 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
     'MYSQL_SERVER': ['HDFS', 'ZOOKEEPER', 'HBASE', 'FLUME', 'SQOOP', 'STORM']
   },
 
+  dbPropertyMap: {
+    'HIVE_SERVER': 'javax.jdo.option.ConnectionDriverName',
+    'HIVE_METASTORE': 'javax.jdo.option.ConnectionDriverName',
+    'OOZIE_SERVER': 'oozie.service.JPAService.jdbc.url'
+  },
+
   /**
    * additional configs with template values
    * Part of value to substitute has following format: "<replace-value>"
@@ -895,7 +901,7 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
    * make server call to clean MYSQL
    */
   cleanMySqlServer: function () {
-    var hostname = App.HostComponent.find().filterProperty('componentName', 'MYSQL_SERVER').get('firstObject.hostName');
+    var hostname = App.HostComponent.find().findProperty('componentName', 'MYSQL_SERVER').get('hostName');
 
     if (this.get('content.reassign.component_name') === 'MYSQL_SERVER') {
       hostname = this.get('content.reassignHosts.target');
@@ -916,7 +922,7 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
    * make server call to configure MYSQL
    */
   configureMySqlServer : function () {
-    var hostname = App.HostComponent.find().filterProperty('componentName', 'MYSQL_SERVER').get('firstObject.hostName');
+    var hostname = App.HostComponent.find().findProperty('componentName', 'MYSQL_SERVER').get('hostName');
 
     if (this.get('content.reassign.component_name') === 'MYSQL_SERVER') {
       hostname = this.get('content.reassignHosts.target');
@@ -939,7 +945,7 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
       sender: this,
       data: {
         context: "Start MySQL Server",
-        hostName: App.HostComponent.find().filterProperty('componentName', 'MYSQL_SERVER').get('firstObject.hostName'),
+        hostName: App.HostComponent.find().findProperty('componentName', 'MYSQL_SERVER').get('hostName'),
         serviceName: "HIVE",
         componentName: "MYSQL_SERVER",
         HostRoles: {
@@ -1007,23 +1013,6 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
     return ['HIVE_SERVER', 'HIVE_METASTORE', 'OOZIE_SERVER'].contains(this.get('content.reassign.component_name'));
   },
 
-  dbProperty: function() {
-    var componentName = this.get('content.reassign.component_name');
-
-    var property = null;
-    switch(componentName) {
-      case 'HIVE_SERVER':
-      case 'HIVE_METASTORE':
-        property = 'javax.jdo.option.ConnectionDriverName';
-        break;
-      case 'OOZIE_SERVER':
-        property = 'oozie.service.JPAService.jdbc.url';
-        break;
-    }
-
-    return property;
-  }.property(),
-
   /** @property {Object} propertiesPattern - check pattern according to type of connection properties **/
   propertiesPattern: function() {
     return {
@@ -1078,10 +1067,10 @@ App.ReassignMasterWizardStep4Controller = App.HighAvailabilityProgressPageContro
 
   dbType: function() {
     var databaseTypes = /MySQL|PostgreS|Oracle|Derby|MSSQL|Anywhere/gi;
-    var databaseProp = this.get('content.serviceProperties')[this.get('dbProperty')];
+    var databaseProp = this.get('content.serviceProperties')[Em.getWithDefault(this.get('dbPropertyMap'), this.get('content.reassign.component_name'), null)];
 
     return databaseProp.match(databaseTypes)[0];
-  }.property('dbProperty'),
+  }.property(),
 
   prepareDBCheckAction: function() {
     var ambariProperties = null;

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/app/controllers/main/service/reassign/step6_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/reassign/step6_controller.js b/ambari-web/app/controllers/main/service/reassign/step6_controller.js
index b16e2aa..e1cda96 100644
--- a/ambari-web/app/controllers/main/service/reassign/step6_controller.js
+++ b/ambari-web/app/controllers/main/service/reassign/step6_controller.js
@@ -46,7 +46,7 @@ App.ReassignMasterWizardStep6Controller = App.HighAvailabilityProgressPageContro
     }, this);
     var currentStep = App.router.get('reassignMasterController.currentStep');
     for (var i = 0; i < commands.length; i++) {
-      var title =  Em.I18n.t('services.reassign.step6.tasks.' + commands[i] + '.title').format(hostComponentsNames);
+      var title = Em.I18n.t('services.reassign.step6.tasks.' + commands[i] + '.title').format(hostComponentsNames);
       this.get('tasks').pushObject(Ember.Object.create({
         title: title,
         status: 'PENDING',
@@ -76,21 +76,19 @@ App.ReassignMasterWizardStep6Controller = App.HighAvailabilityProgressPageContro
    * remove tasks by command name
    */
   removeTasks: function(commands) {
-    var tasks = this.get('tasks'),
-        index = null
-        cmd = null;
+    var tasks = this.get('tasks');
 
     commands.forEach(function(command) {
-      cmd = tasks.filterProperty('command', command);
-
-      if (cmd.length === 0) {
-        return false;
-      } else {
-        index = tasks.indexOf( cmd[0] );
+      var index;
+      tasks.forEach(function(_task, _index) {
+        if (_task.get('command') === command) {
+          index = _index;
+        }
+      });
+      if (!Em.isNone(index)) {
+        tasks.splice(index, 1);
       }
-
-      tasks.splice( index, 1 );
-    });
+    }, this);
   },
 
   hideRollbackButton: function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index e31acb3..9a24873 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -273,6 +273,8 @@ Em.I18n.translations = {
   'common.testing': 'Testing',
   'common.noData': 'No Data',
   'common.loading.eclipses': 'Loading...',
+  'common.running': 'Running',
+  'common.stopped': 'Stopped',
 
   'models.alert_instance.tiggered.verbose': "Occurred on {0} <br> Checked on {1}",
   'models.alert_definition.triggered.verbose': "Occurred on {0}",

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/app/models/service/flume.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/service/flume.js b/ambari-web/app/models/service/flume.js
index dd4167f..9bbcc1a 100644
--- a/ambari-web/app/models/service/flume.js
+++ b/ambari-web/app/models/service/flume.js
@@ -59,14 +59,14 @@ App.FlumeAgent = DS.Model.extend({
   displayStatus : function() {
     switch (this.get('status')) {
       case 'RUNNING':
-        return "Running";
+        return Em.I18n.t('common.running');
         break;
       case 'NOT_RUNNING':
-        return "Stopped";
+        return Em.I18n.t('common.stopped');
         break;
       case 'UNKNOWN':
       default:
-        return "Unknown";
+        return Em.I18n.t('common.unknown');
         break;
     }
   }.property('status')

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/app/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view.js b/ambari-web/app/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view.js
index e7a23a3..85b2ec0 100644
--- a/ambari-web/app/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view.js
+++ b/ambari-web/app/views/main/alerts/manage_alert_groups/select_definitions_popup_body_view.js
@@ -37,15 +37,19 @@ App.SelectDefinitionsPopupBodyView = App.TableView.extend({
     this.set('filteredContent', filtered);
   },
 
+  /**
+   * @type {boolean}
+   */
   showOnlySelectedDefs: false,
 
   filterComponent: null,
 
   filterService: null,
 
-  isDisabled: function () {
-    return !this.get('parentView.isLoaded');
-  }.property('parentView.isLoaded'),
+  /**
+   * @type {boolean}
+   */
+  isDisabled: Em.computed.not('parentView.isLoaded'),
 
   didInsertElement: function () {
     var initialDefs = this.get('initialDefs');
@@ -60,37 +64,41 @@ App.SelectDefinitionsPopupBodyView = App.TableView.extend({
    */
   filter: Em.K,
 
+  /**
+   * filter definitions by componentName and serviceName
+   */
   filterDefs: function () {
     var showOnlySelectedDefs = this.get('showOnlySelectedDefs');
     var filterComponent = this.get('filterComponent');
     var filterService = this.get('filterService');
+
     this.get('parentView.availableDefs').forEach(function (defObj) {
-      var componentOnObj = true;
-      var serviceOnObj = true;
-      if (filterComponent) {
-        componentOnObj = (defObj.componentName == filterComponent.get('componentName'));
-      }
-      if (defObj.serviceName && filterService) {
-        serviceOnObj = (defObj.serviceName == filterService.get('serviceName'));
-      }
-      defObj.set('filtered', showOnlySelectedDefs ? (componentOnObj && serviceOnObj && defObj.get('selected')) : (componentOnObj && serviceOnObj));
+      var matchComponent = filterComponent ? (defObj.get('componentName') === filterComponent.get('componentName')) : true,
+          matchService = filterService ? (defObj.get('serviceName') === filterService.get('serviceName')) : true,
+          filtered = (matchComponent && matchService);
+
+      defObj.set('filtered', showOnlySelectedDefs ? (filtered && defObj.get('selected')) : filtered);
     }, this);
     this.set('startIndex', 1);
-  }.observes('parentView.availableDefs', 'filterService', 'filterService.serviceName', 'filterComponent', 'filterComponent.componentName', 'showOnlySelectedDefs'),
+  }.observes('parentView.availableDefs', 'filterService.serviceName', 'filterComponent.componentName', 'showOnlySelectedDefs'),
 
   defSelectMessage: function () {
     var defs = this.get('parentView.availableDefs');
-    var selectedDefs = defs.filterProperty('selected', true);
-    return this.t('alerts.actions.manage_alert_groups_popup.selectDefsDialog.selectedDefsLink').format(selectedDefs.get('length'), defs.get('length'));
+    return this.t('alerts.actions.manage_alert_groups_popup.selectDefsDialog.selectedDefsLink')
+           .format(defs.filterProperty('selected').get('length'), defs.get('length'));
   }.property('parentView.availableDefs.@each.selected'),
 
+  /**
+   * apply component filter
+   * @param {object|null} event
+   */
   selectFilterComponent: function (event) {
-    if (event != null && event.context != null && event.context.componentName != null) {
+    if (event && event.context.get('componentName')) {
       var currentFilter = this.get('filterComponent');
-      if (currentFilter != null) {
+      if (currentFilter) {
         currentFilter.set('selected', false);
       }
-      if (currentFilter != null && currentFilter.componentName === event.context.componentName) {
+      if (currentFilter && currentFilter.get('componentName') === event.context.get('componentName')) {
         // selecting the same filter deselects it.
         this.set('filterComponent', null);
       } else {
@@ -100,13 +108,17 @@ App.SelectDefinitionsPopupBodyView = App.TableView.extend({
     }
   },
 
+  /**
+   * apply service filter
+   * @param {object|null} event
+   */
   selectFilterService: function (event) {
-    if (event != null && event.context != null && event.context.serviceName != null) {
+    if (event && event.context.get('serviceName')) {
       var currentFilter = this.get('filterService');
-      if (currentFilter != null) {
+      if (currentFilter) {
         currentFilter.set('selected', false);
       }
-      if (currentFilter != null && currentFilter.serviceName === event.context.serviceName) {
+      if (currentFilter && currentFilter.get('serviceName') === event.context.get('serviceName')) {
         // selecting the same filter deselects it.
         this.set('filterService', null);
       } else {
@@ -131,16 +143,10 @@ App.SelectDefinitionsPopupBodyView = App.TableView.extend({
   }.observes('allDefsSelected'),
 
   toggleShowSelectedDefs: function () {
-    var filter1 = this.get('filterComponent');
-    if (filter1 != null) {
-      filter1.set('selected', false);
-    }
-    var filter2 = this.get('filterService');
-    if (filter2 != null) {
-      filter2.set('selected', false);
-    }
+    if (this.get('filterComponent')) this.get('filterComponent').set('selected', false);
+    if (this.get('filterService')) this.get('filterService').set('selected', false);
     this.set('filterComponent', null);
     this.set('filterService', null);
-    this.set('showOnlySelectedDefs', !this.get('showOnlySelectedDefs'));
+    this.toggleProperty('showOnlySelectedDefs');
   }
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/app/views/main/host/details/host_component_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/host/details/host_component_view.js b/ambari-web/app/views/main/host/details/host_component_view.js
index fca3a70..0335234 100644
--- a/ambari-web/app/views/main/host/details/host_component_view.js
+++ b/ambari-web/app/views/main/host/details/host_component_view.js
@@ -195,11 +195,11 @@ App.HostComponentView = Em.View.extend({
 
   /**
    * Host component with some <code>workStatus</code> can't be moved (so, disable such action in the dropdown list)
-   * @type {bool}
+   * @type {boolean}
    */
   isMoveComponentDisabled: function () {
-    return App.allHostNames.length === App.HostComponent.find().filterProperty('componentName', this.get('content.componentName')).mapProperty('hostName').length;
-  }.property('content'),
+    return App.get('allHostNames').length === App.HostComponent.find().filterProperty('componentName', this.get('content.componentName')).mapProperty('hostName').length;
+  }.property('content.componentName', 'App.allHostNames'),
 
   /**
    * Host component with some <code>workStatus</code> can't be deleted (so, disable such action in the dropdown list)
@@ -207,41 +207,19 @@ App.HostComponentView = Em.View.extend({
    */
   isDeleteComponentDisabled: function () {
     var stackComponentCount = App.StackServiceComponent.find(this.get('hostComponent.componentName')).get('minToInstall');
-    var installedCount = this.get('componentCounter');
+    var installedCount = App.HostComponent.getCount(this.get('hostComponent.componentName'), 'totalCount');
     return (installedCount <= stackComponentCount)
       || ![App.HostComponentStatus.stopped, App.HostComponentStatus.unknown, App.HostComponentStatus.install_failed, App.HostComponentStatus.upgrade_failed, App.HostComponentStatus.init].contains(this.get('workStatus'));
   }.property('workStatus', 'componentCounter'),
 
   /**
-   * gets number of current component that are applied to the cluster;
-   * @returns {Number}
-   */
-  componentCounter: function() {
-    var component;
-    var stackServiceComponent =  App.StackServiceComponent.find(this.get('hostComponent.componentName'));
-    if (stackServiceComponent && App.get('router.clusterController.isHostContentLoaded')) {
-      if (stackServiceComponent.get('isMaster')) {
-        component = App.MasterComponent.find().findProperty('componentName', this.get('content.componentName'))
-      } else {
-        component = App.SlaveComponent.find().findProperty('componentName', this.get('content.componentName'));
-      }
-    }
-    return component ? component.get('totalCount') : 0;
-  }.property('App.router.clusterController.isHostContentLoaded'),
-
-  /**
    * Gets number of current running components that are applied to the cluster
    * @returns {Number}
    */
   runningComponentCounter: function () {
-    var runningComponents;
-    var self = this;
-
-    runningComponents = App.HostComponent.find().filter(function (component) {
-      return (component.get('componentName') === self.get('content.componentName') && [App.HostComponentStatus.started, App.HostComponentStatus.starting].contains(component.get('workStatus')))
-    });
-
-    return runningComponents ? runningComponents.length : 0;
+    return App.HostComponent.find().filter(function (component) {
+      return (component.get('componentName') === this.get('content.componentName') && [App.HostComponentStatus.started, App.HostComponentStatus.starting].contains(component.get('workStatus')))
+    }, this).length;
   },
 
   /**
@@ -395,7 +373,7 @@ App.HostComponentView = Em.View.extend({
 
     if (component.get('cardinality') !== '1') {
       if (!this.get('isStart')) {
-        if (this.get('componentCounter') > 1) {
+        if (App.HostComponent.getCount(this.get('hostComponent.componentName'), 'totalCount') > 1) {
           if (this.runningComponentCounter()) {
             return false;
           }

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/test/controllers/main/host/details_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/host/details_test.js b/ambari-web/test/controllers/main/host/details_test.js
index 6121cc5..3110428 100644
--- a/ambari-web/test/controllers/main/host/details_test.js
+++ b/ambari-web/test/controllers/main/host/details_test.js
@@ -75,25 +75,34 @@ describe('App.MainHostDetailsController', function () {
   });
 
   describe('#stopComponent()', function () {
+
+    beforeEach(function () {
+      sinon.stub(App, 'showConfirmationPopup', function (callback) {
+        callback();
+      });
+      sinon.stub(controller, 'checkNnLastCheckpointTime', function (callback) {
+        callback();
+      });
+      sinon.stub(controller, 'sendComponentCommand');
+    });
+    afterEach(function () {
+      App.showConfirmationPopup.restore();
+      controller.sendComponentCommand.restore();
+      controller.checkNnLastCheckpointTime.restore();
+    });
+
     it('call sendComponentCommand', function () {
       var event = {
         context: Em.Object.create({
           displayName: 'comp'
         })
       };
-      sinon.stub(App, 'showConfirmationPopup', function (callback) {
-        callback();
-      });
-      sinon.stub(controller, 'sendComponentCommand');
       controller.stopComponent(event);
       expect(App.showConfirmationPopup.calledOnce).to.be.true;
       expect(controller.sendComponentCommand.calledWith(Em.Object.create({
         displayName: 'comp'
-      })), Em.I18n.t('requestInfo.stopHostComponent') + " comp", App.HostComponentStatus.started).to.be.true;
-      App.showConfirmationPopup.restore();
-      controller.sendComponentCommand.restore();
+      })), Em.I18n.t('requestInfo.stopHostComponent') + " comp", App.HostComponentStatus.stopped).to.be.true;
     });
-
     it('stop NN, should check last NN checkpoint before stop', function () {
       var event = {
         context: Em.Object.create({
@@ -101,12 +110,24 @@ describe('App.MainHostDetailsController', function () {
           componentName: 'NAMENODE'
         })
       };
-      sinon.stub(controller, 'checkNnLastCheckpointTime', function() {
-        return true;
-      });
       controller.stopComponent(event);
-      expect(controller.checkNnLastCheckpointTime.calledOnce).to.equal(true);
-      controller.checkNnLastCheckpointTime.restore();
+      expect(controller.checkNnLastCheckpointTime.calledOnce).to.be.true;
+      expect(App.showConfirmationPopup.calledOnce).to.be.true;
+      expect(controller.sendComponentCommand.calledWith(event.context, Em.I18n.t('requestInfo.stopHostComponent') + " NameNode", App.HostComponentStatus.stopped)).to.be.true;
+    });
+  });
+
+  describe("#pullNnCheckPointTime()", function() {
+    it("", function() {
+      controller.pullNnCheckPointTime('host1');
+      expect(App.ajax.send.calledWith({
+        name: 'common.host_component.getNnCheckPointTime',
+        sender: controller,
+        data: {
+          host: 'host1'
+        },
+        success: 'parseNnCheckPointTime'
+      })).to.be.true;
     });
   });
 
@@ -361,7 +382,7 @@ describe('App.MainHostDetailsController', function () {
     });
 
     afterEach(function () {
-      window.$.restore();
+      jQueryMock.restore();
       App.ModalPopup.show.restore();
       controller._doDeleteHostComponent.restore();
     });
@@ -443,11 +464,14 @@ describe('App.MainHostDetailsController', function () {
     beforeEach(function () {
       sinon.spy(App, "showConfirmationPopup");
       sinon.stub(batchUtils, "restartHostComponents", Em.K);
+      sinon.stub(controller, 'checkNnLastCheckpointTime', function(callback) {
+        callback();
+      });
     });
-
     afterEach(function () {
       App.showConfirmationPopup.restore();
       batchUtils.restartHostComponents.restore();
+      controller.checkNnLastCheckpointTime.restore();
     });
 
     it('popup should be displayed', function () {
@@ -464,12 +488,9 @@ describe('App.MainHostDetailsController', function () {
           componentName: 'NAMENODE'
         })
       };
-      sinon.stub(controller, 'checkNnLastCheckpointTime', function() {
-        return true;
-      });
       controller.restartComponent(event);
       expect(controller.checkNnLastCheckpointTime.calledOnce).to.equal(true);
-      controller.checkNnLastCheckpointTime.restore();
+      expect(App.showConfirmationPopup.calledOnce).to.be.true;
     });
   });
 
@@ -568,18 +589,202 @@ describe('App.MainHostDetailsController', function () {
     });
 
     beforeEach(function () {
-      sinon.stub(controller, 'showAddComponentPopup', Em.K);
+      sinon.spy(controller, 'showAddComponentPopup');
+      sinon.stub(controller, 'installHostComponentCall', Em.K);
     });
 
     afterEach(function () {
       controller.showAddComponentPopup.restore();
+      controller.installHostComponentCall.restore();
     });
 
     it('any CLIENT component', function () {
+      controller.set('content.hostName', 'host1');
       var popup = controller.addClientComponent(component);
       expect(controller.showAddComponentPopup.calledOnce).to.be.true;
+      popup.onPrimary();
+      expect(controller.installHostComponentCall.calledWith('host1', component)).to.be.true;
+    });
+  });
+
+  describe("#loadOozieConfigs()", function() {
+    it("", function() {
+      controller.loadOozieConfigs({Clusters: {
+        desired_configs: {
+          'oozie-env': {
+            tag: 'tag'
+          }
+        }
+      }});
+      expect(App.ajax.send.calledWith({
+        name: 'admin.get.all_configurations',
+        sender: controller,
+        data: {
+          urlParams: '(type=oozie-env&tag=tag)'
+        },
+        success: 'onLoadOozieConfigs',
+        error: 'onLoadConfigsErrorCallback'
+      })).to.be.true;
+    });
+  });
+
+  describe("#loadStormConfigs()", function() {
+    it("", function() {
+      controller.loadStormConfigs({Clusters: {
+        desired_configs: {
+          'storm-site': {
+            tag: 'tag'
+          }
+        }
+      }});
+      expect(App.ajax.send.calledWith({
+        name: 'admin.get.all_configurations',
+        sender: controller,
+        data: {
+          urlParams: '(type=storm-site&tag=tag)'
+        },
+        success: 'onLoadStormConfigs'
+      })).to.be.true;
+    });
+  });
+
+  describe("#onLoadStormConfigs()", function() {
+    beforeEach(function () {
+      sinon.stub(controller, 'getStormNimbusHosts').returns("host1");
+      sinon.stub(controller, 'updateZkConfigs', Em.K);
+      sinon.stub(controller, 'saveConfigsBatch', Em.K);
+    });
+    afterEach(function () {
+      controller.getStormNimbusHosts.restore();
+      controller.updateZkConfigs.restore();
+      controller.saveConfigsBatch.restore();
+    });
+    it("", function() {
+      var data = {items: [
+        {
+          type: 'storm-site',
+          properties: {
+            'nimbus.seeds': ''
+          }
+        }
+      ]};
+      controller.set('nimbusHost', 'host2');
+      controller.onLoadStormConfigs(data);
+      expect(controller.updateZkConfigs.calledWith({'storm-site': {
+        'nimbus.seeds': "'host1'"
+      }})).to.be.true;
+      expect(controller.saveConfigsBatch.calledWith([
+        {
+          properties: {
+            'storm-site': {
+              'nimbus.seeds': "'host1'"
+            }
+          },
+          properties_attributes: {
+            'storm-site': {}
+          }
+        }
+      ], 'NIMBUS', 'host2')).to.be.true;
+    });
+  });
+
+  describe("#loadHiveConfigs()", function() {
+    it("", function() {
+      controller.loadHiveConfigs({Clusters: {
+        desired_configs: {
+          'hive-site': {
+            tag: 'tag'
+          },
+          'webhcat-site': {
+            tag: 'tag'
+          },
+          'hive-env': {
+            tag: 'tag'
+          },
+          'core-site': {
+            tag: 'tag'
+          }
+        }
+      }});
+      expect(App.ajax.send.calledWith({
+        name: 'admin.get.all_configurations',
+        sender: controller,
+        data: {
+          urlParams: '(type=hive-site&tag=tag)|(type=webhcat-site&tag=tag)|(type=hive-env&tag=tag)|(type=core-site&tag=tag)'
+        },
+        success: 'onLoadHiveConfigs'
+      })).to.be.true;
     });
+  });
 
+  describe("#loadRangerConfigs()", function() {
+    it("", function() {
+      controller.loadRangerConfigs({Clusters: {
+        desired_configs: {
+          'hdfs-site': {
+            tag: 'tag'
+          },
+          'kms-env': {
+            tag: 'tag'
+          },
+          'core-site': {
+            tag: 'tag'
+          }
+        }
+      }});
+      expect(App.ajax.send.calledWith({
+        name: 'admin.get.all_configurations',
+        sender: controller,
+        data: {
+          urlParams: '(type=core-site&tag=tag)|(type=hdfs-site&tag=tag)|(type=kms-env&tag=tag)'
+        },
+        success: 'onLoadRangerConfigs'
+      })).to.be.true;
+    });
+  });
+
+  describe("#getRangerKMSServerHosts()", function() {
+    beforeEach(function(){
+      sinon.stub(App.HostComponent, 'find').returns([{
+        componentName: 'RANGER_KMS_SERVER',
+        hostName: 'host1'
+      }]);
+    });
+    afterEach(function(){
+      App.HostComponent.find.restore();
+    });
+    it("", function() {
+      controller.set('rangerKMSServerHost', 'host2');
+      controller.set('content.hostName', 'host1');
+      controller.set('deleteRangerKMSServer', true);
+      controller.set('fromDeleteHost', true);
+      expect(controller.getRangerKMSServerHosts()).to.eql(['host2']);
+      expect(controller.get('rangerKMSServerHost')).to.be.empty;
+      expect(controller.get('deleteRangerKMSServer')).to.be.false;
+      expect(controller.get('fromDeleteHost')).to.be.false;
+    });
+  });
+
+  describe("#getStormNimbusHosts()", function() {
+    beforeEach(function(){
+      sinon.stub(App.HostComponent, 'find').returns([{
+        componentName: 'NIMBUS',
+        hostName: 'host1'
+      }]);
+    });
+    afterEach(function(){
+      App.HostComponent.find.restore();
+    });
+    it("", function() {
+      controller.set('nimbusHost', 'host2');
+      controller.set('content.hostName', 'host1');
+      controller.set('deleteNimbusHost', true);
+      controller.set('fromDeleteHost', true);
+      expect(controller.getStormNimbusHosts()).to.eql(['host2']);
+      expect(controller.get('nimbusHost')).to.be.empty;
+      expect(controller.get('deleteNimbusHost')).to.be.false;
+      expect(controller.get('fromDeleteHost')).to.be.false;
+    });
   });
 
   describe('#showAddComponentPopup()', function () {
@@ -913,6 +1118,15 @@ describe('App.MainHostDetailsController', function () {
         }
       });
     });
+    it('accumulo-site is present', function () {
+      var configs = {'accumulo-site': {}};
+      expect(controller.setZKConfigs(configs, 'host1:2181', [])).to.be.true;
+      expect(configs).to.eql({
+        "accumulo-site": {
+          "instance.zookeeper.host": 'host1:2181'
+        }
+      });
+    });
     it('webhcat-site is present', function () {
       var configs = {'webhcat-site': {}};
       expect(controller.setZKConfigs(configs, 'host1:2181', [])).to.be.true;
@@ -1359,6 +1573,7 @@ describe('App.MainHostDetailsController', function () {
       sinon.stub(controller, "doStopAllComponents", Em.K);
       sinon.stub(controller, "doRestartAllComponents", Em.K);
       sinon.stub(controller, "onOffPassiveModeForHost", Em.K);
+      sinon.stub(controller, "setRackIdForHost", Em.K);
     });
 
     afterEach(function () {
@@ -1367,6 +1582,7 @@ describe('App.MainHostDetailsController', function () {
       controller.doStopAllComponents.restore();
       controller.doRestartAllComponents.restore();
       controller.onOffPassiveModeForHost.restore();
+      controller.setRackIdForHost.restore();
     });
 
     it('"deleteHost" action', function () {
@@ -1422,6 +1638,27 @@ describe('App.MainHostDetailsController', function () {
       controller.doAction(option);
       expect(controller.onOffPassiveModeForHost.calledWith({action: "onOffPassiveModeForHost"})).to.be.true;
     });
+
+    it('"setRackId" action', function () {
+      var option = {context: {action: "setRackId"}};
+      controller.doAction(option);
+      expect(controller.setRackIdForHost.calledOnce).to.be.true;
+    });
+  });
+
+  describe("#setRackIdForHost()", function() {
+    beforeEach(function(){
+      sinon.stub(hostsManagement, 'setRackInfo', Em.K);
+    });
+    afterEach(function() {
+      hostsManagement.setRackInfo.restore();
+    });
+    it("", function() {
+      controller.set('content.rack', 'rack');
+      controller.set('content.hostName', 'host1');
+      controller.setRackIdForHost();
+      expect(hostsManagement.setRackInfo.calledWith({message: Em.I18n.t('hosts.host.details.setRackId')}, [{hostName: 'host1'}], 'rack')).to.be.true;
+    });
   });
 
   describe('#onOffPassiveModeForHost()', function () {
@@ -2118,23 +2355,23 @@ describe('App.MainHostDetailsController', function () {
       sinon.stub(controller, 'isServiceMetricsLoaded', function (callback) {
         callback();
       });
+      sinon.stub(controller, 'loadConfigs', Em.K);
     });
 
     afterEach(function () {
       controller.removeHostComponentModel.restore();
       controller.isServiceMetricsLoaded.restore();
+      controller.loadConfigs.restore();
     });
 
     it('ZOOKEEPER_SERVER component', function () {
       var data = {
         componentName: 'ZOOKEEPER_SERVER'
       };
-      sinon.stub(controller, 'loadConfigs', Em.K);
       controller._doDeleteHostComponentSuccessCallback({}, {}, data);
       expect(controller.get('_deletedHostComponentResult')).to.be.null;
       expect(controller.get('fromDeleteZkServer')).to.be.true;
       expect(controller.loadConfigs.calledOnce).to.be.true;
-      controller.loadConfigs.restore();
     });
     it('Not ZOOKEEPER_SERVER component', function () {
       var data = {
@@ -2153,6 +2390,33 @@ describe('App.MainHostDetailsController', function () {
       controller._doDeleteHostComponentSuccessCallback({}, {}, data);
       expect(controller.removeHostComponentModel.calledWith('COMPONENT', 'h1')).to.be.true;
     });
+    it('HIVE_METASTORE component', function () {
+      var data = {
+        componentName: 'HIVE_METASTORE'
+      };
+      controller._doDeleteHostComponentSuccessCallback({}, {}, data);
+      expect(controller.get('_deletedHostComponentResult')).to.be.null;
+      expect(controller.get('deleteHiveMetaStore')).to.be.true;
+      expect(controller.loadConfigs.calledWith('loadHiveConfigs')).to.be.true;
+    });
+    it('NIMBUS component', function () {
+      var data = {
+        componentName: 'NIMBUS'
+      };
+      controller._doDeleteHostComponentSuccessCallback({}, {}, data);
+      expect(controller.get('_deletedHostComponentResult')).to.be.null;
+      expect(controller.get('deleteNimbusHost')).to.be.true;
+      expect(controller.loadConfigs.calledWith('loadStormConfigs')).to.be.true;
+    });
+    it('RANGER_KMS_SERVER component', function () {
+      var data = {
+        componentName: 'RANGER_KMS_SERVER'
+      };
+      controller._doDeleteHostComponentSuccessCallback({}, {}, data);
+      expect(controller.get('_deletedHostComponentResult')).to.be.null;
+      expect(controller.get('deleteRangerKMSServer')).to.be.true;
+      expect(controller.loadConfigs.calledWith('loadRangerConfigs')).to.be.true;
+    });
   });
 
   describe('#upgradeComponentSuccessCallback()', function () {
@@ -3023,4 +3287,48 @@ describe('App.MainHostDetailsController', function () {
       });
     });
   });
+
+  describe("#checkComponentDependencies()", function() {
+
+    beforeEach(function () {
+      this.mock = sinon.stub(App.StackServiceComponent, 'find');
+      sinon.stub(App.HostComponent, 'find').returns([{
+        hostName: 'host1',
+        componentName: 'C1'
+      }]);
+    });
+    afterEach(function () {
+      this.mock.restore();
+      App.HostComponent.find.restore();
+    });
+
+    it("no dependencies", function () {
+      var opt = {scope: '*'};
+      this.mock.returns(Em.Object.create({
+        dependencies: []
+      }));
+      expect(controller.checkComponentDependencies('C1', opt)).to.be.empty;
+    });
+    it("dependecies already installed", function () {
+      var opt = {scope: '*', installedComponents: ['C2']};
+      this.mock.returns(Em.Object.create({
+        dependencies: [{componentName: 'C2'}]
+      }));
+      expect(controller.checkComponentDependencies('C1', opt)).to.be.empty;
+    });
+    it("dependecies should be added", function () {
+      var opt = {scope: '*', installedComponents: ['C2']};
+      this.mock.returns(Em.Object.create({
+        dependencies: [{componentName: 'C3'}]
+      }));
+      expect(controller.checkComponentDependencies('C1', opt)).to.eql(['C3']);
+    });
+    it("scope is host", function () {
+      var opt = {scope: 'host', hostName: 'host1'};
+      this.mock.returns(Em.Object.create({
+        dependencies: [{componentName: 'C3', scope: 'host'}]
+      }));
+      expect(controller.checkComponentDependencies('C1', opt)).to.eql(['C3']);
+    });
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/test/controllers/main/host/host_alerts_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/host/host_alerts_controller_test.js b/ambari-web/test/controllers/main/host/host_alerts_controller_test.js
new file mode 100644
index 0000000..ac75090
--- /dev/null
+++ b/ambari-web/test/controllers/main/host/host_alerts_controller_test.js
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+var App = require('app');
+require('controllers/main/host/host_alerts_controller');
+
+var controller;
+
+describe('App.MainHostAlertsController', function () {
+
+  beforeEach(function() {
+    controller = App.MainHostAlertsController.create();
+  });
+
+  describe("#routeToAlertDefinition()", function () {
+
+    beforeEach(function () {
+      sinon.stub(App.AlertDefinition, 'find').returns('alertDefinition');
+      sinon.stub(App.router, 'transitionTo', Em.K);
+    });
+    afterEach(function () {
+      App.AlertDefinition.find.restore();
+      App.router.transitionTo.restore();
+    });
+
+    it("", function () {
+      controller.routeToAlertDefinition({context: 'id'});
+      expect(App.AlertDefinition.find.calledWith('id')).to.be.true;
+      expect(App.router.transitionTo.calledWith('main.alerts.alertDetails', 'alertDefinition')).to.be.true;
+    });
+  });
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js b/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js
index 6867056..ff52a35 100644
--- a/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js
+++ b/ambari-web/test/controllers/main/service/reassign/step1_controller_test.js
@@ -172,4 +172,75 @@ describe('App.ReassignMasterWizardStep1Controller', function () {
       expect(reassignCtrl.get('content.hasManualSteps')).to.be.false;
     });
   });
+
+  describe("#getConfigUrlParams()", function() {
+    it("unknown component", function() {
+      expect(controller.getConfigUrlParams("", {})).to.be.empty;
+    });
+    it("OOZIE_SERVER component", function() {
+      var data = {
+        Clusters: {
+          desired_configs: {
+            'oozie-site': {
+              tag: 'tag'
+            },
+            'oozie-env': {
+              tag: 'tag'
+            }
+          }
+        }
+      };
+      expect(controller.getConfigUrlParams("OOZIE_SERVER", data)).to.eql([
+        "(type=oozie-site&tag=tag)",
+        "(type=oozie-env&tag=tag)"
+      ]);
+    });
+    it("HIVE_SERVER component", function() {
+      var data = {
+        Clusters: {
+          desired_configs: {
+            'hive-site': {
+              tag: 'tag'
+            },
+            'hive-env': {
+              tag: 'tag'
+            }
+          }
+        }
+      };
+      expect(controller.getConfigUrlParams("HIVE_SERVER", data)).to.eql([
+        "(type=hive-site&tag=tag)",
+        "(type=hive-env&tag=tag)"
+      ]);
+    });
+  });
+
+  describe("#onLoadConfigsTags()", function () {
+    beforeEach(function () {
+      this.mock = sinon.stub(controller, 'getConfigUrlParams');
+      sinon.stub(App.ajax, 'send');
+    });
+    afterEach(function () {
+      this.mock.restore();
+      App.ajax.send.restore();
+    });
+    it("empty params", function () {
+      this.mock.returns([]);
+      controller.onLoadConfigsTags();
+      expect(App.ajax.send.called).to.be.false;
+    });
+    it("correct params", function () {
+      this.mock.returns(['p1', 'p2']);
+      controller.onLoadConfigsTags();
+      expect(App.ajax.send.calledWith({
+        name: 'reassign.load_configs',
+        sender: controller,
+        data: {
+          urlParams: 'p1|p2'
+        },
+        success: 'onLoadConfigs',
+        error: ''
+      })).to.be.true;
+    });
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/test/controllers/main/service/reassign/step2_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/reassign/step2_controller_test.js b/ambari-web/test/controllers/main/service/reassign/step2_controller_test.js
index 487409e..a341587 100644
--- a/ambari-web/test/controllers/main/service/reassign/step2_controller_test.js
+++ b/ambari-web/test/controllers/main/service/reassign/step2_controller_test.js
@@ -94,4 +94,51 @@ describe('App.ReassignMasterWizardStep2Controller', function () {
       expect(controller.customClientSideValidation()).to.be.false;
     });
   });
+
+  describe("#mastersToShow", function() {
+    it("", function() {
+      controller.set('content.reassign.component_name', 'C1');
+      controller.propertyDidChange('mastersToShow');
+      expect(controller.get('mastersToShow')).to.eql(['C1']);
+    });
+  });
+
+  describe("#mastersToMove", function() {
+    it("", function() {
+      controller.set('content.reassign.component_name', 'C1');
+      controller.propertyDidChange('mastersToMove');
+      expect(controller.get('mastersToMove')).to.eql(['C1']);
+    });
+  });
+
+  describe("#additionalHostsList", function () {
+    beforeEach(function () {
+      sinon.stub(App.HostComponent, 'find').returns([Em.Object.create({
+        componentName: 'C1',
+        hostName: 'host1'
+      })]);
+    });
+    afterEach(function () {
+      App.HostComponent.find.restore();
+    });
+    it("servicesMastersToShow empty", function () {
+      controller.reopen({
+        servicesMastersToShow: []
+      });
+      controller.set('content.reassign.component_name', 'C1');
+      controller.propertyDidChange('additionalHostsList');
+      expect(controller.get('additionalHostsList')).to.be.empty;
+    });
+    it("servicesMastersToShow has one master", function () {
+      controller.reopen({
+        servicesMastersToShow: [{}]
+      });
+      controller.set('content.reassign.component_name', 'C1');
+      controller.propertyDidChange('additionalHostsList');
+      expect(controller.get('additionalHostsList')).to.eql([{
+        label: Em.I18n.t('services.reassign.step2.currentHost'),
+        host: 'host1'
+      }]);
+    });
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js b/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js
new file mode 100644
index 0000000..713eaed
--- /dev/null
+++ b/ambari-web/test/controllers/main/service/reassign/step3_controller_test.js
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+require('controllers/main/service/reassign/step3_controller');
+var controller;
+
+describe('App.ReassignMasterWizardStep3Controller', function () {
+
+  beforeEach(function(){
+    controller = App.ReassignMasterWizardStep3Controller.create();
+  });
+
+  describe("#submit()", function() {
+    var mock = {
+      getKDCSessionState: function (callback) {
+        callback();
+      }
+    };
+    before(function () {
+      sinon.stub(App, 'get').returns(mock);
+      sinon.spy(mock, 'getKDCSessionState');
+      sinon.stub(App.router, 'send', Em.K);
+    });
+    after(function () {
+      App.get.restore();
+      mock.getKDCSessionState.restore();
+      App.router.send.restore();
+    });
+    it("", function () {
+      controller.submit();
+      expect(mock.getKDCSessionState.calledOnce).to.be.true;
+      expect(App.router.send.calledWith("next")).to.be.true;
+    });
+  });
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/test/controllers/main/service/reassign/step4_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/reassign/step4_controller_test.js b/ambari-web/test/controllers/main/service/reassign/step4_controller_test.js
index b38c67e..99d1269 100644
--- a/ambari-web/test/controllers/main/service/reassign/step4_controller_test.js
+++ b/ambari-web/test/controllers/main/service/reassign/step4_controller_test.js
@@ -258,6 +258,42 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
       controller.removeUnneededTasks();
       expect(controller.get('tasks').mapProperty('id')).to.eql([1,2,3,4,5,6,7,8,9,10,11,12]);
     });
+
+    it('reassign component is Metrics Collector', function () {
+      controller.set('content.hasManualSteps', false);
+      controller.set('content.databaseType', 'mysql');
+      controller.set('content.reassign.component_name', 'METRICS_COLLECTOR');
+      isHaEnabled = false;
+
+      controller.set('tasks', commandsForDB);
+      controller.removeUnneededTasks();
+      expect(controller.get('tasks').mapProperty('id')).to.eql([1,2,5,6,8,10,12]);
+    });
+
+    it('reassign component is Mysql Server', function () {
+      controller.set('content.hasManualSteps', false);
+      controller.set('content.databaseType', 'mysql');
+      controller.set('content.reassign.component_name', 'MYSQL_SERVER');
+      isHaEnabled = false;
+
+      controller.set('tasks', commandsForDB);
+      controller.removeUnneededTasks();
+      expect(controller.get('tasks').mapProperty('id')).to.eql([1,2,3,4,5,6,8,9,10,11,12]);
+    });
+  });
+
+  describe("#stopRequiredServices()", function() {
+    before(function () {
+      sinon.stub(controller, 'stopServices', Em.K);
+    });
+    after(function () {
+      controller.stopServices.restore();
+    });
+    it("", function() {
+      controller.set('content.reassign.component_name', 'JOBTRACKER');
+      controller.stopRequiredServices();
+      expect(controller.stopServices.calledWith(['HDFS', 'ZOOKEEPER', 'HBASE', 'FLUME', 'SQOOP', 'STORM'])).to.be.true;
+    });
   });
 
   describe('#initializeTasks()', function () {
@@ -265,14 +301,25 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
       controller.set('tasks', []);
       sinon.stub(controller, 'getHostComponentsNames', Em.K);
       sinon.stub(controller, 'removeUnneededTasks', Em.K);
+      this.mock = sinon.stub(controller, 'isComponentWithDB');
     });
     afterEach(function () {
       controller.removeUnneededTasks.restore();
       controller.getHostComponentsNames.restore();
+      this.mock.restore();
     });
     it('No commands', function () {
       controller.set('commands', []);
       controller.set('commandsForDB', []);
+      this.mock.returns(false);
+      controller.initializeTasks();
+
+      expect(controller.get('tasks')).to.be.empty;
+    });
+    it('No commands', function () {
+      controller.set('commands', []);
+      controller.set('commandsForDB', []);
+      this.mock.returns(true);
       controller.initializeTasks();
 
       expect(controller.get('tasks')).to.be.empty;
@@ -483,7 +530,7 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
         componentName: 'APP_TIMELINE_SERVER',
         result: [
           "(type=yarn-site&tag=5)",
-          "(type=yarn-env&tag=8)",
+          "(type=yarn-env&tag=8)"
         ]
       },
       {
@@ -498,6 +545,30 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
         result: [
           "(type=webhcat-site&tag=7)"
         ]
+      },
+      {
+        componentName: 'HIVE_SERVER',
+        result: [
+          '(type=hive-site&tag=10)',
+          '(type=webhcat-site&tag=7)',
+          '(type=hive-env&tag=11)',
+          '(type=core-site&tag=2)'
+        ]
+      },
+      {
+        componentName: 'HIVE_METASTORE',
+        result: [
+          '(type=hive-site&tag=10)',
+          '(type=webhcat-site&tag=7)',
+          '(type=hive-env&tag=11)',
+          '(type=core-site&tag=2)'
+        ]
+      },
+      {
+        componentName: 'MYSQL_SERVER',
+        result: [
+          '(type=hive-site&tag=10)'
+        ]
       }
     ];
 
@@ -512,7 +583,9 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
           'oozie-site': {tag: 6},
           'webhcat-site': {tag: 7},
           'yarn-env': {tag: 8},
-          'accumulo-site': {tag: 9}
+          'accumulo-site': {tag: 9},
+          'hive-site': {tag: 10},
+          'hive-env': {tag: 11}
         }
       }
     };
@@ -582,6 +655,7 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
       sinon.stub(controller, 'setSecureConfigs', Em.K);
       sinon.stub(controller, 'setSpecificNamenodeConfigs', Em.K);
       sinon.stub(controller, 'setSpecificResourceMangerConfigs', Em.K);
+      sinon.stub(controller, 'setSpecificHiveConfigs', Em.K);
       sinon.stub(controller, 'getWebAddressPort', Em.K);
       sinon.stub(controller, 'getComponentDir', Em.K);
       sinon.stub(controller, 'saveClusterStatus', Em.K);
@@ -594,6 +668,7 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
       controller.setSecureConfigs.restore();
       controller.setSpecificNamenodeConfigs.restore();
       controller.setSpecificResourceMangerConfigs.restore();
+      controller.setSpecificHiveConfigs.restore();
       controller.getWebAddressPort.restore();
       controller.getComponentDir.restore();
       controller.saveClusterStatus.restore();
@@ -647,6 +722,23 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
       expect(controller.saveConfigsToServer.calledWith({'hdfs-site': {}})).to.be.true;
       expect(controller.saveServiceProperties.calledWith({'hdfs-site': {}})).to.be.true;
     });
+    it('component is HIVE_METASTORE, has configs', function () {
+      controller.set('content.reassign.component_name', 'HIVE_METASTORE');
+
+      controller.onLoadConfigs({items: [
+        {
+          type: 'hive-site',
+          properties: {}
+        }
+      ]});
+      expect(controller.setAdditionalConfigs.calledWith({'hive-site': {}}, 'HIVE_METASTORE', 'host1')).to.be.true;
+      expect(controller.setSecureConfigs.calledWith([], {'hive-site': {}}, 'HIVE_METASTORE')).to.be.true;
+      expect(controller.setSpecificHiveConfigs.calledWith({'hive-site': {}}, 'host1')).to.be.true;
+      expect(controller.getComponentDir.calledWith({'hive-site': {}}, 'HIVE_METASTORE')).to.be.true;
+      expect(controller.saveClusterStatus.calledWith([])).to.be.true;
+      expect(controller.saveConfigsToServer.calledWith({'hive-site': {}})).to.be.true;
+      expect(controller.saveServiceProperties.calledWith({'hive-site': {}})).to.be.true;
+    });
   });
 
   describe('#loadStep()', function () {
@@ -1231,31 +1323,283 @@ describe('App.ReassignMasterWizardStep4Controller', function () {
     });
   });
 
-  describe('#testsMySqlServer()', function () {
+  describe('#cleanMySqlServer()', function () {
     beforeEach(function() {
       sinon.stub(App.HostComponent, 'find', function() {
         return Em.A([
           Em.Object.create({
             'componentName': 'MYSQL_SERVER',
-            'hostName': 'c6401.ambari.apache.org'
+            'hostName': 'host1'
           })
         ]);
       });
     });
-
     afterEach(function() {
       App.HostComponent.find.restore();
     });
 
-    it('Cleans MySql Server', function () {
+    it('component_name is C1', function () {
+      controller.set('content.reassign.component_name', 'C1');
       controller.cleanMySqlServer();
-      expect(App.ajax.send.calledOnce).to.be.true;
+      expect(App.ajax.send.calledWith({
+        name: 'service.mysql.clean',
+        sender: controller,
+        data: {
+          host: 'host1'
+        },
+        success: 'startPolling',
+        error: 'onTaskError'
+      })).to.be.true;
+    });
+
+    it('component_name is MYSQL_SERVER', function () {
+      controller.set('content.reassign.component_name', 'MYSQL_SERVER');
+      controller.set('content.reassignHosts.target', 'host2');
+      controller.cleanMySqlServer();
+      expect(App.ajax.send.calledWith({
+        name: 'service.mysql.clean',
+        sender: controller,
+        data: {
+          host: 'host2'
+        },
+        success: 'startPolling',
+        error: 'onTaskError'
+      })).to.be.true;
     });
+  });
 
-    it('Configures MySql Server', function () {
+  describe('#configureMySqlServer()', function () {
+    beforeEach(function() {
+      sinon.stub(App.HostComponent, 'find', function() {
+        return Em.A([
+          Em.Object.create({
+            'componentName': 'MYSQL_SERVER',
+            'hostName': 'host1'
+          })
+        ]);
+      });
+    });
+    afterEach(function() {
+      App.HostComponent.find.restore();
+    });
+
+    it('component_name is C1', function () {
+      controller.set('content.reassign.component_name', 'C1');
       controller.configureMySqlServer();
-      expect(App.ajax.send.calledOnce).to.be.true;
+      expect(App.ajax.send.calledWith({
+        name: 'service.mysql.configure',
+        sender: controller,
+        data: {
+          host: 'host1'
+        },
+        success: 'startPolling',
+        error: 'onTaskError'
+      })).to.be.true;
     });
 
+    it('component_name is MYSQL_SERVER', function () {
+      controller.set('content.reassign.component_name', 'MYSQL_SERVER');
+      controller.set('content.reassignHosts.target', 'host2');
+      controller.configureMySqlServer();
+      expect(App.ajax.send.calledWith({
+        name: 'service.mysql.configure',
+        sender: controller,
+        data: {
+          host: 'host2'
+        },
+        success: 'startPolling',
+        error: 'onTaskError'
+      })).to.be.true;
+    });
+  });
+
+  describe("#startRequiredServices()", function() {
+    beforeEach(function () {
+      sinon.stub(controller, 'startServices', Em.K);
+    });
+    afterEach(function () {
+      controller.startServices.restore();
+    });
+    it("component has related services", function() {
+      controller.set('content.reassign.component_name', 'JOBTRACKER');
+      controller.startRequiredServices();
+      expect(controller.startServices.calledWith(false, ['HDFS', 'ZOOKEEPER', 'HBASE', 'FLUME', 'SQOOP', 'STORM'])).to.be.true;
+    });
+    it("component does not have related services", function() {
+      controller.set('content.reassign.component_name', 'C1');
+      controller.startRequiredServices();
+      expect(controller.startServices.calledWith(true)).to.be.true;
+    });
+  });
+
+  describe("#setSpecificHiveConfigs()", function() {
+    beforeEach(function () {
+      sinon.stub(App.HostComponent, 'find').returns([
+        {
+          componentName: 'HIVE_METASTORE',
+          hostName: 'host1'
+        },
+        {
+          componentName: 'HIVE_METASTORE',
+          hostName: 'host3'
+        },
+        {
+          componentName: 'HIVE_SERVER',
+          hostName: 'host4'
+        }
+      ]);
+    });
+    afterEach(function () {
+      App.HostComponent.find.restore();
+    });
+    it("reassign component is HIVE_METASTORE", function() {
+      var configs = {
+        'hive-env': {
+          'hive_user': 'hive_user',
+          'webhcat_user': 'webhcat_user'
+        },
+        'hive-site': {
+          'hive.metastore.uris': ''
+        },
+        'webhcat-site': {
+          'templeton.hive.properties': 'thrift'
+        },
+        'core-site': {
+
+        }
+      };
+      controller.set('content.reassignHosts.source', 'host1');
+      controller.set('content.reassign.component_name', 'HIVE_METASTORE');
+      controller.setSpecificHiveConfigs(configs, 'host2');
+      expect(configs['hive-site']['hive.metastore.uris']).to.equal('thrift://host3:9083,thrift://host2:9083');
+      expect(configs['webhcat-site']['templeton.hive.properties']).to.equal('thrift');
+      expect(configs['core-site']['hadoop.proxyuser.hive_user.hosts']).to.equal('host3,host2,host4');
+      expect(configs['core-site']['hadoop.proxyuser.webhcat_user.hosts']).to.equal('host3,host2,host4');
+    });
+
+    it("reassign component is HIVE_SERVER", function() {
+      var configs = {
+        'hive-env': {
+          'hive_user': 'hive_user',
+          'webhcat_user': 'webhcat_user'
+        },
+        'hive-site': {
+          'hive.metastore.uris': ''
+        },
+        'webhcat-site': {
+          'templeton.hive.properties': 'thrift'
+        },
+        'core-site': {
+
+        }
+      };
+      controller.set('content.reassignHosts.source', 'host1');
+      controller.set('content.reassign.component_name', 'HIVE_SERVER');
+      controller.setSpecificHiveConfigs(configs, 'host2');
+      expect(configs['hive-site']['hive.metastore.uris']).to.equal('thrift://host1:9083,thrift://host3:9083');
+      expect(configs['webhcat-site']['templeton.hive.properties']).to.equal('thrift');
+      expect(configs['core-site']['hadoop.proxyuser.hive_user.hosts']).to.equal('host1,host3,host4,host2');
+      expect(configs['core-site']['hadoop.proxyuser.webhcat_user.hosts']).to.equal('host1,host3,host4,host2');
+    });
+  });
+
+  describe("#startMySqlServer()", function() {
+    beforeEach(function () {
+      sinon.stub(App.HostComponent, 'find').returns([
+        Em.Object.create({
+          componentName: 'MYSQL_SERVER',
+          hostName: 'host1'
+        })
+      ]);
+    });
+    afterEach(function () {
+      App.HostComponent.find.restore();
+    });
+    it("", function() {
+      controller.startMySqlServer();
+      expect(App.ajax.send.calledWith({
+        name: 'common.host.host_component.update',
+        sender: controller,
+        data: {
+          context: "Start MySQL Server",
+          hostName: 'host1',
+          serviceName: "HIVE",
+          componentName: "MYSQL_SERVER",
+          HostRoles: {
+            state: "STARTED"
+          }
+        },
+        success: 'startPolling',
+        error: 'onTaskError'
+      })).to.be.true;
+    });
+  });
+
+  describe("#restartMySqlServer()", function() {
+    beforeEach(function () {
+      sinon.stub(App.HostComponent, 'find').returns([
+        Em.Object.create({
+          componentName: 'MYSQL_SERVER',
+          hostName: 'host1'
+        })
+      ]);
+    });
+    afterEach(function () {
+      App.HostComponent.find.restore();
+    });
+    it("", function() {
+      controller.set('content', Em.Object.create({
+        cluster: Em.Object.create({
+          name: 'cl1'
+        })
+      }));
+      controller.restartMySqlServer();
+      expect(App.ajax.send.calledWith({
+        name: 'restart.hostComponents',
+        sender: controller,
+        data: {
+          context: 'Restart MySql Server',
+          resource_filters: [{
+            component_name: "MYSQL_SERVER",
+            hosts: 'host1',
+            service_name: "HIVE"
+          }],
+          operation_level: {
+            level: "HOST_COMPONENT",
+            cluster_name: 'cl1',
+            service_name: "HIVE",
+            hostcomponent_name: "MYSQL_SERVER"
+          }
+        },
+        success: 'startPolling',
+        error: 'onTaskError'
+      })).to.be.true;
+    });
+  });
+
+  describe("#startNewMySqlServer()", function() {
+    it("", function() {
+      controller.set('content', Em.Object.create({
+        reassignHosts: Em.Object.create({
+          target: 'host1'
+        })
+      }));
+      controller.startNewMySqlServer();
+      expect(App.ajax.send.calledWith({
+        name: 'common.host.host_component.update',
+        sender: controller,
+        data: {
+          context: "Start MySQL Server",
+          hostName: 'host1',
+          serviceName: "HIVE",
+          componentName: "MYSQL_SERVER",
+          HostRoles: {
+            state: "STARTED"
+          }
+        },
+        success: 'startPolling',
+        error: 'onTaskError'
+      })).to.be.true;
+    });
   });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/test/controllers/main/service/reassign/step6_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/reassign/step6_controller_test.js b/ambari-web/test/controllers/main/service/reassign/step6_controller_test.js
index 25b52da..be3c8fe 100644
--- a/ambari-web/test/controllers/main/service/reassign/step6_controller_test.js
+++ b/ambari-web/test/controllers/main/service/reassign/step6_controller_test.js
@@ -19,17 +19,18 @@
 App = require('app');
 
 require('controllers/main/service/reassign/step6_controller');
+var controller;
 
 describe('App.ReassignMasterWizardStep6Controller', function () {
 
-  var controller = App.ReassignMasterWizardStep6Controller.create({
-    content: Em.Object.create({
-      reassign: Em.Object.create(),
-      reassignHosts: Em.Object.create()
-    })
-  });
-
   beforeEach(function () {
+    controller = App.ReassignMasterWizardStep6Controller.create({
+      content: Em.Object.create({
+        reassign: Em.Object.create(),
+        reassignHosts: Em.Object.create()
+      }),
+      startServices: Em.K
+    });
     sinon.stub(App.ajax, 'send', Em.K);
   });
   afterEach(function () {
@@ -148,19 +149,6 @@ describe('App.ReassignMasterWizardStep6Controller', function () {
     });
   });
 
-  describe('#startServices()', function () {
-    before(function () {
-      sinon.stub(App.router, 'get').returns({"skip.service.checks": "false"});
-    });
-    after(function () {
-      App.router.get.restore();
-    });
-    it('', function () {
-      controller.startServices();
-      expect(App.ajax.send.calledOnce).to.be.true;
-    });
-  });
-
   describe('#deleteHostComponents()', function () {
 
     it('No host components', function () {
@@ -197,14 +185,14 @@ describe('App.ReassignMasterWizardStep6Controller', function () {
     it('task success', function () {
       var error = {
         responseText: 'org.apache.ambari.server.controller.spi.NoSuchResourceException'
-      }
+      };
       controller.onDeleteHostComponentsError(error);
       expect(controller.onComponentsTasksSuccess.calledOnce).to.be.true;
     });
     it('unknown error', function () {
       var error = {
         responseText: ''
-      }
+      };
       controller.onDeleteHostComponentsError(error);
       expect(controller.onTaskError.calledOnce).to.be.true;
     });
@@ -238,4 +226,30 @@ describe('App.ReassignMasterWizardStep6Controller', function () {
       expect(controller.get('multiTaskCounter')).to.equal(0);
     });
   });
+
+  describe("#removeTasks()", function() {
+    it("no tasks to delete", function() {
+      controller.set('tasks', [Em.Object.create()]);
+      controller.removeTasks([]);
+      expect(controller.get('tasks').length).to.equal(1);
+    });
+    it("one task to delete", function() {
+      controller.set('tasks', [Em.Object.create({command: 'task1'})]);
+      controller.removeTasks(['task1']);
+      expect(controller.get('tasks')).to.be.empty;
+    });
+  });
+
+  describe("#startAllServices()", function() {
+    beforeEach(function () {
+      sinon.stub(controller, 'startServices', Em.K);
+    });
+    afterEach(function () {
+      controller.startServices.restore();
+    });
+    it("", function () {
+      controller.startAllServices();
+      expect(controller.startServices.calledWith(true)).to.be.true;
+    });
+  });
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/test/controllers/main/service/reassign/step7_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/service/reassign/step7_controller_test.js b/ambari-web/test/controllers/main/service/reassign/step7_controller_test.js
index 304fdb6..238ebea 100644
--- a/ambari-web/test/controllers/main/service/reassign/step7_controller_test.js
+++ b/ambari-web/test/controllers/main/service/reassign/step7_controller_test.js
@@ -19,32 +19,92 @@
 App = require('app');
 
 require('controllers/main/service/reassign/step7_controller');
+var controller;
 
 describe('App.ReassignMasterWizardStep7Controller', function () {
 
-  var controller = App.ReassignMasterWizardStep7Controller.create({
-    content: Em.Object.create({
-      reassign: Em.Object.create(),
-      reassignHosts: Em.Object.create()
-    })
-  });
-
   beforeEach(function () {
     sinon.stub(App.ajax, 'send', Em.K);
+    controller = App.ReassignMasterWizardStep7Controller.create({
+      content: Em.Object.create({
+        reassign: Em.Object.create(),
+        reassignHosts: Em.Object.create()
+      })
+    });
   });
   afterEach(function () {
     App.ajax.send.restore();
   });
 
   describe('#initializeTasks()', function () {
-
     it('should set isLoaded to true', function () {
       controller.set('isLoaded', false);
 
       controller.initializeTasks();
       expect(controller.get('isLoaded')).to.be.true;
     });
+  });
 
+  describe("#putHostComponentsInMaintenanceMode()", function() {
+    it("no host-components", function() {
+      controller.set('hostComponents', []);
+      controller.putHostComponentsInMaintenanceMode();
+      expect(App.ajax.send.called).to.be.false;
+      expect(controller.get('multiTaskCounter')).to.equal(0);
+    });
+    it("one host-component", function() {
+      controller.set('hostComponents', ['C1']);
+      controller.set('content.reassignHosts.target', 'host1');
+      controller.putHostComponentsInMaintenanceMode();
+      expect(App.ajax.send.calledWith({
+        name: 'common.host.host_component.passive',
+        sender: controller,
+        data: {
+          hostName: 'host1',
+          passive_state: "ON",
+          componentName: 'C1'
+        },
+        success: 'onComponentsTasksSuccess',
+        error: 'onTaskError'
+      })).to.be.true;
+      expect(controller.get('multiTaskCounter')).to.equal(0);
+    });
+    it("two host-components", function() {
+      controller.set('hostComponents', ['C1', 'C2']);
+      controller.putHostComponentsInMaintenanceMode();
+      expect(App.ajax.send.calledTwice).to.be.true;
+      expect(controller.get('multiTaskCounter')).to.equal(0);
+    });
   });
 
+  describe("#deleteHostComponents()", function() {
+    it("no host-components", function() {
+      controller.set('hostComponents', []);
+      controller.deleteHostComponents();
+      expect(App.ajax.send.called).to.be.false;
+      expect(controller.get('multiTaskCounter')).to.equal(0);
+    });
+    it("one host-component", function() {
+      controller.set('hostComponents', ['C1']);
+      controller.set('content.reassignHosts.target', 'host1');
+      controller.deleteHostComponents();
+      expect(App.ajax.send.calledWith({
+        name: 'common.delete.host_component',
+        sender: controller,
+        data: {
+          hostName: 'host1',
+          componentName: 'C1'
+        },
+        success: 'onComponentsTasksSuccess',
+        error: 'onDeleteHostComponentsError'
+      })).to.be.true;
+      expect(controller.get('multiTaskCounter')).to.equal(0);
+    });
+    it("two host-components", function() {
+      controller.set('hostComponents', ['C1', 'C2']);
+      controller.deleteHostComponents();
+      expect(App.ajax.send.calledTwice).to.be.true;
+      expect(controller.get('multiTaskCounter')).to.equal(0);
+    });
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/test/models/service/flume_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/models/service/flume_test.js b/ambari-web/test/models/service/flume_test.js
index 3b3417f..efad7e5 100644
--- a/ambari-web/test/models/service/flume_test.js
+++ b/ambari-web/test/models/service/flume_test.js
@@ -29,19 +29,23 @@ var flumeAgent,
   cases = [
     {
       status: 'RUNNING',
-      healthClass: App.healthIconClassGreen
+      healthClass: App.healthIconClassGreen,
+      displayStatus: Em.I18n.t('common.running')
     },
     {
       status: 'NOT_RUNNING',
-      healthClass: App.healthIconClassRed
+      healthClass: App.healthIconClassRed,
+      displayStatus: Em.I18n.t('common.stopped')
     },
     {
       status: 'UNKNOWN',
-      healthClass: App.healthIconClassYellow
+      healthClass: App.healthIconClassYellow,
+      displayStatus: Em.I18n.t('common.unknown')
     },
     {
       status: 'ANOTHER_STATUS',
-      healthClass: App.healthIconClassYellow
+      healthClass: App.healthIconClassYellow,
+      displayStatus: Em.I18n.t('common.unknown')
     }
   ];
 
@@ -65,4 +69,13 @@ describe('App.FlumeAgent', function () {
     });
   });
 
+  describe('#displayStatus', function () {
+    cases.forEach(function (item) {
+      var displayStatus = item.displayStatus;
+      it('should be ' + displayStatus, function () {
+        flumeAgent.set('status', item.status);
+        expect(flumeAgent.get('displayStatus')).to.equal(displayStatus);
+      });
+    });
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/test/views/main/alerts/add_alert_definition/step1_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/alerts/add_alert_definition/step1_view_test.js b/ambari-web/test/views/main/alerts/add_alert_definition/step1_view_test.js
new file mode 100644
index 0000000..cd8a47e
--- /dev/null
+++ b/ambari-web/test/views/main/alerts/add_alert_definition/step1_view_test.js
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+require('views/main/alerts/add_alert_definition/step1_view');
+
+var view;
+
+describe('App.AddAlertDefinitionStep1View', function () {
+
+  beforeEach(function () {
+    view = App.AddAlertDefinitionStep1View.create({
+      controller: Em.Object.create({
+        loadStep: Em.K
+      })
+    });
+  });
+
+  describe("#didInsertElement()", function () {
+    beforeEach(function () {
+      sinon.spy(view.get('controller'), 'loadStep');
+    });
+    afterEach(function () {
+      view.get('controller').loadStep.restore();
+    });
+
+    it("loadStep should be called", function () {
+      view.didInsertElement();
+      expect(view.get('controller').loadStep.calledOnce).to.be.true;
+    });
+  });
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/4e5489ba/ambari-web/test/views/main/alerts/add_alert_definition/step3_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/alerts/add_alert_definition/step3_view_test.js b/ambari-web/test/views/main/alerts/add_alert_definition/step3_view_test.js
new file mode 100644
index 0000000..f89abd9
--- /dev/null
+++ b/ambari-web/test/views/main/alerts/add_alert_definition/step3_view_test.js
@@ -0,0 +1,41 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+require('views/main/alerts/add_alert_definition/step3_view');
+
+var view;
+
+describe('App.AddAlertDefinitionStep3View', function () {
+
+  beforeEach(function () {
+    view = App.AddAlertDefinitionStep3View.create({
+      controller: Em.Object.create()
+    });
+  });
+
+  describe("#willInsertElement()", function () {
+    it("alertDefinitionToDisplay should be set", function () {
+      view.set('controller.content', {
+        formattedToRequestConfigs: 'formattedToRequestConfigs'
+      });
+      view.willInsertElement();
+      expect(view.get('alertDefinitionToDisplay')).to.equal('\"formattedToRequestConfigs\"');
+    });
+  });
+});