Implemented table building functions

Change-Id: Ie4003080b13725561df22de41ec85f8c3f31c794
diff --git a/web/gui2/src/main/webapp/tests/app/fw/remote/websocket.service.spec.ts b/web/gui2/src/main/webapp/tests/app/fw/remote/websocket.service.spec.ts
index 5c8d6b7..391b62c 100644
--- a/web/gui2/src/main/webapp/tests/app/fw/remote/websocket.service.spec.ts
+++ b/web/gui2/src/main/webapp/tests/app/fw/remote/websocket.service.spec.ts
@@ -33,8 +33,6 @@
 
 class MockGlyphService {}
 
-class MockWSock {}
-
 /**
  * ONOS GUI -- Remote -- Web Socket Service - Unit Tests
  */
@@ -103,7 +101,7 @@
             'noHandlersWarn', 'resetState',
             'createWebSocket', 'bindHandlers', 'unbindHandlers',
             'addOpenListener', 'removeOpenListener', 'sendEvent',
-            'setVeilDelegate', 'setLoadingDelegate'
+            'setVeilDelegate', 'setLoadingDelegate', 'isConnected', 'closeWebSocket'
         ])).toBeTruthy();
     });
 
@@ -228,9 +226,7 @@
     });
 
     it('should warn if no arguments, unbindHandlers', () => {
-        expect(wss.unbindHandlers(
-            new Map<string, (data) => void>([])
-        )).toBeNull();
+        expect(wss.unbindHandlers([])).toBeNull();
         expect(logServiceSpy.warn).toHaveBeenCalledWith(
             'WSS.unbindHandlers(): no event handlers'
         );
diff --git a/web/gui2/src/main/webapp/tests/app/fw/remote/wsock.service.spec.ts b/web/gui2/src/main/webapp/tests/app/fw/remote/wsock.service.spec.ts
deleted file mode 100644
index 61d5ab4..0000000
--- a/web/gui2/src/main/webapp/tests/app/fw/remote/wsock.service.spec.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Foundation
- *
- * 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.
- */
-import { TestBed, inject } from '@angular/core/testing';
-
-import { LogService } from '../../../../app/log.service';
-import { ConsoleLoggerService } from '../../../../app/consolelogger.service';
-import { WSock } from '../../../../app/fw/remote/wsock.service';
-
-/**
- * ONOS GUI -- Remote -- WSock Service - Unit Tests
- */
-describe('WSock', () => {
-    let log: LogService;
-
-    beforeEach(() => {
-        log = new ConsoleLoggerService();
-
-        TestBed.configureTestingModule({
-            providers: [WSock,
-                { provide: LogService, useValue: log },
-            ]
-        });
-    });
-
-    it('should be created', inject([WSock], (service: WSock) => {
-        expect(service).toBeTruthy();
-    }));
-});
diff --git a/web/gui2/src/main/webapp/tests/app/fw/svg/icon.directive.spec.ts b/web/gui2/src/main/webapp/tests/app/fw/svg/icon.directive.spec.ts
deleted file mode 100644
index 4c5c252..0000000
--- a/web/gui2/src/main/webapp/tests/app/fw/svg/icon.directive.spec.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  Copyright 2016-present Open Networking Foundation
- *
- *  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.
- */
-import { TestBed, inject } from '@angular/core/testing';
-
-import { ElementRef } from '@angular/core';
-import { LogService } from '../../../../app/log.service';
-import { ConsoleLoggerService } from '../../../../app/consolelogger.service';
-import { IconDirective } from '../../../../app/fw/svg/icon.directive';
-import { IconService } from '../../../../app/fw/svg/icon.service';
-import { GlyphService } from '../../../../app/fw/svg/glyph.service';
-import { SvgUtilService } from '../../../../app/fw/svg/svgutil.service';
-import { FnService } from '../../../../app/fw//util/fn.service';
-import { ActivatedRoute, Router} from '@angular/router';
-
-class MockFnService {}
-
-class MockGlyphService {}
-
-class MockIconService {}
-
-/**
- * ONOS GUI -- SVG -- Icon Directive - Unit Tests
- */
-describe('IconDirective', () => {
-    let log: LogService;
-    const elementMock = <any>{ };
-
-    beforeEach(() => {
-        log = new ConsoleLoggerService();
-
-        TestBed.configureTestingModule({
-            providers: [ IconDirective,
-                { provide: FnService, useClass: MockFnService },
-                { provide: LogService, useValue: log },
-                { provide: ElementRef, useValue: elementMock },
-                { provide: GlyphService, useClass: MockGlyphService },
-                { provide: IconService, useClass: MockIconService },
-            ]
-        });
-    });
-
-    afterEach(() => {
-        log = null;
-    });
-
-    it('should create an instance', inject([IconDirective], (directive: IconDirective) => {
-        expect(directive).toBeTruthy();
-    }));
-});
diff --git a/web/gui2/src/main/webapp/tests/app/fw/util/fn.service.spec.ts b/web/gui2/src/main/webapp/tests/app/fw/util/fn.service.spec.ts
index 84b5f094..bf75091 100644
--- a/web/gui2/src/main/webapp/tests/app/fw/util/fn.service.spec.ts
+++ b/web/gui2/src/main/webapp/tests/app/fw/util/fn.service.spec.ts
@@ -235,7 +235,7 @@
             'isFirefox', 'parseDebugFlags',
             'debugOn', 'debug', 'find', 'inArray', 'removeFromArray',
             'isEmptyObject', 'cap', 'noPx', 'noPxStyle', 'endsWith',
-            'inEvilList', 'analyze', 'sanitize'
+            'inEvilList', 'analyze', 'sanitize', 'sameObjProps', 'containsObj'
 //            'find', 'inArray', 'removeFromArray', 'isEmptyObject', 'sameObjProps', 'containsObj', 'cap',
 //            'eecode', 'noPx', 'noPxStyle', 'endsWith', 'addToTrie', 'removeFromTrie', 'trieLookup',
 //            'classNames', 'extend', 'sanitize'
diff --git a/web/gui2/src/main/webapp/tests/app/fw/widget/button.service.spec.ts b/web/gui2/src/main/webapp/tests/app/fw/widget/button.service.spec.ts
index cc8113b..c3e501d 100644
--- a/web/gui2/src/main/webapp/tests/app/fw/widget/button.service.spec.ts
+++ b/web/gui2/src/main/webapp/tests/app/fw/widget/button.service.spec.ts
@@ -20,14 +20,11 @@
 import { ButtonService } from '../../../../app/fw/widget/button.service';
 import { FnService } from '../../../../app/fw/util/fn.service';
 import { IconService } from '../../../../app/fw/svg/icon.service';
-import { TooltipService } from '../../../../app/fw/widget/tooltip.service';
 
 class MockIconService {}
 
 class MockFnService {}
 
-class MockTooltipService {}
-
 /**
  * ONOS GUI -- Widget -- Button Service - Unit Tests
  */
@@ -42,7 +39,6 @@
                 { provide: LogService, useValue: log },
                 { provide: IconService, useClass: MockIconService },
                 { provide: FnService, useClass: MockFnService },
-                { provide: TooltipService, useClass: MockTooltipService },
             ]
         });
     });
