Merge "Add unittests for template generator angular"

This commit is contained in:
Zuul 2017-11-01 00:36:20 +00:00 committed by Gerrit Code Review
commit 2d98c50fee
71 changed files with 4447 additions and 487 deletions

1
.eslintignore Normal file
View File

@ -0,0 +1 @@
heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/js/vendors/*

265
.eslintrc.js Normal file
View File

@ -0,0 +1,265 @@
module.exports = {
"env": {
"browser": true,
"jasmine": true,
},
"plugins": ["jasmine"],
"globals": {
"angular": true,
"module": true,
"inject": true,
"saveAs": true,
"json2yaml": true
},
"extends": ["eslint:recommended", "plugin:jasmine/recommended"],
"rules": {
"accessor-pairs": "error",
"array-bracket-newline": "off",
"array-bracket-spacing": "off",
"array-callback-return": "error",
"array-element-newline": "off",
"arrow-body-style": "error",
"arrow-parens": "error",
"arrow-spacing": "error",
"block-scoped-var": "off",
"block-spacing": "off",
"brace-style": "off",
"callback-return": "off",
"camelcase": "off",
"capitalized-comments": "off",
"class-methods-use-this": "error",
"comma-dangle": "off",
"comma-spacing": "off",
"comma-style": "off",
"complexity": "off",
"computed-property-spacing": [
"error",
"never"
],
"consistent-return": "off",
"consistent-this": "off",
"curly": "off",
"default-case": "off",
"dot-location": [
"error",
"property"
],
"dot-notation": "off",
"eol-last": "off",
"eqeqeq": "off",
"for-direction": "error",
"func-call-spacing": "off",
"func-name-matching": "off",
"func-names": "off",
"func-style": "off",
"function-paren-newline": "off",
"generator-star-spacing": "error",
"getter-return": "error",
"global-require": "error",
"guard-for-in": "off",
"handle-callback-err": "error",
"id-blacklist": "error",
"id-length": "off",
"id-match": "error",
"indent": "off",
"indent-legacy": "off",
"init-declarations": "off",
"jasmine/prefer-toHaveBeenCalledWith": "off",
"jsx-quotes": "error",
"key-spacing": "off",
"keyword-spacing": "off",
"line-comment-position": "off",
"linebreak-style": [
"error",
"unix"
],
"lines-around-comment": "off",
"lines-around-directive": "off",
"lines-between-class-members": "error",
"max-depth": "off",
"max-len": "off",
"max-lines": "off",
"max-nested-callbacks": "error",
"max-params": "off",
"max-statements": "off",
"max-statements-per-line": "off",
"multiline-comment-style": "off",
"multiline-ternary": "off",
"new-parens": "off",
"newline-after-var": "off",
"newline-before-return": "off",
"newline-per-chained-call": "off",
"no-alert": "off",
"no-array-constructor": "error",
"no-await-in-loop": "error",
"no-bitwise": "off",
"no-buffer-constructor": "error",
"no-caller": "error",
"no-catch-shadow": "off",
"no-confusing-arrow": "error",
"no-continue": "off",
"no-div-regex": "error",
"no-duplicate-imports": "error",
"no-else-return": "off",
"no-empty-function": "off",
"no-eq-null": "off",
"no-eval": "error",
"no-extend-native": "error",
"no-extra-bind": "off",
"no-extra-label": "off",
"no-extra-parens": "off",
"no-floating-decimal": "off",
"no-implicit-coercion": [
"error",
{
"boolean": false,
"number": false,
"string": false
}
],
"no-implicit-globals": "off",
"no-implied-eval": "error",
"no-inline-comments": "off",
"no-inner-declarations": [
"error",
"functions"
],
"no-invalid-this": "off",
"no-iterator": "error",
"no-label-var": "error",
"no-lone-blocks": "off",
"no-lonely-if": "off",
"no-loop-func": "off",
"no-magic-numbers": "off",
"no-mixed-operators": "off",
"no-mixed-requires": "error",
"no-multi-assign": "off",
"no-multi-spaces": "off",
"no-multi-str": "error",
"no-multiple-empty-lines": "off",
"no-native-reassign": "error",
"no-negated-condition": "off",
"no-negated-in-lhs": "error",
"no-nested-ternary": "off",
"no-new": "error",
"no-new-func": "off",
"no-new-object": "error",
"no-new-require": "error",
"no-new-wrappers": "error",
"no-octal-escape": "error",
"no-param-reassign": "off",
"no-path-concat": "error",
"no-plusplus": "off",
"no-process-env": "error",
"no-process-exit": "error",
"no-proto": "off",
"no-prototype-builtins": "off",
"no-redeclare": "off",
"no-restricted-globals": "error",
"no-restricted-imports": "error",
"no-restricted-modules": "error",
"no-restricted-properties": "error",
"no-restricted-syntax": "error",
"no-return-assign": "off",
"no-return-await": "error",
"no-script-url": "error",
"no-self-compare": "error",
"no-sequences": "off",
"no-shadow": "off",
"no-shadow-restricted-names": "off",
"no-spaced-func": "off",
"no-sync": "error",
"no-tabs": "off",
"no-template-curly-in-string": "error",
"no-ternary": "off",
"no-throw-literal": "off",
"no-trailing-spaces": [
"error",
{
"ignoreComments": true,
"skipBlankLines": true
}
],
"no-undef-init": "off",
"no-undefined": "off",
"no-underscore-dangle": "off",
"no-unmodified-loop-condition": "off",
"no-unneeded-ternary": "off",
"no-unused-expressions": "off",
"no-unused-vars": "off",
"no-use-before-define": "off",
"no-useless-call": "off",
"no-useless-computed-key": "error",
"no-useless-concat": "off",
"no-useless-constructor": "error",
"no-useless-rename": "error",
"no-useless-return": "off",
"no-var": "off",
"no-void": "off",
"no-warning-comments": "off",
"no-whitespace-before-property": "error",
"no-with": "error",
"nonblock-statement-body-position": [
"error",
"any"
],
"object-curly-newline": "off",
"object-curly-spacing": "off",
"object-property-newline": "off",
"object-shorthand": "off",
"one-var": "off",
"one-var-declaration-per-line": "off",
"operator-assignment": "off",
"operator-linebreak": "off",
"padded-blocks": "off",
"padding-line-between-statements": "error",
"prefer-arrow-callback": "off",
"prefer-const": "error",
"prefer-destructuring": "off",
"prefer-numeric-literals": "error",
"prefer-promise-reject-errors": "error",
"prefer-reflect": "off",
"prefer-rest-params": "off",
"prefer-spread": "off",
"prefer-template": "off",
"quote-props": "off",
"quotes": "off",
"radix": "off",
"require-await": "error",
"require-jsdoc": "off",
"rest-spread-spacing": "error",
"semi": "off",
"semi-spacing": "off",
"semi-style": "off",
"sort-imports": "error",
"sort-keys": "off",
"sort-vars": "off",
"space-before-blocks": "off",
"space-before-function-paren": "off",
"space-in-parens": "off",
"space-infix-ops": "off",
"space-unary-ops": "off",
"spaced-comment": "off",
"strict": "off",
"switch-colon-spacing": "off",
"symbol-description": "error",
"template-curly-spacing": "error",
"template-tag-spacing": "error",
"unicode-bom": [
"error",
"never"
],
"valid-jsdoc": "off",
"valid-typeof": [
"error",
{
"requireStringLiterals": false
}
],
"vars-on-top": "off",
"wrap-iife": "off",
"wrap-regex": "off",
"yield-star-spacing": "error",
"yoda": "off"
}
};

4
.gitignore vendored
View File

@ -110,3 +110,7 @@ ENV/
# backup files
*.bak
coverage/*
node_modules/*
package-lock.json

View File

@ -10,7 +10,7 @@
{% endblock %}
{% block main %}
<div ng-show="loading" class="col-xs-12 load-block" ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.LoadingCtrl">
<div ng-show="loading" class="col-xs-12 load-block" ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.LoadingController">
<md-icon md-svg-src="{$ basePath $}css/img/icons/spinner.svg" class="spinner"></md-icon>
</div>
<div ng-cloak>
@ -19,7 +19,7 @@
<span flex></span>
<div class="col-sm-11" style="height:80px;">
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.AgentCtrl" style="display:inline-block">
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.AgentController" style="display:inline-block">
<md-input-container class="md-block" flex-gt-xs>
<label>Template Version</label>
<md-select ng-model="template_version" ng-change="update_template_version(template_version)">
@ -29,16 +29,16 @@
</md-select>
</md-input-container>
</div>
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.TempModalCtrl" style="display:inline-block">
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.TempModalController" style="display:inline-block">
<md-tooltip style="font-size:12px !important;" md-direction="top">Generate Template</md-tooltip>
<md-button class="md-fab md-mini md-primary" ng-click="open()" aria-label="Generate Template">
<md-icon md-svg-src="{$ basePath $}css/img/icons/file-text-o.svg"></md-icon>
</md-button>
</div>
<div class="md-menu" ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.DraftMenuCtrl" style="display:inline-block">
<div class="md-menu" ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.DraftMenuController" style="display:inline-block">
<md-tooltip style="font-size:12px !important;" md-direction="top">Manage Drafts</md-tooltip>
<md-menu>
<md-button class="md-fab md-mini" ng-click="openMenu($mdOpenMenu, $event)" aria-label="Manage Drafts">
<md-button class="md-fab md-mini" ng-click="openMenu($mdMenu, $event)" aria-label="Manage Drafts">
<md-icon md-svg-src="{$ basePath $}css/img/icons/floppy-o.svg"></md-icon>
</md-button>
<md-menu-content width="4" ng-mouseleave="closeMenu()">
@ -66,7 +66,7 @@
</md-menu-content>
</md-menu>
</div>
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.ClearCanvasCtrl" style="display:inline-block">
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.ClearCanvasController" style="display:inline-block">
<md-tooltip style="font-size:12px !important;" md-direction="top">Clear Canvas</md-tooltip>
<md-button ng-click="clear_canvas()" class="md-fab md-mini md-warn" aria-label="clear canvas">
<md-icon md-svg-src="{$ basePath $}css/img/icons/trash.svg"></md-icon>
@ -82,7 +82,7 @@
<span flex></span>
<!-- Icon Drag sidebar -->
<div class="col-sm-11" style="text-align:center" ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.IconCtrl">
<div class="col-sm-11" style="text-align:center" ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.IconController">
<div draggable ng-repeat="(reskey, resobj) in resource_types" class="os-resource" draggable="true" id="{$ reskey $}" ng-if="admin || !resource_admin[reskey]">
<md-tooltip md-direction="top" style="font-size:12px !important;">{$ resobj.name $}</md-tooltip>
<md-icon style="height: 36px; width: 36px;" md-svg-src="{$ basePath $}js/resources/{$ reskey|lowercase $}/{$ reskey|lowercase $}.svg"></md-icon>
@ -95,7 +95,7 @@
<span flex></span>
<!-- Drop Canvas -->
<div class="col-sm-11" style="margin-bottom: 10%; min-height:400px; height: 500px">
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.VisCtrl" id="canvas_area" droppable>
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.VisController" id="canvas_area" droppable>
<vis-network component="hotnetwork" data="data" options="options" events="events">
</vis-network>
</div>
@ -104,17 +104,17 @@
<!-- End Drop Canvas -->
<!-- Node Modal -->
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.FormModalCtrl" class="md-padding" id="popupContainer" ng-cloak>
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.FormModalController" class="md-padding" id="popupContainer" ng-cloak>
</div>
<!-- End Node Modal -->
<!-- Edge Modal -->
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.EdgeFormModalCtrl" class="md-padding" id="popupEdgeContainer" ng-cloak>
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.EdgeFormModalController" class="md-padding" id="popupEdgeContainer" ng-cloak>
</div>
<!-- End Edge Modal -->
<!-- Load Draft Modal -->
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.DraftModalCtrl" class="md-padding" ng-cloak>
<div ng-controller="horizon.dashboard.project.heat_dashboard.template_generator.DraftModalController" class="md-padding" ng-cloak>
</div>
<!-- End Load Draft Modal -->
</div>

View File

@ -64,9 +64,12 @@ ADD_JS_FILES.extend(
'static'),
sub_path='%s/components' % JS_BASE,
ext='.js',
trim_base_path=True) if file not in ADD_JS_FILES
trim_base_path=True)
if file not in ADD_JS_FILES and 'spec.js' not in file
])
ADD_JS_FILES.extend(
discover_files(os.path.join(HEAT_DASHBOARD_ROOT, 'static'),
sub_path='%s/resources' % JS_BASE,
ext='.js', trim_base_path=True))
[file for file in discover_files(
os.path.join(HEAT_DASHBOARD_ROOT, 'static'),
sub_path='%s/resources' % JS_BASE,
ext='.js', trim_base_path=True) if 'spec.js' not in file
])

View File

@ -163,3 +163,7 @@ md-icon.spinner{
color: #fff;
}
.div-scroll{
overflow: auto;
max-height: 500px;
}

View File

@ -3,11 +3,11 @@
'use strict';
angular.module('horizon.dashboard.project.heat_dashboard.template_generator')
.controller('horizon.dashboard.project.heat_dashboard.template_generator.AgentCtrl', [
.controller('horizon.dashboard.project.heat_dashboard.template_generator.AgentController', [
'$scope','hotgenAgent', 'hotgenGlobals', 'hotgenMessage',
function($scope, hotgenAgent, hotgenGlobals, hotgenMessage){
var init = function(){
$scope.template_versions = [];
$scope.init = function(){
/* *********************************************************************
* The following selections should be replaced by OpenStack API response
*/
@ -35,10 +35,15 @@
});
};
init();
$scope.init();
$scope.update_template_version = function(template_version){
hotgenGlobals.set_template_version(template_version)
hotgenGlobals.set_template_version(template_version);
return true;
};
$scope.load_template_version = function(){
$scope.template_version = hotgenGlobals.get_template_version()
}
$scope.$on('update_template_version', $scope.load_template_version);
}])
})();

View File

@ -0,0 +1,100 @@
(function() {
'use strict';
describe('horizon.dashboard.project.heat_dashboard.template_generator.AgentController', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
var $httpBackend, requestHandler;
var $location;
var hotgenGlobals;
beforeEach(inject(function($injector){
$location = $injector.get('$location');
hotgenGlobals = $injector.get('hotgenGlobals');
spyOn($location, 'absUrl').and.callFake(function (p) {
return 'http://some-url/';
});
}));
beforeEach(inject(function($injector) {
// Set up the mock http service responses
$httpBackend = $injector.get('$httpBackend');
requestHandler = $httpBackend.when('GET', 'http://some-url/get_resource_options')
.respond(200, {
'auth': {
'tenant_id': 'tenant-id',
'admin': false,
},
'template_versions': [
{'name': 'v1', 'id': 'v1'},
{'name': 'v2', 'id': 'v2'}
],
}
);
}));
var $controller, controller, $scope;
beforeEach(inject(function(_$controller_, $rootScope) {
$controller = _$controller_;
$scope = $rootScope.$new();
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should exist', function(){
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.AgentController', { $scope: $scope,});
expect(controller).toBeDefined();
$httpBackend.flush();
});
it('should return array with 2 items', function(){
$httpBackend.expectGET('http://some-url/get_resource_options');
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.AgentController', { $scope: $scope,});
$httpBackend.flush();
expect($scope.template_versions.length).toEqual(2);
});
it('should return empty array', function(){
requestHandler.respond(500, '');
$httpBackend.expectGET('http://some-url/get_resource_options');
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.AgentController', { $scope: $scope,});
$httpBackend.flush();
expect($scope.template_versions.length).toEqual(0);
});
it('should return true', function(){
$httpBackend.expectGET('http://some-url/get_resource_options');
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.AgentController', { $scope: $scope,});
$httpBackend.flush();
expect($scope.update_template_version()).toEqual(true);
});
it('should set template version from hotgenGlobals', function(){
$httpBackend.expectGET('http://some-url/get_resource_options');
hotgenGlobals.set_template_version('template_version-1');
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.AgentController', { $scope: $scope,});
$httpBackend.flush();
$scope.load_template_version();
expect($scope.template_version).toEqual('template_version-1');
});
});
})();

View File

