diff --git a/src/constants/schedule-constants.js b/src/constants/schedule-constants.js
index af0c6206..7737bbb5 100644
--- a/src/constants/schedule-constants.js
+++ b/src/constants/schedule-constants.js
@@ -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';
diff --git a/src/digital-components/date-picker/date-picker.vue b/src/digital-components/date-picker/date-picker.vue
index b57dcdc1..f30f9b7d 100644
--- a/src/digital-components/date-picker/date-picker.vue
+++ b/src/digital-components/date-picker/date-picker.vue
@@ -669,7 +669,6 @@ export default {
}
},
async updateSelectableDates(monthStart, monthEnd) {
- console.log(this.mainStore);
const moreSelectableDates = await this.customSelectableDatesCallback(
monthStart,
monthEnd,
diff --git a/src/layouts/policy-endorsements/policy-endorsements.spec.js b/src/layouts/policy-endorsements/policy-endorsements.spec.js
index 86b8fa73..c01818f5 100644
--- a/src/layouts/policy-endorsements/policy-endorsements.spec.js
+++ b/src/layouts/policy-endorsements/policy-endorsements.spec.js
@@ -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());
diff --git a/src/layouts/policy-endorsements/policy-endorsements.vue b/src/layouts/policy-endorsements/policy-endorsements.vue
index 22154818..1d4e1972 100644
--- a/src/layouts/policy-endorsements/policy-endorsements.vue
+++ b/src/layouts/policy-endorsements/policy-endorsements.vue
@@ -16,6 +16,7 @@
cmsWidgetName="SiteSubHeaderWidget"
class="mt-5" />
{
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);
diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue
index 8e08bd97..8ea67941 100644
--- a/src/layouts/policy-vehicles/policy-vehicles.vue
+++ b/src/layouts/policy-vehicles/policy-vehicles.vue
@@ -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;
@@ -117,16 +117,16 @@ export default {
? vehicle?.coverages[0].deductible
: 0;
},
- selectedVehicleHasEndorsements() {
- const vehicle = this.policyVehicles.find((policyVehicle) =>
+ endorsementsForSelectedVehicle() {
+ const vehicle = this.policyVehicles?.find((policyVehicle) =>
policyVehicle?.vin === this.selectedVehicleVin);
- if (!vehicle) {
- return false;
+ if (vehicle?.endorsements?.length > 0) {
+ return vehicle.endorsements;
}
- return vehicle.endorsements?.length > 0;
+ 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;
},
@@ -161,7 +161,7 @@ export default {
},
beforeMount() {
if (this.policyVehicles?.length === 1) {
- this.selectedVehicleVin = this.policyVehicles[0].vin;
+ this.selectedVehicleVin = this.policyVehicles[0]?.vin;
}
},
methods:
@@ -182,7 +182,8 @@ export default {
vin: this.selectedVehicleVin,
noCoverage: this.noCoverageForSelectedVehicle,
deductible: this.deductibleForSelectedVehicle,
- repairWaived: this.repairWaivedForSelectedVehicle
+ repairWaived: this.repairWaivedForSelectedVehicle,
+ endorsements: this.endorsementsForSelectedVehicle
});
useMainStore().updateVehicle(this.vehicleFromLookup);
@@ -205,7 +206,7 @@ export default {
{},
{}
);
- } else if (this.selectedVehicleHasEndorsements) {
+ } else if (this.endorsementsForSelectedVehicle?.length > 0) {
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD_WITH_ENDORSEMENTS,
this.$route
diff --git a/src/layouts/schedule-page/schedule-page.vue b/src/layouts/schedule-page/schedule-page.vue
index 27dd855a..10718c95 100644
--- a/src/layouts/schedule-page/schedule-page.vue
+++ b/src/layouts/schedule-page/schedule-page.vue
@@ -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 supportingItems = useMainStore().lineItems.supportingItems !== null;
const damageInfo =
diff --git a/src/layouts/schedule-page/time-slot-modal-question/time-slot-modal-question.vue b/src/layouts/schedule-page/time-slot-modal-question/time-slot-modal-question.vue
index d671bb1b..d482f9f4 100644
--- a/src/layouts/schedule-page/time-slot-modal-question/time-slot-modal-question.vue
+++ b/src/layouts/schedule-page/time-slot-modal-question/time-slot-modal-question.vue
@@ -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);
diff --git a/src/layouts/service-location/appointment-type-question/appointment-type-question.vue b/src/layouts/service-location/appointment-type-question/appointment-type-question.vue
index dc7dadb2..19dae4e5 100644
--- a/src/layouts/service-location/appointment-type-question/appointment-type-question.vue
+++ b/src/layouts/service-location/appointment-type-question/appointment-type-question.vue
@@ -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;
}
}
}
diff --git a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue
index 3829dd76..f9ea85b2 100644
--- a/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue
+++ b/src/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue
@@ -31,7 +31,7 @@
@@ -43,13 +43,14 @@
:onModalOpenedCallback="onModalOpened"
:onModalClosedCallback="onModalClosed"
@isModalOpened="setModalStatus"
- @footer-button-event="setMobileLocation">
+ @footerButtonEvent="setMobileLocation">
+ preserveCityAndStateOnReset="true"
+ includeStreetAddress2="true" />
({
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 {