This is an automated email from the ASF dual-hosted git repository.

ishanbha pushed a commit to branch branch-feature-AMBARI-14714-ui
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/branch-feature-AMBARI-14714-ui 
by this push:
     new 6c23fb9  [AMBARI-22844] Install wizard mpack/service filter on 
selection screen (#232)
6c23fb9 is described below

commit 6c23fb90e8816414b06e5fc6450293f28ef926cb
Author: Jason Golieb <[email protected]>
AuthorDate: Thu Feb 1 11:39:21 2018 -0500

    [AMBARI-22844] Install wizard mpack/service filter on selection screen 
(#232)
    
    * AMBARI-22802 Styling for install wizard
    
    * Install services from multiple mpacks. Service groups are created with 
names hard-coded to be <mpackId>-<mpackVersion>.
    
    * Fixed unit tests.
    
    * Moved style changes out of bootstrap-ambari.css
    
    * Additional style tweaks.
    
    * Additional style tweaks.
    
    * Restore line removed by wrong conflict resolution.
    
    * More style tweaks.
    
    * Moved tooltip activation to individual components.
    
    * Implemented mpack and service filtering.
    
    * Unit tests
    
    * Merge branch 'branch-feature-AMBARI-14714-ui' into 
AMBARI-22804_multi-mpack-deployment
    
    # Conflicts:
    #   ambari-web/app/controllers/wizard/step7_controller.js
    #   ambari-web/app/styles/application.less
    #   ambari-web/app/styles/bootstrap_overrides.less
    #   ambari-web/app/styles/wizard.less
    #   ambari-web/app/templates/wizard/downloadMpacks.hbs
    #   ambari-web/app/templates/wizard/selectMpacks.hbs
    #   ambari-web/app/templates/wizard/verifyProducts.hbs
    
    * Unit tests.
    
    * Unit tests and minor tweaks.
    
    * Unit tests.
---
 ambari-web/app/assets/test/tests.js                |   6 +
 .../wizard/downloadMpacks_controller.js            |   2 -
 .../controllers/wizard/selectMpacks_controller.js  |  64 +++++++
 .../wizard/verifyProducts_controller.js            |   2 +-
 ambari-web/app/messages.js                         |   2 +
 ambari-web/app/styles/application.less             |  12 +-
 ambari-web/app/styles/widgets.less                 |   4 -
 ambari-web/app/styles/wizard.less                  |   4 +
 .../app/templates/wizard/customMpackRepos.hbs      |   4 +-
 .../app/templates/wizard/customProductRepos.hbs    |   4 +-
 ambari-web/app/templates/wizard/selectMpacks.hbs   |  20 ++-
 ambari-web/app/templates/wizard/verifyProducts.hbs |   2 +-
 ambari-web/test/controllers/installer_test.js      |  47 ++++++
 .../controllers/wizard/customProductRepos_test.js  |  80 +++++++++
 .../test/controllers/wizard/downloadMpacks_test.js |  87 ++++++++++
 .../test/controllers/wizard/selectMpacks_test.js   |  84 ++++++++++
 .../test/controllers/wizard/verifyProducts_test.js |  54 ++++++
 .../test/controllers/wizard/wizardStep_test.js     |  51 ++++++
 ambari-web/test/controllers/wizard_test.js         | 108 ++++++++++++
 .../views/wizard/configureDownload_view_test.js    |  13 +-
 .../views/wizard/customMpackRepos_view_test.js     |  44 +++++
 .../views/wizard/customProductRepos_view_test.js   | 185 +++++++++++++++++++++
 22 files changed, 851 insertions(+), 28 deletions(-)

diff --git a/ambari-web/app/assets/test/tests.js 
b/ambari-web/app/assets/test/tests.js
index cd31406..22f9e41 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -137,6 +137,10 @@ var files = [
   'test/controllers/wizard_test',
   'test/controllers/wizard/configureDownload_test',
   'test/controllers/wizard/selectMpacks_test',
+  'test/controllers/wizard/downloadMpacks_test',
+  'test/controllers/wizard/customProductRepos_test',
+  'test/controllers/wizard/verifyProducts_test',
+  'test/controllers/wizard/wizardStep_test',
   'test/controllers/wizard/step0_test',
   'test/controllers/wizard/step1_test',
   'test/controllers/wizard/step2_test',
@@ -390,6 +394,8 @@ var files = [
   'test/views/wizard/step3/hostWarningPopupBody_view_test',
   'test/views/wizard/step3/hostWarningPopupFooter_view_test',
   'test/views/wizard/configureDownload_view_test',
+  'test/views/wizard/customMpackRepos_view_test',
+  'test/views/wizard/customProductRepos_view_test',
   'test/views/wizard/step0_view_test',
   'test/views/wizard/step1_view_test',
   'test/views/wizard/step2_view_test',
diff --git a/ambari-web/app/controllers/wizard/downloadMpacks_controller.js 
b/ambari-web/app/controllers/wizard/downloadMpacks_controller.js
index 1266e24..717357e 100644
--- a/ambari-web/app/controllers/wizard/downloadMpacks_controller.js
+++ b/ambari-web/app/controllers/wizard/downloadMpacks_controller.js
@@ -64,7 +64,6 @@ App.WizardDownloadMpacksController = 
App.WizardStepController.extend({
   },
 
   downloadMpackSuccess: function (data, opt, params) {
-    console.dir("Mpack " + params.name + " download completed with success 
code " + data.status);
     this.get('mpacks').findProperty('name', params.name).set('succeeded', 
true);
     this.get('mpacks').findProperty('name', params.name).set('failed', false);
     this.get('mpacks').findProperty('name', params.name).set('inProgress', 
false);
@@ -74,7 +73,6 @@ App.WizardDownloadMpacksController = 
App.WizardStepController.extend({
     if(request.status == 409) {
       this.downloadMpackSuccess(request, opt, params);
     } else {
-      console.dir("Mpack " + params.name + " download failed with error code " 
+ request.status);
       this.get('mpacks').findProperty('name', params.name).set('succeeded', 
false);
       this.get('mpacks').findProperty('name', params.name).set('failed', true);
       this.get('mpacks').findProperty('name', params.name).set('inProgress', 
false);
diff --git a/ambari-web/app/controllers/wizard/selectMpacks_controller.js 
b/ambari-web/app/controllers/wizard/selectMpacks_controller.js
index da37323..56ef0ac 100644
--- a/ambari-web/app/controllers/wizard/selectMpacks_controller.js
+++ b/ambari-web/app/controllers/wizard/selectMpacks_controller.js
@@ -27,6 +27,14 @@ App.WizardSelectMpacksController = 
App.WizardStepController.extend({
 
   noRecommendationAvailable: false,
 
+  filterMpacksText: "",
+
+  filterServicesText: "",
+
+  filterMpacksPlaceholder: Em.I18n.t('installer.selectMpacks.filterMpacks'),
+
+  filterServicesPlaceholder: 
Em.I18n.t('installer.selectMpacks.filterServices'),
+
   loadRegistry: function () {
     return App.ajax.send({
       name: 'registry.all',
@@ -43,6 +51,15 @@ App.WizardSelectMpacksController = 
App.WizardStepController.extend({
             name: mpack.RegistryMpackInfo.mpack_name,
             displayName: mpack.RegistryMpackInfo.mpack_display_name,
             description: mpack.RegistryMpackInfo.mpack_description,
+            //this is the text that will be used to filter this mpack in the UI
+            //at this point, this is just the text that comes from this mpack
+            //but additional text will be appended to form the final filterOn 
value
+            //from the mpack's services, specifically the service name
+            filterOn: (
+              (mpack.RegistryMpackInfo.mpack_name || "") + " "
+              + (mpack.RegistryMpackInfo.mpack_display_name || "") + " "
+              + (mpack.RegistryMpackInfo.mpack_description || "")
+            ).toLowerCase(),
             logoUrl: mpack.RegistryMpackInfo.mpack_logo_url,
             versions: mpack.versions ? mpack.versions.map((version, index) => {
               return Em.Object.create({
@@ -93,10 +110,19 @@ App.WizardSelectMpacksController = 
App.WizardStepController.extend({
 
     const uniqueServices = {};
     mpackServiceVersions.forEach(service => {
+      //append service name to filterOn of the containing mpack
+      const mpackFilterOn = service.get('mpackVersion.mpack.filterOn');
+      service.set('mpackVersion.mpack.filterOn', ((mpackFilterOn) + " " + 
(service.name || "")).toLowerCase());
+
       uniqueServices[service.name] = Em.Object.create({
         name: service.name,
         displayName: service.displayName,
         description: service.description,
+        filterOn: (
+          (service.name || "") + " "
+          + (service.description || "") + " "
+          + (service.get('mpackVersion.mpack.displayName') || "" )
+        ).toLowerCase(),
         displayedVersion: function () {
           return this.get('versions').filterProperty('displayed')[0];
         }.property('[email protected]')
@@ -495,6 +521,44 @@ App.WizardSelectMpacksController = 
App.WizardStepController.extend({
     this.get('wizardController').setStepUnsaved('selectMpacks');
   },
 
+  filteredMpacks: function () {
+    const mpacks = this.get('content.mpacks');
+    const filterText = this.get('filterMpacksText').toLowerCase();
+
+    if (filterText.length > 2) {
+      const filteredMpacks = mpacks.filter(mpack => {
+        return mpack.get('filterOn').indexOf(filterText) > -1;
+      });
+    
+      return filteredMpacks;
+    }
+
+    return mpacks;
+  }.property('content.mpacks', 'filterMpacksText'),
+
+  clearFilterMpacks: function () {
+    this.set('filterMpacksText', "");
+  },
+
+  filteredServices: function () {
+    const services = this.get('content.mpackServices');
+    const filterText = this.get('filterServicesText').toLowerCase();
+
+    if (filterText.length > 2) {
+      const filteredServices = services.filter(service => {
+        return service.get('filterOn').indexOf(filterText) > -1;
+      });
+
+      return filteredServices;
+    }
+
+    return services;
+  }.property('content.mpackServices', 'filterServicesText'),
+
+  clearFilterServices: function () {
+    this.set('filterServicesText', "");
+  },
+
   /**
    * Onclick handler for <code>Next</code> button.
    * Disable 'Next' button while it is already under process. (using Router's 
property 'nextBtnClickInProgress')
diff --git a/ambari-web/app/controllers/wizard/verifyProducts_controller.js 
b/ambari-web/app/controllers/wizard/verifyProducts_controller.js
index 6b37509..3e3b600 100644
--- a/ambari-web/app/controllers/wizard/verifyProducts_controller.js
+++ b/ambari-web/app/controllers/wizard/verifyProducts_controller.js
@@ -91,7 +91,7 @@ App.WizardVerifyProductsController = 
App.WizardStepController.extend({
    */
   setRepoState: function (repo, state) {
     switch (state) {
-      case this.get('VERIFYREPO_INPROGRESS:'):
+      case this.get('VERIFYREPO_INPROGRESS'):
         repo.set('succeeded', false);
         repo.set('failed', false);
         repo.set('inProgress', true);
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index bba8fe7..acf2a00 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -638,6 +638,8 @@ Em.I18n.translations = {
   'installer.selectMpacks.advancedModeMessage': 'If you go back to use case 
selection, all current selections will be removed. Continue?',
   'installer.selectMpacks.basicModeHelp': 'This step lets you choose the use 
case(s) that fit your needs and the management packs that fulfill those use 
cases will be selected for you; however, if you would rather choose individual 
management packs and/or services directly, click this button. Be aware that if 
you return to use case selection mode, any selections you have made will be 
removed.',
   'installer.selectMpacks.advancedModeHelp': 'By clicking this button, you can 
return to use case selection mode. However, any existing selections will be 
removed.',
+  'installer.selectMpacks.filterMpacks': 'Search management packs',
+  'installer.selectMpacks.filterServices': 'Search services',
 
   'installer.configureDownload.header': 'Configure Download',
   'installer.configureDownload.body.title': 'Choose download method',
diff --git a/ambari-web/app/styles/application.less 
b/ambari-web/app/styles/application.less
index 5f6beae..535223c 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -2885,15 +2885,9 @@ td .no-data {
   }
 }
 
-.input-group.url-input {
-  width: 100%;
-
-  .input-group-btn {
-    width: 1%;
-
-    .revert-button {
-      padding: 0 10px;
-    }
+.input-group-btn {
+  .icon-button-addon {
+    padding: 0 10px;
   }
 }
 
diff --git a/ambari-web/app/styles/widgets.less 
b/ambari-web/app/styles/widgets.less
index 9bf60f0..5a77967 100644
--- a/ambari-web/app/styles/widgets.less
+++ b/ambari-web/app/styles/widgets.less
@@ -493,7 +493,3 @@
   background-color: rgba(211, 237, 247, 0.39);
   padding: 10px 5px 0 10px;
 }
-
-.input-group-btn {
-  width: auto;
-}
diff --git a/ambari-web/app/styles/wizard.less 
b/ambari-web/app/styles/wizard.less
index ad7fcb1..0209589 100644
--- a/ambari-web/app/styles/wizard.less
+++ b/ambari-web/app/styles/wizard.less
@@ -1023,4 +1023,8 @@
 .dropdown-menu input[type="checkbox"]:checked + label:after,
 .table input[type="checkbox"]:checked + label:after {
   line-height: 2;
+}
+
+.filter-input {
+  margin: 15px;
 }
\ No newline at end of file
diff --git a/ambari-web/app/templates/wizard/customMpackRepos.hbs 
b/ambari-web/app/templates/wizard/customMpackRepos.hbs
index 2b77b9f..ee3850e 100644
--- a/ambari-web/app/templates/wizard/customMpackRepos.hbs
+++ b/ambari-web/app/templates/wizard/customMpackRepos.hbs
@@ -41,10 +41,10 @@
               <a target="_blank" {{bindAttr href="mpack.publicUrl"}}><i 
class="icon icon-external-link"></i></a>
             </td>
             <td class="col-sm-6">
-              <div class="input-group url-input required">
+              <div class="input-group required">
                 {{view Em.TextField class="form-control" 
valueBinding="mpack.downloadUrl"}} 
                 <span class="input-group-btn">
-                  <button type="button" class="btn btn-default revert-button" 
{{bindAttr title="view.revertButtonTooltip" value="mpack.id"}} {{action 
revertUrl target="view"}}><i class="icon icon-rotate-left"></i></button>
+                  <button type="button" class="btn btn-default 
icon-button-addon" {{bindAttr title="view.revertButtonTooltip" 
value="mpack.id"}} {{action revertUrl target="view"}}><i class="icon 
icon-rotate-left"></i></button>
                 </span>
               </div>
             </td>
diff --git a/ambari-web/app/templates/wizard/customProductRepos.hbs 
b/ambari-web/app/templates/wizard/customProductRepos.hbs
index 20a488a..6b50276 100644
--- a/ambari-web/app/templates/wizard/customProductRepos.hbs
+++ b/ambari-web/app/templates/wizard/customProductRepos.hbs
@@ -77,10 +77,10 @@
                       <a target="_blank" {{bindAttr href="repo.publicUrl"}}><i 
class="icon icon-external-link"></i></a>
                     </td>
                     <td class="col-sm-7">
-                      <div class="input-group url-input required">
+                      <div class="input-group required">
                         {{view Em.TextField class="form-control" 
valueBinding="repo.downloadUrl"}}
                         <span class="input-group-btn">
-                          <button type="button" class="btn btn-default 
revert-button" {{bindAttr title="view.revertButtonTooltip" value="repo.id" }} 
{{action revertUrl target="view" }}>
+                          <button type="button" class="btn btn-default 
icon-button-addon" {{bindAttr title="view.revertButtonTooltip" value="repo.id" 
}} {{action revertUrl target="view" }}>
                             <i class="icon icon-rotate-left"></i>
                           </button>
                         </span>
diff --git a/ambari-web/app/templates/wizard/selectMpacks.hbs 
b/ambari-web/app/templates/wizard/selectMpacks.hbs
index 9a1bb7f..0c60a1e 100644
--- a/ambari-web/app/templates/wizard/selectMpacks.hbs
+++ b/ambari-web/app/templates/wizard/selectMpacks.hbs
@@ -54,9 +54,15 @@
       <div class="panel-body tab-content flex-fill">
         {{#if controller.content.advancedMode}}
         <div role="tabpanel" class="tab-pane active" id="mpacks">
+          <div class="input-group filter-input">
+            {{view Em.TextField class="form-control" 
valueBinding="controller.filterMpacksText" 
placeholderBinding="controller.filterMpacksPlaceholder"}}
+            <span class="input-group-btn">
+              <button class="btn btn-default icon-button-addon" type="button" 
{{action clearFilterMpacks target="controller"}}><span class="icon 
icon-rotate-left"></span></button>
+            </span>
+          </div>
           <div class="options-list">
-            {{#if controller.content.mpacks}}
-            {{#each mpack in controller.content.mpacks}}
+            {{#if controller.filteredMpacks}}
+            {{#each mpack in controller.filteredMpacks}}
             {{view App.WizardMpackView mpackBinding="mpack"}}
             {{/each}}
             {{else}}
@@ -65,9 +71,15 @@
           </div>
         </div>
         <div role="tabpanel" class="tab-pane" id="services">
+          <div class="input-group filter-input">
+            {{view Em.TextField class="form-control" 
valueBinding="controller.filterServicesText" 
placeholderBinding="controller.filterServicesPlaceholder"}}
+            <span class="input-group-btn">
+              <button class="btn btn-default icon-button-addon" type="button" 
{{action clearFilterServices target="controller"}}><span class="icon 
icon-rotate-left"></span></button>
+            </span>
+          </div>
           <div class="options-list">
-            {{#if controller.content.mpackServices}} 
-            {{#each service in controller.content.mpackServices}}
+            {{#if controller.filteredServices}} 
+            {{#each service in controller.filteredServices}}
             {{view App.WizardServiceView serviceBinding="service"}}
             {{/each}}
             {{else}}
diff --git a/ambari-web/app/templates/wizard/verifyProducts.hbs 
b/ambari-web/app/templates/wizard/verifyProducts.hbs
index a5a12ab..7182b7c 100644
--- a/ambari-web/app/templates/wizard/verifyProducts.hbs
+++ b/ambari-web/app/templates/wizard/verifyProducts.hbs
@@ -24,7 +24,7 @@
       {{#if App.router.nextBtnClickInProgress}}
       {{view App.SpinnerView}}
       {{else}}
-      <p class="step-description">{{t 
installer.customProductRepos.body.description}}</p>
+      <p class="step-description">{{t 
installer.verifyProducts.body.description}}</p>
         <table class="table table-hover">
           <thead>
             <tr>
diff --git a/ambari-web/test/controllers/installer_test.js 
b/ambari-web/test/controllers/installer_test.js
index 06eca32..9cf017e 100644
--- a/ambari-web/test/controllers/installer_test.js
+++ b/ambari-web/test/controllers/installer_test.js
@@ -1334,4 +1334,51 @@ describe('App.InstallerController', function () {
       expect(installerController.getStepSavedState('step0')).to.be.false;
     });
   });
+
+  describe('#hasErrors', function () {
+    before(function () {
+      installerController.addError("There is an error.");
+    });
+
+    it('Should return true if there are errors.', function () {
+      var hasErrors = installerController.get('hasErrors');
+
+      expect(hasErrors).to.be.true;
+    });
+
+    it('Should return false if there are no errors.', function () {
+      installerController.clearErrors();
+      var hasErrors = installerController.get('hasErrors');
+
+      expect(hasErrors).to.be.false;
+    });
+  });
+
+  describe('#getStepController', function () {
+    var wizardStep0Controller = {};
+    var wizardStep1Controller = {};
+    var wizardStep2Controller = {};
+
+    before(function () {
+      installerController.set('steps', [
+        "step0",
+        "step1",
+        "step2"
+      ]);
+
+      App.router.set('wizardStep0Controller', wizardStep0Controller);
+      App.router.set('wizardStep1Controller', wizardStep1Controller);
+      App.router.set('wizardStep2Controller', wizardStep2Controller);
+    });
+
+    it('Should return controller for the step number provided.', function () {
+      var stepController = installerController.getStepController(2);
+      expect(stepController).to.equal(wizardStep2Controller);
+    });
+
+    it('Should return controller for the step name provided.', function () {
+      var stepController = installerController.getStepController("step1");
+      expect(stepController).to.equal(wizardStep1Controller);
+    });
+  });
 });
diff --git a/ambari-web/test/controllers/wizard/customProductRepos_test.js 
b/ambari-web/test/controllers/wizard/customProductRepos_test.js
new file mode 100644
index 0000000..60cce4e
--- /dev/null
+++ b/ambari-web/test/controllers/wizard/customProductRepos_test.js
@@ -0,0 +1,80 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var controller = App.WizardCustomProductReposController.create({
+  operatingSystems: [
+    Em.Object.create({
+      type: 'alpha',
+      selected: true
+    }),
+    Em.Object.create({
+      type: 'bravo',
+      selected: false
+    })
+  ],
+  mpacks: [
+    {
+      operatingSystems: [
+        Em.Object.create({
+          type: 'charlie',
+          repos: [
+            Em.Object.create({
+              id: 0,
+              expected: true
+            }),
+            Em.Object.create({
+              id: 1,
+              expected: false
+            })
+          ]
+        })
+      ]
+    }
+  ]
+});
+
+describe('App.WizardCustomProductReposController', function () {
+  describe('#isOsSelected', function () {
+    it('Correctly reports whether an OS is selected', function () {
+      expect(controller.isOsSelected('alpha')).to.be.true;
+      expect(controller.isOsSelected('bravo')).to.be.false;
+      expect(controller.isOsSelected('charle')).to.be.false;
+    });
+  });  
+
+  describe('#anySelectedOs', function () {
+    it('Correctly reports whether any OS is selected', function () {
+      controller.get('operatingSystems')[0].set('selected', false);
+      expect(controller.get('anySelectedOs')).to.be.false;
+
+      controller.get('operatingSystems')[0].set('selected', true);
+      expect(controller.get('anySelectedOs')).to.be.true;
+    });
+  });  
+
+  describe('#findRepoById', function () {
+    //cannot be tested because the code under test uses for..of loops, so left 
it pending for now
+    it('Returns the repo with the given id');
+    //here's the test for when we can test it:
+    //function () {
+    //  var actual = controller.findRepoById(0);
+    //  expect(actual.get('expected')).to.be.true;
+    //} 
+  });  
+});
\ No newline at end of file
diff --git a/ambari-web/test/controllers/wizard/downloadMpacks_test.js 
b/ambari-web/test/controllers/wizard/downloadMpacks_test.js
new file mode 100644
index 0000000..953445e
--- /dev/null
+++ b/ambari-web/test/controllers/wizard/downloadMpacks_test.js
@@ -0,0 +1,87 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var controller = App.WizardDownloadMpacksController.create();
+
+describe('App.WizardConfigureDownloadController', function () {
+  beforeEach(function () {
+    var mpacks = [
+      Em.Object.create({
+        name: 'alpha',
+        succeeded: false,
+        failed: false,
+        inProgress: true
+      }),
+      Em.Object.create({
+        name: 'bravo',
+        succeeded: false,
+        failed: false,
+        inProgress: true
+      })
+    ];
+
+    controller.set('mpacks', mpacks);
+  })
+
+  describe('#downloadMpackSuccess', function () {
+    it('Sets succeeded to true, failed to false, and inProgress to false', 
function () {
+      var expected = Em.Object.create({
+        name: 'alpha',
+        succeeded: true,
+        failed: false,
+        inProgress: false
+      });
+
+      controller.downloadMpackSuccess({ status: 200 }, null, { name: 'alpha' 
});
+      var actual = controller.get('mpacks').objectAt(0);
+      
+      expect(actual).to.deep.equal(expected);
+    });
+  });
+
+  describe('#downloadMpackError', function () {
+    it('Sets succeeded to false, failed to true, and inProgress to false', 
function () {
+      var expected = Em.Object.create({
+        name: 'alpha',
+        succeeded: false,
+        failed: true,
+        inProgress: false
+      });
+
+      controller.downloadMpackError({ status: 500 }, null, null, null, { name: 
'alpha' });
+      var actual = controller.get('mpacks').objectAt(0);
+
+      expect(actual).to.deep.equal(expected);
+    });
+
+    it('Sets succeeded to true, failed to false, and inProgress to false on 
409 response', function () {
+      var expected = Em.Object.create({
+        name: 'alpha',
+        succeeded: true,
+        failed: false,
+        inProgress: false
+      });
+
+      controller.downloadMpackError({ status: 409 }, null, null, null, { name: 
'alpha' });
+      var actual = controller.get('mpacks').objectAt(0);
+
+      expect(actual).to.deep.equal(expected);
+    });
+  });
+});
\ No newline at end of file
diff --git a/ambari-web/test/controllers/wizard/selectMpacks_test.js 
b/ambari-web/test/controllers/wizard/selectMpacks_test.js
index 963a0f0..166289e 100644
--- a/ambari-web/test/controllers/wizard/selectMpacks_test.js
+++ b/ambari-web/test/controllers/wizard/selectMpacks_test.js
@@ -1166,4 +1166,88 @@ describe('App.WizardSelectMpacksController', function () 
{
       wizardSelectMpacksController.clearSelection.restore();
     });
   });
+
+  describe('#filteredMpacks', function () {
+    var mpacks = [
+      Em.Object.create({
+        filterOn: "alphabravo"
+      }),
+      Em.Object.create({
+        filterOn: "alphacharlie"
+      }),
+      Em.Object.create({
+        filterOn: "bravodelta"
+      })
+    ];
+    
+    beforeEach(function () {
+      wizardSelectMpacksController.set('content.mpacks', mpacks);
+      wizardSelectMpacksController.set('filterMpacksText', 'alpha');
+    })
+
+    it('should return the correctly filtered mpacks', function () {
+      var expected = [
+        Em.Object.create({
+          filterOn: "alphabravo"
+        }),
+        Em.Object.create({
+          filterOn: "alphacharlie"
+        })
+      ];
+
+      var actual = wizardSelectMpacksController.get('filteredMpacks');
+
+      expect(actual).to.deep.equal(expected);
+    });
+
+    it('should return all mpacks when there is no filter text', function () {
+      wizardSelectMpacksController.clearFilterMpacks();
+
+      var actual = wizardSelectMpacksController.get('filteredMpacks');
+
+      expect(actual).to.deep.equal(mpacks);
+    });
+  });
+
+  describe('#filteredServices', function () {
+    var services = [
+      Em.Object.create({
+        filterOn: "alphabravo"
+      }),
+      Em.Object.create({
+        filterOn: "alphacharlie"
+      }),
+      Em.Object.create({
+        filterOn: "bravodelta"
+      })
+    ];
+
+    beforeEach(function () {
+      wizardSelectMpacksController.set('content.mpackServices', services);
+      wizardSelectMpacksController.set('filterServicesText', 'alpha');
+    })
+
+    it('should return the correctly filtered services', function () {
+      var expected = [
+        Em.Object.create({
+          filterOn: "alphabravo"
+        }),
+        Em.Object.create({
+          filterOn: "alphacharlie"
+        })
+      ];
+
+      var actual = wizardSelectMpacksController.get('filteredServices');
+
+      expect(actual).to.deep.equal(expected);
+    });
+
+    it('should return all services when there is no filter text', function () {
+      wizardSelectMpacksController.clearFilterServices();
+
+      var actual = wizardSelectMpacksController.get('filteredServices');
+
+      expect(actual).to.deep.equal(services);
+    });
+  });
 });
diff --git a/ambari-web/test/controllers/wizard/verifyProducts_test.js 
b/ambari-web/test/controllers/wizard/verifyProducts_test.js
new file mode 100644
index 0000000..7992f9f
--- /dev/null
+++ b/ambari-web/test/controllers/wizard/verifyProducts_test.js
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var controller = App.WizardVerifyProductsController.create();
+
+describe('App.WizardVerifyProductsController', function () {
+  describe('#setRepoState', function () {
+    it('Sets repo state correctly', function () {
+      var actualInProgress = Em.Object.create({});
+      var actualSucceeded = Em.Object.create({});
+      var actualFailed = Em.Object.create({});
+
+      var expectedInProgress = Em.Object.create({
+        succeeded: false,
+        failed: false,
+        inProgress: true
+      });
+      var expectedSucceeded = Em.Object.create({
+        succeeded: true,
+        failed: false,
+        inProgress: false
+      });
+      var expectedFailed = Em.Object.create({
+        succeeded: false,
+        failed: true,
+        inProgress: false
+      });
+
+      controller.setRepoState(actualInProgress, 
controller.get('VERIFYREPO_INPROGRESS'));
+      controller.setRepoState(actualSucceeded, 
controller.get('VERIFYREPO_SUCCEEDED'));
+      controller.setRepoState(actualFailed, 
controller.get('VERIFYREPO_FAILED'));
+      
+      expect(actualInProgress).to.deep.equal(expectedInProgress);
+      expect(actualSucceeded).to.deep.equal(expectedSucceeded);
+      expect(actualFailed).to.deep.equal(expectedFailed);
+    });
+  });
+});
\ No newline at end of file
diff --git a/ambari-web/test/controllers/wizard/wizardStep_test.js 
b/ambari-web/test/controllers/wizard/wizardStep_test.js
new file mode 100644
index 0000000..25e3176
--- /dev/null
+++ b/ambari-web/test/controllers/wizard/wizardStep_test.js
@@ -0,0 +1,51 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var controller = App.WizardStepController.create({
+  wizardController: App.WizardController.create({
+    steps: [
+      'FirstStep',
+      'SecondStep',
+      'ThirdStep'
+    ],
+    currentStep: 1
+  })
+});
+
+describe('App.WizardStepController', function () {
+  describe('#isStepDisabled', function () {
+    it('Returns false when this step is before current step', function () {
+      controller.set('wizardController.stepName', 'FirstStep');
+      var actual = controller.isStepDisabled();
+      expect(actual).to.be.false;
+    });
+
+    it('Returns false when this step is the current step', function () {
+      controller.set('wizardController.stepName', 'SecondStep');
+      var actual = controller.isStepDisabled();
+      expect(actual).to.be.false;
+    });
+
+    it('Returns true when this step is after current step', function () {
+      controller.set('wizardController.stepName', 'ThirdStep');
+      var actual = controller.isStepDisabled();
+      expect(actual).to.be.false;
+    });
+  });
+});
\ No newline at end of file
diff --git a/ambari-web/test/controllers/wizard_test.js 
b/ambari-web/test/controllers/wizard_test.js
index 808e41e..461ad22 100644
--- a/ambari-web/test/controllers/wizard_test.js
+++ b/ambari-web/test/controllers/wizard_test.js
@@ -1828,5 +1828,113 @@ describe('App.WizardController', function () {
     });
   });
 
+  describe('#getPreviousStepName', function () {
+    var wizardController;
 
+    before(function () {
+      wizardController = App.WizardController.create({
+        currentStep: null,
+        steps: null
+      });
+      sinon.stub(wizardController, 'setStepsEnable');
+    });
+
+    afterEach(function () {
+      wizardController.set('steps', null);
+    });
+
+    it('Should return null when first step is current', function () {
+      wizardController.set('currentStep', 0);
+      
+      var stepName = wizardController.getPreviousStepName();
+      
+      expect(stepName).to.be.null;
+    });
+
+    it('Should return name of previous step when there is a steps array', 
function () {
+      var steps = [
+        'FirstStep',
+        'SecondStep',
+        'ThirdStep'
+      ];
+
+      wizardController.set('steps', steps);
+      wizardController.set('currentStep', 1);
+
+      var stepName = wizardController.getPreviousStepName();
+
+      expect(stepName).to.equal(steps[0]);
+    });
+
+    it('Should return step name of the form "step<x-1>" when there is no steps 
array', function () {
+      wizardController.set('currentStep', 1);
+
+      var stepName = wizardController.getPreviousStepName();
+
+      expect(stepName).to.equal("step0");
+    });
+  });
+
+  describe('#getNextStepName', function () {
+    var wizardController;
+
+    before(function () {
+      wizardController = App.WizardController.create({
+        currentStep: null,
+        steps: null
+      });
+      sinon.stub(wizardController, 'setStepsEnable');
+    });
+
+    afterEach(function () {
+      wizardController.set('steps', null);
+    });
+
+    it('Should return null when last step is current and there is no steps 
array', function () {
+      wizardController.set('totalSteps', 3);
+      wizardController.set('currentStep', 2);
+
+      var stepName = wizardController.getNextStepName();
+
+      expect(stepName).to.be.null;
+    });
+
+    it('Should return null when last step is current and there is a steps 
array', function () {
+      var steps = [
+        'FirstStep',
+        'SecondStep',
+        'ThirdStep'
+      ];
+
+      wizardController.set('steps', steps);
+      wizardController.set('currentStep', 2);
+
+      var stepName = wizardController.getNextStepName();
+
+      expect(stepName).to.be.null;
+    });
+
+    it('Should return name of next step when there is a steps array', function 
() {
+      var steps = [
+        'FirstStep',
+        'SecondStep',
+        'ThirdStep'
+      ];
+
+      wizardController.set('steps', steps);
+      wizardController.set('currentStep', 1);
+
+      var stepName = wizardController.getNextStepName();
+
+      expect(stepName).to.equal(steps[2]);
+    });
+
+    it('Should return step name of the form "step<x+1>" when there is no steps 
array', function () {
+      wizardController.set('currentStep', 1);
+
+      var stepName = wizardController.getNextStepName();
+
+      expect(stepName).to.equal("step2");
+    });
+  });
 });
diff --git a/ambari-web/test/views/wizard/configureDownload_view_test.js 
b/ambari-web/test/views/wizard/configureDownload_view_test.js
index 63c68e0..16992fa 100644
--- a/ambari-web/test/views/wizard/configureDownload_view_test.js
+++ b/ambari-web/test/views/wizard/configureDownload_view_test.js
@@ -36,16 +36,23 @@ describe('App.WizardConfigureDownloadView', function () {
   })
 
   describe('#useRedHatSatelliteChanged', function () {
-    it('Sets useProxy to false and calls useProxyChanged', function () {
+    it('Sets useProxy to false, calls useProxyChanged, and shows modal', 
function () {
       controller.set('content.downloadConfig.useProxy', true);
       sinon.stub(view, 'useProxyChanged');
-
-      view.useRedHatSatelliteChanged();
+      sinon.stub(App.ModalPopup, 'show');
+      
+      view.useRedHatSatelliteChanged({
+        currentTarget: {
+          checked: true
+        }
+      });
 
       expect(controller.get('content.downloadConfig.useProxy')).to.be.false;
       expect(view.useProxyChanged.called).to.be.true;
+      expect(App.ModalPopup.show.called).to.be.true;
 
       view.useProxyChanged.restore();
+      App.ModalPopup.show.restore();
     });
   });
 
diff --git a/ambari-web/test/views/wizard/customMpackRepos_view_test.js 
b/ambari-web/test/views/wizard/customMpackRepos_view_test.js
new file mode 100644
index 0000000..7c316f1
--- /dev/null
+++ b/ambari-web/test/views/wizard/customMpackRepos_view_test.js
@@ -0,0 +1,44 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var controller = App.WizardCustomMpackReposController.create({ mpacks: [] });
+var view = App.WizardCustomMpackReposView.create({ controller: controller });
+
+describe('App.WizardCustomMpackReposView', function () {
+  describe('#revertUrl', function () {
+    it('Sets downloadUrl to the value of publicUrl', function () {
+      var mpacks = [
+        Em.Object.create({
+          id: 0,
+          downloadUrl: 'downloadUrl',
+          publicUrl: 'publicUrl'
+        })
+      ];
+      controller.set('mpacks', mpacks);
+
+      view.revertUrl({
+        currentTarget: {
+          value: 0
+        }
+      });
+
+      
expect(mpacks[0].get('downloadUrl')).to.equal(mpacks[0].get('publicUrl'));
+    });
+  });
+});
\ No newline at end of file
diff --git a/ambari-web/test/views/wizard/customProductRepos_view_test.js 
b/ambari-web/test/views/wizard/customProductRepos_view_test.js
new file mode 100644
index 0000000..8f691a3
--- /dev/null
+++ b/ambari-web/test/views/wizard/customProductRepos_view_test.js
@@ -0,0 +1,185 @@
+/**
+ * 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.
+ */
+
+var App = require('app');
+var controller = App.WizardCustomProductReposController.create({
+  operatingSystems: [
+    Em.Object.create({
+      type: 'alpha',
+      selected: false,
+      mpacks: [
+        Em.Object.create({
+          id: '0-alpha',
+          operatingSystems: [
+            Em.Object.create({
+              type: 'alpha',
+              selected: false,
+              isFirstSelected: false,
+              isLastSelected: false
+            }),
+            Em.Object.create({
+              type: 'bravo',
+              selected: true,
+              isFirstSelected: true,
+              isLastSelected: true
+            })
+          ]
+        }),
+        Em.Object.create({
+          id: '1-alpha',
+          operatingSystems: [
+            Em.Object.create({
+              type: 'alpha',
+              selected: false,
+              isFirstSelected: false,
+              isLastSelected: false
+            }),
+            Em.Object.create({
+              type: 'bravo',
+              selected: true,
+              isFirstSelected: true,
+              isLastSelected: true
+            })
+          ]
+        })
+      ]
+    }),
+    Em.Object.create({
+      type: 'bravo',
+      selected: true,
+      mpacks: [
+        Em.Object.create({
+          id: '0-bravo',
+          operatingSystems: [
+            Em.Object.create({
+              type: 'alpha',
+              selected: false,
+              isFirstSelected: false,
+              isLastSelected: false
+            }),
+            Em.Object.create({
+              type: 'bravo',
+              selected: true,
+              isFirstSelected: true,
+              isLastSelected: true
+            })
+          ]
+        }),
+        Em.Object.create({
+          id: '1-bravo',
+          operatingSystems: [
+            Em.Object.create({
+              type: 'alpha',
+              selected: false,
+              isFirstSelected: false,
+              isLastSelected: false
+            }),
+            Em.Object.create({
+              type: 'bravo',
+              selected: true,
+              isFirstSelected: true,
+              isLastSelected: true
+            })
+          ]
+        })
+      ]
+    })
+  ]
+});
+var view = App.WizardCustomProductReposView.create({ controller: controller, 
parentView: {} });
+
+describe('App.WizardCustomProductReposView', function () {
+  describe('#revertUrl', function () {
+    it('Sets downloadUrl to the value of publicUrl', function () {
+      var repo = Em.Object.create({
+        id: 0,
+        downloadUrl: 'downloadUrl',
+        publicUrl: 'publicUrl'
+      });
+      sinon.stub(view.get('controller'), 'findRepoById').returns(repo);
+
+      view.revertUrl({
+        currentTarget: {
+          value: 0
+        }
+      });
+
+      expect(repo.get('downloadUrl')).to.equal(repo.get('publicUrl'));
+    });
+  });
+
+  describe('#selectedOsChanged', function () {
+    before(function () {
+      view.set('parentView', view);
+    });
+
+    it('Correctly toggles the OS when it was previously unselected.', function 
() {
+      view.get('controller.operatingSystems')[0].set('selected', true);
+      view.selectedOsChanged({
+        srcElement: {
+          name: 'alpha'
+        }
+      });
+
+      var actual = view.get('controller.operatingSystems');
+
+      //checking that controller.toggleOs() worked
+      
expect(actual[0].get('mpacks')[0].get('operatingSystems')[0].get('selected')).to.be.true;
+      
expect(actual[0].get('mpacks')[1].get('operatingSystems')[0].get('selected')).to.be.true;
+
+      //checking that view.updateOsState() worked
+      
expect(actual[0].get('mpacks')[0].get('operatingSystems')[0].get('isFirstSelected')).to.be.true;
+      
expect(actual[0].get('mpacks')[0].get('operatingSystems')[0].get('isLastSelected')).to.be.false;
+      
expect(actual[0].get('mpacks')[0].get('operatingSystems')[1].get('isFirstSelected')).to.be.false;
+      
expect(actual[0].get('mpacks')[0].get('operatingSystems')[1].get('isLastSelected')).to.be.true;
+
+      
expect(actual[0].get('mpacks')[1].get('operatingSystems')[0].get('isFirstSelected')).to.be.true;
+      
expect(actual[0].get('mpacks')[1].get('operatingSystems')[0].get('isLastSelected')).to.be.false;
+      
expect(actual[0].get('mpacks')[1].get('operatingSystems')[1].get('isFirstSelected')).to.be.false;
+      
expect(actual[0].get('mpacks')[1].get('operatingSystems')[1].get('isLastSelected')).to.be.true;
+    });
+
+    it('Correctly toggles the OS when it was previously selected.', function 
() {
+      view.get('controller.operatingSystems')[1].set('selected', false);
+      view.selectedOsChanged({
+        srcElement: {
+          name: 'bravo'
+        }
+      });
+
+      var actual = view.get('controller.operatingSystems');
+
+      //checking that controller.toggleOs() worked
+      
expect(actual[1].get('mpacks')[0].get('operatingSystems')[0].get('selected')).to.be.false;
+      
expect(actual[1].get('mpacks')[1].get('operatingSystems')[0].get('selected')).to.be.false;
+
+      //checking that view.updateOsState() worked
+      //actually, it will change nothing because nothing is selected for OS 
"bravo" now
+      
expect(actual[1].get('mpacks')[0].get('operatingSystems')[0].get('isFirstSelected')).to.be.false;
+      
expect(actual[1].get('mpacks')[0].get('operatingSystems')[0].get('isLastSelected')).to.be.false;
+      
expect(actual[1].get('mpacks')[0].get('operatingSystems')[1].get('isFirstSelected')).to.be.true;
+      
expect(actual[1].get('mpacks')[0].get('operatingSystems')[1].get('isLastSelected')).to.be.true;
+
+      
expect(actual[1].get('mpacks')[1].get('operatingSystems')[0].get('isFirstSelected')).to.be.false;
+      
expect(actual[1].get('mpacks')[1].get('operatingSystems')[0].get('isLastSelected')).to.be.false;
+      
expect(actual[1].get('mpacks')[1].get('operatingSystems')[1].get('isFirstSelected')).to.be.true;
+      
expect(actual[1].get('mpacks')[1].get('operatingSystems')[1].get('isLastSelected')).to.be.true;
+    });
+
+  });
+});
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to