@ -4,11 +4,11 @@
angular.module('hotgen-agent', ['hotgen-utils', ])
.factory('hotgenAgent', ['$http', '$location', 'hotgenNotify',
function($http, $location, hotgenNotify) {
var static_url = $location.absUrl();
if (static_url.substr(-1) != '/'){
static_url += '/';
}
var get_resource_options = function(){
var static_url = $location.absUrl();
if (static_url.substr(-1) != '/'){
static_url += '/';
}
return $http({
method: 'GET',
url: static_url+'get_resource_options'

View File

@ -0,0 +1,82 @@
(function () {
'use strict';
describe('hotgen-agent module', function () {
it('should be defined', function () {
expect(angular.module('hotgen-agent')).toBeDefined();
});
});
describe('hotgen-utils.hotgenStates', function(){
beforeEach(module('hotgen-agent'));
var hotgenAgent;
beforeEach(inject(function(_hotgenAgent_){
hotgenAgent = _hotgenAgent_;
}));
var $httpBackend, requestHandler;
var $location;
beforeEach(inject(function($injector){
$location = $injector.get('$location');
}));
beforeEach(inject(function($injector) {
// Set up the mock http service responses
$httpBackend = $injector.get('$httpBackend');
requestHandler = $httpBackend.when('GET', 'http://some-url/get_resource_options')
.respond(200, {
'auth': {
'tenant_id': 'tenant-id',
'admin': false,
}}
);
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should exist', function(){
expect(hotgenAgent).toBeDefined();
});
it('should return get_resource_options', function(){
spyOn($location, 'absUrl').and.callFake(function (p) {
return 'http://some-url/';
});
$httpBackend.expectGET('http://some-url/get_resource_options');
var optionsPromise = hotgenAgent.get_resource_options();
optionsPromise.then(function(options){
expect(options.auth.tenant_id).toEqual('tenant-id');
expect(options.auth.admin).toEqual(false);
});
$httpBackend.flush();
});
it('should return error', function(){
spyOn($location, 'absUrl').and.callFake(function (p) {
return 'http://some-url';
});
requestHandler.respond(500, '');
$httpBackend.expectGET('http://some-url/get_resource_options');
var optionsPromise = hotgenAgent.get_resource_options();
optionsPromise.then(function(options){
expect(options).toEqual(null);
});
$httpBackend.flush();
});
});
})();

View File

@ -0,0 +1,29 @@
(function() {
'use strict';
describe('hotgen-utils compile directive', function(){
beforeEach(module('hotgen-utils'));
var $compile, $rootScope, $scope, $isolateScope, element;
beforeEach(inject(function($rootScope, $compile) {
$scope = $rootScope.$new();
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<div compile="<h1>Compile Me</h1>"></div>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
// If the directive uses isolate scope, we need to get a reference to it
// explicitly
}));
it('Replaces the element with the appropriate content', function() {
expect(element.html()).toContain("Compile Me");
});
});
})();

View File

@ -0,0 +1,51 @@
(function() {
'use strict';
describe('horizon.dashboard.project.heat_dashboard.template_generator dependson directive', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $compile, $rootScope, $scope, $isolateScope, element;
beforeEach(inject(function($rootScope, $compile) {
$scope = $rootScope.$new();
$scope.dependson = ['node-id-1111', 'node-id-2222', 'node-id-3333'];
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<depends-on dependson="dependson"></depends-on>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
// If the directive uses isolate scope, we need to get a reference to it
// explicitly
$isolateScope = element.isolateScope();
}));
it('Replaces the element with the appropriate content', function() {
expect(element.find('label').html()).toContain("Depends on");
});
it('toggle function modifies array', function() {
var array = [0, 1, 2, 3, 4];
$isolateScope.toggle(5, array);
expect(array.length).toEqual(6);
$isolateScope.toggle(0, array);
$isolateScope.toggle(5, array);
expect(array.length).toEqual(4);
});
it('check array item existence ', function() {
var array = [0, 1, 2, 3, 4];
expect($isolateScope.exists(5, array)).toEqual(false);
expect($isolateScope.exists(1, array)).toEqual(true);
});
});
})();

View File

@ -5,15 +5,21 @@
angular.module('horizon.dashboard.project.heat_dashboard.template_generator').directive('draggable', [function(){
return function ($scope, element){
var el = element[0];
el.draggable = true;
el.addEventListener('dragstart', function(e){
this.style.opacity = '0.4';
e.dataTransfer.setData('text', e.target.id);
}, false);
el.addEventListener('dragend', function(e){
this.style.opacity = '1.0';
}, false);
el.draggable = true;
$scope.dragstartHandler = function(e){
el.style.opacity = '0.4';
e.dataTransfer.setData('text', e.target.id);
}
$scope.dragendHandler = function(e){
el.style.opacity = '1.0';
}
el.addEventListener('dragstart', $scope.dragstartHandler, false);
el.addEventListener('dragend', $scope.dragendHandler, false);
}
}]);

View File

@ -0,0 +1,52 @@
(function() {
'use strict';
describe('horizon.dashboard.project.heat_dashboard.template_generator draggable directive', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
var $compile, $rootScope, $scope, $isolateScope, element;
beforeEach(inject(function($rootScope, $compile) {
$scope = $rootScope.$new();
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<div draggable >drag me</div>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
// If the directive uses isolate scope, we need to get a reference to it
// explicitly
$isolateScope = element.isolateScope();
}));
it('Replaces the element with the appropriate content', function() {
expect(element[0].draggable).toEqual(true);
});
it('should change style when drag start', function() {
var mockEvent = {
'type': 'dragstart',
'dataTransfer': {
'setData': function(key, value){},
},
'target': {'id': 'icon-1'}
};
$scope.dragstartHandler(mockEvent, element);
expect(element[0].style.opacity).toEqual('0.4')
});
it('should change style when drag end', function() {
var mockEvent = {
'type': 'dragend',
};
$scope.dragendHandler(mockEvent, element);
expect(element[0].style.opacity).toEqual('1')
});
});
})();

View File

@ -11,13 +11,7 @@
nodes: hotgenStates.get_nodes(),
edges: hotgenStates.get_edges(),
}
var el = element[0];
el.addEventListener('dragover', function(e){
if (e.preventDefault){
e.preventDefault();
}
},true);
el.addEventListener('drop', function(e){
$scope.dropHandler = function(e){
var resource_types = hotgenGlobals.get_resource_icons();
var dropped_elem_id = e.dataTransfer.getData("text");
var dropped_elem_base = document.getElementById(dropped_elem_id);
@ -31,7 +25,7 @@
$scope.data.nodes.add({
id: id,
label: node_label,
shape: 'image',
shape: 'circularImage',
title: resource_type,
icon: {
face: 'FontAwesome',
@ -39,11 +33,22 @@
size: 50,
color: dragged_resource.color,
},
borderWidth: 0,
borderWidthSelected: 0,
color: {border: '#ffffff', background: '#ffffff', highlight: '#ffffff', hover: '#ffffff'},
image: basePath+'js/resources/'+resource_type.toLowerCase()+'/'+resource_type.toLowerCase()+'-gray.svg',
});
hotgenStates.update_saved_flags(id, false)
e.preventDefault();
},false);
}
$scope.dragoverHandler = function(e){
if (e.preventDefault){
e.preventDefault();
}
}
var el = element[0];
el.addEventListener('dragover', $scope.dragoverHandler, true);
el.addEventListener('drop', $scope.dropHandler, false);
}
}
}]);

View File

@ -0,0 +1,70 @@
(function() {
'use strict';
describe('horizon.dashboard.project.heat_dashboard.template_generator droppable directive', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
var hotgenGlobals;
beforeEach(inject(function($injector){
hotgenGlobals = $injector.get('hotgenGlobals');
}));
var $compile, $rootScope, $scope, $isolateScope, element;
beforeEach(inject(function($rootScope, $compile) {
$scope = $rootScope.$new();
// element will enable you to test your directive's element on the DOM
element = $compile('<div droppable >drop me</div>')($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
// If the directive uses isolate scope, we need to get a reference to it
// explicitly
$isolateScope = element.isolateScope();
}));
it('Replaces the element with the appropriate content', function() {
expect(element.html()).toEqual('drop me');
});
it('Dragover event with preventDefault', function() {
var mockEvent= {
type: 'dragover',
preventDefault: function(){},
}
spyOn(mockEvent, 'preventDefault');
$scope.dragoverHandler(mockEvent);
expect(mockEvent.preventDefault).toHaveBeenCalled();
});
it('Dragover event with !preventDefault', function() {
var mockEvent= {
type: 'dragover',
}
$scope.dragoverHandler(mockEvent);
});
it('Drop event', function() {
var resource_type = 'OS::Project::ResourceType';
hotgenGlobals.update_resource_icons(resource_type, {
'code': '', 'color': '#000'
})
var mockEvent = {
type: 'drop',
dataTransfer: {
getData: function(key){return resource_type},
},
target: {id: 'icon-1'},
preventDefault: function(){},
};
$scope.dropHandler(mockEvent);
});
});
})();

View File

@ -0,0 +1,126 @@
(function() {
'use strict';
describe('hotgen-utils.hotgenGlobals', function(){
beforeEach(module('hotgen-utils'));
var hotgenGlobals;
beforeEach(inject(function(_hotgenGlobals_){
hotgenGlobals = _hotgenGlobals_;
}));
it('should exist', function(){
expect(hotgenGlobals).toBeDefined();
});
it('check get_element', function(){
var returnValue = hotgenGlobals.get_element('resource_icons');
expect(Object.keys(returnValue).length).toEqual(0);
});
it('check node_labels', function(){
var returnValue = hotgenGlobals.get_node_labels();
expect(Object.keys(returnValue).length).toEqual(0);
hotgenGlobals.update_node_labels('key1', 'label1')
expect(Object.keys(returnValue).length).toEqual(1);
});
it('check node_admin', function(){
var returnValue = hotgenGlobals.get_node_admin();
expect(Object.keys(returnValue).length).toEqual(0);
hotgenGlobals.update_node_admin('key1', 'admin');
expect(Object.keys(returnValue).length).toEqual(1);
});
it('check resource_icons', function(){
var returnValue = hotgenGlobals.get_resource_icons();
expect(Object.keys(returnValue).length).toEqual(0);
hotgenGlobals.update_resource_icons('key1', 'admin');
expect(Object.keys(returnValue).length).toEqual(1);
});
it('check get_resource_components', function(){
var returnValue = hotgenGlobals.get_resource_components();
expect(Object.keys(returnValue).length).toEqual(0);
hotgenGlobals.update_resource_components('key1', 'component');
expect(Object.keys(returnValue).length).toEqual(1);
});
it('check get_edge_directions', function(){
var returnValue = hotgenGlobals.get_edge_directions();
expect(Object.keys(returnValue).length).toEqual(0);
hotgenGlobals.update_edge_directions('key1', 'edge');
expect(Object.keys(returnValue).length).toEqual(1);
});
it('check get_template_version', function(){
var returnValue = hotgenGlobals.get_template_version();
expect(returnValue).toEqual(null);
hotgenGlobals.set_template_version(['v1', 'v2']);
expect(hotgenGlobals.get_template_version().length).toEqual(2);
});
it('check get_necessary_properties', function(){
var returnValue = hotgenGlobals.get_necessary_properties();
expect(Object.keys(returnValue).length).toEqual(0);
hotgenGlobals.update_necessary_properties('key1', ['p1', 'p2']);
expect(hotgenGlobals.get_necessary_properties()['key1'].length).toEqual(2);
});
it('check get_resource_types', function(){
var returnValue = hotgenGlobals.get_resource_types();
expect(Object.keys(returnValue).length).toEqual(0);
});
it('check get_resource_options', function(){
var returnValue = hotgenGlobals.get_resource_options();
expect(Object.keys(returnValue).length).toEqual(1);
hotgenGlobals.update_resource_options(['op1', 'op2']);
expect(Object.keys(returnValue).length).toEqual(3);
});
it('check get_resource_outputs', function(){
hotgenGlobals.set_resource_outputs('key1', '');
var returnValue = hotgenGlobals.get_resource_outputs('key1');
expect(returnValue).toEqual('');
});
it('check get_reference_file', function(){
hotgenGlobals.set_reference_file('key1', '');
var returnValue = hotgenGlobals.get_reference_file('key1');
expect(returnValue).toEqual('');
});
});
})();

View File

@ -2,7 +2,7 @@
'use strict';
angular.module('horizon.dashboard.project.heat_dashboard.template_generator')
.controller('horizon.dashboard.project.heat_dashboard.template_generator.IconCtrl', ['$scope', 'hotgenGlobals',
.controller('horizon.dashboard.project.heat_dashboard.template_generator.IconController', ['$scope', 'hotgenGlobals',
'horizon.dashboard.project.heat_dashboard.template_generator.basePath',
function($scope, hotgenGlobals, basePath){
$scope.resource_types = hotgenGlobals.get_resource_icons();

View File

@ -0,0 +1,38 @@
(function() {
'use strict';
describe('horizon.dashboard.project.heat_dashboard.template_generator.IconController', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
var $controller, controller, $scope, hotgenGlobals;
beforeEach(inject(function($injector){
hotgenGlobals = $injector.get('hotgenGlobals');
}));
beforeEach(inject(function(_$controller_, $rootScope) {
$controller = _$controller_;
$scope = $rootScope.$new();
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.IconController', { $scope: $scope,});
}));
it('should exist', function(){
expect(controller).toBeDefined();
});
it('check scope parameters', inject([ '$window', function($window){
var icons_number = Object.keys(hotgenGlobals.get_resource_icons()).length;
expect(Object.keys($scope.resource_types).length).toEqual(icons_number);
var admin_number = Object.keys(hotgenGlobals.get_node_admin()).length;
expect(Object.keys($scope.resource_admin).length).toEqual(admin_number);
expect($scope.admin).toEqual(false);
expect($scope.basePath).toBe($window.STATIC_URL + 'dashboard/project/heat_dashboard/template_generator/');
}]));
});
})();

View File

@ -4,7 +4,7 @@
angular
.module('horizon.dashboard.project.heat_dashboard.template_generator')
.controller('horizon.dashboard.project.heat_dashboard.template_generator.LoadingCtrl', [
.controller('horizon.dashboard.project.heat_dashboard.template_generator.LoadingController', [
'$scope', 'hotgenNotify',
'horizon.dashboard.project.heat_dashboard.template_generator.basePath',
function($scope, hotgenNotify, basePath){
@ -17,4 +17,4 @@
}])
})();
})();

View File

@ -0,0 +1,36 @@
(function() {
'use strict';
describe('LoadingController', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
var $controller, controller, $scope, $rootScope;
beforeEach(inject(function(_$controller_, $rootScope) {
$controller = _$controller_;
$scope = $rootScope.$new();
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.LoadingController', { $scope: $scope,});
}));
beforeEach(inject(function(_$rootScope_) {
$rootScope = _$rootScope_;
}));
it('should exist', function(){
expect(controller).toBeDefined();
});
it('loading is false by default', function(){
expect($scope.loading).toEqual(true);
});
it('loading is true after message received', function(){
$rootScope.$broadcast('handle_resources_loaded');
expect($scope.loading).toEqual(false);
});
});
})();

View File

@ -4,13 +4,15 @@
angular
.module('horizon.dashboard.project.heat_dashboard.template_generator')
.controller('horizon.dashboard.project.heat_dashboard.template_generator.DraftMenuCtrl', ['$scope',
'$mdDialog', 'hotgenStates', 'hotgenNotify', 'hotgenMessage',
.controller('horizon.dashboard.project.heat_dashboard.template_generator.DraftMenuController', ['$scope',
'$mdDialog', 'hotgenStates', 'hotgenGlobals', 'hotgenNotify', 'hotgenMessage',
'horizon.dashboard.project.heat_dashboard.template_generator.basePath',
function($scope, $mdDialog, hotgenStates, hotgenNotify, hotgenMessage, basePath){
function($scope, $mdDialog, hotgenStates, hotgenGlobals, hotgenNotify, hotgenMessage, basePath){
$scope.basePath = basePath;
$scope.openMenu = function($mdOpenMenu, ev){
$mdOpenMenu(ev);
var originatorEv;
$scope.openMenu = function($mdMenu, ev){
originatorEv = ev;
$mdMenu.open(ev);
};
$scope.data = {
nodes: hotgenStates.get_nodes(),
@ -33,7 +35,8 @@
saved_depends_ons: hotgenStates.get_saved_dependsons(),
is_saved: hotgenStates.get_saved_flags(),
incremented_labels: hotgenStates.get_incremented_labels(),
counter: hotgenStates.get_counters()
counter: hotgenStates.get_counters(),
template_version: hotgenGlobals.get_template_version(),
}
var today = new Date();
@ -55,7 +58,7 @@
}]);
angular.module('horizon.dashboard.project.heat_dashboard.template_generator')
.controller('horizon.dashboard.project.heat_dashboard.template_generator.ClearCanvasCtrl', ['$scope',
.controller('horizon.dashboard.project.heat_dashboard.template_generator.ClearCanvasController', ['$scope',
'hotgenStates', 'hotgenNotify',
'horizon.dashboard.project.heat_dashboard.template_generator.basePath',
function($scope, hotgenStates, hotgenNotify, basePath){
@ -74,4 +77,4 @@
}]);
})();
})();

View File

@ -0,0 +1,135 @@
(function() {
'use strict';
describe('horizon.dashboard.project.heat_dashboard.template_generator.DraftMenuController', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
var $controller, controller, $scope, $rootScope, $mdMenu;
beforeEach(inject(function($injector){
$rootScope = $injector.get('$rootScope');
$mdMenu = $injector.get('$mdMenu');
spyOn($rootScope, '$broadcast');
$mdMenu.open = jasmine.createSpy().and.callFake(function() {
return function (callBack) {
callBack(true); //return the value to be assigned.
}
});
}));
beforeEach(inject(function(_$controller_, $rootScope) {
$controller = _$controller_;
$scope = $rootScope.$new();
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.DraftMenuController', { $scope: $scope,});
}));
afterEach(function() {
localStorage.clear();
});
it('DraftMenuController should exist', function(){
expect(controller).toBeDefined();
});
it('DraftMenuController basePath', inject([ '$window', function($window){
expect($scope.basePath).toBe($window.STATIC_URL + 'dashboard/project/heat_dashboard/template_generator/');
}]));
it('scope.openMenu ', function(){
$scope.openMenu($mdMenu, {});
expect($mdMenu.open).toHaveBeenCalled();
});
it('DraftMenuController scope.data contains nodes and edges', function(){
expect($scope.data.nodes.length).toEqual(0);
expect($scope.data.edges.length).toEqual(0);
});
it('scope.save_draft stores in localStorage', function(){
expect(localStorage.length).toEqual(0);
$scope.save_draft();
expect(localStorage.length).toEqual(0);
$scope.data.nodes.add({'id': 'some-id'});
$scope.save_draft();
expect(localStorage.length).toEqual(2);
$scope.data.nodes.add({'id': 'some-id-2'});
$scope.save_draft();
expect(localStorage.length).toEqual(3);
});
it('scope.load_draft', function(){
$scope.load_draft();
expect($rootScope.$broadcast).toHaveBeenCalledWith('handle_load_draft');
});
it('scope.import_draft', function(){
$scope.import_draft();
});
it('scope.export_draft', function(){
$scope.export_draft();
});
});
describe('horizon.dashboard.project.heat_dashboard.template_generator.ClearCanvasController', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
var $controller, controller, $scope, $rootScope;
beforeEach(inject(function($injector){
$rootScope = $injector.get('$rootScope');
spyOn($rootScope, '$broadcast');
}));
beforeEach(inject(function(_$controller_, $rootScope) {
$controller = _$controller_;
$scope = $rootScope.$new();
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.ClearCanvasController', { $scope: $scope,});
}));
afterEach(function() {
localStorage.clear();
});
it('ClearCanvasController should exist', function(){
expect(controller).toBeDefined();
});
it('ClearCanvasController basePath', inject([ '$window', function($window){
expect($scope.basePath).toBe($window.STATIC_URL + 'dashboard/project/heat_dashboard/template_generator/');
}]));
it('ClearCanvasController scope.data contains nodes and edges', function(){
expect($scope.data.nodes.length).toEqual(0);
expect($scope.data.edges.length).toEqual(0);
});
it('scope.clear_canvas should empty $scope.data', function(){
$scope.data.nodes.add({'id': 'some-node-id'});
$scope.data.edges.add({'id': 'some-edge-id'});
expect($scope.data.nodes.length).toEqual(1);
expect($scope.data.edges.length).toEqual(1);
$scope.clear_canvas();
expect($scope.data.nodes.length).toEqual(0);
expect($scope.data.edges.length).toEqual(0);
});
});
})();

View File

@ -2,23 +2,11 @@
'use strict';
angular.module('horizon.dashboard.project.heat_dashboard.template_generator')
.controller('horizon.dashboard.project.heat_dashboard.template_generator.DraftModalCtrl', ['$scope',
'$mdDialog', 'hotgenNotify', 'hotgenMessage', 'hotgenStates',
.controller('horizon.dashboard.project.heat_dashboard.template_generator.DraftModalController', ['$scope',
'$mdDialog', 'hotgenNotify', 'hotgenMessage', 'hotgenStates', 'hotgenGlobals',
'horizon.dashboard.project.heat_dashboard.template_generator.basePath',
function($scope, $mdDialog, hotgenNotify, hotgenMessage, hotgenStates, basePath){
$scope.showDialog = function(){
$mdDialog.show({
controller: DraftDialogController,
templateUrl: basePath + 'templates/modal_draft.html',
parent: angular.element(document.body),
clickOutsideToClose:true
}).then(function(){
hotgenNotify.show_success('The draft is loaded successfully.');
}, function(){
// hotgenNotify.show_error('dismiss a modal');
});
DraftDialogController.$inject = ['$scope', '$mdDialog', 'hotgenStates'];
function DraftDialogController($scope, $mdDialog, hotgenStates) {
function($scope, $mdDialog, hotgenNotify, hotgenMessage, hotgenStates, hotgenGlobals, basePath){
$scope.draftDialogController = function ($scope, $mdDialog, hotgenStates) {
$scope.draft_list = [];
$scope.latest_draft = JSON.parse(localStorage.getItem('draft_'+localStorage.saved_counter));
for (var i = 0 ; i < 10; i++){
@ -46,16 +34,31 @@
hotgenStates.set_saved_flags(draft.is_saved);
hotgenStates.set_counters(draft.counter);
hotgenStates.set_incremented_labels(draft.incremented_labels);
hotgenGlobals.set_template_version(draft.template_version);
hotgenMessage.broadcast_update_template_version();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
}
}
$scope.$on('handle_load_draft', function(event, args){
$scope.showDialog();
});
};
$scope.showDialog = function(){
$scope.draftDialogController.$inject = ['$scope', '$mdDialog', 'hotgenStates'];
$mdDialog.show({
controller: $scope.draftDialogController,
templateUrl: basePath + 'templates/modal_draft.html',
parent: angular.element(document.body),
clickOutsideToClose:true
}).then(function(){
hotgenNotify.show_success('The draft is loaded successfully.');
}, function(){
// hotgenNotify.show_error('dismiss a modal');
});
}
$scope.handle_load_draft = function(event, args){
$scope.showDialog();
}
$scope.$on('handle_load_draft', $scope.handle_load_draft);
}]);
})();
})();

View File

@ -0,0 +1,94 @@
(function() {
'use strict';
describe('horizon.dashboard.project.heat_dashboard.template_generator.DraftModalController', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
beforeEach(module('hotgen-utils'));
var hotgenStates;
beforeEach(inject(function(_hotgenStates_){
hotgenStates = _hotgenStates_;
}));
var $controller, controller, $scope, $rootScope, $mdDialog;
beforeEach(inject(function($injector){
$rootScope = $injector.get('$rootScope');
$mdDialog = $injector.get('$mdDialog');
}));
beforeEach(inject(function(_$controller_, $rootScope) {
$controller = _$controller_;
$scope = $rootScope.$new();
spyOn($scope, '$on');
spyOn($mdDialog, 'show');
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.DraftModalController',
{ $scope: $scope, $mdDialog: $mdDialog});
$mdDialog.show = jasmine.createSpy().and.callFake(function() {
return {
then: (function (callBack) {
callBack(true); //return the value to be assigned.
}, function(callBack){
callBack(false)}
)
}
});
}));
afterEach(function(){
localStorage.clear();
$mdDialog.cancel();
})
it('should exist', function(){
expect(controller).toBeDefined();
});
it('$scope.$on should be called', function(){
var event = $rootScope.$broadcast('handle_load_draft');
expect($scope.$on).toHaveBeenCalled();
$scope.handle_load_draft(event, {});
});
it('show dialog', function(){
$scope.showDialog();
$scope.$digest();
expect($mdDialog.show).toHaveBeenCalled();
});
it('draftDialogController', function(){
var draft = {}
localStorage.setItem('draft_1', JSON.stringify(draft))
$scope.draftDialogController($scope, $mdDialog, hotgenStates);
expect($scope.data.nodes.length).toEqual(0);
});
it('draftDialogController load draft', function(){
var draft = {'nodes': {'node-1':{}}, 'edges': {'edge-1':{}}};
$scope.draftDialogController($scope, $mdDialog, hotgenStates);
$scope.load(draft);
expect($scope.data.nodes.length).toEqual(1);
expect($scope.data.edges.length).toEqual(1);
});
it('draftDialogController cancel', function(){
$scope.draftDialogController($scope, $mdDialog, hotgenStates);
$scope.cancel();
});
});
})();

