commit
001fcce06e
16 changed files with 1313 additions and 187 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -5,9 +5,7 @@
|
|||
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
|
||||
<div class="fade-on-route-transition sub-container make-tall">
|
||||
<h1>Part Questions Page Placeholder</h1>
|
||||
<funnel-footer
|
||||
cmsWidgetName="FunnelFooterWidget" @back-clicked="backButtonAction"
|
||||
/>
|
||||
<funnel-footer cmsWidgetName="FunnelFooterWidget" @back-clicked="backButtonAction" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -65,10 +63,7 @@ export default {
|
|||
);
|
||||
},
|
||||
arePagePrerequisitesValid() {
|
||||
if (Object.keys(store.getters.pageData(fmgPageValues.PART_QUESTIONS)).length !== 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return Object.keys(store.getters.pageData(fmgPageValues.PART_QUESTIONS)).length !== 0;
|
||||
},
|
||||
resetDependentState() {
|
||||
// Set
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ export default {
|
|||
// Check if only a single part is present for the tint and set the v-model if it is.
|
||||
AutoSelectIfSinglePart() {
|
||||
// Check if the selected tint only has a single feature
|
||||
Object.keys(this.PartDataFromApi.partsOrQuestions).forEach((key) => {
|
||||
Object.keys(this.PartDataFromApi.partsOrQuestions ?? {}).forEach((key) => {
|
||||
const currentGlassSelection =
|
||||
this.PartDataFromApi.partsOrQuestions[key];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,37 +1,38 @@
|
|||
import { shallowMount } from "@vue/test-utils";
|
||||
import { shallowMount } from "@vue/test-utils";
|
||||
import vinLookup from "./vin-lookup.vue";
|
||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios.js";
|
||||
|
||||
import store from "@/store";
|
||||
|
||||
jest.mock("@/store", () => ({
|
||||
commit: jest.fn(),
|
||||
dispatch: jest.fn(),
|
||||
getters: {
|
||||
vehicle: {
|
||||
year: 2019,
|
||||
carId: 'initial carId'
|
||||
},
|
||||
order: {
|
||||
serviceLocation: {
|
||||
zipCode: "45253"
|
||||
commit: jest.fn(),
|
||||
dispatch: jest.fn(),
|
||||
getters: {
|
||||
vehicle: {
|
||||
year: 2019,
|
||||
carId: 'initial carId'
|
||||
},
|
||||
customer: {
|
||||
emailAddress: "builddigitaltest@safelite.com"
|
||||
order: {
|
||||
serviceLocation: {
|
||||
zipCode: "45253"
|
||||
},
|
||||
customer: {
|
||||
emailAddress: "builddigitaltest@safelite.com"
|
||||
}
|
||||
},
|
||||
payment: {
|
||||
insuranceCoverage: {
|
||||
isVerified: true
|
||||
}
|
||||
},
|
||||
damage: {
|
||||
glassToReplace: "windshield"
|
||||
}
|
||||
},
|
||||
payment: {
|
||||
insuranceCoverage: {
|
||||
isVerified: true
|
||||
}
|
||||
},
|
||||
damage: {
|
||||
glassToReplace: "windshield"
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
import { getDamageString, getIsWindshieldOnly,isGlassAvailableForCarId } from "@/helpers/damage-helper";
|
||||
import { getDamageString, getIsWindshieldOnly, isGlassAvailableForCarId } from "@/helpers/damage-helper";
|
||||
|
||||
jest.mock("@/helpers/damage-helper", () => ({
|
||||
isGlassAvailableForCarId: jest.fn(() => {
|
||||
|
|
@ -45,21 +46,21 @@ jest.mock("@/helpers/damage-helper", () => ({
|
|||
describe("vin-lookup.vue", () => {
|
||||
it("Should update the funnel-footer forward button when VIN is changed", (done) => {
|
||||
//Arrange
|
||||
const { wrapper } = setupMocks({ });
|
||||
const { wrapper } = setupMocks({});
|
||||
//Act
|
||||
wrapper.setData({vin: "newValue"});
|
||||
wrapper.setData({ vin: "newValue" });
|
||||
//Assert
|
||||
wrapper.vm.$nextTick(() => {
|
||||
expect(wrapper.vm.$refs.funnelFooter.updateButtonText).toBeCalled();
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
it("Should call navigateForward() if the store carId matches the vin response carId and forward button is clicked", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({ });
|
||||
wrapper.vm.navigateForward = jest.fn();
|
||||
const { wrapper } = setupMocks({});
|
||||
wrapper.vm.navigateForward = jest.fn();
|
||||
|
||||
// Act
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
|
|
@ -70,17 +71,17 @@ describe("vin-lookup.vue", () => {
|
|||
|
||||
it("Should not call navigateForward() if the store carId does not match the vin response carId and forward button is clicked", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({ });
|
||||
const { wrapper } = setupMocks({});
|
||||
const vehicleLookupApiResponse = {
|
||||
data: {
|
||||
carId: 'new carId' // does not match the store value
|
||||
}
|
||||
};
|
||||
};
|
||||
const vinPromise = Promise.resolve(vehicleLookupApiResponse);
|
||||
|
||||
|
||||
wrapper.vm.lookupVehicle = jest.fn().mockImplementation(() => vinPromise);
|
||||
|
||||
wrapper.vm.navigateForward = jest.fn();
|
||||
wrapper.vm.navigateForward = jest.fn();
|
||||
|
||||
// Act
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
|
|
@ -91,16 +92,16 @@ describe("vin-lookup.vue", () => {
|
|||
|
||||
it("Should call navigateForward() if the store carId does not match the vin response carId but does match previously enterted carId and forward button is clicked", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({ });
|
||||
const { wrapper } = setupMocks({});
|
||||
const vehicleLookupApiResponse = {
|
||||
data: {
|
||||
carId: 'new carId' // does not match the store value
|
||||
}
|
||||
};
|
||||
};
|
||||
const vinPromise = Promise.resolve(vehicleLookupApiResponse);
|
||||
|
||||
|
||||
wrapper.vm.lookupVehicle = jest.fn().mockImplementation(() => vinPromise);
|
||||
wrapper.vm.navigateForward = jest.fn();
|
||||
wrapper.vm.navigateForward = jest.fn();
|
||||
|
||||
wrapper.vm.previouslyEnteredCarId = 'new carId';
|
||||
|
||||
|
|
@ -113,7 +114,7 @@ describe("vin-lookup.vue", () => {
|
|||
|
||||
it("Should not call navigateForward() if zip service returns a non-serviceable flag", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({ });
|
||||
const { wrapper } = setupMocks({});
|
||||
const zipValidationApiResponse = {
|
||||
data: {
|
||||
isServiceable: false
|
||||
|
|
@ -121,9 +122,9 @@ describe("vin-lookup.vue", () => {
|
|||
};
|
||||
|
||||
const zipPromise = Promise.resolve(zipValidationApiResponse);
|
||||
|
||||
|
||||
wrapper.vm.validateZip = jest.fn().mockImplementation(() => zipPromise);
|
||||
wrapper.vm.navigateForward = jest.fn();
|
||||
wrapper.vm.navigateForward = jest.fn();
|
||||
|
||||
wrapper.vm.previouslyEnteredCarId = 'new carId';
|
||||
|
||||
|
|
@ -136,16 +137,16 @@ describe("vin-lookup.vue", () => {
|
|||
|
||||
it("Should not call navigateForward() when forward button is clicked but lookupVehicle errors out.", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({ });
|
||||
const { wrapper } = setupMocks({});
|
||||
const vehicleLookupApiResponse = {
|
||||
data: {
|
||||
carId: 'new carId' // does not match the store value
|
||||
}
|
||||
};
|
||||
};
|
||||
const vinPromise = Promise.reject(vehicleLookupApiResponse);
|
||||
|
||||
|
||||
wrapper.vm.lookupVehicle = jest.fn().mockImplementation(() => vinPromise);
|
||||
wrapper.vm.navigateForward = jest.fn();
|
||||
wrapper.vm.navigateForward = jest.fn();
|
||||
|
||||
wrapper.vm.previouslyEnteredCarId = 'new carId';
|
||||
|
||||
|
|
@ -155,19 +156,75 @@ describe("vin-lookup.vue", () => {
|
|||
//Assert
|
||||
expect(wrapper.vm.navigateForward).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe("navigateForward", () => {
|
||||
test("carId is different from returned vehicle and selected glass isn't available => continue with different glass", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({
|
||||
customMountOptions: {
|
||||
router: {
|
||||
navigateAfterSave: jest.fn()
|
||||
}
|
||||
}
|
||||
});
|
||||
wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
|
||||
wrapper.setData({
|
||||
isCarIdDifferent: true,
|
||||
isSelectedGlassAvailableForVehicle: false
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.navigateForward();
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.$router.navigateAfterSave).toBeCalledTimes(1);
|
||||
expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalledWith(navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS, wrapper.vm.$route, expect.anything(), expect.anything(), expect.anything());
|
||||
})
|
||||
|
||||
test("carId matches => navigateForwardWithSingleCarMatch", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
|
||||
wrapper.setData({
|
||||
isCarIdDifferent: false,
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.navigateForward();
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.navigateForwardWithSingleCarMatch).toBeCalledTimes(1);
|
||||
})
|
||||
|
||||
test("selected glass is available for returned vehicle => navigateForwardWithSingleCarMatch", async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
|
||||
wrapper.setData({
|
||||
isSelectedGlassAvailableForVehicle: true,
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.navigateForward();
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.navigateForwardWithSingleCarMatch).toBeCalledTimes(1);
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
function setupMocks({ customMountOptions }) {
|
||||
const mountOptions = getMountOptions({});
|
||||
const mountOptions = getMountOptions({
|
||||
...customMountOptions
|
||||
});
|
||||
|
||||
const finalMountOptions = Object.assign(mountOptions, customMountOptions);
|
||||
// Modify/augment default mount options
|
||||
finalMountOptions.global.mocks["$store"] = store;
|
||||
finalMountOptions.global.mixins = [mockMixin];
|
||||
finalMountOptions['attachTo'] = document.body; // append wrapper to document.body to test DOM methods
|
||||
mountOptions.global.mocks["$store"] = store;
|
||||
mountOptions.global.mixins = [mockMixin];
|
||||
mountOptions['attachTo'] = document.body; // append wrapper to document.body to test DOM methods
|
||||
|
||||
const wrapper = shallowMount(vinLookup, finalMountOptions);
|
||||
const wrapper = shallowMount(vinLookup, mountOptions);
|
||||
mockOutPromises(wrapper);
|
||||
mockOutStubFunctions(wrapper);
|
||||
return { wrapper };
|
||||
|
|
@ -183,8 +240,8 @@ function mockOutPromises(wrapper) {
|
|||
data: {
|
||||
carId: 'initial carId'
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
const zipPromise = Promise.resolve(zipValidationApiResponse);
|
||||
const vinPromise = Promise.resolve(vehicleLookupApiResponse);
|
||||
|
||||
|
|
@ -197,8 +254,8 @@ function mockOutStubFunctions(wrapper) {
|
|||
wrapper.vm.$refs.funnelFooter.removeLoader = jest.fn();
|
||||
}
|
||||
|
||||
const mockMixin = {
|
||||
const mockMixin = {
|
||||
methods: {
|
||||
getCmsContent: jest.fn(() => "placeholder CMS content"),
|
||||
getCmsContent: jest.fn(() => "placeholder CMS content"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
<div class="page-container-grouped-styles">
|
||||
<loadingModal ref="loadingModal"/>
|
||||
<funnelHeader cmsWidgetName="FunnelHeaderWidget" />
|
||||
<vehicleBanner
|
||||
<vehicleBanner
|
||||
cmsWidgetName="VehicleBannerWidget"
|
||||
:displayGenericVehicleImage="false"
|
||||
/>
|
||||
|
|
@ -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 }
|
||||
);
|
||||
|
|
|
|||
28
src/mixins/vin-pages-mixin.js
Normal file
28
src/mixins/vin-pages-mixin.js
Normal file
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
921
src/mixins/vin-pages-mixin.spec.js
Normal file
921
src/mixins/vin-pages-mixin.spec.js
Normal file
|
|
@ -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: '<loadingModal ref="loadingModal" />',
|
||||
// render() {
|
||||
// return '<div ref="loadingModal"></div>'
|
||||
// },
|
||||
mixins: [vinPagesMixin, baseMixin.baseMixin]
|
||||
};
|
||||
|
||||
// const mockVinComponent = Vue.component("mockcomponent", {
|
||||
// template: '<loadingModal ref="loadingModal" />',
|
||||
// mixins: [vinPagesMixin, baseMixin.baseMixin]
|
||||
// })
|
||||
|
||||
const wrapper = shallowMount(mockVinComponent, mocks);
|
||||
|
||||
wrapper.vm.$refs.loadingModal.showModal = jest.fn();
|
||||
|
||||
return { wrapper };
|
||||
}
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue