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 00000000..0e488e9e --- /dev/null +++ b/src/layouts/capability-questions/capability-questions.spec.js @@ -0,0 +1,402 @@ +// 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 { 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: [ + { + 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?", + selectedAnswer: "1|nextQuestion|3|Yes", + selectedAnswerText: "Yes", + questionNum: 1, + }, + { + questionText: + "Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?", + selectedAnswer: "2|nextQuestion|3|Yes", + selectedAnswerText: "Yes", + questionNum: 2, + }, + ], + }, + ], + }; +}; +useMainStore().pageData = baseStoreGettersPageData; +useMainStore().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({}); + 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: + "Is your vehicle equipped with the Panoramic Sunroof which can be identified by having a glass panel over the rear seats?", + selectedAnswer: "1|nextQuestion|3|Yes", + selectedAnswerText: "Yes", + questionNum: 1, + }, + { + questionText: + "Is your vehicle equipped with a heated windshield that melts snow and ice from underneath the windshield wiper blades?", + selectedAnswer: "2|nextQuestion|3|Yes", + 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 pinia store", async () => { + // Arrange + const { wrapper } = setupMocks({}); + + wrapper.vm.questionsData = [ + { + glassLocation: "Windshield", + glassName: "Single", + answerData: { + answerResult: "FW04848", + answeredQuestions: [], + }, + questions: [], + parts: [ + { + childPartQuestions: [], + }, + ], + }, + ]; + useMainStore().getPartsOrQuestions = jest.fn(() => { + return { + data: { + partsOrQuestions: [], + }, + }; + }); + + // Act + wrapper.vm.forwardButtonAction(); + + await nextTick(); + + //Assert + expect(wrapper.vm.saveCapabilityQuestionAnswers).toHaveBeenCalled; + wrapper.unmount(); + }); + test("Should call GET_PARTS_OR_QUESTIONS API", async () => { + // Arrange + const { wrapper } = setupMocks({}); + + wrapper.vm.questionsData = [ + { + glassLocation: "Windshield", + glassName: "Single", + answerData: { + answerResult: "FW04848", + answeredQuestions: [], + }, + questions: [], + parts: [ + { + childPartQuestions: [], + }, + ], + }, + ]; + useMainStore().getPartsOrQuestions = jest.fn(() => { + return { + data: { + partsOrQuestions: [], + }, + }; + }); + + // Act + wrapper.vm.forwardButtonAction(); + + await nextTick(); + + //Assert + expect(wrapper.vm.getPartsOrQuestions).toHaveBeenCalled; + + 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: [], + }, + ], + }, + ]; + useMainStore().getPartsOrQuestions = jest.fn(() => { + return { + data: { + partsOrQuestions: [], + }, + }; + }); + 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(), + }, + actionList: [ + { + actionName: "saveCapabilityQuestionAnswers", + data: {}, + }, + { + actionName: "getPartsOrQuestions", + data: {}, + }, + ], + route: { + query: { + issPage: "capability-questions", + }, + }, + data() { + return { + computedSwitcher: [ + { + glassLocation: "Windshield", + glassName: "Single", + answerData: { + answerResult: "FW04848", + answeredQuestions: [], + }, + }, + ], + }; + }, + questionsData: { + get() { + return this.computedSwitcher; + }, + set(val) { + this.computedSwitcher = val; + }, + }, + }, +}) { + + useMainStore().getPartsOrQuestions = jest.fn(() => { + return { + data: { + partsOrQuestions: [], + } + }; + }); + const mountOptions = getMountOptions({ + ...mountOptionsMockData, + mixins: [baseMixin, vehicleQuestionsMixin], + }); + mountOptions["attachTo"] = document.body; + + const wrapper = shallowMount(capabilityQuestions, mountOptions); + + return { wrapper }; +} \ No newline at end of file diff --git a/src/layouts/capability-questions/capability-questions.vue b/src/layouts/capability-questions/capability-questions.vue index 23ba630f..0b5cca78 100644 --- a/src/layouts/capability-questions/capability-questions.vue +++ b/src/layouts/capability-questions/capability-questions.vue @@ -1,33 +1,21 @@ diff --git a/src/store/index.js b/src/store/index.js index c2b8142b..c500e8d5 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -395,7 +395,6 @@ export const useMainStore = defineStore({ endpoint: `${endpoints.GetCapabilityQuestions.url}/${carId}/${partNumber}`, }); }, - lookupVehicleByVin(vin) { return globalMethods.callHttpClient({ method: endpoints.LookupVehicleByVin.method, @@ -736,6 +735,29 @@ export const useMainStore = defineStore({ // Save new values this.updateMoldingQuestionAnswers(moldingQuestionAnswersArray); }, + saveCapabilityQuestionAnswers(capabilityQuestionAnswersArray) { + const sortedPreviousResultsArray = sortArrayOfObjectsByPropertyValue( + this.order.damage.capabilityQuestionAnswers, + "result" + ); + const sortedCapabilityQuestionAnswersArray = sortArrayOfObjectsByPropertyValue( + capabilityQuestionAnswersArray, + "result" + ); + const haveCapabilityQuestionAnswersChanged = + sortedPreviousResultsArray?.length !== sortedCapabilityQuestionAnswersArray.length || + !sortedPreviousResultsArray?.every( + (x, i) => x.result === sortedCapabilityQuestionAnswersArray[i].result + ); + + if (haveCapabilityQuestionAnswersChanged) { + this.updateGlassParts(null); + this.updateSupportingItems(null); + } + + // Save new values + this.updateCapabilityQuestionAnswers(capabilityQuestionAnswersArray); + }, addEventToBus (event) { this.applicationUser.eventBus.push(event);