View File

@ -2,59 +2,59 @@
'use strict';
angular.module('horizon.dashboard.project.heat_dashboard.template_generator')
.controller('horizon.dashboard.project.heat_dashboard.template_generator.EdgeFormModalCtrl', ['$scope',
.controller('horizon.dashboard.project.heat_dashboard.template_generator.EdgeFormModalController', ['$scope',
'$mdDialog', 'hotgenNotify', 'hotgenMessage', 'hotgenGlobals', 'hotgenStates',
'horizon.dashboard.project.heat_dashboard.template_generator.basePath',
function($scope, $mdDialog, hotgenNotify, hotgenMessage, hotgenGlobals, hotgenStates, basePath){
$scope.showTabDialog = function(){
$mdDialog.show({
controller: EdgeDialogController,
controllerAs: 'ctrl',
templateUrl: basePath+'templates/modal_edge.html',
parent: angular.element(document.body),
clickOutsideToClose:true
}).then(function(){
// hotgenNotify.show_success('close the modal');
}, function(){
// hotgenNotify.show_error('dismiss a modal');
});
EdgeDialogController.$inject = ['$scope', '$mdDialog', 'hotgenStates'];
function EdgeDialogController($scope, $mdDialog, hotgenStates,) {
$scope.is_depends = false;
$scope.delete_resource = function() {
hotgenStates.get_network().deleteSelected();
hotgenNotify.show_success('The selected edge has been delete successfully.')
$mdDialog.cancel();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.selected = hotgenStates.get_selected();
if ($scope.selected.id in hotgenStates.get_saved_resources()){
$scope.resource = hotgenStates.get_saved_resources()[$scope.selected.id].data;
} else{
$scope.resource = {}
}
if ($scope.selected.edge.arrows && $scope.selected.edge.arrows.middle == true){
$scope.is_depends = true;
}
var from_type = $scope.selected.resource_type.from;
var to_type = $scope.selected.resource_type.to;
$scope.from_type = from_type.replace(/_/g, ':');
$scope.to_type = to_type.replace(/_/g, ':');
$scope.from_node = {
class: hotgenGlobals.get_resource_icons()[from_type].class,
color: hotgenGlobals.get_resource_icons()[from_type].color,
id: $scope.selected.from_node.id,
}
$scope.to_node = {
class: hotgenGlobals.get_resource_icons()[to_type].class,
color: hotgenGlobals.get_resource_icons()[to_type].color,
id: $scope.selected.to_node.id,
}
$scope.edgeDialogController = function($scope, $mdDialog, hotgenStates, basePath) {
$scope.is_depends = false;
$scope.delete_resource = function() {
hotgenStates.get_network().deleteSelected();
hotgenNotify.show_success('The selected edge has been delete successfully.')
$mdDialog.cancel();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.selected = hotgenStates.get_selected();
if ($scope.selected.id in hotgenStates.get_saved_resources()){
$scope.resource = hotgenStates.get_saved_resources()[$scope.selected.id].data;
} else{
$scope.resource = {}
}
if ($scope.selected.edge.arrows && $scope.selected.edge.arrows.middle == true){
$scope.is_depends = true;
}
var from_type = $scope.selected.resource_type.from;
var to_type = $scope.selected.resource_type.to;
$scope.from_type = from_type.replace(/_/g, ':');
$scope.to_type = to_type.replace(/_/g, ':');
$scope.from_node = {
image: basePath+'js/resources/'+from_type.toLowerCase()+'/'+from_type.toLowerCase()+'.svg',
id: $scope.selected.from_node.id,
}
$scope.to_node = {
image: basePath+'js/resources/'+to_type.toLowerCase()+'/'+to_type.toLowerCase()+'.svg',
id: $scope.selected.to_node.id,
}
}
$scope.showTabDialog = function(){
$scope.edgeDialogController.$inject = ['$scope', '$mdDialog', 'hotgenStates',
'horizon.dashboard.project.heat_dashboard.template_generator.basePath'];
$mdDialog.show({
controller: $scope.edgeDialogController,
controllerAs: 'ctrl',
templateUrl: basePath+'templates/modal_edge.html',
parent: angular.element(document.body),
clickOutsideToClose:true
}).then(function(){
// hotgenNotify.show_success('close the modal');
}, function(){
// hotgenNotify.show_error('dismiss a modal');
});
};
$scope.$on('handle_edit_edge', function(event, args){
$scope.handle_edit_edge = function(event, args){
/* Click a edge and decide to show modal or not */
var from_type = args.from_type;
var to_type = args.to_type;
@ -64,7 +64,7 @@
var depends_ons = hotgenStates.get_saved_dependsons();
if ( !( from_type in edge_directions) || !(to_type in edge_directions[from_type])){
if (from_id in depends_ons && depends_ons[from_id] == to_id){
;
//;
}
else {
hotgenNotify.show_warning('The edge might be invalid.');
@ -72,7 +72,11 @@
}
}
$scope.showTabDialog();
});
};
$scope.$on('handle_edit_edge', $scope.handle_edit_edge);
}]);
})();
})();

View File

@ -0,0 +1,196 @@
(function() {
'use strict';
describe('horizon.dashboard.project.heat_dashboard.template_generator.EdgeFormModalController', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var hotgenGlobals, hotgenStates, basePath;
beforeEach(inject(function($injector){
hotgenGlobals = $injector.get('hotgenGlobals');
hotgenStates = $injector.get('hotgenStates');
basePath = $injector.get('horizon.dashboard.project.heat_dashboard.template_generator.basePath');
}));
var $controller, controller, $scope, $rootScope, $mdDialog;
beforeEach(inject(function($injector){
$rootScope = $injector.get('$rootScope');
$mdDialog = $injector.get('$mdDialog');
}));
beforeEach(inject(function(_$controller_, $rootScope) {
$controller = _$controller_;
$scope = $rootScope.$new();
spyOn($scope, '$on');
spyOn($mdDialog, 'show');
spyOn($mdDialog, 'cancel');
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.EdgeFormModalController',
{ $scope: $scope, $mdDialog: $mdDialog});
$mdDialog.show = jasmine.createSpy().and.callFake(function() {
return {
then: (function (callBack) {
callBack(true); //return the value to be assigned.
}, function(callBack){
callBack(false)}
)
}
});
$mdDialog.cancel = jasmine.createSpy().and.callFake(function() {
return function(callBack){callBack(true)};
});
}));
it('should exist', function(){
expect(controller).toBeDefined();
});
it('$scope.$on should be called', function(){
var event = $rootScope.$broadcast('handle_edit_edge');
expect($scope.$on).toHaveBeenCalled();
});
it('show dialog with no parameters set.', function(){
$scope.showTabDialog();
$scope.$digest();
expect($mdDialog.show).toHaveBeenCalled();
});
it('handle_edit_edge valid edges', function(){
var event = $rootScope.$broadcast('handle_edit_edge');
hotgenGlobals.update_edge_directions('from_id', {'to_id': {}});
hotgenStates.update_saved_dependsons('from_id', 'to_id');
$scope.handle_edit_edge(event, {
'from_type': 'from_type', 'to_type': 'to_type',
'from_id': 'from_id', 'to_id': 'to_id',
});
expect($mdDialog.show).toHaveBeenCalled();
});
it('handle_edit_edge invalid edges #1', function(){
var event = $rootScope.$broadcast('handle_edit_edge');
hotgenGlobals.update_edge_directions('from_type', {'to_type': {}})
expect($mdDialog.show).not.toHaveBeenCalled();
$scope.handle_edit_edge(event, {
'from_type': 'from_type', 'to_type': 'to_type',
'from_id': 'from_id', 'to_id': 'to_id',
});
});
it('handle_edit_edge invalid edges #2', function(){
var event = $rootScope.$broadcast('handle_edit_edge');
hotgenGlobals.update_edge_directions('from_id', {'to': {}})
$scope.handle_edit_edge(event, {
'from_type': 'from_type', 'to_type': 'to_type',
'from_id': 'from_id', 'to_id': 'to_id',
});
expect($mdDialog.show).not.toHaveBeenCalled();
});
it('cancel dialog', function(){
hotgenStates.set_selected({
id: 'edge-id',
edge: {arrows: {middle: true}},
resource_type: {from: 'from_type', to: 'to_type'},
from_node: {id: 'from_id'},
to_node: {id: 'to_id'}
});
hotgenStates.set_saved_resources({
'edge-id': {data: {'resource property': 'something'}}
});
$scope.edgeDialogController($scope, $mdDialog, hotgenStates, basePath);
$scope.cancel();
expect($mdDialog.cancel).toHaveBeenCalled();
});
it('delete resource dialog', function(){
hotgenStates.set_selected({
id: 'edge-id',
edge: {arrows: {middle: true}},
resource_type: {from: 'from_type', to: 'to_type'},
from_node: {id: 'from_id'},
to_node: {id: 'to_id'}
});
hotgenStates.set_saved_resources({
'edge-id': {data: {'resource property': 'something'}}
});
hotgenStates.set_network({
deleteSelected: function(){}
});
$scope.edgeDialogController($scope, $mdDialog, hotgenStates, basePath);
$scope.delete_resource();
expect($mdDialog.cancel).toHaveBeenCalled();
});
it('handle_edit_edge test depends on edge.', function(){
hotgenStates.set_selected({
id: 'edge-id',
edge: {arrows: {middle: true}},
resource_type: {from: 'from_type', to: 'to_type'},
from_node: {id: 'from_id'},
to_node: {id: 'to_id'}
});
hotgenStates.set_saved_resources({
'edge-id': {data: {'resource property': 'something'}}
});
$scope.edgeDialogController($scope, $mdDialog, hotgenStates, basePath);
expect($scope.is_depends).toEqual(true);
expect(Object.keys($scope.resource).length).toEqual(1);
expect($scope.from_node.image).toEqual(basePath+'js/resources/from_type/from_type.svg')
});
it('handle_edit_edge test properties edge.', function(){
hotgenStates.set_selected({
id: 'edge-id',
edge: {},
resource_type: {from: 'from_type', to: 'to_type'},
from_node: {id: 'from_id'},
to_node: {id: 'to_id'}
});
hotgenStates.set_saved_resources({
'edge-id': {
data: {'resource property': 'something'}
}
})
$scope.edgeDialogController($scope, $mdDialog, hotgenStates, basePath);
expect($scope.is_depends).toEqual(false);
expect(Object.keys($scope.resource).length).toEqual(1);
});
it('handle_edit_edge test not saved edge.', function (){
hotgenStates.set_selected({
id: 'edge-id',
edge: {},
resource_type: {from: 'from_type', to: 'to_type'},
from_node: {id: 'from_id'},
to_node: {id: 'to_id'}
});
hotgenStates.set_saved_resources({
'node-id': {
data: {'resource property': 'something'}
}
})
$scope.edgeDialogController($scope, $mdDialog, hotgenStates, basePath);
expect(Object.keys($scope.resource).length).toEqual(0)
});
});
})();

View File

