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 2015/07/20 18:55:19 UTC
ambari git commit: AMBARI-12460 Repositories url validation works
incorrect. (atkach)
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 <at...@hortonworks.com>
Authored: Mon Jul 20 16:47:30 2015 +0300
Committer: Andrii Tkach <at...@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;
+ });
+ });
});