Remove deprecated scope handling
The `initScope` function is deprecated since ocata, so this patch replaces it into `initAction` if it needed, or removes it. Also, gets scope from second parameter of perform function. Futher more, removes deprecated `scope` parameter for `modal` function of wizard-modal-service. Change-Id: I8979b699a9b4383b894db9bdcbad80f15c1df150 Closes-Bug: #1640049
This commit is contained in:
parent
f911d0dd40
commit
9a758638ee
@ -149,7 +149,7 @@
|
||||
*
|
||||
* If an action does not have an initAction() function, it is ignored.
|
||||
*/
|
||||
function initActions(scope) {
|
||||
function initActions() {
|
||||
angular.forEach(self.itemActions, setActionScope);
|
||||
angular.forEach(self.batchActions, setActionScope);
|
||||
angular.forEach(self.globalActions, setActionScope);
|
||||
@ -157,14 +157,6 @@
|
||||
function setActionScope(action) {
|
||||
if (action.service.initAction) {
|
||||
action.service.initAction();
|
||||
} else if (action.service.initScope) {
|
||||
// The use of scope in action services breaks the singleton nature
|
||||
// of the services, and should be stopped. State should be held on
|
||||
// controllers instead; scope is now passed into allow() and perform()
|
||||
// methods.
|
||||
$log.warn('The initScope() method is deprecated. ' +
|
||||
'Invocation of it will stop in Queens.');
|
||||
action.service.initScope(scope.$new());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -170,9 +170,8 @@
|
||||
});
|
||||
|
||||
it('initActions calls initAction on item and batch actions', function () {
|
||||
var action = {service: {initAction: angular.noop, initScope: angular.noop}};
|
||||
var action = {service: {initAction: angular.noop}};
|
||||
spyOn(action.service, 'initAction');
|
||||
spyOn(action.service, 'initScope');
|
||||
type.batchActions.push(action);
|
||||
type.initActions({
|
||||
'$new': function () {
|
||||
@ -180,22 +179,9 @@
|
||||
}
|
||||
});
|
||||
expect(action.service.initAction).toHaveBeenCalled();
|
||||
expect(action.service.initScope).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('initActions calls initScope if initAction is not defined', function () {
|
||||
var action = {service: {initScope: angular.noop}};
|
||||
spyOn(action.service, 'initScope');
|
||||
type.batchActions.push(action);
|
||||
type.initActions({
|
||||
'$new': function () {
|
||||
return 4;
|
||||
}
|
||||
});
|
||||
expect(action.service.initScope).toHaveBeenCalledWith(4);
|
||||
});
|
||||
|
||||
it('initActions ignores initAction and initScope when not present', function () {
|
||||
it('initActions ignores initAction when not present', function () {
|
||||
var action = {service: {}};
|
||||
type.batchActions.push(action);
|
||||
var returned = type.initActions({});
|
||||
|
@ -115,7 +115,7 @@
|
||||
* - When using 'delete-selected' for 'batch' type, all selected rows are passed as
|
||||
* an array.
|
||||
*
|
||||
* There is a third optional function, initAction (which was previously called initScope)
|
||||
* There is a third optional function, initAction.
|
||||
* Actions may perform post-config (in the angular sense) initialization by
|
||||
* providing an initAction method. This might be typically invoked by initActions()
|
||||
* on a ResourceType. Actions should not perform blocking operations in their
|
||||
|
@ -25,8 +25,7 @@
|
||||
'horizon.framework.util.actions.action-result.service',
|
||||
'horizon.framework.widgets.modal-wait-spinner.service',
|
||||
'$q',
|
||||
'$routeParams',
|
||||
'$rootScope'
|
||||
'$routeParams'
|
||||
];
|
||||
|
||||
function controller(
|
||||
@ -34,8 +33,7 @@
|
||||
resultService,
|
||||
spinnerService,
|
||||
$q,
|
||||
$routeParams,
|
||||
$rootScope
|
||||
$routeParams
|
||||
) {
|
||||
var ctrl = this;
|
||||
|
||||
@ -54,7 +52,7 @@
|
||||
function loadData(response) {
|
||||
spinnerService.hideModalSpinner();
|
||||
ctrl.showDetails = true;
|
||||
ctrl.resourceType.initActions($rootScope.$new());
|
||||
ctrl.resourceType.initActions();
|
||||
ctrl.itemData = response.data;
|
||||
ctrl.itemName = ctrl.resourceType.itemName(response.data);
|
||||
}
|
||||
|
@ -28,13 +28,11 @@
|
||||
* .controller('modalExampleCtrl', ExampleCtrl);
|
||||
*
|
||||
* ExampleCtrl.$inject = [
|
||||
* '$scope',
|
||||
* 'horizon.framework.widgets.modal.wizard-modal.service'
|
||||
* ];
|
||||
*
|
||||
* function ExampleCtrl($scope, wizardModalService) {
|
||||
* var options = {
|
||||
* scope: scope, // the scope to use for the Wizard
|
||||
* workflow: workflow, // the workflow used in the wizard
|
||||
* submit: submit // callback to call on a wizard submit
|
||||
* };
|
||||
@ -81,13 +79,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
// backwards compatibility
|
||||
if (angular.isDefined(params.scope)) {
|
||||
$log.warn('The "scope" param to modal() is deprecated.' +
|
||||
'Handling of it will stop in Queens.');
|
||||
options.scope = params.scope;
|
||||
}
|
||||
|
||||
return $uibModal.open(options);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
"use strict";
|
||||
|
||||
describe('horizon.framework.widgets.wizard-modal.service', function() {
|
||||
var service, modal, $scope;
|
||||
var service, modal;
|
||||
|
||||
beforeEach(module('horizon.framework'));
|
||||
beforeEach(module(function($provide) {
|
||||
@ -26,8 +26,7 @@
|
||||
$provide.value('$uibModal', modal);
|
||||
}));
|
||||
|
||||
beforeEach(inject(function($injector, _$rootScope_) {
|
||||
$scope = _$rootScope_.$new();
|
||||
beforeEach(inject(function($injector) {
|
||||
service = $injector.get('horizon.framework.widgets.modal.wizard-modal.service');
|
||||
}));
|
||||
|
||||
@ -43,7 +42,7 @@
|
||||
|
||||
it('should open the modal if called with required parameters', function() {
|
||||
spyOn(modal, 'open').and.callThrough();
|
||||
service.modal({scope: $scope, workflow: {}, submit: {}});
|
||||
service.modal({workflow: {}, submit: {}});
|
||||
expect(modal.open).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@ -51,11 +50,10 @@
|
||||
spyOn(modal, 'open').and.callThrough();
|
||||
var workflow = {id: 'w'};
|
||||
var submit = {id: 's'};
|
||||
service.modal({scope: $scope, workflow: workflow, submit: submit});
|
||||
service.modal({workflow: workflow, submit: submit});
|
||||
expect(modal.open).toHaveBeenCalled();
|
||||
var modalOpenArgs = modal.open.calls.argsFor(0)[0];
|
||||
expect(modalOpenArgs.controller).toEqual('WizardModalController as modalCtrl');
|
||||
expect(modalOpenArgs.scope).toEqual($scope);
|
||||
expect(modalOpenArgs.resolve.workflow()).toEqual(workflow);
|
||||
expect(modalOpenArgs.resolve.submit()).toEqual(submit);
|
||||
});
|
||||
|
@ -193,11 +193,11 @@
|
||||
}
|
||||
|
||||
function onGlobalActionSelected(action) {
|
||||
if (action.service.initScope) {
|
||||
action.service.initScope($scope.$new());
|
||||
if (action.service.initAction) {
|
||||
action.service.initAction();
|
||||
}
|
||||
|
||||
return action.service.perform();
|
||||
return action.service.perform(null, $scope.$new());
|
||||
}
|
||||
|
||||
function onActionSelected(action) {
|
||||
@ -206,11 +206,11 @@
|
||||
typeData.load(ctrl.resourceId).then(performAction, loadFailed);
|
||||
|
||||
function performAction(resource) {
|
||||
if (action.service.initScope) {
|
||||
action.service.initScope($scope.$new());
|
||||
if (action.service.initAction) {
|
||||
action.service.initAction();
|
||||
}
|
||||
|
||||
return action.service.perform(resource.data);
|
||||
return action.service.perform(resource.data, $scope.$new());
|
||||
}
|
||||
|
||||
function loadFailed(reason) {
|
||||
|
@ -55,12 +55,9 @@
|
||||
success: gettext('Image %s was successfully created.')
|
||||
};
|
||||
|
||||
var model = {};
|
||||
|
||||
var scope;
|
||||
|
||||
var service = {
|
||||
initScope: initScope,
|
||||
perform: perform,
|
||||
allowed: allowed
|
||||
};
|
||||
@ -68,48 +65,25 @@
|
||||
return service;
|
||||
|
||||
//////////////
|
||||
function initScope($scope) {
|
||||
var watchImageChange = $scope.$on(events.IMAGE_CHANGED, onImageChange);
|
||||
var watchMetadataChange = $scope.$on(events.IMAGE_METADATA_CHANGED, onMetadataChange);
|
||||
|
||||
scope = $scope;
|
||||
|
||||
$scope.$on('$destroy', destroy);
|
||||
|
||||
function destroy() {
|
||||
watchImageChange();
|
||||
watchMetadataChange();
|
||||
}
|
||||
}
|
||||
|
||||
function onImageChange(e, image) {
|
||||
model.image = image;
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
function onMetadataChange(e, metadata) {
|
||||
model.metadata = metadata;
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
function allowed() {
|
||||
return policy.ifAllowed({ rules: [['image', 'add_image']] });
|
||||
}
|
||||
|
||||
function perform() {
|
||||
model.image = {};
|
||||
model.metadata = {};
|
||||
scope.image = {};
|
||||
function perform(selected, $scope) {
|
||||
scope = $scope;
|
||||
|
||||
return wizardModalService.modal({
|
||||
scope: scope,
|
||||
workflow: createWorkflow,
|
||||
submit: submit
|
||||
}).result;
|
||||
}
|
||||
|
||||
function submit() {
|
||||
var finalModel = angular.extend({}, model.image, model.metadata);
|
||||
function submit(stepModels) {
|
||||
var finalModel = angular.extend(
|
||||
{},
|
||||
stepModels.imageForm,
|
||||
stepModels.updateMetadataForm);
|
||||
if (finalModel.source_type === 'url') {
|
||||
delete finalModel.data;
|
||||
} else {
|
||||
|
@ -29,10 +29,8 @@
|
||||
};
|
||||
|
||||
var wizardModalService = {
|
||||
modal: function (config) {
|
||||
deferredModal = $q.defer();
|
||||
deferredModal.resolve(config.scope.image);
|
||||
return {result: deferredModal.promise};
|
||||
modal: function () {
|
||||
return { result: {catch: angular.noop} };
|
||||
}
|
||||
};
|
||||
|
||||
@ -54,7 +52,7 @@
|
||||
}
|
||||
};
|
||||
|
||||
var service, events, $scope, deferredModal, deferredCreate, $q;
|
||||
var service, $scope, deferredCreate, $q;
|
||||
|
||||
///////////////////////
|
||||
|
||||
@ -71,7 +69,6 @@
|
||||
beforeEach(inject(function($injector, _$rootScope_, _$q_) {
|
||||
$scope = _$rootScope_.$new();
|
||||
service = $injector.get('horizon.app.core.images.actions.create.service');
|
||||
events = $injector.get('horizon.app.core.images.events');
|
||||
$q = _$q_;
|
||||
}));
|
||||
|
||||
@ -85,14 +82,11 @@
|
||||
it('open the modal with the correct parameters', function() {
|
||||
spyOn(wizardModalService, 'modal').and.callThrough();
|
||||
|
||||
service.initScope($scope);
|
||||
service.perform();
|
||||
service.perform(null, $scope);
|
||||
|
||||
expect(wizardModalService.modal).toHaveBeenCalled();
|
||||
expect($scope.image).toEqual({});
|
||||
|
||||
var modalArgs = wizardModalService.modal.calls.argsFor(0)[0];
|
||||
expect(modalArgs.scope).toEqual($scope);
|
||||
expect(modalArgs.workflow).toBeDefined();
|
||||
expect(modalArgs.submit).toBeDefined();
|
||||
});
|
||||
@ -105,14 +99,10 @@
|
||||
spyOn(glanceAPI, 'createImage').and.callThrough();
|
||||
spyOn(wizardModalService, 'modal').and.callThrough();
|
||||
|
||||
service.initScope($scope);
|
||||
service.perform();
|
||||
|
||||
$scope.$emit(events.IMAGE_CHANGED, image);
|
||||
$scope.$emit(events.IMAGE_METADATA_CHANGED, newMetadata);
|
||||
service.perform(null, $scope);
|
||||
|
||||
var modalArgs = wizardModalService.modal.calls.argsFor(0)[0];
|
||||
modalArgs.submit();
|
||||
modalArgs.submit({imageForm: image, updateMetadataForm: newMetadata});
|
||||
$scope.$apply();
|
||||
|
||||
expect(glanceAPI.createImage.calls.argsFor(0)[0]).toEqual(
|
||||
@ -128,12 +118,10 @@
|
||||
spyOn(glanceAPI, 'createImage').and.callThrough();
|
||||
spyOn(wizardModalService, 'modal').and.callThrough();
|
||||
|
||||
service.initScope($scope);
|
||||
service.perform();
|
||||
$scope.$emit(events.IMAGE_CHANGED, image);
|
||||
service.perform(null, $scope);
|
||||
|
||||
var modalArgs = wizardModalService.modal.calls.argsFor(0)[0];
|
||||
modalArgs.submit();
|
||||
modalArgs.submit({imageForm: image});
|
||||
|
||||
expect(glanceAPI.createImage.calls.argsFor(0)[0]).toEqual({ name: 'Test',
|
||||
source_type: 'file-direct', data: {name: 'test_file'}});
|
||||
@ -148,12 +136,10 @@
|
||||
spyOn(glanceAPI, 'createImage').and.callThrough();
|
||||
spyOn(wizardModalService, 'modal').and.callThrough();
|
||||
|
||||
service.initScope($scope);
|
||||
service.perform();
|
||||
$scope.$emit(events.IMAGE_CHANGED, image);
|
||||
service.perform(null, $scope);
|
||||
|
||||
var modalArgs = wizardModalService.modal.calls.argsFor(0)[0];
|
||||
modalArgs.submit();
|
||||
modalArgs.submit({imageForm: image});
|
||||
|
||||
expect(glanceAPI.createImage.calls.argsFor(0)[0]).toEqual({ name: 'Test',
|
||||
source_type: 'url', image_url: 'http://somewhere'});
|
||||
@ -168,12 +154,10 @@
|
||||
spyOn(glanceAPI, 'createImage').and.callThrough();
|
||||
spyOn(wizardModalService, 'modal').and.callThrough();
|
||||
|
||||
service.initScope($scope);
|
||||
service.perform();
|
||||
$scope.$emit(events.IMAGE_CHANGED, image);
|
||||
service.perform(null, $scope);
|
||||
|
||||
var modalArgs = wizardModalService.modal.calls.argsFor(0)[0];
|
||||
modalArgs.submit();
|
||||
modalArgs.submit({imageForm: image});
|
||||
|
||||
expect(glanceAPI.createImage.calls.argsFor(0)[0]).toEqual({ name: 'Test',
|
||||
source_type: 'file-direct', data: {name: 'test_file'}});
|
||||
@ -188,71 +172,15 @@
|
||||
spyOn(glanceAPI, 'createImage').and.callThrough();
|
||||
spyOn(wizardModalService, 'modal').and.callThrough();
|
||||
|
||||
service.initScope($scope);
|
||||
service.perform();
|
||||
$scope.$emit(events.IMAGE_CHANGED, image);
|
||||
service.perform(null, $scope);
|
||||
|
||||
var modalArgs = wizardModalService.modal.calls.argsFor(0)[0];
|
||||
modalArgs.submit();
|
||||
modalArgs.submit({imageForm: image});
|
||||
|
||||
expect(glanceAPI.createImage.calls.argsFor(0)[0]).toEqual({ name: 'Test',
|
||||
source_type: 'url', image_url: 'http://somewhere'});
|
||||
});
|
||||
|
||||
it('should raise event even if update metadata fails', function() {
|
||||
var image = { name: 'Test', id: '2' };
|
||||
var failedPromise = function() {
|
||||
return {
|
||||
then: function(callback, errorCallback) {
|
||||
errorCallback();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
spyOn(wizardModalService, 'modal').and.callThrough();
|
||||
spyOn(glanceAPI, 'createImage').and.callThrough();
|
||||
spyOn(metadataService, 'editMetadata').and.callFake(failedPromise);
|
||||
spyOn($scope, '$emit').and.callThrough();
|
||||
|
||||
service.initScope($scope);
|
||||
service.perform();
|
||||
$scope.$apply();
|
||||
|
||||
$scope.$emit(events.IMAGE_CHANGED, image);
|
||||
$scope.$emit(events.IMAGE_METADATA_CHANGED, newMetadata);
|
||||
|
||||
var newMetadata = {prop1: '11', prop3: '3'};
|
||||
var modalArgs = wizardModalService.modal.calls.argsFor(0)[0];
|
||||
modalArgs.submit();
|
||||
$scope.$apply();
|
||||
|
||||
expect($scope.$emit).toHaveBeenCalledWith(
|
||||
'horizon.app.core.images.IMAGE_METADATA_CHANGED', undefined);
|
||||
});
|
||||
|
||||
it('should destroy the event watchers', function() {
|
||||
var newImage = { name: 'Test2', id: '2' };
|
||||
var newMetadata = {p1: '11', p3: '3'};
|
||||
|
||||
spyOn(wizardModalService, 'modal').and.callThrough();
|
||||
spyOn(glanceAPI, 'createImage').and.callThrough();
|
||||
spyOn(metadataService, 'editMetadata').and.callThrough();
|
||||
|
||||
service.initScope($scope);
|
||||
service.perform();
|
||||
$scope.$apply();
|
||||
|
||||
$scope.$emit('$destroy');
|
||||
$scope.$emit(events.IMAGE_CHANGED, newImage);
|
||||
$scope.$emit(events.IMAGE_METADATA_CHANGED, newMetadata);
|
||||
|
||||
var modalArgs = wizardModalService.modal.calls.argsFor(0)[0];
|
||||
modalArgs.submit();
|
||||
$scope.$apply();
|
||||
|
||||
expect(glanceAPI.createImage.calls.argsFor(0)[0]).toEqual({});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
||||
|
@ -52,11 +52,9 @@
|
||||
toast,
|
||||
imagesResourceType
|
||||
) {
|
||||
var scope, context, deleteImagePromise;
|
||||
var notAllowedMessage = gettext("You are not allowed to delete images: %s");
|
||||
|
||||
var service = {
|
||||
initScope: initScope,
|
||||
allowed: allowed,
|
||||
perform: perform
|
||||
};
|
||||
@ -65,17 +63,29 @@
|
||||
|
||||
//////////////
|
||||
|
||||
function initScope(newScope) {
|
||||
scope = newScope;
|
||||
context = { };
|
||||
deleteImagePromise = policy.ifAllowed({rules: [['image', 'delete_image']]});
|
||||
}
|
||||
|
||||
function perform(items) {
|
||||
function perform(items, newScope) {
|
||||
var scope = newScope;
|
||||
var context = { };
|
||||
var images = angular.isArray(items) ? items : [items];
|
||||
context.labels = labelize(images.length);
|
||||
context.deleteEntity = deleteImage;
|
||||
return $qExtensions.allSettled(images.map(checkPermission)).then(afterCheck);
|
||||
|
||||
function checkPermission(image) {
|
||||
return {promise: allowed(image), context: image};
|
||||
}
|
||||
|
||||
function afterCheck(result) {
|
||||
var outcome = $q.reject(); // Reject the promise by default
|
||||
if (result.fail.length > 0) {
|
||||
toast.add('error', getMessage(notAllowedMessage, result.fail));
|
||||
outcome = $q.reject(result.fail);
|
||||
}
|
||||
if (result.pass.length > 0) {
|
||||
outcome = deleteModal.open(scope, result.pass.map(getEntity), context).then(createResult);
|
||||
}
|
||||
return outcome;
|
||||
}
|
||||
}
|
||||
|
||||
function allowed(image) {
|
||||
@ -84,7 +94,6 @@
|
||||
if (image) {
|
||||
return $q.all([
|
||||
notProtected(image),
|
||||
deleteImagePromise,
|
||||
policy.ifAllowed({ rules: [['image', 'delete_image']] }),
|
||||
notDeleted(image)
|
||||
]);
|
||||
@ -93,22 +102,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function checkPermission(image) {
|
||||
return {promise: allowed(image), context: image};
|
||||
}
|
||||
|
||||
function afterCheck(result) {
|
||||
var outcome = $q.reject(); // Reject the promise by default
|
||||
if (result.fail.length > 0) {
|
||||
toast.add('error', getMessage(notAllowedMessage, result.fail));
|
||||
outcome = $q.reject(result.fail);
|
||||
}
|
||||
if (result.pass.length > 0) {
|
||||
outcome = deleteModal.open(scope, result.pass.map(getEntity), context).then(createResult);
|
||||
}
|
||||
return outcome;
|
||||
}
|
||||
|
||||
function createResult(deleteModalResult) {
|
||||
// To make the result of this action generically useful, reformat the return
|
||||
// from the deleteModal into a standard form
|
||||
|
@ -91,19 +91,8 @@
|
||||
|
||||
beforeEach(function() {
|
||||
spyOn(deleteModalService, 'open').and.callThrough();
|
||||
service.initScope($scope, labelize);
|
||||
});
|
||||
|
||||
function labelize(count) {
|
||||
return {
|
||||
title: ngettext('title', 'titles', count),
|
||||
message: ngettext('message', 'messages', count),
|
||||
submit: ngettext('submit', 'submits', count),
|
||||
success: ngettext('success', 'successs', count),
|
||||
error: ngettext('error', 'errors', count)
|
||||
};
|
||||
}
|
||||
|
||||
////////////
|
||||
|
||||
it('should open the delete modal and show correct labels', testSingleLabels);
|
||||
@ -221,7 +210,6 @@
|
||||
beforeEach(function() {
|
||||
spyOn(resolver, 'success');
|
||||
spyOn(resolver, 'error');
|
||||
service.initScope($scope);
|
||||
});
|
||||
|
||||
////////////
|
||||
|
@ -56,15 +56,8 @@
|
||||
var message = {
|
||||
success: gettext('Image %s was successfully updated.')
|
||||
};
|
||||
var modifyImagePolicyCheck, scope;
|
||||
|
||||
var model = {
|
||||
image: {},
|
||||
metadata: {}
|
||||
};
|
||||
|
||||
var service = {
|
||||
initScope: initScope,
|
||||
allowed: allowed,
|
||||
perform: perform
|
||||
};
|
||||
@ -73,15 +66,9 @@
|
||||
|
||||
//////////////
|
||||
|
||||
function initScope($scope) {
|
||||
scope = $scope;
|
||||
$scope.$on(events.IMAGE_METADATA_CHANGED, onMetadataChange);
|
||||
modifyImagePolicyCheck = policy.ifAllowed({rules: [['image', 'modify_image']]});
|
||||
}
|
||||
|
||||
function allowed(image) {
|
||||
return $q.all([
|
||||
modifyImagePolicyCheck,
|
||||
policy.ifAllowed({rules: [['image', 'modify_image']]}),
|
||||
isActive(image)
|
||||
]);
|
||||
}
|
||||
@ -89,62 +76,59 @@
|
||||
function perform(image) {
|
||||
var deferred = glance.getImage(image.id);
|
||||
deferred.then(onLoad);
|
||||
scope.imagePromise = deferred;
|
||||
var data = {};
|
||||
data.imagePromise = deferred;
|
||||
|
||||
function onLoad(response) {
|
||||
var localImage = response.data;
|
||||
model.image = localImage;
|
||||
data.image = localImage;
|
||||
}
|
||||
|
||||
return wizardModalService.modal({
|
||||
scope: scope,
|
||||
data: data,
|
||||
workflow: editWorkflow,
|
||||
submit: submit
|
||||
}).result;
|
||||
}
|
||||
|
||||
function onMetadataChange(e, metadata) {
|
||||
model.metadata = metadata;
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
function submit() {
|
||||
function submit(stepModels) {
|
||||
var image = stepModels.imageForm;
|
||||
var metadata = stepModels.updateMetadataForm;
|
||||
return updateMetadata().then(updateImage, onUpdateImageFail);
|
||||
}
|
||||
|
||||
function updateImage() {
|
||||
var finalModel = model.image;
|
||||
return glance.updateImage(finalModel).then(onUpdateImageSuccess, onUpdateImageFail);
|
||||
}
|
||||
|
||||
function onUpdateImageSuccess() {
|
||||
toast.add('success', interpolate(message.success, [model.image.name]));
|
||||
return actionResultService.getActionResult()
|
||||
.updated(imageResourceType, model.image.id)
|
||||
.result;
|
||||
}
|
||||
|
||||
function onUpdateImageFail() {
|
||||
return actionResultService.getActionResult()
|
||||
.failed(imageResourceType, model.image.id)
|
||||
.result;
|
||||
}
|
||||
|
||||
function updateMetadata() {
|
||||
|
||||
return metadataService
|
||||
.getMetadata('image', model.image.id)
|
||||
.then(onMetadataGet);
|
||||
|
||||
function onMetadataGet(response) {
|
||||
var updated = model.metadata;
|
||||
var removed = angular.copy(response.data);
|
||||
angular.forEach(updated, function(value, key) {
|
||||
delete removed[key];
|
||||
});
|
||||
function updateMetadata() {
|
||||
|
||||
return metadataService
|
||||
.editMetadata('image', model.image.id, updated, Object.keys(removed));
|
||||
.getMetadata('image', image.id)
|
||||
.then(onMetadataGet);
|
||||
|
||||
function onMetadataGet(response) {
|
||||
var updated = metadata;
|
||||
var removed = angular.copy(response.data);
|
||||
angular.forEach(updated, function(value, key) {
|
||||
delete removed[key];
|
||||
});
|
||||
|
||||
return metadataService
|
||||
.editMetadata('image', image.id, updated, Object.keys(removed));
|
||||
}
|
||||
}
|
||||
|
||||
function updateImage() {
|
||||
return glance.updateImage(image).then(onUpdateImageSuccess, onUpdateImageFail);
|
||||
}
|
||||
|
||||
function onUpdateImageSuccess() {
|
||||
toast.add('success', interpolate(message.success, [image.name]));
|
||||
return actionResultService.getActionResult()
|
||||
.updated(imageResourceType, image.id)
|
||||
.result;
|
||||
}
|
||||
|
||||
function onUpdateImageFail() {
|
||||
return actionResultService.getActionResult()
|
||||
.failed(imageResourceType, image.id)
|
||||
.result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,8 @@
|
||||
'use strict';
|
||||
|
||||
describe('horizon.app.core.images.actions.edit.service', function() {
|
||||
var service, $scope, $q, deferred, testImage, $timeout, updateImageDeferred;
|
||||
var service, $scope, $q, deferred, $timeout, updateImageDeferred;
|
||||
var image = {id: 1, name: 'Original'};
|
||||
var existingMetadata = {p1: '1', p2: '2'};
|
||||
|
||||
var metadataService = {
|
||||
@ -52,7 +53,7 @@
|
||||
},
|
||||
getImage: function() {
|
||||
var imageLoad = $q.defer();
|
||||
imageLoad.resolve({data: {id: 1, name: 'Test'}});
|
||||
imageLoad.resolve({data: image});
|
||||
return imageLoad.promise;
|
||||
}
|
||||
};
|
||||
@ -91,7 +92,6 @@
|
||||
$scope = _$rootScope_.$new();
|
||||
$q = _$q_;
|
||||
service = $injector.get('horizon.app.core.images.actions.edit.service');
|
||||
service.initScope($scope);
|
||||
deferred = $q.defer();
|
||||
updateImageDeferred = $q.defer();
|
||||
$timeout = _$timeout_;
|
||||
@ -101,16 +101,12 @@
|
||||
it('should open the modal with the correct parameters', function() {
|
||||
spyOn(wizardModalService, 'modal').and.callThrough();
|
||||
|
||||
testImage = {id: '12'};
|
||||
service.initScope($scope);
|
||||
service.perform(testImage);
|
||||
service.perform(image, $scope);
|
||||
$timeout.flush();
|
||||
|
||||
expect(wizardModalService.modal).toHaveBeenCalled();
|
||||
expect($scope.imagePromise).toBeDefined();
|
||||
|
||||
var modalArgs = wizardModalService.modal.calls.argsFor(0)[0];
|
||||
expect(modalArgs.scope).toEqual($scope);
|
||||
expect(modalArgs.workflow).toBeDefined();
|
||||
});
|
||||
|
||||
@ -124,45 +120,32 @@
|
||||
describe('submit', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
var image = {id: 1, name: 'Original'};
|
||||
|
||||
spyOn(glanceAPI, 'updateImage').and.callThrough();
|
||||
spyOn(wizardModalService, 'modal').and.callThrough();
|
||||
|
||||
service.initScope($scope);
|
||||
service.perform(image);
|
||||
service.perform(image, $scope);
|
||||
|
||||
$timeout.flush();
|
||||
});
|
||||
|
||||
it('passes the image from the model to updateImage', function() {
|
||||
var modalArgs = wizardModalService.modal.calls.argsFor(0)[0];
|
||||
modalArgs.submit();
|
||||
modalArgs.submit({imageForm: image});
|
||||
|
||||
updateImageDeferred.resolve();
|
||||
$timeout.flush();
|
||||
expect(glanceAPI.updateImage.calls.argsFor(0)[0]).toEqual({id: 1, name: 'Test'});
|
||||
expect(glanceAPI.updateImage.calls.argsFor(0)[0]).toEqual(image);
|
||||
});
|
||||
|
||||
it('returns a failed result if API call fails', function() {
|
||||
var modalArgs = wizardModalService.modal.calls.argsFor(0)[0];
|
||||
var result = modalArgs.submit();
|
||||
var result = modalArgs.submit({imageForm: image});
|
||||
updateImageDeferred.reject();
|
||||
result.then(function err(data) {
|
||||
expect(data.failed.length).toBe(1);
|
||||
});
|
||||
$timeout.flush();
|
||||
});
|
||||
|
||||
it('updates metadata on event', function() {
|
||||
$scope.$emit('horizon.app.core.images.IMAGE_METADATA_CHANGED', {i_am: 'metadata'});
|
||||
$scope.$apply();
|
||||
spyOn(metadataService, 'editMetadata').and.callThrough();
|
||||
|
||||
var modalArgs = wizardModalService.modal.calls.argsFor(0)[0];
|
||||
modalArgs.submit();
|
||||
|
||||
expect(metadataService.editMetadata.calls.argsFor(0)[2]).toEqual({i_am: 'metadata'});
|
||||
});
|
||||
});
|
||||
|
||||
function permissionShouldFail(permissions) {
|
||||
|
@ -269,8 +269,6 @@
|
||||
*/
|
||||
function events() {
|
||||
return {
|
||||
IMAGE_CHANGED: 'horizon.app.core.images.IMAGE_CHANGED',
|
||||
IMAGE_METADATA_CHANGED: 'horizon.app.core.images.IMAGE_METADATA_CHANGED',
|
||||
IMAGE_UPLOAD_PROGRESS: 'horizon.app.core.images.IMAGE_UPLOAD_PROGRESS'
|
||||
};
|
||||
}
|
||||
|
@ -56,7 +56,7 @@
|
||||
ctrl.apiVersion = 0;
|
||||
ctrl.allowPublicizeImage = true;
|
||||
|
||||
ctrl.image = {
|
||||
$scope.stepModels.imageForm = ctrl.image = {
|
||||
source_type: '',
|
||||
image_url: '',
|
||||
data: {},
|
||||
@ -96,11 +96,9 @@
|
||||
|
||||
init();
|
||||
|
||||
var imageChangedWatcher = $scope.$watchCollection('ctrl.image', watchImageCollection);
|
||||
var watchUploadProgress = $scope.$on(events.IMAGE_UPLOAD_PROGRESS, watchImageUpload);
|
||||
|
||||
$scope.$on('$destroy', function() {
|
||||
imageChangedWatcher();
|
||||
watchUploadProgress();
|
||||
});
|
||||
|
||||
@ -148,13 +146,6 @@
|
||||
return (type === 'file-legacy' || type === 'file-direct');
|
||||
}
|
||||
|
||||
// emits new data to parent listeners
|
||||
function watchImageCollection(newValue, oldValue) {
|
||||
if (newValue !== oldValue) {
|
||||
$scope.$emit(events.IMAGE_CHANGED, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
glance.getImages({paginate: false}).success(onGetImages);
|
||||
policyAPI.ifAllowed({rules: [['image', 'publicize_image']]}).then(
|
||||
|
@ -49,6 +49,7 @@
|
||||
|
||||
beforeEach(inject(function ($injector, _$rootScope_, _$q_, _$timeout_) {
|
||||
$scope = _$rootScope_.$new();
|
||||
$scope.stepModels = {imageForm: {}, updateMetadataForm: {}};
|
||||
$q = _$q_;
|
||||
$timeout = _$timeout_;
|
||||
|
||||
@ -93,19 +94,6 @@
|
||||
expect(ctrl.ramdiskImages).toEqual([{disk_format: 'ari'}]);
|
||||
});
|
||||
|
||||
it('should emit events on image change', function() {
|
||||
spyOn($scope, '$emit').and.callThrough();
|
||||
|
||||
var ctrl = createController();
|
||||
ctrl.image = 1;
|
||||
$scope.$apply();
|
||||
|
||||
ctrl.image = 2;
|
||||
$scope.$apply();
|
||||
|
||||
expect($scope.$emit).toHaveBeenCalledWith('horizon.app.core.images.IMAGE_CHANGED', 2);
|
||||
});
|
||||
|
||||
it('should have options for visibility, protected and copying', function() {
|
||||
var ctrl = createController();
|
||||
|
||||
|
@ -52,12 +52,12 @@
|
||||
];
|
||||
|
||||
ctrl.imageVisibilityOptions = [
|
||||
{ label: gettext('Public'), value: 'public'},
|
||||
{ label: gettext('Public'), value: 'public' },
|
||||
{ label: gettext('Private'), value: 'private' }
|
||||
];
|
||||
|
||||
ctrl.setFormats = setFormats;
|
||||
ctrl.allowPublicizeImage = { rules: [['image', 'image:publicize_image']]};
|
||||
ctrl.allowPublicizeImage = { rules: [['image', 'image:publicize_image']] };
|
||||
|
||||
$scope.imagePromise.then(init);
|
||||
|
||||
@ -76,7 +76,7 @@
|
||||
}
|
||||
|
||||
function init(response) {
|
||||
ctrl.image = response.data;
|
||||
$scope.stepModels.imageForm = ctrl.image = response.data;
|
||||
ctrl.image.kernel = ctrl.image.properties.kernel_id;
|
||||
ctrl.image.ramdisk = ctrl.image.properties.ramdisk_id;
|
||||
ctrl.image.architecture = ctrl.image.properties.architecture;
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
beforeEach(inject(function ($injector, _$rootScope_, _$q_, _$timeout_) {
|
||||
$scope = _$rootScope_.$new();
|
||||
$scope.stepModels = {imageForm: {}, updateMetadataForm: {}};
|
||||
$q = _$q_;
|
||||
$timeout = _$timeout_;
|
||||
|
||||
@ -132,22 +133,5 @@
|
||||
expect(ctrl.image.container_format).toEqual('ari');
|
||||
});
|
||||
|
||||
it("should destroy the image changed watcher when the controller is destroyed", function() {
|
||||
setImagePromise({id: '1', container_format: 'bare', properties: []});
|
||||
spyOn($scope, '$emit').and.callThrough();
|
||||
|
||||
var ctrl = createController();
|
||||
ctrl.image = 1;
|
||||
$scope.$apply();
|
||||
|
||||
$scope.$emit("$destroy");
|
||||
$scope.$emit.calls.reset();
|
||||
|
||||
ctrl.image = 2;
|
||||
$scope.$apply();
|
||||
|
||||
expect($scope.$emit).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
||||
|
@ -92,7 +92,7 @@
|
||||
|
||||
function onMetadataChanged(newValue, oldValue) {
|
||||
if (newValue !== oldValue) {
|
||||
$scope.$emit(events.IMAGE_METADATA_CHANGED, newValue);
|
||||
$scope.stepModels.updateMetadataForm = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,7 @@
|
||||
beforeEach(inject(function($injector, _$rootScope_, _$q_) {
|
||||
$controller = $injector.get('$controller');
|
||||
$scope = _$rootScope_.$new();
|
||||
$scope.stepModels = {imageForm: {}, updateMetadataForm: {}};
|
||||
$q = _$q_;
|
||||
}));
|
||||
|
||||
@ -118,7 +119,7 @@
|
||||
expect(metadataTreeService.Tree).toHaveBeenCalledWith(availableMetadata, []);
|
||||
});
|
||||
|
||||
it('should emit imageMetadataChanged event when metadata changes', function() {
|
||||
it('should update stepModels.updateMetadataForm when metadata changes', function() {
|
||||
var deferred = $q.defer();
|
||||
deferred.resolve({data: {id: '1'}});
|
||||
$scope.imagePromise = deferred.promise;
|
||||
@ -135,10 +136,7 @@
|
||||
mockGetExisting.and.returnValue('2');
|
||||
$scope.$apply();
|
||||
|
||||
expect($scope.$emit).toHaveBeenCalledWith(
|
||||
'horizon.app.core.images.IMAGE_METADATA_CHANGED',
|
||||
'2'
|
||||
);
|
||||
expect($scope.stepModels.updateMetadataForm).toEqual('2');
|
||||
});
|
||||
|
||||
function createController() {
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
deprecations:
|
||||
- Remove formerly deprecated initScope() function for
|
||||
Angularized actions. Instead use initAction() and get
|
||||
scope from second parameter of perform() function.
|
Loading…
Reference in New Issue
Block a user