@ -2,16 +2,155 @@
'use strict';
angular.module('horizon.dashboard.project.heat_dashboard.template_generator')
.controller('horizon.dashboard.project.heat_dashboard.template_generator.FormModalCtrl', ['$scope', '$compile',
.controller('horizon.dashboard.project.heat_dashboard.template_generator.FormModalController', ['$scope', '$compile',
'$mdDialog', 'hotgenNotify', 'hotgenMessage', 'hotgenGlobals', 'hotgenUtils', 'hotgenStates',
'horizon.dashboard.project.heat_dashboard.template_generator.basePath',
function($scope, $compile, $mdDialog,
hotgenNotify, hotgenMessage, hotgenGlobals, hotgenUtils, hotgenStates, basePath){
$scope.selected = hotgenStates.get_selected();
$scope.data = {
nodes: hotgenStates.get_nodes(),
edges: hotgenStates.get_edges(),
};
$scope.dialogController = function ($scope, $mdDialog, hotgenStates) {
$scope.delete_resource = function() {
var label = hotgenStates.get_selected().node.label;
hotgenStates.get_network().deleteSelected();
hotgenNotify.show_success(label + ' has been delete successfully.')
$mdDialog.cancel();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.selected = hotgenStates.get_selected();
$scope.data = {
nodes: hotgenStates.get_nodes(),
edges: hotgenStates.get_edges(),
};
$scope.save = function() {
$mdDialog.hide();
hotgenStates.update_saved_resources($scope.selected.id, {
type: $scope.selected.resource_type,
data: angular.copy($scope.resource)
});
hotgenStates.update_saved_dependsons($scope.selected.id, $scope.dependson);
var label = hotgenStates.get_label_by_uuid($scope.selected.node.id);
var prop_label = $scope.get_label($scope.selected.resource_type);
if (prop_label && $scope.resource[prop_label]){
label = label + '(' + $scope.resource[prop_label]+')';
}
var new_node_image = $scope.data.nodes.get($scope.selected.id).image.replace('-gray.svg', '-blue.svg');
var shape = $scope.selected.node.shape;
var color = "#3f51b5"
if (shape === 'icon'){
color = $scope.selected.node.icon.color;
}
$scope.data.nodes.update({
id: $scope.selected.id,
label: label,
font: { color: color},
image: new_node_image,
})
// Mark the node is saved.
hotgenStates.update_saved_flags($scope.selected.id, true);
// Update depends on edges
var related_edges = hotgenStates.get_network().getConnectedEdges($scope.selected.id);
for ( var idx in related_edges){
var edge = $scope.data.edges.get(related_edges[idx]);
if (edge.from == $scope.selected.id && edge.arrows && edge.arrows.middle == true){
$scope.data.edges.remove(edge.id);
}
}
for (var idx in $scope.dependson){
$scope.data.edges.add({
from: $scope.selected.id,
to: $scope.dependson[idx],
arrows: {middle:true},
dashes: false,
color: '#448AFF',
});
}
// Mark edges connected from the node are saved and update style.
for (var idx in $scope.connectedoptions){
var connected_option = $scope.connectedoptions[idx];
for (var idx_edge in connected_option){
hotgenStates.update_saved_flags(connected_option[idx_edge].edge.id, true);
var color = "#3f51b5";
$scope.data.edges.update({
id: connected_option[idx_edge].edge.id,
dashes: false,
color: color,
})
}
}
return true;
};
$scope.resource_type = $scope.selected.resource_type.replace(/_/g, ':');
if ($scope.selected.id in hotgenStates.get_saved_resources()){
$scope.resource = hotgenStates.get_saved_resources()[$scope.selected.id].data;
} else{
$scope.resource = {}
}
if ($scope.selected.id in hotgenStates.get_saved_dependsons()){
$scope.dependson = hotgenStates.get_saved_dependsons()[$scope.selected.id];
} else{
$scope.dependson = []
}
// Add connected edge resource
$scope.get_connected_options = function(){
var related_edges = hotgenStates.get_network().getConnectedEdges($scope.selected.id);
var connected_options = {};
for (var idx in related_edges){
var edge = $scope.data.edges.get(related_edges[idx]);
if (edge.from != $scope.selected.id || (edge.arrows && edge.arrows.middle == true)){
continue;
}
var node = $scope.data.nodes.get(edge.to);
var edge_directions = hotgenGlobals.get_edge_directions();
if (! ($scope.selected.resource_type in edge_directions)){
continue;
}
var mapping = edge_directions[$scope.selected.resource_type];
if (!(node.title in mapping)){
continue;
}
var property = mapping[node.title].property;
if (!(property in connected_options)){
connected_options[property] = [];
}
connected_options[property].push({
value: hotgenUtils.get_resource_string(hotgenStates.get_label_by_uuid(node.id)),
id: node.id,
resource_type: node.title,
edge: edge
});
}
return connected_options;
}
$scope.connectedoptions = $scope.get_connected_options();
$scope.component = hotgenGlobals.get_resource_components()[$scope.selected.resource_type];
$scope.get_label = function(node_type){
return hotgenGlobals.get_node_labels()[node_type];
}
}
$scope.showTabDialog = function(){
$scope.dialogController.$inject = ['$scope', '$mdDialog', 'hotgenStates'];
$mdDialog.show({
controller: DialogController,
controller: $scope.dialogController,
controllerAs: 'ctrl',
templateUrl: basePath+'templates/modal_resource.html',
parent: angular.element(document.body),
@ -21,146 +160,13 @@
}, function(){
// hotgenNotify.show_error('dismiss a modal');
});
DialogController.$inject = ['$scope', '$mdDialog', 'hotgenStates'];
function DialogController($scope, $mdDialog, hotgenStates) {
$scope.delete_resource = function() {
var label = hotgenStates.get_selected().node.label;
hotgenStates.get_network().deleteSelected();
hotgenNotify.show_success(label + ' has been delete successfully.')
$mdDialog.cancel();
};
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.selected = hotgenStates.get_selected();
$scope.data = {
nodes: hotgenStates.get_nodes(),
edges: hotgenStates.get_edges(),
};
$scope.save = function() {
$mdDialog.hide();
hotgenStates.update_saved_resources($scope.selected.id, {
type: $scope.selected.resource_type,
data: angular.copy($scope.resource)
});
hotgenStates.update_saved_dependsons($scope.selected.id, $scope.dependson);
var label = hotgenStates.get_label_by_uuid($scope.selected.node.id);
var prop_label = $scope.get_label($scope.selected.resource_type);
if (prop_label && $scope.resource[prop_label]){
label = label + '(' + $scope.resource[prop_label]+')';
}
var new_node_image = $scope.data.nodes.get($scope.selected.id).image.replace('-gray.svg', '-blue.svg');
var shape = $scope.selected.node.shape;
var color = "#3f51b5"
if (shape === 'icon'){
color = $scope.selected.node.icon.color;
}
$scope.data.nodes.update({
id: $scope.selected.id,
label: label,
font: { color: color},
image: new_node_image,
})
// Mark the node is saved.
hotgenStates.update_saved_flags($scope.selected.id, true);
// Update depends on edges
var related_edges = hotgenStates.get_network().getConnectedEdges($scope.selected.id);
for ( var idx in related_edges){
var edge = $scope.data.edges.get(related_edges[idx]);
if (edge.from == $scope.selected.id && edge.arrows && edge.arrows.middle == true){
$scope.data.edges.remove(edge.id);
}
}
for (var idx in $scope.dependson){
$scope.data.edges.add({
from: $scope.selected.id,
to: $scope.dependson[idx],
arrows: {middle:true},
dashes: false,
color: '#448AFF',
});
}
// Mark edges connected from the node are saved and update style.
for (var idx in $scope.connectedoptions){
var connected_option = $scope.connectedoptions[idx];
for (var idx_edge in connected_option){
hotgenStates.update_saved_flags(connected_option[idx_edge].edge.id, true);
var color = "#3f51b5";
$scope.data.edges.update({
id: connected_option[idx_edge].edge.id,
dashes: false,
color: color,
})
}
}
};
$scope.resource_type = $scope.selected.resource_type.replace(/_/g, ':');
if ($scope.selected.id in hotgenStates.get_saved_resources()){
$scope.resource = hotgenStates.get_saved_resources()[$scope.selected.id].data;
} else{
$scope.resource = {}
}
if ($scope.selected.id in hotgenStates.get_saved_dependsons()){
$scope.dependson = hotgenStates.get_saved_dependsons()[$scope.selected.id];
} else{
$scope.dependson = []
}
// Add connected edge resource
$scope.get_connected_options = function(){
var related_edges = hotgenStates.get_network().getConnectedEdges($scope.selected.id);
var connected_options = {};
for (var idx in related_edges){
var edge = $scope.data.edges.get(related_edges[idx]);
if (edge.from != $scope.selected.id || (edge.arrows && edge.arrows.middle == true)){
continue;
}
var node = $scope.data.nodes.get(edge.to);
var edge_directions = hotgenGlobals.get_edge_directions();
if (! ($scope.selected.resource_type in edge_directions)){
continue;
}
var mapping = edge_directions[$scope.selected.resource_type];
if (!(node.title in mapping)){
continue;
}
var property = mapping[node.title].property;
if (!(property in connected_options)){
connected_options[property] = [];
}
connected_options[property].push({
value: hotgenUtils.get_resource_string(hotgenStates.get_label_by_uuid(node.id)),
id: node.id,
resource_type: node.title,
edge: edge
});
}
return connected_options;
}
$scope.connectedoptions = $scope.get_connected_options()
$scope.component = hotgenGlobals.get_resource_components()[$scope.selected.resource_type];
$scope.get_label = function(node_type){
return hotgenGlobals.get_node_labels()[node_type];
}
}
};
$scope.$on('handle_edit_node', function(event, args){
$scope.handle_edit_node = function(event, args){
hotgenNotify.show_info('Show details of resource ' + args.replace(/_/g, ':') +'.');
$scope.showTabDialog();
});
}
$scope.$on('handle_edit_node', $scope.handle_edit_node);
}]);
})();
})();

View File

@ -0,0 +1,278 @@
(function() {
'use strict';
describe('horizon.dashboard.project.heat_dashboard.template_generator.FormModalController', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var hotgenGlobals, hotgenStates, basePath;
beforeEach(inject(function($injector){
hotgenGlobals = $injector.get('hotgenGlobals');
hotgenStates = $injector.get('hotgenStates');
basePath = $injector.get('horizon.dashboard.project.heat_dashboard.template_generator.basePath');
}));
var $controller, controller, $scope, $rootScope, $mdDialog;
beforeEach(inject(function($injector){
$rootScope = $injector.get('$rootScope');
$mdDialog = $injector.get('$mdDialog');
}));
beforeEach(inject(function(_$controller_, $rootScope) {
$controller = _$controller_;
$scope = $rootScope.$new();
spyOn($scope, '$on');
spyOn($mdDialog, 'show');
spyOn($mdDialog, 'hide');
spyOn($mdDialog, 'cancel');
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.FormModalController',
{ $scope: $scope, $mdDialog: $mdDialog});
$mdDialog.show = jasmine.createSpy().and.callFake(function() {
return {
then: (function (callBack) {
callBack(true); //return the value to be assigned.
}, function(callBack){
callBack(false)}
)
}
});
$mdDialog.cancel = jasmine.createSpy().and.callFake(function() {
return function(callBack){callBack(true)};
});
}));
it('should exist', function(){
expect(controller).toBeDefined();
});
it('$scope.$on should be called', function(){
var event = $rootScope.$broadcast('handle_edit_node');
expect($scope.$on).toHaveBeenCalled();
});
it('$scope.handle_edit_node', function(){
var event = $rootScope.$broadcast('handle_edit_node');
spyOn($scope, 'showTabDialog');
$scope.handle_edit_node(event, 'OS__Project__ResourceType');
expect($scope.showTabDialog).toHaveBeenCalled();
});
it('show dialog with no parameters set.', function(){
$scope.showTabDialog();
$scope.$digest();
expect($mdDialog.show).toHaveBeenCalled();
});
it('cancel dialog', function(){
var node = {id: 'node_id', label: 'Node_1', title: 'NodeType_1'}
var to_node = {id: 'to_node_id', label: 'ToNode_1', title: 'ToType_1'}
var edge1 = {id: 'edge_id_1', from: 'node_id', to: 'to_node_id'}
var edge2 = {id: 'edge_id_2', from: 'from_node_id', to: 'node_id'}
hotgenStates.set_selected({
id: node.id,
node: node,
resource_type: node.title,
});
var network = {getConnectedEdges: function(data){
return [edge1.id, edge2.id];
}}
hotgenStates.set_network(network);
$scope.data.nodes.add(node);
$scope.data.edges.add(edge1);
$scope.data.edges.add(edge2);
$scope.dialogController($scope, $mdDialog, hotgenStates);
$scope.cancel();
expect($mdDialog.cancel).toHaveBeenCalled();
});
it('get label', function(){
var node = {id: 'node_id', label: 'Node_1', title: 'NodeType_1'}
var to_node = {id: 'to_node_id', label: 'ToNode_1', title: 'ToType_1'}
var edge1 = {id: 'edge_id_1', from: 'node_id', to: 'to_node_id'}
var edge2 = {id: 'edge_id_2', from: 'from_node_id', to: 'node_id'}
hotgenStates.set_selected({
id: node.id,
node: node,
resource_type: node.title,
});
var network = {getConnectedEdges: function(data){
return [edge1.id, edge2.id];
}}
hotgenStates.set_network(network);
$scope.data.nodes.add(node);
$scope.data.edges.add(edge1);
$scope.data.edges.add(edge2);
hotgenGlobals.update_node_labels(node.title, node.label)
$scope.dialogController($scope, $mdDialog, hotgenStates);
var nodelabel = $scope.get_label('NodeType_1');
expect(nodelabel).toEqual(node.label);
});
it('delete resource', function(){
var node = {id: 'node_id', label: 'Node_1', title: 'NodeType_1'}
var to_node = {id: 'to_node_id', label: 'ToNode_1', title: 'ToType_1'}
var edge1 = {id: 'edge_id_1', from: 'node_id', to: 'to_node_id'}
var edge2 = {id: 'edge_id_2', from: 'from_node_id', to: 'node_id'}
hotgenStates.set_selected({
id: node.id,
node: node,
resource_type: node.title,
});
var network = {
deleteSelected: function(){
return true;
},
getConnectedEdges: function(data){
return [edge1.id, edge2.id];
}
};
hotgenStates.set_network(network);
$scope.data.nodes.add(node);
$scope.data.edges.add(edge1);
$scope.data.edges.add(edge2);
$scope.dialogController($scope, $mdDialog, hotgenStates);
$scope.delete_resource();
expect($mdDialog.cancel).toHaveBeenCalled();
});
it('save without depends_on', function(){
var node = {id: 'node_id', label: 'Node_1', title: 'NodeType_1', image: 'image-gray.svg'}
hotgenStates.set_selected({
id: 'node_id',
node: node,
resource_type: 'NodeType_1',
});
var network = {
deleteSelected: function(){
return true;
},
getConnectedEdges: function(data){
return [];
}
};
$scope.data.nodes.add(node);
hotgenGlobals.update_node_labels(node.id, node.label);
hotgenStates.set_incremented_label(node.id, node.label);
hotgenStates.set_network(network);
$scope.dialogController($scope, $mdDialog, hotgenStates);
$scope.dependson = [];
var returnValue = $scope.save();
expect($mdDialog.hide).toHaveBeenCalled();
expect(returnValue).toEqual(true);
});
it('save with depends_on', function(){
var node = {id: 'node_id', label: 'Node_1', title: 'NodeType_1', icon: {color: '#000'},
shape: 'icon', image: 'image-gray.svg'}
var depend_node = {id: 'depend_node_id', label: 'Node_2', title: 'NodeType_2'}
var connected_node = {id: 'conn_node_id', label: 'Node_3', title: 'NodeType_3'}
var connected_node2 = {id: 'conn_node2_id', label: 'Node_4', title: 'NodeType_3'}
var edge = { id: 'edge_id', from: node.id, to: connected_node.id,
resource_type: {from: node.title, to: connected_node.title},
from_node: node, to_node: connected_node};
var edge2 = { id: 'edge2_id', from: node.id, to: connected_node2.id,
resource_type: {from: node.title, to: connected_node2.title},
from_node: node, to_node: connected_node2};
var depend_edge = {id: 'depend_edge_id', from: node.id, to: depend_node.id,
resource_type: {from: node.title, to: depend_node.title},
from_node: node, to_node: depend_node, arrows: {middle: true}};
$scope.data.nodes.add(node);
$scope.data.nodes.add(depend_node);
$scope.data.nodes.add(connected_node);
$scope.data.nodes.add(connected_node2);
$scope.data.edges.add(edge);
$scope.data.edges.add(edge2);
$scope.data.edges.add(depend_edge);
hotgenGlobals.update_node_labels(node.title, 'name');
hotgenGlobals.update_edge_directions(node.title, {'NodeType_3': {property: 'name'}});
hotgenStates.update_saved_resources(node.id, {type: node.title, data: {name: node.label}})
hotgenStates.set_incremented_label(node.id, node.label);
hotgenStates.update_saved_dependsons(node.title, [depend_node.id]);
hotgenStates.update_saved_dependsons(node.id, [depend_node.id]);
hotgenStates.set_selected({
id: 'node_id',
node: node,
resource_type: 'NodeType_1',
});
var network = {
deleteSelected: function(){
return true;
},
getConnectedEdges: function(data){
return [edge.id, edge2.id, depend_edge.id,];
}
};
hotgenStates.set_network(network);
$scope.dialogController($scope, $mdDialog, hotgenStates);
$scope.dependson = [depend_node.id];
var returnValue = $scope.save();
expect($mdDialog.hide).toHaveBeenCalled();
expect(returnValue).toEqual(true);
});
it('save with trivial cases', function(){
var node = {id: 'node_id', label: 'Node_1', title: 'NodeType_1', icon: {color: '#000'},
shape: 'icon', image: 'image-gray.svg'}
var depend_node = {id: 'depend_node_id', label: 'Node_2', title: 'NodeType_2'}
var connected_node = {id: 'conn_node_id', label: 'Node_3', title: 'NodeType_3'}
var edge = { id: 'edge_id', from: node.id, to: connected_node.id,
resource_type: {from: node.title, to: connected_node.title},
from_node: node, to_node: connected_node};
var depend_edge = {id: 'depend_edge_id', from: node.id, to: depend_node.id,
resource_type: {from: node.title, to: depend_node.title},
from_node: node, to_node: depend_node, arrows: {middle: true}};
$scope.data.nodes.add(node);
$scope.data.nodes.add(depend_node);
$scope.data.nodes.add(connected_node);
$scope.data.edges.add(edge);
$scope.data.edges.add(depend_edge);
hotgenGlobals.update_node_labels(node.title, 'name');
hotgenGlobals.update_edge_directions(node.title, {'NodeType_2': {}});
hotgenStates.update_saved_resources(node.id, {type: node.title, data: {name: node.label}})
hotgenStates.set_incremented_label(node.id, node.label);
hotgenStates.update_saved_dependsons(node.title, [depend_node.id]);
hotgenStates.update_saved_dependsons(node.id, [depend_node.id]);
hotgenStates.set_selected({
id: node.id,
node: node,
resource_type: node.title,
});
var network = {
deleteSelected: function(){
return true;
},
getConnectedEdges: function(data){
return [edge.id, depend_edge.id];
}
};
hotgenStates.set_network(network);
$scope.dialogController($scope, $mdDialog, hotgenStates);
$scope.dependson = [depend_node.id];
var returnValue = $scope.save();
expect($mdDialog.hide).toHaveBeenCalled();
expect(returnValue).toEqual(true);
});
});
})();

View File

