diff options
Diffstat (limited to 'framework/src/onos/web/gui/src/main/webapp/tests/app/fw/widget/table-spec.js')
-rw-r--r-- | framework/src/onos/web/gui/src/main/webapp/tests/app/fw/widget/table-spec.js | 340 |
1 files changed, 340 insertions, 0 deletions
diff --git a/framework/src/onos/web/gui/src/main/webapp/tests/app/fw/widget/table-spec.js b/framework/src/onos/web/gui/src/main/webapp/tests/app/fw/widget/table-spec.js new file mode 100644 index 00000000..4f8f0c0f --- /dev/null +++ b/framework/src/onos/web/gui/src/main/webapp/tests/app/fw/widget/table-spec.js @@ -0,0 +1,340 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + ONOS GUI -- Widget -- Table Service - Unit Tests + */ +describe('factory: fw/widget/table.js', function () { + var $log, $compile, $rootScope, + fs, ts, mast, is, + scope, + containerDiv, + headerDiv, bodyDiv, + header, body, + mockHeader, + mockHeaderHeight = 40; + + var onosFixedHeaderTags = + '<div class="summary-list" onos-fixed-header>' + + '<div class="table-header">' + + '<table>' + + '<tr>' + + '<td colId="type" class="table-icon"></td>' + + '<td colId="id">Host ID </td>' + + '<td colId="mac" sortable>MAC Address </td>' + + '<td colId="location" col-width="110px">Location </td>' + + '</tr>' + + '</table>' + + '</div>' + + + '<div class="table-body">' + + '<table>' + + '<tr class="ignore-width">' + + '<td class="not-picked"></td>' + + '</tr>' + + '<tr>' + + '<td class="table-icon">Some Icon</td>' + + '<td>Some ID</td>' + + '<td>Some MAC Address</td>' + + '<td>Some Location</td>' + + '</tr>' + + '</table>' + + '</div>' + + '</div>', + + onosSortableHeaderTags = + '<div onos-sortable-header ' + + 'sort-callback="sortCallback(requestParams)">' + + '<table>' + + '<tr>' + + '<td colId="type"></td>' + + '<td colId="id" sortable>Host ID </td>' + + '<td colId="mac" sortable>MAC Address </td>' + + '<td colId="location" sortable>Location </td>' + + '</tr>' + + '</table>' + + '</div>'; + + beforeEach(module('onosWidget', 'onosUtil', 'onosMast', 'onosSvg')); + + var mockWindow = { + innerWidth: 600, + innerHeight: 400, + navigator: { + userAgent: 'defaultUA' + }, + on: function () {}, + addEventListener: function () {} + }; + + beforeEach(function () { + module(function ($provide) { + $provide.value('$window', mockWindow); + }); + }); + + beforeEach(inject(function (_$log_, _$compile_, _$rootScope_, + FnService, TableService, MastService, IconService) { + $log = _$log_; + $compile = _$compile_; + $rootScope = _$rootScope_; + fs = FnService; + ts = TableService; + mast = MastService; + is = IconService; + })); + + beforeEach(function () { + scope = $rootScope.$new(); + scope.tableData = []; + }); + + // Note: dummy header so that d3 doesn't trip up. + // $compile has to be used on the directive tag element, so it can't + // be included in the tag strings declared above. + beforeEach(function () { + mockHeader = d3.select('body') + .append('h2') + .classed('tabular-header', true) + .style({ + height: mockHeaderHeight + 'px', + margin: 0, + padding: 0 + }) + .text('Some Header'); + }); + + afterEach(function () { + containerDiv = undefined; + headerDiv = undefined; + bodyDiv = undefined; + header = undefined; + body = undefined; + mockHeader.remove(); + }); + + function populateTableData() { + scope.tableData = [ + { + type: 'endstation', + id: '1234', + mac: '00:00:03', + location: 'USA' + } + ]; + } + + it('should define TableBuilderService', function () { + expect(ts).toBeDefined(); + }); + + it('should define api functions', function () { + expect(fs.areFunctions(ts, [ + 'resetSortIcons' + ])).toBeTruthy(); + }); + + function compile(elem) { + var compiled = $compile(elem); + compiled(scope); + scope.$digest(); + } + + function selectTables() { + expect(containerDiv.find('div').length).toBe(2); + + headerDiv = angular.element(containerDiv[0].querySelector('.table-header')); + expect(headerDiv.length).toBe(1); + + bodyDiv = angular.element(containerDiv[0].querySelector('.table-body')); + expect(bodyDiv.length).toBe(1); + + header = headerDiv.find('table'); + expect(header.length).toBe(1); + + body = bodyDiv.find('table'); + expect(body.length).toBe(1); + } + + function verifyGivenTags(dirName, div) { + expect(div).toBeDefined(); + expect(div.attr(dirName)).toBe(''); + } + + function verifyDefaultSize() { + expect(header.css('width')).toBe('570px'); + expect(body.css('width')).toBe('570px'); + } + + function verifyHeight() { + var padding = 22, + mastHeight = 36, + tableHeight = (mockWindow.innerHeight - mockHeaderHeight) - + (fs.noPx(headerDiv.css('height')) + mastHeight + padding); + + expect(bodyDiv.css('height')).toBe(tableHeight + 'px'); + } + + function verifyColWidth() { + var hdrs = header.find('td'), + cols = body.find('td'); + + expect(angular.element(hdrs[0]).css('width')).toBe('33px'); + expect(angular.element(hdrs[3]).css('width')).toBe('110px'); + + expect(angular.element(cols[1]).css('width')).toBe('33px'); + expect(angular.element(cols[4]).css('width')).toBe('110px'); + } + + function verifyCallbacks(h) { + expect(scope.sortCallback).not.toHaveBeenCalled(); + + h[0].click(); + expect(scope.sortCallback).not.toHaveBeenCalled(); + + h[1].click(); + expect(scope.sortCallback).toHaveBeenCalledWith({ + sortCol: 'id', + sortDir: 'asc' + }); + h[1].click(); + expect(scope.sortCallback).toHaveBeenCalledWith({ + sortCol: 'id', + sortDir: 'desc' + }); + h[1].click(); + expect(scope.sortCallback).toHaveBeenCalledWith({ + sortCol: 'id', + sortDir: 'asc' + }); + + h[2].click(); + expect(scope.sortCallback).toHaveBeenCalledWith({ + sortCol: 'mac', + sortDir: 'asc' + }); + h[2].click(); + expect(scope.sortCallback).toHaveBeenCalledWith({ + sortCol: 'mac', + sortDir: 'desc' + }); + h[2].click(); + expect(scope.sortCallback).toHaveBeenCalledWith({ + sortCol: 'mac', + sortDir: 'asc' + }); + + h[3].click(); + expect(scope.sortCallback).toHaveBeenCalledWith({ + sortCol: 'location', + sortDir: 'asc' + }); + h[3].click(); + expect(scope.sortCallback).toHaveBeenCalledWith({ + sortCol: 'location', + sortDir: 'desc' + }); + h[3].click(); + expect(scope.sortCallback).toHaveBeenCalledWith({ + sortCol: 'location', + sortDir: 'asc' + }); + } + + function verifyIcons(h) { + var currH, div; + + h[1].click(); + currH = angular.element(h[1]); + div = currH.find('div'); + expect(div.html()).toBe( + '<svg class="embeddedIcon" width="10" height="10" viewBox="0 0 ' + + '50 50"><g class="icon upArrow"><rect width="50" height="50" ' + + 'rx="5"></rect><use width="50" height="50" class="glyph" xmlns:' + + 'xlink="http://www.w3.org/1999/xlink" xlink:href="#triangleUp">' + + '</use></g></svg>' + ); + h[1].click(); + div = currH.find('div'); + expect(div.html()).toBe( + '<svg class="embeddedIcon" width="10" height="10" viewBox="0 0 ' + + '50 50"><g class="icon downArrow"><rect width="50" height="50" ' + + 'rx="5"></rect><use width="50" height="50" class="glyph" xmlns:' + + 'xlink="http://www.w3.org/1999/xlink" xlink:href="#triangleDown">' + + '</use></g></svg>' + ); + + h[2].click(); + div = currH.children(); + // clicked on a new element, so the previous icon should have been deleted + expect(div.html()).toBeFalsy(); + + // the new element should have the ascending icon + currH = angular.element(h[2]); + div = currH.children(); + expect(div.html()).toBe( + '<svg class="embeddedIcon" width="10" height="10" viewBox="0 0 ' + + '50 50"><g class="icon upArrow"><rect width="50" height="50" ' + + 'rx="5"></rect><use width="50" height="50" class="glyph" xmlns:' + + 'xlink="http://www.w3.org/1999/xlink" xlink:href="#triangleUp">' + + '</use></g></svg>' + ); + } + + it('should affirm that onos-fixed-header is working', function () { + containerDiv = angular.element(onosFixedHeaderTags); + + compile(containerDiv); + + verifyGivenTags('onos-fixed-header', containerDiv); + selectTables(); + verifyDefaultSize(); + + populateTableData(); + + scope.$emit('LastElement'); + scope.$digest(); + + verifyHeight(); + verifyColWidth(); + + mockWindow.innerHeight = 300; + scope.$digest(); + verifyHeight(); + + mockWindow.innerWidth = 500; + scope.$digest(); + verifyColWidth(); + }); + + it('should affirm that onos-sortable-header is working', function () { + headerDiv = angular.element(onosSortableHeaderTags); + + compile(headerDiv); + verifyGivenTags('onos-sortable-header', headerDiv); + + scope.sortCallback = jasmine.createSpy('sortCallback'); + + header = headerDiv.find('td'); + verifyCallbacks(header); + verifyIcons(header); + }); + + // Note: testing resetSortIcons isn't feasible because due to the nature of + // directive compilation: they are jQuery elements, not d3 elements, + // so the function doesn't work. + +}); |