diff --git a/web/gui2/src/main/webapp/tests/app/fw/widget/tablebuilder.service.spec.ts b/web/gui2/src/main/webapp/tests/app/fw/widget/tablebuilder.service.spec.ts
deleted file mode 100644
index 1126d28..0000000
--- a/web/gui2/src/main/webapp/tests/app/fw/widget/tablebuilder.service.spec.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Foundation
- *
- * 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.
- */
-import { TestBed, inject } from '@angular/core/testing';
-
-import { LogService } from '../../../../app/log.service';
-import { ConsoleLoggerService } from '../../../../app/consolelogger.service';
-import { TableBuilderService } from '../../../../app/fw/widget/tablebuilder.service';
-import { FnService } from '../../../../app/fw//util/fn.service';
-import { LoadingService } from '../../../../app/fw/layer/loading.service';
-import { WebSocketService } from '../../../../app/fw/remote/websocket.service';
-
-class MockFnService {}
-
-class MockLoadingService {}
-
-class MockWebSocketService {}
-
-/*
- ONOS GUI -- Widget -- Table Builder Service - Unit Tests
- */
-describe('TableBuilderService', () => {
-    let log: LogService;
-
-    beforeEach(() => {
-        log = new ConsoleLoggerService();
-
-        TestBed.configureTestingModule({
-            providers: [TableBuilderService,
-                { provide: FnService, useClass: MockFnService },
-                { provide: LoadingService, useClass: MockLoadingService },
-                { provide: LogService, useValue: log },
-                { provide: WebSocketService, useClass: MockWebSocketService },
-
-            ]
-        });
-    });
-
-    it('should be created', inject([TableBuilderService], (service: TableBuilderService) => {
-        expect(service).toBeTruthy();
-    }));
-});
diff --git a/web/gui2/src/main/webapp/tests/app/fw/widget/tooltip.directive.spec.ts b/web/gui2/src/main/webapp/tests/app/fw/widget/tooltip.directive.spec.ts
deleted file mode 100644
index 7445a05..0000000
--- a/web/gui2/src/main/webapp/tests/app/fw/widget/tooltip.directive.spec.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Foundation
- *
- * 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.
- */
-import { TestBed, inject } from '@angular/core/testing';
-
-import { TooltipDirective } from '../../../../app/fw/widget/tooltip.directive';
-import { LogService } from '../../../../app/log.service';
-import { ConsoleLoggerService } from '../../../../app/consolelogger.service';
-import { FnService } from '../../../../app/fw/util/fn.service';
-
-class MockFnService {}
-
-/**
- * ONOS GUI -- Widget -- Tooltip Directive - Unit Tests
- */
-describe('TooltipDirective', () => {
-    let log: LogService;
-
-    beforeEach(() => {
-        log = new ConsoleLoggerService();
-
-        TestBed.configureTestingModule({
-            providers: [ TooltipDirective,
-                { provide: FnService, useClass: MockFnService },
-                { provide: LogService, useValue: log },
-            ]
-        });
-    });
-
-    afterEach(() => {
-        log = null;
-    });
-
-    it('should create an instance', inject([TooltipDirective], (directive: TooltipDirective) => {
-        expect(directive).toBeTruthy();
-    }));
-});
diff --git a/web/gui2/src/main/webapp/tests/app/fw/widget/tooltip.service.spec.ts b/web/gui2/src/main/webapp/tests/app/fw/widget/tooltip.service.spec.ts
deleted file mode 100644
index 98a5a18..0000000
--- a/web/gui2/src/main/webapp/tests/app/fw/widget/tooltip.service.spec.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Foundation
- *
- * 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.
- */
-import { TestBed, inject } from '@angular/core/testing';
-
-import { LogService } from '../../../../app/log.service';
-import { ConsoleLoggerService } from '../../../../app/consolelogger.service';
-import { TooltipService } from '../../../../app/fw/widget/tooltip.service';
-import { FnService } from '../../../../app/fw/util/fn.service';
-
-class MockFnService {}
-
-/**
- * ONOS GUI -- Widget -- Tooltip Service - Unit Tests
- */
-describe('TooltipService', () => {
-    let log: LogService;
-
-    beforeEach(() => {
-        log = new ConsoleLoggerService();
-
-        TestBed.configureTestingModule({
-            providers: [TooltipService,
-                { provide: LogService, useValue: log },
-                { provide: FnService, useClass: MockFnService },
-            ]
-        });
-    });
-
-    it('should be created', inject([TooltipService], (service: TooltipService) => {
-        expect(service).toBeTruthy();
-    }));
-});
diff --git a/web/gui2/src/main/webapp/tests/app/onos.component.spec.ts b/web/gui2/src/main/webapp/tests/app/onos.component.spec.ts
index 7a15504..8dcb9e0 100644
--- a/web/gui2/src/main/webapp/tests/app/onos.component.spec.ts
+++ b/web/gui2/src/main/webapp/tests/app/onos.component.spec.ts
@@ -59,6 +59,8 @@
 
 class MockKeyService {}
 