@ -2,163 +2,166 @@
'use strict';
angular.module('horizon.dashboard.project.heat_dashboard.template_generator')
.controller('horizon.dashboard.project.heat_dashboard.template_generator.TempModalCtrl', ['$scope',
.controller('horizon.dashboard.project.heat_dashboard.template_generator.TempModalController', ['$scope',
'$mdDialog', 'hotgenNotify', 'hotgenUtils', 'hotgenStates', 'hotgenGlobals',
'horizon.dashboard.project.heat_dashboard.template_generator.basePath',
function($scope, $mdDialog, hotgenNotify, hotgenUtils, hotgenStates, hotgenGlobals, basePath){
$scope.basePath = basePath;
$scope.dialogController = function ($scope, $mdDialog, hotgenStates, hotgenGlobals, hotgenNotify) {
$scope.all_saved = false;
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.download = function() {
// TODO: jump to stack creation page, or send to heat api.
// Temporarily Download
var today = new Date();
var filename = "template-"+today.toISOString();
var blob = new Blob([$scope.template_contents], {type: "text/plain;charset=utf-8"});
saveAs(blob, filename+".yaml.txt");
hotgenNotify.show_success('Template is downloaded.');
};
$scope.save = function() {
hotgenNotify.show_warning('Not implemented yet. To submit to create a stack.')
$mdDialog.cancel();
};
$scope.extract_properties = function(resource_data){
for (var property in resource_data){
var func = null;
switch (property){
case 'description':
case 'public_key':
func = hotgenUtils.escape_characters;
break;
case 'metadata':
case 'scheduler_hints':
case 'value_specs':
func = hotgenUtils.extract_keyvalue;
break;
case 'allocation_pools':
case 'allowed_address_pairs':
case 'block_device_mapping':
case 'block_device_mapping_v2':
case 'fixed_ips':
case 'host_routes':
case 'personality':
case 'rules':
func = hotgenUtils.extract_list_of_keyvalue;
break;
case 'dns_nameservers':
case 'dhcp_agent_ids':
case 'tags':
func = hotgenUtils.extract_list;
break;
case 'resource_def':
func = hotgenUtils.extract_resource_def;
break;
default:
break;
}
if ( func != null){
resource_data[property] = func(resource_data[property]);
}
hotgenUtils.strip_property(resource_data, property);
}
return resource_data;
}
$scope.warning = "Warning: Some resources remain unsaved."
$scope.generate = function(){
// Generate `resources` & `outputs` section
var resource_root = {};
var outputs_root = {};
if( hotgenStates.get_saved_flags_length() == 0 || hotgenStates.get_saved_resources_length() == 0){
$scope.all_saved = false;
$scope.warning = "Warning: Cannot generate, no resource has been saved.";
return '';
}
$scope.all_saved = hotgenStates.is_all_saved();
$scope.saved_resources = hotgenStates.get_saved_resources();
$scope.data = {
nodes: hotgenStates.get_nodes(),
}
var depends_ons = hotgenStates.get_saved_dependsons();
for (var idkey in $scope.saved_resources){
// Generate `resources` section
var resource_type = $scope.saved_resources[idkey].type;
var resource_name = hotgenStates.get_label_by_uuid(idkey);
var copy_data = angular.copy($scope.saved_resources[idkey].data)
var properties = $scope.extract_properties(copy_data);
resource_root[resource_name] = {
type: resource_type.replace(/_/g, ':'),
};
if (Object.keys(properties).length > 0){
resource_root[resource_name]["properties"] = properties;
}
if (idkey in depends_ons){
var depends_ids = angular.copy(depends_ons[idkey]);
if (depends_ons[idkey].length > 0){
resource_root[resource_name]['depends_on'] = [];
for (var idx in depends_ids){
resource_root[resource_name]['depends_on'].push(hotgenStates.get_label_by_uuid(depends_ids[idx]));
}
}
}
// Generate `outputs` section
var output_detail = hotgenGlobals.get_resource_outputs(resource_type);
for (var idx in output_detail){
var output_key = resource_name + '_' + output_detail[idx].property;
outputs_root[output_key] = {
description: 'The ' + output_detail[idx].property + ' of ' + resource_name +'.',
value: '{ get_attr: ['+resource_name+', '+output_detail[idx].property+'] }',
};
}
}
var today = new Date();
var template_version = hotgenGlobals.get_template_version().split('.')[1]
var template_root = {
heat_template_version: template_version,
description: 'version 2017-09-01 created by HOT Generator at '+ today.toUTCString() + '.',
resources: resource_root,
}
if (Object.keys(outputs_root).length > 0){
template_root['outputs'] = outputs_root
}
var json_string = JSON.stringify(template_root);
return json2yaml(json_string);
}
$scope.template_contents = $scope.generate();
$scope.template = {
title: 'Template',
content: $scope.template_contents,
};
}
$scope.open = function(){
if (hotgenGlobals.get_template_version() == null){
hotgenNotify.show_error('Please select template version at first.');
return;
}
$scope.dialogController.$inject = ['$scope', '$mdDialog', 'hotgenStates', 'hotgenGlobals', 'hotgenNotify'];
$mdDialog.show({
parent: angular.element(document.body),
clickOutsideToClose:true,
templateUrl: basePath+'templates/modal_template.html',
controller: DialogController,
controller: $scope.dialogController,
}).then(function(){
;
// ;
}, function(){
;
// ;
});
};
DialogController.$inject = ['$scope', '$mdDialog', 'hotgenStates', 'hotgenGlobals', 'hotgenNotify'];
function DialogController($scope, $mdDialog, hotgenStates, hotgenGlobals, hotgenNotify) {
$scope.all_saved = false;
$scope.cancel = function() {
$mdDialog.cancel();
};
$scope.download = function() {
// TODO: jump to stack creation page, or send to heat api.
// Temporarily Download
var today = new Date();
var filename = "template-"+today.toISOString();
var blob = new Blob([$scope.template_contents], {type: "text/plain;charset=utf-8"});
saveAs(blob, filename+".yaml.txt");
hotgenNotify.show_success('Template is downloaded.');
};
$scope.save = function() {
hotgenNotify.show_warning('Not implemented yet. To submit to create a stack.')
$mdDialog.cancel();
};
$scope.extract_properties = function(resource_data){
for (var property in resource_data){
var func = null;
switch (property){
case 'description':
case 'public_key':
func = hotgenUtils.escape_characters;
break;
case 'metadata':
case 'scheduler_hints':
case 'value_specs':
func = hotgenUtils.extract_keyvalue;
break;
case 'allocation_pools':
case 'allowed_address_pairs':
case 'block_device_mapping':
case 'block_device_mapping_v2':
case 'fixed_ips':
case 'host_routes':
case 'personality':
case 'rules':
func = hotgenUtils.extract_list_of_keyvalue;
break;
case 'dns_nameservers':
case 'dhcp_agent_ids':
case 'tags':
func = hotgenUtils.extract_list;
break;
case 'resource_def':
func = hotgenUtils.extract_resource_def;
break;
default:
break;
}
if ( func != null){
resource_data[property] = func(resource_data[property]);
}
hotgenUtils.strip_property(resource_data, property);
}
return resource_data;
}
$scope.generate = function(){
// Generate `resources` & `outputs` section
var resource_root = {};
var outputs_root = {};
if( hotgenStates.get_saved_flags_length() == 0 || hotgenStates.get_saved_resources_length() == 0){
$scope.all_saved = false;
return 'Cannot generate, no resource has been saved.';
}
$scope.all_saved = hotgenStates.is_all_saved();
$scope.saved_resources = hotgenStates.get_saved_resources();
$scope.data = {
nodes: hotgenStates.get_nodes(),
}
var depends_ons = hotgenStates.get_saved_dependsons();
for (var idkey in $scope.saved_resources){
// Generate `resources` section
var resource_type = $scope.saved_resources[idkey].type;
var resource_name = hotgenStates.get_label_by_uuid(idkey);
var copy_data = angular.copy($scope.saved_resources[idkey].data)
var properties = $scope.extract_properties(copy_data);
resource_root[resource_name] = {
type: resource_type.replace(/_/g, ':'),
};
if (Object.keys(properties).length > 0){
resource_root[resource_name]["properties"] = properties;
}
if (idkey in depends_ons){
var depends_ids = angular.copy(depends_ons[idkey]);
if (depends_ons[idkey].length > 0){
resource_root[resource_name]['depends_on'] = [];
for (var idx in depends_ids){
resource_root[resource_name]['depends_on'].push(hotgenStates.get_label_by_uuid(depends_ids[idx]));
}
}
}
// Generate `outputs` section
var output_detail = hotgenGlobals.get_resource_outputs(resource_type);
for (var idx in output_detail){
var output_key = resource_name + '_' + output_detail[idx].property;
outputs_root[output_key] = {
description: 'The ' + output_detail[idx].property + ' of ' + resource_name +'.',
value: '{ get_attr: ['+resource_name+', '+output_detail[idx].property+'] }',
};
}
}
var today = new Date();
var template_version = hotgenGlobals.get_template_version().split('.')[1]
var template_root = {
heat_template_version: template_version,
description: 'version 2017-09-01 created by HOT Generator at '+ today.toUTCString() + '.',
resources: resource_root,
}
if (Object.keys(outputs_root).length > 0){
template_root['outputs'] = outputs_root
}
var json_string = JSON.stringify(template_root);
return json2yaml(json_string);
}
$scope.template_contents = $scope.generate();
$scope.template = {
title: 'Template',
content: $scope.template_contents,
};
}
}]);
})();

View File

@ -0,0 +1,159 @@
(function() {
'use strict';
describe('horizon.dashboard.project.heat_dashboard.template_generator.TempModalController', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var hotgenGlobals, hotgenStates, hotgenNotify, basePath;
beforeEach(inject(function($injector){
hotgenGlobals = $injector.get('hotgenGlobals');
hotgenStates = $injector.get('hotgenStates');
hotgenNotify = $injector.get('hotgenNotify');
basePath = $injector.get('horizon.dashboard.project.heat_dashboard.template_generator.basePath');
}));
var $controller, controller, $scope, $rootScope, $mdDialog;
beforeEach(inject(function($injector){
$rootScope = $injector.get('$rootScope');
$mdDialog = $injector.get('$mdDialog');
}));
beforeEach(inject(function(_$controller_, $rootScope) {
$controller = _$controller_;
$scope = $rootScope.$new();
spyOn($mdDialog, 'show');
spyOn($mdDialog, 'cancel');
spyOn(hotgenNotify, 'show_success');
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.TempModalController',
{ $scope: $scope, $mdDialog: $mdDialog});
$mdDialog.show = jasmine.createSpy().and.callFake(function() {
return {
then: (function (callBack) {
callBack(true); //return the value to be assigned.
}, function(callBack){
callBack(false)}
)
}
});
$mdDialog.cancel = jasmine.createSpy().and.callFake(function() {
return function(callBack){callBack(true)};
});
}));
it('should exist', function(){
expect(controller).toBeDefined();
expect($mdDialog).toBeDefined();
});
it('$scope.open', function(){
$scope.open();
expect($mdDialog.show).not.toHaveBeenCalled();
hotgenGlobals.set_template_version('2017-09-01.template');
$scope.open();
expect($mdDialog.show).toHaveBeenCalled();
});
it('$scope.dialogController', function(){
$scope.dialogController($scope, $mdDialog, hotgenStates, hotgenGlobals, hotgenNotify);
expect($scope.all_saved).toEqual(false);
});
it('$scope.dialogController $cancel', function(){
$scope.dialogController($scope, $mdDialog, hotgenStates, hotgenGlobals, hotgenNotify);
$scope.cancel();
expect($mdDialog.cancel).toHaveBeenCalled();
});
it('$scope.dialogController download', function(){
$scope.dialogController($scope, $mdDialog, hotgenStates, hotgenGlobals, hotgenNotify);
$scope.download();
expect(hotgenNotify.show_success).toHaveBeenCalled();
});
it('$scope.dialogController save', function(){
$scope.dialogController($scope, $mdDialog, hotgenStates, hotgenGlobals, hotgenNotify);
$scope.save();
expect($mdDialog.cancel).toHaveBeenCalled();
});
it('$scope.dialogController extract_properties', function(){
$scope.dialogController($scope, $mdDialog, hotgenStates, hotgenGlobals, hotgenNotify);
var to_extract = {
description: '', public_key: '',
metadata: '', scheduler_hints: '', value_specs: '',
allocation_pools: '', allowed_address_pairs: '', block_device_mapping: '',
block_device_mapping_v2: '', fixed_ips: '', host_routes: '',
personality: '',
rules: '', dns_nameservers: '', dhcp_agent_ids: '', tags: '',
resource_def: '',
others: ''
}
var resource_data = $scope.extract_properties(to_extract);
expect(Object.keys(resource_data).length).toEqual(2);
});
it('$scope.dialogController generate', function(){
$scope.dialogController($scope, $mdDialog, hotgenStates, hotgenGlobals, hotgenNotify);
hotgenStates.update_saved_resources('node_id', {
type: 'Node_Type',
data: { description: '', public_key: '',
metadata: '', scheduler_hints: '', value_specs: '',
allocation_pools: '', allowed_address_pairs: '', block_device_mapping: '',
block_device_mapping_v2: '', fixed_ips: '', host_routes: '',
personality: '',
rules: '', dns_nameservers: '', dhcp_agent_ids: '', tags: '',
resource_def: '',
others: ''}
});
hotgenStates.set_saved_flags({'node_id': true});
hotgenStates.update_saved_dependsons('node_id', ['depend_on_id']);
hotgenStates.set_incremented_label('depend_on_id', 'depend_on_label');
hotgenGlobals.set_resource_outputs('Node_Type', {'property': 'public_key'});
hotgenGlobals.set_template_version('2017-09-01.template');
var yamlstring = $scope.generate();
expect(yamlstring.length).toBeGreaterThan(0);
});
it('$scope.dialogController trivial generate', function(){
$scope.dialogController($scope, $mdDialog, hotgenStates, hotgenGlobals, hotgenNotify);
hotgenStates.update_saved_resources('node_id', {
type: 'Node_Type',
data: {metadata: ''}
});
hotgenStates.set_saved_flags({'node_id': true});
hotgenGlobals.set_template_version('2017-09-01.template');
var yamlstring = $scope.generate();
expect(yamlstring.length).toBeGreaterThan(0);
});
it('$scope.dialogController trivial dependson generate', function(){
$scope.dialogController($scope, $mdDialog, hotgenStates, hotgenGlobals, hotgenNotify);
hotgenStates.update_saved_resources('node_id', {
type: 'Node_Type',
data: {metadata: ''}
});
hotgenStates.set_saved_flags({'node_id': true});
hotgenStates.update_saved_dependsons('node_id', []);
hotgenGlobals.set_template_version('2017-09-01.template');
var yamlstring = $scope.generate();
expect(yamlstring.length).toBeGreaterThan(0);
});
});
})();

View File

@ -66,7 +66,7 @@
saved_dependsons = to_set;
}
var is_all_saved = function(){
return ! (false in Object.keys(saved_flags));
return(Object.values(saved_flags).indexOf(false) == -1);
};
var get_saved_flags_length = function(){
return Object.keys(saved_flags).length;

View File

@ -0,0 +1,123 @@
(function() {
'use strict';
describe('hotgen-utils.hotgenStates', function(){
beforeEach(module('hotgen-utils'));
var hotgenStates;
beforeEach(inject(function(_hotgenStates_){
hotgenStates = _hotgenStates_;
}));
it('should exist', function(){
expect(hotgenStates).toBeDefined();
});
it('check nodes and edges', function(){
expect(hotgenStates.get_nodes().length).toEqual(0);
expect(hotgenStates.get_edges().length).toEqual(0);
});
it('check network', function(){
expect(hotgenStates.get_network()).toEqual(null);
var networkMock = {};
hotgenStates.set_network(networkMock);
expect( hotgenStates.get_network().constructor).toEqual(Object);
});
it('check increment counter/labels', function(){
expect(Object.keys(hotgenStates.get_incremented_labels()).length).toEqual(0);
expect(Object.keys(hotgenStates.get_counters()).length).toEqual(0);
expect(hotgenStates.increment_counter('type1')).toEqual(1);
expect(hotgenStates.increment_counter('type1')).toEqual(2);
expect(hotgenStates.get_counter('type1')).toEqual(2);
hotgenStates.set_incremented_labels({});
hotgenStates.set_incremented_label('type1', 'type1_2');
expect(hotgenStates.get_label_by_uuid('type1')).toEqual('type1_2');
hotgenStates.set_counters({});
});
it('check saved_flags', function(){
expect(hotgenStates.get_saved_flags_length()).toEqual(0);
expect(hotgenStates.is_all_saved()).toEqual(true);
expect(Object.keys( hotgenStates.get_saved_flags()).length).toEqual(0);
hotgenStates.set_saved_flags({'flag1': true});
expect(hotgenStates.is_all_saved()).toEqual(true);
expect(hotgenStates.get_saved_flags_length()).toEqual(1);
expect(hotgenStates.get_saved_flags()['flag1']).toEqual(true);
hotgenStates.update_saved_flags('flag1', false);
expect(hotgenStates.is_all_saved()).toEqual(false);
expect(hotgenStates.get_saved_flags()['flag1']).toEqual(false);
expect(hotgenStates.get_saved_flags_length()).toEqual(1);
});
it('check dependsons', function(){
expect(Object.keys(hotgenStates.get_saved_dependsons()).length).toEqual(0);
hotgenStates.set_saved_dependsons({'type1': ['resource1', 'resource2']});
expect( hotgenStates.get_saved_dependsons()['type1'].length).toEqual(2);
hotgenStates.update_saved_dependsons('type2', ['resource3']);
expect( hotgenStates.get_saved_dependsons()['type2'].length).toEqual(1);
});
it('check saved resources', function(){
var returnValue = hotgenStates.get_saved_resources();
expect(Object.keys(returnValue).length).toEqual(0);
expect(hotgenStates.get_saved_resources_length()).toEqual(0);
hotgenStates.set_saved_resources({'resource_name': {'properties':{}}});
returnValue = hotgenStates.get_saved_resources();
expect(Object.keys(returnValue).length).toEqual(1);
expect(hotgenStates.get_saved_resources_length()).toEqual(1);
hotgenStates.update_saved_resources('resource_name', {'properties':{}});
hotgenStates.delete_saved_resources('resource_name');
returnValue = hotgenStates.get_saved_resources();
expect(Object.keys(returnValue).length).toEqual(0);
expect(hotgenStates.get_saved_resources_length()).toEqual(0);
});
it('check selected', function(){
var returnValue = hotgenStates.get_selected();
expect(Object.keys(returnValue).length).toEqual(0);
hotgenStates.set_selected({'nodes': {}});
expect(Object.keys(hotgenStates.get_selected()).length).toEqual(1);
});
it('check clear', function(){
hotgenStates.clear_states();
});
});
})();

View File

@ -0,0 +1,42 @@
(function () {
'use strict';
describe('horizon.dashboard.project.heat_dashboard.template_generator module', function () {
it('should be defined', function () {
expect(angular.module('horizon.dashboard.project.heat_dashboard.template_generator')).toBeDefined();
});
});
describe('horizon.dashboard.project.heat_dashboard.template_generator.basePath', function () {
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
it('should be defined and set correctly', inject([
'horizon.dashboard.project.heat_dashboard.template_generator.basePath', '$window',
function (basePath, $window) {
expect(basePath).toBeDefined();
expect(basePath).toBe($window.STATIC_URL + 'dashboard/project/heat_dashboard/template_generator/');
}])
);
});
describe('horizon.dashboard.project.heat_dashboard.template_generator $locationProvider config', function () {
var $locationProvider;
beforeEach(function () {
angular.module('locationProviderConfig', [])
.config(function(_$locationProvider_) {
$locationProvider= _$locationProvider_;
spyOn($locationProvider, 'html5Mode');
});
module('locationProviderConfig');
module('horizon.dashboard.project.heat_dashboard.template_generator');
inject();
});
it('should set html5 mode', function() {
expect($locationProvider.html5Mode)
.toHaveBeenCalledWith({ enabled: true, requireBase: false });
});
});
})();

View File

@ -14,42 +14,50 @@
});
var show_success = function(message) {
if ($rootScope.message_level < 2){
return;
return -1;
}
notify({
message: message,
classes: ['alert-success',],
duration: 3000,
}); };
});
return 0;
};
var show_error = function(message) {
if ($rootScope.message_level < 0){
return;
return -1;
}
notify({
message: message,
classes: ['alert-danger',],
// duration: 5000,
});};
});
return 0;
};
var show_info = function(message) {
if ($rootScope.message_level < 3){
return;
return -1;
}
notify({
message: message,
classes: ['alert-info',],
duration: 3000,
});};
});
return 0;
};
var show_warning = function(message) {
if ($rootScope.message_level < 1){
return;
return -1;
}
notify({
message: message,
classes: ['alert-warning',],
duration: 5000,
});};
});
return 0;
};
return {
show_success: show_success,
@ -72,13 +80,17 @@
$rootScope.$broadcast('handle_load_draft');
};
var broadcast_resources_loaded = function(){
$rootScope.$broadcast('handle_resources_loaded')
$rootScope.$broadcast('handle_resources_loaded');
};
var broadcast_update_template_version = function(){
$rootScope.$broadcast('update_template_version');
};
return {
broadcast_edit_node: broadcast_edit_node,
broadcast_edit_edge: broadcast_edit_edge,
broadcast_load_draft: broadcast_load_draft,
broadcast_resources_loaded: broadcast_resources_loaded,
broadcast_update_template_version: broadcast_update_template_version,
}
}])
.factory('hotgenUtils', function(){
@ -104,7 +116,7 @@
}
var escape_characters = function(value){
return '"'+value.replace(/\\/g, '\\\\')
.replace(/\"/g, '\\"')
.replace(/"/g, '\\"')
.replace(/\n/g, "\\n")+'"';
}
var extract_keyvalue = function(value){
@ -127,24 +139,26 @@
}
var extract_list_of_keyvalue = function(value_list){
if (value_list instanceof Array ){
for (var idx in value_list){
for (var idx=value_list.length-1; idx>=0; --idx){
if (Object.keys(value_list[idx]).length == 0){
value_list.splice(idx,1)
value_list.splice(idx, 1)
}
}
if (value_list.length == 0){
return null;
}
return value_list
}
if (value_list.length == 0){
return null;
}
return value_list
return null;
}
var extract_list = function(value_list){
if (value_list instanceof Array){
if (value_list.length == 0){
return null;
}
return value_list
}
return value_list
return null;
}
var extract_dicts = function check_dicts(value_dict){
for (var key in value_dict){
@ -160,7 +174,7 @@
}
}
var extract_array = function extract_array(value_list){
for (var idx in value_list){
for (var idx=value_list.length-1; idx>=0; --idx){
if (value_list[idx] == null || value_list[idx] == ''){
value_list.splice(idx, 1)
} else if (value_list[idx].constructor && value_list[idx].constructor == Object){
@ -216,4 +230,4 @@
})
})();
})();

View File

@ -0,0 +1,327 @@
(function() {
'use strict';
describe('hotgen-utils.hotgen-utils hotgenUUID', function(){
beforeEach(module('hotgen-utils'));
var hotgenUUID;
beforeEach(inject(function(_hotgenUUID_){
hotgenUUID = _hotgenUUID_;
}));
it('hotgenUUID should exist', function(){
expect(hotgenUUID).toBeDefined();
});
it('uuid length > 0', function(){
var returnValue = hotgenUUID.uuid();
expect(returnValue.length).toBeGreaterThan(0);
});
});
describe('hotgen-utils.hotgen-utils hotgenNotify', function(){
beforeEach(module('hotgen-utils'));
/* inject hotgenNotify */
var hotgenNotify;
beforeEach(inject(function(_hotgenNotify_){
hotgenNotify = _hotgenNotify_;
}));
/* inject rootScope */
var $rootScope;
beforeEach(inject(function(_$rootScope_) {
$rootScope = _$rootScope_;
}));
it('should exist', function(){
expect(hotgenNotify).toBeDefined();
});
it('should show success', function(){
$rootScope.message_level = 4;
var returnValue = hotgenNotify.show_success('success notify unit test!');
expect(returnValue).toEqual(0);
});
it('should not show success', function(){
$rootScope.message_level = 0;
var returnValue = hotgenNotify.show_success('success notify unit test!');
expect(returnValue).toEqual(-1);
});
it('should show error', function(){
$rootScope.message_level = 4;
var returnValue = hotgenNotify.show_error('fail notify unit test!');
expect(returnValue).toEqual(0);
});
it('should not show error', function(){
$rootScope.message_level = -1;
var returnValue = hotgenNotify.show_error('fail notify unit test!');
expect(returnValue).toEqual(-1);
});
it('should show info', function(){
$rootScope.message_level = 4;
var returnValue = hotgenNotify.show_info('info notify unit test!');
expect(returnValue).toEqual(0);
});
it('should not show info', function(){
$rootScope.message_level = 0;
var returnValue = hotgenNotify.show_info('info notify unit test!');
expect(returnValue).toEqual(-1);
});
it('should show warning', function(){
$rootScope.message_level = 4;
var returnValue = hotgenNotify.show_warning('warning notify unit test!');
expect(returnValue).toEqual(0);
});
it('should not show warning', function(){
$rootScope.message_level = 0;
var returnValue = hotgenNotify.show_warning('warning notify unit test!');
expect(returnValue).toEqual(-1);
});
});
describe('hotgen-utils.hotgen-utils hotgenMessage', function(){
beforeEach(module('hotgen-utils'));
var hotgenMessage;
beforeEach(inject(function(_hotgenMessage_){
hotgenMessage = _hotgenMessage_;
}));
/* inject rootScope */
var $rootScope;
beforeEach(inject(function(_$rootScope_) {
$rootScope = _$rootScope_;
spyOn($rootScope, '$broadcast');
}));
it('hotgenMessage should exist', function(){
expect(hotgenMessage).toBeDefined();
});
it('should call event handle_edit_node', function(){
hotgenMessage.broadcast_edit_node('note_type');
expect($rootScope.$broadcast).toHaveBeenCalledWith('handle_edit_node', 'note_type');
});
it('should call event handle_edit_edge', function(){
hotgenMessage.broadcast_edit_edge('from_type', 'to_type', 'from_id', 'to_id');
expect($rootScope.$broadcast).toHaveBeenCalledWith('handle_edit_edge', {
'from_type': 'from_type', 'to_type': 'to_type',
'from_id': 'from_id', 'to_id': 'to_id',
});
});
it('should call event handle_load_draft', function(){
hotgenMessage.broadcast_load_draft('note_type');
expect($rootScope.$broadcast).toHaveBeenCalledWith('handle_load_draft');
});
it('should call event handle_resources_loaded', function(){
hotgenMessage.broadcast_resources_loaded();
expect($rootScope.$broadcast).toHaveBeenCalledWith('handle_resources_loaded');
});
it('should call event update_template_version', function(){
hotgenMessage.broadcast_update_template_version();
expect($rootScope.$broadcast).toHaveBeenCalledWith('update_template_version');
});
});
describe('hotgen-utils.hotgen-utils hotgenUtils', function(){
beforeEach(module('hotgen-utils'));
var hotgenUtils;
beforeEach(inject(function(_hotgenUtils_){
hotgenUtils = _hotgenUtils_;
}));
it('hotgenUtils should exist', function(){
expect(hotgenUtils).toBeDefined();
});
it('should return string contains get_resource', function(){
var returnValue = hotgenUtils.get_resource_string('identity');
expect(returnValue).toEqual('{ get_resource: identity }');
});
it('should filter elements', function(){
var property = 'name';
var array = ['ignore me', 1, '{ get_resource: find me }',
{'name': '{ get_resource: find me too }'},
{'no name': 'ignore me'}];
var returnValue = hotgenUtils.filter_and_return_get_resource_element(array, property);
expect(returnValue.length).toEqual(2);
});
it('should escape characters', function(){
var returnValue = hotgenUtils.escape_characters('replace " and \\ and \n ');
expect(returnValue).toEqual('"replace \\" and \\\\ and \\n "');
});
it('should extrace keyvalue', function(){
var keyvalue = [{'key': 'key1', 'value': 'value1'},
{'key': 'key2', 'value': 'value2'}];
var returnValue = hotgenUtils.extract_keyvalue(keyvalue);
expect(returnValue['key1']).toEqual('value1');
expect(returnValue['key2']).toEqual('value2');
keyvalue = [{}, {}];
returnValue = hotgenUtils.extract_keyvalue(keyvalue);
expect(returnValue).toEqual(null);
keyvalue = '';
returnValue = hotgenUtils.extract_keyvalue(keyvalue);
expect(returnValue).toEqual(null);
keyvalue = [''];
returnValue = hotgenUtils.extract_keyvalue(keyvalue);
expect(returnValue).toEqual(null);
});
it('should extract list of keyvalue', function(){
var keyvalue = [];
var returnValue = hotgenUtils.extract_list_of_keyvalue(keyvalue);
expect(returnValue).toEqual(null);
keyvalue = 1;
returnValue = hotgenUtils.extract_list_of_keyvalue(keyvalue);
expect(returnValue).toEqual(null);
keyvalue = [{'destination': 'destination', 'nexthop': 'nexthop'}, {}];
returnValue = hotgenUtils.extract_list_of_keyvalue(keyvalue);
expect(returnValue.length).toEqual(1);
keyvalue = [{}, {}];
returnValue = hotgenUtils.extract_list_of_keyvalue(keyvalue);
expect(returnValue).toEqual(null);
});
it('should extract list', function(){
var keyvalue = [];
var returnValue = hotgenUtils.extract_list(keyvalue);
expect(returnValue).toEqual(null);
keyvalue = 1;
returnValue = hotgenUtils.extract_list(keyvalue);
expect(returnValue).toEqual(null);
keyvalue = ['keep me', 'keep me too'];
returnValue = hotgenUtils.extract_list(keyvalue);
expect(returnValue.length).toEqual(2);
});
it('should extract dicts', function(){
var keyvalue = {'discard me': '', 'discard me too': null};
var returnValue = hotgenUtils.extract_dicts(keyvalue);
expect(Object.keys(returnValue).length).toEqual(0);
keyvalue = {'keep me': [], 'keep me too': 'me'};
returnValue = hotgenUtils.extract_dicts(keyvalue);
expect(Object.keys(returnValue).length).toEqual(2);
});
it('should strip_property', function(){
var keyvalue = {'property': {'discard me': '', 'discard me too': null}};
hotgenUtils.strip_property(keyvalue, 'property');
expect(Object.keys(keyvalue).length).toEqual(0);
keyvalue = {'property': {'keep me': [], 'keep me too': 'me'}};
hotgenUtils.strip_property(keyvalue, 'property');
expect(Object.keys(keyvalue).length).toEqual(1);
keyvalue = {'property': {'keep me': [{}, []], 'keep me too': 'me'}};
hotgenUtils.strip_property(keyvalue, 'property');
expect(Object.keys(keyvalue).length).toEqual(1);
expect(Object.keys(keyvalue['property']).length).toEqual(1);
keyvalue = {'property': [null, '', {}, [] ]};
hotgenUtils.strip_property(keyvalue, 'property');
expect(Object.keys(keyvalue).length).toEqual(0);
keyvalue = {'property': [1, 2, {'keep me': 3}, [4, 5, 6]]};
hotgenUtils.strip_property(keyvalue, 'property');
expect(Object.keys(keyvalue).length).toEqual(1);
expect(Object.keys(keyvalue['property']).length).toEqual(4);
keyvalue = {'property': [ ['', ''], [[[]]] ]};
hotgenUtils.strip_property(keyvalue, 'property');
expect(Object.keys(keyvalue).length).toEqual(0);
});
it('should extract resource_def', function(){
var keyvalue = {'properties': [{'key': 'k1', 'value': 'v1'}],
'metadata': [{'key': 'k2', 'value': 'v2'}],
'type': 'some file'};
var returnValue = hotgenUtils.extract_resource_def(keyvalue);
expect(returnValue.properties['k1']).toEqual('v1');
expect(returnValue.metadata['k2']).toEqual('v2');
var keyvalue = {'type': 'some file'};
var returnValue = hotgenUtils.extract_resource_def(keyvalue);
expect(returnValue.type).toEqual('some file');
});
});
})();

View File

@ -2,7 +2,7 @@
'use strict';
angular.module('horizon.dashboard.project.heat_dashboard.template_generator')
.controller('horizon.dashboard.project.heat_dashboard.template_generator.VisCtrl',
.controller('horizon.dashboard.project.heat_dashboard.template_generator.VisController',
['$scope', '$rootScope', 'hotgenNotify', 'hotgenMessage', 'hotgenGlobals', 'hotgenStates',
'horizon.dashboard.project.heat_dashboard.template_generator.basePath',
function($scope, $rootScope, hotgenNotify, hotgenMessage, hotgenGlobals, hotgenStates, basePath) {
@ -127,6 +127,7 @@
$scope.click = function(params){
if (params.nodes.length > 0){
$scope.network.disableEditMode();
var selected_id = params.nodes[0];
var selected_node = $scope.data.nodes.get(selected_id);
var selected_type = selected_node.title
@ -136,9 +137,9 @@
id: selected_id,
node: selected_node,
}) ;
hotgenMessage.broadcast_edit_node(selected_type);
} else if (params.edges.length > 0){
$scope.network.disableEditMode();
var selected_id = params.edges[0];
var selected_edge = $scope.data.edges.get(selected_id);
var from_node = $scope.data.nodes.get(selected_edge.from);
@ -154,7 +155,7 @@
});
hotgenMessage.broadcast_edit_edge(from_node.title, to_node.title, from_node.id, to_node.id);
} else {
;
// ;
}
};
@ -199,7 +200,7 @@
$scope.validate_edge = function(data){
if (data.from == data.to ){
hotgenNotify.show_error("The resource cannot be connected with itself.");
// hotgenNotify.show_warning("");
return false;
}
var from_node = $scope.get_node(data.from);

View File

@ -0,0 +1,203 @@
(function() {
'use strict';
describe('horizon.dashboard.project.heat_dashboard.template_generator.VisController', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
var $controller, controller, $scope, $rootScope, hotgenGlobals, hotgenStates;
beforeEach(inject(function($injector){
hotgenGlobals = $injector.get('hotgenGlobals');
hotgenStates = $injector.get('hotgenStates');
$rootScope = $injector.get('$rootScope');
spyOn($rootScope, '$broadcast');
}));
beforeEach(inject(function(_$controller_, $rootScope) {
$controller = _$controller_;
$scope = $rootScope.$new();
controller = $controller('horizon.dashboard.project.heat_dashboard.template_generator.VisController', { $scope: $scope,});
}));
it('should exist', function(){
expect(controller).toBeDefined();
});
it('check scope parameters', function(){
expect($scope.data.nodes.length).toEqual(0);
expect($scope.data.edges.length).toEqual(0);
expect($scope.options.autoResize).toEqual(true);
});
it('check $scope.get_node found', function(){
$scope.data.nodes.add({id: 'from_id'});
var returnValue = $scope.get_node('from_id');
expect(returnValue.id).toEqual('from_id');
});
it('check validate edge: invalid same node.', function(){
var data = {from: 'from_id', to: 'from_id'};
var returnValue = $scope.validate_edge(data);
expect(returnValue).toEqual(false);
});
it('check validate edge: connection allowed/ not allowed.', function(){
$scope.data.nodes.add({id: 'from_id', title: 'from_type'});
$scope.data.nodes.add({id: 'to_id', title: 'to_type'});
hotgenGlobals.update_edge_directions('from', {to: {}});
var data = {from: 'from_id', to: 'to_id'};
expect($scope.validate_edge(data)).toEqual(false);
hotgenGlobals.update_edge_directions('from_type', {to: {}});
expect($scope.validate_edge(data)).toEqual(false);
$scope.data.nodes.add({id: 'another_to_id', title: 'to_type'});
$scope.data.nodes.add({id: 'third_to_id', title: 'from_type'});
$scope.network = {getConnectedNodes: function(data){
return ['another_to_id', 'third_to_id'];
}}
hotgenGlobals.update_edge_directions('from_type', {to_type: {limit: 0}});
expect($scope.validate_edge(data)).toEqual(false);
hotgenGlobals.update_edge_directions('from_type', {to_type: {limit: 10, lonely: true}});
expect($scope.validate_edge(data)).toEqual(false);
hotgenGlobals.update_edge_directions('from_type', {to_type: {limit: 10, lonely: false, occupied: true}});
expect($scope.validate_edge(data)).toEqual(false);
hotgenGlobals.update_edge_directions('from_type', {to_type: {limit: 10, lonely: false, occupied: false}});
expect($scope.validate_edge(data)).toEqual(true);
$scope.data.nodes.update({id: 'third_to_id', title: 'another_type'});
hotgenGlobals.update_edge_directions('from_type', {to_type: {limit: 10, lonely: false, occupied: true}});
expect($scope.validate_edge(data)).toEqual(true);
});
it('manipulation.addEdge: valid to add edge', function(){
var addEdgeFunction = $scope.options.manipulation.addEdge;
var data = {from: 'from_id', to: 'to_id'};
var mockCallbackFunction = jasmine.createSpy().and.callFake(function() {return function(){}})
spyOn($scope, 'validate_edge').and.callFake(function(){return true});
addEdgeFunction(data, mockCallbackFunction);
expect(mockCallbackFunction).toHaveBeenCalledWith(data);
});
it('manipulation.addEdge: invalid to add edge', function(){
var addEdgeFunction = $scope.options.manipulation.addEdge;
var data = {from: 'from_id', to: 'to_id'};
var mockCallbackFunction = jasmine.createSpy().and.callFake(function() {return function(){}})
spyOn($scope, 'validate_edge').and.callFake(function(){return false});
addEdgeFunction(data, mockCallbackFunction);
expect(mockCallbackFunction).toHaveBeenCalledWith(null);
});
it('manipulation.deleteNode', function(){
var deleteNodeFunction = $scope.options.manipulation.deleteNode;
var data = {nodes: ['node_id'], edges:['edge_id']}
var mockCallbackFunction = jasmine.createSpy().and.callFake(function() {return function(){}})
deleteNodeFunction(data, mockCallbackFunction);
expect(mockCallbackFunction).toHaveBeenCalledWith(data);
});
it('manipulation.deleteEdge', function(){
$scope.data.nodes.add({id: 'from_id', title: 'from_type'});
$scope.data.nodes.add({id: 'to_id', title: 'to_type'});
$scope.data.edges.add({id: 'edge_id', from: 'from_id', to: 'to_id'});
var deleteEdgeFunction = $scope.options.manipulation.deleteEdge;
var data = {edges:['edge_id']}
var mockCallbackFunction = jasmine.createSpy().and.callFake(function() {return function(){}})
deleteEdgeFunction(data, mockCallbackFunction);
expect(mockCallbackFunction).toHaveBeenCalledWith(data);
});
it('click nothing', function(){
var param = {edges: [], nodes: []}
$scope.click(param);
expect($rootScope.$broadcast).not.toHaveBeenCalled();
});
it('click to show node dialog', function(){
$scope.data.nodes.add({id: 'from_id', title: 'from_type'});
var param = {edges: [], nodes: ['from_id']}
$scope.network = {disableEditMode: function(data){}}
$scope.click(param);
expect($rootScope.$broadcast).toHaveBeenCalledWith('handle_edit_node', 'from_type');
});
it('click to show edge dialog', function(){
$scope.data.nodes.add({id: 'from_id', title: 'from_type'});
$scope.data.nodes.add({id: 'to_id', title: 'to_type'});
$scope.data.edges.add({id: 'edge_id', from: 'from_id', to: 'to_id'});
var param = {edges:['edge_id'], nodes:[]}
$scope.network = {disableEditMode: function(data){}}
$scope.click(param);
var broadcast_param = {
from_type: 'from_type', to_type: 'to_type',
from_id: 'from_id', to_id: 'to_id',
};
expect($rootScope.$broadcast).toHaveBeenCalledWith('handle_edit_edge', broadcast_param);
});
it('events on load', function(){
var network = {}
spyOn(hotgenStates, 'set_network');
var onloadFunction = $scope.events.onload;
onloadFunction(network);
expect(hotgenStates.set_network).toHaveBeenCalledWith(network);
});
it('get_added_edge_id: find the extra item', function(){
var old_ids = [1 ,2 ,3, 4];
var new_ids = [1, 2, 5, 3, 4];
var find = $scope.get_added_edge_id(old_ids, new_ids);
expect(find).toEqual(5);
});
it('get mapping', function(){
hotgenGlobals.update_edge_directions('from_type', {to_type: {limit: 10}});
expect($scope.get_mapping('from_type', 'to_type').limit).toEqual(10);
expect($scope.get_mapping('from_type', 'to')).toEqual(false);
expect($scope.get_mapping('from', 'to')).toEqual(false);
});
it('get modal: found/not found', function(){
hotgenGlobals.update_edge_directions('from_type', {to_type: {limit: 10, modal: 'modal'}});
$scope.data.nodes.add({id: 'from_id', title: 'from_type'});
$scope.data.nodes.add({id: 'to_id', title: 'to_type'});
$scope.data.nodes.add({id: 'from', title: 'from'});
expect($scope.get_modal({from: 'from_id', to: 'to_id'})).toEqual('modal');
expect($scope.get_modal({from: 'from', to: 'to_id'})).toEqual(undefined);
})
});
})();

View File

@ -0,0 +1,83 @@
(function() {
'use strict';
describe('component os-cinder-volume', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
$scope.resource = {};
$scope.dependson = [];
$scope.connectedoptions = [];
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-cinder-volume volume="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-cinder-volume>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with resource set', function() {
$scope.resource = {metadata: [], scheduler_hints:[]};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-cinder-volume volume="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-cinder-volume>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
it('metadata should be successfully added', function() {
var $ctrl = element.isolateScope().$ctrl;
$ctrl.add_metadata();
expect($scope.resource.metadata.length).toEqual(2);
});
it('metadata should be successfully deleted', function() {
var $ctrl = element.isolateScope().$ctrl;
$ctrl.delete_metadata();
expect($scope.resource.metadata.length).toEqual(0);
});
it('scheduler_hints should be successfully added', function() {
var $ctrl = element.isolateScope().$ctrl;
$ctrl.add_scheduler_hints();
expect($scope.resource.scheduler_hints.length).toEqual(2);
});
it('scheduler_hints should be successfully deleted', function() {
var $ctrl = element.isolateScope().$ctrl;
$ctrl.delete_scheduler_hints();
expect($scope.resource.scheduler_hints.length).toEqual(0);
});
});
})();

View File

@ -0,0 +1,78 @@
(function() {
'use strict';
describe('os-cinder-volume-attachment', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var hotgenGlobals;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
hotgenGlobals = $injector.get('hotgenGlobals');
hotgenGlobals.update_resource_options({
instances: [{id: 'instance1-id', name: 'instance1'}],
volumes: [{id: 'volume1-id', name: 'volume1-id'}],
});
$scope.resource = {};
$scope.dependson = [];
$scope.connectedoptions = [];
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-cinder-volume-attachment'+
' volumeattachment="resource" dependson="dependson"'+
' connectedoptions="connectedoptions" form-reference='
+'"resourceForm"></os-cinder-volume-attachment>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with no connectedoptions set', function() {
element = $compile(angular.element('<os-cinder-volume-attachment'+
' volumeattachment="resource" dependson="dependson"'+
' form-reference='
+'"resourceForm"></os-cinder-volume-attachment>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with connectedoptions set', function() {
$scope.resource = {instance_uuid: 'instance-uuid', volume_id: 'volume-id'}
$scope.connectedoptions = {instance_uuid: [{value: 'instance-uuid'}],
volume_id: [{value: 'volume-id'}]};
element = $compile(angular.element('<os-cinder-volume-attachment'+
' volumeattachment="resource" dependson="dependson"'+
' connectedoptions="connectedoptions" form-reference='
+'"resourceForm"></os-cinder-volume-attachment>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
expect($isolateScope.$ctrl.volumeattachment.instance_uuid).toEqual('instance-uuid');
expect($isolateScope.$ctrl.volumeattachment.volume_id).toEqual('volume-id');
});
});
})();

View File

@ -70,12 +70,13 @@
if (oldValue === newValue){
return;
}
if (newValue === true){
if (newValue === true || newValue === 'true'){
$scope.controller.resourcegroup.resource_def.properties = [{}];
if (!($scope.filecontent && $scope.filecontent.length >= 0)){
$scope.controller.resourcegroup.resource_def.type = '';
}
} else{
// ;
}
});
$scope.file_upload = function(element){
@ -91,8 +92,8 @@
hotgenNotify.show_success('Read file content.');
hotgenGlobals.set_reference_file(file.name, reader.result)
$scope.filecontent = reader.result;
}
reader.readAsText(file);
}
reader.readAsText(file);
} else {
hotgenNotify.show_error('File type is not supported.');
}
@ -103,26 +104,26 @@
}, 0);
};
this.delete_property = function(index){
this.resourcegroup.resource_def.properties.splice(index, 1)
this.resourcegroup.resource_def.properties.splice(index, 1);
}
this.add_property = function(){
this.resourcegroup.resource_def.properties.push({})
this.resourcegroup.resource_def.properties.push({});
}
this.delete_metadata = function(index){
this.resourcegroup.resource_def.metadata.splice(index, 1)
this.resourcegroup.resource_def.metadata.splice(index, 1);
}
this.add_metadata = function(){
this.resourcegroup.resource_def.metadata.push({})
this.resourcegroup.resource_def.metadata.push({});
}
};
}
function osHeatResourceGroupPath (basePath){
return basePath + 'js/resources/os__heat__resourcegroup/os__heat__resourcegroup.html';
};
}
osHeatResourceGroupController.$inject = ['$scope', 'hotgenGlobals', 'hotgenNotify',
'horizon.dashboard.project.heat_dashboard.template_generator.validationRules',

View File

@ -0,0 +1,144 @@
(function() {
'use strict';
describe('component os-heat-resource-group', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var hotgenNotify;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
hotgenNotify = $injector.get('hotgenNotify');
spyOn(hotgenNotify, 'show_success');
spyOn(hotgenNotify, 'show_error');
$scope.resource = {};
$scope.dependson = [];
$scope.connectedoptions = [];
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-heat-resource-group resourcegroup="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-heat-resource-group>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Properties");
expect($isolateScope.is_upload).toEqual('false');
});
it('find tab title with resource set', function() {
$scope.resource = {resource_def: {type: 'filepath.yaml'}};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-heat-resource-group resourcegroup="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-heat-resource-group>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
expect($isolateScope.is_upload ).toEqual('true');
});
it('$scope.is_upload should be successfully watched', function() {
$isolateScope.is_upload = 'true';
$isolateScope.$digest();
$isolateScope.is_upload = 'false';
$isolateScope.$digest();
$isolateScope.filecontent = 'some thing here';
$isolateScope.is_upload = 'true';
$isolateScope.$digest();
expect($isolateScope.controller.resourcegroup.resource_def.type ).toEqual('');
});
it('file should be successfully uploaded', function() {
var blob = new Blob([''], {type: '', });
blob['name'] = 'filename.yaml'
var upload_element = {files: [blob], }
spyOn(window, 'FileReader').and.returnValue({
readAsText: function(file) {
this.onload({});
},
result: 'file contents.'
});
$isolateScope.file_upload(upload_element);
expect($isolateScope.filecontent).toEqual('file contents.');
expect(hotgenNotify.show_success).toHaveBeenCalled();
});
it('file should be not uploaded return undefined', function() {
var upload_element = {files: []}
var returnValue = $isolateScope.file_upload(upload_element);
expect(returnValue).toEqual(undefined);
});
it('file should be not uploaded show error', function() {
var upload_element = {files: [{name: 'file.txt'}]}
var returnValue = $isolateScope.file_upload(upload_element);
expect(hotgenNotify.show_error).toHaveBeenCalled();
});
it('metadata should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_metadata();
expect($ctrl.resourcegroup.resource_def.metadata.length).toEqual(1);
});
it('metadata should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_metadata();
$ctrl.delete_metadata();
expect($ctrl.resourcegroup.resource_def.metadata.length).toEqual(0);
});
it('property should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_property();
expect($ctrl.resourcegroup.resource_def.properties.length).toEqual(2);
});
it('property should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_property();
expect($ctrl.resourcegroup.resource_def.properties.length).toEqual(0);
});
it('click upload', function() {
spyOn(window, 'setTimeout').and.callFake(function(){});
$isolateScope.clickUpload();
expect(setTimeout).toHaveBeenCalled();
});
});
})();

