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/bailout-page/bailout-page.vue b/src/layouts/bailout-page/bailout-page.vue
index 87797893..4a60c8e9 100644
--- a/src/layouts/bailout-page/bailout-page.vue
+++ b/src/layouts/bailout-page/bailout-page.vue
@@ -39,7 +39,7 @@
inputId="phoneNumberField"
cmsWidgetName="PhoneNumberQuestion"
isRequired
- mask="###-###-####"
+ :mask="mask"
disableAutoFill
:validationRules="rules.phoneNumber" />
@@ -101,6 +101,16 @@ export default {
},
footerButtonText() {
return this.getCmsContent(this.widget.drawerFooter, widgetFields.FOOTER_WIDGET.FORWARD_BUTTON_TEXT);
+ },
+ mask() {
+ return {
+ mask: 'x##-###-####',
+ tokens: {
+ x: {
+ pattern: /[2-9]/
+ }
+ }
+ };
}
},
methods: {
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..df58619e 100644
--- a/src/layouts/welcome-page/welcome-page.vue
+++ b/src/layouts/welcome-page/welcome-page.vue
@@ -34,6 +34,7 @@
inputId="policyZipCode"
cmsWidgetName="PolicyZipQuestion"
isRequired
+ mask="#####"
:isDisabled="isPolicyZipDisabled"
:validationRules="rules.policyZip" />
@@ -85,7 +86,7 @@
cmsWidgetName="PhoneNumberQuestion"
:validationRules="rules.phoneNumber"
isRequired
- mask="###-###-####"
+ :mask="mask"
disableAutoFill />
@@ -153,11 +154,18 @@
id="welcomeFooter"
class="row position-sticky top-100">
@@ -173,6 +181,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 +190,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 +199,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 +251,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 +312,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() {