+class MockLionService {}
+
 class MockNavService {}
 
 class MockOnosService {}
@@ -73,6 +75,11 @@
 
 class MockVeilComponent {}
 
+class MockWebSocketService {
+    createWebSocket() {}
+    isConnected() { return false; }
+}
+
 /**
  * ONOS GUI -- Onos Component - Unit Tests
  */
@@ -81,6 +88,8 @@
     let fs: FnService;
     let ar: MockActivatedRoute;
     let windowMock: Window;
+    let fixture;
+    let app;
 
     beforeEach(async(() => {
         log = new ConsoleLoggerService();
@@ -117,6 +126,7 @@
                 { provide: GlyphService, useClass: MockGlyphService },
                 { provide: IconService, useClass: MockIconService },
                 { provide: KeyService, useClass: MockKeyService },
+                { provide: LionService, useClass: MockLionService },
                 { provide: LogService, useValue: log },
                 { provide: NavService, useClass: MockNavService },
                 { provide: OnosService, useClass: MockOnosService },
@@ -124,20 +134,22 @@
                 { provide: PanelService, useClass: MockPanelService },
                 { provide: SpriteService, useClass: MockSpriteService },
                 { provide: ThemeService, useClass: MockThemeService },
+                { provide: WebSocketService, useClass: MockWebSocketService },
                 { provide: Window, useFactory: (() => windowMock ) },
             ]
         }).compileComponents();
