diff --git a/src/common/modules/neoleap/__mocks__/create-application.mock.ts b/src/common/modules/neoleap/__mocks__/create-application.mock.ts index 3853390..96465c0 100644 --- a/src/common/modules/neoleap/__mocks__/create-application.mock.ts +++ b/src/common/modules/neoleap/__mocks__/create-application.mock.ts @@ -1,758 +1,198 @@ -function getRandomWithDigits(digits: number): string { - const min = Math.pow(10, digits - 1); // e.g. 1000 for 4 digits - const max = Math.pow(10, digits) - 1; // e.g. 9999 for 4 digits +import { randomInt, randomUUID } from 'crypto'; - const result = Math.floor(Math.random() * (max - min + 1)) + min; - return result.toString(); +/** Generate a string of `n` random digits (first digit never 0). */ +function randomDigits(n: number): string { + if (n <= 0) return '0'; + let s = String(randomInt(1, 10)); // first digit 1–9 + for (let i = 1; i < n; i++) s += String(randomInt(0, 10)); + return s; } -export const CREATE_APPLICATION_MOCK = { - ResponseHeader: { - Version: '1.0.0', - MsgUid: 'adaa1893-9f95-48a8-b7a1-0422bcf629b5', - Source: 'ZOD', - ServiceId: 'CreateNewApplication', - ReqDateTime: '2025-06-03T07:32:16.304Z', - RspDateTime: '2025-06-03T08:21:15.662', - ResponseCode: '000', - ResponseType: 'Success', - ProcessingTime: 1665, - EncryptionKey: null, - ResponseDescription: 'Operation Successful', - LocalizedResponseDescription: null, - CustomerSpecificResponseDescriptionList: null, - HeaderUserDataList: null, - }, +/** Build a fresh mock object every time it's called */ +export function buildCreateApplicationMock() { + const now = new Date().toISOString(); - CreateNewApplicationResponseDetails: { - InstitutionCode: '1100', - ApplicationTypeDetails: { - TypeCode: '01', - Description: 'Normal Primary', - Additional: false, - Corporate: false, - UserData: null, + return { + ResponseHeader: { + Version: '1.0.0', + MsgUid: randomUUID(), + Source: 'ZOD', + ServiceId: 'CreateNewApplication', + ReqDateTime: now, + RspDateTime: now, + ResponseCode: '000', + ResponseType: 'Success', + ProcessingTime: 1665, + EncryptionKey: null, + ResponseDescription: 'Operation Successful', + LocalizedResponseDescription: null, + CustomerSpecificResponseDescriptionList: null, + HeaderUserDataList: null, }, - ApplicationDetails: { - cif: null, - ApplicationNumber: '3300000000073', - ExternalApplicationNumber: '3', - ApplicationStatus: '04', - Organization: 0, - Product: '1101', - ApplicatonDate: '2025-05-29', - ApplicationSource: 'O', - SalesSource: null, - DeliveryMethod: 'V', - ProgramCode: null, - Campaign: null, - Plastic: null, - Design: null, - ProcessStage: '99', - ProcessStageStatus: 'S', - Score: null, - ExternalScore: null, - RequestedLimit: 0, - SuggestedLimit: null, - AssignedLimit: 0, - AllowedLimitList: null, - EligibilityCheckResult: '00', - EligibilityCheckDescription: null, - Title: 'Mr.', - FirstName: 'Abdalhamid', - SecondName: null, - ThirdName: null, - LastName: ' Ahmad', - FullName: 'Abdalhamid Ahmad', - EmbossName: 'ABDALHAMID AHMAD', - PlaceOfBirth: null, - DateOfBirth: '1999-01-07', - LocalizedDateOfBirth: '1999-01-07', - Age: 26, - Gender: 'M', - Married: 'U', - Nationality: '682', - IdType: '01', - IdNumber: '1089055972', - IdExpiryDate: '2031-09-17', - EducationLevel: null, - ProfessionCode: 0, - NumberOfDependents: 0, - EmployerName: 'N/A', - EmploymentYears: 0, - EmploymentMonths: 0, - EmployerPhoneArea: null, - EmployerPhoneNumber: null, - EmployerPhoneExtension: null, - EmployerMobile: null, - EmployerFaxArea: null, - EmployerFax: null, - EmployerCity: null, - EmployerAddress: null, - EmploymentActivity: null, - EmploymentStatus: null, - CIF: null, - BankAccountNumber: ' ', - Currency: { - CurrCode: '682', - AlphaCode: 'SAR', + + CreateNewApplicationResponseDetails: { + InstitutionCode: '1100', + ApplicationTypeDetails: { + TypeCode: '01', + Description: 'Normal Primary', + Additional: false, + Corporate: false, + UserData: null, }, - RequestedCurrencyList: null, - CreditAccountNumber: '6000000000000000', - AccountType: '30', - OpenDate: null, - Income: 0, - AdditionalIncome: 0, - TotalIncome: 0, - CurrentBalance: 0, - AverageBalance: 0, - AssetsBalance: 0, - InsuranceBalance: 0, - DepositAmount: 0, - GuarenteeAccountNumber: null, - GuarenteeAmount: 0, - InstalmentAmount: 0, - AutoDebit: 'N', - PaymentMethod: '2', - BillingCycle: 'C1', - OldIssueDate: null, - OtherPaymentsDate: null, - MaximumDelinquency: null, - CreditBureauDecision: null, - CreditBureauUserData: null, - ECommerce: 'N', - NumberOfCards: 0, - OtherBank: null, - OtherBankDescription: null, - InsuranceProduct: null, - SocialCode: '000', - JobGrade: 0, - Flags: [ - { - Position: 1, - Value: '0', - }, - { - Position: 2, - Value: '0', - }, - { - Position: 3, - Value: '0', - }, - { - Position: 4, - Value: '0', - }, - { - Position: 5, - Value: '0', - }, - { - Position: 6, - Value: '0', - }, - { - Position: 7, - Value: '0', - }, - { - Position: 8, - Value: '0', - }, - { - Position: 9, - Value: '0', - }, - { - Position: 10, - Value: '0', - }, - { - Position: 11, - Value: '0', - }, - { - Position: 12, - Value: '0', - }, - { - Position: 13, - Value: '0', - }, - { - Position: 14, - Value: '0', - }, - { - Position: 15, - Value: '0', - }, - { - Position: 16, - Value: '0', - }, - { - Position: 17, - Value: '0', - }, - { - Position: 18, - Value: '0', - }, - { - Position: 19, - Value: '0', - }, - { - Position: 20, - Value: '0', - }, - { - Position: 21, - Value: '0', - }, - { - Position: 22, - Value: '0', - }, - { - Position: 23, - Value: '0', - }, - { - Position: 24, - Value: '0', - }, - { - Position: 25, - Value: '0', - }, - { - Position: 26, - Value: '0', - }, - { - Position: 27, - Value: '0', - }, - { - Position: 28, - Value: '0', - }, - { - Position: 29, - Value: '0', - }, - { - Position: 30, - Value: '0', - }, - { - Position: 31, - Value: '0', - }, - { - Position: 32, - Value: '0', - }, - { - Position: 33, - Value: '0', - }, - { - Position: 34, - Value: '0', - }, - { - Position: 35, - Value: '0', - }, - { - Position: 36, - Value: '0', - }, - { - Position: 37, - Value: '0', - }, - { - Position: 38, - Value: '0', - }, - { - Position: 39, - Value: '0', - }, - { - Position: 40, - Value: '0', - }, - { - Position: 41, - Value: '0', - }, - { - Position: 42, - Value: '0', - }, - { - Position: 43, - Value: '0', - }, - { - Position: 44, - Value: '0', - }, - { - Position: 45, - Value: '0', - }, - { - Position: 46, - Value: '0', - }, - { - Position: 47, - Value: '0', - }, - { - Position: 48, - Value: '0', - }, - { - Position: 49, - Value: '0', - }, - { - Position: 50, - Value: '0', - }, - { - Position: 51, - Value: '0', - }, - { - Position: 52, - Value: '0', - }, - { - Position: 53, - Value: '0', - }, - { - Position: 54, - Value: '0', - }, - { - Position: 55, - Value: '0', - }, - { - Position: 56, - Value: '0', - }, - { - Position: 57, - Value: '0', - }, - { - Position: 58, - Value: '0', - }, - { - Position: 59, - Value: '0', - }, - { - Position: 60, - Value: '0', - }, - { - Position: 61, - Value: '0', - }, - { - Position: 62, - Value: '0', - }, - { - Position: 63, - Value: '0', - }, - { - Position: 64, - Value: '0', - }, - ], - CheckFlags: [ - { - Position: 1, - Value: '0', - }, - { - Position: 2, - Value: '0', - }, - { - Position: 3, - Value: '0', - }, - { - Position: 4, - Value: '0', - }, - { - Position: 5, - Value: '0', - }, - { - Position: 6, - Value: '0', - }, - { - Position: 7, - Value: '0', - }, - { - Position: 8, - Value: '0', - }, - { - Position: 9, - Value: '0', - }, - { - Position: 10, - Value: '0', - }, - { - Position: 11, - Value: '0', - }, - { - Position: 12, - Value: '0', - }, - { - Position: 13, - Value: '0', - }, - { - Position: 14, - Value: '0', - }, - { - Position: 15, - Value: '0', - }, - { - Position: 16, - Value: '0', - }, - { - Position: 17, - Value: '0', - }, - { - Position: 18, - Value: '0', - }, - { - Position: 19, - Value: '0', - }, - { - Position: 20, - Value: '0', - }, - { - Position: 21, - Value: '0', - }, - { - Position: 22, - Value: '0', - }, - { - Position: 23, - Value: '0', - }, - { - Position: 24, - Value: '0', - }, - { - Position: 25, - Value: '0', - }, - { - Position: 26, - Value: '0', - }, - { - Position: 27, - Value: '0', - }, - { - Position: 28, - Value: '0', - }, - { - Position: 29, - Value: '0', - }, - { - Position: 30, - Value: '0', - }, - { - Position: 31, - Value: '0', - }, - { - Position: 32, - Value: '0', - }, - { - Position: 33, - Value: '0', - }, - { - Position: 34, - Value: '0', - }, - { - Position: 35, - Value: '0', - }, - { - Position: 36, - Value: '0', - }, - { - Position: 37, - Value: '0', - }, - { - Position: 38, - Value: '0', - }, - { - Position: 39, - Value: '0', - }, - { - Position: 40, - Value: '0', - }, - { - Position: 41, - Value: '0', - }, - { - Position: 42, - Value: '0', - }, - { - Position: 43, - Value: '0', - }, - { - Position: 44, - Value: '0', - }, - { - Position: 45, - Value: '0', - }, - { - Position: 46, - Value: '0', - }, - { - Position: 47, - Value: '0', - }, - { - Position: 48, - Value: '0', - }, - { - Position: 49, - Value: '0', - }, - { - Position: 50, - Value: '0', - }, - { - Position: 51, - Value: '0', - }, - { - Position: 52, - Value: '0', - }, - { - Position: 53, - Value: '0', - }, - { - Position: 54, - Value: '0', - }, - { - Position: 55, - Value: '0', - }, - { - Position: 56, - Value: '0', - }, - { - Position: 57, - Value: '0', - }, - { - Position: 58, - Value: '0', - }, - { - Position: 59, - Value: '0', - }, - { - Position: 60, - Value: '0', - }, - { - Position: 61, - Value: '0', - }, - { - Position: 62, - Value: '0', - }, - { - Position: 63, - Value: '0', - }, - { - Position: 64, - Value: '0', - }, - ], - Maker: null, - Checker: null, - ReferredTo: null, - ReferralReason: null, - UserData1: null, - UserData2: null, - UserData3: null, - UserData4: null, - UserData5: null, - AdditionalFields: [], - }, - ApplicationStatusDetails: { - StatusCode: '04', - Description: 'Approved', - Canceled: false, - }, - CorporateDetails: null, - CustomerDetails: { - Id: 115158, - CustomerCode: '100000024619', - IdNumber: ' ', - TypeId: 0, - PreferredLanguage: 'EN', - ExternalCustomerCode: null, - Title: ' ', - FirstName: ' ', - LastName: ' ', - DateOfBirth: null, - UserData1: '2031-09-17', - UserData2: '01', - UserData3: null, - UserData4: '682', - CustomerSegment: null, - Gender: 'U', - Married: 'U', - }, - AccountDetailsList: [ - { - Id: getRandomWithDigits(5), - InstitutionCode: '1100', - AccountNumber: getRandomWithDigits(16), - Currency: { - CurrCode: '682', - AlphaCode: 'SAR', - }, - AccountTypeCode: '30', - ClassId: '2', - AccountStatus: '00', - VipFlag: '0', - BlockedAmount: 0, - EquivalentBlockedAmount: null, - UnclearCredit: 0, - EquivalentUnclearCredit: null, - AvailableBalance: 0, - EquivalentAvailableBalance: null, - AvailableBalanceToSpend: 0, - CreditLimit: 0, - RemainingCashLimit: null, - UserData1: 'D36407C9AE4C28D2185', - UserData2: null, - UserData3: 'D36407C9AE4C28D2185', - UserData4: null, - UserData5: `SA${getRandomWithDigits(22)}`, - }, - ], - CardDetailsList: [ - { - pvv: null, - ResponseCardIdentifier: { - Id: getRandomWithDigits(5), - Pan: 'DDDDDDDDDDDDDDDDDDD', - MaskedPan: '999999_9999', - VPan: getRandomWithDigits(16), - Seqno: 0, - }, - ExpiryDate: '2031-09-30', - EffectiveDate: '2025-06-02', - CardStatus: '30', - OldPlasticExpiryDate: null, - OldPlasticCardStatus: null, - EmbossingName: 'ABDALHAMID AHMAD', + ApplicationDetails: { + cif: null, + ApplicationNumber: '3300000000073', + ExternalApplicationNumber: '3', + ApplicationStatus: '04', + Organization: 0, + Product: '1101', + ApplicatonDate: '2025-05-29', + ApplicationSource: 'O', + SalesSource: null, + DeliveryMethod: 'V', + ProgramCode: null, + Campaign: null, + Plastic: null, + Design: null, + ProcessStage: '99', + ProcessStageStatus: 'S', + Score: null, + ExternalScore: null, + RequestedLimit: 0, + SuggestedLimit: null, + AssignedLimit: 0, + AllowedLimitList: null, + EligibilityCheckResult: '00', + EligibilityCheckDescription: null, Title: 'Mr.', FirstName: 'Abdalhamid', + SecondName: null, + ThirdName: null, LastName: ' Ahmad', - Additional: false, - BatchNumber: 8849, - ServiceCode: '226', - Kinship: null, + FullName: 'Abdalhamid Ahmad', + EmbossName: 'ABDALHAMID AHMAD', + PlaceOfBirth: null, DateOfBirth: '1999-01-07', - LastActivity: null, - LastStatusChangeDate: '2025-06-03', - ActivationDate: null, - DateLastIssued: null, - PVV: null, - UserData: '4', - UserData1: '3', - UserData2: null, - UserData3: null, - UserData4: null, - UserData5: null, - Memo: null, - CardAuthorizationParameters: null, - L10NTitle: null, - L10NFirstName: null, - L10NLastName: null, - PinStatus: '40', - OldPinStatus: '0', - CustomerIdNumber: '1089055972', - Language: 0, + LocalizedDateOfBirth: '1999-01-07', + Age: 26, + Gender: 'M', + Married: 'U', + Nationality: '682', + IdType: '01', + IdNumber: '1089055972', + IdExpiryDate: '2031-09-17', + EducationLevel: null, + ProfessionCode: 0, + NumberOfDependents: 0, + EmployerName: 'N/A', + EmploymentYears: 0, + EmploymentMonths: 0, + CIF: null, + BankAccountNumber: ' ', + Currency: { CurrCode: '682', AlphaCode: 'SAR' }, + CreditAccountNumber: '6000000000000000', + AccountType: '30', + Income: 0, + AdditionalIncome: 0, + TotalIncome: 0, + CurrentBalance: 0, + AverageBalance: 0, + AssetsBalance: 0, + InsuranceBalance: 0, + DepositAmount: 0, + GuarenteeAccountNumber: null, + GuarenteeAmount: 0, + InstalmentAmount: 0, + AutoDebit: 'N', + PaymentMethod: '2', + BillingCycle: 'C1', + MaximumDelinquency: null, + CreditBureauDecision: null, + ECommerce: 'N', + NumberOfCards: 0, + SocialCode: '000', + JobGrade: 0, + Flags: Array.from({ length: 64 }, (_, i) => ({ + Position: i + 1, + Value: '0', + })), + CheckFlags: Array.from({ length: 64 }, (_, i) => ({ + Position: i + 1, + Value: '0', + })), }, - ], - }, -}; + + ApplicationStatusDetails: { + StatusCode: '04', + Description: 'Approved', + Canceled: false, + }, + + CustomerDetails: { + Id: 115158, + CustomerCode: '100000024619', + IdNumber: ' ', + TypeId: 0, + PreferredLanguage: 'EN', + ExternalCustomerCode: null, + Title: ' ', + FirstName: ' ', + LastName: ' ', + DateOfBirth: null, + UserData1: '2031-09-17', + UserData2: '01', + UserData3: null, + UserData4: '682', + CustomerSegment: null, + Gender: 'U', + Married: 'U', + }, + + AccountDetailsList: [ + { + Id: randomDigits(5), + InstitutionCode: '1100', + AccountNumber: randomDigits(16), + Currency: { CurrCode: '682', AlphaCode: 'SAR' }, + AccountTypeCode: '30', + ClassId: '2', + AccountStatus: '00', + VipFlag: '0', + BlockedAmount: 0, + AvailableBalance: 0, + UserData1: 'D36407C9AE4C28D2185', + UserData3: 'D36407C9AE4C28D2185', + UserData5: `SA${randomDigits(22)}`, + }, + ], + + CardDetailsList: [ + { + pvv: null, + ResponseCardIdentifier: { + Id: randomDigits(5), + Pan: 'DDDDDDDDDDDDDDDDDDD', + MaskedPan: '999999_9999', + VPan: randomDigits(16), + Seqno: 0, + }, + ExpiryDate: '2031-09-30', + EffectiveDate: '2025-06-02', + CardStatus: '30', + EmbossingName: 'ABDALHAMID AHMAD', + Title: 'Mr.', + FirstName: 'Abdalhamid', + LastName: ' Ahmad', + BatchNumber: 8849, + ServiceCode: '226', + DateOfBirth: '1999-01-07', + LastStatusChangeDate: '2025-06-03', + PinStatus: '40', + OldPinStatus: '0', + CustomerIdNumber: '1089055972', + Language: 0, + }, + ], + }, + }; +} diff --git a/src/common/modules/neoleap/services/neoleap.service.ts b/src/common/modules/neoleap/services/neoleap.service.ts index cb5860f..b6ce0eb 100644 --- a/src/common/modules/neoleap/services/neoleap.service.ts +++ b/src/common/modules/neoleap/services/neoleap.service.ts @@ -10,8 +10,8 @@ import { InitiateKycRequestDto } from '~/customer/dtos/request'; import { Customer } from '~/customer/entities'; import { Gender } from '~/customer/enums'; import { + buildCreateApplicationMock, CARD_EMBOSSING_DETAILS_MOCK, - CREATE_APPLICATION_MOCK, INITIATE_KYC_MOCK, INQUIRE_APPLICATION_MOCK, } from '../__mocks__/'; @@ -95,7 +95,7 @@ export class NeoLeapService { const responseKey = 'CreateNewApplicationResponseDetails'; if (!this.useGateway) { - return plainToInstance(CreateApplicationResponse, CREATE_APPLICATION_MOCK[responseKey], { + return plainToInstance(CreateApplicationResponse, buildCreateApplicationMock()[responseKey], { excludeExtraneousValues: true, }); } @@ -169,7 +169,7 @@ export class NeoLeapService { const responseKey = 'CreateNewApplicationResponseDetails'; if (!this.useGateway) { - return plainToInstance(CreateApplicationResponse, CREATE_APPLICATION_MOCK[responseKey], { + return plainToInstance(CreateApplicationResponse, buildCreateApplicationMock()[responseKey], { excludeExtraneousValues: true, }); }