| /******************************************************************************** |
| * Copyright (c) 2020 Contributors to the Eclipse Foundation |
| * |
| * See the NOTICE file(s) distributed with this work for additional |
| * information regarding copyright ownership. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0 |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| ********************************************************************************/ |
| |
| import {EventEmitter} from "@angular/core"; |
| import {async, ComponentFixture, TestBed} from "@angular/core/testing"; |
| import {MockStore, provideMockStore} from "@ngrx/store/testing"; |
| import {of, timer} from "rxjs"; |
| import {I18nModule, IAPIProcessTask, IAPISearchOptions} from "../../../../../core"; |
| import { |
| EErrorCode, |
| fetchContactDetailsAction, |
| fetchSettingsAction, |
| getStatementLoadingSelector, |
| IStatementInformationFormValue, |
| openContactDataBaseAction, |
| setErrorAction, |
| startContactSearchAction, |
| statementInformationFormValueSelector, |
| statementTypesSelector, |
| submitStatementInformationFormAction, |
| taskSelector |
| } from "../../../../../store"; |
| import {createSelectOptionsMock} from "../../../../../test"; |
| import {StatementInformationFormModule} from "../../statement-information-form.module"; |
| import {StatementInformationFormComponent} from "./statement-information-form.component"; |
| |
| describe("StatementInformationFormComponent", () => { |
| const today = new Date().toISOString().slice(0, 10); |
| let component: StatementInformationFormComponent; |
| let fixture: ComponentFixture<StatementInformationFormComponent>; |
| let mockStore: MockStore; |
| |
| beforeEach(async(() => { |
| TestBed.configureTestingModule({ |
| imports: [ |
| I18nModule, |
| StatementInformationFormModule |
| ], |
| providers: [ |
| provideMockStore({ |
| initialState: {statements: {}, settings: {}, contacts: {}, attachments: {}}, |
| selectors: [ |
| { |
| selector: statementTypesSelector, |
| value: createSelectOptionsMock(5, "Statement Type") |
| } |
| ] |
| }) |
| ] |
| }).compileComponents(); |
| })); |
| |
| beforeEach(() => { |
| fixture = TestBed.createComponent(StatementInformationFormComponent); |
| mockStore = TestBed.inject(MockStore); |
| component = fixture.componentInstance; |
| }); |
| |
| it("should initialize form for existing statements", async () => { |
| const statementInformationFormValueSelectorMock = mockStore.overrideSelector(statementInformationFormValueSelector, {}); |
| const value: IStatementInformationFormValue = createStatementInfoFormValue({ |
| title: "Title", |
| typeId: 19 |
| }); |
| expect(component).toBeDefined(); |
| fixture.detectChanges(); |
| await fixture.whenStable(); |
| statementInformationFormValueSelectorMock.setResult({...value}); |
| mockStore.refreshState(); |
| await fixture.whenStable(); |
| expect(component.appFormGroup.touched).toBeTrue(); |
| expect(component.getValue()).toEqual(value); |
| }); |
| |
| it("should initialize for new statements", async () => { |
| const statementInformationFormValueSelectorMock = mockStore.overrideSelector(statementInformationFormValueSelector, {}); |
| const value = createStatementInfoFormValue({ |
| dueDate: today, |
| receiptDate: today, |
| creationDate: today, |
| typeId: 0 |
| }); |
| component.appForNewStatement = true; |
| expect(component).toBeDefined(); |
| fixture.detectChanges(); |
| await fixture.whenStable(); |
| statementInformationFormValueSelectorMock.setResult({title: "Title"}); |
| mockStore.refreshState(); |
| await fixture.whenStable(); |
| expect(component.appFormGroup.untouched).toBeTrue(); |
| expect(component.getValue()).toEqual(value); |
| }); |
| |
| it("should initialize for new statements without statement types", async () => { |
| const statementInformationFormValueSelectorMock = mockStore.overrideSelector(statementInformationFormValueSelector, {}); |
| mockStore.overrideSelector(statementTypesSelector, null); |
| const value = createStatementInfoFormValue({ |
| typeId: undefined, |
| dueDate: today, |
| receiptDate: today, |
| creationDate: today |
| }); |
| component.appForNewStatement = true; |
| expect(component).toBeDefined(); |
| fixture.detectChanges(); |
| await fixture.whenStable(); |
| statementInformationFormValueSelectorMock.setResult({title: "Title"}); |
| mockStore.refreshState(); |
| await fixture.whenStable(); |
| expect(component.appFormGroup.untouched).toBeTrue(); |
| expect(component.getValue()).toEqual(value); |
| }); |
| |
| it("should disable form when loading", async () => { |
| const getStatementLoadingSelectorMock = mockStore.overrideSelector(getStatementLoadingSelector, {}); |
| fixture.detectChanges(); |
| await fixture.whenStable(); |
| |
| getStatementLoadingSelectorMock.setResult({}); |
| mockStore.refreshState(); |
| |
| expect(component.appFormGroup.enabled).toBeTrue(); |
| |
| getStatementLoadingSelectorMock.setResult({submittingStatementInformation: true}); |
| mockStore.refreshState(); |
| |
| expect(component.appFormGroup.enabled).toBeFalse(); |
| |
| getStatementLoadingSelectorMock.setResult({submittingStatementInformation: false}); |
| mockStore.refreshState(); |
| |
| expect(component.appFormGroup.enabled).toBeTrue(); |
| }); |
| |
| it("should fetch settings for new statements", async () => { |
| const dispatchSpy = spyOn(component.store, "dispatch"); |
| component.appForNewStatement = true; |
| fixture.detectChanges(); |
| await fixture.whenStable(); |
| expect(dispatchSpy).toHaveBeenCalledWith(fetchSettingsAction()); |
| }); |
| |
| it("should fetch contact details on value changes", async () => { |
| const formValueChangesMock = new EventEmitter<any>(); |
| (component.appFormGroup as any).valueChanges = formValueChangesMock; |
| component.task$ = of({statementId: undefined} as IAPIProcessTask); |
| fixture.detectChanges(); |
| await fixture.whenStable(); |
| |
| const value: Partial<IStatementInformationFormValue> = { |
| contactId: "19191919" |
| }; |
| const dispatchSpy = spyOn(component.store, "dispatch"); |
| component.appFormGroup.patchValue(value); |
| formValueChangesMock.next(value); |
| |
| await timer(0).toPromise(); |
| |
| expect(dispatchSpy).toHaveBeenCalledWith(fetchContactDetailsAction({contactId: value.contactId, statementId: undefined})); |
| }); |
| |
| it("should open contact data base module", async () => { |
| const dispatchSpy = spyOn(component.store, "dispatch"); |
| component.openContactDataBaseModule(); |
| expect(dispatchSpy).toHaveBeenCalledWith(openContactDataBaseAction()); |
| }); |
| |
| it("should search for new contacts", async () => { |
| const dispatchSpy = spyOn(component.store, "dispatch"); |
| const options: IAPISearchOptions = { |
| q: "", |
| page: 0, |
| size: 10 |
| }; |
| |
| component.search(); |
| expect(dispatchSpy).toHaveBeenCalledWith(startContactSearchAction({options})); |
| |
| options.q = "191919"; |
| component.searchText = options.q; |
| component.changePage(null); |
| expect(dispatchSpy).toHaveBeenCalledWith(startContactSearchAction({options})); |
| |
| options.page = 19; |
| component.changePage(options.page); |
| expect(dispatchSpy).toHaveBeenCalledWith(startContactSearchAction({options})); |
| }); |
| |
| it("should mark all as touched when invalid form is submitted", async () => { |
| component.appForNewStatement = true; |
| fixture.detectChanges(); |
| await fixture.whenStable(); |
| |
| const dispatchSpy = spyOn(component.store, "dispatch"); |
| |
| expect(component.appFormGroup.touched).toBeFalse(); |
| expect(component.appFormGroup.invalid).toBeTrue(); |
| await component.submit(); |
| expect(component.appFormGroup.touched).toBeTrue(); |
| expect(dispatchSpy).toHaveBeenCalledWith(setErrorAction({ |
| statementId: "new", |
| error: EErrorCode.MISSING_FORM_DATA |
| })); |
| }); |
| |
| it("should submit information for a new statement", async () => { |
| const value = createStatementInfoFormValue({ |
| title: "Title", |
| creationDate: today, |
| dueDate: today, |
| receiptDate: today, |
| typeId: 3, |
| city: "city", |
| district: "district", |
| contactId: "contactId", |
| customerReference: "" |
| }); |
| |
| component.appForNewStatement = true; |
| fixture.detectChanges(); |
| await fixture.whenStable(); |
| |
| component.appFormGroup.patchValue(value); |
| fixture.detectChanges(); |
| await fixture.whenStable(); |
| |
| const dispatchSpy = spyOn(component.store, "dispatch"); |
| |
| expect(component.getValue()).toEqual(value); |
| |
| await component.submit(true); |
| expect(dispatchSpy).toHaveBeenCalledWith(submitStatementInformationFormAction({ |
| new: true, |
| value, |
| responsible: true |
| })); |
| |
| await component.submit(false); |
| expect(dispatchSpy).toHaveBeenCalledWith(submitStatementInformationFormAction({ |
| new: true, |
| value, |
| responsible: false |
| })); |
| }); |
| |
| it("should submit information for an existing statement", async () => { |
| const task: Partial<IAPIProcessTask> = { |
| taskId: "19191919", |
| statementId: 19 |
| }; |
| const value = createStatementInfoFormValue({ |
| title: "Title", |
| dueDate: today, |
| receiptDate: today, |
| creationDate: today, |
| typeId: 3, |
| city: "city", |
| district: "district", |
| contactId: "contactId" |
| }); |
| |
| mockStore.overrideSelector(taskSelector, task as IAPIProcessTask); |
| |
| fixture.detectChanges(); |
| await fixture.whenStable(); |
| |
| component.appFormGroup.patchValue(value); |
| fixture.detectChanges(); |
| await fixture.whenStable(); |
| |
| const dispatchSpy = spyOn(component.store, "dispatch"); |
| |
| expect(component.getValue()).toEqual(value); |
| |
| await component.submit(true); |
| expect(dispatchSpy).toHaveBeenCalledWith(submitStatementInformationFormAction({ |
| statementId: task.statementId, |
| taskId: task.taskId, |
| value, |
| responsible: true |
| })); |
| |
| await component.submit(false); |
| expect(dispatchSpy).toHaveBeenCalledWith(submitStatementInformationFormAction({ |
| statementId: task.statementId, |
| taskId: task.taskId, |
| value, |
| responsible: false |
| })); |
| }); |
| }); |
| |
| function createStatementInfoFormValue(value: Partial<IStatementInformationFormValue>): IStatementInformationFormValue { |
| return { |
| title: null, |
| dueDate: null, |
| receiptDate: null, |
| creationDate: null, |
| typeId: null, |
| city: null, |
| district: null, |
| contactId: null, |
| customerReference: null, |
| attachments: { |
| add: [], |
| edit: [], |
| email: [], |
| transferMailText: false, |
| mailTextAttachmentId: null |
| }, |
| sourceMailId: undefined, |
| ...value, |
| }; |
| } |