blob: 1ba71a774efbe9aa206d69fbb24235a6d1a11687 [file] [log] [blame]
/*
******************************************************************************
* Copyright © 2018 PTA GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*
******************************************************************************
*/
/* tslint:disable:no-unused-variable */
import { EventEmitter } from '@angular/core';
import { ComponentFixture, TestBed, async, fakeAsync, tick } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { DaterangepickerConfig } from 'ng2-daterangepicker';
import { StringToDatePipe } from '../../common-components/pipes/string-to-date.pipe';
import { SessionContext } from '../../common/session-context';
import { GridMeasure } from '../../model/grid-measure';
import { LockHelperService } from './../../services/lock-helper.service';
import { RoleAccess } from '../../model/role-access';
import { GridMeasureService } from '../../services/grid-measure.service';
import { GRIDMEASURE } from '../../test-data/grid-measures';
import { USERS } from '../../test-data/users';
import { AbstractMockObservableService } from '../../testing/abstract-mock-observable.service';
import { MockComponent } from '../../testing/mock.component';
import { ActivatedRouteStub, RouterStub } from '../../testing/router-stubs';
import { GridMeasureDetailComponent } from './grid-measure-detail.component';
import { Globals } from '../../common/globals';
import { RoleAccessHelperService } from '../../services/jobs/role-access-helper.service';
import { ModeValidator } from '../../custom_modules/helpers/mode-validator';
import { BaseDataLoaderService } from '../../services/jobs/base-data-loader.service';
import { ToasterMessageService } from '../../services/toaster-message.service';
import { MessageService } from 'primeng/api';
class FakeRouter {
navigate(commands: any[]) {
return commands[0];
}
}
describe('GridMeasureDetailComponent', () => {
let component: GridMeasureDetailComponent;
let fixture: ComponentFixture<GridMeasureDetailComponent>;
const gridmeasures: GridMeasure[] = JSON.parse(JSON.stringify(GRIDMEASURE));
let routerStub: RouterStub;
let activatedStub: ActivatedRouteStub;
// let router: Router;
routerStub = {
navigate: jasmine.createSpy('navigate').and.callThrough()
};
class MockService extends AbstractMockObservableService {
storeGridMeasure() {
return this;
}
getGridMeasure(id: number) {
return this;
}
}
class MockDocumentService extends AbstractMockObservableService {
public uploadGridMeasureAttachments(gridmeasuereId: number, file: File) {
return this;
}
public getGridMeasureAttachments(gridmeasuereId: number) {
return this;
}
public deleteGridMeasureAttachment(documentId: number, index: number) {
return this;
}
public downloadGridMeasureAttachment(documentId: number) {
return this;
}
}
class MockLockService extends AbstractMockObservableService {
checkLockedByUser(measureId: number, lockType: string, lockedByOtherEmitter$: EventEmitter<boolean>) {
lockedByOtherEmitter$.emit(this.content);
}
createLock(gridmeasureId: number, lockType: string) {
return this;
}
deleteLock(measureId: number, lockType: string) {
return this;
}
}
let toasterMessageService: ToasterMessageService;
let messageService: MessageService;
let mockService: MockService;
let mockDocService: MockDocumentService;
let mockLockHelperService: MockLockService;
let sessionContext: SessionContext;
let roleAccessHelper: RoleAccessHelperService;
beforeEach(async(() => {
activatedStub = new ActivatedRouteStub();
sessionContext = new SessionContext();
messageService = new MessageService;
mockService = new MockService();
mockDocService = new MockDocumentService();
mockLockHelperService = new MockLockService();
toasterMessageService = new ToasterMessageService(sessionContext, messageService);
roleAccessHelper = new RoleAccessHelperService();
TestBed.configureTestingModule({
imports: [
FormsModule
],
declarations: [
GridMeasureDetailComponent,
StringToDatePipe,
MockComponent({ selector: 'input', inputs: ['options'] }),
MockComponent({ selector: 'app-grid-measures', inputs: ['gridId', 'withEditButtons'] }),
MockComponent({ selector: 'app-loading-spinner', inputs: [] }),
MockComponent({
selector: 'app-buttons-container',
inputs: ['activeButtons', 'isValidForm', 'isValidForSave', 'isReadOnlyForm', 'gridMeasureStatusId', 'gridMeasureId']
}),
MockComponent({
selector: 'app-single-grid-measure-detail-tab',
inputs: ['isReadOnlyForm', 'singleGridMeasure', 'gridMeasureDetail', 'dateTimePattern',
'dateFormatLocale', 'tabIndex', 'showSpinnerSingleGrid']
}),
MockComponent({
selector: 'app-grid-measure-detail-tab',
inputs: ['showSpinnerGrid', 'gridMeasureDetail', 'readOnlyForm']
}),
MockComponent({
selector: 'app-email-distribution-entry',
inputs: ['isReadOnlyForm', 'gridMeasureDetail']
}),
MockComponent({
selector: 'app-email-distribution-list',
inputs: ['gridId', 'withEditButtons', 'gridMeasureDetail']
}),
MockComponent({
selector: 'app-status-changes',
inputs: ['gridId', 'withEditButtons', 'gridMeasureDetail']
}),
MockComponent({
selector: 'app-grid-measure-detail-header',
inputs: ['showSpinnerGrid', 'gridMeasureDetail', 'isReadOnlyForm']
})
],
providers: [
SessionContext,
ModeValidator,
{ provide: ActivatedRoute, useValue: activatedStub },
{ provide: Router, useValue: routerStub },
{ provide: GridMeasureService, useValue: mockService },
{ provide: LockHelperService, useValue: mockLockHelperService },
// { provide: DocumentService, useValue: mockDocService },
{ provide: BaseDataLoaderService, useValue: {} },
{ provide: DaterangepickerConfig, useClass: DaterangepickerConfig },
{ provide: RoleAccessHelperService, useValue: roleAccessHelper },
{ provide: ToasterMessageService, useValue: toasterMessageService }
]
}).compileComponents();
}));
beforeEach(async(() => {
sessionContext.setCurrUser(USERS[0]);
sessionContext.setAllUsers(USERS);
// we need to init the component and the path... because of OnInit
mockService.content = JSON.parse(JSON.stringify(GRIDMEASURE[0]));
mockDocService.content = [{ id: 1, documentName: 'docdoc.doc' }];
const roleAcess: RoleAccess = {
editRoles: [{
name: 'planned-policies-measureplanner',
gridMeasureStatusIds: [
0,
1
]
}, {
name: 'planned-policies-superuser',
gridMeasureStatusIds: [
0,
1
]
}, {
name: 'planned-policies-measureapplicant',
gridMeasureStatusIds: [
0,
1
]
}],
controls: [{
gridMeasureStatusId: 0,
activeButtons: [
'save',
'apply',
'cancel'
],
inactiveFields: [
'titeldermassnahme'
]
},
{
gridMeasureStatusId: 1,
activeButtons: [
'save',
'cancel',
'forapproval'
],
inactiveFields: [
'titeldermassnahme'
]
}],
stornoSection:
{
'stornoRoles': [
'planned-policies-measureapplicant',
'planned-policies-measureplanner',
'planned-policies-measureapprover',
'planned-policies-requester',
'planned-policies-clearance'
]
},
duplicateSection:
{
'duplicateRoles': [
'planned-policies-measureapplicant'
]
}
};
roleAccessHelper.init(roleAcess);
activatedStub.testParams = { id: 555, mode: Globals.MODE.EDIT };
fixture = TestBed.createComponent(GridMeasureDetailComponent);
fixture.whenStable().then(() => {
component = fixture.componentInstance;
component.id = activatedStub.testParams['id'];
fixture.detectChanges();
});
}));
it('should create', (() => {
expect(component).toBeTruthy();
}));
it('should go to overview if the url is not edit or view', async(() => {
spyOn(component, 'goToOverview').and.callThrough();
fixture.detectChanges();
activatedStub.testParams = { id: 555, mode: 'bla' };
fixture.whenRenderingDone().then(() => {
fixture.detectChanges();
expect(component.goToOverview).toHaveBeenCalled();
});
}));
it('should stop spinner and create a new grid measure if no id', async(() => {
component.id = undefined;
spyOn((component as any), 'checkModeAndInitiateGm').and.callThrough();
(component as any).checkModeAndInitiateGm('bla', false, undefined);
fixture.whenRenderingDone().then(() => {
fixture.detectChanges();
expect((component as any).checkModeAndInitiateGm).toHaveBeenCalledWith('bla', false, undefined);
expect(component.showSpinner).toBeFalsy();
});
}));
it('should set status to new for a newly created gridmeasure', async(() => {
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
component.gridMeasureDetail.statusId = NaN;
component.storageInProgress = true;
(component as any).createGridMeasure();
fixture.detectChanges();
component.storageInProgress = false;
(component as any).createGridMeasure();
fixture.detectChanges();
fixture.whenRenderingDone().then(() => {
fixture.detectChanges();
expect((component as any).gridMeasureDetail.statusId).toBe(Globals.STATUS.NEW);
});
}));
it('should call createNewSingleGridMeasureTab on button click', () => {
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
expect(component.gridMeasureDetail.listSingleGridmeasures.length).toBe(2);
component.disableNewTabBtn = false;
spyOn(component, 'createNewSingleGridMeasureTab').and.callThrough();
fixture.detectChanges();
fixture.whenStable().then(() => {
const button = fixture.debugElement.nativeElement.querySelector('#newSingleGridMeasureBtn');
button.click();
fixture.detectChanges();
expect(component.createNewSingleGridMeasureTab).toHaveBeenCalled();
expect(component.gridMeasureDetail.listSingleGridmeasures.length).toBe(3);
});
});
it('should createNewSingleGridMeasureTab if limit is not reached', () => {
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
expect(component.gridMeasureDetail.listSingleGridmeasures.length).toBe(2);
component.createNewSingleGridMeasureTab();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.gridMeasureDetail.listSingleGridmeasures.length).toBe(3);
});
});
it('should not createNewSingleGridMeasureTab if limit is reached', () => {
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
const actualNumberOfSingleGridMeasureTabs = component.gridMeasureDetail.listSingleGridmeasures.length - 1;
for (let i = actualNumberOfSingleGridMeasureTabs; i < Globals.MAX_NUMBER_OF_TABS; i++) {
component.createNewSingleGridMeasureTab();
}
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.gridMeasureDetail.listSingleGridmeasures.length).toBe(Globals.MAX_NUMBER_OF_TABS);
});
});
it('should handle a service error correctly after create gridmeasure called', fakeAsync(() => {
spyOn(console, 'log').and.callThrough();
spyOn(mockService, 'storeGridMeasure').and.callThrough();
mockService.content = JSON.parse(JSON.stringify(gridmeasures[2]));
mockService.error = 'Error';
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
component.storageInProgress = false;
(component as any).createGridMeasure();
fixture.detectChanges();
expect(console.log).toHaveBeenCalled();
}));
it('should disable save button on init with no values in required fields', () => {
component.gridMeasureDetail = {};
(component as any).onReceiveGridMeasureDetail();
fixture.whenRenderingDone().then(() => {
fixture.detectChanges();
expect((component as any).validForSave).toBeFalsy('valid for save should be true');
});
});
it('should disable apply button on init with no values in required fields', async(() => {
component.gridMeasureDetail = {};
(component as any).onReceiveGridMeasureDetail();
fixture.detectChanges();
fixture.whenRenderingDone().then(() => {
fixture.detectChanges();
expect((component as any).validForm).toBeFalsy('Form not valid');
});
}));
it('should enable apply button after filling all required fields', async(() => {
component.gridMeasureDetail = gridmeasures[0];
(component as any).onReceiveGridMeasureDetail();
fixture.detectChanges();
fixture.whenRenderingDone().then(() => {
fixture.detectChanges();
expect((component as any).validForm).toBeFalsy('apply button is enabled');
});
}));
it('should navigate to Overview after click on abortbutton', () => {
spyOn(component, 'goToOverview').and.callThrough();
fixture.detectChanges();
component.goToOverview();
fixture.detectChanges();
expect(component.goToOverview).toHaveBeenCalled();
expect(routerStub.navigate).toHaveBeenCalledWith(['/overview']);
});
it('should not call delete lock after click on abortbutton for new unsaved gridmeasure', () => {
spyOn(mockLockHelperService, 'deleteLock');
spyOn(component, 'goToOverview').and.callThrough();
component.readOnlyForm = false;
component.id = undefined;
fixture.detectChanges();
fixture.whenStable().then(() => {
const button = fixture.debugElement.nativeElement.querySelector('button#abortButton');
button.click();
fixture.detectChanges();
expect(mockLockHelperService.deleteLock).toHaveBeenCalled();
expect(routerStub.navigate).toHaveBeenCalledWith(['/overview']);
});
});
it('should create a GridMeasure after click on applybutton', async(() => {
spyOn(mockService, 'storeGridMeasure').and.callThrough();
mockService.content = JSON.parse(JSON.stringify(gridmeasures[2]));
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
component.storageInProgress = true;
fixture.detectChanges();
component.updateGridMeasureStatus(Globals.STATUS.APPLIED);
expect(mockService.storeGridMeasure).not.toHaveBeenCalled();
component.storageInProgress = false;
fixture.detectChanges();
component.updateGridMeasureStatus(Globals.STATUS.APPLIED);
expect(mockService.storeGridMeasure).toHaveBeenCalled();
}));
it('should handle a service error correctly after applybutton', fakeAsync(() => {
spyOn(console, 'log').and.callThrough();
mockService.error = 'Error';
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
fixture.detectChanges();
tick();
component.updateGridMeasureStatus(Globals.STATUS.APPLIED);
tick();
expect(console.log).toHaveBeenCalled();
}));
it('should be able to set for approval a GridMeasure', async(() => {
spyOn(mockService, 'storeGridMeasure').and.callThrough();
mockService.content = gridmeasures[2];
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
component.gridMeasureDetail.statusId = Globals.STATUS.APPLIED;
fixture.detectChanges();
component.updateGridMeasureStatus(Globals.STATUS.FORAPPROVAL);
expect(mockService.storeGridMeasure).toHaveBeenCalled();
expect(component.gridMeasureDetail.statusId).toBe(Globals.STATUS.FORAPPROVAL);
}));
it('should handle a service error correctly after forapproval button', fakeAsync(() => {
spyOn(console, 'log').and.callThrough();
mockService.error = 'Error';
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
fixture.detectChanges();
tick();
component.updateGridMeasureStatus(Globals.STATUS.FORAPPROVAL);
tick();
expect(console.log).toHaveBeenCalled();
}));
it('should be able to approve a GridMeasure', async(() => {
spyOn(mockService, 'storeGridMeasure').and.callThrough();
mockService.content = gridmeasures[2];
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
component.gridMeasureDetail.statusId = Globals.STATUS.FORAPPROVAL;
fixture.detectChanges();
component.updateGridMeasureStatus(Globals.STATUS.APPROVED);
expect(mockService.storeGridMeasure).toHaveBeenCalled();
expect(component.gridMeasureDetail.statusId).toBe(Globals.STATUS.APPROVED);
}));
it('should handle a service error correctly after approve button', fakeAsync(() => {
spyOn(console, 'log').and.callThrough();
mockService.error = 'Error';
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
fixture.detectChanges();
tick();
component.updateGridMeasureStatus(Globals.STATUS.APPROVED);
tick();
expect(console.log).toHaveBeenCalled();
}));
it('should be able to send back a GridMeasure', async(() => {
spyOn(mockService, 'storeGridMeasure').and.callThrough();
mockService.content = gridmeasures[2];
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
component.gridMeasureDetail.statusId = Globals.STATUS.FORAPPROVAL;
fixture.detectChanges();
component.updateGridMeasureStatus(Globals.STATUS.APPLIED);
expect(mockService.storeGridMeasure).toHaveBeenCalled();
expect(component.gridMeasureDetail.statusId).toBe(Globals.STATUS.APPLIED);
}));
it('should handle a service error correctly after reject button', fakeAsync(() => {
spyOn(console, 'log').and.callThrough();
mockService.error = 'Error';
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
fixture.detectChanges();
tick();
component.updateGridMeasureStatus(Globals.STATUS.APPLIED);
tick();
expect(console.log).toHaveBeenCalled();
}));
it('should be able to cancel a GridMeasure', async(() => {
spyOn(mockService, 'storeGridMeasure').and.callThrough();
mockService.content = gridmeasures[2];
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
component.gridMeasureDetail.statusId = Globals.STATUS.APPROVED;
fixture.detectChanges();
component.updateGridMeasureStatus(Globals.STATUS.CANCELED);
expect(mockService.storeGridMeasure).toHaveBeenCalled();
expect(component.gridMeasureDetail.statusId).toBe(Globals.STATUS.CANCELED);
}));
it('should handle a service error correctly after cancel button', fakeAsync(() => {
spyOn(console, 'log').and.callThrough();
mockService.error = 'Error';
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
fixture.detectChanges();
tick();
component.updateGridMeasureStatus(Globals.STATUS.CANCELED);
tick();
expect(console.log).toHaveBeenCalled();
}));
it('should create a GridMeasure after click on savebutton', async(() => {
mockService.content = gridmeasures[2];
spyOn(mockService, 'storeGridMeasure').and.callThrough();
fixture.detectChanges();
component.createGridMeasure();
expect(mockService.storeGridMeasure).toHaveBeenCalled();
}));
it('should checkLockedByUser correctly when form is writable', fakeAsync(() => {
spyOn(mockLockHelperService, 'createLock').and.callThrough();
component.viewModeReadOnly = false;
mockLockHelperService.content = false;
component.checkLockedByUser();
tick();
fixture.detectChanges();
expect(mockLockHelperService.createLock).toHaveBeenCalled();
expect(component.showSpinner).toBeFalsy();
}));
it('should deleteLock correctly when not readonly form', fakeAsync(() => {
spyOn(mockLockHelperService, 'deleteLock').and.callThrough();
component.readOnlyForm = false;
mockLockHelperService.content = false;
component.deleteLock(false, null);
tick();
fixture.detectChanges();
expect(mockLockHelperService.deleteLock).toHaveBeenCalled();
}));
it('should deleteLock correctly when form is readonly', fakeAsync(() => {
spyOn(mockLockHelperService, 'deleteLock').and.callThrough();
component.readOnlyForm = true;
mockLockHelperService.content = false;
component.deleteLock(false, null);
tick();
fixture.detectChanges();
expect(mockLockHelperService.deleteLock).not.toHaveBeenCalled();
}));
it('should handle onUnlock correctly', fakeAsync(() => {
const testableComp: any = component;
spyOn(component, 'deleteLock').and.callThrough();
spyOn(component, 'recheckLockedByUser').and.callThrough();
mockService.error = 'Error';
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
fixture.detectChanges();
tick();
testableComp.unlockInProgress = false;
component.onUnlock(false);
tick();
expect(testableComp.unlockInProgress).toBeTruthy();
expect(component.deleteLock).not.toHaveBeenCalled();
tick();
component.onUnlock(true);
expect(component.recheckLockedByUser).not.toHaveBeenCalled();
component.recheckLockedByUser();
expect(testableComp.unlockInPorgress).toBeFalsy();
component.onUnlock(true);
tick();
expect(component.deleteLock).toHaveBeenCalled();
}));
it('should navigate to cancle page if cancel button clicked', async(() => {
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
spyOn(component, 'goToCancelPage').and.callThrough();
fixture.detectChanges();
component.goToCancelPage();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(routerStub.navigate).toHaveBeenCalled();
});
}));
it('should try to duplicate a gm if duplicate button clicked', async(() => {
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
component.storageInProgress = true;
fixture.detectChanges();
spyOn(component, 'duplicateGM').and.callThrough();
fixture.detectChanges();
component.duplicateGM();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.duplicateGM).toHaveBeenCalled();
});
}));
it('should navigate to the right grid measure after duplication', async(() => {
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
fixture.detectChanges();
spyOn((component as any), 'navigateAfterCreate').and.callThrough();
fixture.detectChanges();
(component as any).navigateAfterCreate(true, component.gridMeasureDetail);
fixture.detectChanges();
fixture.whenRenderingDone().then(() => {
expect((component as any).navigateAfterCreate).toHaveBeenCalled();
expect(routerStub.navigate).toHaveBeenCalledWith(['/overview']);
setTimeout(() => {
expect(routerStub.navigate).toHaveBeenCalledWith(['/gridMeasureDetail/', component.gridMeasureDetail.id, Globals.MODE.EDIT]);
}, 500);
});
}));
it('should navigate to overview after created new grid measure (not duplicate)', async(() => {
component.gridMeasureDetail = JSON.parse(JSON.stringify(gridmeasures[0]));
fixture.detectChanges();
spyOn((component as any), 'navigateAfterCreate').and.callThrough();
fixture.detectChanges();
(component as any).navigateAfterCreate(false, component.gridMeasureDetail);
fixture.detectChanges();
fixture.whenRenderingDone().then(() => {
expect((component as any).navigateAfterCreate).toHaveBeenCalled();
expect(routerStub.navigate).toHaveBeenCalledWith(['/overview']);
});
}));
});