diff --git a/jest.config.js b/jest.config.js
index c5401c28f..bfb4bf71f 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -13,14 +13,9 @@ module.exports = {
"!src/router/**/*.js",
"!src/helpers/unit-test-helper.js",
"!src/layouts/vehicle-damage/windshield-options/windshield-options.vue",
- "!src/layouts/molding-questions/**/*.vue",
- "!src/layouts/capability-questions/**/*.vue",
- "!src/layouts/part-questions/**/*.vue",
"!src/layouts/reveal/**/*.vue",
- "!src/layouts/quote/**/*.vue",
"!src/ux-components/text-link/**/*.vue",
- "!src/common-components/question-chain/**/*.vue",
- "!src/layouts/quote/**/*.vue", // Temporary
+ "!src/common-components/date-picker/**/*.vue",
"!src/layouts/vin-lookup/**/*.vue", //Temporary for Quote page testing
"!src/common-components/funnel-header/menu-modal/**/*.vue",
// END
diff --git a/src/assets/img/icons/ccpa-icon.svg b/src/assets/img/icons/ccpa-icon.svg
new file mode 100644
index 000000000..30eb3e086
--- /dev/null
+++ b/src/assets/img/icons/ccpa-icon.svg
@@ -0,0 +1,6 @@
+
diff --git a/src/common-components/button-question/button-question.spec.js b/src/common-components/button-question/button-question.spec.js
index 006cbcf2c..132e5edb9 100644
--- a/src/common-components/button-question/button-question.spec.js
+++ b/src/common-components/button-question/button-question.spec.js
@@ -1,4 +1,4 @@
-import { shallowMount } from "@vue/test-utils";
+import { shallowMount, mount } from "@vue/test-utils";
import buttonQuestion from "@/common-components/button-question/button-question";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
@@ -115,6 +115,38 @@ describe("buttonQuestion.vue", () => {
"2020",
]);
});
+ test("should accept an imported component for buttonTypeObject and successfully add it to components", async () => {
+ // Arrange
+ const mockComponent = {
+ name: "mockComponent",
+ methods: {
+ mockComponentMethod() {
+ return "mockComponentMethod return value";
+ },
+ },
+ };
+
+ const wrapper = await shallowMount(
+ buttonQuestion,
+ setupMocks({
+ propsData: {
+ buttonTypeString: "mockComponent",
+ buttonTypeObject: mockComponent,
+ },
+ })
+ );
+
+ // Act
+ const componentList = wrapper.vm.$options.components;
+ const componentExists = !!componentList.mockComponent;
+ const componentNameMatches = componentList.mockComponent.name === mockComponent.name;
+ const componentMethodMatches =
+ componentList.mockComponent.methods.mockComponentMethod() ===
+ mockComponent.methods.mockComponentMethod();
+
+ // Assert
+ expect(componentExists && componentNameMatches && componentMethodMatches).toBe(true);
+ });
});
describe("buttonsInfo", () => {
diff --git a/src/common-components/date-picker/date-picker-spec.js b/src/common-components/date-picker/date-picker-spec.js1
similarity index 100%
rename from src/common-components/date-picker/date-picker-spec.js
rename to src/common-components/date-picker/date-picker-spec.js1
diff --git a/src/common-components/funnel-footer/funnel-footer.spec.js b/src/common-components/funnel-footer/funnel-footer.spec.js
index cd2a06663..6360fb34a 100644
--- a/src/common-components/funnel-footer/funnel-footer.spec.js
+++ b/src/common-components/funnel-footer/funnel-footer.spec.js
@@ -2,7 +2,7 @@ import { mount } from "@vue/test-utils";
import funnelFooter from "./funnel-footer";
describe("funnel-footer.vue", () => {
- it("Should emit ForwardClicked on button click", async () => {
+ test("Should emit ForwardClicked on button click", async () => {
// Act
const wrapper = mount(funnelFooter, {
mixins: [mockMixin],
@@ -12,7 +12,7 @@ describe("funnel-footer.vue", () => {
expect(wrapper.emitted()["ForwardClicked"][0]).toHaveBeenCalled;
});
- it("Should emit BackClicked on link click", async () => {
+ test("Should emit BackClicked on link click", async () => {
// Act
const wrapper = mount(funnelFooter, {
mixins: [mockMixin],
@@ -22,7 +22,7 @@ describe("funnel-footer.vue", () => {
expect(wrapper.emitted()["BackClicked"][0]).toHaveBeenCalled;
});
- it("Should change button text when update button text is called", async () => {
+ test("Should change button text when update button text is called", async () => {
// Act
const wrapper = mount(funnelFooter, {
mixins: [mockMixin],
@@ -32,6 +32,23 @@ describe("funnel-footer.vue", () => {
// Assert
expect(wrapper.componentVM.customButtontext).toBe("newText");
});
+
+ test("should run removeLoader fn on buttonMain and return false for onkeydown fn", async () => {
+ // Arrange
+ const wrapper = mount(funnelFooter, {
+ mixins: [mockMixin],
+ });
+
+ // Act
+ wrapper.vm.$refs.buttonMain.removeLoader = jest.fn();
+ wrapper.vm.removeLoader();
+ const spy = jest.spyOn(document, "onkeydown");
+ document.onkeydown();
+
+ // Assert
+ expect(wrapper.vm.$refs.buttonMain.removeLoader).toHaveBeenCalled();
+ expect(spy).toReturnWith(true);
+ });
});
const mockMixin = {
diff --git a/src/common-components/funnel-header/menu-modal/menu-modal.vue b/src/common-components/funnel-header/menu-modal/menu-modal.vue
index 55ed98dd9..fd0c96cb8 100644
--- a/src/common-components/funnel-header/menu-modal/menu-modal.vue
+++ b/src/common-components/funnel-header/menu-modal/menu-modal.vue
@@ -44,16 +44,28 @@
+
+
+
+
+
@@ -147,6 +159,11 @@ export default {
overflow-y: visible;
.modal-body {
padding: 2rem;
+ .ccpa-icon {
+ width: 2.0625rem;
+ height: 1rem;
+ margin-left: 0.5rem;
+ }
}
.modal-fullscreen {
width: 100vw;
diff --git a/src/common-components/layouts/questions-page-layout/questions-page-layout.spec.js b/src/common-components/layouts/questions-page-layout/questions-page-layout.spec.js
new file mode 100644
index 000000000..72da3c9df
--- /dev/null
+++ b/src/common-components/layouts/questions-page-layout/questions-page-layout.spec.js
@@ -0,0 +1,253 @@
+// Components
+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 vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin";
+
+// 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(),
+}));
+
+jest.mock("@/helpers/heritage-integration/navigation-helper", () => ({
+ navigateToHeritageFunnel: jest.fn(),
+}));
+
+describe("questionsPageLayout.vue", () => {
+ describe("method showThisQuestionChain...", () => {
+ test("Should return true if index prop and passed index match", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ await wrapper.setProps({ index: 0 });
+
+ const testGlassPiece = {
+ questions: [
+ {
+ questionSequence: 1,
+ questionText:
+ "Is your vehicle equipped with the optional Lane-Keeping System which tugs on the steering wheel and/or beeps to alert you if you drift too close to the edge of the lane?",
+ answers: [],
+ },
+ ],
+ };
+ const testIndex = 0;
+
+ // Act
+ const result = wrapper.vm.showThisQuestionChain(testGlassPiece, testIndex);
+
+ //Assert
+ expect(result).toBe(true);
+
+ wrapper.unmount();
+ });
+
+ test("Should return true if answerResult exists", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ await wrapper.setProps({ index: 0 });
+
+ const testGlassPiece = {
+ questions: [
+ {
+ questionSequence: 1,
+ questionText:
+ "Is your vehicle equipped with the optional Lane-Keeping System which tugs on the steering wheel and/or beeps to alert you if you drift too close to the edge of the lane?",
+ answers: [],
+ },
+ ],
+ answerData: {
+ answerResult: "test",
+ },
+ };
+ const testIndex = 1;
+
+ // Act
+ const result = wrapper.vm.showThisQuestionChain(testGlassPiece, testIndex);
+
+ //Assert
+ expect(result).toBe(true);
+
+ wrapper.unmount();
+ });
+
+ test("Should return false if indexes don't match and answerResult is missing", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ await wrapper.setProps({ index: 0 });
+
+ const testGlassPiece = {
+ questions: [
+ {
+ questionSequence: 1,
+ questionText:
+ "Is your vehicle equipped with the optional Lane-Keeping System which tugs on the steering wheel and/or beeps to alert you if you drift too close to the edge of the lane?",
+ answers: [],
+ },
+ ],
+ };
+ const testIndex = 1;
+
+ // Act
+ const result = wrapper.vm.showThisQuestionChain(testGlassPiece, testIndex);
+
+ //Assert
+ expect(result).toBe(false);
+
+ wrapper.unmount();
+ });
+
+ test("Should return false if no questions", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ await wrapper.setProps({ index: 0 });
+
+ const testGlassPiece = {};
+ const testIndex = 0;
+
+ // Act
+ const result = wrapper.vm.showThisQuestionChain(testGlassPiece, testIndex);
+
+ //Assert
+ expect(result).toBe(false);
+
+ wrapper.unmount();
+ });
+
+ test("Should return false if suppressed", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ await wrapper.setProps({ index: 0 });
+
+ const testGlassPiece = {
+ isSuppressedPart: true,
+ questions: [
+ {
+ questionSequence: 1,
+ questionText:
+ "Is your vehicle equipped with the optional Lane-Keeping System which tugs on the steering wheel and/or beeps to alert you if you drift too close to the edge of the lane?",
+ answers: [],
+ },
+ ],
+ answerData: {
+ answerResult: "test",
+ },
+ };
+ const testIndex = 0;
+
+ // Act
+ const result = wrapper.vm.showThisQuestionChain(testGlassPiece, testIndex);
+
+ //Assert
+ expect(result).toBe(false);
+
+ wrapper.unmount();
+ });
+ });
+
+ describe("method handleForwardButtonAction...", () => {
+ test("Should emit forwardButtonAction", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ await wrapper.setProps({});
+
+ // Act
+ wrapper.vm.handleForwardButtonAction();
+
+ //Assert
+ expect(wrapper.emitted()).toHaveProperty("forwardButtonAction");
+
+ wrapper.unmount();
+ });
+ });
+
+ describe("method handleBackButtonAction...", () => {
+ test("Should emit backButtonAction", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ await wrapper.setProps({});
+
+ // Act
+ wrapper.vm.handleBackButtonAction();
+
+ //Assert
+ expect(wrapper.emitted()).toHaveProperty("back-click");
+
+ wrapper.unmount();
+ });
+ });
+});
+
+function setupMocks() {
+ 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,
+ },
+ ],
+ },
+ ],
+ };
+ };
+ const mountOptions = getMountOptions({
+ mixins: [baseMixin, vehicleQuestionsMixin],
+ });
+ mountOptions["attachTo"] = document.body;
+ const wrapper = shallowMount(questionsPageLayout, mountOptions);
+
+ return { wrapper };
+}
diff --git a/src/common-components/questions-page-layout/questions-page-layout.vue b/src/common-components/layouts/questions-page-layout/questions-page-layout.vue
similarity index 94%
rename from src/common-components/questions-page-layout/questions-page-layout.vue
rename to src/common-components/layouts/questions-page-layout/questions-page-layout.vue
index 85ccd33ad..d2d6aaab2 100644
--- a/src/common-components/questions-page-layout/questions-page-layout.vue
+++ b/src/common-components/layouts/questions-page-layout/questions-page-layout.vue
@@ -27,7 +27,7 @@
ref="funnelFooter"
cmsWidgetName="FunnelFooterWidget"
:isForwardActionDisabled="!isMetaValid"
- @back-clicked="backButtonAction"
+ @back-clicked="handleBackButtonClicked"
@ForwardClicked="handleForwardButtonAction" />
@@ -51,7 +51,7 @@ export default {
alertFewMoreQuestionsCopy: String,
questionsData: Array,
validationRules: String,
- modelValue: Array,
+ modelValue: Object,
index: Number,
},
computed: {
@@ -66,16 +66,17 @@ export default {
},
methods: {
showThisQuestionChain(glass, i) {
+ // return false if no questions or if suppressed
if (!glass.questions || glass.questions?.length < 1 || glass.isSuppressedPart) {
return false;
- } // return false if no questions or if suppressed
+ }
return this.index === i || glass.answerData?.answerResult?.length > 0;
},
handleForwardButtonAction() {
this.$emit("forwardButtonAction");
},
handleBackButtonAction() {
- this.$emit("backButtonAction");
+ this.$emit("back-click");
},
showLoadingModal() {
this.$refs.loadingModal.showModal();
diff --git a/src/common-components/modal/modal.spec.js b/src/common-components/modal/modal.spec.js
index 85472d6eb..2664accfa 100644
--- a/src/common-components/modal/modal.spec.js
+++ b/src/common-components/modal/modal.spec.js
@@ -6,6 +6,10 @@ describe("modal.vue", () => {
// Act
const wrapper = shallowMount(Modal, {
mixins: [mockMixin],
+ props: {
+ cmsWidgetName: "test",
+ },
+ attachTo: document.body,
});
expect(wrapper.html()).toEqual(expect.stringContaining(mockCmsContent["HeaderText"]));
});
@@ -14,6 +18,10 @@ describe("modal.vue", () => {
// Act
const wrapper = shallowMount(Modal, {
mixins: [mockMixin],
+ props: {
+ cmsWidgetName: "test",
+ },
+ attachTo: document.body,
});
expect(wrapper.html()).toEqual(expect.stringContaining(mockCmsContent["SubheaderText"]));
});
@@ -22,6 +30,10 @@ describe("modal.vue", () => {
// Act
const wrapper = shallowMount(Modal, {
mixins: [mockMixin],
+ props: {
+ cmsWidgetName: "test",
+ },
+ attachTo: document.body,
});
expect(wrapper.html()).toEqual(expect.stringContaining(mockCmsContent["Image"]));
});
@@ -30,6 +42,10 @@ describe("modal.vue", () => {
// Act
const wrapper = shallowMount(Modal, {
mixins: [mockMixin],
+ props: {
+ cmsWidgetName: "test",
+ },
+ attachTo: document.body,
});
expect(wrapper.html()).toEqual(expect.stringContaining(mockCmsContent["BodyText"]));
});
diff --git a/src/common-components/modal/modal.vue b/src/common-components/modal/modal.vue
index 1546860a8..9a8e6c211 100644
--- a/src/common-components/modal/modal.vue
+++ b/src/common-components/modal/modal.vue
@@ -16,7 +16,7 @@
aria-label="Close">
-
![]()
+
@@ -25,7 +25,7 @@
@@ -60,6 +60,12 @@ export default {
return this.getCmsContent(this.cmsWidgetName, "FooterText");
},
},
+ mounted() {
+ const modal = document.querySelector("#" + this.cmsWidgetName);
+ modal.addEventListener("hidden.bs.modal", (event) => {
+ this.$refs.buttonMain.resetButtonStyle();
+ });
+ },
components: {
buttonMain,
},
diff --git a/src/common-components/question-chain/question-chain.spec.js b/src/common-components/question-chain/question-chain.spec.js
new file mode 100644
index 000000000..8288f351c
--- /dev/null
+++ b/src/common-components/question-chain/question-chain.spec.js
@@ -0,0 +1,322 @@
+import { shallowMount } from "@vue/test-utils";
+import questionChain from "@/common-components/question-chain/question-chain.vue";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+import { nextTick } from "vue";
+
+jest.mock(
+ "@/store",
+ () => {
+ return {};
+ },
+ { virtual: true }
+);
+
+describe("Question Chain component", () => {
+ describe("on create...", () => {
+ test("Should populate questions data array", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ const expectedFirstQuestionAnswer = {
+ answerResult: "DB09410",
+ buttonLabel: "Yes",
+ nextQuestionSequence: null,
+ questionSequence: 1,
+ questionType: "answer",
+ value: "1|answer|DB09410|Yes",
+ };
+
+ //Act
+ await nextTick();
+
+ //Assert
+ expect(wrapper.vm.questions[0].answers[0]).toMatchObject(expectedFirstQuestionAnswer);
+ });
+
+ test("Should not include suppressed questions on questions data array", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ await wrapper.setData({
+ questionData: [
+ {
+ questionSequence: 1,
+ questionText: "Question here?",
+ answers: [
+ {
+ answerResult: "DB09410",
+ answerText: "Yes",
+ nextQuestionSequence: null,
+ },
+ {
+ answerResult: "DB10840",
+ answerText: "No",
+ nextQuestionSequence: null,
+ },
+ ],
+ suppressThisQuestion: true,
+ },
+ ],
+ });
+
+ //Act
+ await nextTick();
+
+ //Assert
+ expect(wrapper.vm.questions[0]).toBeFalsy();
+ });
+ });
+
+ describe("method handleAnswer...", () => {
+ test("should run getQuestionChainAnswerIfComplete", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ const testQuestion = {};
+ const testReturnedAnswer = "aReturnedAnswer";
+ wrapper.vm.getQuestionChainAnswerIfComplete = jest.fn();
+
+ //Act
+ wrapper.vm.handleAnswer(testQuestion, testReturnedAnswer);
+
+ //Assert
+ expect(wrapper.vm.getQuestionChainAnswerIfComplete).toBeCalled();
+ });
+
+ test("should emit update:modelValue if returnedAnswer contains 'answer'", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ const testQuestion = {};
+ const testReturnedAnswer = "1|answer|DB10840|No";
+
+ //Act
+ wrapper.vm.handleAnswer(testQuestion, testReturnedAnswer);
+
+ //Assert
+ expect(wrapper.emitted()).toHaveProperty("update:modelValue");
+ expect(wrapper.emitted()["update:modelValue"][0][0]).toMatchObject({
+ answerResult: "DB10840",
+ });
+ });
+
+ test("should NOT emit update:modelValue if no returnedAnswer", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ const testQuestion = {};
+
+ //Act
+ wrapper.vm.handleAnswer(testQuestion);
+
+ //Assert
+ expect(wrapper.emitted()).not.toHaveProperty("update:modelValue");
+ });
+
+ test("should NOT emit update:modelValue if returnedAnswer contains 'nextQuestion'", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ const testQuestion = {};
+ const testReturnedAnswer = "1|nextQuestion|DB10840|No";
+
+ //Act
+ wrapper.vm.handleAnswer(testQuestion, testReturnedAnswer);
+
+ //Assert
+ expect(wrapper.emitted()).not.toHaveProperty("update:modelValue");
+ });
+ });
+
+ describe("method getQuestionChainAnswerIfComplete...", () => {
+ test("should return false if no returned answer", () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ const result = wrapper.vm.getQuestionChainAnswerIfComplete();
+
+ //Assert
+ expect(result).toBeFalsy();
+ });
+
+ test("should set the answerSelected to match the answered one", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ const testReturnedAnswer = "1|answer|DB10840|No";
+ await wrapper.setData({
+ questionData: [
+ {
+ questionSequence: 1,
+ questionText: "Question here?",
+ answers: [
+ {
+ answerResult: "DB09410",
+ answerText: "Yes",
+ nextQuestionSequence: null,
+ },
+ {
+ answerResult: "DB10840",
+ answerText: "No",
+ nextQuestionSequence: null,
+ },
+ ],
+ },
+ ],
+ });
+
+ //Act
+ wrapper.vm.getQuestionChainAnswerIfComplete(testReturnedAnswer);
+
+ //Assert
+ expect(wrapper.vm.questions[0].answerSelected).toBe("1|answer|DB10840|No");
+ });
+
+ test("should remove answers of questions after the answered one", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ const testReturnedAnswer = "1|answer|DB10840|No";
+ await wrapper.setData({
+ questionData: [
+ {
+ questionSequence: 1,
+ questionText: "Question here?",
+ answers: [
+ {
+ answerResult: "DB09410",
+ answerText: "Yes",
+ nextQuestionSequence: null,
+ },
+ {
+ answerResult: "DB10840",
+ answerText: "No",
+ nextQuestionSequence: null,
+ },
+ ],
+ },
+ {
+ questionSequence: 2,
+ questionText: "Question 2",
+ answers: [
+ {
+ answerResult: "2-yes",
+ answerText: "Yes",
+ nextQuestionSequence: null,
+ },
+ {
+ answerResult: "2-no",
+ answerText: "No",
+ nextQuestionSequence: null,
+ },
+ ],
+ answerSelected: "previously selected answer",
+ },
+ ],
+ });
+
+ //Act
+ wrapper.vm.getQuestionChainAnswerIfComplete(testReturnedAnswer);
+
+ //Assert
+ expect(wrapper.vm.questions[1].answerSelected).toBeUndefined;
+ });
+
+ test("should return false if returnedAnswer is a nextQuestion (not a final answer)", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ const testReturnedAnswer = "1|nextQuestion|DB10840|No";
+
+ //Act
+ const result = wrapper.vm.getQuestionChainAnswerIfComplete(testReturnedAnswer);
+
+ //Assert
+ expect(result).toBeFalsy();
+ });
+
+ test("should trigger scroll to .current-question if returnedAnswer is a nextQuestion (not a final answer)", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ const testReturnedAnswer = "1|nextQuestion|DB10840|No";
+
+ //Act
+ wrapper.vm.getQuestionChainAnswerIfComplete(testReturnedAnswer);
+
+ await nextTick();
+
+ //Assert
+ expect(Element.prototype.scrollIntoView).toHaveBeenCalled();
+ });
+
+ test("should return answer object if returnedAnswer is a final matching answer", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({});
+ const testReturnedAnswer = "1|answer|DB10840|No";
+ await wrapper.setData({
+ questions: [
+ {
+ questionSequence: 1,
+ questionText: "Question here?",
+ answers: [
+ {
+ answerResult: "DB09410",
+ answerText: "Yes",
+ nextQuestionSequence: null,
+ },
+ {
+ answerResult: "DB10840",
+ answerText: "No",
+ nextQuestionSequence: null,
+ },
+ ],
+ },
+ ],
+ index: 0,
+ });
+
+ //Act
+ const result = wrapper.vm.getQuestionChainAnswerIfComplete(testReturnedAnswer);
+
+ //Assert
+ expect(result).toMatchObject({
+ answerResult: "DB10840",
+ answeredQuestions: [
+ { questionNum: 1, questionText: "Question here?", selectedAnswerText: "No" },
+ {
+ questionNum: 1,
+ questionText: "Does only your center sliding piece need to be replaced?",
+ selectedAnswerText: "No",
+ },
+ ],
+ index: 0,
+ });
+ });
+ });
+});
+
+function setupMocks({
+ questionDataProp = [
+ {
+ questionSequence: 1,
+ questionText: "Does only your center sliding piece need to be replaced?",
+ answers: [
+ {
+ answerResult: "DB09410",
+ answerText: "Yes",
+ nextQuestionSequence: null,
+ },
+ {
+ answerResult: "DB10840",
+ answerText: "No",
+ nextQuestionSequence: null,
+ },
+ ],
+ },
+ ],
+}) {
+ Element.prototype.scrollIntoView = jest.fn();
+
+ const mountOptions = getMountOptions({});
+ mountOptions.propsData = {
+ questionData: questionDataProp,
+ };
+ mountOptions["attachTo"] = document.body;
+
+ const wrapper = shallowMount(questionChain, mountOptions);
+
+ return { wrapper };
+}
diff --git a/src/common-components/question-chain/question-chain.spec.js1 b/src/common-components/question-chain/question-chain.spec.js1
deleted file mode 100644
index 84795fac0..000000000
--- a/src/common-components/question-chain/question-chain.spec.js1
+++ /dev/null
@@ -1,241 +0,0 @@
-import { shallowMount } from "@vue/test-utils";
-import questionChain from "@/common-components/question-chain/question-chain.vue";
-import { getMountOptions } from "@/helpers/unit-test-helper.js";
-import store from "@/store";
-jest.mock("@/store",()=>{return{};},{virtual:true});
-
-describe("Question Chain component", () => {
-
- it("Should not emit a modelValue change when setting selectedValue if isNewModelValueComplete is false", () => {
-
- //Arrange
- const { wrapper } = setupMocks({ modelValueProp: [] });
- wrapper.vm.currentQuestion = 6;
- const answerReturned = [wrapper.vm.questions[wrapper.vm.currentQuestion].answers[0].Name.toString()];
- const localThis = {
- $emit: jest.fn(),
- getNewModelValue: jest.fn(() => { return false })
- }
-
- //Act
- questionChain.computed.selectedValue.set.call(localThis, answerReturned);
-
- //Assert
- expect(localThis.$emit).not.toBeCalled();
- });
-
- it("Should emit a modelValue change when setting selectedValue if isNewModelValueComplete is true", () => {
-
- //Arrange
- const { wrapper } = setupMocks({ modelValueProp: [] });
- wrapper.vm.currentQuestion = 6;
- const answerReturned = [wrapper.vm.questions[wrapper.vm.currentQuestion].answers[0].Name.toString()];
- const localThis = {
- $emit: jest.fn(),
- getNewModelValue: jest.fn(() => { return true })
- }
-
- //Act
- questionChain.computed.selectedValue.set.call(localThis, answerReturned);
-
- //Assert
- expect(localThis.$emit).toBeCalledWith("update:modelValue", true);
- });
-
- it("should return false if no returned answer is given", () => {
-
- //Arrange
- const { wrapper } = setupMocks({ modelValueProp: [] });
- wrapper.vm.currentQuestion = 1;
- const answerReturned = null;
-
- //Act
- const result = wrapper.vm.getNewModelValue(answerReturned);
-
- //Assert
- expect(result).toEqual(false);
- });
-
- it("should return false if the user's answer on the current question leads to another question", () => {
-
- //Arrange
- const { wrapper } = setupMocks({ modelValueProp: [] });
- wrapper.vm.currentQuestion = 1;
- const answerReturned = [wrapper.vm.questions[wrapper.vm.currentQuestion].answers[0].Name.toString()];
-
- //Act
- const result = wrapper.vm.getNewModelValue(answerReturned);
-
- //Assert
- expect(result).toEqual(false);
- });
-
- it("should return an object with the final answer if the user's answer on the current question is a part number", () => {
-
- //Arrange
- const { wrapper } = setupMocks({ modelValueProp: [] });
- wrapper.vm.currentQuestion = 6;
- const answerReturned = [wrapper.vm.questions[wrapper.vm.currentQuestion].answers[0].Name.toString()];
-
- //Act
- const result = wrapper.vm.getNewModelValue(answerReturned);
-
- //Assert
- expect(result).toEqual(
- {
- answerResult: 'DW02102',
- answeredQuestions: [
- {
- questionText: 'Is your vehicle equipped with heated seats?',
- selectedAnswerText: 'Yes'
- }
- ]
- }
- );
-
- });
-
-});
-
-function setupMocks({
- modelValueProp = "",
- questionDataProp = {
- "glassName": "Single",
- "glassLocation": "Windshield",
- "parts": null,
- "partQuestions": [
- {
- "questionSequence": 1,
- "questionText": "Is your Cherokee the Overland edition which can be identified by having a wood and leather wrapped steering wheel?",
- "answers": [
- {
- "answerText": "Yes",
- "nextQuestionSequence": 2,
- "answerResult": ""
- },
- {
- "answerText": "No",
- "nextQuestionSequence": 3,
- "answerResult": ""
- }
- ]
- },
- {
- "questionSequence": 2,
- "questionText": "Is your vehicle equipped with rain sensing wipers that adjust their speed automatically when it rains?",
- "answers": [
- {
- "answerText": "Yes",
- "nextQuestionSequence": null,
- "answerResult": "DW02270"
- },
- {
- "answerText": "No",
- "nextQuestionSequence": null,
- "answerResult": "DW02264"
- }
- ]
- },
- {
- "questionSequence": 3,
- "questionText": "Is your vehicle equipped with rain sensing wipers that adjust their speed automatically when it rains?",
- "answers": [
- {
- "answerText": "Yes",
- "nextQuestionSequence": null,
- "answerResult": "DW02268"
- },
- {
- "answerText": "No",
- "nextQuestionSequence": 4,
- "answerResult": ""
- }
- ]
- },
- {
- "questionSequence": 4,
- "questionText": "Is your vehicle equipped with automatic climate control which will change the fan speed automatically in order to maintain a set temperature?",
- "answers": [
- {
- "answerText": "Yes",
- "nextQuestionSequence": 5,
- "answerResult": ""
- },
- {
- "answerText": "No",
- "nextQuestionSequence": 6,
- "answerResult": ""
- }
- ]
- },
- {
- "questionSequence": 5,
- "questionText": "Is your vehicle equipped with heated seats?",
- "answers": [
- {
- "answerText": "Yes",
- "nextQuestionSequence": null,
- "answerResult": "DW02104"
- },
- {
- "answerText": "No",
- "nextQuestionSequence": null,
- "answerResult": "DW02103"
- }
- ]
- },
- {
- "questionSequence": 6,
- "questionText": "Is your vehicle equipped with heated seats?",
- "answers": [
- {
- "answerText": "Yes",
- "nextQuestionSequence": null,
- "answerResult": "DW02102"
- },
- {
- "answerText": "No",
- "nextQuestionSequence": null,
- "answerResult": "DW02101"
- }
- ]
- }
- ],
- },
- methodsToMock = [],
-}) {
-
- //Mock store
- store.dispatch = jest.fn(() => dataFromStoreApi);
- store.getters = { vehicle: {year: 2019, make: 'honda', model: 'civc', style: '2 Door', category: 'CAR'} };
- const mountOptions = getMountOptions({
- store: {
- dispatch: store.dispatch,
- getters: store.getters,
- },
- });
-
- //Mock props
- const mockMixin = {
- methods: {
- getCmsContent: jest.fn()
- }
- }
- mountOptions.propsData = {
- modelValue: modelValueProp,
- questionData: questionDataProp,
- };
- mountOptions.mixins = [mockMixin];
-
- //Mock methods
- methodsToMock.forEach((methodName) => {
- questionChain.methods[methodName] = jest.fn();
- });
-
- const wrapper = shallowMount(questionChain, mountOptions);
-
- //Mock CMS content
- const cmsContent = {
- };
- return { wrapper, cmsContent };
-}
\ No newline at end of file
diff --git a/src/common-components/question-chain/question-chain.vue b/src/common-components/question-chain/question-chain.vue
index 432fd2eca..11874670b 100644
--- a/src/common-components/question-chain/question-chain.vue
+++ b/src/common-components/question-chain/question-chain.vue
@@ -29,7 +29,7 @@ export default {
};
},
props: {
- questionData: Object,
+ questionData: Array,
validationRules: String,
modelValue: Object,
index: Number,
@@ -84,11 +84,7 @@ export default {
handleAnswer(question, returnedAnswer) {
/*
returnedAnswer example format:
- {
- "checkValue": "1|answer|DD11132|Yes",
- "value": "1|answer|DD11132|Yes",
- "buttonId": "Driver-Front-1-1|answer|DD11132|Yes"
- }
+ "1|answer|DD11132|Yes"
*/
question.answerSelected = returnedAnswer;
diff --git a/src/common-components/textbox-question/textbox-question.vue b/src/common-components/textbox-question/textbox-question.vue
index 05d17dcd4..1fd8c3256 100644
--- a/src/common-components/textbox-question/textbox-question.vue
+++ b/src/common-components/textbox-question/textbox-question.vue
@@ -4,6 +4,7 @@
:for="inputId"
:aria-label="questionText"
class="form-label"
+ :class="[questionAlignment === 'center' ? 'text-center w-100 mb-5' : '']"
v-html="labelText">
{
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]: false,
@@ -43,6 +47,9 @@ describe("getPageToRouteExistingOrderTo", () => {
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,
@@ -62,6 +69,9 @@ describe("getPageToRouteExistingOrderTo", () => {
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,
@@ -82,6 +92,9 @@ describe("getPageToRouteExistingOrderTo", () => {
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,
@@ -103,6 +116,9 @@ describe("getPageToRouteExistingOrderTo", () => {
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,
@@ -125,6 +141,9 @@ describe("getPageToRouteExistingOrderTo", () => {
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,
@@ -152,6 +171,9 @@ describe("getPageToRouteExistingOrderTo", () => {
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,
@@ -179,6 +201,9 @@ describe("getPageToRouteExistingOrderTo", () => {
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,
@@ -206,6 +231,9 @@ describe("getPageToRouteExistingOrderTo", () => {
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,
@@ -233,6 +261,9 @@ describe("getPageToRouteExistingOrderTo", () => {
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,
@@ -260,6 +291,9 @@ describe("getPageToRouteExistingOrderTo", () => {
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,
@@ -289,6 +323,9 @@ describe("getPageToRouteExistingOrderTo", () => {
},
};
+ store.commit(storeMutations.UPDATE_IS_REPAIR, false);
+ store.commit(storeMutations.UPDATE_MAKE, "acura");
+
// Act
const result = await getPageToRouteExistingOrderTo(toRoute, true);
diff --git a/src/helpers/heritage-integration/order-helper.js b/src/helpers/heritage-integration/order-helper.js
index a18cf74bb..9a24e9c24 100644
--- a/src/helpers/heritage-integration/order-helper.js
+++ b/src/helpers/heritage-integration/order-helper.js
@@ -17,12 +17,8 @@ import { storeMutations } from "@/constants/store-mutations";
export async function loadSessionIfPresent() {
const funnelCookie = getFunnelCookie();
- // Do nothing if there is no cookie, correlation id, or referral number.
- if (
- funnelCookie == null ||
- funnelCookie.ReferralCorrelationId == null ||
- !funnelCookie.ReferralNumber
- ) {
+ // Do nothing if there is no cookie or session to use for loading.
+ if (funnelCookie == null || funnelCookie.SavedSessionId == null) {
return null;
}
@@ -33,15 +29,8 @@ export async function loadSessionIfPresent() {
return null;
}
- // Load referral if there is a cookie, and it doesn't indicate it needs a state reset.
- return (
- await loadSession(
- funnelCookie.ReferralNumber,
- funnelCookie.ReferralDate,
- funnelCookie.ReferralCorrelationId,
- funnelCookie.ReferralParentAccountNumber,
- )
- ).data;
+ // Loads session including referral if there is a cookie, and it doesn't indicate it needs a state reset.
+ return (await loadSession(funnelCookie.SavedSessionId)).data;
}
/*
@@ -72,16 +61,13 @@ export async function saveSession() {
Calls API to load session given the referral number, referralDate, and referralCorrelationId
and returns the response.
*/
-async function loadSession(referralNumber, referralDate, referralCorrelationId, accountNumber) {
+async function loadSession(savedSessionId) {
// await the saveSessionPromise in the store to make sure we're loading up to date information
await store.getters.applicationUser.saveSessionPromise;
const response = await baseMixin.methods.dispatchStoreAction(
storeActions.LOAD_SESSION,
{
- referralNumber: referralNumber.toString(),
- referralDate: referralDate,
- referralCorrelationId: referralCorrelationId,
- accountNumber: accountNumber?.toString(),
+ savedSessionId: savedSessionId?.toString(),
},
false
);
diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js
index 5ec0f4f69..74c911e05 100644
--- a/src/helpers/heritage-integration/order-helper.spec.js
+++ b/src/helpers/heritage-integration/order-helper.spec.js
@@ -24,6 +24,7 @@ describe("loadSessionIfPresent", () => {
ShouldResetState: testShouldResetState,
ReferralCorrelationId: "xxx",
ReferralNumber: "12345",
+ SavedSessionId: "aa115a05-e268-4eb4-a095-1d54b44f4a99",
};
document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}=${JSON.stringify(
@@ -46,6 +47,7 @@ describe("loadSessionIfPresent", () => {
ShouldResetState: true,
ReferralCorrelationId: "xxx-xxx-xxx",
ReferralNumber: "12345",
+ SavedSessionId: "aa115a05-e268-4eb4-a095-1d54b44f4a99",
});
const mockData = {
@@ -103,6 +105,7 @@ describe("loadSessionIfPresent", () => {
ReferralNumber: 123456,
ReferralCorrelationId: "yyy-yyy-yyyy",
ReferralDate: new Date(),
+ SavedSessionId: "aa115a05-e268-4eb4-a095-1d54b44f4a99",
});
const mockData = {
diff --git a/src/layouts/address-lookup/address-lookup.spec.js b/src/layouts/address-lookup/address-lookup.spec.js
index 21ac345ee..bc9839803 100644
--- a/src/layouts/address-lookup/address-lookup.spec.js
+++ b/src/layouts/address-lookup/address-lookup.spec.js
@@ -292,7 +292,7 @@ describe("address-lookup.vue", () => {
// Assert
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(
- navigationScenarios.CONTINUING_WITH_MULTIPLE_VEHICLES,
+ navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES,
undefined,
{},
{},
@@ -381,7 +381,7 @@ describe("address-lookup.vue", () => {
// Assert
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(
- navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS,
+ navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
undefined,
{},
{ displayVehicleChangeAlert: true }
diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue
index 17d7012f1..d7ced0576 100644
--- a/src/layouts/address-lookup/address-lookup.vue
+++ b/src/layouts/address-lookup/address-lookup.vue
@@ -364,7 +364,7 @@ export default {
matchingCars.length === 1
) {
this.$router.navigateWithSaving(
- this.navigationScenarios.SELECTED_VIN_HAS_MISMATCHED_GLASS,
+ this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
this.$route,
{},
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
@@ -373,7 +373,7 @@ export default {
await this.navigateForwardWithSingleCarMatch();
} else {
this.$router.navigateWithSaving(
- this.navigationScenarios.CONTINUING_WITH_MULTIPLE_VEHICLES,
+ this.navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES,
this.$route,
{},
{},
diff --git a/src/layouts/capability-questions/capability-questions.spec.js b/src/layouts/capability-questions/capability-questions.spec.js
new file mode 100644
index 000000000..c59857182
--- /dev/null
+++ b/src/layouts/capability-questions/capability-questions.spec.js
@@ -0,0 +1,404 @@
+// Components
+import capabilityQuestions from "@/layouts/capability-questions/capability-questions";
+
+// Supporting Files
+import { shallowMount } from "@vue/test-utils";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+import store 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(),
+}));
+
+jest.mock(
+ "@/store",
+ () => {
+ return {};
+ },
+ { virtual: true }
+);
+
+jest.mock("@/helpers/heritage-integration/navigation-helper", () => ({
+ navigateToHeritageFunnel: jest.fn(),
+}));
+
+const baseStoreGettersPageData = () => {
+ return {
+ partsOrQuestions: [
+ {
+ parts: [
+ {
+ childPartQuestions: [],
+ },
+ ],
+ capabilityQuestions: [
+ {
+ questionSequence: 1,
+ questionText:
+ "Is your vehicle equipped with the optional Lane-Keeping System which tugs on the steering wheel and/or beeps to alert you if you drift too close to the edge of the lane?",
+ answers: [
+ {
+ answerResult1: "DYNAMIC",
+ answerResult2: "1",
+ answerText: "Yes",
+ nextQuestionSequence: null,
+ answerResult: "DYNAMIC",
+ },
+ {
+ answerResult1: "Unknown",
+ answerResult2: "0",
+ answerText: "No",
+ nextQuestionSequence: null,
+ answerResult: "Unknown",
+ },
+ ],
+ },
+ ],
+ partQuestions: [],
+ questions: [],
+ 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,
+ },
+ ],
+ },
+ ],
+ };
+};
+store.getters = {
+ pageData: baseStoreGettersPageData,
+ damage: baseStoreGettersDamage,
+};
+store.commit = jest.fn();
+
+afterEach(() => {
+ // reset store after each test
+ store.getters = {
+ pageData: baseStoreGettersPageData,
+ damage: baseStoreGettersDamage,
+ };
+});
+
+describe("capabilityQuestions.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({});
+ store.getters.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
+ store.getters = {
+ pageData: jest.fn(() => {
+ return {
+ partsOrQuestions: [],
+ };
+ }),
+ 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
+ const { wrapper } = setupMocks({});
+ const spy = jest.spyOn(wrapper.vm, "handleAnswerUpdates");
+
+ // Act
+ wrapper.setData({
+ selectedAnswers: {
+ "Windshield-Single": {
+ 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?",
+ 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,
+ },
+ ],
+ index: 0,
+ },
+ },
+ });
+
+ await nextTick();
+
+ //Assert
+ expect(spy).toHaveBeenCalled();
+
+ wrapper.unmount();
+ });
+ });
+
+ describe("forwardButtonAction", () => {
+ test("Should clear out answerData", () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+
+ wrapper.vm.questionsData = [
+ {
+ glassLocation: "Windshield",
+ glassName: "Single",
+ answerData: {
+ answerResult: "FW04848",
+ answeredQuestions: [],
+ },
+ questions: [],
+ parts: [
+ {
+ childPartQuestions: [{}],
+ },
+ ],
+ },
+ ];
+ wrapper.vm.dispatchStoreAction = jest.fn(() => {
+ return {
+ data: [],
+ };
+ });
+
+ // Act
+ wrapper.vm.forwardButtonAction();
+
+ //Assert
+ expect(wrapper.vm.questionsData[0].answerData).toEqual({});
+
+ wrapper.unmount();
+ });
+
+ test("Should save to Vuex store", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+
+ wrapper.vm.questionsData = [
+ {
+ glassLocation: "Windshield",
+ glassName: "Single",
+ answerData: {
+ answerResult: "FW04848",
+ answeredQuestions: [],
+ },
+ questions: [],
+ parts: [
+ {
+ childPartQuestions: [],
+ },
+ ],
+ },
+ ];
+ wrapper.vm.dispatchStoreAction = jest.fn(() => {
+ return {
+ data: [],
+ };
+ });
+ const spy = jest.spyOn(wrapper.vm, "dispatchStoreAction");
+
+ // Act
+ wrapper.vm.forwardButtonAction();
+
+ await nextTick();
+
+ //Assert
+ expect(spy).toHaveBeenNthCalledWith(
+ 1,
+ "saveCapabilityQuestionAnswers",
+ [
+ {
+ answeredQuestions: [],
+ glassLocation: "Windshield",
+ glassName: "Single",
+ isSuppressedPart: undefined,
+ result: "FW04848",
+ result1: "FW04848",
+ result2: undefined,
+ },
+ ],
+ false
+ );
+
+ wrapper.unmount();
+ });
+
+ test("Should call GET_PART_FROM_CAPABILITY_QUESTION_ANSWER API", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+
+ wrapper.vm.questionsData = [
+ {
+ glassLocation: "Windshield",
+ glassName: "Single",
+ answerData: {
+ answerResult: "FW04848",
+ answeredQuestions: [],
+ },
+ questions: [],
+ parts: [
+ {
+ childPartQuestions: [],
+ },
+ ],
+ },
+ ];
+ wrapper.vm.dispatchStoreAction = jest.fn(() => {
+ return {
+ data: [],
+ };
+ });
+ const spy = jest.spyOn(wrapper.vm, "dispatchStoreAction");
+
+ // Act
+ wrapper.vm.forwardButtonAction();
+
+ await nextTick();
+
+ //Assert
+ expect(spy).toHaveBeenNthCalledWith(
+ 2,
+ "getPartFromCapabilityQuestionAnswer",
+ "Windshield",
+ false
+ );
+
+ wrapper.unmount();
+ });
+
+ test("Should trigger navigateForward", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+
+ wrapper.vm.questionsData = [
+ {
+ glassLocation: "Windshield",
+ glassName: "Single",
+ answerData: {
+ answerResult: "FW04848",
+ answeredQuestions: [],
+ },
+ questions: [],
+ parts: [
+ {
+ childPartQuestions: [],
+ },
+ ],
+ },
+ ];
+ wrapper.vm.dispatchStoreAction = jest.fn(() => {
+ return {
+ data: [],
+ };
+ });
+ 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(),
+ },
+ store: {
+ getters: store.getters,
+ commit: store.commit,
+ },
+ route: {
+ query: {
+ fmgPage: "capability-questions",
+ },
+ },
+ },
+}) {
+ const mountOptions = getMountOptions({
+ ...mountOptionsMockData,
+ mixins: [baseMixin, vehicleQuestionsMixin],
+ });
+ mountOptions["attachTo"] = document.body;
+
+ const wrapper = shallowMount(capabilityQuestions, mountOptions);
+
+ return { wrapper };
+}
diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue
index 7415ac000..c3122b9a3 100644
--- a/src/layouts/capability-questions/capability-questions.vue
+++ b/src/layouts/capability-questions/capability-questions.vue
@@ -6,17 +6,17 @@
:alertFewMoreQuestionsHeader="AlertFewMoreQuestionsHeader"
:alertFewMoreQuestionsCopy="AlertFewMoreQuestionsCopy"
:questionsData="questionsData"
- :validationRules="questions - required"
+ validationRules="questions-required"
v-model="selectedAnswers"
@forwardButtonAction="forwardButtonAction"
- @backButtonAction="backButtonAction"
+ @back-click="navigateBack"
:index="currentGlassIndex" />