ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From atk...@apache.org
Subject ambari git commit: AMBARI-18288 Cover main views with unit tests. (atkach)
Date Wed, 31 Aug 2016 19:06:31 GMT
Repository: ambari
Updated Branches:
  refs/heads/trunk a6558f869 -> 9e71d6fb6


AMBARI-18288 Cover main views 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/9e71d6fb
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9e71d6fb
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9e71d6fb

Branch: refs/heads/trunk
Commit: 9e71d6fb611250f22dbcd7cf0e18a9e2f78f8d90
Parents: a6558f8
Author: Andrii Tkach <atkach@apache.org>
Authored: Wed Aug 31 20:34:11 2016 +0300
Committer: Andrii Tkach <atkach@apache.org>
Committed: Wed Aug 31 20:34:11 2016 +0300

----------------------------------------------------------------------
 ambari-web/app/assets/test/tests.js             |   1 +
 ambari-web/test/views/main/admin_test.js        |  31 +
 .../views/main/alert_definitions_view_test.js   | 354 +++++++-
 ambari-web/test/views/main/dashboard_test.js    |  47 +-
 ambari-web/test/views/main/host_test.js         | 897 ++++++++++++++++++-
 ambari-web/test/views/main/menu_test.js         | 264 ++++--
 ambari-web/test/views/main/views_view_test.js   |  45 +
 7 files changed, 1563 insertions(+), 76 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/9e71d6fb/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 7dbac75..4c9b192 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -247,6 +247,7 @@ var files = [
   'test/views/main/dashboard_test',
   'test/views/main/menu_test',
   'test/views/main/host_test',
+  'test/views/main/views_view_test',
   'test/views/main/alert_definitions_view_test',
   'test/views/main/alerts/manage_alert_groups_view_test',
   'test/views/main/alerts/manage_alert_notifications_view_test',

http://git-wip-us.apache.org/repos/asf/ambari/blob/9e71d6fb/ambari-web/test/views/main/admin_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/admin_test.js b/ambari-web/test/views/main/admin_test.js
index 3e6b4f6..7c5b2bd 100644
--- a/ambari-web/test/views/main/admin_test.js
+++ b/ambari-web/test/views/main/admin_test.js
@@ -96,4 +96,35 @@ describe('App.MainAdminView', function () {
     });
   });
 
