From 301bb84845098efbcc920d5f9b1d1be365cb55a4 Mon Sep 17 00:00:00 2001 From: AlisonGriffiths Date: Thu, 14 Nov 2024 16:50:03 +0000 Subject: [PATCH 1/5] Initial commit of psc list screen v9 content changes --- locales/cy/individual-psc-list.json | 25 +++- locales/en/individual-psc-list.json | 25 +++- .../individualPscList/individualPscList.njk | 141 ++++++++++++++---- 3 files changed, 157 insertions(+), 34 deletions(-) diff --git a/locales/cy/individual-psc-list.json b/locales/cy/individual-psc-list.json index ef7fe906..f7c79997 100644 --- a/locales/cy/individual-psc-list.json +++ b/locales/cy/individual-psc-list.json @@ -1,6 +1,23 @@ { - "individual_psc_list_main_title": "To be translated", - "individual_psc_list_hint_1": "To be translated", - "individual_psc_list_hint_2": "To be translated", - "individual_psc_list_born_in": "To be translated" + "ind_psc_list_main_title": "To be translated", + "ind_psc_list_description": "To be translated", + "ind_psc_list_can_verify_heading": "To be translated", + "ind_psc_list_can_verify_description": "To be translated ", + "ind_psc_list_can_verify_description2": " To be translated", + "ind_psc_list_summary_card_key1": "To be translated", + "ind_psc_list_summary_card_key2": "To be translated", + "ind_psc_list_summary_card_key3": "To be translated", + "ind_psc_list_summary_card_verify_link": "To be translated", + "ind_psc_list_cannot_verify_heading": "To be translated", + "ind_psc_list_cannot_verify_description": "To be translated ", + "ind_psc_list_cannot_verify_description2": "To be translated ", + "ind_psc_list_cannot_verify_description3": ", To be translated", + "ind_psc_list_cannot_verify_details_main_link": "To be translated", + "ind_psc_list_cannot_verify_details_description": "To be translated", + "ind_psc_list_not_found_details_main_link": "To be translated", + "ind_psc_list_not_found_details_description": "To be translated", + "ind_psc_list_not_found_details_description2": "To be translated", + "ind_psc_list_not_found_details_description3": "To be translated ", + "ind_psc_list_not_found_details_description4": "To be translated ", + "ind_psc_list_not_found_details_description5": ", To be translated" } \ No newline at end of file diff --git a/locales/en/individual-psc-list.json b/locales/en/individual-psc-list.json index 68d4fe60..0759da46 100644 --- a/locales/en/individual-psc-list.json +++ b/locales/en/individual-psc-list.json @@ -1,6 +1,23 @@ { - "individual_psc_list_main_title": "Which PSC are you providing verification details for?", - "individual_psc_list_hint_1": "The following PSCs for", - "individual_psc_list_hint_2": "still need to provide their identity verification details. We will not show PSCs whose identity has been confirmed. You can only provide verification details for one PSC at a time.", - "individual_psc_list_born_in": "Born in" + "ind_psc_list_main_title": "PSC identity verification status", + "ind_psc_list_description": "An overview of which PSCs still need to provide their verification details, and who has done it already.", + "ind_psc_list_can_verify_heading": "PSCs that need to provide verification details", + "ind_psc_list_can_verify_description": "These PSCs for ", + "ind_psc_list_can_verify_description2": " can provide their verification details now. You can only provide details for one PSC at a time.", + "ind_psc_list_summary_card_key1": "Date of birth", + "ind_psc_list_summary_card_key2": "Verification deadline", + "ind_psc_list_summary_card_key3": "Verification status", + "ind_psc_list_summary_card_verify_link": "Provide verification details", + "ind_psc_list_cannot_verify_heading": "PSCs that cannot provide verification details yet", + "ind_psc_list_cannot_verify_description": "These PSCs for ", + "ind_psc_list_cannot_verify_description2": "must wait until ", + "ind_psc_list_cannot_verify_description3": ", which is the company's confirmation statement date. They will have 14 days from this date to provide their verification details.", + "ind_psc_list_cannot_verify_details_main_link": "Why do these PSCs need to wait?", + "ind_psc_list_cannot_verify_details_description": "These PSCs were registered with Companies House before the new identity verification requirements were introduced. We are not able to accept their verification details until the company has reached its confirmation statement date.", + "ind_psc_list_not_found_details_main_link": "I can't find the PSC I'm looking for", + "ind_psc_list_not_found_details_description": "You can only use this service to provide verification details for PSCs that are shown on the Companies House register.", + "ind_psc_list_not_found_details_description2": "If the company has recently notified Companies House of a new PSC, you must wait until that filing is accepted and the new PSC appears on the public register.", + "ind_psc_list_not_found_details_description3": "If a PSC has their personal information protected from being shown on the register, you'll need to provide their verification details using a paper form. To request a form, email ", + "ind_psc_list_not_found_details_description4": "or call ", + "ind_psc_list_not_found_details_description5": ", and provide the company name and number." } \ No newline at end of file diff --git a/src/views/router_views/individualPscList/individualPscList.njk b/src/views/router_views/individualPscList/individualPscList.njk index dea22ba6..39f875c6 100644 --- a/src/views/router_views/individualPscList/individualPscList.njk +++ b/src/views/router_views/individualPscList/individualPscList.njk @@ -1,35 +1,124 @@ {% extends "layouts/default.njk" %} -{% from "govuk/components/radios/macro.njk" import govukRadios %} +{% from "govuk/components/summary-list/macro.njk" import govukSummaryList %} +{% from "govuk/components/details/macro.njk" import govukDetails %} -{% set title = i18n.individual_psc_list_main_title %} +{% set title = i18n.ind_psc_list_main_title %} {% block main_content %}
- {% include "includes/csrf_token.njk" %} -
- {{ govukRadios({ - classes: "govuk-radios", - id: "psc-individual-radios", - name: "pscSelect", - fieldset: { - legend: { - text: i18n.individual_psc_list_main_title, - isPageHeading: true, - classes: "govuk-fieldset__legend--l" - } - }, - hint: { - text: [i18n.individual_psc_list_hint_1, companyName, i18n.individual_psc_list_hint_2] | join(" ") - }, - items: pscRadioItems, - value: selectedPscId - }) - }} -
- + {% include "includes/csrf_token.njk" %} + +

