Pārlūkot izejas kodu

AMBARI-11205 Adding an empty 'Dataset2' doesn't show anything on 'Preview'. (atkach)

Andrii Tkach 10 gadi atpakaļ
vecāks
revīzija
736696ba15

+ 17 - 18
ambari-web/app/controllers/main/service/widgets/create/step2_controller.js

@@ -268,10 +268,10 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
           ];
           break;
         case 'TEMPLATE':
-          expressionData = this.parseTemplateExpression(this);
+          expressionData = this.parseTemplateExpression(this.get('templateValue'), this.get('expressions'));
           break;
         case 'GRAPH':
-          expressionData = this.parseGraphDataset(this);
+          expressionData = this.parseGraphDataset(this.get('dataSets'));
           break;
       }
     }
@@ -281,14 +281,14 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
 
   /**
    * parse Graph data set
-   * @param {Ember.View} view
+   * @param {Array} dataSets
    * @returns {{metrics: Array, values: Array}}
    */
-  parseGraphDataset: function (view) {
+  parseGraphDataset: function (dataSets) {
     var metrics = [];
     var values = [];
 
-    view.get('dataSets').forEach(function (dataSet) {
+    dataSets.forEach(function (dataSet) {
       var result = this.parseExpression(dataSet.get('expression'));
       metrics.pushObjects(result.metrics);
       values.push({
@@ -305,16 +305,17 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
 
   /**
    * parse expression from template
-   * @param {Ember.View} view
+   * @param {string} templateValue
+   * @param {Array} expressions
    * @returns {{metrics: Array, values: {value: *}[]}}
    */
-  parseTemplateExpression: function (view) {
+  parseTemplateExpression: function (templateValue, expressions) {
     var metrics = [];
     var self = this;
-    var expression = view.get('templateValue').replace(/\{\{Expression[\d]\}\}/g, function (exp) {
+    var expression = templateValue.replace(/\{\{Expression[\d]\}\}/g, function (exp) {
       var result;
-      if (view.get('expressions').someProperty('alias', exp)) {
-        result = self.parseExpression(view.get('expressions').findProperty('alias', exp));
+      if (expressions.someProperty('alias', exp)) {
+        result = self.parseExpression(expressions.findProperty('alias', exp));
         metrics.pushObjects(result.metrics);
         return result.value;
       }
@@ -372,7 +373,7 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
   updateProperties: function () {
     var result = {};
 
-    this.get('widgetPropertiesViews').forEach(function(property){
+    this.get('widgetPropertiesViews').forEach(function (property) {
       for (var key in property.valueMap) {
         result[property.valueMap[key]] = property.get(key);
       }
@@ -477,7 +478,7 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
     for (var i = 0, l = expression.length; i < l; i++) {
       if (this.get('OPERATORS').contains(expression[i])) {
         if (str.trim().length > 0) {
-          data.pushObject(this.getExpressionVariable(str.trim(), id, metrics));
+          data.pushObject(this.getExpressionVariable(str.trim(), ++id, metrics));
           str = '';
         }
         data.pushObject(Em.Object.create({
@@ -490,7 +491,7 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
       }
     }
     if (str.trim().length > 0) {
-      data.pushObject(this.getExpressionVariable(str.trim(), id, metrics));
+      data.pushObject(this.getExpressionVariable(str.trim(), ++id, metrics));
     }
     return data;
   },
@@ -509,7 +510,7 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
     if (isNaN(Number(name))) {
       metric = metrics.findProperty('name', name);
       return Em.Object.create({
-        id: ++id,
+        id: id,
         name: metric.name,
         isMetric: true,
         componentName: metric.component_name,
@@ -519,7 +520,7 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
       });
     } else {
       return Em.Object.create({
-        id: ++id,
+        id: id,
         name: name,
         isNumber: true
       });
@@ -527,9 +528,7 @@ App.WidgetWizardStep2Controller = Em.Controller.extend({
   },
 
   next: function () {
-    if (!this.get('isSubmitDisabled')) {
-      App.router.send('next');
-    }
+    App.router.send('next');
   }
 });
 

+ 10 - 6
ambari-web/app/views/common/widget/graph_widget_view.js

@@ -78,14 +78,18 @@ App.GraphWidgetView = Em.View.extend(App.WidgetMixin, {
     if (this.get('content.values')) {
       this.get('content.values').forEach(function (value) {
         var expression = this.extractExpressions(value)[0];
-        var computedExpressions;
+        var computedData;
+        var datasetKey = value.value.match(this.get('EXPRESSION_REGEX'))[0];
 
         if (expression) {
-          computedExpressions = this.computeExpression(expression, metrics);
-          seriesData.push({
-            name: value.name,
-            data: computedExpressions[value.value.match(this.get('EXPRESSION_REGEX'))[0]]
-          });
+          computedData = this.computeExpression(expression, metrics)[datasetKey];
+          //exclude empty datasets
+          if (computedData.length > 0) {
+            seriesData.push({
+              name: value.name,
+              data: computedData
+            });
+          }
         }
       }, this);
     }

+ 312 - 26
ambari-web/test/controllers/main/service/widgets/create/step2_controller_test.js

@@ -26,20 +26,20 @@ describe('App.WidgetWizardStep2Controller', function () {
     content: Em.Object.create()
   });
 
-  describe("#isEditWidget", function() {
-    it("empty name", function() {
+  describe("#isEditWidget", function () {
+    it("empty name", function () {
       controller.set('content.controllerName', '');
       controller.propertyDidChange('isEditWidget');
       expect(controller.get('isEditWidget')).to.be.false;
     });
-    it("correct name", function() {
+    it("correct name", function () {
       controller.set('content.controllerName', 'widgetEditController');
       controller.propertyDidChange('isEditWidget');
       expect(controller.get('isEditWidget')).to.be.true;
     });
   });
 
-  describe("#filteredMetrics", function() {
+  describe("#filteredMetrics", function () {
     var testCases = [
       {
         metric: {
@@ -159,7 +159,7 @@ describe('App.WidgetWizardStep2Controller', function () {
     });
   });
 
-  describe("#isExpressionComplete()", function() {
+  describe("#isExpressionComplete()", function () {
     var testCases = [
       {
         expression: null,
@@ -185,54 +185,54 @@ describe('App.WidgetWizardStep2Controller', function () {
     });
   });
 
-  describe("#isGraphDataComplete()", function() {
+  describe("#isGraphDataComplete()", function () {
     beforeEach(function () {
       this.mock = sinon.stub(controller, 'isExpressionComplete');
     });
     afterEach(function () {
       this.mock.restore();
     });
-    it("dataSets is empty", function() {
+    it("dataSets is empty", function () {
       expect(controller.isGraphDataComplete([])).to.be.false;
     });
-    it("label is empty", function() {
+    it("label is empty", function () {
       expect(controller.isGraphDataComplete([Em.Object.create({label: ''})])).to.be.false;
     });
-    it("expression is not complete", function() {
+    it("expression is not complete", function () {
       this.mock.returns(false);
       expect(controller.isGraphDataComplete([Em.Object.create({label: 'abc'})])).to.be.false;
     });
-    it("expression is complete", function() {
+    it("expression is complete", function () {
       this.mock.returns(true);
       expect(controller.isGraphDataComplete([Em.Object.create({label: 'abc'})])).to.be.true;
     });
   });
 
-  describe("#isTemplateDataComplete()", function() {
+  describe("#isTemplateDataComplete()", function () {
     beforeEach(function () {
       this.mock = sinon.stub(controller, 'isExpressionComplete');
     });
     afterEach(function () {
       this.mock.restore();
     });
-    it("expressions is empty", function() {
+    it("expressions is empty", function () {
       expect(controller.isTemplateDataComplete([])).to.be.false;
     });
-    it("templateValue is empty", function() {
+    it("templateValue is empty", function () {
       expect(controller.isTemplateDataComplete([{}], '')).to.be.false;
     });
-    it("expression is not complete", function() {
+    it("expression is not complete", function () {
       this.mock.returns(false);
       expect(controller.isTemplateDataComplete([{}], 'abc')).to.be.false;
     });
-    it("expression is complete", function() {
+    it("expression is complete", function () {
       this.mock.returns(true);
       expect(controller.isTemplateDataComplete([{}], 'abc')).to.be.true;
     });
   });
 
-  describe("#addDataSet()", function() {
-    it("", function() {
+  describe("#addDataSet()", function () {
+    it("", function () {
       controller.get('dataSets').clear();
       controller.addDataSet(null, true);
       expect(controller.get('dataSets').objectAt(0).get('id')).to.equal(1);
@@ -253,8 +253,8 @@ describe('App.WidgetWizardStep2Controller', function () {
     });
   });
 
-  describe("#addExpression()", function() {
-    it("", function() {
+  describe("#addExpression()", function () {
+    it("", function () {
       controller.get('expressions').clear();
       controller.addExpression(null, true);
       expect(controller.get('expressions').objectAt(0).get('id')).to.equal(1);
@@ -275,36 +275,36 @@ describe('App.WidgetWizardStep2Controller', function () {
     });
   });
 
-  describe("#initWidgetData()", function() {
-    it("new data", function() {
+  describe("#initWidgetData()", function () {
+    it("new data", function () {
       controller.set('expressions', []);
       controller.set('dataSets', []);
       controller.get('content').setProperties({
-        widgetProperties: {a:1},
+        widgetProperties: {a: 1},
         widgetValues: [1],
         widgetMetrics: [2]
       });
 
       controller.initWidgetData();
 
-      expect(controller.get('widgetProperties')).to.eql({a:1});
+      expect(controller.get('widgetProperties')).to.eql({a: 1});
       expect(controller.get('widgetValues')).to.eql([]);
       expect(controller.get('widgetMetrics')).to.eql([]);
       expect(controller.get('expressions')).to.not.be.empty;
       expect(controller.get('dataSets')).to.not.be.empty;
     });
-    it("previously edited", function() {
+    it("previously edited", function () {
       controller.set('expressions', [{}]);
       controller.set('dataSets', [{}]);
       controller.get('content').setProperties({
-        widgetProperties: {a:1},
+        widgetProperties: {a: 1},
         widgetValues: [1],
         widgetMetrics: [2]
       });
 
       controller.initWidgetData();
 
-      expect(controller.get('widgetProperties')).to.eql({a:1});
+      expect(controller.get('widgetProperties')).to.eql({a: 1});
       expect(controller.get('widgetValues')).to.eql([1]);
       expect(controller.get('widgetMetrics')).to.eql([2]);
       expect(controller.get('expressions')).to.not.be.empty;
@@ -312,4 +312,290 @@ describe('App.WidgetWizardStep2Controller', function () {
     });
   });
 
+  describe("#updateExpressions()", function () {
+    beforeEach(function () {
+      sinon.stub(controller, 'parseExpression').returns({values: [1], metrics: [1]});
+      sinon.stub(controller, 'parseTemplateExpression').returns({values: [1], metrics: [1]});
+      sinon.stub(controller, 'parseGraphDataset').returns({values: [1], metrics: [1]});
+    });
+    afterEach(function () {
+      controller.parseExpression.restore();
+      controller.parseTemplateExpression.restore();
+      controller.parseGraphDataset.restore();
+    });
+    it("empty expressions", function () {
+      controller.set('expressions', []);
+      controller.updateExpressions();
+      expect(controller.parseExpression.called).to.be.false;
+      expect(controller.parseTemplateExpression.called).to.be.false;
+      expect(controller.parseGraphDataset.called).to.be.false;
+      expect(controller.get('widgetValues')).to.be.empty;
+      expect(controller.get('widgetMetrics')).to.be.empty;
+    });
+    it("empty dataSets", function () {
+      controller.set('dataSets', []);
+      controller.updateExpressions();
+      expect(controller.parseExpression.called).to.be.false;
+      expect(controller.parseTemplateExpression.called).to.be.false;
+      expect(controller.parseGraphDataset.called).to.be.false;
+      expect(controller.get('widgetValues')).to.be.empty;
+      expect(controller.get('widgetMetrics')).to.be.empty;
+    });
+    it("GAUGE widget", function () {
+      controller.set('expressions', [{}]);
+      controller.set('content.widgetType', 'GAUGE');
+      controller.set('dataSets', [{}]);
+      //controller.updateExpressions();
+      expect(controller.parseExpression.calledOnce).to.be.true;
+      expect(controller.parseTemplateExpression.called).to.be.false;
+      expect(controller.parseGraphDataset.called).to.be.false;
+      expect(controller.get('widgetValues')).to.not.be.empty;
+      expect(controller.get('widgetMetrics')).to.not.be.empty;
+    });
+    it("NUMBER widget", function () {
+      controller.set('expressions', [{}]);
+      controller.set('content.widgetType', 'NUMBER');
+      controller.set('dataSets', [{}]);
+      //controller.updateExpressions();
+      expect(controller.parseExpression.calledOnce).to.be.true;
+      expect(controller.parseTemplateExpression.called).to.be.false;
+      expect(controller.parseGraphDataset.called).to.be.false;
+      expect(controller.get('widgetValues')).to.not.be.empty;
+      expect(controller.get('widgetMetrics')).to.not.be.empty;
+    });
+    it("TEMPLATE widget", function () {
+      controller.set('expressions', [{}]);
+      controller.set('content.widgetType', 'TEMPLATE');
+      controller.set('dataSets', [{}]);
+      //controller.updateExpressions();
+      expect(controller.parseExpression.called).to.be.false;
+      expect(controller.parseTemplateExpression.calledOnce).to.be.true;
+      expect(controller.parseGraphDataset.called).to.be.false;
+      expect(controller.get('widgetValues')).to.not.be.empty;
+      expect(controller.get('widgetMetrics')).to.not.be.empty;
+    });
+    it("GRAPH widget", function () {
+      controller.set('expressions', [{}]);
+      controller.set('content.widgetType', 'GRAPH');
+      controller.set('dataSets', [{}]);
+      //controller.updateExpressions();
+      expect(controller.parseExpression.called).to.be.false;
+      expect(controller.parseTemplateExpression.called).to.be.false;
+      expect(controller.parseGraphDataset.calledOnce).to.be.true;
+      expect(controller.get('widgetValues')).to.not.be.empty;
+      expect(controller.get('widgetMetrics')).to.not.be.empty;
+    });
+  });
+
+  describe("#parseGraphDataset()", function () {
+    beforeEach(function () {
+      sinon.stub(controller, 'parseExpression').returns({value: 'value'});
+    });
+    afterEach(function () {
+      controller.parseExpression.restore();
+    });
+    it("empty dataSets", function () {
+      expect(controller.parseGraphDataset([])).to.be.eql({
+        metrics: [],
+        values: []
+      });
+    });
+    it("correct dataSets", function () {
+      var result = controller.parseGraphDataset([Em.Object.create({label: 'label'})]);
+      expect(result.values).to.be.eql([
+        {
+          "name": "label",
+          "value": "value"
+        }
+      ]);
+      expect(result.metrics).to.be.empty;
+    });
+  });
+
+  describe("#parseTemplateExpression()", function () {
+    beforeEach(function () {
+      sinon.stub(controller, 'parseExpression').returns({value: 'value'});
+    });
+    afterEach(function () {
+      controller.parseExpression.restore();
+    });
+    it("empty expressions", function () {
+      expect(controller.parseTemplateExpression("{{Expression1}}", [])).to.be.eql({
+        metrics: [],
+        values: [
+          {
+            value: "{{Expression1}}"
+          }
+        ]
+      });
+    });
+    it("correct expressions", function () {
+      var result = controller.parseTemplateExpression("{{Expression1}}", [Em.Object.create({alias: '{{Expression1}}'})]);
+      expect(result.values).to.be.eql([
+        {
+          value: "value"
+        }
+      ]);
+      expect(result.metrics).to.be.empty;
+    });
+  });
+
+  describe("#parseExpression()", function () {
+    it("expression is empty", function () {
+      expect(controller.parseExpression({data: []})).to.eql({
+        metrics: [],
+        value: ''
+      });
+    });
+    it("expression is correct", function () {
+      var data = [
+        {
+          name: 'm1',
+          serviceName: 'S1',
+          componentName: 'C1',
+          metricPath: 'mp',
+          hostComponentCriteria: 'hcc',
+          isMetric: true
+        },
+        {
+          name: '+'
+        },
+        {
+          name: '10'
+        }
+      ];
+      expect(controller.parseExpression({data: data})).to.eql({
+        metrics: [
+          {
+            "name": "m1",
+            "service_name": "S1",
+            "component_name": "C1",
+            "metric_path": "mp",
+            "host_component_criteria": "hcc"
+          }
+        ],
+        value: '${m1+10}'
+      });
+    });
+  });
+
+  describe("#updateProperties()", function () {
+    it("widgetPropertiesViews is empty", function () {
+      controller.set('widgetPropertiesViews', []);
+      expect(controller.get('widgetProperties')).to.be.empty;
+    });
+    it("widgetPropertiesViews is correct", function () {
+      controller.set('widgetPropertiesViews', [
+        Em.Object.create({
+          valueMap: {
+            "key1": 'alias1'
+          },
+          key1: 1
+        })
+      ]);
+      expect(controller.get('widgetProperties')).to.eql({
+        "alias1": 1
+      });
+    });
+  });
+
+  describe("#renderProperties()", function () {
+    beforeEach(function () {
+      this.mock = sinon.stub(App.WidgetType, 'find');
+      sinon.stub(App.WidgetPropertyTypes, 'findProperty').returns({valueMap: {}});
+      sinon.stub(App.WidgetProperty, 'create').returns({});
+    });
+    afterEach(function () {
+      this.mock.restore();
+      App.WidgetPropertyTypes.findProperty.restore();
+      App.WidgetProperty.create.restore();
+    });
+    it("no properties", function () {
+      this.mock.returns(Em.Object.create({properties: []}));
+      controller.renderProperties();
+      expect(controller.get('widgetPropertiesViews')).to.be.empty;
+    });
+    it("correct properties", function () {
+      this.mock.returns(Em.Object.create({properties: [{}]}));
+      controller.renderProperties();
+      expect(App.WidgetProperty.create.calledWith({valueMap: {}})).to.be.true;
+      expect(controller.get('widgetPropertiesViews')).to.not.be.empty;
+    });
+  });
+
+  describe("#parseValue()", function () {
+    beforeEach(function () {
+      sinon.stub(controller, 'getExpressionData').returns({});
+    });
+    afterEach(function () {
+      controller.getExpressionData.restore();
+    });
+    it("empty value", function () {
+      expect(controller.parseValue("", [])).to.be.empty;
+    });
+    it("correct value", function () {
+      expect(controller.parseValue("${m1}", [])).to.not.be.empty;
+      expect(controller.getExpressionData.calledWith("m1", [])).to.be.true;
+    });
+  });
+
+  describe("#getExpressionData()", function () {
+    beforeEach(function () {
+      sinon.stub(controller, 'getExpressionVariable').returns({});
+    });
+    afterEach(function () {
+      controller.getExpressionVariable.restore();
+    });
+    it("empty expression", function () {
+      expect(controller.getExpressionData("", [])).to.be.empty;
+    });
+    it("correct expression", function () {
+      expect(controller.getExpressionData("m1+10", [])).to.not.be.empty;
+      expect(controller.getExpressionVariable.getCall(0).args).to.eql(["m1", 1, []]);
+      expect(controller.getExpressionVariable.getCall(1).args).to.eql(["10", 3, []]);
+    });
+  });
+
+  describe("#getExpressionVariable()", function () {
+    it("get metric definition", function () {
+      var metrics = [
+        {
+          name: 'm1',
+          component_name: 'C1',
+          service_name: 'S1',
+          metric_path: 'mp',
+          host_component_criteria: 'hcc'
+        }
+      ];
+      expect(controller.getExpressionVariable("m1", 1, metrics)).to.be.eql(Em.Object.create({
+        id: 1,
+        name: 'm1',
+        isMetric: true,
+        componentName: 'C1',
+        serviceName: 'S1',
+        metricPath: 'mp',
+        hostComponentCriteria: 'hcc'
+      }));
+    });
+    it("get number definition", function () {
+      expect(controller.getExpressionVariable("10", 2, [])).to.be.eql(Em.Object.create({
+        id: 2,
+        name: "10",
+        isNumber: true
+      }));
+    });
+  });
+
+  describe("#next()", function () {
+    beforeEach(function () {
+      sinon.stub(App.router, 'send');
+    });
+    afterEach(function () {
+      App.router.send.restore();
+    });
+    it("", function () {
+      controller.next();
+      expect(App.router.send.calledWith('next'));
+    });
+  });
 });