From ef8224ed98b317950142858eefce80deaa0dfb38 Mon Sep 17 00:00:00 2001 From: Peter Piela Date: Mon, 21 Aug 2017 11:23:16 -0400 Subject: [PATCH] Added unit tests for edit-portgroup functionality. Added unit tests for edit-portgroup functionality. Change-Id: If3d80100cdc47eec876452c4fd24878d9d4d0a13 --- .../edit-portgroup.controller.spec.js | 129 +++++++++++++++++ .../ironic/ironic.backend-mock.service.js | 132 +++++++++++------- 2 files changed, 211 insertions(+), 50 deletions(-) create mode 100644 ironic_ui/static/dashboard/admin/ironic/edit-portgroup/edit-portgroup.controller.spec.js diff --git a/ironic_ui/static/dashboard/admin/ironic/edit-portgroup/edit-portgroup.controller.spec.js b/ironic_ui/static/dashboard/admin/ironic/edit-portgroup/edit-portgroup.controller.spec.js new file mode 100644 index 00000000..52d3658a --- /dev/null +++ b/ironic_ui/static/dashboard/admin/ironic/edit-portgroup/edit-portgroup.controller.spec.js @@ -0,0 +1,129 @@ +/* + * Copyright 2015 Hewlett Packard Enterprise Development Company LP + * Copyright 2016 Cray Inc. + * + * 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('horizon.dashboard.admin.ironic.edit-portgroup', function () { + var ironicBackendMockService, ctrl, node, portgroup, uibModalInstance; + + beforeEach(module('horizon.dashboard.admin.ironic')); + + beforeEach(module('horizon.framework.util')); + + beforeEach(module(function($provide) { + $provide.value('$uibModal', {}); + })); + + beforeEach(module(function($provide) { + uibModalInstance = {}; + $provide.value('$uibModalInstance', uibModalInstance); + })); + + beforeEach(module(function($provide) { + $provide.value('horizon.framework.widgets.toast.service', + {add: function() {}}); + })); + + beforeEach(module('horizon.app.core.openstack-service-api')); + + beforeEach(inject(function($injector) { + ironicBackendMockService = + $injector.get('horizon.dashboard.admin.ironic.backend-mock.service'); + ironicBackendMockService.init(); + + var ironicAPI = + $injector.get('horizon.app.core.openstack-service-api.ironic'); + ironicAPI.createNode( + {driver: ironicBackendMockService.params.defaultDriver}) + .then(function(response) { + node = response.data; + ironicAPI.createPortgroup({node_uuid: node.uuid}) + .then(function(response) { + portgroup = response; + var controller = $injector.get('$controller'); + ctrl = controller('EditPortgroupController', + {portgroup: portgroup}); + }); + }); + ironicBackendMockService.flush(); + })); + + afterEach(function() { + ironicBackendMockService.postTest(); + }); + + it('controller should be defined', function () { + expect(ctrl).toBeDefined(); + }); + + it('controller base construction', function () { + var properties = angular.copy(BASE_PORTGROUP_CONTROLLER_PROPERTIES); + properties.push('modalTitle', + 'updatePortgroup', + 'submit', + 'submitButtonTitle'); + + expect(Object.getOwnPropertyNames(ctrl).sort()).toEqual( + properties.sort()); + + angular.forEach( + ['address', 'name', 'standalone_ports_supported', 'mode'], + function(property) { + expect(ctrl[property].value).toEqual(portgroup[property]); + }); + + angular.forEach( + ['properties', 'extra'], + function(collection) { + expect(ctrl[collection].properties).toEqual(portgroup[collection]); + }); + }); + + it('updatePortgroup', function () { + var portgroupParams = { + address: 'aa:aa:aa:aa:aa:aa', + name: 'my-portgroup', + standalone_ports_supported: !portgroup.standalone_ports_supported, + mode: '802.3ad', + extra: { + extra_1: 'extra_1_value' + }, + properties: { + prop1_1: 'prop_1_value' + } + }; + + uibModalInstance.close = function(portgroup) { + angular.forEach(portgroupParams, + function(value, property) { + expect(portgroup[property]).toEqual(value); + }); + }; + + angular.forEach(portgroupParams, + function(value, property) { + if (typeof value === 'object') { + ctrl[property].properties = value; + } else { + ctrl[property].value = value; + } + }); + ctrl.submit(); + ironicBackendMockService.flush(); + }); + }); +})(); diff --git a/ironic_ui/static/dashboard/admin/ironic/ironic.backend-mock.service.js b/ironic_ui/static/dashboard/admin/ironic/ironic.backend-mock.service.js index 98d67ffc..d34ee927 100644 --- a/ironic_ui/static/dashboard/admin/ironic/ironic.backend-mock.service.js +++ b/ironic_ui/static/dashboard/admin/ironic/ironic.backend-mock.service.js @@ -421,46 +421,76 @@ return [status, ""]; }); - function _addItem(node, path, value) { - var parts = path.substring(1).split("/"); - var leaf = parts.pop(); - var obj = node; - for (var i = 0; i < parts.length; i++) { - var part = parts[i]; - if (angular.isUndefined(obj[part])) { - obj[part] = {}; + function _addItem(obj, path, value) { + var pathNames = path.substring(1).split("/"); + var leaf = pathNames.pop(); + var part = obj; + for (var i = 0; i < pathNames.length; i++) { + var name = pathNames[i]; + if (angular.isUndefined(part[name])) { + part[name] = {}; } - obj = obj[part]; + part = part[name]; } - obj[leaf] = value; + part[leaf] = value; } - function _removeItem(node, path) { - var parts = path.substring(1).split("/"); - var leaf = parts.pop(); - var obj = node; - for (var i = 0; i < parts.length; i++) { - obj = obj[parts[i]]; + function _removeItem(obj, path) { + var pathNames = path.substring(1).split("/"); + var leaf = pathNames.pop(); + var part = obj; + for (var i = 0; i < pathNames.length; i++) { + part = part[pathNames[i]]; } - delete obj[leaf]; + delete part[leaf]; } - function _replaceItem(node, path, value) { - if (path === "/name" && - node.name !== null) { - delete nodes[node.name]; - if (value !== null) { - nodes[value] = node; + function _replaceItem(obj, path, value, collection) { + // Special handling for changing the name of an object + // that is stored in a name-indexed collection. + if (path === "/name" && obj.name !== null) { + if (angular.isDefined(collection)) { + delete collection[obj.name]; + if (value !== null) { + collection[value] = obj; + } } } - var parts = path.substring(1).split("/"); - var leaf = parts.pop(); - var obj = node; - for (var i = 0; i < parts.length; i++) { - obj = obj[parts[i]]; + var pathNames = path.substring(1).split("/"); + var leaf = pathNames.pop(); + var part = obj; + for (var i = 0; i < pathNames.length; i++) { + part = part[pathNames[i]]; } - obj[leaf] = value; + part[leaf] = value; + } + + /** + * @description Apply a patch to a specified object. + * + * @param {object} obj - Object to be patched, e.g. node, port, ... + * @param {object} patch - Patch object. + * @param {object} collection - Optional. Collection to which the + * object belongs. Only required if the collection indexes the + * object by name. + * @return {void} + */ + function patchObject(obj, patch, collection) { + angular.forEach(patch, function(operation) { + switch (operation.op) { + case "add": + _addItem(obj, operation.path, operation.value); + break; + case "remove": + _removeItem(obj, operation.path); + break; + case "replace": + _replaceItem(obj, operation.path, operation.value, collection); + break; + default: + } + }); } // Update node @@ -472,21 +502,7 @@ var status = responseCode.RESOURCE_NOT_FOUND; var node = service.getNode(params.nodeId); if (angular.isDefined(node)) { - var patch = JSON.parse(data).patch; - angular.forEach(patch, function(operation) { - switch (operation.op) { - case "add": - _addItem(node, operation.path, operation.value); - break; - case "remove": - _removeItem(node, operation.path); - break; - case "replace": - _replaceItem(node, operation.path, operation.value); - break; - default: - } - }); + patchObject(node, JSON.parse(data).patch, nodes); status = responseCode.SUCCESS; } return [status, node]; @@ -539,9 +555,9 @@ ['nodeId']) .respond(function(method, url, data, headers, params) { if (angular.isDefined(nodes[params.nodeId])) { - return [200, nodes[params.nodeId].bootDevice]; + return [responseCode.SUCCESS, nodes[params.nodeId].bootDevice]; } else { - return [400, null]; + return [responseCode.BAD_QUERY, null]; } }); @@ -552,9 +568,10 @@ ['nodeId']) .respond(function(method, url, data, headers, params) { if (angular.isDefined(nodes[params.nodeId])) { - return [200, nodes[params.nodeId].supportedBootDevices]; + return [responseCode.SUCCESS, + nodes[params.nodeId].supportedBootDevices]; } else { - return [400, null]; + return [responseCode.BAD_QUERY, null]; } }); @@ -565,7 +582,7 @@ ['nodeId']) .respond(function(method, url, data, headers, params) { data = JSON.parse(data); - var status = 404; + var status = responseCode.RESOURCE_NOT_FOUND; if (angular.isDefined(nodes[params.nodeId])) { var node = nodes[params.nodeId]; if (node.supportedBootDevices.indexOf(data.boot_device) !== -1) { @@ -573,7 +590,7 @@ if (angular.isDefined(data.persistent)) { node.bootDevice.persistent = data.persistent; } - status = 200; + status = responseCode.SUCCESS; } } return [status, null]; @@ -671,6 +688,21 @@ return [status, ""]; }); + // Update portgroup + $httpBackend.whenPATCH(/\/api\/ironic\/portgroups\/([^\/]+)$/, + undefined, + undefined, + ['portgroupId']) + .respond(function(method, url, data, headers, params) { + var status = responseCode.RESOURCE_NOT_FOUND; + var portgroup = service.getPortgroup(params.portgroupId); + if (angular.isDefined(portgroup)) { + patchObject(portgroup, JSON.parse(data).patch, portgroups); + status = responseCode.SUCCESS; + } + return [status, portgroup]; + }); + // Get portgroup ports $httpBackend.whenGET(/\/api\/ironic\/portgroups\/([^\/]+)\/ports$/, undefined,