diff --git a/openstack_dashboard/static/app/core/cloud-services/hz-if-cinder-extensions.directive.js b/openstack_dashboard/static/app/core/cloud-services/hz-if-cinder-extensions.directive.js new file mode 100644 index 0000000000..ca2f4cb3a4 --- /dev/null +++ b/openstack_dashboard/static/app/core/cloud-services/hz-if-cinder-extensions.directive.js @@ -0,0 +1,74 @@ +/* + * 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.app.core.cloud-services') + .directive('hzIfCinderExtensions', hzCinderExtensions); + + hzCinderExtensions.$inject = [ + 'hzPromiseToggleTemplateDirective', + 'horizon.app.core.openstack-service-api.cinderExtensions' + ]; + + /** + * @ngdoc directive + * @name hz.api:directive:hzIfCinderExtensions + * @module hz.api + * @description + * + * Add this directive to any element containing content which should + * only be evaluated when the specified cinder extensions are enabled by + * the cinder servers in the currently selected region. If the cinder extensions + * are enabled, the content will be evaluated. Otherwise, the content will + * not be compiled. In addition, the element and everything contained by + * it will be removed completely, leaving a simple HTML comment. + * + * This is evaluated once per page load. In current horizon, this means + * it will get re-evaluated with events like the user opening another panel, + * changing logins, or changing their region. + * + * The hz-if-cinder-extensions attribute may be set to a single extension (String) + * or an array of extensions (each one being a String). + * All of the following are examples: + * + * hz-if-cinder-extensions='"SchedulerHints"' + * hz-if-cinder-extensions='["SchedulerHints"]' + * hz-if-cinder-extensions='["SchedulerHints", "DiskConfig"]' + * + * @example + * + * In the below, if the SchedulerHints cinder extension is not enabled, then + * the div element with hz-if-cinder-extensions and all of the elements inside + * of it will be removed and never evaluated by the angular compiler. + * + ```html +
+ +
+ ``` + */ + function hzCinderExtensions(hzPromiseToggleTemplateDirective, cinderExtensions) { + return angular.extend( + hzPromiseToggleTemplateDirective[0], + { + singlePromiseResolver: cinderExtensions.ifNameEnabled, + name: 'hzIfCinderExtensions' + } + ); + } + +})(); diff --git a/openstack_dashboard/static/app/core/cloud-services/hz-if-cinder-extensions.directive.spec.js b/openstack_dashboard/static/app/core/cloud-services/hz-if-cinder-extensions.directive.spec.js new file mode 100644 index 0000000000..4ee7a37fb9 --- /dev/null +++ b/openstack_dashboard/static/app/core/cloud-services/hz-if-cinder-extensions.directive.spec.js @@ -0,0 +1,86 @@ +/* + * 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.app.core.cloud-services.hzCinderExtension', function () { + var $compile, $scope, deferred, cinderExtensionsAPI; + + var template = [ + '
', + '
', + '
', + '
', + '
', + '
' + ].join(''); + + beforeEach(function() { + cinderExtensionsAPI = { + ifNameEnabled: function() { + return deferred.promise; + } + }; + + spyOn(cinderExtensionsAPI, 'ifNameEnabled').and.callThrough(); + + module('horizon.app.core.cloud-services'); + module('horizon.framework.util.promise-toggle'); + + module('horizon.app.core.openstack-service-api', function($provide) { + $provide.value( + 'horizon.app.core.openstack-service-api.cinderExtensions', cinderExtensionsAPI + ); + }); + + inject(function (_$compile_, _$q_, _$rootScope_) { + $compile = _$compile_; + deferred = _$q_.defer(); + $scope = _$rootScope_.$new(); + }); + + }); + + // Please note, this code is primarily intended to verify that the + // directive specifies the correct name and that it uses the settings + // service API. Testing of the variations on inputs being resolved + // are tested in the hz-promise-toggle spec. + it('should evaluate child elements when extension is enabled', function () { + var element = $compile(template)($scope); + + deferred.resolve(); + + expect(element.children().length).toBe(0); + expect(cinderExtensionsAPI.ifNameEnabled).toHaveBeenCalledWith('ext_name'); + + $scope.$apply(); + expect(element.children().length).toBe(1); + }); + + it('should not evaluate child elements when extension is NOT enabled', function () { + var element = $compile(template)($scope); + + deferred.reject(); + + expect(element.children().length).toBe(0); + expect(cinderExtensionsAPI.ifNameEnabled).toHaveBeenCalledWith('ext_name'); + + $scope.$apply(); + expect(element.children().length).toBe(0); + }); + + }); + +})();