From 5ccccc25483cea13474d80bd2a936d08dde8ebec Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 1 Feb 2022 14:49:21 -0500 Subject: [PATCH 1/4] Created state invalidation --- src/constants/store-actions.js | 9 ++- src/constants/store-mutations.js | 15 +++++ src/helpers/event-bus/event-bus.js | 6 +- src/layouts/vehicle-damage/vehicle-damage.vue | 7 ++- src/layouts/vehicle-make/vehicle-make.spec.js | 4 +- src/layouts/vehicle-make/vehicle-make.vue | 21 ++++++- .../vehicle-model/vehicle-model.spec.js | 4 +- src/layouts/vehicle-model/vehicle-model.vue | 19 ++++++- .../vehicle-style/vehicle-style.spec.js | 4 +- src/layouts/vehicle-style/vehicle-style.vue | 13 ++++- src/layouts/vehicle-year/vehicle-year.vue | 20 ++++++- src/router/index.js | 51 ++++++++++++----- src/store/index.js | 55 ++++++++++++++++++- 13 files changed, 192 insertions(+), 36 deletions(-) diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 263f153df..177211ae0 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -11,9 +11,12 @@ const storeActions = { GET_EVOX_IMAGE: "getEvoxImage", LOOKUP_VEHICLE_BY_YMMS: "lookupVehicleByYmms", LOOKUP_VEHICLE_BY_VIN: "lookupVehicleByVin", - // EVENT BUS - ADD_EVENT_TO_BUS: "addEventToBus", - REMOVE_EVENT_FROM_BUS: "removeEventFromBus", + + // DEPENDENCY MUTATIONS + RESET_VEHICLE_AND_DEPS: "resetVehicleAndDependencies", + RESET_DAMAGE_AND_DEPS: "resetDamageAndDependencies", + RESET_REGISTRATION_AND_DEPS: "resetRegistrationAndDependencies", + RESET_PARTS_AND_DEPS: "resetPartsAndDependencies", }; export { storeActions }; diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 61882b691..c52c955f0 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -1,9 +1,24 @@ const storeMutations = { + + // VEHICLE MUTATIONS UPDATE_YEAR: "updateYear", UPDATE_MAKE: "updateMake", UPDATE_MODEL: "updateModel", UPDATE_STYLE: "updateStyle", + UPDATE_CAR_ID: "updateCarId", + UPDATE_VEHICLE_CATEGORY: "updateVehicleCategory", UPDATE_VEHICLE: "updateVehicle", + + // EVENT BUS MUTATIONS + ADD_EVENT_TO_BUS: "addEventToBus", + REMOVE_EVENT_FROM_BUS: "removeEventFromBus", + + // DEPENDENCY MUTATIONS + RESET_VEHICLE_AND_DEPS: "resetVehicleAndDependencies", + RESET_DAMAGE_AND_DEPS: "resetDamageAndDependencies", + RESET_REGISTRATION_AND_DEPS: "resetRegistrationAndDependencies", + RESET_PARTS_AND_DEPS: "resetPartsAndDependencies", + }; export { storeMutations }; diff --git a/src/helpers/event-bus/event-bus.js b/src/helpers/event-bus/event-bus.js index 47f229210..19b30870c 100644 --- a/src/helpers/event-bus/event-bus.js +++ b/src/helpers/event-bus/event-bus.js @@ -1,10 +1,10 @@ import store from "@/store"; -import { storeActions } from "@/constants/store-actions.js"; +import { storeMutations } from "@/constants/store-mutations.js"; export default { // Adds event to the bus given its category, subcategory, and eventValue; addEventToBus(category, subCategory, eventValue) { - store.commit(storeActions.ADD_EVENT_TO_BUS, { + store.commit(storeMutations.ADD_EVENT_TO_BUS, { category: category, subCategory: subCategory, eventValue: eventValue, @@ -15,7 +15,7 @@ export default { readAndPopEventFromBus(category, subCategory) { const event = store.getters.eventBusItem(category, subCategory); - store.commit(storeActions.REMOVE_EVENT_FROM_BUS, { + store.commit(storeMutations.REMOVE_EVENT_FROM_BUS, { category: category, subCategory: subCategory, }); diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index ba46df331..b27259e49 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -18,9 +18,10 @@ import replaceOptionsQuestion from"@/layouts/vehicle-damage/replace-options-ques // Supporting files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { settleAllPromises } from "@/helpers/layout-helper"; +import { storeActions } from "@/constants/store-actions"; import store from "@/store"; import baseMixin from "@/mixins/base-mixin"; -import { storeActions } from "@/constants/store-actions"; + export default { name: "vehicle-damage", @@ -69,6 +70,10 @@ export default { arePagePrerequisitesValid() { return store.getters.vehicle.carId !== null; }, + resetDependentState() { + // Invokes + store.dispatch(storeActions.RESET_PARTS_AND_DEPS); + }, }, components: { funnelHeader, diff --git a/src/layouts/vehicle-make/vehicle-make.spec.js b/src/layouts/vehicle-make/vehicle-make.spec.js index 146dd6318..b3a006c20 100644 --- a/src/layouts/vehicle-make/vehicle-make.spec.js +++ b/src/layouts/vehicle-make/vehicle-make.spec.js @@ -153,7 +153,7 @@ describe("vehicle-make.vue", () => { pageHeaderWidgetHeaderText: "Select a make to get started", mountOptionsMockData: { router: { - navigate: jest.fn(), + navigateForward: jest.fn(), }, }, }); @@ -170,7 +170,7 @@ describe("vehicle-make.vue", () => { //Assert apiPromise.finally(() => { - expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); + expect(wrapper.vm.$router.navigateForward).toHaveBeenCalled(); done(); }); }); diff --git a/src/layouts/vehicle-make/vehicle-make.vue b/src/layouts/vehicle-make/vehicle-make.vue index 111b16e5f..f95172547 100644 --- a/src/layouts/vehicle-make/vehicle-make.vue +++ b/src/layouts/vehicle-make/vehicle-make.vue @@ -25,7 +25,10 @@ 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 { storeMutations } from "@/constants/store-mutations"; +import { storeActions } from "@/constants/store-actions"; import store from "@/store"; + export default { name: "vehicle-make", data() { @@ -75,17 +78,31 @@ export default { methods: { backButtonAction() { // route to move backwards - this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); + this.$router.navigateForward( + this.navigationScenarios.CLICKED_BACK, + this.$route + ); }, arePagePrerequisitesValid() { return store.getters.vehicle.year !== null; }, + resetDependentState() { + // Set + store.commit(storeMutations.UPDATE_MODEL, null); + store.commit(storeMutations.UPDATE_STYLE, null); + store.commit(storeMutations.UPDATE_CAR_ID, null); + store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null); + + // Invokes + store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS); + store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS); + }, }, watch: { selectedMake(make) { this.$store.commit(this.storeMutations.UPDATE_MAKE, make); - this.$router.navigate( + this.$router.navigateAfterSave( this.navigationScenarios.SELECTED_MAKE, this.$route ); diff --git a/src/layouts/vehicle-model/vehicle-model.spec.js b/src/layouts/vehicle-model/vehicle-model.spec.js index 4c61215ba..b1e240288 100644 --- a/src/layouts/vehicle-model/vehicle-model.spec.js +++ b/src/layouts/vehicle-model/vehicle-model.spec.js @@ -141,7 +141,7 @@ describe("vehicle-model.vue", () => { pageHeaderWidgetHeaderText: "Select a model to get started", mountOptionsMockData: { router: { - navigate: jest.fn(), + navigateForward: jest.fn(), }, }, }); @@ -156,7 +156,7 @@ describe("vehicle-model.vue", () => { await nextTick(); //Assert apiPromise.finally(() => { - expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); + expect(wrapper.vm.$router.navigateForward).toHaveBeenCalled(); done(); }); }); diff --git a/src/layouts/vehicle-model/vehicle-model.vue b/src/layouts/vehicle-model/vehicle-model.vue index b27b98d40..06794e9a2 100644 --- a/src/layouts/vehicle-model/vehicle-model.vue +++ b/src/layouts/vehicle-model/vehicle-model.vue @@ -24,6 +24,8 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner"; // Supporting files import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; +import { storeMutations } from "@/constants/store-mutations"; +import { storeActions } from "@/constants/store-actions"; import { settleAllPromises } from "@/helpers/layout-helper"; import store from "@/store"; @@ -77,17 +79,30 @@ export default { methods: { backButtonAction() { // route to move backwards - this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); + this.$router.navigateForward( + this.navigationScenarios.CLICKED_BACK, + this.$route + ); }, arePagePrerequisitesValid() { return store.getters.vehicle.make !== null; }, + resetDependentState() { + // Set + store.commit(storeMutations.UPDATE_STYLE, null); + store.commit(storeMutations.UPDATE_CAR_ID, null); + store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null); + + // Invokes + store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS); + store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS); + }, }, watch: { selectedModel(model) { this.$store.commit(this.storeMutations.UPDATE_MODEL, model); - this.$router.navigate( + this.$router.navigateAfterSave( this.navigationScenarios.SELECTED_MODEL, this.$route ); diff --git a/src/layouts/vehicle-style/vehicle-style.spec.js b/src/layouts/vehicle-style/vehicle-style.spec.js index 183b22d57..e52818cf6 100644 --- a/src/layouts/vehicle-style/vehicle-style.spec.js +++ b/src/layouts/vehicle-style/vehicle-style.spec.js @@ -154,7 +154,7 @@ describe("vehicle-style.vue", () => { pageHeaderWidgetHeaderText: "Select a style to get started", mountOptionsMockData: { router: { - navigate: jest.fn(), + navigateForward: jest.fn(), }, }, }); @@ -171,7 +171,7 @@ describe("vehicle-style.vue", () => { //Assert apiPromise.finally(() => { - expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); + expect(wrapper.vm.$router.navigateForward).toHaveBeenCalled(); done(); }); }); diff --git a/src/layouts/vehicle-style/vehicle-style.vue b/src/layouts/vehicle-style/vehicle-style.vue index 7193c9e39..ec1cd4598 100644 --- a/src/layouts/vehicle-style/vehicle-style.vue +++ b/src/layouts/vehicle-style/vehicle-style.vue @@ -25,6 +25,7 @@ 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 { storeActions } from "@/constants/store-actions"; import store from "@/store"; export default { @@ -77,7 +78,10 @@ export default { methods: { backButtonAction() { // route to move backwards - this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route); + this.$router.navigateForward( + this.navigationScenarios.CLICKED_BACK, + this.$route + ); }, setVehicle() { return this.dispatchNonBlockingStoreAction( @@ -93,13 +97,18 @@ export default { arePagePrerequisitesValid() { return store.getters.vehicle.model !== null; }, + resetDependentState() { + // Invokes + store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS); + store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS); + }, }, watch: { selectedStyle(style) { this.$store.commit(this.storeMutations.UPDATE_STYLE, style); this.setVehicle().then(() => { - this.$router.navigate( + this.$router.navigateAfterSave( this.navigationScenarios.SELECTED_STYLE, this.$route ); diff --git a/src/layouts/vehicle-year/vehicle-year.vue b/src/layouts/vehicle-year/vehicle-year.vue index ddef0d5a8..aeeaecf94 100644 --- a/src/layouts/vehicle-year/vehicle-year.vue +++ b/src/layouts/vehicle-year/vehicle-year.vue @@ -20,7 +20,9 @@ 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 eventBus from "@/helpers/event-bus/event-bus"; +import { storeMutations } from "@/constants/store-mutations"; +import { storeActions } from "@/constants/store-actions"; +import store from "@/store"; export default { name: "vehicle-year", @@ -71,8 +73,9 @@ export default { watch: { selectedYear(year) { + this.$store.commit(this.storeMutations.UPDATE_YEAR, year); - this.$router.navigate( + this.$router.navigateAfterSave( this.navigationScenarios.SELECTED_YEAR, this.$route ); @@ -82,6 +85,19 @@ export default { arePagePrerequisitesValid() { return true; }, + resetDependentState() { + + // Set + store.commit(storeMutations.UPDATE_MAKE, null); + store.commit(storeMutations.UPDATE_MODEL, null); + store.commit(storeMutations.UPDATE_STYLE, null); + store.commit(storeMutations.UPDATE_CAR_ID, null); + store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null); + + // Invokes + store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS); + store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS); + } }, components: { yearQuestion, diff --git a/src/router/index.js b/src/router/index.js index eb4942d6a..ac31a1c6d 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -45,16 +45,16 @@ const routes = [ // 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. - const arePagePrerequisitesValid = router + const component = router .getRoutes() - .filter((x) => x.name === to.query.fmgPage)[0] - .components.default.methods.arePagePrerequisitesValid(); + .filter((x) => x.name === to.query.fmgPage)[0].components; - if (!arePagePrerequisitesValid) { + if (!arePagePrerequisitesValid(component)) { await GoToFunnelStartOn404(next); } - return next({ name: to.query.fmgPage, query: to.query, params: to.params }); + + return next({ name: to.query.fmgPage, query: to.query, params: to.params }); } // Get route info for the given url. Names will have a 1:1 relationship with names in the Cms. @@ -74,7 +74,7 @@ const routes = [ .filter((x) => x.name === routeData[0].name)[0] .components.default(); - if (!nextComponent.default.methods.arePagePrerequisitesValid()) { + if (!arePagePrerequisitesValid(nextComponent)) { await GoToFunnelStartOn404(next); } @@ -102,23 +102,36 @@ const router = createRouter({ //---------------------------------------------------------- Router Functions ---------------------------------------------------------- +router.navigateForward = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) => { + navigate(scenario, currentRoute, false, optionalQuery, optionalParams); +} + +router.navigateAfterSave = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) => { + navigate(scenario, currentRoute, true, optionalQuery, optionalParams); +} + +// PRIVATE FUNCTIONS + // Navigate to the next route, depending on the scenario. -router.navigate = ( - scenario, - currentRoute, - optionalQuery = {}, - optionalParams = {} -) => { +function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, optionalParams = {}) { if (!scenario) { console.error("No scenario provided. Please review the routing table."); return; } // Match our maps up and navigate if we have a destination. - const matchingScenarioMap = router.getNavigationMap(scenario, currentRoute); + const matchingScenarioMap = getNavigationMap(scenario, currentRoute); if (matchingScenarioMap.destinationFmgPageValue !== undefined) { // We're always pushing the same path, just changing query strings. Make sure our optional query strings get combined with our fmgPage one. + + // If we need to do invalidation + const currentComponent = currentRoute.matched[0].components; + + if (invalidateOnSave) { + resetDependentState(currentComponent); + } + router.push({ name: "root", query: Object.assign(optionalQuery, { @@ -132,7 +145,7 @@ router.navigate = ( }; // Get navigation map depending on the scenario and the current 'page' you're on. -router.getNavigationMap = (scenario, currentRoute) => { +function getNavigationMap(scenario, currentRoute) { const fmgPageValue = currentRoute.query.fmgPage; const matchedQueryValue = routingTable .filter( @@ -197,4 +210,14 @@ async function GoToFunnelStartOn404(next) { }); } +// Checks arePagePrerequisitesValid on the component passed in. +function arePagePrerequisitesValid(component) { + return component.default.methods.arePagePrerequisitesValid(); +} + +// Reset dependant state on route change. +function resetDependentState(component) { + return component.default.methods.resetDependentState(); +} + export default router; diff --git a/src/store/index.js b/src/store/index.js index 9d5078f74..22107ab76 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -3,7 +3,7 @@ import { endpoints } from "@/constants/endpoints.js"; import { storeMutations } from "@/constants/store-mutations"; import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; -import eventBus from "../helpers/event-bus/event-bus"; + export default createStore({ plugins: [createPersistedState()], @@ -35,6 +35,8 @@ export default createStore({ // See IMPORTANT note at top of "state" declaration. mutations: { + + // VEHICLE MUTATIONS updateYear(state, year) { state.order.vehicle.year = year; }, @@ -47,10 +49,18 @@ export default createStore({ updateStyle(state, style) { state.order.vehicle.style = style; }, + updateCarId(state, carId) { + state.order.vehicle.carId = carId; + }, + updateVehicleCategory(state, category) { + state.order.vehicle.category = category; + }, updateVehicle(state, data) { state.order.vehicle.carId = data.carId; state.order.vehicle.category = data.category; }, + + // EVENT BUS MUTATIONS addEventToBus(state, event) { state.applicationUser.eventBus.push(event); }, @@ -67,6 +77,31 @@ export default createStore({ state.applicationUser.eventBus.splice(itemIndex, 1); } }, + + // DEPENDENCY MUTATIONS + resetVehicleAndDependencies(state) { + state.order.vehicle.year = null; + state.order.vehicle.make = null; + state.order.vehicle.model = null; + state.order.vehicle.style = null; + state.order.vehicle.carId = null; + state.order.vehicle.category = null; + }, + resetDamageAndDependencies(state) { + state.order.vehicle.damage.isRepair = null; + state.order.vehicle.damage.numberOfChips = null; + state.order.vehicle.damage.windshieldGlassToReplace = null; + state.order.vehicle.damage.driverSideGlassToReplace = null; + state.order.vehicle.damage.passengerSideGlassToReplace = null; + state.order.vehicle.damage.rearGlassToReplace = null; + + }, + resetRegistrationAndDependencies(state) { + + }, + resetPartsAndDependencies(state) { + + } }, getters: { vehicle: (state) => state.order.vehicle, @@ -146,6 +181,24 @@ export default createStore({ }); }, + // DEPENDENCY ACTIONS + resetVehicleAndDependencies(context) { + context.commit(storeMutations.RESET_VEHICLE_AND_DEPS); + context.commit(storeMutations.RESET_DAMAGE_AND_DEPS); + context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS); + }, + resetDamageAndDependencies(context) { + context.commit(storeMutations.RESET_DAMAGE_AND_DEPS); + context.commit(storeMutations.RESET_PARTS_AND_DEPS); + }, + resetRegistrationAndDependencies(context) { + context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS); + context.commit(storeMutations.RESET_PARTS_AND_DEPS) + }, + resetPartsAndDependencies(context) { + context.commit(storeMutations.RESET_PARTS_AND_DEPS); + }, + // Content API Actions getRouteInfo(context, { pageName }) { return globalMethods.callHttpClient({ From 5d9bfe0d0b731d15aa642e4f0e5d8163abd19eeb Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 1 Feb 2022 16:21:49 -0500 Subject: [PATCH 2/4] begin store mock --- .../vehicle-damage/vehicle-damage.spec.js | 26 ++ src/layouts/vehicle-make/vehicle-make.spec.js | 52 +++- src/layouts/vehicle-make/vehicle-make.vue | 2 +- .../vehicle-model/vehicle-model.spec.js | 38 ++- src/layouts/vehicle-model/vehicle-model.vue | 2 +- .../vehicle-style/vehicle-style.spec.js | 4 +- src/layouts/vehicle-style/vehicle-style.vue | 2 +- src/layouts/vehicle-year/vehicle-year.spec.js | 52 +++- src/router/index.js | 2 +- src/store/index.js | 1 - src/store/store.spec.js | 228 +++++++++++++++++- 11 files changed, 385 insertions(+), 24 deletions(-) diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js index caf008b78..0dbcc5c69 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.spec.js +++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js @@ -12,6 +12,8 @@ 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 store from "@/store"; // Mock our module for promises. jest.mock("@/helpers/layout-helper.js", () => ({ @@ -25,6 +27,8 @@ jest.mock("@/helpers/cms-content-helper", () => ({ // Mock Store jest.mock("@/store", () => ({ + commit: jest.fn(), + dispatch: jest.fn(), getters: { vehicle: { carId: "C00000000", @@ -137,6 +141,28 @@ describe("vehicle-damage.vue", () => { }); }); +describe("vehicle-damage.vue", () => { + test("Call invalidation, ResetPartsAndDeps should be called", async () => { + + //Arrange + const { wrapper } = setupMocks({}); + + //Act + vehicleDamage.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-damage" } }, + undefined, + (c) => c(wrapper.vm) + ); + + wrapper.vm.resetDependentState(); + + //Assert + expect(store.dispatch).toBeCalledWith(storeActions.RESET_PARTS_AND_DEPS) + + }); +}); + function setupMocks({ pageHeaderWidgetHeaderText = {}, mountOptionsMockData = {}, diff --git a/src/layouts/vehicle-make/vehicle-make.spec.js b/src/layouts/vehicle-make/vehicle-make.spec.js index b3a006c20..b2c4dcaf7 100644 --- a/src/layouts/vehicle-make/vehicle-make.spec.js +++ b/src/layouts/vehicle-make/vehicle-make.spec.js @@ -1,15 +1,23 @@ -import { shallowMount, flushPromises } from "@vue/test-utils"; +// Supporting Files +import { shallowMount } from "@vue/test-utils"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; +import { settleAllPromises } from "@/helpers/layout-helper.js"; +import { nextTick } from "vue"; +import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; +import { storeMutations } from "@/constants/store-mutations"; +import { storeActions } from "@/constants/store-actions"; + +// Components import vehicleMake from "@/layouts/vehicle-make/vehicle-make.vue"; import makeQuestion from "@/layouts/vehicle-make/make-question/make-question"; import funnelHeader from "@/common-components/funnel-header/funnel-header"; 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"; +import store from "@/store"; jest.mock("@/store", () => ({ + commit: jest.fn(), + dispatch: jest.fn(), getters: { vehicle: { year: 2019, @@ -27,9 +35,6 @@ jest.mock("@/helpers/layout-helper.js", () => ({ settleAllPromises: jest.fn(), })); -beforeEach(() => { - jest.resetModules(); -}); describe("vehicle-make.vue", () => { test("Make question component is initized with api data", async (done) => { @@ -153,7 +158,7 @@ describe("vehicle-make.vue", () => { pageHeaderWidgetHeaderText: "Select a make to get started", mountOptionsMockData: { router: { - navigateForward: jest.fn(), + navigate: jest.fn(), }, }, }); @@ -170,7 +175,7 @@ describe("vehicle-make.vue", () => { //Assert apiPromise.finally(() => { - expect(wrapper.vm.$router.navigateForward).toHaveBeenCalled(); + expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); done(); }); }); @@ -190,13 +195,40 @@ describe("vehicle-make.vue", () => { ); let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); - await nextTick(); //Assert expect(arePagePrerequisitesValid).toBe(true); }); }); +describe("vehicle-make.vue", () => { + test("Year set, call invalidation, model, style, carId, category should be null", async () => { + + //Arrange + const { wrapper } = setupMocks({}); + + //Act + vehicleMake.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-make" } }, + undefined, + (c) => c(wrapper.vm) + ); + + wrapper.vm.resetDependentState(); + + //Assert + expect(store.commit).toBeCalledWith(storeMutations.UPDATE_MODEL, null) + expect(store.commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null) + expect(store.commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null) + expect(store.commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null) + + expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_AND_DEPS) + expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_AND_DEPS) + + }); +}); + function setupMocks({ vehicleMakeQuestionCmsContent = {}, makeQuestionInitialData = {}, diff --git a/src/layouts/vehicle-make/vehicle-make.vue b/src/layouts/vehicle-make/vehicle-make.vue index f95172547..b7be8f578 100644 --- a/src/layouts/vehicle-make/vehicle-make.vue +++ b/src/layouts/vehicle-make/vehicle-make.vue @@ -78,7 +78,7 @@ export default { methods: { backButtonAction() { // route to move backwards - this.$router.navigateForward( + this.$router.navigate( this.navigationScenarios.CLICKED_BACK, this.$route ); diff --git a/src/layouts/vehicle-model/vehicle-model.spec.js b/src/layouts/vehicle-model/vehicle-model.spec.js index b1e240288..7f8f96eb6 100644 --- a/src/layouts/vehicle-model/vehicle-model.spec.js +++ b/src/layouts/vehicle-model/vehicle-model.spec.js @@ -7,10 +7,13 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he // Supporting files import { settleAllPromises } from "@/helpers/layout-helper.js"; -import { shallowMount, flushPromises } from "@vue/test-utils"; +import { shallowMount } from "@vue/test-utils"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; import { nextTick } from "vue"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; +import { storeMutations } from "@/constants/store-mutations"; +import { storeActions } from "@/constants/store-actions"; +import store from "@/store"; // Mock our module for promises. jest.mock("@/helpers/layout-helper.js", () => ({ @@ -24,6 +27,8 @@ jest.mock("@/helpers/cms-content-helper", () => ({ // Mock Store jest.mock("@/store", () => ({ + commit: jest.fn(), + dispatch: jest.fn(), getters: { vehicle: { make: "Acura", @@ -141,7 +146,7 @@ describe("vehicle-model.vue", () => { pageHeaderWidgetHeaderText: "Select a model to get started", mountOptionsMockData: { router: { - navigateForward: jest.fn(), + navigate: jest.fn(), }, }, }); @@ -156,7 +161,7 @@ describe("vehicle-model.vue", () => { await nextTick(); //Assert apiPromise.finally(() => { - expect(wrapper.vm.$router.navigateForward).toHaveBeenCalled(); + expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); done(); }); }); @@ -182,6 +187,33 @@ describe("vehicle-model.vue", () => { }); }); +describe("vehicle-model.vue", () => { + test("Year set, call invalidation, style, carId, category should be null", async () => { + + //Arrange + const { wrapper } = setupMocks({}); + + //Act + vehicleModel.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-model" } }, + undefined, + (c) => c(wrapper.vm) + ); + + wrapper.vm.resetDependentState(); + + //Assert + expect(store.commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null) + expect(store.commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null) + expect(store.commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null) + + expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_AND_DEPS) + expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_AND_DEPS) + + }); +}); + function setupMocks({ buttonQuestionContent = {}, modelQuestionInitialData = {}, diff --git a/src/layouts/vehicle-model/vehicle-model.vue b/src/layouts/vehicle-model/vehicle-model.vue index 06794e9a2..72faea5a1 100644 --- a/src/layouts/vehicle-model/vehicle-model.vue +++ b/src/layouts/vehicle-model/vehicle-model.vue @@ -79,7 +79,7 @@ export default { methods: { backButtonAction() { // route to move backwards - this.$router.navigateForward( + this.$router.navigate( this.navigationScenarios.CLICKED_BACK, this.$route ); diff --git a/src/layouts/vehicle-style/vehicle-style.spec.js b/src/layouts/vehicle-style/vehicle-style.spec.js index e52818cf6..183b22d57 100644 --- a/src/layouts/vehicle-style/vehicle-style.spec.js +++ b/src/layouts/vehicle-style/vehicle-style.spec.js @@ -154,7 +154,7 @@ describe("vehicle-style.vue", () => { pageHeaderWidgetHeaderText: "Select a style to get started", mountOptionsMockData: { router: { - navigateForward: jest.fn(), + navigate: jest.fn(), }, }, }); @@ -171,7 +171,7 @@ describe("vehicle-style.vue", () => { //Assert apiPromise.finally(() => { - expect(wrapper.vm.$router.navigateForward).toHaveBeenCalled(); + expect(wrapper.vm.$router.navigate).toHaveBeenCalled(); done(); }); }); diff --git a/src/layouts/vehicle-style/vehicle-style.vue b/src/layouts/vehicle-style/vehicle-style.vue index ec1cd4598..8cf948cdc 100644 --- a/src/layouts/vehicle-style/vehicle-style.vue +++ b/src/layouts/vehicle-style/vehicle-style.vue @@ -78,7 +78,7 @@ export default { methods: { backButtonAction() { // route to move backwards - this.$router.navigateForward( + this.$router.navigate( this.navigationScenarios.CLICKED_BACK, this.$route ); diff --git a/src/layouts/vehicle-year/vehicle-year.spec.js b/src/layouts/vehicle-year/vehicle-year.spec.js index 9b27e6555..5ef3ea404 100644 --- a/src/layouts/vehicle-year/vehicle-year.spec.js +++ b/src/layouts/vehicle-year/vehicle-year.spec.js @@ -1,18 +1,35 @@ import { shallowMount, flushPromises } from "@vue/test-utils"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; +import { settleAllPromises } from "@/helpers/layout-helper.js"; +import { nextTick } from "vue"; +import { storeMutations } from "@/constants/store-mutations"; +import { storeActions } from "@/constants/store-actions"; +import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; + import vehicleYear from "@/layouts/vehicle-year/vehicle-year.vue"; import yearQuestion from "@/layouts/vehicle-year/year-question/year-question"; import funnelHeader from "@/common-components/funnel-header/funnel-header"; 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 store from "@/store"; + +jest.mock("@/store", () => ({ + commit: jest.fn(), + dispatch: jest.fn(), +})); // 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(), +})); + + describe("vehicle-year.vue", () => { test("Year question component is initized with api data", async (done) => { //Arrange @@ -123,6 +140,34 @@ describe("vehicle-year.vue", () => { }); }); +describe("vehicle-year.vue", () => { + test("Year set, call invalidation, make, model, style, carId, category should be null", async () => { + + //Arrange + const { wrapper } = setupMocks({}); + + //Act + vehicleYear.beforeRouteEnter.call( + wrapper.vm, + { query: { fmgPage: "vehicle-year" } }, + undefined, + (c) => c(wrapper.vm) + ); + + wrapper.vm.resetDependentState(); + + //Assert + expect(store.commit).toBeCalledWith(storeMutations.UPDATE_MAKE, null) + expect(store.commit).toBeCalledWith(storeMutations.UPDATE_MODEL, null) + expect(store.commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null) + expect(store.commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null) + expect(store.commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null) + + expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_AND_DEPS) + expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_AND_DEPS) + + }); +}); function setupMocks({ vehicleYearQuestionCmsContent = {}, yearQuestionInitialData = {}, @@ -146,7 +191,9 @@ function setupMocks({ yearQuestionInitialData: yearQuestionInitialData, }; const apiPromise = Promise.resolve(apiResponses); + settleAllPromises.mockImplementation(() => apiPromise); + fetchCmsContentForPage.mockImplementation(() => Promise.resolve()); //Mock year question methods yearQuestion.methods = { @@ -162,6 +209,7 @@ function setupMocks({ funnelSubHeader.methods = { initializeComponent: jest.fn(), }; + const mountOptions = getMountOptions(mountOptionsMockData); const wrapper = shallowMount(vehicleYear, mountOptions); const yearQuestionWrapper = wrapper.findComponent({ name: "yearQuestion" }); diff --git a/src/router/index.js b/src/router/index.js index ac31a1c6d..02859e660 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -102,7 +102,7 @@ const router = createRouter({ //---------------------------------------------------------- Router Functions ---------------------------------------------------------- -router.navigateForward = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) => { +router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) => { navigate(scenario, currentRoute, false, optionalQuery, optionalParams); } diff --git a/src/store/index.js b/src/store/index.js index 22107ab76..41a78c5c8 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -35,7 +35,6 @@ export default createStore({ // See IMPORTANT note at top of "state" declaration. mutations: { - // VEHICLE MUTATIONS updateYear(state, year) { state.order.vehicle.year = year; diff --git a/src/store/store.spec.js b/src/store/store.spec.js index e71f07909..0fd96f719 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -1,16 +1,240 @@ -import store from "./index"; import globalMethods from "@/global-methods"; +import store from "@/store"; + +// Mock Store +jest.mock("@/store", () => ({ + commit: jest.fn(), + dispatch: jest.fn(), + // IMPORTANT: Be VERY careful when modifying these fields for at least a few reasons: + // * The CMS can reference the fields by name + // * Return users may have a previous "version" of the model, and we don't want + // them to have a breaking experience, because the model might have changed. + state: { + order: { + vehicle: { + year: null, + make: null, + model: null, + style: null, + carId: null, + category: null, + damage: { + isRepair: null, + numberOfChips: null, + glassToReplace: null, + }, + }, + }, + applicationUser: { + eventBus: [], + }, + }, + // See IMPORTANT note at top of "state" declaration. + + mutations: { + // VEHICLE MUTATIONS + updateYear: jest.fn(), + updateMake: jest.fn(), + updateModel(state, model) { + state.order.vehicle.model = model; + }, + updateStyle(state, style) { + state.order.vehicle.style = style; + }, + updateCarId(state, carId) { + state.order.vehicle.carId = carId; + }, + updateVehicleCategory(state, category) { + state.order.vehicle.category = category; + }, + updateVehicle(state, data) { + state.order.vehicle.carId = data.carId; + state.order.vehicle.category = data.category; + }, + + // EVENT BUS MUTATIONS + addEventToBus(state, event) { + state.applicationUser.eventBus.push(event); + }, + removeEventFromBus(state, eventData) { + const matchedEvent = state.applicationUser.eventBus.find( + ({ category, subCategory }) => + category === eventData.category && + subCategory === eventData.subCategory + ); + const itemIndex = state.applicationUser.eventBus.indexOf(matchedEvent); + + // If the item exists, remove it. + if (itemIndex > -1) { + state.applicationUser.eventBus.splice(itemIndex, 1); + } + }, + + // DEPENDENCY MUTATIONS + resetVehicleAndDependencies(state) { + state.order.vehicle.year = null; + state.order.vehicle.make = null; + state.order.vehicle.model = null; + state.order.vehicle.style = null; + state.order.vehicle.carId = null; + state.order.vehicle.category = null; + }, + resetDamageAndDependencies(state) { + state.order.vehicle.damage.isRepair = null; + state.order.vehicle.damage.numberOfChips = null; + state.order.vehicle.damage.windshieldGlassToReplace = null; + state.order.vehicle.damage.driverSideGlassToReplace = null; + state.order.vehicle.damage.passengerSideGlassToReplace = null; + state.order.vehicle.damage.rearGlassToReplace = null; + + }, + resetRegistrationAndDependencies(state) { + + }, + resetPartsAndDependencies(state) { + + } + }, + getters: { + vehicle: (state) => state.order.vehicle, + eventBusItem: (state) => (eventCategory, eventSubCategory) => { + const matchedEvent = state.applicationUser.eventBus.find( + ({ category, subCategory }) => + category === eventCategory && subCategory === eventSubCategory + ); + + return matchedEvent !== undefined ? matchedEvent.eventValue : undefined; + }, + eventBus: (state) => state.applicationUser.eventBus, + }, + actions: { + // Vehicle API Actions + getVehicleYears(context) { + return globalMethods.callHttpClient({ + method: endpoints.GetVehicleYears.method, + endpoint: endpoints.GetVehicleYears.url, + payload: {}, + }); + }, + lookupVehicleByYmms(context, { year, make, model, style }) { + return globalMethods.callHttpClient({ + method: endpoints.LookupVehicleByYmms.method, + endpoint: `${endpoints.LookupVehicleByYmms.url}/${year}/${make}/${model}/${style}`, + payload: {}, + }); + }, + lookupVehicleByVin(context, { vin }) { + return globalMethods.callHttpClient({ + method: endpoints.LookupVehicleByVin.method, + endpoint: endpoints.LookupVehicleByVin.url, + payload: { + vin: vin, // EX "1J4GW58S4XC541166" + }, + }); + }, + getVehicleMakes(context, { year }) { + return globalMethods.callHttpClient({ + method: endpoints.GetVehicleMakes.method, + endpoint: `${endpoints.GetVehicleMakes.url}/${year}`, + payload: {}, + }); + }, + getVehicleModels(context, { year, make }) { + return globalMethods.callHttpClient({ + method: endpoints.GetVehicleModels.method, + endpoint: `${endpoints.GetVehicleModels.url}/${year}/${make}`, + payload: {}, + }); + }, + getVehicleStyles(context, { year, make, model }) { + return globalMethods.callHttpClient({ + method: endpoints.GetVehicleStyles.method, + endpoint: `${endpoints.GetVehicleStyles.url}/${year}/${make}/${model}`, + payload: {}, + }); + }, + setVehicle(context, { year, make, model, style }) { + return globalMethods + .callHttpClient({ + methods: endpoints.GetVehicle.method, + endpoint: `${endpoints.GetVehicle.url}/${year}/${make}/${model}/${style}`, + payload: {}, + }) + .then((response) => { + context.commit(storeMutations.UPDATE_VEHICLE, response.data); + return response; + }); + }, + getDamageOptions(context, { carId }) { + return globalMethods.callHttpClient({ + methods: endpoints.GetDamageOptions.method, + endpoint: `${endpoints.GetDamageOptions.url}/${carId}`, + payload: {}, + }); + }, + + // DEPENDENCY ACTIONS + resetVehicleAndDependencies(context) { + context.commit(storeMutations.RESET_VEHICLE_AND_DEPS); + context.commit(storeMutations.RESET_DAMAGE_AND_DEPS); + context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS); + }, + resetDamageAndDependencies(context) { + context.commit(storeMutations.RESET_DAMAGE_AND_DEPS); + context.commit(storeMutations.RESET_PARTS_AND_DEPS); + }, + resetRegistrationAndDependencies(context) { + context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS); + context.commit(storeMutations.RESET_PARTS_AND_DEPS) + }, + resetPartsAndDependencies(context) { + context.commit(storeMutations.RESET_PARTS_AND_DEPS); + }, + + // Content API Actions + getRouteInfo(context, { pageName }) { + return globalMethods.callHttpClient({ + method: endpoints.GetRouteInfo.method, + endpoint: endpoints.GetRouteInfo.url, + payload: { + pageName: pageName, + }, + }); + }, + getHomepageName(context) { + return globalMethods.callHttpClient({ + method: endpoints.GetHomepageInfo.method, + endpoint: endpoints.GetHomepageInfo.url, + }); + }, + getPageData(context, { pageName }) { + return globalMethods.callHttpClient({ + method: endpoints.GetPageData.method, + endpoint: `${endpoints.GetPageData.url}/${pageName}`, + payload: {}, + }); + }, + getEvoxImage(context, { relativeUrl }) { + return globalMethods.callMockHttpClient({ + method: endpoints.GetPageData.method, + endpoint: relativeUrl, + payload: {}, + }); + }, + }, +})); describe("Actions", () => { it("Should return list of years retrieved", async () => { // Arrange let years = []; - + console.log(getPageData); // Act globalMethods.callHttpClient = jest.fn(); globalMethods.callHttpClient.mockImplementation(() => { return Promise.resolve({ data: [2023, 2022, 2021] }); }); + await store.dispatch("getVehicleYears").then((response) => { years = response.data; }); From 66aa4190fbf49d28874ef8f8e88ede382b455673 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 1 Feb 2022 22:26:05 -0500 Subject: [PATCH 3/4] Unit test coverage to 89%, redid store / store tests --- jest.config.js | 2 +- src/constants/store-mutations.js | 1 - src/store/index.js | 442 ++++++++--------- src/store/store.spec.js | 784 +++++++++++++------------------ 4 files changed, 559 insertions(+), 670 deletions(-) diff --git a/jest.config.js b/jest.config.js index bce302e5a..36c4507fc 100644 --- a/jest.config.js +++ b/jest.config.js @@ -18,7 +18,7 @@ module.exports = { testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"], coverageThreshold: { global: { - statements: 87, + statements: 89, }, }, }; diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index c52c955f0..f779b11cf 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -7,7 +7,6 @@ const storeMutations = { UPDATE_STYLE: "updateStyle", UPDATE_CAR_ID: "updateCarId", UPDATE_VEHICLE_CATEGORY: "updateVehicleCategory", - UPDATE_VEHICLE: "updateVehicle", // EVENT BUS MUTATIONS ADD_EVENT_TO_BUS: "addEventToBus", diff --git a/src/store/index.js b/src/store/index.js index 41a78c5c8..2d35422a6 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -5,6 +5,227 @@ import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; + +// Export State +export const state = { + order: { + vehicle: { + year: null, + make: null, + model: null, + style: null, + carId: null, + category: null, + damage: { + isRepair: null, + numberOfChips: null, + glassToReplace: null, + }, + }, + }, + applicationUser: { + eventBus: [], + }, +} + +// Export Mutations +export const mutations = { + // VEHICLE MUTATIONS + updateYear(state, year) { + state.order.vehicle.year = year; + }, + updateMake(state, make) { + state.order.vehicle.make = make; + }, + updateModel(state, model) { + state.order.vehicle.model = model; + }, + updateStyle(state, style) { + state.order.vehicle.style = style; + }, + updateCarId(state, carId) { + state.order.vehicle.carId = carId; + }, + updateVehicleCategory(state, category) { + state.order.vehicle.category = category; + }, + + // EVENT BUS MUTATIONS + addEventToBus(state, event) { + state.applicationUser.eventBus.push(event); + }, + removeEventFromBus(state, eventData) { + const matchedEvent = state.applicationUser.eventBus.find( + ({ category, subCategory }) => + category === eventData.category && + subCategory === eventData.subCategory + ); + const itemIndex = state.applicationUser.eventBus.indexOf(matchedEvent); + + // If the item exists, remove it. + if (itemIndex > -1) { + state.applicationUser.eventBus.splice(itemIndex, 1); + } + }, + + // DEPENDENCY MUTATIONS + resetVehicleAndDependencies(state) { + state.order.vehicle.year = null; + state.order.vehicle.make = null; + state.order.vehicle.model = null; + state.order.vehicle.style = null; + state.order.vehicle.carId = null; + state.order.vehicle.category = null; + }, + resetDamageAndDependencies(state) { + state.order.vehicle.damage.isRepair = null; + state.order.vehicle.damage.numberOfChips = null; + state.order.vehicle.damage.windshieldGlassToReplace = null; + state.order.vehicle.damage.driverSideGlassToReplace = null; + state.order.vehicle.damage.passengerSideGlassToReplace = null; + state.order.vehicle.damage.rearGlassToReplace = null; + + }, + resetRegistrationAndDependencies(state) { + + }, + resetPartsAndDependencies(state) { + + } +} + +// Export Getters +export const getters = { + vehicle: (state) => state.order.vehicle, + eventBusItem: (state) => (eventCategory, eventSubCategory) => { + const matchedEvent = state.applicationUser.eventBus.find( + ({ category, subCategory }) => + category === eventCategory && subCategory === eventSubCategory + ); + + return matchedEvent !== undefined ? matchedEvent.eventValue : undefined; + }, + eventBus: (state) => state.applicationUser.eventBus, +} + +// Export Actions +export const actions = { + // Vehicle API Actions + getVehicleYears(context) { + return globalMethods.callHttpClient({ + method: endpoints.GetVehicleYears.method, + endpoint: endpoints.GetVehicleYears.url, + payload: {}, + }); + }, + lookupVehicleByYmms(context, { year, make, model, style }) { + return globalMethods.callHttpClient({ + method: endpoints.LookupVehicleByYmms.method, + endpoint: `${endpoints.LookupVehicleByYmms.url}/${year}/${make}/${model}/${style}`, + payload: {}, + }); + }, + lookupVehicleByVin(context, { vin }) { + return globalMethods.callHttpClient({ + method: endpoints.LookupVehicleByVin.method, + endpoint: endpoints.LookupVehicleByVin.url, + payload: { + vin: vin, // EX "1J4GW58S4XC541166" + }, + }); + }, + getVehicleMakes(context, { year }) { + return globalMethods.callHttpClient({ + method: endpoints.GetVehicleMakes.method, + endpoint: `${endpoints.GetVehicleMakes.url}/${year}`, + payload: {}, + }); + }, + getVehicleModels(context, { year, make }) { + return globalMethods.callHttpClient({ + method: endpoints.GetVehicleModels.method, + endpoint: `${endpoints.GetVehicleModels.url}/${year}/${make}`, + payload: {}, + }); + }, + getVehicleStyles(context, { year, make, model }) { + return globalMethods.callHttpClient({ + method: endpoints.GetVehicleStyles.method, + endpoint: `${endpoints.GetVehicleStyles.url}/${year}/${make}/${model}`, + payload: {}, + }); + }, + setVehicle(context, { year, make, model, style }) { + return globalMethods + .callHttpClient({ + methods: endpoints.GetVehicle.method, + endpoint: `${endpoints.GetVehicle.url}/${year}/${make}/${model}/${style}`, + payload: {}, + }) + .then((response) => { + context.commit(storeMutations.UPDATE_CAR_ID, response.data.carId); + context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, response.data.category); + return response; + }); + }, + getDamageOptions(context, { carId }) { + return globalMethods.callHttpClient({ + methods: endpoints.GetDamageOptions.method, + endpoint: `${endpoints.GetDamageOptions.url}/${carId}`, + payload: {}, + }); + }, + + // DEPENDENCY ACTIONS + resetVehicleAndDependencies(context) { + context.commit(storeMutations.RESET_VEHICLE_AND_DEPS); + context.commit(storeMutations.RESET_DAMAGE_AND_DEPS); + context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS); + }, + resetDamageAndDependencies(context) { + context.commit(storeMutations.RESET_DAMAGE_AND_DEPS); + context.commit(storeMutations.RESET_PARTS_AND_DEPS); + }, + resetRegistrationAndDependencies(context) { + context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS); + context.commit(storeMutations.RESET_PARTS_AND_DEPS) + }, + resetPartsAndDependencies(context) { + context.commit(storeMutations.RESET_PARTS_AND_DEPS); + }, + + // Content API Actions + getRouteInfo(context, { pageName }) { + return globalMethods.callHttpClient({ + method: endpoints.GetRouteInfo.method, + endpoint: endpoints.GetRouteInfo.url, + payload: { + pageName: pageName, + }, + }); + }, + getHomepageName(context) { + return globalMethods.callHttpClient({ + method: endpoints.GetHomepageInfo.method, + endpoint: endpoints.GetHomepageInfo.url, + }); + }, + getPageData(context, { pageName }) { + return globalMethods.callHttpClient({ + method: endpoints.GetPageData.method, + endpoint: `${endpoints.GetPageData.url}/${pageName}`, + payload: {}, + }); + }, + getEvoxImage(context, { relativeUrl }) { + return globalMethods.callHttpClient({ + method: endpoints.GetPageData.method, + endpoint: relativeUrl, + payload: {}, + }); + }, +} + export default createStore({ plugins: [createPersistedState()], @@ -12,221 +233,8 @@ export default createStore({ // * The CMS can reference the fields by name // * Return users may have a previous "version" of the model, and we don't want // them to have a breaking experience, because the model might have changed. - state: { - order: { - vehicle: { - year: null, - make: null, - model: null, - style: null, - carId: null, - category: null, - damage: { - isRepair: null, - numberOfChips: null, - glassToReplace: null, - }, - }, - }, - applicationUser: { - eventBus: [], - }, - }, - // See IMPORTANT note at top of "state" declaration. - - mutations: { - // VEHICLE MUTATIONS - updateYear(state, year) { - state.order.vehicle.year = year; - }, - updateMake(state, make) { - state.order.vehicle.make = make; - }, - updateModel(state, model) { - state.order.vehicle.model = model; - }, - updateStyle(state, style) { - state.order.vehicle.style = style; - }, - updateCarId(state, carId) { - state.order.vehicle.carId = carId; - }, - updateVehicleCategory(state, category) { - state.order.vehicle.category = category; - }, - updateVehicle(state, data) { - state.order.vehicle.carId = data.carId; - state.order.vehicle.category = data.category; - }, - - // EVENT BUS MUTATIONS - addEventToBus(state, event) { - state.applicationUser.eventBus.push(event); - }, - removeEventFromBus(state, eventData) { - const matchedEvent = state.applicationUser.eventBus.find( - ({ category, subCategory }) => - category === eventData.category && - subCategory === eventData.subCategory - ); - const itemIndex = state.applicationUser.eventBus.indexOf(matchedEvent); - - // If the item exists, remove it. - if (itemIndex > -1) { - state.applicationUser.eventBus.splice(itemIndex, 1); - } - }, - - // DEPENDENCY MUTATIONS - resetVehicleAndDependencies(state) { - state.order.vehicle.year = null; - state.order.vehicle.make = null; - state.order.vehicle.model = null; - state.order.vehicle.style = null; - state.order.vehicle.carId = null; - state.order.vehicle.category = null; - }, - resetDamageAndDependencies(state) { - state.order.vehicle.damage.isRepair = null; - state.order.vehicle.damage.numberOfChips = null; - state.order.vehicle.damage.windshieldGlassToReplace = null; - state.order.vehicle.damage.driverSideGlassToReplace = null; - state.order.vehicle.damage.passengerSideGlassToReplace = null; - state.order.vehicle.damage.rearGlassToReplace = null; - - }, - resetRegistrationAndDependencies(state) { - - }, - resetPartsAndDependencies(state) { - - } - }, - getters: { - vehicle: (state) => state.order.vehicle, - eventBusItem: (state) => (eventCategory, eventSubCategory) => { - const matchedEvent = state.applicationUser.eventBus.find( - ({ category, subCategory }) => - category === eventCategory && subCategory === eventSubCategory - ); - - return matchedEvent !== undefined ? matchedEvent.eventValue : undefined; - }, - eventBus: (state) => state.applicationUser.eventBus, - }, - actions: { - // Vehicle API Actions - getVehicleYears(context) { - return globalMethods.callHttpClient({ - method: endpoints.GetVehicleYears.method, - endpoint: endpoints.GetVehicleYears.url, - payload: {}, - }); - }, - lookupVehicleByYmms(context, { year, make, model, style }) { - return globalMethods.callHttpClient({ - method: endpoints.LookupVehicleByYmms.method, - endpoint: `${endpoints.LookupVehicleByYmms.url}/${year}/${make}/${model}/${style}`, - payload: {}, - }); - }, - lookupVehicleByVin(context, { vin }) { - return globalMethods.callHttpClient({ - method: endpoints.LookupVehicleByVin.method, - endpoint: endpoints.LookupVehicleByVin.url, - payload: { - vin: vin, // EX "1J4GW58S4XC541166" - }, - }); - }, - getVehicleMakes(context, { year }) { - return globalMethods.callHttpClient({ - method: endpoints.GetVehicleMakes.method, - endpoint: `${endpoints.GetVehicleMakes.url}/${year}`, - payload: {}, - }); - }, - getVehicleModels(context, { year, make }) { - return globalMethods.callHttpClient({ - method: endpoints.GetVehicleModels.method, - endpoint: `${endpoints.GetVehicleModels.url}/${year}/${make}`, - payload: {}, - }); - }, - getVehicleStyles(context, { year, make, model }) { - return globalMethods.callHttpClient({ - method: endpoints.GetVehicleStyles.method, - endpoint: `${endpoints.GetVehicleStyles.url}/${year}/${make}/${model}`, - payload: {}, - }); - }, - setVehicle(context, { year, make, model, style }) { - return globalMethods - .callHttpClient({ - methods: endpoints.GetVehicle.method, - endpoint: `${endpoints.GetVehicle.url}/${year}/${make}/${model}/${style}`, - payload: {}, - }) - .then((response) => { - context.commit(storeMutations.UPDATE_VEHICLE, response.data); - return response; - }); - }, - getDamageOptions(context, { carId }) { - return globalMethods.callHttpClient({ - methods: endpoints.GetDamageOptions.method, - endpoint: `${endpoints.GetDamageOptions.url}/${carId}`, - payload: {}, - }); - }, - - // DEPENDENCY ACTIONS - resetVehicleAndDependencies(context) { - context.commit(storeMutations.RESET_VEHICLE_AND_DEPS); - context.commit(storeMutations.RESET_DAMAGE_AND_DEPS); - context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS); - }, - resetDamageAndDependencies(context) { - context.commit(storeMutations.RESET_DAMAGE_AND_DEPS); - context.commit(storeMutations.RESET_PARTS_AND_DEPS); - }, - resetRegistrationAndDependencies(context) { - context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS); - context.commit(storeMutations.RESET_PARTS_AND_DEPS) - }, - resetPartsAndDependencies(context) { - context.commit(storeMutations.RESET_PARTS_AND_DEPS); - }, - - // Content API Actions - getRouteInfo(context, { pageName }) { - return globalMethods.callHttpClient({ - method: endpoints.GetRouteInfo.method, - endpoint: endpoints.GetRouteInfo.url, - payload: { - pageName: pageName, - }, - }); - }, - getHomepageName(context) { - return globalMethods.callHttpClient({ - method: endpoints.GetHomepageInfo.method, - endpoint: endpoints.GetHomepageInfo.url, - }); - }, - getPageData(context, { pageName }) { - return globalMethods.callHttpClient({ - method: endpoints.GetPageData.method, - endpoint: `${endpoints.GetPageData.url}/${pageName}`, - payload: {}, - }); - }, - getEvoxImage(context, { relativeUrl }) { - return globalMethods.callMockHttpClient({ - method: endpoints.GetPageData.method, - endpoint: relativeUrl, - payload: {}, - }); - }, - }, + state, + mutations, + getters, + actions, }); diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 0fd96f719..28c727ab9 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -1,552 +1,434 @@ import globalMethods from "@/global-methods"; -import store from "@/store"; +import { mutations, state, actions } from "@/store"; +import { storeMutations } from "@/constants/store-mutations"; -// Mock Store -jest.mock("@/store", () => ({ - commit: jest.fn(), - dispatch: jest.fn(), - // IMPORTANT: Be VERY careful when modifying these fields for at least a few reasons: - // * The CMS can reference the fields by name - // * Return users may have a previous "version" of the model, and we don't want - // them to have a breaking experience, because the model might have changed. - state: { - order: { - vehicle: { - year: null, - make: null, - model: null, - style: null, - carId: null, - category: null, - damage: { - isRepair: null, - numberOfChips: null, - glassToReplace: null, - }, - }, - }, - applicationUser: { - eventBus: [], - }, - }, - // See IMPORTANT note at top of "state" declaration. +// Mock global method +globalMethods.callHttpClient = jest.fn(); - mutations: { - // VEHICLE MUTATIONS - updateYear: jest.fn(), - updateMake: jest.fn(), - updateModel(state, model) { - state.order.vehicle.model = model; - }, - updateStyle(state, style) { - state.order.vehicle.style = style; - }, - updateCarId(state, carId) { - state.order.vehicle.carId = carId; - }, - updateVehicleCategory(state, category) { - state.order.vehicle.category = category; - }, - updateVehicle(state, data) { - state.order.vehicle.carId = data.carId; - state.order.vehicle.category = data.category; - }, +describe("Mutations", () => { - // EVENT BUS MUTATIONS - addEventToBus(state, event) { - state.applicationUser.eventBus.push(event); - }, - removeEventFromBus(state, eventData) { - const matchedEvent = state.applicationUser.eventBus.find( - ({ category, subCategory }) => - category === eventData.category && - subCategory === eventData.subCategory - ); - const itemIndex = state.applicationUser.eventBus.indexOf(matchedEvent); + it("Updates vehicle year in state", () => { + // Arrange + const storeState = state; - // If the item exists, remove it. - if (itemIndex > -1) { - state.applicationUser.eventBus.splice(itemIndex, 1); - } - }, + // Act + mutations.updateYear(storeState, "2019"); - // DEPENDENCY MUTATIONS - resetVehicleAndDependencies(state) { - state.order.vehicle.year = null; - state.order.vehicle.make = null; - state.order.vehicle.model = null; - state.order.vehicle.style = null; - state.order.vehicle.carId = null; - state.order.vehicle.category = null; - }, - resetDamageAndDependencies(state) { - state.order.vehicle.damage.isRepair = null; - state.order.vehicle.damage.numberOfChips = null; - state.order.vehicle.damage.windshieldGlassToReplace = null; - state.order.vehicle.damage.driverSideGlassToReplace = null; - state.order.vehicle.damage.passengerSideGlassToReplace = null; - state.order.vehicle.damage.rearGlassToReplace = null; + // Assert + expect(storeState.order.vehicle.year).toEqual("2019"); + }); - }, - resetRegistrationAndDependencies(state) { + it("Updates vehicle make in state", () => { + // Arrange + const storeState = state; - }, - resetPartsAndDependencies(state) { + // Act + mutations.updateMake(storeState, "Acura"); + // Assert + expect(storeState.order.vehicle.make).toEqual("Acura"); + }); + + it("Updates vehicle model in state", () => { + // Arrange + const storeState = state; + + // Act + mutations.updateModel(storeState, "ILX"); + + // Assert + expect(storeState.order.vehicle.model).toEqual("ILX"); + }); + + it("Updates vehicle style in state", () => { + // Arrange + const storeState = state; + + // Act + mutations.updateStyle(storeState, "4 DOOR SEDAN"); + + // Assert + expect(storeState.order.vehicle.style).toEqual("4 DOOR SEDAN"); + }); + + it("Updates vehicle carId in state", () => { + // Arrange + const storeState = state; + + // Act + mutations.updateCarId(storeState, "C0000001"); + + // Assert + expect(storeState.order.vehicle.carId).toEqual("C0000001"); + }); + + it("Updates vehicle vehicle category in state", () => { + // Arrange + const storeState = state; + + // Act + mutations.updateVehicleCategory(storeState, "CAR"); + + // Assert + expect(storeState.order.vehicle.category).toEqual("CAR"); + }); + + it("Remove item to eventBus in state", () => { + // Arrange + const storeState = state; + const event = { category: "CategoryOne", subCategory: "SubCategoryOne" } + + // Act / Assert + mutations.addEventToBus(storeState, event); + expect(storeState.applicationUser.eventBus).toEqual([event]); + + // Act / Assert + mutations.removeEventFromBus(storeState, event); + expect(storeState.applicationUser.eventBus).toEqual([]); + + }); + + it("Adds item to eventBus in state", () => { + // Arrange + const storeState = state; + + // Act + mutations.addEventToBus(storeState, { EventOne: "ValueOne" }); + + // Assert + expect(storeState.applicationUser.eventBus).toEqual([{ EventOne: "ValueOne" }]); + }); + + it("resetVehicleAndDependencies, should set fields to null", () => { + // Arrange + const storeState = state; + + mutations.updateYear(storeState, "2019"); + mutations.updateMake(storeState, "Acura"); + mutations.updateModel(storeState, "ILX"); + mutations.updateStyle(storeState, "4 DOOR SEDAN"); + mutations.updateCarId(storeState, "C0000001"); + mutations.updateVehicleCategory(storeState, "CAR"); + + // Expect + expect(storeState.order.vehicle.year).toEqual("2019"); + expect(storeState.order.vehicle.make).toEqual("Acura"); + expect(storeState.order.vehicle.model).toEqual("ILX"); + expect(storeState.order.vehicle.style).toEqual("4 DOOR SEDAN"); + expect(storeState.order.vehicle.carId).toEqual("C0000001"); + expect(storeState.order.vehicle.category).toEqual("CAR"); + + // Act + mutations.resetVehicleAndDependencies(storeState); + + // Expect + expect(storeState.order.vehicle.year).toEqual(null); + expect(storeState.order.vehicle.make).toEqual(null); + expect(storeState.order.vehicle.model).toEqual(null); + expect(storeState.order.vehicle.style).toEqual(null); + expect(storeState.order.vehicle.carId).toEqual(null); + expect(storeState.order.vehicle.category).toEqual(null); + + }); + + it("resetDamageAndDependencies, should set fields to null", () => { + // Arrange + const storeState = state; + + storeState.order.vehicle.damage = { + isRepair: true, + numberOfChips: 2, + windshieldGlassToReplace: "Front", + driverSideGlassToReplace: "Rear", + passengerSideGlassToReplace: "Rear", + rearGlassToReplace: "Slider" } - }, - getters: { - vehicle: (state) => state.order.vehicle, - eventBusItem: (state) => (eventCategory, eventSubCategory) => { - const matchedEvent = state.applicationUser.eventBus.find( - ({ category, subCategory }) => - category === eventCategory && subCategory === eventSubCategory - ); - return matchedEvent !== undefined ? matchedEvent.eventValue : undefined; - }, - eventBus: (state) => state.applicationUser.eventBus, - }, - actions: { - // Vehicle API Actions - getVehicleYears(context) { - return globalMethods.callHttpClient({ - method: endpoints.GetVehicleYears.method, - endpoint: endpoints.GetVehicleYears.url, - payload: {}, - }); - }, - lookupVehicleByYmms(context, { year, make, model, style }) { - return globalMethods.callHttpClient({ - method: endpoints.LookupVehicleByYmms.method, - endpoint: `${endpoints.LookupVehicleByYmms.url}/${year}/${make}/${model}/${style}`, - payload: {}, - }); - }, - lookupVehicleByVin(context, { vin }) { - return globalMethods.callHttpClient({ - method: endpoints.LookupVehicleByVin.method, - endpoint: endpoints.LookupVehicleByVin.url, - payload: { - vin: vin, // EX "1J4GW58S4XC541166" - }, - }); - }, - getVehicleMakes(context, { year }) { - return globalMethods.callHttpClient({ - method: endpoints.GetVehicleMakes.method, - endpoint: `${endpoints.GetVehicleMakes.url}/${year}`, - payload: {}, - }); - }, - getVehicleModels(context, { year, make }) { - return globalMethods.callHttpClient({ - method: endpoints.GetVehicleModels.method, - endpoint: `${endpoints.GetVehicleModels.url}/${year}/${make}`, - payload: {}, - }); - }, - getVehicleStyles(context, { year, make, model }) { - return globalMethods.callHttpClient({ - method: endpoints.GetVehicleStyles.method, - endpoint: `${endpoints.GetVehicleStyles.url}/${year}/${make}/${model}`, - payload: {}, - }); - }, - setVehicle(context, { year, make, model, style }) { - return globalMethods - .callHttpClient({ - methods: endpoints.GetVehicle.method, - endpoint: `${endpoints.GetVehicle.url}/${year}/${make}/${model}/${style}`, - payload: {}, - }) - .then((response) => { - context.commit(storeMutations.UPDATE_VEHICLE, response.data); - return response; - }); - }, - getDamageOptions(context, { carId }) { - return globalMethods.callHttpClient({ - methods: endpoints.GetDamageOptions.method, - endpoint: `${endpoints.GetDamageOptions.url}/${carId}`, - payload: {}, - }); - }, + // Expect + expect(storeState.order.vehicle.damage.isRepair).toEqual(true); + expect(storeState.order.vehicle.damage.numberOfChips).toEqual(2); + expect(storeState.order.vehicle.damage.windshieldGlassToReplace).toEqual("Front"); + expect(storeState.order.vehicle.damage.driverSideGlassToReplace).toEqual("Rear"); + expect(storeState.order.vehicle.damage.passengerSideGlassToReplace).toEqual("Rear"); + expect(storeState.order.vehicle.damage.rearGlassToReplace).toEqual("Slider"); - // DEPENDENCY ACTIONS - resetVehicleAndDependencies(context) { - context.commit(storeMutations.RESET_VEHICLE_AND_DEPS); - context.commit(storeMutations.RESET_DAMAGE_AND_DEPS); - context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS); - }, - resetDamageAndDependencies(context) { - context.commit(storeMutations.RESET_DAMAGE_AND_DEPS); - context.commit(storeMutations.RESET_PARTS_AND_DEPS); - }, - resetRegistrationAndDependencies(context) { - context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS); - context.commit(storeMutations.RESET_PARTS_AND_DEPS) - }, - resetPartsAndDependencies(context) { - context.commit(storeMutations.RESET_PARTS_AND_DEPS); - }, + // Act + mutations.resetDamageAndDependencies(storeState); - // Content API Actions - getRouteInfo(context, { pageName }) { - return globalMethods.callHttpClient({ - method: endpoints.GetRouteInfo.method, - endpoint: endpoints.GetRouteInfo.url, - payload: { - pageName: pageName, - }, - }); - }, - getHomepageName(context) { - return globalMethods.callHttpClient({ - method: endpoints.GetHomepageInfo.method, - endpoint: endpoints.GetHomepageInfo.url, - }); - }, - getPageData(context, { pageName }) { - return globalMethods.callHttpClient({ - method: endpoints.GetPageData.method, - endpoint: `${endpoints.GetPageData.url}/${pageName}`, - payload: {}, - }); - }, - getEvoxImage(context, { relativeUrl }) { - return globalMethods.callMockHttpClient({ - method: endpoints.GetPageData.method, - endpoint: relativeUrl, - payload: {}, - }); - }, - }, -})); + // Expect + expect(storeState.order.vehicle.damage.isRepair).toEqual(null); + expect(storeState.order.vehicle.damage.numberOfChips).toEqual(null); + expect(storeState.order.vehicle.damage.windshieldGlassToReplace).toEqual(null); + expect(storeState.order.vehicle.damage.driverSideGlassToReplace).toEqual(null); + expect(storeState.order.vehicle.damage.passengerSideGlassToReplace).toEqual(null); + expect(storeState.order.vehicle.damage.rearGlassToReplace).toEqual(null); + + }); + +}); describe("Actions", () => { - it("Should return list of years retrieved", async () => { + it("getVehicleYears action, should return years array", async () => { + // Arrange - let years = []; - console.log(getPageData); + const context = state; + // Act - globalMethods.callHttpClient = jest.fn(); globalMethods.callHttpClient.mockImplementation(() => { return Promise.resolve({ data: [2023, 2022, 2021] }); }); - await store.dispatch("getVehicleYears").then((response) => { - years = response.data; - }); - // Assert - expect(years[0]).toBe(2023); + const response = await actions.getVehicleYears(context) + + expect(response.data).toEqual([2023, 2022, 2021]); }); - it("Should return list of makes retrieved", async () => { + it("lookupVehicleByYmms action, should return car data", async () => { + // Arrange - let makes = []; + const context = state; // Act globalMethods.callHttpClient.mockImplementation(() => { - return Promise.resolve({ data: ["Baic", "Honda", "Ford"] }); - }); - await store.dispatch("getVehicleMakes", { year: 2023 }).then((response) => { - makes = response.data; + return Promise.resolve({ data: { carId: "C00000001" } }); }); // Assert - expect(makes[0]).toBe("Baic"); + const response = await actions.lookupVehicleByYmms(context, "2019", "Acura", "ILX", "4 DOOR SEDAN") + + expect(response.data).toEqual({ carId: "C00000001" }); }); - it("Should return list of models retrieved", async () => { + it("lookupVehicleByVin action, should return car data", async () => { + // Arrange - let models = []; + const context = state; // Act globalMethods.callHttpClient.mockImplementation(() => { - return Promise.resolve({ data: ["BJ40 (MEX)", "Civic", "Accord"] }); + return Promise.resolve({ data: { carId: "C00000001" } }); }); - await store - .dispatch("getVehicleModels", { year: 2023, make: "Baic" }) - .then((response) => { - models = response.data; - }); // Assert - expect(models[0]).toBe("BJ40 (MEX)"); + const response = await actions.lookupVehicleByVin(context, "12345678901234567") + + expect(response.data).toEqual({ carId: "C00000001" }); }); - it("Should return list of styles retrieved", async () => { + it("getVehicleMakes action, should return makes list", async () => { + // Arrange - let styles = []; + const context = state; // Act globalMethods.callHttpClient.mockImplementation(() => { - return Promise.resolve({ data: ["4 DOOR UTILITY", "2 DOOR"] }); + return Promise.resolve({ data: ["Acura", "Honda"] }); }); - await store - .dispatch("getVehicleStyles", { - year: 2023, - make: "Baic", - model: "BJ40 (MEX)", - }) - .then((response) => { - styles = response.data; - }); // Assert - expect(styles[0]).toBe("4 DOOR UTILITY"); + const response = await actions.getVehicleMakes(context, "2019") + + expect(response.data).toEqual(["Acura", "Honda"]); }); - it("Should return list of damage options retrieved", async () => { + it("getVehicleModels action, should return models list", async () => { + // Arrange - let damageOptions = []; + const context = state; // Act globalMethods.callHttpClient.mockImplementation(() => { - return Promise.resolve({ data: ["Front Window", "Rear Window"] }); + return Promise.resolve({ data: ["ILX", "RDX"] }); }); - await store - .dispatch("getDamageOptions", { - carId: "CR00070154", - }) - .then((response) => { - damageOptions = response.data; - }); // Assert - expect(damageOptions[0]).toBe("Front Window"); + const response = await actions.getVehicleModels(context, "2019", "Acura") + + expect(response.data).toEqual(["ILX", "RDX"]); }); - it("Should return data from url retrieved", async () => { + it("getVehicleStyles action, should return models list", async () => { + // Arrange - let routeInfo = []; + const context = state; // Act globalMethods.callHttpClient.mockImplementation(() => { - return Promise.resolve({ - data: { - Result: "Route Info Data", - }, - }); + return Promise.resolve({ data: { style: "4 DOOR SEDAN" } }); }); - await store - .dispatch("getRouteInfo", { pageName: "vehicle-year" }) - .then((response) => { - routeInfo = response.data.Result; - }); // Assert - expect(routeInfo).toBe("Route Info Data"); + const response = await actions.getVehicleStyles(context, "2019", "Acura", "ILX") + + expect(response.data).toEqual({ style: "4 DOOR SEDAN" }); }); - it("Should return page data from url retrieved", async () => { + it("setVehicle action, should get vehicle data and set carId and vehicle category", async () => { + // Arrange - let pageData = []; + const context = state; + const commit = jest.fn(); + + context.commit = commit; // Act globalMethods.callHttpClient.mockImplementation(() => { - return Promise.resolve({ - data: { - Result: "Page Info Data", - }, - }); + return Promise.resolve({ data: { carId: "C00000000", category: "CAR" } }); }); - await store - .dispatch("getPageData", { pageName: "vehicle-year" }) - .then((response) => { - pageData = response.data.Result; - }); // Assert - expect(pageData).toBe("Page Info Data"); + const response = await actions.setVehicle(context, "C00000000") + + expect(commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, "C00000000"); + expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, "CAR"); + expect(response.data).toEqual({ carId: "C00000000", category: "CAR" }); }); - it("Should return data from url retrieved", async () => { + it("getDamageOptions action", async () => { + // Arrange - let returnData = []; + const context = state; // Act globalMethods.callHttpClient.mockImplementation(() => { - return Promise.resolve({ - data: { - Result: "2018 Honda Civic", - }, - }); + return Promise.resolve({ data: ["Windshield", "DriversFrontDoor"] }); }); - await store - .dispatch("lookupVehicleByYmms", { - year: "2018", - make: "Honda", - model: "Civic", - style: "2 Door", - }) - .then((response) => { - returnData = response.data.Result; - }); + + const response = await actions.getDamageOptions(context, "C00000000") // Assert - expect(returnData).toBe("2018 Honda Civic"); + expect(response.data).toEqual(["Windshield", "DriversFrontDoor"]); }); - it("Should return vehicle data from url retrieved", async () => { + it("resetVehicleAndDependencies action", async () => { + // Arrange - let returnData = []; + const context = state; + const commit = jest.fn(); + + context.commit = commit; // Act + await actions.resetVehicleAndDependencies(context) + + expect(commit).toBeCalledWith(storeMutations.RESET_VEHICLE_AND_DEPS); + expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_AND_DEPS); + expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_AND_DEPS); + + }); + + it("resetDamageAndDependencies action", async () => { + + // Arrange + const context = state; + const commit = jest.fn(); + + context.commit = commit; + + // Act + await actions.resetDamageAndDependencies(context) + + expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_AND_DEPS); + expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS); + + }); + + it("resetRegistrationAndDependencies action", async () => { + + // Arrange + const context = state; + const commit = jest.fn(); + + context.commit = commit; + + // Act + await actions.resetRegistrationAndDependencies(context) + + expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_AND_DEPS); + expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS); + + }); + + it("resetPartsAndDependencies action", async () => { + + // Arrange + const context = state; + const commit = jest.fn(); + + context.commit = commit; + + // Act + await actions.resetPartsAndDependencies(context) + + expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS); + + }); + + it("getRouteInfo action, returns route info", async () => { + + // Arrange + const context = state; + globalMethods.callHttpClient.mockImplementation(() => { - return Promise.resolve({ - data: { - Result: "2021 Honda Civic", - }, - }); + return Promise.resolve({ data: { Widget: "Data" } }); }); - await store - .dispatch("lookupVehicleByVin", { vin: "12345678" }) - .then((response) => { - returnData = response.data.Result; - }); - - // Assert - expect(returnData).toBe("2021 Honda Civic"); - }); - - it("Should return vehicle image data from url retrieved", async () => { - // Arrange - let returnData = []; // Act - globalMethods.callMockHttpClient = jest.fn(); - globalMethods.callMockHttpClient.mockImplementation(() => { - return Promise.resolve({ - data: { - Result: "2008_honda_civic.jpg", - }, - }); + const response = await actions.getRouteInfo(context, "vehicle-year") + + + expect(response.data).toEqual({ Widget: "Data" }); + + }); + + it("getHomepageName action, returns homepage name", async () => { + + // Arrange + const context = state; + + globalMethods.callHttpClient.mockImplementation(() => { + return Promise.resolve({ data: { Name: "vehicle-year" } }); }); - await store - .dispatch("getEvoxImage", { relativeUrl: "evox_image.com" }) - .then((response) => { - returnData = response.data.Result; + + // Act + const response = await actions.getHomepageName(context) + + + expect(response.data).toEqual({ Name: "vehicle-year" }); + + }); + + it("getPageData action, returns page data", async () => { + + // Arrange + const context = state; + + globalMethods.callHttpClient.mockImplementation(() => { + return Promise.resolve({ data: { Results: [{ Widget: "Data" }] } }); + }); + + // Act + const response = await actions.getPageData(context, "vehicle-year") + + + expect(response.data).toEqual({ Results: [{ Widget: "Data" }] }); + + }); + + it("getEvoxImage action, returns image url", async () => { + // Arrange + const context = state; + + globalMethods.callHttpClient.mockImplementation(() => { + return Promise.resolve({ data: { imageUrl: "https://test.com" } }); }); - // Assert - expect(returnData).toBe("2008_honda_civic.jpg"); - }); -}); + // Act + const response = await actions.getEvoxImage(context, { relativeUrl: "https://relativeurl.com" } ); -describe("Mutations", () => { - it("Should update the year property in the store", () => { - // Act - store.commit("updateYear", 2020); - // Assert - expect(store.state.order.vehicle.year).toBe(2020); + expect(response.data).toEqual({ imageUrl: "https://test.com" }); }); - it("Should update the make property in the store", () => { - // Act - store.commit("updateMake", "Honda"); - - // Assert - expect(store.state.order.vehicle.make).toBe("Honda"); - }); - - it("Should update the model property in the store", () => { - // Act - store.commit("updateModel", "Civic"); - - // Assert - expect(store.state.order.vehicle.model).toBe("Civic"); - }); - - it("Should update the style property in the store", () => { - // Act - store.commit("updateStyle", "2 Door"); - - // Assert - expect(store.state.order.vehicle.style).toBe("2 Door"); - }); - - it("Should update the carID and category propertys in the store", () => { - // Arrange - const carData = { - carId: "123abc", - category: "car", - }; - // Act - store.commit("updateVehicle", carData); - - // Assert - expect(store.state.order.vehicle.carId).toBe("123abc"); - expect(store.state.order.vehicle.category).toBe("car"); - }); - - it("Should add event onto bus and update state", () => { - // Arrange - const event = { - category: "TestCategoryOne", - subCategory: "TestSubCategoryOne", - eventValue: "TestEventValueOne", - }; - - // Act - store.commit("addEventToBus", event); - - //Assert - expect(store.state.applicationUser.eventBus[0].category).toBe( - "TestCategoryOne" - ); - expect(store.state.applicationUser.eventBus[0].subCategory).toBe( - "TestSubCategoryOne" - ); - expect(store.state.applicationUser.eventBus[0].eventValue).toBe( - "TestEventValueOne" - ); - }); -}); - -describe("Getters", () => { - it("Should validate vehicle getter", () => { - // Arrange - const vehicle = store.getters.vehicle; - - // Assert - expect(typeof vehicle).toBe("object"); - }); - - it("Should get item from bus via getter", () => { - // Arrange - const event = { - category: "TestCategoryOne", - subCategory: "TestSubCategoryOne", - eventValue: "TestEventValueOne", - }; - - // Act - store.commit("addEventToBus", event); - - // Assert - const returnedEventValue = store.getters.eventBusItem( - event.category, - event.subCategory - ); - expect(returnedEventValue).toBe("TestEventValueOne"); - }); - - it("Should get eventbus from getter, should have length > 0", () => { - // Arrange - const event = { - category: "TestCategoryOne", - subCategory: "TestSubCategoryOne", - eventValue: "TestEventValueOne", - }; - - // Act - store.commit("addEventToBus", event); - - //Assert - expect(store.getters.eventBus.length).toBeGreaterThan(0); - }); -}); +}); \ No newline at end of file From 0765361f5309395e510835fb1ab5cd810537f7ec Mon Sep 17 00:00:00 2001 From: FrankRua Date: Wed, 2 Feb 2022 10:04:30 -0500 Subject: [PATCH 4/4] more tests! --- src/store/index.js | 22 +++++----- src/store/store.spec.js | 93 +++++++++++++++++++++++++++++++---------- 2 files changed, 82 insertions(+), 33 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 2d35422a6..a0c64fcfc 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -16,11 +16,11 @@ export const state = { style: null, carId: null, category: null, - damage: { - isRepair: null, - numberOfChips: null, - glassToReplace: null, - }, + }, + damage: { + isRepair: null, + numberOfChips: null, + glassToReplace: null, }, }, applicationUser: { @@ -78,12 +78,12 @@ export const mutations = { state.order.vehicle.category = null; }, resetDamageAndDependencies(state) { - state.order.vehicle.damage.isRepair = null; - state.order.vehicle.damage.numberOfChips = null; - state.order.vehicle.damage.windshieldGlassToReplace = null; - state.order.vehicle.damage.driverSideGlassToReplace = null; - state.order.vehicle.damage.passengerSideGlassToReplace = null; - state.order.vehicle.damage.rearGlassToReplace = null; + state.order.damage.isRepair = null; + state.order.damage.numberOfChips = null; + state.order.damage.windshieldGlassToReplace = null; + state.order.damage.driverSideGlassToReplace = null; + state.order.damage.passengerSideGlassToReplace = null; + state.order.damage.rearGlassToReplace = null; }, resetRegistrationAndDependencies(state) { diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 28c727ab9..f33595e58 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -1,10 +1,11 @@ import globalMethods from "@/global-methods"; -import { mutations, state, actions } from "@/store"; +import { mutations, state, actions, getters } from "@/store"; import { storeMutations } from "@/constants/store-mutations"; // Mock global method globalMethods.callHttpClient = jest.fn(); + describe("Mutations", () => { it("Updates vehicle year in state", () => { @@ -135,7 +136,7 @@ describe("Mutations", () => { // Arrange const storeState = state; - storeState.order.vehicle.damage = { + storeState.order.damage = { isRepair: true, numberOfChips: 2, windshieldGlassToReplace: "Front", @@ -145,23 +146,23 @@ describe("Mutations", () => { } // Expect - expect(storeState.order.vehicle.damage.isRepair).toEqual(true); - expect(storeState.order.vehicle.damage.numberOfChips).toEqual(2); - expect(storeState.order.vehicle.damage.windshieldGlassToReplace).toEqual("Front"); - expect(storeState.order.vehicle.damage.driverSideGlassToReplace).toEqual("Rear"); - expect(storeState.order.vehicle.damage.passengerSideGlassToReplace).toEqual("Rear"); - expect(storeState.order.vehicle.damage.rearGlassToReplace).toEqual("Slider"); + expect(storeState.order.damage.isRepair).toEqual(true); + expect(storeState.order.damage.numberOfChips).toEqual(2); + expect(storeState.order.damage.windshieldGlassToReplace).toEqual("Front"); + expect(storeState.order.damage.driverSideGlassToReplace).toEqual("Rear"); + expect(storeState.order.damage.passengerSideGlassToReplace).toEqual("Rear"); + expect(storeState.order.damage.rearGlassToReplace).toEqual("Slider"); // Act mutations.resetDamageAndDependencies(storeState); // Expect - expect(storeState.order.vehicle.damage.isRepair).toEqual(null); - expect(storeState.order.vehicle.damage.numberOfChips).toEqual(null); - expect(storeState.order.vehicle.damage.windshieldGlassToReplace).toEqual(null); - expect(storeState.order.vehicle.damage.driverSideGlassToReplace).toEqual(null); - expect(storeState.order.vehicle.damage.passengerSideGlassToReplace).toEqual(null); - expect(storeState.order.vehicle.damage.rearGlassToReplace).toEqual(null); + expect(storeState.order.damage.isRepair).toEqual(null); + expect(storeState.order.damage.numberOfChips).toEqual(null); + expect(storeState.order.damage.windshieldGlassToReplace).toEqual(null); + expect(storeState.order.damage.driverSideGlassToReplace).toEqual(null); + expect(storeState.order.damage.passengerSideGlassToReplace).toEqual(null); + expect(storeState.order.damage.rearGlassToReplace).toEqual(null); }); @@ -417,18 +418,66 @@ describe("Actions", () => { }); it("getEvoxImage action, returns image url", async () => { - // Arrange - const context = state; + // Arrange + const context = state; - globalMethods.callHttpClient.mockImplementation(() => { - return Promise.resolve({ data: { imageUrl: "https://test.com" } }); - }); + globalMethods.callHttpClient.mockImplementation(() => { + return Promise.resolve({ data: { imageUrl: "https://test.com" } }); + }); - // Act - const response = await actions.getEvoxImage(context, { relativeUrl: "https://relativeurl.com" } ); + // Act + const response = await actions.getEvoxImage(context, { relativeUrl: "https://relativeurl.com" }); - expect(response.data).toEqual({ imageUrl: "https://test.com" }); + expect(response.data).toEqual({ imageUrl: "https://test.com" }); + }); + +}); + +describe("Getters", () => { + it("Vehicle getter, should return vehicle data", () => { + // Arrange + const storeState = state; + + // Act + mutations.updateYear(storeState, "2019"); + mutations.updateMake(storeState, "Acura"); + mutations.updateModel(storeState, "ILX"); + + // Assert + expect(getters.vehicle(storeState).year).toEqual("2019"); + expect(getters.vehicle(storeState).make).toEqual("Acura"); + expect(getters.vehicle(storeState).model).toEqual("ILX"); + + }); + + it("Get event bus item by event category and eventSubCategory", () => { + // Arrange + const storeState = state; + const event = { category: "CategoryOne", subCategory: "SubCategoryOne", eventValue: "EventValueOne" }; + + // Act + mutations.addEventToBus(storeState, event); + + // Assert + //expect(storeState.applicationUser.eventBus).toEqual([event]); + expect(getters.eventBusItem(storeState)(event.category, event.subCategory)).toEqual(event.eventValue); + + }); + + it("Get event bus", () => { + // Arrange + const storeState = state; + storeState.applicationUser.eventBus = []; + + const event = { category: "CategoryOne", subCategory: "SubCategoryOne", eventValue: "EventValueOne" }; + + // Act + mutations.addEventToBus(storeState, event); + + // Assert + expect(getters.eventBus(storeState)).toEqual([event]); + }); }); \ No newline at end of file