Ver código fonte

AMBARI-7775. Create App, step2. User can input negative value and proceed next. (onechiporenko)

Oleg Nechiporenko 10 anos atrás
pai
commit
61c8f5f982

+ 2 - 2
contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step2_controller.js

@@ -99,13 +99,13 @@ App.CreateAppWizardStep2Controller = Ember.ArrayController.extend({
   },
 
   /**
-   * Check if param is integer
+   * Check if param is integer (and >= 0)
    * @param {string} value value to check
    * @return {Boolean}
    * @method isNotInteger
    */
   isNotInteger: function (value) {
-    return !(value.trim().length && (value % 1 == 0));
+    return !(value && value.trim().length && (value % 1 == 0) && value >= 0);
   },
 
   /**

+ 4 - 4
contrib/views/slider/src/main/resources/ui/app/templates/createAppWizard/step1.hbs

@@ -92,7 +92,7 @@
         <label class="control-label">{{t wizard.step1.schedulerOptions.queueName}}</label>
       </div>
       <div class="col-xs-7">
-        {{input class="form-control" valueBinding="controller.newApp.queueName" placeholderTranslation="form.placeholder.optional"}}
+        {{input class="form-control queueName" valueBinding="controller.newApp.queueName" placeholderTranslation="form.placeholder.optional"}}
       </div>
     </div>
     <!-- Scheduler Options end -->
@@ -139,7 +139,7 @@
         <label class="control-label">{{t wizard.step1.logAggregation.filePatterns.include}}</label>
       </div>
       <div class="col-xs-7">
-        {{input class="form-control" valueBinding="controller.newApp.includeFilePatterns" placeholderTranslation="form.placeholder.include.file.patterns"}}
+        {{input class="form-control includeFilePatterns" valueBinding="controller.newApp.includeFilePatterns" placeholderTranslation="form.placeholder.include.file.patterns"}}
       </div>
     </div>
     <div class="row">
@@ -147,7 +147,7 @@
         <label class="control-label">{{t wizard.step1.logAggregation.filePatterns.exclude}}</label>
       </div>
       <div class="col-xs-7">
-        {{input class="form-control" valueBinding="controller.newApp.excludeFilePatterns" placeholderTranslation="form.placeholder.exclude.file.patterns"}}
+        {{input class="form-control excludeFilePatterns" valueBinding="controller.newApp.excludeFilePatterns" placeholderTranslation="form.placeholder.exclude.file.patterns"}}
       </div>
     </div>
     <div class="row">
@@ -156,7 +156,7 @@
       </div>
       <div class="col-xs-7">
         <div class="input-group">
-          {{input class="form-control" valueBinding="controller.newApp.frequency" placeholderTranslation="form.placeholder.frequency"}}
+          {{input class="form-control frequency" valueBinding="controller.newApp.frequency" placeholderTranslation="form.placeholder.frequency"}}
           <div class="input-group-addon">{{t common.seconds}}</div>
         </div>
       </div>

+ 4 - 4
contrib/views/slider/src/main/resources/ui/app/templates/createAppWizard/step2.hbs

@@ -34,9 +34,9 @@
       {{#each}}
         <tr>
           <td>{{displayName}}</td>
-          <td>{{input class="cell-narrow" valueBinding="numInstances"}}</td>
-          <td>{{input class="cell-wide" valueBinding="yarnMemory"}}</td>
-          <td>{{input class="cell-narrow" valueBinding="yarnCPU"}}</td>
+          <td>{{input class="cell-narrow numInstances" valueBinding="numInstances"}}</td>
+          <td>{{input class="cell-wide yarnMemory" valueBinding="yarnMemory"}}</td>
+          <td>{{input class="cell-narrow yarnCPU" valueBinding="yarnCPU"}}</td>
           <td>
             <div {{bs-bind-tooltip content=view.checkBoxPopover}}>
               {{input type="checkbox" checkedBinding="yarnLabelChecked" class="checkbox-inline"}}
@@ -44,7 +44,7 @@
           </td>
           <td class="cell-auto">
             <div {{bs-bind-tooltip content=view.yarnLabelPopover}}>
-              {{input valueBinding="yarnLabel" disabledBinding="yarnLabelNotChecked"}}
+              {{input class="yarnLabel" valueBinding="yarnLabel" disabledBinding="yarnLabelNotChecked"}}
             </div>
           </td>
         </tr>

+ 87 - 7
contrib/views/slider/src/main/resources/ui/test/integration/processes/create_new_app_test.js

@@ -75,6 +75,7 @@ var appTypes = {
 
 var selectors = {
     buttonNext: 'button.next-btn',
+    buttonBack: 'button.btn:eq(1)',
     step2: {
       content: '#step2 table tbody'
     }
@@ -82,6 +83,12 @@ var selectors = {
   newApp = {
     name: 'new_app',
     type: 'HBASE',
+    includeFilePatterns: 'includeFilePatterns1',
+    excludeFilePatterns: 'excludeFilePatterns1',
+    frequency: 'frequency1',
+    queueName: 'queueName1',
+    specialLabel: 'specialLabel1',
+    selectedYarnLabel: 'selectedYarnLabel1',
     components: {
       HBASE_MASTER: 4,
       HBASE_REGIONSERVER: 5
@@ -127,15 +134,15 @@ test('basic (no errors - just valid data)', function () {
 
     equal(find(selectors.buttonNext).attr('disabled'), null, '"Next"-button should be enabled at the beginning of Step 2');
     equal(find(selectors.step2.content + ' tr').length, 2, 'Selected App Type has 2 components');
-    equal(find(selectors.step2.content + ' tr:eq(0) input').val(), '1', 'Component count for 1st component is valid by default');
-    equal(find(selectors.step2.content + ' tr:eq(1) input').val(), '2', 'Component count for 2nd component is valid by default');
+    equal(find(selectors.step2.content + ' tr:eq(0) .numInstances').val(), '1', 'Component count for 1st component is valid by default');
+    equal(find(selectors.step2.content + ' tr:eq(1) .numInstances').val(), '2', 'Component count for 2nd component is valid by default');
 
-    fillIn(selectors.step2.content + ' tr:eq(0) input:eq(0)', newApp.components.HBASE_MASTER);
-    fillIn(selectors.step2.content + ' tr:eq(1) input:eq(0)', newApp.components.HBASE_REGIONSERVER);
+    fillIn(selectors.step2.content + ' tr:eq(0) .numInstances', newApp.components.HBASE_MASTER);
+    fillIn(selectors.step2.content + ' tr:eq(1) .numInstances', newApp.components.HBASE_REGIONSERVER);
 
-    equal(find(selectors.step2.content + ' tr:eq(0) input:eq(4)').attr('disabled'), 'disabled', 'YARN label input-field should be disabled by default');
-    find(selectors.step2.content + ' tr:eq(0) input:eq(3)').click();
-    equal(find(selectors.step2.content + ' tr:eq(0) input:eq(4)').attr('disabled'), null, 'YARN label input-field should be enabled after checkbox checked');
+    equal(find(selectors.step2.content + ' tr:eq(0) .yarnLabel').attr('disabled'), 'disabled', 'YARN label input-field should be disabled by default');
+    find(selectors.step2.content + ' tr:eq(0) .checkbox-inline').click();
+    equal(find(selectors.step2.content + ' tr:eq(0) .yarnLabel').attr('disabled'), null, 'YARN label input-field should be enabled after checkbox checked');
 
     click(selectors.buttonNext);
     andThen(function () {
@@ -196,4 +203,77 @@ test('check step1', function () {
   find('.special-label-radio').click();
   equal(find('.special-label').attr('disabled'), null, '"Special YARN label"-textfield should be enabled if proper radio-button selected');
 
+});
+
+test('check step2', function () {
+
+  visit('/createAppWizard/step1');
+  fillIn('#app-name-input', newApp.name);
+  click(selectors.buttonNext);
+
+  andThen(function () {
+    fillIn(selectors.step2.content + ' tr:eq(0) .numInstances', -1);
+    andThen(function () {
+      equal(find(selectors.buttonNext).attr('disabled'), 'disabled', '"Next"-button should be disabled because invalid value provided for Instances count');
+      equal(find('.alert').length, 1, 'Alert-box is on page');
+    });
+    fillIn(selectors.step2.content + ' tr:eq(0) .numInstances', 1);
+    andThen(function () {
+      equal(find(selectors.buttonNext).attr('disabled'), null);
+      equal(find('.alert').length, 0, 'Alert-box is hidden');
+    });
+    fillIn(selectors.step2.content + ' tr:eq(0) .yarnMemory', -1);
+    andThen(function () {
+      equal(find(selectors.buttonNext).attr('disabled'), 'disabled', '"Next"-button should be disabled because invalid value provided for Memory');
+      equal(find('.alert').length, 1, 'Alert-box is on page');
+    });
+    fillIn(selectors.step2.content + ' tr:eq(0) .yarnMemory', 1024);
+    andThen(function () {
+      equal(find(selectors.buttonNext).attr('disabled'), null);
+      equal(find('.alert').length, 0, 'Alert-box is hidden');
+    });
+    fillIn(selectors.step2.content + ' tr:eq(0) .yarnCPU', -1);
+    andThen(function () {
+      equal(find(selectors.buttonNext).attr('disabled'), 'disabled', '"Next"-button should be disabled because invalid value provided for CPU Cores');
+      equal(find('.alert').length, 1, 'Alert-box is on page');
+    });
+    fillIn(selectors.step2.content + ' tr:eq(0) .yarnCPU', 1024);
+    andThen(function () {
+      equal(find(selectors.buttonNext).attr('disabled'), null);
+      equal(find('.alert').length, 0, 'Alert-box is hidden');
+    });
+
+    equal(find(selectors.step2.content + ' tr:eq(0) .yarnLabel').attr('disabled'), 'disabled', 'Labels-field is disabled by default');
+    find(selectors.step2.content + ' tr:eq(0) .checkbox-inline').click();
+    andThen(function () {
+      equal(find(selectors.step2.content + ' tr:eq(0) yarnLabel').attr('disabled'), null, 'Labels-field should be enabled when checkbox clicked');
+    });
+  });
+
+});
+
+test('check step2 back', function () {
+
+  visit('/createAppWizard/step1');
+  fillIn('#app-name-input', newApp.name);
+  fillIn('.includeFilePatterns', newApp.includeFilePatterns);
+  fillIn('.excludeFilePatterns', newApp.excludeFilePatterns);
+  fillIn('.frequency', newApp.frequency);
+  fillIn('.queueName', newApp.queueName);
+  find('.selectedYarnLabel:eq(2)').click();
+  fillIn('.special-label', newApp.specialLabel);
+  click(selectors.buttonNext);
+
+  andThen(function () {
+    click(selectors.buttonBack);
+    andThen(function () {
+      equal(find('#app-name-input').val(), newApp.name, 'Name is restored');
+      equal(find('.includeFilePatterns').val(), newApp.includeFilePatterns, 'includeFilePatterns is restored');
+      equal(find('.excludeFilePatterns').val(), newApp.excludeFilePatterns, 'excludeFilePatterns is restored');
+      equal(find('.frequency').val(), newApp.frequency, 'frequency is restored');
+      equal(find('.queueName').val(), newApp.queueName, 'queueName is restored');
+      equal(find('.special-label').val(), newApp.specialLabel, 'specialLabel is restored');
+    });
+  });
+
 });

+ 37 - 0
contrib/views/slider/src/main/resources/ui/test/unit/controllers/createAppWizard/step2_controller_test.js

@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF 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.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+moduleFor('controller:createAppWizardStep2', 'App.CreateAppWizardStep2Controller', {
+
+  needs: [
+    'controller:createAppWizard'
+  ]
+
+});
+
+test('isNotInteger', function () {
+
+  var controller = this.subject({});
+  equal(controller.isNotInteger('1'), false, 'Valid value');
+  equal(controller.isNotInteger('-1'), true, 'Invalid value (1)');
+  equal(controller.isNotInteger('bbb'), true, 'Invalid value (2)');
+  equal(controller.isNotInteger('1a'), true, 'Invalid value (3)');
+  equal(controller.isNotInteger('!@#$%^'), true, 'Invalid value (4)');
+  equal(controller.isNotInteger(null), true, 'Invalid value (5)');
+
+});