AMBARI-15084 Cover service's 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/1bd4c232 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/1bd4c232 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/1bd4c232 Branch: refs/heads/branch-dev-patch-upgrade Commit: 1bd4c2329192157f0977bb7e1941485202b04837 Parents: 84ca6a8 Author: Andrii Tkach <atk...@hortonworks.com> Authored: Thu Feb 18 09:51:59 2016 +0200 Committer: Andrii Tkach <atk...@hortonworks.com> Committed: Thu Feb 18 09:51:59 2016 +0200 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 2 + ambari-web/app/models/service.js | 2 +- .../app/views/common/chart/linear_time.js | 4 + ambari-web/app/views/main/service/info/menu.js | 45 +- .../app/views/main/service/info/summary.js | 154 ++-- .../service/reassign/step4_controller_test.js | 5 +- .../test/views/common/chart/linear_time_test.js | 3 +- .../stack_upgrade/upgrade_wizard_view_test.js | 5 - .../service/info/component_list_view_test.js | 153 ++++ .../test/views/main/service/info/config_test.js | 99 ++- .../test/views/main/service/info/menu_test.js | 93 ++ .../views/main/service/info/summary_test.js | 852 +++++++++++++------ 12 files changed, 1040 insertions(+), 377 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/1bd4c232/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 0695d06..06c4c31 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -270,6 +270,8 @@ var files = [ 'test/views/main/service/item_test', 'test/views/main/service/info/config_test', 'test/views/main/service/info/summary_test', + 'test/views/main/service/info/menu_test', + 'test/views/main/service/info/component_list_view_test', 'test/views/main/service/info/metrics/ambari_metrics/regionserver_base_test', 'test/views/main/service/info/metrics/flume/flume_agent_metrics_section_test', 'test/views/main/service/services/ranger_test', http://git-wip-us.apache.org/repos/asf/ambari/blob/1bd4c232/ambari-web/app/models/service.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/service.js b/ambari-web/app/models/service.js index 39a6b1c..c1ed776 100644 --- a/ambari-web/app/models/service.js +++ b/ambari-web/app/models/service.js @@ -229,7 +229,7 @@ App.Service.Health = { * association between service and extended model name * @type {Object} */ - App.Service.extendedModel = { +App.Service.extendedModel = { 'HDFS': 'HDFSService', 'HBASE': 'HBaseService', 'YARN': 'YARNService', http://git-wip-us.apache.org/repos/asf/ambari/blob/1bd4c232/ambari-web/app/views/common/chart/linear_time.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/common/chart/linear_time.js b/ambari-web/app/views/common/chart/linear_time.js index 064bec3..864203d 100644 --- a/ambari-web/app/views/common/chart/linear_time.js +++ b/ambari-web/app/views/common/chart/linear_time.js @@ -199,6 +199,10 @@ App.ChartLinearTimeView = Ember.View.extend(App.ExportMetricsMixin, { }); }, + setCurrentTimeIndex: function () { + this.set('currentTimeIndex', this.get('parentView.currentTimeRangeIndex')); + }.observes('parentView.currentTimeRangeIndex'), + /** * Maps server data into series format ready for export to graph and JSON formats * @param jsonData http://git-wip-us.apache.org/repos/asf/ambari/blob/1bd4c232/ambari-web/app/views/main/service/info/menu.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/service/info/menu.js b/ambari-web/app/views/main/service/info/menu.js index 3de23fd..3533a72 100644 --- a/ambari-web/app/views/main/service/info/menu.js +++ b/ambari-web/app/views/main/service/info/menu.js @@ -21,29 +21,46 @@ var App = require('app'); App.MainServiceInfoMenuView = Em.CollectionView.extend({ tagName: 'ul', classNames: ["nav", "nav-tabs", "background-text"], - content:function(){ + content: function () { var menuItems = [ - { label: Em.I18n.t('services.service.info.menu.summary'), id: 'summary-service-tab',routing:'summary', active:"active"} - //{ label:'Audit', routing:'audit'} + { + label: Em.I18n.t('services.service.info.menu.summary'), + id: 'summary-service-tab', + routing: 'summary', + active: "active" + } ]; - if(this.get('heatmapTab')) menuItems.push({ label: Em.I18n.t('services.service.info.menu.heatmaps'), id: 'heatmap-service-tab', routing:'heatmaps'}); - if(this.get('configTab')) menuItems.push({ label: Em.I18n.t('services.service.info.menu.configs'), id: 'configs-service-tab', routing:'configs'}); + if (this.get('heatmapTab')) { + menuItems.push({ + label: Em.I18n.t('services.service.info.menu.heatmaps'), + id: 'heatmap-service-tab', + routing: 'heatmaps' + }); + } + if (this.get('configTab')) { + menuItems.push({ + label: Em.I18n.t('services.service.info.menu.configs'), + id: 'configs-service-tab', + routing: 'configs' + }); + } return menuItems; }.property(), - init: function(){ this._super(); this.activateView(); }, + init: function () { + this._super(); + this.activateView(); + }, - activateView:function () { - $.each(this._childViews, function () { - this.set('active', (document.URL.endsWith(this.get('content.routing')) ? "active" : "")); - }); + activateView: function () { + this.get('_childViews').forEach(function(view) { + view.set('active', (document.URL.endsWith(view.get('content.routing')) ? "active" : "")); + }, this); }.observes('App.router.location.lastSetURL'), - deactivateChildViews: function() { - $.each(this._childViews, function(){ - this.set('active', ""); - }); + deactivateChildViews: function () { + this.get('_childViews').setEach('active', ''); }, itemViewClass: Em.View.extend({ http://git-wip-us.apache.org/repos/asf/ambari/blob/1bd4c232/ambari-web/app/views/main/service/info/summary.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/service/info/summary.js b/ambari-web/app/views/main/service/info/summary.js index d0aadc0..2482913 100644 --- a/ambari-web/app/views/main/service/info/summary.js +++ b/ambari-web/app/views/main/service/info/summary.js @@ -89,7 +89,7 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin hasManyServers: Em.computed.gt('servers.length', 1), clientsHostText: function () { - if (this.get('controller.content.installedClients').length == 0) { + if (this.get('controller.content.installedClients').length === 0) { return ''; } else if (this.get("hasManyClients")) { return Em.I18n.t('services.service.summary.viewHosts'); @@ -134,9 +134,11 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin return result; }.property('controller.content'), - historyServerUI: function(){ - var service=this.get('controller.content'); - return (App.singleNodeInstall ? "http://" + App.singleNodeAlias + ":19888" : "http://" + service.get("hostComponents").findProperty('isMaster', true).get("host").get("publicHostName")+":19888"); + historyServerUI: function () { + var master = this.get('controller.content.hostComponents').findProperty('isMaster'); + return (App.singleNodeInstall + ? "http://" + App.singleNodeAlias + ":19888" + : "http://" + master.get("host.publicHostName") + ":19888"); }.property('controller.content'), /** @@ -189,7 +191,7 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin updateComponentList: function(source, data) { var sourceIds = source.mapProperty('id'); var dataIds = data.mapProperty('id'); - if (sourceIds.length == 0) { + if (sourceIds.length === 0) { source.pushObjects(data); } if (source.length > data.length) { @@ -216,13 +218,14 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin }, /** + * @type {Em.View} * Wrapper for displayName. used to render correct display name for mysql_server */ componentNameView: Ember.View.extend({ template: Ember.Handlebars.compile('{{view.displayName}}'), comp : null, - displayName: function(){ - if(this.get('comp.componentName') == 'MYSQL_SERVER'){ + displayName: function () { + if (this.get('comp.componentName') === 'MYSQL_SERVER') { return this.t('services.hive.databaseComponent'); } return this.get('comp.displayName'); @@ -232,43 +235,32 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin service: null, getServiceModel: function (serviceName) { - var svc = App.Service.find(serviceName); - var svcName = svc.get('serviceName'); - if (svcName) { - switch (svcName.toLowerCase()) { - case 'hdfs': - svc = App.HDFSService.find().objectAt(0); - break; - case 'yarn': - svc = App.YARNService.find().objectAt(0); - break; - case 'hbase': - svc = App.HBaseService.find().objectAt(0); - break; - case 'flume': - svc = App.FlumeService.find().objectAt(0); - break; - case 'storm': - svc = App.StormService.find().objectAt(0); - break; - default: - break; - } + var extended = App.Service.extendedModel[serviceName]; + if (extended) { + return App[extended].find().objectAt(0); } - return svc; + return App.Service.find(serviceName); }, - isHide:true, - moreStatsView:Em.View.extend({ - tagName:"a", - template:Ember.Handlebars.compile('{{t services.service.summary.moreStats}}'), - attributeBindings:[ 'href' ], - classNames:[ 'more-stats' ], - click:function (event) { + /** + * @type {boolean} + * @default true + */ + isHide: true, + + /** + * @type {Em.View} + */ + moreStatsView: Em.View.extend({ + tagName: "a", + template: Ember.Handlebars.compile('{{t services.service.summary.moreStats}}'), + attributeBindings: ['href'], + classNames: ['more-stats'], + click: function (event) { this._parentView._parentView.set('isHide', false); this.remove(); }, - href:'javascript:void(null)' + href: 'javascript:void(null)' }), serviceName: Em.computed.alias('service.serviceName'), @@ -293,7 +285,7 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin return App.AlertDefinition.find().someProperty('serviceName', this.get('controller.content.serviceName')); }.property('controller.content.serviceName'), - updateComponentInformation: function() { + updateComponentInformation: function () { var hc = this.get('controller.content.restartRequiredHostsAndComponents'); var hostsCount = 0; var componentsCount = 0; @@ -305,10 +297,11 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin this.set('hostsCount', hostsCount); }.observes('controller.content.restartRequiredHostsAndComponents'), - rollingRestartSlaveComponentName : function() { + rollingRestartSlaveComponentName: function() { return batchUtils.getRollingRestartComponentName(this.get('serviceName')); }.property('serviceName'), - rollingRestartActionName : function() { + + rollingRestartActionName: function() { var label = null; var componentName = this.get('rollingRestartSlaveComponentName'); if (componentName) { @@ -349,6 +342,7 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin }, bodyMessage); } }, + rollingRestartStaleConfigSlaveComponents: function (componentName) { batchUtils.launchHostComponentRollingRestart(componentName.context, this.get('service.displayName'), this.get('service.passiveState') === "ON", true); }, @@ -358,31 +352,25 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin * the array into sections of 5 for displaying on the page * (will only display rows with 5 items) */ - constructGraphObjects: function(graphNames) { - var result = [], graphObjects = [], chunkSize = this.get('chunkSize'); - var self = this; - var serviceName = this.get('controller.content.serviceName'); - var stackService = App.StackService.find().findProperty('serviceName', serviceName); + constructGraphObjects: function (graphNames) { + var self = this, + stackService = App.StackService.find(this.get('controller.content.serviceName')); if (!graphNames && !stackService.get('isServiceWithWidgets')) { - self.get('serviceMetricGraphs').clear(); - self.set('isServiceMetricLoaded', false); + this.get('serviceMetricGraphs').clear(); + this.set('isServiceMetricLoaded', false); return; } - // load time range for current service from server - self.getUserPref(self.get('persistKey')).complete(function () { - var index = self.get('currentTimeRangeIndex'); + // load time range(currentTimeRangeIndex) for current service from server + this.getUserPref(self.get('persistKey')).complete(function () { + var result = [], graphObjects = [], chunkSize = self.get('chunkSize'); if (graphNames) { - graphNames.forEach(function(graphName) { - graphObjects.push(App["ChartServiceMetrics" + graphName].extend({ - setCurrentTimeIndex: function () { - this.set('currentTimeIndex', this.get('parentView.currentTimeRangeIndex')); - }.observes('parentView.currentTimeRangeIndex') - })); + graphNames.forEach(function (graphName) { + graphObjects.push(App["ChartServiceMetrics" + graphName].extend()); }); } - while(graphObjects.length) { + while (graphObjects.length) { result.push(graphObjects.splice(0, chunkSize)); } self.set('serviceMetricGraphs', result); @@ -394,6 +382,11 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin * Contains graphs for this particular service */ serviceMetricGraphs: [], + + /** + * @type {boolean} + * @default false + */ isServiceMetricLoaded: false, /** @@ -409,7 +402,7 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin }, getUserPrefErrorCallback: function (request) { - if (request.status == 404) { + if (request.status === 404) { this.postUserPref(this.get('persistKey'), 0); this.set('currentTimeRangeIndex', 0); } @@ -543,7 +536,7 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin this._super(); var svcName = this.get('controller.content.serviceName'); this.set('service', this.getServiceModel(svcName)); - var isMetricsSupported = svcName != 'STORM' || App.get('isStormMetricsSupported'); + var isMetricsSupported = svcName !== 'STORM' || App.get('isStormMetricsSupported'); this.get('controller').getActiveWidgetLayout(); if (App.get('supports.customizedWidgetLayout')) { @@ -551,11 +544,35 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin } if (svcName && isMetricsSupported) { - var allServices = require('data/service_graph_config'); + var allServices = require('data/service_graph_config'); this.constructGraphObjects(allServices[svcName.toLowerCase()]); } - // adjust the summary table height + this.adjustSummaryHeight(); + this.makeSortable(); + this.addWidgetTooltip(); + App.loadTimer.finish('Service Summary Page'); + }, + + addWidgetTooltip: function() { + Em.run.later(this, function () { + App.tooltip($("[rel='add-widget-tooltip']")); + // enable description show up on hover + $('.thumbnail').hoverIntent(function() { + if ($(this).is(':hover')) { + $(this).find('.hidden-description').delay(1000).fadeIn(200).end(); + } + }, function() { + $(this).find('.hidden-description').stop().hide().end(); + }); + }, 1000); + }, + + /** + * adjust the summary table height + */ + adjustSummaryHeight: function() { var summaryTable = document.getElementById('summary-info'); + if (summaryTable) { var rows = $(summaryTable).find('tr'); if (rows != null && rows.length > 0) { @@ -567,19 +584,6 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, App.TimeRangeMixin } } } - this.makeSortable(); - Em.run.later(this, function () { - App.tooltip($("[rel='add-widget-tooltip']")); - // enalble description show up on hover - $('.thumbnail').hoverIntent(function() { - if ($(this).is(':hover')) { - $(this).find('.hidden-description').delay(1000).fadeIn(200).end(); - } - }, function() { - $(this).find('.hidden-description').stop().hide().end(); - }); - }, 1000); - App.loadTimer.finish('Service Summary Page'); }, willDestroyElement: function() { http://git-wip-us.apache.org/repos/asf/ambari/blob/1bd4c232/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 945718f..4406bb0 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 @@ -952,7 +952,10 @@ describe('App.ReassignMasterWizardStep4Controller', function () { it('reassign host does not match current', function () { controller.set('content.reassignHosts.source', 'host2'); controller.startNameNode(); - expect(controller.updateComponent.calledWith('NAMENODE', ['host1'], 'HDFS', 'Start')).to.be.true; + expect(controller.updateComponent.getCall(0).args[0]).to.be.equal('NAMENODE'); + expect(controller.updateComponent.getCall(0).args[1][0]).to.be.equal('host1'); + expect(controller.updateComponent.getCall(0).args[2]).to.be.equal('HDFS'); + expect(controller.updateComponent.getCall(0).args[3]).to.be.equal('Start'); }); it('reassign host matches current', function () { http://git-wip-us.apache.org/repos/asf/ambari/blob/1bd4c232/ambari-web/test/views/common/chart/linear_time_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/common/chart/linear_time_test.js b/ambari-web/test/views/common/chart/linear_time_test.js index c547249..0484fd1 100644 --- a/ambari-web/test/views/common/chart/linear_time_test.js +++ b/ambari-web/test/views/common/chart/linear_time_test.js @@ -302,7 +302,8 @@ describe('App.ChartLinearTimeView', function () { parentView: Em.Object.create({ currentTimeRangeIndex: 2 }) - }) + }), + timeUnitSecondsSetter: Em.K }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/1bd4c232/ambari-web/test/views/main/admin/stack_upgrade/upgrade_wizard_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/admin/stack_upgrade/upgrade_wizard_view_test.js b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_wizard_view_test.js index 6349dfe..5630a8c 100644 --- a/ambari-web/test/views/main/admin/stack_upgrade/upgrade_wizard_view_test.js +++ b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_wizard_view_test.js @@ -74,11 +74,6 @@ describe('App.upgradeWizardView', function () { }); describe("#activeGroup", function () { - after(function () { - view.reopen({ - activeGroup: Em.Object.create() - }); - }); it("status is updated", function () { view.reopen({ activeStatuses: ['IN_PROGRESS'], http://git-wip-us.apache.org/repos/asf/ambari/blob/1bd4c232/ambari-web/test/views/main/service/info/component_list_view_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/service/info/component_list_view_test.js b/ambari-web/test/views/main/service/info/component_list_view_test.js new file mode 100644 index 0000000..1537f2b --- /dev/null +++ b/ambari-web/test/views/main/service/info/component_list_view_test.js @@ -0,0 +1,153 @@ +/** + * 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/service/info/menu'); + + +describe('App.SummaryMasterComponentsView', function () { + var view; + + beforeEach(function () { + view = App.SummaryMasterComponentsView.create({ + controller: Em.Object.create() + }); + }); + + describe("#mastersCompWillChange", function() { + + beforeEach(function() { + sinon.stub(view, 'removeTooltips'); + }); + afterEach(function() { + view.removeTooltips.restore(); + }); + + it("removeTooltips should be called", function() { + view.mastersCompWillChange(); + expect(view.removeTooltips.calledOnce).to.be.true; + }); + }); + + describe("#mastersCompDidChange", function() { + + beforeEach(function() { + sinon.stub(view, 'attachTooltip'); + }); + afterEach(function() { + view.attachTooltip.restore(); + }); + + it("attachTooltip should be called", function() { + view.mastersCompDidChange(); + expect(view.attachTooltip.calledOnce).to.be.true; + }); + }); + + describe("#didInsertElement", function() { + + beforeEach(function() { + sinon.stub(view, 'attachTooltip'); + }); + afterEach(function() { + view.attachTooltip.restore(); + }); + + it("attachTooltip should be called", function() { + view.didInsertElement(); + expect(view.attachTooltip.calledOnce).to.be.true; + }); + }); + + describe("#willDestroyElement", function() { + var mock = {tooltip: Em.K}; + + beforeEach(function() { + sinon.spy(mock, 'tooltip'); + sinon.stub(window, '$').returns(mock); + }); + afterEach(function() { + mock.tooltip.restore(); + window.$.restore(); + }); + + it("tooltip should be called", function() { + view.willDestroyElement(); + expect(mock.tooltip.calledWith('destroy')).to.be.true; + }); + }); + + describe("#removeTooltips", function() { + var mock = { + tooltip: Em.K + }; + + beforeEach(function() { + sinon.spy(mock, 'tooltip'); + sinon.stub(window, '$').returns(mock); + }); + afterEach(function() { + mock.tooltip.restore(); + window.$.restore(); + }); + + it("tooltip should be called", function() { + mock.length = 1; + view.removeTooltips(); + expect(mock.tooltip.calledWith('destroy')).to.be.true; + }); + + it("tooltip should not be called", function() { + mock.length = 0; + view.removeTooltips(); + expect(mock.tooltip.called).to.be.false; + }); + }); + + describe("#attachTooltip", function() { + var mock = { + tooltip: Em.K + }; + + beforeEach(function() { + sinon.stub(App, 'tooltip'); + sinon.stub(window, '$').returns(mock); + }); + afterEach(function() { + App.tooltip.restore(); + window.$.restore(); + }); + + it("tooltip should be called", function() { + mock.length = 1; + view.attachTooltip(); + expect(App.tooltip.calledOnce).to.be.true; + }); + + it("tooltip should not be called", function() { + mock.length = 0; + view.attachTooltip(); + expect(App.tooltip.called).to.be.false; + }); + }); + + + + +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/1bd4c232/ambari-web/test/views/main/service/info/config_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/service/info/config_test.js b/ambari-web/test/views/main/service/info/config_test.js index 4e369ea..fb66243 100644 --- a/ambari-web/test/views/main/service/info/config_test.js +++ b/ambari-web/test/views/main/service/info/config_test.js @@ -19,6 +19,7 @@ var App = require('app'); require('views/main/service/info/configs'); +var batchUtils = require('utils/batch_scheduled_requests'); describe('App.MainServiceInfoConfigsView', function () { @@ -26,7 +27,11 @@ describe('App.MainServiceInfoConfigsView', function () { beforeEach(function () { view = App.MainServiceInfoConfigsView.create({ - controller: Em.Object.create() + controller: Em.Object.create({ + loadStep: Em.K, + clearStep: Em.K, + content: Em.Object.create() + }) }); }); @@ -101,4 +106,96 @@ describe('App.MainServiceInfoConfigsView', function () { }); }); + describe("#didInsertElement()", function() { + var mock = { + isLoading: function () { + return { + done: function (callback) { + callback(); + } + } + } + }; + + beforeEach(function() { + sinon.stub(App.router, 'get').returns(mock); + sinon.stub(view.get('controller'), 'loadStep'); + sinon.stub(view, 'resetConfigTabSelection'); + view.didInsertElement(); + }); + afterEach(function() { + App.router.get.restore(); + view.get('controller').loadStep.restore(); + view.resetConfigTabSelection.restore(); + }); + + it("loadStep should be called", function() { + expect(view.get('controller').loadStep.calledOnce).to.be.true; + }); + + it("resetConfigTabSelection should be called", function() { + expect(view.resetConfigTabSelection.calledOnce).to.be.true; + }); + }); + + describe("#willDestroyElement()", function() { + + beforeEach(function() { + sinon.stub(view.get('controller'), 'clearStep'); + }); + afterEach(function() { + view.get('controller').clearStep.restore(); + }); + + it("resetConfigTabSelection should be called", function() { + view.willDestroyElement(); + expect(view.get('controller').clearStep.calledOnce).to.be.true; + }); + }); + + describe("#rollingRestartSlaveComponentName", function() { + + beforeEach(function() { + sinon.stub(batchUtils, 'getRollingRestartComponentName', function(input) { + return input; + }); + }); + afterEach(function() { + batchUtils.getRollingRestartComponentName.restore(); + }); + + it("should return service name", function() { + view.set('controller.content.serviceName', 'S1'); + view.propertyDidChange('rollingRestartSlaveComponentName'); + expect(view.get('rollingRestartSlaveComponentName')).to.equal('S1'); + }); + }); + + describe("#rollingRestartActionName", function() { + + beforeEach(function() { + sinon.stub(App.format, 'role', function(input) { + return input; + }); + }); + afterEach(function() { + App.format.role.restore(); + }); + + it("should return action name", function() { + view.reopen({ + rollingRestartSlaveComponentName: 'C1' + }); + view.propertyDidChange('rollingRestartActionName'); + expect(view.get('rollingRestartActionName')).to.equal(Em.I18n.t('rollingrestart.dialog.title').format('C1')); + }); + + it("should return empty", function() { + view.reopen({ + rollingRestartSlaveComponentName: null + }); + view.propertyDidChange('rollingRestartActionName'); + expect(view.get('rollingRestartActionName')).to.be.empty; + }); + }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/1bd4c232/ambari-web/test/views/main/service/info/menu_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/service/info/menu_test.js b/ambari-web/test/views/main/service/info/menu_test.js new file mode 100644 index 0000000..5caa5b0 --- /dev/null +++ b/ambari-web/test/views/main/service/info/menu_test.js @@ -0,0 +1,93 @@ +/** + * 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/service/info/menu'); + + +describe('App.MainServiceInfoMenuView', function () { + var view; + + beforeEach(function () { + view = App.MainServiceInfoMenuView.create({ + controller: Em.Object.create() + }); + }); + + describe("#content", function() { + + it("heatmapTab and configTab are false", function() { + view.setProperties({ + configTab: false, + heatmapTab: false + }); + view.propertyDidChange('content'); + expect(view.get('content').mapProperty('id')).to.eql(['summary-service-tab']); + }); + + it("heatmapTab - false, configTab - true", function() { + view.setProperties({ + configTab: true, + heatmapTab: false + }); + view.propertyDidChange('content'); + expect(view.get('content').mapProperty('id')).to.eql(['summary-service-tab', 'configs-service-tab']); + }); + + it("heatmapTab - true, configTab - false", function() { + view.setProperties({ + configTab: false, + heatmapTab: true + }); + view.propertyDidChange('content'); + expect(view.get('content').mapProperty('id')).to.eql(['summary-service-tab', 'heatmap-service-tab']); + }); + + it("heatmapTab - true, configTab - true", function() { + view.setProperties({ + configTab: true, + heatmapTab: true + }); + view.propertyDidChange('content'); + expect(view.get('content').mapProperty('id')).to.eql(['summary-service-tab', 'heatmap-service-tab', 'configs-service-tab']); + }); + }); + + describe("#activateView()", function() { + it("_childViews should be active", function() { + view.set('_childViews', [ + Em.Object.create({active: '', content: {routing: 'login'}}) + ]); + view.activateView(); + expect(view.get('_childViews')[0].get('active')).to.equal('active'); + }); + }); + + describe("#deactivateChildViews()", function() { + it("_childViews should be deactivated", function() { + view.set('_childViews', [ + Em.Object.create({active: 'active'}), + Em.Object.create({active: 'active'}) + ]); + view.deactivateChildViews(); + expect(view.get('_childViews')[0].get('active')).to.be.empty; + expect(view.get('_childViews')[1].get('active')).to.be.empty; + }); + }); +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/1bd4c232/ambari-web/test/views/main/service/info/summary_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/service/info/summary_test.js b/ambari-web/test/views/main/service/info/summary_test.js index 5e24490..6a84bb6 100644 --- a/ambari-web/test/views/main/service/info/summary_test.js +++ b/ambari-web/test/views/main/service/info/summary_test.js @@ -31,7 +31,8 @@ describe('App.MainServiceInfoSummaryView', function() { serviceName: 'HDFS', hostComponents: [] }), - getActiveWidgetLayout: Em.K + getActiveWidgetLayout: Em.K, + loadWidgetLayouts: Em.K }), alertsController: Em.Object.create(), service: Em.Object.create() @@ -196,270 +197,17 @@ describe('App.MainServiceInfoSummaryView', function() { }); - describe('#didInsertElement', function () { - - var cases = [ - { - serviceName: 'STORM', - isStormMetricsSupported: false, - isConstructGraphObjectsCalled: false, - title: 'Storm, metrics not supported' - }, - { - serviceName: 'STORM', - isStormMetricsSupported: true, - isConstructGraphObjectsCalled: true, - title: 'Storm, metrics supported' - }, - { - serviceName: 'HDFS', - isConstructGraphObjectsCalled: true, - title: 'not Storm' - } - ]; - - beforeEach(function () { - sinon.stub(view, 'constructGraphObjects', Em.K); - this.mock = sinon.stub(App, 'get'); - }); - - afterEach(function () { - view.constructGraphObjects.restore(); - this.mock.restore(); - }); - - cases.forEach(function (item) { - it(item.title, function () { - view.set('controller.content.serviceName', item.serviceName); - this.mock.withArgs('isStormMetricsSupported').returns(item.isStormMetricsSupported); - view.didInsertElement(); - expect(view.constructGraphObjects.calledOnce).to.equal(item.isConstructGraphObjectsCalled); - }); - }); - - }); - - describe.skip('#setTimeRange', function () { - - var cases = [ - { - currentTimeRangeIndex: 0, - isServiceMetricLoaded: false, - graphIds: [], - title: 'no event passed' - }, - { - event: {}, - currentTimeRangeIndex: 0, - isServiceMetricLoaded: false, - graphIds: [], - title: 'no event context passed' - }, - { - event: { - context: { - index: 1 - } - }, - currentTimeRangeIndex: 1, - isServiceMetricLoaded: false, - graphIds: [], - title: 'no service name set' - }, - { - event: { - context: { - index: 2 - } - }, - serviceName: 'HDFS', - currentTimeRangeIndex: 2, - isServiceMetricLoaded: true, - graphIds: [ - [ - 'service-metrics-hdfs-space-utilization', 'service-metrics-hdfs-file-operations', - 'service-metrics-hdfs-block-status', 'service-metrics-hdfs-io', 'service-metrics-hdfs-rpc' - ], - [ - 'service-metrics-hdfs-gc', 'service-metrics-hdfs-jvm-heap', 'service-metrics-hdfs-jvm-threads' - ] - ] - }, - { - event: { - context: { - index: 3 - } - }, - serviceName: 'YARN', - currentTimeRangeIndex: 3, - isServiceMetricLoaded: true, - graphIds: [ - [ - 'service-metrics-yarn-queue-allocated', 'service-metrics-yarn-queue-memory-resource', - 'service-metrics-yarn-queue-allocated-container', 'service-metrics-yarn-node-manager-statuses', - 'service-metrics-yarn-apps-current-states' - ], - [ - 'service-metrics-yarn-apps-finished-states', 'service-metrics-yarn-rpc', 'service-metrics-yarn-gc', - 'service-metrics-yarn-jvm-threads', 'service-metrics-yarn-jvm-heap' - ] - ] - }, - { - event: { - context: { - index: 4 - } - }, - serviceName: 'HBASE', - currentTimeRangeIndex: 4, - isServiceMetricLoaded: true, - graphIds: [ - [ - 'service-metrics-hbase-cluster-requests', 'service-metrics-hbase-regionserver-rw-requests', - 'service-metrics-hbase-regionserver-regions', 'service-metrics-hbase-regionserver-queuesize', - 'service-metrics-hbase-hlog-split-time' - ], - [ - 'service-metrics-hbase-hlog-split-size' - ] - ] - }, - { - event: { - context: { - index: 5 - } - }, - serviceName: 'AMBARI_METRICS', - currentTimeRangeIndex: 5, - isServiceMetricLoaded: true, - graphIds: [ - [ - 'service-metrics-ambari-metrics-master-average-load', - 'service-metrics-ambari-metrics-region-server-store-files', - 'service-metrics-ambari-metrics-region-server-regions', - 'service-metrics-ambari-metrics-region-server-requests', - 'service-metrics-ambari-metrics-region-server-block-cache-hit-percent' - ], - [ - 'service-metrics-ambari-metrics-region-server-compaction-queue-size' - ] - ] - }, - { - event: { - context: { - index: 6 - } - }, - serviceName: 'FLUME', - currentTimeRangeIndex: 6, - isServiceMetricLoaded: true, - graphIds: [ - [ - 'service-metrics-flume-channel-size-mma', 'service-metrics-flume-channel-size-sum', - 'service-metrics-flume-incoming_mma', 'service-metrics-flume-incoming_sum', - 'service-metrics-flume-outgoing_mma' - ], - [ - 'service-metrics-flume-outgoing_sum' - ] - ] - }, - { - event: { - context: { - index: 7 - } - }, - serviceName: 'STORM', - currentTimeRangeIndex: 7, - isServiceMetricLoaded: true, - graphIds: [ - [ - 'service-metrics-storm-supervisor-allocated', 'service-metrics-storm-executors', - 'service-metrics-storm-topologies', 'service-metrics-storm-tasks' - ] - ] - }, - { - event: { - context: { - index: 8 - } - }, - serviceName: 'KAFKA', - chunkSize: 4, - currentTimeRangeIndex: 8, - isServiceMetricLoaded: true, - graphIds: [ - [ - 'service-metrics-kafka-broker-topic-metrics', 'service-metrics-kafka-controller-metrics', - 'service-metrics-kafka-controler-status-metrics', 'service-metrics-kafka-replica-manager-metrics' - ], - [ - 'service-metrics-kafka-log-metrics', 'service-metrics-kafka-replica-fetcher-metrics' - ] - ] - } - ]; - - beforeEach(function () { - sinon.stub(view, 'postUserPref', Em.K); - view.setProperties({ - chunkSize: 5, - currentTimeRangeIndex: 0, - isServiceMetricLoaded: false, - serviceMetricGraphs: [] - }); - }); - - afterEach(function () { - view.postUserPref.restore(); - }); - - cases.forEach(function (item) { - it(item.serviceName || item.title, function () { - view.set('chunkSize', Em.isNone(item.chunkSize) ? 5 : item.chunkSize); - view.set('service.serviceName', item.serviceName); - view.setTimeRange(item.event); - var graphIndices = [], - graphIds = view.get('serviceMetricGraphs').map(function (graphs) { - return graphs.map(function (graph) { - var graphView = graph.create(); - graphIndices.push(graphView.get('currentTimeIndex')); - return graphView.get('id'); - }); - }); - expect(view.get('currentTimeRangeIndex')).to.equal(item.currentTimeRangeIndex); - expect(view.get('isServiceMetricLoaded')).to.equal(item.isServiceMetricLoaded); - if (item.event && item.event.context && item.serviceName) { - expect(graphIndices.uniq()).to.eql([item.currentTimeRangeIndex]); - } - expect(graphIds).to.eql(item.graphIds); - }); - }); - - }); - describe("#restartAllStaleConfigComponents", function () { describe('trigger restartAllServiceHostComponents', function () { beforeEach(function () { - view = App.MainServiceInfoSummaryView.create({ - controller: Em.Object.create({ - content: { - serviceName: "HDFS" - }, - getActiveWidgetLayout: Em.K - }), - service: Em.Object.create({ - displayName: 'HDFS' - }) - }); + view.set('controller.content', Em.Object.create({ + serviceName: "HDFS" + })); + view.set('service', Em.Object.create({ + displayName: 'HDFS' + })); sinon.stub(batchUtils, "restartAllServiceHostComponents", Em.K); }); @@ -479,25 +227,20 @@ describe('App.MainServiceInfoSummaryView', function() { var mainServiceItemController; beforeEach(function () { - view = App.MainServiceInfoSummaryView.create({ - controller: Em.Object.create({ - content: { - serviceName: "HDFS", - hostComponents: [{ - componentName: 'NAMENODE', - workStatus: 'STARTED' - }], - restartRequiredHostsAndComponents: { - "host1": ['NameNode'], - "host2": ['DataNode', 'ZooKeeper'] - } - }, - getActiveWidgetLayout: Em.K - }), - service: Em.Object.create({ - displayName: 'HDFS' - }) - }); + view.set('controller.content', Em.Object.create({ + serviceName: "HDFS", + hostComponents: [{ + componentName: 'NAMENODE', + workStatus: 'STARTED' + }], + restartRequiredHostsAndComponents: { + "host1": ['NameNode'], + "host2": ['DataNode', 'ZooKeeper'] + } + })); + view.set('service', Em.Object.create({ + displayName: 'HDFS' + })); mainServiceItemController = App.MainServiceItemController.create({}); sinon.stub(mainServiceItemController, 'checkNnLastCheckpointTime', function() { return true; @@ -580,4 +323,555 @@ describe('App.MainServiceInfoSummaryView', function() { }); }); + describe("#clientsHostText", function() { + + it("no installed clients", function() { + view.set('controller.content.installedClients', []); + view.propertyDidChange('clientsHostText'); + expect(view.get('clientsHostText')).to.be.empty; + }); + + it("has many clients", function() { + view.set('controller.content.installedClients', [1]); + view.reopen({ + hasManyClients: true + }); + view.propertyDidChange('clientsHostText'); + expect(view.get('clientsHostText')).to.be.equal(Em.I18n.t('services.service.summary.viewHosts')); + }); + + it("otherwise", function() { + view.set('controller.content.installedClients', [1]); + view.reopen({ + hasManyClients: false + }); + view.propertyDidChange('clientsHostText'); + expect(view.get('clientsHostText')).to.be.equal(Em.I18n.t('services.service.summary.viewHost')); + }); + }); + + describe("#historyServerUI", function() { + + it("singleNodeInstall is true", function() { + App.set('singleNodeInstall', true); + App.set('singleNodeAlias', 'alias'); + view.propertyDidChange('historyServerUI'); + expect(view.get('historyServerUI')).to.equal("http://alias:19888"); + }); + + it("singleNodeInstall is false", function () { + App.set('singleNodeInstall', false); + view.set('controller.content', Em.Object.create({ + hostComponents: [ + Em.Object.create({ + isMaster: true, + host: Em.Object.create({ + publicHostName: 'host1' + }) + }) + ] + })); + view.propertyDidChange('historyServerUI'); + expect(view.get('historyServerUI')).to.equal("http://host1:19888"); + }); + }); + + describe("#serversHost", function() { + + it("should return empty object", function() { + view.set('controller.content', Em.Object.create({ + id: 'S1', + hostComponents: [] + })); + view.propertyDidChange('serversHost'); + expect(view.get('serversHost')).to.be.empty; + }); + + it("should return server object", function() { + view.set('controller.content', Em.Object.create({ + id: 'ZOOKEEPER', + hostComponents: [ + Em.Object.create({ + isMaster: true + }) + ] + })); + view.propertyDidChange('serversHost'); + expect(view.get('serversHost')).to.eql(Em.Object.create({ + isMaster: true + })); + }); + }); + + describe("#updateComponentList()", function() { + + it("add components to empty source", function() { + var source = [], + data = [{id: 1}]; + view.updateComponentList(source, data); + expect(source.mapProperty('id')).to.eql([1]); + }); + + it("add components to exist source", function() { + var source = [{id: 1}], + data = [{id: 1}, {id: 2}]; + view.updateComponentList(source, data); + expect(source.mapProperty('id')).to.eql([1, 2]); + }); + + it("remove components from exist source", function() { + var source = [{id: 1}, {id: 2}], + data = [{id: 1}]; + view.updateComponentList(source, data); + expect(source.mapProperty('id')).to.eql([1]); + }); + }); + + describe("#componentNameView", function () { + var componentNameView; + + beforeEach(function () { + componentNameView = view.get('componentNameView').create(); + }); + + describe("#displayName", function () { + + it("component is MYSQL_SERVER", function () { + componentNameView.set('comp', Em.Object.create({ + componentName: 'MYSQL_SERVER' + })); + componentNameView.propertyDidChange('displayName'); + expect(componentNameView.get('displayName')).to.equal(Em.I18n.t('services.hive.databaseComponent')); + }); + + it("any component", function () { + componentNameView.set('comp', Em.Object.create({ + componentName: 'C1', + displayName: 'c1' + })); + componentNameView.propertyDidChange('displayName'); + expect(componentNameView.get('displayName')).to.equal('c1'); + }); + }); + }); + + + describe("#getServiceModel()", function() { + + beforeEach(function() { + sinon.stub(App.Service, 'find').returns({serviceName: 'S1'}); + sinon.stub(App.HDFSService, 'find').returns([{serviceName: 'HDFS'}]); + }); + afterEach(function() { + App.Service.find.restore(); + App.HDFSService.find.restore(); + }); + + it("HDFS service", function() { + expect(view.getServiceModel('HDFS')).to.eql({serviceName: 'HDFS'}); + }); + + it("Simple model service", function() { + expect(view.getServiceModel('S1')).to.eql({serviceName: 'S1'}); + }); + }); + + describe("#updateComponentInformation()", function () { + it("should count hosts and components", function () { + view.set('controller.content.restartRequiredHostsAndComponents', { + 'host1': ['c1', 'c2'] + }); + view.updateComponentInformation(); + expect(view.get('componentsCount')).to.equal(2); + expect(view.get('hostsCount')).to.equal(1); + }); + }); + + describe("#rollingRestartSlaveComponentName ", function() { + + beforeEach(function() { + sinon.stub(batchUtils, 'getRollingRestartComponentName').returns('C1'); + }); + afterEach(function() { + batchUtils.getRollingRestartComponentName.restore(); + }); + + it("should returns component name", function() { + view.set('serviceName', 'S1'); + view.propertyDidChange('rollingRestartSlaveComponentName'); + expect(view.get('rollingRestartSlaveComponentName')).to.equal('C1'); + }); + }); + + describe("#rollingRestartActionName ", function() { + + beforeEach(function() { + sinon.stub(App.format, 'role').returns('C1'); + }); + afterEach(function() { + App.format.role.restore(); + }); + + it("rollingRestartSlaveComponentName is set", function() { + view.reopen({ + rollingRestartSlaveComponentName: 'C1' + }); + view.propertyDidChange('rollingRestartActionName'); + expect(view.get('rollingRestartActionName')).to.equal(Em.I18n.t('rollingrestart.dialog.title').format('C1')); + }); + + it("rollingRestartSlaveComponentName is null", function() { + view.reopen({ + rollingRestartSlaveComponentName: null + }); + view.propertyDidChange('rollingRestartActionName'); + expect(view.get('rollingRestartActionName')).to.be.null; + }); + }); + + describe("#rollingRestartStaleConfigSlaveComponents() ", function() { + + beforeEach(function() { + sinon.stub(batchUtils, 'launchHostComponentRollingRestart'); + }); + afterEach(function() { + batchUtils.launchHostComponentRollingRestart.restore(); + }); + + it("launchHostComponentRollingRestart should be called", function() { + view.get('service').setProperties({ + displayName: 's1', + passiveState: 'ON' + }); + view.rollingRestartStaleConfigSlaveComponents({context: 'C1'}); + expect(batchUtils.launchHostComponentRollingRestart.calledWith( + 'C1', 's1', true, true + )).to.be.true; + }); + }); + + describe("#constructGraphObjects()", function() { + var mock = Em.Object.create({ + isServiceWithWidgets: false + }); + + beforeEach(function() { + sinon.stub(App.StackService, 'find').returns(mock); + sinon.stub(view, 'getUserPref').returns({ + complete: function(callback){callback();} + }) + }); + afterEach(function() { + App.StackService.find.restore(); + view.getUserPref.restore(); + }); + + it("metrics not loaded", function() { + mock.set('isServiceWithWidgets', false); + view.constructGraphObjects(null); + expect(view.get('isServiceMetricLoaded')).to.be.false; + expect(view.getUserPref.called).to.be.false; + }); + + it("metrics loaded", function() { + App.ChartServiceMetricsG1 = Em.Object.extend(); + mock.set('isServiceWithWidgets', true); + view.constructGraphObjects(['G1']); + expect(view.get('isServiceMetricLoaded')).to.be.true; + expect(view.getUserPref.calledOnce).to.be.true; + expect(view.get('serviceMetricGraphs')).to.not.be.empty; + }); + }); + + describe("#getUserPrefSuccessCallback()", function() { + + it("currentTimeRangeIndex should be set", function() { + view.getUserPrefSuccessCallback(1); + expect(view.get('currentTimeRangeIndex')).to.equal(1); + }); + }); + + describe("#getUserPrefErrorCallback()", function() { + + beforeEach(function() { + sinon.stub(view, 'postUserPref'); + }); + afterEach(function() { + view.postUserPref.restore(); + }); + + it("request.status = 404", function() { + view.getUserPrefErrorCallback({status: 404}); + expect(view.get('currentTimeRangeIndex')).to.equal(0); + expect(view.postUserPref.calledOnce).to.be.true; + }); + + it("request.status = 403", function() { + view.getUserPrefErrorCallback({status: 403}); + expect(view.postUserPref.called).to.be.false; + }); + }); + + describe("#widgetActions", function() { + + beforeEach(function() { + this.mock = sinon.stub(App, 'isAuthorized'); + view.setProperties({ + staticWidgetLayoutActions: [{id: 1}], + staticAdminPrivelegeWidgetActions: [{id: 2}], + staticGeneralWidgetActions: [{id: 3}] + }); + }); + afterEach(function() { + this.mock.restore(); + }); + + it("not authorized", function() { + this.mock.returns(false); + view.propertyDidChange('widgetActions'); + expect(view.get('widgetActions').mapProperty('id')).to.eql([3]); + }); + + it("is authorized", function() { + this.mock.returns(true); + App.supports.customizedWidgetLayout = true; + view.propertyDidChange('widgetActions'); + expect(view.get('widgetActions').mapProperty('id')).to.eql([1, 2, 3]); + }); + }); + + describe("#doWidgetAction()", function() { + + beforeEach(function() { + view.set('controller.action1', Em.K); + sinon.stub(view.get('controller'), 'action1'); + }); + afterEach(function() { + view.get('controller').action1.restore(); + }); + + it("action exist", function() { + view.doWidgetAction({context: 'action1'}); + expect(view.get('controller').action1.calledOnce).to.be.true; + }); + }); + + describe("#setTimeRange", function() { + + it("range = 0", function() { + var widget = Em.Object.create({ + widgetType: 'GRAPH', + properties: { + time_range: '0' + } + }); + view.set('controller.widgets', [widget]); + view.setTimeRange({context: {value: '0'}}); + expect(widget.get('properties')['time_range']).to.equal('0') + }); + + it("range = 1", function() { + var widget = Em.Object.create({ + widgetType: 'GRAPH', + properties: { + time_range: 0 + } + }); + view.set('controller.widgets', [widget]); + view.setTimeRange({context: {value: '1'}}); + expect(widget.get('properties')['time_range']).to.equal('1') + }); + }); + + describe("#makeSortable()", function() { + var mock = { + on: function(arg1, arg2, callback) { + callback(); + }, + off: Em.K, + sortable: function() { + return { + disableSelection: Em.K + } + } + }; + + beforeEach(function() { + sinon.stub(window, '$').returns(mock); + sinon.spy(mock, 'on'); + sinon.spy(mock, 'off'); + sinon.spy(mock, 'sortable'); + view.makeSortable(); + }); + afterEach(function() { + window.$.restore(); + mock.on.restore(); + mock.off.restore(); + mock.sortable.restore(); + }); + + it("on() should be called", function() { + expect(mock.on.calledWith('DOMNodeInserted', '#widget_layout')).to.be.true; + }); + + it("sortable() should be called", function() { + expect(mock.sortable.calledOnce).to.be.true; + }); + + it("off() should be called", function() { + expect(mock.off.calledWith('DOMNodeInserted', '#widget_layout')).to.be.true; + }); + }); + + describe('#didInsertElement', function () { + + beforeEach(function () { + sinon.stub(view, 'constructGraphObjects', Em.K); + this.mock = sinon.stub(App, 'get'); + sinon.stub(view, 'getServiceModel'); + sinon.stub(view.get('controller'), 'getActiveWidgetLayout'); + sinon.stub(view.get('controller'), 'loadWidgetLayouts'); + sinon.stub(view, 'adjustSummaryHeight'); + sinon.stub(view, 'makeSortable'); + sinon.stub(view, 'addWidgetTooltip'); + + }); + + afterEach(function () { + view.constructGraphObjects.restore(); + this.mock.restore(); + view.getServiceModel.restore(); + view.get('controller').getActiveWidgetLayout.restore(); + view.get('controller').loadWidgetLayouts.restore(); + view.adjustSummaryHeight.restore(); + view.makeSortable.restore(); + view.addWidgetTooltip.restore(); + }); + + it("getServiceModel should be called", function() { + view.didInsertElement(); + expect(view.getServiceModel.calledOnce).to.be.true; + }); + it("adjustSummaryHeight should be called", function() { + view.didInsertElement(); + expect(view.adjustSummaryHeight.calledOnce).to.be.true; + }); + it("addWidgetTooltip should be called", function() { + view.didInsertElement(); + expect(view.addWidgetTooltip.calledOnce).to.be.true; + }); + it("makeSortable should be called", function() { + view.didInsertElement(); + expect(view.makeSortable.calledOnce).to.be.true; + }); + it("getActiveWidgetLayout should be called", function() { + view.didInsertElement(); + expect(view.get('controller').getActiveWidgetLayout.calledOnce).to.be.true; + }); + + describe("serviceName is null, metrics not supported, widgets not supported", function() { + beforeEach(function () { + view.set('controller.content.serviceName', null); + this.mock.returns(false); + view.didInsertElement(); + }); + + it("loadWidgetLayouts should not be called", function() { + expect(view.get('controller').loadWidgetLayouts.called).to.be.false; + }); + it("constructGraphObjects should not be called", function() { + expect(view.constructGraphObjects.called).to.be.false; + }); + }); + + describe("serviceName is set, metrics is supported, widgets is supported", function() { + beforeEach(function () { + view.set('controller.content.serviceName', 'S1'); + this.mock.returns(true); + view.didInsertElement(); + }); + + it("loadWidgetLayouts should be called", function() { + expect(view.get('controller').loadWidgetLayouts.calledOnce).to.be.true; + }); + it("constructGraphObjects should be called", function() { + expect(view.constructGraphObjects.calledOnce).to.be.true; + }); + }); + }); + + describe("#addWidgetTooltip()", function() { + var mock = { + hoverIntent: Em.K + }; + + beforeEach(function() { + sinon.stub(Em.run, 'later', function(arg1, callback) { + callback(); + }); + sinon.stub(App, 'tooltip'); + sinon.stub(window, '$').returns(mock); + sinon.spy(mock, 'hoverIntent'); + view.addWidgetTooltip(); + }); + afterEach(function() { + Em.run.later.restore(); + App.tooltip.restore(); + window.$.restore(); + mock.hoverIntent.restore(); + }); + + it("Em.run.later should be called", function() { + expect(Em.run.later.calledOnce).to.be.true; + }); + it("App.tooltip should be called", function() { + expect(App.tooltip.calledOnce).to.be.true; + }); + it("hoverIntent should be called", function() { + expect(mock.hoverIntent.calledOnce).to.be.true; + }); + }); + + describe("#adjustSummaryHeight()", function() { + var jQueryMock = { + find: Em.K, + attr: Em.K + }; + + beforeEach(function() { + sinon.stub(window, '$').returns(jQueryMock); + this.mockFind = sinon.stub(jQueryMock, 'find'); + sinon.spy(jQueryMock, 'attr'); + this.mockGetElementById = sinon.stub(document, 'getElementById'); + }); + afterEach(function() { + this.mockGetElementById.restore(); + window.$.restore(); + this.mockFind.restore(); + jQueryMock.attr.restore(); + }); + + it("summary-info not in DOM", function() { + this.mockGetElementById.returns(null); + view.adjustSummaryHeight(); + expect(jQueryMock.find.called).to.be.false; + }); + + it("summary-info has no rows", function() { + this.mockGetElementById.returns({}); + this.mockFind.returns(null); + view.adjustSummaryHeight(); + expect(jQueryMock.find.calledOnce).to.be.true; + expect(jQueryMock.attr.called).to.be.false; + }); + + it("summary-info has rows", function() { + this.mockGetElementById.returns({ + clientHeight: 10 + }); + this.mockFind.returns([{}]); + view.adjustSummaryHeight(); + expect(jQueryMock.attr.calledWith('style', "height:20px;")).to.be.true; + }); + }); }); \ No newline at end of file