diff --git a/jest.config.js b/jest.config.js
index c5309b45d..a73aac7ea 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -20,9 +20,8 @@ module.exports = {
"!src/layouts/reveal/**/*.vue",
"!src/layouts/estimate/**/*.vue",
// TODO REMOVE THESE AFTER WRITING UNIT TESTS
- "!src/layouts/address-vehicles/address-vehicles.vue",
"!src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue",
- "!src/ux-components/alert\alert.vue",
+ "!src/ux-components/alert/alert.vue",
"!src/helpers/validation-rules.js",
// END
], // ! means exclude from coverage.
diff --git a/src/layouts/address-lookup/address-lookup.spec.js b/src/layouts/address-lookup/address-lookup.spec.js
index d1f261f9a..c66ead3c7 100644
--- a/src/layouts/address-lookup/address-lookup.spec.js
+++ b/src/layouts/address-lookup/address-lookup.spec.js
@@ -48,9 +48,9 @@ describe("address-lookup.vue", () => {
await wrapper.vm.forwardButtonAction();
// Assert
- expect(wrapper.findComponent({ ref: "alertNonServiceableZip" }).isVisible()).toBe(true);
- });
-
+ expect(wrapper.findComponent({ ref: "alertNonServiceableZip" }).isVisible()).toBe(true);
+ });
+
test("if the address matches a different vehicle display the Matched Different VehicleAlert", async () => {
// Arrange
const mockRegistrationAddress = {
@@ -76,8 +76,8 @@ describe("address-lookup.vue", () => {
await wrapper.vm.forwardButtonAction();
// Assert
- expect(wrapper.findComponent({ ref: "alertMatchedDifferentVehicle" }).isVisible()).toBe(true);
- });
+ expect(wrapper.findComponent({ ref: "alertMatchedDifferentVehicle" }).isVisible()).toBe(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 () => {
// Arrange
@@ -121,7 +121,7 @@ describe("address-lookup.vue", () => {
}
return Promise.resolve({ data });
- })
+ })
await wrapper.setData({
customerQuestions: {
@@ -133,7 +133,7 @@ describe("address-lookup.vue", () => {
await wrapper.vm.forwardButtonAction();
// Assert
- expect(wrapper.findComponent({ ref: "alertVinLookupsByHomeAddressNotAllowed" }).isVisible()).toBe(true);
+ expect(wrapper.findComponent({ ref: "alertVinLookupsByHomeAddressNotAllowed" }).isVisible()).toBe(true);
});
@@ -169,7 +169,7 @@ describe("address-lookup.vue", () => {
return Promise.resolve({ data });
- })
+ })
await wrapper.setData({
customerQuestions: {
@@ -183,13 +183,13 @@ describe("address-lookup.vue", () => {
await wrapper.vm.forwardButtonAction();
// Assert
- expect(wrapper.findComponent({ ref: "alertVinNotFound" }).isVisible()).toBe(true);
+ expect(wrapper.findComponent({ ref: "alertVinNotFound" }).isVisible()).toBe(true);
});
- });
+ });
describe("navigation", () => {
-
+
test("if the back button is clicked, navigate back", async () => {
// Arrange
const { wrapper } = setupMocks(addressLookup, {
@@ -197,7 +197,7 @@ describe("address-lookup.vue", () => {
});
// Act
- await wrapper.vm.backButtonAction();
+ await wrapper.vm.backButtonAction();
// Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
@@ -246,7 +246,7 @@ describe("address-lookup.vue", () => {
}
return Promise.resolve({ data });
- })
+ })
await wrapper.setData({
customerQuestions: {
@@ -261,7 +261,7 @@ describe("address-lookup.vue", () => {
// Assert
expect(wrapper.vm.navigateForward).toHaveBeenCalled();
- });
+ });
test("if the car entered matches one of multiple vehicles found, update vehicle info and navigate to the heritage funnel", async () => {
// Arrange
@@ -306,7 +306,7 @@ describe("address-lookup.vue", () => {
return Promise.resolve({ data });
- })
+ })
await wrapper.setData({
customerQuestions: {
@@ -322,8 +322,7 @@ describe("address-lookup.vue", () => {
// Assert
expect(wrapper.vm.updateVehicleInfo).toHaveBeenCalled();
expect(navigateAfterSaveToHeritageFunnel).toHaveBeenCalled();
-
- });
+ });
test("if the car entered does not match any of the multiple vehicles found, navigate to address-vehicles page", async () => {
// Arrange
@@ -368,20 +367,20 @@ describe("address-lookup.vue", () => {
return Promise.resolve({ data });
- })
-
+ })
+
const carsFound = [{
- vin: "TEST_VIN",
- vehicle: {
- carId: "CARID"
- }
- },
- {
- vin: "TEST_VIN2",
- vehicle: {
- carId: "CARID2"
- }
- }]
+ vin: "TEST_VIN",
+ vehicle: {
+ carId: "CARID"
+ }
+ },
+ {
+ vin: "TEST_VIN2",
+ vehicle: {
+ carId: "CARID2"
+ }
+ }]
await wrapper.setData({
customerQuestions: {
@@ -396,8 +395,7 @@ describe("address-lookup.vue", () => {
// Assert
expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledWith(navigationScenarios.CONTINUING_WITH_MULTIPLE_VEHICLES, undefined, {}, {}, carsFound);
-
- });
+ });
test("if the car entered matches one of the vehicles found but the zip is NOT serviceable, do not navigate forward", async () => {
// Arrange
@@ -442,7 +440,7 @@ describe("address-lookup.vue", () => {
return Promise.resolve({ data });
- })
+ })
await wrapper.setData({
customerQuestions: {
@@ -458,7 +456,7 @@ describe("address-lookup.vue", () => {
// Assert
expect(wrapper.vm.navigateForward).toHaveBeenCalledTimes(0);
- });
+ });
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 () => {
// Arrange
@@ -492,7 +490,7 @@ describe("address-lookup.vue", () => {
return Promise.resolve({ data });
- })
+ })
await wrapper.setData({
customerQuestions: {
@@ -520,13 +518,74 @@ describe("address-lookup.vue", () => {
await wrapper.vm.navigateForward(carEntered, carsFound);
// Assert
- expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledWith(navigationScenarios.CONTINUING_WITH_DIFFERENT_GLASS, undefined, {}, {"displayVehicleChangeAlert": true}, {});
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, undefined, {}, { "displayVehicleChangeAlert": true }, {});
});
+ test("single car was found and matches entered vehicle => navigateForwardWithSingleCarMatch", async () => {
+ // Arrange
+ const carEntered = {
+ carId: "CARID2"
+ };
+
+ const carsFound = [
+ {
+ vin: "TEST_VIN_2",
+ vehicle: {
+ carId: "CARID2"
+ }
+ }
+ ];
+
+ const { wrapper } = setupMocks({}, {});
+ wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
+
+ // Act
+ wrapper.vm.navigateForward(carEntered, carsFound);
+
+ // Assert
+ expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalledTimes(1);
+ });
+
+ test("multiple cars were found and one matches entered vehicle => navigateForwardWithSingleCarMatch", async () => {
+ // Arrange
+ const carEntered = {
+ carId: "CARID2"
+ };
+
+ const carsFound = [
+ {
+ vin: "TEST_VIN_1",
+ vehicle: {
+ carId: "CARID1"
+ }
+ },
+ {
+ vin: "TEST_VIN_2",
+ vehicle: {
+ carId: "CARID2"
+ }
+ },
+ {
+ vin: "TEST_VIN_3",
+ vehicle: {
+ carId: "CARID3"
+ }
+ }
+ ];
+
+ const { wrapper } = setupMocks({}, {});
+ wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
+
+ // Act
+ wrapper.vm.navigateForward(carEntered, carsFound);
+
+ // Assert
+ expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalledTimes(1);
+ });
});
- describe("reseting dependent state", () => {
+ describe("resetting dependent state", () => {
test("when reseting dependent state, license plate is set to null and parts state and dependencies are reset", async () => {
// Arrange
const commitSpy = jest.spyOn(store, "commit");
@@ -544,7 +603,7 @@ describe("address-lookup.vue", () => {
});
});
-
+
describe("registration and service zips", () => {
describe("if registration zip is serviceable", () => {
test("if registration address is provided => update service address on successful continue", async () => {
@@ -556,7 +615,7 @@ describe("address-lookup.vue", () => {
zipCode: "43215"
}
- const { wrapper } = setupMocks(addressLookup,{
+ const { wrapper } = setupMocks(addressLookup, {
isZipServiceable: true
});
@@ -572,7 +631,7 @@ describe("address-lookup.vue", () => {
await wrapper.vm.forwardButtonAction();
// Assert
- expect(baseMixin.methods.dispatchStoreAction).toHaveBeenCalledWith(storeActions.UPDATE_SERVICE_LOCATION_WITH_VEHICLE_REGISTRATION);
+ expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalledWith(storeActions.UPDATE_SERVICE_LOCATION_WITH_VEHICLE_REGISTRATION);
});
});
@@ -619,8 +678,8 @@ describe("address-lookup.vue", () => {
}
const { wrapper } = setupMocks(addressLookup, {
- isZipServiceable: false
- }
+ isZipServiceable: false
+ }
);
expect(wrapper.vm.showServiceZipField).toBeFalsy();
@@ -651,8 +710,8 @@ describe("address-lookup.vue", () => {
}
const { wrapper } = setupMocks(addressLookup, {
- isZipServiceable: false
- }
+ isZipServiceable: false
+ }
);
store.commit(storeMutations.UPDATE_CAR_ID, "CARID");
@@ -735,7 +794,7 @@ describe("address-lookup.vue", () => {
});
});
-function setupMocks(mountOptions, { isZipServiceable = true, lookupVinbyAddressResponse }) {
+function setupMocks(mountOptions, { isZipServiceable = true, lookupVinbyAddressResponse, partsOrQuestions = [] }) {
store.commit(storeMutations.RESET_STATE);
const wrapper = shallowMount(addressLookup, getMountOptions({
...mountOptions,
@@ -757,7 +816,13 @@ function setupMocks(mountOptions, { isZipServiceable = true, lookupVinbyAddressR
}
}]
}
- }
+ },
+ {
+ actionName: storeActions.GET_PARTS_OR_QUESTIONS,
+ data: {
+ partsOrQuestions: partsOrQuestions
+ }
+ },
],
router: {
navigate: jest.fn(),
@@ -772,6 +837,5 @@ function setupMocks(mountOptions, { isZipServiceable = true, lookupVinbyAddressR
wrapper.vm.$refs.loadingModal.showModal = jest.fn();
return { wrapper };
-
}
diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue
index 2e13299de..aa5d9fa90 100644
--- a/src/layouts/address-lookup/address-lookup.vue
+++ b/src/layouts/address-lookup/address-lookup.vue
@@ -85,12 +85,14 @@ import { storeMutations } from "@/constants/store-mutations";
import baseMixin from "@/mixins/base-mixin";
import { navigateAfterSaveToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
import { getDamageString, isGlassAvailableForCarId } from "@/helpers/damage-helper";
+import vinPagesMixin from "@/mixins/vin-pages-mixin";
defineRule("service-zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED));
defineRule("service-zip-format", regex(/(^\d{5}$)|(^\d{5}-\d{4}$)/, errorMessages.SERVICE_ZIP_FORMAT));
export default {
name: "address-lookup",
+ mixins: [vinPagesMixin],
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
@@ -291,26 +293,23 @@ export default {
this.$router.navigateAfterSave(
// then navigate back to "vehicle-damage", and display vehicle changed alert
// on that page
- this.navigationScenarios.CONTINUING_WITH_DIFFERENT_GLASS,
+ this.navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS,
this.$route, {}, {
displayVehicleChangeAlert: true
}, {}
);
} else {
// otherwise
- this.$refs.loadingModal.showModal();
- navigateAfterSaveToHeritageFunnel(this.$route);
+ this.navigateForwardWithSingleCarMatch();
}
} else if (carsFound.length > 1) {
// if multiple cars were found
let matchingCars = carsFound.filter(car => car.vehicle.carId === carEntered.carId);
if (matchingCars.length === 1) {
- this.$refs.loadingModal.showModal();
-
// and one and only of them matches the car id entered
const matchingCar = matchingCars[0];
this.updateVehicleInfo(matchingCar.vin, matchingCar.vehicle);
- navigateAfterSaveToHeritageFunnel(this.$route);
+ this.navigateForwardWithSingleCarMatch();
} else {
// if there are no matches or there are multiple matches, navigate to "address-vehicles" page
this.$router.navigateAfterSave(this.navigationScenarios.CONTINUING_WITH_MULTIPLE_VEHICLES, this.$route, {}, {}, carsFound);
@@ -329,8 +328,8 @@ export default {
{
licenseLastName: lastName,
licenseStreetAddress: streetAddress,
- licenseZip: zip,
- licenseState: state,
+ licenseZip: zip,
+ licenseState: state
}, false
);
},
@@ -361,9 +360,7 @@ export default {
const serviceLocation = store.getters.order.serviceLocation;
if (!serviceLocation.address && serviceLocation.zipCode && serviceLocation.zipCode == store.getters.vehicle.registration.zipCode) {
- baseMixin.methods.dispatchStoreAction(
- storeActions.UPDATE_SERVICE_LOCATION_WITH_VEHICLE_REGISTRATION
- );
+ this.dispatchStoreAction(storeActions.UPDATE_SERVICE_LOCATION_WITH_VEHICLE_REGISTRATION);
}
}
},
diff --git a/src/layouts/address-vehicles/address-vehicles.spec.js b/src/layouts/address-vehicles/address-vehicles.spec.js
index 90eeaecbe..0a89f214c 100644
--- a/src/layouts/address-vehicles/address-vehicles.spec.js
+++ b/src/layouts/address-vehicles/address-vehicles.spec.js
@@ -7,7 +7,6 @@ import { getMountOptions } from "@/helpers/unit-test-helper.js";
import store from "@/store";
import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper";
-
// Mock our module for promises.
jest.mock("@/helpers/damage-helper", () => ({
isGlassAvailableForCarId: () => {
@@ -17,7 +16,6 @@ jest.mock("@/helpers/damage-helper", () => ({
describe("addressVehicles.vue", () => {
-
test("Should return true for valid page requisites if carId / zipCode / emailAddress / pageData exists", async () => {
// Arrange
const { wrapper } = setupMocks({});
@@ -225,40 +223,32 @@ describe("addressVehicles.vue", () => {
wrapper.unmount();
});
- test("Should navigate to navigateAfterSaveToHeritageFunnel if carId is not different on navigateForward", async () => {
+ test("carId is not different on navigateForward (car was found) => Should handle navigating forward with car match", async () => {
// Arrange
const { wrapper } = setupMocks({});
wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
wrapper.vm.$refs.loadingModal.showModal = jest.fn();
navigateToHeritage.navigateAfterSaveToHeritageFunnel = jest.fn();
+ wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
// Act
wrapper.setData({
- selectedVehicleVin: ['5NMS3CADXLH233004'],
- isSelectedGlassAvailableForVehicle: true,
isCarIdDifferent: false,
});
await wrapper.vm.navigateForward();
//Assert
- expect(navigateToHeritage.navigateAfterSaveToHeritageFunnel).toBeCalledTimes(1);
+ expect(wrapper.vm.navigateForwardWithSingleCarMatch).toBeCalledTimes(1);
wrapper.unmount();
});
-
});
-
-function setupMocks({
- // modelValueProp = "1900",
- cmsQuestionText = "CMS text goes here",
- // dataFromStoreApi = [],
-}) {
+function setupMocks({}) {
//Mock store
store.dispatch = jest.fn(() => {});
store.getters = {
pageData: jest.fn((pageName) => {
- // console.log('pageName: ', pageName) // address-vehicles
return [
{
vehicle: {
@@ -295,9 +285,6 @@ function setupMocks({
}
};
- // baseMixin.methods.dispatchStoreAction = jest.fn();
-
-
const mountOptions = getMountOptions({
store: {
dispatch: store.dispatch,
@@ -320,16 +307,6 @@ function setupMocks({
}
return null;
}),
- // dispatchStoreAction: jest.fn(() => {
- // console.log("23424243")
- // }),
- // isGlassAvailableForCarId: () => {
- // console.log("%%%%%%%%%%%%%%%")
- // return Promise.resolve(true)
- // }
-
- // lookupVin: jest.fn(() => Promise.resolve(lookupVinResponse)),
-
},
computed: {
dynamicStrings() {
@@ -337,18 +314,10 @@ function setupMocks({
}
}
}
- // mountOptions.propsData = {
- // modelValue: modelValueProp,
- // };
mountOptions.mixins = [mockMixin];
const wrapper = shallowMount(addressVehicles, mountOptions);
- //Mock CMS content
- const cmsContent = {
- QuestionText: cmsQuestionText,
- };
-
return { wrapper };
}
diff --git a/src/layouts/address-vehicles/address-vehicles.vue b/src/layouts/address-vehicles/address-vehicles.vue
index faf71e1fb..db4000956 100644
--- a/src/layouts/address-vehicles/address-vehicles.vue
+++ b/src/layouts/address-vehicles/address-vehicles.vue
@@ -71,13 +71,15 @@ import { isGlassAvailableForCarId } from "@/helpers/damage-helper";
import { doesCopyContainRouterLink,
splitCopyOnCMSPlaceHolder,
getRouterLinkRouteFromCopy,
- getRouterLinkDisplayTextFromCopy, } from "@/helpers/cms-content-helper"
+ getRouterLinkDisplayTextFromCopy, } from "@/helpers/cms-content-helper";
+import vinPagesMixin from "@/mixins/vin-pages-mixin";
// DEFINE VALIDATION RULES
defineRule("vehicle-required", required(errorMessages.VEHICLE_REQUIRED));
export default {
name: "address-vehicles",
+ mixins: [vinPagesMixin],
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
@@ -188,8 +190,7 @@ export default {
);
return;
} else {
- this.$refs.loadingModal.showModal();
- navigateAfterSaveToHeritageFunnel(this.$route);
+ this.navigateForwardWithSingleCarMatch();
return;
}
},
diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js
index 44ab645dd..d711fa8bb 100644
--- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js
+++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js
@@ -9,6 +9,7 @@ import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { nextTick } from "vue";
+import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations";
import store from "@/store";
@@ -223,7 +224,7 @@ describe("license-plate-lookup.vue", () => {
});
describe("navigateForward", () => {
- test("NavigateAfterSave should be called if isCarIdDifferent is true and isSelectedGlassAvailableForVehicle is false when navigateForward is called", async () => {
+ test("navigateAfterSave should be called if isCarIdDifferent is true and isSelectedGlassAvailableForVehicle is false when navigateForward is called", async () => {
// Arrange
const { wrapper } = setupMocks({});
@@ -259,6 +260,38 @@ describe("license-plate-lookup.vue", () => {
//Assert
expect(navigateToHeritage.navigateAfterSaveToHeritageFunnel).toHaveBeenCalled();
});
+
+ test("carId matches returned vehicle => navigateForwardWithSingleCarMatch", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ await wrapper.setData({
+ isCarIdDifferent: false
+ })
+
+ wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
+
+ // Act
+ await wrapper.vm.navigateForward();
+
+ //Assert
+ expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalledTimes(1);
+ });
+
+ test("selected glass is available for returned vehicle => navigateForwardWithSingleCarMatch", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ await wrapper.setData({
+ isSelectedGlassAvailableForVehicle: true
+ })
+
+ wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
+
+ // Act
+ await wrapper.vm.navigateForward();
+
+ //Assert
+ expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalledTimes(1);
+ });
});
});
@@ -484,7 +517,7 @@ describe("license-plate-lookup.vue", () => {
expect(store.dispatch).toHaveBeenCalled();
})
- test("dispatch non blocking store action called on validate zip", async () => {
+ test("dispatchStoreAction called on validate zip", async () => {
// Arrange
const { wrapper } = setupMocks({});
@@ -497,7 +530,7 @@ describe("license-plate-lookup.vue", () => {
expect(baseMixin.methods.dispatchStoreAction).toHaveBeenCalled();
});
- test("dispatch non blocking store action called on lookup vin", async () => {
+ test("dispatchStoreAction called on lookup vin", async () => {
// Arrange
const { wrapper } = setupMocks({});
@@ -514,11 +547,8 @@ describe("license-plate-lookup.vue", () => {
function setupMocks({
pageHeaderWidgetHeaderText = {},
- mountOptionsMockData = {
- router: {
- navigate: jest.fn(),
- },
- },
+ mountOptionsMockData = {},
+ partsOrQuestions = []
}) {
store.commit(storeMutations.RESET_STATE);
//Mock api responses
@@ -537,6 +567,21 @@ function setupMocks({
},
};
+ mountOptionsMockData = {
+ ...mountOptionsMockData,
+ router: {
+ navigate: jest.fn(),
+ },
+ actionList: [
+ {
+ actionName: storeActions.GET_PARTS_OR_QUESTIONS,
+ data: {
+ partsOrQuestions: partsOrQuestions
+ }
+ },
+ ]
+ }
+
const apiPromise = Promise.resolve(apiResponses);
settleAllPromises.mockImplementation(() => apiPromise);
diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue
index f3a5d3e83..b0360776c 100644
--- a/src/layouts/license-plate-lookup/license-plate-lookup.vue
+++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue
@@ -98,10 +98,10 @@ import baseMixin from "@/mixins/base-mixin.js";
import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations";
import { errorMessages } from "@/constants/error-messages";
-import { navigateAfterSaveToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
import { getDamageString, isGlassAvailableForCarId, } from "@/helpers/damage-helper";
import { required, regex, } from "@/helpers/validation-rules";
import { Form, defineRule, } from "vee-validate";
+import vinPagesMixin from "@/mixins/vin-pages-mixin";
// DEFINE VALIDATION RULES
defineRule("license-plate-required", required(errorMessages.LICENSE_PLATE_REQUIRED));
@@ -112,6 +112,7 @@ defineRule("email-address-format", regex(/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9_\-.]+
export default {
name: "license-plate-lookup",
+ mixins: [vinPagesMixin],
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
@@ -297,8 +298,7 @@ export default {
);
return;
} else {
- this.$refs.loadingModal.showModal();
- navigateAfterSaveToHeritageFunnel(this.$route);
+ this.navigateForwardWithSingleCarMatch();
return;
}
},
@@ -312,7 +312,7 @@ export default {
},
updateCustomerInfo(vin, vehicleInfo, registrationState, serviceState) {
if (this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle) {
- store.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
+ store.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
}
store.commit(storeMutations.UPDATE_VEHICLE_VIN, vin);
store.commit(storeMutations.UPDATE_YEAR, vehicleInfo.year);
diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue
index e8c021954..36a7d6465 100644
--- a/src/layouts/part-questions/part-questions.vue
+++ b/src/layouts/part-questions/part-questions.vue
@@ -5,9 +5,7 @@
-
@@ -132,7 +132,6 @@ import loadingModal from '@/common-components/loading-modal/loading-modal.vue';
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import store from "@/store";
-import baseMixin from "@/mixins/base-mixin.js";
import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations";
import { errorMessages } from "@/constants/error-messages";
@@ -141,6 +140,7 @@ import { required, regex } from "@/helpers/validation-rules";
import { Form, defineRule } from "vee-validate";
import { navigateAfterSaveToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
+import vinPagesMixin from "@/mixins/vin-pages-mixin";
// DEFINE VALIDATION RULES
defineRule("zip-required", required(errorMessages.SERVICE_ZIP_REQUIRED));
@@ -152,6 +152,7 @@ defineRule("vin-format", regex(/^[a-hA-Hj-nJ-NpPr-zR-Z0-9]{17}$/, errorMessages.
export default {
name: "vin-lookup",
+ mixins: [vinPagesMixin],
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
@@ -322,21 +323,20 @@ export default {
},
navigateForward(){
if(this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle){
- this.$router.navigateAfterSave(this.navigationScenarios.CLICKED_FORWARD, this.$route, {}, { displayVehicleChangeAlert: true }, {});
+ this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, this.$route, {}, { displayVehicleChangeAlert: true }, {});
return;
} else {
- this.$refs.loadingModal.showModal();
- navigateAfterSaveToHeritageFunnel(this.$route);
+ this.navigateForwardWithSingleCarMatch();
return;
}
},
validateZip(zip) {
- return baseMixin.methods.dispatchStoreAction(storeActions.VALIDATE_ZIP, {
+ return this.dispatchStoreAction(storeActions.VALIDATE_ZIP, {
zip,
});
},
lookupVehicle(vin) {
- return baseMixin.methods.dispatchStoreAction(
+ return this.dispatchStoreAction(
storeActions.LOOKUP_VEHICLE_BY_VIN,
{ vin }
);
diff --git a/src/mixins/vin-pages-mixin.js b/src/mixins/vin-pages-mixin.js
new file mode 100644
index 000000000..8f33fdf92
--- /dev/null
+++ b/src/mixins/vin-pages-mixin.js
@@ -0,0 +1,28 @@
+import store from "@/store";
+import { storeActions } from "@/constants/store-actions.js";
+import { storeMutations } from "@/constants/store-mutations.js";
+import { navigateAfterSaveToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
+
+export default {
+ methods: {
+ async navigateForwardWithSingleCarMatch() {
+ const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS);
+
+ const partsOrQuestions = result.data.partsOrQuestions;
+ const hasPartsQuestions = partsOrQuestions.some(pq => pq.partQuestions?.length > 0);
+ const hasGlassLocationWithMultipleParts = partsOrQuestions.some(pq => pq.parts?.length > 1);
+
+ if (hasPartsQuestions) {
+ this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, this.$route, {}, {}, result.data);
+ }
+ else if (hasGlassLocationWithMultipleParts) {
+ this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, this.$route, {}, {}, result.data);
+ }
+ else {
+ store.commit(storeMutations.UPDATE_PARTS, result.data);
+ this.$refs.loadingModal.showModal();
+ navigateAfterSaveToHeritageFunnel(this.$route);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/mixins/vin-pages-mixin.spec.js b/src/mixins/vin-pages-mixin.spec.js
new file mode 100644
index 000000000..747b62793
--- /dev/null
+++ b/src/mixins/vin-pages-mixin.spec.js
@@ -0,0 +1,921 @@
+import vinPagesMixin from "@/mixins/vin-pages-mixin";
+import { shallowMount } from "@vue/test-utils";
+import { setupMocksForJsFiles, getMountOptions } from "@/helpers/unit-test-helper.js";
+import { storeActions } from "@/constants/store-actions";
+import { storeMutations } from "@/constants/store-mutations";
+import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
+import store from "@/store";
+import loadingModal from '@/common-components/loading-modal/loading-modal.vue';
+import { navigateAfterSaveToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
+
+jest.mock("@/helpers/heritage-integration/navigation-helper", () => ({
+ navigateAfterSaveToHeritageFunnel: jest.fn()
+}));
+
+describe("vin-pages-mixin", () => {
+ afterEach(() => {
+ jest.clearAllMocks();
+ })
+
+ describe("navigateForwardWithSingleCarMatch", () => {
+ describe("should go to parts-questions", () => {
+ test("single glass location has part question => go to parts-questions", async () => {
+ // Arrange
+ const partsOrQuestions = [
+ {
+ "glassName": "Single",
+ "glassLocation": "Windshield",
+ "parts": null,
+ "partQuestions": [
+ {
+ "questionSequence": 1,
+ "questionText": "Is there a line running across the bottom, driver's side then up the center of the Windshield?",
+ "answers": [
+ {
+ "answerText": "Yes",
+ "nextQuestionSequence": null,
+ "answerResult": "DW01144"
+ },
+ {
+ "answerText": "No",
+ "nextQuestionSequence": null,
+ "answerResult": "DW01143"
+ }
+ ]
+ }
+ ]
+ }
+ ];
+
+ const { wrapper } = setupMocks({
+ partsOrQuestions: partsOrQuestions
+ });
+
+ // Act
+ await wrapper.vm.navigateForwardWithSingleCarMatch();
+
+ // Assert
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledTimes(1);
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
+ });
+
+ test("multiple glass locations have part questions => go to parts-questions", async () => {
+ // Arrange
+ const partsOrQuestions = [
+ {
+ "glassName": "Single",
+ "glassLocation": "Windshield",
+ "parts": null,
+ "partQuestions": [
+ {
+ "questionSequence": 1,
+ "questionText": "Is there a line running across the bottom, driver's side then up the center of the Windshield?",
+ "answers": [
+ {
+ "answerText": "Yes",
+ "nextQuestionSequence": null,
+ "answerResult": "DW01144"
+ },
+ {
+ "answerText": "No",
+ "nextQuestionSequence": null,
+ "answerResult": "DW01143"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "glassName": "Front",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "DD08158GTYN",
+ "description": "driver side, front",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Quarter",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "DQ08162GTYN",
+ "description": "driver side, 1 hole",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "SideDoor",
+ "glassLocation": "Driver",
+ "parts": null,
+ "partQuestions": [
+ {
+ "questionSequence": 2,
+ "questionText": "Is this a super awesome question?",
+ "answers": [
+ {
+ "answerText": "Yes",
+ "nextQuestionSequence": null,
+ "answerResult": "DW01144000"
+ },
+ {
+ "answerText": "Super yes",
+ "nextQuestionSequence": null,
+ "answerResult": "DW01143001"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "glassName": "Stationary",
+ "glassLocation": "Rear",
+ "parts": [
+ {
+ "partNumber": "DB08165GTNN",
+ "description": "heated glass, stationary",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ }
+ ];
+
+ const { wrapper } = setupMocks({
+ partsOrQuestions: partsOrQuestions
+ });
+
+ // Act
+ await wrapper.vm.navigateForwardWithSingleCarMatch();
+
+ // Assert
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledTimes(1);
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
+ });
+
+ test("multiple glass locations selected, one has part question => go to parts-questions", async () => {
+ // Arrange
+ const partsOrQuestions = [
+ {
+ "glassName": "Single",
+ "glassLocation": "Windshield",
+ "parts": null,
+ "partQuestions": [
+ {
+ "questionSequence": 1,
+ "questionText": "Is there a line running across the bottom, driver's side then up the center of the Windshield?",
+ "answers": [
+ {
+ "answerText": "Yes",
+ "nextQuestionSequence": null,
+ "answerResult": "DW01144"
+ },
+ {
+ "answerText": "No",
+ "nextQuestionSequence": null,
+ "answerResult": "DW01143"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "glassName": "Front",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "DD08158GTYN",
+ "description": "driver side, front",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Quarter",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "DQ08162GTYN",
+ "description": "driver side, 1 hole",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "SideDoor",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "DD08160GTYN",
+ "description": "driver side, body side, 1 hole",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Stationary",
+ "glassLocation": "Rear",
+ "parts": [
+ {
+ "partNumber": "DB08165GTNN",
+ "description": "heated glass, stationary",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ }
+ ];
+
+ const { wrapper } = setupMocks({
+ partsOrQuestions: partsOrQuestions
+ });
+
+ // Act
+ await wrapper.vm.navigateForwardWithSingleCarMatch();
+
+ // Assert
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledTimes(1);
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
+ });
+
+ test("a selected glass location has part questions and multiple parts => go to parts-questions", async () => {
+ // Arrange
+ const partsOrQuestions = [
+ {
+ "glassName": "Single",
+ "glassLocation": "Windshield",
+ "parts": null,
+ "partQuestions": [
+ {
+ "questionSequence": 1,
+ "questionText": "Is there a line running across the bottom, driver's side then up the center of the Windshield?",
+ "answers": [
+ {
+ "answerText": "Yes",
+ "nextQuestionSequence": null,
+ "answerResult": "DW01144"
+ },
+ {
+ "answerText": "No",
+ "nextQuestionSequence": null,
+ "answerResult": "DW01143"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "glassName": "Front",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "DD08158GTYN",
+ "description": "driver side, front",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Quarter",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "DQ08162GTYN",
+ "description": "driver side, 1 hole",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DQ08162YPYN",
+ "description": "driver side, 1 hole",
+ "color": "Gray Tint Privacy",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "SideDoor",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "DD08160GTYN",
+ "description": "driver side, body side, 1 hole",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DD08160YPYN",
+ "description": "driver side, body side, 1 hole",
+ "color": "Gray Tint Privacy",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Stationary",
+ "glassLocation": "Rear",
+ "parts": [
+ {
+ "partNumber": "DB08165GTNN",
+ "description": "heated glass, stationary",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DB08165YPNN",
+ "description": "heated glass, stationary",
+ "color": "Gray Tint Privacy",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DB08166GTNN",
+ "description": "stationary",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DB08167GTNN",
+ "description": "heated glass, movable, 8 hole",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DB08167YPNN",
+ "description": "heated glass, movable, 8 hole",
+ "color": "Gray Tint Privacy",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ }
+ ];
+
+ const { wrapper } = setupMocks({
+ partsOrQuestions: partsOrQuestions
+ });
+
+ // Act
+ await wrapper.vm.navigateForwardWithSingleCarMatch();
+
+ // Assert
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledTimes(1);
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
+ });
+ });
+
+ describe("should go to vehicle-parts", () => {
+ test("single glass location has multiple parts => go to vehicle-parts", async () => {
+ // Arrange
+ const partsOrQuestions = [
+ {
+ "glassName": "Stationary",
+ "glassLocation": "Rear",
+ "parts": [
+ {
+ "partNumber": "FB25724GTYN",
+ "description": "heated glass, solar, antenna",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "FB25759GTYN",
+ "description": "heated glass, solar, antenna, w/diversity antenna",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ }
+ ];
+
+ const { wrapper } = setupMocks({
+ partsOrQuestions: partsOrQuestions
+ });
+
+ // Act
+ await wrapper.vm.navigateForwardWithSingleCarMatch();
+
+ // Assert
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledTimes(1);
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
+ });
+
+ test("multiple glass locations selected, one of them has multiple parts => go to vehicle parts", async () => {
+ // Arrange
+ const partsOrQuestions = [
+ {
+ "glassName": "Single",
+ "glassLocation": "Windshield",
+ "parts": [
+ {
+ "partNumber": "FW03647GTNN",
+ "description": "solar, 3rd visor band",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": [
+ {
+ "partNumber": "MWF03647",
+ "partType": "MOULDING",
+ "description": "Upper "
+ }
+ ]
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Back",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "FD25747GTYN",
+ "description": "solar, driver side, rear, ex models and above",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Front",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "FD25719GTYN",
+ "description": "solar, driver side, front, ex models and above",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Vent",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "FV25749GTNN",
+ "description": "solar, driver side, rear",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Stationary",
+ "glassLocation": "Rear",
+ "parts": [
+ {
+ "partNumber": "FB25724GTYN",
+ "description": "heated glass, solar, antenna",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "FB25759GTYN",
+ "description": "heated glass, solar, antenna, w/diversity antenna",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ }
+ ];
+
+ const { wrapper } = setupMocks({
+ partsOrQuestions: partsOrQuestions
+ });
+
+ // Act
+ await wrapper.vm.navigateForwardWithSingleCarMatch();
+
+ // Assert
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledTimes(1);
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
+ });
+
+ test("multiple glass locations selected, multiple have multiple parts => go to vehicle-parts", async () => {
+ // Arrange
+ const partsOrQuestions = [
+ {
+ "glassName": "Single",
+ "glassLocation": "Windshield",
+ "parts": [
+ {
+ "partNumber": "DW02101GTYN",
+ "description": "solar",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Back",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "DD12202GTYN",
+ "description": "solar, driver side, rear",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DD12202YPYN",
+ "description": "solar, driver side, rear",
+ "color": "Gray Tint Privacy",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Front",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "DD12198GTYN",
+ "description": "solar, driver side, front",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DD12200GTYN",
+ "description": "solar, driver side, front, laminated, soundproofing",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Quarter",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "DQ12204GTYNOEM",
+ "description": "solar, driver side, encap",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DQ12204YPYNOEM",
+ "description": "solar, driver side, encap",
+ "color": "Gray Tint Privacy",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DQ12205GTYNOEM",
+ "description": "solar, antenna, driver side, encap",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DQ12205YPYNOEM",
+ "description": "solar, antenna, driver side, encap",
+ "color": "Gray Tint Privacy",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DQ12207GTYN",
+ "description": "solar, driver side, encap, chrome molding",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DQ12207YPYNOEM",
+ "description": "solar, driver side, encap, chrome molding",
+ "color": "Gray Tint Privacy",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DQ12208GTYNOEM",
+ "description": "solar, antenna, driver side, encap, chrome molding",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DQ12208YPYNOEM",
+ "description": "solar, antenna, driver side, encap, chrome molding",
+ "color": "Gray Tint Privacy",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Stationary",
+ "glassLocation": "Rear",
+ "parts": [
+ {
+ "partNumber": "DB12209GTYN",
+ "description": "heated glass, solar, 1 hole",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ },
+ {
+ "partNumber": "DB12209YPYN",
+ "description": "heated glass, solar, 1 hole",
+ "color": "Gray Tint Privacy",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ }
+ ];
+
+ const { wrapper } = setupMocks({
+ partsOrQuestions: partsOrQuestions
+ });
+
+ // Act
+ await wrapper.vm.navigateForwardWithSingleCarMatch();
+
+ // Assert
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledTimes(1);
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS, wrapper.vm.$route, {}, {}, { partsOrQuestions });
+ });
+ });
+
+ describe("should go to heritage funnel", () => {
+ test("single glass location selected, has no part questions and has one part => go to heritage funnel", async () => {
+ // Arrange
+ const partsOrQuestions = [
+ {
+ "glassName": "Single",
+ "glassLocation": "Windshield",
+ "parts": [
+ {
+ "partNumber": "FW04186GTYN",
+ "description": "solar, soundproofing, lane keep assist",
+ "color": "Green Tint",
+ "requiresRecalibration": true,
+ "requiresCapabilityQuestions": false,
+ "childParts": [
+ {
+ "partNumber": "GGG 3563 KIT",
+ "partType": "MOULDING",
+ "description": "Kit, Top & Sides "
+ }
+ ]
+ }
+ ],
+ "partQuestions": null
+ }
+ ]
+
+ const { wrapper } = setupMocks({
+ partsOrQuestions: partsOrQuestions
+ });
+
+ // Act
+ await wrapper.vm.navigateForwardWithSingleCarMatch();
+
+ // Assert
+ expect(navigateAfterSaveToHeritageFunnel).toHaveBeenCalledTimes(1);
+ });
+
+ test("multiple glass locations selected, each has one part and no part questions => go to heritage funnel", async () => {
+ // Arrange
+ const partsOrQuestions = [
+ {
+ "glassName": "Single",
+ "glassLocation": "Windshield",
+ "parts": [
+ {
+ "partNumber": "FW04186GTYN",
+ "description": "solar, soundproofing, lane keep assist",
+ "color": "Green Tint",
+ "requiresRecalibration": true,
+ "requiresCapabilityQuestions": false,
+ "childParts": [
+ {
+ "partNumber": "GGG 3563 KIT",
+ "partType": "MOULDING",
+ "description": "Kit, Top & Sides "
+ }
+ ]
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Back",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "FD25457GTYN",
+ "description": "solar, driver side, rear",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Front",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "FD27090GTYN",
+ "description": "solar, driver side, front",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Vent",
+ "glassLocation": "Driver",
+ "parts": [
+ {
+ "partNumber": "FV25459GTNN",
+ "description": "solar, driver side, rear",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ },
+ {
+ "glassName": "Stationary",
+ "glassLocation": "Rear",
+ "parts": [
+ {
+ "partNumber": "FB25460GTYN",
+ "description": "heated glass, solar",
+ "color": "Green Tint",
+ "requiresRecalibration": false,
+ "requiresCapabilityQuestions": false,
+ "childParts": null
+ }
+ ],
+ "partQuestions": null
+ }
+ ];
+
+ const { wrapper } = setupMocks({
+ partsOrQuestions: partsOrQuestions
+ });
+
+ // wrapper.vm.navigateAfterSaveToHeritageFunnel = jest.fn();
+ store.commit = jest.fn();
+
+ // Act
+ await wrapper.vm.navigateForwardWithSingleCarMatch();
+
+ // Assert
+ expect(store.commit).toHaveBeenCalledTimes(1);
+ expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_PARTS, { partsOrQuestions })
+ expect(wrapper.vm.$refs.loadingModal.showModal).toHaveBeenCalledTimes(1);
+ expect(navigateAfterSaveToHeritageFunnel).toHaveBeenCalledTimes(1);
+ });
+ });
+ });
+});
+
+function setupMocks({ partsOrQuestions = [] }) {
+ const baseMixin = setupMocksForJsFiles({
+ actionList: [
+ {
+ actionName: storeActions.GET_PARTS_OR_QUESTIONS,
+ data: {
+ partsOrQuestions: partsOrQuestions
+ }
+ },
+ ],
+ });
+
+ const mocks = getMountOptions({
+ router: {
+ navigateAfterSave: jest.fn()
+ },
+
+ });
+
+ const mockVinComponent = {
+ components: { loadingModal },
+ template: '
',
+ // render() {
+ // return '
'
+ // },
+ mixins: [vinPagesMixin, baseMixin.baseMixin]
+ };
+
+ // const mockVinComponent = Vue.component("mockcomponent", {
+ // template: '
',
+ // mixins: [vinPagesMixin, baseMixin.baseMixin]
+ // })
+
+ const wrapper = shallowMount(mockVinComponent, mocks);
+
+ wrapper.vm.$refs.loadingModal.showModal = jest.fn();
+
+ return { wrapper };
+}
\ No newline at end of file
diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js
index d7491a6bf..7bf425efc 100644
--- a/src/router/router-constants/navigation-scenarios.js
+++ b/src/router/router-constants/navigation-scenarios.js
@@ -8,11 +8,11 @@ const navigationScenarios = {
CLICKED_FORWARD: "CLICKED_FORWARD",
CLICKED_FORWARD_WITH_VIN: "CLICKED_FORWARD_WITH_VIN",
SELECTED_PARTS: "SELECTED_PARTS",
- CONTINUING_WITH_PARTS_QUESTION: "CONTINUING_WITH_PARTS_QUESTION",
- CONTINUING_WITH_MULTIPLE_PARTS: "CONTINUING_WITH_MULTIPLE_PARTS",
+ SELECTED_VIN_WITH_PART_QUESTIONS: "SELECTED_VIN_WITH_PART_QUESTIONS",
+ SELECTED_VIN_WITH_MULTIPLE_PARTS: "SELECTED_VIN_WITH_MULTIPLE_PARTS",
CONTINUING_WITH_SINGLE_PART: "CONTINUING_WITH_SINGLE_PART",
CONTINUING_WITH_MULTIPLE_VEHICLES: "CONTINUING_WITH_MULTIPLE_VEHICLES",
- CONTINUING_WITH_DIFFERENT_GLASS: "CONTINUING_WITH_DIFFERENT_GLASS",
+ SELECTED_VIN_HAS_MISMATCHED_GLASS: "SELECTED_VIN_HAS_MISMATCHED_GLASS",
CLICKED_FORWARD_WITHOUT_VIN: "CLICKED_FORWARD_WITHOUT_VIN",
SELECTED_MANUAL_VIN: "SELECTED_MANUAL_VIN",
SELECTED_LICENSE_PLATE: "SELECTED_LICENSE_PLATE",
diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js
index 4c8ef5363..78c5ac242 100644
--- a/src/router/router-constants/routing-table.js
+++ b/src/router/router-constants/routing-table.js
@@ -72,7 +72,7 @@ const routingTable = [
maps: [
{
scenario: navigationScenarios.CLICKED_BACK,
- destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
+ destinationFmgPageValue: fmgPageValues.VIN_LOOKUP,
},
{
scenario: navigationScenarios.SELECTED_PARTS,
@@ -105,12 +105,20 @@ const routingTable = [
destinationFmgPageValue: fmgPageValues.ESTIMATE,
},
{
- scenario: navigationScenarios.CLICKED_FORWARD,
+ scenario: navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS,
destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
},
{
scenario: navigationScenarios.CLICKED_BACK_WITH_VIN,
destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
+ },
+ {
+ scenario: navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS,
+ destinationFmgPageValue: fmgPageValues.PART_QUESTIONS
+ },
+ {
+ scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS,
+ destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS
}
],
},
@@ -125,6 +133,14 @@ const routingTable = [
scenario: navigationScenarios.CLICKED_FORWARD,
destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
},
+ {
+ scenario: navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS,
+ destinationFmgPageValue: fmgPageValues.PART_QUESTIONS
+ },
+ {
+ scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS,
+ destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS
+ }
],
},
{
@@ -139,9 +155,17 @@ const routingTable = [
destinationFmgPageValue: fmgPageValues.ADDRESS_VEHICLES,
},
{
- scenario: navigationScenarios.CONTINUING_WITH_DIFFERENT_GLASS,
+ scenario: navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS,
destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
},
+ {
+ scenario: navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS,
+ destinationFmgPageValue: fmgPageValues.PART_QUESTIONS
+ },
+ {
+ scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS,
+ destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS
+ }
],
},
{
@@ -154,7 +178,15 @@ const routingTable = [
{
scenario: navigationScenarios.CLICKED_FORWARD,
destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
- },
+ },
+ {
+ scenario: navigationScenarios.SELECTED_VIN_WITH_PART_QUESTIONS,
+ destinationFmgPageValue: fmgPageValues.PART_QUESTIONS
+ },
+ {
+ scenario: navigationScenarios.SELECTED_VIN_WITH_MULTIPLE_PARTS,
+ destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS
+ }
],
},
{
@@ -178,6 +210,15 @@ const routingTable = [
},
],
},
+ {
+ fmgPageValue: fmgPageValues.PART_QUESTIONS,
+ maps: [
+ {
+ scenario: navigationScenarios.CLICKED_BACK,
+ destinationFmgPageValue: fmgPageValues.VIN_LOOKUP
+ }
+ ]
+ },
];
export { routingTable };
diff --git a/src/store/index.js b/src/store/index.js
index dda0fab35..c3e54d27b 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -539,7 +539,16 @@ export const actions = {
// Parts API Actions
- getPartsOrQuestions(context, { carId, glassArray, zipCode, vin = '' }) {
+ getPartsOrQuestions(context) {
+ const vehicle = context.getters.vehicle;
+ const damage = context.getters.damage;
+ const order = context.state.order;
+
+ const carId = vehicle.carId;
+ const glassArray = damage.glassToReplace;
+ const zipCode = order.serviceLocation.zipCode;
+ const vin = vehicle.vin;
+
return globalMethods.callHttpClient({
method: endpoints.GetPartsOrQuestions.method,
endpoint: endpoints.GetPartsOrQuestions.url,