blob: b4429f0f63de8e508891675151f2d8d52a441d05 [file] [log] [blame]
/********************************************************************************
* 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,
};
}