Merge branch 'develop' into feature/CSR-1373
This commit is contained in:
commit
8445e7fd4e
32 changed files with 167 additions and 2191 deletions
1
src/constants/pay-with-insurance-states.js
Normal file
1
src/constants/pay-with-insurance-states.js
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export const payWithInsuranceStates = ["AZ", "CT", "FL", "KY", "MA", "MN", "NY", "SC"];
|
||||||
|
|
@ -58,10 +58,6 @@ const storeActions = {
|
||||||
RESET_STATE: "resetState",
|
RESET_STATE: "resetState",
|
||||||
|
|
||||||
// SAVE COMPONENT STATE
|
// SAVE COMPONENT STATE
|
||||||
SAVE_VEHICLE_YEAR: "saveVehicleYear",
|
|
||||||
SAVE_VEHICLE_MAKE: "saveVehicleMake",
|
|
||||||
SAVE_VEHICLE_MODEL: "saveVehicleModel",
|
|
||||||
SAVE_VEHICLE_STYLE: "saveVehicleStyle",
|
|
||||||
SAVE_VEHICLE: "saveVehicle",
|
SAVE_VEHICLE: "saveVehicle",
|
||||||
SAVE_VEHICLE_DAMAGE: "saveVehicleDamage",
|
SAVE_VEHICLE_DAMAGE: "saveVehicleDamage",
|
||||||
SAVE_VIN_LOOKUP: "saveVinLookup",
|
SAVE_VIN_LOOKUP: "saveVinLookup",
|
||||||
|
|
@ -87,6 +83,7 @@ const storeActions = {
|
||||||
SAVE_VAPS: "saveVaps",
|
SAVE_VAPS: "saveVaps",
|
||||||
SAVE_CUSTOMER_DETAILS: "saveCustomerDetails",
|
SAVE_CUSTOMER_DETAILS: "saveCustomerDetails",
|
||||||
SAVE_SERVICE_LOCATION_TECH_NOTES: "saveServiceLocationTechNotes",
|
SAVE_SERVICE_LOCATION_TECH_NOTES: "saveServiceLocationTechNotes",
|
||||||
|
SAVE_WORK_ORDER_FLAG: "saveWorkOrderFlag",
|
||||||
};
|
};
|
||||||
|
|
||||||
export { storeActions };
|
export { storeActions };
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
const storeMutations = {
|
const storeMutations = {
|
||||||
|
UPDATE_WORK_ORDER_FLAG: "updateWorkOrderFlag",
|
||||||
|
|
||||||
// VEHICLE MUTATIONS
|
// VEHICLE MUTATIONS
|
||||||
UPDATE_YEAR: "updateYear",
|
UPDATE_YEAR: "updateYear",
|
||||||
UPDATE_MAKE: "updateMake",
|
UPDATE_MAKE: "updateMake",
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ describe("vehicleBanner", () => {
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
displayGenericVehicleImageProp: true,
|
displayGenericVehicleImageProp: true,
|
||||||
imageUrlValue: "NULL",
|
imageUrlValue: "NULL",
|
||||||
|
displayUnmatchedVehicleIconProp: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
@ -87,7 +88,12 @@ describe("vehicleBanner", () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks({ displayGenericVehicleImageProp, imageUrlValue, categoryValue = "CAR" }) {
|
function setupMocks({
|
||||||
|
displayGenericVehicleImageProp,
|
||||||
|
displayUnmatchedVehicleIconProp,
|
||||||
|
imageUrlValue,
|
||||||
|
categoryValue = "CAR",
|
||||||
|
}) {
|
||||||
const mockGetCmsContent = jest.fn();
|
const mockGetCmsContent = jest.fn();
|
||||||
mockGetCmsContent((cmsWidget, field) => {
|
mockGetCmsContent((cmsWidget, field) => {
|
||||||
return field;
|
return field;
|
||||||
|
|
@ -108,7 +114,10 @@ function setupMocks({ displayGenericVehicleImageProp, imageUrlValue, categoryVal
|
||||||
});
|
});
|
||||||
|
|
||||||
//Mock props
|
//Mock props
|
||||||
mountOptions.propsData = { displayGenericVehicleImage: displayGenericVehicleImageProp };
|
mountOptions.propsData = {
|
||||||
|
displayGenericVehicleImage: displayGenericVehicleImageProp,
|
||||||
|
displayUnmatchedVehicleIconProp: displayUnmatchedVehicleIconProp,
|
||||||
|
};
|
||||||
mountOptions.mixins = [mockMixin];
|
mountOptions.mixins = [mockMixin];
|
||||||
const wrapper = shallowMount(vehicleBanner, mountOptions);
|
const wrapper = shallowMount(vehicleBanner, mountOptions);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,16 @@ export default {
|
||||||
required: false,
|
required: false,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
displayUnmatchedVehicleIcon: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
vehicleCategory: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
vehicleImageToDisplay() {
|
vehicleImageToDisplay() {
|
||||||
|
|
@ -29,7 +39,8 @@ export default {
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
this.$store.getters.vehicle.imageUrl === null ||
|
this.$store.getters.vehicle.imageUrl === null ||
|
||||||
this.$store.getters.vehicle.imageUrl === "NULL"
|
this.$store.getters.vehicle.imageUrl === "NULL" ||
|
||||||
|
this.displayUnmatchedVehicleIcon
|
||||||
) {
|
) {
|
||||||
return this.getUnmatchedVehicleIcon();
|
return this.getUnmatchedVehicleIcon();
|
||||||
}
|
}
|
||||||
|
|
@ -57,7 +68,8 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getUnmatchedVehicleIcon() {
|
getUnmatchedVehicleIcon() {
|
||||||
switch (this.$store.getters.vehicle.category) {
|
const category = this.vehicleCategory ?? this.$store.getters.vehicle.category;
|
||||||
|
switch (category) {
|
||||||
case this.vehicleCategories.CAR:
|
case this.vehicleCategories.CAR:
|
||||||
return this.carUnmatchedVehicleIcon;
|
return this.carUnmatchedVehicleIcon;
|
||||||
case this.vehicleCategories.SUV:
|
case this.vehicleCategories.SUV:
|
||||||
|
|
|
||||||
|
|
@ -103,9 +103,6 @@ async function getLatestPageForRedirection() {
|
||||||
// If this is a non-CTA navigation, determine where to send the user based on page prerequisites.
|
// If this is a non-CTA navigation, determine where to send the user based on page prerequisites.
|
||||||
// This also works if a user has a 'fmg' start_type query string but no current order.
|
// This also works if a user has a 'fmg' start_type query string but no current order.
|
||||||
// That shouldn't happen, but it's possible.
|
// That shouldn't happen, but it's possible.
|
||||||
const vehicleMakeComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_MAKE);
|
|
||||||
const vehicleModelComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_MODEL);
|
|
||||||
const vehicleStyleComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_STYLE);
|
|
||||||
const vehicleDamageComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_DAMAGE);
|
const vehicleDamageComponent = await getLazyLoadedComponent(fmgPageValues.VEHICLE_DAMAGE);
|
||||||
const estimateComponent = await getLazyLoadedComponent(fmgPageValues.ESTIMATE);
|
const estimateComponent = await getLazyLoadedComponent(fmgPageValues.ESTIMATE);
|
||||||
const vinLookupComponent = await getLazyLoadedComponent(fmgPageValues.VIN_LOOKUP);
|
const vinLookupComponent = await getLazyLoadedComponent(fmgPageValues.VIN_LOOKUP);
|
||||||
|
|
@ -121,14 +118,8 @@ async function getLatestPageForRedirection() {
|
||||||
|
|
||||||
const skipVin = await skipVinLookup();
|
const skipVin = await skipVinLookup();
|
||||||
|
|
||||||
if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) {
|
if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) {
|
||||||
return fmgPageValues.VEHICLE_YEAR;
|
return fmgPageValues.VEHICLE;
|
||||||
} else if (!vehicleModelComponent.methods.arePagePrerequisitesValid()) {
|
|
||||||
return fmgPageValues.VEHICLE_MAKE;
|
|
||||||
} else if (!vehicleStyleComponent.methods.arePagePrerequisitesValid()) {
|
|
||||||
return fmgPageValues.VEHICLE_MODEL;
|
|
||||||
} else if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) {
|
|
||||||
return fmgPageValues.VEHICLE_STYLE;
|
|
||||||
} else if (!estimateComponent.methods.arePagePrerequisitesValid()) {
|
} else if (!estimateComponent.methods.arePagePrerequisitesValid()) {
|
||||||
return fmgPageValues.VEHICLE_DAMAGE;
|
return fmgPageValues.VEHICLE_DAMAGE;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -170,10 +161,7 @@ function overrideYmmsDirectionIfNeeded(toRoute) {
|
||||||
|
|
||||||
if (store.getters.payment.insuranceCoverage.isVerified) {
|
if (store.getters.payment.insuranceCoverage.isVerified) {
|
||||||
switch (fmgPageValue) {
|
switch (fmgPageValue) {
|
||||||
case fmgPageValues.VEHICLE_YEAR:
|
case fmgPageValues.VEHICLE: {
|
||||||
case fmgPageValues.VEHICLE_MAKE:
|
|
||||||
case fmgPageValues.VEHICLE_MODEL:
|
|
||||||
case fmgPageValues.VEHICLE_STYLE: {
|
|
||||||
return fmgPageValues.VEHICLE_DAMAGE;
|
return fmgPageValues.VEHICLE_DAMAGE;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ jest.mock("@/router/dynamic-routing/component-loader.js", () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe("getPageToRouteExistingOrderTo", () => {
|
describe("getPageToRouteExistingOrderTo", () => {
|
||||||
test("should return vehicle-year", async () => {
|
test("should return vehicle", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const toRoute = {
|
const toRoute = {
|
||||||
query: {},
|
query: {},
|
||||||
|
|
@ -31,75 +31,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
// Mock out the lazy load calls for all components.
|
||||||
mockLazyLoadComponentReturnValues({
|
mockLazyLoadComponentReturnValues({
|
||||||
[fmgPageValues.VEHICLE_MAKE]: false,
|
[fmgPageValues.VEHICLE]: true,
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(result).toBe(fmgPageValues.VEHICLE_YEAR);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("should return vehicle-make", async () => {
|
|
||||||
// Arrange
|
|
||||||
const toRoute = {
|
|
||||||
query: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
store.commit(storeMutations.UPDATE_IS_REPAIR, false);
|
|
||||||
store.commit(storeMutations.UPDATE_MAKE, "acura");
|
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
|
||||||
mockLazyLoadComponentReturnValues({
|
|
||||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
|
||||||
[fmgPageValues.VEHICLE_MODEL]: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(result).toBe(fmgPageValues.VEHICLE_MAKE);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("should return vehicle-model", async () => {
|
|
||||||
// Arrange
|
|
||||||
const toRoute = {
|
|
||||||
query: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
store.commit(storeMutations.UPDATE_IS_REPAIR, false);
|
|
||||||
store.commit(storeMutations.UPDATE_MAKE, "acura");
|
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
|
||||||
mockLazyLoadComponentReturnValues({
|
|
||||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
|
||||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
|
||||||
[fmgPageValues.VEHICLE_STYLE]: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(result).toBe(fmgPageValues.VEHICLE_MODEL);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("should return vehicle-style", async () => {
|
|
||||||
// Arrange
|
|
||||||
const toRoute = {
|
|
||||||
query: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
store.commit(storeMutations.UPDATE_IS_REPAIR, false);
|
|
||||||
store.commit(storeMutations.UPDATE_MAKE, "acura");
|
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
|
||||||
mockLazyLoadComponentReturnValues({
|
|
||||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
|
||||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
|
||||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
|
||||||
[fmgPageValues.VEHICLE_DAMAGE]: false,
|
[fmgPageValues.VEHICLE_DAMAGE]: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -107,7 +39,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
||||||
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(result).toBe(fmgPageValues.VEHICLE_STYLE);
|
expect(result).toBe(fmgPageValues.VEHICLE);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should return vehicle-damage", async () => {
|
test("should return vehicle-damage", async () => {
|
||||||
|
|
@ -121,9 +53,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
// Mock out the lazy load calls for all components.
|
||||||
mockLazyLoadComponentReturnValues({
|
mockLazyLoadComponentReturnValues({
|
||||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
[fmgPageValues.VEHICLE]: true,
|
||||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
|
||||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
|
||||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
[fmgPageValues.ESTIMATE]: false,
|
[fmgPageValues.ESTIMATE]: false,
|
||||||
});
|
});
|
||||||
|
|
@ -156,9 +86,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
// Mock out the lazy load calls for all components.
|
||||||
mockLazyLoadComponentReturnValues({
|
mockLazyLoadComponentReturnValues({
|
||||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
[fmgPageValues.VEHICLE]: true,
|
||||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
|
||||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
|
||||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
[fmgPageValues.ESTIMATE]: true,
|
[fmgPageValues.ESTIMATE]: true,
|
||||||
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||||
|
|
@ -186,9 +114,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
// Mock out the lazy load calls for all components.
|
||||||
mockLazyLoadComponentReturnValues({
|
mockLazyLoadComponentReturnValues({
|
||||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
[fmgPageValues.VEHICLE]: true,
|
||||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
|
||||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
|
||||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
[fmgPageValues.ESTIMATE]: true,
|
[fmgPageValues.ESTIMATE]: true,
|
||||||
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||||
|
|
@ -216,9 +142,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
// Mock out the lazy load calls for all components.
|
||||||
mockLazyLoadComponentReturnValues({
|
mockLazyLoadComponentReturnValues({
|
||||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
[fmgPageValues.VEHICLE]: true,
|
||||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
|
||||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
|
||||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
[fmgPageValues.ESTIMATE]: true,
|
[fmgPageValues.ESTIMATE]: true,
|
||||||
[fmgPageValues.CAPABILITY_QUESTIONS]: true,
|
[fmgPageValues.CAPABILITY_QUESTIONS]: true,
|
||||||
|
|
@ -246,9 +170,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
// Mock out the lazy load calls for all components.
|
||||||
mockLazyLoadComponentReturnValues({
|
mockLazyLoadComponentReturnValues({
|
||||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
[fmgPageValues.VEHICLE]: true,
|
||||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
|
||||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
|
||||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
[fmgPageValues.ESTIMATE]: true,
|
[fmgPageValues.ESTIMATE]: true,
|
||||||
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||||
|
|
@ -276,9 +198,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
// Mock out the lazy load calls for all components.
|
||||||
mockLazyLoadComponentReturnValues({
|
mockLazyLoadComponentReturnValues({
|
||||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
[fmgPageValues.VEHICLE]: true,
|
||||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
|
||||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
|
||||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
[fmgPageValues.ESTIMATE]: true,
|
[fmgPageValues.ESTIMATE]: true,
|
||||||
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||||
|
|
@ -306,9 +226,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
||||||
|
|
||||||
// Mock out the lazy load calls for all components.
|
// Mock out the lazy load calls for all components.
|
||||||
mockLazyLoadComponentReturnValues({
|
mockLazyLoadComponentReturnValues({
|
||||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
[fmgPageValues.VEHICLE]: true,
|
||||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
|
||||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
|
||||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||||
[fmgPageValues.ESTIMATE]: true,
|
[fmgPageValues.ESTIMATE]: true,
|
||||||
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,7 @@ export default {
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.dispatchStoreAction(this.storeActions.SAVE_WORK_ORDER_FLAG, true, false);
|
||||||
this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -263,6 +263,9 @@ describe("quote.vue", () => {
|
||||||
payment: {
|
payment: {
|
||||||
isInsurance: null,
|
isInsurance: null,
|
||||||
},
|
},
|
||||||
|
serviceLocation: {
|
||||||
|
state: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
wrapper.vm.$route = { query: { isInsurance: "true" } };
|
wrapper.vm.$route = { query: { isInsurance: "true" } };
|
||||||
|
|
@ -290,6 +293,9 @@ describe("quote.vue", () => {
|
||||||
payment: {
|
payment: {
|
||||||
isInsurance: null,
|
isInsurance: null,
|
||||||
},
|
},
|
||||||
|
serviceLocation: {
|
||||||
|
state: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
wrapper.vm.$route = { query: { isInsurance: "false" } };
|
wrapper.vm.$route = { query: { isInsurance: "false" } };
|
||||||
|
|
@ -317,6 +323,9 @@ describe("quote.vue", () => {
|
||||||
payment: {
|
payment: {
|
||||||
isInsurance: true,
|
isInsurance: true,
|
||||||
},
|
},
|
||||||
|
serviceLocation: {
|
||||||
|
state: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
// Ensure that query param isn't overriding selection
|
// Ensure that query param isn't overriding selection
|
||||||
|
|
@ -345,6 +354,9 @@ describe("quote.vue", () => {
|
||||||
payment: {
|
payment: {
|
||||||
isInsurance: false,
|
isInsurance: false,
|
||||||
},
|
},
|
||||||
|
serviceLocation: {
|
||||||
|
state: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
// Ensure that query param isn't overriding selection
|
// Ensure that query param isn't overriding selection
|
||||||
|
|
@ -374,6 +386,9 @@ describe("quote.vue", () => {
|
||||||
payment: {
|
payment: {
|
||||||
isInsurance: null, // Ensure that previous selection isn't overriding selection
|
isInsurance: null, // Ensure that previous selection isn't overriding selection
|
||||||
},
|
},
|
||||||
|
serviceLocation: {
|
||||||
|
state: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
mockTierOnePrice = 200;
|
mockTierOnePrice = 200;
|
||||||
|
|
@ -404,6 +419,9 @@ describe("quote.vue", () => {
|
||||||
payment: {
|
payment: {
|
||||||
isInsurance: null, // Ensure that previous selection isn't overriding selection
|
isInsurance: null, // Ensure that previous selection isn't overriding selection
|
||||||
},
|
},
|
||||||
|
serviceLocation: {
|
||||||
|
state: null,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
mockTierOnePrice = 505;
|
mockTierOnePrice = 505;
|
||||||
|
|
@ -421,6 +439,33 @@ describe("quote.vue", () => {
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.vm.isInsuranceSelected).toBe(true);
|
expect(wrapper.vm.isInsuranceSelected).toBe(true);
|
||||||
});
|
});
|
||||||
|
test("Should default to insurence if user Service zip is from certain States", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
store.getters = {
|
||||||
|
order: {
|
||||||
|
lineItems: {
|
||||||
|
glassParts: ["item", "item2"],
|
||||||
|
},
|
||||||
|
payment: {
|
||||||
|
isInsurance: null,
|
||||||
|
},
|
||||||
|
serviceLocation: {
|
||||||
|
state: "AZ",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
wrapper.vm.$route = { query: null };
|
||||||
|
//Act
|
||||||
|
await quote.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { fmgPage: "quote" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.vm.isInsuranceSelected).toBe(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks({ customMountOptions }) {
|
function setupMocks({ customMountOptions }) {
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ import { errorMessages } from "@/constants/error-messages";
|
||||||
import { Form, defineRule } from "vee-validate";
|
import { Form, defineRule } from "vee-validate";
|
||||||
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
||||||
import { applicationConfig } from "@/constants/application-config";
|
import { applicationConfig } from "@/constants/application-config";
|
||||||
|
import { payWithInsuranceStates } from "@/constants/pay-with-insurance-states";
|
||||||
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -154,11 +154,18 @@ export default {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
getDefaultIsInsuranceSelectedValue(availableLineItems) {
|
getDefaultIsInsuranceSelectedValue(availableLineItems) {
|
||||||
|
const serviceLocationState = store.getters.order.serviceLocation.state;
|
||||||
// Override if coming back from QuoteDetails. Remove override after Quote release
|
// Override if coming back from QuoteDetails. Remove override after Quote release
|
||||||
const isInsuranceOverrideValue = this.$route.query?.isInsurance;
|
const isInsuranceOverrideValue = this.$route.query?.isInsurance;
|
||||||
|
|
||||||
const defaultIsInsuranceSelectedValue = this.$store.getters.order.payment.isInsurance;
|
const defaultIsInsuranceSelectedValue = this.$store.getters.order.payment.isInsurance;
|
||||||
if (isInsuranceOverrideValue != null) {
|
//Default to Insurance Tab if user Service zip is from certain States
|
||||||
|
if (
|
||||||
|
serviceLocationState != null &&
|
||||||
|
payWithInsuranceStates.find((item) => item === serviceLocationState)
|
||||||
|
)
|
||||||
|
return true;
|
||||||
|
else if (isInsuranceOverrideValue != null) {
|
||||||
return isInsuranceOverrideValue == "true";
|
return isInsuranceOverrideValue == "true";
|
||||||
} else if (defaultIsInsuranceSelectedValue != null) {
|
} else if (defaultIsInsuranceSelectedValue != null) {
|
||||||
return defaultIsInsuranceSelectedValue;
|
return defaultIsInsuranceSelectedValue;
|
||||||
|
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
import makeQuestion from "@/layouts/vehicle-make/make-question/make-question";
|
|
||||||
import { shallowMount } from "@vue/test-utils";
|
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
|
||||||
import store from "@/store";
|
|
||||||
jest.mock(
|
|
||||||
"@/store",
|
|
||||||
() => {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
{ virtual: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
describe("make-question.vue", () => {
|
|
||||||
test("Selected make is emitted upon selection.", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({ modelValueProp: "honda" });
|
|
||||||
const makeToSelect = "ford";
|
|
||||||
|
|
||||||
//Act
|
|
||||||
wrapper.setValue({ selectedMake: makeToSelect });
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ selectedMake: "ford" }]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("make-question.vue", () => {
|
|
||||||
test("Data from store api are used as radio question answers.", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper, cmsContent } = setupMocks({
|
|
||||||
dataFromStoreApi: ["honda", "ford", "dodge"],
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
const initialData = makeQuestion.methods.loadInitialData.call(wrapper.vm);
|
|
||||||
makeQuestion.methods.initializeComponent.call(wrapper.vm, initialData);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
const buttonQuestionComponent = await wrapper.findComponent({
|
|
||||||
name: "buttonQuestion",
|
|
||||||
});
|
|
||||||
expect(buttonQuestionComponent.attributes("answers")).toBe("honda,ford,dodge");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
modelValueProp = "1900",
|
|
||||||
cmsQuestionText = "CMS text goes here",
|
|
||||||
dataFromStoreApi = [],
|
|
||||||
}) {
|
|
||||||
//Mock store
|
|
||||||
store.dispatch = jest.fn(() => dataFromStoreApi);
|
|
||||||
store.getters = { vehicle: { year: 2019 } };
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
store: {
|
|
||||||
dispatch: store.dispatch,
|
|
||||||
getters: store.getters,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
//Mock props
|
|
||||||
const mockMixin = {
|
|
||||||
methods: {
|
|
||||||
getCmsContent: jest.fn(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
mountOptions.propsData = {
|
|
||||||
modelValue: modelValueProp,
|
|
||||||
};
|
|
||||||
mountOptions.mixins = [mockMixin];
|
|
||||||
const wrapper = shallowMount(makeQuestion, mountOptions);
|
|
||||||
|
|
||||||
//Mock CMS content
|
|
||||||
const cmsContent = {
|
|
||||||
QuestionText: cmsQuestionText,
|
|
||||||
};
|
|
||||||
return { wrapper, cmsContent };
|
|
||||||
}
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
<template>
|
|
||||||
<buttonQuestion
|
|
||||||
class="radioQuestion"
|
|
||||||
isOverflowScrollable
|
|
||||||
selectingInitiatesLoad
|
|
||||||
:questionText="questionText"
|
|
||||||
:answers="makes"
|
|
||||||
groupName="ChooseVehicleMake"
|
|
||||||
textPosition="text-start"
|
|
||||||
v-model="selectedValue"
|
|
||||||
isRequired />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import buttonQuestion from "@/digital-components/button-question/button-question";
|
|
||||||
// Supporting files
|
|
||||||
import store from "@/store";
|
|
||||||
import { storeActions } from "@/constants/store-actions.js";
|
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "make-question",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
makes: [],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
modelValue: String,
|
|
||||||
cmsWidgetName: String,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
questionText() {
|
|
||||||
return this.getCmsContent(this.cmsWidgetName, "QuestionText");
|
|
||||||
},
|
|
||||||
selectedValue: {
|
|
||||||
get: function () {
|
|
||||||
return this.modelValue;
|
|
||||||
},
|
|
||||||
set: function (newValue) {
|
|
||||||
this.$emit("update:modelValue", newValue);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
buttonQuestion,
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadInitialData() {
|
|
||||||
return baseMixin.methods.dispatchStoreAction(storeActions.GET_VEHICLE_MAKES, {
|
|
||||||
year: store.getters.vehicle.year,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
initializeComponent(initialData) {
|
|
||||||
this.makes = initialData;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,228 +0,0 @@
|
||||||
// Supporting Files
|
|
||||||
import { shallowMount } from "@vue/test-utils";
|
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
|
||||||
import { nextTick } from "vue";
|
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
|
||||||
import store from "@/store";
|
|
||||||
|
|
||||||
// Components
|
|
||||||
import vehicleMake from "@/layouts/vehicle-make/vehicle-make.vue";
|
|
||||||
import makeQuestion from "@/layouts/vehicle-make/make-question/make-question";
|
|
||||||
|
|
||||||
jest.mock("@/store", () => ({
|
|
||||||
commit: jest.fn(),
|
|
||||||
dispatch: jest.fn(),
|
|
||||||
// getters: jest.fn().mockImplementation(() => ({
|
|
||||||
// vehicle: {
|
|
||||||
// year: 2019,
|
|
||||||
// },
|
|
||||||
// })),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Mock fetchCmsContentForPage
|
|
||||||
jest.mock("@/helpers/cms-content-helper", () => ({
|
|
||||||
fetchCmsContentForPage: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Mock our module for promises.
|
|
||||||
jest.mock("@/helpers/layout-helper.js", () => ({
|
|
||||||
settleAllPromises: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe("vehicle-make.vue", () => {
|
|
||||||
test("Make question component is initized with api data", async (done) => {
|
|
||||||
//Arrange
|
|
||||||
const makeQuestionInitialData = ["honda", "ford", "dodge"];
|
|
||||||
const { wrapper, apiPromise } = setupMocks({
|
|
||||||
makeQuestionInitialData: makeQuestionInitialData,
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
vehicleMake.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-make" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
apiPromise.finally(() => {
|
|
||||||
expect(makeQuestion.methods.initializeComponent).toHaveBeenCalledWith(
|
|
||||||
makeQuestionInitialData
|
|
||||||
);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("vehicle-make.vue", () => {
|
|
||||||
test("BackButtonAction triggers a router.navigateWithoutSaving change", async (done) => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper, apiPromise } = setupMocks({
|
|
||||||
pageHeaderWidgetHeaderText: "Select a make to get started",
|
|
||||||
mountOptionsMockData: {
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn(),
|
|
||||||
navigateWithoutSaving: jest.fn(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
vehicleMake.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-make" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
wrapper.vm.backButtonAction();
|
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
apiPromise.finally(() => {
|
|
||||||
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("vehicle-make.vue", () => {
|
|
||||||
describe("arePagePrerequisitesValue", () => {
|
|
||||||
test("Year set, arePagePrerequisitesValid should be true", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({
|
|
||||||
vehicleData: {
|
|
||||||
year: 2019,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
vehicleMake.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-make" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
|
|
||||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(arePagePrerequisitesValid).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("Year not set, arePagePrerequisitesValid should be false", async () => {
|
|
||||||
//Arrange
|
|
||||||
store.getters.vehicle.year = jest.fn().mockReturnValueOnce(undefined);
|
|
||||||
const { wrapper } = setupMocks({});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(arePagePrerequisitesValid).toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("selectedMake changes => save make in store", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn(),
|
|
||||||
navigateWithSaving: jest.fn(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await wrapper.setData({
|
|
||||||
selectedMake: "Make",
|
|
||||||
});
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalledTimes(1);
|
|
||||||
expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalledWith(
|
|
||||||
"saveVehicleMake",
|
|
||||||
"Make",
|
|
||||||
false
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("selectedMake changes => navigate with saving", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({
|
|
||||||
mountOptionsMockData: {
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn(),
|
|
||||||
navigateWithSaving: jest.fn(),
|
|
||||||
},
|
|
||||||
route: {
|
|
||||||
fmgPage: "test",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await wrapper.setData({
|
|
||||||
selectedMake: "Make",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledTimes(1);
|
|
||||||
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(
|
|
||||||
"SELECTED_MAKE",
|
|
||||||
expect.anything()
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
vehicleMakeQuestionCmsContent = {},
|
|
||||||
makeQuestionInitialData = {},
|
|
||||||
pageHeaderWidgetHeaderText = {},
|
|
||||||
mountOptionsMockData = {},
|
|
||||||
vehicleData = {},
|
|
||||||
}) {
|
|
||||||
//Mock api responses
|
|
||||||
const apiResponses = {
|
|
||||||
cmsContent: {
|
|
||||||
FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
|
|
||||||
VehicleMakeQuestion: vehicleMakeQuestionCmsContent,
|
|
||||||
VehicleBannerWidget: {
|
|
||||||
GenericVehicleImage:
|
|
||||||
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
|
|
||||||
},
|
|
||||||
FunnelHeaderWidget: {
|
|
||||||
LogoImage:
|
|
||||||
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
makeQuestionInitialData: makeQuestionInitialData,
|
|
||||||
};
|
|
||||||
|
|
||||||
const apiPromise = Promise.resolve(apiResponses);
|
|
||||||
|
|
||||||
store.getters = {
|
|
||||||
vehicle: vehicleData,
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
|
||||||
settleAllPromises.mockImplementation(() => apiPromise);
|
|
||||||
|
|
||||||
//Mock make question methods
|
|
||||||
makeQuestion.methods = {
|
|
||||||
loadInitialData: jest.fn(),
|
|
||||||
initializeComponent: jest.fn(),
|
|
||||||
};
|
|
||||||
|
|
||||||
const mountOptions = getMountOptions(mountOptionsMockData);
|
|
||||||
const wrapper = shallowMount(vehicleMake, mountOptions);
|
|
||||||
const makeQuestionWrapper = wrapper.findComponent({ name: "makeQuestion" });
|
|
||||||
makeQuestionWrapper.vm.initializeComponent = makeQuestion.methods.initializeComponent;
|
|
||||||
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
|
|
||||||
|
|
||||||
return { wrapper, apiPromise };
|
|
||||||
}
|
|
||||||
|
|
@ -1,95 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="page-container-grouped-styles">
|
|
||||||
<funnelHeader cmsWidgetName="FunnelHeaderWidget" />
|
|
||||||
<div class="select-car">
|
|
||||||
<div class="select-car-form rounded text-center">
|
|
||||||
<vehicleBanner cmsWidgetName="VehicleBannerWidget" displayGenericVehicleImage />
|
|
||||||
<funnelSubHeader
|
|
||||||
cmsWidgetName="FunnelSubHeaderWidget"
|
|
||||||
:hasBackButton="true"
|
|
||||||
@click-event="backButtonAction"
|
|
||||||
headerColor="light-header" />
|
|
||||||
<div class="fade-on-route-transition">
|
|
||||||
<makeQuestion
|
|
||||||
v-model="selectedMake"
|
|
||||||
ref="makeQuestion"
|
|
||||||
cmsWidgetName="VehicleMakeQuestion" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Components
|
|
||||||
import makeQuestion from "@/layouts/vehicle-make/make-question/make-question";
|
|
||||||
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
|
||||||
import vehicleBanner from "@/fmg-components/vehicle-banner/vehicle-banner";
|
|
||||||
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
|
||||||
// Supporting files
|
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
|
||||||
import { storeActions } from "@/constants/store-actions";
|
|
||||||
import store from "@/store";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "vehicle-make",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
selectedMake: null,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {},
|
|
||||||
|
|
||||||
async beforeRouteEnter(to, from, next) {
|
|
||||||
// Call APIs
|
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
|
||||||
const makeQuestionInitialDataPromise = makeQuestion.methods.loadInitialData();
|
|
||||||
|
|
||||||
// Settle promises and get results
|
|
||||||
const promiseResultMap = [
|
|
||||||
{
|
|
||||||
resultKey: "cmsContent",
|
|
||||||
promise: cmsContentPromise,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
resultKey: "makeQuestionInitialData",
|
|
||||||
promise: makeQuestionInitialDataPromise,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
|
||||||
// Call the "next" function to complete the transition to this page.
|
|
||||||
next((vm) => {
|
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
|
||||||
vm.$refs.makeQuestion.initializeComponent(resultMap.makeQuestionInitialData);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
backButtonAction() {
|
|
||||||
// route to move backwards
|
|
||||||
this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
|
|
||||||
},
|
|
||||||
arePagePrerequisitesValid() {
|
|
||||||
if (store.getters.vehicle.year) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
selectedMake(make) {
|
|
||||||
this.dispatchStoreAction(storeActions.SAVE_VEHICLE_MAKE, make, false);
|
|
||||||
this.$router.navigateWithSaving(this.navigationScenarios.SELECTED_MAKE, this.$route);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
makeQuestion,
|
|
||||||
funnelHeader,
|
|
||||||
vehicleBanner,
|
|
||||||
funnelSubHeader,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
import modelQuestion from "@/layouts/vehicle-model/model-question/model-question";
|
|
||||||
import { shallowMount } from "@vue/test-utils";
|
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
|
||||||
import store from "@/store";
|
|
||||||
jest.mock(
|
|
||||||
"@/store",
|
|
||||||
() => {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
{ virtual: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
describe("model-question.vue", () => {
|
|
||||||
test("Selected model is emitted upon selection.", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({ modelValueProp: "Accord" });
|
|
||||||
const modelToSelect = "Civic";
|
|
||||||
|
|
||||||
//Act
|
|
||||||
wrapper.setValue({ selectedModel: modelToSelect });
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ selectedModel: "Civic" }]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("model-question.vue", () => {
|
|
||||||
test("Data from store api are used as radio question answers.", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper, cmsContent } = setupMocks({
|
|
||||||
dataFromStoreApi: ["accord", "civic", "insight"],
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
const initialData = modelQuestion.methods.loadInitialData.call(wrapper.vm);
|
|
||||||
modelQuestion.methods.initializeComponent.call(wrapper.vm, initialData);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
const buttonQuestionComponent = await wrapper.findComponent({
|
|
||||||
name: "buttonQuestion",
|
|
||||||
});
|
|
||||||
expect(buttonQuestionComponent.attributes("answers")).toBe("accord,civic,insight");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
modelValueProp = "1900",
|
|
||||||
cmsQuestionText = "CMS text goes here",
|
|
||||||
dataFromStoreApi = [],
|
|
||||||
}) {
|
|
||||||
//Mock store
|
|
||||||
store.dispatch = jest.fn(() => dataFromStoreApi);
|
|
||||||
store.getters = { vehicle: { year: 2019, make: "honda" } };
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
store: {
|
|
||||||
dispatch: store.dispatch,
|
|
||||||
getters: store.getters,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
//Mock props
|
|
||||||
const mockMixin = {
|
|
||||||
methods: {
|
|
||||||
getCmsContent: jest.fn(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
mountOptions.propsData = {
|
|
||||||
modelValue: modelValueProp,
|
|
||||||
};
|
|
||||||
mountOptions.mixins = [mockMixin];
|
|
||||||
const wrapper = shallowMount(modelQuestion, mountOptions);
|
|
||||||
|
|
||||||
//Mock CMS content
|
|
||||||
const cmsContent = {
|
|
||||||
QuestionText: cmsQuestionText,
|
|
||||||
};
|
|
||||||
return { wrapper, cmsContent };
|
|
||||||
}
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
<template>
|
|
||||||
<buttonQuestion
|
|
||||||
class="radioQuestion"
|
|
||||||
isOverflowScrollable
|
|
||||||
selectingInitiatesLoad
|
|
||||||
:questionText="questionText"
|
|
||||||
:answers="models"
|
|
||||||
groupName="ChooseVehicleModel"
|
|
||||||
textPosition="text-start"
|
|
||||||
v-model="selectedValue"
|
|
||||||
isRequired />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import buttonQuestion from "@/digital-components/button-question/button-question";
|
|
||||||
// Supporting files
|
|
||||||
import store from "@/store";
|
|
||||||
import { storeActions } from "@/constants/store-actions.js";
|
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "model-question",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
models: [],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
modelValue: String,
|
|
||||||
cmsWidgetName: String,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
questionText() {
|
|
||||||
return this.getCmsContent(this.cmsWidgetName, "QuestionText");
|
|
||||||
},
|
|
||||||
selectedValue: {
|
|
||||||
get: function () {
|
|
||||||
return this.modelValue;
|
|
||||||
},
|
|
||||||
set: function (newValue) {
|
|
||||||
this.$emit("update:modelValue", newValue);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
buttonQuestion,
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadInitialData() {
|
|
||||||
return baseMixin.methods.dispatchStoreAction(storeActions.GET_VEHICLE_MODELS, {
|
|
||||||
year: store.getters.vehicle.year,
|
|
||||||
make: store.getters.vehicle.make,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
initializeComponent(initialData) {
|
|
||||||
this.models = initialData;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
// Components
|
|
||||||
import vehicleModel from "@/layouts/vehicle-model/vehicle-model.vue";
|
|
||||||
import modelQuestion from "@/layouts/vehicle-model/model-question/model-question";
|
|
||||||
|
|
||||||
// Supporting files
|
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
|
||||||
import { shallowMount } from "@vue/test-utils";
|
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
|
||||||
import { nextTick } from "vue";
|
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
|
||||||
|
|
||||||
// Mock our module for promises.
|
|
||||||
jest.mock("@/helpers/layout-helper.js", () => ({
|
|
||||||
settleAllPromises: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Mock fetchCmsContentForPage
|
|
||||||
jest.mock("@/helpers/cms-content-helper", () => ({
|
|
||||||
fetchCmsContentForPage: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Mock Store
|
|
||||||
jest.mock("@/store", () => ({
|
|
||||||
commit: jest.fn(),
|
|
||||||
dispatch: jest.fn(),
|
|
||||||
getters: {
|
|
||||||
vehicle: {
|
|
||||||
make: "Acura",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe("vehicle-model.vue", () => {
|
|
||||||
test("Model question component is initized with api data", async (done) => {
|
|
||||||
//Arange
|
|
||||||
const modelQuestionInitialData = ["accord", "civic", "insight"];
|
|
||||||
const { wrapper, apiPromise } = setupMocks({
|
|
||||||
modelQuestionInitialData: modelQuestionInitialData,
|
|
||||||
});
|
|
||||||
//Act
|
|
||||||
vehicleModel.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-model" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
//Assert
|
|
||||||
apiPromise.finally(() => {
|
|
||||||
expect(modelQuestion.methods.initializeComponent).toHaveBeenCalledWith(
|
|
||||||
modelQuestionInitialData
|
|
||||||
);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("vehicle-model.vue", () => {
|
|
||||||
test("BackButtonAction triggers a router.navigateWithoutSaving change", async (done) => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper, apiPromise } = setupMocks({
|
|
||||||
pageHeaderWidgetHeaderText: "Select a model to get started",
|
|
||||||
mountOptionsMockData: {
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn(),
|
|
||||||
navigateWithoutSaving: jest.fn(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
//Act
|
|
||||||
vehicleModel.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-model" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
wrapper.vm.backButtonAction();
|
|
||||||
await nextTick();
|
|
||||||
//Assert
|
|
||||||
apiPromise.finally(() => {
|
|
||||||
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe("vehicle-model.vue", () => {
|
|
||||||
test("Make set, arePagePrerequisitesValid should be true ", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
vehicleModel.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-model" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
|
|
||||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(arePagePrerequisitesValid).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
buttonQuestionContent = {},
|
|
||||||
modelQuestionInitialData = {},
|
|
||||||
pageHeaderWidgetHeaderText = {},
|
|
||||||
mountOptionsMockData = {},
|
|
||||||
}) {
|
|
||||||
//Mock api responses
|
|
||||||
const apiResponses = {
|
|
||||||
cmsContent: {
|
|
||||||
FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
|
|
||||||
VehicleModelQuestion: buttonQuestionContent,
|
|
||||||
VehicleBannerWidget: {
|
|
||||||
GenericVehicleImage:
|
|
||||||
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
|
|
||||||
},
|
|
||||||
FunnelHeaderWidget: {
|
|
||||||
LogoImage:
|
|
||||||
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
modelQuestionInitialData: modelQuestionInitialData,
|
|
||||||
};
|
|
||||||
const apiPromise = Promise.resolve(apiResponses);
|
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiPromise);
|
|
||||||
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
|
||||||
|
|
||||||
//Mock model question methods
|
|
||||||
modelQuestion.methods = {
|
|
||||||
loadInitialData: jest.fn(),
|
|
||||||
initializeComponent: jest.fn(),
|
|
||||||
};
|
|
||||||
const mountOptions = getMountOptions(mountOptionsMockData);
|
|
||||||
const wrapper = shallowMount(vehicleModel, mountOptions);
|
|
||||||
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
|
|
||||||
|
|
||||||
const modelQuestionWrapper = wrapper.findComponent({ name: "modelQuestion" });
|
|
||||||
modelQuestionWrapper.vm.initializeComponent = modelQuestion.methods.initializeComponent;
|
|
||||||
|
|
||||||
return { wrapper, apiPromise };
|
|
||||||
}
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="page-container-grouped-styles">
|
|
||||||
<funnelHeader cmsWidgetName="FunnelHeaderWidget" />
|
|
||||||
<div class="select-car">
|
|
||||||
<div class="select-car-form rounded text-center">
|
|
||||||
<vehicleBanner cmsWidgetName="VehicleBannerWidget" displayGenericVehicleImage />
|
|
||||||
<funnelSubHeader
|
|
||||||
cmsWidgetName="FunnelSubHeaderWidget"
|
|
||||||
:hasBackButton="true"
|
|
||||||
@click-event="backButtonAction"
|
|
||||||
headerColor="light-header" />
|
|
||||||
<div class="fade-on-route-transition">
|
|
||||||
<modelQuestion
|
|
||||||
v-model="selectedModel"
|
|
||||||
ref="modelQuestion"
|
|
||||||
cmsWidgetName="VehicleModelQuestion" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Components
|
|
||||||
import modelQuestion from "@/layouts/vehicle-model/model-question/model-question";
|
|
||||||
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
|
||||||
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
|
||||||
import vehicleBanner from "@/fmg-components/vehicle-banner/vehicle-banner";
|
|
||||||
// Supporting files
|
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
|
||||||
import { storeMutations } from "@/constants/store-mutations";
|
|
||||||
import { storeActions } from "@/constants/store-actions";
|
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
|
||||||
import store from "@/store";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "vehicle-model",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
selectedModel: null,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {},
|
|
||||||
|
|
||||||
async beforeRouteEnter(to, from, next) {
|
|
||||||
// Call APIs
|
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
|
||||||
const modelQuestionInitialDataPromise = modelQuestion.methods.loadInitialData();
|
|
||||||
|
|
||||||
// Settle promises and get results
|
|
||||||
const promiseResultMap = [
|
|
||||||
{
|
|
||||||
resultKey: "cmsContent",
|
|
||||||
promise: cmsContentPromise,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
resultKey: "modelQuestionInitialData",
|
|
||||||
promise: modelQuestionInitialDataPromise,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
|
||||||
|
|
||||||
// Call the "next" function to complete the transition to this page.
|
|
||||||
next((vm) => {
|
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
|
||||||
vm.$refs.modelQuestion.initializeComponent(resultMap.modelQuestionInitialData);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
backButtonAction() {
|
|
||||||
// route to move backwards
|
|
||||||
this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
|
|
||||||
},
|
|
||||||
arePagePrerequisitesValid() {
|
|
||||||
if (store.getters.vehicle.make) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
selectedModel(model) {
|
|
||||||
this.dispatchStoreAction(storeActions.SAVE_VEHICLE_MODEL, model, false);
|
|
||||||
this.$router.navigateWithSaving(this.navigationScenarios.SELECTED_MODEL, this.$route);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
modelQuestion,
|
|
||||||
funnelHeader,
|
|
||||||
funnelSubHeader,
|
|
||||||
vehicleBanner,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
import styleQuestion from "@/layouts/vehicle-style/style-question/style-question";
|
|
||||||
import { shallowMount } from "@vue/test-utils";
|
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
|
||||||
import store from "@/store";
|
|
||||||
jest.mock(
|
|
||||||
"@/store",
|
|
||||||
() => {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
{ virtual: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
describe("style-question.vue", () => {
|
|
||||||
test("Selected style is emitted upon selection.", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({ modelValueProp: "2 Door" });
|
|
||||||
const styleToSelect = "4 Door";
|
|
||||||
|
|
||||||
//Act
|
|
||||||
wrapper.setValue({ selectedStyle: styleToSelect });
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ selectedStyle: "4 Door" }]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("style-question.vue", () => {
|
|
||||||
test("Data from store api are used as radio question answers.", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper, cmsContent } = setupMocks({
|
|
||||||
dataFromStoreApi: ["2 Door", "4 Door"],
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
const initialData = styleQuestion.methods.loadInitialData.call(wrapper.vm);
|
|
||||||
styleQuestion.methods.initializeComponent.call(wrapper.vm, initialData);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
const buttonQuestionComponent = await wrapper.findComponent({
|
|
||||||
name: "buttonQuestion",
|
|
||||||
});
|
|
||||||
expect(buttonQuestionComponent.attributes("answers")).toBe("2 Door,4 Door");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
modelValueProp = "1900",
|
|
||||||
cmsQuestionText = "CMS text goes here",
|
|
||||||
dataFromStoreApi = [],
|
|
||||||
}) {
|
|
||||||
//Mock store
|
|
||||||
store.dispatch = jest.fn(() => dataFromStoreApi);
|
|
||||||
store.getters = { vehicle: { year: 2019, make: "honda", model: "civc" } };
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
store: {
|
|
||||||
dispatch: store.dispatch,
|
|
||||||
getters: store.getters,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
//Mock props
|
|
||||||
const mockMixin = {
|
|
||||||
methods: {
|
|
||||||
getCmsContent: jest.fn(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
mountOptions.propsData = {
|
|
||||||
modelValue: modelValueProp,
|
|
||||||
};
|
|
||||||
mountOptions.mixins = [mockMixin];
|
|
||||||
const wrapper = shallowMount(styleQuestion, mountOptions);
|
|
||||||
|
|
||||||
//Mock CMS content
|
|
||||||
const cmsContent = {
|
|
||||||
QuestionText: cmsQuestionText,
|
|
||||||
};
|
|
||||||
return { wrapper, cmsContent };
|
|
||||||
}
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
<template>
|
|
||||||
<buttonQuestion
|
|
||||||
class="radioQuestion"
|
|
||||||
isOverflowScrollable
|
|
||||||
selectingInitiatesLoad
|
|
||||||
:questionText="questionText"
|
|
||||||
:answers="styles"
|
|
||||||
groupName="ChooseVehicleStyle"
|
|
||||||
textPosition="text-start"
|
|
||||||
v-model="selectedValue"
|
|
||||||
isRequired />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import buttonQuestion from "@/digital-components/button-question/button-question";
|
|
||||||
// Supporting files
|
|
||||||
import store from "@/store";
|
|
||||||
import { storeActions } from "@/constants/store-actions.js";
|
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "style-question",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
styles: [],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
modelValue: String,
|
|
||||||
cmsWidgetName: String,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
questionText() {
|
|
||||||
return this.getCmsContent(this.cmsWidgetName, "QuestionText");
|
|
||||||
},
|
|
||||||
selectedValue: {
|
|
||||||
get: function () {
|
|
||||||
return this.modelValue;
|
|
||||||
},
|
|
||||||
set: function (newValue) {
|
|
||||||
this.$emit("update:modelValue", newValue);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
buttonQuestion,
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadInitialData() {
|
|
||||||
return baseMixin.methods.dispatchStoreAction(storeActions.GET_VEHICLE_STYLES, {
|
|
||||||
year: store.getters.vehicle.year,
|
|
||||||
make: store.getters.vehicle.make,
|
|
||||||
model: store.getters.vehicle.model,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
initializeComponent(initialData) {
|
|
||||||
this.styles = initialData;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,256 +0,0 @@
|
||||||
// Components
|
|
||||||
import vehicleStyle from "@/layouts/vehicle-style/vehicle-style.vue";
|
|
||||||
import styleQuestion from "@/layouts/vehicle-style/style-question/style-question";
|
|
||||||
|
|
||||||
// Supporting files
|
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
|
||||||
import { nextTick } from "vue";
|
|
||||||
import { shallowMount } from "@vue/test-utils";
|
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
|
||||||
import { storeActions } from "@/constants/store-actions";
|
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
|
||||||
import router from "@/router";
|
|
||||||
import store from "@/store";
|
|
||||||
import { storeMutations } from "@/constants/store-mutations";
|
|
||||||
|
|
||||||
// Mock our module for promises.
|
|
||||||
jest.mock("@/helpers/layout-helper.js", () => ({
|
|
||||||
settleAllPromises: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Mock fetchCmsContentForPage
|
|
||||||
jest.mock("@/helpers/cms-content-helper", () => ({
|
|
||||||
fetchCmsContentForPage: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Mock fetchCmsContentForPage
|
|
||||||
jest.mock("@/router", () => ({
|
|
||||||
overrideNavigation: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe("vehicle-style.vue", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("Style question component is initized with api data", async (done) => {
|
|
||||||
//Arrange
|
|
||||||
const styleQuestionInitialData = ["2 Door", "4 Door"];
|
|
||||||
const { wrapper, apiPromise } = setupMocks({
|
|
||||||
styleQuestionInitialData: styleQuestionInitialData,
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
vehicleStyle.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-style" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
apiPromise.finally(() => {
|
|
||||||
expect(styleQuestion.methods.initializeComponent).toHaveBeenCalledWith(
|
|
||||||
styleQuestionInitialData
|
|
||||||
);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("BackButtonAction triggers a router.navigateWithoutSaving change", async (done) => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper, apiPromise } = setupMocks({
|
|
||||||
pageHeaderWidgetHeaderText: "Select a style to get started",
|
|
||||||
mountOptionsMockData: {
|
|
||||||
router: {
|
|
||||||
navigate: jest.fn(),
|
|
||||||
navigateWithSaving: jest.fn(),
|
|
||||||
navigateWithoutSaving: jest.fn(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
vehicleStyle.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-style" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
wrapper.vm.backButtonAction();
|
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
apiPromise.finally(() => {
|
|
||||||
expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("setVehicle triggers a dispatchStoreAction commit", async (done) => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper, apiPromise } = setupMocks({
|
|
||||||
pageHeaderWidgetHeaderText: "Select a style to get started",
|
|
||||||
mountOptionsMockData: {
|
|
||||||
actionList: [
|
|
||||||
{
|
|
||||||
actionName: storeActions.SET_VEHICLE,
|
|
||||||
data: "mockData",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
vehicleStyle.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-style" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
wrapper.vm.setVehicle();
|
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
apiPromise.finally(() => {
|
|
||||||
expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalled();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("Model set, arePagePrerequisitesValid should be true ", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
vehicleStyle.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-style" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
|
|
||||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(arePagePrerequisitesValid).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("there is only one vehicle style => autoselect and move to vehicle damage", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({
|
|
||||||
styleQuestionInitialData: ["2 door sedan"],
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await vehicleStyle.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-style" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_STYLE, "2 door sedan");
|
|
||||||
expect(router.overrideNavigation).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
test("there is only one vehicle style and vehicle-damage was visited => don't autoselect or move to vehicle damage", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({
|
|
||||||
styleQuestionInitialData: ["2 door sedan"],
|
|
||||||
mountOptionsMockData: {
|
|
||||||
store: {
|
|
||||||
getters: {
|
|
||||||
applicationUser: {
|
|
||||||
pageData: {
|
|
||||||
"part-questions": null,
|
|
||||||
"vehicle-make": {},
|
|
||||||
"vehicle-model": {},
|
|
||||||
"vehicle-style": {},
|
|
||||||
"vehicle-damage": {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await vehicleStyle.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-style" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(store.commit).not.toHaveBeenCalledWith(storeMutations.UPDATE_STYLE, "2 door sedan");
|
|
||||||
expect(router.overrideNavigation).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
vehicleStyleQuestionCmsContent = {},
|
|
||||||
styleQuestionInitialData = {},
|
|
||||||
pageHeaderWidgetHeaderText = {},
|
|
||||||
mountOptionsMockData = {},
|
|
||||||
}) {
|
|
||||||
//Mock api responses
|
|
||||||
const apiResponses = {
|
|
||||||
cmsContent: {
|
|
||||||
FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
|
|
||||||
VehicleStyleQuestion: vehicleStyleQuestionCmsContent,
|
|
||||||
VehicleBannerWidget: {
|
|
||||||
GenericVehicleImage:
|
|
||||||
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
|
|
||||||
},
|
|
||||||
FunnelHeaderWidget: {
|
|
||||||
LogoImage:
|
|
||||||
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
styleQuestionInitialData: styleQuestionInitialData,
|
|
||||||
};
|
|
||||||
|
|
||||||
const apiPromise = Promise.resolve(apiResponses);
|
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiPromise);
|
|
||||||
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
|
||||||
|
|
||||||
//Mock style question methods
|
|
||||||
styleQuestion.methods = {
|
|
||||||
loadInitialData: jest.fn(),
|
|
||||||
initializeComponent: jest.fn(),
|
|
||||||
};
|
|
||||||
|
|
||||||
store.commit = jest.fn();
|
|
||||||
store.dispatch = jest.fn();
|
|
||||||
store.getters = mountOptionsMockData.store?.getters ?? {
|
|
||||||
vehicle: {
|
|
||||||
model: "TL",
|
|
||||||
},
|
|
||||||
applicationUser: {
|
|
||||||
pageData: {
|
|
||||||
"part-questions": null,
|
|
||||||
"vehicle-make": {},
|
|
||||||
"vehicle-model": {},
|
|
||||||
"vehicle-style": {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
...mountOptionsMockData,
|
|
||||||
store,
|
|
||||||
});
|
|
||||||
const wrapper = shallowMount(vehicleStyle, mountOptions);
|
|
||||||
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
|
|
||||||
|
|
||||||
const styleQuestionWrapper = wrapper.findComponent({ name: "styleQuestion" });
|
|
||||||
styleQuestionWrapper.vm.initializeComponent = styleQuestion.methods.initializeComponent;
|
|
||||||
|
|
||||||
return { wrapper, apiPromise };
|
|
||||||
}
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="page-container-grouped-styles">
|
|
||||||
<funnelHeader cmsWidgetName="FunnelHeaderWidget" />
|
|
||||||
<div class="select-car">
|
|
||||||
<div class="select-car-form rounded text-center">
|
|
||||||
<vehicleBanner cmsWidgetName="VehicleBannerWidget" displayGenericVehicleImage />
|
|
||||||
<funnelSubHeader
|
|
||||||
cmsWidgetName="FunnelSubHeaderWidget"
|
|
||||||
:hasBackButton="true"
|
|
||||||
@click-event="backButtonAction"
|
|
||||||
headerColor="light-header" />
|
|
||||||
<div class="fade-on-route-transition">
|
|
||||||
<styleQuestion
|
|
||||||
v-model="selectedStyle"
|
|
||||||
ref="styleQuestion"
|
|
||||||
cmsWidgetName="VehicleStyleQuestion" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Components
|
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
|
||||||
import styleQuestion from "@/layouts/vehicle-style/style-question/style-question";
|
|
||||||
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
|
||||||
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
|
||||||
import vehicleBanner from "@/fmg-components/vehicle-banner/vehicle-banner";
|
|
||||||
|
|
||||||
// Supporting files
|
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
|
||||||
import { storeActions } from "@/constants/store-actions";
|
|
||||||
import store from "@/store";
|
|
||||||
import { storeMutations } from "@/constants/store-mutations";
|
|
||||||
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
|
|
||||||
import router from "@/router";
|
|
||||||
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "vehicle-style",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
selectedStyle: null,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {},
|
|
||||||
|
|
||||||
async beforeRouteEnter(to, from, next) {
|
|
||||||
// Call APIs
|
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
|
||||||
const styleQuestionInitialDataPromise = styleQuestion.methods.loadInitialData();
|
|
||||||
|
|
||||||
// Settle promises and get results
|
|
||||||
const promiseResultMap = [
|
|
||||||
{
|
|
||||||
resultKey: "cmsContent",
|
|
||||||
promise: cmsContentPromise,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
resultKey: "styleQuestionInitialData",
|
|
||||||
promise: styleQuestionInitialDataPromise,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
|
||||||
const visitedVehicleDamage =
|
|
||||||
JSON.stringify(store.getters.applicationUser.pageData).indexOf(
|
|
||||||
fmgPageValues.VEHICLE_DAMAGE
|
|
||||||
) < 0
|
|
||||||
? false
|
|
||||||
: true;
|
|
||||||
|
|
||||||
// If we have exactly one style then navigate directly to vehicle-damage
|
|
||||||
if (resultMap.styleQuestionInitialData.length === 1 && !visitedVehicleDamage) {
|
|
||||||
store.commit(storeMutations.UPDATE_STYLE, resultMap.styleQuestionInitialData[0]);
|
|
||||||
|
|
||||||
await baseMixin.methods.dispatchStoreAction(storeActions.SET_VEHICLE, {
|
|
||||||
year: store.getters.vehicle.year,
|
|
||||||
make: store.getters.vehicle.make,
|
|
||||||
model: store.getters.vehicle.model,
|
|
||||||
style: store.getters.vehicle.style,
|
|
||||||
});
|
|
||||||
|
|
||||||
//emulate selecting the vehicle style
|
|
||||||
router.overrideNavigation(navigationScenarios.SELECTED_STYLE, to, next, true);
|
|
||||||
} else {
|
|
||||||
next((vm) => {
|
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
|
||||||
vm.$refs.styleQuestion.initializeComponent(resultMap.styleQuestionInitialData);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
backButtonAction() {
|
|
||||||
// route to move backwards
|
|
||||||
this.$router.navigateWithoutSaving(this.navigationScenarios.CLICKED_BACK, this.$route);
|
|
||||||
},
|
|
||||||
setVehicle() {
|
|
||||||
return this.dispatchStoreAction(this.storeActions.SET_VEHICLE, {
|
|
||||||
year: this.$store.getters.vehicle.year,
|
|
||||||
make: this.$store.getters.vehicle.make,
|
|
||||||
model: this.$store.getters.vehicle.model,
|
|
||||||
style: this.$store.getters.vehicle.style,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
arePagePrerequisitesValid() {
|
|
||||||
if (store.getters.vehicle.model) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
selectedStyle(style) {
|
|
||||||
this.dispatchStoreAction(storeActions.SAVE_VEHICLE_STYLE, style, false);
|
|
||||||
this.setVehicle().then(() => {
|
|
||||||
this.$router.navigateWithSaving(
|
|
||||||
this.navigationScenarios.SELECTED_STYLE,
|
|
||||||
this.$route
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
styleQuestion,
|
|
||||||
funnelHeader,
|
|
||||||
funnelSubHeader,
|
|
||||||
vehicleBanner,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
import { shallowMount, flushPromises } from "@vue/test-utils";
|
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
|
||||||
import { nextTick } from "vue";
|
|
||||||
import { storeMutations } from "@/constants/store-mutations";
|
|
||||||
import { storeActions } from "@/constants/store-actions";
|
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
|
||||||
|
|
||||||
import vehicleYear from "@/layouts/vehicle-year/vehicle-year.vue";
|
|
||||||
import yearQuestion from "@/layouts/vehicle-year/year-question/year-question";
|
|
||||||
|
|
||||||
import store from "@/store";
|
|
||||||
|
|
||||||
jest.mock("@/store", () => ({
|
|
||||||
commit: jest.fn(),
|
|
||||||
dispatch: jest.fn(),
|
|
||||||
getters: {
|
|
||||||
applicationUser: {
|
|
||||||
experiments: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Mock our module for promises.
|
|
||||||
jest.mock("@/helpers/layout-helper.js", () => ({
|
|
||||||
settleAllPromises: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Mock fetchCmsContentForPage
|
|
||||||
jest.mock("@/helpers/cms-content-helper", () => ({
|
|
||||||
fetchCmsContentForPage: jest.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe("vehicle-year.vue", () => {
|
|
||||||
test("Year question component is initized with api data", async (done) => {
|
|
||||||
//Arrange
|
|
||||||
const yearQuestionInitialData = ["2023", "2022", "2021"];
|
|
||||||
const { wrapper, apiPromise } = setupMocks({
|
|
||||||
yearQuestionInitialData: yearQuestionInitialData,
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
vehicleYear.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-year" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
apiPromise.finally(() => {
|
|
||||||
expect(yearQuestion.methods.initializeComponent).toHaveBeenCalledWith(
|
|
||||||
yearQuestionInitialData
|
|
||||||
);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("vehicle-year.vue", () => {
|
|
||||||
test("arePagePrerequisitesValid should be true ", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
vehicleYear.beforeRouteEnter.call(
|
|
||||||
wrapper.vm,
|
|
||||||
{ query: { fmgPage: "vehicle-make" } },
|
|
||||||
undefined,
|
|
||||||
(c) => c(wrapper.vm)
|
|
||||||
);
|
|
||||||
|
|
||||||
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(arePagePrerequisitesValid).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
vehicleYearQuestionCmsContent = {},
|
|
||||||
yearQuestionInitialData = {},
|
|
||||||
pageHeaderWidgetHeaderText = {},
|
|
||||||
mountOptionsMockData = {},
|
|
||||||
}) {
|
|
||||||
//Mock api responses
|
|
||||||
const apiResponses = {
|
|
||||||
cmsContent: {
|
|
||||||
FunnelSubHeaderWidget: { HeaderText: pageHeaderWidgetHeaderText },
|
|
||||||
VehicleYearQuestion: vehicleYearQuestionCmsContent,
|
|
||||||
VehicleBannerWidget: {
|
|
||||||
GenericVehicleImage:
|
|
||||||
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
|
|
||||||
},
|
|
||||||
FunnelHeaderWidget: {
|
|
||||||
LogoImage:
|
|
||||||
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
yearQuestionInitialData: yearQuestionInitialData,
|
|
||||||
};
|
|
||||||
const apiPromise = Promise.resolve(apiResponses);
|
|
||||||
|
|
||||||
settleAllPromises.mockImplementation(() => apiPromise);
|
|
||||||
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
|
||||||
|
|
||||||
//Mock year question methods
|
|
||||||
yearQuestion.methods = {
|
|
||||||
loadInitialData: jest.fn(),
|
|
||||||
initializeComponent: jest.fn(),
|
|
||||||
};
|
|
||||||
|
|
||||||
const mountOptions = getMountOptions(mountOptionsMockData);
|
|
||||||
const wrapper = shallowMount(vehicleYear, mountOptions);
|
|
||||||
const yearQuestionWrapper = wrapper.findComponent({ name: "yearQuestion" });
|
|
||||||
yearQuestionWrapper.vm.initializeComponent = yearQuestion.methods.initializeComponent;
|
|
||||||
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
|
|
||||||
|
|
||||||
return { wrapper, apiPromise };
|
|
||||||
}
|
|
||||||
|
|
@ -1,110 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="page-container-grouped-styles">
|
|
||||||
<funnelHeader cmsWidgetName="FunnelHeaderWidget" />
|
|
||||||
<div class="select-car">
|
|
||||||
<div class="select-car-form rounded text-center">
|
|
||||||
<vehicleBanner cmsWidgetName="VehicleBannerWidget" displayGenericVehicleImage />
|
|
||||||
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" headerColor="light-header" />
|
|
||||||
<div class="fade-on-route-transition">
|
|
||||||
<yearQuestion
|
|
||||||
class="fade-on-route-transition"
|
|
||||||
v-model="selectedYear"
|
|
||||||
ref="yearQuestion"
|
|
||||||
cmsWidgetName="VehicleYearQuestion" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Components
|
|
||||||
import yearQuestion from "@/layouts/vehicle-year/year-question/year-question";
|
|
||||||
import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
|
|
||||||
import vehicleBanner from "@/fmg-components/vehicle-banner/vehicle-banner";
|
|
||||||
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
|
||||||
|
|
||||||
// Supporting files
|
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
|
||||||
import { storeActions } from "@/constants/store-actions";
|
|
||||||
import { experimentUniverses } from "@/constants/experiments";
|
|
||||||
import { getDeviceIdValue, getSessionKeyValue } from "@/helpers/heritage-integration/cookie-helper";
|
|
||||||
import store from "@/store";
|
|
||||||
|
|
||||||
import baseMixin from "@/mixins/base-mixin";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "vehicle-year",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
selectedYear: null,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {},
|
|
||||||
|
|
||||||
async beforeRouteEnter(to, from, next) {
|
|
||||||
// Call APIs
|
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
|
||||||
const yearQuestionInitialDataPromise = yearQuestion.methods.loadInitialData();
|
|
||||||
|
|
||||||
const experimentForLogging = store.getters.applicationUser.experiments.find(
|
|
||||||
(e) => e.universeName === experimentUniverses.CONCEPT_FUNNEL
|
|
||||||
);
|
|
||||||
|
|
||||||
// If the concept funnel experiment is found, as it should be when coming from safelite.com, then log the experiment exposure.
|
|
||||||
if (experimentForLogging !== undefined) {
|
|
||||||
// Log experiment exposure
|
|
||||||
baseMixin.methods.dispatchStoreAction(
|
|
||||||
storeActions.LOG_EXPERIMENT_EXPOSURE,
|
|
||||||
{
|
|
||||||
userId: getDeviceIdValue(),
|
|
||||||
sessionKey: getSessionKeyValue(),
|
|
||||||
pageName: to.query.fmgPage,
|
|
||||||
experiment: experimentForLogging,
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Settle promises and get results
|
|
||||||
const promiseResultMap = [
|
|
||||||
{
|
|
||||||
resultKey: "cmsContent",
|
|
||||||
promise: cmsContentPromise,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
resultKey: "yearQuestionInitialData",
|
|
||||||
promise: yearQuestionInitialDataPromise,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
let resultMap = await settleAllPromises(promiseResultMap);
|
|
||||||
|
|
||||||
// Call the "next" function to complete the transition to this page.
|
|
||||||
next((vm) => {
|
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
|
||||||
vm.$refs.yearQuestion.initializeComponent(resultMap.yearQuestionInitialData);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
selectedYear(year) {
|
|
||||||
const parsedYear = parseInt(year);
|
|
||||||
this.dispatchStoreAction(storeActions.SAVE_VEHICLE_YEAR, parsedYear);
|
|
||||||
this.$router.navigateWithSaving(this.navigationScenarios.SELECTED_YEAR, this.$route);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
arePagePrerequisitesValid() {
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
yearQuestion,
|
|
||||||
funnelHeader,
|
|
||||||
vehicleBanner,
|
|
||||||
funnelSubHeader,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
import yearQuestion from "@/layouts/vehicle-year/year-question/year-question";
|
|
||||||
import { shallowMount } from "@vue/test-utils";
|
|
||||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
|
||||||
import store from "@/store";
|
|
||||||
jest.mock(
|
|
||||||
"@/store",
|
|
||||||
() => {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
{ virtual: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
describe("year-question.vue", () => {
|
|
||||||
test("Selected year is emitted upon selection.", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper } = setupMocks({ modelValueProp: "2020" });
|
|
||||||
const yearToSelect = "2021";
|
|
||||||
|
|
||||||
//Act
|
|
||||||
wrapper.setValue({ modelValue: yearToSelect });
|
|
||||||
await wrapper.vm.$nextTick();
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ modelValue: "2021" }]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("year-question.vue", () => {
|
|
||||||
test("Data from store api are used as radio question answers.", async () => {
|
|
||||||
//Arrange
|
|
||||||
const { wrapper, cmsContent } = setupMocks({
|
|
||||||
dataFromStoreApi: ["2023", "2022", "2021"],
|
|
||||||
});
|
|
||||||
|
|
||||||
//Act
|
|
||||||
const initialData = yearQuestion.methods.loadInitialData.call(wrapper.vm);
|
|
||||||
yearQuestion.methods.initializeComponent.call(wrapper.vm, initialData);
|
|
||||||
|
|
||||||
//Assert
|
|
||||||
const buttonQuestionComponent = await wrapper.findComponent({
|
|
||||||
name: "buttonQuestion",
|
|
||||||
});
|
|
||||||
expect(buttonQuestionComponent.attributes("answers")).toBe("2023,2022,2021");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function setupMocks({
|
|
||||||
modelValueProp = "1900",
|
|
||||||
cmsQuestionText = "CMS text goes here",
|
|
||||||
dataFromStoreApi = [],
|
|
||||||
}) {
|
|
||||||
//Mock store
|
|
||||||
store.dispatch = jest.fn(() => dataFromStoreApi);
|
|
||||||
const mountOptions = getMountOptions({
|
|
||||||
store: {
|
|
||||||
dispatch: store.dispatch,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
//Mock props
|
|
||||||
const mockMixin = {
|
|
||||||
methods: {
|
|
||||||
getCmsContent: jest.fn(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
mountOptions.propsData = {
|
|
||||||
modelValue: modelValueProp,
|
|
||||||
};
|
|
||||||
mountOptions.mixins = [mockMixin];
|
|
||||||
|
|
||||||
const wrapper = shallowMount(yearQuestion, mountOptions);
|
|
||||||
|
|
||||||
//Mock CMS content
|
|
||||||
const cmsContent = {
|
|
||||||
QuestionText: cmsQuestionText,
|
|
||||||
};
|
|
||||||
return { wrapper, cmsContent };
|
|
||||||
}
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
<template>
|
|
||||||
<buttonQuestion
|
|
||||||
class="radioQuestion"
|
|
||||||
isOverflowScrollable
|
|
||||||
selectingInitiatesLoad
|
|
||||||
:questionText="questionText"
|
|
||||||
:answers="years"
|
|
||||||
groupName="ChooseVehicleYear"
|
|
||||||
textPosition="text-start"
|
|
||||||
v-model="selectedValue"
|
|
||||||
isRequired />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import buttonQuestion from "@/digital-components/button-question/button-question";
|
|
||||||
// Supporting files
|
|
||||||
import { storeActions } from "@/constants/store-actions.js";
|
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
|
||||||
export default {
|
|
||||||
name: "year-question",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
years: [],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
modelValue: String,
|
|
||||||
cmsWidgetName: String,
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
buttonQuestion,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
questionText() {
|
|
||||||
return this.getCmsContent(this.cmsWidgetName, "QuestionText");
|
|
||||||
},
|
|
||||||
selectedValue: {
|
|
||||||
get: function () {
|
|
||||||
return this.modelValue;
|
|
||||||
},
|
|
||||||
set: function (newValue) {
|
|
||||||
this.$emit("update:modelValue", newValue);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadInitialData() {
|
|
||||||
return baseMixin.methods.dispatchStoreAction(storeActions.GET_VEHICLE_YEARS, {});
|
|
||||||
},
|
|
||||||
initializeComponent(initialData) {
|
|
||||||
this.years = initialData;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -58,7 +58,9 @@
|
||||||
<vehicleBanner
|
<vehicleBanner
|
||||||
cmsWidgetName="VehicleBannerWidget"
|
cmsWidgetName="VehicleBannerWidget"
|
||||||
:displayGenericVehicleImage="displayGeneric"
|
:displayGenericVehicleImage="displayGeneric"
|
||||||
:displayVehicleImage="vehicle.imageUrl"
|
:displayVehicleImage="imageUrl"
|
||||||
|
:vehicleCategory="category"
|
||||||
|
:displayUnmatchedVehicleIcon="unmatchedVehicleIcon"
|
||||||
class="mt-5 mb-3"
|
class="mt-5 mb-3"
|
||||||
ref="banner" />
|
ref="banner" />
|
||||||
|
|
||||||
|
|
@ -110,17 +112,17 @@ export default {
|
||||||
selectedMake: this.selectedMakefromStore(),
|
selectedMake: this.selectedMakefromStore(),
|
||||||
selectedModel: this.selectedModelfromStore(),
|
selectedModel: this.selectedModelfromStore(),
|
||||||
selectedStyle: this.selectedStylefromStore(),
|
selectedStyle: this.selectedStylefromStore(),
|
||||||
vehicle: {
|
carId: null,
|
||||||
carId: null,
|
category: null,
|
||||||
category: null,
|
imageUrl: null,
|
||||||
imageUrl: null,
|
imageVifNumber: null,
|
||||||
imageVifNumber: null,
|
imageVifColor: null,
|
||||||
imageVifColor: null,
|
|
||||||
},
|
|
||||||
yearOptions: [],
|
yearOptions: [],
|
||||||
makeOptions: [],
|
makeOptions: [],
|
||||||
modelOptions: [],
|
modelOptions: [],
|
||||||
styleOptions: [],
|
styleOptions: [],
|
||||||
|
displayGeneric: this.displayGenericFromStore(),
|
||||||
|
unmatchedVehicleIcon: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -279,7 +281,18 @@ export default {
|
||||||
this.selectedModel,
|
this.selectedModel,
|
||||||
style
|
style
|
||||||
);
|
);
|
||||||
this.vehicle = result?.data;
|
this.carId = result?.data.carId;
|
||||||
|
this.category = result?.data.category;
|
||||||
|
this.imageUrl = result?.data.imageUrl;
|
||||||
|
this.imageVifNumber = result?.data.imageVifNumber;
|
||||||
|
this.imageVifColor = result?.data.imageVifColor;
|
||||||
|
if (this.imageUrl == null) {
|
||||||
|
this.displayGeneric = false;
|
||||||
|
this.unmatchedVehicleIcon = true;
|
||||||
|
} else this.unmatchedVehicleIcon = false;
|
||||||
|
} else {
|
||||||
|
this.imageUrl = null;
|
||||||
|
this.displayGeneric = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -293,6 +306,15 @@ export default {
|
||||||
style: style,
|
style: style,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
displayGenericFromStore() {
|
||||||
|
if (store.getters.vehicle.imageUrl !== null) return false;
|
||||||
|
else if (
|
||||||
|
store.getters.vehicle.imageUrl === null &&
|
||||||
|
store.getters.vehicle.carId !== null
|
||||||
|
)
|
||||||
|
return false;
|
||||||
|
else return true;
|
||||||
|
},
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
@ -305,7 +327,11 @@ export default {
|
||||||
make: this.selectedMake,
|
make: this.selectedMake,
|
||||||
model: this.selectedModel,
|
model: this.selectedModel,
|
||||||
style: this.selectedStyle,
|
style: this.selectedStyle,
|
||||||
vehicle: this.vehicle,
|
carId: this.carId,
|
||||||
|
category: this.category,
|
||||||
|
imageUrl: this.imageUrl,
|
||||||
|
imageVifNumber: this.imageVifNumber,
|
||||||
|
imageVifColor: this.imageVifColor,
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
@ -353,12 +379,6 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
|
||||||
displayGeneric() {
|
|
||||||
return !this.selectedStyle;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
funnelHeader,
|
funnelHeader,
|
||||||
funnelFooter,
|
funnelFooter,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
const fmgPageValues = {
|
const fmgPageValues = {
|
||||||
VEHICLE_YEAR: "vehicle-year",
|
|
||||||
VEHICLE_MAKE: "vehicle-make",
|
|
||||||
VEHICLE_MODEL: "vehicle-model",
|
|
||||||
VEHICLE_STYLE: "vehicle-style",
|
|
||||||
VEHICLE: "vehicle",
|
VEHICLE: "vehicle",
|
||||||
VEHICLE_DAMAGE: "vehicle-damage",
|
VEHICLE_DAMAGE: "vehicle-damage",
|
||||||
ADDRESS_LOOKUP: "address-lookup",
|
ADDRESS_LOOKUP: "address-lookup",
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,6 @@ const navigationScenarios = {
|
||||||
CLICKED_FORWARD: "CLICKED_FORWARD",
|
CLICKED_FORWARD: "CLICKED_FORWARD",
|
||||||
CLICKED_FORWARD_WITH_CASH: "CLICKED_FORWARD_WITH_CASH",
|
CLICKED_FORWARD_WITH_CASH: "CLICKED_FORWARD_WITH_CASH",
|
||||||
|
|
||||||
// YMMS
|
|
||||||
SELECTED_YEAR: "SELECTED_YEAR",
|
|
||||||
SELECTED_MODEL: "SELECTED_MODEL",
|
|
||||||
SELECTED_MAKE: "SELECTED_MAKE",
|
|
||||||
SELECTED_STYLE: "SELECTED_STYLE",
|
|
||||||
|
|
||||||
// Vin selection
|
// Vin selection
|
||||||
CLICKED_BACK_WITH_VIN: "CLICKED_BACK_WITH_VIN",
|
CLICKED_BACK_WITH_VIN: "CLICKED_BACK_WITH_VIN",
|
||||||
CLICKED_FORWARD_WITH_VIN: "CLICKED_FORWARD_WITH_VIN",
|
CLICKED_FORWARD_WITH_VIN: "CLICKED_FORWARD_WITH_VIN",
|
||||||
|
|
|
||||||
|
|
@ -13,54 +13,7 @@ const routingTable = function (store) {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
fmgPageValue: fmgPageValues.VEHICLE_YEAR,
|
|
||||||
maps: [
|
|
||||||
{
|
|
||||||
scenario: navigationScenarios.SELECTED_YEAR,
|
|
||||||
destinationFmgPageValue: fmgPageValues.VEHICLE_MAKE,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fmgPageValue: fmgPageValues.VEHICLE_MAKE,
|
|
||||||
maps: [
|
|
||||||
{
|
|
||||||
scenario: navigationScenarios.SELECTED_MAKE,
|
|
||||||
destinationFmgPageValue: fmgPageValues.VEHICLE_MODEL,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
scenario: navigationScenarios.CLICKED_BACK,
|
|
||||||
destinationFmgPageValue: fmgPageValues.VEHICLE_YEAR,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fmgPageValue: fmgPageValues.VEHICLE_MODEL,
|
|
||||||
maps: [
|
|
||||||
{
|
|
||||||
scenario: navigationScenarios.SELECTED_MODEL,
|
|
||||||
destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
scenario: navigationScenarios.CLICKED_BACK,
|
|
||||||
destinationFmgPageValue: fmgPageValues.VEHICLE_MAKE,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fmgPageValue: fmgPageValues.VEHICLE_STYLE,
|
|
||||||
maps: [
|
|
||||||
{
|
|
||||||
scenario: navigationScenarios.SELECTED_STYLE,
|
|
||||||
destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
scenario: navigationScenarios.CLICKED_BACK,
|
|
||||||
destinationFmgPageValue: fmgPageValues.VEHICLE_MODEL,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
fmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
|
fmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
|
||||||
maps: [
|
maps: [
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import {
|
||||||
// Export State
|
// Export State
|
||||||
const getDefaultState = () => {
|
const getDefaultState = () => {
|
||||||
return {
|
return {
|
||||||
|
submitAfterSave: false,
|
||||||
order: {
|
order: {
|
||||||
vehicle: {
|
vehicle: {
|
||||||
year: null,
|
year: null,
|
||||||
|
|
@ -123,6 +124,10 @@ export const state = getDefaultState();
|
||||||
|
|
||||||
// Export Mutations
|
// Export Mutations
|
||||||
export const mutations = {
|
export const mutations = {
|
||||||
|
updateWorkOrderFlag(state, submitAfterSave) {
|
||||||
|
state.submitAfterSave = submitAfterSave;
|
||||||
|
},
|
||||||
|
|
||||||
// VEHICLE MUTATIONS
|
// VEHICLE MUTATIONS
|
||||||
updateYear(state, year) {
|
updateYear(state, year) {
|
||||||
state.order.vehicle.year = year;
|
state.order.vehicle.year = year;
|
||||||
|
|
@ -1400,6 +1405,7 @@ export const actions = {
|
||||||
method: endpoints.SaveSession.method,
|
method: endpoints.SaveSession.method,
|
||||||
endpoint: endpoints.SaveSession.url,
|
endpoint: endpoints.SaveSession.url,
|
||||||
payload: {
|
payload: {
|
||||||
|
submitAfterSave: context.state.submitAfterSave,
|
||||||
applicationUser: {
|
applicationUser: {
|
||||||
crmCustomerId: applicationUser.crmCustomerId,
|
crmCustomerId: applicationUser.crmCustomerId,
|
||||||
experiments: applicationUser.experiments,
|
experiments: applicationUser.experiments,
|
||||||
|
|
@ -1552,93 +1558,19 @@ export const actions = {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
saveWorkOrderFlag(context, submitAfterSave) {
|
||||||
|
context.commit(storeMutations.UPDATE_WORK_ORDER_FLAG, submitAfterSave);
|
||||||
|
},
|
||||||
|
|
||||||
// Business domain actions
|
// Business domain actions
|
||||||
|
|
||||||
// Vehicle
|
// Vehicle
|
||||||
saveVehicleYear(context, year) {
|
saveVehicle(
|
||||||
//Reset dependent state when changing
|
context,
|
||||||
if (context.state.order.vehicle.year !== year) {
|
{ year, make, model, style, carId, category, imageUrl, imageVifNumber, imageVifColor }
|
||||||
context.commit(storeMutations.UPDATE_MAKE, null);
|
) {
|
||||||
context.commit(storeMutations.UPDATE_MODEL, null);
|
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
||||||
context.commit(storeMutations.UPDATE_STYLE, null);
|
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
||||||
context.commit(storeMutations.UPDATE_CAR_ID, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_VIN, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
|
|
||||||
|
|
||||||
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
|
||||||
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
|
||||||
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
|
||||||
|
|
||||||
//Save new values
|
|
||||||
context.commit(storeMutations.UPDATE_YEAR, year);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
saveVehicleMake(context, make) {
|
|
||||||
//Reset dependent state when changing
|
|
||||||
if (context.state.order.vehicle.make !== make) {
|
|
||||||
context.commit(storeMutations.UPDATE_MODEL, null);
|
|
||||||
context.commit(storeMutations.UPDATE_STYLE, null);
|
|
||||||
context.commit(storeMutations.UPDATE_CAR_ID, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_VIN, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
|
|
||||||
|
|
||||||
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
|
||||||
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
|
||||||
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
|
||||||
|
|
||||||
//Save new values
|
|
||||||
context.commit(storeMutations.UPDATE_MAKE, make);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
saveVehicleModel(context, model) {
|
|
||||||
//Reset dependent state when changing
|
|
||||||
if (context.state.order.vehicle.model !== model) {
|
|
||||||
context.commit(storeMutations.UPDATE_STYLE, null);
|
|
||||||
context.commit(storeMutations.UPDATE_CAR_ID, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_VIN, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
|
|
||||||
|
|
||||||
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
|
||||||
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
|
||||||
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
|
||||||
|
|
||||||
//Save new values
|
|
||||||
context.commit(storeMutations.UPDATE_MODEL, model);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
saveVehicleStyle(context, style) {
|
|
||||||
//Reset dependent state when changing
|
|
||||||
if (context.state.order.vehicle.style !== style) {
|
|
||||||
context.commit(storeMutations.UPDATE_CAR_ID, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_VIN, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
|
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
|
|
||||||
|
|
||||||
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
|
||||||
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
|
||||||
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
|
||||||
|
|
||||||
//Save new values
|
|
||||||
context.commit(storeMutations.UPDATE_STYLE, style);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
saveVehicle(context, { year, make, model, style, vehicle }) {
|
|
||||||
context.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES);
|
|
||||||
|
|
||||||
if (context.state.order.vehicle.year !== year) {
|
if (context.state.order.vehicle.year !== year) {
|
||||||
context.commit(storeMutations.UPDATE_YEAR, year);
|
context.commit(storeMutations.UPDATE_YEAR, year);
|
||||||
|
|
@ -1652,11 +1584,11 @@ export const actions = {
|
||||||
if (context.state.order.vehicle.style !== style) {
|
if (context.state.order.vehicle.style !== style) {
|
||||||
context.commit(storeMutations.UPDATE_STYLE, style);
|
context.commit(storeMutations.UPDATE_STYLE, style);
|
||||||
}
|
}
|
||||||
context.commit(storeMutations.UPDATE_CAR_ID, vehicle.carId);
|
context.commit(storeMutations.UPDATE_CAR_ID, carId);
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, vehicle.category);
|
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, category);
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, vehicle.imageUrl);
|
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, imageUrl);
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, vehicle.imageVifNumber);
|
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, imageVifNumber);
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, vehicle.imageVifColor);
|
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, imageVifColor);
|
||||||
},
|
},
|
||||||
|
|
||||||
saveVehicleDamage(
|
saveVehicleDamage(
|
||||||
|
|
|
||||||
|
|
@ -1573,168 +1573,6 @@ describe("Actions", () => {
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_REGISTRATION, payload.registrationInfo);
|
expect(commit).toBeCalledWith(storeMutations.UPDATE_REGISTRATION, payload.registrationInfo);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("saveVehicleYear, should wipe out vehicle info if year changes", () => {
|
|
||||||
// Arrange
|
|
||||||
const context = state;
|
|
||||||
|
|
||||||
context.state = {
|
|
||||||
order: {
|
|
||||||
vehicle: {
|
|
||||||
year: "2015",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const commit = jest.fn();
|
|
||||||
const dispatch = jest.fn();
|
|
||||||
|
|
||||||
context.commit = commit;
|
|
||||||
context.dispatch = dispatch;
|
|
||||||
|
|
||||||
// Act
|
|
||||||
actions.saveVehicleYear(context, "2016");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(dispatch).toHaveBeenNthCalledWith(
|
|
||||||
1,
|
|
||||||
storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES
|
|
||||||
);
|
|
||||||
expect(dispatch).toHaveBeenNthCalledWith(
|
|
||||||
2,
|
|
||||||
storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_MAKE, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_MODEL, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_VIN, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("saveVehicleMake, should wipe out vehicle info if make changes", () => {
|
|
||||||
// Arrange
|
|
||||||
const context = state;
|
|
||||||
|
|
||||||
context.state = {
|
|
||||||
order: {
|
|
||||||
vehicle: {
|
|
||||||
make: "Honda",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const commit = jest.fn();
|
|
||||||
const dispatch = jest.fn();
|
|
||||||
|
|
||||||
context.commit = commit;
|
|
||||||
context.dispatch = dispatch;
|
|
||||||
|
|
||||||
// Act
|
|
||||||
actions.saveVehicleMake(context, "Toyota");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(dispatch).toHaveBeenNthCalledWith(
|
|
||||||
1,
|
|
||||||
storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES
|
|
||||||
);
|
|
||||||
expect(dispatch).toHaveBeenNthCalledWith(
|
|
||||||
2,
|
|
||||||
storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_MODEL, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_VIN, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("saveVehicle model, should wipe out vehicle info if model changes", () => {
|
|
||||||
// Arrange
|
|
||||||
const context = state;
|
|
||||||
|
|
||||||
context.state = {
|
|
||||||
order: {
|
|
||||||
vehicle: {
|
|
||||||
model: "Civic",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const commit = jest.fn();
|
|
||||||
const dispatch = jest.fn();
|
|
||||||
|
|
||||||
context.commit = commit;
|
|
||||||
context.dispatch = dispatch;
|
|
||||||
|
|
||||||
// Act
|
|
||||||
actions.saveVehicleModel(context, "Accord");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(dispatch).toHaveBeenNthCalledWith(
|
|
||||||
1,
|
|
||||||
storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES
|
|
||||||
);
|
|
||||||
expect(dispatch).toHaveBeenNthCalledWith(
|
|
||||||
2,
|
|
||||||
storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_VIN, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("saveVehicleStyle, should wipe out vehicle info if style changes", () => {
|
|
||||||
// Arrange
|
|
||||||
const context = state;
|
|
||||||
|
|
||||||
context.state = {
|
|
||||||
order: {
|
|
||||||
vehicle: {
|
|
||||||
style: "Sedan",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const commit = jest.fn();
|
|
||||||
const dispatch = jest.fn();
|
|
||||||
|
|
||||||
context.commit = commit;
|
|
||||||
context.dispatch = dispatch;
|
|
||||||
|
|
||||||
// Act
|
|
||||||
actions.saveVehicleStyle(context, "SUV");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(dispatch).toHaveBeenNthCalledWith(
|
|
||||||
1,
|
|
||||||
storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES
|
|
||||||
);
|
|
||||||
expect(dispatch).toHaveBeenNthCalledWith(
|
|
||||||
2,
|
|
||||||
storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_VIN, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_URL, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, null);
|
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, null);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("saveVehicle, should save vehicle info", () => {
|
it("saveVehicle, should save vehicle info", () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const context = state;
|
const context = state;
|
||||||
|
|
@ -1762,14 +1600,20 @@ describe("Actions", () => {
|
||||||
make: "Honda",
|
make: "Honda",
|
||||||
model: "Civic",
|
model: "Civic",
|
||||||
style: "Sedan",
|
style: "Sedan",
|
||||||
vehicle: {
|
carId: "C00000000",
|
||||||
carId: "C00000000",
|
category: "CAR",
|
||||||
category: "CAR",
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
actions.saveVehicle(context, payload);
|
actions.saveVehicle(context, payload);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
|
expect(dispatch).toHaveBeenNthCalledWith(
|
||||||
|
1,
|
||||||
|
storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES
|
||||||
|
);
|
||||||
|
expect(dispatch).toHaveBeenNthCalledWith(
|
||||||
|
2,
|
||||||
|
storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES
|
||||||
|
);
|
||||||
if (context.state.order.vehicle.year !== payload.year) {
|
if (context.state.order.vehicle.year !== payload.year) {
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_YEAR, payload.year);
|
expect(commit).toBeCalledWith(storeMutations.UPDATE_YEAR, payload.year);
|
||||||
}
|
}
|
||||||
|
|
@ -1782,8 +1626,8 @@ describe("Actions", () => {
|
||||||
if (context.state.order.vehicle.style !== payload.style) {
|
if (context.state.order.vehicle.style !== payload.style) {
|
||||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_STYLE, payload.style);
|
expect(commit).toBeCalledWith(storeMutations.UPDATE_STYLE, payload.style);
|
||||||
}
|
}
|
||||||
context.commit(storeMutations.UPDATE_CAR_ID, payload.vehicle.carId);
|
context.commit(storeMutations.UPDATE_CAR_ID, payload.carId);
|
||||||
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, payload.vehicle.category);
|
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, payload.category);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("saveVehicleDamage, should wipe out damage if different", () => {
|
it("saveVehicleDamage, should wipe out damage if different", () => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue