Increase test coverage for SO MON UI
[so.git] / so-monitoring / so-monitoring-ui / src / main / frontend / src / app / home / home.component.spec.ts
index 1e1485e..cc11ebc 100644 (file)
-/**\r
-============LICENSE_START=======================================================\r
- Copyright (C) 2018 Ericsson. All rights reserved.\r
-================================================================================\r
-Licensed under the Apache License, Version 2.0 (the "License");\r
-you may not use this file except in compliance with the License.\r
-You may obtain a copy of the License at\r
-\r
-    http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-Unless required by applicable law or agreed to in writing, software\r
-distributed under the License is distributed on an "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-See the License for the specific language governing permissions and\r
- limitations under the License.\r
-\r
-SPDX-License-Identifier: Apache-2.0\r
-============LICENSE_END=========================================================\r
-\r
-@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com\r
-*/\r
-\r
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';\r
-\r
-import { HomeComponent } from './home.component';\r
-import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\r
-import { MatTableModule } from '@angular/material';\r
-import { FormsModule } from '@angular/forms';\r
-import { MatDatepickerModule } from '@angular/material/datepicker';\r
-import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';\r
-import { HttpClientModule } from '@angular/common/http';\r
-import { HttpClient } from '@angular/common/http';\r
-import { inject } from '@angular/core/testing';\r
-import { RouterModule } from '@angular/router';\r
-import { APP_BASE_HREF } from '@angular/common';\r
-import { ToastrNotificationService } from '../toastr-notification-service.service';\r
-import { environment } from '../../environments/environment.prod';\r
-\r
-class StubbedToastrNotificationService extends ToastrNotificationService {\r
-  toastrSettings() {\r
-  }\r
-}\r
-\r
-describe('HomeComponent', () => {\r
-  let component: HomeComponent;\r
-  let fixture: ComponentFixture<HomeComponent>;\r
-\r
-  beforeEach(async(() => {\r
-    TestBed.configureTestingModule({\r
-      providers: [HomeComponent, HttpClient, HttpTestingController,\r
-        { provide: APP_BASE_HREF, useValue: '/' },\r
-        { provide: ToastrNotificationService, useClass: StubbedToastrNotificationService }],\r
-      imports: [MatTableModule, FormsModule, MatDatepickerModule, HttpClientModule, RouterModule.forRoot([])],\r
-      declarations: [HomeComponent],\r
-      schemas: [\r
-        CUSTOM_ELEMENTS_SCHEMA\r
-      ]\r
-    })\r
-      .compileComponents();\r
-  }));\r
-\r
-  // Ensure creation of HomeComponent component\r
-  it('component should be created', inject([HttpTestingController, HomeComponent],\r
-    (httpClient: HttpTestingController, service: HomeComponent) => {\r
-      expect(service).toBeTruthy();\r
-    }));\r
-\r
-  // Ensure all statistic variables are initialised to zero\r
-  it('ensure statistic variables are defaulted at zero', async(inject([HttpTestingController, HomeComponent],\r
-    (httpClient: HttpTestingController, service: HomeComponent) => {\r
-      expect(service.totalVal === 0 && service.completeVal === 0 &&\r
-        service.inProgressVal === 0 && service.failedVal === 0 &&\r
-        service.pendingVal === 0 && service.unlockedVal === 0 &&\r
-        service.percentageComplete === 0 && service.percentageFailed === 0 &&\r
-        service.percentageInProg === 0 && service.percentagePending === 0 &&\r
-        service.percentageUnlocked === 0).toBeTruthy();\r
-    })));\r
-});\r
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com, andrei.barcovschi@ericsson.com
+*/
+
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HomeComponent } from './home.component';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+import { MatTableModule, MatNativeDateModule, MatTableDataSource, MatPaginatorModule } from '@angular/material';
+import { FormsModule } from '@angular/forms';
+import { MatDatepickerModule } from '@angular/material/datepicker';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { HttpClientModule } from '@angular/common/http';
+import { HttpClient } from '@angular/common/http';
+import { inject } from '@angular/core/testing';
+import { RouterModule } from '@angular/router';
+import { APP_BASE_HREF } from '@angular/common';
+import { ToastrNotificationService } from '../toastr-notification-service.service';
+import { environment } from '../../environments/environment.prod';
+import { Observable, of, throwError } from 'rxjs';
+import { SearchRequest } from '../model/SearchRequest.model';
+import { DataService } from '../data.service'; // may be able to remove
+import { Process } from '../model/process.model';
+import { By } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { ProcessInstanceId } from '../model/processInstanceId.model';
+import { HttpResponse } from '@angular/common/http';
+import { Router } from '@angular/router';
+import { Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+import { DetailsComponent } from '../details/details.component';
+
+// Generate stub for toastr popup notifications
+class StubbedToastrNotificationService extends ToastrNotificationService {
+  toastrSettings() {}
+  info() {}
+  error() {}
+}
+
+const routes: Routes = [ { path: 'details/114e9ae4-4a32-11e9-8646-d663bd873d93' , component: DetailsComponent} ]
+
+describe('HomeComponent', () => {
+  let spyDataService: jasmine.SpyObj<DataService>;
+  let router: Router;
+  let component: HomeComponent;
+  let fixture: ComponentFixture<HomeComponent>;
+
+  beforeEach(() => {
+    spyDataService = jasmine.createSpyObj('DataService', ['retrieveInstance', 'getProcessInstanceId']);
+
+    TestBed.configureTestingModule({
+      providers: [
+        { provide: DataService, useValue: spyDataService },
+        { provide: APP_BASE_HREF, useValue: '/' },
+        { provide: ToastrNotificationService, useClass: StubbedToastrNotificationService }],
+      imports: [MatPaginatorModule, BrowserAnimationsModule, MatTableModule, FormsModule, MatDatepickerModule, MatNativeDateModule, HttpClientModule, RouterTestingModule.withRoutes(routes)],
+      declarations: [HomeComponent, DetailsComponent],
+      schemas: [
+        CUSTOM_ELEMENTS_SCHEMA
+      ]
+    });
+
+    fixture = TestBed.createComponent(HomeComponent);
+    router = TestBed.get(Router);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  // Ensure creation of HomeComponent component
+  it('component should be created', () => {
+    expect(component).toBeTruthy();
+  });
+
+  // Ensure all statistic variables are initialised to zero
+  it('should ensure statistic variables are defaulted at zero', () => {
+    expect(component.totalVal === 0 && component.completeVal === 0 &&
+      component.inProgressVal === 0 && component.failedVal === 0 &&
+      component.pendingVal === 0 && component.unlockedVal === 0 &&
+      component.percentageComplete === 0 && component.percentageFailed === 0 &&
+      component.percentageInProg === 0 && component.percentagePending === 0 &&
+      component.percentageUnlocked === 0).toBeTruthy();
+  });
+
+  it('should should navigate to a process if response status is OK', async(() => {
+      spyDataService.getProcessInstanceId.and.returnValue(of(<HttpResponse<ProcessInstanceId>>{body: {processInstanceId: '114e9ae4-4a32-11e9-8646-d663bd873d93'}, status: 200}));
+      spyOn(router, 'navigate');
+      component.getProcessIsntanceId('e8a75940-4a32-11e9-8646-d663bd873d93');
+
+      fixture.whenStable().then(() => {
+        expect(router.navigate).toHaveBeenCalledWith(['/details/114e9ae4-4a32-11e9-8646-d663bd873d93']);
+      });
+    }));
+
+  it('should handle error if no process instance id found', () => {
+    spyDataService.getProcessInstanceId.and.returnValue(of(<HttpResponse<ProcessInstanceId>>{body: {processInstanceId: 'getProcessInstanceId error not found'}, status: 404}));
+    component.getProcessIsntanceId('e8a75940-4a32-11e9-8646-d663bd873d93');
+  });
+
+  it('should handle error when searchData.getSearchRequest returns an error', () => {
+      spyOn(component.searchData, 'getSearchRequest').and.callFake(() => {
+        return throwError(new Error('getSearchRequest error'));
+      });
+      component.makeCall();
+  });
+
+  it('should handle error when dataService.retrieveInstance returns an error', () => {
+      spyOn(component.searchData, 'getSearchRequest').and.returnValue(of(getSearchRequest("965d3c92-44e0-11e9-b210-d663bd873d93", "85a7c354-44e0-11e9-b210-d663bd873d93", undefined, undefined, undefined, undefined, undefined, undefined, "ALL")));
+      spyDataService.retrieveInstance.and.callFake(() => {
+        return throwError(new Error('retrieveInstance error'));
+      });
+      component.makeCall();
+  });
+
+  it('should calculate statistics correctly', async(() => {
+    let requestStatusTypes: string[] = ["COMPLETE", "IN_PROGRESS", "FAILED", "PENDING", "UNLOCKED"];
+    let processArr: Process[] = [];
+
+    // create 5 processes, one of each requestStatusType, with default time.
+    requestStatusTypes.forEach((status) => {
+      let serviceName = "service-" + status;
+      var process = getProcess("85a7c354-44e0-11e9-b210-d663bd873d93", "965d3c92-44e0-11e9-b210-d663bd873d93", serviceName, "048a6212-44e1-11e9-b210-d663bd873d93", status, "TestType", undefined, undefined);
+      processArr.push(process);
+    })
+
+      // search request has default filter.
+      spyOn(component.searchData, 'getSearchRequest').and.returnValue(of(getSearchRequest(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, "ALL")));
+      spyDataService.retrieveInstance.and.returnValue(of(processArr));
+      component.makeCall();
+
+      fixture.whenStable().then(() => {
+        fixture.detectChanges();
+
+        expect(
+          component.totalVal === 5 && component.completeVal === 1 &&
+          component.inProgressVal === 1 && component.failedVal === 1 &&
+          component.pendingVal === 1 && component.unlockedVal === 1 &&
+          component.percentageComplete === 20 &&
+          component.percentageFailed === 20 &&
+          component.percentageInProg === 20 &&
+          component.percentagePending === 20 &&
+          component.percentageUnlocked === 20)
+          .toBeTruthy();
+      });
+    }));
+
+  function getSearchRequest(selectedValueSII = "EQ", serviceInstanceIdVal: string, selectedValueRI = "EQ", requestIdVal: string, selectedValueSN = "EQ", serviceInstanceNameVal: string, startTimeInMilliseconds = 0, endTimeInMilliseconds = 4, selectedValueSTATUS?: string): SearchRequest {
+    if (startTimeInMilliseconds > endTimeInMilliseconds) {
+      console.error("End time cannot be greater than start time.");
+      return undefined;
+    }
+    if (typeof selectedValueSTATUS === "string")
+      return new SearchRequest({ serviceInstanceId: [selectedValueSII, serviceInstanceIdVal], requestId: [selectedValueRI, requestIdVal], serviceInstanceName: [selectedValueSN, serviceInstanceNameVal], requestStatus: ["EQ", selectedValueSTATUS] }, startTimeInMilliseconds, endTimeInMilliseconds);
+    else
+      return new SearchRequest({ serviceInstanceId: [selectedValueSII, serviceInstanceIdVal], requestId: [selectedValueRI, requestIdVal], serviceInstanceName: [selectedValueSN, serviceInstanceNameVal] }, startTimeInMilliseconds, endTimeInMilliseconds);
+  }
+
+  function getProcess(requestIdVal: string, serviceInstanceIdVal: string, serviceIstanceNameVal: string, networkIdVal: string, requestStatusVal: string, serviceTypeVal: string, startTimeVal = "1", endTimeVal = "2"): Process {
+    return <Process>{ requestId: requestIdVal, serviceInstanceId: serviceInstanceIdVal, serviceIstanceName: serviceIstanceNameVal, networkId: networkIdVal, requestStatus: requestStatusVal, serviceType: serviceTypeVal, startTime: startTimeVal, endTime: endTimeVal };
+  }
+});