ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From atk...@apache.org
Subject ambari git commit: AMBARI-12460 Repositories url validation works incorrect. (atkach)
Date Mon, 20 Jul 2015 16:55:19 GMT
Repository: ambari
Updated Branches:
  refs/heads/trunk 1e81d16ef -> 7481fbbf1


AMBARI-12460 Repositories url validation works incorrect. (atkach)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7481fbbf
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7481fbbf
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7481fbbf

Branch: refs/heads/trunk
Commit: 7481fbbf1f14d20bada35d0298ddee11493a021e
Parents: 1e81d16
Author: Andrii Tkach <atkach@hortonworks.com>
Authored: Mon Jul 20 16:47:30 2015 +0300
Committer: Andrii Tkach <atkach@hortonworks.com>
Committed: Mon Jul 20 16:47:30 2015 +0300

----------------------------------------------------------------------
 ambari-web/app/models/repository.js             |  5 +-
 .../admin/stack_upgrade/edit_repositories.hbs   |  2 +-
 ambari-web/app/utils/validator.js               | 11 ++++
 ambari-web/app/views/common/controls_view.js    | 38 ++++++-------
 .../stack_upgrade/upgrade_version_box_view.js   | 34 ++++++++---
 ambari-web/test/utils/validator_test.js         | 18 ++++++
 .../test/views/common/controls_view_test.js     | 59 +++++++++++++++-----
 7 files changed, 118 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/7481fbbf/ambari-web/app/models/repository.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/repository.js b/ambari-web/app/models/repository.js
index 8515514..66c22bf 100644
--- a/ambari-web/app/models/repository.js
+++ b/ambari-web/app/models/repository.js
@@ -18,6 +18,7 @@
 
 
 var App = require('app');
