From 915cfd5a215f33b539317e4fe060d995c33ba5f5 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Thu, 27 Jan 2022 17:23:09 -0500 Subject: [PATCH] Added logic to validate pages --- src/layouts/vehicle-damage/vehicle-damage.vue | 58 ++++++------ src/layouts/vehicle-make/vehicle-make.spec.js | 89 ++++++++++++++----- src/layouts/vehicle-make/vehicle-make.vue | 16 ++-- src/layouts/vehicle-model/vehicle-model.vue | 5 ++ src/layouts/vehicle-style/vehicle-style.vue | 24 ++++- src/layouts/vehicle-year/vehicle-year.vue | 9 +- src/router/index.js | 18 +++- 7 files changed, 157 insertions(+), 62 deletions(-) diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index c00669245..e18b594e0 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -1,11 +1,9 @@ diff --git a/src/layouts/vehicle-make/vehicle-make.spec.js b/src/layouts/vehicle-make/vehicle-make.spec.js index 83a7f1862..41a7939ad 100644 --- a/src/layouts/vehicle-make/vehicle-make.spec.js +++ b/src/layouts/vehicle-make/vehicle-make.spec.js @@ -7,23 +7,40 @@ import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner"; import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header"; import { settleAllPromises } from "@/helpers/layout-helper.js"; import { nextTick } from "vue"; +import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; + +// Mock Store +jest.mock("@/store", () => ({ + getters: { + vehicle: { + year: 2019, + } + } +})); + +// Mock fetchCmsContentForPage +jest.mock("@/helpers/cms-content-helper", () => ({ + fetchCmsContentForPage: jest.fn(), +})); // Mock our module for promises. jest.mock("@/helpers/layout-helper.js", () => ({ settleAllPromises: jest.fn(), })); + describe("vehicle-make.vue", () => { test("Make question component is initized with api data", async (done) => { //Arrange const vehicleMakeQuestionCmsContent = { QuestionText: "What make is your vehicle?" }; const makeQuestionInitialData = ["honda", "ford", "dodge"]; - const { wrapper, apiPromise } = setupMocks( { - vehicleMakeQuestionCmsContent: vehicleMakeQuestionCmsContent, + const { wrapper, apiPromise } = setupMocks({ + vehicleMakeQuestionCmsContent: vehicleMakeQuestionCmsContent, makeQuestionInitialData: makeQuestionInitialData, - } ); + }); + //Act vehicleMake.beforeRouteEnter.call(wrapper.vm, { query: { fmgPage: "vehicle-make" } }, undefined, (c) => c(wrapper.vm)); @@ -40,8 +57,8 @@ describe("vehicle-make.vue", () => { //Arrange const pageHeaderWidgetHeaderText = "Select a make to get started"; - const { wrapper, apiPromise } = setupMocks( { pageHeaderWidgetHeaderText: pageHeaderWidgetHeaderText }); - + const { wrapper, apiPromise } = setupMocks({ pageHeaderWidgetHeaderText: pageHeaderWidgetHeaderText }); + //Act vehicleMake.beforeRouteEnter.call(wrapper.vm, { query: { fmgPage: "vehicle-make" } }, undefined, (c) => c(wrapper.vm)); @@ -61,8 +78,8 @@ describe("vehicle-make.vue", () => { LogoImage: "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3", } - const { wrapper, apiPromise } = setupMocks( { SiteHeaderWidget: SiteHeaderWidget}); - + const { wrapper, apiPromise } = setupMocks({ SiteHeaderWidget: SiteHeaderWidget }); + //Act vehicleMake.beforeRouteEnter.call(wrapper.vm, { query: { fmgPage: "vehicle-make" } }, undefined, (c) => c(wrapper.vm)); @@ -82,8 +99,8 @@ describe("vehicle-make.vue", () => { GenericVehicleImage: "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3", } - const { wrapper, apiPromise } = setupMocks( { VehicleBannerWidget: VehicleBannerWidget}); - + const { wrapper, apiPromise } = setupMocks({ VehicleBannerWidget: VehicleBannerWidget }); + //Act vehicleMake.beforeRouteEnter.call(wrapper.vm, { query: { fmgPage: "vehicle-make" } }, undefined, (c) => c(wrapper.vm)); @@ -97,9 +114,9 @@ describe("vehicle-make.vue", () => { describe("vehicle-make.vue", () => { test("BackButtonAction triggers a router.navigate change", async (done) => { - + //Arrange - const { wrapper, apiPromise } = setupMocks( { + const { wrapper, apiPromise } = setupMocks({ pageHeaderWidgetHeaderText: "Select a make to get started", mountOptionsMockData: { router: { @@ -121,32 +138,59 @@ describe("vehicle-make.vue", () => { }); }); +describe("vehicle-make.vue", () => { + test("arePagePrerequisitesValid", async (done) => { + + //Arrange + const { wrapper, apiPromise } = setupMocks({ + pageHeaderWidgetHeaderText: "Select a make to get started", + mountOptionsMockData: {}, + }); + + //Act + vehicleMake.beforeRouteEnter.call(wrapper.vm, { query: { fmgPage: "vehicle-make" } }, undefined, (c) => c(wrapper.vm)); + + let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); + await nextTick(); + + //Assert + apiPromise.finally(() => { + expect(arePagePrerequisitesValid).toBe(true); + done(); + }); + }); +}); + + function setupMocks({ vehicleMakeQuestionCmsContent = {}, makeQuestionInitialData = {}, pageHeaderWidgetHeaderText = {}, mountOptionsMockData = {}, }) { - + //Mock api responses const apiResponses = { cmsContent: { FunnelSubHeaderWidget: pageHeaderWidgetHeaderText, VehicleMakeQuestion: vehicleMakeQuestionCmsContent, - 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", - }, + 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", + }, }, makeQuestionInitialData: makeQuestionInitialData, }; + const apiPromise = Promise.resolve(apiResponses); + + fetchCmsContentForPage.mockImplementation(() => Promise.resolve()); settleAllPromises.mockImplementation(() => apiPromise); //Mock make question methods @@ -163,6 +207,7 @@ function setupMocks({ funnelSubHeader.methods = { initializeComponent: jest.fn(), }; + const mountOptions = getMountOptions(mountOptionsMockData); const wrapper = shallowMount(vehicleMake, mountOptions); const makeQuestionWrapper = wrapper.findComponent({ name: "makeQuestion" }); diff --git a/src/layouts/vehicle-make/vehicle-make.vue b/src/layouts/vehicle-make/vehicle-make.vue index 91fe4c9d5..ee90b2d36 100644 --- a/src/layouts/vehicle-make/vehicle-make.vue +++ b/src/layouts/vehicle-make/vehicle-make.vue @@ -4,11 +4,11 @@
-
@@ -25,6 +25,7 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he // Supporting files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; +import store from "@/store"; export default { name: "vehicle-make", data() { @@ -53,7 +54,6 @@ export default { ]; const resultMap = await settleAllPromises(promiseResultMap); - // Call the "next" function to complete the transition to this page. next((vm) => { vm.$refs.funnelSubHeader.initializeComponent( @@ -77,6 +77,10 @@ export default { // route to move backwards this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); }, + arePagePrerequisitesValid() { + console.log(store.getters.vehicle); + return store.getters.vehicle.year !== null; + }, }, watch: { diff --git a/src/layouts/vehicle-model/vehicle-model.vue b/src/layouts/vehicle-model/vehicle-model.vue index b06486c74..b27b98d40 100644 --- a/src/layouts/vehicle-model/vehicle-model.vue +++ b/src/layouts/vehicle-model/vehicle-model.vue @@ -25,6 +25,8 @@ import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner"; // Supporting files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; +import store from "@/store"; + export default { name: "vehicle-model", data() { @@ -77,6 +79,9 @@ export default { // route to move backwards this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); }, + arePagePrerequisitesValid() { + return store.getters.vehicle.make !== null; + }, }, watch: { diff --git a/src/layouts/vehicle-style/vehicle-style.vue b/src/layouts/vehicle-style/vehicle-style.vue index 3c0023db1..7193c9e39 100644 --- a/src/layouts/vehicle-style/vehicle-style.vue +++ b/src/layouts/vehicle-style/vehicle-style.vue @@ -25,6 +25,8 @@ import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner"; // Supporting files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; +import store from "@/store"; + export default { name: "vehicle-style", data() { @@ -78,17 +80,31 @@ export default { this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); }, setVehicle() { - return this.dispatchNonBlockingStoreAction(this.storeActions.SET_VEHICLE, {year: this.$store.getters.vehicle.year, make: this.$store.getters.vehicle.make, model: this.$store.getters.vehicle.model, style: this.$store.getters.vehicle.style}); - } + return this.dispatchNonBlockingStoreAction( + this.storeActions.SET_VEHICLE, + { + year: this.$store.getters.vehicle.year, + make: this.$store.getters.vehicle.make, + model: this.$store.getters.vehicle.model, + style: this.$store.getters.vehicle.style, + } + ); + }, + arePagePrerequisitesValid() { + return store.getters.vehicle.model !== null; + }, }, watch: { selectedStyle(style) { this.$store.commit(this.storeMutations.UPDATE_STYLE, style); this.setVehicle().then(() => { - this.$router.navigate(this.navigationScenarios.SELECTED_STYLE, this.$route); + this.$router.navigate( + this.navigationScenarios.SELECTED_STYLE, + this.$route + ); }); - } + }, }, components: { diff --git a/src/layouts/vehicle-year/vehicle-year.vue b/src/layouts/vehicle-year/vehicle-year.vue index dbf488ea2..ddef0d5a8 100644 --- a/src/layouts/vehicle-year/vehicle-year.vue +++ b/src/layouts/vehicle-year/vehicle-year.vue @@ -4,9 +4,7 @@
- +
@@ -80,6 +78,11 @@ export default { ); }, }, + methods: { + arePagePrerequisitesValid() { + return true; + }, + }, components: { yearQuestion, funnelHeader, diff --git a/src/router/index.js b/src/router/index.js index 2a80032f6..7482a3d50 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -44,6 +44,13 @@ const routes = [ try { // If we already have our route, go to it. if (router.hasRoute(to.query.fmgPage)) { + // Since our route is already in scope, we can grab the component from it and call the arePagePrerequisitesValid function. + let arePagePrerequisitesValid = router.getRoutes().filter(x => x.name === to.query.fmgPage)[0].components.default.methods.arePagePrerequisitesValid(); + + if (!arePagePrerequisitesValid) { + await GoToFunnelStartOn404(next); + } + return next({ name: to.query.fmgPage, query: to.query }); } @@ -57,9 +64,17 @@ const routes = [ component: routeData[0].component, }); + // Call the next components arePagePrerequisitesValid method before load. + // If it returns false, use the 404 logic. + let nextComponent = await router.getRoutes().filter(x => x.name === routeData[0].name)[0].components.default(); + + if (!nextComponent.default.methods.arePagePrerequisitesValid()) { + await GoToFunnelStartOn404(next); + } + // Assign current query string parameters, as well as our fmgPage one. next({ name: routeData[0].name, query: Object.assign(to.query, { fmgPage: routeData[0].name }) }); - + } catch (error) { console.log(error); @@ -79,6 +94,7 @@ const router = createRouter({ //---------------------------------------------------------- Router Functions ---------------------------------------------------------- + // Navigate to the next route, depending on the scenario. router.navigate = ( scenario,