+
+        fixture = TestBed.createComponent(OnosComponent);
+        app = fixture.componentInstance;
     }));
 
     it('should create the app', async(() => {
-        const fixture = TestBed.createComponent(OnosComponent);
-        const app = fixture.debugElement.componentInstance;
         expect(app).toBeTruthy();
     }));
 
-    it(`should have as title 'onos'`, async(() => {
-        const fixture = TestBed.createComponent(OnosComponent);
-        const app = fixture.debugElement.componentInstance;
-        expect(app.title).toEqual('onos');
-    }));
+//    it(`should have as title 'onos'`, async(() => {
+//        const fixture = TestBed.createComponent(OnosComponent);
+//        const app = fixture.componentInstance;
+//        expect(app.title).toEqual('onos');
+//    }));
 });
diff --git a/web/gui2/src/main/webapp/tests/app/view/apps/apps.component.spec.ts b/web/gui2/src/main/webapp/tests/app/view/apps/apps.component.spec.ts
index a998cb0..6682e41 100644
--- a/web/gui2/src/main/webapp/tests/app/view/apps/apps.component.spec.ts
+++ b/web/gui2/src/main/webapp/tests/app/view/apps/apps.component.spec.ts
@@ -14,72 +14,126 @@
  * limitations under the License.
  */
 import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
+import { ActivatedRoute, Params } from '@angular/router';
 import { LogService } from '../../../../app/log.service';
-import { ConsoleLoggerService } from '../../../../app/consolelogger.service';
 import { AppsComponent } from '../../../../app/view/apps/apps.component';
 import { DialogService } from '../../../../app/fw/layer/dialog.service';
 import { FnService } from '../../../../app/fw/util/fn.service';
+import { IconComponent } from '../../../../app/fw/svg/icon/icon.component';
 import { IconService } from '../../../../app/fw/svg/icon.service';
 import { KeyService } from '../../../../app/fw/util/key.service';
 import { LionService } from '../../../../app/fw/util/lion.service';
+import { LoadingService } from '../../../../app/fw/layer/loading.service';
 import { PanelService } from '../../../../app/fw/layer/panel.service';
-import { TableBuilderService } from '../../../../app/fw/widget/tablebuilder.service';
+import { ThemeService } from '../../../../app/fw/util/theme.service';
 import { UrlFnService } from '../../../../app/fw/remote/urlfn.service';
 import { WebSocketService } from '../../../../app/fw/remote/websocket.service';
+import { of } from 'rxjs';
+
+class MockActivatedRoute extends ActivatedRoute {
+    constructor(params: Params) {
+        super();
+        this.queryParams = of(params);
+    }
+}
 
 class MockDialogService {}
 
 class MockFnService {}
 
-class MockIconService {}
+class MockIconService {
+    loadIconDef() {}
+}
 
 class MockKeyService {}
 
-class MockLionService {}
+class MockLoadingService {
+    startAnim() {}
+    stop() {}
+    waiting() {}
+}
 
 class MockPanelService {}
 
 class MockTableBuilderService {}
 
+class MockThemeService {}
+
 class MockUrlFnService {}
 
