-/**\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 { DetailsComponent } from './details.component';\r
-import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\r
-import { RouterTestingModule } from '@angular/router/testing';\r
-import { MatTableModule } from '@angular/material';\r
-import { inject } from '@angular/core/testing';\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 { RouterModule } from '@angular/router';\r
-import { APP_BASE_HREF } from '@angular/common';\r
-import { ToastrNotificationService } from '../toastr-notification-service.service';\r
-import { DataService } from '../data.service';\r
-import { Observable, of } from 'rxjs';\r
-import { ACTINST } from '../model/activityInstance.model';\r
-import { PDI } from '../model/processDefinition.model';\r
-import { PII } from '../model/processInstance.model';\r
-import { VarInstance } from '../model/variableInstance.model';\r
-\r
-// Generate stub for toastr popup notifications\r
-class StubbedToastrNotificationService extends ToastrNotificationService {\r
- toastrSettings() {\r
- }\r
-}\r
-\r
-// Create SPY Object for Jasmine tests to mock DataService\r
-let spyDataService: jasmine.SpyObj<DataService>;\r
-\r
-describe('DetailsComponent', () => {\r
- beforeEach(async(() => {\r
- spyDataService = jasmine.createSpyObj('DataService', ['getActivityInstance', 'getVariableInstance']);\r
-\r
- TestBed.configureTestingModule({\r
- providers: [DetailsComponent, HttpClient, HttpTestingController,\r
- { provide: APP_BASE_HREF, useValue: '/' },\r
- { provide: ToastrNotificationService, useClass: StubbedToastrNotificationService },\r
- { provide: DataService, useValue: spyDataService }],\r
- imports: [RouterTestingModule, MatTableModule, HttpClientModule, RouterModule.forRoot([])],\r
- schemas: [\r
- CUSTOM_ELEMENTS_SCHEMA\r
- ]\r
- })\r
- .compileComponents();\r
- }));\r
-\r
- // Ensure creation of DetailsComponent component\r
- it('component should be created', inject([DetailsComponent],\r
- (detailsComponent: DetailsComponent) => {\r
- expect(detailsComponent).toBeTruthy();\r
- }));\r
-\r
-\r
- // Mock an activityInstance and ensure array is populated\r
- it('activityInstance should be defined if data service returns activities', inject([DetailsComponent],\r
- (detailsComponent: DetailsComponent) => {\r
- const activity: ACTINST = {\r
- activityId: "",\r
- processInstanceId: "",\r
- calledProcessInstanceId: "",\r
- activityName: "",\r
- activityType: "",\r
- durationInMillis: "1",\r
- endTime: "",\r
- startTime: ""\r
- };\r
- spyDataService.getActivityInstance.and.returnValue(of([activity]));\r
- detailsComponent.getActInst("");\r
- expect(detailsComponent.activityInstance.length).toEqual(1);\r
- }));\r
-\r
-\r
- // Create a processDefinition and ensure it is defined\r
- it('processDefinition should be defined if PDI populated', inject([DetailsComponent],\r
- (detailsComponent: DetailsComponent) => {\r
- const activity: PDI = {\r
- processDefinitionId: "1",\r
- processDefinitionXml: ""\r
- };\r
- detailsComponent.getProcessDefinition("");\r
- detailsComponent.processDefinition = activity;\r
- expect(detailsComponent.processDefinition).toBeDefined();\r
- }));\r
-\r
-\r
- // Create a processInstance and ensure it is defined\r
- it('processInstance should be defined if PII populated', inject([DetailsComponent],\r
- (detailsComponent: DetailsComponent) => {\r
- const testVals: PII = {\r
- processInstancId: "1",\r
- processDefinitionId: "1",\r
- processDefinitionName: "test",\r
- superProcessInstanceId: "1"\r
- };\r
- detailsComponent.getProcInstance("");\r
- detailsComponent.processInstance = testVals;\r
- expect(detailsComponent.processInstance).toBeDefined();\r
- }));\r
-\r
-\r
- // displayCamundaflow test\r
- // TODO\r
-\r
- // Mock an variableInstance and ensure array is populated\r
- it('variableInstance should be defined if data service returns activities', inject([DetailsComponent],\r
- (detailsComponent: DetailsComponent) => {\r
- const activity2: VarInstance = {\r
- name: "a",\r
- type: "a",\r
- value: "1"\r
- };\r
- spyDataService.getVariableInstance.and.returnValue(of([activity2]));\r
- detailsComponent.getVarInst("");\r
- expect(detailsComponent.variableInstance.length).toEqual(1);\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 { DetailsComponent } from './details.component';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+import { RouterTestingModule } from '@angular/router/testing';
+import { MatTableModule } from '@angular/material';
+import { inject } from '@angular/core/testing';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { HttpClientModule } from '@angular/common/http';
+import { HttpClient } from '@angular/common/http';
+import { RouterModule } from '@angular/router';
+import { APP_BASE_HREF } from '@angular/common';
+import { ToastrNotificationService } from '../toastr-notification-service.service';
+import { DataService } from '../data.service';
+import { Observable, of, throwError } from 'rxjs';
+import { ACTINST } from '../model/activityInstance.model';
+import { PDI } from '../model/processDefinition.model';
+import { PII } from '../model/processInstance.model';
+import { VarInstance } from '../model/variableInstance.model';
+import { ActivatedRoute } from '@angular/router';
+import { Params } from '@angular/router';
+
+// Generate stub for toastr popup notifications
+class StubbedToastrNotificationService extends ToastrNotificationService {
+ toastrSettings() {}
+ info() {}
+ error() {}
+}
+
+const startActivity: ACTINST = {
+ activityId: "StartEvent_1",
+ processInstanceId: "processInstanceId-val-1234",
+ calledProcessInstanceId: "",
+ activityName: "",
+ activityType: "",
+ durationInMillis: "1",
+ endTime: "",
+ startTime: ""
+};
+
+const subProcessActivity: ACTINST = {
+ activityId: "CallActivity_14h26ae",
+ processInstanceId: "processInstanceId-val-1234",
+ calledProcessInstanceId: "1234",
+ activityName: "",
+ activityType: "",
+ durationInMillis: "1",
+ endTime: "",
+ startTime: ""
+};
+
+const processDefinition: PDI = {
+ processDefinitionId: "processDefinitionId-val-1234",
+ processDefinitionXml: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+ "<bpmn:definitions xmlns:bpmn=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\" xmlns:di=\"http://www.omg.org/spec/DD/20100524/DI\" xmlns:dc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:camunda=\"http://camunda.org/schema/1.0/bpmn\" id=\"Definitions_01lwydo\" targetNamespace=\"http://bpmn.io/schema/bpmn\" exporter=\"Camunda Modeler\" exporterVersion=\"2.2.4\">" +
+ " <bpmn:process id=\"Process_1\" isExecutable=\"true\">" +
+ " <bpmn:startEvent id=\"StartEvent_1\">" +
+ " <bpmn:outgoing>SequenceFlow_1rrp6qt</bpmn:outgoing>" +
+ " </bpmn:startEvent>" +
+ " <bpmn:callActivity id=\"CallActivity_14h26ae\" name=\"Sub Process\" calledElement=\"DecomposeService\">" +
+ " <bpmn:incoming>SequenceFlow_1rrp6qt</bpmn:incoming>" +
+ " <bpmn:outgoing>SequenceFlow_0yvdjct</bpmn:outgoing>" +
+ " </bpmn:callActivity>" +
+ " <bpmn:sequenceFlow id=\"SequenceFlow_1rrp6qt\" sourceRef=\"StartEvent_1\" targetRef=\"CallActivity_14h26ae\" />" +
+ " <bpmn:endEvent id=\"EndEvent_039q5o1\">" +
+ " <bpmn:incoming>SequenceFlow_0yvdjct</bpmn:incoming>" +
+ " </bpmn:endEvent>" +
+ " <bpmn:sequenceFlow id=\"SequenceFlow_0yvdjct\" sourceRef=\"CallActivity_14h26ae\" targetRef=\"EndEvent_039q5o1\" />" +
+ " </bpmn:process>" +
+ " <bpmndi:BPMNDiagram id=\"BPMNDiagram_1\">" +
+ " <bpmndi:BPMNPlane id=\"BPMNPlane_1\" bpmnElement=\"Process_1\">" +
+ " <bpmndi:BPMNShape id=\"_BPMNShape_StartEvent_2\" bpmnElement=\"StartEvent_1\">" +
+ " <dc:Bounds x=\"173\" y=\"102\" width=\"36\" height=\"36\" />" +
+ " </bpmndi:BPMNShape>" +
+ " <bpmndi:BPMNShape id=\"CallActivity_14h26ae_di\" bpmnElement=\"CallActivity_14h26ae\">" +
+ " <dc:Bounds x=\"267\" y=\"80\" width=\"100\" height=\"80\" />" +
+ " </bpmndi:BPMNShape>" +
+ " <bpmndi:BPMNEdge id=\"SequenceFlow_1rrp6qt_di\" bpmnElement=\"SequenceFlow_1rrp6qt\">" +
+ " <di:waypoint x=\"209\" y=\"120\" />" +
+ " <di:waypoint x=\"267\" y=\"120\" />" +
+ " </bpmndi:BPMNEdge>" +
+ " <bpmndi:BPMNShape id=\"EndEvent_039q5o1_di\" bpmnElement=\"EndEvent_039q5o1\">" +
+ " <dc:Bounds x=\"451\" y=\"102\" width=\"36\" height=\"36\" />" +
+ " </bpmndi:BPMNShape>" +
+ " <bpmndi:BPMNEdge id=\"SequenceFlow_0yvdjct_di\" bpmnElement=\"SequenceFlow_0yvdjct\">" +
+ " <di:waypoint x=\"367\" y=\"120\" />" +
+ " <di:waypoint x=\"451\" y=\"120\" />" +
+ " </bpmndi:BPMNEdge>" +
+ " </bpmndi:BPMNPlane>" +
+ " </bpmndi:BPMNDiagram>" +
+ "</bpmn:definitions>"
+};
+
+const emptyProcessDefinition: PDI = {
+ processDefinitionId: "processDefinitionId-val",
+ processDefinitionXml: ""
+};
+
+const processInstance: PII = {
+ processInstancId: "processInstanceId-val-1234",
+ processDefinitionId: "1",
+ processDefinitionName: "test",
+ superProcessInstanceId: "1"
+};
+
+const varInstanceObj: VarInstance = {
+ name: 'ABC',
+ type: 'Object',
+ value: '{value: 1234}'
+};
+
+const varInstanceStr: VarInstance = {
+ name: 'NameStr',
+ type: 'String',
+ value: 'valOfStr'
+};
+
+describe('DetailsComponent', (displayCamundaflow = {}) => {
+ // Create SPY Object for Jasmine tests to mock DataService
+ let spyDataService: jasmine.SpyObj<DataService>;
+ let component: DetailsComponent;
+ let fixture: ComponentFixture<DetailsComponent>;
+
+ beforeEach(async(() => {
+ spyDataService = jasmine.createSpyObj('DataService', ['getActivityInstance', 'getVariableInstance', 'getProcessDefinition', 'getProcessInstance']);
+
+ TestBed.configureTestingModule({
+ providers: [DetailsComponent, HttpClient, HttpTestingController,
+ { provide: APP_BASE_HREF, useValue: '/' },
+ { provide: ToastrNotificationService, useClass: StubbedToastrNotificationService },
+ { provide: DataService, useValue: spyDataService },
+ { provide: ActivatedRoute, useValue: { params: of({ id: '1234' }) } }],
+ imports: [RouterTestingModule, MatTableModule, HttpClientModule, RouterModule.forRoot([])],
+ declarations: [DetailsComponent],
+ schemas: [
+ CUSTOM_ELEMENTS_SCHEMA
+ ]
+ });
+ fixture = TestBed.createComponent(DetailsComponent);
+ component = fixture.componentInstance;
+ }));
+
+ // Ensure creation of DetailsComponent component
+ it('component should be created', inject([DetailsComponent],
+ (detailsComponent: DetailsComponent) => {
+ expect(detailsComponent).toBeTruthy();
+ }));
+
+ // Create a processInstance and ensure it is defined
+ it('processInstance should be defined if PII populated', async(() => {
+ spyDataService.getActivityInstance.and.returnValue(Promise.resolve([startActivity, subProcessActivity]));
+ spyDataService.getProcessDefinition.and.returnValue(of(processDefinition));
+ spyDataService.getProcessInstance.and.returnValue(Promise.resolve(processInstance));
+ spyDataService.getVariableInstance.and.returnValue(of([varInstanceObj]));
+ component.ngOnInit();
+
+ fixture.whenStable().then(() => {
+ expect(component.processInstance).toBeDefined();
+ });
+ }));
+
+ it('should handle bpmnViewer.importXML error', () => {
+ spyDataService.getActivityInstance.and.returnValue(Promise.resolve([startActivity, subProcessActivity]));
+ spyDataService.getProcessDefinition.and.returnValue(of(emptyProcessDefinition));
+ spyDataService.getProcessInstance.and.returnValue(Promise.resolve(processInstance));
+ spyDataService.getVariableInstance.and.returnValue(of([varInstanceObj]));
+ component.ngOnInit();
+ });
+
+ it('should handle error when dataService.getProcessInstance returns an error', () => {
+ spyDataService.getVariableInstance.and.returnValue(of([varInstanceObj]));
+ spyDataService.getProcessInstance.and.returnValue(Promise.reject(new Error('getProcessInstance Promise should not be resolved')));
+ component.ngOnInit();
+ });
+
+ it('should handle error when data.getVariableInstance returns an error', () => {
+ spyDataService.getActivityInstance.and.returnValue(Promise.resolve([startActivity, subProcessActivity]));
+ spyDataService.getProcessDefinition.and.returnValue(of(processDefinition));
+ spyDataService.getProcessInstance.and.returnValue(Promise.resolve(processInstance));
+ spyDataService.getVariableInstance.and.callFake(() => {
+ return throwError(new Error('getVariableInstance error'));
+ });
+ component.ngOnInit();
+ });
+
+ it('should handle error when data.getActivityInstance and data.getProcessDefinition return errors', () => {
+ spyDataService.getProcessInstance.and.returnValue(Promise.resolve(processInstance));
+ spyDataService.getVariableInstance.and.returnValue(of([varInstanceObj]));
+ spyDataService.getProcessDefinition.and.returnValue(of(processDefinition));
+ spyDataService.getActivityInstance.and.returnValue(Promise.reject(new Error('getActivityInstance Promise should not be resolved')));
+ spyDataService.getProcessDefinition.and.callFake(() => {
+ return throwError(new Error('getProcessDefinition error'));
+ });
+ component.ngOnInit();
+ });
+});
<!-- Dropdown Filter and TextBox for Service Instance Id -->
<div class="container-home">
<mat-form-field class="selectFilter">
- <mat-select class="formatBox" [(ngModel)]="searchData.selectedValueSII" name="sel" placeholder="Select Filter">
+ <mat-select class="formatBox" [(value)]="searchData.selectedValueSII" placeholder="Select Filter">
<mat-option *ngFor="let option of options" [value]="option.value">{{option.name}}</mat-option>
</mat-select>
</mat-form-field>
<!-- Dropdown Filter and TextBox for Request Id -->
<div class="container-home">
<mat-form-field class="selectFilter">
- <mat-select class="formatBox" [(ngModel)]="searchData.selectedValueRI" name="sel" placeholder="Select Filter">
+ <mat-select class="formatBox" [(value)]="searchData.selectedValueRI" placeholder="Select Filter">
<mat-option *ngFor="let option of options" [value]="option.value">{{option.name}}</mat-option>
</mat-select>
</mat-form-field>
<!-- Dropdown box for Start Hour selection -->
<mat-form-field class="selectHour">
- <mat-select class="formatBox" [(ngModel)]="searchData.selectedStartHour" name="hourFrom" placeholder="Select Hour">
+ <mat-select class="formatBox" [(value)]="searchData.selectedStartHour" placeholder="Select Hour">
<mat-option *ngFor="let option of hourOptions" [value]="option">{{option}}</mat-option>
</mat-select>
</mat-form-field>
<!-- Dropdown box for Start Minute selection -->
<mat-form-field class="selectMinute">
- <mat-select class="formatBox" [(ngModel)]="searchData.selectedStartMinute" name="minuteFrom" placeholder="Select Minute">
+ <mat-select class="formatBox" [(value)]="searchData.selectedStartMinute" placeholder="Select Minute">
<mat-option *ngFor="let option of minuteOptions" [value]="option">{{option}}</mat-option>
</mat-select>
</mat-form-field>
<!-- Dropdown Filter and TextBox for Service Name -->
<div class="container-home">
<mat-form-field class="selectFilter">
- <mat-select class="formatBox" [(ngModel)]="searchData.selectedValueSN" name="sel" placeholder="Select Filter">
+ <mat-select class="formatBox" [(value)]="searchData.selectedValueSN" placeholder="Select Filter">
<mat-option *ngFor="let option of options" [value]="option.value">{{option.name}}</mat-option>
</mat-select>
</mat-form-field>
<!-- Dropdown box for End Hour selection -->
<mat-form-field class="selectHour">
- <mat-select class="formatBox" [(ngModel)]="searchData.selectedEndHour" name="hourTo" placeholder="Select Hour">
+ <mat-select class="formatBox" [(value)]="searchData.selectedEndHour" placeholder="Select Hour">
<mat-option *ngFor="let option of hourOptions" [value]="option">{{option}}</mat-option>
</mat-select>
</mat-form-field>
<!-- Dropdown box for End Minute selection -->
<mat-form-field class="selectMinute">
- <mat-select class="formatBox" [(ngModel)]="searchData.selectedEndMinute" name="minuteTo" placeholder="Select Minute">
+ <mat-select class="formatBox" [(value)]="searchData.selectedEndMinute" placeholder="Select Minute">
<mat-option *ngFor="let option of minuteOptions" [value]="option">{{option}}</mat-option>
</mat-select>
</mat-form-field>
<!-- Dropdown Filter for Status -->
<div class="container-home">
<mat-form-field class="selectFilter">
- <mat-select class="formatBox" [(ngModel)]="searchData.selectedValueSTATUS" name="sel" placeholder="Status">
+ <mat-select class="formatBox" [(value)]="searchData.selectedValueSTATUS" placeholder="Status">
<mat-option *ngFor="let statusOption of statusOptions" [value]="statusOption.value">{{ statusOption.name }}</mat-option>
</mat-select>
</mat-form-field>
-/**\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 };
+ }
+});
--- /dev/null
+/**
+============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: andrei.barcovschi@ericsson.com
+*/
+
+import { SearchData } from './searchData.model';
+import { SearchRequest } from './SearchRequest.model';
+import { Observable, throwError } from 'rxjs';
+
+describe('SearchData', () => {
+ let searchRequest: SearchRequest;
+ let searchData: SearchData;
+
+ beforeEach(() => {
+ searchData = new SearchData();
+ });
+
+ it('should return a SearchRequest observable with selectedValueSTATUS != ALL', () => { // NOT ALL CHANGE TEST TO TEST THIS ISNTESASD
+ searchData.serviceInstanceId = "bd827d8c-4b07-11e9-8646-d663bd873d93";
+ searchData.requestId = "cf1343d8-4b07-11e9-8646-d663bd873d93";
+ searchData.serviceInstanceName = "service-123";
+ searchData.selectedValueSTATUS = "COMPLETE";
+
+ searchData.getSearchRequest().subscribe((request: SearchRequest) => {
+ searchRequest = request;
+ });
+ let filters = searchRequest.getFilters();
+ expect(searchRequest.getFilters()).toEqual({ serviceInstanceId: [ 'EQ', 'bd827d8c-4b07-11e9-8646-d663bd873d93' ],
+ requestId: [ 'EQ', 'cf1343d8-4b07-11e9-8646-d663bd873d93' ],
+ serviceInstanceName: [ 'EQ', 'service-123' ],
+ requestStatus: [ 'EQ', 'COMPLETE' ]
+ });
+ expect(searchRequest.getStartTimeInMilliseconds()).toBe(searchData.startDate.getTime());
+ expect(searchRequest.getEndTimeInMilliseconds()).toBe(searchData.endDate.getTime());
+ });
+
+ it('should throw an error if found incorrect start or end date', () => {
+ searchData.startDate = null;
+ searchData.endDate = undefined;
+ searchData.getSearchRequest().subscribe({
+ error: (err) => {
+ expect(err).toEqual('Found end or start date empty, Please enter start and end date')
+ }
+ });
+ });
+
+ it('should throw an error if startTimeInMilliseconds > endTimeInMilliseconds', () => {
+ searchData.startDate = new Date('March 20, 2019 02:00:00');
+ searchData.endDate = new Date('March 20, 2019 01:00:00');
+ searchData.selectedStartHour = '02';
+ searchData.selectedEndHour = '01';
+ searchData.selectedStartMinute = '00';
+ searchData.selectedEndMinute = '00';
+
+ searchData.getSearchRequest().subscribe({
+ error: (err) => {
+ expect(err).toEqual("End time: " + searchData.endDate + " can not be greater then start time: " + searchData.startDate)
+ }
+ });
+ });
+});