Merge pull request #549 from Safelite/feature/richardson/SSR-1100

Welcome page validation updates
This commit is contained in:
brich1212safe 2024-02-16 15:31:47 -05:00 committed by GitHub
commit 47a2a10e84
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 336 additions and 177 deletions

View file

@ -32,17 +32,21 @@ const errorMessages = Object.freeze({
OPTION_REQUIRED: 'Please select an option', OPTION_REQUIRED: 'Please select an option',
VEHICLE_REQUIRED: 'Please select a vehicle', VEHICLE_REQUIRED: 'Please select a vehicle',
POLICY_NUMBER_REQUIRED: 'Please enter your policy number', 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_REQUIRED: 'Please enter phone number',
PHONE_NUMBER_FORMAT: 'Please enter your phone number. The format must be ###-###-####', PHONE_NUMBER_FORMAT: 'Please enter your phone number. The format must be ###-###-####',
POLICY_ZIP_REQUIRED: 'Please enter your policy ZIP', POLICY_ZIP_REQUIRED: 'Please enter your policy ZIP',
POLICY_ZIP_FORMAT: 'Please enter a valid ZIP', POLICY_ZIP_FORMAT: 'Please enter a valid ZIP',
LOSS_CAUSE_REQUIRED: 'Please enter loss cause', LOSS_CAUSE_REQUIRED: 'Please enter loss cause',
LOSS_CITY_REQUIRED: 'Please enter a city', LOSS_CITY_REQUIRED: 'Please enter a city',
LOSS_CITY_FORMAT: 'Please enter only alpha characters',
LOSS_STATE_REQUIRED: 'Please select an option', LOSS_STATE_REQUIRED: 'Please select an option',
LOSS_DATE_REQUIRED: LOSS_DATE_REQUIRED:
'Please select a date. Format must be MM/DD/YYYY and the date must be not in the future', 'Please select a date. Format must be MM/DD/YYYY and the date must be not in the future',
DAMAGE_DATE_REQUIREMENT: DAMAGE_DATE_REQUIREMENT:
'Damage date must be within the past 10 years', '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', DAMAGE_OPTION_REQUIRED: 'Please select an option',
POLICYHOLDER_FIRST_NAME_REQUIRED: 'Please enter the policyholder first name', POLICYHOLDER_FIRST_NAME_REQUIRED: 'Please enter the policyholder first name',

View file

@ -7,8 +7,18 @@
const globalRules = Object.freeze({ const globalRules = Object.freeze({
POLICYHOLDER_FIRST_NAME_REQUIRED: 'policyholder-first-name-required', POLICYHOLDER_FIRST_NAME_REQUIRED: 'policyholder-first-name-required',
POLICYHOLDER_LAST_NAME_REQUIRED: 'policyholder-last-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', FIRST_NAME_REQUIRED: 'first-name-required',
LAST_NAME_REQUIRED: 'last-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_REQUIRED: 'email-required',
EMAIL_ADDRESS_FORMAT: 'email-address-format', EMAIL_ADDRESS_FORMAT: 'email-address-format',
PHONE_NUMBER_REQUIRED: 'phone-number-required', PHONE_NUMBER_REQUIRED: 'phone-number-required',

View file

@ -102,7 +102,7 @@ export default {
}, },
validationRules: String, validationRules: String,
cmsWidgetName: { cmsWidgetName: {
String, type: String,
default: '' default: ''
}, },
maxLength: String, maxLength: String,

View file

@ -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 * @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 * @summary Define global rules related to zip codes
*/ */
@ -61,8 +119,11 @@ function defineGlobalZipCodeRules() {
*/ */
export default function defineGlobalRules() { export default function defineGlobalRules() {
defineGlobalNameRules(); defineGlobalNameRules();
defineGlobalDateOfLossRules();
defineGlobalEmailRules(); defineGlobalEmailRules();
defineGlobalPhoneNumberRules(); defineGlobalPhoneNumberRules();
defineGlobalPolicyNumberRules();
defineGlobalPolicyZipCodeRules();
defineGlobalZipCodeRules(); defineGlobalZipCodeRules();
defineRule(globalRules.OPTION_REQUIRED, required(errorMessages.OPTION_REQUIRED)); defineRule(globalRules.OPTION_REQUIRED, required(errorMessages.OPTION_REQUIRED));

View file

@ -69,7 +69,7 @@ function setupMocks({
} }
}; };
mountOptionsMockData = { const mockDataMountOptions = {
...mountOptionsMockData, ...mountOptionsMockData,
router: { router: {
navigate: jest.fn() navigate: jest.fn()
@ -81,12 +81,13 @@ function setupMocks({
settleAllPromises.mockImplementation(() => apiPromise); settleAllPromises.mockImplementation(() => apiPromise);
fetchCmsContentForPage.mockImplementation(() => Promise.resolve()); fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
const mountOptions = getMountOptions(mountOptionsMockData); const mountOptions = getMountOptions(mockDataMountOptions);
const wrapper = shallowMount(welcomePage, mountOptions); const wrapper = shallowMount(welcomePage, mountOptions);
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent; wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => ''); wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
return { wrapper, apiPromise }; return { wrapper, apiPromise };
} }
@ -175,170 +176,243 @@ describe('welcome-page.vue', () => {
}); });
describe('navigation', () => { describe('navigation', () => {
test('if duplicates found, navigate to duplicate check page', async () => { describe('When zip code check fails', () => {
// Arrange test('Navigation should not happen', async () => {
const { wrapper } = getMountedComponent({}); // Arrange
useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({})); const { wrapper } = setupMocks({});
useMainStore().applicationUser.duplicateOrders = [{ test: 'a' }]; 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 // Act
await wrapper.vm.forwardButtonAction(); await wrapper.vm.forwardButtonAction();
// Assert // Assert
expect(wrapper.vm.mainStore.getDuplicateReferrals).toHaveBeenCalled(); expect(wrapper.vm.mainStore.getDuplicateReferrals).toHaveBeenCalledTimes(0);
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( expect(wrapper.vm.$router.navigate).toHaveBeenCalledTimes(0);
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;
// Act describe('When zip code check succeeds', () => {
await wrapper.vm.forwardButtonAction(); 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 // Act
expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled(); await wrapper.vm.forwardButtonAction();
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 // Assert
await wrapper.vm.forwardButtonAction(); 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 // Act
expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled(); await wrapper.vm.forwardButtonAction();
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 // Assert
await wrapper.vm.forwardButtonAction(); 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 // Act
expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled(); await wrapper.vm.forwardButtonAction();
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 // Assert
await wrapper.vm.forwardButtonAction(); 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 // Act
expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled(); await wrapper.vm.forwardButtonAction();
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 = []; // Assert
useMainStore().order.policy.policyLookupSuccessful = true; expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled();
useMainStore().order.policy.vehicles = [ expect(wrapper.vm.mainStore.getCoveragePolicyInfo).not.toHaveBeenCalled();
{ vin: 'TEST_VIN' }, });
{ vin: 'TEST_VIN2' } 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 // Act
await wrapper.vm.forwardButtonAction(); await wrapper.vm.forwardButtonAction();
// Assert // Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( expect(wrapper.vm.mainStore.updatePolicyData).toHaveBeenCalled();
navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_WITH_VEHICLES, expect(wrapper.vm.mainStore.getCoveragePolicyInfo).toHaveBeenCalled();
undefined, });
{}, test('if policy and vehicles are found but no duplicates, navigate to policy-vehicle page', async () => {
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } // Arrange
); const { wrapper } = setupMocks({});
}); useMainStore().getDuplicateReferrals = jest.fn().mockImplementation(() => Promise.resolve({}));
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({}));
useMainStore().applicationUser.duplicateOrders = []; useMainStore().applicationUser.duplicateOrders = [];
useMainStore().order.policy.policyLookupSuccessful = true; useMainStore().order.policy.policyLookupSuccessful = true;
useMainStore().order.policy.vehicles = []; 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 useMainStore().applicationUser.duplicateOrders = [];
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( useMainStore().order.policy.policyLookupSuccessful = true;
navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_NO_VEHICLES, useMainStore().order.policy.vehicles = [];
undefined, wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({
{}, data: {
{ [routerParams.SAVE_SESSION_SYNCHRONOUS]: true } isValid: 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 = []; // Act
useMainStore().order.policy.policyLookupSuccessful = true; await wrapper.vm.forwardButtonAction();
useMainStore().order.policy.vehicles = null;
// 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 wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( data: {
navigationScenarios.CLICKED_FORWARD_POLICY_VERIFIED_NO_VEHICLES, isValid: true
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({}));
useMainStore().order.policy.policyLookupSuccessful = false; // Act
useMainStore().applicationUser.duplicateOrders = []; await wrapper.vm.forwardButtonAction();
// Act // Assert
await wrapper.vm.forwardButtonAction(); 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 useMainStore().order.policy.policyLookupSuccessful = false;
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith( useMainStore().applicationUser.duplicateOrders = [];
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));
// Act wrapper.vm.mainStore.validateZip = jest.fn().mockImplementation(() => Promise.resolve({
await wrapper.vm.forwardButtonAction(); data: {
isValid: true
}
}));
// Assert // Act
expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); 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();
});
}); });
}); });

