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",
|
||||
|
||||
// SAVE COMPONENT STATE
|
||||
SAVE_VEHICLE_YEAR: "saveVehicleYear",
|
||||
SAVE_VEHICLE_MAKE: "saveVehicleMake",
|
||||
SAVE_VEHICLE_MODEL: "saveVehicleModel",
|
||||
SAVE_VEHICLE_STYLE: "saveVehicleStyle",
|
||||
SAVE_VEHICLE: "saveVehicle",
|
||||
SAVE_VEHICLE_DAMAGE: "saveVehicleDamage",
|
||||
SAVE_VIN_LOOKUP: "saveVinLookup",
|
||||
|
|
@ -87,6 +83,7 @@ const storeActions = {
|
|||
SAVE_VAPS: "saveVaps",
|
||||
SAVE_CUSTOMER_DETAILS: "saveCustomerDetails",
|
||||
SAVE_SERVICE_LOCATION_TECH_NOTES: "saveServiceLocationTechNotes",
|
||||
SAVE_WORK_ORDER_FLAG: "saveWorkOrderFlag",
|
||||
};
|
||||
|
||||
export { storeActions };
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
const storeMutations = {
|
||||
UPDATE_WORK_ORDER_FLAG: "updateWorkOrderFlag",
|
||||
|
||||
// VEHICLE MUTATIONS
|
||||
UPDATE_YEAR: "updateYear",
|
||||
UPDATE_MAKE: "updateMake",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ describe("vehicleBanner", () => {
|
|||
const { wrapper } = setupMocks({
|
||||
displayGenericVehicleImageProp: true,
|
||||
imageUrlValue: "NULL",
|
||||
displayUnmatchedVehicleIconProp: true,
|
||||
});
|
||||
|
||||
// Assert
|
||||
|
|
@ -87,7 +88,12 @@ describe("vehicleBanner", () => {
|
|||
);
|
||||
});
|
||||
|
||||
function setupMocks({ displayGenericVehicleImageProp, imageUrlValue, categoryValue = "CAR" }) {
|
||||
function setupMocks({
|
||||
displayGenericVehicleImageProp,
|
||||
displayUnmatchedVehicleIconProp,
|
||||
imageUrlValue,
|
||||
categoryValue = "CAR",
|
||||
}) {
|
||||
const mockGetCmsContent = jest.fn();
|
||||
mockGetCmsContent((cmsWidget, field) => {
|
||||
return field;
|
||||
|
|
@ -108,7 +114,10 @@ function setupMocks({ displayGenericVehicleImageProp, imageUrlValue, categoryVal
|
|||
});
|
||||
|
||||
//Mock props
|
||||
mountOptions.propsData = { displayGenericVehicleImage: displayGenericVehicleImageProp };
|
||||
mountOptions.propsData = {
|
||||
displayGenericVehicleImage: displayGenericVehicleImageProp,
|
||||
displayUnmatchedVehicleIconProp: displayUnmatchedVehicleIconProp,
|
||||
};
|
||||
mountOptions.mixins = [mockMixin];
|
||||
const wrapper = shallowMount(vehicleBanner, mountOptions);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,16 @@ export default {
|
|||
required: false,
|
||||
default: null,
|
||||
},
|
||||
displayUnmatchedVehicleIcon: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
vehicleCategory: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
vehicleImageToDisplay() {
|
||||
|
|
@ -29,7 +39,8 @@ export default {
|
|||
}
|
||||
if (
|
||||
this.$store.getters.vehicle.imageUrl === null ||
|
||||
this.$store.getters.vehicle.imageUrl === "NULL"
|
||||
this.$store.getters.vehicle.imageUrl === "NULL" ||
|
||||
this.displayUnmatchedVehicleIcon
|
||||
) {
|
||||
return this.getUnmatchedVehicleIcon();
|
||||
}
|
||||
|
|
@ -57,7 +68,8 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
getUnmatchedVehicleIcon() {
|
||||
switch (this.$store.getters.vehicle.category) {
|
||||
const category = this.vehicleCategory ?? this.$store.getters.vehicle.category;
|
||||
switch (category) {
|
||||
case this.vehicleCategories.CAR:
|
||||
return this.carUnmatchedVehicleIcon;
|
||||
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.
|
||||
// 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.
|
||||
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 estimateComponent = await getLazyLoadedComponent(fmgPageValues.ESTIMATE);
|
||||
const vinLookupComponent = await getLazyLoadedComponent(fmgPageValues.VIN_LOOKUP);
|
||||
|
|
@ -121,14 +118,8 @@ async function getLatestPageForRedirection() {
|
|||
|
||||
const skipVin = await skipVinLookup();
|
||||
|
||||
if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) {
|
||||
return fmgPageValues.VEHICLE_YEAR;
|
||||
} 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;
|
||||
if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) {
|
||||
return fmgPageValues.VEHICLE;
|
||||
} else if (!estimateComponent.methods.arePagePrerequisitesValid()) {
|
||||
return fmgPageValues.VEHICLE_DAMAGE;
|
||||
} else {
|
||||
|
|
@ -170,10 +161,7 @@ function overrideYmmsDirectionIfNeeded(toRoute) {
|
|||
|
||||
if (store.getters.payment.insuranceCoverage.isVerified) {
|
||||
switch (fmgPageValue) {
|
||||
case fmgPageValues.VEHICLE_YEAR:
|
||||
case fmgPageValues.VEHICLE_MAKE:
|
||||
case fmgPageValues.VEHICLE_MODEL:
|
||||
case fmgPageValues.VEHICLE_STYLE: {
|
||||
case fmgPageValues.VEHICLE: {
|
||||
return fmgPageValues.VEHICLE_DAMAGE;
|
||||
}
|
||||
default: {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ jest.mock("@/router/dynamic-routing/component-loader.js", () => ({
|
|||
}));
|
||||
|
||||
describe("getPageToRouteExistingOrderTo", () => {
|
||||
test("should return vehicle-year", async () => {
|
||||
test("should return vehicle", async () => {
|
||||
// Arrange
|
||||
const toRoute = {
|
||||
query: {},
|
||||
|
|
@ -31,75 +31,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
|||
|
||||
// Mock out the lazy load calls for all components.
|
||||
mockLazyLoadComponentReturnValues({
|
||||
[fmgPageValues.VEHICLE_MAKE]: false,
|
||||
});
|
||||
|
||||
// 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]: true,
|
||||
[fmgPageValues.VEHICLE_DAMAGE]: false,
|
||||
});
|
||||
|
||||
|
|
@ -107,7 +39,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
|||
const result = await getPageToRouteExistingOrderTo(toRoute, false);
|
||||
|
||||
//Assert
|
||||
expect(result).toBe(fmgPageValues.VEHICLE_STYLE);
|
||||
expect(result).toBe(fmgPageValues.VEHICLE);
|
||||
});
|
||||
|
||||
test("should return vehicle-damage", async () => {
|
||||
|
|
@ -121,9 +53,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
|||
|
||||
// Mock out the lazy load calls for all components.
|
||||
mockLazyLoadComponentReturnValues({
|
||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||
[fmgPageValues.VEHICLE]: true,
|
||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||
[fmgPageValues.ESTIMATE]: false,
|
||||
});
|
||||
|
|
@ -156,9 +86,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
|||
|
||||
// Mock out the lazy load calls for all components.
|
||||
mockLazyLoadComponentReturnValues({
|
||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||
[fmgPageValues.VEHICLE]: true,
|
||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||
[fmgPageValues.ESTIMATE]: true,
|
||||
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||
|
|
@ -186,9 +114,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
|||
|
||||
// Mock out the lazy load calls for all components.
|
||||
mockLazyLoadComponentReturnValues({
|
||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||
[fmgPageValues.VEHICLE]: true,
|
||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||
[fmgPageValues.ESTIMATE]: true,
|
||||
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||
|
|
@ -216,9 +142,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
|||
|
||||
// Mock out the lazy load calls for all components.
|
||||
mockLazyLoadComponentReturnValues({
|
||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||
[fmgPageValues.VEHICLE]: true,
|
||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||
[fmgPageValues.ESTIMATE]: true,
|
||||
[fmgPageValues.CAPABILITY_QUESTIONS]: true,
|
||||
|
|
@ -246,9 +170,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
|||
|
||||
// Mock out the lazy load calls for all components.
|
||||
mockLazyLoadComponentReturnValues({
|
||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||
[fmgPageValues.VEHICLE]: true,
|
||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||
[fmgPageValues.ESTIMATE]: true,
|
||||
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||
|
|
@ -276,9 +198,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
|||
|
||||
// Mock out the lazy load calls for all components.
|
||||
mockLazyLoadComponentReturnValues({
|
||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||
[fmgPageValues.VEHICLE]: true,
|
||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||
[fmgPageValues.ESTIMATE]: true,
|
||||
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||
|
|
@ -306,9 +226,7 @@ describe("getPageToRouteExistingOrderTo", () => {
|
|||
|
||||
// Mock out the lazy load calls for all components.
|
||||
mockLazyLoadComponentReturnValues({
|
||||
[fmgPageValues.VEHICLE_MAKE]: true,
|
||||
[fmgPageValues.VEHICLE_MODEL]: true,
|
||||
[fmgPageValues.VEHICLE_STYLE]: true,
|
||||
[fmgPageValues.VEHICLE]: true,
|
||||
[fmgPageValues.VEHICLE_DAMAGE]: true,
|
||||
[fmgPageValues.ESTIMATE]: true,
|
||||
[fmgPageValues.CAPABILITY_QUESTIONS]: false,
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ export default {
|
|||
false
|
||||
);
|
||||
|
||||
this.dispatchStoreAction(this.storeActions.SAVE_WORK_ORDER_FLAG, true, false);
|
||||
this.$router.navigateWithSaving(this.navigationScenarios.CLICKED_FORWARD, this.$route);
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -263,6 +263,9 @@ describe("quote.vue", () => {
|
|||
payment: {
|
||||
isInsurance: null,
|
||||
},
|
||||
serviceLocation: {
|
||||
state: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
wrapper.vm.$route = { query: { isInsurance: "true" } };
|
||||
|
|
@ -290,6 +293,9 @@ describe("quote.vue", () => {
|
|||
payment: {
|
||||
isInsurance: null,
|
||||
},
|
||||
serviceLocation: {
|
||||
state: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
wrapper.vm.$route = { query: { isInsurance: "false" } };
|
||||
|
|
@ -317,6 +323,9 @@ describe("quote.vue", () => {
|
|||
payment: {
|
||||
isInsurance: true,
|
||||
},
|
||||
serviceLocation: {
|
||||
state: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
// Ensure that query param isn't overriding selection
|
||||
|
|
@ -345,6 +354,9 @@ describe("quote.vue", () => {
|
|||
payment: {
|
||||
isInsurance: false,
|
||||
},
|
||||
serviceLocation: {
|
||||
state: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
// Ensure that query param isn't overriding selection
|
||||
|
|
@ -374,6 +386,9 @@ describe("quote.vue", () => {
|
|||
payment: {
|
||||
isInsurance: null, // Ensure that previous selection isn't overriding selection
|
||||
},
|
||||
serviceLocation: {
|
||||
state: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
mockTierOnePrice = 200;
|
||||
|
|
@ -404,6 +419,9 @@ describe("quote.vue", () => {
|
|||
payment: {
|
||||
isInsurance: null, // Ensure that previous selection isn't overriding selection
|
||||
},
|
||||
serviceLocation: {
|
||||
state: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
mockTierOnePrice = 505;
|
||||
|
|
@ -421,6 +439,33 @@ describe("quote.vue", () => {
|
|||
//Assert
|
||||
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 }) {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ import { errorMessages } from "@/constants/error-messages";
|
|||
import { Form, defineRule } from "vee-validate";
|
||||
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
||||
import { applicationConfig } from "@/constants/application-config";
|
||||
|
||||
import { payWithInsuranceStates } from "@/constants/pay-with-insurance-states";
|
||||
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
||||
|
||||
export default {
|
||||
|
|
@ -154,11 +154,18 @@ export default {
|
|||
);
|
||||
},
|
||||
getDefaultIsInsuranceSelectedValue(availableLineItems) {
|
||||
const serviceLocationState = store.getters.order.serviceLocation.state;
|
||||
// Override if coming back from QuoteDetails. Remove override after Quote release
|
||||
const isInsuranceOverrideValue = this.$route.query?.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";
|
||||
} else if (defaultIsInsuranceSelectedValue != null) {
|
||||
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
|
||||
cmsWidgetName="VehicleBannerWidget"
|
||||
:displayGenericVehicleImage="displayGeneric"
|
||||
:displayVehicleImage="vehicle.imageUrl"
|
||||
:displayVehicleImage="imageUrl"
|
||||
:vehicleCategory="category"
|
||||
:displayUnmatchedVehicleIcon="unmatchedVehicleIcon"
|
||||
class="mt-5 mb-3"
|
||||
ref="banner" />
|
||||
|
||||
|
|
@ -110,17 +112,17 @@ export default {
|
|||
selectedMake: this.selectedMakefromStore(),
|
||||
selectedModel: this.selectedModelfromStore(),
|
||||
selectedStyle: this.selectedStylefromStore(),
|
||||
vehicle: {
|
||||
carId: null,
|
||||
category: null,
|
||||
imageUrl: null,
|
||||
imageVifNumber: null,
|
||||
imageVifColor: null,
|
||||
},
|
||||
carId: null,
|
||||
category: null,
|
||||
imageUrl: null,
|
||||
imageVifNumber: null,
|
||||
imageVifColor: null,
|
||||
yearOptions: [],
|
||||
makeOptions: [],
|
||||
modelOptions: [],
|
||||
styleOptions: [],
|
||||
displayGeneric: this.displayGenericFromStore(),
|
||||
unmatchedVehicleIcon: false,
|
||||
};
|
||||
},
|
||||
|
||||
|
|
@ -279,7 +281,18 @@ export default {
|
|||
this.selectedModel,
|
||||
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,
|
||||
});
|
||||
},
|
||||
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() {
|
||||
return true;
|
||||
},
|
||||
|
|
@ -305,7 +327,11 @@ export default {
|
|||
make: this.selectedMake,
|
||||
model: this.selectedModel,
|
||||
style: this.selectedStyle,
|
||||
vehicle: this.vehicle,
|
||||
carId: this.carId,
|
||||
category: this.category,
|
||||
imageUrl: this.imageUrl,
|
||||
imageVifNumber: this.imageVifNumber,
|
||||
imageVifColor: this.imageVifColor,
|
||||
},
|
||||
false
|
||||
);
|
||||
|
|
@ -353,12 +379,6 @@ export default {
|
|||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
displayGeneric() {
|
||||
return !this.selectedStyle;
|
||||
},
|
||||
},
|
||||
|
||||
components: {
|
||||
funnelHeader,
|
||||
funnelFooter,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
const fmgPageValues = {
|
||||
VEHICLE_YEAR: "vehicle-year",
|
||||
VEHICLE_MAKE: "vehicle-make",
|
||||
VEHICLE_MODEL: "vehicle-model",
|
||||
VEHICLE_STYLE: "vehicle-style",
|
||||
VEHICLE: "vehicle",
|
||||
VEHICLE_DAMAGE: "vehicle-damage",
|
||||
ADDRESS_LOOKUP: "address-lookup",
|
||||
|
|
|
|||
|
|
@ -12,12 +12,6 @@ const navigationScenarios = {
|
|||
CLICKED_FORWARD: "CLICKED_FORWARD",
|
||||
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
|
||||
CLICKED_BACK_WITH_VIN: "CLICKED_BACK_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,
|
||||
maps: [
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import {
|
|||
// Export State
|
||||
const getDefaultState = () => {
|
||||
return {
|
||||
submitAfterSave: false,
|
||||
order: {
|
||||
vehicle: {
|
||||
year: null,
|
||||
|
|
@ -123,6 +124,10 @@ export const state = getDefaultState();
|
|||
|
||||
// Export Mutations
|
||||
export const mutations = {
|
||||
updateWorkOrderFlag(state, submitAfterSave) {
|
||||
state.submitAfterSave = submitAfterSave;
|
||||
},
|
||||
|
||||
// VEHICLE MUTATIONS
|
||||
updateYear(state, year) {
|
||||
state.order.vehicle.year = year;
|
||||
|
|
@ -1400,6 +1405,7 @@ export const actions = {
|
|||
method: endpoints.SaveSession.method,
|
||||
endpoint: endpoints.SaveSession.url,
|
||||
payload: {
|
||||
submitAfterSave: context.state.submitAfterSave,
|
||||
applicationUser: {
|
||||
crmCustomerId: applicationUser.crmCustomerId,
|
||||
experiments: applicationUser.experiments,
|
||||
|
|
@ -1552,93 +1558,19 @@ export const actions = {
|
|||
);
|
||||
},
|
||||
|
||||
saveWorkOrderFlag(context, submitAfterSave) {
|
||||
context.commit(storeMutations.UPDATE_WORK_ORDER_FLAG, submitAfterSave);
|
||||
},
|
||||
|
||||
// Business domain actions
|
||||
|
||||
// Vehicle
|
||||
saveVehicleYear(context, year) {
|
||||
//Reset dependent state when changing
|
||||
if (context.state.order.vehicle.year !== year) {
|
||||
context.commit(storeMutations.UPDATE_MAKE, null);
|
||||
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_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);
|
||||
saveVehicle(
|
||||
context,
|
||||
{ year, make, model, style, carId, category, imageUrl, imageVifNumber, imageVifColor }
|
||||
) {
|
||||
context.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES);
|
||||
context.dispatch(storeActions.RESET_REGISTRATION_STATE_AND_DEPENDENCIES);
|
||||
|
||||
if (context.state.order.vehicle.year !== year) {
|
||||
context.commit(storeMutations.UPDATE_YEAR, year);
|
||||
|
|
@ -1652,11 +1584,11 @@ export const actions = {
|
|||
if (context.state.order.vehicle.style !== style) {
|
||||
context.commit(storeMutations.UPDATE_STYLE, style);
|
||||
}
|
||||
context.commit(storeMutations.UPDATE_CAR_ID, vehicle.carId);
|
||||
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, vehicle.category);
|
||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, vehicle.imageUrl);
|
||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, vehicle.imageVifNumber);
|
||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, vehicle.imageVifColor);
|
||||
context.commit(storeMutations.UPDATE_CAR_ID, carId);
|
||||
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, category);
|
||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, imageUrl);
|
||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, imageVifNumber);
|
||||
context.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, imageVifColor);
|
||||
},
|
||||
|
||||
saveVehicleDamage(
|
||||
|
|
|
|||
|
|
@ -1573,168 +1573,6 @@ describe("Actions", () => {
|
|||
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", () => {
|
||||
// Arrange
|
||||
const context = state;
|
||||
|
|
@ -1762,14 +1600,20 @@ describe("Actions", () => {
|
|||
make: "Honda",
|
||||
model: "Civic",
|
||||
style: "Sedan",
|
||||
vehicle: {
|
||||
carId: "C00000000",
|
||||
category: "CAR",
|
||||
},
|
||||
carId: "C00000000",
|
||||
category: "CAR",
|
||||
};
|
||||
actions.saveVehicle(context, payload);
|
||||
|
||||
//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) {
|
||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_YEAR, payload.year);
|
||||
}
|
||||
|
|
@ -1782,8 +1626,8 @@ describe("Actions", () => {
|
|||
if (context.state.order.vehicle.style !== payload.style) {
|
||||
expect(commit).toBeCalledWith(storeMutations.UPDATE_STYLE, payload.style);
|
||||
}
|
||||
context.commit(storeMutations.UPDATE_CAR_ID, payload.vehicle.carId);
|
||||
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, payload.vehicle.category);
|
||||
context.commit(storeMutations.UPDATE_CAR_ID, payload.carId);
|
||||
context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, payload.category);
|
||||
});
|
||||
|
||||
it("saveVehicleDamage, should wipe out damage if different", () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue