From c0f4ee6e07d198421019269d2a74e9abcaabff5f Mon Sep 17 00:00:00 2001 From: Shaoquan Chen Date: Mon, 29 Jun 2015 13:39:59 -0700 Subject: [PATCH] JSCS cleanup - launch-instance.js This patch breaks up launc-instance.js into small pieces according to Horizon code style. Change-Id: I852943a5223289391b1b8a315be80a48dcd39fb6 Partially-Implements: blueprint jscs-cleanup --- .../project/images/images/tables.py | 2 +- .../dashboards/project/instances/tables.py | 2 +- .../templates/network_topology/index.html | 2 +- openstack_dashboard/enabled/_10_project.py | 14 +- openstack_dashboard/karma.conf.js | 1 - .../launch-instance-modal.controller.js | 57 +++++ .../launch-instance-modal.controller.spec.js | 118 +++++++++ ...ance.model.js => launch-instance-model.js} | 0 ....spec.js => launch-instance-model.spec.js} | 0 .../launch-instance-wizard.controller.js | 36 +++ .../launch-instance-wizard.controller.spec.js | 61 +++++ .../launch-instance-workflow.service.js | 82 ++++++ .../launch-instance-workflow.service.spec.js | 70 ++++++ .../launch-instance/launch-instance.js | 153 ------------ .../launch-instance/launch-instance.module.js | 64 +++++ .../launch-instance.module.spec.js | 40 +++ .../launch-instance/launch-instance.spec.js | 233 ------------------ .../source/source.controller.js | 2 +- .../launch-instance/source/source.spec.js | 2 +- 19 files changed, 543 insertions(+), 396 deletions(-) create mode 100644 openstack_dashboard/static/dashboard/launch-instance/launch-instance-modal.controller.js create mode 100644 openstack_dashboard/static/dashboard/launch-instance/launch-instance-modal.controller.spec.js rename openstack_dashboard/static/dashboard/launch-instance/{launch-instance.model.js => launch-instance-model.js} (100%) rename openstack_dashboard/static/dashboard/launch-instance/{launch-instance.model.spec.js => launch-instance-model.spec.js} (100%) create mode 100644 openstack_dashboard/static/dashboard/launch-instance/launch-instance-wizard.controller.js create mode 100644 openstack_dashboard/static/dashboard/launch-instance/launch-instance-wizard.controller.spec.js create mode 100644 openstack_dashboard/static/dashboard/launch-instance/launch-instance-workflow.service.js create mode 100644 openstack_dashboard/static/dashboard/launch-instance/launch-instance-workflow.service.spec.js delete mode 100644 openstack_dashboard/static/dashboard/launch-instance/launch-instance.js create mode 100644 openstack_dashboard/static/dashboard/launch-instance/launch-instance.module.js create mode 100644 openstack_dashboard/static/dashboard/launch-instance/launch-instance.module.spec.js delete mode 100644 openstack_dashboard/static/dashboard/launch-instance/launch-instance.spec.js diff --git a/openstack_dashboard/dashboards/project/images/images/tables.py b/openstack_dashboard/dashboards/project/images/images/tables.py index a18733ebc4..06f6961689 100644 --- a/openstack_dashboard/dashboards/project/images/images/tables.py +++ b/openstack_dashboard/dashboards/project/images/images/tables.py @@ -65,7 +65,7 @@ class LaunchImageNG(LaunchImage): def __init__(self, attrs=None, **kwargs): if attrs is None: - attrs = {"ng-controller": "LaunchInstanceModalCtrl"} + attrs = {"ng-controller": "LaunchInstanceModalController"} kwargs['preempt'] = True super(LaunchImage, self).__init__(attrs, **kwargs) diff --git a/openstack_dashboard/dashboards/project/instances/tables.py b/openstack_dashboard/dashboards/project/instances/tables.py index 71e97005dc..95f51c05b5 100644 --- a/openstack_dashboard/dashboards/project/instances/tables.py +++ b/openstack_dashboard/dashboards/project/instances/tables.py @@ -354,7 +354,7 @@ class LaunchLinkNG(LaunchLink): def __init__(self, attrs={ - "ng-controller": "LaunchInstanceModalCtrl", + "ng-controller": "LaunchInstanceModalController", "ng-click": "openLaunchInstanceWizard(" + "{successUrl: '/project/instances/'})" }, diff --git a/openstack_dashboard/dashboards/project/network_topology/templates/network_topology/index.html b/openstack_dashboard/dashboards/project/network_topology/templates/network_topology/index.html index efcc228cb0..95ecb33150 100644 --- a/openstack_dashboard/dashboards/project/network_topology/templates/network_topology/index.html +++ b/openstack_dashboard/dashboards/project/network_topology/templates/network_topology/index.html @@ -29,7 +29,7 @@
{% if launch_instance_allowed %} {% if show_ng_launch %} - {% if instance_quota_exceeded %}{% trans "Launch Instance (Quota exceeded)"%}{% else %}{% trans "Launch Instance"%}{% endif %} + {% if instance_quota_exceeded %}{% trans "Launch Instance (Quota exceeded)"%}{% else %}{% trans "Launch Instance"%}{% endif %} {% endif %} {% if instance_quota_exceeded %}{% trans "Launch Instance (Quota exceeded)"%}{% else %}{% trans "Launch Instance"%}{% endif %} {% endif %} diff --git a/openstack_dashboard/enabled/_10_project.py b/openstack_dashboard/enabled/_10_project.py index 9a7df090fa..a768372d08 100644 --- a/openstack_dashboard/enabled/_10_project.py +++ b/openstack_dashboard/enabled/_10_project.py @@ -31,8 +31,11 @@ ADD_JS_FILES = [ 'dashboard/workflow/decorator.service.js', 'dashboard/workflow/workflow.service.js', 'dashboard/cloud-services/cloud-services.js', - LAUNCH_INST + 'launch-instance.js', - LAUNCH_INST + 'launch-instance.model.js', + LAUNCH_INST + 'launch-instance.module.js', + LAUNCH_INST + 'launch-instance-workflow.service.js', + LAUNCH_INST + 'launch-instance-modal.controller.js', + LAUNCH_INST + 'launch-instance-wizard.controller.js', + LAUNCH_INST + 'launch-instance-model.js', LAUNCH_INST + 'source/source.controller.js', LAUNCH_INST + 'source/source-help.controller.js', LAUNCH_INST + 'flavor/flavor.controller.js', @@ -54,8 +57,11 @@ ADD_JS_SPEC_FILES = [ 'dashboard/dashboard.module.spec.js', 'dashboard/workflow/workflow.module.spec.js', 'dashboard/cloud-services/cloud-services.spec.js', - LAUNCH_INST + 'launch-instance.spec.js', - LAUNCH_INST + 'launch-instance.model.spec.js', + LAUNCH_INST + 'launch-instance.module.spec.js', + LAUNCH_INST + 'launch-instance-workflow.service.spec.js', + LAUNCH_INST + 'launch-instance-modal.controller.spec.js', + LAUNCH_INST + 'launch-instance-wizard.controller.spec.js', + LAUNCH_INST + 'launch-instance-model.spec.js', LAUNCH_INST + 'source/source.spec.js', LAUNCH_INST + 'flavor/flavor.spec.js', LAUNCH_INST + 'network/network.spec.js', diff --git a/openstack_dashboard/karma.conf.js b/openstack_dashboard/karma.conf.js index b4bf321f6e..aa1baa4be0 100644 --- a/openstack_dashboard/karma.conf.js +++ b/openstack_dashboard/karma.conf.js @@ -91,7 +91,6 @@ module.exports = function (config) { * not significant. */ '**/*.module.js', - '**/launch-instance.js', /** * Followed by other JavaScript files that defines angular providers diff --git a/openstack_dashboard/static/dashboard/launch-instance/launch-instance-modal.controller.js b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-modal.controller.js new file mode 100644 index 0000000000..99080354f3 --- /dev/null +++ b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-modal.controller.js @@ -0,0 +1,57 @@ +/* + * (c) Copyright 2015 Hewlett-Packard Development Company, L.P. + * + * Licensed 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. + */ +(function () { + 'use strict'; + + angular + .module('hz.dashboard.launch-instance') + .controller('LaunchInstanceModalController', LaunchInstanceModalController); + + LaunchInstanceModalController.$inject = [ + '$scope', + '$modal', + '$window', + 'hz.dashboard.launch-instance.modal-spec' + ]; + + function LaunchInstanceModalController($scope, $modal, $window, modalSpec) { + $scope.openLaunchInstanceWizard = openLaunchInstanceWizard; + + function openLaunchInstanceWizard(launchContext) { + var localSpec = { + resolve: { + launchContext: function () { + return launchContext; + } + } + }; + angular.extend(localSpec, modalSpec); + var launchInstanceModal = $modal.open(localSpec); + var handleModalClose = function (redirectPropertyName) { + return function () { + if (launchContext && launchContext[redirectPropertyName]) { + $window.location.href = launchContext[redirectPropertyName]; + } + }; + }; + launchInstanceModal.result.then( + handleModalClose('successUrl'), + handleModalClose('dismissUrl') + ); + } + } + +})(); diff --git a/openstack_dashboard/static/dashboard/launch-instance/launch-instance-modal.controller.spec.js b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-modal.controller.spec.js new file mode 100644 index 0000000000..f72ef18680 --- /dev/null +++ b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-modal.controller.spec.js @@ -0,0 +1,118 @@ +/* + * (c) Copyright 2015 Hewlett-Packard Development Company, L.P. + * + * Licensed 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. + */ +(function () { + 'use strict'; + + describe('LaunchInstanceModalController tests', function() { + var ctrl; + var modal; + var scope; + var $window; + + beforeEach(module('hz.dashboard')); + beforeEach(module(function($provide) { + modal = { + open: function() { + return { + result: { + then: angular.noop + } + }; + } + }; + $window = { location: { href: '/' } }; + $provide.value('$modal', modal); + $provide.value('$modalSpec', {}); + $provide.value('$window', $window); + })); + + beforeEach(inject(function($controller) { + scope = {}; + ctrl = $controller('LaunchInstanceModalController', { $scope: scope }); + })); + + it('defines the controller', function() { + expect(ctrl).toBeDefined(); + }); + + it('defines openLaunchInstanceWizard', function() { + expect(scope.openLaunchInstanceWizard).toBeDefined(); + }); + + describe('openLaunchInstanceWizard function tests', function() { + var func; + var launchContext; + + beforeEach(function() { + func = scope.openLaunchInstanceWizard; + launchContext = {}; + }); + + it('calls modal.open', function() { + spyOn(modal, 'open').and.returnValue({ result: { then: angular.noop } }); + func(launchContext); + expect(modal.open).toHaveBeenCalled(); + }); + + it('calls modal.open with expected values', function() { + spyOn(modal, 'open').and.returnValue({ result: { then: angular.noop } }); + launchContext = { info: 'information' }; + func(launchContext); + + var resolve = modal.open.calls.argsFor(0)[0].resolve; + expect(resolve).toBeDefined(); + expect(resolve.launchContext).toBeDefined(); + expect(resolve.launchContext()).toEqual({ info: 'information' }); + }); + + it('sets up the correct success and failure paths', function() { + var successFunc; + var errFunc; + + launchContext = { successUrl: '/good/path', dismissUrl: '/bad/path' }; + spyOn(modal, 'open').and + .returnValue({ + result: { + then: function(x, y) { successFunc = x; errFunc = y; } + } + }); + func(launchContext); + successFunc('successUrl'); + expect($window.location.href).toBe('/good/path'); + errFunc('dismissUrl'); + expect($window.location.href).toBe('/bad/path'); + }); + + it("doesn't redirect if not configured to", function() { + var successFunc; + var errFunc; + launchContext = {}; + spyOn(modal, 'open').and + .returnValue({ + result: { + then: function(x, y) { successFunc = x; errFunc = y; } + } + }); + func(launchContext); + successFunc('successUrl'); + expect($window.location.href).toBe('/'); + errFunc('dismissUrl'); + expect($window.location.href).toBe('/'); + }); + }); + }); + +})(); diff --git a/openstack_dashboard/static/dashboard/launch-instance/launch-instance.model.js b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-model.js similarity index 100% rename from openstack_dashboard/static/dashboard/launch-instance/launch-instance.model.js rename to openstack_dashboard/static/dashboard/launch-instance/launch-instance-model.js diff --git a/openstack_dashboard/static/dashboard/launch-instance/launch-instance.model.spec.js b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-model.spec.js similarity index 100% rename from openstack_dashboard/static/dashboard/launch-instance/launch-instance.model.spec.js rename to openstack_dashboard/static/dashboard/launch-instance/launch-instance-model.spec.js diff --git a/openstack_dashboard/static/dashboard/launch-instance/launch-instance-wizard.controller.js b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-wizard.controller.js new file mode 100644 index 0000000000..c657b65b96 --- /dev/null +++ b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-wizard.controller.js @@ -0,0 +1,36 @@ +/* + * (c) Copyright 2015 Hewlett-Packard Development Company, L.P. + * + * Licensed 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. + */ +(function () { + 'use strict'; + + angular + .module('hz.dashboard.launch-instance') + .controller('LaunchInstanceWizardController', LaunchInstanceWizardController); + + LaunchInstanceWizardController.$inject = [ + '$scope', + 'launchInstanceModel', + 'hz.dashboard.launch-instance.workflow' + ]; + + function LaunchInstanceWizardController($scope, launchInstanceModel, launchInstanceWorkflow) { + $scope.workflow = launchInstanceWorkflow; + $scope.model = launchInstanceModel; + $scope.model.initialize(true); + $scope.submit = $scope.model.createInstance; + } + +})(); diff --git a/openstack_dashboard/static/dashboard/launch-instance/launch-instance-wizard.controller.spec.js b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-wizard.controller.spec.js new file mode 100644 index 0000000000..dc48cb464d --- /dev/null +++ b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-wizard.controller.spec.js @@ -0,0 +1,61 @@ +/* + * (c) Copyright 2015 Hewlett-Packard Development Company, L.P. + * + * Licensed 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. + */ +(function () { + 'use strict'; + + describe('LaunchInstanceWizardController tests', function() { + var ctrl; + var model = { + createInstance: function() { + return 'created'; + }, + initialize: angular.noop + }; + var scope = {}; + + beforeEach(module('hz.dashboard')); + beforeEach(module(function ($provide) { + $provide.value('serviceCatalog', {}); + $provide.value('launchInstanceModel', model); + $provide.value('hz.dashboard.launch-instance.workflow', { thing: true }); + })); + beforeEach(inject(function ($controller) { + spyOn(model, 'initialize'); + var locals = { + $scope: scope + }; + ctrl = $controller('LaunchInstanceWizardController', locals); + })); + + it('defines the controller', function() { + expect(ctrl).toBeDefined(); + }); + + it('calls initialize on the given model', function() { + expect(scope.model.initialize).toHaveBeenCalled(); + }); + + it('sets scope.workflow to the given workflow', function() { + expect(scope.workflow).toEqual({ thing: true }); + }); + + it('defines scope.submit', function() { + expect(scope.submit).toBeDefined(); + expect(scope.submit()).toBe('created'); + }); + }); + +})(); diff --git a/openstack_dashboard/static/dashboard/launch-instance/launch-instance-workflow.service.js b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-workflow.service.js new file mode 100644 index 0000000000..bb00d1274f --- /dev/null +++ b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-workflow.service.js @@ -0,0 +1,82 @@ +/* + * (c) Copyright 2015 Hewlett-Packard Development Company, L.P. + * + * Licensed 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. + */ +(function () { + 'use strict'; + + angular + .module('hz.dashboard.launch-instance') + .factory('hz.dashboard.launch-instance.workflow', launchInstanceWorkflow); + + launchInstanceWorkflow.$inject = [ + 'dashboardBasePath', + 'hz.dashboard.workflow.factory' + ]; + + function launchInstanceWorkflow(path, dashboardWorkflow) { + return dashboardWorkflow({ + title: gettext('Launch Instance'), + + steps: [ + { + title: gettext('Select Source'), + templateUrl: path + 'launch-instance/source/source.html', + helpUrl: path + 'launch-instance/source/source.help.html', + formName: 'launchInstanceSourceForm' + }, + { + title: gettext('Flavor'), + templateUrl: path + 'launch-instance/flavor/flavor.html', + helpUrl: path + 'launch-instance/flavor/flavor.help.html', + formName: 'launchInstanceFlavorForm' + }, + { + title: gettext('Networks'), + templateUrl: path + 'launch-instance/network/network.html', + helpUrl: path + 'launch-instance/network/network.help.html', + formName: 'launchInstanceNetworkForm', + requiredServiceTypes: ['network'] + }, + { + title: gettext('Security Groups'), + templateUrl: path + 'launch-instance/security-groups/security-groups.html', + helpUrl: path + 'launch-instance/security-groups/security-groups.help.html', + formName: 'launchInstanceAccessAndSecurityForm' + }, + { + title: gettext('Key Pair'), + templateUrl: path + 'launch-instance/keypair/keypair.html', + helpUrl: path + 'launch-instance/keypair/keypair.help.html', + formName: 'launchInstanceKeypairForm' + }, + { + title: gettext('Configuration'), + templateUrl: path + 'launch-instance/configuration/configuration.html', + helpUrl: path + 'launch-instance/configuration/configuration.help.html', + formName: 'launchInstanceConfigurationForm' + } + ], + + btnText: { + finish: gettext('Launch Instance') + }, + + btnIcon: { + finish: 'fa fa-cloud-download' + } + }); + } + +})(); diff --git a/openstack_dashboard/static/dashboard/launch-instance/launch-instance-workflow.service.spec.js b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-workflow.service.spec.js new file mode 100644 index 0000000000..9ee5a3ecaf --- /dev/null +++ b/openstack_dashboard/static/dashboard/launch-instance/launch-instance-workflow.service.spec.js @@ -0,0 +1,70 @@ +/* + * (c) Copyright 2015 Hewlett-Packard Development Company, L.P. + * + * Licensed 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. + */ +(function() { + 'use strict'; + + describe('hz.dashboard.launch-instance.workflow tests', function () { + var launchInstanceWorkflow; + + beforeEach(module('hz.dashboard')); + beforeEach(module(function($provide) { + // Need to mock hz.framework.workflow from 'horizon' + var workflow = function(spec, decorators) { + angular.forEach(decorators, function(decorator) { + decorator(spec); + }); + return spec; + }; + $provide.value('horizon.openstack-service-api.serviceCatalog', {}); + $provide.value('horizon.framework.util.workflow.service', workflow); + })); + + beforeEach(inject(function ($injector) { + launchInstanceWorkflow = $injector.get('hz.dashboard.launch-instance.workflow'); + })); + + it('should be defined', function () { + expect(launchInstanceWorkflow).toBeDefined(); + }); + + it('should have a title property', function () { + expect(launchInstanceWorkflow.title).toBeDefined(); + }); + + it('should have the six steps defined', function () { + expect(launchInstanceWorkflow.steps).toBeDefined(); + expect(launchInstanceWorkflow.steps.length).toBe(6); + + var forms = [ + 'launchInstanceSourceForm', + 'launchInstanceFlavorForm', + 'launchInstanceNetworkForm', + 'launchInstanceAccessAndSecurityForm', + 'launchInstanceKeypairForm', + 'launchInstanceConfigurationForm' + ]; + + forms.forEach(function(expectedForm, idx) { + expect(launchInstanceWorkflow.steps[idx].formName).toBe(expectedForm); + }); + }); + + it('specifies that the network step requires the network service type', function() { + expect(launchInstanceWorkflow.steps[2].requiredServiceTypes).toEqual(['network']); + }); + }); + +})(); diff --git a/openstack_dashboard/static/dashboard/launch-instance/launch-instance.js b/openstack_dashboard/static/dashboard/launch-instance/launch-instance.js deleted file mode 100644 index 7ff351bd1b..0000000000 --- a/openstack_dashboard/static/dashboard/launch-instance/launch-instance.js +++ /dev/null @@ -1,153 +0,0 @@ -(function () { - 'use strict'; - - var module = angular.module('hz.dashboard.launch-instance', [ 'ngSanitize' ]); - - module.factory('launchInstanceWorkflow', [ - 'dashboardBasePath', - 'hz.dashboard.workflow.factory', - - function (path, dashboardWorkflow) { - - return dashboardWorkflow({ - title: gettext('Launch Instance'), - - steps: [ - { - title: gettext('Select Source'), - templateUrl: path + 'launch-instance/source/source.html', - helpUrl: path + 'launch-instance/source/source.help.html', - formName: 'launchInstanceSourceForm' - }, - { - title: gettext('Flavor'), - templateUrl: path + 'launch-instance/flavor/flavor.html', - helpUrl: path + 'launch-instance/flavor/flavor.help.html', - formName: 'launchInstanceFlavorForm' - }, - { - title: gettext('Networks'), - templateUrl: path + 'launch-instance/network/network.html', - helpUrl: path + 'launch-instance/network/network.help.html', - formName: 'launchInstanceNetworkForm', - requiredServiceTypes: ['network'] - }, - { - title: gettext('Security Groups'), - templateUrl: path + 'launch-instance/security-groups/security-groups.html', - helpUrl: path + 'launch-instance/security-groups/security-groups.help.html', - formName: 'launchInstanceAccessAndSecurityForm' - }, - { - title: gettext('Key Pair'), - templateUrl: path + 'launch-instance/keypair/keypair.html', - helpUrl: path + 'launch-instance/keypair/keypair.help.html', - formName: 'launchInstanceKeypairForm' - }, - { - title: gettext('Configuration'), - templateUrl: path + 'launch-instance/configuration/configuration.html', - helpUrl: path + 'launch-instance/configuration/configuration.help.html', - formName: 'launchInstanceConfigurationForm' - } - ], - - btnText: { - finish: gettext('Launch Instance') - }, - - btnIcon: { - finish: 'fa fa-cloud-download' - } - }); - } - ]); - - // Using bootstrap-ui modal widget - module.constant('launchInstanceWizardModalSpec', { - backdrop: 'static', - controller: 'ModalContainerCtrl', - template: '', - windowClass: 'modal-dialog-wizard' - }); - - /** - * @name bootSourceTypes - * @description Boot source types - */ - module.constant('bootSourceTypes', { - IMAGE: 'image', - INSTANCE_SNAPSHOT: 'snapshot', - VOLUME: 'volume', - VOLUME_SNAPSHOT: 'volume_snapshot' - }); - - /** - * @ngdoc filter - * @name diskFormat - * @description - * Expects object and returns disk_format property value. - * Returns empty string if input is null or not an object. - * Uniquely required for the source step implementation of transfer tables - */ - module.filter('diskFormat', function() { - return function(input) { - if (input === null || !angular.isObject(input) || - !angular.isDefined(input.disk_format) || input.disk_format === null) { - return ''; - } else { - return input.disk_format.toUpperCase(); - } - }; - }); - - module.controller('LaunchInstanceWizardCtrl', [ - '$scope', - 'launchInstanceModel', - 'launchInstanceWorkflow', - LaunchInstanceWizardCtrl - ]); - - module.controller('LaunchInstanceModalCtrl', [ - '$scope', - '$modal', - '$window', - 'launchInstanceWizardModalSpec', - LaunchInstanceModalCtrl - ]); - - function LaunchInstanceWizardCtrl($scope, launchInstanceModel, launchInstanceWorkflow) { - $scope.workflow = launchInstanceWorkflow; - $scope.model = launchInstanceModel; - $scope.model.initialize(true); - $scope.submit = $scope.model.createInstance; - } - - function LaunchInstanceModalCtrl($scope, $modal, $window, modalSpec) { - $scope.openLaunchInstanceWizard = function (launchContext) { - - var localSpec = { - resolve: { - launchContext: function() { return launchContext; } - } - }; - - angular.extend(localSpec, modalSpec); - - var launchInstanceModal = $modal.open(localSpec); - - var handleModalClose = function(redirectPropertyName) { - return function() { - if (launchContext && launchContext[redirectPropertyName]) { - $window.location.href = launchContext[redirectPropertyName]; - } - }; - }; - - launchInstanceModal.result.then(handleModalClose('successUrl'), - handleModalClose('dismissUrl')); - - }; - } - -})(); diff --git a/openstack_dashboard/static/dashboard/launch-instance/launch-instance.module.js b/openstack_dashboard/static/dashboard/launch-instance/launch-instance.module.js new file mode 100644 index 0000000000..c3d8bb8cc3 --- /dev/null +++ b/openstack_dashboard/static/dashboard/launch-instance/launch-instance.module.js @@ -0,0 +1,64 @@ +/* + * (c) Copyright 2015 Hewlett-Packard Development Company, L.P. + * + * Licensed 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. + */ +(function () { + 'use strict'; + + angular + .module('hz.dashboard.launch-instance', [ + 'ngSanitize' + ]) + .constant('hz.dashboard.launch-instance.modal-spec', { + backdrop: 'static', + controller: 'ModalContainerCtrl', + template: '', + windowClass: 'modal-dialog-wizard' + }) + + /** + * @name hz.dashboard.launch-instance.boot-source-types + * @description Boot source types + */ + .constant('hz.dashboard.launch-instance.boot-source-types', { + IMAGE: 'image', + INSTANCE_SNAPSHOT: 'snapshot', + VOLUME: 'volume', + VOLUME_SNAPSHOT: 'volume_snapshot' + }) + + /** + * @ngdoc filter + * @name diskFormat + * @description + * Expects object and returns disk_format property value. + * Returns empty string if input is null or not an object. + * Uniquely required for the source step implementation of transfer tables + */ + .filter('diskFormat', diskFormat); + + function diskFormat() { + return filter; + + function filter(input) { + if (input === null || !angular.isObject(input) || + !angular.isDefined(input.disk_format) || input.disk_format === null) { + return ''; + } else { + return input.disk_format.toUpperCase(); + } + } + } + +})(); diff --git a/openstack_dashboard/static/dashboard/launch-instance/launch-instance.module.spec.js b/openstack_dashboard/static/dashboard/launch-instance/launch-instance.module.spec.js new file mode 100644 index 0000000000..52f429540c --- /dev/null +++ b/openstack_dashboard/static/dashboard/launch-instance/launch-instance.module.spec.js @@ -0,0 +1,40 @@ +/* + * (c) Copyright 2015 Hewlett-Packard Development Company, L.P. + * + * Licensed 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. + */ +(function () { + 'use strict'; + + describe('hz.dashboard.launch-instance module', function() { + + beforeEach(module('hz.dashboard')); + + it('should be defined.', function () { + expect(angular.module('hz.dashboard.launch-instance')).toBeDefined(); + }); + + describe('hz.dashboard.launch-instance.modal-spec', function () { + var launchInstancedModalSpec; + + beforeEach(inject(function ($injector) { + launchInstancedModalSpec = $injector.get('hz.dashboard.launch-instance.modal-spec'); + })); + + it('should be defined', function () { + expect(launchInstancedModalSpec).toBeDefined(); + }); + }); + }); + +})(); diff --git a/openstack_dashboard/static/dashboard/launch-instance/launch-instance.spec.js b/openstack_dashboard/static/dashboard/launch-instance/launch-instance.spec.js deleted file mode 100644 index 2444891d19..0000000000 --- a/openstack_dashboard/static/dashboard/launch-instance/launch-instance.spec.js +++ /dev/null @@ -1,233 +0,0 @@ -/* - * (c) Copyright 2015 Hewlett-Packard Development Company, L.P. - * - * Licensed 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. - */ -(function() { - 'use strict'; - - describe('Launch Instance Tests', function() { - - beforeEach(module('hz.dashboard')); - - it('should be defined.', function () { - expect(angular.module('hz.dashboard.launch-instance')).toBeDefined(); - }); - - describe('launchInstanceWorkflow', function () { - var launchInstanceWorkflow; - - beforeEach(module(function($provide) { - // Need to mock hz.framework.workflow from 'horizon' - var workflow = function(spec, decorators) { - angular.forEach(decorators, function(decorator) { - decorator(spec); - }); - return spec; - }; - - $provide.value('horizon.openstack-service-api.serviceCatalog', {}); - $provide.value('horizon.framework.util.workflow.service', workflow); - })); - - beforeEach(inject(function ($injector) { - launchInstanceWorkflow = $injector.get('launchInstanceWorkflow'); - })); - - it('should be defined', function () { - expect(launchInstanceWorkflow).toBeDefined(); - }); - - it('should have a title property', function () { - expect(launchInstanceWorkflow.title).toBeDefined(); - }); - - it('should have the six steps defined', function () { - expect(launchInstanceWorkflow.steps).toBeDefined(); - expect(launchInstanceWorkflow.steps.length).toBe(6); - - var forms = [ - 'launchInstanceSourceForm', - 'launchInstanceFlavorForm', - 'launchInstanceNetworkForm', - 'launchInstanceAccessAndSecurityForm', - 'launchInstanceKeypairForm', - 'launchInstanceConfigurationForm' - ]; - - forms.forEach(function(expectedForm, idx) { - expect(launchInstanceWorkflow.steps[idx].formName).toBe(expectedForm); - }); - }); - - it('specifies that the network step requires the network service type', function() { - expect(launchInstanceWorkflow.steps[2].requiredServiceTypes).toEqual(['network']); - }); - }); - - describe('launchInstanceWizardModalSpec', function () { - var launchInstanceWizardModalSpec; - - beforeEach(inject(function ($injector) { - launchInstanceWizardModalSpec = $injector.get('launchInstanceWizardModalSpec'); - })); - - it('should be defined', function () { - expect(launchInstanceWizardModalSpec).toBeDefined(); - }); - }); - - describe('LaunchInstanceWizardCtrl', function() { - var ctrl; - var model = { - createInstance: function() { - return 'created'; - }, - initialize: angular.noop - }; - - var scope = {}; - - beforeEach(module(function ($provide) { - $provide.value('serviceCatalog', {}); - $provide.value('launchInstanceModel', model); - })); - - beforeEach(inject(function ($controller) { - spyOn(model, 'initialize'); - var locals = { - $scope: scope, - launchInstanceWorkflow: { thing: true } - }; - ctrl = $controller('LaunchInstanceWizardCtrl', locals); - })); - - it('defines the controller', function() { - expect(ctrl).toBeDefined(); - }); - - it('calls initialize on the given model', function() { - expect(scope.model.initialize).toHaveBeenCalled(); - }); - - it('sets scope.workflow to the given workflow', function() { - expect(scope.workflow).toEqual({ thing: true }); - }); - - it('defines scope.submit', function() { - expect(scope.submit).toBeDefined(); - expect(scope.submit()).toBe('created'); - }); - - }); - - describe('LaunchInstanceModalCtrl', function() { - var ctrl; - var modal; - var scope; - var $window; - - beforeEach(module(function($provide) { - modal = { - open: function() { - return { - result: { - then: angular.noop - } - }; - } - }; - $window = { location: { href: '/' } }; - - $provide.value('$modal', modal); - $provide.value('$modalSpec', {}); - $provide.value('$window', $window); - })); - - beforeEach(inject(function($controller) { - scope = {}; - ctrl = $controller('LaunchInstanceModalCtrl', { $scope: scope }); - })); - - it('defines the controller', function() { - expect(ctrl).toBeDefined(); - }); - - it('defines openLaunchInstanceWizard', function() { - expect(scope.openLaunchInstanceWizard).toBeDefined(); - }); - - describe('openLaunchInstanceWizard function tests', function() { - var func; - var launchContext; - - beforeEach(function() { - func = scope.openLaunchInstanceWizard; - launchContext = {}; - }); - - it('calls modal.open', function() { - spyOn(modal, 'open').and.returnValue({ result: { then: angular.noop } }); - func(launchContext); - expect(modal.open).toHaveBeenCalled(); - }); - - it('calls modal.open with expected values', function() { - spyOn(modal, 'open').and.returnValue({ result: { then: angular.noop } }); - launchContext = { info: 'information' }; - func(launchContext); - - var resolve = modal.open.calls.argsFor(0)[0].resolve; - expect(resolve).toBeDefined(); - expect(resolve.launchContext).toBeDefined(); - expect(resolve.launchContext()).toEqual({ info: 'information' }); - }); - - it('sets up the correct success and failure paths', function() { - var successFunc; - var errFunc; - - launchContext = { successUrl: '/good/path', dismissUrl: '/bad/path' }; - spyOn(modal, 'open').and - .returnValue({ - result: { - then: function(x, y) { successFunc = x; errFunc = y; } - } - }); - func(launchContext); - successFunc('successUrl'); - expect($window.location.href).toBe('/good/path'); - errFunc('dismissUrl'); - expect($window.location.href).toBe('/bad/path'); - }); - - it("doesn't redirect if not configured to", function() { - var successFunc; - var errFunc; - launchContext = {}; - spyOn(modal, 'open').and - .returnValue({ - result: { - then: function(x, y) { successFunc = x; errFunc = y; } - } - }); - func(launchContext); - successFunc('successUrl'); - expect($window.location.href).toBe('/'); - errFunc('dismissUrl'); - expect($window.location.href).toBe('/'); - }); - }); - }); - }); -})(); diff --git a/openstack_dashboard/static/dashboard/launch-instance/source/source.controller.js b/openstack_dashboard/static/dashboard/launch-instance/source/source.controller.js index 6da10a3c7f..6b12d38ab3 100644 --- a/openstack_dashboard/static/dashboard/launch-instance/source/source.controller.js +++ b/openstack_dashboard/static/dashboard/launch-instance/source/source.controller.js @@ -32,7 +32,7 @@ LaunchInstanceSourceController.$inject = [ '$scope', - 'bootSourceTypes', + 'hz.dashboard.launch-instance.boot-source-types', 'bytesFilter', 'horizon.framework.widgets.charts.donutChartSettings', 'dateFilter', diff --git a/openstack_dashboard/static/dashboard/launch-instance/source/source.spec.js b/openstack_dashboard/static/dashboard/launch-instance/source/source.spec.js index b1110b9e73..3efe3a6020 100644 --- a/openstack_dashboard/static/dashboard/launch-instance/source/source.spec.js +++ b/openstack_dashboard/static/dashboard/launch-instance/source/source.spec.js @@ -25,7 +25,7 @@ var scope, ctrl, $browser, deferred; beforeEach(module(function($provide) { - $provide.value('bootSourceTypes', noop); + $provide.value('hz.dashboard.launch-instance.boot-source-types', noop); $provide.value('bytesFilter', noop); $provide.value('horizon.framework.widgets.charts.donutChartSettings', noop); $provide.value('dateFilter', noop);