Skip to content

Commit

Permalink
Merge pull request #174 from companieshouse/feature/add-page-validati…
Browse files Browse the repository at this point in the history
…on-psc-details

Feature/add page validation psc details
  • Loading branch information
eedwards0 authored Nov 29, 2024
2 parents fbbc10d + 69770b6 commit 7ad158a
Show file tree
Hide file tree
Showing 11 changed files with 306 additions and 147 deletions.
4 changes: 3 additions & 1 deletion locales/cy/personal_code.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"personal_code_details_summaryText": "to be translated",
"personal_code_details_text": "to be translated",
"personal_code_born": "to be translated ",
"personal_code_button": "to be translated"
"personal_code_button": "to be translated",
"personal_code_error_summary": "personal_code_error_summary: to be translated ",
"personal_code_error_inline": "personal_code_error_inline: to be translated "

}
4 changes: 3 additions & 1 deletion locales/en/personal_code.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"personal_code_details_summaryText": "Where to find the Companies House personal code",
"personal_code_details_text": "This is an 11 character code that is given to a person after they have verified their identity with Companies House.",
"personal_code_born": "Born ",
"personal_code_button": "Save and continue"
"personal_code_button": "Save and continue",
"personal_code_error_summary": "Enter the Companies House personal code for ",
"personal_code_error_inline": "Enter the Companies House personal code for "

}
89 changes: 9 additions & 80 deletions src/lib/utils/error-manifests/errorManifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,109 +2,38 @@ import { getLocalesService } from "../../../utils/localise";

const localesService = getLocalesService();

const errorManifest = (lang: string = "en") => ({
const errorManifest = (lang: string = "en", attribute: string = "") => ({
generic: {
serverError: {
summary: localesService.i18nCh.resolveSingleKey("server_error_summary", lang) || "There was an error processing your request. Please try again."
summary: localesService.i18nCh.resolveSingleKey("server_error_summary", lang)
}
},

validation: {
default: {
summary: localesService.i18nCh.resolveSingleKey("validation_error_summary", lang) || "Your request contains validation errors",
inline: localesService.i18nCh.resolveSingleKey("validation_error_inline", lang) || "Your request contains validation errors"
},
firstName: {
blank: {
summary: "Enter the first name",
inline: "Enter the first name"
},
incorrect: {
summary: "Enter a valid firstname",
inline: "Enter a valid firstname"
}
},
middleName: {
blank: {},
incorrect: {
summary: "Enter a valid middle name",
inline: "Enter a valid middle name"
}
},
lastName: {
blank: {
summary: "Enter the last name",
inline: "Enter the last name"
},
incorrect: {
summary: "Enter a valid last name",
inline: "Enter a valid last name"
}
},
dateOfBirth: {
blank: {
summary: "Enter the date of birth",
inline: "Enter the date of birth"
},
incorrect: {
summary: "Enter a valid date of birth",
inline: "Enter a valid date of birth"
}
summary: localesService.i18nCh.resolveSingleKey("validation_error_summary", lang),
inline: localesService.i18nCh.resolveSingleKey("validation_error_inline", lang)
},
pscType: {
blank: {
summary: localesService.i18nCh.resolveSingleKey("psc_type_error_summary", lang) || "Select if you're providing verification details for a PSC or RLE",
inline: localesService.i18nCh.resolveSingleKey("psc_type_error_inline", lang) || "Inline: Select if you're providing verification details for a PSC or RLE"
},
incorrect: {}
},
pscVerificationStatus: {
blank: {
summary: "Select the PSC you're providing verification details for",
inline: "Select the PSC you're providing verification details for"
summary: localesService.i18nCh.resolveSingleKey("psc_type_error_summary", lang),
inline: localesService.i18nCh.resolveSingleKey("psc_type_error_inline", lang)
},
incorrect: {}
},
relevantOfficerConfirmation: {
personalCode: {
blank: {
summary: "Confirm if the relevant officer is a director of the relevant legal entity, or someone whose roles and responsibilities correspond to that of a company director.",
inline: "Confirm if the relevant officer is a director of the relevant legal entity, or someone whose roles and responsibilities correspond to that of a company director."
summary: (localesService.i18nCh.resolveSingleKey("personal_code_error_summary", lang) + attribute),
inline: (localesService.i18nCh.resolveSingleKey("personal_code_error_inline", lang) + attribute)
},
incorrect: {}
},
relevantOfficerPersonalCode: {
blank: {
summary: "Enter the personal code for the relevant officer",
inline: "Enter the personal code for the relevant officer"
},
incorrect: {
summary: "Enter a valid personal code for the relevant officer",
inline: "Enter a valid personal code for the relevant officer"
}
},
pscPersonalCode: {
blank: {
summary: "Enter the personal code for the PSC",
inline: "Enter the personal code for the PSC"
},
incorrect: {
summary: "Enter a valid personal code for the PSC",
inline: "Enter a valid personal code for the PSC"
}
},
pscIdentityVerificationStatement: {
blank: {
summary: "Confirm if the identity verification statement is correct",
inline: "Confirm if the identity verification statement is correct"
},
incorrect: {}
},
relevantOfficerStatementConfirmation: {
blank: {
summary: "Summary error text for relevantOfficerStatementConfirmation to be provided",
inline: "Inline error text for relevantOfficerStatementConfirmation to be provided"
},
incorrect: {}
}
}
});
Expand Down
21 changes: 21 additions & 0 deletions src/lib/validation/form-validators/pscVerification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,27 @@ export class PscVerificationFormsValidator extends GenericValidator {
}
}

validatePersonalCode (payload: any, _lang: string, pscName: string): Promise<Object> {
logger.info(`Request to validate Personal Code form`);
this.errorManifest = errorManifest(this.lang, pscName);

try {
if (typeof payload.personalCode === "undefined" || payload.personalCode === "") {
this.errors.stack.personalCode = this.errorManifest.validation.personalCode.blank;
}

// validate additional form fields here
if (!Object.keys(this.errors.stack).length) {
return Promise.resolve({});
} else {
return Promise.reject(this.errors);
}
} catch (err) {
this.errors.serverError = this.errorManifest.generic.serverError;
return Promise.reject(this.errors);
}
}

validateRleVerificationStatus (payload: any): Promise<any> {
return Promise.resolve({});
}
Expand Down
54 changes: 38 additions & 16 deletions src/routers/handlers/personal-code/personalCodeHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import { formatDateBorn } from "../../utils";
import { PscVerification, PscVerificationData } from "@companieshouse/api-sdk-node/dist/services/psc-verification-link/types";
import { patchPscVerification } from "../../../services/pscVerificationService";
import { getPscIndividual } from "../../../services/pscService";
import { PscVerificationFormsValidator } from "../../../lib/validation/form-validators/pscVerification";

interface PersonalCodeViewData extends BaseViewData {
pscName: string,
monthBorn: string,
monthYearBorn: string,
personalCode: string,
selectedPscId: string
selectedPscId: string,
nextPageUrl: string
}

export class PersonalCodeHandler extends GenericHandler<PersonalCodeViewData> {
Expand All @@ -34,7 +36,7 @@ export class PersonalCodeHandler extends GenericHandler<PersonalCodeViewData> {
...baseViewData,
...getLocaleInfo(locales, lang),
pscName: pscIndividual.resource?.name!,
monthBorn: formatDateBorn(pscIndividual.resource?.dateOfBirth, selectLang(req.query.lang)),
monthYearBorn: formatDateBorn(pscIndividual.resource?.dateOfBirth, selectLang(req.query.lang)),
personalCode: verification?.data?.verificationDetails?.uvid || "",
currentUrl: resolveUrlTemplate(PrefixedUrls.PERSONAL_CODE),
backURL: addSearchParams(PrefixedUrls.INDIVIDUAL_PSC_LIST, { companyNumber, lang }),
Expand All @@ -57,20 +59,40 @@ export class PersonalCodeHandler extends GenericHandler<PersonalCodeViewData> {
};
}

public async executePost (req: Request, res: Response) {
public async executePost (req: Request, res: Response): Promise<ViewModel<PersonalCodeViewData>> {
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 viewData = await this.getViewData(req, res);

const nextPageUrl = getUrlWithTransactionIdAndSubmissionId(PrefixedUrls.INDIVIDUAL_STATEMENT, req.params.transactionId, req.params.submissionId);
const lang = selectLang(req.query.lang);
return (addSearchParams(nextPageUrl, { lang }));
try {
const lang = selectLang(req.query.lang);
const uvid = req.body.personalCode;

const queryParams = new URLSearchParams(req.url.split("?")[1]);
const verification: PscVerificationData = {
pscAppointmentId: req.query?.selectedPscId as string,
verificationDetails: {
uvid: uvid
}
};

queryParams.set("lang", lang);
const nextPageUrl = getUrlWithTransactionIdAndSubmissionId(PrefixedUrls.INDIVIDUAL_STATEMENT, req.params.transactionId, req.params.submissionId);
viewData.nextPageUrl = `${nextPageUrl}?${queryParams}`;
const validator = new PscVerificationFormsValidator(lang);
viewData.errors = await validator.validatePersonalCode(req.body, lang, viewData.pscName);

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);

} catch (err: any) {
logger.error(`${req.method} error: problem handling PSC details (personal code) request: ${err.message}`);
viewData.errors = this.processHandlerException(err);
}

return {
templatePath: PersonalCodeHandler.templatePath,
viewData
};
}

}
9 changes: 8 additions & 1 deletion src/routers/personalCodeRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ personalCodeRouter.get("/", handleExceptions(async (req: Request, res: Response)

personalCodeRouter.post("/", handleExceptions(async (req: Request, res: Response, _next: NextFunction) => {
const handler = new PersonalCodeHandler();
res.redirect(await handler.executePost(req, res));
const params = await handler.executePost(req, res);

if (!Object.keys(params.viewData.errors).length) {
res.redirect(params.viewData.nextPageUrl);
} else {
res.render(params.templatePath, params.viewData);
}

}));

export default personalCodeRouter;
4 changes: 4 additions & 0 deletions src/views/partials/error_summary.njk
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{% from "govuk/components/error-summary/macro.njk" import govukErrorSummary %}

<div class="govuk-grid-column-two-thirds">

{% if errors is not undefined and errors is not null and errors | length %}
<div class="govuk-error-summary" data-module="govuk-error-summary">
<div role="alert">
Expand All @@ -24,3 +26,5 @@
</div>
</div>
{% endif %}

</div>
34 changes: 28 additions & 6 deletions src/views/router_views/personal_code/personal_code.njk
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
pscName,
" (",
i18n.personal_code_born,
monthBorn,
monthYearBorn,
")"
] | join %}

Expand All @@ -23,14 +23,36 @@
<h1 class="govuk-heading-l" id="personal-code--title">
{{title}}
</h1>

<div class="govuk-form-group">
{% set inputOptions = {
id: "personalCode",
classes: "govuk-input--width-10 govuk-input--extra-letter-spacing",
name: "personalCode",
value: personalCode
} %}

{% if errors is not undefined and errors is not null and errors | length %}
{% set inputOptions = {
id: inputOptions.id,
classes: inputOptions.classes,
name: inputOptions.name,
value: inputOptions.value,
errorMessage: {
text: i18n.personal_code_error_inline + pscName
}
} %}
{% endif %}

{{ govukInput(inputOptions) }}
{{ govukInput({
id: "personalCode",
classes: "govuk-input--width-10 govuk-input--extra-letter-spacing",
name: "personalCode",
value: personalCode
id: "selectedPscId",
type:"hidden",
name: "selectedPscId",
value: selectedPscId
})
}}

{{ govukInput({
id: "selectedPscId",
type:"hidden",
Expand Down Expand Up @@ -59,4 +81,4 @@
</div>
</form>

{% endblock %}
{% endblock %}
26 changes: 25 additions & 1 deletion test/mocks/pscVerification.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export const UVID = "123abc456edf";
export const SELF_URI = `/transactions/${TRANSACTION_ID}/persons-with-significant-control-verification/${PSC_VERIFICATION_ID}`;

export const INITIAL_PSC_DATA: PscVerificationData = {
companyNumber: COMPANY_NUMBER
companyNumber: COMPANY_NUMBER,
pscAppointmentId: PSC_APPOINTMENT_ID
};

export const LINKS: Links = {
Expand All @@ -26,6 +27,22 @@ export const INDIVIDUAL_DATA: PscVerificationData = {
}
};

export const PATCHED_PERSONAL_CODE_DATA: PscVerificationData = {
companyNumber: COMPANY_NUMBER,
pscAppointmentId: PSC_APPOINTMENT_ID,
verificationDetails: {
uvid: UVID
}
};

export const INITIAL_PERSONAL_CODE_DATA: PscVerificationData = {
companyNumber: COMPANY_NUMBER,
pscAppointmentId: PSC_APPOINTMENT_ID,
verificationDetails: {
uvid: ""
}
};

export const PATCH_INDIVIDUAL_DATA: PscVerificationData = {
companyNumber: COMPANY_NUMBER,
pscAppointmentId: PSC_APPOINTMENT_ID
Expand All @@ -50,6 +67,12 @@ export const PATCH_PERSONAL_CODE_DATA: PscVerificationData = {
}
};

export const PATCH_BLANK_PERSONAL_CODE_DATA: PscVerificationData = {
verificationDetails: {
uvid: ""
}
};

export const PATCH_INDIVIDUAL_STATEMENT: PscVerification = {
data: PATCH_INDIVIDUAL_STATEMENT_DATA,
createdAt: FIRST_DATE,
Expand Down Expand Up @@ -111,6 +134,7 @@ function initPscVerification (data: PscVerificationData) {
// Returns the PSC verification with data fields in camel case
export const INDIVIDUAL_VERIFICATION_CREATED: PscVerification = initPscVerification(INITIAL_PSC_DATA);
export const INDIVIDUAL_VERIFICATION_FULL: PscVerification = initPscVerification(INDIVIDUAL_DATA);
export const IND_VERIFICATION_PERSONAL_CODE: PscVerification = initPscVerification(INITIAL_PERSONAL_CODE_DATA);
export const INDIVIDUAL_VERIFICATION_PATCH: PscVerification = initPscVerification(PATCH_INDIVIDUAL_DATA);
export const RLE_VERIFICATION_PATCH: PscVerification = initPscVerification(PATCH_RLE_DATA);
export const RLE_VERIFICATION_FULL: PscVerification = initPscVerification(RLE_DATA_FULL);
Loading

0 comments on commit 7ad158a

Please sign in to comment.