Files
monorepo/LCU.WebApps.External.OnlineLoanApp/src/app/loan-wizard/application-wizard.service.spec.ts
T
2026-03-25 11:54:22 -05:00

237 lines
12 KiB
TypeScript

import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { CreditApplicationDaoService } from '../shared/credit-application-dao.service';
import { ApplicationWizardService } from './application-wizard.service';
import { MaskingService } from '../shared/masking/masking.service';
import { MemberInfoFormComponent } from './field-groups/member/member-info-form.component';
import { TextMaskModule } from 'angular2-text-mask';
import { MemberInfoPageService } from './wizards/common/member/member-info-page.service';
import { CommonGroups } from './field-groups/common-groups';
import { LoanTypeSet } from '../shared/loan-type';
import { of } from 'rxjs';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { CreditApplicationValues } from '../shared/credit-application-values';
import { TranslateModule } from '@ngx-translate/core';
import { BorrowerType } from '../shared/borrower-type';
import { apiTranslatorPreTranslate } from '../testing/shared-mocks/api-translator-pre-post';
import { EquityMemberInfoPageService } from './wizards/equity/equity-member-info-page.service';
import { configureTestSuite } from 'ng-bullet';
import { CreditApplicationService } from '../shared/credit-application.service';
const createTestFormGroup = (formBuilder: FormBuilder): FormGroup => {
const group = formBuilder.group({});
CommonGroups.MEMBER_INFO.fields.forEach((eachField) => {
group.addControl(eachField.field, formBuilder.control('', eachField.validation.slice()));
}, this);
return group;
};
describe('ApplicationWizardService', () => {
let applicationWizardService: ApplicationWizardService;
let creditApplicationDaoService: CreditApplicationDaoService;
let creditApplicationService: CreditApplicationService;
let component: MemberInfoFormComponent;
let fixture: ComponentFixture<MemberInfoFormComponent>;
let memberInfoPageService: MemberInfoPageService;
let equityMemberInfoPageService: EquityMemberInfoPageService;
let formBuilder: FormBuilder;
configureTestSuite(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
NgbModule.forRoot(),
ReactiveFormsModule,
TextMaskModule,
HttpClientTestingModule,
TranslateModule.forRoot()
],
declarations: [
MemberInfoFormComponent
],
schemas: [NO_ERRORS_SCHEMA],
providers: []
});
});
beforeEach(() => {
formBuilder = TestBed.get(FormBuilder);
applicationWizardService = TestBed.get(ApplicationWizardService);
applicationWizardService.setLoanType(LoanTypeSet[0].id);
creditApplicationDaoService = TestBed.get(CreditApplicationDaoService);
creditApplicationService = TestBed.get(CreditApplicationService);
memberInfoPageService = TestBed.get(MemberInfoPageService);
equityMemberInfoPageService = TestBed.get(EquityMemberInfoPageService);
fixture = TestBed.createComponent(MemberInfoFormComponent);
component = fixture.componentInstance;
component.group = createTestFormGroup(formBuilder);
});
it('should create', () => {
expect(applicationWizardService).toBeTruthy();
});
it('should determine whether or not a page can be visited', () => {
const canVisitStep1: boolean = applicationWizardService.canVisitPage('step-1');
const canVisitStep2: boolean = applicationWizardService.canVisitPage('step-2');
expect(canVisitStep1).toBe(true);
expect(canVisitStep2).toBe(false);
});
it('should determine a page can be visited because there were no errors', () => {
spyOn(applicationWizardService, 'getFieldErrors').and.callThrough().and.returnValue([]);
const noErrors: boolean = applicationWizardService.canVisitPage('step-2');
expect(noErrors).toBe(true);
});
it('should determine if there is a co-applicant', () => {
spyOn(MaskingService, 'unMaskNumber').and.callThrough().and.returnValue(1000);
spyOn(applicationWizardService, 'getFieldValue').and.callThrough();
spyOn(memberInfoPageService, 'createMemberInformationGroup').and.callThrough();
spyOn(creditApplicationService, 'saveCreditApplication').and.returnValue(of(true));
component.group.patchValue({
'applicantType': CreditApplicationValues.CHOICE_YES,
'limitRequested': '1000',
'maritalStatus': CreditApplicationValues.CHOICE_NO
});
creditApplicationService.saveMemberInformation(component.group.value);
const isCoApplicant: boolean = applicationWizardService.isCoApplicant();
expect(isCoApplicant).toBe(true);
component.group.patchValue({
'applicantType': CreditApplicationValues.CHOICE_NO,
'limitRequested': '1000',
'maritalStatus': CreditApplicationValues.CHOICE_NO
});
creditApplicationService.saveMemberInformation(component.group.value);
const changedCoApplicant: boolean = applicationWizardService.isCoApplicant();
expect(changedCoApplicant).toBe(false);
});
it('should submit an application ', () => {
const application = applicationWizardService.getFullCreditApplication();
spyOn(creditApplicationDaoService, 'submitApplication').and.returnValue(of(true));
applicationWizardService.submitCreditApplication(application);
expect(creditApplicationDaoService.submitApplication).toHaveBeenCalled();
});
it('should submit an application for decision', () => {
const application = applicationWizardService.getFullCreditApplication();
spyOn(creditApplicationDaoService, 'decideApplication').and.returnValue(of(true));
applicationWizardService.submitApplicationForDecision(application);
expect(creditApplicationDaoService.decideApplication).toHaveBeenCalled();
});
it('should update an applications decision status', () => {
spyOn(creditApplicationDaoService, 'getApplicationDecision').and.returnValue(of(true));
applicationWizardService.updateApplicationDecisionStatus();
expect(creditApplicationDaoService.getApplicationDecision).toHaveBeenCalled();
});
it('should return data for primary applicant', () => {
spyOn(applicationWizardService, 'getFullCreditApplication').and.returnValue(apiTranslatorPreTranslate);
const primaryData1 = applicationWizardService.getIndividualGroupValues('employmentInformation', BorrowerType.PRIMARY_BORROWER);
expect(primaryData1).toEqual(apiTranslatorPreTranslate.fullInfoBorrowers[0].employmentInformation);
expect(Array.isArray(primaryData1)).toBeTruthy();
});
it('should return data for secondary applicant', () => {
spyOn(applicationWizardService, 'getFullCreditApplication').and.returnValue(apiTranslatorPreTranslate);
const primaryData1 = applicationWizardService.getIndividualGroupValues('otherIncomeInformation', BorrowerType.CO_BORROWER);
expect(primaryData1).toEqual(apiTranslatorPreTranslate.fullInfoBorrowers[1].otherIncomeInformation);
});
it('should return the applicant\'s first name', () => {
spyOn(applicationWizardService, 'getFullCreditApplication').and.returnValue(apiTranslatorPreTranslate);
expect(applicationWizardService.getApplicantName(BorrowerType.PRIMARY_BORROWER))
.toEqual(apiTranslatorPreTranslate.fullInfoBorrowers[0].personalInformation.firstName);
expect(applicationWizardService.getApplicantName(BorrowerType.CO_BORROWER))
.toEqual(apiTranslatorPreTranslate.fullInfoBorrowers[1].personalInformation.firstName);
});
it('should return a field value w/ or w/o a group', () => {
spyOn(applicationWizardService, 'getFullCreditApplication').and.returnValue(apiTranslatorPreTranslate);
expect(applicationWizardService.getFieldValue('loanType')).toEqual(apiTranslatorPreTranslate.loanType);
expect(applicationWizardService.getFieldValue('estimatedValue', 'collateralInformation'))
.toBe(apiTranslatorPreTranslate.collateralInformation.estimatedValue);
});
it('should determine that a loan needs collateral information', () => {
spyOn(applicationWizardService, 'getFullCreditApplication').and.returnValue(apiTranslatorPreTranslate);
// apiTranslatorPreTranslate is using Loan type 8, which does not require collateral.
// 8 used to be MANUFACTURED_HOME_LOAN which is commented out as of 2023.
expect(applicationWizardService.needsCollateral()).toBe(false);
});
it('should determine that a loan doesn\'t need collateral information', () => {
const creditCardApplication = apiTranslatorPreTranslate;
creditCardApplication.loanType = LoanTypeSet[0];
spyOn(applicationWizardService, 'getFullCreditApplication').and.returnValue(creditCardApplication);
expect(applicationWizardService.needsCollateral()).toBe(false);
});
it('should return true if the co-borrower is married to the primary borrower', () => {
spyOn(applicationWizardService, 'getFullCreditApplication').and.returnValue(apiTranslatorPreTranslate);
expect(applicationWizardService.isCoApplicantSpouse()).toBe(true);
});
it('should return false if the co-borrower is not married to the primary borrower', () => {
const applicantsAreNotMarriedToEachOther = apiTranslatorPreTranslate;
applicantsAreNotMarriedToEachOther.hasCoApplicantSpouse = null;
spyOn(applicationWizardService, 'getFullCreditApplication').and.returnValue(applicantsAreNotMarriedToEachOther);
expect(applicationWizardService.isCoApplicantSpouse()).toBe(false);
});
// tslint:disable-next-line:max-line-length
it('should return false if the applicant/co-applicant does not need to provide spouse information (if primary and co-borrower are not married to each other)', () => {
apiTranslatorPreTranslate.hasCoApplicantSpouse = CreditApplicationValues.CHOICE_YES;
apiTranslatorPreTranslate.fullInfoBorrowers[0].personalInformation.maritalStatus = CreditApplicationValues.CHOICE_YES;
spyOn(applicationWizardService, 'getFullCreditApplication').and.returnValue(apiTranslatorPreTranslate);
spyOn(applicationWizardService, 'isCoApplicantSpouse').and.callThrough();
expect(applicationWizardService.isApplicantNonSpouse(BorrowerType.CO_BORROWER)).toBe(false);
});
it('should return true if the applicant/co-applicant needs to provide spouse information', () => {
apiTranslatorPreTranslate.hasCoApplicantSpouse = CreditApplicationValues.CHOICE_NO;
spyOn(applicationWizardService, 'getFullCreditApplication').and.returnValue(apiTranslatorPreTranslate);
spyOn(applicationWizardService, 'isCoApplicantSpouse').and.callThrough();
expect(applicationWizardService.isApplicantNonSpouse(BorrowerType.PRIMARY_BORROWER)).toBe(true);
});
it('should return false if this is not a Manufactured Home', () => {
const mfgHomeNotOnRentedLotApplication = apiTranslatorPreTranslate;
mfgHomeNotOnRentedLotApplication.loanType = LoanTypeSet[4];
spyOn(applicationWizardService, 'getFullCreditApplication').and.returnValue(mfgHomeNotOnRentedLotApplication);
expect(applicationWizardService.isRentedLotInfoRequired()).toBe(false);
expect(applicationWizardService.isLienPositionInfoRequired()).toBe(true);
});
it('should return group values', () => {
spyOn(applicationWizardService, 'getFullCreditApplication').and.returnValue(apiTranslatorPreTranslate);
expect(applicationWizardService.getGroupValues('collateralInformation')).toEqual(apiTranslatorPreTranslate.collateralInformation);
expect(applicationWizardService.getGroupValues('someNonExistantGroup')).toEqual({});
});
it('should return an individual from the application', () => {
spyOn(applicationWizardService, 'getFullCreditApplication').and.returnValue(apiTranslatorPreTranslate);
expect(applicationWizardService.getIndividualByBorrowerType(BorrowerType.CO_BORROWER))
.toEqual(apiTranslatorPreTranslate.fullInfoBorrowers[1]);
});
it('should correctly calculate a simple next route name', () => {
const service = applicationWizardService;
expect(service.getSimpleRouteName('https://applydev.landmarkcu.com/loan-wizard/cc/re/step-2')).toEqual('step-2');
expect(service.getSimpleRouteName('https://a.x.com/lw/cc/re/step-1?fbclid=IwAR226oQp-ISjjS9U1I440bjA')).toEqual('step-1');
});
});