-class MockWebSocketService {}
+class MockWebSocketService {
+    createWebSocket() {}
+    isConnected() { return false; }
+    unbindHandlers() {}
+    bindHandlers() {}
+}
 
 /**
  * ONOS GUI -- Apps View -- Unit Tests
  */
 describe('AppsComponent', () => {
-    let log: LogService;
+    let fs: FnService;
+    let ar: MockActivatedRoute;
+    let windowMock: Window;
+    let logServiceSpy: jasmine.SpyObj<LogService>;
     let component: AppsComponent;
     let fixture: ComponentFixture<AppsComponent>;
-    const windowMock = <any>{ location: <any> { hostname: 'localhost' } };
+    const bundleObj = {
+        'core.view.App': {
+            test: 'test1'
+        }
+    };
+    const mockLion = (key) =>  {
+        return bundleObj[key] || '%' + key + '%';
+    };
 
     beforeEach(async(() => {
-        log = new ConsoleLoggerService();
+        const logSpy = jasmine.createSpyObj('LogService', ['info', 'debug', 'warn', 'error']);
+        ar = new MockActivatedRoute({'debug': 'txrx'});
+
+        windowMock = <any>{
+            location: <any> {
+                hostname: 'foo',
+                host: 'foo',
+                port: '80',
+                protocol: 'http',
+                search: { debug: 'true'},
+                href: 'ws://foo:123/onos/ui/websock/path',
+                absUrl: 'ws://foo:123/onos/ui/websock/path'
+            }
+        };
+        fs = new FnService(ar, logSpy, windowMock);
 
         TestBed.configureTestingModule({
-            declarations: [ AppsComponent ],
+            declarations: [ AppsComponent, IconComponent ],
             providers: [
                 { provide: DialogService, useClass: MockDialogService },
-                { provide: FnService, useClass: MockFnService },
+                { provide: FnService, useValue: fs },
                 { provide: IconService, useClass: MockIconService },
                 { provide: KeyService, useClass: MockKeyService },
-                { provide: LionService, useClass: MockLionService },
-                { provide: LogService, useValue: log },
+                { provide: LionService, useFactory: (() => {
+                        return {
+                            bundle: ((bundleId) => mockLion),
+                            ubercache: new Array()
+                        };
+                    })
+                },
+                { provide: LoadingService, useClass: MockLoadingService },
+                { provide: LogService, useValue: logSpy },
                 { provide: PanelService, useClass: MockPanelService },
-                { provide: TableBuilderService, useClass: MockTableBuilderService },
+                { provide: ThemeService, useClass: MockThemeService },
                 { provide: UrlFnService, useClass: MockUrlFnService },
                 { provide: WebSocketService, useClass: MockWebSocketService },
                 { provide: Window, useValue: windowMock },
             ]
         })
         .compileComponents();
+        logServiceSpy = TestBed.get(LogService);
     }));
 
     beforeEach(() => {
         fixture = TestBed.createComponent(AppsComponent);
-        component = fixture.componentInstance;
+        component = fixture.debugElement.componentInstance;
         fixture.detectChanges();
     });
 
diff --git a/web/gui2/src/main/webapp/tests/app/view/device/device.component.spec.ts b/web/gui2/src/main/webapp/tests/app/view/device/device.component.spec.ts
index 960d241..6d54ac4 100644
--- a/web/gui2/src/main/webapp/tests/app/view/device/device.component.spec.ts
+++ b/web/gui2/src/main/webapp/tests/app/view/device/device.component.spec.ts
@@ -14,46 +14,50 @@
  * limitations under the License.
  */
 import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
+import { ActivatedRoute, Params } from '@angular/router';
+import { DebugElement } from '@angular/core';
+import { By } from '@angular/platform-browser';
 import { LogService } from '../../../../app/log.service';
-import { ConsoleLoggerService } from '../../../../app/consolelogger.service';
 import { DeviceComponent } from '../../../../app/view/device/device.component';
 
 import { DetailsPanelService } from '../../../../app/fw/layer/detailspanel.service';
 import { FnService, WindowSize } from '../../../../app/fw/util/fn.service';
 import { IconService } from '../../../../app/fw/svg/icon.service';
 import { GlyphService } from '../../../../app/fw/svg/glyph.service';
+import { IconComponent } from '../../../../app/fw/svg/icon/icon.component';
 import { KeyService } from '../../../../app/fw/util/key.service';
 import { LoadingService } from '../../../../app/fw/layer/loading.service';
 import { NavService } from '../../../../app/fw/nav/nav.service';
 import { MastService } from '../../../../app/fw/mast/mast.service';
 import { PanelService } from '../../../../app/fw/layer/panel.service';
 import { SvgUtilService } from '../../../../app/fw/svg/svgutil.service';
-import { TableBuilderService } from '../../../../app/fw/widget/tablebuilder.service';
 import { TableDetailService } from '../../../../app/fw/widget/tabledetail.service';
+import { ThemeService } from '../../../../app/fw/util/theme.service';
 import { WebSocketService } from '../../../../app/fw/remote/websocket.service';
+import { of } from 'rxjs';
 
-class MockDetailsPanelService {}
-
-class MockFnService {
-    windowSize(offH: number = 0, offW: number = 0): WindowSize {
-        return {
-            height: 123,
-            width: 456
-        };
+class MockActivatedRoute extends ActivatedRoute {
+    constructor(params: Params) {
+        super();
+        this.queryParams = of(params);
     }
 }
 
-class MockIconService {}
+class MockDetailsPanelService {}
+
+class MockFnService {}
+
+class MockIconService {
+    loadIconDef() {}
+}
 
 class MockGlyphService {}
 
 class MockKeyService {}
 
 class MockLoadingService {
-    startAnim() {
-        // Do nothing
-    }
+    startAnim() {}
+    stop() {}
 }
 
 class MockNavService {}
@@ -66,49 +70,81 @@
 
 class MockTableDetailService {}
 
-class MockWebSocketService {}
+class MockThemeService {}
+
+class MockWebSocketService {
+    createWebSocket() {}
+    isConnected() { return false; }
+    unbindHandlers() {}
+    bindHandlers() {}
+}
 
 /**
  * ONOS GUI -- Device View Module - Unit Tests
  */
 describe('DeviceComponent', () => {
-    let log: LogService;
+    let fs: FnService;
+    let ar: MockActivatedRoute;
+    let windowMock: Window;
+    let logServiceSpy: jasmine.SpyObj<LogService>;
     let component: DeviceComponent;
     let fixture: ComponentFixture<DeviceComponent>;
-    const windowMock = <any>{ location: <any> { hostname: 'localhost' } };
 
     beforeEach(async(() => {
-        log = new ConsoleLoggerService();
+        const logSpy = jasmine.createSpyObj('LogService', ['info', 'debug', 'warn', 'error']);
+        ar = new MockActivatedRoute({'debug': 'txrx'});
+
+        windowMock = <any>{
+            location: <any> {
+                hostname: 'foo',
+                host: 'foo',
+                port: '80',
+                protocol: 'http',
+                search: { debug: 'true'},
+                href: 'ws://foo:123/onos/ui/websock/path',
+                absUrl: 'ws://foo:123/onos/ui/websock/path'
+            }
+        };
+        fs = new FnService(ar, logSpy, windowMock);
+
 
         TestBed.configureTestingModule({
-            declarations: [ DeviceComponent ],
+            declarations: [ DeviceComponent, IconComponent ],
             providers: [
                 { provide: DetailsPanelService, useClass: MockDetailsPanelService },
-                { provide: FnService, useClass: MockFnService },
+                { provide: FnService, useValue: fs },
                 { provide: IconService, useClass: MockIconService },
                 { provide: GlyphService, useClass: MockGlyphService },
                 { provide: KeyService, useClass: MockKeyService },
                 { provide: LoadingService, useClass: MockLoadingService },
                 { provide: MastService, useClass: MockMastService },
                 { provide: NavService, useClass: MockNavService },
-                { provide: LogService, useValue: log },
+                { provide: LogService, useValue: logSpy },
                 { provide: PanelService, useClass: MockPanelService },
-                { provide: TableBuilderService, useClass: MockTableBuilderService },
                 { provide: TableDetailService, useClass: MockTableDetailService },
+                { provide: ThemeService, useClass: MockThemeService },
                 { provide: WebSocketService, useClass: MockWebSocketService },
                 { provide: Window, useValue: windowMock },
              ]
         })
         .compileComponents();
+        logServiceSpy = TestBed.get(LogService);
     }));
 
     beforeEach(() => {
         fixture = TestBed.createComponent(DeviceComponent);
-        component = fixture.componentInstance;
+        component = fixture.debugElement.componentInstance;
         fixture.detectChanges();
     });
 
     it('should create', () => {
         expect(component).toBeTruthy();
     });
+
+    it('should have .table-header with "Friendly Name..."', () => {
+        const appDe: DebugElement = fixture.debugElement;
+        const divDe = appDe.query(By.css('.table-header'));
+        const div: HTMLElement = divDe.nativeElement;
+        expect(div.textContent).toEqual('Friendly Name Device ID Master Ports Vendor H/W Version S/W Version Protocol ');
+    });
 });