View File

@ -1,5 +1,5 @@
<md-tabs md-dynamic-height md-stretch-tabs="always" md-border-bottom>
<md-tab label="Details">
<md-tab label="Properties">
<md-content layout-padding>
<md-input-container class="md-block" flex-gt-xs>
<label>Floating Network</label>

View File

@ -0,0 +1,92 @@
(function() {
'use strict';
describe('component os-neutron-floatingip', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var hotgenGlobals;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
hotgenGlobals = $injector.get('hotgenGlobals');
hotgenGlobals.update_resource_options({
floating_networks: [{id: 'floating-network1-id', name: 'floating-network1-id'}],
floating_subnets: [{id: 'floating-subnet1-id', name: 'floating-subnet1-id'}],
ports: [{id: 'port1-id', name: 'port1-id'}],
});
$scope.resource = {};
$scope.dependson = [];
$scope.connectedoptions = [];
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-neutron-floatingip floatingip="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-neutron-floatingip>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with no connectedoptions set', function() {
element = $compile(angular.element('<os-neutron-floatingip floatingip="resource"'+
' dependson="dependson"'+
' form-reference="resourceForm"></os-neutron-floatingip>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with connectedoptions set', function() {
$scope.resource = {floating_network: 'floating-network-id',
floating_subnet: 'floating-subnet-id',
port_id: 'port_id'}
$scope.connectedoptions = {floating_network: [{value: 'floating-network-id'}],
floating_subnet: [{value: 'floating-subnet-id'}],
port_id: [{value: 'port-id'}],
};
element = $compile(angular.element('<os-neutron-floatingip floatingip="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-neutron-floatingip>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
it('value_spec should be successfully added', function() {
var $ctrl = element.isolateScope().$ctrl;
$ctrl.add_value_specs();
expect($scope.resource.value_specs.length).toEqual(2);
});
it('value_spec should be successfully deleted', function() {
var $ctrl = element.isolateScope().$ctrl;
$ctrl.delete_value_specs();
expect($scope.resource.value_specs.length).toEqual(0);
});
});
})();

View File

@ -0,0 +1,78 @@
(function() {
'use strict';
describe('os-neutron-floatingip-association', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var hotgenGlobals;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
hotgenGlobals = $injector.get('hotgenGlobals');
hotgenGlobals.update_resource_options({
floatingips: [{id: 'floatingip1-id', name: 'floatingip1-id'}],
ports: [{id: 'port1-id', name: 'port1-id'}],
});
$scope.resource = {};
$scope.dependson = [];
$scope.connectedoptions = [];
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-neutron-floatingip-association'+
' floatingipassociation="resource" dependson="dependson" '+
'connectedoptions="connectedoptions" form-reference="resourceForm">'+
'</os-neutron-floatingip-association>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with no connectedoptions set', function() {
element = $compile(angular.element('<os-neutron-floatingip-association'+
' floatingipassociation="resource" dependson="dependson" '+
' form-reference="resourceForm">'+
'</os-neutron-floatingip-association>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with connectedoptions set', function() {
$scope.resource = {floatingip_id: 'floatingip-id',
port_id: 'port_id'}
$scope.connectedoptions = {floatingip_id: [{value: 'floatingip-id'}],
port_id: [{value: 'port-id'}],
};
element = $compile(angular.element('<os-neutron-floatingip-association'+
' floatingipassociation="resource" dependson="dependson" '+
'connectedoptions="connectedoptions" form-reference="resourceForm">'+
'</os-neutron-floatingip-association>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
});
})();

View File

@ -1,5 +1,5 @@
<md-tabs md-dynamic-height md-stretch-tabs="always" md-border-bottom>
<md-tab label="Details" >
<md-tab label="Properties" >
<md-content layout-padding>
<md-input-container class="md-block" flex-gt-xs>

View File

@ -14,7 +14,7 @@
color: '#40a5f2'
},
label: 'fixed_ip_address',
modal_component: '<os-neutron-floatingip-association floatingipassociation="resource" dependson="dependson" connectedoptions="connectedoptions" form-reference="resourceForm"></os-neutron-floatingip-association>',
modal_component: '<os-neutron-floatingip-association floatingipassociation="resource" dependson="dependson" connectedoptions="connectedoptions" form-reference="resourceForm"></os-neutron-floatingip-association>',
edge_settings: {
'OS__Neutron__FloatingIP': {
'type': 'property',

View File

@ -1,5 +1,5 @@
<md-tabs md-dynamic-height md-stretch-tabs="always" md-border-bottom>
<md-tab label="Details" >
<md-tab label="Properties" >
<md-content layout-padding>
<md-input-container class="md-block" flex-gt-xs>
<label>Name</label>

View File

@ -0,0 +1,61 @@
(function() {
'use strict';
describe('component os-neutron-net', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
$scope.resource = {};
$scope.dependson = [];
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-neutron-net network="resource" '+
'dependson="dependson" form-reference="resourceForm">'+
'</os-neutron-net>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title Properties with resource properties set', function() {
$scope.resource = { tags: [], dhcp_agent_ids: [], admin_state_up: true, value_specs: []};
element = $compile(angular.element('<os-neutron-net network="resource" '+
'dependson="dependson" form-reference="resourceForm">'+
'</os-neutron-net>'))($scope);
$scope.$digest();
expect(element.find('span').html()).toContain("Properties");
});
it('value_spec should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_value_specs();
expect($scope.resource.value_specs.length).toEqual(2);
});
it('value_spec should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_value_specs();
expect($scope.resource.value_specs.length).toEqual(0);
});
});
})();

View File

@ -1,5 +1,5 @@
<md-tabs md-dynamic-height md-stretch-tabs="always" md-border-bottom>
<md-tab label="Details" >
<md-tab label="Properties" >
<md-content layout-padding>
<md-input-container class="md-block" flex-gt-xs>

View File

@ -212,7 +212,7 @@
display: dev_owner
}
});
};
}
function querySearch (query) {
return query ? this.device_owners.filter( createFilterFor(query) ) : this.device_owners;

View File

@ -0,0 +1,146 @@
(function() {
'use strict';
describe('component os-neutron-port', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var hotgenGlobals;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
hotgenGlobals = $injector.get('hotgenGlobals');
hotgenGlobals.update_resource_options({
networks: [{id: 'network1-id', name: 'network1-id'}],
security_groups: [{id: 'secgroup1-id', name: 'secgroup1-id'}],
subnets: [{id: 'subnet1-id', name: 'subnet-id'}]
});
$scope.resource = {};
$scope.dependson = [];
$scope.connectedoptions = [];
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-neutron-port port="resource" '+
'dependson="dependson" connectedoptions="connectedoptions" '+
'form-reference="resourceForm"></os-neutron-port>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with no connectedoptions set', function() {
element = $compile(angular.element('<os-neutron-port port="resource" '+
'dependson="dependson" '+
'form-reference="resourceForm"></os-neutron-port>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with connectedoptions set', function() {
$scope.resource = {device_owner: 'someone',
network: 'network-id',
security_groups: ['secgroup-id'],
'fixed_ips.subnet': ['subnet-id'],}
$scope.connectedoptions = {network: [{value: 'network-id'}],
security_groups: [{value: 'secgroup-id'}],
'fixed_ips.subnet': [{value: 'subnet-id'}],
};
element = $compile(angular.element('<os-neutron-port port="resource" '+
'dependson="dependson" connectedoptions="connectedoptions" '+
'form-reference="resourceForm"></os-neutron-port>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
it('value_spec should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_value_specs();
expect($scope.resource.value_specs.length).toEqual(2);
});
it('value_spec should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_value_specs();
expect($scope.resource.value_specs.length).toEqual(0);
});
it('allowed address pair should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_allowed_address_pair();
expect($scope.resource.allowed_address_pairs.length).toEqual(2);
});
it('allowed address pair should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_allowed_address_pair();
expect($scope.resource.allowed_address_pairs.length).toEqual(0);
});
it('fixed_ip should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_fixed_ip();
expect($scope.resource.fixed_ips.length).toEqual(2);
});
it('fixed_ip should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_fixed_ip();
expect($scope.resource.fixed_ips.length).toEqual(0);
});
it('searchTextChange set device_owner', function(){
var $ctrl = $isolateScope.$ctrl;
$ctrl.searchTextChange('device_owner_01');
expect($scope.resource.device_owner).toEqual('device_owner_01');
});
it('selectedItemChange set device_owner', function(){
var $ctrl = $isolateScope.$ctrl;
$ctrl.selectedItemChange({display: 'device_owner_01'});
expect($scope.resource.device_owner).toEqual('device_owner_01');
});
it('querySearch set device_owner', function(){
var $ctrl = $isolateScope.$ctrl;
var retValue = $ctrl.querySearch('');
expect(retValue.length).toEqual(3);
retValue = $ctrl.querySearch('network:dhcp');
expect(retValue).toEqual([ { value: 'network_dhcp', display: 'network:dhcp' }]);
});
});
})();

View File

@ -1,5 +1,5 @@
<md-tabs md-dynamic-height md-stretch-tabs="always" md-border-bottom>
<md-tab label="Details" >
<md-tab label="Properties" >
<md-content layout-padding>
<md-input-container class="md-block" flex-gt-xs>
<label>Name</label>

View File

@ -0,0 +1,99 @@
(function() {
'use strict';
describe('component os-neutron-router', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var hotgenGlobals;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
hotgenGlobals = $injector.get('hotgenGlobals');
hotgenGlobals.update_resource_options({
networks: [{id: 'network1-id', name: 'network1-id'}],
subnets: [{id: 'subnet1-id', name: 'subnet-id'}]
});
$scope.resource = {};
$scope.dependson = [];
$scope.connectedoptions = [];
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-neutron-router router="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-neutron-router>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with no connectedoptions set', function() {
element = $compile(angular.element('<os-neutron-router router="resource"'+
' dependson="dependson"'+
' form-reference="resourceForm"></os-neutron-router>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with connectedoptions set', function(){
$scope.resource = {'external_gateway_info.network': 'network-id',
'ext_fixed_ips.subnet': ['subnet-id'],}
$scope.connectedoptions = {'external_gateway_info.network': [{value: 'network-id'}],
'ext_fixed_ips.subnet': [{value: 'subnet-id'}],
};
element = $compile(angular.element('<os-neutron-router router="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-neutron-router>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
it('value_spec should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_value_specs();
expect($scope.resource.value_specs.length).toEqual(2);
});
it('value_spec should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_value_specs();
expect($scope.resource.value_specs.length).toEqual(0);
});
it('external_fixed_ip should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_external_fixed_ip();
expect($scope.resource.external_gateway_info.external_fixed_ips.length).toEqual(2);
});
it('external_fixed_ip should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_external_fixed_ip();
expect($scope.resource.external_gateway_info.external_fixed_ips.length).toEqual(0);
});
});
})();

View File

@ -1,5 +1,5 @@
<md-tabs md-dynamic-height md-stretch-tabs="always" md-border-bottom>
<md-tab label="Details" >
<md-tab label="Properties" >
<md-content layout-padding>
<p ng-if="$ctrl.message">{$ $ctrl.message $}</p>
<md-input-container class="md-block" flex-gt-xs>

View File

@ -131,7 +131,7 @@
}
return $scope.options.routers;
}
};
}
osNeutronRouterInterfaceController.$inject = ['$scope', 'hotgenGlobals', ];
osNeutronRouterInterfacePath.$inject = ['horizon.dashboard.project.heat_dashboard.template_generator.basePath'];

View File

