Merge remote-tracking branch 'origin/develop' into feature/CSR-774

This commit is contained in:
Scott Kiener 2022-11-30 10:32:36 -05:00
commit eb60bfb618
8 changed files with 198 additions and 139 deletions

View file

@ -1,10 +1,10 @@
// Components
import questionsPageLayout from "@/common-components/questions-page-layout/questions-page-layout";
import questionsPageLayout from "@/common-components/layouts/questions-page-layout/questions-page-layout";
// Supporting Files
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import baseMixin from "../../mixins/base-mixin";
import baseMixin from "../../../mixins/base-mixin";
import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin";
// Mock our module for promises.

View file

@ -74,16 +74,7 @@ async function getLatestPageForRedirection() {
fmgPageValues.CAPABILITY_QUESTIONS
);
const vinOptionalVehiclePromise = store.dispatch(storeActions.IS_VIN_OPTIONAL_VEHICLE);
const promiseResultMap = [
{
resultKey: "vinOptionalOptions",
promise: vinOptionalVehiclePromise,
},
];
const resultMap = await settleAllPromises(promiseResultMap);
var isVinOptionalVehicle = resultMap.vinOptionalOptions;
const isVinOptionalVehicle = await store.dispatch(storeActions.IS_VIN_OPTIONAL_VEHICLE);
if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) {
return fmgPageValues.VEHICLE_YEAR;

View file

@ -16,7 +16,7 @@
<script>
// Components
import questionsPageLayout from "@/common-components/questions-page-layout/questions-page-layout";
import questionsPageLayout from "@/common-components/layouts/questions-page-layout/questions-page-layout";
// Supporting Files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
@ -67,38 +67,13 @@ export default {
AlertFewMoreQuestionsCopy() {
return this.getCmsContent("AdditionalPartsQuestionsAlert", "BodyText");
},
pageData() {
return this.$store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS);
partsOrQuestionsData() {
return this.$store.getters.pageData(fmgPageValues.CAPABILITY_QUESTIONS)
.partsOrQuestions;
},
},
mounted() {
// are there alreadyAnsweredQuestions?
const alreadyAnsweredQuestions = store.getters.damage.capabilityQuestionAnswers;
this.questionsData = this.pageData.partsOrQuestions
.filter((x) => x.capabilityQuestions)
.map((glass, index) => {
// NOTE: questions for property "questions" can differ between layouts
glass.questions = glass.capabilityQuestions;
glass.answerKey = glass.glassLocation + "-" + glass.glassName;
// reset selectedAnswers for this glass
this.selectedAnswers[glass.answerKey] = [];
const updatedGlass = this.setupInitialData(glass, index, alreadyAnsweredQuestions);
// Set up watch for each set of glass questions
this.$watch(
"selectedAnswers." + glass.answerKey,
(newValue) => {
if (newValue && Object.keys(newValue).length > 0) {
this.handleAnswerUpdates(newValue, glass.answerKey);
}
},
{ deep: true }
);
return updatedGlass;
});
this.getInitialQuestionData();
},
methods: {
arePagePrerequisitesValid() {
@ -106,12 +81,46 @@ export default {
fmgPageValues.CAPABILITY_QUESTIONS
);
return (
capabilityQuestionsPageData &&
capabilityQuestionsPageData.partsOrQuestions.some(
(el) => el.capabilityQuestions.length > 0
// has capabilityQuestions array and has glassName not null
capabilityQuestionsPageData?.partsOrQuestions?.some((part) => part?.glassName) &&
capabilityQuestionsPageData?.partsOrQuestions?.some(
(part) => part?.capabilityQuestions?.length > 0
)
);
},
getInitialQuestionData() {
// get any questions that were already answered
const alreadyAnsweredQuestions = store.getters.damage.capabilityQuestionAnswers;
this.questionsData = this.partsOrQuestionsData
.filter((x) => x.capabilityQuestions)
.map((glass, index) => {
// NOTE: questions for property "questions" can differ between layouts
glass.questions = glass.capabilityQuestions;
glass.answerKey = glass.glassLocation + "-" + glass.glassName;
// reset selectedAnswers for this glass
this.selectedAnswers[glass.answerKey] = [];
const updatedGlass = this.setupInitialData(
glass,
index,
alreadyAnsweredQuestions
);
// Set up watch for each set of glass questions
this.$watch(
"selectedAnswers." + glass.answerKey,
(newValue) => {
if (newValue && Object.keys(newValue).length > 0) {
this.handleAnswerUpdates(newValue, glass.answerKey);
}
},
{ deep: true }
);
return updatedGlass;
});
},
async forwardButtonAction() {
const questionAnswersArray = this.questionsData.map((glass) => {
// get answerResult2 of returned answer
@ -142,6 +151,7 @@ export default {
});
// save to vuex store as order.damage.capabilityQuestionAnswers (array)
// used in GET_PART_FROM_CAPABILITY_QUESTION_ANSWER call following this one
await this.dispatchStoreAction(
this.storeActions.SAVE_CAPABILITY_QUESTION_ANSWERS,
questionAnswersArray,
@ -149,7 +159,7 @@ export default {
);
// get parts from the capabilityQuestionAnswers
const partsOrQuestions = this.pageData.partsOrQuestions;
const partsOrQuestions = this.partsOrQuestionsData;
for (let answer of questionAnswersArray) {
const partFromCapabilityQuestionAnswer = (
await this.dispatchStoreAction(

View file

@ -132,7 +132,6 @@ export default {
async beforeRouteEnter(to, from, next) {
//Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
const vinOptionalVehiclePromise = store.dispatch(storeActions.IS_VIN_OPTIONAL_VEHICLE);
//Settle promises and get results
const promiseResultMap = [
@ -140,15 +139,13 @@ export default {
resultKey: "cmsContent",
promise: cmsContentPromise,
},
{
resultKey: "vinOptionalOptions",
promise: vinOptionalVehiclePromise,
},
];
const resultMap = await settleAllPromises(promiseResultMap);
const isVinOptionalVehicle = await store.dispatch(storeActions.IS_VIN_OPTIONAL_VEHICLE);
next((vm) => {
vm.isVinOptionalVehicle = resultMap.vinOptionalOptions;
vm.isVinOptionalVehicle = isVinOptionalVehicle;
if (resultMap.cmsContent.FunnelFooterWidget.ForwardButtonText.includes("|")) {
const forwardTextOption =
resultMap.cmsContent.FunnelFooterWidget.ForwardButtonText.split("|");

View file

@ -16,7 +16,7 @@
<script>
// Components
import questionsPageLayout from "@/common-components/questions-page-layout/questions-page-layout";
import questionsPageLayout from "@/common-components/layouts/questions-page-layout/questions-page-layout";
// Supporting Files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
@ -67,51 +67,59 @@ export default {
AlertFewMoreQuestionsCopy() {
return this.getCmsContent("AdditionalPartsQuestionsAlert", "BodyText");
},
pageData() {
return this.$store.getters.pageData(fmgPageValues.MOLDING_QUESTIONS);
partsOrQuestionsData() {
return this.$store.getters.pageData(fmgPageValues.MOLDING_QUESTIONS).partsOrQuestions;
},
},
mounted() {
// are there alreadyAnsweredQuestions?
const alreadyAnsweredQuestions = store.getters.damage.moldingQuestionAnswers;
this.questionsData = this.pageData.partsOrQuestions
.filter((x) => x.parts[0].childPartQuestions.length)
.map((glass, index) => {
// NOTE: questions for property "questions" can differ between layouts
glass.questions = glass.parts[0].childPartQuestions;
glass.answerKey = glass.glassLocation + "-" + glass.glassName;
// reset selectedAnswers for this glass
this.selectedAnswers[glass.answerKey] = [];
const updatedGlass = this.setupInitialData(glass, index, alreadyAnsweredQuestions);
this.$watch(
"selectedAnswers." + glass.answerKey,
(newValue) => {
if (newValue && Object.keys(newValue).length > 0) {
this.handleAnswerUpdates(newValue, glass.answerKey);
}
},
{ deep: true }
);
return updatedGlass;
});
this.getInitialQuestionData();
},
methods: {
arePagePrerequisitesValid() {
const moldingQuestionsFromPageData = store.getters.pageData(
fmgPageValues.MOLDING_QUESTIONS
);
return (
moldingQuestionsFromPageData &&
// has childPartQuestions array and has glassName not null
moldingQuestionsFromPageData?.partsOrQuestions?.some((part) => part?.glassName) &&
moldingQuestionsFromPageData.partsOrQuestions.some((glass) =>
glass.parts?.some((part) => part?.childPartQuestions.length > 0)
glass.parts?.some((part) => part?.childPartQuestions?.length > 0)
)
);
},
getInitialQuestionData() {
// get any questions that were already answered
const alreadyAnsweredQuestions = store.getters.damage.moldingQuestionAnswers;
this.questionsData = this.partsOrQuestionsData
.filter((x) => x.parts[0].childPartQuestions.length)
.map((glass, index) => {
// NOTE: questions for property "questions" can differ between layouts
glass.questions = glass.parts[0].childPartQuestions;
glass.answerKey = glass.glassLocation + "-" + glass.glassName;
// reset selectedAnswers for this glass
this.selectedAnswers[glass.answerKey] = [];
const updatedGlass = this.setupInitialData(
glass,
index,
alreadyAnsweredQuestions
);
// Set up watch for each set of glass questions
this.$watch(
"selectedAnswers." + glass.answerKey,
(newValue) => {
if (newValue && Object.keys(newValue).length > 0) {
this.handleAnswerUpdates(newValue, glass.answerKey);
}
},
{ deep: true }
);
return updatedGlass;
});
},
async forwardButtonAction() {
const questionAnswersArray = this.questionsData.map((glass) => {
return {
@ -136,7 +144,7 @@ export default {
);
// get parts from the questionAnswers
let partsOrQuestions = this.pageData.partsOrQuestions;
let partsOrQuestions = this.partsOrQuestionsData;
for (let answer of questionAnswersArray) {
partsOrQuestions.find((partOrQuestion) => {
return (

View file

@ -98,14 +98,6 @@ store.getters = {
};
store.commit = jest.fn();
afterEach(() => {
// reset store after each test
store.getters = {
pageData: baseStoreGettersPageData,
damage: baseStoreGettersDamage,
};
});
describe("partQuestions.vue...", () => {
describe("method arePagePrerequisitesValid...", () => {
test("Should return true for valid page requisites if pageData exists", () => {
@ -162,6 +154,10 @@ describe("partQuestions.vue...", () => {
describe("watch on selectedAnswers should be set up...", () => {
test("Should trigger handleAnswerUpdates if watched data changes", async () => {
// Arrange
store.getters = {
pageData: baseStoreGettersPageData,
damage: baseStoreGettersDamage,
};
const { wrapper } = setupMocks({});
const spy = jest.spyOn(wrapper.vm, "handleAnswerUpdates");
@ -172,14 +168,12 @@ describe("partQuestions.vue...", () => {
answerResult: "FW04848",
answeredQuestions: [
{
questionText:
"Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?",
questionText: "One?",
selectedAnswerText: "Yes",
questionNum: 1,
},
{
questionText:
"Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?",
questionText: "Two?",
selectedAnswerText: "Yes",
questionNum: 2,
},
@ -191,6 +185,27 @@ describe("partQuestions.vue...", () => {
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();
@ -199,20 +214,23 @@ describe("partQuestions.vue...", () => {
});
describe("forwardButtonAction", () => {
test("Should clear out answerData", () => {
test("Should clear out answerData", async () => {
// Arrange
const { wrapper } = setupMocks({});
wrapper.vm.questionsData = [
{
glassLocation: "Windshield",
glassName: "Single",
answerData: {
answerResult: "FW04848",
answeredQuestions: [],
await wrapper.setData({
questionsData: [
{
glassLocation: "fbfWindshield",
glassName: "fbfSingle",
answerData: {
answerResult: "FW04848",
answeredQuestions: [],
},
},
},
];
],
});
wrapper.vm.dispatchStoreAction = jest.fn(() => {
return {
data: {
@ -224,6 +242,8 @@ describe("partQuestions.vue...", () => {
// Act
wrapper.vm.forwardButtonAction();
await nextTick();
//Assert
expect(wrapper.vm.questionsData[0].answerData).toEqual({});
@ -371,6 +391,28 @@ function setupMocks({
fmgPage: "part-questions",
},
},
data() {
return {
computedSwitcher: [
{
glassLocation: "Windshield",
glassName: "Single",
answerData: {
answerResult: "FW04848",
answeredQuestions: [],
},
},
],
};
},
questionsData: {
get() {
return this.computedSwitcher;
},
set(val) {
this.computedSwitcher = val;
},
},
},
}) {
const mountOptions = getMountOptions({

View file

@ -16,7 +16,7 @@
<script>
// Components
import questionsPageLayout from "@/common-components/questions-page-layout/questions-page-layout";
import questionsPageLayout from "@/common-components/layouts/questions-page-layout/questions-page-layout";
// Supporting Files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
@ -67,47 +67,57 @@ export default {
AlertFewMoreQuestionsCopy() {
return this.getCmsContent("AlertPartsQuestions", "BodyText");
},
pageData() {
return this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS);
partsOrQuestionsData() {
return this.$store.getters.pageData(fmgPageValues.PART_QUESTIONS).partsOrQuestions;
},
},
mounted() {
// are there alreadyAnsweredQuestions?
const alreadyAnsweredQuestions = store.getters.damage.partQuestionAnswers;
this.questionsData = this.pageData.partsOrQuestions
.filter((x) => x.partQuestions)
.map((glass, index) => {
// NOTE: questions for property "questions" can differ between layouts
glass.questions = glass.partQuestions;
glass.answerKey = glass.glassLocation + "-" + glass.glassName;
// reset selectedAnswers for this glass
this.selectedAnswers[glass.answerKey] = [];
const updatedGlass = this.setupInitialData(glass, index, alreadyAnsweredQuestions);
// Set up watch for each set of glass questions
this.$watch(
"selectedAnswers." + glass.answerKey,
(newValue) => {
if (newValue && Object.keys(newValue).length > 0) {
this.handleAnswerUpdates(newValue, glass.answerKey);
}
},
{ deep: true }
);
return updatedGlass;
});
this.getInitialQuestionData();
},
methods: {
arePagePrerequisitesValid() {
const partQuestionsFromPageData = store.getters.pageData(fmgPageValues.PART_QUESTIONS);
return (
partQuestionsFromPageData &&
Object.keys(partQuestionsFromPageData.partsOrQuestions).length > 0
// has .partQuestions array and has glassName not null
partQuestionsFromPageData?.partsOrQuestions?.some((part) => part?.glassName) &&
partQuestionsFromPageData?.partsOrQuestions?.some(
(part) => part?.partQuestions?.length > 0
)
);
},
getInitialQuestionData() {
// get any questions that were already answered
const alreadyAnsweredQuestions = store.getters.damage.partQuestionAnswers;
this.questionsData = this.partsOrQuestionsData
.filter((x) => x.partQuestions)
.map((glass, index) => {
// NOTE: questions for property "questions" can differ between layouts
glass.questions = glass.partQuestions;
glass.answerKey = glass.glassLocation + "-" + glass.glassName;
// reset selectedAnswers for this glass
this.selectedAnswers[glass.answerKey] = [];
const updatedGlass = this.setupInitialData(
glass,
index,
alreadyAnsweredQuestions
);
// Set up watch for each set of glass questions
this.$watch(
"selectedAnswers." + glass.answerKey,
(newValue) => {
if (newValue && Object.keys(newValue).length > 0) {
this.handleAnswerUpdates(newValue, glass.answerKey);
}
},
{ deep: true }
);
return updatedGlass;
});
},
async forwardButtonAction() {
const questionAnswersArray = this.questionsData.map((glass) => {
return {
@ -127,6 +137,7 @@ export default {
});
// save to vuex store as order.damage.partQuestionAnswers (array)
// used in GET_PARTS call following this one
await this.dispatchStoreAction(
this.storeActions.SAVE_PART_QUESTION_ANSWERS,
questionAnswersArray,