You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2019/02/07 17:00:24 UTC

[ambari] branch trunk updated: AMBARI-25148 Cover views of Widget Create wizard with unit tests

This is an automated email from the ASF dual-hosted git repository.

atkach pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 1c9d0d3  AMBARI-25148 Cover views of Widget Create wizard with unit tests
1c9d0d3 is described below

commit 1c9d0d34fe2835551cd07b71ee7921a3612a7ece
Author: Andrii Tkach <at...@apache.org>
AuthorDate: Thu Feb 7 13:09:25 2019 +0200

    AMBARI-25148 Cover views of Widget Create wizard with unit tests
---
 .../main/service/widgets/create/expression_view.js | 105 +++---
 .../service/widgets/create/expression_view_test.js | 383 +++++++++++++++++++++
 .../main/service/widgets/create/step2_view_test.js |  56 +++
 3 files changed, 499 insertions(+), 45 deletions(-)

diff --git a/ambari-web/app/views/main/service/widgets/create/expression_view.js b/ambari-web/app/views/main/service/widgets/create/expression_view.js
index 9260551..1d4611d 100644
--- a/ambari-web/app/views/main/service/widgets/create/expression_view.js
+++ b/ambari-web/app/views/main/service/widgets/create/expression_view.js
@@ -220,7 +220,9 @@ App.AddMetricExpressionView = Em.View.extend({
       placeholder_text: Em.I18n.t('dashboard.widgets.wizard.step2.selectMetric'),
       no_results_text: Em.I18n.t('widget.create.wizard.step2.noMetricFound'),
       onChangeCallback: function (event, obj) {
-        var filteredComponentMetrics = self.get('controller.filteredMetrics').filterProperty('component_name', self.get('currentSelectedComponent.componentName')).filterProperty('level', self.get('currentSelectedComponent.level'));
+        var filteredComponentMetrics = self.get('controller.filteredMetrics')
+        .filterProperty('component_name', self.get('currentSelectedComponent.componentName'))
+        .filterProperty('level', self.get('currentSelectedComponent.level'));
         var filteredMetric = filteredComponentMetrics.findProperty('name', obj.selected);
         var selectedMetric = Em.Object.create({
           name: obj.selected,
@@ -236,7 +238,7 @@ App.AddMetricExpressionView = Em.View.extend({
           selectedMetric.tag = self.get('currentSelectedComponent.tag');
         }
         self.set('currentSelectedComponent.selectedMetric', selectedMetric);
-        if (self.get('currentSelectedComponent.selectedAggregation') == Em.I18n.t('dashboard.widgets.wizard.step2.aggregateFunction.scanOps')) {
+        if (self.get('currentSelectedComponent.selectedAggregation') === Em.I18n.t('dashboard.widgets.wizard.step2.aggregateFunction.scanOps')) {
           var defaultAggregator = self.get('parentView.AGGREGATE_FUNCTIONS')[0];
           self.set('currentSelectedComponent.selectedAggregation', defaultAggregator);
         }
@@ -312,52 +314,11 @@ App.AddMetricExpressionView = Em.View.extend({
    */
   componentMap: function () {
     var hasNameNodeFederation = App.get('hasNameNodeFederation');
-    var servicesMap = {};
+    var servicesMap = this.getServicesMap();
     var result = [];
-    var nameServiceGroups = [];
-    var masterNames = App.StackServiceComponent.find().filterProperty('isMaster').mapProperty('componentName');
+    var nameServiceGroups = this.getNameServiceGroups();
     var parentView = this.get('parentView');
     var expressionId = "_" + parentView.get('expression.id');
-    if (this.get('controller.filteredMetrics')) {
-      this.get('controller.filteredMetrics').forEach(function (metric) {
-        // ignore NameNode component level metrics on federated cluster
-        if (hasNameNodeFederation && metric.component_name === 'NAMENODE' && metric.level === 'COMPONENT') return false;
-
-        var service = servicesMap[metric.service_name];
-        if (!service) {
-          service = {
-              count: 0,
-              components: {}
-          };
-          servicesMap[metric.service_name] = service;
-        }
-
-        var componentId = masterNames.contains(metric.component_name) ? metric.component_name + '_' + metric.level : metric.component_name;
-        service.count++;
-        if (service.components[componentId]) {
-          service.components[componentId].count++;
-          service.components[componentId].metrics.push(metric.name);
-        } else {
-          service.components[componentId] = {
-            component_name: metric.component_name,
-            level: metric.level,
-            count: 1,
-            hostComponentCriteria: metric.host_component_criteria,
-            metrics: [metric.name]
-          };
-        }
-      }, this);
-    }
-
-    if (hasNameNodeFederation) {
-      App.HDFSService.find().objectAt(0).get('masterComponentGroups').forEach(function(group) {
-        nameServiceGroups.push({
-          tag: group.name,
-          displayName: Em.I18n.t('dashboard.widgets.wizard.step2.nameSpaceDropDownItem').format(group.name),
-          component: null
-        });
-      });
-    }
 
     for (var serviceName in servicesMap) {
       var components = [];
@@ -392,6 +353,60 @@ App.AddMetricExpressionView = Em.View.extend({
 
     return this.putContextServiceOnTop(result);
   }.property('controller.filteredMetrics', 'App.router.clusterController.isComponentsStateLoaded'),
+  
+  getNameServiceGroups: function() {
+    const hasNameNodeFederation = App.get('hasNameNodeFederation');
+    const nameServiceGroups = [];
+  
+    if (hasNameNodeFederation) {
+      App.HDFSService.find('HDFS').get('masterComponentGroups').forEach(function(group) {
+        nameServiceGroups.push({
+          tag: group.name,
+          displayName: Em.I18n.t('dashboard.widgets.wizard.step2.nameSpaceDropDownItem').format(group.name),
+          component: null
+        });
+      });
+    }
+    return nameServiceGroups;
+  },
+  
+  getServicesMap: function() {
+    const servicesMap = {};
+    const hasNameNodeFederation = App.get('hasNameNodeFederation');
+    const masterNames = App.StackServiceComponent.find().filterProperty('isMaster').mapProperty('componentName');
+  
+    if (this.get('controller.filteredMetrics')) {
+      this.get('controller.filteredMetrics').forEach(function (metric) {
+        // ignore NameNode component level metrics on federated cluster
+        if (hasNameNodeFederation && metric.component_name === 'NAMENODE' && metric.level === 'COMPONENT') return false;
+      
+        var service = servicesMap[metric.service_name];
+        if (!service) {
+          service = {
+            count: 0,
+            components: {}
+          };
+          servicesMap[metric.service_name] = service;
+        }
+      
+        var componentId = masterNames.contains(metric.component_name) ? metric.component_name + '_' + metric.level : metric.component_name;
+        service.count++;
+        if (service.components[componentId]) {
+          service.components[componentId].count++;
+          service.components[componentId].metrics.push(metric.name);
+        } else {
+          service.components[componentId] = {
+            component_name: metric.component_name,
+            level: metric.level,
+            count: 1,
+            hostComponentCriteria: metric.host_component_criteria,
+            metrics: [metric.name]
+          };
+        }
+      }, this);
+    }
+    return servicesMap;
+  },
 
   createComponentItem: function (service, serviceName, componentId, expressionId, tag) {
     var stackComponent = App.StackServiceComponent.find(service.components[componentId].component_name);
diff --git a/ambari-web/test/views/main/service/widgets/create/expression_view_test.js b/ambari-web/test/views/main/service/widgets/create/expression_view_test.js
index f0bc647..f10c132 100644
--- a/ambari-web/test/views/main/service/widgets/create/expression_view_test.js
+++ b/ambari-web/test/views/main/service/widgets/create/expression_view_test.js
@@ -553,3 +553,386 @@ describe("App.InputCursorTextfieldView", function() {
   });
 
 });
+
+describe('#App.AddMetricExpressionView', function() {
+  var AddMetricExpressionView;
+  
+  beforeEach(function() {
+    AddMetricExpressionView = App.AddMetricExpressionView.create({
+      currentSelectedComponent: Em.Object.create(),
+      controller: Em.Object.create(),
+      parentView: Em.Object.create({
+        AGGREGATE_FUNCTIONS: ['fun1']
+      }),
+      elementId: '1'
+    });
+  });
+  
+  describe('#metricsSelectionObj.onChangeCallback', function() {
+  
+    beforeEach(function() {
+      AddMetricExpressionView.set('controller.filteredMetrics',  [{
+        component_name: 'C1',
+        level: 'l1',
+        name: 'metric1',
+        widget_id: 1
+      }]);
+      AddMetricExpressionView.set('currentSelectedComponent', Em.Object.create({
+        componentName: 'C1',
+        serviceName: 'S1',
+        level: 'l1',
+        hostComponentCriteria: 'criteria1',
+        tag: 'tag1',
+        selectedAggregation: Em.I18n.t('dashboard.widgets.wizard.step2.aggregateFunction.scanOps')
+      }));
+      var metricsSelectionObj = AddMetricExpressionView.get('metricsSelectionObj');
+      metricsSelectionObj.onChangeCallback({}, {selected: 'metric1'});
+    });
+    
+    it('selectedMetric should be set', function() {
+      expect(AddMetricExpressionView.get('currentSelectedComponent.selectedMetric')).to.be.eql(Em.Object.create({
+        name: 'metric1',
+        hostComponentCriteria: 'criteria1',
+        tag: 'tag1',
+        componentName: 'C1',
+        serviceName: 'S1',
+        metricPath: 1,
+        isMetric: true
+      }));
+    });
+  
+    it('selectedAggregation should be set', function() {
+      expect(AddMetricExpressionView.get('currentSelectedComponent.selectedAggregation')).to.be.equal('fun1');
+    });
+  });
+  
+  describe('#aggregateFnSelectionObj.onChangeCallback', function() {
+
+    it('selectedAggregation should be set', function() {
+      AddMetricExpressionView.set('currentSelectedComponent', Em.Object.create({}));
+      var aggregateFnSelectionObj = AddMetricExpressionView.get('aggregateFnSelectionObj');
+      aggregateFnSelectionObj.onChangeCallback({}, {selected: 'name1'});
+      expect(AddMetricExpressionView.get('currentSelectedComponent.selectedAggregation')).to.be.equal('name1');
+    });
+  });
+  
+  describe('#selectComponents', function() {
+    var event = {
+      context: {},
+      stopPropagation: sinon.spy()
+    };
+    beforeEach(function() {
+      AddMetricExpressionView.selectComponents(event);
+    });
+
+    it('currentSelectedComponent should be set', function() {
+      expect(AddMetricExpressionView.get('currentSelectedComponent')).to.be.an.object;
+    });
+  
+    it('stopPropagation should be called', function() {
+      expect(event.stopPropagation.called).to.be.true;
+    });
+  });
+  
+  describe('#addMetric', function() {
+    var event = {
+      context: Em.Object.create({
+        selectedMetric: {
+          metricPath: 'path',
+          name: 'metric1'
+        },
+        selectedAggregation: 'fun1',
+        isAddEnabled: true,
+        showAggregateSelect: true
+      })
+    };
+    var data = [];
+    beforeEach(function() {
+      sinon.stub(AddMetricExpressionView, 'cancel');
+      AddMetricExpressionView.set('parentView.expression', {
+        data: data
+      });
+      AddMetricExpressionView.addMetric(event);
+    });
+    afterEach(function() {
+      AddMetricExpressionView.cancel.restore();
+    });
+    
+    it('metric should be added', function() {
+      expect(data[0]).to.be.eql(Em.Object.create({
+        id: 1,
+        metricPath: 'path._fun1',
+        name: 'metric1._fun1'
+      }));
+    });
+  
+    it('cancel should be called', function() {
+      expect(AddMetricExpressionView.cancel.called).to.be.true;
+    });
+  });
+  
+  describe('#cancel', function() {
+    
+    it('selectedAggregation should be set', function() {
+      AddMetricExpressionView.cancel();
+      expect(AddMetricExpressionView.get('currentSelectedComponent.selectedAggregation')).to.be.equal(
+        Em.I18n.t('dashboard.widgets.wizard.step2.aggregateFunction.scanOps')
+      );
+    });
+  
+    it('selectedMetric should be null', function() {
+      AddMetricExpressionView.cancel();
+      expect(AddMetricExpressionView.get('currentSelectedComponent.selectedMetric')).to.be.null;
+    });
+  });
+  
+  describe('#getNameServiceGroups', function() {
+    beforeEach(function() {
+      sinon.stub(App, 'get').returns(true);
+      sinon.stub(App.HDFSService, 'find').returns(Em.Object.create({
+        masterComponentGroups: [
+          {
+            name: 'g1'
+          }
+        ]
+      }));
+    });
+    afterEach(function() {
+      App.get.restore();
+      App.HDFSService.find.restore();
+    });
+    
+    it('should return service groups', function() {
+      expect(AddMetricExpressionView.getNameServiceGroups()).to.be.eql([{
+        tag: 'g1',
+        displayName: Em.I18n.t('dashboard.widgets.wizard.step2.nameSpaceDropDownItem').format('g1'),
+        component: null
+      }]);
+    });
+  });
+  
+  describe('#getServicesMap', function() {
+    beforeEach(function() {
+      sinon.stub(App, 'get').returns(true);
+      sinon.stub(App.StackServiceComponent, 'find').returns([{
+        isMaster: true,
+        componentName: 'C2'
+      }]);
+    });
+    afterEach(function() {
+      App.get.restore();
+      App.StackServiceComponent.find.restore();
+    });
+  
+    it('should return empty when no metrics', function() {
+      AddMetricExpressionView.set('controller.filteredMetrics', []);
+      expect(AddMetricExpressionView.getServicesMap()).to.be.empty;
+    });
+  
+    it('should return empty when no metrics', function() {
+      AddMetricExpressionView.set('controller.filteredMetrics', [
+        {
+          name: 'metric1',
+          component_name: 'NAMENODE',
+          level: 'COMPONENT',
+          service_name: 'HDFS',
+          host_component_criteria: 'criteria1'
+        },
+        {
+          name: 'metric2',
+          component_name: 'C1',
+          service_name: 'S1',
+          level: 'COMPONENT',
+          host_component_criteria: 'criteria1'
+        },
+        {
+          name: 'metric3',
+          component_name: 'C2',
+          service_name: 'S1',
+          level: 'COMPONENT',
+          host_component_criteria: 'criteria1'
+        }
+      ]);
+      expect(AddMetricExpressionView.getServicesMap()).to.be.eql({
+        "S1": {
+          "components": {
+            "C1": {
+              "component_name": "C1",
+              "count": 1,
+              "hostComponentCriteria": "criteria1",
+              "level": "COMPONENT",
+              "metrics": [
+                "metric2"
+              ]
+            },
+            "C2_COMPONENT": {
+              "component_name": "C2",
+              "count": 1,
+              "hostComponentCriteria": "criteria1",
+              "level": "COMPONENT",
+              "metrics": [
+                "metric3"
+              ]
+            }
+          },
+          "count": 2
+        }
+      });
+    });
+  });
+  
+  describe('#componentMap', function() {
+    var nameServiceGroups = [{}];
+    beforeEach(function() {
+      sinon.stub(App, 'get').returns(true);
+      sinon.stub(AddMetricExpressionView, 'getServicesMap').returns({
+        "S1": {
+          "components": {
+            "C1": {
+              "component_name": "C1",
+              "count": 1,
+              "hostComponentCriteria": "criteria1",
+              "level": "COMPONENT",
+              "metrics": [
+                "metric2"
+              ]
+            }
+          },
+          "count": 1
+        },
+        "HDFS": {
+          "components": {
+            "NAMENODE": {
+              "component_name": "NAMENODE",
+              "count": 1,
+              "hostComponentCriteria": "criteria1",
+              "level": "COMPONENT",
+              "metrics": [
+                "metric3"
+              ]
+            }
+          },
+          "count": 1
+        }
+      });
+      sinon.stub(AddMetricExpressionView, 'getNameServiceGroups').returns(nameServiceGroups);
+      sinon.stub(App.HostComponent, 'getCount').returns(1);
+      sinon.stub(AddMetricExpressionView, 'createComponentItem').returns({});
+      sinon.stub(AddMetricExpressionView, 'putContextServiceOnTop', function(result) {
+        return result;
+      });
+      sinon.stub(App.StackService, 'find').returns(Em.Object.create({displayName: 'foo'}));
+    });
+    afterEach(function() {
+      App.get.restore();
+      AddMetricExpressionView.getServicesMap.restore();
+      App.HostComponent.getCount.restore();
+      AddMetricExpressionView.getNameServiceGroups.restore();
+      AddMetricExpressionView.createComponentItem.restore();
+      AddMetricExpressionView.putContextServiceOnTop.restore();
+      App.StackService.find.restore();
+    });
+    
+    it('should return map of components', function() {
+      AddMetricExpressionView.propertyDidChange('componentMap');
+      expect(AddMetricExpressionView.get('componentMap')).to.be.eql([
+        Em.Object.create({
+          serviceName: 'S1',
+          //in order to support panel lists
+          href: '#S1',
+          displayName: 'foo',
+          count: 1,
+          components: [{}]
+        }),
+        Em.Object.create({
+          serviceName: 'HDFS',
+          //in order to support panel lists
+          href: '#HDFS',
+          displayName: 'foo',
+          count: 1,
+          components: [
+            Em.Object.create({
+              displayName: 'NameNodes',
+              isGroup: true,
+              components: nameServiceGroups
+            })
+          ]
+        })
+      ]);
+    });
+  });
+  
+  describe('#createComponentItem', function() {
+    beforeEach(function() {
+      sinon.stub(App.StackServiceComponent, 'find').returns(Em.Object.create({
+        isMaster: true,
+        displayName: 'c1'
+      }));
+    });
+    afterEach(function() {
+      App.StackServiceComponent.find.restore();
+    });
+    
+    it('should return component', function() {
+      var service = {
+        "components": {
+          "C1": {
+            "component_name": "C1",
+            "count": 1,
+            "hostComponentCriteria": "criteria1",
+            "level": "HOSTCOMPONENT",
+            "metrics": [
+              "metric2"
+            ]
+          }
+        }
+      };
+      var component = AddMetricExpressionView.createComponentItem(service, 'S1', 'C1', '1', 'tag1');
+      component.reopen({
+        showAggregateSelect: false,
+        isAddEnabled: false
+      });
+      expect(component).to.be.eql(Em.Object.create({
+        componentName: 'C1',
+        isAddEnabled: false,
+        level: 'HOSTCOMPONENT',
+        displayName: Em.I18n.t('widget.create.wizard.step2.activeComponents').format('c1'),
+        tag: 'tag1',
+        count: 1,
+        metrics: ['metric2'],
+        selected: false,
+        id: 'C11tag1',
+        aggregatorId: 'C11_aggregator',
+        serviceName: 'S1',
+        showAggregateSelect: false,
+        selectedMetric: null,
+        selectedAggregation: Em.I18n.t('dashboard.widgets.wizard.step2.aggregateFunction.scanOps'),
+        hostComponentCriteria: 'criteria1'
+      }));
+    });
+  });
+  
+  describe('#putContextServiceOnTop', function() {
+    
+    it('should move service to the top of array', function() {
+      AddMetricExpressionView.set('controller.content', {widgetService: 'S2'});
+      var serviceComponentMap = [
+        {
+          serviceName: 'S1'
+        },
+        {
+          serviceName: 'S2'
+        }
+      ];
+      expect(AddMetricExpressionView.putContextServiceOnTop(serviceComponentMap)).to.be.eql([
+        {
+          serviceName: 'S2'
+        },
+        {
+          serviceName: 'S1'
+        }
+      ]);
+    });
+  });
+ 
+});
diff --git a/ambari-web/test/views/main/service/widgets/create/step2_view_test.js b/ambari-web/test/views/main/service/widgets/create/step2_view_test.js
index f2baf86..3d5899f 100644
--- a/ambari-web/test/views/main/service/widgets/create/step2_view_test.js
+++ b/ambari-web/test/views/main/service/widgets/create/step2_view_test.js
@@ -130,3 +130,59 @@ describe('App.WidgetWizardStep2View', function () {
     });
   });
 });
+
+describe('#App.WidgetPropertySelectView', function() {
+  var view;
+  
+  beforeEach(function() {
+    view = App.WidgetPropertySelectView.create({
+      property: Em.Object.create({
+        options: [
+          {
+            label: 'l1',
+            value: 'v1'
+          }
+        ]
+      })
+    });
+  });
+  
+  describe('#didInsertElement', function() {
+    beforeEach(function() {
+      sinon.stub(view, 'addObserver');
+      sinon.stub(view, 'setValue');
+      view.set('property.value', 'v1');
+      view.didInsertElement();
+    });
+    afterEach(function() {
+      view.addObserver.restore();
+      view.setValue.restore();
+    });
+    
+    it('should set selection', function() {
+      expect(view.get('selection')).to.be.eql({
+        label: 'l1',
+        value: 'v1'
+      });
+    });
+  
+    it('addObserver should be called', function() {
+      expect(view.addObserver.calledWith('selection.value', view, 'setValue')).to.be.true;
+    });
+  
+    it('setValue should be called', function() {
+      expect(view.setValue.called).to.be.true;
+    });
+  });
+ 
+  describe('#setValue', function() {
+    
+    it('should set value to 1', function() {
+      view.set('selection', {
+        value: 1
+      });
+      view.setValue();
+      expect(view.get('property.value')).to.be.equal(1);
+    });
+  });
+});