Merge pull request #381 from Safelite/refactor/linting6
Linting for first 10 layouts
This commit is contained in:
commit
8c39458d91
23 changed files with 1268 additions and 1400 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
// Components
|
// Components
|
||||||
import addressLookup from '@/layouts/address-lookup/address-lookup.vue';
|
import addressLookup from '@/layouts/address-lookup/address-lookup';
|
||||||
|
|
||||||
// Supporting Files
|
// Supporting Files
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
||||||
|
|
@ -18,6 +18,79 @@ jest.mock('@/helpers/layout-helper.js', () => ({
|
||||||
settleAllPromises: jest.fn()
|
settleAllPromises: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function setupMocks({
|
||||||
|
lookupVinbyAddressResponse,
|
||||||
|
partsOrQuestions = [],
|
||||||
|
isStatePermissible = true,
|
||||||
|
vinVehicles = [],
|
||||||
|
carId = 'C0000',
|
||||||
|
route = null
|
||||||
|
}) {
|
||||||
|
useMainStore().lookupVinByAddress = jest.fn().mockImplementation(() => Promise.resolve({
|
||||||
|
data: lookupVinbyAddressResponse || {
|
||||||
|
isStatePermissible: true,
|
||||||
|
vinVehicles: [
|
||||||
|
{
|
||||||
|
vin: 'TEST_VIN',
|
||||||
|
vehicle: {
|
||||||
|
carId: 'CARID'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
useMainStore().getPartsOrQuestions = jest.fn().mockImplementation(() => Promise.resolve({
|
||||||
|
data: {
|
||||||
|
partsOrQuestions
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const wrapper = shallowMount(addressLookup,
|
||||||
|
getMountOptions({
|
||||||
|
route: route || undefined,
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn()
|
||||||
|
},
|
||||||
|
mainStore: {
|
||||||
|
order: {
|
||||||
|
vehicle: {
|
||||||
|
carId,
|
||||||
|
registration: {
|
||||||
|
licensePlate: 'TESTPLATE',
|
||||||
|
zipCode: '12345'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
customer: {
|
||||||
|
emailAddress: 'test@test.com'
|
||||||
|
},
|
||||||
|
serviceLocation: {
|
||||||
|
zipCode: '11111'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
const apiResponses = {
|
||||||
|
vinLookupResponse: {
|
||||||
|
isStatePermissible,
|
||||||
|
vinVehicles
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
settleAllPromises.mockImplementation(() => apiResponses);
|
||||||
|
|
||||||
|
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
|
||||||
|
wrapper.vm.setCmsContent = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.enableForwardAction = jest.fn();
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
describe('address-lookup.vue', () => {
|
describe('address-lookup.vue', () => {
|
||||||
describe('page level alerts', () => {
|
describe('page level alerts', () => {
|
||||||
test('if the address matches a different vehicle display the Matched Different VehicleAlert', async () => {
|
test('if the address matches a different vehicle display the Matched Different VehicleAlert', async () => {
|
||||||
|
|
@ -51,9 +124,7 @@ describe('address-lookup.vue', () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.findComponent({ ref: 'alertMatchedDifferentVehicle' }).isVisible()).toBe(
|
expect(wrapper.findComponent({ ref: 'alertMatchedDifferentVehicle' }).isVisible()).toBe(true);
|
||||||
true
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('if the address matches two identical YMM vehicles, then display Two Identical YMM Vehicle alert', async () => {
|
test('if the address matches two identical YMM vehicles, then display Two Identical YMM Vehicle alert', async () => {
|
||||||
|
|
@ -88,9 +159,7 @@ describe('address-lookup.vue', () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.findComponent({ ref: 'alertMatchedTwoIdenticalYMMVehicle' }).isVisible()).toBe(
|
expect(wrapper.findComponent({ ref: 'alertMatchedTwoIdenticalYMMVehicle' }).isVisible()).toBe(true);
|
||||||
true
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('if the looking up VIN by address is not allowed in the state selected display the Vin Lookup By HomeAddress Not Allowed Alert', async () => {
|
test('if the looking up VIN by address is not allowed in the state selected display the Vin Lookup By HomeAddress Not Allowed Alert', async () => {
|
||||||
|
|
@ -135,9 +204,7 @@ describe('address-lookup.vue', () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(
|
expect(wrapper.findComponent({ ref: 'alertVinLookupsByHomeAddressNotAllowed' }).isVisible()).toBe(true);
|
||||||
wrapper.findComponent({ ref: 'alertVinLookupsByHomeAddressNotAllowed' }).isVisible()
|
|
||||||
).toBe(true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('if no vehicles found, display Vin Not Found alert', async () => {
|
test('if no vehicles found, display Vin Not Found alert', async () => {
|
||||||
|
|
@ -278,13 +345,11 @@ describe('address-lookup.vue', () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES,
|
||||||
navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES,
|
|
||||||
undefined,
|
undefined,
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
carsFound
|
carsFound);
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('if a different vehicle is found than the one entered and the selected glass is not available for that vehicle, navigate back to vehicle-damage page', async () => {
|
test('if a different vehicle is found than the one entered and the selected glass is not available for that vehicle, navigate back to vehicle-damage page', async () => {
|
||||||
|
|
@ -310,7 +375,7 @@ describe('address-lookup.vue', () => {
|
||||||
|
|
||||||
useMainStore().order.vehicle.carId = 'CARID';
|
useMainStore().order.vehicle.carId = 'CARID';
|
||||||
|
|
||||||
let carsFound = [
|
const carsFound = [
|
||||||
{
|
{
|
||||||
vin: 'TEST_VIN2',
|
vin: 'TEST_VIN2',
|
||||||
vehicle: {
|
vehicle: {
|
||||||
|
|
@ -323,12 +388,10 @@ describe('address-lookup.vue', () => {
|
||||||
await wrapper.vm.navigateForward(carsFound);
|
await wrapper.vm.navigateForward(carsFound);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||||
navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
|
||||||
undefined,
|
undefined,
|
||||||
{},
|
{},
|
||||||
{ displayVehicleChangeAlert: true }
|
{ displayVehicleChangeAlert: true });
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('single car was found and matches entered vehicle => navigateForwardWithSingleCarMatch', async () => {
|
test('single car was found and matches entered vehicle => navigateForwardWithSingleCarMatch', async () => {
|
||||||
|
|
@ -391,84 +454,3 @@ describe('address-lookup.vue', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
lookupVinbyAddressResponse,
|
|
||||||
partsOrQuestions = [],
|
|
||||||
isStatePermissible = true,
|
|
||||||
vinVehicles = [],
|
|
||||||
carId = 'C0000',
|
|
||||||
route = null
|
|
||||||
}) {
|
|
||||||
useMainStore().lookupVinByAddress = jest.fn().mockImplementation(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
data: lookupVinbyAddressResponse
|
|
||||||
? lookupVinbyAddressResponse
|
|
||||||
: {
|
|
||||||
isStatePermissible: true,
|
|
||||||
vinVehicles: [
|
|
||||||
{
|
|
||||||
vin: 'TEST_VIN',
|
|
||||||
vehicle: {
|
|
||||||
carId: 'CARID'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
useMainStore().getPartsOrQuestions = jest.fn().mockImplementation(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
data: {
|
|
||||||
partsOrQuestions: partsOrQuestions
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const wrapper = shallowMount(
|
|
||||||
addressLookup,
|
|
||||||
getMountOptions({
|
|
||||||
route: route ? route : undefined,
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn()
|
|
||||||
},
|
|
||||||
mainStore: {
|
|
||||||
order: {
|
|
||||||
vehicle: {
|
|
||||||
carId: carId,
|
|
||||||
registration: {
|
|
||||||
licensePlate: 'TESTPLATE',
|
|
||||||
zipCode: '12345'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
customer: {
|
|
||||||
emailAddress: 'test@test.com'
|
|
||||||
},
|
|
||||||
serviceLocation: {
|
|
||||||
zipCode: '11111'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const apiResponses = {
|
|
||||||
vinLookupResponse: {
|
|
||||||
isStatePermissible: isStatePermissible,
|
|
||||||
vinVehicles: vinVehicles
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiResponses);
|
|
||||||
|
|
||||||
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
|
|
||||||
wrapper.vm.setCmsContent = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.enableForwardAction = jest.fn();
|
|
||||||
|
|
||||||
return { wrapper };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" >
|
<Form
|
||||||
|
ref="theForm"
|
||||||
|
v-slot="{ meta }"
|
||||||
|
@submit="onSubmit"
|
||||||
|
@invalid-submit="onInvalidSubmit">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
<div class="fade-on-route-transition position-relative">
|
<div class="fade-on-route-transition position-relative">
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
|
|
@ -9,51 +13,56 @@
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="select-car-form rounded">
|
<div class="select-car-form rounded">
|
||||||
<vehicleBanner
|
<vehicleBanner
|
||||||
class="mt-2 mb-4"
|
ref="vehicleBanner"
|
||||||
cmsWidgetName="VehicleBannerWidget"
|
class="mt-2 mb-4"
|
||||||
ref="vehicleBanner"
|
cmsWidgetName="VehicleBannerWidget"
|
||||||
:displayGenericVehicleImage="false" />
|
:displayGenericVehicleImage="false" />
|
||||||
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" ref="siteSubHeader" class="mb-5" />
|
<siteSubHeader
|
||||||
|
ref="siteSubHeader"
|
||||||
|
cmsWidgetName="SiteSubHeaderWidget"
|
||||||
|
class="mb-5" />
|
||||||
<alert
|
<alert
|
||||||
ref="alertVinNotFound"
|
v-if="displayVinNotFoundAlert"
|
||||||
v-if="displayVinNotFoundAlert"
|
ref="alertVinNotFound"
|
||||||
class="mb-4 mt-4"
|
class="mb-4 mt-4"
|
||||||
cmsWidgetName="AlertVinNotFoundWidget"
|
cmsWidgetName="AlertVinNotFoundWidget"
|
||||||
alertClass="alert-danger"
|
alertClass="alert-danger"
|
||||||
v-bind:isDismissible="false" />
|
:isDismissible="false" />
|
||||||
<alert
|
<alert
|
||||||
ref="alertMatchedDifferentVehicle"
|
v-if="displayMatchedDifferentVehicleAlert"
|
||||||
v-if="displayMatchedDifferentVehicleAlert"
|
ref="alertMatchedDifferentVehicle"
|
||||||
class="mb-4 mt-4"
|
class="mb-4 mt-4"
|
||||||
:manualHeadline="AlertMatchedDifferentVehicleHeader"
|
:manualHeadline="AlertMatchedDifferentVehicleHeader"
|
||||||
:manualCopy="AlertMatchedDifferentVehicleBody"
|
:manualCopy="AlertMatchedDifferentVehicleBody"
|
||||||
alertClass="alert-warning"
|
alertClass="alert-warning"
|
||||||
v-bind:isDismissible="false" />
|
:isDismissible="false" />
|
||||||
<alert
|
<alert
|
||||||
ref="alertMatchedTwoIdenticalYMMVehicle"
|
v-if="displayMatchedTwoIdenticalYMMVehicleAlert"
|
||||||
v-if="displayMatchedTwoIdenticalYMMVehicleAlert"
|
ref="alertMatchedTwoIdenticalYMMVehicle"
|
||||||
class="mb-4 mt-4"
|
class="mb-4 mt-4"
|
||||||
cmsWidgetName="AlertMatchedTwoIdenticalYMMVehicleWidget"
|
cmsWidgetName="AlertMatchedTwoIdenticalYMMVehicleWidget"
|
||||||
:manualHeadline="AlertMatchedTwoIdenticalYMMVehicleHeader"
|
:manualHeadline="AlertMatchedTwoIdenticalYMMVehicleHeader"
|
||||||
:manualCopy="AlertMatchedTwoIdenticalYMMVehicleBody"
|
:manualCopy="AlertMatchedTwoIdenticalYMMVehicleBody"
|
||||||
alertClass="alert-warning"
|
alertClass="alert-warning"
|
||||||
v-bind:isDismissible="false" />
|
:isDismissible="false" />
|
||||||
<alert
|
<alert
|
||||||
ref="alertVinLookupsByHomeAddressNotAllowed"
|
v-if="displayVinLookupByHomeAddressNotAllowedAlert"
|
||||||
v-if="displayVinLookupByHomeAddressNotAllowedAlert"
|
ref="alertVinLookupsByHomeAddressNotAllowed"
|
||||||
class="mt-4"
|
class="mt-4"
|
||||||
cmsWidgetName="AlertVinLookupsByHomeAddressNotAllowedWidget"
|
cmsWidgetName="AlertVinLookupsByHomeAddressNotAllowedWidget"
|
||||||
alertClass="alert-danger"
|
alertClass="alert-danger"
|
||||||
v-bind:isDismissible="false" />
|
:isDismissible="false" />
|
||||||
<customerQuestions ref="customerQuestions" v-model="customerQuestions" />
|
<customerQuestions
|
||||||
|
ref="customerQuestions"
|
||||||
|
v-model="customerQuestions" />
|
||||||
<siteFooter
|
<siteFooter
|
||||||
class="mt-5"
|
ref="siteFooter"
|
||||||
cmsWidgetName="SiteFooterWidget"
|
class="mt-5"
|
||||||
ref="siteFooter"
|
cmsWidgetName="SiteFooterWidget"
|
||||||
:isDisabled="!meta.valid"
|
:isDisabled="!meta.valid"
|
||||||
@ForwardClicked="forwardButtonAction"
|
:isForwardActionDisabled="!meta.valid"
|
||||||
@back-clicked="backButtonAction"
|
@ForwardClicked="forwardButtonAction"
|
||||||
:isForwardActionDisabled="!meta.valid" />
|
@back-clicked="backButtonAction" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -67,7 +76,7 @@
|
||||||
<script>
|
<script>
|
||||||
// Components
|
// Components
|
||||||
import baseFormMixin from '@/mixins/base-form-mixin';
|
import baseFormMixin from '@/mixins/base-form-mixin';
|
||||||
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
import siteHeader from '@/iss-components/site-header/site-header';
|
||||||
import siteFooter from '@/iss-components/site-footer/site-footer';
|
import siteFooter from '@/iss-components/site-footer/site-footer';
|
||||||
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner';
|
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner';
|
||||||
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header';
|
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header';
|
||||||
|
|
@ -84,10 +93,21 @@ import { routerParams } from '@/router/router-constants/router-params';
|
||||||
import { getDamageString, isGlassAvailableForCarId } from '@/helpers/damage-helper';
|
import { getDamageString, isGlassAvailableForCarId } from '@/helpers/damage-helper';
|
||||||
|
|
||||||
import vinPagesMixin from '@/mixins/vin-pages-mixin';
|
import vinPagesMixin from '@/mixins/vin-pages-mixin';
|
||||||
import { useMainStore } from '@/store'
|
import { useMainStore } from '@/store';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'address-lookup',
|
name: 'address-lookup',
|
||||||
|
components: {
|
||||||
|
siteHeader,
|
||||||
|
siteFooter,
|
||||||
|
vehicleBanner,
|
||||||
|
siteSubHeader,
|
||||||
|
customerQuestions,
|
||||||
|
textboxQuestion,
|
||||||
|
alert,
|
||||||
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
|
Form
|
||||||
|
},
|
||||||
mixins: [baseFormMixin, vinPagesMixin],
|
mixins: [baseFormMixin, vinPagesMixin],
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
// Call APIs
|
// Call APIs
|
||||||
|
|
@ -122,6 +142,52 @@ export default {
|
||||||
forwardButtonCarStyle: ''
|
forwardButtonCarStyle: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
AlertMatchedDifferentVehicleHeader() {
|
||||||
|
return this.getCmsContent('AlertMatchedDifferentVehicleWidget',
|
||||||
|
'HeadlineText').replaceAll('{custom:damage}', getDamageString());
|
||||||
|
},
|
||||||
|
AlertMatchedDifferentVehicleBody() {
|
||||||
|
const vinYmmFound = `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
|
||||||
|
const vinYmmExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
||||||
|
|
||||||
|
return this.getCmsContent('AlertMatchedDifferentVehicleWidget', 'BodyText')
|
||||||
|
.replaceAll('{custom:damage}', getDamageString())
|
||||||
|
.replaceAll('{custom:vinYmmFound}', vinYmmFound)
|
||||||
|
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
|
||||||
|
},
|
||||||
|
AlertMatchedTwoIdenticalYMMVehicleHeader() {
|
||||||
|
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget',
|
||||||
|
'HeadlineText').replaceAll('{custom:damage}', getDamageString());
|
||||||
|
},
|
||||||
|
AlertMatchedTwoIdenticalYMMVehicleBody() {
|
||||||
|
const vinYmmsFound = `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model} ${this.customAlertData?.vehicleInfo?.style}`;
|
||||||
|
const vinYmmsExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model} ${this.mainStore.order.vehicle.style}`;
|
||||||
|
|
||||||
|
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget', 'BodyText')
|
||||||
|
.replaceAll('{custom:damage}', getDamageString())
|
||||||
|
.replaceAll('{custom:vinYmmsFound}', vinYmmsFound)
|
||||||
|
.replaceAll('{custom:vinYmmsExpected}', vinYmmsExpected);
|
||||||
|
},
|
||||||
|
isTwoIdenticalYMMVehicleFound() {
|
||||||
|
const vinYmmFound = `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
|
||||||
|
const vinYmmExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
||||||
|
return (vinYmmFound.toLowerCase() == vinYmmExpected.toLowerCase());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
customerQuestions: {
|
||||||
|
handler() {
|
||||||
|
// if they modify one of the lookup fields (address, city, state, zipCode, or lastName), then modify the button text back to "Get my personalized quote"
|
||||||
|
this.$refs.siteFooter.updateButtonText(this.getCmsContent('siteFooterWidget', 'ForwardButtonText'));
|
||||||
|
this.resetWarningsAndErrors();
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.attachCustomEvents();
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return this.mainStore.order.vehicle.carId !== null;
|
return this.mainStore.order.vehicle.carId !== null;
|
||||||
|
|
@ -133,12 +199,10 @@ export default {
|
||||||
},
|
},
|
||||||
attachCustomEvents() {
|
attachCustomEvents() {
|
||||||
this.prependActionToMethod(this, this.forwardButtonAction, () => {
|
this.prependActionToMethod(this, this.forwardButtonAction, () => {
|
||||||
this.pushEventToGA(
|
this.pushEventToGA(this.$route.query[this.queryStrings.ISS_PAGE],
|
||||||
this.$route.query[this.queryStrings.ISS_PAGE],
|
|
||||||
this.GaActions.SUBMITTED,
|
this.GaActions.SUBMITTED,
|
||||||
this.GaLabels.ADDRESS_LOOKUP,
|
this.GaLabels.ADDRESS_LOOKUP,
|
||||||
true
|
true);
|
||||||
);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -175,7 +239,7 @@ export default {
|
||||||
const carsFound = resultMap.vinLookupResponse.vinVehicles;
|
const carsFound = resultMap.vinLookupResponse.vinVehicles;
|
||||||
|
|
||||||
// Handle cases for different amounts of VINS found for the address.
|
// Handle cases for different amounts of VINS found for the address.
|
||||||
if (carsFound.length == 1) {
|
if (carsFound.length === 1) {
|
||||||
// Single VIN found
|
// Single VIN found
|
||||||
const carFound = carsFound[0].vehicle;
|
const carFound = carsFound[0].vehicle;
|
||||||
|
|
||||||
|
|
@ -186,19 +250,15 @@ export default {
|
||||||
this.customAlertData.vehicleInfo = carFound;
|
this.customAlertData.vehicleInfo = carFound;
|
||||||
if (this.isTwoIdenticalYMMVehicleFound) {
|
if (this.isTwoIdenticalYMMVehicleFound) {
|
||||||
this.displayMatchedTwoIdenticalYMMVehicleAlert = true;
|
this.displayMatchedTwoIdenticalYMMVehicleAlert = true;
|
||||||
this.forwardButtonCarStyle= carFound.style;
|
this.forwardButtonCarStyle = carFound.style;
|
||||||
} else {
|
} else {
|
||||||
this.displayMatchedDifferentVehicleAlert = true;
|
this.displayMatchedDifferentVehicleAlert = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(
|
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(carFound.carId);
|
||||||
carFound.carId
|
|
||||||
);
|
|
||||||
|
|
||||||
// Update button "Continue with..."
|
// Update button "Continue with..."
|
||||||
this.$refs.siteFooter.updateButtonText(
|
this.$refs.siteFooter.updateButtonText(`Continue with ${carFound.year} ${carFound.make} ${carFound.model} ${this.forwardButtonCarStyle}`);
|
||||||
`Continue with ${carFound.year} ${carFound.make} ${carFound.model} ${this.forwardButtonCarStyle}`
|
|
||||||
);
|
|
||||||
return this.$refs.siteFooter.removeLoader();
|
return this.$refs.siteFooter.removeLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -206,9 +266,7 @@ export default {
|
||||||
vehicleInfoToCommit = Object.assign(carFound, { vin: carsFound[0].vin });
|
vehicleInfoToCommit = Object.assign(carFound, { vin: carsFound[0].vin });
|
||||||
} else if (carsFound.length > 1) {
|
} else if (carsFound.length > 1) {
|
||||||
// If multiple cars were found and one and only one of them matches the carId entered, save the vehicle info
|
// If multiple cars were found and one and only one of them matches the carId entered, save the vehicle info
|
||||||
const matchingCars = carsFound.filter(
|
const matchingCars = carsFound.filter((vin) => vin.vehicle.carId === this.mainStore.order.vehicle.carId);
|
||||||
(vin) => vin.vehicle.carId === this.mainStore.order.vehicle.carId
|
|
||||||
);
|
|
||||||
|
|
||||||
if (matchingCars.length === 1) {
|
if (matchingCars.length === 1) {
|
||||||
vehicleInfoToCommit = Object.assign(matchingCars[0].vehicle, {
|
vehicleInfoToCommit = Object.assign(matchingCars[0].vehicle, {
|
||||||
|
|
@ -223,55 +281,47 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save vehicle, customer, service and registration information
|
// Save vehicle, customer, service and registration information
|
||||||
await useMainStore().saveRegistrationAddressLookup(
|
await useMainStore().saveRegistrationAddressLookup({
|
||||||
{
|
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
|
||||||
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
|
vehicleInfo:
|
||||||
vehicleInfo:
|
|
||||||
Object.keys(vehicleInfoToCommit).length === 0
|
Object.keys(vehicleInfoToCommit).length === 0
|
||||||
? null
|
? null
|
||||||
: vehicleInfoToCommit,
|
: vehicleInfoToCommit,
|
||||||
registrationInfo: {
|
registrationInfo: {
|
||||||
firstName: this.customerQuestions.firstName,
|
firstName: this.customerQuestions.firstName,
|
||||||
lastName: this.customerQuestions.lastName,
|
lastName: this.customerQuestions.lastName,
|
||||||
address: this.customerQuestions.addressQuestions.streetAddress,
|
address: this.customerQuestions.addressQuestions.streetAddress,
|
||||||
city: this.customerQuestions.addressQuestions.city,
|
city: this.customerQuestions.addressQuestions.city,
|
||||||
state: this.customerQuestions.addressQuestions.state,
|
state: this.customerQuestions.addressQuestions.state,
|
||||||
zipCode: this.customerQuestions.addressQuestions.zipCode
|
zipCode: this.customerQuestions.addressQuestions.zipCode
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
false
|
false);
|
||||||
);
|
|
||||||
|
|
||||||
return await this.navigateForward(carsFound);
|
return this.navigateForward(carsFound);
|
||||||
},
|
},
|
||||||
async navigateForward(carsFound) {
|
async navigateForward(carsFound) {
|
||||||
// Match vehicles found to vehicles in state.
|
// Match vehicles found to vehicles in state.
|
||||||
const matchingCars = carsFound.filter(
|
const matchingCars = carsFound.filter((car) => car.vehicle.carId === useMainStore().order.vehicle.carId);
|
||||||
(car) => car.vehicle.carId === useMainStore().order.vehicle.carId
|
|
||||||
);
|
|
||||||
|
|
||||||
// If a different vehicle is found than the one entered and the selected glass is not available for that vehicle then navigate back to "vehicle-damage"
|
// If a different vehicle is found than the one entered and the selected glass is not available for that vehicle then navigate back to "vehicle-damage"
|
||||||
// display vehicle changed alert on that page.
|
// display vehicle changed alert on that page.
|
||||||
if (
|
if (
|
||||||
this.isCarIdDifferent &&
|
this.isCarIdDifferent
|
||||||
!this.isSelectedGlassAvailableForVehicle
|
&& !this.isSelectedGlassAvailableForVehicle
|
||||||
) {
|
) {
|
||||||
this.$router.navigate(
|
this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||||
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
|
||||||
this.$route,
|
this.$route,
|
||||||
{},
|
{},
|
||||||
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
|
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true });
|
||||||
);
|
|
||||||
} else if (matchingCars.length === 1) {
|
} else if (matchingCars.length === 1) {
|
||||||
await this.navigateForwardWithSingleCarMatch();
|
await this.navigateForwardWithSingleCarMatch();
|
||||||
} else {
|
} else {
|
||||||
this.$router.navigate(
|
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES,
|
||||||
this.navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES,
|
|
||||||
this.$route,
|
this.$route,
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
carsFound
|
carsFound);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
resetWarningsAndErrors() {
|
resetWarningsAndErrors() {
|
||||||
|
|
@ -280,68 +330,6 @@ export default {
|
||||||
this.displayVinLookupByHomeAddressNotAllowedAlert = false;
|
this.displayVinLookupByHomeAddressNotAllowedAlert = false;
|
||||||
this.$refs.siteFooter.enableForwardAction();
|
this.$refs.siteFooter.enableForwardAction();
|
||||||
}
|
}
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.attachCustomEvents();
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
AlertMatchedDifferentVehicleHeader() {
|
|
||||||
return this.getCmsContent(
|
|
||||||
'AlertMatchedDifferentVehicleWidget',
|
|
||||||
'HeadlineText'
|
|
||||||
).replaceAll('{custom:damage}', getDamageString());
|
|
||||||
},
|
|
||||||
AlertMatchedDifferentVehicleBody() {
|
|
||||||
const vinYmmFound = `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
|
|
||||||
const vinYmmExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
|
||||||
|
|
||||||
return this.getCmsContent('AlertMatchedDifferentVehicleWidget', 'BodyText')
|
|
||||||
.replaceAll('{custom:damage}', getDamageString())
|
|
||||||
.replaceAll('{custom:vinYmmFound}', vinYmmFound)
|
|
||||||
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
|
|
||||||
},
|
|
||||||
AlertMatchedTwoIdenticalYMMVehicleHeader() {
|
|
||||||
return this.getCmsContent(
|
|
||||||
'AlertMatchedTwoIdenticalYMMVehicleWidget',
|
|
||||||
'HeadlineText'
|
|
||||||
).replaceAll('{custom:damage}', getDamageString());
|
|
||||||
},
|
|
||||||
AlertMatchedTwoIdenticalYMMVehicleBody() {
|
|
||||||
const vinYmmsFound = `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model} ${this.customAlertData?.vehicleInfo?.style}`;
|
|
||||||
const vinYmmsExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model} ${this.mainStore.order.vehicle.style}`;
|
|
||||||
|
|
||||||
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget', 'BodyText')
|
|
||||||
.replaceAll('{custom:damage}', getDamageString())
|
|
||||||
.replaceAll('{custom:vinYmmsFound}', vinYmmsFound)
|
|
||||||
.replaceAll('{custom:vinYmmsExpected}', vinYmmsExpected);
|
|
||||||
},
|
|
||||||
isTwoIdenticalYMMVehicleFound() {
|
|
||||||
const vinYmmFound = `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
|
|
||||||
const vinYmmExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
|
||||||
return (vinYmmFound.toLowerCase()==vinYmmExpected.toLowerCase());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
customerQuestions: {
|
|
||||||
handler(newValue) {
|
|
||||||
// if they modify one of the lookup fields (address, city, state, zipCode, or lastName), then modify the button text back to "Get my personalized quote"
|
|
||||||
this.$refs.siteFooter.updateButtonText(
|
|
||||||
this.getCmsContent('siteFooterWidget', 'ForwardButtonText')
|
|
||||||
);
|
|
||||||
this.resetWarningsAndErrors();
|
|
||||||
},
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
siteHeader,
|
|
||||||
siteFooter,
|
|
||||||
vehicleBanner,
|
|
||||||
siteSubHeader,
|
|
||||||
customerQuestions,
|
|
||||||
textboxQuestion,
|
|
||||||
alert,
|
|
||||||
Form,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,21 @@
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import customerQuestions from '@/layouts/address-lookup/customer-questions/customer-questions';
|
import customerQuestions from '@/layouts/address-lookup/customer-questions/customer-questions';
|
||||||
|
|
||||||
const customerModel = {
|
// const customerModel = {
|
||||||
addressQuestions: {
|
// addressQuestions: {
|
||||||
streetAddress: '',
|
// streetAddress: '',
|
||||||
city: '',
|
// city: '',
|
||||||
state: '',
|
// state: '',
|
||||||
zipCode: ''
|
// zipCode: ''
|
||||||
},
|
// },
|
||||||
firstName: '',
|
// firstName: '',
|
||||||
lastName: '',
|
// lastName: '',
|
||||||
emailAddress: ''
|
// emailAddress: ''
|
||||||
};
|
// };
|
||||||
|
|
||||||
describe('customerQuestions.vue', () => {
|
describe('customerQuestions.vue', () => {
|
||||||
it('Should render customerQuestions sub-components (addressQuestions, first name, last name, and email textbox-questions)', async () => {
|
it('Should render customerQuestions sub-components '
|
||||||
|
+ 'addressQuestions, first name, last name, and email textbox - questions)', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const wrapper = shallowMount(customerQuestions);
|
const wrapper = shallowMount(customerQuestions);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<addressQuestions ref="addressQuestions" v-model="customerModel.addressQuestions" />
|
<addressQuestions
|
||||||
|
ref="addressQuestions"
|
||||||
|
v-model="customerModel.addressQuestions" />
|
||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<textboxQuestion
|
<textboxQuestion
|
||||||
cmsWidgetName="FirstNameQuestionWidget"
|
|
||||||
v-model="customerModel.firstName"
|
|
||||||
ref="firstName"
|
ref="firstName"
|
||||||
|
v-model="customerModel.firstName"
|
||||||
|
cmsWidgetName="FirstNameQuestionWidget"
|
||||||
inputId="08497a2efd9a4a73a70360ab47b4838d"
|
inputId="08497a2efd9a4a73a70360ab47b4838d"
|
||||||
disableAutoFill
|
disableAutoFill
|
||||||
:validationRules="rules.firstName" />
|
:validationRules="rules.firstName" />
|
||||||
|
|
@ -14,9 +16,9 @@
|
||||||
<div class="row mb-4">
|
<div class="row mb-4">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<textboxQuestion
|
<textboxQuestion
|
||||||
cmsWidgetName="LastNameQuestionWidget"
|
|
||||||
v-model="customerModel.lastName"
|
|
||||||
ref="lastName"
|
ref="lastName"
|
||||||
|
v-model="customerModel.lastName"
|
||||||
|
cmsWidgetName="LastNameQuestionWidget"
|
||||||
inputId="0030e56a57e74a4ab92de7fb8e97fec5"
|
inputId="0030e56a57e74a4ab92de7fb8e97fec5"
|
||||||
disableAutoFill
|
disableAutoFill
|
||||||
:validationRules="rules.lastName" />
|
:validationRules="rules.lastName" />
|
||||||
|
|
@ -25,13 +27,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import addressQuestions from '@/iss-components/address-questions/address-questions.vue';
|
import addressQuestions from '@/iss-components/address-questions/address-questions';
|
||||||
import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue';
|
import textboxQuestion from '@/digital-components/textbox-question/textbox-question';
|
||||||
import globalRules from '@/constants/global-rules';
|
import globalRules from '@/constants/global-rules';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'customer-questions',
|
name: 'customer-questions',
|
||||||
emits: ['update:modelValue'], // The component emits an event
|
components: {
|
||||||
|
addressQuestions,
|
||||||
|
textboxQuestion
|
||||||
|
}, // The component emits an event
|
||||||
props: {
|
props: {
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
|
@ -50,6 +55,7 @@ export default {
|
||||||
},
|
},
|
||||||
validationRules: String
|
validationRules: String
|
||||||
},
|
},
|
||||||
|
emits: ['update:modelValue'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
rules: {
|
rules: {
|
||||||
|
|
@ -60,17 +66,13 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
customerModel: {
|
customerModel: {
|
||||||
get: function () {
|
get() {
|
||||||
return this.modelValue;
|
return this.modelValue;
|
||||||
},
|
},
|
||||||
set: function (newValue) {
|
set(newValue) {
|
||||||
this.$emit('update:modelValue', newValue);
|
this.$emit('update:modelValue', newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
components: {
|
|
||||||
addressQuestions,
|
|
||||||
textboxQuestion
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,42 @@
|
||||||
import addressVehiclesQuestion from '@/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue';
|
import addressVehiclesQuestion from '@/layouts/address-vehicles/address-vehicles-question/address-vehicles-question';
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||||
|
|
||||||
|
function setupMocks({
|
||||||
|
modelValueProp = 'TESTCAR',
|
||||||
|
cmsQuestionText = 'CMS text goes here'
|
||||||
|
}) {
|
||||||
|
const mountOptions = getMountOptions();
|
||||||
|
|
||||||
|
// Mock props
|
||||||
|
mountOptions.propsData = {
|
||||||
|
modelValue: modelValueProp
|
||||||
|
};
|
||||||
|
|
||||||
|
const wrapper = shallowMount(addressVehiclesQuestion, mountOptions);
|
||||||
|
|
||||||
|
// Mock CMS content
|
||||||
|
const cmsContent = {
|
||||||
|
QuestionText: cmsQuestionText
|
||||||
|
};
|
||||||
|
return { wrapper, cmsContent };
|
||||||
|
}
|
||||||
|
|
||||||
|
const mockMixin = {
|
||||||
|
methods: {
|
||||||
|
getCmsContent: jest.fn((contentName) => {
|
||||||
|
if (contentName === 'AlertMatchedDifferentVehicleWidget') {
|
||||||
|
return 'AlertMatchedDifferentVehicleWidgetTestReturn';
|
||||||
|
}
|
||||||
|
if (contentName === 'AlertMatchedTwoIdenticalYMMVehicleWidget') {
|
||||||
|
return 'AlertMatchedTwoIdenticalYMMVehicleWidgetTestReturn';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
vehicles: jest.fn(() => [{ vehicle: 'test' }])
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
describe('address-vehicles-question.vue', () => {
|
describe('address-vehicles-question.vue', () => {
|
||||||
test('Selected vehicle is emitted upon selection', async () => {
|
test('Selected vehicle is emitted upon selection', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|
@ -14,13 +49,13 @@ describe('address-vehicles-question.vue', () => {
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([
|
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([
|
||||||
{ selectedVehicle: '2016 Jaguar F-Type' },
|
{ selectedVehicle: '2016 Jaguar F-Type' }
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
test('Should return content for differentVehicleAlertHeader', () => {
|
test('Should return content for differentVehicleAlertHeader', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const wrapper = shallowMount(addressVehiclesQuestion, {
|
const wrapper = shallowMount(addressVehiclesQuestion, {
|
||||||
mixins: [mockMixin],
|
mixins: [mockMixin]
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
@ -62,40 +97,3 @@ describe('address-vehicles-question.vue', () => {
|
||||||
expect(wrapper.vm.AlertMatchedTwoIdenticalYMMVehicleBody).toEqual('AlertMatchedTwoIdenticalYMMVehicleWidgetTestReturn');
|
expect(wrapper.vm.AlertMatchedTwoIdenticalYMMVehicleBody).toEqual('AlertMatchedTwoIdenticalYMMVehicleWidgetTestReturn');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockMixin = {
|
|
||||||
methods: {
|
|
||||||
getCmsContent: jest.fn((contentName) => {
|
|
||||||
if (contentName === 'AlertMatchedDifferentVehicleWidget') {
|
|
||||||
return 'AlertMatchedDifferentVehicleWidgetTestReturn';
|
|
||||||
}
|
|
||||||
if (contentName === 'AlertMatchedTwoIdenticalYMMVehicleWidget') {
|
|
||||||
return 'AlertMatchedTwoIdenticalYMMVehicleWidgetTestReturn';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}),
|
|
||||||
vehicles: jest.fn(() => {
|
|
||||||
return [{ vehicle: 'test' }];
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
modelValueProp = 'TESTCAR',
|
|
||||||
cmsQuestionText = 'CMS text goes here'
|
|
||||||
}) {
|
|
||||||
const mountOptions = getMountOptions();
|
|
||||||
|
|
||||||
// Mock props
|
|
||||||
mountOptions.propsData = {
|
|
||||||
modelValue: modelValueProp
|
|
||||||
};
|
|
||||||
|
|
||||||
const wrapper = shallowMount(addressVehiclesQuestion, mountOptions);
|
|
||||||
|
|
||||||
// Mock CMS content
|
|
||||||
const cmsContent = {
|
|
||||||
QuestionText: cmsQuestionText
|
|
||||||
};
|
|
||||||
return { wrapper, cmsContent };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,36 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<alert
|
<alert
|
||||||
ref="differentVehicleAlert"
|
|
||||||
v-if="displayMatchedDifferentVehicleAlert"
|
v-if="displayMatchedDifferentVehicleAlert"
|
||||||
|
id="address-vehicles-question-alert"
|
||||||
|
ref="differentVehicleAlert"
|
||||||
class="my-4"
|
class="my-4"
|
||||||
cmsWidgetName="AlertMatchedDifferentVehicleWidget"
|
cmsWidgetName="AlertMatchedDifferentVehicleWidget"
|
||||||
:manualHeadline="differentVehicleAlertHeader"
|
:manualHeadline="differentVehicleAlertHeader"
|
||||||
:manualCopy="differentVehicleAlertBody"
|
:manualCopy="differentVehicleAlertBody"
|
||||||
alertClass="alert-warning"
|
alertClass="alert-warning"
|
||||||
v-bind:isDismissible="false"
|
:isDismissible="false" />
|
||||||
id="address-vehicles-question-alert" />
|
|
||||||
<alert
|
<alert
|
||||||
ref="alertMatchedTwoIdenticalYMMVehicle"
|
v-if="displayMatchedTwoIdenticalYMMVehicleAlert"
|
||||||
v-if="displayMatchedTwoIdenticalYMMVehicleAlert"
|
id="address-vehicles-question-alert"
|
||||||
class="my-4"
|
ref="alertMatchedTwoIdenticalYMMVehicle"
|
||||||
cmsWidgetName="AlertMatchedTwoIdenticalYMMVehicleWidget"
|
class="my-4"
|
||||||
:manualHeadline="AlertMatchedTwoIdenticalYMMVehicleHeader"
|
cmsWidgetName="AlertMatchedTwoIdenticalYMMVehicleWidget"
|
||||||
:manualCopy="AlertMatchedTwoIdenticalYMMVehicleBody"
|
:manualHeadline="AlertMatchedTwoIdenticalYMMVehicleHeader"
|
||||||
alertClass="alert-warning"
|
:manualCopy="AlertMatchedTwoIdenticalYMMVehicleBody"
|
||||||
v-bind:isDismissible="false"
|
alertClass="alert-warning"
|
||||||
id="address-vehicles-question-alert" />
|
:isDismissible="false" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<buttonQuestion
|
<buttonQuestion
|
||||||
class="address-vehicles-question"
|
|
||||||
ref="addressVehiclesQuestion"
|
ref="addressVehiclesQuestion"
|
||||||
|
v-model="selectedVehicleVin"
|
||||||
|
class="address-vehicles-question"
|
||||||
buttonTypeString="listButton"
|
buttonTypeString="listButton"
|
||||||
groupName="ChooseAddressVehicle"
|
groupName="ChooseAddressVehicle"
|
||||||
:questionText="questionText"
|
:questionText="questionText"
|
||||||
:answers="vehicles"
|
:answers="vehicles"
|
||||||
v-model="selectedVehicleVin"
|
|
||||||
isRequired
|
isRequired
|
||||||
:validation-rules="validationRules" />
|
:validationRules="validationRules" />
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -43,6 +41,10 @@ import { getDamageString } from '@/helpers/damage-helper';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'address-vehicles-question',
|
name: 'address-vehicles-question',
|
||||||
|
components: {
|
||||||
|
buttonQuestion,
|
||||||
|
alert
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
vehicles: Array,
|
vehicles: Array,
|
||||||
vehicleSelected: Object,
|
vehicleSelected: Object,
|
||||||
|
|
@ -53,12 +55,11 @@ export default {
|
||||||
displayMatchedDifferentVehicleAlert: Boolean,
|
displayMatchedDifferentVehicleAlert: Boolean,
|
||||||
displayMatchedTwoIdenticalYMMVehicleAlert: Boolean
|
displayMatchedTwoIdenticalYMMVehicleAlert: Boolean
|
||||||
},
|
},
|
||||||
|
emits: ['update: modelValue'],
|
||||||
computed: {
|
computed: {
|
||||||
differentVehicleAlertHeader() {
|
differentVehicleAlertHeader() {
|
||||||
return this.getCmsContent('AlertMatchedDifferentVehicleWidget', 'HeadlineText').replaceAll(
|
return this.getCmsContent('AlertMatchedDifferentVehicleWidget', 'HeadlineText').replaceAll('{custom:damage}',
|
||||||
'{custom:damage}',
|
getDamageString());
|
||||||
getDamageString()
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
differentVehicleAlertBody() {
|
differentVehicleAlertBody() {
|
||||||
const vinYmmFound = `${this.selectedVehicle?.vehicle.year} ${this.selectedVehicle?.vehicle.make} ${this.selectedVehicle?.vehicle.model}`;
|
const vinYmmFound = `${this.selectedVehicle?.vehicle.year} ${this.selectedVehicle?.vehicle.make} ${this.selectedVehicle?.vehicle.model}`;
|
||||||
|
|
@ -70,10 +71,8 @@ export default {
|
||||||
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
|
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
|
||||||
},
|
},
|
||||||
AlertMatchedTwoIdenticalYMMVehicleHeader() {
|
AlertMatchedTwoIdenticalYMMVehicleHeader() {
|
||||||
return this.getCmsContent(
|
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget',
|
||||||
'AlertMatchedTwoIdenticalYMMVehicleWidget',
|
'HeadlineText').replaceAll('{custom:damage}', getDamageString());
|
||||||
'HeadlineText'
|
|
||||||
).replaceAll('{custom:damage}', getDamageString());
|
|
||||||
},
|
},
|
||||||
AlertMatchedTwoIdenticalYMMVehicleBody() {
|
AlertMatchedTwoIdenticalYMMVehicleBody() {
|
||||||
const vinYmmsFound = `${this.selectedVehicle?.vehicle.year} ${this.selectedVehicle?.vehicle.make} ${this.selectedVehicle?.vehicle.model} ${this.selectedVehicle?.vehicle.style}`;
|
const vinYmmsFound = `${this.selectedVehicle?.vehicle.year} ${this.selectedVehicle?.vehicle.make} ${this.selectedVehicle?.vehicle.model} ${this.selectedVehicle?.vehicle.style}`;
|
||||||
|
|
@ -88,10 +87,10 @@ export default {
|
||||||
return this.getCmsContent('VehicleConfirmationQuestion', 'QuestionText');
|
return this.getCmsContent('VehicleConfirmationQuestion', 'QuestionText');
|
||||||
},
|
},
|
||||||
selectedVehicleVin: {
|
selectedVehicleVin: {
|
||||||
get: function () {
|
get() {
|
||||||
return this.modelValue;
|
return this.modelValue;
|
||||||
},
|
},
|
||||||
set: function (newValue) {
|
set(newValue) {
|
||||||
this.$emit('update:modelValue', newValue);
|
this.$emit('update:modelValue', newValue);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -99,17 +98,13 @@ export default {
|
||||||
// this computed is only needed for the computed differentVehicleAlertBody text above
|
// this computed is only needed for the computed differentVehicleAlertBody text above
|
||||||
return this.vehicles.find(({ vin }) => vin === this.selectedVehicleVin);
|
return this.vehicles.find(({ vin }) => vin === this.selectedVehicleVin);
|
||||||
},
|
},
|
||||||
vehicleSelected(){
|
vehicleSelected() {
|
||||||
return this.vehicleSelected;
|
return this.vehicleSelected;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
components: {
|
|
||||||
buttonQuestion,
|
|
||||||
alert
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.address-vehicles-question {
|
.address-vehicles-question {
|
||||||
.question-text {
|
.question-text {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,104 @@ jest.mock('@/helpers/layout-helper.js', () => ({
|
||||||
settleAllPromises: jest.fn()
|
settleAllPromises: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function setupMocks({
|
||||||
|
route = null,
|
||||||
|
lookupVehicleByVinResponse
|
||||||
|
}) {
|
||||||
|
useMainStore().applicationUser = {
|
||||||
|
pageData: {
|
||||||
|
'address-vehicles':
|
||||||
|
[
|
||||||
|
{
|
||||||
|
vehicle: {
|
||||||
|
carId: 'CR00069309',
|
||||||
|
category: 'SUV',
|
||||||
|
imageUrl:
|
||||||
|
'https://dbhdyzvm8lm25.cloudfront.net/color_0320_032/MY2020/13769/13769_cc0320_032_WW8.jpg',
|
||||||
|
imageVifColor: 'white',
|
||||||
|
imageVifNumber: '13769',
|
||||||
|
make: 'Hyundai',
|
||||||
|
model: 'Santa Fe',
|
||||||
|
style: '4 door utility',
|
||||||
|
year: 2020
|
||||||
|
},
|
||||||
|
vin: '5NMS3CADXLH233004'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useMainStore().lookupVehicleByVin = jest.fn().mockImplementation(() => Promise.resolve({
|
||||||
|
data: lookupVehicleByVinResponse || {
|
||||||
|
vehicle: {
|
||||||
|
carId: 'CARID'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const mountOptions = getMountOptions({
|
||||||
|
route: route || undefined,
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn()
|
||||||
|
},
|
||||||
|
mainStore: {
|
||||||
|
order: {
|
||||||
|
vehicle: {
|
||||||
|
carId: 'CR00069309',
|
||||||
|
category: 'SUV',
|
||||||
|
imageUrl:
|
||||||
|
'https://dbhdyzvm8lm25.cloudfront.net/color_0320_032/MY2020/13769/13769_cc0320_032_WW8.jpg',
|
||||||
|
imageVifColor: 'white',
|
||||||
|
imageVifNumber: '13769',
|
||||||
|
make: 'Hyundai',
|
||||||
|
model: 'Santa Fe',
|
||||||
|
style: '4 door utility',
|
||||||
|
year: 2020
|
||||||
|
},
|
||||||
|
vin: '5NMS3CADXLH233004'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const apiResponses = {
|
||||||
|
cmsContent: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
settleAllPromises.mockImplementation(() => apiResponses);
|
||||||
|
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
||||||
|
|
||||||
|
// Mock props
|
||||||
|
const mockMixin = {
|
||||||
|
methods: {
|
||||||
|
getCmsContent: jest.fn((contentName) => {
|
||||||
|
if (contentName === 'FoundMultipleVehicles') {
|
||||||
|
return 'FoundMultipleVehiclesTestReturn';
|
||||||
|
}
|
||||||
|
if (contentName === 'ProvideVinAlert') {
|
||||||
|
return 'ProvideVinAlertTestReturn';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
dynamicStrings() {
|
||||||
|
return { ROUTER_LINK: 'routerLink:' };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mountOptions.mixins = [mockMixin];
|
||||||
|
|
||||||
|
const wrapper = shallowMount(addressVehicles, mountOptions);
|
||||||
|
|
||||||
|
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
|
||||||
|
wrapper.vm.setCmsContent = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
describe('address-vehicles.vue', () => {
|
describe('address-vehicles.vue', () => {
|
||||||
test('Should navigate to CLICKED_BACK if backButtonAction is run', async () => {
|
test('Should navigate to CLICKED_BACK if backButtonAction is run', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|
@ -132,118 +230,14 @@ describe('address-vehicles.vue', () => {
|
||||||
useMainStore().order.vehicle.carId = 'CR00000395';
|
useMainStore().order.vehicle.carId = 'CR00000395';
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
addressVehicles.beforeRouteEnter.call(
|
addressVehicles.beforeRouteEnter.call(wrapper.vm,
|
||||||
wrapper.vm,
|
|
||||||
{ query: { issPage: 'address-vehicles' } },
|
{ query: { issPage: 'address-vehicles' } },
|
||||||
undefined,
|
undefined,
|
||||||
(c) => c(wrapper.vm)
|
(c) => c(wrapper.vm));
|
||||||
);
|
|
||||||
|
|
||||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(arePagePrerequisitesValid).toBe(true);
|
expect(arePagePrerequisitesValid).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
route = null,
|
|
||||||
lookupVehicleByVinResponse
|
|
||||||
}) {
|
|
||||||
useMainStore().applicationUser = {
|
|
||||||
pageData: {
|
|
||||||
'address-vehicles':
|
|
||||||
[
|
|
||||||
{
|
|
||||||
vehicle: {
|
|
||||||
carId: 'CR00069309',
|
|
||||||
category: 'SUV',
|
|
||||||
imageUrl:
|
|
||||||
'https://dbhdyzvm8lm25.cloudfront.net/color_0320_032/MY2020/13769/13769_cc0320_032_WW8.jpg',
|
|
||||||
imageVifColor: 'white',
|
|
||||||
imageVifNumber: '13769',
|
|
||||||
make: 'Hyundai',
|
|
||||||
model: 'Santa Fe',
|
|
||||||
style: '4 door utility',
|
|
||||||
year: 2020
|
|
||||||
},
|
|
||||||
vin: '5NMS3CADXLH233004'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useMainStore().lookupVehicleByVin = jest.fn().mockImplementation(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
data: lookupVehicleByVinResponse
|
|
||||||
? lookupVehicleByVinResponse : {
|
|
||||||
vehicle: {
|
|
||||||
carId: 'CARID'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
route: route ? route : undefined,
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn()
|
|
||||||
},
|
|
||||||
mainStore: {
|
|
||||||
order: {
|
|
||||||
vehicle: {
|
|
||||||
carId: 'CR00069309',
|
|
||||||
category: 'SUV',
|
|
||||||
imageUrl:
|
|
||||||
'https://dbhdyzvm8lm25.cloudfront.net/color_0320_032/MY2020/13769/13769_cc0320_032_WW8.jpg',
|
|
||||||
imageVifColor: 'white',
|
|
||||||
imageVifNumber: '13769',
|
|
||||||
make: 'Hyundai',
|
|
||||||
model: 'Santa Fe',
|
|
||||||
style: '4 door utility',
|
|
||||||
year: 2020
|
|
||||||
},
|
|
||||||
vin: '5NMS3CADXLH233004'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const apiResponses = {
|
|
||||||
cmsContent: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiResponses);
|
|
||||||
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
|
||||||
|
|
||||||
// Mock props
|
|
||||||
const mockMixin = {
|
|
||||||
methods: {
|
|
||||||
getCmsContent: jest.fn((contentName) => {
|
|
||||||
if (contentName === 'FoundMultipleVehicles') {
|
|
||||||
return 'FoundMultipleVehiclesTestReturn';
|
|
||||||
}
|
|
||||||
if (contentName === 'ProvideVinAlert') {
|
|
||||||
return 'ProvideVinAlertTestReturn';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
dynamicStrings() {
|
|
||||||
return { ROUTER_LINK: 'routerLink:' };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
mountOptions.mixins = [mockMixin];
|
|
||||||
|
|
||||||
const wrapper = shallowMount(addressVehicles, mountOptions);
|
|
||||||
|
|
||||||
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
|
|
||||||
wrapper.vm.setCmsContent = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
|
||||||
|
|
||||||
return { wrapper };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<Form
|
<Form
|
||||||
@submit="onSubmit"
|
|
||||||
@invalidSubmit="onInvalidSubmit"
|
|
||||||
ref="theForm"
|
ref="theForm"
|
||||||
v-slot="{ meta }">
|
v-slot="{ meta }"
|
||||||
|
@submit="onSubmit"
|
||||||
|
@invalidSubmit="onInvalidSubmit">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
<div class="fade-on-route-transition sub-container overflow-scroll px-5">
|
<div class="fade-on-route-transition sub-container overflow-scroll px-5">
|
||||||
|
|
@ -13,44 +13,51 @@
|
||||||
:displayGenericVehicleImage="false" />
|
:displayGenericVehicleImage="false" />
|
||||||
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" />
|
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" />
|
||||||
<alert
|
<alert
|
||||||
cmsWidgetName="FoundMultipleVehicles"
|
id="multiple-vehicles-alert"
|
||||||
ref="alertFoundMultipleVehicles"
|
ref="alertFoundMultipleVehicles"
|
||||||
|
cmsWidgetName="FoundMultipleVehicles"
|
||||||
class="my-5"
|
class="my-5"
|
||||||
alertClass="alert-warning"
|
alertClass="alert-warning"
|
||||||
:manualHeadline="AlertFoundMultipleVehiclesHeader"
|
:manualHeadline="AlertFoundMultipleVehiclesHeader"
|
||||||
manualCopy=""
|
manualCopy=""
|
||||||
v-bind:isDismissible="false"
|
:isDismissible="false" />
|
||||||
id="multiple-vehicles-alert" />
|
|
||||||
<addressVehiclesQuestion
|
<addressVehiclesQuestion
|
||||||
ref="addressVehiclesQuestion"
|
ref="addressVehiclesQuestion"
|
||||||
|
v-model="selectedVehicleVin"
|
||||||
cmsWidgetName="VehicleConfirmationQuestion"
|
cmsWidgetName="VehicleConfirmationQuestion"
|
||||||
:vehicles="VehiclesForQuestions"
|
:vehicles="VehiclesForQuestions"
|
||||||
:vehicleSelected ="VehicleSelected"
|
:vehicleSelected="VehicleSelected"
|
||||||
validationRules="vehicle-required"
|
validationRules="vehicle-required"
|
||||||
v-model="selectedVehicleVin"
|
|
||||||
:isCarIdDifferent="isCarIdDifferent"
|
:isCarIdDifferent="isCarIdDifferent"
|
||||||
:displayMatchedDifferentVehicleAlert = "displayMatchedDifferentVehicleAlert"
|
:displayMatchedDifferentVehicleAlert="displayMatchedDifferentVehicleAlert"
|
||||||
:displayMatchedTwoIdenticalYMMVehicleAlert = "displayMatchedTwoIdenticalYMMVehicleAlert" />
|
:displayMatchedTwoIdenticalYMMVehicleAlert="displayMatchedTwoIdenticalYMMVehicleAlert" />
|
||||||
<div class="alert-provide-vin my-3"
|
<div
|
||||||
v-if="splitAlertProvideVinBodyForLink.length">
|
v-if="splitAlertProvideVinBodyForLink.length"
|
||||||
<span v-for="copy in splitAlertProvideVinBodyForLink" :key="copy">
|
class="alert-provide-vin my-3">
|
||||||
<span v-if="doesCopyContainRouterLink(copy)" class="text-body">
|
<span
|
||||||
|
v-for="copy in splitAlertProvideVinBodyForLink"
|
||||||
|
:key="copy">
|
||||||
|
<span
|
||||||
|
v-if="doesCopyContainRouterLink(copy)"
|
||||||
|
class="text-body">
|
||||||
<router-link
|
<router-link
|
||||||
:to="{
|
:to="{
|
||||||
query: { issPage: `${getRouterLinkRouteFromCopy(copy)}` },
|
query: { issPage: `${getRouterLinkRouteFromCopy(copy)}` },
|
||||||
name: 'root',
|
name: 'root',
|
||||||
}"
|
}">{{ getRouterLinkDisplayTextFromCopy(copy) }}</router-link>
|
||||||
>{{ getRouterLinkDisplayTextFromCopy(copy) }}</router-link >
|
|
||||||
</span>
|
</span>
|
||||||
<span v-else class="m-0 text-body" v-html="copy"></span>
|
<span
|
||||||
|
v-else
|
||||||
|
class="m-0 text-body"
|
||||||
|
v-html="copy"></span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<siteFooter
|
<siteFooter
|
||||||
|
ref="siteFooter"
|
||||||
cmsWidgetName="SiteFooterWidget"
|
cmsWidgetName="SiteFooterWidget"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
:isForwardActionDisabled="!meta.valid"
|
||||||
@backClicked="backButtonAction"
|
@backClicked="backButtonAction"
|
||||||
@forwardClicked="forwardButtonAction"
|
@forwardClicked="forwardButtonAction" />
|
||||||
ref="siteFooter" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
@ -58,7 +65,6 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Import Supporting Files
|
// Import Supporting Files
|
||||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper';
|
import { settleAllPromises } from '@/helpers/layout-helper';
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
import { issPageValues } from '@/router/router-constants/issPage-values';
|
import { issPageValues } from '@/router/router-constants/issPage-values';
|
||||||
|
|
@ -67,20 +73,21 @@ import { required } from '@/helpers/validation-rules';
|
||||||
import { Form, defineRule } from 'vee-validate';
|
import { Form, defineRule } from 'vee-validate';
|
||||||
import { isGlassAvailableForCarId } from '@/helpers/damage-helper';
|
import { isGlassAvailableForCarId } from '@/helpers/damage-helper';
|
||||||
import {
|
import {
|
||||||
|
fetchCmsContentForPage,
|
||||||
doesCopyContainRouterLink,
|
doesCopyContainRouterLink,
|
||||||
splitCopyOnCMSPlaceHolder,
|
splitCopyOnCMSPlaceHolder,
|
||||||
getRouterLinkRouteFromCopy,
|
getRouterLinkRouteFromCopy,
|
||||||
getRouterLinkDisplayTextFromCopy
|
getRouterLinkDisplayTextFromCopy
|
||||||
} from '@/helpers/cms-content-helper';
|
} from '@/helpers/cms-content-helper.js';
|
||||||
import { routerParams } from '@/router/router-constants/router-params';
|
import { routerParams } from '@/router/router-constants/router-params';
|
||||||
import vinPagesMixin from '@/mixins/vin-pages-mixin';
|
import vinPagesMixin from '@/mixins/vin-pages-mixin';
|
||||||
|
|
||||||
// Import Component
|
// Import Component
|
||||||
import baseFormMixin from '@/mixins/base-form-mixin';
|
import baseFormMixin from '@/mixins/base-form-mixin';
|
||||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
import siteFooter from '@/iss-components/site-footer/site-footer';
|
||||||
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
import siteHeader from '@/iss-components/site-header/site-header';
|
||||||
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
|
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header';
|
||||||
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
|
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner';
|
||||||
import alert from '@/ux-components/alert/alert';
|
import alert from '@/ux-components/alert/alert';
|
||||||
import addressVehiclesQuestion from '@/layouts/address-vehicles/address-vehicles-question/address-vehicles-question';
|
import addressVehiclesQuestion from '@/layouts/address-vehicles/address-vehicles-question/address-vehicles-question';
|
||||||
|
|
||||||
|
|
@ -89,6 +96,16 @@ defineRule('vehicle-required', required(errorMessages.VEHICLE_REQUIRED));
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'address-vehicles',
|
name: 'address-vehicles',
|
||||||
|
components: {
|
||||||
|
siteFooter,
|
||||||
|
siteHeader,
|
||||||
|
siteSubHeader,
|
||||||
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
|
Form,
|
||||||
|
vehicleBanner,
|
||||||
|
alert,
|
||||||
|
addressVehiclesQuestion
|
||||||
|
},
|
||||||
mixins: [baseFormMixin, vinPagesMixin],
|
mixins: [baseFormMixin, vinPagesMixin],
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
|
@ -131,15 +148,13 @@ export default {
|
||||||
return this.VehiclesForQuestions.length;
|
return this.VehiclesForQuestions.length;
|
||||||
},
|
},
|
||||||
AlertFoundMultipleVehiclesHeader() {
|
AlertFoundMultipleVehiclesHeader() {
|
||||||
return this.getCmsContent(
|
return this.getCmsContent('FoundMultipleVehicles',
|
||||||
'FoundMultipleVehicles',
|
'HeadlineText').replaceAll('{custom:vehicleCount}', this.vehicleCount);
|
||||||
'HeadlineText'
|
|
||||||
).replaceAll('{custom:vehicleCount}', this.vehicleCount);
|
|
||||||
},
|
},
|
||||||
isTwoIdenticalYMMVehicleFound() {
|
isTwoIdenticalYMMVehicleFound() {
|
||||||
const vinYmmFound = `${ this.selectedVehicle?.vehicle.year} ${this.selectedVehicle?.vehicle.make} ${this.selectedVehicle?.vehicle.model}`;
|
const vinYmmFound = `${this.selectedVehicle?.vehicle.year} ${this.selectedVehicle?.vehicle.make} ${this.selectedVehicle?.vehicle.model}`;
|
||||||
const vinYmmExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
const vinYmmExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
||||||
return (vinYmmFound.toLowerCase()==vinYmmExpected.toLowerCase());
|
return (vinYmmFound.toLowerCase() === vinYmmExpected.toLowerCase());
|
||||||
},
|
},
|
||||||
AlertProvideVinBody() {
|
AlertProvideVinBody() {
|
||||||
return this.getCmsContent('ProvideVinAlert', 'BodyText');
|
return this.getCmsContent('ProvideVinAlert', 'BodyText');
|
||||||
|
|
@ -157,9 +172,9 @@ export default {
|
||||||
return {
|
return {
|
||||||
vin: v.vin,
|
vin: v.vin,
|
||||||
vehicle: v.vehicle,
|
vehicle: v.vehicle,
|
||||||
Text: v.vehicle.year + ' ' + v.vehicle.make + ' ' + v.vehicle.model,
|
Text: `${v.vehicle.year} ${v.vehicle.make} ${v.vehicle.model}`,
|
||||||
Name: v.vin,
|
Name: v.vin,
|
||||||
SubText: 'VIN ' + vinStart + vinEnd
|
SubText: `VIN ${vinStart}${vinEnd}`
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
return mappedData;
|
return mappedData;
|
||||||
|
|
@ -168,14 +183,37 @@ export default {
|
||||||
return useMainStore().pageData(issPageValues.ADDRESS_VEHICLES);
|
return useMainStore().pageData(issPageValues.ADDRESS_VEHICLES);
|
||||||
},
|
},
|
||||||
selectedVehicle() {
|
selectedVehicle() {
|
||||||
return this.VehiclesForQuestions.find(
|
return this.VehiclesForQuestions.find(({ vin }) => vin === this.selectedVehicleVin);
|
||||||
({ vin }) => vin === this.selectedVehicleVin
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
VehicleSelected() {
|
VehicleSelected() {
|
||||||
return this.mainStore.order.vehicle;
|
return this.mainStore.order.vehicle;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
selectedVehicleVin: {
|
||||||
|
handler() {
|
||||||
|
this.resetWarningsAndErrors();
|
||||||
|
// does this vehicle match the previously selected carId?
|
||||||
|
this.isCarIdDifferent
|
||||||
|
= this.selectedVehicle?.vehicle.carId !== useMainStore().vehicle.carId;
|
||||||
|
if (this.isCarIdDifferent
|
||||||
|
&& this.selectedVehicle?.vehicle.carId !== this.previouslyEnteredCarId) {
|
||||||
|
this.previouslyEnteredCarId = this.selectedVehicle?.vehicle.carId;
|
||||||
|
if (this.isTwoIdenticalYMMVehicleFound) {
|
||||||
|
const carStyle = this.selectedVehicle?.vehicle.style;
|
||||||
|
this.displayMatchedTwoIdenticalYMMVehicleAlert = true;
|
||||||
|
this.forwardButtonCarStyle = carStyle;
|
||||||
|
} else {
|
||||||
|
this.displayMatchedDifferentVehicleAlert = true;
|
||||||
|
}
|
||||||
|
this.$refs.siteFooter.updateButtonText(`Continue with ${this.selectedVehicle.vehicle.year} ${this.selectedVehicle.vehicle.make} ${this.selectedVehicle.vehicle.model} ${this.forwardButtonCarStyle}`);
|
||||||
|
} else {
|
||||||
|
this.$refs.siteFooter.updateButtonText(this.getCmsContent('SiteFooterWidget', 'ForwardButtonText'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
doesCopyContainRouterLink,
|
doesCopyContainRouterLink,
|
||||||
splitCopyOnCMSPlaceHolder,
|
splitCopyOnCMSPlaceHolder,
|
||||||
|
|
@ -199,19 +237,15 @@ export default {
|
||||||
if (!vinLookup) {
|
if (!vinLookup) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(
|
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vinLookup.data.carId);
|
||||||
vinLookup.data.carId
|
await useMainStore().saveVin({
|
||||||
);
|
vehicleInfo: Object.assign(this.selectedVehicle.vehicle, {
|
||||||
await useMainStore().saveVin(
|
vin: this.selectedVehicle.vin
|
||||||
{
|
}),
|
||||||
vehicleInfo: Object.assign(this.selectedVehicle.vehicle, {
|
isSelectedGlassAvailableForVehicle:
|
||||||
vin: this.selectedVehicle.vin
|
|
||||||
}),
|
|
||||||
isSelectedGlassAvailableForVehicle:
|
|
||||||
this.isSelectedGlassAvailableForVehicle
|
this.isSelectedGlassAvailableForVehicle
|
||||||
},
|
},
|
||||||
false
|
false);
|
||||||
);
|
|
||||||
|
|
||||||
return await this.navigateForward();
|
return await this.navigateForward();
|
||||||
},
|
},
|
||||||
|
|
@ -219,12 +253,10 @@ export default {
|
||||||
// If the vehicle selected on this page is different from the one originally entered and the selected glass is not available
|
// If the vehicle selected on this page is different from the one originally entered and the selected glass is not available
|
||||||
// for that vehicle, then navigate back to "vehicle-damage" and display vehicle changed alert on that page.
|
// for that vehicle, then navigate back to "vehicle-damage" and display vehicle changed alert on that page.
|
||||||
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
|
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
|
||||||
this.$router.navigate(
|
this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||||
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
|
||||||
this.$route,
|
this.$route,
|
||||||
{},
|
{},
|
||||||
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
|
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true });
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
await this.navigateForwardWithSingleCarMatch();
|
await this.navigateForwardWithSingleCarMatch();
|
||||||
}
|
}
|
||||||
|
|
@ -234,49 +266,11 @@ export default {
|
||||||
this.displayMatchedTwoIdenticalYMMVehicleAlert = false;
|
this.displayMatchedTwoIdenticalYMMVehicleAlert = false;
|
||||||
this.forwardButtonCarStyle = '';
|
this.forwardButtonCarStyle = '';
|
||||||
}
|
}
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
selectedVehicleVin: {
|
|
||||||
handler() {
|
|
||||||
this.resetWarningsAndErrors();
|
|
||||||
// does this vehicle match the previously selected carId?
|
|
||||||
this.isCarIdDifferent =
|
|
||||||
this.selectedVehicle?.vehicle.carId !== useMainStore().vehicle.carId;
|
|
||||||
if (this.isCarIdDifferent &&
|
|
||||||
this.selectedVehicle?.vehicle.carId !== this.previouslyEnteredCarId) {
|
|
||||||
this.previouslyEnteredCarId = this.selectedVehicle?.vehicle.carId;
|
|
||||||
if(this.isTwoIdenticalYMMVehicleFound){
|
|
||||||
const carStyle = this.selectedVehicle?.vehicle.style;
|
|
||||||
this.displayMatchedTwoIdenticalYMMVehicleAlert = true;
|
|
||||||
this.forwardButtonCarStyle= carStyle;
|
|
||||||
} else {
|
|
||||||
this.displayMatchedDifferentVehicleAlert = true;
|
|
||||||
}
|
|
||||||
this.$refs.siteFooter.updateButtonText(
|
|
||||||
`Continue with ${this.selectedVehicle.vehicle.year} ${this.selectedVehicle.vehicle.make} ${this.selectedVehicle.vehicle.model} ${this.forwardButtonCarStyle}`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.$refs.siteFooter.updateButtonText(
|
|
||||||
this.getCmsContent('SiteFooterWidget', 'ForwardButtonText')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
deep: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
siteFooter,
|
|
||||||
siteHeader,
|
|
||||||
siteSubHeader,
|
|
||||||
Form,
|
|
||||||
vehicleBanner,
|
|
||||||
alert,
|
|
||||||
addressVehiclesQuestion
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.alert-provide-vin {
|
.alert-provide-vin {
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" >
|
<Form
|
||||||
|
ref="theForm"
|
||||||
|
v-slot="{ meta }"
|
||||||
|
@submit="onSubmit"
|
||||||
|
@invalid-submit="onInvalidSubmit">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
<div class="fade-on-route-transition position-relative">
|
<div class="fade-on-route-transition position-relative">
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget"/>
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
<div class="container-fluid pb-2">
|
<div class="container-fluid pb-2">
|
||||||
<p>Placeholder for bailout page</p>
|
<p>Placeholder for bailout page</p>
|
||||||
<siteFooter
|
<siteFooter
|
||||||
cmsWidgetName="SiteFooterWidget"
|
|
||||||
ref="siteFooter"
|
ref="siteFooter"
|
||||||
|
cmsWidgetName="SiteFooterWidget"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
:isForwardActionDisabled="!meta.valid"
|
||||||
@ForwardClicked="forwardButtonAction"
|
@ForwardClicked="forwardButtonAction"
|
||||||
@back-clicked="backButtonAction"
|
@back-clicked="backButtonAction" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -30,15 +33,14 @@ import { useMainStore } from '@/store';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'bailout-page',
|
name: 'bailout-page',
|
||||||
|
components: {
|
||||||
|
siteHeader,
|
||||||
|
siteFooter,
|
||||||
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
|
Form
|
||||||
|
},
|
||||||
mixins: [BaseFormMixin],
|
mixins: [BaseFormMixin],
|
||||||
data() {
|
async beforeRouteEnter(to, from, next) {
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const mainStore = useMainStore();
|
|
||||||
return { mainStore };
|
|
||||||
},
|
|
||||||
async beforeRouteEnter(to, from, next)
|
|
||||||
{
|
|
||||||
// Call APIs
|
// Call APIs
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
// Settle promises and get results
|
// Settle promises and get results
|
||||||
|
|
@ -48,11 +50,17 @@ export default {
|
||||||
promise: cmsContentPromise
|
promise: cmsContentPromise
|
||||||
}];
|
}];
|
||||||
// use resultMap to populate layout content.
|
// use resultMap to populate layout content.
|
||||||
let resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
setup() {
|
||||||
|
const mainStore = useMainStore();
|
||||||
|
return { mainStore };
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
},
|
||||||
methods:
|
methods:
|
||||||
{
|
{
|
||||||
backButtonAction() {
|
backButtonAction() {
|
||||||
|
|
@ -62,13 +70,6 @@ export default {
|
||||||
},
|
},
|
||||||
navigateForward() {
|
navigateForward() {
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
components: {
|
};
|
||||||
siteHeader,
|
|
||||||
siteFooter,
|
|
||||||
Form
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ import capabilityQuestions from '@/layouts/capability-questions/capability-quest
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
import baseMixin from '../../mixins/base-mixin';
|
|
||||||
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
|
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
|
||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
|
import baseMixin from '@/mixins/base-mixin';
|
||||||
|
|
||||||
// Mock our module for promises.
|
// Mock our module for promises.
|
||||||
jest.mock('@/helpers/layout-helper.js', () => ({
|
jest.mock('@/helpers/layout-helper.js', () => ({
|
||||||
|
|
@ -19,78 +19,134 @@ jest.mock('@/helpers/cms-content-helper', () => ({
|
||||||
fetchCmsContentForPage: jest.fn()
|
fetchCmsContentForPage: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const baseStoreGettersPageData = () => {
|
const baseStoreGettersPageData = () => ({
|
||||||
return {
|
partsOrQuestions: [
|
||||||
partsOrQuestions: [
|
{
|
||||||
{
|
parts: [
|
||||||
parts: [
|
{
|
||||||
{
|
childPartQuestions: []
|
||||||
childPartQuestions: []
|
}
|
||||||
}
|
],
|
||||||
],
|
capabilityQuestions: [
|
||||||
capabilityQuestions: [
|
{
|
||||||
{
|
questionSequence: 1,
|
||||||
questionSequence: 1,
|
questionText:
|
||||||
questionText:
|
|
||||||
'Is your vehicle equipped with the optional Lane-Keeping System which tugs on the steering wheel and/or beeps to alert you if you drift too close to the edge of the lane?',
|
'Is your vehicle equipped with the optional Lane-Keeping System which tugs on the steering wheel and/or beeps to alert you if you drift too close to the edge of the lane?',
|
||||||
answers: [
|
answers: [
|
||||||
{
|
{
|
||||||
answerResult1: 'DYNAMIC',
|
answerResult1: 'DYNAMIC',
|
||||||
answerResult2: '1',
|
answerResult2: '1',
|
||||||
answerText: 'Yes',
|
answerText: 'Yes',
|
||||||
nextQuestionSequence: null,
|
nextQuestionSequence: null,
|
||||||
answerResult: 'DYNAMIC'
|
answerResult: 'DYNAMIC'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
answerResult1: 'Unknown',
|
answerResult1: 'Unknown',
|
||||||
answerResult2: '0',
|
answerResult2: '0',
|
||||||
answerText: 'No',
|
answerText: 'No',
|
||||||
nextQuestionSequence: null,
|
nextQuestionSequence: null,
|
||||||
answerResult: 'Unknown'
|
answerResult: 'Unknown'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
partQuestions: [],
|
partQuestions: [],
|
||||||
questions: [],
|
questions: [],
|
||||||
glassLocation: 'Windshield',
|
glassLocation: 'Windshield',
|
||||||
glassName: 'Single',
|
glassName: 'Single',
|
||||||
answerKey: 'Windshield-Single',
|
answerKey: 'Windshield-Single',
|
||||||
answerData: null
|
answerData: null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
});
|
||||||
};
|
const baseStoreGettersDamage = () => ({
|
||||||
const baseStoreGettersDamage = () => {
|
partsQuestionAnswers: [
|
||||||
return {
|
{
|
||||||
partsQuestionAnswers: [
|
glassLocation: 'Windshield',
|
||||||
{
|
glassName: 'Single',
|
||||||
glassLocation: 'Windshield',
|
result: 'FW04848',
|
||||||
glassName: 'Single',
|
answeredQuestions: [
|
||||||
result: 'FW04848',
|
{
|
||||||
answeredQuestions: [
|
questionText:
|
||||||
{
|
|
||||||
questionText:
|
|
||||||
'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?',
|
'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?',
|
||||||
selectedAnswer: '1|nextQuestion|3|Yes',
|
selectedAnswer: '1|nextQuestion|3|Yes',
|
||||||
selectedAnswerText: 'Yes',
|
selectedAnswerText: 'Yes',
|
||||||
questionNum: 1
|
questionNum: 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
questionText:
|
questionText:
|
||||||
'Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?',
|
'Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?',
|
||||||
selectedAnswer: '2|nextQuestion|3|Yes',
|
selectedAnswer: '2|nextQuestion|3|Yes',
|
||||||
selectedAnswerText: 'Yes',
|
selectedAnswerText: 'Yes',
|
||||||
questionNum: 2
|
questionNum: 2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
});
|
||||||
};
|
|
||||||
useMainStore().pageData = baseStoreGettersPageData;
|
useMainStore().pageData = baseStoreGettersPageData;
|
||||||
useMainStore().damage = baseStoreGettersDamage;
|
useMainStore().damage = baseStoreGettersDamage;
|
||||||
|
|
||||||
|
function setupMocks({
|
||||||
|
mountOptionsMockData = {
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn()
|
||||||
|
},
|
||||||
|
actionList: [
|
||||||
|
{
|
||||||
|
actionName: 'saveCapabilityQuestionAnswers',
|
||||||
|
data: {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
actionName: 'getPartsOrQuestions',
|
||||||
|
data: {}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
route: {
|
||||||
|
query: {
|
||||||
|
issPage: 'capability-questions'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
computedSwitcher: [
|
||||||
|
{
|
||||||
|
glassLocation: 'Windshield',
|
||||||
|
glassName: 'Single',
|
||||||
|
answerData: {
|
||||||
|
answerResult: 'FW04848',
|
||||||
|
answeredQuestions: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
questionsData: {
|
||||||
|
get() {
|
||||||
|
return this.computedSwitcher;
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.computedSwitcher = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
useMainStore().getPartsOrQuestions = jest.fn(() => ({
|
||||||
|
data: {
|
||||||
|
partsOrQuestions: []
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
const mountOptions = getMountOptions({
|
||||||
|
...mountOptionsMockData,
|
||||||
|
mixins: [baseMixin, vehicleQuestionsMixin]
|
||||||
|
});
|
||||||
|
mountOptions.attachTo = document.body;
|
||||||
|
|
||||||
|
const wrapper = shallowMount(capabilityQuestions, mountOptions);
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
describe('capabilityQuestions.vue', () => {
|
describe('capabilityQuestions.vue', () => {
|
||||||
describe('method arePagePrerequisitesValid...', () => {
|
describe('method arePagePrerequisitesValid...', () => {
|
||||||
test('Should return true for valid page requisites if pageData exists', () => {
|
test('Should return true for valid page requisites if pageData exists', () => {
|
||||||
|
|
@ -109,9 +165,7 @@ describe('capabilityQuestions.vue', () => {
|
||||||
test('Should return false for valid page requisites if partsOrQuestions in pageData is missing', () => {
|
test('Should return false for valid page requisites if partsOrQuestions in pageData is missing', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
useMainStore().pageData = jest.fn(() => {
|
useMainStore().pageData = jest.fn(() => undefined);
|
||||||
return undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = wrapper.vm.arePagePrerequisitesValid();
|
const result = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
@ -124,11 +178,9 @@ describe('capabilityQuestions.vue', () => {
|
||||||
|
|
||||||
test('Should be at least one item in partsOrQuestions', () => {
|
test('Should be at least one item in partsOrQuestions', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
useMainStore().pageData = jest.fn(() => {
|
useMainStore().pageData = jest.fn(() => ({
|
||||||
return {
|
partsOrQuestions: []
|
||||||
partsOrQuestions: []
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
useMainStore().damage = baseStoreGettersDamage;
|
useMainStore().damage = baseStoreGettersDamage;
|
||||||
|
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
@ -207,11 +259,9 @@ describe('capabilityQuestions.vue', () => {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
wrapper.vm.dispatchStoreAction = jest.fn(() => {
|
wrapper.vm.dispatchStoreAction = jest.fn(() => ({
|
||||||
return {
|
data: []
|
||||||
data: []
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
wrapper.vm.forwardButtonAction();
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
@ -242,13 +292,11 @@ describe('capabilityQuestions.vue', () => {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
useMainStore().getPartsOrQuestions = jest.fn(() => {
|
useMainStore().getPartsOrQuestions = jest.fn(() => ({
|
||||||
return {
|
data: {
|
||||||
data: {
|
partsOrQuestions: []
|
||||||
partsOrQuestions: []
|
}
|
||||||
}
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
wrapper.vm.forwardButtonAction();
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
@ -279,11 +327,9 @@ describe('capabilityQuestions.vue', () => {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
wrapper.vm.dispatchStoreAction = jest.fn(() => {
|
wrapper.vm.dispatchStoreAction = jest.fn(() => ({
|
||||||
return {
|
data: []
|
||||||
data: []
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
wrapper.vm.forwardButtonAction();
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
@ -316,13 +362,11 @@ describe('capabilityQuestions.vue', () => {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
useMainStore().getPartsOrQuestions = jest.fn(() => {
|
useMainStore().getPartsOrQuestions = jest.fn(() => ({
|
||||||
return {
|
data: {
|
||||||
data: {
|
partsOrQuestions: []
|
||||||
partsOrQuestions: []
|
}
|
||||||
}
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
wrapper.vm.navigateForward = jest.fn();
|
wrapper.vm.navigateForward = jest.fn();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -335,65 +379,3 @@ describe('capabilityQuestions.vue', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
mountOptionsMockData = {
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn()
|
|
||||||
},
|
|
||||||
actionList: [
|
|
||||||
{
|
|
||||||
actionName: 'saveCapabilityQuestionAnswers',
|
|
||||||
data: {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
actionName: 'getPartsOrQuestions',
|
|
||||||
data: {}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
route: {
|
|
||||||
query: {
|
|
||||||
issPage: 'capability-questions'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
computedSwitcher: [
|
|
||||||
{
|
|
||||||
glassLocation: 'Windshield',
|
|
||||||
glassName: 'Single',
|
|
||||||
answerData: {
|
|
||||||
answerResult: 'FW04848',
|
|
||||||
answeredQuestions: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
},
|
|
||||||
questionsData: {
|
|
||||||
get() {
|
|
||||||
return this.computedSwitcher;
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.computedSwitcher = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
useMainStore().getPartsOrQuestions = jest.fn(() => {
|
|
||||||
return {
|
|
||||||
data: {
|
|
||||||
partsOrQuestions: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
...mountOptionsMockData,
|
|
||||||
mixins: [baseMixin, vehicleQuestionsMixin]
|
|
||||||
});
|
|
||||||
mountOptions['attachTo'] = document.body;
|
|
||||||
|
|
||||||
const wrapper = shallowMount(capabilityQuestions, mountOptions);
|
|
||||||
|
|
||||||
return { wrapper };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
<template>
|
<template>
|
||||||
<Form
|
<Form
|
||||||
@submit="onSubmit"
|
ref="theForm"
|
||||||
@invalidSubmit="onInvalidSubmit" ref="theForm"
|
|
||||||
v-slot="{ meta }"
|
v-slot="{ meta }"
|
||||||
>
|
@submit="onSubmit"
|
||||||
|
@invalidSubmit="onInvalidSubmit">
|
||||||
<questionsPageLayout
|
<questionsPageLayout
|
||||||
isRequired
|
ref="questionsPageLayout"
|
||||||
ref="questionsPageLayout"
|
v-model="selectedAnswers"
|
||||||
:isMetaValid="meta.valid"
|
isRequired
|
||||||
:alertFewMoreQuestionsHeader="AlertFewMoreQuestionsHeader"
|
:isMetaValid="meta.valid"
|
||||||
:alertFewMoreQuestionsCopy="AlertFewMoreQuestionsCopy"
|
:alertFewMoreQuestionsHeader="AlertFewMoreQuestionsHeader"
|
||||||
:questionsData="questionsData"
|
:alertFewMoreQuestionsCopy="AlertFewMoreQuestionsCopy"
|
||||||
:validationRules="rules.optionRequired"
|
:questionsData="questionsData"
|
||||||
v-model="selectedAnswers"
|
:validationRules="rules.optionRequired"
|
||||||
@forwardButtonAction="forwardButtonAction"
|
:index="currentGlassIndex"
|
||||||
@back-click="navigateBack"
|
@forwardButtonAction="forwardButtonAction"
|
||||||
:index="currentGlassIndex" />
|
@back-click="navigateBack" />
|
||||||
</Form>
|
</Form>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -30,25 +30,16 @@ import { Form } from 'vee-validate';
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
import globalRules from '@/constants/global-rules';
|
import globalRules from '@/constants/global-rules';
|
||||||
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
|
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
|
||||||
import questionsPageLayout from '@/iss-components/questions-page-layout/questions-page-layout.vue';
|
import questionsPageLayout from '@/iss-components/questions-page-layout/questions-page-layout';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'capability-questions',
|
name: 'capability-questions',
|
||||||
mixins: [baseFormMixin, vehicleQuestionsMixin],
|
|
||||||
components: {
|
components: {
|
||||||
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
Form,
|
Form,
|
||||||
questionsPageLayout
|
questionsPageLayout
|
||||||
},
|
},
|
||||||
data() {
|
mixins: [baseFormMixin, vehicleQuestionsMixin],
|
||||||
return {
|
|
||||||
questionsData: [],
|
|
||||||
selectedAnswers: {},
|
|
||||||
currentGlassIndex: 0,
|
|
||||||
rules: {
|
|
||||||
optionRequired: globalRules.OPTION_REQUIRED
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
|
||||||
|
|
@ -66,6 +57,16 @@ export default {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
questionsData: [],
|
||||||
|
selectedAnswers: {},
|
||||||
|
currentGlassIndex: 0,
|
||||||
|
rules: {
|
||||||
|
optionRequired: globalRules.OPTION_REQUIRED
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
AlertFewMoreQuestionsHeader() {
|
AlertFewMoreQuestionsHeader() {
|
||||||
return this.getCmsContent('AdditionalPartsQuestionsAlert', 'HeadlineText');
|
return this.getCmsContent('AdditionalPartsQuestionsAlert', 'HeadlineText');
|
||||||
|
|
@ -85,9 +86,8 @@ export default {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
const capabilityQuestionsFromPageData = useMainStore().pageData(issPageValues.CAPABILITY_QUESTIONS);
|
const capabilityQuestionsFromPageData = useMainStore().pageData(issPageValues.CAPABILITY_QUESTIONS);
|
||||||
return (
|
return (
|
||||||
capabilityQuestionsFromPageData?.partsOrQuestions?.some((part) => part?.glassName) &&
|
capabilityQuestionsFromPageData?.partsOrQuestions?.some((part) => part?.glassName)
|
||||||
capabilityQuestionsFromPageData?.partsOrQuestions?.some(
|
&& capabilityQuestionsFromPageData?.partsOrQuestions?.some((part) => part?.capabilityQuestions?.length > 0)
|
||||||
(part) => part?.capabilityQuestions?.length > 0)
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
getInitialQuestionData() {
|
getInitialQuestionData() {
|
||||||
|
|
@ -98,24 +98,20 @@ export default {
|
||||||
.map((glass, index) => {
|
.map((glass, index) => {
|
||||||
// NOTE: questions for property "questions" can differ between layouts
|
// NOTE: questions for property "questions" can differ between layouts
|
||||||
glass.questions = glass.capabilityQuestions;
|
glass.questions = glass.capabilityQuestions;
|
||||||
glass.answerKey = glass.glassLocation + '-' + glass.glassName;
|
glass.answerKey = `${glass.glassLocation}-${glass.glassName}`;
|
||||||
// reset selectedAnswers for this glass
|
// reset selectedAnswers for this glass
|
||||||
this.selectedAnswers[glass.answerKey] = [];
|
this.selectedAnswers[glass.answerKey] = [];
|
||||||
const updatedGlass = this.setupInitialData(
|
const updatedGlass = this.setupInitialData(glass,
|
||||||
glass,
|
|
||||||
index,
|
index,
|
||||||
alreadyAnsweredQuestions
|
alreadyAnsweredQuestions);
|
||||||
);
|
|
||||||
// Set up watch for each set of glass questions
|
// Set up watch for each set of glass questions
|
||||||
this.$watch(
|
this.$watch(`selectedAnswers.${glass.answerKey}`,
|
||||||
'selectedAnswers.' + glass.answerKey,
|
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
if (newValue && Object.keys(newValue).length > 0) {
|
if (newValue && Object.keys(newValue).length > 0) {
|
||||||
this.handleAnswerUpdates(newValue, glass.answerKey);
|
this.handleAnswerUpdates(newValue, glass.answerKey);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true });
|
||||||
);
|
|
||||||
return updatedGlass;
|
return updatedGlass;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -124,9 +120,7 @@ export default {
|
||||||
// get answerResult2 of returned answer
|
// get answerResult2 of returned answer
|
||||||
let selectedAnswerResult2;
|
let selectedAnswerResult2;
|
||||||
glass.questions.forEach((q) => {
|
glass.questions.forEach((q) => {
|
||||||
const idx = q.answers.findIndex(
|
const idx = q.answers.findIndex((a) => a.answerResult === glass.answerData.answerResult);
|
||||||
(a) => a.answerResult === glass.answerData.answerResult
|
|
||||||
);
|
|
||||||
if (idx !== -1) {
|
if (idx !== -1) {
|
||||||
selectedAnswerResult2 = q.answers[idx].answerResult2;
|
selectedAnswerResult2 = q.answers[idx].answerResult2;
|
||||||
}
|
}
|
||||||
|
|
@ -149,13 +143,11 @@ export default {
|
||||||
await this.mainStore.saveCapabilityQuestionAnswers(questionAnswersArray);
|
await this.mainStore.saveCapabilityQuestionAnswers(questionAnswersArray);
|
||||||
// get parts from the capabilityQuestionAnswers
|
// get parts from the capabilityQuestionAnswers
|
||||||
const partsOrQuestions = this.partsOrQuestionsData;
|
const partsOrQuestions = this.partsOrQuestionsData;
|
||||||
for (let answer of questionAnswersArray) {
|
for (const answer of questionAnswersArray) {
|
||||||
partsOrQuestions.find((partOrQuestion) => {
|
partsOrQuestions.find((partOrQuestion) => (
|
||||||
return (
|
partOrQuestion.glassLocation === answer.glassLocation
|
||||||
partOrQuestion.glassLocation === answer.glassLocation &&
|
&& partOrQuestion.glassName === answer.glassName
|
||||||
partOrQuestion.glassName === answer.glassName
|
)).parts[0].childParts = [
|
||||||
);
|
|
||||||
}).parts[0].childParts = [
|
|
||||||
{
|
{
|
||||||
partNumber: answer.partNum
|
partNumber: answer.partNum
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,8 +76,7 @@ describe('contactDetails.vue', () => {
|
||||||
const checkboxLabel = getRandomString(50, 100);
|
const checkboxLabel = getRandomString(50, 100);
|
||||||
const mockMixin = {
|
const mockMixin = {
|
||||||
methods: {
|
methods: {
|
||||||
getCmsContent: jest.fn().mockImplementation(() =>
|
getCmsContent: jest.fn().mockImplementation(() => checkboxLabel),
|
||||||
checkboxLabel),
|
|
||||||
setCmsContent: jest.fn()
|
setCmsContent: jest.fn()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -107,8 +106,7 @@ describe('contactDetails.vue', () => {
|
||||||
const disclaimerText = getRandomString(50, 100);
|
const disclaimerText = getRandomString(50, 100);
|
||||||
const mockMixin = {
|
const mockMixin = {
|
||||||
methods: {
|
methods: {
|
||||||
getCmsContent: jest.fn().mockImplementation(() =>
|
getCmsContent: jest.fn().mockImplementation(() => disclaimerText),
|
||||||
disclaimerText),
|
|
||||||
setCmsContent: jest.fn()
|
setCmsContent: jest.fn()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
describe ('test', () => {
|
describe('test', () => {
|
||||||
test ('dummy test', () => {
|
test('dummy test', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
let test = "test";
|
let test = 'test';
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
test = "test2"
|
test = 'test2';
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(test.length).toBe(5);
|
expect(test.length).toBe(5);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
// *Testing to be completed on SSR-603
|
// *Testing to be completed on SSR-603
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -283,8 +283,7 @@ export default {
|
||||||
if (!store.order.damage.isRepair) {
|
if (!store.order.damage.isRepair) {
|
||||||
const parts = store.order.lineItems.glassParts;
|
const parts = store.order.lineItems.glassParts;
|
||||||
|
|
||||||
if (parts != null && parts.filter((part) =>
|
if (parts != null && parts.filter((part) => part.requiresRecalibration).length > 0) {
|
||||||
part.requiresRecalibration).length > 0) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -427,7 +426,7 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
.body-text {
|
.body-text {
|
||||||
p {
|
p {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,19 @@
|
||||||
import { shallowMount, mount } from '@vue/test-utils';
|
import { mount } from '@vue/test-utils';
|
||||||
import recalModal from '@/layouts/coverage-statement/recal-modal/recal-modal.vue';
|
import recalModal from '@/layouts/coverage-statement/recal-modal/recal-modal';
|
||||||
|
|
||||||
|
const mockCmsContent = {
|
||||||
|
HeaderText: 'Sample header text here.',
|
||||||
|
SubheaderText: 'Sample subheader text here.',
|
||||||
|
Image: 'https://www.sampleImage.sample',
|
||||||
|
BodyText: 'Sample body text here.',
|
||||||
|
FooterText: 'Sample footer text here.'
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockMixin = {
|
||||||
|
methods: {
|
||||||
|
getCmsContent: jest.fn((widgetName, cmsFieldName) => mockCmsContent[cmsFieldName])
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
describe('modal.vue', () => {
|
describe('modal.vue', () => {
|
||||||
it('Should display header text when HeaderText is defined in the CMS', async () => {
|
it('Should display header text when HeaderText is defined in the CMS', async () => {
|
||||||
|
|
@ -11,7 +25,7 @@ describe('modal.vue', () => {
|
||||||
},
|
},
|
||||||
attachTo: document.body
|
attachTo: document.body
|
||||||
});
|
});
|
||||||
expect(wrapper.html()).toEqual(expect.stringContaining(mockCmsContent['HeaderText']));
|
expect(wrapper.html()).toEqual(expect.stringContaining(mockCmsContent.HeaderText));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should display subheader text when SubheaderText is defined in the CMS', async () => {
|
it('Should display subheader text when SubheaderText is defined in the CMS', async () => {
|
||||||
|
|
@ -23,7 +37,7 @@ describe('modal.vue', () => {
|
||||||
},
|
},
|
||||||
attachTo: document.body
|
attachTo: document.body
|
||||||
});
|
});
|
||||||
expect(wrapper.html()).toEqual(expect.stringContaining(mockCmsContent['SubheaderText']));
|
expect(wrapper.html()).toEqual(expect.stringContaining(mockCmsContent.SubheaderText));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should insert image url when Image is defined in the CMS', async () => {
|
it('Should insert image url when Image is defined in the CMS', async () => {
|
||||||
|
|
@ -35,7 +49,7 @@ describe('modal.vue', () => {
|
||||||
},
|
},
|
||||||
attachTo: document.body
|
attachTo: document.body
|
||||||
});
|
});
|
||||||
expect(wrapper.html()).toEqual(expect.stringContaining(mockCmsContent['Image']));
|
expect(wrapper.html()).toEqual(expect.stringContaining(mockCmsContent.Image));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should display body text when BodyText is defined in the CMS', async () => {
|
it('Should display body text when BodyText is defined in the CMS', async () => {
|
||||||
|
|
@ -47,22 +61,6 @@ describe('modal.vue', () => {
|
||||||
},
|
},
|
||||||
attachTo: document.body
|
attachTo: document.body
|
||||||
});
|
});
|
||||||
expect(wrapper.html()).toEqual(expect.stringContaining(mockCmsContent['BodyText']));
|
expect(wrapper.html()).toEqual(expect.stringContaining(mockCmsContent.BodyText));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockMixin = {
|
|
||||||
methods: {
|
|
||||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
|
|
||||||
return mockCmsContent[cmsFieldName];
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const mockCmsContent = {
|
|
||||||
HeaderText: 'Sample header text here.',
|
|
||||||
SubheaderText: 'Sample subheader text here.',
|
|
||||||
Image: 'https://www.sampleImage.sample',
|
|
||||||
BodyText: 'Sample body text here.',
|
|
||||||
FooterText: 'Sample footer text here.'
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -3,21 +3,28 @@
|
||||||
:ref="ModalName"
|
:ref="ModalName"
|
||||||
:modalId="ModalName"
|
:modalId="ModalName"
|
||||||
:footerButtonText="ModalCloseButtonText"
|
:footerButtonText="ModalCloseButtonText"
|
||||||
@footer-button-event="closeModal"
|
@footer-button-event="closeModal">
|
||||||
>
|
|
||||||
<div class="recal-modal-body ps-4 pe-4 pt-0 pb-5">
|
<div class="recal-modal-body ps-4 pe-4 pt-0 pb-5">
|
||||||
<h5 class="mb-4 text-center" v-html="ModalHeadline"></h5>
|
<h5
|
||||||
<img :src="ModalImage" class="mw-100 d-flex mx-auto mb-4" alt="" />
|
class="mb-4 text-center"
|
||||||
<p class="fw-bold mb-2 subheader-text" v-html="ModalSubheadertext"></p>
|
v-html="ModalHeadline"></h5>
|
||||||
<p class="mb-0 small" v-html="ModalBodyText"></p>
|
<img
|
||||||
|
:src="ModalImage"
|
||||||
|
class="mw-100 d-flex mx-auto mb-4"
|
||||||
|
alt="" />
|
||||||
|
<p
|
||||||
|
class="fw-bold mb-2 subheader-text"
|
||||||
|
v-html="ModalSubheadertext"></p>
|
||||||
|
<p
|
||||||
|
class="mb-0 small"
|
||||||
|
v-html="ModalBodyText"></p>
|
||||||
<p
|
<p
|
||||||
class="my-4 caption modal-sub-body"
|
|
||||||
v-if="ModalSubBodyText"
|
v-if="ModalSubBodyText"
|
||||||
|
class="my-4 caption modal-sub-body"
|
||||||
v-html="ModalSubBodyText">
|
v-html="ModalSubBodyText">
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</modal>
|
</modal>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -25,17 +32,12 @@ import modal from '@/digital-components/modal/modal';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'recal-modal',
|
name: 'recal-modal',
|
||||||
|
components: {
|
||||||
|
modal
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
cmsWidgetName: String
|
cmsWidgetName: String
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
openModal() {
|
|
||||||
this.$refs[this.ModalName].openModal();
|
|
||||||
},
|
|
||||||
closeModal() {
|
|
||||||
this.$refs[this.ModalName].closeModal();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
ModalName() {
|
ModalName() {
|
||||||
return this.cmsWidgetName;
|
return this.cmsWidgetName;
|
||||||
|
|
@ -59,13 +61,18 @@ export default {
|
||||||
return this.getCmsContent(this.cmsWidgetName, 'FooterText');
|
return this.getCmsContent(this.cmsWidgetName, 'FooterText');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
methods: {
|
||||||
modal
|
openModal() {
|
||||||
|
this.$refs[this.ModalName].openModal();
|
||||||
|
},
|
||||||
|
closeModal() {
|
||||||
|
this.$refs[this.ModalName].closeModal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
.recal-modal-body {
|
.recal-modal-body {
|
||||||
.modal-sub-body {
|
.modal-sub-body {
|
||||||
|
|
@ -84,5 +91,4 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
// Components
|
// Components
|
||||||
import entryPage from '@/layouts/entry-page/entry-page.vue';
|
import entryPage from '@/layouts/entry-page/entry-page';
|
||||||
|
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
||||||
import { fetchCmsContentForPage, setupModalLinks } from '@/helpers/cms-content-helper';
|
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||||
import { useMainStore } from '@/store';
|
|
||||||
|
|
||||||
// Mock our module for promises.
|
// Mock our module for promises.
|
||||||
jest.mock('@/helpers/layout-helper.js', () => ({
|
jest.mock('@/helpers/layout-helper.js', () => ({
|
||||||
|
|
@ -18,16 +17,6 @@ jest.mock('@/helpers/cms-content-helper', () => ({
|
||||||
setupModalLinks: jest.fn()
|
setupModalLinks: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('entry-page.vue', () => {
|
|
||||||
test('should render', () => {
|
|
||||||
const queryString = 'policynumber="123456"'
|
|
||||||
const { wrapper } = setupMocks(queryString);
|
|
||||||
|
|
||||||
console.log(wrapper.vm.$route.query);
|
|
||||||
expect(wrapper).toBeTruthy();
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
function setupMocks(queryString) {
|
function setupMocks(queryString) {
|
||||||
const mountOptions = getMountOptions({
|
const mountOptions = getMountOptions({
|
||||||
router: {
|
router: {
|
||||||
|
|
@ -36,15 +25,23 @@ function setupMocks(queryString) {
|
||||||
route: { queryString }
|
route: { queryString }
|
||||||
});
|
});
|
||||||
|
|
||||||
const wrapper = shallowMount(
|
const wrapper = shallowMount(entryPage,
|
||||||
entryPage,
|
mountOptions);
|
||||||
mountOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
const apiResponses = {};
|
const apiResponses = {};
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiResponses);
|
settleAllPromises.mockImplementation(() => apiResponses);
|
||||||
fetchCmsContentForPage.mockImplementation (() => {});
|
fetchCmsContentForPage.mockImplementation(() => { });
|
||||||
|
|
||||||
return { wrapper };
|
return { wrapper };
|
||||||
};
|
}
|
||||||
|
|
||||||
|
describe('entry-page.vue', () => {
|
||||||
|
test('should render', () => {
|
||||||
|
const queryString = 'policynumber="123456"';
|
||||||
|
const { wrapper } = setupMocks(queryString);
|
||||||
|
|
||||||
|
console.log(wrapper.vm.$route.query);
|
||||||
|
expect(wrapper).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<p id="message" v-show="unauthorized">Unauthorized Access.</p>
|
<p
|
||||||
|
v-show="unauthorized"
|
||||||
|
id="message">
|
||||||
|
Unauthorized Access.
|
||||||
|
</p>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -10,40 +14,42 @@ import { useMainStore } from '@/store';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'entry-page',
|
name: 'entry-page',
|
||||||
mixins: [],
|
components: {
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
unauthorized: false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
mixins: [],
|
||||||
setup() {
|
setup() {
|
||||||
const mainStore = useMainStore();
|
const mainStore = useMainStore();
|
||||||
mainStore.resetISSConfigState();
|
mainStore.resetISSConfigState();
|
||||||
mainStore.resetPageFields();
|
mainStore.resetPageFields();
|
||||||
return { mainStore };
|
return { mainStore };
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
unauthorized: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.validateClientTagOnEntry();
|
this.validateClientTagOnEntry();
|
||||||
},
|
},
|
||||||
methods:
|
methods:
|
||||||
{
|
{
|
||||||
navigateForward() {
|
navigateForward() {
|
||||||
this.$router.navigate(
|
this.$router.navigate(this.navigationScenarios.MOVE_FORWARD_ENTRY_PAGE,
|
||||||
this.navigationScenarios.MOVE_FORWARD_ENTRY_PAGE,
|
this.$route);
|
||||||
this.$route
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
parseQueryParms() {
|
parseQueryParms() {
|
||||||
// Dump the query string parameters into an array. Remove casing on the key for easy compare.
|
// Dump the query string parameters into an array. Remove casing on the key for easy compare.
|
||||||
let queryStringParams = [];
|
const queryStringParams = [];
|
||||||
for (let param in this.$route.query) {
|
for (const param in this.$route.query) {
|
||||||
queryStringParams[param.toLowerCase()] = this.$route.query[param];
|
queryStringParams[param.toLowerCase()] = this.$route.query[param];
|
||||||
}
|
}
|
||||||
return queryStringParams;
|
return queryStringParams;
|
||||||
},
|
},
|
||||||
async validateClientTagOnEntry() {
|
async validateClientTagOnEntry() {
|
||||||
const queryStringParams = this.parseQueryParms();
|
const queryStringParams = this.parseQueryParms();
|
||||||
const clientTag = queryStringParams['clienttag'];
|
const clientTag = queryStringParams.clienttag;
|
||||||
const clientTagPresent = !!clientTag;
|
const clientTagPresent = !!clientTag;
|
||||||
let authorized = false;
|
let authorized = false;
|
||||||
|
|
||||||
|
|
@ -66,7 +72,7 @@ export default {
|
||||||
|
|
||||||
if (authorized) {
|
if (authorized) {
|
||||||
// Forced full location redirect here. We do not want the entry page as part of the router/flow/path history.
|
// Forced full location redirect here. We do not want the entry page as part of the router/flow/path history.
|
||||||
window.location = '/?issPage=' + issPageValues.WELCOME_PAGE;
|
window.location = `/?issPage=${issPageValues.WELCOME_PAGE}`;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
populateISSConfigValues(data) {
|
populateISSConfigValues(data) {
|
||||||
|
|
@ -76,9 +82,9 @@ export default {
|
||||||
this.mainStore.issConfig.styleSheet = data.styleSheet;
|
this.mainStore.issConfig.styleSheet = data.styleSheet;
|
||||||
this.mainStore.issConfig.isCoverageEnabled = data.coverageEnabled;
|
this.mainStore.issConfig.isCoverageEnabled = data.coverageEnabled;
|
||||||
|
|
||||||
// NOTE: This is only here for testing purposes. Will be removed and replaced by actual token/signature validation when work is completed.
|
// NOTE: This is only here for testing purposes.
|
||||||
if (data.authentication == 'RSAToken')
|
// Will be removed and replaced by actual token / signature validation when work is completed.
|
||||||
this.mainStore.issConfig.isAuthenticated = true;
|
if (data.authentication === 'RSAToken') this.mainStore.issConfig.isAuthenticated = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (data.clientFlags) {
|
if (data.clientFlags) {
|
||||||
|
|
@ -97,20 +103,20 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error parsing client flags: ' + e);
|
console.error(`Error parsing client flags: ${e}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
combineClientParameters(configParams, queryStringParams) {
|
combineClientParameters(configParams, queryStringParams) {
|
||||||
let finalParams = [];
|
const finalParams = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const clientParams = JSON.parse(configParams);
|
const clientParams = JSON.parse(configParams);
|
||||||
|
|
||||||
for (let cparam in clientParams) {
|
for (const cparam in clientParams) {
|
||||||
let cname = clientParams[cparam].toLowerCase();
|
const cname = clientParams[cparam].toLowerCase();
|
||||||
|
|
||||||
for (let qsparam in queryStringParams) {
|
for (const qsparam in queryStringParams) {
|
||||||
let qsname = qsparam.toLowerCase();
|
const qsname = qsparam.toLowerCase();
|
||||||
|
|
||||||
if (cname === qsname) {
|
if (cname === qsname) {
|
||||||
finalParams[cname] = queryStringParams[cname];
|
finalParams[cname] = queryStringParams[cname];
|
||||||
|
|
@ -118,16 +124,16 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error combining client parameters: ' + e);
|
console.error(`Error combining client parameters: ${e}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalParams;
|
return finalParams;
|
||||||
},
|
},
|
||||||
populateStoreItemsFromParams(params) {
|
populateStoreItemsFromParams(params) {
|
||||||
// Populate store items from parameters.
|
// Populate store items from parameters.
|
||||||
for (let param in params) {
|
for (const param in params) {
|
||||||
let name = param.toLowerCase();
|
const name = param.toLowerCase();
|
||||||
let value = params[param];
|
const value = params[param];
|
||||||
|
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case 'policynumber':
|
case 'policynumber':
|
||||||
|
|
@ -158,18 +164,15 @@ export default {
|
||||||
case 'token':
|
case 'token':
|
||||||
case 'signature':
|
case 'signature':
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
computed: {
|
};
|
||||||
},
|
|
||||||
components: {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
#message {
|
#message {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// Components
|
// Components
|
||||||
import licensePlateLookup from '@/layouts/license-plate-lookup/license-plate-lookup.vue';
|
import licensePlateLookup from '@/layouts/license-plate-lookup/license-plate-lookup';
|
||||||
|
|
||||||
// Supporting Files
|
// Supporting Files
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
import { settleAllPromises } from '@/helpers/layout-helper.js';
|
||||||
|
|
@ -23,6 +23,83 @@ jest.mock('@/helpers/cms-content-helper', () => ({
|
||||||
fetchCmsContentForPage: jest.fn()
|
fetchCmsContentForPage: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function setupMocks({
|
||||||
|
isZipValid = true,
|
||||||
|
isZipServiceable = true,
|
||||||
|
lookupVinByPlateResponse,
|
||||||
|
partsOrQuestions = [],
|
||||||
|
vehicle = {},
|
||||||
|
vin = null,
|
||||||
|
carId = 'C0000',
|
||||||
|
vinLookupResponseError = null,
|
||||||
|
route = null
|
||||||
|
}) {
|
||||||
|
useMainStore().validateZip = jest.fn().mockImplementation(() => Promise.resolve({
|
||||||
|
data: {
|
||||||
|
isValid: isZipValid,
|
||||||
|
isServiceable: isZipServiceable
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
useMainStore().lookupVinByPlate = jest.fn().mockImplementation(() => Promise.resolve({
|
||||||
|
data: lookupVinByPlateResponse || {
|
||||||
|
vin: 'TEST_VIN',
|
||||||
|
vehicle: {
|
||||||
|
carId: 'CARID'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
useMainStore().getPartsOrQuestions = jest.fn().mockImplementation(() => Promise.resolve({
|
||||||
|
data: {
|
||||||
|
partsOrQuestions
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const wrapper = shallowMount(licensePlateLookup,
|
||||||
|
getMountOptions({
|
||||||
|
route: route || undefined,
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn()
|
||||||
|
},
|
||||||
|
mainStore: {
|
||||||
|
order: {
|
||||||
|
vehicle: {
|
||||||
|
carId,
|
||||||
|
registration: {
|
||||||
|
licensePlate: 'TESTPLATE',
|
||||||
|
zipCode: '12345'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
const apiResponses = {
|
||||||
|
serviceZipValidationResponse: {
|
||||||
|
isValid: isZipValid,
|
||||||
|
isServiceable: isZipServiceable
|
||||||
|
},
|
||||||
|
vinLookupResponse: {
|
||||||
|
vin,
|
||||||
|
vehicle,
|
||||||
|
error: vinLookupResponseError
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
settleAllPromises.mockImplementation(() => apiResponses);
|
||||||
|
|
||||||
|
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
|
||||||
|
wrapper.vm.setCmsContent = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn();
|
||||||
|
wrapper.vm.$refs.siteFooter.enableForwardButton = jest.fn();
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
describe('license-plate-lookup.vue', () => {
|
describe('license-plate-lookup.vue', () => {
|
||||||
describe('page level alerts', () => {
|
describe('page level alerts', () => {
|
||||||
test('If license plate matches a different vehicle, display MatchedDifferentVehicleAlert', async () => {
|
test('If license plate matches a different vehicle, display MatchedDifferentVehicleAlert', async () => {
|
||||||
|
|
@ -43,9 +120,7 @@ describe('license-plate-lookup.vue', () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.findComponent({ ref: 'alertMatchedDifferentVehicle' }).isVisible()).toBe(
|
expect(wrapper.findComponent({ ref: 'alertMatchedDifferentVehicle' }).isVisible()).toBe(true);
|
||||||
true
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('If license plate matches two identical YMM vehicles, display alertMatchedTwoIdenticalYMMVehicle', async () => {
|
test('If license plate matches two identical YMM vehicles, display alertMatchedTwoIdenticalYMMVehicle', async () => {
|
||||||
|
|
@ -67,9 +142,7 @@ describe('license-plate-lookup.vue', () => {
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.findComponent({ ref: 'alertMatchedTwoIdenticalYMMVehicle' }).isVisible()).toBe(
|
expect(wrapper.findComponent({ ref: 'alertMatchedTwoIdenticalYMMVehicle' }).isVisible()).toBe(true);
|
||||||
true
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('If no vehicles found, display VinNotFound alert', async () => {
|
test('If no vehicles found, display VinNotFound alert', async () => {
|
||||||
|
|
@ -101,7 +174,7 @@ describe('license-plate-lookup.vue', () => {
|
||||||
describe('navigation', () => {
|
describe('navigation', () => {
|
||||||
test('Clicking back button navigates back', async () => {
|
test('Clicking back button navigates back', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const { wrapper, apiPromise } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
router: {
|
router: {
|
||||||
navigate: jest.fn()
|
navigate: jest.fn()
|
||||||
|
|
@ -109,12 +182,10 @@ describe('license-plate-lookup.vue', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Act
|
// Act
|
||||||
licensePlateLookup.beforeRouteEnter.call(
|
licensePlateLookup.beforeRouteEnter.call(wrapper.vm,
|
||||||
wrapper.vm,
|
|
||||||
{ query: { issPage: 'license-plate-lookup' } },
|
{ query: { issPage: 'license-plate-lookup' } },
|
||||||
undefined,
|
undefined,
|
||||||
(c) => c(wrapper.vm)
|
(c) => c(wrapper.vm));
|
||||||
);
|
|
||||||
await wrapper.vm.backButtonAction();
|
await wrapper.vm.backButtonAction();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
@ -155,7 +226,7 @@ describe('license-plate-lookup.vue', () => {
|
||||||
|
|
||||||
useMainStore().order.vehicle.carId = 'CARID';
|
useMainStore().order.vehicle.carId = 'CARID';
|
||||||
|
|
||||||
let carsFound = [
|
const carsFound = [
|
||||||
{
|
{
|
||||||
vin: 'TEST_VIN2',
|
vin: 'TEST_VIN2',
|
||||||
vehicle: {
|
vehicle: {
|
||||||
|
|
@ -168,12 +239,10 @@ describe('license-plate-lookup.vue', () => {
|
||||||
await wrapper.vm.navigateForward(carsFound);
|
await wrapper.vm.navigateForward(carsFound);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||||
navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
|
||||||
undefined,
|
undefined,
|
||||||
{},
|
{},
|
||||||
{ displayVehicleChangeAlert: true }
|
{ displayVehicleChangeAlert: true });
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -184,103 +253,15 @@ describe('license-plate-lookup.vue', () => {
|
||||||
useMainStore().order.vehicle.carId = 'CR00000395';
|
useMainStore().order.vehicle.carId = 'CR00000395';
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
licensePlateLookup.beforeRouteEnter.call(
|
licensePlateLookup.beforeRouteEnter.call(wrapper.vm,
|
||||||
wrapper.vm,
|
|
||||||
{ query: { issPage: 'license-plate-lookup' } },
|
{ query: { issPage: 'license-plate-lookup' } },
|
||||||
undefined,
|
undefined,
|
||||||
(c) => c(wrapper.vm)
|
(c) => c(wrapper.vm));
|
||||||
);
|
|
||||||
|
|
||||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
const arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(arePagePrerequisitesValid).toBe(true);
|
expect(arePagePrerequisitesValid).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
isZipValid = true,
|
|
||||||
isZipServiceable = true,
|
|
||||||
lookupVinByPlateResponse,
|
|
||||||
partsOrQuestions = [],
|
|
||||||
vehicle = {},
|
|
||||||
vin = null,
|
|
||||||
carId = 'C0000',
|
|
||||||
vinLookupResponseError = null,
|
|
||||||
route = null
|
|
||||||
}) {
|
|
||||||
useMainStore().validateZip = jest.fn().mockImplementation(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
data: {
|
|
||||||
isValid: isZipValid,
|
|
||||||
isServiceable: isZipServiceable
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
useMainStore().lookupVinByPlate = jest.fn().mockImplementation(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
data: lookupVinByPlateResponse
|
|
||||||
? lookupVinByPlateResponse : {
|
|
||||||
vin: 'TEST_VIN',
|
|
||||||
vehicle: {
|
|
||||||
carId: 'CARID'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
useMainStore().getPartsOrQuestions = jest.fn().mockImplementation(() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
data: {
|
|
||||||
partsOrQuestions: partsOrQuestions
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const wrapper = shallowMount(
|
|
||||||
licensePlateLookup,
|
|
||||||
getMountOptions({
|
|
||||||
route: route ? route : undefined,
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn()
|
|
||||||
},
|
|
||||||
mainStore: {
|
|
||||||
order: {
|
|
||||||
vehicle: {
|
|
||||||
carId: carId,
|
|
||||||
registration: {
|
|
||||||
licensePlate: 'TESTPLATE',
|
|
||||||
zipCode: '12345'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const apiResponses = {
|
|
||||||
serviceZipValidationResponse: {
|
|
||||||
isValid: isZipValid,
|
|
||||||
isServiceable: isZipServiceable
|
|
||||||
},
|
|
||||||
vinLookupResponse: {
|
|
||||||
vin: vin,
|
|
||||||
vehicle: vehicle,
|
|
||||||
error: vinLookupResponseError
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiResponses);
|
|
||||||
|
|
||||||
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => '');
|
|
||||||
wrapper.vm.setCmsContent = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.disableForwardButton = jest.fn();
|
|
||||||
wrapper.vm.$refs.siteFooter.enableForwardButton = jest.fn();
|
|
||||||
|
|
||||||
return { wrapper };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" >
|
<Form
|
||||||
|
ref="theForm"
|
||||||
|
v-slot="{ meta }"
|
||||||
|
@submit="onSubmit"
|
||||||
|
@invalid-submit="onInvalidSubmit">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
<div class="fade-on-route-transition position-relative">
|
<div class="fade-on-route-transition position-relative">
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
|
|
@ -8,57 +12,60 @@
|
||||||
<div class="row px-3">
|
<div class="row px-3">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="select-car-form rounded">
|
<div class="select-car-form rounded">
|
||||||
<vehicleBanner class="mt-2 mb-4" cms-widget-name="VehicleBannerWidget" :display-generic-vehicle-image="false" />
|
<vehicleBanner
|
||||||
<siteSubHeader cms-widget-name="SiteSubHeaderWidget" />
|
class="mt-2 mb-4"
|
||||||
|
cmsWidgetName="VehicleBannerWidget"
|
||||||
|
:displayGenericVehicleImage="false" />
|
||||||
|
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" />
|
||||||
<alert
|
<alert
|
||||||
ref="alertVinNotFound"
|
v-if="displayVinNotFoundAlert"
|
||||||
v-if="displayVinNotFoundAlert"
|
ref="alertVinNotFound"
|
||||||
class="mb-4"
|
class="mb-4"
|
||||||
cmsWidgetName="AlertVinNotFoundWidget"
|
cmsWidgetName="AlertVinNotFoundWidget"
|
||||||
alertClass="alert-danger"
|
alertClass="alert-danger"
|
||||||
v-bind:isDismissible="false" />
|
:isDismissible="false" />
|
||||||
<alert
|
<alert
|
||||||
ref="alertMatchedDifferentVehicle"
|
v-if="displayMatchedDifferentVehicleAlert"
|
||||||
v-if="displayMatchedDifferentVehicleAlert"
|
ref="alertMatchedDifferentVehicle"
|
||||||
class="mb-4"
|
class="mb-4"
|
||||||
cmsWidgetName="AlertMatchedDifferentVehicleWidget"
|
cmsWidgetName="AlertMatchedDifferentVehicleWidget"
|
||||||
:manualHeadline="AlertMatchedDifferentVehicleHeader"
|
:manualHeadline="AlertMatchedDifferentVehicleHeader"
|
||||||
:manualCopy="AlertMatchedDifferentVehicleBody"
|
:manualCopy="AlertMatchedDifferentVehicleBody"
|
||||||
alertClass="alert-warning"
|
alertClass="alert-warning"
|
||||||
v-bind:isDismissible="false" />
|
:isDismissible="false" />
|
||||||
<alert
|
<alert
|
||||||
ref="alertMatchedTwoIdenticalYMMVehicle"
|
v-if="displayMatchedTwoIdenticalYMMVehicleAlert"
|
||||||
v-if="displayMatchedTwoIdenticalYMMVehicleAlert"
|
ref="alertMatchedTwoIdenticalYMMVehicle"
|
||||||
class="mb-4"
|
class="mb-4"
|
||||||
cmsWidgetName="AlertMatchedTwoIdenticalYMMVehicleWidget"
|
cmsWidgetName="AlertMatchedTwoIdenticalYMMVehicleWidget"
|
||||||
:manualHeadline="AlertMatchedTwoIdenticalYMMVehicleHeader"
|
:manualHeadline="AlertMatchedTwoIdenticalYMMVehicleHeader"
|
||||||
:manualCopy="AlertMatchedTwoIdenticalYMMVehicleBody"
|
:manualCopy="AlertMatchedTwoIdenticalYMMVehicleBody"
|
||||||
alertClass="alert-warning"
|
alertClass="alert-warning"
|
||||||
v-bind:isDismissible="false" />
|
:isDismissible="false" />
|
||||||
<textboxQuestion
|
<textboxQuestion
|
||||||
cmsWidgetName="LicensePlateNumberQuestionWidget"
|
id="license-plate-question-wrapper"
|
||||||
v-model="licensePlate"
|
v-model="licensePlate"
|
||||||
isRequired
|
cmsWidgetName="LicensePlateNumberQuestionWidget"
|
||||||
disableAutoFill
|
isRequired
|
||||||
id="license-plate-question-wrapper"
|
disableAutoFill
|
||||||
inputId="license-plate-question"
|
inputId="license-plate-question"
|
||||||
validationRules="license-plate-required" />
|
validationRules="license-plate-required" />
|
||||||
<dropdownQuestion
|
<dropdownQuestion
|
||||||
cmsWidgetName="StateQuestionWidget"
|
ref="state"
|
||||||
v-model="licenseState"
|
v-model="licenseState"
|
||||||
ref="state"
|
cmsWidgetName="StateQuestionWidget"
|
||||||
inputId="8fdf9dc2e13e430eb57529499dceb3eb"
|
inputId="8fdf9dc2e13e430eb57529499dceb3eb"
|
||||||
:options="stateOptions"
|
:options="stateOptions"
|
||||||
disableAutoFill
|
disableAutoFill
|
||||||
validationRules="state-required"
|
validationRules="state-required"
|
||||||
class="mt-4 mb-2"/>
|
class="mt-4 mb-2" />
|
||||||
<siteFooter
|
<siteFooter
|
||||||
class="mt-5"
|
ref="siteFooter"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
class="mt-5"
|
||||||
cms-widget-name="SiteFooterWidget"
|
:isForwardActionDisabled="!meta.valid"
|
||||||
@back-clicked="backButtonAction"
|
cmsWidgetName="SiteFooterWidget"
|
||||||
@forward-clicked="forwardButtonAction"
|
@back-clicked="backButtonAction"
|
||||||
ref="siteFooter" />
|
@forward-clicked="forwardButtonAction" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -75,21 +82,21 @@ import { settleAllPromises } from '@/helpers/layout-helper';
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
import { errorMessages } from '@/constants/error-messages';
|
import { errorMessages } from '@/constants/error-messages';
|
||||||
import { required } from '@/helpers/validation-rules';
|
import { required } from '@/helpers/validation-rules';
|
||||||
import { defineRule } from 'vee-validate';
|
import { defineRule, Form } from 'vee-validate';
|
||||||
import { getDamageString, isGlassAvailableForCarId } from '@/helpers/damage-helper.js';
|
import { getDamageString, isGlassAvailableForCarId } from '@/helpers/damage-helper.js';
|
||||||
import { routerParams } from '@/router/router-params.js'
|
import { routerParams } from '@/router/router-params.js';
|
||||||
import { states } from '@/constants/states';
|
import { states } from '@/constants/states';
|
||||||
|
|
||||||
// Import Component
|
// Import Component
|
||||||
import baseFormMixin from '@/mixins/base-form-mixin';
|
import baseFormMixin from '@/mixins/base-form-mixin';
|
||||||
import vinPagesMixin from '@/mixins/vin-pages-mixin';
|
import vinPagesMixin from '@/mixins/vin-pages-mixin';
|
||||||
import { Form } from 'vee-validate';
|
|
||||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
import siteFooter from '@/iss-components/site-footer/site-footer';
|
||||||
import siteHeader from '@/iss-components/site-header/site-header.vue';
|
import siteHeader from '@/iss-components/site-header/site-header';
|
||||||
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header.vue';
|
import siteSubHeader from '@/iss-components/site-sub-header/site-sub-header';
|
||||||
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner.vue';
|
import vehicleBanner from '@/iss-components/vehicle-banner/vehicle-banner';
|
||||||
import textboxQuestion from '@/digital-components/textbox-question/textbox-question.vue';
|
import textboxQuestion from '@/digital-components/textbox-question/textbox-question';
|
||||||
import dropdownQuestion from '@/digital-components/dropdown-question/dropdown-question.vue';
|
import dropdownQuestion from '@/digital-components/dropdown-question/dropdown-question';
|
||||||
import alert from '@/ux-components/alert/alert';
|
import alert from '@/ux-components/alert/alert';
|
||||||
|
|
||||||
// Define Validation Rules
|
// Define Validation Rules
|
||||||
|
|
@ -98,6 +105,17 @@ defineRule('state-required', required(errorMessages.STATE_REQUIRED));
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'license-plate-lookup',
|
name: 'license-plate-lookup',
|
||||||
|
components: {
|
||||||
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
|
Form,
|
||||||
|
siteFooter,
|
||||||
|
siteHeader,
|
||||||
|
siteSubHeader,
|
||||||
|
vehicleBanner,
|
||||||
|
textboxQuestion,
|
||||||
|
dropdownQuestion,
|
||||||
|
alert
|
||||||
|
},
|
||||||
mixins: [baseFormMixin, vinPagesMixin],
|
mixins: [baseFormMixin, vinPagesMixin],
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
// Call APIs
|
// Call APIs
|
||||||
|
|
@ -134,6 +152,56 @@ export default {
|
||||||
forwardButtonCarStyle: ''
|
forwardButtonCarStyle: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
AlertMatchedDifferentVehicleHeader() {
|
||||||
|
return this.getCmsContent('AlertMatchedDifferentVehicleWidget',
|
||||||
|
'HeadlineText').replaceAll('{custom:damage}', getDamageString());
|
||||||
|
},
|
||||||
|
AlertMatchedDifferentVehicleBody() {
|
||||||
|
const vinYmmFound = `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
|
||||||
|
const vinYmmExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
||||||
|
|
||||||
|
return this.getCmsContent('AlertMatchedDifferentVehicleWidget', 'BodyText')
|
||||||
|
.replaceAll('{custom:damage}', getDamageString())
|
||||||
|
.replaceAll('{custom:vinYmmFound}', vinYmmFound)
|
||||||
|
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
|
||||||
|
},
|
||||||
|
AlertMatchedTwoIdenticalYMMVehicleHeader() {
|
||||||
|
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget',
|
||||||
|
'HeadlineText').replaceAll('{custom:damage}', getDamageString());
|
||||||
|
},
|
||||||
|
AlertMatchedTwoIdenticalYMMVehicleBody() {
|
||||||
|
const vinYmmsFound = `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model} ${this.customAlertData?.vehicleInfo?.style}`;
|
||||||
|
const vinYmmsExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model} ${this.mainStore.order.vehicle.style}`;
|
||||||
|
|
||||||
|
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget', 'BodyText')
|
||||||
|
.replaceAll('{custom:damage}', getDamageString())
|
||||||
|
.replaceAll('{custom:vinYmmsFound}', vinYmmsFound)
|
||||||
|
.replaceAll('{custom:vinYmmsExpected}', vinYmmsExpected);
|
||||||
|
},
|
||||||
|
isTwoIdenticalYMMVehicleFound() {
|
||||||
|
const vinYmmFound = `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
|
||||||
|
const vinYmmExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
||||||
|
return (vinYmmFound.toLowerCase() === vinYmmExpected.toLowerCase());
|
||||||
|
},
|
||||||
|
stateOptions: {
|
||||||
|
get() {
|
||||||
|
return states;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
licensePlate() {
|
||||||
|
this.$refs.siteFooter.updateButtonText(this.getCmsContent('SiteFooterWidget', 'ForwardButtonText'));
|
||||||
|
},
|
||||||
|
registrationZipCode() {
|
||||||
|
this.$refs.siteFooter.updateButtonText(this.getCmsContent('SiteFooterWidget', 'ForwardButtonText'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.attachCustomEvents();
|
||||||
|
this.loadDefaultsFromStore();
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return this.mainStore.order.vehicle.carId !== null;
|
return this.mainStore.order.vehicle.carId !== null;
|
||||||
|
|
@ -147,12 +215,10 @@ export default {
|
||||||
},
|
},
|
||||||
attachCustomEvents() {
|
attachCustomEvents() {
|
||||||
this.prependActionToMethod(this, this.forwardButtonAction, () => {
|
this.prependActionToMethod(this, this.forwardButtonAction, () => {
|
||||||
this.pushEventToGA(
|
this.pushEventToGA(this.$route.query[this.queryStrings.ISS_PAGE],
|
||||||
this.$route.query[this.queryStrings.ISS_PAGE],
|
|
||||||
this.GaActions.SUBMITTED,
|
this.GaActions.SUBMITTED,
|
||||||
this.GaLabels.LICENSE_PLATE_LOOKUP,
|
this.GaLabels.LICENSE_PLATE_LOOKUP,
|
||||||
true
|
true);
|
||||||
);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
// NOTE: If form is not valid, this method is not called when 'Continue' button is clicked
|
// NOTE: If form is not valid, this method is not called when 'Continue' button is clicked
|
||||||
|
|
@ -160,8 +226,7 @@ export default {
|
||||||
this.resetWarningsAndErrors();
|
this.resetWarningsAndErrors();
|
||||||
|
|
||||||
// Lookup VIN
|
// Lookup VIN
|
||||||
const vinLookupResponse = await useMainStore().lookupVinByPlate(
|
const vinLookupResponse = await useMainStore().lookupVinByPlate(this.licensePlate, this.licenseState);
|
||||||
this.licensePlate, this.licenseState);
|
|
||||||
|
|
||||||
// Settle promises and get results
|
// Settle promises and get results
|
||||||
const promiseResultMap = [
|
const promiseResultMap = [
|
||||||
|
|
@ -178,33 +243,31 @@ export default {
|
||||||
this.displayVinNotFoundAlert = true;
|
this.displayVinNotFoundAlert = true;
|
||||||
this.$refs.siteFooter.disableForwardButton();
|
this.$refs.siteFooter.disableForwardButton();
|
||||||
return this.$refs.siteFooter.removeLoader();
|
return this.$refs.siteFooter.removeLoader();
|
||||||
};
|
}
|
||||||
|
|
||||||
// Vehicle found from VIN lookup
|
// Vehicle found from VIN lookup
|
||||||
const vehicleFromLookup = resultMap.vinLookupResponse.vehicle;
|
const vehicleFromLookup = resultMap.vinLookupResponse.vehicle;
|
||||||
|
|
||||||
// Check if the CarId has changed
|
// Check if the CarId has changed
|
||||||
this.isCarIdDifferent =
|
this.isCarIdDifferent
|
||||||
vehicleFromLookup.carId !== useMainStore().order.vehicle.carId;
|
= vehicleFromLookup.carId !== useMainStore().order.vehicle.carId;
|
||||||
// Handle changing car
|
// Handle changing car
|
||||||
if (
|
if (
|
||||||
this.isCarIdDifferent &&
|
this.isCarIdDifferent
|
||||||
vehicleFromLookup.carId !== this.previouslyEnteredCarId
|
&& vehicleFromLookup.carId !== this.previouslyEnteredCarId
|
||||||
) {
|
) {
|
||||||
// Display Alert
|
// Display Alert
|
||||||
this.previouslyEnteredCarId = vehicleFromLookup.carId;
|
this.previouslyEnteredCarId = vehicleFromLookup.carId;
|
||||||
this.customAlertData.vehicleInfo = vehicleFromLookup;
|
this.customAlertData.vehicleInfo = vehicleFromLookup;
|
||||||
|
|
||||||
if (this.isTwoIdenticalYMMVehicleFound){
|
if (this.isTwoIdenticalYMMVehicleFound) {
|
||||||
this.displayMatchedTwoIdenticalYMMVehicleAlert = true;
|
this.displayMatchedTwoIdenticalYMMVehicleAlert = true;
|
||||||
this.forwardButtonCarStyle= vehicleFromLookup.style;
|
this.forwardButtonCarStyle = vehicleFromLookup.style;
|
||||||
} else {
|
} else {
|
||||||
this.displayMatchedDifferentVehicleAlert = true;
|
this.displayMatchedDifferentVehicleAlert = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(
|
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vehicleFromLookup.carId);
|
||||||
vehicleFromLookup.carId
|
|
||||||
);
|
|
||||||
|
|
||||||
// Update button "Continue with..."
|
// Update button "Continue with..."
|
||||||
this.$refs.siteFooter.updateButtonText(`Continue with ${vehicleFromLookup.year} ${vehicleFromLookup.make} ${vehicleFromLookup.model} ${this.forwardButtonCarStyle}`);
|
this.$refs.siteFooter.updateButtonText(`Continue with ${vehicleFromLookup.year} ${vehicleFromLookup.make} ${vehicleFromLookup.model} ${this.forwardButtonCarStyle}`);
|
||||||
|
|
@ -212,17 +275,15 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save vehicle, license plate, and registration information
|
// Save vehicle, license plate, and registration information
|
||||||
await useMainStore().saveRegistrationLicensePlateLookup(
|
await useMainStore().saveRegistrationLicensePlateLookup({
|
||||||
{
|
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
|
||||||
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
|
vehicleInfo: Object.assign(vinLookupResponse.data.vehicle, { vin: vinLookupResponse.data.vin }),
|
||||||
vehicleInfo: Object.assign(vinLookupResponse.data.vehicle, { vin: vinLookupResponse.data.vin }),
|
registrationInfo: {
|
||||||
registrationInfo: {
|
licensePlate: this.licensePlate,
|
||||||
licensePlate: this.licensePlate,
|
state: this.licenseState
|
||||||
state: this.licenseState
|
}
|
||||||
}
|
},
|
||||||
},
|
false);
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
return await this.navigateForward();
|
return await this.navigateForward();
|
||||||
},
|
},
|
||||||
|
|
@ -230,12 +291,10 @@ export default {
|
||||||
// If a different vehicle is found than the one entered and the selected glass is not available for that vehicle then navigate back to "vehicle-damage"
|
// If a different vehicle is found than the one entered and the selected glass is not available for that vehicle then navigate back to "vehicle-damage"
|
||||||
// display vehicle changed alert on that page.
|
// display vehicle changed alert on that page.
|
||||||
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
|
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
|
||||||
this.$router.navigate(
|
this.$router.navigate(this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||||
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
|
||||||
this.$route,
|
this.$route,
|
||||||
{},
|
{},
|
||||||
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
|
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true });
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
await this.navigateForwardWithSingleCarMatch();
|
await this.navigateForwardWithSingleCarMatch();
|
||||||
}
|
}
|
||||||
|
|
@ -244,79 +303,11 @@ export default {
|
||||||
this.displayVinNotFoundAlert = false;
|
this.displayVinNotFoundAlert = false;
|
||||||
this.displayMatchedDifferentVehicleAlert = false;
|
this.displayMatchedDifferentVehicleAlert = false;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.attachCustomEvents();
|
|
||||||
this.loadDefaultsFromStore();
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
AlertMatchedDifferentVehicleHeader() {
|
|
||||||
return this.getCmsContent(
|
|
||||||
'AlertMatchedDifferentVehicleWidget',
|
|
||||||
'HeadlineText'
|
|
||||||
).replaceAll('{custom:damage}', getDamageString());
|
|
||||||
},
|
|
||||||
AlertMatchedDifferentVehicleBody() {
|
|
||||||
const vinYmmFound = `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
|
|
||||||
const vinYmmExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
|
||||||
|
|
||||||
return this.getCmsContent('AlertMatchedDifferentVehicleWidget', 'BodyText')
|
|
||||||
.replaceAll('{custom:damage}', getDamageString())
|
|
||||||
.replaceAll('{custom:vinYmmFound}', vinYmmFound)
|
|
||||||
.replaceAll('{custom:vinYmmExpected}', vinYmmExpected);
|
|
||||||
},
|
|
||||||
AlertMatchedTwoIdenticalYMMVehicleHeader() {
|
|
||||||
return this.getCmsContent(
|
|
||||||
'AlertMatchedTwoIdenticalYMMVehicleWidget',
|
|
||||||
'HeadlineText'
|
|
||||||
).replaceAll('{custom:damage}', getDamageString());
|
|
||||||
},
|
|
||||||
AlertMatchedTwoIdenticalYMMVehicleBody() {
|
|
||||||
const vinYmmsFound = `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model} ${this.customAlertData?.vehicleInfo?.style}`;
|
|
||||||
const vinYmmsExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model} ${this.mainStore.order.vehicle.style}`;
|
|
||||||
|
|
||||||
return this.getCmsContent('AlertMatchedTwoIdenticalYMMVehicleWidget', 'BodyText')
|
|
||||||
.replaceAll('{custom:damage}', getDamageString())
|
|
||||||
.replaceAll('{custom:vinYmmsFound}', vinYmmsFound)
|
|
||||||
.replaceAll('{custom:vinYmmsExpected}', vinYmmsExpected);
|
|
||||||
},
|
|
||||||
isTwoIdenticalYMMVehicleFound() {
|
|
||||||
const vinYmmFound = `${this.customAlertData?.vehicleInfo?.year} ${this.customAlertData?.vehicleInfo?.make} ${this.customAlertData?.vehicleInfo?.model}`;
|
|
||||||
const vinYmmExpected = `${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
|
||||||
return (vinYmmFound.toLowerCase()==vinYmmExpected.toLowerCase());
|
|
||||||
},
|
|
||||||
stateOptions: {
|
|
||||||
get: function () {
|
|
||||||
return states;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
licensePlate() {
|
|
||||||
this.$refs.siteFooter.updateButtonText(
|
|
||||||
this.getCmsContent('SiteFooterWidget', 'ForwardButtonText')
|
|
||||||
);
|
|
||||||
},
|
|
||||||
registrationZipCode() {
|
|
||||||
this.$refs.siteFooter.updateButtonText(
|
|
||||||
this.getCmsContent('SiteFooterWidget', 'ForwardButtonText')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
Form,
|
|
||||||
siteFooter,
|
|
||||||
siteHeader,
|
|
||||||
siteSubHeader,
|
|
||||||
vehicleBanner,
|
|
||||||
textboxQuestion,
|
|
||||||
dropdownQuestion,
|
|
||||||
alert
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
#license-plate-question-wrapper .form-test-error {
|
#license-plate-question-wrapper .form-test-error {
|
||||||
/**
|
/**
|
||||||
Override extra margin-bottom in the error message in TextboxQuestion
|
Override extra margin-bottom in the error message in TextboxQuestion
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ import moldingQuestions from '@/layouts/molding-questions/molding-questions';
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
import { getMountOptions } from '@/helpers/unit-test-helper.js';
|
||||||
import { useMainStore } from '@/store';
|
import { useMainStore } from '@/store';
|
||||||
import baseMixin from '../../mixins/base-mixin';
|
|
||||||
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
|
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
|
||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
|
import baseMixin from '@/mixins/base-mixin';
|
||||||
|
|
||||||
// Mock our module for promises.
|
// Mock our module for promises.
|
||||||
jest.mock('@/helpers/layout-helper.js', () => ({
|
jest.mock('@/helpers/layout-helper.js', () => ({
|
||||||
|
|
@ -19,79 +19,136 @@ jest.mock('@/helpers/cms-content-helper', () => ({
|
||||||
fetchCmsContentForPage: jest.fn()
|
fetchCmsContentForPage: jest.fn()
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const baseStoreGettersPageData = () => {
|
function setupMocks({
|
||||||
return {
|
mountOptionsMockData = {
|
||||||
partsOrQuestions: [
|
router: {
|
||||||
|
navigate: jest.fn()
|
||||||
|
},
|
||||||
|
actionList: [
|
||||||
{
|
{
|
||||||
parts: [
|
actionName: 'saveMoldingQuestionAnswers',
|
||||||
{
|
data: {}
|
||||||
childPartQuestions: [
|
},
|
||||||
{
|
{
|
||||||
questionSequence: 1,
|
actionName: 'getPartsOrQuestions',
|
||||||
questionText:
|
data: {}
|
||||||
'Does the rubber seal around your windshield have a chrome strip running through it?',
|
|
||||||
answers: [
|
|
||||||
{
|
|
||||||
answerResult: 'WKT D1106 C',
|
|
||||||
answerText: 'Yes',
|
|
||||||
nextQuestionSequence: null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
answerResult: 'WKT D1106 B',
|
|
||||||
answerText: 'No',
|
|
||||||
nextQuestionSequence: null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
basePartNumber: 'DW01105',
|
|
||||||
color: 'Green Tint, Blue Shade',
|
|
||||||
requiresRecalibration: false,
|
|
||||||
recalibrationType: '',
|
|
||||||
canSafeliteRecalibrate: false,
|
|
||||||
requiresCapabilityQuestions: false,
|
|
||||||
childParts: null,
|
|
||||||
partNumber: 'DW01105GBNN',
|
|
||||||
description: 'solar',
|
|
||||||
partType: 'WINDSHIELD'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
partQuestions: [],
|
|
||||||
glassLocation: 'Windshield',
|
|
||||||
glassName: 'Single',
|
|
||||||
answerKey: 'Windshield-Single',
|
|
||||||
answerData: null
|
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
};
|
route: {
|
||||||
};
|
query: {
|
||||||
const baseStoreGettersDamage = () => {
|
issPage: 'molding-questions'
|
||||||
return {
|
}
|
||||||
partsQuestionAnswers: [
|
},
|
||||||
{
|
data() {
|
||||||
glassLocation: 'Windshield',
|
return {
|
||||||
glassName: 'Single',
|
computedSwitcher: [
|
||||||
result: 'FW04848',
|
|
||||||
answeredQuestions: [
|
|
||||||
{
|
{
|
||||||
questionText:
|
glassLocation: 'Windshield',
|
||||||
'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?',
|
glassName: 'Single',
|
||||||
selectedAnswer: '1|nextQuestion|3|Yes',
|
answerData: {
|
||||||
selectedAnswerText: 'Yes',
|
answerResult: 'FW04848',
|
||||||
questionNum: 1
|
answeredQuestions: []
|
||||||
},
|
}
|
||||||
{
|
|
||||||
questionText:
|
|
||||||
'Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?',
|
|
||||||
selectedAnswer: '2|nextQuestion|3|Yes',
|
|
||||||
selectedAnswerText: 'Yes',
|
|
||||||
questionNum: 2
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
questionsData: {
|
||||||
|
get() {
|
||||||
|
return this.computedSwitcher;
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.computedSwitcher = val;
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
};
|
}
|
||||||
};
|
}) {
|
||||||
|
useMainStore().getPartsOrQuestions = jest.fn(() => ({
|
||||||
|
data: {
|
||||||
|
partsOrQuestions: []
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
const mountOptions = getMountOptions({
|
||||||
|
...mountOptionsMockData,
|
||||||
|
mixins: [baseMixin, vehicleQuestionsMixin]
|
||||||
|
});
|
||||||
|
mountOptions.attachTo = document.body;
|
||||||
|
|
||||||
|
const wrapper = shallowMount(moldingQuestions, mountOptions);
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseStoreGettersPageData = () => ({
|
||||||
|
partsOrQuestions: [
|
||||||
|
{
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
childPartQuestions: [
|
||||||
|
{
|
||||||
|
questionSequence: 1,
|
||||||
|
questionText:
|
||||||
|
'Does the rubber seal around your windshield have a chrome strip running through it?',
|
||||||
|
answers: [
|
||||||
|
{
|
||||||
|
answerResult: 'WKT D1106 C',
|
||||||
|
answerText: 'Yes',
|
||||||
|
nextQuestionSequence: null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
answerResult: 'WKT D1106 B',
|
||||||
|
answerText: 'No',
|
||||||
|
nextQuestionSequence: null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
basePartNumber: 'DW01105',
|
||||||
|
color: 'Green Tint, Blue Shade',
|
||||||
|
requiresRecalibration: false,
|
||||||
|
recalibrationType: '',
|
||||||
|
canSafeliteRecalibrate: false,
|
||||||
|
requiresCapabilityQuestions: false,
|
||||||
|
childParts: null,
|
||||||
|
partNumber: 'DW01105GBNN',
|
||||||
|
description: 'solar',
|
||||||
|
partType: 'WINDSHIELD'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
partQuestions: [],
|
||||||
|
glassLocation: 'Windshield',
|
||||||
|
glassName: 'Single',
|
||||||
|
answerKey: 'Windshield-Single',
|
||||||
|
answerData: null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
const baseStoreGettersDamage = () => ({
|
||||||
|
partsQuestionAnswers: [
|
||||||
|
{
|
||||||
|
glassLocation: 'Windshield',
|
||||||
|
glassName: 'Single',
|
||||||
|
result: 'FW04848',
|
||||||
|
answeredQuestions: [
|
||||||
|
{
|
||||||
|
questionText:
|
||||||
|
'Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?',
|
||||||
|
selectedAnswer: '1|nextQuestion|3|Yes',
|
||||||
|
selectedAnswerText: 'Yes',
|
||||||
|
questionNum: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
questionText:
|
||||||
|
'Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?',
|
||||||
|
selectedAnswer: '2|nextQuestion|3|Yes',
|
||||||
|
selectedAnswerText: 'Yes',
|
||||||
|
questionNum: 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
useMainStore().pageData = baseStoreGettersPageData;
|
useMainStore().pageData = baseStoreGettersPageData;
|
||||||
useMainStore().damage = baseStoreGettersDamage;
|
useMainStore().damage = baseStoreGettersDamage;
|
||||||
|
|
@ -114,9 +171,7 @@ describe('moldingQuestions.vue', () => {
|
||||||
test('Should return false for valid page requisites if partsOrQuestions in pageData is missing', () => {
|
test('Should return false for valid page requisites if partsOrQuestions in pageData is missing', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
useMainStore().pageData = jest.fn(() => {
|
useMainStore().pageData = jest.fn(() => undefined);
|
||||||
return undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const result = wrapper.vm.arePagePrerequisitesValid();
|
const result = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
@ -129,11 +184,9 @@ describe('moldingQuestions.vue', () => {
|
||||||
|
|
||||||
test('Should be at least one item in partsOrQuestions', () => {
|
test('Should be at least one item in partsOrQuestions', () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
useMainStore().pageData = jest.fn(() => {
|
useMainStore().pageData = jest.fn(() => ({
|
||||||
return {
|
partsOrQuestions: []
|
||||||
partsOrQuestions: []
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
useMainStore().damage = baseStoreGettersDamage;
|
useMainStore().damage = baseStoreGettersDamage;
|
||||||
|
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
@ -207,13 +260,11 @@ describe('moldingQuestions.vue', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
wrapper.vm.dispatchStoreAction = jest.fn(() => {
|
wrapper.vm.dispatchStoreAction = jest.fn(() => ({
|
||||||
return {
|
data: {
|
||||||
data: {
|
partsOrQuestions: []
|
||||||
partsOrQuestions: []
|
}
|
||||||
}
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
wrapper.vm.forwardButtonAction();
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
@ -238,13 +289,11 @@ describe('moldingQuestions.vue', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
useMainStore().getPartsOrQuestions = jest.fn(() => {
|
useMainStore().getPartsOrQuestions = jest.fn(() => ({
|
||||||
return {
|
data: {
|
||||||
data: {
|
partsOrQuestions: []
|
||||||
partsOrQuestions: []
|
}
|
||||||
}
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
wrapper.vm.forwardButtonAction();
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
@ -270,13 +319,11 @@ describe('moldingQuestions.vue', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
useMainStore().getPartsOrQuestions = jest.fn(() => {
|
useMainStore().getPartsOrQuestions = jest.fn(() => ({
|
||||||
return {
|
data: {
|
||||||
data: {
|
partsOrQuestions: []
|
||||||
partsOrQuestions: []
|
}
|
||||||
}
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
wrapper.vm.forwardButtonAction();
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
@ -303,13 +350,11 @@ describe('moldingQuestions.vue', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
useMainStore().getPartsOrQuestions = jest.fn(() => {
|
useMainStore().getPartsOrQuestions = jest.fn(() => ({
|
||||||
return {
|
data: {
|
||||||
data: {
|
partsOrQuestions: []
|
||||||
partsOrQuestions: []
|
}
|
||||||
}
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
wrapper.vm.navigateForward = jest.fn();
|
wrapper.vm.navigateForward = jest.fn();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -322,66 +367,3 @@ describe('moldingQuestions.vue', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
mountOptionsMockData = {
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn()
|
|
||||||
},
|
|
||||||
actionList: [
|
|
||||||
{
|
|
||||||
actionName: 'saveMoldingQuestionAnswers',
|
|
||||||
data: {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
actionName: 'getPartsOrQuestions',
|
|
||||||
data: {}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
route: {
|
|
||||||
query: {
|
|
||||||
issPage: 'molding-questions'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
computedSwitcher: [
|
|
||||||
{
|
|
||||||
glassLocation: 'Windshield',
|
|
||||||
glassName: 'Single',
|
|
||||||
answerData: {
|
|
||||||
answerResult: 'FW04848',
|
|
||||||
answeredQuestions: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
},
|
|
||||||
questionsData: {
|
|
||||||
get() {
|
|
||||||
return this.computedSwitcher;
|
|
||||||
},
|
|
||||||
set(val) {
|
|
||||||
this.computedSwitcher = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
useMainStore().getPartsOrQuestions = jest.fn(() => {
|
|
||||||
return {
|
|
||||||
data: {
|
|
||||||
partsOrQuestions: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
...mountOptionsMockData,
|
|
||||||
mixins: [baseMixin, vehicleQuestionsMixin]
|
|
||||||
});
|
|
||||||
mountOptions['attachTo'] = document.body;
|
|
||||||
|
|
||||||
const wrapper = shallowMount(moldingQuestions, mountOptions);
|
|
||||||
|
|
||||||
return { wrapper };
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<Form
|
<Form
|
||||||
@submit="onSubmit"
|
|
||||||
@invalidSubmit="onInvalidSubmit"
|
|
||||||
ref="theForm"
|
ref="theForm"
|
||||||
v-slot="{ meta }"
|
v-slot="{ meta }"
|
||||||
>
|
@submit="onSubmit"
|
||||||
|
@invalidSubmit="onInvalidSubmit">
|
||||||
<questionsPageLayout
|
<questionsPageLayout
|
||||||
isRequired
|
id="molding-question-wrapper"
|
||||||
ref="questionsPageLayout"
|
ref="questionsPageLayout"
|
||||||
|
v-model="selectedAnswers"
|
||||||
|
isRequired
|
||||||
:isMetaValid="meta.valid"
|
:isMetaValid="meta.valid"
|
||||||
:alertFewMoreQuestionsHeader="AlertFewMoreQuestionsHeader"
|
:alertFewMoreQuestionsHeader="AlertFewMoreQuestionsHeader"
|
||||||
:alertFewMoreQuestionsCopy="AlertFewMoreQuestionsCopy"
|
:alertFewMoreQuestionsCopy="AlertFewMoreQuestionsCopy"
|
||||||
:questionsData="questionsData"
|
:questionsData="questionsData"
|
||||||
:validationRules="rules.optionRequired"
|
:validationRules="rules.optionRequired"
|
||||||
v-model="selectedAnswers"
|
|
||||||
@forwardButtonAction="forwardButtonAction"
|
|
||||||
@back-click="navigateBack"
|
|
||||||
:index="currentGlassIndex"
|
:index="currentGlassIndex"
|
||||||
id="molding-question-wrapper"
|
@forwardButtonAction="forwardButtonAction"
|
||||||
/>
|
@back-click="navigateBack" />
|
||||||
</Form>
|
</Form>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -33,10 +31,15 @@ import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||||
|
|
||||||
// Import Component
|
// Import Component
|
||||||
import { Form } from 'vee-validate';
|
import { Form } from 'vee-validate';
|
||||||
import questionsPageLayout from '@/iss-components/questions-page-layout/questions-page-layout.vue';
|
import questionsPageLayout from '@/iss-components/questions-page-layout/questions-page-layout';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'molding-questions',
|
name: 'molding-questions',
|
||||||
|
components: {
|
||||||
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
|
Form,
|
||||||
|
questionsPageLayout
|
||||||
|
},
|
||||||
mixins: [BaseFormMixin, vehicleQuestionsMixin],
|
mixins: [BaseFormMixin, vehicleQuestionsMixin],
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
|
@ -67,10 +70,8 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
AlertFewMoreQuestionsHeader() {
|
AlertFewMoreQuestionsHeader() {
|
||||||
return this.getCmsContent(
|
return this.getCmsContent('AdditionalPartsQuestionsAlert',
|
||||||
'AdditionalPartsQuestionsAlert',
|
'HeadlineText');
|
||||||
'HeadlineText'
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
AlertFewMoreQuestionsCopy() {
|
AlertFewMoreQuestionsCopy() {
|
||||||
return this.getCmsContent('AdditionalPartsQuestionsAlert', 'BodyText');
|
return this.getCmsContent('AdditionalPartsQuestionsAlert', 'BodyText');
|
||||||
|
|
@ -85,62 +86,48 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
const moldingQuestionsFromPageData = useMainStore().pageData(
|
const moldingQuestionsFromPageData = useMainStore().pageData(issPageValues.MOLDING_QUESTIONS);
|
||||||
issPageValues.MOLDING_QUESTIONS
|
|
||||||
);
|
|
||||||
return (
|
return (
|
||||||
// has childPartQuestions array and has glassName not null
|
// has childPartQuestions array and has glassName not null
|
||||||
moldingQuestionsFromPageData?.partsOrQuestions?.some(
|
moldingQuestionsFromPageData?.partsOrQuestions?.some((part) => part?.glassName)
|
||||||
(part) => part?.glassName
|
&& moldingQuestionsFromPageData.partsOrQuestions.some((glass) => glass.parts?.some((part) => part?.childPartQuestions?.length > 0))
|
||||||
) &&
|
|
||||||
moldingQuestionsFromPageData.partsOrQuestions.some((glass) =>
|
|
||||||
glass.parts?.some((part) => part?.childPartQuestions?.length > 0)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
getInitialQuestionData() {
|
getInitialQuestionData() {
|
||||||
// get any questions that were already answered
|
// get any questions that were already answered
|
||||||
const alreadyAnsweredQuestions =
|
const alreadyAnsweredQuestions
|
||||||
useMainStore().damage.moldingQuestionAnswers;
|
= useMainStore().damage.moldingQuestionAnswers;
|
||||||
this.questionsData = this.partsOrQuestionsData
|
this.questionsData = this.partsOrQuestionsData
|
||||||
.filter((x) => x.parts[0].childPartQuestions.length)
|
.filter((x) => x.parts[0].childPartQuestions.length)
|
||||||
.map((glass, index) => {
|
.map((glass, index) => {
|
||||||
// NOTE: questions for property "questions" can differ between layouts
|
// NOTE: questions for property "questions" can differ between layouts
|
||||||
glass.questions = glass.parts[0].childPartQuestions;
|
glass.questions = glass.parts[0].childPartQuestions;
|
||||||
glass.answerKey = glass.glassLocation + '-' + glass.glassName;
|
glass.answerKey = `${glass.glassLocation}-${glass.glassName}`;
|
||||||
// reset selectedAnswers for this glass
|
// reset selectedAnswers for this glass
|
||||||
this.selectedAnswers[glass.answerKey] = [];
|
this.selectedAnswers[glass.answerKey] = [];
|
||||||
const updatedGlass = this.setupInitialData(
|
const updatedGlass = this.setupInitialData(glass,
|
||||||
glass,
|
|
||||||
index,
|
index,
|
||||||
alreadyAnsweredQuestions
|
alreadyAnsweredQuestions);
|
||||||
);
|
|
||||||
// Set up watch for each set of glass questions
|
// Set up watch for each set of glass questions
|
||||||
this.$watch(
|
this.$watch(`selectedAnswers.${glass.answerKey}`,
|
||||||
'selectedAnswers.' + glass.answerKey,
|
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
if (newValue && Object.keys(newValue).length > 0) {
|
if (newValue && Object.keys(newValue).length > 0) {
|
||||||
this.handleAnswerUpdates(
|
this.handleAnswerUpdates(newValue,
|
||||||
newValue,
|
glass.answerKey);
|
||||||
glass.answerKey
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true });
|
||||||
);
|
|
||||||
return updatedGlass;
|
return updatedGlass;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async forwardButtonAction() {
|
async forwardButtonAction() {
|
||||||
const questionAnswersArray = this.questionsData.map((glass) => {
|
const questionAnswersArray = this.questionsData.map((glass) => ({
|
||||||
return {
|
glassLocation: glass.glassLocation,
|
||||||
glassLocation: glass.glassLocation,
|
glassName: glass.glassName,
|
||||||
glassName: glass.glassName,
|
partNum: glass.answerData.answerResult,
|
||||||
partNum: glass.answerData.answerResult,
|
answeredQuestions: glass.answerData.answeredQuestions,
|
||||||
answeredQuestions: glass.answerData.answeredQuestions,
|
isSuppressedPart: glass.isSuppressedPart
|
||||||
isSuppressedPart: glass.isSuppressedPart
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
// clear out answerData for future page loads; must occur prior to store save
|
// clear out answerData for future page loads; must occur prior to store save
|
||||||
this.questionsData.forEach((glass) => {
|
this.questionsData.forEach((glass) => {
|
||||||
glass.answerData = {};
|
glass.answerData = {};
|
||||||
|
|
@ -149,14 +136,12 @@ export default {
|
||||||
await this.mainStore.saveMoldingQuestionAnswers(questionAnswersArray);
|
await this.mainStore.saveMoldingQuestionAnswers(questionAnswersArray);
|
||||||
|
|
||||||
// get parts from the questionAnswers
|
// get parts from the questionAnswers
|
||||||
let partsOrQuestions = this.partsOrQuestionsData;
|
const partsOrQuestions = this.partsOrQuestionsData;
|
||||||
for (let answer of questionAnswersArray) {
|
for (const answer of questionAnswersArray) {
|
||||||
partsOrQuestions.find((partOrQuestion) => {
|
partsOrQuestions.find((partOrQuestion) => (
|
||||||
return (
|
partOrQuestion.glassLocation === answer.glassLocation
|
||||||
partOrQuestion.glassLocation === answer.glassLocation &&
|
&& partOrQuestion.glassName === answer.glassName
|
||||||
partOrQuestion.glassName === answer.glassName
|
)).parts[0].childParts = [
|
||||||
);
|
|
||||||
}).parts[0].childParts = [
|
|
||||||
{
|
{
|
||||||
partNumber: answer.partNum
|
partNumber: answer.partNum
|
||||||
}
|
}
|
||||||
|
|
@ -165,15 +150,11 @@ export default {
|
||||||
|
|
||||||
this.navigateForward(partsOrQuestions, null);
|
this.navigateForward(partsOrQuestions, null);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
components: {
|
|
||||||
Form,
|
|
||||||
questionsPageLayout
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
#molding-question-wrapper p.text-body.small {
|
#molding-question-wrapper p.text-body.small {
|
||||||
margin-bottom: 0 !important; // Overrides extra margin-bottom on alert body text
|
margin-bottom: 0 !important; // Overrides extra margin-bottom on alert body text
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }" >
|
<Form
|
||||||
|
ref="theForm"
|
||||||
|
v-slot="{ meta }"
|
||||||
|
@submit="onSubmit"
|
||||||
|
@invalid-submit="onInvalidSubmit">
|
||||||
<div class="page-container-grouped-styles">
|
<div class="page-container-grouped-styles">
|
||||||
<div class="fade-on-route-transition position-relative">
|
<div class="fade-on-route-transition position-relative">
|
||||||
<siteHeader cmsWidgetName="SiteHeaderWidget"/>
|
<siteHeader cmsWidgetName="SiteHeaderWidget" />
|
||||||
<div class="container-fluid pb-2">
|
<div class="container-fluid pb-2">
|
||||||
<p>Placeholder for order confirmation page</p>
|
<p>Placeholder for order confirmation page</p>
|
||||||
<siteFooter
|
<siteFooter
|
||||||
cmsWidgetName="SiteFooterWidget"
|
|
||||||
ref="siteFooter"
|
ref="siteFooter"
|
||||||
|
cmsWidgetName="SiteFooterWidget"
|
||||||
:isForwardActionDisabled="!meta.valid"
|
:isForwardActionDisabled="!meta.valid"
|
||||||
@ForwardClicked="forwardButtonAction"
|
@ForwardClicked="forwardButtonAction"
|
||||||
@back-clicked="backButtonAction"
|
@back-clicked="backButtonAction" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -26,8 +29,15 @@ import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||||
import { settleAllPromises } from '@/helpers/layout-helper';
|
import { settleAllPromises } from '@/helpers/layout-helper';
|
||||||
import { Form } from 'vee-validate';
|
import { Form } from 'vee-validate';
|
||||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'order-confirmation',
|
name: 'order-confirmation',
|
||||||
|
components: {
|
||||||
|
siteHeader,
|
||||||
|
siteFooter,
|
||||||
|
// eslint-disable-next-line vue/no-reserved-component-names
|
||||||
|
Form
|
||||||
|
},
|
||||||
mixins: [BaseFormMixin],
|
mixins: [BaseFormMixin],
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
// Call APIs
|
// Call APIs
|
||||||
|
|
@ -39,7 +49,7 @@ export default {
|
||||||
promise: cmsContentPromise
|
promise: cmsContentPromise
|
||||||
}];
|
}];
|
||||||
// use resultMap to populate layout content.
|
// use resultMap to populate layout content.
|
||||||
let resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
});
|
});
|
||||||
|
|
@ -53,16 +63,9 @@ export default {
|
||||||
return this.navigateForward();
|
return this.navigateForward();
|
||||||
},
|
},
|
||||||
navigateForward() {
|
navigateForward() {
|
||||||
this.$router.navigate(
|
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD,
|
||||||
this.navigationScenarios.CLICKED_FORWARD,
|
this.$route);
|
||||||
this.$route
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
components: {
|
};
|
||||||
siteHeader,
|
|
||||||
siteFooter,
|
|
||||||
Form
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue