diff --git a/src/server/plugins/postcode-lookup/models/index.js b/src/server/plugins/postcode-lookup/models/index.js index 34593c18a..fefbd0a4d 100644 --- a/src/server/plugins/postcode-lookup/models/index.js +++ b/src/server/plugins/postcode-lookup/models/index.js @@ -343,9 +343,14 @@ export const manualPayloadSchema = Joi.object() '*': 'Enter town or city' }), [countyFieldName]: Joi.string().trim().allow('').required(), - [postcodeFieldName]: Joi.string().trim().required().messages({ - '*': 'Enter postcode' - }) + [postcodeFieldName]: Joi.string() + .pattern(/^[a-zA-Z]{1,2}\d[a-zA-Z\d]?\s?\d[a-zA-Z]{2}$/) + .trim() + .required() + .messages({ + 'string.pattern.base': 'Enter a valid postcode', + '*': 'Enter postcode' + }) }) .required() diff --git a/test/form/postcode-lookup.test.js b/test/form/postcode-lookup.test.js index 915205515..70ff6d0cd 100644 --- a/test/form/postcode-lookup.test.js +++ b/test/form/postcode-lookup.test.js @@ -556,6 +556,51 @@ describe('Postcode lookup form pages', () => { expect($heading).toBeInTheDocument() }) + it('should render validation error when invalid postcode is provided on manual page', async () => { + const { csrfToken, headers } = await initialiseJourney(server) + + // Dispatch to postcode journey + await server.inject({ + url: `${basePath}/address`, + method: 'POST', + headers, + payload: { + action: 'external-ybMHIv', + crumb: csrfToken + } + }) + + const { response, container } = await renderResponse(server, { + url: '/postcode-lookup?step=manual', + method: 'POST', + headers, + payload: { + step: 'manual', + addressLine1: '1 Street Name', + addressLine2: '', + town: 'Middletown', + county: '', + postcode: 'INVALID123', + crumb: csrfToken + } + }) + + expect(response.statusCode).toBe(StatusCodes.OK) + const $errorSummary = container.getByRole('alert') + + const $heading = within($errorSummary).getByRole('heading', { + name: 'There is a problem', + level: 2 + }) + expect($heading).toBeInTheDocument() + + // Verify the specific postcode error message is shown + const $postcodeError = container.getByRole('link', { + name: 'Enter a valid postcode' + }) + expect($postcodeError).toBeInTheDocument() + }) + it('should redirect back to the source page after successful POST to manual page', async () => { const { csrfToken, headers } = await initialiseJourney(server)