diff --git a/package.json b/package.json index 29a983c99..7447d7388 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "lazysizes": "^5.3.2", "lodash": "^4.17.11", "moment": "^2.29.4", + "postcode": "^5.1.0", "prop-types": "^15.8.1", "pure-react-carousel": "1.30.1", "react": "^17.0.2", diff --git a/playwright/components/organisms/marketingPreferences.spec.js b/playwright/components/organisms/marketingPreferences.spec.js index eaf9eca94..99b4fb29e 100644 --- a/playwright/components/organisms/marketingPreferences.spec.js +++ b/playwright/components/organisms/marketingPreferences.spec.js @@ -142,6 +142,42 @@ test.describe('marketing preferences component', () => { await page.locator('div#marketing-preferences--default input#mp_postcode').fill('E1 8QS'); // clear the email field await expect(page.locator('div#marketing-preferences--default div.field-post > div > label[for="mp_postcode"] > span > span')).toBeHidden(''); + // Test postcode fix functionality - case correction + await page.locator('div#marketing-preferences--default input#mp_postcode').fill(''); // clear the field + await page.locator('div#marketing-preferences--default input#mp_postcode').type('sw1a 2aa'); + await page.locator('div#marketing-preferences--default input#mp_address2').click(); + await expect(page.locator('div#marketing-preferences--default div.field-post > div > label[for="mp_postcode"] > span > span')).toBeHidden(''); + + // Test postcode fix functionality - I to 1 correction + await page.locator('div#marketing-preferences--default input#mp_postcode').fill(''); // clear the field + await page.locator('div#marketing-preferences--default input#mp_postcode').type('SWIA 2AA'); + await page.locator('div#marketing-preferences--default input#mp_address2').click(); + await expect(page.locator('div#marketing-preferences--default div.field-post > div > label[for="mp_postcode"] > span > span')).toBeHidden(''); + + // Test postcode fix functionality - O to 0 correction + await page.locator('div#marketing-preferences--default input#mp_postcode').fill(''); // clear the field + await page.locator('div#marketing-preferences--default input#mp_postcode').type('SW1A OAA'); + await page.locator('div#marketing-preferences--default input#mp_address2').click(); + await expect(page.locator('div#marketing-preferences--default div.field-post > div > label[for="mp_postcode"] > span > span')).toBeHidden(''); + + // Test postcode fix functionality - 1 to I correction + await page.locator('div#marketing-preferences--default input#mp_postcode').fill(''); // clear the field + await page.locator('div#marketing-preferences--default input#mp_postcode').type('SW1A 21A'); + await page.locator('div#marketing-preferences--default input#mp_address2').click(); + await expect(page.locator('div#marketing-preferences--default div.field-post > div > label[for="mp_postcode"] > span > span')).toBeHidden(''); + + // Test postcode fix functionality - 0 to O correction + await page.locator('div#marketing-preferences--default input#mp_postcode').fill(''); // clear the field + await page.locator('div#marketing-preferences--default input#mp_postcode').type('SW1A 20A'); + await page.locator('div#marketing-preferences--default input#mp_address2').click(); + await expect(page.locator('div#marketing-preferences--default div.field-post > div > label[for="mp_postcode"] > span > span')).toBeHidden(''); + + // Test invalid postcode that cannot be fixed + await page.locator('div#marketing-preferences--default input#mp_postcode').fill(''); // clear the field + await page.locator('div#marketing-preferences--default input#mp_postcode').type('INVALID123'); + await page.locator('div#marketing-preferences--default input#mp_address2').click(); + await expect(page.locator('div#marketing-preferences--default div.field-post > div > label[for="mp_postcode"] > span > span')).toContainText('Please enter a valid postcode'); + // country field should show error message when value is not entered await page.locator('div#marketing-preferences--default input#mp_country').type('United Kingdom'); await page.locator('div#marketing-preferences--default input#mp_country').fill(''); // clear the email field diff --git a/src/components/Organisms/MarketingPreferencesDS/_MarketingPrefsConfig.js b/src/components/Organisms/MarketingPreferencesDS/_MarketingPrefsConfig.js index dc9ec76bd..a766a88f1 100644 --- a/src/components/Organisms/MarketingPreferencesDS/_MarketingPrefsConfig.js +++ b/src/components/Organisms/MarketingPreferencesDS/_MarketingPrefsConfig.js @@ -1,5 +1,6 @@ import * as yup from 'yup'; import { merge } from 'lodash'; +import { fix as fixPostcode, isValid } from 'postcode'; const setInitialValues = overrideValues => { const defaultValues = { @@ -63,6 +64,15 @@ const buildValidationSchema = overrideOptions => { const phoneRegex = /^(((((\+44)|(0044))\s?\d{4}|\(?0\d{4}\)?)\s?\d{3}\s?\d{3})|((((\+44)|(0044))\s?\d{3}|\(?0\d{3}\)?)\s?\d{3}\s?\d{4})|((((\+44)|(0044))\s?\d{2}|\(?0\d{2}\)?)\s?\d{4}\s?\d{4}))(\s?\\#(\d{4}|\d{3}))?$/; + const transformPostcode = postcode => { + if (typeof postcode === 'string') { + return fixPostcode(postcode); + } + return postcode; + }; + + const validatePostcode = postcode => isValid(postcode); + const mpValidationFields = { mp_email: yup.string() .when('mp_permissionEmail', { @@ -108,7 +118,7 @@ const buildValidationSchema = overrideOptions => { mp_postcode: yup.string().when('mp_permissionPost', { is: val => (!(mpValidationOptions.mp_permissionPost.disableOption) && mpValidationOptions.mp_permissionPost[val]), - then: schema => schema.required('Please enter your postcode').matches(/^[a-zA-Z]{1,2}\d[a-zA-Z\d]?\s*\d[a-zA-Z]{2}$/, 'Please enter a valid postcode') + then: schema => schema.required('Please enter your postcode').transform(transformPostcode).test('postcode-valid', 'Please enter a valid postcode', validatePostcode) }), mp_country: yup.string().when('mp_permissionPost', { diff --git a/yarn.lock b/yarn.lock index 546fefc0f..f53b76322 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11221,9 +11221,14 @@ posix-character-classes@^0.1.0: possible-typed-array-names@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae" + resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae" integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg== +postcode@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/postcode/-/postcode-5.1.0.tgz#ef30a2a4028fd20255fb0aceccf4c70baab8df5b" + integrity sha512-rjwIdlQ8UvdOnUVZRCZQA54PmQJeoMBDQb4RsW5z3MVp/u7Gcet1vsjVy/p0+YX+R7cmgU9DEJf0zSx5mWqxAA== + postcss-attribute-case-insensitive@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz#d93e46b504589e94ac7277b0463226c68041a880"