Merge branch 'develop' into feature/CSR-1855
This commit is contained in:
commit
93a9f5ff5f
13 changed files with 502 additions and 55 deletions
|
|
@ -24,12 +24,13 @@ module.exports = {
|
||||||
"!src/layouts/review/*.vue", // Temp test exclusion while in development
|
"!src/layouts/review/*.vue", // Temp test exclusion while in development
|
||||||
"!src/layouts/payment/*.vue", // Temp test exclusion while in development
|
"!src/layouts/payment/*.vue", // Temp test exclusion while in development
|
||||||
"!src/layouts/payment-pia-return/*.vue", // Temp test exclusion while in development
|
"!src/layouts/payment-pia-return/*.vue", // Temp test exclusion while in development
|
||||||
|
"!src/layouts/insurance/*.vue", // Temp test exclusion while in development
|
||||||
// END
|
// END
|
||||||
], // ! means exclude from coverage.
|
], // ! means exclude from coverage.
|
||||||
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
|
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
|
||||||
coverageThreshold: {
|
coverageThreshold: {
|
||||||
global: {
|
global: {
|
||||||
statements: 78,
|
statements: 77,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Uncomment this to avoid the massive amount of warnings we are getting for onSubmit and onInvalidSubmit
|
// Uncomment this to avoid the massive amount of warnings we are getting for onSubmit and onInvalidSubmit
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,11 @@
|
||||||
:maxlength="maxLength ? maxLength : '999'"
|
:maxlength="maxLength ? maxLength : '999'"
|
||||||
@focus="$emit('focus', $event.target.value)"
|
@focus="$emit('focus', $event.target.value)"
|
||||||
@keydown="keyDownHandler" />
|
@keydown="keyDownHandler" />
|
||||||
<button v-if="includeSearchIcon" type="submit" aria-label="Search button" />
|
<button
|
||||||
|
v-if="includeSearchIcon"
|
||||||
|
type="submit"
|
||||||
|
aria-label="Search button"
|
||||||
|
@click="focusSearchInput" />
|
||||||
<template v-if="includeImageQuestion">
|
<template v-if="includeImageQuestion">
|
||||||
<template v-if="!isDisabled">
|
<template v-if="!isDisabled">
|
||||||
<label class="camera-icon-input" v-show="!isImageProcessing">
|
<label class="camera-icon-input" v-show="!isImageProcessing">
|
||||||
|
|
@ -169,6 +173,11 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
focusSearchInput() {
|
||||||
|
//Focus cursor in input when search icon is clicked
|
||||||
|
const field = document.querySelector("input");
|
||||||
|
field.focus();
|
||||||
|
},
|
||||||
async imageChanged(e) {
|
async imageChanged(e) {
|
||||||
let file = e.target.files[0];
|
let file = e.target.files[0];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ export default {
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.menu-modal-container {
|
.menu-modal-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 1.47rem 1rem 1.47rem 1.47rem;
|
padding: 1.47rem 0 1.47rem 1.47rem;
|
||||||
right: 0;
|
right: 0;
|
||||||
button {
|
button {
|
||||||
border: none;
|
border: none;
|
||||||
|
|
@ -186,7 +186,7 @@ export default {
|
||||||
}
|
}
|
||||||
.menu-modal-container {
|
.menu-modal-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 1.47rem 1rem 1.47rem 1.47rem;
|
padding: 1.47rem 0 1.47rem 1.47rem;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: -5rem;
|
top: -5rem;
|
||||||
button {
|
button {
|
||||||
|
|
|
||||||
3
src/layouts/insurance/insurance.spec.js
Normal file
3
src/layouts/insurance/insurance.spec.js
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
describe("insurance", () => {
|
||||||
|
it.todo("Should render a normal string");
|
||||||
|
});
|
||||||
326
src/layouts/insurance/insurance.vue
Normal file
326
src/layouts/insurance/insurance.vue
Normal file
|
|
@ -0,0 +1,326 @@
|
||||||
|
<template>
|
||||||
|
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm" v-slot="{ meta }">
|
||||||
|
<loadingModal ref="loadingModal" />
|
||||||
|
<div class="container-fluid page-container-grouped-styles">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<funnelHeader cmsWidgetName="FunnelHeaderWidget" ref="funnelHeader" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-6 col-xl-4">
|
||||||
|
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" class="mt-4" />
|
||||||
|
|
||||||
|
<textboxQuestion
|
||||||
|
class="mb-2 mt-5"
|
||||||
|
cmsWidgetName="InsuranceCoQuestionWidget"
|
||||||
|
includeSearchIcon
|
||||||
|
cornerStyle="rounded" />
|
||||||
|
|
||||||
|
<navbar
|
||||||
|
cmsWidgetName="FunnelFooterWidget"
|
||||||
|
ref="navbar"
|
||||||
|
:isForwardActionDisabled="!meta.valid"
|
||||||
|
@back-clicked="backButtonAction"
|
||||||
|
@ForwardClicked="forwardButtonAction" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Components
|
||||||
|
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
||||||
|
import navbar from "@/fmg-components/nav-bar/nav-bar";
|
||||||
|
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
||||||
|
import textboxQuestion from "@/digital-components/textbox-question/textbox-question";
|
||||||
|
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
|
||||||
|
|
||||||
|
// Supporting files
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
|
import { errorMessages } from "@/constants/error-messages";
|
||||||
|
import {
|
||||||
|
getDamageString,
|
||||||
|
getIsWindshieldOnly,
|
||||||
|
isGlassAvailableForCarId,
|
||||||
|
} from "@/helpers/damage-helper";
|
||||||
|
import { required, regex } from "@/helpers/validation-rules";
|
||||||
|
import { Form, defineRule } from "vee-validate";
|
||||||
|
import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
||||||
|
import { routerParams } from "@/router/router-constants/router-params";
|
||||||
|
|
||||||
|
import store from "@/store";
|
||||||
|
import vinPagesMixin from "@/mixins/vin-pages-mixin";
|
||||||
|
|
||||||
|
// DEFINE VALIDATION RULES
|
||||||
|
defineRule("zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED));
|
||||||
|
defineRule("zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT));
|
||||||
|
defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIRED));
|
||||||
|
defineRule(
|
||||||
|
"email-address-format",
|
||||||
|
regex(
|
||||||
|
/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$/,
|
||||||
|
errorMessages.EMAIL_ADDRESS_FORMAT
|
||||||
|
)
|
||||||
|
);
|
||||||
|
defineRule("vin-required", required(errorMessages.VIN_REQUIRED));
|
||||||
|
defineRule("vin-format", regex(/^[a-hA-Hj-nJ-NpPr-zR-Z0-9]{17}$/, errorMessages.VIN_FORMAT));
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "insurance",
|
||||||
|
mixins: [vinPagesMixin],
|
||||||
|
async beforeRouteEnter(to, from, next) {
|
||||||
|
// Call APIs
|
||||||
|
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
||||||
|
|
||||||
|
// Settle promises and get results
|
||||||
|
const promiseResultMap = [
|
||||||
|
{
|
||||||
|
resultKey: "cmsContent",
|
||||||
|
promise: cmsContentPromise,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
||||||
|
// Call the "next" function to complete the transition to this page.
|
||||||
|
next((vm) => {
|
||||||
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
vin: this.getVinFromStore(),
|
||||||
|
serviceZipCode: this.getZipFromStore() ?? this.$route.query.zipcode,
|
||||||
|
emailAddress: this.getEmailFromStore(),
|
||||||
|
isCarIdDifferent: false,
|
||||||
|
customAlertData: {},
|
||||||
|
previouslyEnteredCarId: "",
|
||||||
|
vinPopulatedOnPageLoad: this.getVinFromStore()?.length > 0,
|
||||||
|
isSelectedGlassAvailableForVehicle: true,
|
||||||
|
displayInvalidZipAlert: false,
|
||||||
|
displayNonServiceableZipAlert: false,
|
||||||
|
displayVinNotFoundAlert: false,
|
||||||
|
displayMatchedDifferentVehicleAlert: false,
|
||||||
|
displayVinScanFailedAlert: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
arePagePrerequisitesValid() {
|
||||||
|
return store.getters.vehicle.carId !== null;
|
||||||
|
},
|
||||||
|
getEmailFromStore() {
|
||||||
|
return this.$store.getters.order.customer.emailAddress;
|
||||||
|
},
|
||||||
|
getVinFromStore() {
|
||||||
|
return this.$store.getters.vehicle.vin;
|
||||||
|
},
|
||||||
|
getZipFromStore() {
|
||||||
|
return this.$store.getters.order.serviceLocation.zipCode;
|
||||||
|
},
|
||||||
|
attachCustomEvents() {
|
||||||
|
this.prependActionToMethod(this, this.forwardButtonAction, () => {
|
||||||
|
this.pushEventToGA(
|
||||||
|
this.$route.query[this.queryStrings.FMG_PAGE],
|
||||||
|
this.GaActions.SUBMITTED,
|
||||||
|
this.GaLabels.VIN_LOOKUP,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
backButtonAction() {
|
||||||
|
// route to move backwards
|
||||||
|
this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||||
|
},
|
||||||
|
async forwardButtonAction() {
|
||||||
|
this.resetAlerts();
|
||||||
|
|
||||||
|
// If this is a new VIN Lookup, do both a Vehicle Lookup and a Zip Validation
|
||||||
|
if (!this.vinPopulatedOnPageLoad) {
|
||||||
|
const vehicleLookupResponse = this.dispatchStoreActionWithLogging(
|
||||||
|
storeActions.LOOKUP_VEHICLE_BY_VIN,
|
||||||
|
{ vin: this.vin },
|
||||||
|
"vin-lookup"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Settle promises and get results
|
||||||
|
const promiseResultMap = [
|
||||||
|
{
|
||||||
|
resultKey: "vehicleLookupResponse",
|
||||||
|
promise: vehicleLookupResponse,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resultKey: "zipCodeData",
|
||||||
|
promise: this.getZipCodeData(this.serviceZipCode),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
||||||
|
// If a Service Zip is entered and it is an invalid zip code (ex. 11111) then show an alert
|
||||||
|
const isZipValid = resultMap.zipCodeData.isValid;
|
||||||
|
if (this.serviceZipCode && !isZipValid) {
|
||||||
|
this.displayInvalidZipAlert = true;
|
||||||
|
return this.$refs.navbar.removeLoader();
|
||||||
|
}
|
||||||
|
this.displayInvalidZipAlert = false;
|
||||||
|
|
||||||
|
// If either lookup fails, remove the loader and stop processing the page.
|
||||||
|
if (!resultMap.vehicleLookupResponse || !resultMap.zipCodeData.isServiceable) {
|
||||||
|
// If the vehicle result is undefined, the vin entered was invalid.
|
||||||
|
if (!resultMap.vehicleLookupResponse) {
|
||||||
|
this.displayVinNotFoundAlert = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if Service Zip entered is serviceable, if not display an alert
|
||||||
|
if (!resultMap.zipCodeData.isServiceable) {
|
||||||
|
this.displayNonServiceableZipAlert = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove loader and stop processing the page.
|
||||||
|
return this.$refs.navbar.removeLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the CarId is different from the lookup vs what is in state currently.
|
||||||
|
this.isCarIdDifferent =
|
||||||
|
resultMap.vehicleLookupResponse.carId !== this.$store.getters.vehicle.carId;
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.isCarIdDifferent &&
|
||||||
|
resultMap.vehicleLookupResponse.carId !== this.previouslyEnteredCarId
|
||||||
|
) {
|
||||||
|
this.previouslyEnteredCarId = resultMap.vehicleLookupResponse.carId;
|
||||||
|
this.customAlertData.vehicleInfo = resultMap.vehicleLookupResponse;
|
||||||
|
this.displayMatchedDifferentVehicleAlert = true;
|
||||||
|
|
||||||
|
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(
|
||||||
|
resultMap.vehicleLookupResponse.carId,
|
||||||
|
"vin-lookup"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update button "Continue with..."
|
||||||
|
this.$refs.navbar.updateButtonText(
|
||||||
|
`Continue with ${resultMap.vehicleLookupResponse.year} ${resultMap.vehicleLookupResponse.make} ${resultMap.vehicleLookupResponse.model}`
|
||||||
|
);
|
||||||
|
return this.$refs.navbar.removeLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save vin, vehicle, customer and service information
|
||||||
|
await this.dispatchStoreAction(
|
||||||
|
storeActions.SAVE_VIN_LOOKUP,
|
||||||
|
{
|
||||||
|
isSelectedGlassAvailableForVehicle: this.isSelectedGlassAvailableForVehicle,
|
||||||
|
vehicleInfo: Object.assign(resultMap.vehicleLookupResponse, {
|
||||||
|
vin: this.vin,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailAddress, false);
|
||||||
|
await this.dispatchStoreAction(
|
||||||
|
storeActions.SAVE_SERVICE_ZIP_CODE_INFO,
|
||||||
|
{
|
||||||
|
state: resultMap.zipCodeData.state,
|
||||||
|
zipCode: this.serviceZipCode,
|
||||||
|
zipCodeCtu: resultMap.zipCodeData.zipCodeCtu,
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
return await this.navigateForward();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a VIN has already been found. Validate the Service Zip (in case of changes)
|
||||||
|
const zipCodeData = await this.getZipCodeData(this.serviceZipCode);
|
||||||
|
|
||||||
|
// Check if Service Zip entered is serviceable then save the ZIP info
|
||||||
|
if (zipCodeData.isServiceable) {
|
||||||
|
//Only save the zipCode, state, and zipCodeCtu if the zip changed or we lack zipCodeCtu
|
||||||
|
if (
|
||||||
|
this.$store.getters.order.serviceLocation.zipCode != this.serviceZipCode ||
|
||||||
|
!this.$store.getters.order.serviceLocation.zipCodeCtu
|
||||||
|
) {
|
||||||
|
await this.dispatchStoreAction(
|
||||||
|
storeActions.SAVE_SERVICE_ZIP_CODE_INFO,
|
||||||
|
{
|
||||||
|
state: zipCodeData.state,
|
||||||
|
zipCode: this.serviceZipCode,
|
||||||
|
zipCodeCtu: zipCodeData.zipCodeCtu,
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailAddress, false);
|
||||||
|
|
||||||
|
return await this.navigateForward();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the Service Zip is NOT serviceable then show an alert
|
||||||
|
if (zipCodeData.isValid) {
|
||||||
|
this.displayNonServiceableZipAlert = true;
|
||||||
|
} else {
|
||||||
|
this.displayInvalidZipAlert = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.$refs.navbar.removeLoader();
|
||||||
|
},
|
||||||
|
async navigateForward() {
|
||||||
|
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
|
||||||
|
this.$router.navigateWithSaving(
|
||||||
|
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||||
|
this.$route,
|
||||||
|
{},
|
||||||
|
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await this.navigateForwardWithSingleCarMatch();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
displayVinScanAlert() {
|
||||||
|
this.displayVinScanFailedAlert = true;
|
||||||
|
},
|
||||||
|
getVinFromImage(image) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.dispatchStoreActionWithLogging(
|
||||||
|
storeActions.LOOKUP_VIN_BY_IMAGE,
|
||||||
|
image,
|
||||||
|
"vin-lookup"
|
||||||
|
)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.data.length > 0) {
|
||||||
|
resolve(response.data[0]);
|
||||||
|
} else {
|
||||||
|
reject("No VINs detected.");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
reject("An error occurred during the lookup.");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resetAlerts() {
|
||||||
|
this.displayMatchedDifferentVehicleAlert = false;
|
||||||
|
this.displayNonServiceableZipAlert = false;
|
||||||
|
this.displayInvalidZipAlert = false;
|
||||||
|
this.displayVinNotFoundAlert = false;
|
||||||
|
this.displayVinScanFailedAlert = false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.attachCustomEvents();
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
funnelHeader,
|
||||||
|
navbar,
|
||||||
|
funnelSubHeader,
|
||||||
|
textboxQuestion,
|
||||||
|
Form,
|
||||||
|
loadingModal,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -512,7 +512,7 @@ describe("payment.vue", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("handleIFrameContentWindwMessage", () => {
|
describe("handleIFrameContentWindowMessage", () => {
|
||||||
test("Navigates back if afterpay is closed", () => {
|
test("Navigates back if afterpay is closed", () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const event = {
|
const event = {
|
||||||
|
|
@ -524,7 +524,7 @@ describe("payment.vue", () => {
|
||||||
wrapper.vm.backButtonAction = jest.fn();
|
wrapper.vm.backButtonAction = jest.fn();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
wrapper.vm.handleIFrameContentWindwMessage(event);
|
wrapper.vm.handleIFrameContentWindowMessage(event);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.backButtonAction).toBeCalled();
|
expect(wrapper.vm.backButtonAction).toBeCalled();
|
||||||
|
|
@ -539,7 +539,7 @@ describe("payment.vue", () => {
|
||||||
const wrapper = setupMocks({});
|
const wrapper = setupMocks({});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
wrapper.vm.handleIFrameContentWindwMessage(event);
|
wrapper.vm.handleIFrameContentWindowMessage(event);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.shouldBlockInteraction).toBe(true);
|
expect(wrapper.vm.shouldBlockInteraction).toBe(true);
|
||||||
|
|
|
||||||
|
|
@ -643,17 +643,19 @@ export default {
|
||||||
|
|
||||||
this.submitHopForm();
|
this.submitHopForm();
|
||||||
},
|
},
|
||||||
handleIFrameContentWindwMessage(event) {
|
handleIFrameContentWindowMessage(event) {
|
||||||
if (event.data.indexOf("afterpayClosed") > -1) {
|
if (typeof event.data === "string") {
|
||||||
this.backButtonAction();
|
if (event.data.indexOf("afterpayClosed") > -1) {
|
||||||
}
|
this.backButtonAction();
|
||||||
if (event.data.indexOf("creditCardSubmit") > -1) {
|
}
|
||||||
this.setUIBlock(true);
|
if (event.data.indexOf("creditCardSubmit") > -1) {
|
||||||
|
this.setUIBlock(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setIFrameListener() {
|
setIFrameListener() {
|
||||||
window.addEventListener("message", (event) =>
|
window.addEventListener("message", (event) =>
|
||||||
this.handleIFrameContentWindwMessage(event)
|
this.handleIFrameContentWindowMessage(event)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
setUIBlock(val) {
|
setUIBlock(val) {
|
||||||
|
|
|
||||||
|
|
@ -140,42 +140,6 @@ describe("quote.vue", () => {
|
||||||
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
|
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("IsInsurance true should navigateToHeritageFunnel", async () => {
|
|
||||||
//Arrange
|
|
||||||
store.getters = {
|
|
||||||
payment: {
|
|
||||||
insuranceCoverage: {},
|
|
||||||
isInsurance: true,
|
|
||||||
},
|
|
||||||
order: {
|
|
||||||
lineItems: [],
|
|
||||||
payment: {
|
|
||||||
parentAccountNumber: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const { wrapper } = setupMocks({
|
|
||||||
customMountOptions: {
|
|
||||||
router: {
|
|
||||||
navigateWithSaving: jest.fn(),
|
|
||||||
},
|
|
||||||
route: { quote },
|
|
||||||
mixins: [mockMixin],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
wrapper.vm.dispatchStoreAction = jest.fn(() => {
|
|
||||||
return {
|
|
||||||
data: [],
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
await wrapper.vm.forwardButtonAction();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(navigateToHeritage.navigateToHeritageFunnel).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
test("should pass arePagePrerequisitesValid with a repair order", () => {
|
test("should pass arePagePrerequisitesValid with a repair order", () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
store.getters = {
|
store.getters = {
|
||||||
|
|
|
||||||
|
|
@ -327,11 +327,10 @@ export default {
|
||||||
|
|
||||||
const payment = this.$store.getters.payment;
|
const payment = this.$store.getters.payment;
|
||||||
if (payment.isInsurance) {
|
if (payment.isInsurance) {
|
||||||
navigateToHeritageFunnel({
|
this.$router.navigateWithSaving(
|
||||||
shouldSaveSession: true,
|
this.navigationScenarios.CLICKED_FORWARD_WITH_INSURANCE,
|
||||||
pageNameToLog: "quote",
|
this.$route
|
||||||
loadingModal: this.$refs.loadingModal,
|
);
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
this.$router.navigateWithSaving(
|
this.$router.navigateWithSaving(
|
||||||
this.navigationScenarios.CLICKED_FORWARD_WITH_CASH,
|
this.navigationScenarios.CLICKED_FORWARD_WITH_CASH,
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ const fmgPageValues = {
|
||||||
ESTIMATE: "estimate",
|
ESTIMATE: "estimate",
|
||||||
ADDRESS_VEHICLES: "address-vehicles",
|
ADDRESS_VEHICLES: "address-vehicles",
|
||||||
QUOTE: "quote",
|
QUOTE: "quote",
|
||||||
|
INSURANCE: "insurance",
|
||||||
SERVICE_LOCATION: "service-location",
|
SERVICE_LOCATION: "service-location",
|
||||||
HERITAGE: "heritage",
|
HERITAGE: "heritage",
|
||||||
SCHEDULE: "schedule",
|
SCHEDULE: "schedule",
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ const navigationScenarios = {
|
||||||
CLICKED_BACK: "CLICKED_BACK",
|
CLICKED_BACK: "CLICKED_BACK",
|
||||||
CLICKED_FORWARD: "CLICKED_FORWARD",
|
CLICKED_FORWARD: "CLICKED_FORWARD",
|
||||||
CLICKED_FORWARD_WITH_CASH: "CLICKED_FORWARD_WITH_CASH",
|
CLICKED_FORWARD_WITH_CASH: "CLICKED_FORWARD_WITH_CASH",
|
||||||
|
CLICKED_FORWARD_WITH_INSURANCE: "CLICKED_FORWARD_WITH_INSURANCE",
|
||||||
|
|
||||||
// Vin selection
|
// Vin selection
|
||||||
CLICKED_BACK_WITH_VIN: "CLICKED_BACK_WITH_VIN",
|
CLICKED_BACK_WITH_VIN: "CLICKED_BACK_WITH_VIN",
|
||||||
|
|
|
||||||
|
|
@ -389,6 +389,23 @@ const routingTable = function (store) {
|
||||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CASH,
|
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CASH,
|
||||||
destinationFmgPageValue: fmgPageValues.SERVICE_LOCATION,
|
destinationFmgPageValue: fmgPageValues.SERVICE_LOCATION,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_FORWARD_WITH_INSURANCE,
|
||||||
|
destinationFmgPageValue: fmgPageValues.INSURANCE,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fmgPageValue: fmgPageValues.INSURANCE,
|
||||||
|
maps: [
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_BACK,
|
||||||
|
destinationFmgPageValue: fmgPageValues.QUOTE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||||
|
destinationFmgPageValue: fmgPageValues.SCHEDULE,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2929,6 +2929,130 @@ describe("Actions", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe("validateOrderPromoAndSaveServerData", () => {
|
describe("validateOrderPromoAndSaveServerData", () => {
|
||||||
|
it("should add GUIDs if not there to provided lineItemsToUse.vaps before sending the http call", async () => {
|
||||||
|
// Arrange
|
||||||
|
const context = state;
|
||||||
|
const promoCode = "testPromo";
|
||||||
|
const lineItemsToUse = { vaps: [{ partNumber: 1 }], promos: [2] };
|
||||||
|
const addableVaps = [{ partNumber: "addableVap" }];
|
||||||
|
|
||||||
|
context["getters"] = {
|
||||||
|
order: {
|
||||||
|
serviceLocation: {
|
||||||
|
appointmentType: "test",
|
||||||
|
state: "test",
|
||||||
|
zipCodeCtu: "test",
|
||||||
|
},
|
||||||
|
vehicle: {
|
||||||
|
carId: "test",
|
||||||
|
year: "test",
|
||||||
|
},
|
||||||
|
referralCorrelationId: "test",
|
||||||
|
eon: "test",
|
||||||
|
damage: {
|
||||||
|
isRepair: true,
|
||||||
|
glassToReplace: null,
|
||||||
|
},
|
||||||
|
payment: {
|
||||||
|
parentAccountNumber: "test",
|
||||||
|
},
|
||||||
|
referralSequenceNumber: "test",
|
||||||
|
lineItems: {
|
||||||
|
serverData: "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
globalMethods.callHttpClient = jest.fn().mockResolvedValue({
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
crypto.randomUUID = jest.fn(() => "GUID");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
actions.validateOrderPromoAndSaveServerData(context, {
|
||||||
|
payload: {
|
||||||
|
promoCode: promoCode,
|
||||||
|
lineItemsToUse: lineItemsToUse,
|
||||||
|
addableVaps: addableVaps,
|
||||||
|
},
|
||||||
|
pageNameToLog: "test",
|
||||||
|
});
|
||||||
|
|
||||||
|
const firstCallArgs = globalMethods.callHttpClient.mock.calls[0];
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
const vapsItem = firstCallArgs[0].payload.order.lineItemsOnOrder.filter(
|
||||||
|
(item) => item.partNumber == 1
|
||||||
|
)[0];
|
||||||
|
expect(vapsItem.id).toEqual("GUID");
|
||||||
|
});
|
||||||
|
it("should not duplicate ids during syncing if there are two identical vaps items", async () => {
|
||||||
|
// Arrange
|
||||||
|
const context = state;
|
||||||
|
const promoCode = "testPromo";
|
||||||
|
// AddableVaps will sync its ids to vaps already on the order
|
||||||
|
const lineItemsToUse = {
|
||||||
|
vaps: [
|
||||||
|
{ partNumber: "SBB22", id: "GUID1" },
|
||||||
|
{ partNumber: "SBB22", id: "GUID2" },
|
||||||
|
],
|
||||||
|
promos: [2],
|
||||||
|
};
|
||||||
|
const addableVaps = [{ partNumber: "SBB22" }, { partNumber: "SBB22" }];
|
||||||
|
|
||||||
|
context["getters"] = {
|
||||||
|
order: {
|
||||||
|
serviceLocation: {
|
||||||
|
appointmentType: "test",
|
||||||
|
state: "test",
|
||||||
|
zipCodeCtu: "test",
|
||||||
|
},
|
||||||
|
vehicle: {
|
||||||
|
carId: "test",
|
||||||
|
year: "test",
|
||||||
|
},
|
||||||
|
referralCorrelationId: "test",
|
||||||
|
eon: "test",
|
||||||
|
damage: {
|
||||||
|
isRepair: true,
|
||||||
|
glassToReplace: null,
|
||||||
|
},
|
||||||
|
payment: {
|
||||||
|
parentAccountNumber: "test",
|
||||||
|
},
|
||||||
|
referralSequenceNumber: "test",
|
||||||
|
lineItems: {
|
||||||
|
serverData: "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
globalMethods.callHttpClient = jest.fn().mockResolvedValue({
|
||||||
|
data: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
crypto.randomUUID = jest.fn(() => "GUID");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
actions.validateOrderPromoAndSaveServerData(context, {
|
||||||
|
payload: {
|
||||||
|
promoCode: promoCode,
|
||||||
|
lineItemsToUse: lineItemsToUse,
|
||||||
|
addableVaps: addableVaps,
|
||||||
|
},
|
||||||
|
pageNameToLog: "test",
|
||||||
|
});
|
||||||
|
|
||||||
|
const firstCallArgs = globalMethods.callHttpClient.mock.calls[0];
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
const vapsItems = firstCallArgs[0].payload.addableVaps.filter(
|
||||||
|
(item) => item.partNumber == "SBB22"
|
||||||
|
);
|
||||||
|
expect(vapsItems[1].id).toEqual("GUID1");
|
||||||
|
expect(vapsItems[0].id).toEqual("GUID2");
|
||||||
|
});
|
||||||
it("should add GUIDs if not there to provided addableVaps before sending the http call", async () => {
|
it("should add GUIDs if not there to provided addableVaps before sending the http call", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const context = state;
|
const context = state;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue