alfresco-ng2-components/lib/process-services/form/start-form.component.spec.ts
Silviu Popa cf68f656cf [NO_ISSUE] - fix unit test on process-services (#4732)
* [NO_ISSUE] - fix unit test on process-services

* [NO_ISSUE] - lint

* remove unused code
2019-05-16 10:09:26 +01:00

455 lines
23 KiB
TypeScript

/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* 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 { CUSTOM_ELEMENTS_SCHEMA, SimpleChange } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { of, throwError } from 'rxjs';
import { startFormDateWidgetMock, startFormDropdownDefinitionMock, startFormTextDefinitionMock, startMockForm, startMockFormWithTab } from '../../core/mock';
import { startFormAmountWidgetMock, startFormNumberWidgetMock, startFormRadioButtonWidgetMock } from '../../core/mock';
import { StartFormComponent } from './start-form.component';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { FormService, WidgetVisibilityService, setupTestBed, CoreModule, FormModel, FormOutcomeModel } from '@alfresco/adf-core';
import { TranslateService } from '@ngx-translate/core';
describe('StartFormComponent', () => {
let formService: FormService;
let component: StartFormComponent;
let fixture: ComponentFixture<StartFormComponent>;
let getStartFormSpy: jasmine.Spy;
let visibilityService: WidgetVisibilityService;
let translate: TranslateService;
const exampleId1 = 'my:process1';
const exampleId2 = 'my:process2';
setupTestBed({
imports: [
NoopAnimationsModule,
CoreModule.forRoot()
],
declarations: [
StartFormComponent
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
});
beforeEach(() => {
fixture = TestBed.createComponent(StartFormComponent);
component = fixture.componentInstance;
formService = TestBed.get(FormService);
visibilityService = TestBed.get(WidgetVisibilityService);
translate = TestBed.get(TranslateService);
getStartFormSpy = spyOn(formService, 'getStartFormDefinition').and.returnValue(of({
processDefinitionName: 'my:process'
}));
spyOn(translate, 'instant').and.callFake((key) => { return key; });
spyOn(translate, 'get').and.callFake((key) => { return of(key); });
});
afterEach(() => {
fixture.destroy();
});
it('should load start form on change if processDefinitionId defined', () => {
component.processDefinitionId = exampleId1;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
expect(formService.getStartFormDefinition).toHaveBeenCalled();
});
it('should load start form when processDefinitionId changed', () => {
component.processDefinitionId = exampleId1;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
expect(formService.getStartFormDefinition).toHaveBeenCalled();
});
it('should check visibility when the start form is loaded', () => {
spyOn(visibilityService, 'refreshVisibility');
component.processDefinitionId = exampleId1;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
expect(formService.getStartFormDefinition).toHaveBeenCalled();
expect(visibilityService.refreshVisibility).toHaveBeenCalled();
});
it('should not load start form when changes notified but no change to processDefinitionId', () => {
component.processDefinitionId = exampleId1;
component.ngOnChanges({ otherProp: new SimpleChange(exampleId1, exampleId2, true) });
expect(formService.getStartFormDefinition).not.toHaveBeenCalled();
});
it('should consume errors encountered when loading start form', () => {
getStartFormSpy.and.returnValue(throwError({}));
component.processDefinitionId = exampleId1;
component.ngOnInit();
});
it('should show outcome buttons by default', () => {
getStartFormSpy.and.returnValue(of({
id: '1',
processDefinitionName: 'my:process',
outcomes: [{
id: 'approve',
name: 'Approve'
}]
}));
component.processDefinitionId = exampleId1;
component.ngOnInit();
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.detectChanges();
expect(component.outcomesContainer).toBeTruthy();
});
it('should show outcome buttons if showOutcomeButtons is true', () => {
getStartFormSpy.and.returnValue(of({
id: '1',
processDefinitionName: 'my:process',
outcomes: [{
id: 'approve',
name: 'Approve'
}]
}));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.detectChanges();
expect(component.outcomesContainer).toBeTruthy();
});
it('should fetch start form details by processDefinitionId ', () => {
getStartFormSpy.and.returnValue(of(startMockForm));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.detectChanges();
expect(component.outcomesContainer).toBeTruthy();
expect(getStartFormSpy).toHaveBeenCalled();
});
describe('Display widgets', () => {
it('should be able to display a textWidget from a process definition', () => {
getStartFormSpy.and.returnValue(of(startFormTextDefinitionMock));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const formFields = component.form.getFormFields();
const labelField = formFields.find((field) => field.id === 'mocktext');
const textWidget = fixture.debugElement.nativeElement.querySelector('text-widget');
const textWidgetLabel = fixture.debugElement.nativeElement.querySelector('.adf-label');
expect(labelField.type).toBe('text');
expect(textWidget).toBeDefined();
expect(textWidgetLabel.innerText).toBe('mockText');
});
});
it('should be able to display a radioButtonWidget from a process definition', () => {
getStartFormSpy.and.returnValue(of(startFormRadioButtonWidgetMock));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const formFields = component.form.getFormFields();
const labelField = formFields.find((field) => field.id === 'radio-but');
const radioButtonWidget = fixture.debugElement.nativeElement.querySelector('radio-buttons-widget');
const radioButtonWidgetLabel = fixture.debugElement.nativeElement.querySelector('.adf-input');
expect(labelField.type).toBe('radio-buttons');
expect(radioButtonWidget).toBeDefined();
expect(radioButtonWidgetLabel.innerText).toBe('radio-buttons');
});
});
it('should be able to display a amountWidget from a process definition', () => {
getStartFormSpy.and.returnValue(of(startFormAmountWidgetMock));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const formFields = component.form.getFormFields();
const labelField = formFields.find((field) => field.id === 'amount');
const amountWidget = fixture.debugElement.nativeElement.querySelector('amount-widget');
const amountWidgetLabel = fixture.debugElement.nativeElement.querySelector('.adf-input');
expect(labelField.type).toBe('amount');
expect(amountWidget).toBeDefined();
expect(amountWidgetLabel.innerText).toBe('amount');
});
});
it('should be able to display a numberWidget from a process definition', () => {
getStartFormSpy.and.returnValue(of(startFormNumberWidgetMock));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const formFields = component.form.getFormFields();
const labelField = formFields.find((field) => field.id === 'number');
const numberWidget = fixture.debugElement.nativeElement.querySelector('number-widget');
expect(labelField.type).toBe('integer');
expect(numberWidget).toBeDefined();
});
});
it('should be able to display a dropDown Widget from a process definition', () => {
getStartFormSpy.and.returnValue(of(startFormDropdownDefinitionMock));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const formFields = component.form.getFormFields();
const labelField = formFields.find((field) => field.id === 'mockTypeDropDown');
const dropDownWidget = fixture.debugElement.nativeElement.querySelector('dropdown-widget');
const selectElement = fixture.debugElement.nativeElement.querySelector('.adf-dropdown-widget>mat-select .mat-select-trigger');
selectElement.click();
expect(selectElement).toBeDefined();
expect(dropDownWidget).toBeDefined();
expect(selectElement.innerText).toBe('Choose one...');
expect(labelField.type).toBe('dropdown');
expect(labelField.options[0].name).toBe('Chooseone...');
expect(labelField.options[1].name).toBe('Option-1');
expect(labelField.options[2].name).toBe('Option-2');
});
});
it('should be able to display a date Widget from a process definition', () => {
getStartFormSpy.and.returnValue(of(startFormDateWidgetMock));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const formFields = component.form.getFormFields();
const labelField = formFields.find((field) => field.id === 'date');
const dateWidget = fixture.debugElement.nativeElement.querySelector('dropdown-widget');
const dateLabelElement = fixture.debugElement.nativeElement.querySelector('#data-widget .mat-form-field-infix> .adf-label');
expect(dateWidget).toBeDefined();
expect(labelField.type).toBe('date');
expect(dateLabelElement.innerText).toBe('date (D-M-YYYY)');
});
});
it('should fetch and define form fields with proper type', () => {
getStartFormSpy.and.returnValue(of(startMockForm));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
const formFields = component.form.getFormFields();
const labelField = formFields.find((field) => field.id === 'billdate');
expect(labelField.type).toBe('date');
const formFields1 = component.form.getFormFields();
const labelField1 = formFields1.find((field) => field.id === 'claimtype');
expect(labelField1.type).toBe('dropdown');
});
it('should show dropdown options', () => {
getStartFormSpy.and.returnValue(of(startMockForm));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.detectChanges();
fixture.whenStable().then(() => {
const formFields = component.form.getFormFields();
const labelField = formFields.find((field) => field.id === 'claimtype');
expect(labelField.type).toBe('dropdown');
expect(labelField.options[0].name).toBe('Chooseone...');
expect(labelField.options[1].name).toBe('Cashless');
expect(labelField.options[2].name).toBe('Reimbursement');
});
});
it('should display start form with fields ', async(() => {
getStartFormSpy.and.returnValue(of(startMockForm));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.whenStable().then(() => {
fixture.detectChanges();
const formFieldsWidget = fixture.debugElement.nativeElement.querySelector('form-field');
const inputElement = fixture.debugElement.nativeElement.querySelector('.adf-input');
const inputLabelElement = fixture.debugElement.nativeElement.querySelector('.mat-form-field-infix > .adf-label');
const dateElement = fixture.debugElement.nativeElement.querySelector('#billdate');
const dateLabelElement = fixture.debugElement.nativeElement.querySelector('#data-widget .mat-form-field-infix> .adf-label');
const selectElement = fixture.debugElement.nativeElement.querySelector('#claimtype');
const selectLabelElement = fixture.debugElement.nativeElement.querySelector('.adf-dropdown-widget > .adf-label');
expect(formFieldsWidget).toBeDefined();
expect(inputElement).toBeDefined();
expect(dateElement).toBeDefined();
expect(selectElement).toBeDefined();
translate.get(inputLabelElement.textContent).subscribe( (value) => {
expect(value).toBe('ClientName*');
});
translate.get(dateLabelElement.innerText).subscribe( (value) => {
expect(value).toBe('BillDate (D-M-YYYY)');
});
translate.get(selectLabelElement.innerText).subscribe( (value) => {
expect(value).toBe('ClaimType');
});
});
}));
it('should refresh start form on click of refresh button ', async(() => {
getStartFormSpy.and.returnValue(of(startMockForm));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.showRefreshButton = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.detectChanges();
fixture.whenStable().then(() => {
const refreshElement = fixture.debugElement.nativeElement.querySelector('.mat-card-actions>button');
refreshElement.click();
fixture.detectChanges();
/* cspell:disable-next-line */
const selectElement = fixture.debugElement.nativeElement.querySelector('#claimtype');
const selectLabelElement = fixture.debugElement.nativeElement.querySelector('.adf-dropdown-widget > .adf-label');
expect(refreshElement).toBeDefined();
expect(selectElement).toBeDefined();
translate.get(selectLabelElement.innerText).subscribe( (value) => {
expect(value).toBe('ClaimType');
});
});
}));
it('should define custom-tabs ', async(() => {
getStartFormSpy.and.returnValue(of(startMockFormWithTab));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.showRefreshButton = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.detectChanges();
fixture.whenStable().then(() => {
const formTabs = component.form.tabs;
const tabField1 = formTabs.find((tab) => tab.id === 'form1');
const tabField2 = formTabs.find((tab) => tab.id === 'form2');
const tabsWidgetElement = fixture.debugElement.nativeElement.querySelector('tabs-widget');
expect(tabField1.name).toBe('Tab 1');
expect(tabField2.name).toBe('Tab 2');
expect(tabsWidgetElement).toBeDefined();
});
}));
it('should define title and [custom-action-buttons]', async(() => {
getStartFormSpy.and.returnValue(of(startMockFormWithTab));
component.processDefinitionId = exampleId1;
component.showOutcomeButtons = true;
component.showRefreshButton = true;
component.ngOnChanges({ processDefinitionId: new SimpleChange(exampleId1, exampleId2, true) });
fixture.detectChanges();
fixture.whenStable().then(() => {
const titleIcon = fixture.debugElement.nativeElement.querySelector('mat-card-title>mat-icon');
const titleElement = fixture.debugElement.nativeElement.querySelector('mat-card-title>h2');
const actionButtons = fixture.debugElement.nativeElement.querySelectorAll('.mat-button');
expect(titleIcon).toBeDefined();
expect(titleElement).toBeDefined();
expect(actionButtons.length).toBe(4);
expect(actionButtons[0].innerText).toBe('Save');
expect(actionButtons[0].disabled).toBeFalsy();
expect(actionButtons[1].innerText).toBe('Approve');
expect(actionButtons[1].disabled).toBeTruthy();
expect(actionButtons[2].innerText).toBe('Complete');
expect(actionButtons[2].disabled).toBeTruthy();
});
}));
});
describe('OutCome Actions', () => {
it('should not enable outcome button when model missing', () => {
expect(component.isOutcomeButtonVisible(null, false)).toBeFalsy();
});
it('should enable custom outcome buttons', () => {
const formModel = new FormModel();
component.form = formModel;
const outcome = new FormOutcomeModel(formModel, { id: 'action1', name: 'Action 1' });
expect(component.isOutcomeButtonVisible(outcome, component.form.readOnly)).toBeTruthy();
});
it('should allow controlling [complete] button visibility', () => {
const formModel = new FormModel();
component.form = formModel;
const outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.SAVE_ACTION });
component.showSaveButton = true;
expect(component.isOutcomeButtonVisible(outcome, component.form.readOnly)).toBeTruthy();
component.showSaveButton = false;
expect(component.isOutcomeButtonVisible(outcome, component.form.readOnly)).toBeFalsy();
});
it('should show only [complete] button with readOnly form ', () => {
const formModel = new FormModel();
formModel.readOnly = true;
component.form = formModel;
const outcome = new FormOutcomeModel(formModel, { id: '$complete', name: FormOutcomeModel.COMPLETE_ACTION });
component.showCompleteButton = true;
expect(component.isOutcomeButtonVisible(outcome, component.form.readOnly)).toBeTruthy();
});
it('should not show [save] button with readOnly form ', () => {
const formModel = new FormModel();
formModel.readOnly = true;
component.form = formModel;
const outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.SAVE_ACTION });
component.showSaveButton = true;
expect(component.isOutcomeButtonVisible(outcome, component.form.readOnly)).toBeFalsy();
});
it('should show [custom-outcome] button with readOnly form and selected custom-outcome', () => {
const formModel = new FormModel({ selectedOutcome: 'custom-outcome' });
formModel.readOnly = true;
component.form = formModel;
const outcome = new FormOutcomeModel(formModel, { id: '$customoutome', name: 'custom-outcome' });
component.showCompleteButton = true;
component.showSaveButton = true;
expect(component.isOutcomeButtonVisible(outcome, component.form.readOnly)).toBeTruthy();
const outcome1 = new FormOutcomeModel(formModel, { id: '$customoutome2', name: 'custom-outcome2' });
expect(component.isOutcomeButtonVisible(outcome1, component.form.readOnly)).toBeFalsy();
});
it('should allow controlling [save] button visibility', () => {
const formModel = new FormModel();
formModel.readOnly = false;
component.form = formModel;
const outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.COMPLETE_ACTION });
component.showCompleteButton = true;
expect(component.isOutcomeButtonVisible(outcome, component.form.readOnly)).toBeTruthy();
component.showCompleteButton = false;
expect(component.isOutcomeButtonVisible(outcome, component.form.readOnly)).toBeFalsy();
});
});
});