diff --git a/src/digital-components/question-chain/question-chain.spec.js b/src/digital-components/question-chain/question-chain.spec.js index 1dad2d5de..d0e54a895 100644 --- a/src/digital-components/question-chain/question-chain.spec.js +++ b/src/digital-components/question-chain/question-chain.spec.js @@ -482,9 +482,86 @@ describe("Question Chain component", () => { expect(wrapper.vm.currentQuestionNum).toBe(3); expect(wrapper.vm.isQuestionVisible(wrapper.vm.questions[2])).toBe(true); }); + + test("should resolve on Q1 Yes and not show Q2 for Honda HUD question", async () => { + const { wrapper } = setupMocks({ + questionDataProp: getHondaAccordWindshieldQuestions(), + }); + await nextTick(); + + const q1 = wrapper.vm.questions[0]; + wrapper.vm.handleAnswer(q1, "1|answer|FW04796|Yes"); + + expect(wrapper.emitted()["update:modelValue"][0][0]).toMatchObject({ + answerResult: "FW04796", + index: 0, + }); + expect(wrapper.vm.currentQuestionNum).toBe(0); + expect(wrapper.vm.isQuestionVisible(wrapper.vm.questions[1])).toBe(false); + }); + + test("should resolve on Q3 No and not continue after remount", async () => { + const questionDataProp = getHondaAccordWindshieldQuestions(); + questionDataProp[0].answerSelected = "1|nextQuestion|2|No"; + questionDataProp[1].answerSelected = "2|nextQuestion|3|No"; + questionDataProp[2].answerSelected = "3|answer|FW04793|No"; + + const { wrapper } = setupMocks({ questionDataProp }); + await nextTick(); + + expect(wrapper.vm.currentQuestionNum).toBe(0); + expect(wrapper.vm.isQuestionVisible(wrapper.vm.questions[2])).toBe(true); + expect( + wrapper.vm.questions.filter((question) => wrapper.vm.isQuestionVisible(question)) + ).toHaveLength(3); + }); + + test("should show Q2 after answering No on Honda HUD question", async () => { + const { wrapper } = setupMocks({ + questionDataProp: getHondaAccordWindshieldQuestions(), + }); + await nextTick(); + + const q1 = wrapper.vm.questions[0]; + wrapper.vm.handleAnswer(q1, "1|nextQuestion|2|No"); + + expect(wrapper.vm.currentQuestionNum).toBe(2); + expect(wrapper.vm.isQuestionVisible(wrapper.vm.questions[1])).toBe(true); + }); }); }); +function getHondaAccordWindshieldQuestions() { + return [ + { + questionSequence: 1, + questionText: + "Is your vehicle equipped with a Heads-up Display which projects vehicle information, such as speed, onto the windshield?", + answers: [ + { answerResult: "FW04796", answerText: "Yes", nextQuestionSequence: null }, + { answerResult: "", answerText: "No", nextQuestionSequence: 2 }, + ], + }, + { + questionSequence: 2, + questionText: + "Is your vehicle equipped with an auto-dimming rearview mirror which will darken automatically when a vehicles approaches from the rear at night?", + answers: [ + { answerResult: "FW04795", answerText: "Yes", nextQuestionSequence: null }, + { answerResult: "", answerText: "No", nextQuestionSequence: 3 }, + ], + }, + { + questionSequence: 3, + questionText: "Is your vehicle equipped with a power moonroof?", + answers: [ + { answerResult: "FW04794", answerText: "Yes", nextQuestionSequence: null }, + { answerResult: "FW04793", answerText: "No", nextQuestionSequence: null }, + ], + }, + ]; +} + function getCherokeeWindshieldQuestions() { return [ { diff --git a/src/digital-components/question-chain/question-chain.vue b/src/digital-components/question-chain/question-chain.vue index b37755ee7..467e9619e 100644 --- a/src/digital-components/question-chain/question-chain.vue +++ b/src/digital-components/question-chain/question-chain.vue @@ -20,6 +20,7 @@ import buttonQuestion from "@/digital-components/button-question/button-question"; import { useValidateForm } from "vee-validate"; import { + isTerminalQuestionChainAnswer, mapQuestionAnswersForChain, normalizeAnswerSelectedValue, } from "@/helpers/question-chain-helper"; @@ -74,13 +75,18 @@ export default { return !!question.answerSelected || this.isCurrentQuestion(question); }, initializeCurrentQuestionNum() { - const pendingNextQuestion = [...this.questions] + const lastAnsweredQuestion = [...this.questions] .reverse() - .find((question) => question.answerSelected?.includes("|nextQuestion|")); + .find((question) => question.answerSelected); - if (pendingNextQuestion) { + if (isTerminalQuestionChainAnswer(lastAnsweredQuestion?.answerSelected)) { + this.currentQuestionNum = 0; + return; + } + + if (lastAnsweredQuestion?.answerSelected?.includes("|nextQuestion|")) { const nextQuestionSequence = Number( - pendingNextQuestion.answerSelected.split("|")[2] + lastAnsweredQuestion.answerSelected.split("|")[2] ); if ( diff --git a/src/helpers/question-chain-helper.js b/src/helpers/question-chain-helper.js index b5ba8c168..fdf7f194c 100644 --- a/src/helpers/question-chain-helper.js +++ b/src/helpers/question-chain-helper.js @@ -32,6 +32,16 @@ export function mapQuestionAnswersForChain(question) { })); } +export function isTerminalQuestionChainAnswer(answerSelected) { + if (!answerSelected) { + return false; + } + + const [, questionType, answerResult] = answerSelected.split("|"); + + return questionType?.toLowerCase() === "answer" && !!answerResult; +} + export function normalizeAnswerSelectedValue(answerSelected, answers) { if (!answerSelected) { return ""; diff --git a/src/helpers/question-chain-helper.spec.js b/src/helpers/question-chain-helper.spec.js index fa8db3714..f3a31acc1 100644 --- a/src/helpers/question-chain-helper.spec.js +++ b/src/helpers/question-chain-helper.spec.js @@ -1,5 +1,6 @@ import { buildQuestionChainAnswerValue, + isTerminalQuestionChainAnswer, mapQuestionAnswersForChain, normalizeAnswerSelectedValue, } from "./question-chain-helper"; @@ -29,6 +30,21 @@ describe("question-chain-helper", () => { }); }); + describe("isTerminalQuestionChainAnswer", () => { + test("returns true when answer has a part number and no next question", () => { + expect(isTerminalQuestionChainAnswer("1|answer|FW04796|Yes")).toBe(true); + expect(isTerminalQuestionChainAnswer("3|answer|FW04793|No")).toBe(true); + }); + + test("returns false when answer continues to the next question", () => { + expect(isTerminalQuestionChainAnswer("1|nextQuestion|2|No")).toBe(false); + }); + + test("returns false when answer type is answer but part number is missing", () => { + expect(isTerminalQuestionChainAnswer("1|answer||No")).toBe(false); + }); + }); + describe("normalizeAnswerSelectedValue", () => { const answers = [{ value: "1|answer|DW01705|Yes" }, { value: "1|answer|DW01591|No" }];