فهرست منبع

AMBARI-10194. Better Client Side Validation Of Alert Definition Threshold Data (alexantonenko)

Alex Antonenko 10 سال پیش
والد
کامیت
c42db2ebe3
3فایلهای تغییر یافته به همراه134 افزوده شده و 11 حذف شده
  1. 45 5
      ambari-web/app/models/alert_config.js
  2. 14 3
      ambari-web/app/utils/number_utils.js
  3. 75 3
      ambari-web/test/models/alert_config_test.js

+ 45 - 5
ambari-web/app/models/alert_config.js

@@ -18,6 +18,7 @@
 
 
 var App = require('app');
 var App = require('app');
 var validator = require('utils/validator');
 var validator = require('utils/validator');
+var numericUtils = require('utils/number_utils');
 
 
 App.AlertConfigProperty = Ember.Object.extend({
 App.AlertConfigProperty = Ember.Object.extend({
 
 
@@ -389,10 +390,23 @@ App.AlertConfigProperties = {
      * @return {boolean}
      * @return {boolean}
      */
      */
     isValid: function () {
     isValid: function () {
-      if (!this.get('showInputForValue')) return true;
+      if (!this.get('showInputForValue')) {
+        return true;
+      }
+
       var value = this.get('displayValue');
       var value = this.get('displayValue');
-      if (Em.isNone(value)) return false;
+
+      if (Em.isNone(value)) {
+        return false;
+      }
+
       value = ('' + value).trim();
       value = ('' + value).trim();
+
+      //only allow 1/10th of a second
+      if (numericUtils.getFloatDecimals(value) > 1) {
+        return false;
+      }
+
       return validator.isValidFloat(value);
       return validator.isValidFloat(value);
     }.property('displayValue', 'showInputForValue')
     }.property('displayValue', 'showInputForValue')
 
 
@@ -532,9 +546,23 @@ App.AlertConfigProperties.Thresholds = {
 
 
     isValid: function () {
     isValid: function () {
       var value = this.get('displayValue');
       var value = this.get('displayValue');
-      if (!value) return false;
+
+      if (!value) {
+        return false;
+      }
+
       value = ('' + value).trim();
       value = ('' + value).trim();
+      if (numericUtils.getFloatDecimals(value)) {
+        return false;
+      }
+
       value = parseFloat(value);
       value = parseFloat(value);
+
+      //do not allow float values
+      if (parseInt(value, 10) !== value) {
+        return false;
+      }
+
       return this.get('showInputForValue') ? !isNaN(value) && value > 0 && value <= 100 : true;
       return this.get('showInputForValue') ? !isNaN(value) && value > 0 && value <= 100 : true;
     }.property('displayValue', 'showInputForValue'),
     }.property('displayValue', 'showInputForValue'),
 
 
@@ -566,11 +594,23 @@ App.AlertConfigProperties.Thresholds = {
   PositiveMixin: Em.Mixin.create({
   PositiveMixin: Em.Mixin.create({
 
 
     isValid: function () {
     isValid: function () {
-      if (!this.get('showInputForValue')) return true;
+      if (!this.get('showInputForValue')) {
+        return true;
+      }
       var value = this.get('displayValue');
       var value = this.get('displayValue');
-      if (!value) return false;
+
+      if (!value) {
+        return false;
+      }
+
+      //only allow 1/10th of a second
+      if (numericUtils.getFloatDecimals(value) > 1) {
+        return false;
+      }
+
       value = ('' + value).trim();
       value = ('' + value).trim();
       value = parseFloat(value);
       value = parseFloat(value);
+
       return !isNaN(value) && value > 0;
       return !isNaN(value) && value > 0;
     }.property('displayValue', 'showInputForValue')
     }.property('displayValue', 'showInputForValue')
 
 

+ 14 - 3
ambari-web/app/utils/number_utils.js

@@ -5,9 +5,9 @@
  * licenses this file to you under the Apache License, Version 2.0 (the
  * 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.
  * "License"); you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * You may obtain a copy of the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -18,7 +18,7 @@ module.exports = {
 
 
   /**
   /**
    * Convert byte size to other metrics.
    * Convert byte size to other metrics.
-   * 
+   *
    * @param {Number} bytes to convert to string
    * @param {Number} bytes to convert to string
    * @param {Number} precision Number to adjust precision of return value. Default is 0.
    * @param {Number} precision Number to adjust precision of return value. Default is 0.
    * @param {String} parseType
    * @param {String} parseType
@@ -103,5 +103,16 @@ module.exports = {
     } else {
     } else {
       return 0;
       return 0;
     }
     }
+  },
+
+  getFloatDecimals: function (number, separator) {
+    separator = separator || '.';
+
+    var value = '' + number;
+    var decimals = value.split(separator);
+
+    decimals = decimals[1] ? decimals[1].length : 0;
+
+    return decimals;
   }
   }
 };
 };

+ 75 - 3
ambari-web/test/models/alert_config_test.js

@@ -156,14 +156,86 @@ describe('App.AlertConfigProperties', function () {
         expect(model.get('isValid')).to.be.false;
         expect(model.get('isValid')).to.be.false;
       });
       });
 
 
-      it('should be true if displayValue is valid float', function () {
-        model.set('displayValue', '123.456');
+      it('should be false if METRIC displayValue is not valid float', function () {
+        model.set('displayValue', '$1234.444');
+        expect(model.get('isValid')).to.be.false;
+
+        model.set('displayValue', 'hello-world!');
+        expect(model.get('isValid')).to.be.false;
+      });
+
+      it('should be true if METRIC displayValue is valid float with at most one decimal', function () {
+        model.set('displayValue', '123.4');
         expect(model.get('isValid')).to.be.true;
         expect(model.get('isValid')).to.be.true;
 
 
-        model.set('displayValue', '$1234.444');
+        model.set('displayValue', '123.0');
+        expect(model.get('isValid')).to.be.true;
+
+        model.set('displayValue', '666');
+        expect(model.get('isValid')).to.be.true;
+      });
+
+      it('should be false if METRIC displayValue is valid float with more than one decimal', function () {
+        model.set('displayValue', '123.48');
         expect(model.get('isValid')).to.be.false;
         expect(model.get('isValid')).to.be.false;
       });
       });
 
 
+      it('should be true for AGGREGATE percentage with precision of 1', function () {
+        model = Em.Object.create(App.AlertConfigProperties.Thresholds.PercentageMixin, {
+          displayValue: '1',
+          showInputForValue: true
+        });
+
+        expect(model.get('isValid')).to.be.true;
+
+        model.set('displayValue', '88');
+        expect(model.get('isValid')).to.be.true;
+      });
+
+      it('should be false for AGGREGATE percentage values with precision smaller than 1', function () {
+        model = Em.Object.create(App.AlertConfigProperties.Thresholds.PercentageMixin, {
+          displayValue: '70.01',
+          showInputForValue: true
+        });
+
+        expect(model.get('isValid')).to.be.false;
+
+        model.set('displayValue', '70.0');
+        expect(model.get('isValid')).to.be.false;
+
+        model.set('displayValue', '80.000');
+        expect(model.get('isValid')).to.be.false;
+      });
+
+      it('should be true for PORT percentage values with precision of 1/10th', function () {
+        model = App.AlertConfigProperties.Threshold.create({
+          value: '0.4',
+          showInputForValue: true
+        })
+
+        expect(model.get('isValid')).to.be.true;
+
+        model.set('value', '3');
+        expect(model.get('isValid')).to.be.true;
+
+        model.set('value', '33.0');
+        expect(model.get('isValid')).to.be.true;
+      });
+
+      it('should be false for PORT percentage values with precision greater than 1/10th', function() {
+        model = App.AlertConfigProperties.Threshold.create({
+          value: '4.234',
+          showInputForValue: true
+        });
+
+        expect(model.get('isValid')).to.be.false;
+
+        model.set('value', '44.001');
+        expect(model.get('isValid')).to.be.false;
+
+        model.set('value', '112.01');
+        expect(model.get('isValid')).to.be.false;
+      });
 
 
     });
     });