diff --git a/package.json b/package.json index ce9eb7062..d01e6b2dc 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,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 04251e575..ef711fa08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11095,6 +11095,11 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== +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"