diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js index cd31406cec7..22f9e415ad1 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 1266e24dc54..717357e2949 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 da373235687..56ef0acb6db 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('versions.@each.displayed') @@ -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 Next 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 6b375096123..3e3b6002ee7 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 bba8fe76003..acf2a002eb3 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 5f6beae890a..535223c6be9 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 9bf60f0673d..5a77967e8d5 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 ad7fcb1132a..0209589fccc 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 2b77b9f6e29..ee3850e338b 100644 --- a/ambari-web/app/templates/wizard/customMpackRepos.hbs +++ b/ambari-web/app/templates/wizard/customMpackRepos.hbs @@ -41,10 +41,10 @@ -
+
{{view Em.TextField class="form-control" valueBinding="mpack.downloadUrl"}} - +
diff --git a/ambari-web/app/templates/wizard/customProductRepos.hbs b/ambari-web/app/templates/wizard/customProductRepos.hbs index 20a488a7a9c..6b502762030 100644 --- a/ambari-web/app/templates/wizard/customProductRepos.hbs +++ b/ambari-web/app/templates/wizard/customProductRepos.hbs @@ -77,10 +77,10 @@ -
+
{{view Em.TextField class="form-control" valueBinding="repo.downloadUrl"}} - diff --git a/ambari-web/app/templates/wizard/selectMpacks.hbs b/ambari-web/app/templates/wizard/selectMpacks.hbs index 9a1bb7fb8a4..0c60a1eca64 100644 --- a/ambari-web/app/templates/wizard/selectMpacks.hbs +++ b/ambari-web/app/templates/wizard/selectMpacks.hbs @@ -54,9 +54,15 @@
{{#if controller.content.advancedMode}}
+
+ {{view Em.TextField class="form-control" valueBinding="controller.filterMpacksText" placeholderBinding="controller.filterMpacksPlaceholder"}} + + + +
- {{#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 @@
+
+ {{view Em.TextField class="form-control" valueBinding="controller.filterServicesText" placeholderBinding="controller.filterServicesPlaceholder"}} + + + +
- {{#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 a5a12abd73a..7182b7c19bd 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}} -

{{t installer.customProductRepos.body.description}}

+

{{t installer.verifyProducts.body.description}}

diff --git a/ambari-web/test/controllers/installer_test.js b/ambari-web/test/controllers/installer_test.js index 06eca3202a1..9cf017edd74 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 00000000000..60cce4ef31b --- /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 00000000000..953445eb857 --- /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 963a0f0aa07..166289ea3df 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 00000000000..7992f9f7dc6 --- /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 00000000000..25e3176bd6e --- /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 808e41e9c8b..461ad22f4f8 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" 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" 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 63c68e05f2c..16992fa2297 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 00000000000..7c316f16add --- /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 00000000000..8f691a3b1da --- /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