{{ i18n.ind_psc_list_main_title }}

+

{{ i18n.ind_psc_list_description }}

+ +

{{ i18n.ind_psc_list_can_verify_heading }}

+

{{ i18n.ind_psc_list_can_verify_description }}[company_name]{{ i18n.ind_psc_list_can_verify_description2 }}

+ + + {{ govukSummaryList({ + card: { + title: { + text: "[Name of the psc]" + }, + actions: { + items: [ + { + href: "#", + text: i18n.ind_psc_list_summary_card_verify_link, + visuallyHiddenText: "[do we need this?]" + } + ] + } + }, + rows: [ + { + key: { + text: i18n.ind_psc_list_summary_card_key1 + }, + value: { + html: "[partial_dob]" + } + }, + { + key: { + text: i18n.ind_psc_list_summary_card_key2 + }, + value: { + html: "[verification_deadline]" + } + }, + { + key: { + text: i18n.ind_psc_list_summary_card_key3 + }, + value: { + html: '[Unverified]' + } + } + ] +}) }} + +

{{ i18n.ind_psc_list_cannot_verify_heading }}

+

{{ i18n.ind_psc_list_cannot_verify_description }}[company_name]{{ i18n.ind_psc_list_cannot_verify_description2 }}[confirmation_statement_date]{{ i18n.ind_psc_list_cannot_verify_description3 }}

+ +{{ govukDetails({ + summaryText: i18n.ind_psc_list_cannot_verify_details_main_link, + text: i18n.ind_psc_list_cannot_verify_details_description, + attributes: { + "data-event-id": "why-do-pscs-need-to-wait-dropdown" + } +}) }} + +{{ govukSummaryList({ + card: { + title: { + text: "[Name of the psc]" + } + }, + rows: [ + { + key: { + text: i18n.ind_psc_list_summary_card_key1 + }, + value: { + html: "[partial_dob]" + } + }, + { + key: { + text: i18n.ind_psc_list_summary_card_key2 + }, + value: { + html: "[verification_deadline]" + } + }, + { + key: { + text: i18n.ind_psc_list_summary_card_key3 + }, + value: { + html: '[Unverified]' + } + } + ] +}) }} + +{% set pscNotFoundDetails %} +

{{ i18n.ind_psc_list_not_found_details_description }}

+

{{ i18n.ind_psc_list_not_found_details_description2 }}

+

{{ i18n.ind_psc_list_not_found_details_description3 }}[dsr_email_address] + {{ i18n.ind_psc_list_not_found_details_description4 }}[dsr_phone_number] + {{ i18n.ind_psc_list_not_found_details_description5 }}

