diff --git a/bindep.txt b/bindep.txt index 35fc04eb..ce14ebbe 100644 --- a/bindep.txt +++ b/bindep.txt @@ -2,3 +2,10 @@ # see https://docs.openstack.org/infra/bindep/ for additional information. libfontconfig1 [nodejs platform:dpkg] + +# selenium tests +ffmpeg [selenium] +firefox [selenium] +xvfb [selenium platform:dpkg] +# already part of xorg-x11-server on openSUSE +xorg-x11-server-Xvfb [selenium platform:redhat] diff --git a/octavia_dashboard/karma.conf.js b/octavia_dashboard/karma.conf.js index db31dfb6..19651859 100644 --- a/octavia_dashboard/karma.conf.js +++ b/octavia_dashboard/karma.conf.js @@ -120,18 +120,12 @@ module.exports = function (config) { frameworks: ['jasmine'], - browsers: ['PhantomJS'], - - phantomjsLauncher: { - // Have phantomjs exit if a ResourceError is encountered - // (useful if karma exits without killing phantom) - exitOnResourceError: true - }, + browsers: ['Firefox'], reporters: ['progress', 'coverage', 'threshold'], plugins: [ - 'karma-phantomjs-launcher', + 'karma-firefox-launcher', 'karma-jasmine', 'karma-ng-html2js-preprocessor', 'karma-coverage', diff --git a/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js b/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js index 71fdf63a..c40278c6 100644 --- a/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js +++ b/octavia_dashboard/static/app/core/openstack-service-api/lbaasv2.service.js @@ -102,7 +102,7 @@ function getLoadBalancers(full) { var params = { full: full }; return apiService.get('/api/lbaas/loadbalancers/', { params: params }) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve load balancers.')); }); } @@ -119,7 +119,7 @@ function getLoadBalancer(id, full) { var params = { full: full }; return apiService.get('/api/lbaas/loadbalancers/' + id + '/', { params: params }) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve load balancer.')); }); } @@ -135,7 +135,7 @@ function deleteLoadBalancer(id, quiet) { var promise = apiService.delete('/api/lbaas/loadbalancers/' + id + '/'); - return quiet ? promise : promise.error(function () { + return quiet ? promise : promise.catch(function () { toastService.add('error', gettext('Unable to delete load balancer.')); }); } @@ -150,7 +150,7 @@ function createLoadBalancer(spec) { return apiService.post('/api/lbaas/loadbalancers/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to create load balancer.')); }); } @@ -166,7 +166,7 @@ function editLoadBalancer(id, spec) { return apiService.put('/api/lbaas/loadbalancers/' + id + '/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to update load balancer.')); }); } @@ -190,7 +190,7 @@ function getListeners(id) { var params = id ? {params: {loadbalancerId: id}} : {}; return apiService.get('/api/lbaas/listeners/', params) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve listeners.')); }); } @@ -210,7 +210,7 @@ ? {params: {includeChildResources: includeChildResources}} : {}; return apiService.get('/api/lbaas/listeners/' + id + '/', params) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve listener.')); }); } @@ -225,7 +225,7 @@ function createListener(spec) { return apiService.post('/api/lbaas/listeners/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to create listener.')); }); } @@ -242,7 +242,7 @@ function editListener(id, spec) { return apiService.put('/api/lbaas/listeners/' + id + '/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to update listener.')); }); } @@ -258,7 +258,7 @@ function deleteListener(id, quiet) { var promise = apiService.delete('/api/lbaas/listeners/' + id + '/'); - return quiet ? promise : promise.error(function () { + return quiet ? promise : promise.catch(function () { toastService.add('error', gettext('Unable to delete listener.')); }); } @@ -292,7 +292,7 @@ params = { params: params }; } return apiService.get('/api/lbaas/pools/', params) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve pools.')); }); } @@ -312,7 +312,7 @@ ? {params: {includeChildResources: includeChildResources}} : {}; return apiService.get('/api/lbaas/pools/' + id + '/', params) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve pool.')); }); } @@ -327,7 +327,7 @@ function createPool(spec) { return apiService.post('/api/lbaas/pools/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to create pool.')); }); } @@ -344,7 +344,7 @@ function editPool(id, spec) { return apiService.put('/api/lbaas/pools/' + id + '/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to update pool.')); }); } @@ -360,7 +360,7 @@ function deletePool(id, quiet) { var promise = apiService.delete('/api/lbaas/pools/' + id + '/'); - return quiet ? promise : promise.error(function () { + return quiet ? promise : promise.catch(function () { toastService.add('error', gettext('Unable to delete pool.')); }); } @@ -391,7 +391,7 @@ params = { params: params }; } return apiService.get('/api/lbaas/l7policies/', params) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve l7 policies.')); }); } @@ -411,7 +411,7 @@ ? {params: {includeChildResources: includeChildResources}} : {}; return apiService.get('/api/lbaas/l7policies/' + id + '/', params) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve l7 policy.')); }); } @@ -426,7 +426,7 @@ function createL7Policy(spec) { return apiService.post('/api/lbaas/l7policies/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to create l7 policy.')); }); } @@ -443,7 +443,7 @@ function editL7Policy(id, spec) { return apiService.put('/api/lbaas/l7policies/' + id + '/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to update l7 policy.')); }); } @@ -459,7 +459,7 @@ function deleteL7Policy(id, quiet) { var promise = apiService.delete('/api/lbaas/l7policies/' + id + '/'); - return quiet ? promise : promise.error(function () { + return quiet ? promise : promise.catch(function () { toastService.add('error', gettext('Unable to delete l7 policy.')); }); } @@ -479,7 +479,7 @@ function getL7Rules(l7policyId) { return apiService.get('/api/lbaas/l7policies/' + l7policyId + '/l7rules/') - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve l7 rules.')); }); } @@ -496,7 +496,7 @@ function getL7Rule(l7policyId, l7ruleId) { return apiService.get('/api/lbaas/l7policies/' + l7policyId + '/l7rules/' + l7ruleId + '/') - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve l7 rule.')); }); } @@ -513,7 +513,7 @@ function createL7Rule(l7policyId, spec) { return apiService.post('/api/lbaas/l7policies/' + l7policyId + '/l7rules/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to create l7 rule.')); }); } @@ -533,7 +533,7 @@ function editL7Rule(l7policyId, l7ruleId, spec) { return apiService.put('/api/lbaas/l7policies/' + l7policyId + '/l7rules/' + l7ruleId + '/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to update l7 rule.')); }); } @@ -552,7 +552,7 @@ function deleteL7Rule(l7policyId, l7ruleId, quiet) { var promise = apiService.delete('/api/lbaas/l7policies/' + l7policyId + '/l7rules/' + l7ruleId + '/'); - return quiet ? promise : promise.error(function () { + return quiet ? promise : promise.catch(function () { toastService.add('error', gettext('Unable to delete l7 rule.')); }); } @@ -572,7 +572,7 @@ function getMembers(poolId) { return apiService.get('/api/lbaas/pools/' + poolId + '/members/') - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve members.')); }); } @@ -589,7 +589,7 @@ function getMember(poolId, memberId) { return apiService.get('/api/lbaas/pools/' + poolId + '/members/' + memberId + '/') - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve member.')); }); } @@ -606,7 +606,7 @@ function deleteMember(poolId, memberId) { return apiService.delete('/api/lbaas/pools/' + poolId + '/members/' + memberId + '/') - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to delete member.')); }); } @@ -623,7 +623,7 @@ function editMember(poolId, memberId, spec) { return apiService.put('/api/lbaas/pools/' + poolId + '/members/' + memberId + '/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to update member.')); }); } @@ -640,7 +640,7 @@ function updateMemberList(poolId, spec) { return apiService.put('/api/lbaas/pools/' + poolId + '/members/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to update member list.')); }); } @@ -672,14 +672,14 @@ function getHealthMonitors(id) { var params = id ? {params: {poolId: id}} : {}; return apiService.get('/api/lbaas/healthmonitors/', params) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve health monitors.')); }); } function getHealthMonitor(monitorId) { return apiService.get('/api/lbaas/healthmonitors/' + monitorId + '/') - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve health monitor.')); }); } @@ -696,7 +696,7 @@ function editHealthMonitor(id, spec) { return apiService.put('/api/lbaas/healthmonitors/' + id + '/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to update health monitor.')); }); } @@ -712,7 +712,7 @@ function deleteHealthMonitor(id, quiet) { var promise = apiService.delete('/api/lbaas/healthmonitors/' + id + '/'); - return quiet ? promise : promise.error(function () { + return quiet ? promise : promise.catch(function () { toastService.add('error', gettext('Unable to delete health monitor.')); }); } @@ -727,7 +727,7 @@ function createHealthMonitor(spec) { return apiService.post('/api/lbaas/healthmonitors/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to create health monitor.')); }); } @@ -754,14 +754,14 @@ function getFlavors() { var params = {params: {}}; return apiService.get('/api/lbaas/flavors/', params) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve flavors.')); }); } function getFlavor(flavorId) { return apiService.get('/api/lbaas/flavors/' + flavorId + '/') - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve flavor.')); }); } @@ -778,7 +778,7 @@ function editFlavor(id, spec) { return apiService.put('/api/lbaas/flavors/' + id + '/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to update flavor.')); }); } @@ -794,7 +794,7 @@ function deleteFlavor(id, quiet) { var promise = apiService.delete('/api/lbaas/flavors/' + id + '/'); - return quiet ? promise : promise.error(function () { + return quiet ? promise : promise.catch(function () { toastService.add('error', gettext('Unable to delete flavor.')); }); } @@ -809,7 +809,7 @@ function createFlavor(spec) { return apiService.post('/api/lbaas/flavors/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to create flavor.')); }); } @@ -836,14 +836,14 @@ function getFlavorProfiles() { var params = {params: {}}; return apiService.get('/api/lbaas/flavorprofiles/', params) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve flavor profiles.')); }); } function getFlavorProfile(flavorProfileId) { return apiService.get('/api/lbaas/flavorprofiles/' + flavorProfileId + '/') - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve flavor profile.')); }); } @@ -860,7 +860,7 @@ function editFlavorProfile(id, spec) { return apiService.put('/api/lbaas/flavorprofiles/' + id + '/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to update flavor profile.')); }); } @@ -876,7 +876,7 @@ function deleteFlavorProfile(id, quiet) { var promise = apiService.delete('/api/lbaas/flavorprofiles/' + id + '/'); - return quiet ? promise : promise.error(function () { + return quiet ? promise : promise.catch(function () { toastService.add('error', gettext('Unable to delete flavor profile.')); }); } @@ -891,7 +891,7 @@ function createFlavorProfile(spec) { return apiService.post('/api/lbaas/flavorprofiles/', spec) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to create flavor profile.')); }); } @@ -910,7 +910,7 @@ function getAvailabilityZones() { var params = {params: {}}; return apiService.get('/api/lbaas/availabilityzones/', params) - .error(function () { + .catch(function () { toastService.add('error', gettext('Unable to retrieve availability zones.')); }); } diff --git a/octavia_dashboard/static/app/core/openstack-service-api/octavia-barbican.service.js b/octavia_dashboard/static/app/core/openstack-service-api/octavia-barbican.service.js index f9aba0ab..a6e36d22 100644 --- a/octavia_dashboard/static/app/core/openstack-service-api/octavia-barbican.service.js +++ b/octavia_dashboard/static/app/core/openstack-service-api/octavia-barbican.service.js @@ -58,7 +58,7 @@ function getCertificates(quiet) { var promise = apiService.get('/api/octavia-barbican/certificates/'); - return quiet ? promise : promise.error(function handleError() { + return quiet ? promise : promise.catch(function handleError() { toastService.add('error', gettext('Unable to retrieve SSL certificates.')); }); } @@ -77,7 +77,7 @@ function getSecrets(quiet) { var promise = apiService.get('/api/octavia-barbican/secrets/'); - return quiet ? promise : promise.error(function handleError() { + return quiet ? promise : promise.catch(function handleError() { toastService.add('error', gettext('Unable to retrieve secrets.')); }); } diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.controller.spec.js index 622d01a4..1290392d 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.controller.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/loadbalancers/actions/associate-ip/modal.controller.spec.js @@ -105,6 +105,7 @@ it('should associate floating IP if floating IP selected', function() { ctrl = $controller('AssociateFloatingIpModalController'); ctrl.selected = ctrl.options[0]; + associateFail = false; spyOn(network, 'associateFloatingIp').and.callThrough(); spyOn($uibModalInstance, 'close'); ctrl.save(); @@ -116,6 +117,7 @@ it('should allocate floating IP if floating IP pool selected', function() { ctrl = $controller('AssociateFloatingIpModalController'); ctrl.selected = ctrl.options[1]; + associateFail = false; spyOn(network, 'allocateFloatingIp').and.callThrough(); spyOn(network, 'associateFloatingIp').and.callThrough(); spyOn($uibModalInstance, 'close'); diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.controller.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.controller.spec.js index 2d6c3ed7..b6a4cf65 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.controller.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/members/actions/edit-member/modal.controller.spec.js @@ -77,6 +77,7 @@ }); it('should edit member weight, monitor address and port', function() { + fail = false; spyOn(api, 'editMember').and.callThrough(); spyOn($uibModalInstance, 'close'); ctrl.save(); diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/widgets/filterselect/filter-select.component.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/widgets/filterselect/filter-select.component.spec.js index d5872573..b2854d2b 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/widgets/filterselect/filter-select.component.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/widgets/filterselect/filter-select.component.spec.js @@ -197,6 +197,8 @@ beforeEach( inject( function($rootScope, $componentController) { + var events = $._data(document, 'events'); + events.click = []; scope = $rootScope.$new(); ctrl = $componentController('filterSelect', { $scope: scope, diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.js b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.js index d054d58c..bd97cfd6 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.js @@ -740,7 +740,7 @@ model.spec.certificates.push(cert); }); }); - }); + }, certificatesError); $('#wizard-side-nav ul li:last').show(); } } diff --git a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.spec.js b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.spec.js index 78944b7c..a0e2a8b3 100644 --- a/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.spec.js +++ b/octavia_dashboard/static/dashboard/project/lbaasv2/workflow/model.service.spec.js @@ -1026,6 +1026,67 @@ }); }); + describe('Post initialize model (edit listener) no pool children', function() { + + beforeEach(function() { + includeChildResources = true; + delete listenerResources.members; + delete listenerResources.monitor; + model.initialize('listener', '1234'); + scope.$apply(); + }); + + it('should initialize model properties', function() { + expect(model.initializing).toBe(false); + expect(model.initialized).toBe(true); + expect(model.subnets.length).toBe(2); + expect(model.members.length).toEqual(2); + expect(model.spec).toBeDefined(); + expect(model.spec.loadbalancer_id).toBeDefined(); + expect(model.spec.loadbalancer).toBeDefined(); + expect(model.spec.listener).toBeDefined(); + expect(model.spec.pool).toBeDefined(); + expect(model.subnets.length).toBe(2); + expect(model.spec.monitor).toBeDefined(); + }); + + it('should initialize the loadbalancer_id property', function() { + expect(model.spec.loadbalancer_id).toBe('1234'); + }); + + it('should initialize all loadbalancer properties to null', function() { + expect(model.spec.loadbalancer.name).toBeNull(); + expect(model.spec.loadbalancer.description).toBeNull(); + expect(model.spec.loadbalancer.vip_address).toBeNull(); + expect(model.spec.loadbalancer.vip_subnet_id).toBeNull(); + }); + + it('should initialize all listener properties', function() { + expect(model.spec.listener.id).toBe('1234'); + expect(model.spec.listener.name).toBe('Listener 1'); + expect(model.spec.listener.description).toBe('listener description'); + expect(model.spec.listener.protocol).toBe('HTTP'); + expect(model.spec.listener.protocol_port).toBe(80); + expect(model.spec.listener.connection_limit).toBe(999); + }); + + it('should initialize all pool properties', function() { + expect(model.spec.pool.id).toBe('1234'); + expect(model.spec.pool.name).toBe('Pool 1'); + expect(model.spec.pool.description).toBe('pool description'); + expect(model.spec.pool.protocol).toBe('HTTP'); + expect(model.spec.pool.lb_algorithm).toBe('ROUND_ROBIN'); + expect(model.spec.pool.session_persistence.type).toBe('APP_COOKIE'); + expect(model.spec.pool.session_persistence.cookie_name).toBe('cookie_name'); + }); + + it('should initialize context', function() { + expect(model.context.resource).toBe('listener'); + expect(model.context.id).toBeDefined(); + expect(model.context.submit).toBeDefined(); + }); + }); + describe('Post initialize model (edit l7 policy)', function() { beforeEach(function() { diff --git a/package.json b/package.json index 8c4feab3..459600bc 100644 --- a/package.json +++ b/package.json @@ -17,19 +17,17 @@ "bugs": "https://storyboard.openstack.org/#!/project/909", "license": "Apache 2.0", "devDependencies": { - "eslint": "1.10.3", - "eslint-config-openstack": "1.2.4", - "eslint-plugin-angular": "1.0.1", - "jasmine-core": "2.4.1", - "karma": "1.1.2", - "karma-chrome-launcher": "1.0.1", - "karma-cli": "1.0.1", - "karma-coverage": "1.1.1", - "karma-jasmine": "1.0.2", + "eslint": "3.0.0", + "eslint-config-openstack": "4.0.1", + "eslint-plugin-angular": "4.0.1", + "jasmine-core": "3.6.0", + "karma": "5.2.3", + "karma-firefox-launcher": "2.1.0", + "karma-cli": "2.0.0", + "karma-coverage": "2.0.3", + "karma-jasmine": "4.0.1", "karma-ng-html2js-preprocessor": "1.0.0", - "karma-phantomjs-launcher": "1.0.4", - "karma-threshold-reporter": "0.1.15", - "phantomjs-prebuilt": "2.1.14" + "karma-threshold-reporter": "0.1.15" }, "scripts": { "postinstall": "octavia_dashboard/post_install.sh",