+  describe("#NavItemView", function () {
+    var navItemView;
+
+    beforeEach(function() {
+      navItemView = view.get('NavItemView').create({
+        parentView: Em.Object.create()
+      });
+    });
+
+    describe("#isDisabled", function () {
+
+      it("view should be disabled", function() {
+        navItemView.set('parentView.categories', [
+          {name: 'cat1', disabled: true},
+          {name: 'cat2', disabled: false}
+        ]);
+        navItemView.set('item', 'cat1');
+        expect(navItemView.get('isDisabled')).to.be.true;
+      });
+
+      it("view should not be disabled", function() {
+        navItemView.set('parentView.categories', [
+          {name: 'cat1', disabled: true},
+          {name: 'cat2', disabled: false}
+        ]);
+        navItemView.set('item', 'cat2');
+        expect(navItemView.get('isDisabled')).to.be.false;
+      });
+    });
+  });
+
 });
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/9e71d6fb/ambari-web/test/views/main/alert_definitions_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/alert_definitions_view_test.js b/ambari-web/test/views/main/alert_definitions_view_test.js
index 704cde4..8692ae4 100644
--- a/ambari-web/test/views/main/alert_definitions_view_test.js
+++ b/ambari-web/test/views/main/alert_definitions_view_test.js
@@ -23,7 +23,9 @@ require('views/main/alert_definitions_view');
 var view;
 
 function getView() {
-  return App.MainAlertDefinitionsView.create({});
+  return App.MainAlertDefinitionsView.create({
+    controller: Em.Object.create()
+  });
 }
 
 describe('App.MainAlertDefinitionsView', function () {
@@ -63,14 +65,16 @@ describe('App.MainAlertDefinitionsView', function () {
       sinon.stub(App.db, 'getSortingStatuses').returns([
         {
           name: "summary",
-          status: "sorting_asc"
+          status: "sorting"
         }
       ]);
+      sinon.stub(App.db, 'setSortingStatuses');
     });
 
     afterEach(function(){
       view.clearFilterConditionsFromLocalStorage.restore();
       App.db.getSortingStatuses.restore();
+      App.db.setSortingStatuses.restore();
     });
 
     it('should call clearFilterCondition if controller.showFilterConditionsFirstLoad is false', function () {
@@ -84,6 +88,352 @@ describe('App.MainAlertDefinitionsView', function () {
       view.willInsertElement();
       expect(view.clearFilterConditionsFromLocalStorage.calledOnce).to.be.false;
     });
+
+    it('showFilterConditionsFirstLoad is true', function () {
+      view.set('controller', {showFilterConditionsFirstLoad: true, name: 'ctrl1'});
+      view.willInsertElement();
+      expect(App.db.setSortingStatuses.calledWith('ctrl1',
+        [
+          {
+            name: "summary",
+            status: "sorting"
+          },
+          {
+            name: "summary",
+            status: "sorting_asc"
+          }
+        ])).to.be.true;
+    });
+  });
+
+  describe("#didInsertElement()", function () {
+
+    beforeEach(function() {
+      sinon.stub(Em.run, 'next', Em.clb);
+      sinon.stub(view, 'contentObsOnce');
+      sinon.stub(view, 'tooltipsUpdater');
+      view.didInsertElement();
+    });
+
+    afterEach(function() {
+      Em.run.next.restore();
+      view.contentObsOnce.restore();
+      view.tooltipsUpdater.restore();
+    });
+
+    it("isInitialRendering should be false", function() {
+      expect(view.get('isInitialRendering')).to.be.false;
+    });
+
+    it("contentObsOnce should be called", function() {
+      expect(view.contentObsOnce.calledOnce).to.be.true;
+    });
+
+    it("tooltipsUpdater should be called", function() {
+      expect(view.tooltipsUpdater.calledOnce).to.be.true;
+    });
+  });
+
+  describe("#willDestroyElement()", function () {
+    var container = {
+      tooltip: Em.K
+    };
+
+    beforeEach(function() {
+      sinon.stub(window, '$').returns(container);
+      sinon.stub(view, 'removeObserver');
+      sinon.stub(container, 'tooltip');
+      view.willDestroyElement();
+    });
+
+    afterEach(function() {
+      window.$.restore();
+      view.removeObserver.restore();
+      container.tooltip.restore();
+    });
+
+    it("tooltip should be destroyed", function() {
+      expect(container.tooltip.calledWith('destroy')).to.be.true;
+    });
+
+    it("removeObserver should be called", function() {
+      expect(view.removeObserver.calledWith('pageContent.length', view, 'tooltipsUpdater')).to.be.true;
+    });
   });
 
+  describe("#saveStartIndex()", function () {
+
+    it("App.db.setStartIndex should be called", function() {
+      view.set('controller.name', 'ctrl1');
+      view.set('startIndex', 1);
+      view.saveStartIndex();
+      expect(App.db.setStartIndex.calledWith('ctrl1', 1)).to.be.true;
+    });
+  });
+
+  describe("#clearStartIndex()", function () {
+
+    it("App.db.setStartIndex should be called", function() {
+      view.set('controller.name', 'ctrl1');
+      view.clearStartIndex();
+      expect(App.db.setStartIndex.calledWith('ctrl1', null)).to.be.true;
+    });
+  });
+
+  describe("#alertGroupFilterView", function () {
+    var alertGroupFilterView;
+
+    beforeEach(function() {
+      alertGroupFilterView = view.get('alertGroupFilterView').create({
+        parentView: Em.Object.create({
+          updateFilter: Em.K
+        })
+      });
+    });
+
+    describe("#didInsertElement()", function () {
+
+      beforeEach(function() {
+        sinon.stub(alertGroupFilterView, '$').returns({parent: function() {
+          return {
+            addClass: Em.K
+          }
+        }});
+        sinon.stub(alertGroupFilterView, 'showClearFilter');
+        sinon.stub(alertGroupFilterView, 'updateContent');
+        alertGroupFilterView.didInsertElement();
+      });
+
+      afterEach(function() {
+        alertGroupFilterView.$.restore();
+        alertGroupFilterView.updateContent.restore();
+        alertGroupFilterView.showClearFilter.restore();
+      });
+
+      it("updateContent should be called", function() {
+        expect(alertGroupFilterView.updateContent.calledOnce).to.be.true;
+      });
+
+      it("value should be empty", function() {
+        expect(alertGroupFilterView.get('value')).to.be.empty;
+      });
+    });
+
+    describe("#updateContent()", function () {
+
+      beforeEach(function() {
+        sinon.stub(App.AlertGroup, 'find').returns([
+          Em.Object.create({
+            id: 'g1',
+            displayNameDefinitions: 'def1',
+            default: true
+          }),
+          Em.Object.create({
+            id: 'g2',
+            displayNameDefinitions: 'def2',
+            default: false
+          })
+        ]);
+        sinon.stub(alertGroupFilterView, 'onValueChange');
+        alertGroupFilterView.set('parentView.controller', {content: [{}]});
+        alertGroupFilterView.updateContent();
+      });
+
+      afterEach(function() {
+        App.AlertGroup.find.restore();
+        alertGroupFilterView.onValueChange.restore();
+      });
+
+      it("onValueChange should be called", function() {
+        expect(alertGroupFilterView.onValueChange.calledOnce).to.be.true;
+      });
+
+      it("content should be set", function() {
+        expect(alertGroupFilterView.get('content')).to.be.eql([
+          Em.Object.create({
+            value: '',
+            label: Em.I18n.t('common.all') + ' (1)'
+          }),
+          Em.Object.create({
+            value: 'g1',
+            label: 'def1'
+          }),
+          Em.Object.create({
+            value: 'g2',
+            label: 'def2'
+          })
+        ]);
+      });
+    });
+
+    describe("#selectCategory()", function () {
+
+      beforeEach(function() {
+        sinon.stub(alertGroupFilterView.get('parentView'), 'updateFilter');
+        alertGroupFilterView.selectCategory({context: {value: 'val1'}});
+      });
+
+      afterEach(function() {
+        alertGroupFilterView.get('parentView').updateFilter.restore();
+      });
+
+      it("value should be set", function() {
+        expect(alertGroupFilterView.get('value')).to.be.equal('val1');
+      });
+
+      it("updateFilter should be called", function() {
+        expect(alertGroupFilterView.get('parentView').updateFilter.calledWith(
+          7, 'val1', 'alert_group'
+        )).to.be.true;
+      });
+    });
+
+    describe("#onValueChange()", function () {
+
+      beforeEach(function() {
+        sinon.stub(alertGroupFilterView.get('parentView'), 'updateFilter');
+      });
+
+      afterEach(function() {
+        alertGroupFilterView.get('parentView').updateFilter.restore();
+      });
+
+      it("value is undefined", function() {
+        alertGroupFilterView.set('value', undefined);
+        alertGroupFilterView.onValueChange();
+        expect(alertGroupFilterView.get('value')).to.be.empty;
+        expect(alertGroupFilterView.get('parentView').updateFilter.calledWith(
+          7, '', 'alert_group'
+        )).to.be.true;
+      });
+
+      it("value is not undefined", function() {
+        var option = Em.Object.create({
+          selected: true,
+          value: 'val1'
+        });
+        alertGroupFilterView.set('content', [ option ]);
+        alertGroupFilterView.set('value', 'val1');
+        alertGroupFilterView.onValueChange();
+        expect(option.get('selected')).to.be.true;
+        expect(alertGroupFilterView.get('parentView').updateFilter.calledWith(
+          7, 'val1', 'alert_group'
+        )).to.be.true;
+      });
+    });
+  });
+
+  describe("#paginationLeftClass", function() {
+
+    it("startIndex is 2", function() {
+      view.set('startIndex', 2);
+      expect(view.get('paginationLeftClass')).to.equal('paginate_previous');
+    });
+
+    it("startIndex is 1", function() {
+      view.set('startIndex', 1);
+      expect(view.get('paginationLeftClass')).to.equal('paginate_disabled_previous');
+    });
+
+    it("startIndex is 0", function() {
+      view.set('startIndex', 0);
+      expect(view.get('paginationLeftClass')).to.equal('paginate_disabled_previous');
+    });
+  });
+
+  describe("#paginationRightClass", function() {
+
+    it("endIndex more than filteredCount", function() {
+      view.reopen({
+        endIndex: 4,
+        filteredCount: 3
+      });
+      expect(view.get('paginationRightClass')).to.equal('paginate_disabled_next');
+    });
+
+    it("endIndex equal to filteredCount", function() {
+      view.reopen({
+        endIndex: 4,
+        filteredCount: 4
+      });
+      expect(view.get('paginationRightClass')).to.equal('paginate_disabled_next');
+    });
+
+    it("endIndex less than filteredCount", function() {
+      view.reopen({
+        endIndex: 3,
+        filteredCount: 4
+      });
+      view.propertyDidChange('paginationRightClass');
+      expect(view.get('paginationRightClass')).to.equal('paginate_next');
+    });
+  });
+
+  describe("#previousPage()", function () {
+
+    beforeEach(function() {
+      sinon.stub(view, 'tooltipsUpdater');
+    });
+
+    afterEach(function() {
+      view.tooltipsUpdater.restore();
+    });
+
+    it("tooltipsUpdater should be called", function() {
+      view.previousPage();
+      expect(view.tooltipsUpdater.calledOnce).to.be.true;
+    });
+  });
+
+  describe("#nextPage()", function () {
+
+    beforeEach(function() {
+      sinon.stub(view, 'tooltipsUpdater');
+    });
+
+    afterEach(function() {
+      view.tooltipsUpdater.restore();
+    });
+
+    it("tooltipsUpdater should be called", function() {
+      view.nextPage();
+      expect(view.tooltipsUpdater.calledOnce).to.be.true;
+    });
+  });
+
+  describe("#tooltipsUpdater", function () {
+
+    beforeEach(function() {
+      sinon.stub(Em.run, 'next', function(context, callback) {
+        callback();
+      });
+      sinon.stub(App, 'tooltip');
+    });
+
+    afterEach(function() {
+      Em.run.next.restore();
+      App.tooltip.restore();
+    });
+
+    it("App.tooltip should be called", function() {
+      view.tooltipsUpdater();
+      expect(App.tooltip.calledOnce).to.be.true;
+    });
+  });
+
+  describe("#updateFilter()", function () {
+
+    beforeEach(function() {
+      sinon.stub(view, 'tooltipsUpdater');
+    });
+
+    afterEach(function() {
+      view.tooltipsUpdater.restore();
+    });
+
+    it("tooltipsUpdater should be called", function() {
+      view.updateFilter(1, 'val1', 'type1');
+      expect(view.tooltipsUpdater.calledOnce).to.be.true;
+    });
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9e71d6fb/ambari-web/test/views/main/dashboard_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/dashboard_test.js b/ambari-web/test/views/main/dashboard_test.js
index 70e2eb2..6c2f354 100644
--- a/ambari-web/test/views/main/dashboard_test.js
+++ b/ambari-web/test/views/main/dashboard_test.js
@@ -16,4 +16,49 @@
  * limitations under the License.
  */
 
-describe('App.MainDashboardView', function() {});
+
+var App = require('app');
+require('views/main/dashboard');
+
+describe('App.MainDashboardView', function () {
+  var view;
+
+  beforeEach(function() {
+    view = App.MainDashboardView.create()
+  });
+
+  describe("#NavItemView", function () {
+    var navItemView;
+
+    beforeEach(function() {
+      navItemView = view.get('NavItemView').create();
+    });
+
+    describe("#elementId", function () {
+
+      it("label is null", function() {
+        navItemView.set('templateData', {
+          keywords: {
+            category: {
+              label: null
+            }
+          }
+        });
+        navItemView.propertyDidChange('elementId');
+        expect(navItemView.get('elementId')).to.be.empty;
+      });
+
+      it("label has value", function() {
+        navItemView.set('templateData', {
+          keywords: {
+            category: {
+              label: 'l1'
+            }
+          }
+        });
+        navItemView.propertyDidChange('elementId');
+        expect(navItemView.get('elementId')).to.be.equal('dashboard-view-tab-l1');
+      });
+    });
+  });
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/9e71d6fb/ambari-web/test/views/main/host_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/host_test.js b/ambari-web/test/views/main/host_test.js
index 6bb3462..0b789f6 100644
--- a/ambari-web/test/views/main/host_test.js
+++ b/ambari-web/test/views/main/host_test.js
@@ -22,7 +22,15 @@ require('views/main/host');
 
 function getView() {
   return App.MainHostView.create({
-    controller: App.MainHostController.create()
+    controller: App.MainHostController.create({
+      updater: Em.Object.create({
+        tableUpdaterMap: {
+          'Hosts': 'updateHost'
+        },
+        updateHost: Em.K
+      }),
+      name: 'ctrl1'
+    })
   });
 }
 
@@ -81,9 +89,500 @@ describe('App.MainHostView', function () {
         expect(view[item.methodName].callCount).to.equal(item.callCount);
       });
     });
+  });
+
+  describe("#onRequestErrorHandler()", function () {
+
+    beforeEach(function () {
+      sinon.stub(view, 'propertyDidChange');
+      view.onRequestErrorHandler();
+    });
+
+    afterEach(function () {
+      view.propertyDidChange.restore();
+    });
+
+    it("requestError should be null", function () {
+      expect(view.get('requestError')).to.be.null;
+    });
+
+    it("filteringComplete should be true", function () {
+      expect(view.get('filteringComplete')).to.be.true;
+    });
+
+    it("propertyDidChange should be called", function () {
+      expect(view.propertyDidChange.calledWith('pageContent')).to.be.true;
+    });
+  });
+
+  describe("#refresh()", function () {
+
+    beforeEach(function () {
+      sinon.stub(view.get('updater'), 'updateHost');
+      view.refresh();
+    });
+
+    afterEach(function () {
+      view.get('updater').updateHost.restore();
+    });
+
+    it("filteringComplete should be false", function () {
+      expect(view.get('filteringComplete')).to.be.false;
+    });
+
+    it("updateHost should be called", function () {
+      expect(view.get('updater').updateHost.calledOnce).to.be.true;
+    });
+  });
+
+  describe("#resetFilterByColumns()", function () {
+
+    beforeEach(function () {
+      sinon.stub(view, 'saveFilterConditions');
+    });
+
+    afterEach(function () {
+      view.saveFilterConditions.restore();
+    });
+
+    it("empty columns", function () {
+      view.set('filterConditions', []);
+      view.resetFilterByColumns([]);
+      expect(view.saveFilterConditions.called).to.be.false;
+    });
+
+    it("empty filterConditions", function () {
+      view.set('filterConditions', []);
+      view.resetFilterByColumns([1]);
+      expect(view.saveFilterConditions.called).to.be.false;
+    });
+
+    it("saveFilterConditions should be called", function () {
+      view.set('filterConditions', [{
+        iColumn: 1,
+        type: 't1',
+        skipFilter: false
+      }]);
+      view.resetFilterByColumns([1]);
+      expect(view.saveFilterConditions.calledWith(1, '', 't1', false)).to.be.true;
+    });
+  });
+
+  describe("#paginationLeftClass", function () {
+
+    it("startIndex is 2, filteringComplete=true", function () {
+      view.set('filteringComplete', true);
+      view.set('startIndex', 2);
+      expect(view.get('paginationLeftClass')).to.equal('paginate_previous');
+    });
+
+    it("startIndex is 2, filteringComplete=false", function () {
+      view.set('filteringComplete', false);
+      view.set('startIndex', 2);
+      expect(view.get('paginationLeftClass')).to.equal('paginate_disabled_previous');
+    });
+
+    it("startIndex is 1, filteringComplete=true", function () {
+      view.set('filteringComplete', true);
+      view.set('startIndex', 1);
+      expect(view.get('paginationLeftClass')).to.equal('paginate_disabled_previous');
+    });
+
+    it("startIndex is 0, filteringComplete=true", function () {
+      view.set('filteringComplete', true);
+      view.set('startIndex', 0);
+      expect(view.get('paginationLeftClass')).to.equal('paginate_disabled_previous');
+    });
+  });
+
+  describe("#paginationRightClass", function () {
+
+    it("endIndex more than filteredCount, filteringComplete=true", function () {
+      view.reopen({
+        filteringComplete: true,
+        endIndex: 4,
+        filteredCount: 3
+      });
+      expect(view.get('paginationRightClass')).to.equal('paginate_disabled_next');
+    });
+
+    it("endIndex equal to filteredCount, filteringComplete=true", function () {
+      view.reopen({
+        filteringComplete: true,
+        endIndex: 4,
+        filteredCount: 4
+      });
+      expect(view.get('paginationRightClass')).to.equal('paginate_disabled_next');
+    });
+
+    it("endIndex less than filteredCount, filteringComplete=false", function () {
+      view.reopen({
+        filteringComplete: false,
+        endIndex: 3,
+        filteredCount: 4
+      });
+      view.propertyDidChange('paginationRightClass');
+      expect(view.get('paginationRightClass')).to.equal('paginate_disabled_next');
+    });
+
+    it("endIndex less than filteredCount, filteringComplete=true", function () {
+      view.reopen({
+        filteringComplete: true,
+        endIndex: 3,
+        filteredCount: 4
+      });
+      view.propertyDidChange('paginationRightClass');
+      expect(view.get('paginationRightClass')).to.equal('paginate_next');
+    });
+  });
+
+  describe("#rowsPerPageSelectView", function () {
+    var rowsPerPageSelectView;
+
+    beforeEach(function () {
+      rowsPerPageSelectView = view.get('rowsPerPageSelectView').create({
+        parentView: Em.Object.create({
+          saveDisplayLength: Em.K,
+          startIndex: 1
+        }),
+        controller: Em.Object.create()
+      });
+    });
+
+    describe("#disableView()", function () {
+
+      beforeEach(function () {
+        sinon.stub(Em.run, 'next', function (context, callback) {
+          callback.apply(rowsPerPageSelectView);
+        });
+      });
+
+      afterEach(function () {
+        Em.run.next.restore();
+      });
+
+      it("disabled should be false", function () {
+        rowsPerPageSelectView.set('parentView.filteringComplete', true);
+        expect(rowsPerPageSelectView.get('disabled')).to.be.false;
+      });
+    });
+
+    describe("#change()", function () {
+
+      beforeEach(function () {
+        sinon.stub(rowsPerPageSelectView.get('parentView'), 'saveDisplayLength');
+        sinon.stub(Ember.run, 'next', Em.clb);
+      });
+
+      afterEach(function () {
+        rowsPerPageSelectView.get('parentView').saveDisplayLength.restore();
+        Ember.run.next.restore();
+      });
+
+      it("saveDisplayLength should be called", function () {
+        rowsPerPageSelectView.change();
+        expect(rowsPerPageSelectView.get('parentView').saveDisplayLength.calledOnce).to.be.true;
+      });
+
+      it("startIndex = 1", function () {
+        rowsPerPageSelectView.set('parentView.startIndex', 1);
+        rowsPerPageSelectView.change();
+        expect(rowsPerPageSelectView.get('parentView.startIndex')).to.be.equal(1);
+      });
+
+      it("startIndex = 0", function () {
+        rowsPerPageSelectView.set('parentView.startIndex', 0);
+        rowsPerPageSelectView.change();
+        expect(rowsPerPageSelectView.get('parentView.startIndex')).to.be.equal(0);
+      });
+
+      it("startIndex = 2", function () {
+        rowsPerPageSelectView.set('parentView.startIndex', 2);
+        rowsPerPageSelectView.change();
+        expect(rowsPerPageSelectView.get('parentView.startIndex')).to.be.equal(1);
+      });
+    });
+  });
+
+  describe("#saveStartIndex()", function () {
+
+    it("startIndex should be 10", function () {
+      view.set('startIndex', 10);
+      expect(view.get('controller.startIndex')).to.be.equal(10);
+    });
+  });
+
+  describe("#clearFiltersObs()", function () {
+
+    beforeEach(function() {
+      sinon.stub(Em.run, 'next', Em.clb);
+      sinon.stub(view, 'clearFilters');
+    });
+
+    afterEach(function() {
+      Em.run.next.restore();
+      view.clearFilters.restore();
+    });
+
+    it("clearFilters should not be called", function() {
+      view.set('controller.clearFilters', false);
+      view.clearFiltersObs();
+      expect(view.clearFilters.called).to.be.false;
+    });
+
+    it("clearFilters should be called", function() {
+      view.set('controller.clearFilters', true);
+      view.clearFiltersObs();
+      expect(view.clearFilters.calledOnce).to.be.true;
+    });
+  });
+
+  describe("#willInsertElement()", function () {
+
+    beforeEach(function() {
+      sinon.stub(view, 'clearFilterConditionsFromLocalStorage').returns(true);
+      sinon.stub(view, 'addObserver');
+    });
+
+    afterEach(function() {
+      view.clearFilterConditionsFromLocalStorage.restore();
+      view.addObserver.restore();
+    });
+
+    it("filterChangeHappened should be true", function() {
+      view.set('controller.showFilterConditionsFirstLoad', false);
+      view.willInsertElement();
+      expect(view.get('controller.filterChangeHappened')).to.be.true;
+    });
+
+    it("startIndex should be 10", function() {
+      view.set('controller.startIndex', 10);
+      view.willInsertElement();
+      expect(view.get('startIndex')).to.be.equal(10);
+    });
+
+    it("addObserver should be called", function() {
+      view.willInsertElement();
+      expect(view.addObserver.calledWith('pageContent.@each.selected', view, view.selectedHostsObserver)).to.be.true;
+    });
+  });
+
+  describe("#willDestroyElement()", function () {
+    var container = {
+      remove: Em.K
+    };
+
+    beforeEach(function() {
+      sinon.stub(container, 'remove');
+      sinon.stub(window, '$').returns(container);
+    });
+
+    afterEach(function() {
+      container.remove.restore();
+      window.$.restore();
+    });
+
+    it("tooltip should be removed", function() {
+      view.willDestroyElement();
+      expect(container.remove.calledOnce).to.be.true;
+    });
+  });
+
+  describe("#onInitialLoad()", function () {
+
+    beforeEach(function() {
+      sinon.stub(view, 'refresh');
+      sinon.stub(view, 'propertyDidChange');
+      view.set('tableFilteringComplete', true);
+    });
+
+    afterEach(function() {
+      view.refresh.restore();
+      view.propertyDidChange.restore();
+    });
+
+    it("filterChangeHappened should be false", function() {
+      view.onInitialLoad();
+      expect(view.get('controller.filterChangeHappened')).to.be.false;
+    });
+
+    it("refresh should be called", function() {
+      view.set('controller.filterChangeHappened', true);
+      view.onInitialLoad();
+      expect(view.refresh.calledOnce).to.be.true;
+    });
+
+    it("propertyDidChange should be called", function() {
+      view.set('controller.filterChangeHappened', false);
+      view.onInitialLoad();
+      expect(view.propertyDidChange.calledWith('filteringComplete')).to.be.true;
+    });
+  });
+
+  describe("#toggleAllHosts()", function () {
+
+    it("selected should be true", function() {
+      var content = [Em.Object.create({selected: false})];
+      view.reopen({
+        selectAllHosts: true,
+        pageContent: content
+      });
+      view.toggleAllHosts();
+      expect(content[0].get('selected')).to.be.true;
+    });
+  });
+
+  describe("#selectedHostsObserver()", function () {
+
+    beforeEach(function() {
+      sinon.stub(Ember.run, 'once');
+    });
+
+    afterEach(function() {
+      Ember.run.once.restore();
+    });
+
+    it("Ember.run.once should be called", function() {
+      view.selectedHostsObserver();
+      expect(Ember.run.once.calledWith(view, 'updateCheckedFlags')).to.be.true;
+    });
+  });
+
+  describe("#updateCheckedFlags()", function () {
+
+    beforeEach(function() {
+      sinon.stub(view, 'removeObserver');
+      sinon.stub(view, 'combineSelectedFilter');
+      sinon.stub(view, 'addObserver');
+      sinon.stub(App.db, 'setSelectedHosts');
+    });
+
+    afterEach(function() {
+      view.removeObserver.restore();
+      view.combineSelectedFilter.restore();
+      view.addObserver.restore();
+      App.db.setSelectedHosts.restore();
+    });
+
+    it("removeObserver should be called", function() {
+      view.updateCheckedFlags();
+      expect(view.removeObserver.calledWith('selectAllHosts', view, view.toggleAllHosts)).to.be.true;
+    });
+
+    it("combineSelectedFilter should be called", function() {
+      view.updateCheckedFlags();
+      expect(view.combineSelectedFilter.calledOnce).to.be.true;
+    });
+
+    it("App.db.setSelectedHosts should be called", function() {
+      view.set('selectedHosts', []);
+      view.updateCheckedFlags();
+      expect(App.db.setSelectedHosts.calledWith('ctrl1', [])).to.be.true;
+    });
+
+    it("addObserver should be called", function() {
+      view.updateCheckedFlags();
+      expect(view.addObserver.calledWith('selectAllHosts', view, view.toggleAllHosts)).to.be.true;
+    });
+
+    it("selectAllHosts should be false", function() {
+      view.reopen({
+        pageContent: []
+      });
+      view.updateCheckedFlags();
+      expect(view.get('selectAllHosts')).to.be.false;
+    });
+
+    it("selectAllHosts should be true", function() {
+      view.reopen({
+        pageContent: [Em.Object.create({selected: true})]
+      });
+      view.updateCheckedFlags();
+      expect(view.get('selectAllHosts')).to.be.true;
+    });
+  });
+
+  describe("#combineSelectedFilter()", function () {
+
+    beforeEach(function() {
+      sinon.stub(App.db, 'getSelectedHosts').returns(['host2', 'host1']);
+    });
+
+    afterEach(function() {
+      App.db.getSelectedHosts.restore();
+    });
+
+    it("selectedHosts should be set ", function() {
+      view.reopen({
+        pageContent: [
+          Em.Object.create({selected: false, hostName: 'host1'}),
+          Em.Object.create({selected: true, hostName: 'host3'})
+        ]
+      });
+      view.combineSelectedFilter();
+      expect(view.get('selectedHosts')).to.be.eql(['host3', 'host2']);
+    });
+  });
+
+  describe("#filterSelected()", function () {
 
+    beforeEach(function() {
+      sinon.stub(view, 'updateFilter');
+    });
+
+    afterEach(function() {
+      view.updateFilter.restore();
+    });
+
+    it("updateFilter should be called", function() {
+      view.set('selectedHosts', ['host1']);
+      view.filterSelected();
+      expect(view.updateFilter.calledWith(10, ['host1'], 'multiple')).to.be.true;
+    });
   });
 
+  describe("#clearSelection()", function () {
+
+    beforeEach(function() {
+      sinon.stub(App.db, 'setSelectedHosts');
+      sinon.stub(view, 'filterSelected');
+      view.reopen({
+        pageContent: [
+          Em.Object.create({selected: true})
+        ],
+        selectAllHosts: true,
+        selectedHosts: [{}]
+      });
+      view.clearSelection();
+    });
+
+    afterEach(function() {
+      App.db.setSelectedHosts.restore();
+      view.filterSelected.restore();
+    });
+
+    it("selected should be false", function() {
+      expect(view.get('pageContent')[0].get('selected')).to.be.false;
+    });
+
+    it("selectAllHosts should be false", function() {
+      expect(view.get('selectAllHosts')).to.be.false;
+    });
+
+    it("selectedHosts should be empty", function() {
+      expect(view.get('selectedHosts')).to.be.empty;
+    });
+
+    it("App.db.setSelectedHosts should be called", function() {
+      expect(App.db.setSelectedHosts.calledWith('ctrl1', [])).to.be.true;
+    });
+
+    it("filterSelected should be called", function() {
+      expect(view.filterSelected.calledOnce).to.be.true;
+    });
+  });
+
+
   describe('#HostView', function () {
 
     var hostView;
@@ -97,6 +596,43 @@ describe('App.MainHostView', function () {
       });
     });
 
+    describe("#didInsertElement()", function () {
+
+      beforeEach(function() {
+        sinon.stub(App, 'tooltip');
+      });
+
+      afterEach(function() {
+        App.tooltip.restore();
+      });
+
+      it("App.tooltip should be called", function() {
+        hostView.didInsertElement();
+        expect(App.tooltip.calledOnce).to.be.true;
+      });
+    });
+
+    describe("#willDestroyElement()", function () {
+      var container = {
+        remove: Em.K
+      };
+
+      beforeEach(function() {
+        sinon.stub(container, 'remove');
+        sinon.stub(hostView, '$').returns(container);
+      });
+
+      afterEach(function() {
+        container.remove.restore();
+        hostView.$.restore();
+      });
+
+      it("tooltip should be removed", function() {
+        hostView.willDestroyElement();
+        expect(container.remove.calledOnce).to.be.true;
+      });
+    });
+
     describe('#displayComponents', function () {
 
       var cases = [
@@ -234,6 +770,98 @@ describe('App.MainHostView', function () {
 
     });
 
+    describe("#restartRequiredComponentsMessage", function () {
+
+      it("5 components require restart", function() {
+        var content = 'c1, c2, c3, c4, c5' + ' ' + Em.I18n.t('common.components').toLowerCase();
+        hostView.set('content.componentsWithStaleConfigsCount', 5);
+        hostView.set('content.componentsWithStaleConfigs', [
+          {displayName: 'c1'},
+          {displayName: 'c2'},
+          {displayName: 'c3'},
+          {displayName: 'c4'},
+          {displayName: 'c5'}
+        ]);
+        hostView.propertyDidChange('restartRequiredComponentsMessage');
+        expect(hostView.get('restartRequiredComponentsMessage')).to.be.equal(
+          Em.I18n.t('hosts.table.restartComponents.withNames').format(content)
+        );
+      });
+
+      it("1 component require restart", function() {
+        var content = 'c1' + ' ' + Em.I18n.t('common.component').toLowerCase();
+        hostView.set('content.componentsWithStaleConfigsCount', 1);
+        hostView.set('content.componentsWithStaleConfigs', [
+          {displayName: 'c1'}
+        ]);
+        hostView.propertyDidChange('restartRequiredComponentsMessage');
+        expect(hostView.get('restartRequiredComponentsMessage')).to.be.equal(
+          Em.I18n.t('hosts.table.restartComponents.withNames').format(content)
+        );
+      });
+
+      it("6 components require restart", function() {
+        hostView.set('content.componentsWithStaleConfigsCount', 6);
+        hostView.set('content.componentsWithStaleConfigs', [
+          {displayName: 'c1'},
+          {displayName: 'c2'},
+          {displayName: 'c3'},
+          {displayName: 'c4'},
+          {displayName: 'c5'},
+          {displayName: 'c6'}
+        ]);
+        hostView.propertyDidChange('restartRequiredComponentsMessage');
+        expect(hostView.get('restartRequiredComponentsMessage')).to.be.equal(
+          Em.I18n.t('hosts.table.restartComponents.withoutNames').format(6)
+        );
+      });
+    });
+
+    describe("#componentsInPassiveStateMessage", function () {
+
+      it("5 components in passive state", function() {
+        hostView.set('content.componentsInPassiveStateCount', 5);
+        hostView.set('content.componentsInPassiveState', [
+          {displayName: 'c1'},
+          {displayName: 'c2'},
+          {displayName: 'c3'},
+          {displayName: 'c4'},
+          {displayName: 'c5'}
+        ]);
+        hostView.propertyDidChange('componentsInPassiveStateMessage');
+        expect(hostView.get('componentsInPassiveStateMessage')).to.be.equal(
+          Em.I18n.t('hosts.table.componentsInPassiveState.withNames').format('c1, c2, c3, c4, c5')
+        );
+      });
+
+      it("1 components in passive state", function() {
+        hostView.set('content.componentsInPassiveStateCount', 1);
+        hostView.set('content.componentsInPassiveState', [
+          {displayName: 'c1'}
+        ]);
+        hostView.propertyDidChange('componentsInPassiveStateMessage');
+        expect(hostView.get('componentsInPassiveStateMessage')).to.be.equal(
+          Em.I18n.t('hosts.table.componentsInPassiveState.withNames').format('c1')
+        );
+      });
+
+      it("6 components in passive state", function() {
+        hostView.set('content.componentsInPassiveStateCount', 6);
+        hostView.set('content.componentsInPassiveState', [
+          {displayName: 'c1'},
+          {displayName: 'c2'},
+          {displayName: 'c3'},
+          {displayName: 'c4'},
+          {displayName: 'c5'},
+          {displayName: 'c6'}
+        ]);
+        hostView.propertyDidChange('componentsInPassiveStateMessage');
+        expect(hostView.get('componentsInPassiveStateMessage')).to.be.equal(
+          Em.I18n.t('hosts.table.componentsInPassiveState.withoutNames').format(6)
+        );
+      });
+    });
+
     describe('#currentVersion', function () {
 
       var cases = [
@@ -285,9 +913,276 @@ describe('App.MainHostView', function () {
           expect(hostView.get('currentVersion')).to.equal(item.currentVersion);
         });
       });
+    });
+
+    describe("#usageStyle", function () {
+
+      it("usageStyle should be 'width:100%'", function() {
+        hostView.set('content.diskUsage', 100);
+        hostView.propertyDidChange('usageStyle');
+        expect(hostView.get('usageStyle')).to.be.equal('width:100%');
+      });
+    });
+  });
+
+  describe("#updateHostsCount()", function () {
+
+    it("should update host counter in categories", function() {
+      view.reopen({
+        categories: [
+          Em.Object.create({healthStatus: ''}),
+          Em.Object.create({healthStatus: 'HEALTHY'}),
+          Em.Object.create({healthStatus: 'UNKNOWN', hostsCount: 0, hasHosts: false})
+        ]
+      });
+      view.set('controller.hostsCountMap', {
+        TOTAL: 10,
+        HEALTHY: 1
+      });
+      view.updateHostsCount();
+      expect(view.get('categories').mapProperty('hostsCount')).to.be.eql([10, 1, 0]);
+      expect(view.get('categories').mapProperty('hasHosts')).to.be.eql([true, true, false]);
+    });
+  });
+
+  describe("#categoryObject", function () {
+    var categoryObject;
+
+    beforeEach(function() {
+      categoryObject = view.get('categoryObject').create();
+    });
+
+    describe("#label", function () {
+
+      it("should return label", function() {
+        categoryObject.set('hostsCount', 1);
+        categoryObject.set('value', 'val1');
+        expect(categoryObject.get('label')).to.be.equal('val1 (1)');
+      });
+    });
+  });
+
+  describe("#statusFilter", function () {
+    var statusFilter;
+
+    beforeEach(function () {
+      statusFilter = view.get('statusFilter').create({
+        parentView: Em.Object.create({
+          resetFilterByColumns: Em.K,
+          refresh: Em.K,
+          updateFilter: Em.K
+        })
+      });
+    });
+
+    describe("#comboBoxLabel", function () {
+      beforeEach(function() {
+        sinon.stub(statusFilter, 'onCategoryChange');
+      });
+
+      afterEach(function() {
+        statusFilter.onCategoryChange.restore();
+      });
+
+      var testCases = [
+        {
+          value: 'val1',
+          categories: [Em.Object.create({isActive: true, hostsCount: 1, value: "val1"})],
+          totalCount: 10,
+          expected: 'val1 (1)'
+        },
+        {
+          value: 'val1',
+          categories: [Em.Object.create({isActive: false, hostsCount: 1})],
+          totalCount: 10,
+          expected: Em.I18n.t('common.all') + ' (10)'
+        },
+        {
+          value: '',
+          categories: [],
+          totalCount: 10,
+          expected: Em.I18n.t('common.all') + ' (10)'
+        }
+      ];
+
+      testCases.forEach(function(test) {
+        it("value=" + test.value +
+           " categories=" + JSON.stringify(test.categories) +
+           " totalCount=" + test.totalCount, function () {
+          statusFilter.setProperties({
+            value: test.value,
+            categories: test.categories
+          });
+          statusFilter.set('parentView.totalCount', test.totalCount);
+          expect(statusFilter.get('comboBoxLabel')).to.be.equal(test.expected);
+        });
+      });
+    });
+
+    describe("#onCategoryChange()", function () {
+
+      it("should set class", function() {
+        statusFilter.setProperties({
+          value: 'val1',
+          categories: [
+            Em.Object.create({
+              healthStatus: 'val1',
+              class: 'cl1',
+              healthClass: 'hcl1'
+            })
+          ]
+        });
+        expect(statusFilter.get('class')).to.be.equal('cl1 hcl1');
+        expect(statusFilter.get('categories')[0].get('isActive')).to.be.true;
+      });
+    });
+
+    describe("#showClearFilter()", function () {
+
+      beforeEach(function() {
+        sinon.stub(statusFilter, 'selectCategory');
+        sinon.stub(statusFilter, 'onCategoryChange');
+      });
+
+      afterEach(function() {
+        statusFilter.selectCategory.restore();
+        statusFilter.onCategoryChange.restore();
+      });
+
+      it("selectCategory should be called", function() {
+        statusFilter.setProperties({
+          value: 'val1',
+          categories: [
+            Em.Object.create({
+              healthStatus: 'val1'
+            })
+          ]
+        });
+        statusFilter.showClearFilter();
+        expect(statusFilter.selectCategory.getCall(0).args).to.be.eql([
+          {
+            context: Em.Object.create({
+              healthStatus: 'val1'
+            })
+          }
+        ]);
+      });
+    });
+
+    describe("#selectCategory()", function () {
+      var category = Em.Object.create({
+        healthStatus: 'val1',
+        column: 1,
+        isHealthStatus: false,
+        filterValue: 'val1',
+        type: 't1'
+      });
+
+      beforeEach(function() {
+        sinon.stub(statusFilter.get('parentView'), 'resetFilterByColumns');
+        sinon.stub(statusFilter.get('parentView'), 'refresh');
+        sinon.stub(statusFilter.get('parentView'), 'updateFilter');
+        sinon.stub(statusFilter, 'onCategoryChange');
+      });
+
+      afterEach(function() {
+        statusFilter.get('parentView').resetFilterByColumns.restore();
+        statusFilter.get('parentView').refresh.restore();
+        statusFilter.get('parentView').updateFilter.restore();
+        statusFilter.onCategoryChange.restore();
+      });
+
+      it("value should be set", function() {
+        statusFilter.selectCategory({context: category});
+        expect(statusFilter.get('value')).to.be.equal('val1');
+      });
+
+      it("resetFilterByColumns should be called", function() {
+        statusFilter.selectCategory({context: category});
+        expect(statusFilter.get('parentView').resetFilterByColumns.calledWith([0, 7, 8, 9])).to.be.true;
+      });
 
+      it("updateFilter should be called, isHealthStatus=false", function() {
+        category.set('isHealthStatus', false);
+        statusFilter.selectCategory({context: category});
+        expect(statusFilter.get('parentView').updateFilter.calledWith(1, 'val1', 't1')).to.be.true;
+      });
+
+      it("updateFilter should be called, isHealthStatus=true", function() {
+        category.set('isHealthStatus', true);
+        category.set('healthStatus', 'val1');
+        statusFilter.selectCategory({context: category});
+        expect(statusFilter.get('parentView').updateFilter.calledWith(0, 'val1', 'string')).to.be.true;
+      });
+
+      it("refresh should be called, isHealthStatus=true", function() {
+        category.set('isHealthStatus', true);
+        category.set('healthStatus', null);
+        statusFilter.selectCategory({context: category});
+        expect(statusFilter.get('parentView').refresh.calledOnce).to.be.true;
+      });
     });
 
+    describe("#clearFilter()", function () {
+
+      beforeEach(function() {
+        sinon.stub(statusFilter, 'showClearFilter');
+        sinon.stub(statusFilter, 'onCategoryChange');
+      });
+
+      afterEach(function() {
+        statusFilter.showClearFilter.restore();
+        statusFilter.onCategoryChange.restore();
+      });
+
+      it("isActive should be false", function() {
+        statusFilter.set('categories', [Em.Object.create()]);
+        statusFilter.clearFilter();
+        expect(statusFilter.get('categories')[0].get('isActive')).to.be.false;
+      });
+
+      it("value should be empty", function() {
+        statusFilter.clearFilter();
+        expect(statusFilter.get('value')[0]).to.be.empty;
+      });
+
+      it("class should be empty", function() {
+        statusFilter.clearFilter();
+        expect(statusFilter.get('class')).to.be.empty;
+      });
+
+      it("showClearFilter should be called", function() {
+        statusFilter.clearFilter();
+        expect(statusFilter.showClearFilter.calledOnce).to.be.true;
+      });
+    });
   });
 
+  describe("#clearFilters()", function () {
+
+    beforeEach(function() {
+      sinon.stub(view, 'clearFilterConditionsFromLocalStorage');
+      sinon.stub(view, 'refresh');
+    });
+
+    afterEach(function() {
+      view.clearFilterConditionsFromLocalStorage.restore();
+      view.refresh.restore();
+    });
+
+    it("filterConditions should be empty", function() {
+      view.clearFilters();
+      expect(view.get('filterConditions')).to.be.empty;
+    });
+
+    it("clearFilterConditionsFromLocalStorage should be called", function() {
+      view.clearFilters();
+      expect(view.clearFilterConditionsFromLocalStorage.calledOnce).to.be.true;
+    });
+
+    it("refresh should be called", function() {
+      view.clearFilters();
+      expect(view.refresh.calledOnce).to.be.true;
+    });
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9e71d6fb/ambari-web/test/views/main/menu_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/menu_test.js b/ambari-web/test/views/main/menu_test.js
index 04d13f7..c5cc6a2 100644
--- a/ambari-web/test/views/main/menu_test.js
+++ b/ambari-web/test/views/main/menu_test.js
@@ -20,96 +20,216 @@
 var App = require('app');
 require('views/main/menu');
 
-var mainMenuView = App.MainMenuView.create();
 describe('App.MainMenuView', function () {
+  var view;
 
-  describe('#itemViewClass', function () {
+  beforeEach(function () {
+    view = App.MainMenuView.create()
+  });
+
+  describe("#views", function () {
+
+    beforeEach(function() {
+      sinon.stub(App.router, 'get').withArgs('mainViewsController.ambariViews').returns([{}]);
+    });
+
+    afterEach(function() {
+      App.router.get.restore();
+    });
+
+    it("should return views", function() {
+      view.propertyDidChange('views');
+      expect(view.get('views')).to.be.eql([{}]);
+    });
+  });
+
+  describe("#itemViewClass", function () {
+    var itemViewClass;
 
     beforeEach(function () {
-      mainMenuView.reopen({
-        content: [
-          mainMenuView.get('itemViewClass').create({
-            content: {
-              routing: 'dashboard'
-            }
-          }),
-          mainMenuView.get('itemViewClass').create({
-            content: {
-              routing: 'admin'
-            }
-          })
-        ]
+      itemViewClass = view.get('itemViewClass').create({
+        content: Em.Object.create({
+          routing: ['firstroute']
+        })
       });
     });
 
-    describe.skip('#dropdownCategories', function () {
-
-      var cases = [
-        {
-          itemName: 'dashboard',
-          dropdownCategories: [],
-          title: 'not Admin item'
-        },
-        {
-          itemName: 'admin',
-          isHadoopWindowsStack: true,
-          dropdownCategories: [
-            {
-              name: 'stackAndUpgrade',
-              url: 'stack',
-              label: Em.I18n.t('admin.stackUpgrade.title')
-            },
-            {
-              name: 'adminServiceAccounts',
-              url: 'serviceAccounts',
-              label: Em.I18n.t('common.serviceAccounts')
-            }
-          ],
-          title: 'Admin item, HDPWIN'
-        },
-        {
-          itemName: 'admin',
-          isHadoopWindowsStack: false,
-          dropdownCategories: [
-            {
-              name: 'stackAndUpgrade',
-              url: 'stack',
-              label: Em.I18n.t('admin.stackUpgrade.title')
-            },
-            {
-              name: 'adminServiceAccounts',
-              url: 'serviceAccounts',
-              label: Em.I18n.t('common.serviceAccounts')
-            },
-            {
-              name: 'kerberos',
-              url: 'kerberos/',
-              label: Em.I18n.t('common.kerberos')
-            }
-          ],
-          title: 'Admin item, not HDPWIN'
-        }
-      ];
+    describe("#active", function () {
 
       beforeEach(function () {
-        this.mock = sinon.stub(App, 'get');
+        this.mock = sinon.stub(App.router, 'get');
       });
 
       afterEach(function () {
         this.mock.restore();
+        App.router.set('location.lastSetURL', '/login');
       });
 
-      cases.forEach(function (item) {
-        it(item.title, function () {
-          this.mock.withArgs('isHadoopWindowsStack').returns(item.isHadoopWindowsStack);
-          var menuItem = mainMenuView.get('content').findProperty('content.routing', item.itemName);
-          menuItem.propertyDidChange('dropdownCategories');
-          expect(menuItem.get('dropdownCategories')).to.eql(item.dropdownCategories);
-        });
+      it("cluster not loaded", function () {
+        this.mock.withArgs('clusterController.isLoaded').returns(false);
+        itemViewClass.propertyDidChange('active');
+        expect(itemViewClass.get('active')).to.be.empty;
+      });
+
+      it("cluster loaded, firstroute should be active", function () {
+        this.mock.withArgs('clusterController.isLoaded').returns(true);
+        App.router.set('location.lastSetURL', '/main/firstroute');
+        itemViewClass.propertyDidChange('active');
+        expect(itemViewClass.get('active')).to.be.equal('active');
+      });
+
+      it("cluster loaded, dashboard should be active", function () {
+        itemViewClass.set('content.routing', ['dashboard']);
+        this.mock.withArgs('clusterController.isLoaded').returns(true);
+        App.router.set('location.lastSetURL', '/main');
+        itemViewClass.propertyDidChange('active');
+        expect(itemViewClass.get('active')).to.be.equal('active');
+      });
+
+      it("cluster loaded, should be undefined", function () {
+        itemViewClass.set('content.routing', ['dashboard']);
+        this.mock.withArgs('clusterController.isLoaded').returns(true);
+        App.router.set('location.lastSetURL', '');
+        itemViewClass.propertyDidChange('active');
+        expect(itemViewClass.get('active')).to.be.undefined;
       });
 
+      it("cluster loaded, secondroute should not be active", function () {
+        this.mock.withArgs('clusterController.isLoaded').returns(true);
+        App.router.set('location.lastSetURL', '/main/secondroute');
+        itemViewClass.propertyDidChange('active');
+        expect(itemViewClass.get('active')).to.be.empty;
+      });
     });
 
-  });
+    describe("#isViewsItem", function () {
+
+      it("should be false", function() {
+        itemViewClass.set('content.routing', []);
+        itemViewClass.propertyDidChange('isViewsItem');
+        expect(itemViewClass.get('isViewsItem')).to.be.false;
+      });
+
+      it("should be true", function() {
+        itemViewClass.set('content.routing', ['views']);
+        itemViewClass.propertyDidChange('isViewsItem');
+        expect(itemViewClass.get('isViewsItem')).to.be.true;
+      });
+    });
+
+    describe("#goToSection()", function () {
+
+      beforeEach(function() {
+        sinon.stub(App.router, 'set');
+        sinon.stub(App.router, 'route');
+      });
+
+      afterEach(function() {
+        App.router.set.restore();
+        App.router.route.restore();
+      });
 
+      it("should route to main", function() {
+        itemViewClass.goToSection({context: ''});
+        expect(App.router.route.calledWith('main/')).to.be.true;
+      });
+
+      it("should route to hosts", function() {
+        itemViewClass.goToSection({context: 'hosts'});
+        expect(App.router.set.calledWith('mainHostController.showFilterConditionsFirstLoad', false)).to.be.true;
+      });
+
+      it("should route to views", function() {
+        itemViewClass.goToSection({context: 'views'});
+        expect(App.router.route.calledWith('views')).to.be.true;
+      });
+
+      it("should route to alerts", function() {
+        itemViewClass.goToSection({context: 'alerts'});
+        expect(App.router.set.calledWith('mainAlertDefinitionsController.showFilterConditionsFirstLoad', false)).to.be.true;
+      });
+    });
+
+    describe("#AdminDropdownItemView", function () {
+      var adminDropdownItemView;
+
+      beforeEach(function () {
+        adminDropdownItemView = itemViewClass.get('AdminDropdownItemView').create({
+          parentView: Em.Object.create({
+            dropdownCategories: [
+              {name: 'cat1', disabled: true},
+              {name: 'cat2', disabled: false}
+            ],
+            content: Em.Object.create()
+          })
+        });
+      });
+
+      describe("#isDisabled", function () {
+
+        it("should be true", function () {
+          adminDropdownItemView.set('item', 'cat1');
+          adminDropdownItemView.propertyDidChange('isDisabled');
+          expect(adminDropdownItemView.get('isDisabled')).to.be.true;
+        });
+
+        it("should be false", function () {
+          adminDropdownItemView.set('item', 'cat2');
+          adminDropdownItemView.propertyDidChange('isDisabled');
+          expect(adminDropdownItemView.get('isDisabled')).to.be.false;
+        });
+      });
+
+      describe("#goToCategory()", function () {
+        var testCases = [
+          {
+            routing: '',
+            isActive: true,
+            isDisabled: true,
+            expected: false
+          },
+          {
+            routing: 'admin',
+            isActive: true,
+            isDisabled: true,
+            expected: false
+          },
+          {
+            routing: 'admin',
+            isActive: false,
+            isDisabled: true,
+            expected: false
+          },
+          {
+            routing: 'admin',
+            isActive: false,
+            isDisabled: false,
+            expected: true
+          }
+        ];
+
+        beforeEach(function() {
+          sinon.stub(App.router, 'route');
+        });
+
+        afterEach(function() {
+          App.router.route.restore();
+        });
+
+        testCases.forEach(function(test) {
+          it("routing=" + test.routing +
+             " isActive=" + test.isActive +
+             " isDisabled=" + test.isDisabled, function() {
+            adminDropdownItemView.set('parentView.content.routing', test.routing);
+            adminDropdownItemView.reopen({
+              isActive: test.isActive,
+              isDisabled: test.isDisabled
+            });
+            adminDropdownItemView.goToCategory({context: 'context'});
+            expect(App.router.route.called).to.be.equal(test.expected);
+          });
+        });
+      });
+    });
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/9e71d6fb/ambari-web/test/views/main/views_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/views_view_test.js b/ambari-web/test/views/main/views_view_test.js
new file mode 100644
index 0000000..2e24fed
--- /dev/null
+++ b/ambari-web/test/views/main/views_view_test.js
@@ -0,0 +1,45 @@
+/**
+ * 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/views_view');
+
+describe('App.MainViewsView', function () {
+  var view;
+
+  beforeEach(function() {
+    view = App.MainViewsView.create()
+  });
+
+  describe("#views", function () {
+
+    beforeEach(function() {
+      sinon.stub(App.router, 'get').returns([{}]);
+    });
+
+    afterEach(function() {
+      App.router.get.restore();
+    });
+
+    it("should return views", function() {
+      view.propertyDidChange('views');
+      expect(view.get('views')).to.be.eql([{}]);
+    });
+  });
+});


Mime
View raw message