+ {% endset %} + +{{ govukDetails({ + summaryText: i18n.ind_psc_list_not_found_details_main_link, + html: pscNotFoundDetails, + attributes: { + "data-event-id": "why-do-pscs-need-to-wait-dropdown" + } +}) }} {% endblock %} From 191fdc36de15a079c0c7113d0e83f2eb513c79ce Mon Sep 17 00:00:00 2001 From: AlisonGriffiths Date: Tue, 19 Nov 2024 16:55:16 +0000 Subject: [PATCH 2/5] Introduced temp fix for routing issues and fixed tests --- locales/cy/individual-psc-list.json | 3 +- locales/en/individual-psc-list.json | 5 +- src/config/index.ts | 6 ++ .../individualPscListHandler.ts | 73 ++++++++++--------- .../individualStatementHandler.ts | 8 +- .../personal-code/personalCodeHandler.ts | 13 +++- src/routers/personalCodeRouter.ts | 10 +-- .../individualPscList/individualPscList.njk | 34 ++++++--- .../personal_code/personal_code.njk | 9 ++- test/mocks/pscVerification.mock.ts | 10 ++- .../individualStatement.int.ts | 2 +- .../individualStatement.unit.ts | 2 +- .../personal-code/personalCode.int.ts | 6 +- .../personal-code/personalCode.unit.ts | 57 ++++++++------- .../handlers/psc-verified/pscVerified.int.ts | 4 +- .../psc-verified/pscVerifiedHandler.unit.ts | 4 +- 16 files changed, 143 insertions(+), 103 deletions(-) diff --git a/locales/cy/individual-psc-list.json b/locales/cy/individual-psc-list.json index f7c79997..33a84a81 100644 --- a/locales/cy/individual-psc-list.json +++ b/locales/cy/individual-psc-list.json @@ -19,5 +19,6 @@ "ind_psc_list_not_found_details_description2": "To be translated", "ind_psc_list_not_found_details_description3": "To be translated ", "ind_psc_list_not_found_details_description4": "To be translated ", - "ind_psc_list_not_found_details_description5": ", To be translated" + "ind_psc_list_not_found_details_description5": ", To be translated", + "ind_psc_list_status_unverified": "To be translated" } \ No newline at end of file diff --git a/locales/en/individual-psc-list.json b/locales/en/individual-psc-list.json index 0759da46..4f4460fe 100644 --- a/locales/en/individual-psc-list.json +++ b/locales/en/individual-psc-list.json @@ -10,7 +10,7 @@ "ind_psc_list_summary_card_verify_link": "Provide verification details", "ind_psc_list_cannot_verify_heading": "PSCs that cannot provide verification details yet", "ind_psc_list_cannot_verify_description": "These PSCs for ", - "ind_psc_list_cannot_verify_description2": "must wait until ", + "ind_psc_list_cannot_verify_description2": " must wait until ", "ind_psc_list_cannot_verify_description3": ", which is the company's confirmation statement date. They will have 14 days from this date to provide their verification details.", "ind_psc_list_cannot_verify_details_main_link": "Why do these PSCs need to wait?", "ind_psc_list_cannot_verify_details_description": "These PSCs were registered with Companies House before the new identity verification requirements were introduced. We are not able to accept their verification details until the company has reached its confirmation statement date.", @@ -19,5 +19,6 @@ "ind_psc_list_not_found_details_description2": "If the company has recently notified Companies House of a new PSC, you must wait until that filing is accepted and the new PSC appears on the public register.", "ind_psc_list_not_found_details_description3": "If a PSC has their personal information protected from being shown on the register, you'll need to provide their verification details using a paper form. To request a form, email ", "ind_psc_list_not_found_details_description4": "or call ", - "ind_psc_list_not_found_details_description5": ", and provide the company name and number." + "ind_psc_list_not_found_details_description5": ", and provide the company name and number.", + "ind_psc_list_status_unverified": "Unverified" } \ No newline at end of file diff --git a/src/config/index.ts b/src/config/index.ts index 7c228c4c..d9846e66 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -40,6 +40,12 @@ export const env = readEnv(process.env, { DEVELOPERS_LINK: str .describe("Link for developers") .default("https://developer.companieshouse.gov.uk/"), + DSR_EMAIL_ADDRESS: str + .describe("Email Address for DSR team") + .default("dsr@companieshouse.gov.uk"), + DSR_PHONE_NUMBER: str + .describe("Telephone number for the DSR team") + .default("02921 507 370"), FEEDBACK_URL: str .describe("Link for the user to give feedback on the service") .default(""), diff --git a/src/routers/handlers/individual-psc-list/individualPscListHandler.ts b/src/routers/handlers/individual-psc-list/individualPscListHandler.ts index 737a6206..9c6f8790 100644 --- a/src/routers/handlers/individual-psc-list/individualPscListHandler.ts +++ b/src/routers/handlers/individual-psc-list/individualPscListHandler.ts @@ -2,30 +2,30 @@ import { Request, Response } from "express"; import { PrefixedUrls, Urls } from "../../../constants"; import { logger } from "../../../lib/logger"; import { getLocaleInfo, getLocalesService, selectLang } from "../../../utils/localise"; +import { addSearchParams } from "../../../utils/queryParams"; import { getUrlWithTransactionIdAndSubmissionId } from "../../../utils/url"; import { BaseViewData, GenericHandler, ViewModel } from "../generic"; import { CompanyPersonWithSignificantControl } from "@companieshouse/api-sdk-node/dist/services/company-psc/types"; import { getCompanyIndividualPscList } from "../../../services/companyPscService"; import { patchPscVerification } from "../../../services/pscVerificationService"; -import { formatDateBorn } from "../../utils"; - -interface PartialDate { - year: string | number, - month: string | number +import { formatDateBorn, internationaliseDate } from "../../utils"; +import { env } from "../../../config"; + +interface PscListData { + pscId: string, + pscName: string, + pscDob: string, + pscVerificationDeadlineDate: string } -interface RadioButtonData { - text: string, - value: string, - attributes: { [attr: string]: string}, - hint?: { - text: string - }, -} interface IndividualPscListViewData extends BaseViewData { companyName: string, - pscRadioItems: RadioButtonData[], - selectedPscId: string + confirmationStatementDate: string, + dsrEmailAddress: string, + dsrPhoneNumber: string, + pscDetails: PscListData[], + selectedPscId: string | null, + nextPageUrl: string | null } export class IndividualPscListHandler extends GenericHandler { @@ -40,10 +40,17 @@ export class IndividualPscListHandler extends GenericHandler> { @@ -94,22 +107,16 @@ export class IndividualPscListHandler extends GenericHandler { - const hintText = this.formatHintText(psc.dateOfBirth, lang, psc); + const pscFormattedDob = `${formatDateBorn(psc.dateOfBirth, lang)}`; return { - value: psc.links.self.split("/").pop() as string, - text: psc.name, - attributes: { "data-event-id": "selected-PSC-radio-option" }, - hint: hintText ? { - text: hintText - } : undefined + pscId: psc.links.self.split("/").pop() as string, + pscName: psc.name, + pscDob: pscFormattedDob as string, + pscVerificationDeadlineDate: "[pscVerificationDate]" }; }); } - - private formatHintText (dob: PartialDate, lang: string, psc: CompanyPersonWithSignificantControl) { - return `${getLocalesService().i18nCh.resolveSingleKey("individual_psc_list_born_in", lang)} ${formatDateBorn(dob, lang)}`; - } } diff --git a/src/routers/handlers/individual-statement/individualStatementHandler.ts b/src/routers/handlers/individual-statement/individualStatementHandler.ts index ab990b02..bba60a13 100644 --- a/src/routers/handlers/individual-statement/individualStatementHandler.ts +++ b/src/routers/handlers/individual-statement/individualStatementHandler.ts @@ -10,7 +10,7 @@ import { BaseViewData, GenericHandler, ViewModel } from "../generic"; import { formatDateBorn } from "../../utils"; import { PscVerificationData, VerificationStatementEnum } from "@companieshouse/api-sdk-node/dist/services/psc-verification-link/types"; -interface IndividualStatementViewData extends BaseViewData {pscName: string, selectedStatements: string[], dateOfBirth: string} +interface IndividualStatementViewData extends BaseViewData {pscName: string, selectedStatements: string[], dateOfBirth: string, selectedPscId: string} export class IndividualStatementHandler extends GenericHandler { @@ -25,6 +25,7 @@ export class IndividualStatementHandler extends GenericHandler { @@ -24,7 +25,8 @@ export class PersonalCodeHandler extends GenericHandler { const baseViewData = await super.getViewData(req, res); const verification: PscVerification = res.locals.submission; - const pscIndividual = await getPscIndividual(req, verification.data.companyNumber as string, verification.data.pscAppointmentId as string); + const selectedPscId = req.query?.selectedPscId as string; + const pscIndividual = await getPscIndividual(req, verification.data.companyNumber as string, selectedPscId); const lang = selectLang(req.query.lang); const locales = getLocalesService(); @@ -41,7 +43,7 @@ export class PersonalCodeHandler extends GenericHandler { }; function resolveUrlTemplate (prefixedUrl: string): string | null { - return addSearchParams(getUrlWithTransactionIdAndSubmissionId(prefixedUrl, req.params.transactionId, req.params.submissionId), { lang }); + return addSearchParams(getUrlWithTransactionIdAndSubmissionId(prefixedUrl, req.params.transactionId, req.params.submissionId), { lang, selectedPscId }); } } @@ -59,11 +61,16 @@ export class PersonalCodeHandler extends GenericHandler { logger.info(`${PersonalCodeHandler.name} - ${this.executePost.name} called for transaction: ${req.params?.transactionId} and submissionId: ${req.params?.submissionId}`); const uvid = req.body.personalCode; const verification: PscVerificationData = { + pscAppointmentId: req.query?.selectedPscId as string, verificationDetails: { uvid: uvid } }; logger.debug(`${PersonalCodeHandler.name} - ${this.executePost.name} - patching personal code for transaction: ${req.params?.transactionId} and submissionId: ${req.params?.submissionId}`); await patchPscVerification(req, req.params.transactionId, req.params.submissionId, verification); + + const nextPageUrl = getUrlWithTransactionIdAndSubmissionId(PrefixedUrls.INDIVIDUAL_STATEMENT, req.params.transactionId, req.params.submissionId); + const lang = selectLang(req.query.lang); + return (addSearchParams(nextPageUrl, { lang })); } } diff --git a/src/routers/personalCodeRouter.ts b/src/routers/personalCodeRouter.ts index 2d01148f..70cbd934 100644 --- a/src/routers/personalCodeRouter.ts +++ b/src/routers/personalCodeRouter.ts @@ -1,10 +1,6 @@ import { NextFunction, Request, Response, Router } from "express"; -import { PrefixedUrls } from "../constants"; import { handleExceptions } from "../utils/asyncHandler"; import { PersonalCodeHandler } from "./handlers/personal-code/personalCodeHandler"; -import { selectLang } from "../utils/localise"; -import { getUrlWithTransactionIdAndSubmissionId } from "../utils/url"; -import { addSearchParams } from "../utils/queryParams"; const personalCodeRouter: Router = Router({ mergeParams: true }); @@ -16,11 +12,7 @@ personalCodeRouter.get("/", handleExceptions(async (req: Request, res: Response) personalCodeRouter.post("/", handleExceptions(async (req: Request, res: Response, _next: NextFunction) => { const handler = new PersonalCodeHandler(); - await handler.executePost(req, res); - - const nextPageUrl = getUrlWithTransactionIdAndSubmissionId(PrefixedUrls.INDIVIDUAL_STATEMENT, req.params.transactionId, req.params.submissionId); - const lang = selectLang(req.query.lang); - res.redirect(addSearchParams(nextPageUrl, { lang })); + res.redirect(await handler.executePost(req, res)); })); export default personalCodeRouter; diff --git a/src/views/router_views/individualPscList/individualPscList.njk b/src/views/router_views/individualPscList/individualPscList.njk index 39f875c6..d876e029 100644 --- a/src/views/router_views/individualPscList/individualPscList.njk +++ b/src/views/router_views/individualPscList/individualPscList.njk @@ -13,20 +13,25 @@

{{ i18n.ind_psc_list_description }}

{{ i18n.ind_psc_list_can_verify_heading }}

-

{{ i18n.ind_psc_list_can_verify_description }}[company_name]{{ i18n.ind_psc_list_can_verify_description2 }}

+

{{ i18n.ind_psc_list_can_verify_description }}{{ companyName }}{{ i18n.ind_psc_list_can_verify_description2 }}

+{% for psc in pscDetails | sort(attribute = 'pscName') %} + +{% set pscStatusText %} + {{ i18n.ind_psc_list_status_unverified }} +{% endset %} {{ govukSummaryList({ card: { title: { - text: "[Name of the psc]" + text: psc.pscName }, actions: { items: [ { - href: "#", + href: [nextPageUrl+psc.pscId ], text: i18n.ind_psc_list_summary_card_verify_link, - visuallyHiddenText: "[do we need this?]" + visuallyHiddenText: i18n.ind_psc_list_summary_card_verify_link } ] } @@ -37,7 +42,7 @@ text: i18n.ind_psc_list_summary_card_key1 }, value: { - html: "[partial_dob]" + text: psc.pscDob } }, { @@ -45,7 +50,7 @@ text: i18n.ind_psc_list_summary_card_key2 }, value: { - html: "[verification_deadline]" + text: psc.pscVerificationDeadlineDate } }, { @@ -53,14 +58,17 @@ text: i18n.ind_psc_list_summary_card_key3 }, value: { - html: '[Unverified]' + html: pscStatusText } } ] }) }} +{% endfor %} +

{{ i18n.ind_psc_list_cannot_verify_heading }}

-

{{ i18n.ind_psc_list_cannot_verify_description }}[company_name]{{ i18n.ind_psc_list_cannot_verify_description2 }}[confirmation_statement_date]{{ i18n.ind_psc_list_cannot_verify_description3 }}

+

{{ i18n.ind_psc_list_cannot_verify_description }}{{ companyName }} +{{ i18n.ind_psc_list_cannot_verify_description2 }}{{ confirmationStatementDate }}{{ i18n.ind_psc_list_cannot_verify_description3 }}

{{ govukDetails({ summaryText: i18n.ind_psc_list_cannot_verify_details_main_link, @@ -70,6 +78,10 @@ } }) }} +{% set unverifiablePscStatusText %} + {{ i18n.ind_psc_list_status_unverified }} +{% endset %} + {{ govukSummaryList({ card: { title: { @@ -98,7 +110,7 @@ text: i18n.ind_psc_list_summary_card_key3 }, value: { - html: '[Unverified]' + html: unverifiablePscStatusText } } ] @@ -107,8 +119,8 @@ {% set pscNotFoundDetails %}

{{ i18n.ind_psc_list_not_found_details_description }}

{{ i18n.ind_psc_list_not_found_details_description2 }}

-

{{ i18n.ind_psc_list_not_found_details_description3 }}[dsr_email_address] - {{ i18n.ind_psc_list_not_found_details_description4 }}[dsr_phone_number] +

{{ i18n.ind_psc_list_not_found_details_description3 }}{{ dsrEmailAddress }} + {{ i18n.ind_psc_list_not_found_details_description4 }}{{ dsrPhoneNumber }} {{ i18n.ind_psc_list_not_found_details_description5 }}

{% endset %} diff --git a/src/views/router_views/personal_code/personal_code.njk b/src/views/router_views/personal_code/personal_code.njk index cc90934d..093bd4a1 100644 --- a/src/views/router_views/personal_code/personal_code.njk +++ b/src/views/router_views/personal_code/personal_code.njk @@ -31,6 +31,13 @@ value: personalCode }) }} + {{ govukInput({ + id: "selectedPscId", + type:"hidden", + name: "selectedPscId", + value: selectedPscId + }) + }} {{ govukDetails({ summaryText: i18n.personal_code_details_summaryText, @@ -41,7 +48,7 @@ } }) }} - + {{ govukButton({ attributes: { id: "submit", "data-event-id": "personal-code-continue-button" diff --git a/test/mocks/pscVerification.mock.ts b/test/mocks/pscVerification.mock.ts index 95f1174e..24d3e94f 100644 --- a/test/mocks/pscVerification.mock.ts +++ b/test/mocks/pscVerification.mock.ts @@ -4,6 +4,7 @@ export const FIRST_DATE = new Date(2024, 0, 2, 3, 4, 5, 6); export const DOB_DATE = new Date("1970-01-01"); export const COMPANY_NUMBER = "12345678"; export const TRANSACTION_ID = "11111-22222-33333"; +export const PSC_APPOINTMENT_ID = "123456"; export const PSC_VERIFICATION_ID = "662a0de6a2c6f9aead0f32ab"; export const UVID = "123abc456edf"; export const SELF_URI = `/transactions/${TRANSACTION_ID}/persons-with-significant-control-verification/${PSC_VERIFICATION_ID}`; @@ -19,7 +20,7 @@ export const LINKS: Links = { export const INDIVIDUAL_DATA: PscVerificationData = { companyNumber: COMPANY_NUMBER, - pscAppointmentId: PSC_VERIFICATION_ID, + pscAppointmentId: PSC_APPOINTMENT_ID, verificationDetails: { verificationStatements: [VerificationStatementEnum.INDIVIDUAL_VERIFIED] } @@ -27,7 +28,7 @@ export const INDIVIDUAL_DATA: PscVerificationData = { export const PATCH_INDIVIDUAL_DATA: PscVerificationData = { companyNumber: COMPANY_NUMBER, - pscAppointmentId: PSC_VERIFICATION_ID + pscAppointmentId: PSC_APPOINTMENT_ID }; export const PATCH_RLE_DATA: PscVerificationData = { @@ -43,6 +44,7 @@ export const PATCH_INDIVIDUAL_STATEMENT_DATA: PscVerificationData = { }; export const PATCH_PERSONAL_CODE_DATA: PscVerificationData = { + pscAppointmentId: PSC_APPOINTMENT_ID, verificationDetails: { uvid: UVID } @@ -57,7 +59,7 @@ export const PATCH_INDIVIDUAL_STATEMENT: PscVerification = { export const PATCHED_INDIVIDUAL_STATEMENT_DATA: PscVerificationData = { companyNumber: COMPANY_NUMBER, - pscAppointmentId: PSC_VERIFICATION_ID, + pscAppointmentId: PSC_APPOINTMENT_ID, verificationDetails: { nameMismatchReason: NameMismatchReasonEnum.PREFERRED_NAME, verificationStatements: [VerificationStatementEnum.INDIVIDUAL_VERIFIED] @@ -73,7 +75,7 @@ export const PATCHED_INDIVIDUAL_STATEMENT: PscVerification = { export const RLE_DATA_FULL: PscVerificationData = { companyNumber: COMPANY_NUMBER, - pscAppointmentId: PSC_VERIFICATION_ID, + pscAppointmentId: PSC_APPOINTMENT_ID, relevantOfficer: { nameElements: { title: "Sir", diff --git a/test/routers/handlers/individual-statement/individualStatement.int.ts b/test/routers/handlers/individual-statement/individualStatement.int.ts index 879257f6..05c6a2c0 100644 --- a/test/routers/handlers/individual-statement/individualStatement.int.ts +++ b/test/routers/handlers/individual-statement/individualStatement.int.ts @@ -53,7 +53,7 @@ describe("individual statement view", () => { const $ = cheerio.load(resp.text); expect(resp.status).toBe(HttpStatusCode.Ok); - expect($("a.govuk-back-link").attr("href")).toBe(`/persons-with-significant-control-verification/transaction/11111-22222-33333/submission/662a0de6a2c6f9aead0f32ab/individual/personal-code?lang=${lang}`); + expect($("a.govuk-back-link").attr("href")).toBe(`/persons-with-significant-control-verification/transaction/11111-22222-33333/submission/662a0de6a2c6f9aead0f32ab/individual/personal-code?lang=${lang}&selectedPscId=123456`); if (lang === "en") { expect($("div#nameAndDateOfBirth").text()).toBe("Sir Forename Middlename Surname (Born April 2000)"); // expect emphasis applied to PSC name diff --git a/test/routers/handlers/individual-statement/individualStatement.unit.ts b/test/routers/handlers/individual-statement/individualStatement.unit.ts index 5c13f9e5..dfc28f8e 100644 --- a/test/routers/handlers/individual-statement/individualStatement.unit.ts +++ b/test/routers/handlers/individual-statement/individualStatement.unit.ts @@ -54,7 +54,7 @@ describe("Individual statement handler", () => { expect(resp.templatePath).toBe("router_views/individual_statement/individual_statement"); expect(resp.viewData).toMatchObject({ - currentUrl: `${expectedPrefix}/individual/psc-statement?lang=en`, + currentUrl: `${expectedPrefix}/individual/psc-statement?lang=en&selectedPscId=123456`, selectedStatements: [VerificationStatementEnum.INDIVIDUAL_VERIFIED], pscName: "Sir Forename Middlename Surname", dateOfBirth: "April 2000", diff --git a/test/routers/handlers/personal-code/personalCode.int.ts b/test/routers/handlers/personal-code/personalCode.int.ts index eb0ec833..1beb63e1 100644 --- a/test/routers/handlers/personal-code/personalCode.int.ts +++ b/test/routers/handlers/personal-code/personalCode.int.ts @@ -7,7 +7,7 @@ import mockCsrfProtectionMiddleware from "../../../mocks/csrfProtectionMiddlewar import { PrefixedUrls } from "../../../../src/constants"; import { getUrlWithTransactionIdAndSubmissionId } from "../../../../src/utils/url"; import { PSC_INDIVIDUAL } from "../../../mocks/psc.mock"; -import { INDIVIDUAL_VERIFICATION_PATCH, PATCH_INDIVIDUAL_DATA, PSC_VERIFICATION_ID, TRANSACTION_ID } from "../../../mocks/pscVerification.mock"; +import { INDIVIDUAL_VERIFICATION_PATCH, PATCH_INDIVIDUAL_DATA, PSC_APPOINTMENT_ID, PSC_VERIFICATION_ID, TRANSACTION_ID } from "../../../mocks/pscVerification.mock"; import { getPscVerification, patchPscVerification } from "../../../../src/services/pscVerificationService"; import app from "../../../../src/app"; import { PscVerificationData } from "@companieshouse/api-sdk-node/dist/services/psc-verification-link/types"; @@ -54,6 +54,8 @@ describe("personal code router/handler integration tests", () => { it("Should render the Personal Code page with a success status code and the correct links and content", async () => { const queryParams = new URLSearchParams("lang=en"); + queryParams.set("selectedPscId", PSC_APPOINTMENT_ID); + const uriWithQuery = `${PrefixedUrls.PERSONAL_CODE}?${queryParams}`; const uri = getUrlWithTransactionIdAndSubmissionId(uriWithQuery, TRANSACTION_ID, PSC_VERIFICATION_ID); @@ -62,7 +64,7 @@ describe("personal code router/handler integration tests", () => { const $ = cheerio.load(resp.text); - expect($("a.govuk-back-link").attr("href")).toBe("/persons-with-significant-control-verification/transaction/11111-22222-33333/submission/662a0de6a2c6f9aead0f32ab/individual/psc-list?lang=en"); + expect($("a.govuk-back-link").attr("href")).toBe("/persons-with-significant-control-verification/transaction/11111-22222-33333/submission/662a0de6a2c6f9aead0f32ab/individual/psc-list?lang=en&selectedPscId=123456"); }); it("Should display the PSC inidividual's name and DOB on the Personal Code page", async () => { diff --git a/test/routers/handlers/personal-code/personalCode.unit.ts b/test/routers/handlers/personal-code/personalCode.unit.ts index f73e824f..39087c58 100644 --- a/test/routers/handlers/personal-code/personalCode.unit.ts +++ b/test/routers/handlers/personal-code/personalCode.unit.ts @@ -1,7 +1,7 @@ import * as httpMocks from "node-mocks-http"; import { Urls } from "../../../../src/constants"; import { PersonalCodeHandler } from "../../../../src/routers/handlers/personal-code/personalCodeHandler"; -import { COMPANY_NUMBER, INDIVIDUAL_VERIFICATION_PATCH, PATCH_PERSONAL_CODE_DATA, PSC_VERIFICATION_ID, TRANSACTION_ID } from "../../../mocks/pscVerification.mock"; +import { COMPANY_NUMBER, INDIVIDUAL_VERIFICATION_PATCH, PATCH_PERSONAL_CODE_DATA, PSC_APPOINTMENT_ID, PSC_VERIFICATION_ID, TRANSACTION_ID } from "../../../mocks/pscVerification.mock"; import { getPscIndividual } from "../../../../src/services/pscService"; import { PSC_INDIVIDUAL } from "../../../mocks/psc.mock"; import { HttpStatusCode } from "axios"; @@ -34,7 +34,8 @@ describe("personal code handler tests", () => { const req = httpMocks.createRequest({ method: "GET", - url: Urls.PERSONAL_CODE + url: Urls.PERSONAL_CODE, + query: { selectedPscId: PSC_APPOINTMENT_ID } }); const res = httpMocks.createResponse({ locals: { submission: INDIVIDUAL_VERIFICATION_PATCH } }); @@ -55,7 +56,7 @@ describe("personal code handler tests", () => { }, query: { companyNumber: COMPANY_NUMBER, - pscAppointmentId: PSC_VERIFICATION_ID, + pscAppointmentId: PSC_APPOINTMENT_ID, lang: "en" } }); @@ -71,7 +72,7 @@ describe("personal code handler tests", () => { }, query: { companyNumber: COMPANY_NUMBER, - pscAppointmentId: PSC_VERIFICATION_ID, + selectedPscId: PSC_APPOINTMENT_ID, lang: "en" } }); @@ -81,35 +82,35 @@ describe("personal code handler tests", () => { const { templatePath, viewData } = await handler.executeGet(req, res); expect(viewData).toMatchObject({ - backURL: `/persons-with-significant-control-verification/transaction/${TRANSACTION_ID}/submission/${PSC_VERIFICATION_ID}/individual/psc-list?lang=en`, - currentUrl: `/persons-with-significant-control-verification/transaction/${TRANSACTION_ID}/submission/${PSC_VERIFICATION_ID}/individual/personal-code?lang=en` + backURL: `/persons-with-significant-control-verification/transaction/${TRANSACTION_ID}/submission/${PSC_VERIFICATION_ID}/individual/psc-list?lang=en&selectedPscId=123456`, + currentUrl: `/persons-with-significant-control-verification/transaction/${TRANSACTION_ID}/submission/${PSC_VERIFICATION_ID}/individual/personal-code?lang=en&selectedPscId=123456` }); }); }); - describe.skip("executePost", () => { - const req = httpMocks.createRequest({ - method: "POST", - url: Urls.PERSONAL_CODE, - params: { - transactionId: TRANSACTION_ID, - submissionId: PSC_VERIFICATION_ID - }, - query: { - lang: "en", - companyNumber: COMPANY_NUMBER, - pscAppointmentId: PSC_VERIFICATION_ID - }, - body: { - PscVerificationData: PATCH_PERSONAL_CODE_DATA - } - }); - - const res = httpMocks.createResponse({}); - const handler = new PersonalCodeHandler(); + describe("executePost", () => { + it("should return the correct next page", async () => { + const req = httpMocks.createRequest({ + method: "POST", + url: Urls.PERSONAL_CODE, + params: { + transactionId: TRANSACTION_ID, + submissionId: PSC_VERIFICATION_ID + }, + query: { + lang: "en", + selectedPscId: PSC_APPOINTMENT_ID + }, + body: { + PscVerificationData: PATCH_PERSONAL_CODE_DATA + } + }); - const redirectUrl = handler.executePost(req, res); + const res = httpMocks.createResponse({}); + const handler = new PersonalCodeHandler(); - // expect(redirectUrl).toBe(`persons-with-significant-control-verification/transaction/${TRANSACTION_ID}/submission/${PSC_VERIFICATION_ID}/individual/psc-statement?lang=en`); + const nextPage = await handler.executePost(req, res); + expect(nextPage).toBe(`/persons-with-significant-control-verification/transaction/${TRANSACTION_ID}/submission/${PSC_VERIFICATION_ID}/individual/psc-statement?lang=en`); + }); }); }); diff --git a/test/routers/handlers/psc-verified/pscVerified.int.ts b/test/routers/handlers/psc-verified/pscVerified.int.ts index 0c916389..6bbef49a 100644 --- a/test/routers/handlers/psc-verified/pscVerified.int.ts +++ b/test/routers/handlers/psc-verified/pscVerified.int.ts @@ -8,7 +8,7 @@ import { PrefixedUrls } from "../../../../src/constants"; import { getCompanyProfile } from "../../../../src/services/companyProfileService"; import { closeTransaction } from "../../../../src/services/transactionService"; import { PSC_INDIVIDUAL } from "../../../mocks/psc.mock"; -import { COMPANY_NUMBER, INDIVIDUAL_VERIFICATION_FULL, PSC_VERIFICATION_ID, TRANSACTION_ID } from "../../../mocks/pscVerification.mock"; +import { COMPANY_NUMBER, INDIVIDUAL_VERIFICATION_FULL, PSC_APPOINTMENT_ID, PSC_VERIFICATION_ID, TRANSACTION_ID } from "../../../mocks/pscVerification.mock"; import { validCompanyProfile } from "../../../mocks/companyProfile.mock"; import { getUrlWithTransactionIdAndSubmissionId } from "../../../../src/utils/url"; import { getPscVerification } from "../../../../src/services/pscVerificationService"; @@ -68,7 +68,7 @@ describe("psc verified view tests", () => { expect(mockGetCompanyProfile).toHaveBeenCalledTimes(1); expect(mockGetCompanyProfile).toHaveBeenCalledWith(expect.any(IncomingMessage), COMPANY_NUMBER); expect(mockGetPscIndividual).toHaveBeenCalledTimes(1); - expect(mockGetPscIndividual).toHaveBeenCalledWith(expect.any(IncomingMessage), COMPANY_NUMBER, PSC_VERIFICATION_ID); + expect(mockGetPscIndividual).toHaveBeenCalledWith(expect.any(IncomingMessage), COMPANY_NUMBER, PSC_APPOINTMENT_ID); }); }); diff --git a/test/routers/handlers/psc-verified/pscVerifiedHandler.unit.ts b/test/routers/handlers/psc-verified/pscVerifiedHandler.unit.ts index fa2fdae0..fbb21438 100644 --- a/test/routers/handlers/psc-verified/pscVerifiedHandler.unit.ts +++ b/test/routers/handlers/psc-verified/pscVerifiedHandler.unit.ts @@ -8,7 +8,7 @@ import { getCompanyProfile } from "../../../../src/services/companyProfileServic import { closeTransaction } from "../../../../src/services/transactionService"; import middlewareMocks from "../../../mocks/allMiddleware.mock"; import { PSC_INDIVIDUAL } from "../../../mocks/psc.mock"; -import { COMPANY_NUMBER, INDIVIDUAL_VERIFICATION_FULL, PSC_VERIFICATION_ID, TRANSACTION_ID } from "../../../mocks/pscVerification.mock"; +import { COMPANY_NUMBER, INDIVIDUAL_VERIFICATION_FULL, PSC_APPOINTMENT_ID, PSC_VERIFICATION_ID, TRANSACTION_ID } from "../../../mocks/pscVerification.mock"; import { validCompanyProfile } from "../../../mocks/companyProfile.mock"; jest.mock("../../../../src/services/pscService"); @@ -72,7 +72,7 @@ describe("PSC Verified handler", () => { expect(mockGetPscVerification).not.toHaveBeenCalled(); expect(mockGetCompanyProfile).not.toHaveBeenCalled(); expect(mockGetPscIndividual).toHaveBeenCalledTimes(1); - expect(mockGetPscIndividual).toHaveBeenCalledWith(request, COMPANY_NUMBER, PSC_VERIFICATION_ID); + expect(mockGetPscIndividual).toHaveBeenCalledWith(request, COMPANY_NUMBER, PSC_APPOINTMENT_ID); expect(mockCloseTransaction).toHaveBeenCalledTimes(1); expect(mockCloseTransaction).toHaveBeenCalledWith(request, TRANSACTION_ID, PSC_VERIFICATION_ID); From e5fb57a6dbdea4cb78018f457f55bca3ff0c7334 Mon Sep 17 00:00:00 2001 From: AlisonGriffiths Date: Wed, 20 Nov 2024 14:50:17 +0000 Subject: [PATCH 3/5] Updated psc list screen to use the govukTag component --- .../individualPscList/individualPscList.njk | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/views/router_views/individualPscList/individualPscList.njk b/src/views/router_views/individualPscList/individualPscList.njk index d876e029..dcce7018 100644 --- a/src/views/router_views/individualPscList/individualPscList.njk +++ b/src/views/router_views/individualPscList/individualPscList.njk @@ -1,6 +1,7 @@ {% extends "layouts/default.njk" %} {% from "govuk/components/summary-list/macro.njk" import govukSummaryList %} {% from "govuk/components/details/macro.njk" import govukDetails %} +{% from "govuk/components/tag/macro.njk" import govukTag %} {% set title = i18n.ind_psc_list_main_title %} @@ -18,7 +19,10 @@ {% for psc in pscDetails | sort(attribute = 'pscName') %} {% set pscStatusText %} - {{ i18n.ind_psc_list_status_unverified }} + {{ govukTag({ + text: i18n.ind_psc_list_status_unverified, + classes: "govuk-tag--red" + }) }} {% endset %} {{ govukSummaryList({ @@ -79,7 +83,10 @@ }) }} {% set unverifiablePscStatusText %} - {{ i18n.ind_psc_list_status_unverified }} + {{ govukTag({ + text: i18n.ind_psc_list_status_unverified, + classes: "govuk-tag--red" + }) }} {% endset %} {{ govukSummaryList({ From cd00bca65d3adfb3ab59e30b5df48709f4567f57 Mon Sep 17 00:00:00 2001 From: AlisonGriffiths Date: Wed, 20 Nov 2024 15:04:30 +0000 Subject: [PATCH 4/5] Fixed minor sonar code smell --- .../handlers/individual-psc-list/individualPscListHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routers/handlers/individual-psc-list/individualPscListHandler.ts b/src/routers/handlers/individual-psc-list/individualPscListHandler.ts index 9c6f8790..19190ec0 100644 --- a/src/routers/handlers/individual-psc-list/individualPscListHandler.ts +++ b/src/routers/handlers/individual-psc-list/individualPscListHandler.ts @@ -114,7 +114,7 @@ export class IndividualPscListHandler extends GenericHandler Date: Wed, 20 Nov 2024 15:31:38 +0000 Subject: [PATCH 5/5] Fix for high security issue --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 99b9189b..a86319ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4012,9 +4012,9 @@ "peer": true }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0",