Merge branch 'develop' into feature/Digital/SSR-139
This commit is contained in:
commit
a8a1c849e3
10 changed files with 3438 additions and 27 deletions
398
src/layouts/part-questions/part-questions.spec.js
Normal file
398
src/layouts/part-questions/part-questions.spec.js
Normal file
|
|
@ -0,0 +1,398 @@
|
||||||
|
// Components
|
||||||
|
import partQuestions from "@/layouts/part-questions/part-questions";
|
||||||
|
|
||||||
|
// Supporting Files
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import { useMainStore } from "@/store";
|
||||||
|
import baseMixin from "@/mixins/base-mixin";
|
||||||
|
import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin";
|
||||||
|
import { nextTick } from "vue";
|
||||||
|
|
||||||
|
// 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(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
const baseStoreGettersPageData = () => {
|
||||||
|
return {
|
||||||
|
partsOrQuestions: [
|
||||||
|
{
|
||||||
|
parts: null,
|
||||||
|
partQuestions: [
|
||||||
|
{
|
||||||
|
questionSequence: 1,
|
||||||
|
questionText:
|
||||||
|
"Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?",
|
||||||
|
answers: [
|
||||||
|
{
|
||||||
|
answerResult: "",
|
||||||
|
answerText: "Yes",
|
||||||
|
nextQuestionSequence: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
answerResult: "",
|
||||||
|
answerText: "No",
|
||||||
|
nextQuestionSequence: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
glassLocation: "Windshield",
|
||||||
|
glassName: "Single",
|
||||||
|
answerKey: "Windshield-Single",
|
||||||
|
answerData: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
const baseStoreGettersDamage = () => {
|
||||||
|
return {
|
||||||
|
partsQuestionAnswers: [
|
||||||
|
{
|
||||||
|
glassLocation: "Windshield",
|
||||||
|
glassName: "Single",
|
||||||
|
result: "FW04848",
|
||||||
|
answeredQuestions: [
|
||||||
|
{
|
||||||
|
questionText:
|
||||||
|
"Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?",
|
||||||
|
selectedAnswerText: "Yes",
|
||||||
|
questionNum: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
questionText:
|
||||||
|
"Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?",
|
||||||
|
selectedAnswerText: "Yes",
|
||||||
|
questionNum: 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
useMainStore().pageData = baseStoreGettersPageData;
|
||||||
|
useMainStore().damage = baseStoreGettersDamage;
|
||||||
|
|
||||||
|
describe("partQuestions.vue...", () => {
|
||||||
|
describe("method arePagePrerequisitesValid...", () => {
|
||||||
|
test("Should return true for valid page requisites if pageData exists", () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(result).toBe(true);
|
||||||
|
|
||||||
|
wrapper.unmount();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should return false for valid page requisites if partsOrQuestions in pageData is missing", () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
useMainStore().pageData = jest.fn(() => {
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
|
||||||
|
wrapper.unmount();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should be at least one item in partsOrQuestions", () => {
|
||||||
|
// Arrange
|
||||||
|
useMainStore().pageData = jest.fn(() => {
|
||||||
|
return {
|
||||||
|
partsOrQuestions: [],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
useMainStore().damage = baseStoreGettersDamage;
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
|
||||||
|
wrapper.unmount();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("watch on selectedAnswers should be set up...", () => {
|
||||||
|
test("Should trigger handleAnswerUpdates if watched data changes", async () => {
|
||||||
|
// Arrange
|
||||||
|
useMainStore().pageData = baseStoreGettersPageData;
|
||||||
|
useMainStore().damage = baseStoreGettersDamage;
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
const spy = jest.spyOn(wrapper.vm, "handleAnswerUpdates");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
wrapper.setData({
|
||||||
|
selectedAnswers: {
|
||||||
|
"Windshield-Single": {
|
||||||
|
answerResult: "FW04848",
|
||||||
|
answeredQuestions: [
|
||||||
|
{
|
||||||
|
questionText: "One?",
|
||||||
|
selectedAnswerText: "Yes",
|
||||||
|
questionNum: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
questionText: "Two?",
|
||||||
|
selectedAnswerText: "Yes",
|
||||||
|
questionNum: 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
wrapper.setData({
|
||||||
|
selectedAnswers: {
|
||||||
|
"Windshield-Single": {
|
||||||
|
answerResult: "NEW-ANSWER",
|
||||||
|
answeredQuestions: [
|
||||||
|
{
|
||||||
|
questionText: "One?",
|
||||||
|
selectedAnswerText: "Yes",
|
||||||
|
questionNum: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
questionText: "Two?",
|
||||||
|
selectedAnswerText: "Yes",
|
||||||
|
questionNum: 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(spy).toHaveBeenCalled();
|
||||||
|
|
||||||
|
wrapper.unmount();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("forwardButtonAction", () => {
|
||||||
|
test("Should clear out answerData", async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
await wrapper.setData({
|
||||||
|
questionsData: [
|
||||||
|
{
|
||||||
|
glassLocation: "fbfWindshield",
|
||||||
|
glassName: "fbfSingle",
|
||||||
|
answerData: {
|
||||||
|
answerResult: "FW04848",
|
||||||
|
answeredQuestions: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
wrapper.vm.getParts = jest.fn(() => {
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
glassPieceParts: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.vm.questionsData[0].answerData).toEqual({});
|
||||||
|
|
||||||
|
wrapper.unmount();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should save to pinia store", async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
wrapper.vm.questionsData = [
|
||||||
|
{
|
||||||
|
glassLocation: "Windshield",
|
||||||
|
glassName: "Single",
|
||||||
|
answerData: {
|
||||||
|
answerResult: "FW04848",
|
||||||
|
answeredQuestions: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
useMainStore().getParts = jest.fn(() => {
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
glassPieceParts: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.vm.savePartQuestionAnswers).toHaveBeenCalled;
|
||||||
|
wrapper.unmount();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should call GET_PARTS API", async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
wrapper.vm.questionsData = [
|
||||||
|
{
|
||||||
|
glassLocation: "Windshield",
|
||||||
|
glassName: "Single",
|
||||||
|
answerData: {
|
||||||
|
answerResult: "FW04848",
|
||||||
|
answeredQuestions: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
useMainStore().getParts = jest.fn(() => {
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
glassPieceParts: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.vm.getParts).toHaveBeenCalled;
|
||||||
|
|
||||||
|
wrapper.unmount();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Should trigger navigateForward", async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
wrapper.vm.questionsData = [
|
||||||
|
{
|
||||||
|
glassLocation: "Windshield",
|
||||||
|
glassName: "Single",
|
||||||
|
answerData: {
|
||||||
|
answerResult: "FW04848",
|
||||||
|
answeredQuestions: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
useMainStore().getParts = jest.fn(() => {
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
glassPieceParts: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
wrapper.vm.navigateForward = jest.fn();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.vm.navigateForward).toHaveBeenCalled();
|
||||||
|
|
||||||
|
wrapper.unmount();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function setupMocks({
|
||||||
|
mountOptionsMockData = {
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn(),
|
||||||
|
navigateWithSaving: jest.fn(),
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
|
},
|
||||||
|
actionList: [
|
||||||
|
{
|
||||||
|
actionName: "savePartQuestionAnswers",
|
||||||
|
data: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
actionName: "getParts",
|
||||||
|
data: {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
route: {
|
||||||
|
query: {
|
||||||
|
fmgPage: "part-questions",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
computedSwitcher: [
|
||||||
|
{
|
||||||
|
glassLocation: "Windshield",
|
||||||
|
glassName: "Single",
|
||||||
|
answerData: {
|
||||||
|
answerResult: "FW04848",
|
||||||
|
answeredQuestions: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
questionsData: {
|
||||||
|
get() {
|
||||||
|
return this.computedSwitcher;
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.computedSwitcher = val;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}) {
|
||||||
|
|
||||||
|
useMainStore().getParts = jest.fn(() => {
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
glassPieceParts: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const mountOptions = getMountOptions({
|
||||||
|
...mountOptionsMockData,
|
||||||
|
mixins: [baseMixin, vehicleQuestionsMixin],
|
||||||
|
});
|
||||||
|
mountOptions["attachTo"] = document.body;
|
||||||
|
|
||||||
|
const wrapper = shallowMount(partQuestions, mountOptions);
|
||||||
|
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
name: "make-question",
|
name: "make-question",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
makes: Array,
|
makes: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,8 @@
|
||||||
<div class="select-car-form rounded text-center">
|
<div class="select-car-form rounded text-center">
|
||||||
<vehicleBanner cmsWidgetName="VehicleBannerWidget" :displayGenericVehicleImage="true"/>
|
<vehicleBanner cmsWidgetName="VehicleBannerWidget" :displayGenericVehicleImage="true"/>
|
||||||
<siteSubHeader
|
<siteSubHeader
|
||||||
cmsWidgetName="SiteSubHeaderWidget"
|
cmsWidgetName="SiteSubHeaderWidget"
|
||||||
:hasBackButton="true"
|
:hasBackButton="true"
|
||||||
:backButtonAccessibleText="backButtonAccessibleText"
|
|
||||||
@click-event="backButtonAction"
|
@click-event="backButtonAction"
|
||||||
/>
|
/>
|
||||||
<div class="fade-on-route-transition">
|
<div class="fade-on-route-transition">
|
||||||
|
|
@ -97,12 +96,6 @@
|
||||||
this.$route
|
this.$route
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
computed: {
|
|
||||||
backButtonAccessibleText()
|
|
||||||
{
|
|
||||||
return this.getCmsContent(this.cmsWidgetName, "BackButtonAccessibleText")
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
425
src/layouts/vehicle-parts/vehicle-parts.spec.js
Normal file
425
src/layouts/vehicle-parts/vehicle-parts.spec.js
Normal file
|
|
@ -0,0 +1,425 @@
|
||||||
|
// Components
|
||||||
|
import vehicleParts from "@/layouts/vehicle-parts/vehicle-parts.vue";
|
||||||
|
import glassPartQuestion from "@/layouts/vehicle-parts/glass-part-question/glass-part-question";
|
||||||
|
|
||||||
|
// Supporting Files
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import { nextTick } from "vue";
|
||||||
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
|
import { useMainStore } from "@/store";
|
||||||
|
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
|
||||||
|
|
||||||
|
|
||||||
|
// 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(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
useMainStore().getters = {
|
||||||
|
pageData: jest.fn(),
|
||||||
|
damage: {
|
||||||
|
isRepair: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const basePartResponse = {
|
||||||
|
partsOrQuestions: [
|
||||||
|
{
|
||||||
|
glassName: "Stationary",
|
||||||
|
glassLocation: "Rear",
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
partNumber: "DB12209GTYN",
|
||||||
|
description: "heated glass, solar, 1 hole",
|
||||||
|
color: "Green Tint",
|
||||||
|
requiresRecalibration: false,
|
||||||
|
requiresCapabilityQuestions: false,
|
||||||
|
childParts: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
partNumber: "DB12209YPYNOEM",
|
||||||
|
description: "heated glass, solar, 1 hole",
|
||||||
|
color: "Gray Tint Privacy",
|
||||||
|
requiresRecalibration: false,
|
||||||
|
requiresCapabilityQuestions: false,
|
||||||
|
childParts: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
partQuestions: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
describe("vehicle-parts.vue", () => {
|
||||||
|
test("Set cms content called on load", async () => {
|
||||||
|
//Arrange
|
||||||
|
useMainStore().pageData = jest.fn();
|
||||||
|
useMainStore().pageData.mockReturnValue(basePartResponse);
|
||||||
|
useMainStore().lineItems = { glassParts: null };
|
||||||
|
|
||||||
|
const { wrapper, apiPromise } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn()
|
||||||
|
},
|
||||||
|
route: {
|
||||||
|
query: {
|
||||||
|
issPage: "vehicle-parts",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
useMainStore: {
|
||||||
|
getters: useMainStore().getters,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleParts.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-parts" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
wrapper.vm.setCmsContent = jest.fn();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
apiPromise.finally(() => {
|
||||||
|
expect(wrapper.vm.setCmsContent).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("PageData / isRepair populated in Vuex. arePagePrerequisitesValid should be true ", async () => {
|
||||||
|
//Arrange
|
||||||
|
useMainStore().pageData = jest.fn();
|
||||||
|
useMainStore().pageData.mockReturnValue(basePartResponse);
|
||||||
|
useMainStore().lineItems = { glassParts: null };
|
||||||
|
useMainStore().damage.isRepair = false;
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn(),
|
||||||
|
},
|
||||||
|
route: {
|
||||||
|
query: {
|
||||||
|
issPage: "vehicle-parts",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleParts.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-parts" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(arePagePrerequisitesValid).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Initial data, should populate this.selectedGlassParts", async () => {
|
||||||
|
//Arrange
|
||||||
|
useMainStore().pageData = jest.fn();
|
||||||
|
useMainStore().pageData.mockReturnValue(basePartResponse);
|
||||||
|
useMainStore().lineItems = { glassParts: [{ partNumber: "DB12209YPYNOEM" }] };
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn(),
|
||||||
|
},
|
||||||
|
route: {
|
||||||
|
query: {
|
||||||
|
issPage: "vehicle-parts",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleParts.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-parts" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.vm.selectedGlassParts).toEqual({
|
||||||
|
"Rear-Stationary": {
|
||||||
|
partNumber: "DB12209YPYNOEM",
|
||||||
|
description: "heated glass, solar, 1 hole",
|
||||||
|
color: "Gray Tint Privacy",
|
||||||
|
requiresRecalibration: false,
|
||||||
|
requiresCapabilityQuestions: false,
|
||||||
|
childParts: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("User had part questions > navigateBack triggers a router.navigateWithoutSaving change with correct scenario", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn(),
|
||||||
|
},
|
||||||
|
route: {
|
||||||
|
query: {
|
||||||
|
issPage: "vehicle-parts",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleParts.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-parts" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
wrapper.vm.navigateBack();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
||||||
|
navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS,
|
||||||
|
wrapper.vm.$route
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("User did not have part questions > navigateBack triggers a router.navigate change with correct scenario", async () => {
|
||||||
|
//Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn(),
|
||||||
|
},
|
||||||
|
route: {
|
||||||
|
query: {
|
||||||
|
issPage: "vehicle-parts",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleParts.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-parts" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
wrapper.vm.navigateBack();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
||||||
|
navigationScenarios.CLICKED_BACK_WITH_NO_VIN_NOR_QUESTIONS,
|
||||||
|
wrapper.vm.$route
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("ForwardButtonAction triggers a router.navigate change if there are child part questions", async () => {
|
||||||
|
//Arrange
|
||||||
|
useMainStore().pageData = jest.fn();
|
||||||
|
useMainStore().pageData.mockReturnValue({
|
||||||
|
partsOrQuestions: [
|
||||||
|
{
|
||||||
|
glassName: "Single",
|
||||||
|
glassLocation: "Windshield",
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
partNumber: "FW03861GTYN",
|
||||||
|
description:
|
||||||
|
"rain sensor, heated glass, auto dimming mirror, solar, 3rd visor band, condensation sensor",
|
||||||
|
color: "Green Tint",
|
||||||
|
requiresRecalibration: false,
|
||||||
|
requiresCapabilityQuestions: false,
|
||||||
|
recalibrationType: null,
|
||||||
|
childParts: null,
|
||||||
|
childPartQuestions: [
|
||||||
|
{
|
||||||
|
questionSequence: 1,
|
||||||
|
questionText:
|
||||||
|
"Does the rubber seal around your windshield have a chrome strip running through it?",
|
||||||
|
answers: [
|
||||||
|
{
|
||||||
|
answerResult: "WKT D1106 C",
|
||||||
|
answerText: "Yes",
|
||||||
|
nextQuestionSequence: null,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
answerResult: "WKT D1106 B",
|
||||||
|
answerText: "No",
|
||||||
|
nextQuestionSequence: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
partQuestions: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
useMainStore().lineItems = { glassParts: {} };
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn(),
|
||||||
|
},
|
||||||
|
route: {
|
||||||
|
query: {
|
||||||
|
issPage: "vehicle-parts",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
wrapper.setData({
|
||||||
|
selectedGlassParts: { "Rear-Stationary": { partNumber: "FW03861GTYN" } },
|
||||||
|
});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleParts.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-parts" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("ForwardButtonAction triggers a router.navigate change if there are capability questions", async () => {
|
||||||
|
//Arrange
|
||||||
|
useMainStore().pageData = jest.fn();
|
||||||
|
useMainStore().pageData.mockReturnValue({
|
||||||
|
partsOrQuestions: [
|
||||||
|
{
|
||||||
|
glassName: "Single",
|
||||||
|
glassLocation: "Windshield",
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
partNumber: "DB12209GTYN",
|
||||||
|
description: "heated glass, solar, 1 hole",
|
||||||
|
color: "Green Tint",
|
||||||
|
requiresRecalibration: false,
|
||||||
|
requiresCapabilityQuestions: true,
|
||||||
|
childParts: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
partQuestions: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
useMainStore().lineItems = { glassParts: {} };
|
||||||
|
useMainStore().vehicle = { carId: "TEST_CAR_ID" };
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
router: {
|
||||||
|
navigate: jest.fn(),
|
||||||
|
},
|
||||||
|
route: {
|
||||||
|
query: {
|
||||||
|
issPage: "vehicle-parts",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actionList: [
|
||||||
|
{
|
||||||
|
actionName: "getCapabilityQuestions",
|
||||||
|
data: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
wrapper.setData({
|
||||||
|
selectedGlassParts: { "Rear-Stationary": { partNumber: "DB12209GTYN" } },
|
||||||
|
});
|
||||||
|
|
||||||
|
//Act
|
||||||
|
vehicleParts.beforeRouteEnter.call(
|
||||||
|
wrapper.vm,
|
||||||
|
{ query: { issPage: "vehicle-parts" } },
|
||||||
|
undefined,
|
||||||
|
(c) => c(wrapper.vm)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function setupMocks({ pageHeaderWidgetHeaderText = {}, mountOptionsMockData = {} }) {
|
||||||
|
//Mock api responses
|
||||||
|
const apiResponses = {
|
||||||
|
cmsContent: {
|
||||||
|
SiteSubHeaderWidget: pageHeaderWidgetHeaderText,
|
||||||
|
VehicleBannerWidget: {
|
||||||
|
GenericVehicleImage:
|
||||||
|
"https://digitalisscms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
|
||||||
|
},
|
||||||
|
FunnelHeaderWidget: {
|
||||||
|
LogoImage:
|
||||||
|
"https://digitalisscms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
|
||||||
|
},
|
||||||
|
ColorQuestionWidget: "Please choose your rear window tint color",
|
||||||
|
FeatureQuestionWidget: "Ok no choose features",
|
||||||
|
AlertWidget: {
|
||||||
|
BodyText: "Please choose your tint color",
|
||||||
|
HeadlineText: "Just a few more steps to go",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const store = useMainStore();
|
||||||
|
let actionResult = [];
|
||||||
|
store.getCapabilityQuestions.mockImplementation(() => Promise.resolve({data: actionResult,}));
|
||||||
|
|
||||||
|
const apiPromise = Promise.resolve(apiResponses);
|
||||||
|
|
||||||
|
settleAllPromises.mockImplementation(() => apiPromise);
|
||||||
|
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
||||||
|
|
||||||
|
|
||||||
|
const mountOptions = getMountOptions(mountOptionsMockData);
|
||||||
|
const wrapper = shallowMount(vehicleParts, mountOptions);
|
||||||
|
|
||||||
|
const partQuestionRearWrapper = wrapper.findComponent({ name: "glassPartQuestion" });
|
||||||
|
partQuestionRearWrapper.vm.initializeComponent = glassPartQuestion.methods.initializeComponent;
|
||||||
|
|
||||||
|
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
|
||||||
|
wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
|
||||||
|
|
||||||
|
return { wrapper, apiPromise };
|
||||||
|
}
|
||||||
222
src/layouts/vehicle-parts/vehicle-parts.vue
Normal file
222
src/layouts/vehicle-parts/vehicle-parts.vue
Normal file
|
|
@ -0,0 +1,222 @@
|
||||||
|
<template>
|
||||||
|
<Form @submit="onSubmit" @invalid-submit="onInvalidSubmit" ref="theForm">
|
||||||
|
<div class="page-container-grouped-styles vehicle-parts">
|
||||||
|
<siteHeader ref="siteHeader" cmsWidgetName="SiteHeaderWidget" />
|
||||||
|
<vehicleBanner
|
||||||
|
ref="vehicleBanner"
|
||||||
|
cmsWidgetName="VehicleBannerWidget"
|
||||||
|
:displayGenericVehicleImage="false" />
|
||||||
|
<siteSubHeader ref="siteSubHeader" cmsWidgetName="SiteSubHeaderWidget" />
|
||||||
|
<div class="fade-on-route-transition sub-container make-tall">
|
||||||
|
<div class="prevent-squish my-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<alert
|
||||||
|
class="rounded border-0 shadow-sm"
|
||||||
|
alertClass="alert-warning"
|
||||||
|
cmsWidgetName="AlertWidget"
|
||||||
|
:isDismissible="false" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-for="(item, i) in PartsOrQuestions" :key="i">
|
||||||
|
<!-- Render horizontal lines if there is multi-glass (aka if i > 0) -->
|
||||||
|
<hr v-if="i > 0" />
|
||||||
|
<glassPartQuestion
|
||||||
|
:ref="`${RefPrefix}-${item.glassLocation}-${item.glassName}`"
|
||||||
|
v-model="selectedGlassParts[item.glassLocation + '-' + item.glassName]"
|
||||||
|
:glassLocation="item.glassLocation"
|
||||||
|
:glassName="item.glassName"
|
||||||
|
:colorAnswers="item.colorAnswers"
|
||||||
|
:alreadyPopulatedPartsData="alreadyPopulatedPartsData" />
|
||||||
|
</div>
|
||||||
|
<siteFooter
|
||||||
|
cmsWidgetName="siteFooterWidget"
|
||||||
|
ref="siteFooter"
|
||||||
|
:isForwardActionDisabled="isForwardActionDisabled"
|
||||||
|
@tempButtonClicked="() => handleTempButtonClicked(this)"
|
||||||
|
@back-click="navigateBack"
|
||||||
|
@ForwardClicked="forwardButtonAction" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Components
|
||||||
|
import glassPartQuestion from "@/layouts/vehicle-parts/glass-part-question/glass-part-question";
|
||||||
|
import siteHeader from "@/common-components/site-header/site-header";
|
||||||
|
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||||
|
import siteSubHeader from "@/common-components/site-sub-header/site-sub-header";
|
||||||
|
import siteFooter from "@/common-components/site-footer/site-footer";
|
||||||
|
import alert from "@/ux-components/alert/alert";
|
||||||
|
|
||||||
|
// Supporting Files
|
||||||
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
import { issPageValues } from "@/router/router-constants/issPage-values";
|
||||||
|
import { Form } from "vee-validate";
|
||||||
|
import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "vehicle-parts",
|
||||||
|
mixins: [vehicleQuestionsMixin],
|
||||||
|
async beforeRouteEnter(to, from, next) {
|
||||||
|
// Call APIs
|
||||||
|
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
|
||||||
|
// Settle promises and get results
|
||||||
|
const promiseResultMap = [
|
||||||
|
{
|
||||||
|
resultKey: "cmsContent",
|
||||||
|
promise: cmsContentPromise,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
// Call the "next" function to complete the transition to this page.
|
||||||
|
next((vm) => {
|
||||||
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
|
||||||
|
// Glass Part Question dynamic component
|
||||||
|
Object.keys(vm.$refs)
|
||||||
|
.filter((r) => r.includes(vm.RefPrefix) && vm.$refs[r][0] !== undefined)
|
||||||
|
.forEach((c) =>
|
||||||
|
vm.$refs[c][0].initializeComponent({
|
||||||
|
ColorQuestionWidget: resultMap.cmsContent.ColorQuestionWidget,
|
||||||
|
FeatureQuestionWidget: resultMap.cmsContent.FeatureQuestionWidget,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
selectedGlassParts: {},
|
||||||
|
alertWidgetData: Object,
|
||||||
|
alreadyPopulatedPartsData: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isForwardActionDisabled() {
|
||||||
|
return (
|
||||||
|
this.selectedGlassPartNumbers.length !== this.PartsFromApi.partsOrQuestions.length
|
||||||
|
);
|
||||||
|
},
|
||||||
|
selectedGlassPartNumbers() {
|
||||||
|
// Compile all selected parts from the page.
|
||||||
|
const numberArray = [];
|
||||||
|
for (let glassPart of Object.values(this.selectedGlassParts)) {
|
||||||
|
if (glassPart?.partNumber) {
|
||||||
|
numberArray.push(glassPart.partNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numberArray;
|
||||||
|
},
|
||||||
|
PartsOrQuestions() {
|
||||||
|
const partsData = this.PartsFromApi;
|
||||||
|
|
||||||
|
// Map API result data, to vehicle-parts data structure
|
||||||
|
const mappedData = partsData.partsOrQuestions.map((g) => {
|
||||||
|
return {
|
||||||
|
glassName: g.glassName,
|
||||||
|
glassLocation: g.glassLocation,
|
||||||
|
colorAnswers: g.parts?.reduce((arr, p) => {
|
||||||
|
arr.push({
|
||||||
|
ColorAnswerText: p.color,
|
||||||
|
FeatureAnswers: [
|
||||||
|
{
|
||||||
|
FeatureAnswerText:
|
||||||
|
p.description === "" ? p.color : p.description,
|
||||||
|
PartNumber: p.partNumber,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
return arr;
|
||||||
|
}, []),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return mappedData;
|
||||||
|
},
|
||||||
|
|
||||||
|
PartsFromApi() {
|
||||||
|
return this.mainStore.pageData(issPageValues.VEHICLE_PARTS);
|
||||||
|
},
|
||||||
|
|
||||||
|
RefPrefix() {
|
||||||
|
return "partQuestion";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
arePagePrerequisitesValid() {
|
||||||
|
// Check if isRepair is populated and if the pageData we need is here (Parts data)
|
||||||
|
return (
|
||||||
|
this.mainStore.damage.isRepair != null &&
|
||||||
|
this.mainStore.pageData(issPageValues.VEHICLE_PARTS) &&
|
||||||
|
Object.keys(this.mainStore.pageData(issPageValues.VEHICLE_PARTS)).length !== 0
|
||||||
|
);
|
||||||
|
},
|
||||||
|
async forwardButtonAction() {
|
||||||
|
const matchedParts = [];
|
||||||
|
|
||||||
|
// Match them to the parts from the API.
|
||||||
|
for (let [key, value] of Object.entries(this.PartsFromApi.partsOrQuestions)) {
|
||||||
|
for (let [partKey, partValue] of Object.entries(value.parts)) {
|
||||||
|
const currentPart = this.PartsFromApi.partsOrQuestions[key].parts[partKey];
|
||||||
|
|
||||||
|
const isMatched = this.selectedGlassPartNumbers.some(
|
||||||
|
(p) => p === currentPart.partNumber
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isMatched) {
|
||||||
|
matchedParts.push({
|
||||||
|
glassLocation: value.glassLocation,
|
||||||
|
glassName: value.glassName,
|
||||||
|
parts: [currentPart],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If no parts could be matched, throw an error (isForwardActionDisabled is based off of matchedParts)
|
||||||
|
if (this.isForwardActionDisabled) {
|
||||||
|
this.$refs.funnelFooter.removeLoader();
|
||||||
|
throw new Error("Could not match any parts to the selected parts");
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.mainStore.resetMoldingAndCapabilityQuestionAnswersIfNeeded(matchedParts);
|
||||||
|
|
||||||
|
this.navigateForward(matchedParts, null);
|
||||||
|
},
|
||||||
|
|
||||||
|
LoadInitialPartsData() {
|
||||||
|
const partsData = this.PartsFromApi;
|
||||||
|
this.alreadyPopulatedPartsData =
|
||||||
|
this.mainStore.lineItems.glassParts === null
|
||||||
|
? []
|
||||||
|
: this.mainStore.lineItems.glassParts;
|
||||||
|
|
||||||
|
partsData.partsOrQuestions.map((g) => {
|
||||||
|
// If the part is already populated, use the value from the store and populate the v-model.
|
||||||
|
Object.keys(this.alreadyPopulatedPartsData).forEach((key) => {
|
||||||
|
const partNumber = this.alreadyPopulatedPartsData[key].partNumber;
|
||||||
|
g.parts.forEach((p) => {
|
||||||
|
if (p.partNumber === partNumber) {
|
||||||
|
this.selectedGlassParts[g.glassLocation + "-" + g.glassName] = p;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.LoadInitialPartsData();
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
Form,
|
||||||
|
glassPartQuestion,
|
||||||
|
siteHeader,
|
||||||
|
vehicleBanner,
|
||||||
|
siteSubHeader,
|
||||||
|
siteFooter,
|
||||||
|
alert,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -6,8 +6,8 @@ import { useMainStore } from "@/store";
|
||||||
describe("year-question.vue", () => {
|
describe("year-question.vue", () => {
|
||||||
test("Selected year is emitted upon selection.", async () => {
|
test("Selected year is emitted upon selection.", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const { wrapper } = setupMocks({ modelValueProp: "2020" });
|
const { wrapper } = setupMocks({ modelValueProp: 2020 });
|
||||||
const yearToSelect = "2021";
|
const yearToSelect = 2021;
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
wrapper.setValue({ modelValue: yearToSelect });
|
wrapper.setValue({ modelValue: yearToSelect });
|
||||||
|
|
@ -15,7 +15,7 @@ describe("year-question.vue", () => {
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([
|
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([
|
||||||
{ modelValue: "2021" },
|
{ modelValue: 2021 },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -24,7 +24,7 @@ describe("year-question.vue", () => {
|
||||||
test("Data from store api are used as radio question answers.", async () => {
|
test("Data from store api are used as radio question answers.", async () => {
|
||||||
//Arrange
|
//Arrange
|
||||||
const { wrapper, cmsContent } = setupMocks({
|
const { wrapper, cmsContent } = setupMocks({
|
||||||
dataFromStoreApi: ["2023", "2022", "2021"],
|
dataFromStoreApi: [2023, 2022, 2021],
|
||||||
});
|
});
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
|
|
@ -46,7 +46,7 @@ describe("year-question.vue", () => {
|
||||||
|
|
||||||
|
|
||||||
function setupMocks({
|
function setupMocks({
|
||||||
modelValueProp = "1900",
|
modelValueProp = 1900,
|
||||||
cmsQuestionText = "CMS text goes here",
|
cmsQuestionText = "CMS text goes here",
|
||||||
dataFromStoreApi = [],
|
dataFromStoreApi = [],
|
||||||
}) {
|
}) {
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
modelValue: String,
|
modelValue: Number,
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String,
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { issPageValues } from "@/router/router-constants/issPage-values";
|
import { issPageValues } from "@/router/router-constants/issPage-values";
|
||||||
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
|
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
|
||||||
import { useMainStore } from "../store";
|
import { useMainStore } from "@/store";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -405,9 +405,7 @@ export default {
|
||||||
// mimic part-questions page data for consistency
|
// mimic part-questions page data for consistency
|
||||||
for (let partOrQuestion of partsOrQuestions) {
|
for (let partOrQuestion of partsOrQuestions) {
|
||||||
if (this.hasCapabilityQuestions([partOrQuestion])) {
|
if (this.hasCapabilityQuestions([partOrQuestion])) {
|
||||||
let capabilityQuestionsForGlassLocation = (
|
let capabilityQuestionsForGlassLocation = (await useMainStore().getCapabilityQuestions(useMainStore().vehicle.carId, partOrQuestion.parts[0].partNumber)).data;
|
||||||
await self.mainStore.getCapabilityQuestions(useMainStore().vehicle.carId, partOrQuestion.parts[0].partNumber)
|
|
||||||
).data;
|
|
||||||
|
|
||||||
capabilityQuestionsForGlassLocation.forEach((question) => {
|
capabilityQuestionsForGlassLocation.forEach((question) => {
|
||||||
question.answers = question.answers.map((answer) => {
|
question.answers = question.answers.map((answer) => {
|
||||||
|
|
@ -434,7 +432,7 @@ export default {
|
||||||
const collectedGlassParts = this.reducedGlassPartsArray(partsOrQuestions);
|
const collectedGlassParts = this.reducedGlassPartsArray(partsOrQuestions);
|
||||||
|
|
||||||
// save to store lineItems.glassParts
|
// save to store lineItems.glassParts
|
||||||
self.mainStore.updateGlassParts(collectedGlassParts);
|
useMainStore().updateGlassParts(collectedGlassParts);
|
||||||
|
|
||||||
self.$router.navigate(self.navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,self.$route);
|
self.$router.navigate(self.navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,self.$route);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2343
src/mixins/vehicle-questions-mixin.spec.js
Normal file
2343
src/mixins/vehicle-questions-mixin.spec.js
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -57,12 +57,6 @@ const getDefaultState = () => {
|
||||||
isVerified: false,
|
isVerified: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
serviceLocation: {
|
|
||||||
address: null,
|
|
||||||
city: null,
|
|
||||||
state: null,
|
|
||||||
zipCode: null,
|
|
||||||
},
|
|
||||||
referralNumber: null,
|
referralNumber: null,
|
||||||
referralDate: null,
|
referralDate: null,
|
||||||
accountNumber: 0,
|
accountNumber: 0,
|
||||||
|
|
@ -96,6 +90,7 @@ export const useMainStore = defineStore({
|
||||||
getters: {
|
getters: {
|
||||||
vehicle: (state) => state.order.vehicle,
|
vehicle: (state) => state.order.vehicle,
|
||||||
damage: (state) => state.order.damage,
|
damage: (state) => state.order.damage,
|
||||||
|
lineItems: (state) => state.order.lineItems,
|
||||||
eventBusItem: (state) => ( eventCategory, eventSubCategory) => {
|
eventBusItem: (state) => ( eventCategory, eventSubCategory) => {
|
||||||
|
|
||||||
const matchedEvent = state.applicationUser.eventBus.find(
|
const matchedEvent = state.applicationUser.eventBus.find(
|
||||||
|
|
@ -359,12 +354,38 @@ export const useMainStore = defineStore({
|
||||||
this.applicationUser.pageData[issPageValues.CAPABILITY_QUESTIONS] = null;
|
this.applicationUser.pageData[issPageValues.CAPABILITY_QUESTIONS] = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
resetSupportingItemsState() {
|
||||||
|
this.order.lineItems.supportingItems = null;
|
||||||
|
},
|
||||||
|
|
||||||
resetDamageState() {
|
resetDamageState() {
|
||||||
this.order.damage.isRepair = null;
|
this.order.damage.isRepair = null;
|
||||||
this.order.damage.numberOfChips = null;
|
this.order.damage.numberOfChips = null;
|
||||||
this.order.damage.glassToReplace = null;
|
this.order.damage.glassToReplace = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
resetMoldingAndCapabilityQuestionAnswersIfNeeded(matchedParts) {
|
||||||
|
const partsOrQuestionsDataToCompareWith =
|
||||||
|
this.pageData(issPageValues.MOLDING_QUESTIONS)?.partsOrQuestions ??
|
||||||
|
this.pageData(issPageValues.CAPABILITY_QUESTIONS)?.partsOrQuestions ??
|
||||||
|
[];
|
||||||
|
|
||||||
|
const previouslySelectedPartNumbers = getAllPartNumbers(partsOrQuestionsDataToCompareWith);
|
||||||
|
const currentlySelectedPartNumbers = getAllPartNumbers(matchedParts);
|
||||||
|
|
||||||
|
const haveSelectedVehiclePartsChanged =
|
||||||
|
previouslySelectedPartNumbers !== currentlySelectedPartNumbers;
|
||||||
|
|
||||||
|
if (haveSelectedVehiclePartsChanged) {
|
||||||
|
this.updateGlassParts(null);
|
||||||
|
this.resetSupportingItemsState();
|
||||||
|
this.updateMoldingQuestionAnswers(null);
|
||||||
|
this.updateCapabilityQuestionAnswers(null);
|
||||||
|
this.updatePageData({ page: issPageValues.MOLDING_QUESTIONS, data: null});
|
||||||
|
this.updatePageData({ page: issPageValues.CAPABILITY_QUESTIONS, data: null});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
updateVehicleYear(year) {
|
updateVehicleYear(year) {
|
||||||
if(this.order.vehicle.year != year)
|
if(this.order.vehicle.year != year)
|
||||||
{
|
{
|
||||||
|
|
@ -731,3 +752,14 @@ function convertGlassPieceNamingFromApi(glassArray) {
|
||||||
return glassArray;
|
return glassArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAllPartNumbers(partsOrQuestions) {
|
||||||
|
return partsOrQuestions[0]?.parts
|
||||||
|
? [...partsOrQuestions]
|
||||||
|
.map((glass) => glass.parts)
|
||||||
|
.flat()
|
||||||
|
.map((part) => part.partNumber)
|
||||||
|
.filter((partNumber) => !partNumber.toUpperCase().includes("FEE"))
|
||||||
|
.sort()
|
||||||
|
.join(",")
|
||||||
|
: [];
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue