Merge branch 'develop' into feature/SSR-669

This commit is contained in:
Katie Kroell 2023-10-17 10:01:31 -04:00
commit 9ce800f74f
17 changed files with 333 additions and 67 deletions

View file

@ -41,6 +41,8 @@ const errorMessages = Object.freeze({
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_OPTION_REQUIRED: 'Please select an option',
POLICYHOLDER_FIRST_NAME_REQUIRED: 'Please enter the policyholder first name',

View file

@ -1,7 +1,7 @@
const AppointmentTypeStrings = {
IN_SHOP: 'Inshop',
MOBILE: 'Mobile',
MOBILE_NOT_ITAC: 'Mobile-Not-ITAC',
MOBILE_NOT_ITAC_AND_NOT_NOCOMP: 'Mobile-Not-ITAC-And-Not-NoComp',
DROP_OFF: 'Dropoff'
};
const PREMIUM_FEE_PART_TYPE = 'EARLY BIRD';

View file

@ -669,7 +669,6 @@ export default {
}
},
async updateSelectableDates(monthStart, monthEnd) {
console.log(this.mainStore);
const moreSelectableDates = await this.customSelectableDatesCallback(
monthStart,
monthEnd,

View file

@ -7,6 +7,24 @@ import { getMountOptions } from '@/helpers/unit-test-helper.js';
import navigationScenarios from '@/router/router-constants/navigation-scenarios';
import { createTestingPinia } from '@pinia/testing';
import { useMainStore } from '@/store';
import { getRandomString } from '@/helpers/data-generation';
function getMountedComponent(mainInitialState = {}) {
const mountOptions = getMountOptions({
router: {
navigate: jest.fn()
}
});
mountOptions.global.plugins = [createTestingPinia({
initialState: {
main: mainInitialState
}
})];
const wrapper = shallowMount(policyEndorsements, mountOptions);
return { wrapper };
}
describe('policyEndorsements.vue', () => {
describe('Rendering', () => {
@ -30,26 +48,70 @@ describe('policyEndorsements.vue', () => {
// Assert
expect(siteSubHeader.exists()).toBe(true);
});
test('Should render schoolProperty buttonQuestion component', () => {
test('Should render schoolProperty buttonQuestion component if policy vehicle has Educator endorsement', () => {
// Arrange
const wrapper = shallowMount(policyEndorsements, getMountOptions());
// Act
const mainInitialState = {
order: {
policy: {
endorsements: ['Educator']
}
}
};
const { wrapper } = getMountedComponent(mainInitialState);
const buttonQuestion = wrapper.findComponent({ ref: 'schoolPropertyQuestion' });
// Assert
expect(wrapper.vm.educatorEndorsement).toBeTruthy();
expect(buttonQuestion.exists()).toBe(true);
});
test('Should render parkingLot buttonQuestion component', () => {
test('Should not render schoolProperty buttonQuestion component if policy vehicle does not have Educator endorsement', () => {
// Arrange
const wrapper = shallowMount(policyEndorsements, getMountOptions());
const mainInitialState = {
order: {
policy: {
endorsements: [getRandomString(20, 30)]
}
}
};
const { wrapper } = getMountedComponent(mainInitialState);
const buttonQuestion = wrapper.findComponent({ ref: 'schoolPropertyQuestion' });
// Act
// Assert
expect(wrapper.vm.educatorEndorsement).toBeFalsy();
expect(buttonQuestion.exists()).toBe(false);
});
test('Should render parkingLot buttonQuestion component if policy vehicle has Parking Guard endorsement', () => {
// Arrange
const mainInitialState = {
order: {
policy: {
endorsements: ['Parking Guard']
}
}
};
const { wrapper } = getMountedComponent(mainInitialState);
const buttonQuestion = wrapper.findComponent({ ref: 'parkingLotQuestion' });
// Assert
expect(wrapper.vm.parkingGuardEndorsement).toBeTruthy();
expect(buttonQuestion.exists()).toBe(true);
});
test('Should not render parkingLot buttonQuestion component if policy vehicle does not have Parking Guard endorsement', () => {
// Arrange
const mainInitialState = {
order: {
policy: {
endorsements: [getRandomString(20, 30)]
}
}
};
const { wrapper } = getMountedComponent(mainInitialState);
const buttonQuestion = wrapper.findComponent({ ref: 'parkingLotQuestion' });
// Assert
expect(wrapper.vm.parkingGuardEndorsement).toBeFalsy();
expect(buttonQuestion.exists()).toBe(false);
});
test('Should render site footer', () => {
// Arrange
const wrapper = shallowMount(policyEndorsements, getMountOptions());

View file

@ -16,6 +16,7 @@
cmsWidgetName="SiteSubHeaderWidget"
class="mt-5" />
<buttonQuestion
v-if="educatorEndorsement"
ref="schoolPropertyQuestion"
v-model="schoolPropertyAnswer"
class="radioQuestion windshield-chip-count-question mb-4"
@ -29,6 +30,7 @@
:validationRules="rules.selectionRequired">
</buttonQuestion>
<buttonQuestion
v-if="parkingGuardEndorsement"
ref="parkingLotQuestion"
v-model="parkingLotAnswer"
class="radioQuestion windshield-chip-count-question"
@ -43,7 +45,6 @@
</buttonQuestion>
<siteFooter
ref="siteFooter"
class="pt-5"
cmsWidgetName="SiteFooterWidget"
:isForwardActionDisabled="!meta.valid"
@forwardClicked="forwardButtonAction"
@ -117,6 +118,12 @@ export default {
},
parkingLotAnswersFromCms() {
return this.getCmsContent('ParkingLotQuestion', 'Answers');
},
educatorEndorsement() {
return useMainStore().order.policy.endorsements?.includes('Educator') ?? false;
},
parkingGuardEndorsement() {
return useMainStore().order.policy.endorsements?.includes('Parking Guard') ?? false;
}
},
methods:
@ -126,18 +133,24 @@ export default {
},
async forwardButtonAction() {
// TO DO: remove hard coding and update data format once service returns endorsement questions
this.questionAnswersArray.push(
if (this.educatorEndorsement) {
this.questionAnswersArray.push(
{
questionNum: 1,
endorsement: 'Educator',
questionText: this.schoolPropertyQuestionText,
selectedAnswer: this.schoolPropertyAnswer
},
});
};
if (this.parkingGuardEndorsement) {
this.questionAnswersArray.push(
{
questionNum: 2,
endorsement: 'Parking Guard',
questionText: this.parkingLotQuestionText,
selectedAnswer: this.parkingLotAnswer
}
);
});
};
// save answers to store as order.policy.endorsementQuestionAnswers
useMainStore().saveEndorsementQuestionAnswers(this.questionAnswersArray);

View file

@ -117,7 +117,8 @@ describe('policy-vehicles.vue', () => {
vin,
noCoverage: true,
deductible: 0,
repairWaived: false
repairWaived: false,
endorsements: []
};
// Act
@ -135,6 +136,55 @@ describe('policy-vehicles.vue', () => {
}
);
test(
// eslint-disable-next-line max-len
'Selected VIN matches vehicle listed in system and policy vehicle has endorsements => update vehicle and navigate forward with CLICKED_FORWARD_WITH_ENDORSEMENTS scenario.',
async () => {
// Arrange
const { wrapper } = setupMocks({});
const vin = getRandomString(17, 17);
const endorsements = [getRandomString(10, 20)];
await wrapper.setData({
selectedVehicleVin: vin,
policyVehicles: [
{
vin,
endorsements
}
]
});
const year = getRandomInt(1998, 2023);
const lookupVehicleResponse = {
data: {
year
}
};
const store = useMainStore();
store.lookupVehicleByVin.mockReturnValue(Promise.resolve(lookupVehicleResponse));
const expectedInput = {
year,
vin,
noCoverage: true,
deductible: 0,
repairWaived: false,
endorsements
};
// Act
await wrapper.vm.forwardButtonAction();
// Assert
expect(store.updateVehicle).toHaveBeenCalledWith(expectedInput);
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD_WITH_ENDORSEMENTS,
undefined
);
}
);
test(
'Error in lookupVehicleByVin call => bailout true and navigate forward with CLICKED_FORWARD_WITH_BAILOUT scenario.',
async () => {
@ -408,6 +458,120 @@ describe('policy-vehicles.vue', () => {
});
});
describe('endorsementsForSelectedVehicle computed property', () => {
it('policyVehicles is null => empty endorsements array returned', () => {
// Arrange
const testValues = {
policyVehicles: null
};
// Act
const result = policyVehicles.computed.endorsementsForSelectedVehicle.call(testValues);
const expected = [];
// Assert
expect(result).toStrictEqual(expected);
});
it('policyVehicles is empty => empty endorsements array returned', () => {
// Arrange
const testValues = {
policyVehicles: []
};
// Act
const result = policyVehicles.computed.endorsementsForSelectedVehicle.call(testValues);
const expected = [];
// Assert
expect(result).toStrictEqual(expected);
});
it('selectedVehicleVin does not match any vin in policyVehicles => empty endorsements array returned', () => {
// Arrange
const selectedVin = getRandomString(17, 17);
const otherVin = getRandomString(17, 17);
const testValues = {
selectedVehicleVin: selectedVin,
policyVehicles: [
{
vin: otherVin
}
]
};
// Act
const result = policyVehicles.computed.endorsementsForSelectedVehicle.call(testValues);
const expected = [];
// Assert
expect(result).toStrictEqual(expected);
});
it('vehicle VIN match with endorsements null => empty endorsements array returned', () => {
// Arrange
const vin = getRandomString(17, 17);
const testValues = {
selectedVehicleVin: vin,
policyVehicles: [
{
vin,
endorsements: null
}
]
};
// Act
const result = policyVehicles.computed.endorsementsForSelectedVehicle.call(testValues);
const expected = [];
// Assert
expect(result).toStrictEqual(expected);
});
it('vehicle VIN match with empty endorsements => empty endorsements array returned', () => {
// Arrange
const vin = getRandomString(17, 17);
const testValues = {
selectedVehicleVin: vin,
policyVehicles: [
{
vin,
endorsements: []
}
]
};
// Act
const result = policyVehicles.computed.endorsementsForSelectedVehicle.call(testValues);
const expected = [];
// Assert
expect(result).toStrictEqual(expected);
});
it('vehicle VIN match with endorsements => endorsements array returned', () => {
// Arrange
const vin = getRandomString(17, 17);
const endorsements = [getRandomString(10, 20)];
const testValues = {
selectedVehicleVin: vin,
policyVehicles: [
{
vin,
endorsements
}
]
};
// Act
const result = policyVehicles.computed.endorsementsForSelectedVehicle.call(testValues);
// Assert
expect(result).toStrictEqual(endorsements);
});
});
test('first vehicle is auto-selected if only one vehicle on policy', async () => {
// Arrange
const vin = getRandomString(17, 17);

View file

@ -102,12 +102,12 @@ export default {
return mappedData;
},
noCoverageForSelectedVehicle() {
const vehicle = this.policyVehicles.find((policyVehicle) =>
const vehicle = this.policyVehicles?.find((policyVehicle) =>
policyVehicle.vin === this.selectedVehicleVin);
return (vehicle?.coverages?.length ?? 0) === 0;
},
deductibleForSelectedVehicle() {
const vehicle = this.policyVehicles.find((policyVehicle) =>
const vehicle = this.policyVehicles?.find((policyVehicle) =>
policyVehicle?.vin === this.selectedVehicleVin);
if (!vehicle) {
return undefined;
@ -118,16 +118,15 @@ export default {
: 0;
},
endorsementsForSelectedVehicle() {
const vehicle = this.policyVehicles.find((policyVehicle) =>
const vehicle = this.policyVehicles?.find((policyVehicle) =>
policyVehicle?.vin === this.selectedVehicleVin);
if (vehicle?.endorsements?.length > 0) {
return vehicle.endorsements;
}
return [];
},
repairWaivedForSelectedVehicle() {
const vehicle = this.policyVehicles.find((policyVehicle) =>
const vehicle = this.policyVehicles?.find((policyVehicle) =>
policyVehicle.vin === this.selectedVehicleVin);
return vehicle?.endorsements?.includes(endorsementOptions.REPAIR_WAIVED) ?? false;
},
@ -162,7 +161,7 @@ export default {
},
beforeMount() {
if (this.policyVehicles?.length === 1) {
this.selectedVehicleVin = this.policyVehicles[0].vin;
this.selectedVehicleVin = this.policyVehicles[0]?.vin;
}
},
methods:

View file

@ -131,7 +131,7 @@ const getAvailableDates = async (
}
if (appointmentType === AppointmentTypeStrings.MOBILE
|| appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC) {
|| appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP) {
storeActionConfig = {
storeAction: GET_MOBILE_TIME_SLOTS,
payload: {
@ -326,7 +326,7 @@ export default {
&& serviceLocation.zipCodeCtu
&& serviceLocation.appointmentType
&& ((serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE
|| serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC)
|| serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP)
|| serviceLocation.provider.providerNumber);
const paymentInfo = useMainStore().payment.isInsurance !== null;
const supportingItems = useMainStore().lineItems.supportingItems !== null;

View file

@ -166,7 +166,7 @@ export default {
}
if (this.appointmentType === AppointmentTypeStrings.MOBILE
|| this.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC) {
|| this.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP) {
appointmentTypeCmsWidgetName = this.selectedRouteCode?.includes(PREMIUM_TIME_SLOT_ID_FLAG)
? this.mobilePremiumCmsWidgetName
: this.mobileCmsWidgetName;
@ -275,7 +275,7 @@ export default {
},
durationTextBlockCopy() {
if (this.appointmentType === AppointmentTypeStrings.MOBILE
|| this.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC) {
|| this.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP) {
return null;
} if (this.appointmentType === AppointmentTypeStrings.IN_SHOP) {
return this.inshopDurationText;
@ -321,7 +321,7 @@ export default {
if (this.appointmentType === AppointmentTypeStrings.DROP_OFF) {
return this.getAvailableTimeSlotsForDropOff(this.timeSlotsForSelectedDate.timeSlots);
} if (this.appointmentType === AppointmentTypeStrings.MOBILE
|| this.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC) {
|| this.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP) {
return this.getAvailableTimeSlotsForMobile(this.timeSlotsForSelectedDate.timeSlots);
}
return this.getAvailableTimeSlotsForInshop(this.timeSlotsForSelectedDate.timeSlots);

View file

@ -51,15 +51,15 @@ export default {
return this.getCmsContent(this.cmsWidgetName, 'Answers');
},
answersToDisplay() {
const shouldShowMobile = this.isServiceableMobile && this.isITAC;
const shouldShowMobileNotITAC = this.isServiceableMobile && !this.isITAC;
const shouldShowMobile = this.isServiceableMobile && this.isItacOrNoComp;
const shouldShowMobileNotITACNotNoComp = this.isServiceableMobile && !this.isItacOrNoComp;
const shouldShowInshop = this.isServiceableInshop;
const shouldShowDropoff = this.isServiceableInshop && !useMainStore().damage.isRepair;
return this.answersFromCms
? this.answersFromCms.filter((answer) => (
(answer.Name === AppointmentTypeStrings.IN_SHOP && shouldShowInshop)
|| (answer.Name === AppointmentTypeStrings.MOBILE && shouldShowMobile)
|| (answer.Name === AppointmentTypeStrings.MOBILE_NOT_ITAC && shouldShowMobileNotITAC)
|| (answer.Name === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP && shouldShowMobileNotITACNotNoComp)
|| (answer.Name === AppointmentTypeStrings.DROP_OFF && shouldShowDropoff)
))
: [];
@ -75,6 +75,9 @@ export default {
isITAC() {
return useMainStore().policy.isITAC;
},
isItacOrNoComp() {
return useMainStore().policy.isITAC || useMainStore().policy.noCoverage;
},
isMobileOnly() {
return this.isServiceableMobile && !this.isServiceableInshop;
}
@ -86,12 +89,12 @@ export default {
if (
newValue.length === 1
&& newValue.findIndex((answer) => (answer.Name === AppointmentTypeStrings.MOBILE
|| answer.Name === AppointmentTypeStrings.MOBILE_NOT_ITAC)) !== -1
|| answer.Name === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP)) !== -1
) {
if (this.isITAC) {
if (this.isItacOrNoComp) {
this.selectedValues = AppointmentTypeStrings.MOBILE;
} else {
this.selectedValues = AppointmentTypeStrings.MOBILE_NOT_ITAC;
this.selectedValues = AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
}
}
},
@ -100,10 +103,10 @@ export default {
isMobileOnly: {
handler(newValue) {
if (newValue) {
if (this.isITAC) {
if (this.isItacOrNoComp) {
this.selectedValues = AppointmentTypeStrings.MOBILE;
} else {
this.selectedValues = AppointmentTypeStrings.MOBILE_NOT_ITAC;
this.selectedValues = AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
}
}
}

View file

@ -31,7 +31,7 @@
</span>
</div>
<textBlock
v-if="isITAC"
v-if="isItacOrNoComp"
:customText="mobileFeeText"
cmsWidgetName="MobileFeeDisclaimerWidget"
typeStyle="caption" />
@ -43,13 +43,14 @@
:onModalOpenedCallback="onModalOpened"
:onModalClosedCallback="onModalClosed"
@isModalOpened="setModalStatus"
@footer-button-event="setMobileLocation">
@footerButtonEvent="setMobileLocation">
<template v-if="isModalOpened">
<addressQuestions
ref="addressQuestions"
v-model="internalModel.addressQuestions"
captureApartmentNumberOrBusinessName="true"
preserveCityAndStateOnReset="true" />
preserveCityAndStateOnReset="true"
includeStreetAddress2="true" />
<vehicleProtectedQuestion
ref="vehicleProtectedQuestion"
v-model="internalModel.isVehicleProtected"
@ -108,7 +109,7 @@ export default {
default: () => ({
addressQuestions: {
streetAddress: '',
apartmentNumberOrBusinessName: '',
streetAddress2: '',
city: '',
state: '',
zipCode: ''
@ -172,6 +173,9 @@ export default {
isITAC() {
return useMainStore().policy.isITAC;
},
isItacOrNoComp() {
return useMainStore().policy.isITAC || useMainStore().policy.noCoverage;
},
mobileLocationLinkPromptText() {
return this.getCmsContent(this.linkWidgetName, 'HeaderText');
},
@ -298,6 +302,8 @@ export default {
</script>
<style lang="scss" scoped>
@import "@/styles/ux-variables-svg-strings.scss";
.mobile-location-questions {
.center-error-message {
justify-content: center !important;
@ -309,7 +315,7 @@ export default {
display: inline-block;
width: 13px;
height: 16px;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 13 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.49635 1.00142e-07C5.64734 -0.000153295 4.80722 0.175918 4.0274 0.517444C3.24757 0.858969 2.54443 1.35877 1.96099 1.98626C0.765713 3.27588 0.0999756 4.98141 0.0999756 6.75394C0.0999756 8.52646 0.765713 10.232 1.96099 11.5216L5.98324 15.777C6.04954 15.8475 6.12918 15.9036 6.21736 15.9419C6.30555 15.9802 6.40045 16 6.49635 16C6.59225 16 6.68716 15.9802 6.77534 15.9419C6.86353 15.9036 6.94317 15.8475 7.00946 15.777L11.0317 11.52C12.2391 10.2383 12.909 8.52914 12.8999 6.75394C12.9094 4.97818 12.2394 3.26832 11.0317 1.98626C10.4481 1.35899 9.74493 0.859347 8.96514 0.517839C8.18535 0.176331 7.34532 0.000130509 6.49635 1.00142e-07V1.00142e-07ZM6.49635 9.13131C6.02507 9.13131 5.56437 8.98913 5.17251 8.72275C4.78065 8.45637 4.47524 8.07776 4.29488 7.63479C4.11453 7.19181 4.06734 6.70438 4.15928 6.23412C4.25123 5.76387 4.47817 5.33191 4.81142 4.99287C5.14467 4.65384 5.56925 4.42295 6.03148 4.32941C6.49371 4.23587 6.97282 4.28388 7.40823 4.46736C7.84364 4.65085 8.21579 4.96157 8.47762 5.36023C8.73945 5.7589 8.87921 6.2276 8.87921 6.70707C8.87921 7.34974 8.62837 7.96611 8.18185 8.4207C7.73532 8.87528 7.12964 9.13088 6.49794 9.13131H6.49635Z' fill='%231574A1'/%3E%3C/svg%3E%0A");
background-image: url($svg-update-zip-text-link);
background-size: contain;
vertical-align: middle;
margin-right: 0.5em;

View file

@ -194,7 +194,7 @@ export default {
data() {
return {
streetAddress: this.getServiceAddressFromStore(),
apartmentNumberOrBusinessName: this.getServiceAddress2FromStore(),
streetAddress2: this.getServiceAddress2FromStore(),
city: this.getServiceCityFromStore(),
state: this.getServiceStateFromStore(),
zipCode: this.getServiceZipCodeFromStore(),
@ -243,7 +243,7 @@ export default {
return {
addressQuestions: {
streetAddress: this.streetAddress,
apartmentNumberOrBusinessName: this.apartmentNumberOrBusinessName,
streetAddress2: this.streetAddress2,
city: this.city,
state: this.state,
zipCode: this.zipCode
@ -253,8 +253,7 @@ export default {
},
set(newValue) {
this.streetAddress = newValue.addressQuestions.streetAddress;
this.apartmentNumberOrBusinessName =
newValue.addressQuestions.apartmentNumberOrBusinessName;
this.streetAddress2 = newValue.addressQuestions.streetAddress2;
this.city = newValue.addressQuestions.city;
this.state = newValue.addressQuestions.state;
this.zipCode = newValue.addressQuestions.zipCode;
@ -262,7 +261,7 @@ export default {
if (newValue.zipCode !== this.zipCode) {
if (!(this.selectedAppointmentType === AppointmentTypeStrings.MOBILE
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC)) {
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP)) {
this.selectedAppointmentType = null;
}
this.selectedProvider = null;
@ -293,7 +292,7 @@ export default {
},
isMobileLocationDisplayed() {
return this.selectedAppointmentType === AppointmentTypeStrings.MOBILE
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC;
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
},
requiresInshopRecalibration() {
// Specifically check for isRecalibrationServiceableMobile === false, not null or true.
@ -342,7 +341,7 @@ export default {
async forwardButtonAction() {
useMainStore().saveServiceLocation({
address: this.streetAddress,
address2: this.apartmentNumberOrBusinessName,
address2: this.streetAddress2,
city: this.city,
state: this.state,
zipCode: this.zipCode,
@ -417,7 +416,7 @@ export default {
},
resetMobileLocation() {
this.streetAddress = '';
this.apartmentNumberOrBusinessName = '';
this.streetAddress2 = '';
this.city = '';
this.isVehicleProtected = null;

View file

@ -142,7 +142,7 @@ export default {
await nextTick();
if (newValue !== AppointmentTypeStrings.MOBILE && newValue !== AppointmentTypeStrings.MOBILE_NOT_ITAC) {
if (newValue !== AppointmentTypeStrings.MOBILE && newValue !== AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP) {
this.getNextShopsFromList();
}
}

View file

@ -198,6 +198,16 @@ 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',
@ -248,7 +258,7 @@ export default {
rules: {
policyNumber: 'policy-number-required',
policyZip: 'policy-zip-required|policy-zip-format',
lossDate: 'loss-date-required',
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}`,

View file

@ -196,7 +196,7 @@ export const useMainStore = defineStore({
policy: (state) => state.order.policy,
hasAnyNonWindshieldGlassParts: (state) => !state.order.policy.isDamageGlassOnly,
isMobileAppointment: (state) => state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE
|| state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC,
|| state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP,
isDropOffAppointment: (state) => state.order.serviceLocation.appointmentType === AppointmentTypeStrings.DROP_OFF,
isClaimRegistrationRequired: (state) => state.issConfig.isClaimRegistrationRequired,
eventBusItem: (state) => (eventCategory, eventSubCategory) => {
@ -1029,7 +1029,9 @@ export const useMainStore = defineStore({
zipCode: serviceLocation.zipCode,
zipCodeCtu: serviceLocation.zipCodeCtu
},
appointmentType: serviceLocation.appointmentType,
appointmentType: (serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE
|| serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP)
? AppointmentTypeStrings.MOBILE : serviceLocation.appointmentType,
isVehicleProtected: serviceLocation.isVehicleProtected,
provider: {
providerNumber: serviceLocation.provider?.providerNumber,
@ -1119,16 +1121,16 @@ export const useMainStore = defineStore({
this.order.vehicle.registration.lastName = registrationInfo?.lastName;
},
updateServiceLocation(serviceLocationInfo) {
state.order.serviceLocation.address = serviceLocationInfo.address;
state.order.serviceLocation.address2 = serviceLocationInfo.address2;
state.order.serviceLocation.city = serviceLocationInfo.city;
state.order.serviceLocation.state = serviceLocationInfo.state;
state.order.serviceLocation.zipCode = serviceLocationInfo.zipCode;
state.order.serviceLocation.zipCodeCtu = serviceLocationInfo.zipCodeCtu;
state.order.serviceLocation.appointmentType = serviceLocationInfo.appointmentType;
state.order.serviceLocation.isVehicleProtected = serviceLocationInfo.isVehicleProtected;
this.order.serviceLocation.address = serviceLocationInfo.address;
this.order.serviceLocation.address2 = serviceLocationInfo.address2;
this.order.serviceLocation.city = serviceLocationInfo.city;
this.order.serviceLocation.state = serviceLocationInfo.state;
this.order.serviceLocation.zipCode = serviceLocationInfo.zipCode;
this.order.serviceLocation.zipCodeCtu = serviceLocationInfo.zipCodeCtu;
this.order.serviceLocation.appointmentType = serviceLocationInfo.appointmentType;
this.order.serviceLocation.isVehicleProtected = serviceLocationInfo.isVehicleProtected;
state.order.serviceLocation.provider = {
this.order.serviceLocation.provider = {
providerNumber: serviceLocationInfo.provider?.providerNumber,
address: {
streetAddress: serviceLocationInfo.provider?.address?.streetAddress,

View file

@ -153,10 +153,12 @@ describe('Store', () => {
// Arrange
const noCoverage = getRandomBoolean();
const deductible = getRandomInt(1, 500);
const endorsements = [getRandomString(10, 20)];
const vehicle = {
noCoverage,
deductible,
repairWaived: true
repairWaived: true,
endorsements
};
const expectedPolicy = {
@ -164,7 +166,8 @@ describe('Store', () => {
deductible: {
replace: deductible,
repair: 0
}
},
endorsements
};
// Act
@ -178,10 +181,12 @@ describe('Store', () => {
// Arrange
const noCoverage = getRandomBoolean();
const deductible = getRandomInt(1, 500);
const endorsements = [getRandomString(10, 20)];
const vehicle = {
noCoverage,
deductible,
repairWaived: false
repairWaived: false,
endorsements
};
const expectedPolicy = {
@ -189,7 +194,8 @@ describe('Store', () => {
deductible: {
replace: deductible,
repair: deductible
}
},
endorsements
};
// Act
@ -1028,12 +1034,12 @@ describe('Store', () => {
expect(store.isMobileAppointment).toBe(true);
});
it('Should return true for mobile-insurance appointments', () => {
it('Should return true for mobile-NotITAC-and-NotNoComp appointments', () => {
// Arrange
// Act
store.updateServiceLocation({
appointmentType: AppointmentTypeStrings.MOBILE_NOT_ITAC
appointmentType: AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP
});
// Assert

View file

@ -1,3 +1,4 @@
$svg-date-picker-nav-back-button: "data:image/svg+xml,%3Csvg width='7' height='12' viewBox='0 0 7 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0.331685 6.00121C0.330445 5.82446 0.399256 5.65442 0.523053 5.52832L5.84499 0.198256C5.97188 0.0713149 6.14397 -8.63821e-08 6.32341 -6.72174e-08C6.50285 -4.80527e-08 6.67495 0.071315 6.80183 0.198256C6.92872 0.325198 7 0.497368 7 0.67689C7 0.856412 6.92872 1.02858 6.80183 1.15552L1.94874 6.00121L6.80183 10.8526C6.92745 10.9796 6.99751 11.1512 6.99662 11.3299C6.99572 11.5085 6.92393 11.6794 6.79705 11.8051C6.67016 11.9308 6.49857 12.0009 6.32003 12C6.14148 11.9991 5.97061 11.9273 5.84499 11.8003L0.526881 6.47601C0.401568 6.34983 0.331375 6.17908 0.331685 6.00121Z' fill='%231574A1'/%3E%3C/svg%3E%0A";
$svg-date-picker-forward-button: "data:image/svg+xml,%3Csvg width='7' height='12' viewBox='0 0 7 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.66831 5.99879C6.66955 6.17554 6.60074 6.34558 6.47695 6.47168L1.15501 11.8017C1.02812 11.9287 0.85603 12 0.676587 12C0.497145 12 0.325053 11.9287 0.198168 11.8017C0.0712831 11.6748 7.268e-09 11.5026 8.07183e-09 11.3231C8.87567e-09 11.1436 0.0712831 10.9714 0.198168 10.8445L5.05126 5.99879L0.198168 1.14736C0.0725521 1.02042 0.00248585 0.848755 0.00338306 0.670131C0.00428028 0.491506 0.0760674 0.320554 0.202952 0.194881C0.329837 0.0692091 0.501426 -0.000888818 0.679971 9.54485e-06C0.858515 0.000906955 1.02939 0.0727263 1.15501 0.199668L6.47312 5.52399C6.59843 5.65017 6.66862 5.82092 6.66831 5.99879Z' fill='%231574A1'/%3E%3C/svg%3E%0A";
$svg-drop-off-alert: "data:image/svg+xml,%3Csvg viewBox='0 0 12 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0_13957_112512)'%3E%3Cpath d='M5.99865 0C4.81147 4.82643e-07 3.65095 0.352111 2.66392 1.01179C1.67688 1.67146 0.907678 2.60907 0.45361 3.70599C-0.000459241 4.80291 -0.11899 6.00986 0.113013 7.17415C0.345015 8.33845 0.917126 9.40778 1.75697 10.2469C2.59682 11.086 3.66666 11.6571 4.83117 11.8881C5.99567 12.119 7.20251 11.9994 8.29902 11.5443C9.39553 11.0893 10.3324 10.3192 10.9912 9.33159C11.65 8.34396 12.0011 7.18313 12 5.99594C11.9971 4.40566 11.3638 2.88142 10.2388 1.75742C9.11375 0.633431 7.58894 0.00143011 5.99865 0V0ZM5.99865 11.2478C4.96135 11.2473 3.94748 10.9392 3.08518 10.3627C2.22288 9.7861 1.55085 8.96685 1.15401 8.00846C0.75718 7.05006 0.653353 5.99554 0.855656 4.97815C1.05796 3.96077 1.55731 3.02618 2.29061 2.29251C3.0239 1.55884 3.95823 1.059 4.97551 0.856176C5.99279 0.653349 7.04737 0.756633 8.00597 1.15297C8.96457 1.54931 9.78416 2.22092 10.3612 3.08293C10.9382 3.94493 11.2467 4.95864 11.2478 5.99594C11.2478 7.38835 10.6949 8.72377 9.71053 9.70861C8.7262 10.6934 7.39106 11.2471 5.99865 11.2478V11.2478Z' fill='%2306577C'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M6.22736 8.84695C6.30613 8.76818 6.35038 8.66135 6.35038 8.54996V5.30996C6.35038 5.19857 6.30613 5.09174 6.22736 5.01298C6.1486 4.93421 6.04177 4.88996 5.93038 4.88996C5.81899 4.88996 5.71216 4.93421 5.63339 5.01298C5.55463 5.09174 5.51038 5.19857 5.51038 5.30996V8.54996C5.51038 8.66135 5.55463 8.76818 5.63339 8.84695C5.71216 8.92571 5.81899 8.96996 5.93038 8.96996C6.04177 8.96996 6.1486 8.92571 6.22736 8.84695ZM5.69704 3.97918C5.76611 4.02533 5.84731 4.04996 5.93038 4.04996C5.98558 4.05012 6.04026 4.03936 6.09129 4.01831C6.14232 3.99726 6.18868 3.96633 6.22771 3.9273C6.26675 3.88827 6.29768 3.8419 6.31873 3.79088C6.33978 3.73985 6.35053 3.68516 6.35038 3.62996C6.35038 3.54689 6.32574 3.46569 6.27959 3.39662C6.23344 3.32755 6.16785 3.27372 6.0911 3.24193C6.01436 3.21014 5.92991 3.20183 5.84844 3.21803C5.76697 3.23424 5.69213 3.27424 5.63339 3.33298C5.57465 3.39171 5.53465 3.46655 5.51845 3.54802C5.50224 3.6295 5.51056 3.71394 5.54235 3.79069C5.57414 3.86743 5.62797 3.93303 5.69704 3.97918Z' fill='%2306577C'/%3E%3C/g%3E%3Cdefs%3E%3CclipPath id='clip0_13957_112512'%3E%3Crect width='12' height='12' fill='white'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A";
$svg-drop-off-alert: "data:image/svg+xml,%3Csvg viewBox='0 0 12 12' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0_13957_112512)'%3E%3Cpath d='M5.99865 0C4.81147 4.82643e-07 3.65095 0.352111 2.66392 1.01179C1.67688 1.67146 0.907678 2.60907 0.45361 3.70599C-0.000459241 4.80291 -0.11899 6.00986 0.113013 7.17415C0.345015 8.33845 0.917126 9.40778 1.75697 10.2469C2.59682 11.086 3.66666 11.6571 4.83117 11.8881C5.99567 12.119 7.20251 11.9994 8.29902 11.5443C9.39553 11.0893 10.3324 10.3192 10.9912 9.33159C11.65 8.34396 12.0011 7.18313 12 5.99594C11.9971 4.40566 11.3638 2.88142 10.2388 1.75742C9.11375 0.633431 7.58894 0.00143011 5.99865 0V0ZM5.99865 11.2478C4.96135 11.2473 3.94748 10.9392 3.08518 10.3627C2.22288 9.7861 1.55085 8.96685 1.15401 8.00846C0.75718 7.05006 0.653353 5.99554 0.855656 4.97815C1.05796 3.96077 1.55731 3.02618 2.29061 2.29251C3.0239 1.55884 3.95823 1.059 4.97551 0.856176C5.99279 0.653349 7.04737 0.756633 8.00597 1.15297C8.96457 1.54931 9.78416 2.22092 10.3612 3.08293C10.9382 3.94493 11.2467 4.95864 11.2478 5.99594C11.2478 7.38835 10.6949 8.72377 9.71053 9.70861C8.7262 10.6934 7.39106 11.2471 5.99865 11.2478V11.2478Z' fill='%2306577C'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M6.22736 8.84695C6.30613 8.76818 6.35038 8.66135 6.35038 8.54996V5.30996C6.35038 5.19857 6.30613 5.09174 6.22736 5.01298C6.1486 4.93421 6.04177 4.88996 5.93038 4.88996C5.81899 4.88996 5.71216 4.93421 5.63339 5.01298C5.55463 5.09174 5.51038 5.19857 5.51038 5.30996V8.54996C5.51038 8.66135 5.55463 8.76818 5.63339 8.84695C5.71216 8.92571 5.81899 8.96996 5.93038 8.96996C6.04177 8.96996 6.1486 8.92571 6.22736 8.84695ZM5.69704 3.97918C5.76611 4.02533 5.84731 4.04996 5.93038 4.04996C5.98558 4.05012 6.04026 4.03936 6.09129 4.01831C6.14232 3.99726 6.18868 3.96633 6.22771 3.9273C6.26675 3.88827 6.29768 3.8419 6.31873 3.79088C6.33978 3.73985 6.35053 3.68516 6.35038 3.62996C6.35038 3.54689 6.32574 3.46569 6.27959 3.39662C6.23344 3.32755 6.16785 3.27372 6.0911 3.24193C6.01436 3.21014 5.92991 3.20183 5.84844 3.21803C5.76697 3.23424 5.69213 3.27424 5.63339 3.33298C5.57465 3.39171 5.53465 3.46655 5.51845 3.54802C5.50224 3.6295 5.51056 3.71394 5.54235 3.79069C5.57414 3.86743 5.62797 3.93303 5.69704 3.97918Z' fill='%2306577C'/%3E%3C/g%3E%3Cdefs%3E%3CclipPath id='clip0_13957_112512'%3E%3Crect width='12' height='12' fill='white'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A";
$svg-update-zip-text-link: "data:image/svg+xml,%3Csvg viewBox='0 0 13 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.49635 1.00142e-07C5.64734 -0.000153295 4.80722 0.175918 4.0274 0.517444C3.24757 0.858969 2.54443 1.35877 1.96099 1.98626C0.765713 3.27588 0.0999756 4.98141 0.0999756 6.75394C0.0999756 8.52646 0.765713 10.232 1.96099 11.5216L5.98324 15.777C6.04954 15.8475 6.12918 15.9036 6.21736 15.9419C6.30555 15.9802 6.40045 16 6.49635 16C6.59225 16 6.68716 15.9802 6.77534 15.9419C6.86353 15.9036 6.94317 15.8475 7.00946 15.777L11.0317 11.52C12.2391 10.2383 12.909 8.52914 12.8999 6.75394C12.9094 4.97818 12.2394 3.26832 11.0317 1.98626C10.4481 1.35899 9.74493 0.859347 8.96514 0.517839C8.18535 0.176331 7.34532 0.000130509 6.49635 1.00142e-07V1.00142e-07ZM6.49635 9.13131C6.02507 9.13131 5.56437 8.98913 5.17251 8.72275C4.78065 8.45637 4.47524 8.07776 4.29488 7.63479C4.11453 7.19181 4.06734 6.70438 4.15928 6.23412C4.25123 5.76387 4.47817 5.33191 4.81142 4.99287C5.14467 4.65384 5.56925 4.42295 6.03148 4.32941C6.49371 4.23587 6.97282 4.28388 7.40823 4.46736C7.84364 4.65085 8.21579 4.96157 8.47762 5.36023C8.73945 5.7589 8.87921 6.2276 8.87921 6.70707C8.87921 7.34974 8.62837 7.96611 8.18185 8.4207C7.73532 8.87528 7.12964 9.13088 6.49794 9.13131H6.49635Z' fill='%231574A1'/%3E%3C/svg%3E%0A";