diff --git a/src/controllers/checkYourAnswers.ts b/src/controllers/checkYourAnswers.ts index b6e7686..bc2b3b1 100644 --- a/src/controllers/checkYourAnswers.ts +++ b/src/controllers/checkYourAnswers.ts @@ -45,7 +45,12 @@ export const get = async (req: Request, res: Response, next: NextFunction) => { locales.i18nCh.resolveNamespacesKeys(lang) ); - const formattedIdentityDocuments = clientData.idDocumentDetails!; + const identityDocuments = clientData.idDocumentDetails!; + + const formattedIdentityDocuments = identityDocuments.map((doc) => ({ + ...doc, + docName: FormatService.findDocumentName(doc.docName, locales.i18nCh.resolveNamespacesKeys(lang)) + })); const amlBodies = getAmlBodiesAsString(acspDetails); @@ -59,10 +64,11 @@ export const get = async (req: Request, res: Response, next: NextFunction) => { dateOfBirth: formattedDateOfBirth, whenIdentityChecksCompleted: formattedwhenIdentityChecksCompleted, documentsChecked: formattedDocumentsChecked, - idDocumentDetails: formattedIdentityDocuments + idDocumentDetails: identityDocuments }, amlBodies, - acspName: acspDetails.name + acspName: acspDetails.name, + formattedIdentityDocuments }); }; @@ -93,7 +99,12 @@ export const post = async (req: Request, res: Response, next: NextFunction) => { ); const amlBodies = getAmlBodiesAsString(acspDetails); - const formattedIdentityDocuments = clientData.idDocumentDetails!; + const identityDocuments = clientData.idDocumentDetails!; + + const formattedIdentityDocuments = identityDocuments.map((doc) => ({ + ...doc, + docName: FormatService.findDocumentName(doc.docName, locales.i18nCh.resolveNamespacesKeys(lang)) + })); const pageProperties = getPageProperties(formatValidationError(errorList.array(), lang)); res.status(400).render(config.CHECK_YOUR_ANSWERS, { @@ -107,10 +118,11 @@ export const post = async (req: Request, res: Response, next: NextFunction) => { dateOfBirth: formattedDateOfBirth, whenIdentityChecksCompleted: formattedwhenIdentityChecksCompleted, documentsChecked: formattedDocumentsChecked, - idDocumentDetails: formattedIdentityDocuments + idDocumentDetails: identityDocuments }, amlBodies, - acspName: acspDetails.name + acspName: acspDetails.name, + formattedIdentityDocuments }); } else { try { diff --git a/src/controllers/idDocumentDetailsController.ts b/src/controllers/idDocumentDetailsController.ts index 38d80cb..ee11b93 100644 --- a/src/controllers/idDocumentDetailsController.ts +++ b/src/controllers/idDocumentDetailsController.ts @@ -30,7 +30,7 @@ export const get = async (req: Request, res: Response, next: NextFunction) => { ); let payload; if (clientData.idDocumentDetails != null) { - payload = createPayload(clientData.idDocumentDetails, formattedDocumentsChecked); + payload = createPayload(clientData.idDocumentDetails, formattedDocumentsChecked, locales.i18nCh.resolveNamespacesKeys(lang)); } res.render(config.ID_DOCUMENT_DETAILS, { @@ -75,7 +75,7 @@ export const post = async (req: Request, res: Response, next: NextFunction) => { countryList: countryList }); } else { - documentDetailsService.saveIdDocumentDetails(req, clientData, formattedDocumentsChecked, locales.i18nCh.resolveNamespacesKeys(lang)); + documentDetailsService.saveIdDocumentDetails(req, clientData, clientData.documentsChecked!, locales.i18nCh.resolveNamespacesKeys(lang)); const checkYourAnswersFlag = session?.getExtraData(CHECK_YOUR_ANSWERS_FLAG); if (checkYourAnswersFlag) { @@ -94,11 +94,11 @@ const getBackUrl = (selectedOption: string) => { } }; -export const createPayload = (idDocumentDetails: DocumentDetails[], formatDocumentsCheckedText: string[]): { [key: string]: string | undefined } => { +export const createPayload = (idDocumentDetails: DocumentDetails[], formatDocumentsCheckedText: string[], i18: any): { [key: string]: string | undefined } => { const payload: { [key: string]: any | undefined } = {}; idDocumentDetails.forEach((body, index) => { for (let i = 0; i < formatDocumentsCheckedText.length; i++) { - if (formatDocumentsCheckedText[i] === body.docName) { + if (formatDocumentsCheckedText[i] === FormatService.findDocumentName(body.docName, i18)) { payload[`documentNumber_${i + 1}`] = body.documentNumber; if (body.expiryDate) { payload[`expiryDateDay_${i + 1}`] = body.expiryDate!.getDate(); diff --git a/src/services/formatService.ts b/src/services/formatService.ts index 2e92346..b253838 100644 --- a/src/services/formatService.ts +++ b/src/services/formatService.ts @@ -59,43 +59,13 @@ export class FormatService { public static formatDocumentsChecked ( documents: string[] | undefined, i18n: any - ): string { if (!documents || documents.length === 0) { return ""; } - const documentMapping: { [key: string]: string } = { - passport: i18n.biometricPassport, - irish_passport_card: i18n.irishPassport, - UK_or_EU_driving_licence: i18n.ukDriversLicence, - EEA_identity_card: i18n.identityCard, - UK_biometric_residence_permit: i18n.biometricPermit, - UK_biometric_residence_card: i18n.biometricCard, - UK_frontier_worker_permit: i18n.frontierPermit, - - UK_PASS_card: i18n.passCard, - UK_or_EU_digital_tachograph_card: i18n.ukEuDigitalCard, - UK_HM_forces_card: i18n.ukForceCard, - UK_HM_veteran_card: i18n.ukArmedForceCard, - work_permit_photo_id: i18n.photoWorkPermit, - immigration_document_photo_id: i18n.photoimmigrationDoc, - visa_photo_id: i18n.photoVisa, - UK_firearms_licence: i18n.ukFirearmsLicence, - PRADO_supported_photo_id: i18n.photoIdPrado, - birth_certificate: i18n.birthCert, - marriage_certificate: i18n.marriageCert, - immigration_document_non_photo_id: i18n.noPhotoimmigrationDoc, - visa_non_photo_id: i18n.noPhotoVisa, - work_permit_non_photo_id: i18n.noPhotoWorkPermit, - bank_statement: i18n.bankStatement, - rental_agreement: i18n.rentalAgreement, - mortgage_statement: i18n.morgageStatement, - UK_council_tax_statement: i18n.taxStatement, - utility_bill: i18n.utilityBill - }; const formattedDocuments = documents.map((doc) => { - const docText = documentMapping[doc] || doc; + const docText = FormatService.getDocumentName(doc, i18n); return `• ${docText}`; }); @@ -196,4 +166,46 @@ export class FormatService { }); return documentHintText; } + + public static findDocumentName ( + document: string | undefined, + i18n: any + ): string { + if (!document || document.length === 0) { + return ""; + } + return FormatService.getDocumentName(document, i18n); + } + + private static getDocumentName (document: string, i18n: any): string { + const documentMapping: { [key: string]: string } = { + passport: i18n.biometricPassport, + irish_passport_card: i18n.irishPassport, + UK_or_EU_driving_licence: i18n.ukDriversLicence, + EEA_identity_card: i18n.identityCard, + UK_biometric_residence_permit: i18n.biometricPermit, + UK_biometric_residence_card: i18n.biometricCard, + UK_frontier_worker_permit: i18n.frontierPermit, + UK_PASS_card: i18n.passCard, + UK_or_EU_digital_tachograph_card: i18n.ukEuDigitalCard, + UK_HM_forces_card: i18n.ukForceCard, + UK_HM_veteran_card: i18n.ukArmedForceCard, + work_permit_photo_id: i18n.photoWorkPermit, + immigration_document_photo_id: i18n.photoimmigrationDoc, + visa_photo_id: i18n.photoVisa, + UK_firearms_licence: i18n.ukFirearmsLicence, + PRADO_supported_photo_id: i18n.photoIdPrado, + birth_certificate: i18n.birthCert, + marriage_certificate: i18n.marriageCert, + immigration_document_non_photo_id: i18n.noPhotoimmigrationDoc, + visa_non_photo_id: i18n.noPhotoVisa, + work_permit_non_photo_id: i18n.noPhotoWorkPermit, + bank_statement: i18n.bankStatement, + rental_agreement: i18n.rentalAgreement, + mortgage_statement: i18n.morgageStatement, + UK_council_tax_statement: i18n.taxStatement, + utility_bill: i18n.utilityBill + }; + return documentMapping[document] ? documentMapping[document] : document; + } } diff --git a/src/views/check-your-answers/check-your-answers.njk b/src/views/check-your-answers/check-your-answers.njk index e96e6c5..7bda663 100644 --- a/src/views/check-your-answers/check-your-answers.njk +++ b/src/views/check-your-answers/check-your-answers.njk @@ -234,24 +234,24 @@ ] }) }} -{% for item in clientData.idDocumentDetails %} -

{{ item.docName + " " + i18n.details }}

+ {% for doc in formattedIdentityDocuments %} +

{{ doc.docName + " " + i18n.details }}

{{ govukSummaryList({ classes: 'govuk-!-margin-bottom-9', rows: [ { key: { - text: item.docName + " " + i18n.number + text: doc.docName + " " + i18n.number }, value: { - text: item.documentNumber + text: doc.documentNumber }, actions: { items: [ { href: "/tell-companies-house-you-have-verified-someones-identity/id-document-details" + "?lang=" + lang + "#documentNumber_" + loop.index, text: i18n.checkAnswerDetailsChange, - visuallyHiddenText: item.docName + " " + i18n.number + visuallyHiddenText: doc.docName + " " + i18n.number } ] } @@ -261,7 +261,7 @@ text: i18n.ExpiryDate }, value: { - text: item.formattedExpiryDate + text: doc.formattedExpiryDate }, actions: { items: [ @@ -278,7 +278,7 @@ text: i18n.chooseCountryText }, value: { - text: item.countryOfIssue + text: doc.countryOfIssue }, actions: { items: [ diff --git a/test/src/controllers/checkYourAnswers.test.ts b/test/src/controllers/checkYourAnswers.test.ts index 2301a9b..8a1f098 100644 --- a/test/src/controllers/checkYourAnswers.test.ts +++ b/test/src/controllers/checkYourAnswers.test.ts @@ -5,6 +5,11 @@ import { BASE_URL, CHECK_YOUR_ANSWERS, CONFIRMATION } from "../../../src/types/p import { findIdentityByEmail, sendVerifiedClientDetails } from "../../../src/services/identityVerificationService"; import { dummyIdentity } from "../../mocks/identity.mock"; import { sendIdentityVerificationConfirmationEmail } from "../../../src/services/acspEmailService"; +import { sessionMiddleware } from "../../../src/middleware/session_middleware"; +import { getSessionRequestWithPermission } from "../../mocks/session.mock"; +import { ACSP_DETAILS, USER_DATA } from "../../../src/utils/constants"; +import { Request, Response, NextFunction } from "express"; +import { dummyFullProfile } from "../../mocks/acsp_profile.mock"; jest.mock("@companieshouse/api-sdk-node"); jest.mock("../../../src/services/identityVerificationService.ts"); jest.mock("../../../src/services/acspEmailService.ts"); @@ -15,8 +20,11 @@ const mockSendIdentityVerificationConfirmationEmail = sendIdentityVerificationCo const router = supertest(app); +let customMockSessionMiddleware: any; + describe("GET" + CHECK_YOUR_ANSWERS, () => { it("should return status 200", async () => { + createMockSessionMiddleware(); const res = await router.get(BASE_URL + CHECK_YOUR_ANSWERS); expect(res.status).toBe(200); expect(mocks.mockSessionMiddleware).toHaveBeenCalled(); @@ -27,6 +35,7 @@ describe("GET" + CHECK_YOUR_ANSWERS, () => { describe("POST " + CHECK_YOUR_ANSWERS, () => { it("should return status 302 after redirect", async () => { + createMockSessionMiddleware(); await mockSendVerifiedClientDetails.mockResolvedValueOnce({ id: "12345" }); await mockFindIdentityByEmail.mockResolvedValueOnce(undefined); await mockSendIdentityVerificationConfirmationEmail.mockResolvedValueOnce({ status: 200 }); @@ -68,3 +77,23 @@ describe("POST " + CHECK_YOUR_ANSWERS, () => { expect(res.text).toContain("Sorry we are experiencing technical difficulties"); }); }); + +function createMockSessionMiddleware () { + customMockSessionMiddleware = sessionMiddleware as jest.Mock; + const session = getSessionRequestWithPermission(); + session.setExtraData(USER_DATA, { + idDocumentDetails: [ + { + docName: "passport", + documentNumber: "123456789", + expiryDate: new Date("2030-01-01"), + countryOfIssue: "UK" + } + ] + }); + session.setExtraData(ACSP_DETAILS, dummyFullProfile); + customMockSessionMiddleware.mockImplementation((req: Request, res: Response, next: NextFunction) => { + req.session = session; + next(); + }); +} diff --git a/test/src/controllers/idDocumentDetailsController.test.ts b/test/src/controllers/idDocumentDetailsController.test.ts index 16c7bab..ee19317 100644 --- a/test/src/controllers/idDocumentDetailsController.test.ts +++ b/test/src/controllers/idDocumentDetailsController.test.ts @@ -26,6 +26,7 @@ describe("GET" + ID_DOCUMENT_DETAILS, () => { describe("POST " + ID_DOCUMENT_DETAILS, () => { it("should redirect to confirmation page on valid input", async () => { + createMockSessionMiddleware(); const FormData = { documentNumber_1: "ABC12345X", expiryDateDay_1: "01", @@ -55,7 +56,7 @@ describe("POST " + ID_DOCUMENT_DETAILS, () => { }); it("should redirect to confirmation page on valid input", async () => { - createMockSessionMiddleware(); + createMockSessionCheckYourAnswersFlagMiddleware(); const FormData = { documentNumber_1: "ABC12345X", expiryDateDay_1: "01", @@ -82,8 +83,9 @@ describe("createPayload tests", () => { } ]; const formatDocumentsCheckedText = ["UK accredited PASS card"]; + const i18n = { passCard: "UK accredited PASS card" }; - const result = createPayload(idDocumentDetails, formatDocumentsCheckedText); + const result = createPayload(idDocumentDetails, formatDocumentsCheckedText, i18n); expect(result).toEqual({ documentNumber_1: "12345678", @@ -104,8 +106,9 @@ describe("createPayload tests", () => { } ]; const formatDocumentsCheckedText = ["UK HM Armed Forces Veteran Card"]; + const i18n = { ukArmedForceCard: "UK HM Armed Forces Veteran Card" }; - const result = createPayload(idDocumentDetails, formatDocumentsCheckedText); + const result = createPayload(idDocumentDetails, formatDocumentsCheckedText, i18n); expect(result).toEqual({ documentNumber_1: "12345678", @@ -126,8 +129,9 @@ describe("createPayload tests", () => { } ]; const formatDocumentsCheckedText = ["Irish passport card"]; + const i18n = { irishPassport: "Irish passport card" }; - const result = createPayload(idDocumentDetails, formatDocumentsCheckedText); + const result = createPayload(idDocumentDetails, formatDocumentsCheckedText, i18n); expect(result).toEqual({ documentNumber_1: "12345678", @@ -139,7 +143,7 @@ describe("createPayload tests", () => { }); }); -function createMockSessionMiddleware () { +function createMockSessionCheckYourAnswersFlagMiddleware () { customMockSessionMiddleware = sessionMiddleware as jest.Mock; const session = getSessionRequestWithPermission(); session.setExtraData(CHECK_YOUR_ANSWERS_FLAG, true); @@ -151,3 +155,15 @@ function createMockSessionMiddleware () { next(); }); } + +function createMockSessionMiddleware () { + customMockSessionMiddleware = sessionMiddleware as jest.Mock; + const session = getSessionRequestWithPermission(); + session.setExtraData(USER_DATA, { + documentsChecked: ["passport"] + }); + customMockSessionMiddleware.mockImplementation((req: Request, res: Response, next: NextFunction) => { + req.session = session; + next(); + }); +} diff --git a/test/src/services/formatService.test.ts b/test/src/services/formatService.test.ts index e143ba8..9d67390 100644 --- a/test/src/services/formatService.test.ts +++ b/test/src/services/formatService.test.ts @@ -26,4 +26,35 @@ describe("Format Service tests", () => { expect(hintText).toStrictEqual(["Photo Immigration Doc Hint", "Photo Visa Hint"]); }); }); + + describe("findDocumentName tests", () => { + + it("should return the document name for option 1 doc", () => { + const document = "irish_passport_card"; + const i18n = { + irishPassport: "Irish Passport" + }; + + const docName = FormatService.findDocumentName(document, i18n); + expect(docName).toStrictEqual("Irish Passport"); + }); + + it("should return the document name for option 2 doc", () => { + const document = "visa_photo_id"; + const i18n = { + photoVisa: "Photo Visa" + }; + + const docName = FormatService.findDocumentName(document, i18n); + expect(docName).toStrictEqual("Photo Visa"); + }); + + it("should return empty string for no document", () => { + const document = undefined; + const i18n = {}; + + const docName = FormatService.findDocumentName(document, i18n); + expect(docName).toStrictEqual(""); + }); + }); });