@ -0,0 +1,75 @@
(function() {
'use strict';
describe('component os-neutron-routerinterface', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var hotgenGlobals;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
hotgenGlobals = $injector.get('hotgenGlobals');
hotgenGlobals.update_resource_options({
routers: [{id: 'router1-id', name: 'router1-id'}],
subnets: [{id: 'subnet1-id', name: 'subnet1-id'}],
ports: [{id: 'port1-id', name: 'port1-id'}],
});
$scope.resource = {};
$scope.dependson = [];
$scope.connectedoptions = [];
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-neutron-router-interface'+
' routerinterface="resource" dependson="dependson"'+
' connectedoptions="connectedoptions" form-reference="resourceForm">'+
'</os-neutron-router-interface>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with no connectedoptions set', function() {
element = $compile(angular.element('<os-neutron-router-interface'+
' routerinterface="resource" dependson="dependson"'+
' form-reference="resourceForm">'+
'</os-neutron-router-interface>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title with connectedoptions set', function(){
$scope.resource = {port: 'port-id',
subnet: 'subnet-id',
router: 'router-id'}
$scope.connectedoptions = {port: [{value: 'port-id'}],
subnet: [{value: 'subnet-id'}],
router: [{value: 'router-id'}],
};
element = $compile(angular.element('<os-neutron-router-interface'+
' routerinterface="resource" dependson="dependson"'+
' connectedoptions="connectedoptions" form-reference="resourceForm">'+
'</os-neutron-router-interface>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
});
})();

View File

@ -1,5 +1,5 @@
<md-tabs md-dynamic-height md-stretch-tabs="always" md-border-bottom>
<md-tab label="Details" >
<md-tab label="Properties" >
<md-content layout-padding>
<md-input-container class="md-block" flex-gt-xs>
<label>Name</label>

View File

@ -0,0 +1,62 @@
(function() {
'use strict';
describe('component os-neutron-security-group', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
$scope.resource = {};
$scope.dependson = [];
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-neutron-security-group '+
'securitygroup="resource" dependson="dependson" '+
'form-reference="resourceForm"></os-neutron-security-group>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Properties");
});
it('find tab title Properties with rules undefined', function() {
$scope.resource = {rules: []}
element = $compile(angular.element('<os-neutron-security-group '+
'securitygroup="resource" dependson="dependson" '+
'form-reference="resourceForm"></os-neutron-security-group>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Properties");
});
it('rules should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_rule();
expect($scope.resource.rules.length).toEqual(2);
});
it('rules should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_rule();
expect($scope.resource.rules.length).toEqual(0);
});
});
})();

View File

@ -92,7 +92,7 @@
this.subnet.host_routes.splice(index, 1)
}
$scope.validate_dns = function (input_string){
var re = /^.*$/;
var re = /^[A-Za-z0-9_.-]+$/;
var match = re.exec(input_string);
if (match){
return input_string;

View File

@ -0,0 +1,100 @@
(function() {
'use strict';
describe('component os-neutron-subnet', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var hotgenGlobals;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
hotgenGlobals = $injector.get('hotgenGlobals');
hotgenGlobals.update_resource_options({
networks: [{id: 'network1-id', name: 'network1-id'}],
});
$scope.resource = {};
$scope.dependson = [];
$scope.connectedoptions = [];
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-neutron-subnet subnet="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-neutron-subnet>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Basic");
});
it('find tab title with no connectedoptions set', function() {
element = $compile(angular.element('<os-neutron-subnet subnet="resource"'+
' dependson="dependson"'+
' form-reference="resourceForm"></os-neutron-subnet>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Basic");
});
it('find tab title with connectedoptions set', function(){
$scope.resource = {network: 'network-id',}
$scope.connectedoptions = {network: [{value: 'network-id'}]};
element = $compile(angular.element('<os-neutron-subnet subnet="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-neutron-subnet>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Basic");
});
it('allocation_pool should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_allocation_pool();
expect($scope.resource.allocation_pools.length).toEqual(2);
});
it('allocation_pool should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_allocation_pool();
expect($scope.resource.allocation_pools.length).toEqual(0);
});
it('hostroute should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_hostroute();
expect($scope.resource.host_routes.length).toEqual(2);
});
it('hostroute should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_hostroute();
expect($scope.resource.host_routes.length).toEqual(0);
});
it('validate dns', function() {
expect( $isolateScope.validate_dns('@')).toEqual(null);
expect( $isolateScope.validate_dns('8.8.8.8')).toEqual('8.8.8.8');
});
});
})();

View File

@ -1,5 +1,5 @@
<md-tabs md-dynamic-height md-stretch-tabs="always" md-border-bottom>
<md-tab label="Details" >
<md-tab label="Properties" >
<md-content layout-padding>
<md-input-container class="md-block">
<label>Name</label>

View File

@ -0,0 +1,39 @@
(function() {
'use strict';
describe('component os-nova-keypair', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var hotgenGlobals;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
$scope.resource = {};
$scope.dependson = [];
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-nova-keypair keypair="resource" '+
'dependson="dependson" form-reference="resourceForm">'+
'</os-nova-keypair>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Properties");
});
});
})();

View File

@ -1,5 +1,5 @@
<md-tabs md-dynamic-height md-stretch-tabs="never" md-border-bottom>
<md-tab label="Details">
<md-tab label="Basic">
<md-content layout-padding>
<md-input-container class="md-block" flex-gt-xs>
<label>Name</label>

View File

@ -76,13 +76,13 @@
osNovaServerSettings.resource_key,
osNovaServerSettings.modal_component);
for (var i in osNovaServerSettings.edge_settings){
if (osNovaServerSettings.edge_settings[i].modal){
hotgenGlobals.update_resource_components(
osNovaServerSettings.resource_key+'_'+i,
osNovaServerSettings.edge_settings[i].modal);
}
}
// for (var i in osNovaServerSettings.edge_settings){
// if (osNovaServerSettings.edge_settings[i].modal){
// hotgenGlobals.update_resource_components(
// osNovaServerSettings.resource_key+'_'+i,
// osNovaServerSettings.edge_settings[i].modal);
// }
// }
hotgenGlobals.update_edge_directions(
osNovaServerSettings.resource_key,
@ -109,9 +109,6 @@
if (typeof this.instance.personality === 'undefined'){
this.instance.personality = [{}];
}
if (typeof this.instance.scheduler_hints === 'undefined'){
this.instance.scheduler_hints = [];
}
if (typeof this.instance.block_device_mapping === 'undefined'){
this.instance.block_device_mapping = [];
}
@ -123,7 +120,7 @@
}
if (typeof this.instance.networks === 'undefined'){
this.instance.networks = [{}];
};
}
this.disable = {
'key_name': false,
@ -303,7 +300,7 @@
$scope.show_passwd_type = "password";
$scope.bdpv2_source = {}; // Mark the source selected of every block_device_mapping_v2 item.
$scope.how2config_networks = {}
$scope.update_boot_source = function(index){
$scope.update_boot_source = function(){
if ($scope.boot_source == 'image'){
this.$ctrl.instance.image_snapshot = null;
this.$ctrl.instance.volume = null;

View File

@ -0,0 +1,308 @@
(function() {
'use strict';
describe('component os-nova-server', function(){
beforeEach(module('horizon.dashboard.project.heat_dashboard.template_generator'));
beforeEach(module('appTemplates'));
var $scope, $isolateScope, $compile;
var hotgenGlobals, hotgenUtils;
var element;
beforeEach(inject(function($injector) {
$scope = $injector.get('$rootScope').$new();
$compile = $injector.get('$compile');
hotgenGlobals = $injector.get('hotgenGlobals');
hotgenUtils = $injector.get('hotgenUtils');
hotgenGlobals.update_resource_options({
networks: [{id: 'network1-id', name: 'network1-id'}],
subnets: [{id: 'subnet1-id', name: 'subnet1-id'}],
ports: [{id: 'port1-id', name: 'port1-id'}],
volumes: [{id: 'volume1-id', name: 'volume1-id'}],
floatingips: [{id: 'ipaddress', name: 'ipaddress'}],
security_groups: [{id: 'secgroup-id1', name: 'secgroup-id1'}],
keypairs: [{id: 'keyname1', name: 'keyname1'}],
});
$scope.resource = {};
$scope.dependson = [];
$scope.connectedoptions = [];
$scope.resourceForm = {};
// element will enable you to test your directive's element on the DOM
element = $compile(angular.element('<os-nova-server instance="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-nova-server>'))($scope);
// Digest needs to be called to set any values on the directive's scope
$scope.$digest();
$isolateScope = element.isolateScope();
}));
it('find tab title Properties', function() {
expect(element.find('span').html()).toContain("Basic");
});
it('find tab title with no connectedoptions set', function() {
element = $compile(angular.element('<os-nova-server instance="resource"'+
' dependson="dependson"'+
' form-reference="resourceForm"></os-nova-server>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Basic");
});
it('find tab title with connectedoptions set', function(){
$scope.resource = {image: 'image-id', key_name: 'keyname',
security_groups: ['secgroup-01'],
block_device_mapping_v2: [
{volume_id: '{ get_resource: vol01 }'},
{image: 'image-id'}, {image: '{ get_resource: image01 }'},
{snapshot_id: 'snapshot-id'},
{ignore: 'ignore'}
],
networks: [{network: '{ get_resource: network01 }'},
{subnet: '{ get_resource: subnet01 }'},
{port: '{ get_resource: port01 }'},
{floating_ip: '{ get_resource: floatingip01 }'},
{ignore: 'ignore'}
],
}
$scope.connectedoptions = {
'networks.network': [{value: 'network-id'}, {value: '{ get_resource: network01 }'}],
'networks.subnet': [{value: 'subnet-id'}, {value: '{ get_resource: subnet01 }'}],
'networks.port': [{value: 'port-id'}, {value: '{ get_resource: port01 }'}],
'networks.floating_ip': [{value: 'floatingip'}, {value: '{ get_resource: floatingip01 }'}],
key_name: 'keyname',
security_groups: [{value: 'secgroup-id'}],
'block_device_mapping_v2.volume_id': [{value: 'volume-id'},
{value: '{ get_resource: vol01 }'}],
}
element = $compile(angular.element('<os-nova-server instance="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-nova-server>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
$isolateScope.update_boot_source();
for (var i in $scope.resource.block_device_mapping_v2){
$isolateScope.update_source(i);
}
for (var i in $scope.resource.networks){
$isolateScope.update_nwconfig(i);
}
expect(element.find('span').html()).toContain("Basic");
});
it('find tab title with connectedoptions set with error', function(){
$scope.resource = {image: 'image-id', key_name: 'keyname',
security_groups: ['secgroup-01'],
block_device_mapping_v2: [
{volume_id: '{ get_resource: vol01 }'},
{image: 'image-id'}, {image: '{ get_resource: image01 }'},
{snapshot_id: 'snapshot-id'},
{ignore: 'ignore'}
],
networks: [{network: '{ get_resource: network01 }'},
{subnet: '{ get_resource: subnet01 }'},
{port: '{ get_resource: port01 }'},
{floating_ip: '{ get_resource: floatingip01 }'}
],
}
$scope.connectedoptions = {
'networks.network': [{value: 'network-id'}, {value: '{ get_resource: network01 }'}],
'networks.subnet': [{value: 'subnet-id'}, {value: '{ get_resource: subnet01 }'}],
'networks.port': [{value: 'port-id'}, {value: '{ get_resource: port01 }'}],
'networks.floating_ip': [{value: 'floatingip'}, {value: '{ get_resource: floatingip01 }'}],
key_name: 'keyname',
security_groups: [{value: 'secgroup-id'}],
'block_device_mapping_v2.volume_id': [{value: 'volume-id'},
{value: '{ get_resource: vol01 }'}],
}
spyOn(hotgenUtils, 'filter_and_return_get_resource_element').and.callFake(function(){
return [{}]
});
element = $compile(angular.element('<os-nova-server instance="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-nova-server>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
expect(element.find('span').html()).toContain("Basic");
});
it('find tab title with boot from image snapshot', function(){
$scope.resource = {image_snapshot: 'image-id'}
element = $compile(angular.element('<os-nova-server instance="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-nova-server>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
$isolateScope.update_boot_source();
expect(element.find('span').html()).toContain("Basic");
});
it('find tab title with boot from volume ', function(){
$scope.resource = {volume: 'vol-id'}
element = $compile(angular.element('<os-nova-server instance="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-nova-server>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
$isolateScope.update_boot_source();
expect(element.find('span').html()).toContain("Basic");
});
it('find tab title with boot from volume snapshot', function(){
$scope.resource = {volume_snapshot: 'vol-id'}
element = $compile(angular.element('<os-nova-server instance="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-nova-server>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
$isolateScope.update_boot_source();
expect(element.find('span').html()).toContain("Basic");
});
it('find tab title with boot from nothing ', function(){
$scope.resource = {ignore: 'nothing'}
element = $compile(angular.element('<os-nova-server instance="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-nova-server>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
$isolateScope.update_boot_source();
expect(element.find('span').html()).toContain("Basic");
});
it('$scope.show_passwd should be successfully watched', function() {
$isolateScope.show_passwd = true;
$isolateScope.$digest();
expect($isolateScope.show_passwd_type).toEqual('text');
$isolateScope.show_passwd = false;
$isolateScope.$digest();
expect($isolateScope.show_passwd_type).toEqual('password');
});
it('metadata should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_metadata();
expect($scope.resource.metadata.length).toEqual(2);
});
it('metadata should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_metadata();
expect($scope.resource.metadata.length).toEqual(0);
});
it('personality should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_personality();
expect($scope.resource.personality.length).toEqual(2);
});
it('personality should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_personality();
expect($scope.resource.personality.length).toEqual(0);
});
it('block_device_mapping should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_block_device_mapping();
expect($scope.resource.block_device_mapping.length).toEqual(1);
});
it('block_device_mapping should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_block_device_mapping();
$ctrl.delete_block_device_mapping(0);
expect($scope.resource.block_device_mapping.length).toEqual(0);
});
it('block_device_mapping_v2 should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_block_device_mapping_v2();
expect($scope.resource.block_device_mapping_v2.length).toEqual(1);
});
it('block_device_mapping_v2 should be successfully deleted', function() {
$scope.resource = {block_device_mapping_v2: [{volume_id: 'vol-01'}]}
element = $compile(angular.element('<os-nova-server instance="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-nova-server>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_block_device_mapping_v2(0);
expect($scope.resource.block_device_mapping_v2.length).toEqual(0);
});
it('networks should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_networks();
expect($scope.resource.networks.length).toEqual(2);
});
it('networks should be successfully deleted', function() {
$scope.resource = {networks: [{network: 'network-01'}]};
element = $compile(angular.element('<os-nova-server instance="resource"'+
' dependson="dependson" connectedoptions="connectedoptions"'+
' form-reference="resourceForm"></os-nova-server>'))($scope);
$scope.$digest();
$isolateScope = element.isolateScope();
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_networks(0);
expect($scope.resource.networks.length).toEqual(0);
});
it('scheduler_hints should be successfully added', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.add_scheduler_hints();
expect($scope.resource.scheduler_hints.length).toEqual(2);
});
it('scheduler_hints should be successfully deleted', function() {
var $ctrl = $isolateScope.$ctrl;
$ctrl.delete_scheduler_hints();
expect($scope.resource.scheduler_hints.length).toEqual(0);
});
});
})();

View File

@ -9,8 +9,10 @@
</md-icon>
</md-button>
<md-input-container class="md-block" flex-gt-xs ng-repeat="node in nodes._data" ng-if="node.id !== selected.id">
<md-checkbox ng-checked="exists(node.id, dependson)" ng-click="toggle(node.id, dependson)" aria-label="node.label">
{{ node.label }}
</md-checkbox>
</md-input-container>
<div class="div-scroll">
<md-input-container class="md-block" flex-gt-xs ng-repeat="node in nodes._data" ng-if="node.id !== selected.id">
<md-checkbox ng-checked="exists(node.id, dependson)" ng-click="toggle(node.id, dependson)" aria-label="node.label">
{{ node.label }}
</md-checkbox>
</md-input-container>
</div>

View File

@ -14,22 +14,18 @@
<md-list flex>
<md-subheader class="md-no-sticky">FROM</md-subheader>
<md-list-item class="md-3-line">
<span class="fa-stack fa-3x" style="color: {$from_node.color $}">
<i class="fa {$ from_node.class $} fa-stack-1x "></i>
</span>
<div class="md-list-item-text" layout="column">
<md-icon style="height: 50px; width: 50px;" md-svg-src="{$ from_node.image $}"></md-icon>
<div class="md-list-item-text" layout="column">
<h3>{$ from_type $}</h3>
<h4>{$ from_node.id $}</h4>
</div>
</div>
</md-list-item>
</md-list>
<md-divider></md-divider>
<md-list flex>
<md-subheader class="md-no-sticky">TO</md-subheader>
<md-list-item class="md-3-line">
<span class="fa-stack fa-3x" style="color: {$ to_node.color $}">
<i class="fa {$ to_node.class $} fa-stack-1x "></i>
</span>
<md-icon style="height: 50px; width: 50px;" md-svg-src="{$ to_node.image $}"></md-icon>
<div class="md-list-item-text" layout="column">
<h3>{$ to_type $}</h3>
<h4>{$ to_node.id $}</h4>

View File

@ -9,20 +9,18 @@
</md-button>
</div>
</md-toolbar>
<md-dialog-content>
<md-content layout-gt-sm="row" layout-padding>
<div>
<div ng-if="all_saved">
<md-input-container class="md-block">
<label>{$ template.title $}</label>
<textarea ng-model="template.content" md-maxlength="65530" rows="35" cols="150" md-select-on-focus>
</textarea>
</md-input-container>
</div>
<div ng-if="all_saved == false " md-colors="{color: 'default-red-A200'}" >
<span >{$ template.content $}</span>
</div>
</div>
<section>
<md-subheader ng-if="all_saved == false" class="md-warn">{$ warning | translate $}</md-subheader>
<md-input-container class="md-block">
<label>{$ template.title $}</label>
<textarea ng-model="template.content" md-maxlength="65530" rows="35" cols="150" md-select-on-focus>
</textarea>
</md-input-container>
</section>
</md-content>
</md-dialog-content>

100
karma.conf.js Normal file
View File

@ -0,0 +1,100 @@
// Karma configuration
// Generated on Fri Oct 06 2017 11:56:14 GMT+0900 (JST)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'node_modules/angular/angular.min.js',
'node_modules/angular-ui-router/release/angular-ui-router.min.js',
'node_modules/angular-mocks/angular-mocks.js',
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/js/vendors/*.js',
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/js/components/*.module.js',
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/js/components/!(*.spec|*.module).js',
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/js/components/*.spec.js',
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/js/resources/*/!(*.spec).js',
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/js/resources/*/*.spec.js',
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/templates/*.html',
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/js/resources/*/*.html',
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/css/img/icons/*.svg',
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/js/components/!(*.spec).js': 'coverage',
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/js/resources/*/!(*.spec).js': 'coverage',
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/templates/*.html': ['ng-html2js'],
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/js/resources/*/*.html': ['ng-html2js'],
'heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/css/img/icons/*.svg': ['ng-html2js'],
},
ngHtml2JsPreprocessor: {
// stripPrefix: './heat_dashboard/static/',
// prependPrefix: 'undefined',
cacheIdFromPath: function(filepath) {
var cacheId;
if (filepath.indexOf('.svg') != -1){
cacheId = filepath.replace('heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/', '{$ basePath $}');
} else if (filepath.indexOf('.html') != -1){
cacheId = filepath.replace('heat_dashboard/static/', 'undefined');
}
console.log(filepath)
return cacheId;
},
moduleName: 'appTemplates',
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'coverage'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome', ],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}

33
package.json Normal file
View File

@ -0,0 +1,33 @@
{
"name": "heat-dashboard",
"version": "0.0.0",
"description": "OpenStack Heat Dashboard - Angular",
"main": "karma.conf.js",
"directories": {
"doc": "doc"
},
"dependencies": {
"angular-ui-router": "0.4.3",
"angular-mocks": "1.5.8",
"angular": "1.5.8",
"jasmine": "2.8.0",
"jasmine-core": "2.8.0",
"karma-coverage": "1.1.1",
"karma-jasmine": "1.1.0",
"karma-firefox-launcher": "1.0.1",
"karma-chrome-launcher": "2.2.0",
"karma-ng-html2js-preprocessor": "1.0.0",
"karma": "1.7.1"
},
"devDependencies": {
"eslint": "4.9.0",
"eslint-plugin-angular": "3.1.1",
"eslint-plugin-jasmine": "2.9.1"
},
"scripts": {
"test": "karma start karma.conf.js --single-run",
"eslint": "eslint --no-color heat_dashboard/static/dashboard/project/heat_dashboard/template_generator/js/"
},
"author": "",
"license": "Apache-2.0"
}