diff --git a/src/constants/error-messages.js b/src/constants/error-messages.js index 0c8d4719..39543b5f 100644 --- a/src/constants/error-messages.js +++ b/src/constants/error-messages.js @@ -32,17 +32,21 @@ const errorMessages = Object.freeze({ OPTION_REQUIRED: 'Please select an option', VEHICLE_REQUIRED: 'Please select a vehicle', POLICY_NUMBER_REQUIRED: 'Please enter your policy number', + POLICY_NUMBER_FORMAT: 'Please enter an alpha-numeric string', PHONE_NUMBER_REQUIRED: 'Please enter phone number', PHONE_NUMBER_FORMAT: 'Please enter your phone number. The format must be ###-###-####', POLICY_ZIP_REQUIRED: 'Please enter your policy ZIP', POLICY_ZIP_FORMAT: 'Please enter a valid ZIP', LOSS_CAUSE_REQUIRED: 'Please enter loss cause', LOSS_CITY_REQUIRED: 'Please enter a city', + LOSS_CITY_FORMAT: 'Please enter only alpha characters', LOSS_STATE_REQUIRED: 'Please select an option', LOSS_DATE_REQUIRED: 'Please select a date. Format must be MM/DD/YYYY and the date must be not in the future', DAMAGE_DATE_REQUIREMENT: 'Damage date must be within the past 10 years', + DAMAGE_DATE_NO_FUTURE_DATE: + 'Damage date may not be in the future', DAMAGE_OPTION_REQUIRED: 'Please select an option', POLICYHOLDER_FIRST_NAME_REQUIRED: 'Please enter the policyholder first name', diff --git a/src/constants/global-rules.js b/src/constants/global-rules.js index da36b822..70c5834a 100644 --- a/src/constants/global-rules.js +++ b/src/constants/global-rules.js @@ -7,8 +7,18 @@ const globalRules = Object.freeze({ POLICYHOLDER_FIRST_NAME_REQUIRED: 'policyholder-first-name-required', POLICYHOLDER_LAST_NAME_REQUIRED: 'policyholder-last-name-required', + POLICY_NUMBER_FORMAT: 'policy-number-format', + POLICY_NUMBER_REQUIRED: 'policy-number-required', + POLICY_ZIP_FORMAT: 'policy-zip-format', + POLICY_ZIP_REQUIRED: 'policy-zip-required', FIRST_NAME_REQUIRED: 'first-name-required', LAST_NAME_REQUIRED: 'last-name-required', + DATE_OF_LOSS_CITY_FORMAT: 'loss-city-format', + DATE_OF_LOSS_CITY_REQUIRED: 'loss-city-required', + DATE_OF_LOSS_STATE_REQUIRED: 'loss-state-required', + DATE_OF_LOSS_NOT_FUTURE: 'loss-date-lt-tomorrow', + DATE_OF_LOSS_NOT_TEN_YEARS_PAST: 'loss-date-gt-10-years', + DATE_OF_LOSS_REQUIRED: 'loss-date-required', EMAIL_ADDRESS_REQUIRED: 'email-required', EMAIL_ADDRESS_FORMAT: 'email-address-format', PHONE_NUMBER_REQUIRED: 'phone-number-required', diff --git a/src/digital-components/textbox-question/textbox-question.vue b/src/digital-components/textbox-question/textbox-question.vue index 31d912a0..2ba8d5b9 100644 --- a/src/digital-components/textbox-question/textbox-question.vue +++ b/src/digital-components/textbox-question/textbox-question.vue @@ -102,7 +102,7 @@ export default { }, validationRules: String, cmsWidgetName: { - String, + type: String, default: '' }, maxLength: String, diff --git a/src/helpers/global-rule-definer.js b/src/helpers/global-rule-definer.js index daee0de3..eed5e381 100644 --- a/src/helpers/global-rule-definer.js +++ b/src/helpers/global-rule-definer.js @@ -33,6 +33,39 @@ function defineGlobalEmailRules() { ); } +/** + * @summary Define global rules related to date/location of loss information + */ +function defineGlobalDateOfLossRules() { + defineRule(globalRules.DATE_OF_LOSS_REQUIRED, required(errorMessages.LOSS_DATE_REQUIRED)); + defineRule(globalRules.DATE_OF_LOSS_NOT_TEN_YEARS_PAST, (value) => { + const lossDate = new Date(Date.parse(`${value}T00:00:00`)); + const today = new Date(); + const tenYearsAgo = new Date(today.getFullYear() - 10, today.getMonth(), today.getDate(), 0, 0, 0, 0); + if (lossDate < tenYearsAgo) { + return errorMessages.DAMAGE_DATE_REQUIREMENT; + } + + return true; + }); + defineRule(globalRules.DATE_OF_LOSS_NOT_FUTURE, (value) => { + const lossDate = new Date(Date.parse(`${value}T00:00:00`)); + const today = new Date(); + const tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1, 0, 0, 0, 0); + if (lossDate >= tomorrow) { + return errorMessages.DAMAGE_DATE_NO_FUTURE_DATE; + } + + return true; + }); + defineRule(globalRules.DATE_OF_LOSS_CITY_REQUIRED, required(errorMessages.LOSS_CITY_REQUIRED)); + defineRule( + globalRules.DATE_OF_LOSS_CITY_FORMAT, + regex(/^[a-zA-Z .'-]+$/, errorMessages.LOSS_CITY_FORMAT) + ); + defineRule(globalRules.DATE_OF_LOSS_STATE_REQUIRED, required(errorMessages.LOSS_STATE_REQUIRED)); +} + /** * @summary Define global rules related to phone numbers */ @@ -47,6 +80,31 @@ function defineGlobalPhoneNumberRules() { ); } +/** + * @summary Define global rules related to policy numbers + */ +function defineGlobalPolicyNumberRules() { + defineRule(globalRules.POLICY_NUMBER_REQUIRED, required(errorMessages.POLICY_NUMBER_REQUIRED)); + defineRule( + globalRules.POLICY_NUMBER_FORMAT, + regex( + /^~?[a-zA-Z0-9]+$/, + errorMessages.POLICY_NUMBER_FORMAT + ) + ); +} + +/** + * @summary Define global rules related to policy zip codes + */ +function defineGlobalPolicyZipCodeRules() { + defineRule(globalRules.POLICY_ZIP_REQUIRED, required(errorMessages.POLICY_ZIP_REQUIRED)); + defineRule( + globalRules.POLICY_ZIP_FORMAT, + regex(/^\d{5}$/, errorMessages.POLICY_ZIP_FORMAT) + ); +} + /** * @summary Define global rules related to zip codes */ @@ -61,8 +119,11 @@ function defineGlobalZipCodeRules() { */ export default function defineGlobalRules() { defineGlobalNameRules(); + defineGlobalDateOfLossRules(); defineGlobalEmailRules(); defineGlobalPhoneNumberRules(); + defineGlobalPolicyNumberRules(); + defineGlobalPolicyZipCodeRules(); defineGlobalZipCodeRules(); defineRule(globalRules.OPTION_REQUIRED, required(errorMessages.OPTION_REQUIRED)); diff --git a/src/layouts/welcome-page/welcome-page.spec.js b/src/layouts/welcome-page/welcome-page.spec.js index 38733d63..f84bb7bc 100644 --- a/src/layouts/welcome-page/welcome-page.spec.js +++ b/src/layouts/welcome-page/welcome-page.spec.js @@ -69,7 +69,7 @@ function setupMocks({ } }; - mountOptionsMockData = { + const mockDataMountOptions = { ...mountOptionsMockData, router: { navigate: jest.fn() @@ -81,12 +81,13 @@ function setupMocks({ settleAllPromises.mockImplementation(() => apiPromise); fetchCmsContentForPage.mockImplementation(() => Promise.resolve()); - const mountOptions = getMountOptions(mountOptionsMockData); + const mountOptions = getMountOptions(mockDataMountOptions); const wrapper = shallowMount(welcomePage, mountOptions); wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent; wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => ''); + wrapper.vm.$refs.siteFooter.removeLoader = jest.fn(); return { wrapper, apiPromise }; } @@ -175,170 +176,243 @@ describe('welcome-page.vue', () => { }); describe('navigation', () => { - test('if duplicates found, navigate to duplicate check page', async () => { - // Arrange - const { wrapper } = getMountedComponent({}); - useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); - useMainStore().applicationUser.duplicateOrders = [{ test: 'a' }]; + describe('When zip code check fails', () => { + test('Navigation should not happen', async () => { + // Arrange + const { wrapper } = setupMocks({}); + useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); + useMainStore().applicationUser.duplicateOrders = [{ test: 'a' }]; + wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({ + data: { + isValid: false + } + })); - // Act - await wrapper.vm.forwardButtonAction(); + // Act + await wrapper.vm.forwardButtonAction(); - // Assert - expect(wrapper.vm.mainStore.getDuplicateReferrals).toHaveBeenCalled(); - expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD_WITH_DUPLICATES, - undefined, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } - ); + // Assert + expect(wrapper.vm.mainStore.getDuplicateReferrals).toHaveBeenCalledTimes(0); + expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(0); + }); }); - test('if isCoverageEnabled is false, then getCoveragePolicyInfo not called', async () => { - // Arrange - const { wrapper } = getMountedComponent({}); - useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); - useMainStore().issConfig.isCoverageEnabled = false; - // Act - await wrapper.vm.forwardButtonAction(); + describe('When zip code check succeeds', () => { + test('if duplicates found, navigate to duplicate check page', async () => { + // Arrange + const { wrapper } = getMountedComponent({}); + useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); + useMainStore().applicationUser.duplicateOrders = [{ test: 'a' }]; + wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({ + data: { + isValid: true + } + })); - // Assert - expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled(); - expect(wrapper.vm.mainStore.getCoveragePolicyInfo).not.toHaveBeenCalled(); - }); - test('if isCoverageEnabled is true, then getCoveragePolicyInfo called', async () => { - // Arrange - const { wrapper } = getMountedComponent({}); - useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); - useMainStore().issConfig.isCoverageEnabled = true; + // Act + await wrapper.vm.forwardButtonAction(); - // Act - await wrapper.vm.forwardButtonAction(); + // Assert + expect(wrapper.vm.mainStore.getDuplicateReferrals).toHaveBeenCalled(); + expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( + navigationScenarios.CLICKED_FORWARD_WITH_DUPLICATES, + undefined, + {}, + { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + ); + }); + test('if isCoverageEnabled is false, then getCoveragePolicyInfo not called', async () => { + // Arrange + const { wrapper } = getMountedComponent({}); + useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); + useMainStore().issConfig.isCoverageEnabled = false; + wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({ + data: { + isValid: true + } + })); - // Assert - expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled(); - expect(wrapper.vm.mainStore.getCoveragePolicyInfo).toHaveBeenCalled(); - }); - test('if maxCoverageLookupAttemptsReached is true, then getCoveragePolicyInfo not called', async () => { - // Arrange - const { wrapper } = getMountedComponent({}); - useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); - useMainStore().applicationUser.coverageLookupAttempts = 11; + // Act + await wrapper.vm.forwardButtonAction(); - // Act - await wrapper.vm.forwardButtonAction(); + // Assert + expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled(); + expect(wrapper.vm.mainStore.getCoveragePolicyInfo).not.toHaveBeenCalled(); + }); + test('if isCoverageEnabled is true, then getCoveragePolicyInfo called', async () => { + // Arrange + const { wrapper } = getMountedComponent({}); + useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); + useMainStore().issConfig.isCoverageEnabled = true; + wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({ + data: { + isValid: true + } + })); - // Assert - expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled(); - expect(wrapper.vm.mainStore.getCoveragePolicyInfo).not.toHaveBeenCalled(); - }); - test('if maxCoverageLookupAttemptsReached is false, then getCoveragePolicyInfo called', async () => { - // Arrange - const { wrapper } = getMountedComponent({}); - useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); - useMainStore().applicationUser.coverageLookupAttempts = 10; + // Act + await wrapper.vm.forwardButtonAction(); - // Act - await wrapper.vm.forwardButtonAction(); + // Assert + expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled(); + expect(wrapper.vm.mainStore.getCoveragePolicyInfo).toHaveBeenCalled(); + }); + test('if maxCoverageLookupAttemptsReached is true, then getCoveragePolicyInfo not called', async () => { + // Arrange + const { wrapper } = getMountedComponent({}); + useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); + useMainStore().applicationUser.coverageLookupAttempts = 11; + wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({ + data: { + isValid: true + } + })); - // Assert - expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled(); - expect(wrapper.vm.mainStore.getCoveragePolicyInfo).toHaveBeenCalled(); - }); - test('if policy and vehicles are found but no duplicates, navigate to policy-vehicle page', async () => { - // Arrange - const { wrapper } = setupMocks({}); - useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); + // Act + await wrapper.vm.forwardButtonAction(); - useMainStore().applicationUser.duplicateOrders = []; - useMainStore().order.policy.policyLookupSuccessful = true; - useMainStore().order.policy.vehicles = [ - { vin: 'TEST_VIN' }, - { vin: 'TEST_VIN2' } - ]; + // Assert + expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled(); + expect(wrapper.vm.mainStore.getCoveragePolicyInfo).not.toHaveBeenCalled(); + }); + test('if maxCoverageLookupAttemptsReached is false, then getCoveragePolicyInfo called', async () => { + // Arrange + const { wrapper } = getMountedComponent({}); + useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); + useMainStore().applicationUser.coverageLookupAttempts = 10; + wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({ + data: { + isValid: true + } + })); - // Act - await wrapper.vm.forwardButtonAction(); + // Act + await wrapper.vm.forwardButtonAction(); - // Assert - expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_WITH_VEHICLES, - undefined, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } - ); - }); - test('if policy is found, but no vehicles and no duplicates, navigate to vehicle-selection page', async () => { - // Arrange - const { wrapper } = setupMocks({}); - useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); + // Assert + expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled(); + expect(wrapper.vm.mainStore.getCoveragePolicyInfo).toHaveBeenCalled(); + }); + test('if policy and vehicles are found but no duplicates, navigate to policy-vehicle page', async () => { + // Arrange + const { wrapper } = setupMocks({}); + useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); - useMainStore().applicationUser.duplicateOrders = []; - useMainStore().order.policy.policyLookupSuccessful = true; - useMainStore().order.policy.vehicles = []; + useMainStore().applicationUser.duplicateOrders = []; + useMainStore().order.policy.policyLookupSuccessful = true; + useMainStore().order.policy.vehicles = [ + { vin: 'TEST_VIN' }, + { vin: 'TEST_VIN2' } + ]; + wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({ + data: { + isValid: true + } + })); - // Act + // Act + await wrapper.vm.forwardButtonAction(); - await wrapper.vm.forwardButtonAction(); + // Assert + expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( + navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_WITH_VEHICLES, + undefined, + {}, + { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + ); + }); + test('if policy is found, but no vehicles and no duplicates, navigate to vehicle-selection page', async () => { + // Arrange + const { wrapper } = setupMocks({}); + useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); - // Assert - expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_NO_VEHICLES, - undefined, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } - ); - }); - test('if policy is found, but null vehicles and no duplicates, navigate to vehicle-selection page', async () => { - // Arrange - const { wrapper } = setupMocks({}); - useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); + useMainStore().applicationUser.duplicateOrders = []; + useMainStore().order.policy.policyLookupSuccessful = true; + useMainStore().order.policy.vehicles = []; + wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({ + data: { + isValid: true + } + })); - useMainStore().applicationUser.duplicateOrders = []; - useMainStore().order.policy.policyLookupSuccessful = true; - useMainStore().order.policy.vehicles = null; + // Act + await wrapper.vm.forwardButtonAction(); - // Act + // Assert + expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( + navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_NO_VEHICLES, + undefined, + {}, + { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + ); + }); + test('if policy is found, but null vehicles and no duplicates, navigate to vehicle-selection page', async () => { + // Arrange + const { wrapper } = setupMocks({}); + useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); - await wrapper.vm.forwardButtonAction(); + useMainStore().applicationUser.duplicateOrders = []; + useMainStore().order.policy.policyLookupSuccessful = true; + useMainStore().order.policy.vehicles = null; - // Assert - expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_NO_VEHICLES, - undefined, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } - ); - }); - test('if policy is not found and no duplicates, navigate to policy-holder-details page', async () => { - // Arrange - const { wrapper } = setupMocks({}); - useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); + wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({ + data: { + isValid: true + } + })); - useMainStore().order.policy.policyLookupSuccessful = false; - useMainStore().applicationUser.duplicateOrders = []; + // Act + await wrapper.vm.forwardButtonAction(); - // Act - await wrapper.vm.forwardButtonAction(); + // Assert + expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( + navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_NO_VEHICLES, + undefined, + {}, + { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + ); + }); + test('if policy is not found and no duplicates, navigate to policy-holder-details page', async () => { + // Arrange + const { wrapper } = setupMocks({}); + useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); - // Assert - expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( - navigationScenarios.CLICKED_FORWARD_POLICY_UNVERIFIED, - undefined, - {}, - { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } - ); - }); - test('getDuplicateReferrals throws rejected promise => navigate called', async () => { - // Arrange - const { wrapper } = setupMocks({}); - const error = 'duplicate referrals error'; - useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.reject(error)); + useMainStore().order.policy.policyLookupSuccessful = false; + useMainStore().applicationUser.duplicateOrders = []; - // Act - await wrapper.vm.forwardButtonAction(); + wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({ + data: { + isValid: true + } + })); - // Assert - expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( + navigationScenarios.CLICKED_FORWARD_POLICY_UNVERIFIED, + undefined, + {}, + { [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } + ); + }); + test('getDuplicateReferrals throws rejected promise => navigate called', async () => { + // Arrange + const { wrapper } = setupMocks({}); + const error = 'duplicate referrals error'; + useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.reject(error)); + wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({ + data: { + isValid: true + } + })); + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); + }); }); }); diff --git a/src/layouts/welcome-page/welcome-page.vue b/src/layouts/welcome-page/welcome-page.vue index 77a60a5f..70005db2 100644 --- a/src/layouts/welcome-page/welcome-page.vue +++ b/src/layouts/welcome-page/welcome-page.vue @@ -85,7 +85,7 @@ cmsWidgetName="PhoneNumberQuestion" :validationRules="rules.phoneNumber" isRequired - mask="###-###-####" + :mask="mask" disableAutoFill /> @@ -153,11 +153,18 @@ id="welcomeFooter" class="row position-sticky top-100">
+
@@ -173,6 +180,7 @@ import { Form, defineRule } from 'vee-validate'; import siteHeader from '@/iss-components/site-header/site-header.vue'; import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue'; import siteFooter from '@/iss-components/site-footer/site-footer.vue'; +import alert from '@/ux-components/alert/alert.vue'; import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue'; import buttonQuestion from '@/digital-components/button-question/button-question.vue'; import dropdownQuestion from '@/digital-components/dropdown-question/dropdown-question.vue'; @@ -181,7 +189,7 @@ import textBlock from '@/digital-components/text-block/text-block.vue'; // Supporting files import { fetchCmsContentForPage, fetchGlobalCmsContent, updateCmsSiteHeader } from '@/helpers/cms-content-helper'; import settleAllPromises from '@/helpers/layout-helper'; -import { required, regex } from '@/helpers/validation-rules'; +import { required } from '@/helpers/validation-rules'; import errorMessages from '@/constants/error-messages'; import BaseFormMixin from '@/mixins/base-form-mixin.js'; import { useMainStore } from '@/store'; @@ -190,32 +198,14 @@ import globalRules from '@/constants/global-rules'; import routerParams from '@/router/router-constants/router-params'; // define validation rules -defineRule('loss-date-required', required(errorMessages.LOSS_DATE_REQUIRED)); -defineRule('policy-number-required', required(errorMessages.POLICY_NUMBER_REQUIRED)); -defineRule('loss-state-required', required(errorMessages.LOSS_STATE_REQUIRED)); -defineRule('loss-city-required', required(errorMessages.LOSS_CITY_REQUIRED)); defineRule('damage-option-required', required(errorMessages.DAMAGE_OPTION_REQUIRED)); -defineRule('policy-zip-required', required(errorMessages.POLICY_ZIP_REQUIRED)); -defineRule( - 'policy-zip-format', - regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.POLICY_ZIP_FORMAT) -); -defineRule('loss-date-gt-10-years', (value) => { - const lossDate = new Date(Date.parse(`${value}T00:00:00`)); - const today = new Date(); - const tenYearsAgo = new Date(today.getFullYear() - 10, today.getMonth(), today.getDate(), 0, 0, 0, 0); - if (lossDate < tenYearsAgo) { - return errorMessages.DAMAGE_DATE_REQUIREMENT; - } - - return true; -}); export default { name: 'welcome-page', components: { siteHeader, siteSubHeader, + alert, buttonQuestion, textboxQuestion, dropdownQuestion, @@ -260,16 +250,18 @@ export default { data() { return { welcomePageModel: this.getWelcomePageModelFromStore(), + displayInvalidZipAlert: false, duplicates: [], rules: { - policyNumber: 'policy-number-required', - policyZip: 'policy-zip-required|policy-zip-format', - lossDate: 'loss-date-required|loss-date-gt-10-years', damageOption: 'damage-option-required', - phoneNumber: `${globalRules.PHONE_NUMBER_REQUIRED}|${globalRules.PHONE_NUMBER_FORMAT}`, email: `${globalRules.EMAIL_ADDRESS_REQUIRED}|${globalRules.EMAIL_ADDRESS_FORMAT}`, - lossCity: 'loss-city-required', - lossState: 'loss-state-required' + lossCity: `${globalRules.DATE_OF_LOSS_CITY_REQUIRED}|${globalRules.DATE_OF_LOSS_CITY_FORMAT}`, + // eslint-disable-next-line max-len + lossDate: `${globalRules.DATE_OF_LOSS_REQUIRED}|${globalRules.DATE_OF_LOSS_NOT_TEN_YEARS_PAST}|${globalRules.DATE_OF_LOSS_NOT_FUTURE}`, + lossState: `${globalRules.DATE_OF_LOSS_STATE_REQUIRED}`, + policyNumber: `${globalRules.POLICY_NUMBER_REQUIRED}|${globalRules.POLICY_NUMBER_FORMAT}`, + policyZip: `${globalRules.POLICY_ZIP_REQUIRED}|${globalRules.POLICY_ZIP_FORMAT}`, + phoneNumber: `${globalRules.PHONE_NUMBER_REQUIRED}|${globalRules.PHONE_NUMBER_FORMAT}` } }; }, @@ -319,20 +311,38 @@ export default { }, maxCoverageLookupAttemptsReached() { return this.mainStore.applicationUser.coverageLookupAttempts >= 11; + }, + mask() { + return { + mask: 'x##-###-####', + tokens: { + x: { + pattern: /[2-9]/ + } + } + }; } }, methods: { async forwardButtonAction() { - this.mainStore.updatePolicyData(this.welcomePageModel); - await this.mainStore.getDuplicateReferrals() - .then(() => {}, () => {}) - .finally(async () => { - if (this.isCoverageEnabled && !this.maxCoverageLookupAttemptsReached) { - await this.mainStore.getCoveragePolicyInfo()?.then(() => {}, () => {}); + await this.mainStore.validateZip({ zip: this.welcomePageModel.policyZipCode }) + .then(async (zipInfo) => { + if (zipInfo?.data?.isValid === true) { + this.mainStore.updatePolicyData(this.welcomePageModel); + await this.mainStore.getDuplicateReferrals() + .then(() => {}, () => {}) + .finally(async () => { + if (this.isCoverageEnabled && !this.maxCoverageLookupAttemptsReached) { + await this.mainStore.getCoveragePolicyInfo()?.then(() => {}, () => {}); + } else { + this.mainStore.order.policy.policyLookupSuccessful = false; + } + this.navigateForward(); + }); } else { - this.mainStore.order.policy.policyLookupSuccessful = false; + this.displayInvalidZipAlert = true; + this.$refs.siteFooter.removeLoader(); } - this.navigateForward(); }); }, navigateForward() {