+var validator = require('utils/validator');
 
 App.Repository = DS.Model.extend({
   id:  DS.attr('string'), // This is ${osType}-${repoId}.
@@ -40,9 +41,7 @@ App.Repository = DS.Model.extend({
   }.property('id','operatingSystem.isSelected'),
 
   invalidFormatError: function() {
-    var remotePattern = /^(?:(?:https?|ftp):\/{2})(?:\S+(?::\S*)?@)?(?:(?:(?:[\w\-.]))*)(?::[0-9]+)?(?:\/\S*)?$/,
-      localPattern = /^file:\/{2,3}([a-zA-Z][:|]\/){0,1}[\w~!*'();@&=\/\\\-+$,?%#.\[\]]+$/;
-    return !(remotePattern.test(this.get('baseUrl')) || localPattern.test(this.get('baseUrl')));
+    return !validator.isValidBaseUrl(this.get('baseUrl'));
   }.property('baseUrl'),
 
   invalidError: function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7481fbbf/ambari-web/app/templates/main/admin/stack_upgrade/edit_repositories.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/stack_upgrade/edit_repositories.hbs b/ambari-web/app/templates/main/admin/stack_upgrade/edit_repositories.hbs
index 053f7dc..d90c23d 100644
--- a/ambari-web/app/templates/main/admin/stack_upgrade/edit_repositories.hbs
+++ b/ambari-web/app/templates/main/admin/stack_upgrade/edit_repositories.hbs
@@ -19,7 +19,7 @@
 <div class="alert alert-info">
   {{t admin.stackVersions.editRepositories.info}}
 </div>
-<div {{bindAttr class="view.parentView.hasErrors::hidden :alert :alert-warning"}}>
+<div {{bindAttr class="view.parentView.serverValidationFailed::hidden :alert :alert-warning"}}>
   {{t admin.stackVersions.editRepositories.validation.warning}}
 </div>
 <div class="row-fluid">

http://git-wip-us.apache.org/repos/asf/ambari/blob/7481fbbf/ambari-web/app/utils/validator.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/validator.js b/ambari-web/app/utils/validator.js
index 6ed45fd..f436db5 100644
--- a/ambari-web/app/utils/validator.js
+++ b/ambari-web/app/utils/validator.js
@@ -233,5 +233,16 @@ module.exports = {
   isValidURL: function(value) {
     var urlRegex = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7
 FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;
     return urlRegex.test(value);
+  },
+
+  /**
+   * Validate base URL
+   * @param {string} value
+   * @returns {boolean}
+   */
+  isValidBaseUrl: function (value) {
+    var remotePattern = /^(?:(?:https?|ftp):\/{2})(?:\S+(?::\S*)?@)?(?:(?:(?:[\w\-.]))*)(?::[0-9]+)?(?:\/\S*)?$/,
+      localPattern = /^file:\/{2,3}([a-zA-Z][:|]\/){0,1}[\w~!*'();@&=\/\\\-+$,?%#.\[\]]+$/;
+    return remotePattern.test(value) || localPattern.test(value);
   }
 };

http://git-wip-us.apache.org/repos/asf/ambari/blob/7481fbbf/ambari-web/app/views/common/controls_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/controls_view.js b/ambari-web/app/views/common/controls_view.js
index 0ca78b0..178086d 100644
--- a/ambari-web/app/views/common/controls_view.js
+++ b/ambari-web/app/views/common/controls_view.js
@@ -17,6 +17,7 @@
  */
 
 var App = require('app');
+var validator = require('utils/validator');
 
 var delay = (function(){
   var timer = 0;
@@ -41,7 +42,7 @@ App.ServiceConfigPopoverSupport = Ember.Mixin.create({
   popoverPlacement: 'right',
 
   didInsertElement: function () {
-    $('body').tooltip({
+    App.tooltip($('body'), {
       selector: '[data-toggle=tooltip]',
       placement: 'top'
     });
@@ -1626,20 +1627,27 @@ App.BaseUrlTextField = Ember.TextField.extend({
   defaultValue: '',
 
   /**
+   *  validate base URL
+   */
+  validate: function () {
+    if (this.get('repository.skipValidation')) {
+      this.set('repository.hasError', false);
+    } else {
+      this.set('repository.hasError', !(validator.isValidBaseUrl(this.get('value'))));
+    }
+    this.get('parentView').uiValidation();
+  }.observes('value', 'repository.skipValidation'),
+
+  /**
    * Determines if user have put some new value
    * @type {boolean}
    */
-  valueWasChanged: false,
+  valueWasChanged: function () {
+    return this.get('value') !== this.get('defaultValue');
+  }.property('value', 'defaultValue'),
 
   didInsertElement: function () {
     this.set('defaultValue', this.get('value'));
-    this.addObserver('value', this, this.valueWasChangedObs);
-  },
-
-  valueWasChangedObs: function () {
-    var value = this.get('value'),
-      defaultValue = this.get('defaultValue');
-    this.set('valueWasChanged', value !== defaultValue);
   },
 
   /**
@@ -1648,17 +1656,5 @@ App.BaseUrlTextField = Ember.TextField.extend({
    */
   restoreValue: function () {
     this.set('value', this.get('defaultValue'));
-    this.keyUp();
-  },
-
-  /**
-   * Remove error-highlight after user puts some new value
-   * @method keyUp
-   */
-  keyUp: function () {
-    if (Em.get(this, 'repository.hasError')) {
-      Em.set(this, 'repository.hasError', false);
-    }
   }
-
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/7481fbbf/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_box_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_box_view.js b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_box_view.js
index 9e6d5ad..25be6e2 100644
--- a/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_box_view.js
+++ b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_box_view.js
@@ -243,21 +243,36 @@ App.UpgradeVersionBoxView = Em.View.extend({
       classNames: ['repository-list', 'sixty-percent-width-modal'],
       skipValidation: false,
       autoHeight: false,
-      hasErrors: false,
+      /**
+       * @type {boolean}
+       */
+      serverValidationFailed: false,
       bodyClass: Ember.View.extend({
         content: repo,
         skipCheckBox: Ember.Checkbox.extend({
           classNames: ["align-checkbox"],
           change: function() {
             this.get('parentView.content.operatingSystems').forEach(function(os) {
-              if (Em.get(os, 'repositories.length') > 0) {
-                os.get('repositories').forEach(function(repo) {
-                  Em.set(repo, 'hasError', false);
-                })
-              }
-            });
+              os.get('repositories').forEach(function(repo) {
+                repo.set('skipValidation', this.get('checked'));
+              }, this);
+            }, this);
           }
         }),
+
+        /**
+         * set <code>disablePrimary</code> of popup depending on base URL validation
+         */
+        uiValidation: function () {
+          var disablePrimary = !(App.get('isAdmin') && !App.get('isOperator'));
+
+          this.get('content.operatingSystems').forEach(function (os) {
+            os.get('repositories').forEach(function (repo) {
+              disablePrimary = (!disablePrimary) ? repo.get('hasError') : disablePrimary;
+            }, this);
+          }, this);
+          this.set('parentView.disablePrimary', disablePrimary);
+        },
         templateName: require('templates/main/admin/stack_upgrade/edit_repositories'),
         didInsertElement: function () {
           App.tooltip($("[rel=skip-validation-tooltip]"), {placement: 'right'});
@@ -265,12 +280,13 @@ App.UpgradeVersionBoxView = Em.View.extend({
       }),
       header: Em.I18n.t('common.repositories'),
       primary: Em.I18n.t('common.save'),
-      disablePrimary: !(App.get('isAdmin') && !App.get('isOperator')),
+      disablePrimary: false,
       onPrimary: function () {
         var self = this;
         App.get('router.mainAdminStackAndUpgradeController').saveRepoOS(repo, this.get('skipValidation')).done(function(data){
           if (data.length > 0) {
-            self.set('hasErrors', true);
+            self.set('serverValidationFailed', true);
+            self.set('disablePrimary', true);
           } else {
             self.hide();
           }

http://git-wip-us.apache.org/repos/asf/ambari/blob/7481fbbf/ambari-web/test/utils/validator_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/validator_test.js b/ambari-web/test/utils/validator_test.js
index 1219250..e4b5b50 100644
--- a/ambari-web/test/utils/validator_test.js
+++ b/ambari-web/test/utils/validator_test.js
@@ -439,4 +439,22 @@ describe('validator', function () {
       })
     });
   });
+
+  describe('#isValidBaseUrl()', function() {
+    var tests = [
+      {m: '"" - invalid', i: '', e: false},
+      {m: '"http://" - valid', i: 'http://', e: true},
+      {m: '"https://" - valid', i: 'https://', e: true},
+      {m: '"ftp://" - valid', i: 'ftp://', e: true},
+      {m: '"file:///" - valid', i: 'file:///', e: true},
+      {m: '"file3" - invalid', i: 'file3', e: false},
+      {m: '"3" - invalid', i: '3', e: false},
+      {m: '"a" - invalid', i: 'a', e: false}
+    ];
+    tests.forEach(function(test) {
+      it(test.m + ' ', function () {
+        expect(validator.isValidBaseUrl(test.i)).to.equal(test.e);
+      })
+    });
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/7481fbbf/ambari-web/test/views/common/controls_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/common/controls_view_test.js b/ambari-web/test/views/common/controls_view_test.js
index b886ea7..7152e2a 100644
--- a/ambari-web/test/views/common/controls_view_test.js
+++ b/ambari-web/test/views/common/controls_view_test.js
@@ -18,6 +18,7 @@
 
 var App = require('app');
 require('views/common/controls_view');
+var validator = require('utils/validator');
 
 describe('App.ServiceConfigRadioButtons', function () {
 
@@ -1084,42 +1085,70 @@ describe('App.CheckDBConnectionView', function () {
 
 describe('App.BaseUrlTextField', function () {
 
-  var view;
-
-  beforeEach(function () {
-    view = App.BaseUrlTextField.create({
-      repository: Em.Object.create({
-        baseUrl: 'val'
-      })
-    });
-    view.didInsertElement();
+  var view = App.BaseUrlTextField.create({
+    repository: Em.Object.create({
+      baseUrl: 'val'
+    }),
+    parentView: Em.Object.create({
+      uiValidation: Em.K
+    })
   });
 
   describe('#valueWasChanged', function () {
-
     it('should be recalculated after value is changed', function () {
       view.setProperties({
         value: 'val',
-        recommendedValue: 'val'
+        defaultValue: 'val'
       });
       expect(view.get('valueWasChanged')).to.be.false;
       view.set('value', 'newVal');
       expect(view.get('valueWasChanged')).to.be.true;
     });
-
   });
 
-  describe('#restoreValue', function () {
-
+  describe('#restoreValue()', function () {
     it('should unset value', function () {
       view.setProperties({
         value: 'valNew',
-        savedValue: 'val'
+        defaultValue: 'val'
       });
       view.restoreValue();
       expect(view.get('value')).to.equal('val');
     });
+  });
 
+  describe('#didInsertElement()', function () {
+    it('should set defaultValue', function () {
+      view.setProperties({
+        value: 'valNew',
+        defaultValue: 'val'
+      });
+      view.didInsertElement();
+      expect(view.get('defaultValue')).to.equal('valNew');
+    });
   });
 
+  describe('#validate()', function () {
+    beforeEach(function(){
+      sinon.stub(view.get('parentView'), 'uiValidation', Em.K);
+      sinon.stub(validator, 'isValidBaseUrl').returns(true);
+    });
+    afterEach(function(){
+      view.get('parentView').uiValidation.restore();
+      validator.isValidBaseUrl.restore();
+    });
+    it('skip validation', function () {
+      view.set('repository', Em.Object.create({
+        skipValidation: true
+      }));
+      expect(view.get('repository.hasError')).to.be.false;
+    });
+    it('apply validation', function () {
+      view.set('repository', Em.Object.create({
+          skipValidation: false
+      }));
+      expect(view.get('repository.hasError')).to.be.false;
+      expect(validator.isValidBaseUrl.calledOnce).to.be.true;
+    });
+  });
 });


Mime
View raw message