From c1df7db2a4f4aff257e72fa4d411607ce0786acd Mon Sep 17 00:00:00 2001 From: FrankRua Date: Mon, 28 Feb 2022 14:36:56 -0500 Subject: [PATCH] Unit tests for vehicle-parts --- src/helpers/unit-test-helper.js | 4 + .../vehicle-damage/vehicle-damage.spec.js | 530 +++++++++--------- src/layouts/vehicle-damage/vehicle-damage.vue | 1 - .../glass-part-question.vue | 2 +- .../vehicle-parts/vehicle-parts.spec.js | 385 +++++++++++++ src/layouts/vehicle-parts/vehicle-parts.vue | 27 +- 6 files changed, 673 insertions(+), 276 deletions(-) create mode 100644 src/layouts/vehicle-parts/vehicle-parts.spec.js diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 225704aa1..52c0b5c6c 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -2,6 +2,7 @@ import { storeActions } from "@/constants/store-actions"; import { storeMutations } from "@/constants/store-mutations.js"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios.js"; import { vehicleCategories } from "@/constants/vehicle-categories.js"; +import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import baseMixin from "@/mixins/base-mixin"; export function getMountOptions(mockData) { @@ -40,10 +41,13 @@ export function getMountOptions(mockData) { mocks.storeMutations = storeMutations; mocks.navigationScenarios = navigationScenarios; mocks.vehicleCategories = vehicleCategories; + mocks.fmgPageValues = fmgPageValues; // Mock $store and $router when accessing this.$store/$router mocks.$store = mockData.store; mocks.$router = mockData.router; + mocks.$route = mockData.route; + const global = { mocks: mocks, diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js index d903349da..9145bad7c 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.spec.js +++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js @@ -41,214 +41,214 @@ jest.mock("@/store", () => ({ }, })); -// describe("vehicle-damage.vue", () => { -// test("Page header is initailized with api data", async (done) => { -// //Arrange -// const pageHeaderWidgetHeaderText = "Select Damage"; -// const { wrapper, apiPromise } = setupMocks({ -// pageHeaderWidgetHeaderText: pageHeaderWidgetHeaderText, -// }); +describe("vehicle-damage.vue", () => { + test("Page header is initailized with api data", async (done) => { + //Arrange + const pageHeaderWidgetHeaderText = "Select Damage"; + const { wrapper, apiPromise } = setupMocks({ + pageHeaderWidgetHeaderText: pageHeaderWidgetHeaderText, + }); -// //Act -// vehicleDamage.beforeRouteEnter.call( -// wrapper.vm, -// { query: { fmgPage: "vehicle-damage" } }, -// undefined, -// (c) => c(wrapper.vm) -// ); + //Act + vehicleDamage.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-damage" } }, + undefined, + (c) => c(wrapper.vm) + ); -// //Assert -// apiPromise.finally(() => { -// expect(funnelSubHeader.methods.initializeComponent).toHaveBeenCalledWith( -// pageHeaderWidgetHeaderText -// ); -// done(); -// }); -// }); -// }); + //Assert + apiPromise.finally(() => { + expect(funnelSubHeader.methods.initializeComponent).toHaveBeenCalledWith( + pageHeaderWidgetHeaderText + ); + done(); + }); + }); +}); -// describe("vehicle-damage.vue", () => { -// test("Page logo image is initailized with api data", async (done) => { -// //Arrange -// const SiteHeaderWidget = { -// LogoImage: -// "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3", -// }; -// const { wrapper, apiPromise } = setupMocks({ -// SiteHeaderWidget: SiteHeaderWidget, -// }); +describe("vehicle-damage.vue", () => { + test("Page logo image is initailized with api data", async (done) => { + //Arrange + const SiteHeaderWidget = { + LogoImage: + "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3", + }; + const { wrapper, apiPromise } = setupMocks({ + SiteHeaderWidget: SiteHeaderWidget, + }); -// //Act -// vehicleDamage.beforeRouteEnter.call( -// wrapper.vm, -// { query: { fmgPage: "vehicle-damage" } }, -// undefined, -// (c) => c(wrapper.vm) -// ); + //Act + vehicleDamage.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-damage" } }, + undefined, + (c) => c(wrapper.vm) + ); -// //Assert -// apiPromise.finally(() => { -// expect(funnelHeader.methods.initializeComponent).toHaveBeenCalledWith( -// SiteHeaderWidget -// ); -// done(); -// }); -// }); -// }); + //Assert + apiPromise.finally(() => { + expect(funnelHeader.methods.initializeComponent).toHaveBeenCalledWith( + SiteHeaderWidget + ); + done(); + }); + }); +}); -// describe("vehicle-damage.vue", () => { -// test("Vehicle image is initailized with api data", async (done) => { -// //Arrange -// const VehicleBannerWidget = { -// GenericVehicleImage: -// "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3", -// }; -// const { wrapper, apiPromise } = setupMocks({ -// VehicleBannerWidget: VehicleBannerWidget, -// }); +describe("vehicle-damage.vue", () => { + test("Vehicle image is initailized with api data", async (done) => { + //Arrange + const VehicleBannerWidget = { + GenericVehicleImage: + "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3", + }; + const { wrapper, apiPromise } = setupMocks({ + VehicleBannerWidget: VehicleBannerWidget, + }); -// //Act -// vehicleDamage.beforeRouteEnter.call( -// wrapper.vm, -// { query: { fmgPage: "vehicle-damage" } }, -// undefined, -// (c) => c(wrapper.vm) -// ); + //Act + vehicleDamage.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-damage" } }, + undefined, + (c) => c(wrapper.vm) + ); -// //Assert -// apiPromise.finally(() => { -// expect(vehicleBanner.methods.initializeComponent).toHaveBeenCalledWith( -// VehicleBannerWidget -// ); -// done(); -// }); -// }); -// }); + //Assert + apiPromise.finally(() => { + expect(vehicleBanner.methods.initializeComponent).toHaveBeenCalledWith( + VehicleBannerWidget + ); + done(); + }); + }); +}); -// describe("vehicle-damage.vue", () => { -// test("CarId set, arePagePrerequisitesValid should be true ", async () => { -// //Arrange -// const { wrapper } = setupMocks({}); +describe("vehicle-damage.vue", () => { + test("CarId set, arePagePrerequisitesValid should be true ", async () => { + //Arrange + const { wrapper } = setupMocks({}); -// //Act -// vehicleDamage.beforeRouteEnter.call( -// wrapper.vm, -// { query: { fmgPage: "vehicle-damage" } }, -// undefined, -// (c) => c(wrapper.vm) -// ); + //Act + vehicleDamage.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-damage" } }, + undefined, + (c) => c(wrapper.vm) + ); -// let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); -// await nextTick(); + let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); + await nextTick(); -// //Assert -// expect(arePagePrerequisitesValid).toBe(true); -// }); -// }); + //Assert + expect(arePagePrerequisitesValid).toBe(true); + }); +}); -// describe("vehicle-damage.vue", () => { -// test("Call invalidation, ResetPartsAndDeps should be called", async () => { +describe("vehicle-damage.vue", () => { + test("Call invalidation, ResetPartsAndDeps should be called", async () => { -// //Arrange -// const { wrapper } = setupMocks({}); + //Arrange + const { wrapper } = setupMocks({}); -// //Act -// vehicleDamage.beforeRouteEnter.call( -// wrapper.vm, -// { query: { fmgPage: "vehicle-damage" } }, -// undefined, -// (c) => c(wrapper.vm) -// ); + //Act + vehicleDamage.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-damage" } }, + undefined, + (c) => c(wrapper.vm) + ); -// wrapper.vm.resetDependentState(); + wrapper.vm.resetDependentState(); -// //Assert -// expect(store.dispatch).toBeCalledWith(storeActions.RESET_PARTS_AND_DEPS) + //Assert + expect(store.dispatch).toBeCalledWith(storeActions.RESET_PARTS_AND_DEPS) -// }); -// }); + }); +}); -// describe("vehicle-damage.vue", () => { -// test("BackButtonAction triggers a router.navigate change", async () => { +describe("vehicle-damage.vue", () => { + test("BackButtonAction triggers a router.navigate change", async () => { -// //Arrange -// const { wrapper } = setupMocks({}); + //Arrange + const { wrapper } = setupMocks({}); -// //Act -// vehicleDamage.beforeRouteEnter.call( -// wrapper.vm, -// { query: { fmgPage: "vehicle-damage" } }, -// undefined, -// (c) => c(wrapper.vm) -// ); + //Act + vehicleDamage.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-damage" } }, + undefined, + (c) => c(wrapper.vm) + ); -// wrapper.vm.backButtonAction(); + wrapper.vm.backButtonAction(); -// //Assert -// expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); + //Assert + expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); -// }); -// }); + }); +}); describe("vehicle-damage.vue", () => { test("ForwardButtonAction triggers a router.navigate change and saves selections to store", async () => { //Arrange - const partsData = { partsOrQuestions: [{ - glassName: "Single", - glassLocation: "Windshield", - parts: null, - partQuestions: [{ + const partsData = { + partsOrQuestions: [{ + glassName: "Single", + glassLocation: "Windshield", + parts: null, + partQuestions: [{ questionSequence: 1, questionText: "Is your vehicle equipped with a heated steering wheel?", answers: [{ - answerText: "Yes", - nextQuestionSequence: null, - answerResult: "FW04957" - }, - { - answerText: "No", - nextQuestionSequence: 2, - answerResult: "" - }]}, + answerText: "Yes", + nextQuestionSequence: null, + answerResult: "FW04957" + }, + { + answerText: "No", + nextQuestionSequence: 2, + answerResult: "" + }] + }, { questionSequence: 2, questionText: "Is your vehicle equipped with a remote start?", answers: [{ - answerText: "Yes", - nextQuestionSequence: null, - answerResult: "FW04181" - }, - { - answerText: "No", - nextQuestionSequence: null, - answerResult: "FW04179" - }]}]}]}; + answerText: "Yes", + nextQuestionSequence: null, + answerResult: "FW04181" + }, + { + answerText: "No", + nextQuestionSequence: null, + answerResult: "FW04179" + }] + }] + }] + }; const { wrapper } = setupMocks({ pageHeaderWidgetHeaderText: "", mountOptionsMockData: { router: { navigateAfterSave: jest.fn(), }, - actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },],}, + actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },], + }, }); - //jest.mock(storeActions.GET_PARTS_OR_QUESTIONS) - wrapper.vm.selectedWindshieldOptions = { - selectedWindshieldChipCount : null, - selectedWindshieldReplaceOptions : ["Single"], - // selectedDriverSideReplaceOptions: ["Back"], - // selectedPassengerSideReplaceOptions: ["Quarter"], + + wrapper.vm.selectedWindshieldOptions = { + selectedWindshieldChipCount: null, + selectedWindshieldReplaceOptions: ["Single"], selectedWindshieldDamageType: ["Replace"] }; - //wrapper.vm.selectedDamageLocations = ["Windshield", "SideDoor", "RearWindow"]; + wrapper.vm.selectedDamageLocations = ["Windshield"]; - //wrapper.vm.selectedRearReplaceOptions = ["Stationary"]; - // const expectedGlassToReplace = [{location: "Windshield", name: "Single"}, {location: "Driver", name: "Back"}, - // {location: "Passenger", name: "Quarter"}, {location: "Rear", name: "Stationary"}]; - - const expectedGlassToReplace = [{location: "Windshield", name: "Single"}]; + const expectedGlassToReplace = [{ location: "Windshield", name: "Single" }]; //Act vehicleDamage.beforeRouteEnter.call( @@ -259,7 +259,7 @@ describe("vehicle-damage.vue", () => { ); await wrapper.vm.forwardButtonAction(); - + //Assert expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled(); expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace); @@ -268,135 +268,135 @@ describe("vehicle-damage.vue", () => { }); }); -// describe("vehicle-damage.vue", () => { -// test("isWindshieldDamageLocation is true when windshield is selected", async () => { +describe("vehicle-damage.vue", () => { + test("isWindshieldDamageLocation is true when windshield is selected", async () => { -// //Arrange -// const { wrapper } = setupMocks({}); + //Arrange + const { wrapper } = setupMocks({}); -// //Act -// vehicleDamage.beforeRouteEnter.call( -// wrapper.vm, -// { query: { fmgPage: "vehicle-damage" } }, -// undefined, -// (c) => c(wrapper.vm) -// ); + //Act + vehicleDamage.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-damage" } }, + undefined, + (c) => c(wrapper.vm) + ); -// wrapper.vm.selectedDamageLocations = ["Windshield"]; + wrapper.vm.selectedDamageLocations = ["Windshield"]; -// //Assert -// expect(wrapper.vm.isWindshieldDamageLocation).toEqual(true); -// }); -// }); + //Assert + expect(wrapper.vm.isWindshieldDamageLocation).toEqual(true); + }); +}); -// describe("vehicle-damage.vue", () => { -// test("isSideDoorDamageLocation is true Side door is selected", async () => { +describe("vehicle-damage.vue", () => { + test("isSideDoorDamageLocation is true Side door is selected", async () => { -// //Arrange -// const { wrapper } = setupMocks({}); + //Arrange + const { wrapper } = setupMocks({}); -// //Act -// vehicleDamage.beforeRouteEnter.call( -// wrapper.vm, -// { query: { fmgPage: "vehicle-damage" } }, -// undefined, -// (c) => c(wrapper.vm) -// ); + //Act + vehicleDamage.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-damage" } }, + undefined, + (c) => c(wrapper.vm) + ); -// wrapper.vm.selectedDamageLocations = ["Sidedoor"]; + wrapper.vm.selectedDamageLocations = ["Sidedoor"]; -// //Assert -// expect(wrapper.vm.isSideDoorDamageLocation).toEqual(true); -// }); -// }); + //Assert + expect(wrapper.vm.isSideDoorDamageLocation).toEqual(true); + }); +}); -// describe("vehicle-damage.vue", () => { -// test("isRearWindowDamageLocation is true if Rear Window damage is selected", async () => { +describe("vehicle-damage.vue", () => { + test("isRearWindowDamageLocation is true if Rear Window damage is selected", async () => { -// //Arrange -// const { wrapper } = setupMocks({}); + //Arrange + const { wrapper } = setupMocks({}); -// //Act -// vehicleDamage.beforeRouteEnter.call( -// wrapper.vm, -// { query: { fmgPage: "vehicle-damage" } }, -// undefined, -// (c) => c(wrapper.vm) -// ); + //Act + vehicleDamage.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-damage" } }, + undefined, + (c) => c(wrapper.vm) + ); -// wrapper.vm.selectedDamageLocations = ["RearWindow"]; + wrapper.vm.selectedDamageLocations = ["RearWindow"]; -// //Assert -// expect(wrapper.vm.isRearWindowDamageLocation).toEqual(true); -// }); -// }); + //Assert + expect(wrapper.vm.isRearWindowDamageLocation).toEqual(true); + }); +}); -// describe("vehicle-damage.vue", () => { -// test("isWindshieldRepair is true if windshield repair is selected", async () => { +describe("vehicle-damage.vue", () => { + test("isWindshieldRepair is true if windshield repair is selected", async () => { -// //Arrange -// const { wrapper } = setupMocks({}); + //Arrange + const { wrapper } = setupMocks({}); -// //Act -// vehicleDamage.beforeRouteEnter.call( -// wrapper.vm, -// { query: { fmgPage: "vehicle-damage" } }, -// undefined, -// (c) => c(wrapper.vm) -// ); + //Act + vehicleDamage.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-damage" } }, + undefined, + (c) => c(wrapper.vm) + ); -// wrapper.vm.selectedDamageLocations = ["Windshield"]; -// wrapper.vm.selectedWindshieldOptions = { selectedWindshieldDamageType: ["Repair"]}; + wrapper.vm.selectedDamageLocations = ["Windshield"]; + wrapper.vm.selectedWindshieldOptions = { selectedWindshieldDamageType: ["Repair"] }; -// //Assert -// expect(wrapper.vm.isWindshieldRepair).toEqual(true); -// }); -// }); + //Assert + expect(wrapper.vm.isWindshieldRepair).toEqual(true); + }); +}); -// describe("vehicle-damage.vue", () => { -// test("isDriverSideReplace is true if side door driver is selected", async () => { +describe("vehicle-damage.vue", () => { + test("isDriverSideReplace is true if side door driver is selected", async () => { -// //Arrange -// const { wrapper } = setupMocks({}); + //Arrange + const { wrapper } = setupMocks({}); -// //Act -// vehicleDamage.beforeRouteEnter.call( -// wrapper.vm, -// { query: { fmgPage: "vehicle-damage" } }, -// undefined, -// (c) => c(wrapper.vm) -// ); + //Act + vehicleDamage.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-damage" } }, + undefined, + (c) => c(wrapper.vm) + ); -// wrapper.vm.selectedDamageLocations = ["Sidedoor"]; -// wrapper.vm.sideDoorOptionsData = { selectedDoorSides: ["DriverSide"]}; + wrapper.vm.selectedDamageLocations = ["Sidedoor"]; + wrapper.vm.sideDoorOptionsData = { selectedDoorSides: ["DriverSide"] }; -// //Assert -// expect(wrapper.vm.isDriverSideReplace).toEqual(true); -// }); -// }); + //Assert + expect(wrapper.vm.isDriverSideReplace).toEqual(true); + }); +}); -// describe("vehicle-damage.vue", () => { -// test("isPassengerSideReplace is true if side door passenger selected", async () => { +describe("vehicle-damage.vue", () => { + test("isPassengerSideReplace is true if side door passenger selected", async () => { -// //Arrange -// const { wrapper } = setupMocks({}); + //Arrange + const { wrapper } = setupMocks({}); -// //Act -// vehicleDamage.beforeRouteEnter.call( -// wrapper.vm, -// { query: { fmgPage: "vehicle-damage" } }, -// undefined, -// (c) => c(wrapper.vm) -// ); + //Act + vehicleDamage.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-damage" } }, + undefined, + (c) => c(wrapper.vm) + ); -// wrapper.vm.selectedDamageLocations = ["Sidedoor"]; -// wrapper.vm.sideDoorOptionsData = { selectedDoorSides: ["PassengerSide"]}; + wrapper.vm.selectedDamageLocations = ["Sidedoor"]; + wrapper.vm.sideDoorOptionsData = { selectedDoorSides: ["PassengerSide"] }; -// //Assert -// expect(wrapper.vm.isPassengerSideReplace).toEqual(true); -// }); -// }); + //Assert + expect(wrapper.vm.isPassengerSideReplace).toEqual(true); + }); +}); describe("vehicle-damage.vue", () => { test("Call invalidation, ResetPartsAndDeps should be called", async () => { @@ -509,14 +509,14 @@ function setupMocks({ const sideDoorOptionsWrapper = wrapper.findComponent({ name: "sideDoorOptions" }); sideDoorOptionsWrapper.vm.initializeComponent = - sideDoorOptions.methods.initializeComponent; + sideDoorOptions.methods.initializeComponent; const windshieldOptionsWrapper = wrapper.findComponent({ name: "windshieldOptions", }); - + windshieldOptionsWrapper.vm.initializeComponent = - windshieldOptions.methods.initializeComponent; + windshieldOptions.methods.initializeComponent; const funnelSubHeaderWrapper = wrapper.findComponent({ name: "funnelSubHeader", @@ -528,13 +528,13 @@ function setupMocks({ name: "replaceOptionsQuestion", }); backGlassOptionsWrapper.vm.initializeComponent = - replaceOptionsQuestion.methods.initializeComponent; + replaceOptionsQuestion.methods.initializeComponent; const damageLocationQuestionWrapper = wrapper.findComponent({ name: "damageLocationQuestion", }); damageLocationQuestionWrapper.vm.initializeComponent = - damageLocationQuestion.methods.initializeComponent; + damageLocationQuestion.methods.initializeComponent; const funnelFooterWrapper = wrapper.findComponent({ name: "funnelFooter", diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index ce92b6682..8db230860 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -120,7 +120,6 @@ export default { return store.getters.vehicle.carId !== null; }, resetDependentState() { - // Invokes store.dispatch(storeActions.RESET_PARTS_STATE); }, backButtonAction() { diff --git a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue index f5f5cdaa0..83e12a083 100644 --- a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue +++ b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue @@ -103,7 +103,7 @@ export default { } }, methods: { - initializeComponent(cmsContent, initialData) { + initializeComponent(cmsContent) { this.glassColorQuestion = cmsContent.ColorQuestionWidget.QuestionText; this.glassFeatureQuestion = cmsContent.FeatureQuestionWidget.QuestionText; }, diff --git a/src/layouts/vehicle-parts/vehicle-parts.spec.js b/src/layouts/vehicle-parts/vehicle-parts.spec.js new file mode 100644 index 000000000..b52be441b --- /dev/null +++ b/src/layouts/vehicle-parts/vehicle-parts.spec.js @@ -0,0 +1,385 @@ +// Components +import vehicleParts from "@/layouts/vehicle-parts/vehicle-parts.vue"; +import funnelHeader from "@/common-components/funnel-header/funnel-header"; +import funnelFooter from "@/common-components/funnel-footer/funnel-footer"; +import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner"; +import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header"; +import glassPartQuestion from "@/layouts/vehicle-parts/glass-part-question/glass-part-question"; + +// Supporting Files +import { settleAllPromises } from "@/helpers/layout-helper.js"; +import baseMixin from "@/mixins/base-mixin"; +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 { storeActions } from "@/constants/store-actions"; +import { storeMutations } from "@/constants/store-mutations"; +import store from "@/store"; + +// 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(), +})); + +// Mock store +jest.mock("@/store", () => { return {}; }, { virtual: true }); + +store.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-damage.vue", () => { + + test("Page header is initialized with api data", async (done) => { + //Arrange + store.getters.pageData.mockReturnValueOnce({ + 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 + } + ] + }); + + const pageHeaderWidgetHeaderText = "Select Parts"; + const { wrapper, apiPromise } = setupMocks( + { + pageHeaderWidgetHeaderText: pageHeaderWidgetHeaderText, + mountOptionsMockData: { + router: { + navigateAfterSave: jest.fn() + }, + route: { + query: { + fmgPage: 'vehicle-parts', + } + }, + store: { + getters: store.getters + }, + } + }); + + //Act + vehicleParts.beforeRouteEnter.call(wrapper.vm, + { query: { fmgPage: "vehicle-parts" } }, + undefined, + (c) => c(wrapper.vm) + ); + + //Assert + apiPromise.finally(() => { + expect(funnelSubHeader.methods.initializeComponent).toHaveBeenCalledWith(pageHeaderWidgetHeaderText); + done(); + }); + }); + + test("Page logo image is initialized with api data", async (done) => { + //Arrange + const SiteHeaderWidget = { + LogoImage: + "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3", + }; + + store.getters.pageData.mockReturnValueOnce(basePartResponse); + + const { wrapper, apiPromise } = setupMocks( + { + SiteHeaderWidget: SiteHeaderWidget, + mountOptionsMockData: { + router: { + navigateAfterSave: jest.fn() + }, + route: { + query: { + fmgPage: 'vehicle-parts', + } + }, + store: { + getters: store.getters + }, + } + }); + + //Act + vehicleParts.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-parts" } }, + undefined, + (c) => c(wrapper.vm) + ); + + //Assert + apiPromise.finally(() => { + expect(funnelHeader.methods.initializeComponent).toHaveBeenCalledWith(SiteHeaderWidget); + done(); + }); + }); + + test("Vehicle image is initialized with api data", async (done) => { + //Arrange + const VehicleBannerWidget = { + GenericVehicleImage: + "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3", + }; + + store.getters.pageData.mockReturnValue(basePartResponse); + + const { wrapper, apiPromise } = setupMocks( + { + VehicleBannerWidget: VehicleBannerWidget, + mountOptionsMockData: { + router: { + navigateAfterSave: jest.fn() + }, + route: { + query: { + fmgPage: 'vehicle-parts', + } + }, + store: { + getters: store.getters + }, + } + }); + + //Act + vehicleParts.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-parts" } }, + undefined, + (c) => c(wrapper.vm) + ); + + //Assert + apiPromise.finally(() => { + expect(vehicleBanner.methods.initializeComponent).toHaveBeenCalledWith(VehicleBannerWidget); + done(); + }); + }); + + test("PageData / isRepair populated in Vuex. arePagePrerequisitesValid should be true ", async () => { + + //Arrange + store.getters.pageData.mockReturnValueOnce(basePartResponse); + const { wrapper } = setupMocks({ + mountOptionsMockData: { + router: { + navigateAfterSave: jest.fn() + }, + route: { + query: { + fmgPage: 'vehicle-parts', + } + }, + store: { + getters: store.getters + }, + } + }); + + //Act + vehicleParts.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-parts" } }, + undefined, + (c) => c(wrapper.vm) + ); + + let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); + await nextTick(); + + //Assert + expect(arePagePrerequisitesValid).toBe(true); + }); + + test("BackButtonAction triggers a router.navigate change", async () => { + + //Arrange + store.getters.pageData.mockReturnValueOnce(basePartResponse); + const { wrapper } = setupMocks({ + mountOptionsMockData: { + router: { + navigateAfterSave: jest.fn(), + navigate: jest.fn() + }, + route: { + query: { + fmgPage: 'vehicle-parts', + } + }, + store: { + getters: store.getters + }, + } + }); + + //Act + vehicleParts.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-parts" } }, + undefined, + (c) => c(wrapper.vm) + ); + + wrapper.vm.backButtonAction(); + + //Assert + expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); + + }); + + test("ForwardButtonAction triggers a router.navigate change and saves selected parts to store", async () => { + + //Arrange + store.getters.pageData.mockReturnValueOnce(basePartResponse); + store.commit = jest.fn(); + + const { wrapper } = setupMocks({ + mountOptionsMockData: { + router: { + navigateAfterSave: jest.fn(), + navigate: jest.fn() + }, + route: { + query: { + fmgPage: 'vehicle-parts', + } + }, + store: { + getters: store.getters, + commit: store.commit + }, + } + }); + + wrapper.setData({ glassParts: { "Rear-Stationary": { "Rear": ['DB12209YPYNOEM'] } } }); + + //Act + vehicleParts.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-parts" } }, + undefined, + (c) => c(wrapper.vm) + ); + + await wrapper.vm.forwardButtonAction(); + + //Assert + expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled(); + // expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace); + // expect(store.commit).toBeCalledWith(storeMutations.UPDATE_IS_REPAIR, false); + // expect(store.commit).toBeCalledWith(storeMutations.UPDATE_GLASS_TO_REPLACE, expectedGlassToReplace); + }); +}); + +function setupMocks({ pageHeaderWidgetHeaderText = {}, mountOptionsMockData = {} }) { + //Mock api responses + const apiResponses = { + cmsContent: { + FunnelSubHeaderWidget: pageHeaderWidgetHeaderText, + VehicleBannerWidget: { + GenericVehicleImage: + "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3", + }, + FunnelHeaderWidget: { + LogoImage: + "https://digitalconsumercms-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 apiPromise = Promise.resolve(apiResponses); + + settleAllPromises.mockImplementation(() => apiPromise); + fetchCmsContentForPage.mockImplementation(() => Promise.resolve()); + + //Mock damage initialize methods + funnelHeader.methods = { initializeComponent: jest.fn() }; + vehicleBanner.methods = { initializeComponent: jest.fn() }; + funnelSubHeader.methods = { initializeComponent: jest.fn() }; + funnelFooter.methods = { initializeComponent: jest.fn() } + + const mountOptions = getMountOptions(mountOptionsMockData,); + const wrapper = shallowMount(vehicleParts, mountOptions); + + const funnelHeaderWrapper = wrapper.findComponent({ name: "funnelHeader" }); + funnelHeaderWrapper.vm.initializeComponent = funnelHeader.methods.initializeComponent; + + const vehicleBannerWrapper = wrapper.findComponent({ name: "vehicleBanner" }); + vehicleBannerWrapper.vm.initializeComponent = vehicleBanner.methods.initializeComponent; + + const funnelSubHeaderWrapper = wrapper.findComponent({ name: "funnelSubHeader", }); + funnelSubHeaderWrapper.vm.initializeComponent = funnelSubHeader.methods.initializeComponent; + + const funnelFooterWrapper = wrapper.findComponent({ name: "funnelFooter", }); + funnelFooterWrapper.vm.initializeComponent = funnelFooter.methods.initializeComponent; + + const partQuestionRearWrapper = wrapper.findComponent({ name: "glassPartQuestion", }); + partQuestionRearWrapper.vm.initializeComponent = glassPartQuestion.methods.initializeComponent; + + return { wrapper, apiPromise }; +} diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index c73ccaa03..aaa7f8620 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -32,13 +32,20 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he import funnelFooter from "@/common-components/funnel-footer/funnel-footer"; import alert from "@/ux-components/alert/alert"; // Supporting Files -import {fetchCmsContentForPage} from "@/helpers/cms-content-helper"; -import {settleAllPromises} from "@/helpers/layout-helper"; -import {fmgPageValues} from "@/router/router-constants/fmgPage-values"; -import {storeMutations} from "@/constants/store-mutations"; +import { + fetchCmsContentForPage +} from "@/helpers/cms-content-helper"; +import { + settleAllPromises +} from "@/helpers/layout-helper"; +import { + fmgPageValues +} from "@/router/router-constants/fmgPage-values"; +import { + storeMutations +} from "@/constants/store-mutations"; import store from "@/store"; - export default { name: "vehicle-parts", async beforeRouteEnter(to, from, next) { @@ -66,6 +73,7 @@ export default { ); // Glass Part Question dynamic component + Object.keys(vm.$refs) .filter((r) => r.includes(vm.refPrefix) && vm.$refs[r][0] !== undefined) .forEach((c) => @@ -74,12 +82,14 @@ export default { FeatureQuestionWidget: resultMap.cmsContent.FeatureQuestionWidget, }) ); + // Set alertData for the page alert. These use props so we don't call // initializeComponent here. vm.alertWidgetData = { copy: resultMap.cmsContent.AlertWidget.BodyText, headline: resultMap.cmsContent.AlertWidget.HeadlineText }; + }); }, data() { @@ -99,7 +109,7 @@ export default { }, computed: { PartsForQuestions() { - const partsData = store.getters.pageData(this.$route.query.fmgPage); + const partsData = this.$store.getters.pageData(this.$route.query.fmgPage); // Map API result data, to vehicle-parts data structure const mappedData = partsData.partsOrQuestions.map(g => { @@ -142,7 +152,6 @@ export default { this.$route ); }, - forwardButtonAction() { const selectedGlassPartNumbers = []; const matchedParts = []; @@ -167,7 +176,7 @@ export default { } // If no parts could be matched, throw an error. - if(matchedParts.length === 0) { + if (matchedParts.length === 0) { throw new Error("Could not match any parts to the selected parts"); } @@ -180,4 +189,4 @@ export default { }, }; - \ No newline at end of file +