View file

@ -85,7 +85,7 @@
cmsWidgetName="PhoneNumberQuestion" cmsWidgetName="PhoneNumberQuestion"
:validationRules="rules.phoneNumber" :validationRules="rules.phoneNumber"
isRequired isRequired
mask="###-###-####" :mask="mask"
disableAutoFill /> disableAutoFill />
</div> </div>
</div> </div>
@ -153,11 +153,18 @@
id="welcomeFooter" id="welcomeFooter"
class="row position-sticky top-100"> class="row position-sticky top-100">
<div class="col"> <div class="col">
<alert
v-if="displayInvalidZipAlert"
ref="alertInvalidZip"
class="my-4"
cmsWidgetName="AlertInvalidZipWidget"
alertClass="alert-danger"
:isDismissible="false" />
<siteFooter <siteFooter
ref="siteFooter"
class="mt-3" class="mt-3"
cmsWidgetName="SiteFooterWidget" cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid" :isForwardActionDisabled="!meta.valid"
@backClicked="backButtonAction"
@ForwardClicked="forwardButtonAction" /> @ForwardClicked="forwardButtonAction" />
</div> </div>
</div> </div>
@ -173,6 +180,7 @@ import { Form, defineRule } from 'vee-validate';
import siteHeader from '@/iss-components/site-header/site-header.vue'; import siteHeader from '@/iss-components/site-header/site-header.vue';
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-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 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 textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue';
import buttonQuestion from '@/digital-components/button-question/button-question.vue'; import buttonQuestion from '@/digital-components/button-question/button-question.vue';
import dropdownQuestion from '@/digital-components/dropdown-question/dropdown-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 // Supporting files
import { fetchCmsContentForPage, fetchGlobalCmsContent, updateCmsSiteHeader } from '@/helpers/cms-content-helper'; import { fetchCmsContentForPage, fetchGlobalCmsContent, updateCmsSiteHeader } from '@/helpers/cms-content-helper';
import settleAllPromises from '@/helpers/layout-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 errorMessages from '@/constants/error-messages';
import BaseFormMixin from '@/mixins/base-form-mixin.js'; import BaseFormMixin from '@/mixins/base-form-mixin.js';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
@ -190,32 +198,14 @@ import globalRules from '@/constants/global-rules';
import routerParams from '@/router/router-constants/router-params'; import routerParams from '@/router/router-constants/router-params';
// define validation rules // 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('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 { export default {
name: 'welcome-page', name: 'welcome-page',
components: { components: {
siteHeader, siteHeader,
siteSubHeader, siteSubHeader,
alert,
buttonQuestion, buttonQuestion,
textboxQuestion, textboxQuestion,
dropdownQuestion, dropdownQuestion,
@ -260,16 +250,18 @@ export default {
data() { data() {
return { return {
welcomePageModel: this.getWelcomePageModelFromStore(), welcomePageModel: this.getWelcomePageModelFromStore(),
displayInvalidZipAlert: false,
duplicates: [], duplicates: [],
rules: { 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', damageOption: 'damage-option-required',
phoneNumber: `${globalRules.PHONE_NUMBER_REQUIRED}|${globalRules.PHONE_NUMBER_FORMAT}`,
email: `${globalRules.EMAIL_ADDRESS_REQUIRED}|${globalRules.EMAIL_ADDRESS_FORMAT}`, email: `${globalRules.EMAIL_ADDRESS_REQUIRED}|${globalRules.EMAIL_ADDRESS_FORMAT}`,
lossCity: 'loss-city-required', lossCity: `${globalRules.DATE_OF_LOSS_CITY_REQUIRED}|${globalRules.DATE_OF_LOSS_CITY_FORMAT}`,
lossState: 'loss-state-required' // 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() { maxCoverageLookupAttemptsReached() {
return this.mainStore.applicationUser.coverageLookupAttempts >= 11; return this.mainStore.applicationUser.coverageLookupAttempts >= 11;
},
mask() {
return {
mask: 'x##-###-####',
tokens: {
x: {
pattern: /[2-9]/
}
}
};
} }
}, },
methods: { methods: {
async forwardButtonAction() { async forwardButtonAction() {
this.mainStore.updatePolicyData(this.welcomePageModel); await this.mainStore.validateZip({ zip: this.welcomePageModel.policyZipCode })
await this.mainStore.getDuplicateReferrals() .then(async (zipInfo) => {
.then(() => {}, () => {}) if (zipInfo?.data?.isValid === true) {
.finally(async () => { this.mainStore.updatePolicyData(this.welcomePageModel);
if (this.isCoverageEnabled && !this.maxCoverageLookupAttemptsReached) { await this.mainStore.getDuplicateReferrals()
await this.mainStore.getCoveragePolicyInfo()?.then(() => {}, () => {}); .then(() => {}, () => {})
.finally(async () => {
if (this.isCoverageEnabled && !this.maxCoverageLookupAttemptsReached) {
await this.mainStore.getCoveragePolicyInfo()?.then(() => {}, () => {});
} else {
this.mainStore.order.policy.policyLookupSuccessful = false;
}
this.navigateForward();
});
} else { } else {
this.mainStore.order.policy.policyLookupSuccessful = false; this.displayInvalidZipAlert = true;
this.$refs.siteFooter.removeLoader();
} }
this.navigateForward();
}); });
}, },
navigateForward() { navigateForward() {