Jian Li
Committed by Gerrit Code Review

[ONOS-3949] Add chartBuilder.js, interacts with ChartRequestHandler

- Add unit test for chartBuilder.js

Change-Id: I2f5c56b878dda660c28af13ec0229b5ab3665156
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +/*
18 + ONOS GUI -- Widget -- Chart Service
19 + */
20 +(function () {
21 + 'use strict';
22 +
23 + // injected references
24 + // fs -> FnService
25 + // wss -> WebSocketService
26 + // ls -> LoadingService
27 + var $log, $interval, $timeout, fs, wss, ls;
28 +
29 + // constants
30 + var refreshInterval = 2000;
31 +
32 + // example params to buildChart:
33 + // {
34 + // scope: $scope, <- controller scope
35 + // tag: 'device', <- chart identifier
36 + // respCb: respCb, <- websocket response callback (optional)
37 + // query: params <- query parameters in URL (optional)
38 + // }
39 + // Note: query is always an object (empty or containing properties)
40 + // it comes from $location.search()
41 + function buildChart(o) {
42 + var handlers = {},
43 + root = o.tag + 's',
44 + req = o.tag + 'DataRequest',
45 + resp = o.tag + 'DataResponse',
46 + onResp = fs.isF(o.respCb),
47 + oldChartData = [],
48 + refreshPromise;
49 +
50 + o.scope.chartData = [];
51 + o.scope.changedData = [];
52 + o.scope.reqParams = o.reqParams || {};
53 + o.scope.autoRefresh = true;
54 + o.scope.autoRefreshTip = 'Toggle auto refresh';
55 +
56 + // === websocket functions ===
57 + // response
58 + function respCb(data) {
59 + ls.stop();
60 + o.scope.chartData = data[root];
61 + onResp && onResp();
62 +
63 + // check if data changed
64 + if (!angular.equals(o.scope.chartData, oldChartData)) {
65 + o.scope.changedData = [];
66 + // only refresh the chart if there are new changes
67 + if (oldChartData.length) {
68 + angular.forEach(o.scope.chartData, function (item) {
69 + if (!fs.containsObj(oldChartData, item)) {
70 + o.scope.changedData.push(item);
71 + }
72 + });
73 + }
74 + angular.copy(o.scope.chartData, oldChartData);
75 + }
76 + o.scope.$apply();
77 + }
78 + handlers[resp] = respCb;
79 + wss.bindHandlers(handlers);
80 +
81 + // request
82 + function requestCb(params) {
83 + var p = angular.extend({}, params, o.query);
84 + if (wss.isConnected()) {
85 + wss.sendEvent(req, p);
86 + ls.start();
87 + }
88 + }
89 + o.scope.requestCallback = requestCb;
90 +
91 + // === autoRefresh functions ===
92 + function fetchDataIfNotWaiting() {
93 + if (!ls.waiting()) {
94 + if (fs.debugOn('widget')) {
95 + $log.debug('Refreshing ' + root + ' page');
96 + }
97 + requestCb(o.scope.reqParams);
98 + }
99 + }
100 +
101 + function startRefresh() {
102 + refreshPromise = $interval(fetchDataIfNotWaiting, refreshInterval);
103 + }
104 +
105 + function stopRefresh() {
106 + if (refreshPromise) {
107 + $interval.cancel(refreshPromise);
108 + refreshPromise = null;
109 + }
110 + }
111 +
112 + function toggleRefresh() {
113 + o.scope.autoRefresh = !o.scope.autoRefresh;
114 + o.scope.autoRefresh ? startRefresh() : stopRefresh();
115 + }
116 + o.scope.toggleRefresh = toggleRefresh;
117 +
118 + // === Cleanup on destroyed scope ===
119 + o.scope.$on('$destroy', function () {
120 + wss.unbindHandlers(handlers);
121 + stopRefresh();
122 + ls.stop();
123 + });
124 +
125 + requestCb(o.scope.reqParams);
126 + startRefresh();
127 + }
128 +
129 + angular.module('onosWidget')
130 + .factory('ChartBuilderService',
131 + ['$log', '$interval', '$timeout', 'FnService', 'WebSocketService',
132 + 'LoadingService',
133 +
134 + function (_$log_, _$interval_, _$timeout_, _fs_, _wss_, _ls_) {
135 + $log = _$log_;
136 + $interval = _$interval_;
137 + $timeout = _$timeout_;
138 + fs = _fs_;
139 + wss = _wss_;
140 + ls = _ls_;
141 +
142 + return {
143 + buildChart: buildChart
144 + };
145 + }]);
146 +}());
...@@ -78,6 +78,7 @@ ...@@ -78,6 +78,7 @@
78 <script src="app/fw/widget/tooltip.js"></script> 78 <script src="app/fw/widget/tooltip.js"></script>
79 <script src="app/fw/widget/button.js"></script> 79 <script src="app/fw/widget/button.js"></script>
80 <script src="app/fw/widget/tableBuilder.js"></script> 80 <script src="app/fw/widget/tableBuilder.js"></script>
81 + <script src="app/fw/widget/chartBuilder.js"></script>
81 82
82 <script src="app/fw/layer/layer.js"></script> 83 <script src="app/fw/layer/layer.js"></script>
83 <script src="app/fw/layer/panel.js"></script> 84 <script src="app/fw/layer/panel.js"></script>
......
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +/*
18 + ONOS GUI -- Widget -- Chart Builder Service - Unit Tests
19 + */
20 +
21 +describe('factory: fw/widget/chartBuilder.js', function () {
22 + var $log, $rootScope, fs, cbs, is;
23 +
24 + var mockObj;
25 + mockWss = {
26 + bindHandlers: function () {},
27 + sendEvent: function () {},
28 + unbindHandlers: function () {}
29 + };
30 +
31 + beforeEach(module('onosWidget', 'onosUtil', 'onosRemote', 'onosSvg'));
32 +
33 + beforeEach(function () {
34 + module(function ($provide) {
35 + $provide.value('WebSocketService', mockWss);
36 + });
37 + });
38 +
39 + beforeEach(inject(function (_$log_, _$rootScope_,
40 + FnService, ChartBuilderService, IconService) {
41 + $log = _$log_;
42 + $rootScope = _$rootScope_;
43 + fs = FnService;
44 + cbs = ChartBuilderService;
45 + is = IconService;
46 + }));
47 +
48 + beforeEach(function () {
49 + mockObj = {
50 + scope: $rootScope.$new(),
51 + tag: 'foo'
52 + };
53 + });
54 +
55 + afterEach(function () {
56 + mockObj = {};
57 + });
58 +
59 + it('should define ChartBuilderService', function () {
60 + expect(cbs).toBeDefined();
61 + });
62 +
63 + it('should define api functions', function () {
64 + expect(fs.areFunctions(cbs, [
65 + 'buildChart'
66 + ])).toBeTruthy();
67 + });
68 +
69 + it('should verify requestCb', function () {
70 + spyOn(mockWss, 'sendEvent');
71 + expect(mockObj.scope.requestCallback).not.toBeDefined();
72 + cbs.buildChart(mockObj);
73 + expect(mockObj.scope.requestCallback).toBeDefined();
74 + expect(mockWss.sendEvent).toHaveBeenCalled();
75 + });
76 +
77 + it('should set chartData', function () {
78 + expect(mockObj.scope.chartData).not.toBeDefined();
79 + cbs.buildChart(mockObj);
80 + expect(fs.isA(mockObj.scope.chartData)).toBeTruthy();
81 + expect(mockObj.scope.chartData.length).toBe(0);
82 + });
83 +
84 + it('should unbind handlers on destroyed scope', function () {
85 + spyOn(mockWss, 'unbindHandlers');
86 + cbs.buildChart(mockObj);
87 + expect(mockWss.unbindHandlers).not.toHaveBeenCalled();
88 + mockObj.scope.$destroy();
89 + expect(mockWss.unbindHandlers).toHaveBeenCalled();
90 + });
91 +}
...\ No newline at end of file ...\ No newline at end of file