blob: 7356e46247b52e95cac49d78565c9b202e5d7431 [file] [log] [blame]
Matteo Scandolo8cf33a32017-11-14 15:52:29 -08001
2/*
3 * Copyright 2017-present Open Networking Foundation
4
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8
9 * http://www.apache.org/licenses/LICENSE-2.0
10
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19import * as angular from 'angular';
20import 'angular-mocks';
21import 'angular-ui-router';
Matteo Scandolo9ec14ff2019-03-13 15:51:56 -070022import {IXosNodePositioner, IServiceGraphConstraint, XosNodePositioner} from './node-positioner.service';
Matteo Scandolo8cf33a32017-11-14 15:52:29 -080023
24let service: IXosNodePositioner;
25
26let scope: ng.IRootScopeService;
27
28let constraints: string = '';
29
30let mockResource = {
31 query: () => {
32 return;
33 }
34};
35
36const mockModelRest = {
37 getResource: jasmine.createSpy('ModelRest.getResource')
38 .and.returnValue(mockResource)
39};
40
41describe('The XosNodePositioner service', () => {
42
43 beforeEach(() => {
44 angular.module('XosNodePositioner', [])
45 .service('XosNodePositioner', XosNodePositioner)
Matteo Scandolo35fdf242017-11-30 12:29:45 -080046 .value('ModelRest', mockModelRest)
47 .value('XosConfirm', {});
Matteo Scandolo8cf33a32017-11-14 15:52:29 -080048
49 angular.mock.module('XosNodePositioner');
50 });
51
52 beforeEach(angular.mock.inject((
53 XosNodePositioner: IXosNodePositioner,
54 $rootScope: ng.IRootScopeService,
55 _$q_: ng.IQService) => {
56
57 service = XosNodePositioner;
58 scope = $rootScope;
59
60 spyOn(mockResource, 'query').and.callFake(() => {
61 const d = _$q_.defer();
62 d.resolve([{constraints}]);
63 return {$promise: d.promise};
64 });
65 }));
66
67 it('should position the nodes on the svg', (done) => {
68 const svg = {width: 300, height: 100};
69 const nodes = [
70 {data: {name: 'a'}},
71 {data: {name: 'b'}}
72 ];
73 constraints = '["a", "b"]';
74 service.positionNodes(svg, nodes)
75 .then((positioned) => {
76 expect(positioned[0].x).toBe(100);
77 expect(positioned[0].y).toBe(50);
78 expect(positioned[1].x).toBe(200);
79 expect(positioned[1].y).toBe(50);
80 done();
81 });
82
83 scope.$apply();
84 });
85
86 it('should position the nodes on the svg in vertical bundles', (done) => {
87 const svg = {width: 300, height: 90};
88 const nodes = [
89 {data: {name: 'a'}},
90 {data: {name: 'b'}},
91 {data: {name: 'c'}}
92 ];
93 constraints = '["a", ["b", "c"]]';
94 service.positionNodes(svg, nodes)
95 .then((positioned) => {
96 expect(positioned[0].x).toBe(100);
97 expect(positioned[0].y).toBe(45);
98 expect(positioned[1].x).toBe(200);
99 expect(positioned[1].y).toBe(30);
100 expect(positioned[2].x).toBe(200);
101 expect(positioned[2].y).toBe(60);
102 done();
103 });
104
105 scope.$apply();
106 });
107
108 it('should accept null as constraint to leave an empty space', (done) => {
109 const svg = {width: 300, height: 90};
110 const nodes = [
111 {data: {name: 'a'}},
112 {data: {name: 'b'}},
113 {data: {name: 'c'}}
114 ];
115 constraints = '[[null, "a"], ["b", "c"]]';
116 service.positionNodes(svg, nodes)
117 .then((positioned) => {
118 expect(positioned[0].x).toBe(100);
119 expect(positioned[0].y).toBe(60);
120 expect(positioned[1].x).toBe(200);
121 expect(positioned[1].y).toBe(30);
122 expect(positioned[2].x).toBe(200);
123 expect(positioned[2].y).toBe(60);
124 done();
125 });
126
127 scope.$apply();
128 });
Matteo Scandolo35fdf242017-11-30 12:29:45 -0800129
130 it('should set unpositioned nodes at the top', (done) => {
131 const svg = {width: 300, height: 200};
132 const nodes = [
133 {data: {name: 'a'}},
134 {data: {name: 'b'}},
135 {data: {name: 'c'}, type: 'service'},
136 {data: {name: 'd'}, type: 'service'}
137 ];
138 constraints = '["a", "b"]';
139
140 service.positionNodes(svg, nodes)
141 .then((positioned) => {
142 expect(positioned[0].x).toBe(100);
143 expect(positioned[0].y).toBe(100);
144 expect(positioned[1].x).toBe(200);
145 expect(positioned[1].y).toBe(100);
146 expect(positioned[2].x).toBe(100);
147 expect(positioned[2].y).toBe(150);
148 expect(positioned[3].x).toBe(200);
149 expect(positioned[3].y).toBe(150);
150 done();
151 });
152
153 scope.$apply();
154 });
Matteo Scandolo9ec14ff2019-03-13 15:51:56 -0700155
156 describe('the readConstraints method', () => {
157 it('should return the constraint with higher priority', () => {
158 const constraints: IServiceGraphConstraint[] = [
159 {
160 constraints: JSON.stringify(['foo', 'bar']),
161 priority: 10
162 },
163 {
164 constraints: JSON.stringify(['foo', 'bar', 'baz']),
165 priority: 20
166 }
167 ];
168 const fn = service['readConstraints']; // we need this as it's a private method
169 const res = fn(constraints);
170 expect(res).toEqual(['foo', 'bar', 'baz']);
171 });
172 });
Matteo Scandolo8cf33a32017-11-14 15:52:29 -0800173});