Make create load balancer workflow generic
This patch turns the create load balancer workflow into a generic LBaaS workflow that can be used for many actions such as creating or editing any of the LBaaS resources like listeners, pools, etc. This way a single workflow, modal, model, and wizard can be used for all the actions. Partially-Implements: blueprint horizon-lbaas-v2-ui Change-Id: I0b0cff415f5afb4dccf66b7acca8260dbf124015
This commit is contained in:
parent
729c223f77
commit
39c2a18699
|
@ -38,22 +38,17 @@ ADD_JS_FILES = [
|
|||
'dashboard/project/lbaasv2/loadbalancers/detail.controller.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/filters.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/actions/batch-actions.service.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/actions/create/modal.service.js',
|
||||
'dashboard/project/lbaasv2/loadbalancers/actions/create/model.service.js',
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/'
|
||||
'wizard.controller.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/'
|
||||
'workflow.service.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/details/'
|
||||
'details.controller.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/listener/'
|
||||
'listener.controller.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/pool/'
|
||||
'pool.controller.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/members/'
|
||||
'members.controller.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/monitor/'
|
||||
'monitor.controller.js')
|
||||
'dashboard/project/lbaasv2/workflow/modal.service.js',
|
||||
'dashboard/project/lbaasv2/workflow/model.service.js',
|
||||
'dashboard/project/lbaasv2/workflow/workflow.service.js',
|
||||
('dashboard/project/lbaasv2/workflow/loadbalancer/'
|
||||
'loadbalancer.controller.js'),
|
||||
'dashboard/project/lbaasv2/workflow/listener/listener.controller.js',
|
||||
'dashboard/project/lbaasv2/workflow/pool/pool.controller.js',
|
||||
'dashboard/project/lbaasv2/workflow/members/members.controller.js',
|
||||
'dashboard/project/lbaasv2/workflow/monitor/monitor.controller.js'
|
||||
]
|
||||
|
||||
ADD_JS_SPEC_FILES = [
|
||||
|
@ -65,24 +60,17 @@ ADD_JS_SPEC_FILES = [
|
|||
'dashboard/project/lbaasv2/loadbalancers/filters.spec.js',
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/'
|
||||
'batch-actions.service.spec.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/'
|
||||
'modal.service.spec.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/'
|
||||
'model.service.spec.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/'
|
||||
'wizard.controller.spec.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/'
|
||||
'workflow.service.spec.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/details/'
|
||||
'details.controller.spec.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/listener/'
|
||||
'listener.controller.spec.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/pool/'
|
||||
'pool.controller.spec.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/members/'
|
||||
'members.controller.spec.js'),
|
||||
('dashboard/project/lbaasv2/loadbalancers/actions/create/monitor/'
|
||||
'monitor.controller.spec.js')
|
||||
'dashboard/project/lbaasv2/workflow/modal.service.spec.js',
|
||||
'dashboard/project/lbaasv2/workflow/model.service.spec.js',
|
||||
'dashboard/project/lbaasv2/workflow/workflow.service.spec.js',
|
||||
('dashboard/project/lbaasv2/workflow/loadbalancer/'
|
||||
'loadbalancer.controller.spec.js'),
|
||||
'dashboard/project/lbaasv2/workflow/listener/listener.controller.spec.js',
|
||||
'dashboard/project/lbaasv2/workflow/pool/pool.controller.spec.js',
|
||||
'dashboard/project/lbaasv2/workflow/members/members.controller.spec.js',
|
||||
'dashboard/project/lbaasv2/workflow/monitor/monitor.controller.spec.js'
|
||||
]
|
||||
|
||||
ADD_SCSS_FILES = [
|
||||
|
|
|
@ -22,8 +22,10 @@
|
|||
tableBatchActions);
|
||||
|
||||
tableBatchActions.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.actions.create.modal',
|
||||
'$location',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.modal',
|
||||
'horizon.dashboard.project.lbaasv2.basePath',
|
||||
'horizon.app.core.openstack-service-api.policy',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
|
@ -34,13 +36,22 @@
|
|||
* @description
|
||||
* Provides the service for the Load Balancers table batch actions.
|
||||
*
|
||||
* @param createModal The create action modal service.
|
||||
* @param $location The angular $location service.
|
||||
* @param workflowModal The LBaaS workflow modal service.
|
||||
* @param basePath The lbaasv2 module base path.
|
||||
* @param policy The horizon policy service.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @returns Load balancers table batch actions service object.
|
||||
*/
|
||||
|
||||
function tableBatchActions(createModal, basePath, gettext) {
|
||||
function tableBatchActions($location, workflowModal, basePath, policy, gettext) {
|
||||
|
||||
var create = workflowModal.init({
|
||||
controller: 'CreateLoadBalancerWizardController',
|
||||
message: gettext('A new load balancer is being created.'),
|
||||
handle: onCreate,
|
||||
allowed: canCreate
|
||||
});
|
||||
|
||||
var service = {
|
||||
actions: actions
|
||||
|
@ -52,13 +63,23 @@
|
|||
|
||||
function actions() {
|
||||
return [{
|
||||
service: createModal,
|
||||
service: create,
|
||||
template: {
|
||||
type: 'create',
|
||||
text: gettext('Create Load Balancer')
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
function canCreate() {
|
||||
// This rule is made up and should therefore always pass. I assume at some point there
|
||||
// will be a valid rule similar to this that we will want to use.
|
||||
return policy.ifAllowed({ rules: [['neutron', 'create_loadbalancer']] });
|
||||
}
|
||||
|
||||
function onCreate(response) {
|
||||
$location.path('project/ngloadbalancersv2/detail/' + response.data.id);
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
'use strict';
|
||||
|
||||
describe('LBaaS v2 Load Balancers Table Batch Actions Service', function() {
|
||||
var batchActionsService;
|
||||
var $location, actions, policy;
|
||||
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.framework.conf'));
|
||||
|
@ -26,19 +26,57 @@
|
|||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(module(function($provide) {
|
||||
$provide.value('$modal', {});
|
||||
var response = {
|
||||
data: {
|
||||
id: '1'
|
||||
}
|
||||
};
|
||||
var modal = {
|
||||
open: function() {
|
||||
return {
|
||||
result: {
|
||||
then: function(func) {
|
||||
func(response);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
$provide.value('$modal', modal);
|
||||
}));
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
batchActionsService = $injector.get(
|
||||
$location = $injector.get('$location');
|
||||
policy = $injector.get('horizon.app.core.openstack-service-api.policy');
|
||||
var batchActionsService = $injector.get(
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.actions.batchActions');
|
||||
actions = batchActionsService.actions();
|
||||
}));
|
||||
|
||||
it('should define correct table batch actions', function() {
|
||||
var actions = batchActionsService.actions();
|
||||
expect(actions.length).toBe(1);
|
||||
expect(actions[0].template.text).toBe('Create Load Balancer');
|
||||
});
|
||||
|
||||
it('should have the "allowed" and "perform" functions', function() {
|
||||
actions.forEach(function(action) {
|
||||
expect(action.service.allowed).toBeDefined();
|
||||
expect(action.service.perform).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should check policy to allow creating a load balancer', function() {
|
||||
spyOn(policy, 'ifAllowed').and.returnValue(true);
|
||||
var allowed = actions[0].service.allowed();
|
||||
expect(allowed).toBe(true);
|
||||
expect(policy.ifAllowed).toHaveBeenCalledWith({rules: [['neutron', 'create_loadbalancer']]});
|
||||
});
|
||||
|
||||
it('should redirect after create', function() {
|
||||
spyOn($location, 'path').and.callThrough();
|
||||
actions[0].service.perform();
|
||||
expect($location.path).toHaveBeenCalledWith('project/ngloadbalancersv2/detail/1');
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
<h1 translate>Load Balancer Details Help</h1>
|
||||
|
||||
<p translate>Provide the details for the new load balancer. A subnet is required. The subnet is the network on which to allocate the load balancer's IP address. If an IP address is provided it must be a well-formed IPv4 or IPv6 address. The system will attempt to assign the provided IP address to the load balancer.</p>
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Copyright 2015 IBM Corp.
|
||||
*
|
||||
* 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('horizon.dashboard.project.lbaasv2.loadbalancers')
|
||||
.factory('horizon.dashboard.project.lbaasv2.loadbalancers.actions.create.modal',
|
||||
modalService);
|
||||
|
||||
modalService.$inject = [
|
||||
'$modal',
|
||||
'$location',
|
||||
'horizon.framework.widgets.toast.service',
|
||||
'horizon.framework.util.i18n.gettext',
|
||||
'horizon.app.core.openstack-service-api.policy'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @ngname horizon.dashboard.project.lbaasv2.loadbalancers.actions.create.modal
|
||||
*
|
||||
* @description
|
||||
* Provides the service for opening the create load balancer modal.
|
||||
*
|
||||
* @param $modal The angular bootstrap $modal service.
|
||||
* @param $location The angular $location service.
|
||||
* @param toastService The horizon toast service.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @param policy The horizon policy service.
|
||||
* @returns The modal service for the create load balancer workflow.
|
||||
*/
|
||||
|
||||
function modalService($modal, $location, toastService, gettext, policy) {
|
||||
|
||||
var service = {
|
||||
allowed: allowed,
|
||||
perform: perform
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
//////////////
|
||||
|
||||
function allowed() {
|
||||
// This rule is made up and should therefore always pass. I assume at some point there
|
||||
// will be a valid rule similar to this that we will want to use.
|
||||
return policy.ifAllowed({ rules: [['neutron', 'create_loadbalancer']] });
|
||||
}
|
||||
|
||||
function perform() {
|
||||
var spec = {
|
||||
backdrop: 'static',
|
||||
controller: 'ModalContainerController',
|
||||
template: '<wizard ng-controller="CreateLoadBalancerWizardController"></wizard>',
|
||||
windowClass: 'modal-dialog-wizard',
|
||||
// ModalContainerController requires a launchContext parameter...
|
||||
resolve: {
|
||||
launchContext: null
|
||||
}
|
||||
};
|
||||
var modal = $modal.open(spec);
|
||||
modal.result.then(function(response) {
|
||||
toastService.add('success', gettext('A new load balancer is being created.'));
|
||||
$location.path('project/ngloadbalancersv2/detail/' + response.data.id);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
|
@ -22,21 +22,19 @@
|
|||
|
||||
CreateLoadBalancerWizardController.$inject = [
|
||||
'$scope',
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.actions.create.model',
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.actions.create.workflow'
|
||||
'horizon.dashboard.project.lbaasv2.workflow.model',
|
||||
'horizon.dashboard.project.lbaasv2.workflow.workflow',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
function CreateLoadBalancerWizardController(
|
||||
$scope,
|
||||
createLoadBalancerModel,
|
||||
createLoadBalancerWorkflow
|
||||
) {
|
||||
// Note: we set these attributes on the $scope so that the scope inheritance used all
|
||||
// through the wizard continues to work.
|
||||
$scope.workflow = createLoadBalancerWorkflow; // eslint-disable-line angular/controller-as
|
||||
$scope.model = createLoadBalancerModel; // eslint-disable-line angular/controller-as
|
||||
$scope.model.initialize();
|
||||
$scope.submit = $scope.model.createLoadBalancer; // eslint-disable-line angular/controller-as
|
||||
function CreateLoadBalancerWizardController($scope, model, workflowService, gettext) {
|
||||
var scope = $scope;
|
||||
// Note: We set these attributes on the $scope so that the scope inheritance used all through
|
||||
// the wizard continues to work. Using local var to appease eslint angular/ng_controller_as.
|
||||
scope.model = model;
|
||||
scope.submit = scope.model.submit;
|
||||
scope.workflow = workflowService(gettext('Create Load Balancer'), 'fa fa-cloud-download');
|
||||
scope.model.initialize('loadbalancer');
|
||||
}
|
||||
|
||||
})();
|
||||
|
|
|
@ -19,23 +19,21 @@
|
|||
describe('LBaaS v2 Create Load Balancer Wizard Controller', function() {
|
||||
var ctrl;
|
||||
var model = {
|
||||
createLoadBalancer: function() {
|
||||
submit: function() {
|
||||
return 'created';
|
||||
},
|
||||
initialize: angular.noop
|
||||
};
|
||||
var workflow = function() {
|
||||
return 'foo';
|
||||
};
|
||||
var scope = {};
|
||||
|
||||
beforeEach(module('horizon.app.core'));
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.framework.conf'));
|
||||
beforeEach(module('horizon.framework.widgets.toast'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
beforeEach(module(function ($provide) {
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.loadbalancers.actions.create.model',
|
||||
model);
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.loadbalancers.actions.create.workflow',
|
||||
{ thing: true });
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.workflow.model', model);
|
||||
$provide.value('horizon.dashboard.project.lbaasv2.workflow.workflow', workflow);
|
||||
}));
|
||||
beforeEach(inject(function ($controller) {
|
||||
spyOn(model, 'initialize');
|
||||
|
@ -51,7 +49,7 @@
|
|||
});
|
||||
|
||||
it('sets scope.workflow to the given workflow', function() {
|
||||
expect(scope.workflow).toEqual({ thing: true });
|
||||
expect(scope.workflow).toBe('foo');
|
||||
});
|
||||
|
||||
it('defines scope.submit', function() {
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Copyright 2015 IBM Corp.
|
||||
*
|
||||
* 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('horizon.dashboard.project.lbaasv2.loadbalancers')
|
||||
.factory('horizon.dashboard.project.lbaasv2.loadbalancers.actions.create.workflow',
|
||||
createLoadBalancerWorkflow);
|
||||
|
||||
createLoadBalancerWorkflow.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.basePath',
|
||||
'horizon.app.core.workflow.factory',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
function createLoadBalancerWorkflow(basePath, dashboardWorkflow, gettext) {
|
||||
return dashboardWorkflow({
|
||||
title: gettext('Create Load Balancer'),
|
||||
|
||||
steps: [
|
||||
{
|
||||
id: 'loadbalancer',
|
||||
title: gettext('Load Balancer Details'),
|
||||
templateUrl: basePath + 'loadbalancers/actions/create/details/details.html',
|
||||
helpUrl: basePath + 'loadbalancers/actions/create/details/details.help.html',
|
||||
formName: 'createLoadBalancerDetailsForm'
|
||||
},
|
||||
{
|
||||
id: 'listener',
|
||||
title: gettext('Listener Details'),
|
||||
templateUrl: basePath + 'loadbalancers/actions/create/listener/listener.html',
|
||||
helpUrl: basePath + 'loadbalancers/actions/create/listener/listener.help.html',
|
||||
formName: 'createLoadBalancerListenerForm'
|
||||
},
|
||||
{
|
||||
id: 'pool',
|
||||
title: gettext('Pool Details'),
|
||||
templateUrl: basePath + 'loadbalancers/actions/create/pool/pool.html',
|
||||
helpUrl: basePath + 'loadbalancers/actions/create/pool/pool.help.html',
|
||||
formName: 'createLoadBalancerPoolForm'
|
||||
},
|
||||
{
|
||||
id: 'members',
|
||||
title: gettext('Pool Members'),
|
||||
templateUrl: basePath + 'loadbalancers/actions/create/members/members.html',
|
||||
helpUrl: basePath + 'loadbalancers/actions/create/members/members.help.html',
|
||||
formName: 'createLoadBalancerMembersForm'
|
||||
},
|
||||
{
|
||||
id: 'monitor',
|
||||
title: gettext('Monitor'),
|
||||
templateUrl: basePath + 'loadbalancers/actions/create/monitor/monitor.html',
|
||||
helpUrl: basePath + 'loadbalancers/actions/create/monitor/monitor.help.html',
|
||||
formName: 'createLoadBalancerMonitorForm'
|
||||
}
|
||||
],
|
||||
|
||||
btnText: {
|
||||
finish: gettext('Create Load Balancer')
|
||||
},
|
||||
|
||||
btnIcon: {
|
||||
finish: 'fa fa-cloud-download'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright 2015 IBM Corp.
|
||||
*
|
||||
* 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('LBaaS v2 Create Load Balancer Workflow Service', function() {
|
||||
var createLoadBalancerWorkflow;
|
||||
|
||||
beforeEach(module('horizon.app.core'));
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.framework.conf'));
|
||||
beforeEach(module('horizon.framework.widgets.toast'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
createLoadBalancerWorkflow = $injector.get(
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.actions.create.workflow'
|
||||
);
|
||||
}));
|
||||
|
||||
it('should be defined', function () {
|
||||
expect(createLoadBalancerWorkflow).toBeDefined();
|
||||
});
|
||||
|
||||
it('should have a title property', function () {
|
||||
expect(createLoadBalancerWorkflow.title).toBeDefined();
|
||||
});
|
||||
|
||||
it('should have steps defined', function () {
|
||||
expect(createLoadBalancerWorkflow.steps).toBeDefined();
|
||||
expect(createLoadBalancerWorkflow.steps.length).toBe(5);
|
||||
|
||||
var forms = [
|
||||
'createLoadBalancerDetailsForm',
|
||||
'createLoadBalancerListenerForm',
|
||||
'createLoadBalancerPoolForm',
|
||||
'createLoadBalancerMembersForm',
|
||||
'createLoadBalancerMonitorForm'
|
||||
];
|
||||
|
||||
forms.forEach(function(expectedForm, idx) {
|
||||
expect(createLoadBalancerWorkflow.steps[idx].formName).toBe(expectedForm);
|
||||
});
|
||||
});
|
||||
|
||||
it('can be extended', function () {
|
||||
expect(createLoadBalancerWorkflow.append).toBeDefined();
|
||||
expect(createLoadBalancerWorkflow.prepend).toBeDefined();
|
||||
expect(createLoadBalancerWorkflow.after).toBeDefined();
|
||||
expect(createLoadBalancerWorkflow.replace).toBeDefined();
|
||||
expect(createLoadBalancerWorkflow.remove).toBeDefined();
|
||||
expect(createLoadBalancerWorkflow.addController).toBeDefined();
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
|
@ -17,28 +17,28 @@
|
|||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.loadbalancers')
|
||||
.controller('CreateListenerDetailsController', CreateListenerDetailsController);
|
||||
.module('horizon.dashboard.project.lbaasv2')
|
||||
.controller('ListenerDetailsController', ListenerDetailsController);
|
||||
|
||||
CreateListenerDetailsController.$inject = [
|
||||
ListenerDetailsController.$inject = [
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name CreateListenerDetailsController
|
||||
* @name ListenerDetailsController
|
||||
* @description
|
||||
* The `CreateListenerDetailsController` controller provides functions for
|
||||
* configuring the listener details step when creating a new listener.
|
||||
* The `ListenerDetailsController` controller provides functions for
|
||||
* configuring the listener details step of the LBaaS wizard.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function CreateListenerDetailsController(gettext) {
|
||||
function ListenerDetailsController(gettext) {
|
||||
|
||||
var ctrl = this;
|
||||
|
||||
// Error text for invalid fields
|
||||
ctrl.listenerPortError = gettext('The port must be a number between 1 and 65535.');
|
||||
ctrl.portError = gettext('The port must be a number between 1 and 65535.');
|
||||
}
|
||||
})();
|
|
@ -16,20 +16,20 @@
|
|||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('Create Listener Details Step', function() {
|
||||
describe('Listener Details Step', function() {
|
||||
|
||||
beforeEach(module('horizon.framework.util.i18n'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
describe('CreateListenerDetailsController', function() {
|
||||
describe('ListenerDetailsController', function() {
|
||||
var ctrl;
|
||||
|
||||
beforeEach(inject(function($controller) {
|
||||
ctrl = $controller('CreateListenerDetailsController');
|
||||
ctrl = $controller('ListenerDetailsController');
|
||||
}));
|
||||
|
||||
it('should define error messages for invalid fields', function() {
|
||||
expect(ctrl.listenerPortError).toBeDefined();
|
||||
expect(ctrl.portError).toBeDefined();
|
||||
});
|
||||
|
||||
});
|
|
@ -1,9 +1,9 @@
|
|||
<div ng-controller="CreateListenerDetailsController as ctrl">
|
||||
<div ng-controller="ListenerDetailsController as ctrl">
|
||||
<h1 translate>Listener Details</h1>
|
||||
|
||||
<!--content-->
|
||||
<div class="content">
|
||||
<div translate class="subtitle">Provide the details for the new load balancer listener. The listener will only be created if values are provided for all fields marked as required.</div>
|
||||
<div translate class="subtitle">Provide the details for the listener.</div>
|
||||
|
||||
<div class="row form-group">
|
||||
|
||||
|
@ -35,23 +35,24 @@
|
|||
<select class="form-control input-sm" name="listener-protocol"
|
||||
id="listener-protocol"
|
||||
ng-options="protocol for protocol in model.listenerProtocols"
|
||||
ng-model="model.spec.listener.protocol">
|
||||
ng-model="model.spec.listener.protocol" ng-required="model.context.type === 'listener'">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div class="form-field required listener-port"
|
||||
ng-class="{ 'has-error': createLoadBalancerListenerForm['listener-port'].$invalid && createLoadBalancerListenerForm['listener-port'].$dirty }">
|
||||
ng-class="{ 'has-error': listenerDetailForm['listener-port'].$invalid && listenerDetailForm['listener-port'].$dirty }">
|
||||
<label translate class="on-top" for="listener-port">Port</label>
|
||||
<span class="fa fa-exclamation-triangle invalid"
|
||||
ng-show="createLoadBalancerListenerForm['listener-port'].$invalid && createLoadBalancerListenerForm.$dirty"
|
||||
popover="{$ ::ctrl.listenerPortError $}"
|
||||
ng-show="listenerDetailForm['listener-port'].$invalid && listenerDetailForm.$dirty"
|
||||
popover="{$ ::ctrl.portError $}"
|
||||
popover-placement="top" popover-append-to-body="true"
|
||||
popover-trigger="hover"></span>
|
||||
<input name="listener-port" id="listener-port"
|
||||
type="number" class="form-control input-sm"
|
||||
ng-model="model.spec.listener.port" ng-pattern="/^\d+$/" min="1" max="65535">
|
||||
ng-model="model.spec.listener.port" ng-pattern="/^\d+$/" min="1" max="65535"
|
||||
ng-required="model.context.type === 'listener'">
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -17,31 +17,31 @@
|
|||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.loadbalancers')
|
||||
.controller('CreateLoadBalancerDetailsController', CreateLoadBalancerDetailsController);
|
||||
.module('horizon.dashboard.project.lbaasv2')
|
||||
.controller('LoadBalancerDetailsController', LoadBalancerDetailsController);
|
||||
|
||||
CreateLoadBalancerDetailsController.$inject = [
|
||||
LoadBalancerDetailsController.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.patterns',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name CreateLoadBalancerDetailsController
|
||||
* @name LoadBalancerDetailsController
|
||||
* @description
|
||||
* The `CreateLoadBalancerDetailsController` controller provides functions for
|
||||
* configuring the details step of the Create Load Balancer Wizard.
|
||||
* The `LoadBalancerDetailsController` controller provides functions for
|
||||
* configuring the load balancers step of the LBaaS wizard.
|
||||
* @param patterns The LBaaS v2 patterns constant.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function CreateLoadBalancerDetailsController(patterns, gettext) {
|
||||
function LoadBalancerDetailsController(patterns, gettext) {
|
||||
|
||||
var ctrl = this;
|
||||
|
||||
// Error text for invalid fields
|
||||
ctrl.loadbalancerIPError = gettext('The IP address is not valid.');
|
||||
ctrl.ipError = gettext('The IP address is not valid.');
|
||||
|
||||
// IP address validation pattern
|
||||
ctrl.ipPattern = [patterns.ipv4, patterns.ipv6].join('|');
|
|
@ -16,20 +16,20 @@
|
|||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('Create Load Balancer Details Step', function() {
|
||||
describe('Load Balancer Details Step', function() {
|
||||
|
||||
beforeEach(module('horizon.framework.util.i18n'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
describe('CreateLoadBalancerDetailsController', function() {
|
||||
describe('LoadBalancerDetailsController', function() {
|
||||
var ctrl;
|
||||
|
||||
beforeEach(inject(function($controller) {
|
||||
ctrl = $controller('CreateLoadBalancerDetailsController');
|
||||
ctrl = $controller('LoadBalancerDetailsController');
|
||||
}));
|
||||
|
||||
it('should define error messages for invalid fields', function() {
|
||||
expect(ctrl.loadbalancerIPError).toBeDefined();
|
||||
expect(ctrl.ipError).toBeDefined();
|
||||
});
|
||||
|
||||
it('should define patterns for field validation', function() {
|
|
@ -0,0 +1,3 @@
|
|||
<h1 translate>Load Balancer Details Help</h1>
|
||||
|
||||
<p translate>Provide the details for the load balancer. A subnet is required. The subnet is the network on which to allocate the load balancer's IP address. If an IP address is provided it must be a well-formed IPv4 or IPv6 address. The system will attempt to assign the provided IP address to the load balancer.</p>
|
|
@ -1,14 +1,14 @@
|
|||
<div ng-controller="CreateLoadBalancerDetailsController as ctrl">
|
||||
<div ng-controller="LoadBalancerDetailsController as ctrl">
|
||||
<h1 translate>Load Balancer Details</h1>
|
||||
|
||||
<!--content-->
|
||||
<div class="content">
|
||||
<div translate class="subtitle">Provide the details for the new load balancer.</div>
|
||||
<div translate class="subtitle">Provide the details for the load balancer.</div>
|
||||
|
||||
<div class="row form-group">
|
||||
<div class="col-sm-12 col-md-6">
|
||||
<div class="form-field loadbalancer-name"
|
||||
ng-class="{ 'has-error': createLoadBalancerDetailsForm['loadbalancer-name'].$invalid && createLoadBalancerDetailsForm['loadbalancer-name'].$dirty }">
|
||||
ng-class="{ 'has-error': loadBalancerDetailsForm['loadbalancer-name'].$invalid && loadBalancerDetailsForm['loadbalancer-name'].$dirty }">
|
||||
<label translate class="on-top" for="loadbalancer-name">Name</label>
|
||||
<input name="loadbalancer-name" id="loadbalancer-name"
|
||||
type="text" class="form-control input-sm"
|
||||
|
@ -30,11 +30,11 @@
|
|||
<div class="row form-group">
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div class="form-field loadbalancer-ip"
|
||||
ng-class="{ 'has-error': createLoadBalancerDetailsForm['loadbalancer-ip'].$invalid && createLoadBalancerDetailsForm['loadbalancer-ip'].$dirty }">
|
||||
ng-class="{ 'has-error': loadBalancerDetailsForm['loadbalancer-ip'].$invalid && loadBalancerDetailsForm['loadbalancer-ip'].$dirty }">
|
||||
<label translate class="on-top" for="loadbalancer-ip">IP Address</label>
|
||||
<span class="fa fa-exclamation-triangle invalid"
|
||||
ng-show="createLoadBalancerDetailsForm['loadbalancer-ip'].$invalid && createLoadBalancerDetailsForm.$dirty"
|
||||
popover="{$ ::ctrl.loadbalancerIPError $}"
|
||||
ng-show="loadBalancerDetailsForm['loadbalancer-ip'].$invalid && loadBalancerDetailsForm.$dirty"
|
||||
popover="{$ ::ctrl.ipError $}"
|
||||
popover-placement="top" popover-append-to-body="true"
|
||||
popover-trigger="hover"></span>
|
||||
<input name="loadbalancer-ip" id="loadbalancer-ip"
|
|
@ -17,10 +17,10 @@
|
|||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.loadbalancers')
|
||||
.controller('AddMembersController', AddMembersController);
|
||||
.module('horizon.dashboard.project.lbaasv2')
|
||||
.controller('MemberDetailsController', MemberDetailsController);
|
||||
|
||||
AddMembersController.$inject = [
|
||||
MemberDetailsController.$inject = [
|
||||
'$scope',
|
||||
'$compile',
|
||||
'horizon.dashboard.project.lbaasv2.popovers',
|
||||
|
@ -29,18 +29,17 @@
|
|||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name AddMembersController
|
||||
* @name MemberDetailsController
|
||||
* @description
|
||||
* The `AddMembersController` controller provides functions for adding members to a pool.
|
||||
* The `MemberDetailsController` controller provides functions for adding members to a pool.
|
||||
* @param $scope The angular scope object.
|
||||
* @param $compile The angular compile service.
|
||||
* @param popovers LBaaS v2 popover templates constant.
|
||||
* @param popoverTemplates LBaaS v2 popover templates constant.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function AddMembersController($scope, $compile, popoverTemplates, gettext) {
|
||||
|
||||
function MemberDetailsController($scope, $compile, popoverTemplates, gettext) {
|
||||
var ctrl = this;
|
||||
|
||||
// Error text for invalid fields
|
|
@ -16,7 +16,7 @@
|
|||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('Create Load Balancer Add Members Step', function() {
|
||||
describe('Member Details Step', function() {
|
||||
var members = [{
|
||||
id: '1',
|
||||
name: 'foo',
|
||||
|
@ -31,7 +31,7 @@
|
|||
beforeEach(module('horizon.framework.util.i18n'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
describe('AddMembersController', function() {
|
||||
describe('MemberDetailsController', function() {
|
||||
var ctrl, scope;
|
||||
|
||||
beforeEach(inject(function($controller) {
|
||||
|
@ -43,7 +43,7 @@
|
|||
members: members
|
||||
}
|
||||
};
|
||||
ctrl = $controller('AddMembersController', { $scope: scope });
|
||||
ctrl = $controller('MemberDetailsController', { $scope: scope });
|
||||
}));
|
||||
|
||||
it('should define error messages for invalid fields', function() {
|
||||
|
@ -77,7 +77,7 @@
|
|||
});
|
||||
});
|
||||
|
||||
describe('Add Members Template', function() {
|
||||
describe('Member Details Step Template', function() {
|
||||
var $scope, $element, popoverContent;
|
||||
|
||||
beforeEach(module('templates'));
|
||||
|
@ -88,8 +88,7 @@
|
|||
var $templateCache = $injector.get('$templateCache');
|
||||
var basePath = $injector.get('horizon.dashboard.project.lbaasv2.basePath');
|
||||
var popoverTemplates = $injector.get('horizon.dashboard.project.lbaasv2.popovers');
|
||||
var markup = $templateCache.get(
|
||||
basePath + 'loadbalancers/actions/create/members/members.html');
|
||||
var markup = $templateCache.get(basePath + 'workflow/members/members.html');
|
||||
$scope = $injector.get('$rootScope').$new();
|
||||
$scope.model = {
|
||||
spec: {
|
|
@ -1,9 +1,9 @@
|
|||
<div ng-controller="AddMembersController as ctrl">
|
||||
<div ng-controller="MemberDetailsController as ctrl">
|
||||
<h1 translate>Pool Members</h1>
|
||||
|
||||
<!--content-->
|
||||
<div class="content">
|
||||
<div translate class="subtitle">Add members to the load balancer pool. All required listener and pool details must also be provided.</div>
|
||||
<div translate class="subtitle">Add members to the load balancer pool.</div>
|
||||
|
||||
<transfer-table tr-model="ctrl.tableData"
|
||||
limits="::ctrl.tableLimits"
|
||||
|
@ -60,25 +60,25 @@
|
|||
</td>
|
||||
<td class="rsp-p1">
|
||||
<div class="form-field member-weight"
|
||||
ng-class="{ 'has-error': createLoadBalancerMembersForm['{$ ::row.id $}-weight'].$invalid && createLoadBalancerMembersForm['{$ ::row.id $}-weight'].$dirty }">
|
||||
ng-class="{ 'has-error': memberDetailsForm['{$ ::row.id $}-weight'].$invalid && memberDetailsForm['{$ ::row.id $}-weight'].$dirty }">
|
||||
<input name="{$ ::row.id $}-weight" type="number" class="form-control input-sm"
|
||||
ng-model="row.weight" ng-pattern="/^\d+$/" min="1" max="256">
|
||||
</div>
|
||||
<span class="fa fa-exclamation-triangle invalid"
|
||||
ng-show="createLoadBalancerMembersForm['{$ ::row.id $}-weight'].$invalid && createLoadBalancerMembersForm.$dirty"
|
||||
ng-show="memberDetailsForm['{$ ::row.id $}-weight'].$invalid && memberDetailsForm.$dirty"
|
||||
popover="{$ ::ctrl.weightError $}"
|
||||
popover-placement="top" popover-append-to-body="true"
|
||||
popover-trigger="hover"></span>
|
||||
</td>
|
||||
<td class="rsp-p1">
|
||||
<div class="form-field member-port"
|
||||
ng-class="{ 'has-error': createLoadBalancerMembersForm['{$ ::row.id $}-port'].$invalid && createLoadBalancerMembersForm['{$ ::row.id $}-port'].$dirty }">
|
||||
ng-class="{ 'has-error': memberDetailsForm['{$ ::row.id $}-port'].$invalid && memberDetailsForm['{$ ::row.id $}-port'].$dirty }">
|
||||
<input name="{$ ::row.id $}-port" type="number" class="form-control input-sm"
|
||||
ng-model="row.port" ng-pattern="/^\d+$/" min="1" max="65535"
|
||||
ng-required="true">
|
||||
</div>
|
||||
<span class="fa fa-exclamation-triangle invalid"
|
||||
ng-show="createLoadBalancerMembersForm['{$ ::row.id $}-port'].$invalid && createLoadBalancerMembersForm.$dirty"
|
||||
ng-show="memberDetailsForm['{$ ::row.id $}-port'].$invalid && memberDetailsForm.$dirty"
|
||||
popover="{$ ::ctrl.portError $}"
|
||||
popover-placement="top" popover-append-to-body="true"
|
||||
popover-trigger="hover"></span>
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright 2015 IBM Corp.
|
||||
*
|
||||
* 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('horizon.dashboard.project.lbaasv2')
|
||||
.factory('horizon.dashboard.project.lbaasv2.workflow.modal', modalService);
|
||||
|
||||
modalService.$inject = [
|
||||
'$modal',
|
||||
'horizon.framework.widgets.toast.service'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @ngname horizon.dashboard.project.lbaasv2.workflow.modal
|
||||
*
|
||||
* @description
|
||||
* Provides the service for opening the LBaaS create / edit modal.
|
||||
*
|
||||
* @param $modal The angular bootstrap $modal service.
|
||||
* @param toastService The horizon toast service.
|
||||
* @returns The modal service for the LBaaS workflow.
|
||||
*/
|
||||
|
||||
function modalService($modal, toastService) {
|
||||
|
||||
var service = {
|
||||
init: init
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
//////////////
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name init
|
||||
*
|
||||
* @description
|
||||
* Initialize a new scope for an LBaaS workflow modal.
|
||||
*
|
||||
* @param args An object containing the following properties:
|
||||
* controller*: Controller to use for the wizard instance.
|
||||
* message*: String to display using the toast service when wizard completes.
|
||||
* allowed*: Function used to determine if the workflow action is allowed.
|
||||
* handle: Function to call after the modal closes, receives the result of wizard submit.
|
||||
* @returns An object with a single function 'open', used to open the modal.
|
||||
*/
|
||||
|
||||
function init(args) {
|
||||
return {
|
||||
allowed: args.allowed,
|
||||
perform: open
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name open
|
||||
*
|
||||
* @description
|
||||
* Open the modal.
|
||||
*
|
||||
* @param item The row item from the table action.
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function open(item) {
|
||||
var spec = {
|
||||
backdrop: 'static',
|
||||
controller: 'ModalContainerController',
|
||||
template: '<wizard ng-controller="' + args.controller + '"></wizard>',
|
||||
windowClass: 'modal-dialog-wizard',
|
||||
resolve: {
|
||||
launchContext: function() {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
};
|
||||
$modal.open(spec).result.then(onModalClose);
|
||||
}
|
||||
|
||||
function onModalClose(response) {
|
||||
toastService.add('success', args.message);
|
||||
if (args.handle) {
|
||||
args.handle(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
})();
|
|
@ -16,17 +16,16 @@
|
|||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 Load Balancers Table Create Action Modal Service', function() {
|
||||
var modalService, modal;
|
||||
describe('LBaaS v2 Workflow Modal Service', function() {
|
||||
var modalService, modal, response;
|
||||
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.framework.conf'));
|
||||
beforeEach(module('horizon.framework.widgets.toast'));
|
||||
beforeEach(module('horizon.app.core.openstack-service-api'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(module(function($provide) {
|
||||
var response = {
|
||||
response = {
|
||||
data: {
|
||||
id: '1'
|
||||
}
|
||||
|
@ -43,62 +42,64 @@
|
|||
}
|
||||
};
|
||||
|
||||
var policyAPI = {
|
||||
ifAllowed: function() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
$provide.value('$modal', modal);
|
||||
$provide.value('horizon.app.core.openstack-service-api.policy', policyAPI);
|
||||
}));
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
modalService = $injector.get(
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.actions.create.modal');
|
||||
modalService = $injector.get('horizon.dashboard.project.lbaasv2.workflow.modal');
|
||||
}));
|
||||
|
||||
it('should define function for opening a modal', function() {
|
||||
expect(modalService.perform).toBeDefined();
|
||||
});
|
||||
|
||||
it('should be allowed based on policy', function() {
|
||||
expect(modalService.allowed()).toBe(true);
|
||||
it('should define an init function', function() {
|
||||
expect(modalService.init).toBeDefined();
|
||||
});
|
||||
|
||||
describe('modalService "perform" function tests', function() {
|
||||
var toastService, $location;
|
||||
var toastService;
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
toastService = $injector.get('horizon.framework.widgets.toast.service');
|
||||
$location = $injector.get('$location');
|
||||
}));
|
||||
|
||||
it('calls modal.open', function() {
|
||||
spyOn(modal, 'open').and.callThrough();
|
||||
modalService.perform();
|
||||
modalService.init({}).perform();
|
||||
|
||||
expect(modal.open).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls modal.open with expected values', function() {
|
||||
spyOn(modal, 'open').and.callThrough();
|
||||
modalService.perform();
|
||||
modalService.init({}).perform();
|
||||
|
||||
var args = modal.open.calls.argsFor(0)[0];
|
||||
expect(args.backdrop).toBe('static');
|
||||
expect(args.controller).toBeDefined();
|
||||
expect(args.resolve).toBeDefined();
|
||||
expect(args.resolve.launchContext).toBeNull();
|
||||
expect(args.resolve.launchContext).toBeDefined();
|
||||
});
|
||||
|
||||
it('redirects upon success', function() {
|
||||
spyOn(toastService, 'add').and.callThrough();
|
||||
spyOn($location, 'path').and.callThrough();
|
||||
modalService.perform();
|
||||
it('launchContext function returns argument passed to open function', function() {
|
||||
spyOn(modal, 'open').and.callThrough();
|
||||
modalService.init({}).perform('foo');
|
||||
|
||||
expect(toastService.add).toHaveBeenCalledWith('success', jasmine.any(String));
|
||||
expect($location.path).toHaveBeenCalledWith('project/ngloadbalancersv2/detail/1');
|
||||
var args = modal.open.calls.argsFor(0)[0];
|
||||
expect(args.resolve.launchContext()).toBe('foo');
|
||||
});
|
||||
|
||||
it('shows message upon success', function() {
|
||||
spyOn(toastService, 'add').and.callThrough();
|
||||
modalService.init({ message: 'foo' }).perform();
|
||||
|
||||
expect(toastService.add).toHaveBeenCalledWith('success', 'foo');
|
||||
});
|
||||
|
||||
it('handles response upon success', function() {
|
||||
spyOn(toastService, 'add').and.callThrough();
|
||||
var args = { handle: angular.noop };
|
||||
spyOn(args, 'handle');
|
||||
modalService.init(args).perform();
|
||||
|
||||
expect(args.handle).toHaveBeenCalledWith(response);
|
||||
});
|
||||
|
||||
});
|
|
@ -19,11 +19,10 @@
|
|||
var push = Array.prototype.push;
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.loadbalancers')
|
||||
.factory('horizon.dashboard.project.lbaasv2.loadbalancers.actions.create.model',
|
||||
createLoadBalancerModel);
|
||||
.module('horizon.dashboard.project.lbaasv2')
|
||||
.factory('horizon.dashboard.project.lbaasv2.workflow.model', workflowModel);
|
||||
|
||||
createLoadBalancerModel.$inject = [
|
||||
workflowModel.$inject = [
|
||||
'$q',
|
||||
'horizon.app.core.openstack-service-api.neutron',
|
||||
'horizon.app.core.openstack-service-api.nova',
|
||||
|
@ -33,13 +32,12 @@
|
|||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name horizon.dashboard.project.lbaasv2.loadbalancers.actions.create.model
|
||||
* @name horizon.dashboard.project.lbaasv2.workflow.model
|
||||
*
|
||||
* @description
|
||||
* This is the M part of the MVC design pattern for the create load balancer wizard workflow. It
|
||||
* is responsible for providing data to the view of each step in the workflow and collecting the
|
||||
* user's input from the view for creation of the new load balancer. It is also the center point
|
||||
* of communication between the UI and services API.
|
||||
* This is the M part of the MVC design pattern for the LBaaS wizard workflow. It is responsible
|
||||
* for providing data to the view of each step in the workflow and collecting the user's input
|
||||
* from the view. It is also the center point of communication between the UI and services API.
|
||||
*
|
||||
* @param $q The angular service for promises.
|
||||
* @param neutronAPI The neutron service API.
|
||||
|
@ -49,7 +47,7 @@
|
|||
* @returns The model service for the create load balancer workflow.
|
||||
*/
|
||||
|
||||
function createLoadBalancerModel($q, neutronAPI, novaAPI, lbaasv2API, gettext) {
|
||||
function workflowModel($q, neutronAPI, novaAPI, lbaasv2API, gettext) {
|
||||
var initPromise, ports;
|
||||
|
||||
/**
|
||||
|
@ -60,16 +58,14 @@
|
|||
|
||||
initializing: false,
|
||||
initialized: false,
|
||||
context: null,
|
||||
|
||||
/**
|
||||
* @name spec
|
||||
*
|
||||
* @description
|
||||
* A dictionary like object containing specification collected from user
|
||||
* input. Required properties include:
|
||||
*
|
||||
* @property {String} name: The new load balancer name.
|
||||
* @property {String} subnet: The subnet for the load balancer.
|
||||
* input.
|
||||
*/
|
||||
|
||||
spec: null,
|
||||
|
@ -87,21 +83,31 @@
|
|||
*/
|
||||
|
||||
initialize: initialize,
|
||||
createLoadBalancer: createLoadBalancer
|
||||
submit: submit
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name createLoadBalancerModel.initialize
|
||||
* @name workflowModel.initialize
|
||||
* @returns {promise}
|
||||
*
|
||||
* @description
|
||||
* Send request to get all data to initialize the model.
|
||||
*
|
||||
* @param resource Resource type being created / edited, one of 'loadbalancer', 'listener',
|
||||
* 'pool', 'monitor', or 'members'.
|
||||
* @param id ID of the resource being edited.
|
||||
*/
|
||||
|
||||
function initialize() {
|
||||
function initialize(resource, id) {
|
||||
var promise;
|
||||
|
||||
model.context = {
|
||||
resource: resource,
|
||||
id: id,
|
||||
submit: null
|
||||
};
|
||||
|
||||
model.spec = {
|
||||
loadbalancer: {
|
||||
name: null,
|
||||
|
@ -138,13 +144,56 @@
|
|||
} else {
|
||||
model.initializing = true;
|
||||
|
||||
promise = $q.all([
|
||||
lbaasv2API.getLoadBalancers().then(onGetLoadBalancers),
|
||||
neutronAPI.getSubnets().then(onGetSubnets),
|
||||
neutronAPI.getPorts().then(onGetPorts),
|
||||
novaAPI.getServers().then(onGetServers)
|
||||
]);
|
||||
var promises = [];
|
||||
|
||||
promises.push(lbaasv2API.getLoadBalancers().then(onGetLoadBalancers));
|
||||
promises.push(neutronAPI.getSubnets().then(onGetSubnets));
|
||||
promises.push(neutronAPI.getPorts().then(onGetPorts));
|
||||
promises.push(novaAPI.getServers().then(onGetServers));
|
||||
model.context.submit = createLoadBalancer;
|
||||
|
||||
// // Create load balancer (default)
|
||||
// if (resource === 'loadbalancer' && !id) {
|
||||
// promises.push(lbaasv2API.getLoadBalancers().then(onGetLoadBalancers));
|
||||
// promises.push(neutronAPI.getSubnets().then(onGetSubnets));
|
||||
// promises.push(neutronAPI.getPorts().then(onGetPorts));
|
||||
// promises.push(novaAPI.getServers().then(onGetServers));
|
||||
// model.context.submit = createLoadBalancer;
|
||||
// }
|
||||
// // Edit load balancer
|
||||
// else if (resource === 'loadbalancer' && id) {
|
||||
// // Get load balancer
|
||||
// model.context.submit = editLoadBalancer;
|
||||
// }
|
||||
// // Create listener
|
||||
// else if (resource === 'listener' && !id) {
|
||||
// promises.push(neutronAPI.getSubnets().then(onGetSubnets));
|
||||
// promises.push(neutronAPI.getPorts().then(onGetPorts));
|
||||
// promises.push(novaAPI.getServers().then(onGetServers));
|
||||
// model.context.submit = createListener;
|
||||
// }
|
||||
// // Edit listener
|
||||
// else if (resource === 'listener' && id) {
|
||||
// // Get listener, pool, members, monitor
|
||||
// model.context.submit = editListener;
|
||||
// }
|
||||
// // Edit pool
|
||||
// else if (resource === 'pool' && id) {
|
||||
// // Get pool, members, monitor
|
||||
// model.context.submit = editPool;
|
||||
// }
|
||||
// // Edit monitor
|
||||
// else if (resource === 'monitor' && id) {
|
||||
// // Get monitor
|
||||
// model.context.submit = editMonitor;
|
||||
// }
|
||||
// // Edit members
|
||||
// else if (resource === 'members' && id) {
|
||||
// // Get pool members by pool id
|
||||
// model.context.submit = editMembers;
|
||||
// }
|
||||
|
||||
promise = $q.all(promises);
|
||||
promise.then(onInitSuccess, onInitFail);
|
||||
}
|
||||
|
||||
|
@ -164,17 +213,25 @@
|
|||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name createLoadBalancerModel.createLoadBalancer
|
||||
* @name workflowModel.submit
|
||||
* @returns {promise}
|
||||
*
|
||||
* @description
|
||||
* Send request for creating the load balancer.
|
||||
* Send request for completing the wizard.
|
||||
*
|
||||
* @returns Response from the LBaaS V2 API for creating a load balancer.
|
||||
* @returns Response from the LBaaS V2 API.
|
||||
*/
|
||||
|
||||
function createLoadBalancer() {
|
||||
function submit() {
|
||||
var finalSpec = angular.copy(model.spec);
|
||||
var resource = model.context.resource;
|
||||
|
||||
// Load balancer requires subnet
|
||||
if (!finalSpec.loadbalancer.subnet) {
|
||||
delete finalSpec.loadbalancer;
|
||||
} else {
|
||||
finalSpec.loadbalancer.subnet = finalSpec.loadbalancer.subnet.id;
|
||||
}
|
||||
|
||||
// Listener requires protocol and port
|
||||
if (!finalSpec.listener.protocol || !finalSpec.listener.port) {
|
||||
|
@ -182,7 +239,9 @@
|
|||
}
|
||||
|
||||
// Pool requires protocol and method, and also the listener
|
||||
if (!finalSpec.listener || !finalSpec.pool.protocol || !finalSpec.pool.method) {
|
||||
if (resource !== 'pool' && !finalSpec.listener ||
|
||||
!finalSpec.pool.protocol ||
|
||||
!finalSpec.pool.method) {
|
||||
delete finalSpec.pool;
|
||||
}
|
||||
|
||||
|
@ -190,9 +249,11 @@
|
|||
cleanFinalSpecMonitor(finalSpec);
|
||||
removeNulls(finalSpec);
|
||||
|
||||
finalSpec.loadbalancer.subnet = finalSpec.loadbalancer.subnet.id;
|
||||
return model.context.submit(finalSpec);
|
||||
}
|
||||
|
||||
return lbaasv2API.createLoadBalancer(finalSpec);
|
||||
function createLoadBalancer(spec) {
|
||||
return lbaasv2API.createLoadBalancer(spec);
|
||||
}
|
||||
|
||||
function cleanFinalSpecMembers(finalSpec) {
|
|
@ -16,7 +16,7 @@
|
|||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('LBaaS v2 Create Load Balancer Workflow Model Service', function() {
|
||||
describe('LBaaS v2 Workflow Model Service', function() {
|
||||
var model, $q, scope;
|
||||
|
||||
beforeEach(module('horizon.framework.util.i18n'));
|
||||
|
@ -77,7 +77,7 @@
|
|||
|
||||
beforeEach(inject(function ($injector) {
|
||||
model = $injector.get(
|
||||
'horizon.dashboard.project.lbaasv2.loadbalancers.actions.create.model'
|
||||
'horizon.dashboard.project.lbaasv2.workflow.model'
|
||||
);
|
||||
$q = $injector.get('$q');
|
||||
scope = $injector.get('$rootScope').$new();
|
||||
|
@ -130,15 +130,19 @@
|
|||
expect(model.initialize).toBeDefined();
|
||||
});
|
||||
|
||||
it('has a "createLoadBalancer" function', function() {
|
||||
expect(model.createLoadBalancer).toBeDefined();
|
||||
it('has a "submit" function', function() {
|
||||
expect(model.submit).toBeDefined();
|
||||
});
|
||||
|
||||
it('has a "context" object', function() {
|
||||
expect(model.context).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Post initialize model', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model.initialize();
|
||||
model.initialize('loadbalancer');
|
||||
scope.$apply();
|
||||
});
|
||||
|
||||
|
@ -166,6 +170,12 @@
|
|||
expect(model.spec.monitor.status).toBe('200');
|
||||
expect(model.spec.monitor.path).toBe('/');
|
||||
});
|
||||
|
||||
it('should initialize context', function() {
|
||||
expect(model.context.resource).toBe('loadbalancer');
|
||||
expect(model.context.id).toBeUndefined();
|
||||
expect(model.context.submit).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Initialization failure', function() {
|
||||
|
@ -287,7 +297,7 @@
|
|||
});
|
||||
});
|
||||
|
||||
describe('Create Load Balancer', function() {
|
||||
describe('Model submit function', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model.initialize();
|
||||
|
@ -318,7 +328,7 @@
|
|||
model.spec.monitor.retry = 1;
|
||||
model.spec.monitor.timeout = 1;
|
||||
|
||||
var finalSpec = model.createLoadBalancer();
|
||||
var finalSpec = model.submit();
|
||||
|
||||
expect(finalSpec.loadbalancer.name).toBe('Load Balancer 3');
|
||||
expect(finalSpec.loadbalancer.description).toBeUndefined();
|
||||
|
@ -347,12 +357,20 @@
|
|||
expect(finalSpec.monitor.timeout).toBe(1);
|
||||
});
|
||||
|
||||
it('should delete load balancer if any required property is not set', function() {
|
||||
model.spec.loadbalancer.ip = '1.2.3.4';
|
||||
|
||||
var finalSpec = model.submit();
|
||||
|
||||
expect(finalSpec.loadbalancer).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should delete listener if any required property is not set', function() {
|
||||
model.spec.loadbalancer.ip = '1.2.3.4';
|
||||
model.spec.loadbalancer.subnet = model.subnets[0];
|
||||
model.spec.listener.protocol = 'HTTPS';
|
||||
|
||||
var finalSpec = model.createLoadBalancer();
|
||||
var finalSpec = model.submit();
|
||||
|
||||
expect(finalSpec.loadbalancer).toBeDefined();
|
||||
expect(finalSpec.listener).toBeUndefined();
|
||||
|
@ -365,7 +383,7 @@
|
|||
model.spec.listener.protocol = 'HTTPS';
|
||||
model.spec.listener.port = 80;
|
||||
|
||||
var finalSpec = model.createLoadBalancer();
|
||||
var finalSpec = model.submit();
|
||||
|
||||
expect(finalSpec.loadbalancer).toBeDefined();
|
||||
expect(finalSpec.listener).toBeDefined();
|
||||
|
@ -380,7 +398,7 @@
|
|||
model.spec.pool.protocol = 'HTTP';
|
||||
model.spec.pool.method = 'LEAST_CONNECTIONS';
|
||||
|
||||
var finalSpec = model.createLoadBalancer();
|
||||
var finalSpec = model.submit();
|
||||
|
||||
expect(finalSpec.loadbalancer).toBeDefined();
|
||||
expect(finalSpec.listener).toBeDefined();
|
||||
|
@ -399,7 +417,7 @@
|
|||
model.spec.monitor.interval = 1;
|
||||
model.spec.monitor.retry = 1;
|
||||
|
||||
var finalSpec = model.createLoadBalancer();
|
||||
var finalSpec = model.submit();
|
||||
|
||||
expect(finalSpec.loadbalancer).toBeDefined();
|
||||
expect(finalSpec.listener).toBeDefined();
|
|
@ -17,26 +17,26 @@
|
|||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.loadbalancers')
|
||||
.controller('CreateMonitorController', CreateMonitorController);
|
||||
.module('horizon.dashboard.project.lbaasv2')
|
||||
.controller('MonitorDetailsController', MonitorDetailsController);
|
||||
|
||||
CreateMonitorController.$inject = [
|
||||
MonitorDetailsController.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.patterns',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name CreateMonitorController
|
||||
* @name MonitorDetailsController
|
||||
* @description
|
||||
* The `CreateMonitorController` controller provides functions for
|
||||
* configuring the health monitor step when creating a new health monitor.
|
||||
* The `MonitorDetailsController` controller provides functions for
|
||||
* configuring the health monitor step of the LBaaS wizard.
|
||||
* @param patterns The LBaaS v2 patterns constant.
|
||||
* @param gettext The horizon gettext function for translation.
|
||||
* @returns undefined
|
||||
*/
|
||||
|
||||
function CreateMonitorController(patterns, gettext) {
|
||||
function MonitorDetailsController(patterns, gettext) {
|
||||
|
||||
var ctrl = this;
|
||||
|
|
@ -16,16 +16,16 @@
|
|||
(function() {
|
||||
'use strict';
|
||||
|
||||
describe('Create Monitor Step', function() {
|
||||
describe('Monitor Details Step', function() {
|
||||
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
describe('CreateMonitorController', function() {
|
||||
describe('MonitorDetailsController', function() {
|
||||
var ctrl;
|
||||
|
||||
beforeEach(inject(function($controller) {
|
||||
ctrl = $controller('CreateMonitorController');
|
||||
ctrl = $controller('MonitorDetailsController');
|
||||
}));
|
||||
|
||||
it('should define error messages for invalid fields', function() {
|
|
@ -1,9 +1,9 @@
|
|||
<div ng-controller="CreateMonitorController as ctrl">
|
||||
<div ng-controller="MonitorDetailsController as ctrl">
|
||||
<h1 translate>Monitor</h1>
|
||||
|
||||
<!--content-->
|
||||
<div class="content">
|
||||
<div translate class="subtitle">Provide the details for the new health monitor. The monitor will only be created if values are provided for all fields marked as required. A listener and pool are also required.</div>
|
||||
<div translate class="subtitle">Provide the details for the health monitor.</div>
|
||||
|
||||
<div class="row form-group">
|
||||
|
||||
|
@ -24,10 +24,10 @@
|
|||
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div class="form-field required monitor-interval"
|
||||
ng-class="{ 'has-error': createLoadBalancerMonitorForm['monitor-interval'].$invalid && createLoadBalancerMonitorForm['monitor-interval'].$dirty }">
|
||||
ng-class="{ 'has-error': monitorDetailsForm['monitor-interval'].$invalid && monitorDetailsForm['monitor-interval'].$dirty }">
|
||||
<label translate class="on-top" for="monitor-interval">Health check interval (sec)</label>
|
||||
<span class="fa fa-exclamation-triangle invalid"
|
||||
ng-show="createLoadBalancerMonitorForm['monitor-interval'].$invalid && createLoadBalancerMonitorForm.$dirty"
|
||||
ng-show="monitorDetailsForm['monitor-interval'].$invalid && monitorDetailsForm.$dirty"
|
||||
popover="{$ ::ctrl.intervalError $}"
|
||||
popover-placement="top" popover-append-to-body="true"
|
||||
popover-trigger="hover"></span>
|
||||
|
@ -43,10 +43,10 @@
|
|||
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div class="form-field required monitor-retry"
|
||||
ng-class="{ 'has-error': createLoadBalancerMonitorForm['monitor-retry'].$invalid && createLoadBalancerMonitorForm['monitor-retry'].$dirty }">
|
||||
ng-class="{ 'has-error': monitorDetailsForm['monitor-retry'].$invalid && monitorDetailsForm['monitor-retry'].$dirty }">
|
||||
<label translate class="on-top" for="monitor-retry">Retry count before markdown</label>
|
||||
<span class="fa fa-exclamation-triangle invalid"
|
||||
ng-show="createLoadBalancerMonitorForm['monitor-retry'].$invalid && createLoadBalancerMonitorForm.$dirty"
|
||||
ng-show="monitorDetailsForm['monitor-retry'].$invalid && monitorDetailsForm.$dirty"
|
||||
popover="{$ ::ctrl.retryError $}"
|
||||
popover-placement="top" popover-append-to-body="true"
|
||||
popover-trigger="hover"></span>
|
||||
|
@ -62,10 +62,10 @@
|
|||
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div class="form-field required monitor-timeout"
|
||||
ng-class="{ 'has-error': createLoadBalancerMonitorForm['monitor-timeout'].$invalid && createLoadBalancerMonitorForm['monitor-timeout'].$dirty }">
|
||||
ng-class="{ 'has-error': monitorDetailsForm['monitor-timeout'].$invalid && monitorDetailsForm['monitor-timeout'].$dirty }">
|
||||
<label translate class="on-top" for="monitor-timeout">Timeout (sec)</label>
|
||||
<span class="fa fa-exclamation-triangle invalid"
|
||||
ng-show="createLoadBalancerMonitorForm['monitor-timeout'].$invalid && createLoadBalancerMonitorForm.$dirty"
|
||||
ng-show="monitorDetailsForm['monitor-timeout'].$invalid && monitorDetailsForm.$dirty"
|
||||
popover="{$ ::ctrl.timeoutError $}"
|
||||
popover-placement="top" popover-append-to-body="true"
|
||||
popover-trigger="hover"></span>
|
||||
|
@ -92,10 +92,10 @@
|
|||
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div class="form-field monitor-status"
|
||||
ng-class="{ 'has-error': createLoadBalancerMonitorForm['monitor-status'].$invalid && createLoadBalancerMonitorForm['monitor-status'].$dirty }">
|
||||
ng-class="{ 'has-error': monitorDetailsForm['monitor-status'].$invalid && monitorDetailsForm['monitor-status'].$dirty }">
|
||||
<label translate class="on-top" for="monitor-status">Expected HTTP status code</label>
|
||||
<span class="fa fa-exclamation-triangle invalid"
|
||||
ng-show="createLoadBalancerMonitorForm['monitor-status'].$invalid && createLoadBalancerMonitorForm.$dirty"
|
||||
ng-show="monitorDetailsForm['monitor-status'].$invalid && monitorDetailsForm.$dirty"
|
||||
popover="{$ ::ctrl.statusError $}"
|
||||
popover-placement="top" popover-append-to-body="true"
|
||||
popover-trigger="hover"></span>
|
||||
|
@ -111,10 +111,10 @@
|
|||
|
||||
<div class="col-sm-6 col-md-3">
|
||||
<div class="form-field monitor-path"
|
||||
ng-class="{ 'has-error': createLoadBalancerMonitorForm['monitor-path'].$invalid && createLoadBalancerMonitorForm['monitor-path'].$dirty }">
|
||||
ng-class="{ 'has-error': monitorDetailsForm['monitor-path'].$invalid && monitorDetailsForm['monitor-path'].$dirty }">
|
||||
<label translate class="on-top" for="monitor-path">URL path</label>
|
||||
<span class="fa fa-exclamation-triangle invalid"
|
||||
ng-show="createLoadBalancerMonitorForm['monitor-path'].$invalid && createLoadBalancerMonitorForm.$dirty"
|
||||
ng-show="monitorDetailsForm['monitor-path'].$invalid && monitorDetailsForm.$dirty"
|
||||
popover="{$ ::ctrl.pathError $}"
|
||||
popover-placement="top" popover-append-to-body="true"
|
||||
popover-trigger="hover"></span>
|
|
@ -17,7 +17,7 @@
|
|||
'use strict';
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.project.lbaasv2.loadbalancers')
|
||||
.module('horizon.dashboard.project.lbaasv2')
|
||||
.controller('CreatePoolDetailsController', CreatePoolDetailsController);
|
||||
|
||||
CreatePoolDetailsController.$inject = [
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
<!--content-->
|
||||
<div class="content">
|
||||
<div translate class="subtitle">Provide the details for the new load balancer pool. The pool will only be created if values are provided for all fields marked as required.</div>
|
||||
<div translate class="subtitle">Provide the details for the pool.</div>
|
||||
|
||||
<div class="row form-group">
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright 2015 IBM Corp.
|
||||
*
|
||||
* 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('horizon.dashboard.project.lbaasv2')
|
||||
.factory('horizon.dashboard.project.lbaasv2.workflow.workflow', lbaasWorkflow);
|
||||
|
||||
lbaasWorkflow.$inject = [
|
||||
'horizon.dashboard.project.lbaasv2.basePath',
|
||||
'horizon.app.core.workflow.factory',
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
function lbaasWorkflow(basePath, dashboardWorkflow, gettext) {
|
||||
var workflowSteps = [
|
||||
{
|
||||
id: 'loadbalancer',
|
||||
title: gettext('Load Balancer Details'),
|
||||
templateUrl: basePath + 'workflow/loadbalancer/loadbalancer.html',
|
||||
helpUrl: basePath + 'workflow/loadbalancer/loadbalancer.help.html',
|
||||
formName: 'loadBalancerDetailsForm'
|
||||
},
|
||||
{
|
||||
id: 'listener',
|
||||
title: gettext('Listener Details'),
|
||||
templateUrl: basePath + 'workflow/listener/listener.html',
|
||||
helpUrl: basePath + 'workflow/listener/listener.help.html',
|
||||
formName: 'listenerDetailsForm'
|
||||
},
|
||||
{
|
||||
id: 'pool',
|
||||
title: gettext('Pool Details'),
|
||||
templateUrl: basePath + 'workflow/pool/pool.html',
|
||||
helpUrl: basePath + 'workflow/pool/pool.help.html',
|
||||
formName: 'poolDetailsForm'
|
||||
},
|
||||
{
|
||||
id: 'members',
|
||||
title: gettext('Pool Members'),
|
||||
templateUrl: basePath + 'workflow/members/members.html',
|
||||
helpUrl: basePath + 'workflow/members/members.help.html',
|
||||
formName: 'memberDetailsForm'
|
||||
},
|
||||
{
|
||||
id: 'monitor',
|
||||
title: gettext('Monitor Details'),
|
||||
templateUrl: basePath + 'workflow/monitor/monitor.html',
|
||||
helpUrl: basePath + 'workflow/monitor/monitor.help.html',
|
||||
formName: 'monitorDetailsForm'
|
||||
}
|
||||
];
|
||||
|
||||
return initWorkflow;
|
||||
|
||||
function initWorkflow(title, icon, steps) {
|
||||
return dashboardWorkflow({
|
||||
title: title,
|
||||
btnText: {
|
||||
finish: title
|
||||
},
|
||||
btnIcon: {
|
||||
finish: icon
|
||||
},
|
||||
steps: steps ? workflowSteps.filter(function(step) {
|
||||
return steps.indexOf(step.id) > -1;
|
||||
}) : workflowSteps
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright 2015 IBM Corp.
|
||||
*
|
||||
* 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('LBaaS v2 Workflow Service', function() {
|
||||
var workflowService;
|
||||
|
||||
beforeEach(module('horizon.app.core'));
|
||||
beforeEach(module('horizon.framework.util'));
|
||||
beforeEach(module('horizon.framework.conf'));
|
||||
beforeEach(module('horizon.framework.widgets.toast'));
|
||||
beforeEach(module('horizon.dashboard.project.lbaasv2'));
|
||||
|
||||
beforeEach(inject(function ($injector) {
|
||||
workflowService = $injector.get(
|
||||
'horizon.dashboard.project.lbaasv2.workflow.workflow'
|
||||
);
|
||||
}));
|
||||
|
||||
it('should be defined', function () {
|
||||
expect(workflowService).toBeDefined();
|
||||
});
|
||||
|
||||
it('should have a title property', function () {
|
||||
var workflow = workflowService('My Workflow');
|
||||
expect(workflow.title).toBe('My Workflow');
|
||||
});
|
||||
|
||||
it('should have default steps defined', function () {
|
||||
var workflow = workflowService('My Workflow');
|
||||
expect(workflow.steps).toBeDefined();
|
||||
expect(workflow.steps.length).toBe(5);
|
||||
|
||||
var forms = [
|
||||
'loadBalancerDetailsForm',
|
||||
'listenerDetailsForm',
|
||||
'poolDetailsForm',
|
||||
'memberDetailsForm',
|
||||
'monitorDetailsForm'
|
||||
];
|
||||
|
||||
forms.forEach(function(expectedForm, idx) {
|
||||
expect(workflow.steps[idx].formName).toBe(expectedForm);
|
||||
});
|
||||
});
|
||||
|
||||
it('can filter steps', function () {
|
||||
var workflow = workflowService('My Workflow', 'foo', ['listener', 'pool']);
|
||||
expect(workflow.steps).toBeDefined();
|
||||
expect(workflow.steps.length).toBe(2);
|
||||
|
||||
var forms = [
|
||||
'listenerDetailsForm',
|
||||
'poolDetailsForm'
|
||||
];
|
||||
|
||||
forms.forEach(function(expectedForm, idx) {
|
||||
expect(workflow.steps[idx].formName).toBe(expectedForm);
|
||||
});
|
||||
});
|
||||
|
||||
it('can be extended', function () {
|
||||
var workflow = workflowService('My Workflow');
|
||||
expect(workflow.append).toBeDefined();
|
||||
expect(workflow.prepend).toBeDefined();
|
||||
expect(workflow.after).toBeDefined();
|
||||
expect(workflow.replace).toBeDefined();
|
||||
expect(workflow.remove).toBeDefined();
|
||||
expect(workflow.addController).toBeDefined();
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
Loading…
Reference in New Issue