From 893544d709e4127279f1e1136535a1d63696bcf5 Mon Sep 17 00:00:00 2001 From: Oh Date: Tue, 1 Mar 2022 12:18:56 -0500 Subject: [PATCH 01/58] CSR-98 Try basic routing --- src/layouts/vehicle-damage/vehicle-damage.vue | 9 ++++++++- src/router/router-constants/navigation-scenarios.js | 1 + src/router/router-constants/routing-table.js | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index aa888e14a..203e46abb 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -25,7 +25,7 @@ v-model="selectedRearReplaceOptions" groupName="BackGlassReplaceOptionsQuestion" /> - + @@ -137,6 +137,13 @@ export default { this.$route ); }, + forwardButtonAction() { + console.log("Get estimate!") + this.$router.navigate( + this.navigationScenarios.CLICKED_FORWARD, + this.$route + ); + } }, components: { funnelHeader, diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index 48e36996b..338998d0d 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -4,6 +4,7 @@ const navigationScenarios = { SELECTED_MAKE: "SELECTED_MAKE", SELECTED_STYLE: "SELECTED_STYLE", CLICKED_BACK: "CLICKED_BACK", + CLICKED_FORWARD: "CLICKED_FORWARD" }; export { navigationScenarios }; diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 88c47563c..600def25d 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -57,6 +57,10 @@ const routingTable = [ scenario: navigationScenarios.CLICKED_BACK, destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE, }, + { + scenario: navigationScenarios.CLICKED_FORWARD, + destinationUrl: "http://localhost:38000/default.aspx", + }, ], }, ]; From 6ce8bbec8a3b29ca7bf2d0b19cf87fdbd80dd3db Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 8 Mar 2022 17:24:10 -0500 Subject: [PATCH 02/58] CSR-98 Save on every page and redirect to heritage funnel on one --- src/constants/store-mutations.js | 5 +++ src/global-methods.js | 10 +++++- src/layouts/vehicle-damage/vehicle-damage.vue | 21 +++--------- src/mixins/base-mixin.js | 26 +++++++++++++++ src/router/index.js | 33 +++++++++++++------ src/router/router-constants/routing-table.js | 4 +++ src/store/index.js | 20 +++++++++-- vue.config.js | 2 +- vue.release.config.js | 1 + 9 files changed, 91 insertions(+), 31 deletions(-) diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index c07e88bf2..838018590 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -15,6 +15,11 @@ const storeMutations = { UPDATE_GLASS_TO_REPLACE: "updateGlassToReplace", UPDATE_PARTS: "updateParts", + // ORDER MUTATIONS + UPDATE_REFERRAL_NUMBER: "updateReferralNumber", + UPDATE_REFERRAL_DATE: "updateReferralDate", + UPDATE_REFERRAL_CORRELATION_ID: "updateReferralCorrelationId", + // EVENT BUS MUTATIONS ADD_EVENT_TO_BUS: "addEventToBus", REMOVE_EVENT_FROM_BUS: "removeEventFromBus", diff --git a/src/global-methods.js b/src/global-methods.js index 788d4c2e4..7d82a2590 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -5,7 +5,15 @@ import httpStatusCodes from "http-status-codes"; export default { callHttpClient({ method, endpoint, payload }) { return new Promise((resolve, reject) => { - const apiGatewayUrl = applicationConfig.CONSUMER_APIGATEWAY_URL; + // TODO CSR-98 TEMP FOR TESTING + var apiGatewayUrl = applicationConfig.CONSUMER_APIGATEWAY_URL; + + if (endpoint.includes("order")) { + apiGatewayUrl = "https://localhost:44346"; + } + + + // const apiGatewayUrl = applicationConfig.CONSUMER_APIGATEWAY_URL; const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "FixMyGlass", }); diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index a5de80389..5a9eca92f 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -25,7 +25,7 @@ v-model="selectedRearReplaceOptions" groupName="BackGlassReplaceOptionsQuestion" /> - + @@ -49,6 +49,7 @@ import baseMixin from "@/mixins/base-mixin"; import { damageLocationsParts } from "@/constants/damage-locations-parts.js"; import { damageLocationsCms } from "@/constants/damage-locations-cms.js"; + export default { name: "vehicle-damage", async beforeRouteEnter(to, from, next) { @@ -129,6 +130,7 @@ export default { this.$route ); }, + async forwardButtonAction() { var windshieldChipCount = this.selectedWindshieldOptions.selectedWindshieldChipCount && this.isWindshieldDamageLocation ? this.selectedWindshieldOptions.selectedWindshieldChipCount[0] : null; @@ -143,26 +145,11 @@ export default { var partsData = await baseMixin.methods.dispatchNonBlockingStoreAction(this.storeActions.GET_PARTS_OR_QUESTIONS, { carId: store.getters.vehicle.carId, glassArray: this.selectedGlassToReplace()}, false); - - /******** START CSR-98 ********/ - var savedOrderInfo = await baseMixin.methods.dispatchNonBlockingStoreAction(this.storeActions.SAVE_ORDER); - console.log(savedOrderInfo) - /******** END CSR-98 ********/ this.navigateForward(partsData); }, + navigateForward(partsData){ - /******** START CSR-98 ********/ - console.log("Get estimate!") - - // this.$router.navigate( - // this.navigationScenarios.CLICKED_FORWARD, - // this.$route - // ); - /******** END CSR-98 ********/ - - - //found problem questions if (partsData.data.partsOrQuestions.some(pq => pq.partQuestions != null && pq.partQuestions.length > 0)){ this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_DAMAGE_WITH_PART_QUESTIONS, this.$route, {}, {}, partsData.data); diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index d46841b6a..47407c81f 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -1,9 +1,11 @@ import store from "@/store"; +import router from "@/router"; import { storeActions } from "@/constants/store-actions.js"; import { storeMutations } from "@/constants/store-mutations.js"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import { widgetNames } from "@/constants/widget-names.js"; import { vehicleCategories } from "@/constants/vehicle-categories.js"; +import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; export default { data() { @@ -20,6 +22,30 @@ export default { }, savePageDataToStore(page, data){ store.commit(storeMutations.UPDATE_PAGE_DATA, { page: page, data: data }); + }, + async saveOrder() { + var savedOrderInfo = (await this.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER)).data; + store.commit(storeMutations.UPDATE_REFERRAL_NUMBER, savedOrderInfo.referralNumber); + store.commit(storeMutations.UPDATE_REFERRAL_DATE, savedOrderInfo.referralDate); + store.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, savedOrderInfo.referralCorrelationId); + + // console.log(router) + // console.log(router.currentRoute.value.name) + // if (router.currentRoute.value.name) + // this.navigateToHeritageFunnel() + }, + navigateToHeritageFunnel() { + console.log("Get estimate!") + var referralCorrelationId = store.getters.referralCorrelationId; + + router.navigate( + navigationScenarios.CLICKED_FORWARD, + router.currentRoute.value, + { + corid: referralCorrelationId, + src: "concept-funnel" + } + ); } }, computed: { diff --git a/src/router/index.js b/src/router/index.js index 0d98f6698..c792a9bc1 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -132,6 +132,9 @@ function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, return; } + // here?? CSR-98 + baseMixin.methods.saveOrder(); + // Match our maps up and navigate if we have a destination. const matchingScenarioMap = getNavigationMap(scenario, currentRoute); @@ -148,15 +151,20 @@ function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, // Append page data to the store for the NEXT page, if any. It will be an empty object if none is provided. baseMixin.methods.savePageDataToStore(matchingScenarioMap.destinationFmgPageValue, optionalPageData); - router.push({ - name: "root", - query: Object.assign(optionalQuery, { - fmgPage: matchingScenarioMap.destinationFmgPageValue, - }), - params: optionalParams, - }); + // TODO CSR-98 don't hardcode this + if (currentRoute.name == "vehicle-damage") + baseMixin.methods.navigateToHeritageFunnel() + else { + router.push({ + name: "root", + query: Object.assign(optionalQuery, { + fmgPage: matchingScenarioMap.destinationFmgPageValue, + }), + params: optionalParams, + }); + } } else if (matchingScenarioMap.destinationUrl !== undefined) { - navigateToUrl(matchingScenarioMap.destinationUrl); + navigateToUrl(matchingScenarioMap.destinationUrl, optionalQuery); } } @@ -177,9 +185,14 @@ function getNavigationMap(scenario, currentRoute) { //---------------------------------------------------------- Private Functions ---------------------------------------------------------- // Navigate to an external url. -function navigateToUrl(url) { +function navigateToUrl(url, optionalQuery) { // possibly show some loading screen in the future here. - window.location.assign(url); + var externalUrl = new URL(url); + + for (const queryKey in optionalQuery) { + externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]); + } + window.location.assign(externalUrl); } // Get route information by page name. diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 2712c53d2..a6773cd62 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -87,6 +87,10 @@ const routingTable = [ scenario: navigationScenarios.SELECTED_PARTS, destinationFmgPageValue: fmgPageValues.QUOTE, }, + { + scenario: navigationScenarios.CLICKED_FORWARD, + destinationUrl: externalUrls.HERITAGE_FUNNEL, + }, ], }, ]; diff --git a/src/store/index.js b/src/store/index.js index cbab3a84a..2ade585cc 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -29,8 +29,9 @@ export const state = { glassParts: null, otherParts: null }, - referralSeqNum: null, - correlationId: null, + referralNumber: null, + referralDate: null, + referralCorrelationId: null, }, applicationUser: { eventBus: [], @@ -83,6 +84,15 @@ export const mutations = { updatePageData(state, pageData){ state.applicationUser.pageData[pageData.page] = pageData.data; }, + updateReferralCorrelationId(state, referralCorrelationId) { + state.order.referralCorrelationId = referralCorrelationId; + }, + updateReferralNumber(state, referralNumber) { + state.order.referralNumber = referralNumber; + }, + updateReferralDate(state, referralDate) { + state.order.referralDate = referralDate; + }, // EVENT BUS MUTATIONS addEventToBus(state, event) { @@ -144,6 +154,9 @@ export const getters = { eventBus: (state) => state.applicationUser.eventBus, damage: (state) => state.order.damage, lineItems: (state) => state.order.lineItems, + referralNumber: (state) => state.order.referralNumber, + referralDate: (state) => state.order.referralDate, + referralCorrelationId: (state) => state.order.referralCorrelationId, pageData: (state) => (page) => { return state.applicationUser.pageData[page]; } @@ -300,6 +313,9 @@ export const actions = { style: vehicle.style, }, numberOfChips: damage.numberOfChips, + glassToReplace: damage.glassToReplace, + referralNumber: context.getters.referralNumber, + referralDate: context.getters.referralDate }, }); }, diff --git a/vue.config.js b/vue.config.js index 144c143bb..704ca0907 100644 --- a/vue.config.js +++ b/vue.config.js @@ -23,5 +23,5 @@ module.exports = { }, configureWebpack: { devtool: 'source-map' - } + }, }; diff --git a/vue.release.config.js b/vue.release.config.js index 43fffb47f..3c281dc78 100644 --- a/vue.release.config.js +++ b/vue.release.config.js @@ -1,4 +1,5 @@ process.env.VUE_APP_CONSUMER_API_GATEWAY = "__VUE_APP_CONSUMER_API_GATEWAY__"; +process.env.VUE_APP_HERITAGE_FUNNEL = "__VUE_APP_HERITAGE_FUNNEL__"; module.exports = { outputDir: "dist/fmg", From 2f12273f57ec85f8e5482851151a1ef5ab9532f7 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Wed, 9 Mar 2022 14:03:36 -0500 Subject: [PATCH 03/58] Parameter on navigate --- src/router/index.js | 5 +++-- src/router/router-constants/router-parameter-keys.js | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/router/index.js b/src/router/index.js index be434e9d8..3d182ba37 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,10 +1,11 @@ // Supporting files import { createWebHistory, createRouter } from "vue-router"; import { storeActions } from "@/constants/store-actions"; -import baseMixin from "@/mixins/base-mixin"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; +import { routerParameterKeys } from '@/router/router-constants/router-parameter-keys' +import baseMixin from "@/mixins/base-mixin"; import eventBus from "@/helpers/event-bus/event-bus"; import store from "@/store"; @@ -153,7 +154,7 @@ function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, query: Object.assign(optionalQuery, { fmgPage: matchingScenarioMap.destinationFmgPageValue, }), - params: optionalParams, + params: Object.assign(optionalParams, {[routerParameterKeys.FROM_ROUTER_NAVIGATE]: true}) }); } else if (matchingScenarioMap.destinationUrl !== undefined) { navigateToUrl(matchingScenarioMap.destinationUrl); diff --git a/src/router/router-constants/router-parameter-keys.js b/src/router/router-constants/router-parameter-keys.js index 0c75eb738..7ace86f37 100644 --- a/src/router/router-constants/router-parameter-keys.js +++ b/src/router/router-constants/router-parameter-keys.js @@ -1,3 +1,5 @@ -const routerParameterKeys = { }; +const routerParameterKeys = { + FROM_ROUTER_NAVIGATE: 'fromRouterNavigate', + }; export { routerParameterKeys }; \ No newline at end of file From d1fb7db451ffef37b840c62c06aebc7c37b86b7b Mon Sep 17 00:00:00 2001 From: Katie Date: Fri, 11 Mar 2022 12:22:35 -0500 Subject: [PATCH 04/58] CSR-98 Read cookie values and remove as needed --- src/constants/store-actions.js | 1 + src/constants/store-mutations.js | 1 + src/mixins/base-mixin.js | 25 ++++--- src/router/index.js | 24 ++++++- src/router/router-constants/routing-table.js | 5 +- src/store/index.js | 68 +++++++++++--------- 6 files changed, 80 insertions(+), 44 deletions(-) diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index e5d57cdf1..84ecf77e6 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -19,6 +19,7 @@ const storeActions = { RESET_DAMAGE_STATE_AND_DEPENDENCIES: "resetDamageAndDependencies", RESET_REGISTRATION_STATE_AND_DEPENDENCIES: "resetRegistrationAndDependencies", RESET_PARTS_STATE_AND_DEPENDENCIES: "resetPartsAndDependencies", + RESET_STATE: "resetState", }; export { storeActions }; diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 838018590..d6ee3b321 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -29,6 +29,7 @@ const storeMutations = { RESET_DAMAGE_STATE: "resetDamageState", RESET_REGISTRATION_STATE: "resetRegistrationState", RESET_PARTS_STATE: "resetPartsState", + RESET_STATE: "resetState", // OTHER MUTATIONS UPDATE_PAGE_DATA: "updatePageData", diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 47407c81f..5543c681c 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -5,7 +5,6 @@ import { storeMutations } from "@/constants/store-mutations.js"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import { widgetNames } from "@/constants/widget-names.js"; import { vehicleCategories } from "@/constants/vehicle-categories.js"; -import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; export default { data() { @@ -28,14 +27,21 @@ export default { store.commit(storeMutations.UPDATE_REFERRAL_NUMBER, savedOrderInfo.referralNumber); store.commit(storeMutations.UPDATE_REFERRAL_DATE, savedOrderInfo.referralDate); store.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, savedOrderInfo.referralCorrelationId); - - // console.log(router) - // console.log(router.currentRoute.value.name) - // if (router.currentRoute.value.name) - // this.navigateToHeritageFunnel() + }, + getCookieValue(cookieName) { + return document.cookie + ?.split("; ") + ?.find(row => row.startsWith(`${cookieName}=`)) + ?.split("=")[1]; + }, + setCookieValue(cookieName, cookieValue) { + document.cookie = `${cookieName}=${cookieValue}`; + }, + deleteCookie(cookieName) { + console.log("D") + document.cookie = `${cookieName}=; Max-Age=0; path=/; domain=${location.hostname}`; }, navigateToHeritageFunnel() { - console.log("Get estimate!") var referralCorrelationId = store.getters.referralCorrelationId; router.navigate( @@ -43,7 +49,10 @@ export default { router.currentRoute.value, { corid: referralCorrelationId, - src: "concept-funnel" + src: "concept-funnel", + // TODO CSR-98 REMOVE THIS + cns: "all", + experiments: "ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" } ); } diff --git a/src/router/index.js b/src/router/index.js index 33b7190ad..ba1725bd3 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -50,6 +50,24 @@ const routes = [ path: "/", name: "root", async beforeEnter(to, from, next) { + // TODO CSR-98 Also triggers on refresh... should it though? + // Entering the concept funnel + if (from.redirectedFrom === undefined) { + // TODO CSR-98 Don't hardcode cookie name "OrderInfo" + var orderInfoJson = baseMixin.methods.getCookieValue("OrderInfo"); + var orderInfo = orderInfoJson == null ? null : JSON.parse(orderInfoJson); + + if (orderInfo?.ShouldResetState) { + store.dispatch(storeActions.RESET_STATE); + } + else { + // should load referral here + } + + // Delete cookie once state is loaded or reset + baseMixin.methods.deleteCookie("OrderInfo"); + } + // If we have no query string, or we don't have the FmgPage query string. if (to.query.fmgPage === undefined) { await GoToFunnelStartOn404(next); @@ -57,7 +75,6 @@ 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 component = router.getRoutes().filter((x) => x.name === to.query.fmgPage)[0].components; @@ -152,8 +169,9 @@ function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, baseMixin.methods.savePageDataToStore(matchingScenarioMap.destinationFmgPageValue, optionalPageData); // TODO CSR-98 don't hardcode this - if (currentRoute.name == "vehicle-damage") - baseMixin.methods.navigateToHeritageFunnel() + if (currentRoute.name == "vehicle-damage") { + baseMixin.methods.navigateToHeritageFunnel(); + } else { router.push({ name: "root", diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 766f4f95a..e4c657a1d 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -85,15 +85,12 @@ const routingTable = [ }, { scenario: navigationScenarios.SELECTED_PARTS, -<<<<<<< HEAD destinationFmgPageValue: fmgPageValues.QUOTE, }, { scenario: navigationScenarios.CLICKED_FORWARD, - destinationUrl: externalUrls.HERITAGE_FUNNEL, -======= + // destinationUrl: externalUrls.HERITAGE_FUNNEL, destinationFmgPageValue: fmgPageValues.REVEAL, ->>>>>>> develop }, ], }, diff --git a/src/store/index.js b/src/store/index.js index 6097d5896..8e5e801c5 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -7,37 +7,41 @@ import globalMethods from "@/global-methods"; // Export State -export const state = { - order: { - vehicle: { - year: null, - make: null, - model: null, - style: null, - carId: null, - category: null, - imageUrl: null, - imageVifNumber: null, - imageColor: null, +const getDefaultState = () => { + return { + order: { + vehicle: { + year: null, + make: null, + model: null, + style: null, + carId: null, + category: null, + imageUrl: null, + imageVifNumber: null, + imageColor: null, + }, + damage: { + isRepair: null, + numberOfChips: null, + glassToReplace: null, + }, + lineItems:{ + glassParts: null, + otherParts: null + }, + referralNumber: null, + referralDate: null, + referralCorrelationId: null, }, - damage: { - isRepair: null, - numberOfChips: null, - glassToReplace: null, + applicationUser: { + eventBus: [], + pageData: {} }, - lineItems:{ - glassParts: null, - otherParts: null - }, - referralNumber: null, - referralDate: null, - referralCorrelationId: null, - }, - applicationUser: { - eventBus: [], - pageData: {} - }, -} + } +}; + +export const state = getDefaultState(); // Export Mutations export const mutations = { @@ -136,6 +140,9 @@ export const mutations = { resetPartsState(state) { state.order.lineItems.glassParts = null; state.order.lineItems.otherParts = null; + }, + resetState(state) { + Object.assign(state, getDefaultState()); } } @@ -249,6 +256,9 @@ export const actions = { resetPartsAndDependencies(context) { context.commit(storeMutations.RESET_PARTS_STATE); }, + resetState(context) { + context.commit(storeMutations.RESET_STATE); + }, // Content API Actions getRouteInfo(context, { pageName }) { From 399624af8d97436f2982af6163dc63c549046033 Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 15 Mar 2022 15:17:38 -0400 Subject: [PATCH 05/58] CSR-98 Add variable for cookieName OrderInfo --- src/constants/cookie-names.js | 6 ++ src/layouts/vehicle-damage/vehicle-damage.vue | 6 ++ src/mixins/base-mixin.js | 3 +- src/mixins/base-mixin.spec.js | 2 + src/router/index.js | 67 ++++++++++--------- .../router-constants/navigation-scenarios.js | 3 +- src/router/router-constants/routing-table.js | 4 +- 7 files changed, 56 insertions(+), 35 deletions(-) create mode 100644 src/constants/cookie-names.js diff --git a/src/constants/cookie-names.js b/src/constants/cookie-names.js new file mode 100644 index 000000000..33a76ae43 --- /dev/null +++ b/src/constants/cookie-names.js @@ -0,0 +1,6 @@ +const cookieNames = { + ORDER_INFO: "OrderInfo" +}; + +export { cookieNames }; + \ No newline at end of file diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index df457d24c..aeb4e8ac6 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -294,6 +294,12 @@ export default { }, navigateForward(partsData){ + // CSR-98 TEMP + if (store.getters.vehicle.year == 2010) { + this.navigateToHeritageFunnel(); + return; + } + //found problem questions if (partsData.data.partsOrQuestions.some(pq => pq.partQuestions != null && pq.partQuestions.length > 0)){ this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_DAMAGE_WITH_PART_QUESTIONS, this.$route, {}, {}, partsData.data); diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 5543c681c..8fdd6dd8d 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -38,14 +38,13 @@ export default { document.cookie = `${cookieName}=${cookieValue}`; }, deleteCookie(cookieName) { - console.log("D") document.cookie = `${cookieName}=; Max-Age=0; path=/; domain=${location.hostname}`; }, navigateToHeritageFunnel() { var referralCorrelationId = store.getters.referralCorrelationId; router.navigate( - navigationScenarios.CLICKED_FORWARD, + navigationScenarios.MOVE_TO_HERITAGE_FUNNEL, router.currentRoute.value, { corid: referralCorrelationId, diff --git a/src/mixins/base-mixin.spec.js b/src/mixins/base-mixin.spec.js index da684af1b..e1599a319 100644 --- a/src/mixins/base-mixin.spec.js +++ b/src/mixins/base-mixin.spec.js @@ -79,6 +79,8 @@ describe("baseMixin.js", () => { }); }); + + function getMixInInstance({ isDispatchSuccess = true }) { // Mock Store const storeDispatch = jest.fn(); diff --git a/src/router/index.js b/src/router/index.js index ba1725bd3..8d9876a74 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -7,6 +7,7 @@ import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; import eventBus from "@/helpers/event-bus/event-bus"; import store from "@/store"; +import { cookieNames } from "@/constants/cookie-names"; // Components import ComponentTest from "@/layouts/component-test/component-test.vue"; @@ -53,19 +54,7 @@ const routes = [ // TODO CSR-98 Also triggers on refresh... should it though? // Entering the concept funnel if (from.redirectedFrom === undefined) { - // TODO CSR-98 Don't hardcode cookie name "OrderInfo" - var orderInfoJson = baseMixin.methods.getCookieValue("OrderInfo"); - var orderInfo = orderInfoJson == null ? null : JSON.parse(orderInfoJson); - - if (orderInfo?.ShouldResetState) { - store.dispatch(storeActions.RESET_STATE); - } - else { - // should load referral here - } - - // Delete cookie once state is loaded or reset - baseMixin.methods.deleteCookie("OrderInfo"); + handleInfoFromHeritageFunnel(); } // If we have no query string, or we don't have the FmgPage query string. @@ -149,13 +138,14 @@ function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, return; } - // here?? CSR-98 - baseMixin.methods.saveOrder(); + // // here?? CSR-98 + // baseMixin.methods.saveOrder(); // Match our maps up and navigate if we have a destination. const matchingScenarioMap = getNavigationMap(scenario, currentRoute); + const destinationFmgPageValue = matchingScenarioMap.destinationFmgPageValue; - if (matchingScenarioMap.destinationFmgPageValue !== undefined) { + if (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 @@ -166,22 +156,22 @@ function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, } // Append page data to the store for the NEXT page, if any. It will be an empty object if none is provided. - baseMixin.methods.savePageDataToStore(matchingScenarioMap.destinationFmgPageValue, optionalPageData); + baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); - // TODO CSR-98 don't hardcode this - if (currentRoute.name == "vehicle-damage") { - baseMixin.methods.navigateToHeritageFunnel(); - } - else { - router.push({ - name: "root", - query: Object.assign(optionalQuery, { - fmgPage: matchingScenarioMap.destinationFmgPageValue, - }), - params: optionalParams, - }); - } + baseMixin.methods.saveOrder(); + + router.push({ + name: "root", + query: Object.assign(optionalQuery, { + fmgPage: destinationFmgPageValue, + }), + params: optionalParams, + }); } else if (matchingScenarioMap.destinationUrl !== undefined) { + if (matchingScenarioMap.shouldNavigateToHeritageFunnel) { + baseMixin.methods.saveOrder(); + } + navigateToUrl(matchingScenarioMap.destinationUrl, optionalQuery); } } @@ -210,6 +200,7 @@ function navigateToUrl(url, optionalQuery) { for (const queryKey in optionalQuery) { externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]); } + window.location.assign(externalUrl); } @@ -267,4 +258,20 @@ function resetDependentState(component) { return component.default.methods.resetDependentState(); } +// Read info from heritage funnel and reset state or load referral +function handleInfoFromHeritageFunnel() { + var orderInfoJson = baseMixin.methods.getCookieValue(cookieNames.ORDER_INFO); + var orderInfo = orderInfoJson == null ? null : JSON.parse(orderInfoJson); + + if (orderInfo?.ShouldResetState) { + store.dispatch(storeActions.RESET_STATE); + } + else if (orderInfo != null) { + // should load referral here + } + + // Delete cookie once state is loaded or reset + baseMixin.methods.deleteCookie(cookieNames.ORDER_INFO); +} + export default router; \ No newline at end of file diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index 55efdcaec..972944d80 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -8,7 +8,8 @@ const navigationScenarios = { SELECTED_PARTS: "SELECTED_PARTS", SELECTED_DAMAGE_WITH_SINGLE_PART: "SELECTED_DAMAGE_WITH_SINGLE_PART", SELECTED_DAMAGE_WITH_MULTIPLE_PARTS: "SELECTED_DAMAGE_WITH_MULTIPLE_PARTS", - SELECTED_DAMAGE_WITH_PART_QUESTIONS: "SELECTED_DAMAGE_WITH_PART_QUESTIONS" + SELECTED_DAMAGE_WITH_PART_QUESTIONS: "SELECTED_DAMAGE_WITH_PART_QUESTIONS", + MOVE_TO_HERITAGE_FUNNEL: "MOVE_TO_HERITAGE_FUNNEL", }; export { navigationScenarios }; diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 70e47c832..8fc8ad013 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -59,8 +59,9 @@ const routingTable = [ destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE, }, { - scenario: navigationScenarios.CLICKED_FORWARD, + scenario: navigationScenarios.MOVE_TO_HERITAGE_FUNNEL, destinationUrl: externalUrls.HERITAGE_FUNNEL, + shouldNavigateToHeritageFunnel: true }, { scenario: navigationScenarios.SELECTED_DAMAGE_WITH_SINGLE_PART, @@ -89,7 +90,6 @@ const routingTable = [ }, { scenario: navigationScenarios.CLICKED_FORWARD, - // destinationUrl: externalUrls.HERITAGE_FUNNEL, destinationFmgPageValue: fmgPageValues.REVEAL, }, ], From 6a17e122eabdf69dcbb46cdb90838f679065fdca Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 15 Mar 2022 16:13:29 -0400 Subject: [PATCH 06/58] CSR-98 Move functions into heritage-integration-helper --- src/helpers/heritage-integration-helper.js | 57 +++++++++++++++++++ .../heritage-integration-helper.spec.js | 41 +++++++++++++ src/layouts/vehicle-damage/vehicle-damage.vue | 3 +- src/mixins/base-mixin.js | 33 ----------- src/mixins/base-mixin.spec.js | 5 +- src/router/index.js | 22 +------ 6 files changed, 106 insertions(+), 55 deletions(-) create mode 100644 src/helpers/heritage-integration-helper.js create mode 100644 src/helpers/heritage-integration-helper.spec.js diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js new file mode 100644 index 000000000..95ee7ef09 --- /dev/null +++ b/src/helpers/heritage-integration-helper.js @@ -0,0 +1,57 @@ +import { storeActions } from "@/constants/store-actions.js"; +import { storeMutations } from "@/constants/store-mutations.js"; +import { cookieNames } from "@/constants/cookie-names"; +import store from "@/store"; +import router from "@/router"; +import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; +import baseMixin from "../mixins/base-mixin"; + +// Read info from heritage funnel and reset state or load referral +export function handleInfoFromHeritageFunnel() { + var orderInfoJson = getHeritageCookieValue(); + var orderInfo = orderInfoJson == null ? null : JSON.parse(orderInfoJson); + + if (orderInfo?.ShouldResetState) { + store.dispatch(storeActions.RESET_STATE); + } + else if (orderInfo != null) { + // should load referral here + } + + // Delete cookie once state is loaded or reset + deleteHeritageCookie(); +} + +export function navigateToHeritageFunnel() { + var referralCorrelationId = store.getters.referralCorrelationId; + + router.navigate( + navigationScenarios.MOVE_TO_HERITAGE_FUNNEL, + router.currentRoute.value, + { + corid: referralCorrelationId, + src: "concept-funnel", + // TODO CSR-98 REMOVE THIS + cns: "all", + experiments: "ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" + } + ); +} + +export async function saveOrder() { + var savedOrderInfo = (await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER)).data; + store.commit(storeMutations.UPDATE_REFERRAL_NUMBER, savedOrderInfo.referralNumber); + store.commit(storeMutations.UPDATE_REFERRAL_DATE, savedOrderInfo.referralDate); + store.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, savedOrderInfo.referralCorrelationId); +} + +export function getHeritageCookieValue() { + return document.cookie + ?.split("; ") + ?.find(row => row.startsWith(`${cookieNames.ORDER_INFO}=`)) + ?.split("=")[1]; +} + +export function deleteHeritageCookie() { + document.cookie = `${cookieNames.ORDER_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; +} \ No newline at end of file diff --git a/src/helpers/heritage-integration-helper.spec.js b/src/helpers/heritage-integration-helper.spec.js new file mode 100644 index 000000000..9f49b4565 --- /dev/null +++ b/src/helpers/heritage-integration-helper.spec.js @@ -0,0 +1,41 @@ + + // test("getCookieValue: Gets correct cookie value", () => { + // // Arrange + // const mixIn = getMixInInstance({}); + // const testCookieName = "testCookie"; + // const testCookieValue = "testCookieValue"; + + // document.cookie = `yearMakeModel=2020 ACURA MDX;`; + // document.cookie = `SavedQuoteID=d2770645-0680-4852-9649-6170659b1bd6;`; + // document.cookie = `${testCookieName}=${testCookieValue};`; + // document.cookie = `EMBEDDEDPAYMENTPAGE_PAYPAL_SUBMITBUTTON=COMPLETED;`; + // document.cookie = `orderconfirmation=7411543;`; + + // console.log(document.cookie) + + // // Act + // const actualCookieValue = mixIn.methods.getCookieValue(testCookieName); + + // // Assert + // expect(actualCookieValue).toEqual(testCookieValue); + // expect(document.cookie).toEqual(`yearMakeModel=2020 ACURA MDX; SavedQuoteID=d2770645-0680-4852-9649-6170659b1bd6; ${testCookieName}=${testCookieValue}; EMBEDDEDPAYMENTPAGE_PAYPAL_SUBMITBUTTON=COMPLETED; orderconfirmation=7411543`); + // clearCookies(); + // }); + + // test("getCookieValue: Gets undefined cookie value", () => { + // // Arrange + // const mixIn = getMixInInstance({}); + // const testCookieName = "testCookie"; + + // document.cookie = `yearMakeModel=2020 ACURA MDX;`; + // document.cookie = `SavedQuoteID=d2770645-0680-4852-9649-6170659b1bd6;`; + // document.cookie = `EMBEDDEDPAYMENTPAGE_PAYPAL_SUBMITBUTTON=COMPLETED;`; + // document.cookie = `orderconfirmation=7411543;`; + + // // Act + // const actualCookieValue = mixIn.methods.getCookieValue(testCookieName); + + // // Assert + // expect(actualCookieValue).toEqual(undefined); + // expect(document.cookie).toEqual(`yearMakeModel=2020 ACURA MDX; SavedQuoteID=d2770645-0680-4852-9649-6170659b1bd6; EMBEDDEDPAYMENTPAGE_PAYPAL_SUBMITBUTTON=COMPLETED; orderconfirmation=7411543;`); + // }); \ No newline at end of file diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index aeb4e8ac6..d2d786d5d 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -77,6 +77,7 @@ import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; import { damageLocationsCms } from "@/constants/damage-locations-cms.js"; import { damageLocationsSelected } from "@/constants/damage-locations-selected.js"; +import { navigateToHeritageFunnel } from "@/helpers/heritage-integration-helper"; // DEFINE VALIDATION RULES defineRule("replace-options-required", required(errorMessages.REPLACE_OPTIONS_REQUIRED)); @@ -296,7 +297,7 @@ export default { navigateForward(partsData){ // CSR-98 TEMP if (store.getters.vehicle.year == 2010) { - this.navigateToHeritageFunnel(); + navigateToHeritageFunnel(); return; } diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index 8fdd6dd8d..af2eb1c2a 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -22,39 +22,6 @@ export default { savePageDataToStore(page, data){ store.commit(storeMutations.UPDATE_PAGE_DATA, { page: page, data: data }); }, - async saveOrder() { - var savedOrderInfo = (await this.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER)).data; - store.commit(storeMutations.UPDATE_REFERRAL_NUMBER, savedOrderInfo.referralNumber); - store.commit(storeMutations.UPDATE_REFERRAL_DATE, savedOrderInfo.referralDate); - store.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, savedOrderInfo.referralCorrelationId); - }, - getCookieValue(cookieName) { - return document.cookie - ?.split("; ") - ?.find(row => row.startsWith(`${cookieName}=`)) - ?.split("=")[1]; - }, - setCookieValue(cookieName, cookieValue) { - document.cookie = `${cookieName}=${cookieValue}`; - }, - deleteCookie(cookieName) { - document.cookie = `${cookieName}=; Max-Age=0; path=/; domain=${location.hostname}`; - }, - navigateToHeritageFunnel() { - var referralCorrelationId = store.getters.referralCorrelationId; - - router.navigate( - navigationScenarios.MOVE_TO_HERITAGE_FUNNEL, - router.currentRoute.value, - { - corid: referralCorrelationId, - src: "concept-funnel", - // TODO CSR-98 REMOVE THIS - cns: "all", - experiments: "ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" - } - ); - } }, computed: { storeActions() { diff --git a/src/mixins/base-mixin.spec.js b/src/mixins/base-mixin.spec.js index e1599a319..8c33a5774 100644 --- a/src/mixins/base-mixin.spec.js +++ b/src/mixins/base-mixin.spec.js @@ -79,8 +79,6 @@ describe("baseMixin.js", () => { }); }); - - function getMixInInstance({ isDispatchSuccess = true }) { // Mock Store const storeDispatch = jest.fn(); @@ -103,6 +101,9 @@ function getMixInInstance({ isDispatchSuccess = true }) { baseMixIn.methods.$route = route; baseMixIn.methods.storeActions = storeActions; baseMixIn.methods.widgetNames = widgetNames; + baseMixin.document = { + cookie: "" + } store.dispatch = storeDispatch; store.commit = jest.fn(); diff --git a/src/router/index.js b/src/router/index.js index 8d9876a74..7f90a733c 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -7,7 +7,7 @@ import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; import eventBus from "@/helpers/event-bus/event-bus"; import store from "@/store"; -import { cookieNames } from "@/constants/cookie-names"; +import { handleInfoFromHeritageFunnel, saveOrder, } from "@/helpers/heritage-integration-helper"; // Components import ComponentTest from "@/layouts/component-test/component-test.vue"; @@ -158,7 +158,7 @@ function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, // Append page data to the store for the NEXT page, if any. It will be an empty object if none is provided. baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); - baseMixin.methods.saveOrder(); + saveOrder(); router.push({ name: "root", @@ -169,7 +169,7 @@ function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, }); } else if (matchingScenarioMap.destinationUrl !== undefined) { if (matchingScenarioMap.shouldNavigateToHeritageFunnel) { - baseMixin.methods.saveOrder(); + saveOrder(); } navigateToUrl(matchingScenarioMap.destinationUrl, optionalQuery); @@ -258,20 +258,4 @@ function resetDependentState(component) { return component.default.methods.resetDependentState(); } -// Read info from heritage funnel and reset state or load referral -function handleInfoFromHeritageFunnel() { - var orderInfoJson = baseMixin.methods.getCookieValue(cookieNames.ORDER_INFO); - var orderInfo = orderInfoJson == null ? null : JSON.parse(orderInfoJson); - - if (orderInfo?.ShouldResetState) { - store.dispatch(storeActions.RESET_STATE); - } - else if (orderInfo != null) { - // should load referral here - } - - // Delete cookie once state is loaded or reset - baseMixin.methods.deleteCookie(cookieNames.ORDER_INFO); -} - export default router; \ No newline at end of file From 0d6571abf716c53fd10c2cfbc5111daa6e7966cd Mon Sep 17 00:00:00 2001 From: Katie Date: Thu, 17 Mar 2022 08:28:37 -0400 Subject: [PATCH 07/58] CSR-98 Add experiments to query string for testing --- src/helpers/heritage-integration-helper.js | 2 +- src/helpers/unit-test-helper.js | 1 - src/mixins/base-mixin.spec.js | 3 --- src/router/index.js | 4 ++-- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 95ee7ef09..12cba038b 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -33,7 +33,7 @@ export function navigateToHeritageFunnel() { src: "concept-funnel", // TODO CSR-98 REMOVE THIS cns: "all", - experiments: "ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" + experiments: "RemoveServiceAreaPage=ServAreaRemoval_V7=ServAreaNoRemove_V7_TEST=true,ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" } ); } diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 1509a4b16..561798629 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -49,7 +49,6 @@ export function getMountOptions(mockData) { mocks.$router = mockData.router; mocks.$route = mockData.route; - const global = { mocks: mocks, }; diff --git a/src/mixins/base-mixin.spec.js b/src/mixins/base-mixin.spec.js index 8c33a5774..da684af1b 100644 --- a/src/mixins/base-mixin.spec.js +++ b/src/mixins/base-mixin.spec.js @@ -101,9 +101,6 @@ function getMixInInstance({ isDispatchSuccess = true }) { baseMixIn.methods.$route = route; baseMixIn.methods.storeActions = storeActions; baseMixIn.methods.widgetNames = widgetNames; - baseMixin.document = { - cookie: "" - } store.dispatch = storeDispatch; store.commit = jest.fn(); diff --git a/src/router/index.js b/src/router/index.js index 7f90a733c..a49d416aa 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -132,7 +132,7 @@ router.navigateAfterSave = (scenario, currentRoute, optionalQuery = {}, optional // PRIVATE FUNCTIONS // Navigate to the next route, depending on the scenario. -function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) { +async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) { if (!scenario) { console.error("No scenario provided. Please review the routing table."); return; @@ -169,7 +169,7 @@ function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, }); } else if (matchingScenarioMap.destinationUrl !== undefined) { if (matchingScenarioMap.shouldNavigateToHeritageFunnel) { - saveOrder(); + await saveOrder(); } navigateToUrl(matchingScenarioMap.destinationUrl, optionalQuery); From f4a6cc66cfc574b277a73e5d7dab8818199c77ad Mon Sep 17 00:00:00 2001 From: Katie Date: Thu, 17 Mar 2022 16:12:20 -0400 Subject: [PATCH 08/58] CSR-98 Check and edit cookie info as needed --- src/helpers/heritage-integration-helper.js | 37 ++++++++++++++++------ src/router/index.js | 4 +-- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 12cba038b..68cb2484e 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -8,18 +8,16 @@ import baseMixin from "../mixins/base-mixin"; // Read info from heritage funnel and reset state or load referral export function handleInfoFromHeritageFunnel() { - var orderInfoJson = getHeritageCookieValue(); - var orderInfo = orderInfoJson == null ? null : JSON.parse(orderInfoJson); + var orderInfo = getHeritageCookieValue(); if (orderInfo?.ShouldResetState) { store.dispatch(storeActions.RESET_STATE); - } - else if (orderInfo != null) { - // should load referral here + deleteHeritageCookie(); } - // Delete cookie once state is loaded or reset - deleteHeritageCookie(); + if (orderInfo?.DidHeritageFunnelUpdateLast) { + // Load referral here + } } export function navigateToHeritageFunnel() { @@ -43,15 +41,36 @@ export async function saveOrder() { store.commit(storeMutations.UPDATE_REFERRAL_NUMBER, savedOrderInfo.referralNumber); store.commit(storeMutations.UPDATE_REFERRAL_DATE, savedOrderInfo.referralDate); store.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, savedOrderInfo.referralCorrelationId); + + setDidHeritageFunnelUpdateLastInHeritageCookie(false); } +/* Start cookie related functions */ export function getHeritageCookieValue() { - return document.cookie + var cookieJson = document.cookie ?.split("; ") ?.find(row => row.startsWith(`${cookieNames.ORDER_INFO}=`)) ?.split("=")[1]; + + return cookieJson == null ? null : JSON.parse(cookieJson); } export function deleteHeritageCookie() { document.cookie = `${cookieNames.ORDER_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; -} \ No newline at end of file +} + +function setHeritageCookieValue(cookieValue) { + var cookieValueJson = JSON.stringify(cookieValue); + document.cookie = `${cookieNames.ORDER_INFO}=${cookieValueJson}; path=/`; +} + +function setDidHeritageFunnelUpdateLastInHeritageCookie(didHeritageFunnelUpdateLast) { + var cookie = getHeritageCookieValue(); + + if (cookie != null) { + cookie.DidHeritageFunnelUpdateLast = false; + + setHeritageCookieValue(cookie); + } +} +/* End cookie related functions */ \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index d9d03e213..c77285677 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -52,9 +52,9 @@ const routes = [ path: "/", name: "root", async beforeEnter(to, from, next) { - // TODO CSR-98 Also triggers on refresh... should it though? - // Entering the concept funnel + // On entering the concept funnel if (from.redirectedFrom === undefined) { + // Read cookie information, decide what to do next handleInfoFromHeritageFunnel(); } From 442125ed650c90d2ca9e56b4964e4c22c89e5688 Mon Sep 17 00:00:00 2001 From: Katie Date: Thu, 17 Mar 2022 16:50:58 -0400 Subject: [PATCH 09/58] CSR-98 Refactor cookie code --- src/helpers/heritage-integration-helper.js | 36 ++++++++++++++-------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 68cb2484e..eda55a063 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -14,9 +14,12 @@ export function handleInfoFromHeritageFunnel() { store.dispatch(storeActions.RESET_STATE); deleteHeritageCookie(); } - - if (orderInfo?.DidHeritageFunnelUpdateLast) { + else if (orderInfo?.DidHeritageFunnelUpdateLast) { // Load referral here + + // setHeritageCookieProperties({ + // ShouldResetState: false + // }) } } @@ -42,11 +45,13 @@ export async function saveOrder() { store.commit(storeMutations.UPDATE_REFERRAL_DATE, savedOrderInfo.referralDate); store.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, savedOrderInfo.referralCorrelationId); - setDidHeritageFunnelUpdateLastInHeritageCookie(false); + setHeritageCookieProperties({ + DidHeritageFunnelUpdateLast: false + }) } /* Start cookie related functions */ -export function getHeritageCookieValue() { +function getHeritageCookieValue() { var cookieJson = document.cookie ?.split("; ") ?.find(row => row.startsWith(`${cookieNames.ORDER_INFO}=`)) @@ -55,22 +60,29 @@ export function getHeritageCookieValue() { return cookieJson == null ? null : JSON.parse(cookieJson); } -export function deleteHeritageCookie() { +function deleteHeritageCookie() { document.cookie = `${cookieNames.ORDER_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; } function setHeritageCookieValue(cookieValue) { - var cookieValueJson = JSON.stringify(cookieValue); + let cookieValueJson = cookieValue; + if (typeof cookieValue == "object") + cookieValueJson = JSON.stringify(cookieValue); + document.cookie = `${cookieNames.ORDER_INFO}=${cookieValueJson}; path=/`; } -function setDidHeritageFunnelUpdateLastInHeritageCookie(didHeritageFunnelUpdateLast) { - var cookie = getHeritageCookieValue(); +function setHeritageCookieProperties(properties) { + if (typeof properties == "object") { + let cookie = getHeritageCookieValue(); - if (cookie != null) { - cookie.DidHeritageFunnelUpdateLast = false; - - setHeritageCookieValue(cookie); + if (cookie != null) { + Object.keys(properties).forEach(key => { + cookie[key] = properties[key]; + }); + + setHeritageCookieValue(cookie); + } } } /* End cookie related functions */ \ No newline at end of file From 2b6d22fd71fa7de04fffe6962c6752a77b5d1e11 Mon Sep 17 00:00:00 2001 From: Katie Date: Mon, 21 Mar 2022 11:38:18 -0400 Subject: [PATCH 10/58] CSR-98 Save only when user is moving to or has visited heritage --- src/helpers/heritage-integration-helper.js | 31 ++- .../heritage-integration-helper.spec.js | 241 ++++++++++++++++++ src/helpers/unit-test-helper.js | 46 +++- src/router/index.js | 15 +- src/router/router-constants/routing-table.js | 1 - 5 files changed, 306 insertions(+), 28 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index eda55a063..a994ad057 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -8,9 +8,13 @@ import baseMixin from "../mixins/base-mixin"; // Read info from heritage funnel and reset state or load referral export function handleInfoFromHeritageFunnel() { - var orderInfo = getHeritageCookieValue(); + const orderInfo = getHeritageCookieValue(); + console.log("A") + console.log(orderInfo) + console.log(document.cookie) if (orderInfo?.ShouldResetState) { + console.log("B") store.dispatch(storeActions.RESET_STATE); deleteHeritageCookie(); } @@ -21,10 +25,13 @@ export function handleInfoFromHeritageFunnel() { // ShouldResetState: false // }) } + + console.log("D") } -export function navigateToHeritageFunnel() { - var referralCorrelationId = store.getters.referralCorrelationId; +export async function navigateToHeritageFunnel() { + await saveOrder(); + const referralCorrelationId = store.getters.referralCorrelationId; router.navigate( navigationScenarios.MOVE_TO_HERITAGE_FUNNEL, @@ -40,7 +47,8 @@ export function navigateToHeritageFunnel() { } export async function saveOrder() { - var savedOrderInfo = (await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER)).data; + console.log("HI") + const savedOrderInfo = (await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER)).data; store.commit(storeMutations.UPDATE_REFERRAL_NUMBER, savedOrderInfo.referralNumber); store.commit(storeMutations.UPDATE_REFERRAL_DATE, savedOrderInfo.referralDate); store.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, savedOrderInfo.referralCorrelationId); @@ -51,16 +59,23 @@ export async function saveOrder() { } /* Start cookie related functions */ -function getHeritageCookieValue() { - var cookieJson = document.cookie +export function getHeritageCookieValue() { + console.log("A") + const cookieJson = document.cookie ?.split("; ") ?.find(row => row.startsWith(`${cookieNames.ORDER_INFO}=`)) ?.split("=")[1]; - - return cookieJson == null ? null : JSON.parse(cookieJson); + + try { + return JSON.parse(cookieJson); + } catch(error) { + return null; + } } function deleteHeritageCookie() { + // If this cookie is ever created from the concept funnel, will need to add another + // line with the path=/fmg/ document.cookie = `${cookieNames.ORDER_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; } diff --git a/src/helpers/heritage-integration-helper.spec.js b/src/helpers/heritage-integration-helper.spec.js index 9f49b4565..78f673e84 100644 --- a/src/helpers/heritage-integration-helper.spec.js +++ b/src/helpers/heritage-integration-helper.spec.js @@ -1,4 +1,245 @@ +import * as helper from "@/helpers/heritage-integration-helper"; +import { cookieNames } from "@/constants/cookie-names"; +import { setupMocksForJsFiles } from "@/helpers/unit-test-helper.js"; +import { storeActions } from "@/constants/store-actions"; +import { storeMutations } from "@/constants/store-mutations"; +import store from "@/store"; +describe("saveOrder", () => { + + // afterEach(() => { + // removeAllTestCookies(); + // }); + + function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate ) { + return { + referralNumber: mockReferralNumber, + referralCorrelationId: mockCorrelationId, + referralDate: mockReferralDate + } + } + + describe("handleInfoFromHeritageFunnel", () => { + // test("ShouldResetState == true => heritage cookie is deleted", () => { + // // Arrange + // // TODO CSR-98 Can we not mock this?? + // const testShouldResetState = true; + + // const testCookieValue = { + // ShouldResetState: testShouldResetState + // } + + // console.log(cookieNames.ORDER_INFO); + // console.log(testCookieValue) + // console.log(JSON.stringify(testCookieValue)); + // console.log(location.hostname) + // let myString = `${cookieNames.ORDER_INFO}=${JSON.stringify(testCookieValue)};domain=${location.hostname};path=/;`; + // console.log(myString) + // document.cookie = 'OrderInfo={"Hahahah":true};domain=localhost;path=/;'; + // console.log(document.cookie) + // document.cookie = "Ahhh=AHHH;" + // document.cookie = `${cookieNames.ORDER_INFO}=; Max-Age=0; domain=${location.hostname};`; + // console.log(document.cookie) + + // // Act + // helper.handleInfoFromHeritageFunnel(); + + // // Assert + // console.log(document.cookie) + // // expect(document.cookie).toBe(); + // }); + + // test("ShouldResetState == true => reset store", () => { + // // Arrange + // helper.getHeritageCookieValue = jest.fn(x => x.ShouldResetState = false); + + // // Act + // helper.handleInfoFromHeritageFunnel(); + + // // Assert + // expect(helper.getHeritageCookieValue).toHaveBeenCalled(); + // }); + + // test("Heritage cookie is null => store is unchanged", () => { + // // Arrange + // helper.getHeritageCookieValue = jest.fn(x => x.ShouldResetState = true); + + // // Act + // helper.handleInfoFromHeritageFunnel(); + + // // Assert + // expect(helper.getHeritageCookieValue).toHaveBeenCalled(); + // }); + }); + + test("saveOrder => should set state order values", async () => { + // Arrange + const mockReferralNumber = 2; + const mockCorrelationId = "55"; + const mockReferralDate = "2022"; + + const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); + + const mockData = { + actionList: [{ + actionName: storeActions.SAVE_ORDER, + data: mockOrderInfo, + }], + } + + setupMocksForJsFiles(mockData); + + // Act + await helper.saveOrder(); + + // Assert + expect(store.commit).toHaveBeenCalledTimes(3); + expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_REFERRAL_NUMBER, mockReferralNumber); + expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, mockCorrelationId); + expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_REFERRAL_DATE, mockReferralDate); + }); + + // test("saveOrder => should update DidHeritageFunnelUpdateLast cookie value", async () => { + // // Arrange + // const mockReferralNumber = 2; + // const mockCorrelationId = "55"; + // const mockReferralDate = "2022"; + + // const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); + + // const mockData = { + // actionList: [{ + // actionName: storeActions.SAVE_ORDER, + // data: mockOrderInfo, + // }], + // } + + // setupMocksForJsFiles(mockData); + + // // Act + // await helper.saveOrder(); + + // // Assert + + // }); +}); + +describe("navigateToHeritageFunnel", () => { + test("should go to external link", () => { + // Arrange + + // Act + helper.navigateToHeritageFunnel(); + + // Assert + expect(router.navigate).toHaveBeenCalled(); + expect(window.location.assign).toHaveBeenCalled(); + }) +}); + +// TODO CSR-98 Remove skip +describe.skip("cookies", () => { + afterEach(() => { + removeAllTestCookies(); + }) + + describe("getHeritageCookieValue method", () => { + test("gets correct value when cookie is present", () => { + // Arrange + const testReferralNumber = 1566818; + const testReferralDate = "2022-03-15T10:56:24.597"; + const testReferralCorrelationId = "404d2b04-f86e-45c3-b373-127b6217b060"; + const testShouldResetState = false; + const testDidHeritageFunnelUpdateLast = true; + + const testCookieValue = { + ReferralNumber: testReferralNumber, + ReferralDate: testReferralDate, + ReferralCorrelationId: testReferralCorrelationId, + ShouldResetState: testShouldResetState, + DidHeritageFunnelUpdateLast: testDidHeritageFunnelUpdateLast + } + setupCookies({ heritageCookieValue: JSON.stringify(testCookieValue) }); + + // Act + var result = helper.getHeritageCookieValue(); + + // Assert + expect(result).toEqual(testCookieValue); + expect(typeof result).toEqual("object"); + expect(result.ReferralNumber).toEqual(testReferralNumber); + expect(result.ReferralDate).toEqual(testReferralDate); + expect(result.ReferralCorrelationId).toEqual(testReferralCorrelationId); + expect(result.ShouldResetState).toEqual(testShouldResetState); + expect(result.DidHeritageFunnelUpdateLast).toEqual(testDidHeritageFunnelUpdateLast); + }) + + test("returns empty object when value is empty object", () => { + // Arrange + const testCookieValue = {}; + setupCookies({ heritageCookieValue: JSON.stringify(testCookieValue) }); + + // Act + var result = helper.getHeritageCookieValue(); + + // Assert + expect(result).toEqual(testCookieValue); + expect(typeof result).toEqual("object"); + expect(Object.keys(result)).toHaveLength(0); + }) + + test("returns null when value is empty string", () => { + // Arrange + const testCookieValue = ""; + setupCookies({ heritageCookieValue: testCookieValue }); + + // Act + var result = helper.getHeritageCookieValue(); + + // Assert + expect(result).toEqual(null); + }) + + test("returns null when heritage cookie doesn't exist", () => { + // Arrange + setupCookies({ includeHeritageCookie: false }); + + // Act + var result = helper.getHeritageCookieValue(); + + // Assert + expect(result).toEqual(null); + }) + }) +}) + +// document.cookie is not just a string, needs to be added individually +const cookies = { + "orderconfirmation": 1565980, + "optimizelyEndUserId": "oeu1610051865958r0.07937134272718804", + [cookieNames.ORDER_INFO]: `{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false,"DidHeritageFunnelUpdateLast":true}`, + "UNIQUE_SESSION_ID": "33756020-b58e-4ec7-b8b8-3f1576719c40", + "_ga": "GA1.1.1631274579.1622658999", + "da_lid": "B10847599A73EA95861EBB99009A283E27|0|0|0 clientTag=null", + "addshoppers.com": "2%7C1%3A0%7C10%3A1646681050%7C15%3Aaddshoppers.com%7C44%3AODM1OTczNWI0MmFjNGNmMmExNDY3OWRlNTQ1NmM5MGY%3D%7Cef2a50fafe40fc5abf641a14ee5541c70bef2950666f59d3a809fd9352c7b963" +}; + +function setupCookies({ heritageCookieValue = "", includeHeritageCookie = true }) { + console.log(heritageCookieValue) + Object.keys(cookies).forEach(key => { + const cookieValue = key == cookieNames.ORDER_INFO ? heritageCookieValue : cookies[key]; + + if (includeHeritageCookie || key != cookieNames.ORDER_INFO) + document.cookie = `${key}=${cookieValue}`; + }); +} + +function removeAllTestCookies() { + Object.keys(cookies).forEach(key => { + document.cookie = `${key}=;Max-Age=0;`; + }); +} + // test("getCookieValue: Gets correct cookie value", () => { // // Arrange // const mixIn = getMixInInstance({}); diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 561798629..386dfa414 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -4,6 +4,7 @@ import { navigationScenarios } from "@/router/router-constants/navigation-scenar import { vehicleCategories } from "@/constants/vehicle-categories.js"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import baseMixin from "@/mixins/base-mixin"; +import store from "@/store"; export function getMountOptions(mockData) { // Define our mocks to attached to the 'global' object for Vue/Jest. @@ -11,18 +12,20 @@ export function getMountOptions(mockData) { //this is mocking if you use the mixin directly(baseMixin.methods.dispatchNonBlockingStoreAction) vs this.dispatchNonBlockingStoreAction if (mockData.actionList !== undefined) { - baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); - baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { - let actionFilterResult = mockData.actionList.filter( - (x) => x.actionName == actionName - ); + // baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); + // baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { + // let actionFilterResult = mockData.actionList.filter( + // (x) => x.actionName == actionName + // ); - if (actionFilterResult.length > 0 && actionFilterResult.length === 1) { - return Promise.resolve({ - data: actionFilterResult[0].data, - }); - } - }); + // if (actionFilterResult.length > 0 && actionFilterResult.length === 1) { + // return Promise.resolve({ + // data: actionFilterResult[0].data, + // }); + // } + // }); + + setupDispatchNonBlockingStoreAction(mockData); } mocks.dispatchNonBlockingStoreAction = jest.fn(); mocks.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { @@ -55,3 +58,24 @@ export function getMountOptions(mockData) { return { global }; } + +function setupDispatchNonBlockingStoreAction(mockData) { + baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); + baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { + let actionFilterResult = mockData.actionList.filter( + (x) => x.actionName == actionName + ); + + if (actionFilterResult.length > 0 && actionFilterResult.length === 1) { + return Promise.resolve({ + data: actionFilterResult[0].data, + }); + } + }); +} + +export function setupMocksForJsFiles(mockData) { + setupDispatchNonBlockingStoreAction(mockData); + store.commit = jest.fn(); + router.navigate = jest.fn(); +} \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index c77285677..abc7a1991 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -8,7 +8,7 @@ import { routerParameterKeys } from '@/router/router-constants/router-parameter- import baseMixin from "@/mixins/base-mixin"; import eventBus from "@/helpers/event-bus/event-bus"; import store from "@/store"; -import { handleInfoFromHeritageFunnel, saveOrder, } from "@/helpers/heritage-integration-helper"; +import { handleInfoFromHeritageFunnel, saveOrder, getHeritageCookieValue } from "@/helpers/heritage-integration-helper"; // Components import ComponentTest from "@/layouts/component-test/component-test.vue"; @@ -139,8 +139,8 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery return; } - // // here?? CSR-98 - // baseMixin.methods.saveOrder(); + console.log(scenario) + console.log(currentRoute) // Match our maps up and navigate if we have a destination. const matchingScenarioMap = getNavigationMap(scenario, currentRoute); @@ -159,7 +159,9 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery // Append page data to the store for the NEXT page, if any. It will be an empty object if none is provided. baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); - saveOrder(); + // if cookie and referralNumber exists + if (getHeritageCookieValue()?.ReferralNumber) + saveOrder(); router.push({ name: "root", @@ -169,16 +171,13 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery params: Object.assign(optionalParams, {[routerParameterKeys.FROM_ROUTER_NAVIGATE]: true}) }); } else if (matchingScenarioMap.destinationUrl !== undefined) { - if (matchingScenarioMap.shouldNavigateToHeritageFunnel) { - await saveOrder(); - } - navigateToUrl(matchingScenarioMap.destinationUrl, optionalQuery); } } // Get navigation map depending on the scenario and the current 'page' you're on. function getNavigationMap(scenario, currentRoute) { + console.log("A") const fmgPageValue = currentRoute.query.fmgPage; const matchedQueryValue = routingTable .filter( diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 8fc8ad013..c6a758cef 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -61,7 +61,6 @@ const routingTable = [ { scenario: navigationScenarios.MOVE_TO_HERITAGE_FUNNEL, destinationUrl: externalUrls.HERITAGE_FUNNEL, - shouldNavigateToHeritageFunnel: true }, { scenario: navigationScenarios.SELECTED_DAMAGE_WITH_SINGLE_PART, From 1ac05c353b59b84542760f7c174782fb793e3141 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Mon, 21 Mar 2022 12:05:10 -0400 Subject: [PATCH 11/58] CSR-98 to CSR-99 --- src/constants/endpoints.js | 4 + src/constants/store-actions.js | 3 + src/constants/store-mutations.js | 1 + src/global-methods.js | 1 - src/helpers/heritage-integration-helper.js | 36 +-- src/layouts/address-poc/address-poc.vue | 233 ------------------ .../button-question-examples.vue | 138 ----------- src/layouts/nested-radio-poc/nested-radio.vue | 74 ------ src/router/index.js | 29 +-- src/store/index.js | 27 ++ 10 files changed, 59 insertions(+), 487 deletions(-) delete mode 100644 src/layouts/address-poc/address-poc.vue delete mode 100644 src/layouts/button-question-examples/button-question-examples.vue delete mode 100644 src/layouts/nested-radio-poc/nested-radio.vue diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index c547bd28c..03c03cf6c 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -50,6 +50,10 @@ const endpoints = { SaveOrder: { url: "/order/api/v1/order/save", method: "POST", + }, + LoadOrder: { + url: "/order/api/v1/order/load", + method: "POST", } }; diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 84ecf77e6..c0e6893a4 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -13,6 +13,9 @@ const storeActions = { LOOKUP_VEHICLE_BY_VIN: "lookupVehicleByVin", GET_PARTS_OR_QUESTIONS: "getPartsOrQuestions", SAVE_ORDER: "saveOrder", + LOAD_ORDER: "loadOrder", + SET_REFERRAL_INFORMATION: "setReferralInformation", + SET_LOAD_ORDER_DATA: "setLoadOrderData", // DEPENDENCY MUTATIONS RESET_VEHICLE_STATE_AND_DEPENDENCIES: "resetVehicleAndDependencies", diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index d6ee3b321..47dfcacca 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -33,6 +33,7 @@ const storeMutations = { // OTHER MUTATIONS UPDATE_PAGE_DATA: "updatePageData", + SET_LOAD_ORDER_INFO: "setLoadOrderInformation" }; diff --git a/src/global-methods.js b/src/global-methods.js index 7d82a2590..8efd163aa 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -12,7 +12,6 @@ export default { apiGatewayUrl = "https://localhost:44346"; } - // const apiGatewayUrl = applicationConfig.CONSUMER_APIGATEWAY_URL; const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "FixMyGlass", diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index a994ad057..cc2f9379e 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -1,21 +1,16 @@ import { storeActions } from "@/constants/store-actions.js"; -import { storeMutations } from "@/constants/store-mutations.js"; import { cookieNames } from "@/constants/cookie-names"; +import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import store from "@/store"; import router from "@/router"; -import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import baseMixin from "../mixins/base-mixin"; // Read info from heritage funnel and reset state or load referral export function handleInfoFromHeritageFunnel() { const orderInfo = getHeritageCookieValue(); - console.log("A") - console.log(orderInfo) - console.log(document.cookie) if (orderInfo?.ShouldResetState) { - console.log("B") - store.dispatch(storeActions.RESET_STATE); + baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); deleteHeritageCookie(); } else if (orderInfo?.DidHeritageFunnelUpdateLast) { @@ -47,17 +42,30 @@ export async function navigateToHeritageFunnel() { } export async function saveOrder() { - console.log("HI") const savedOrderInfo = (await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER)).data; - store.commit(storeMutations.UPDATE_REFERRAL_NUMBER, savedOrderInfo.referralNumber); - store.commit(storeMutations.UPDATE_REFERRAL_DATE, savedOrderInfo.referralDate); - store.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, savedOrderInfo.referralCorrelationId); + // Save the referral information back from the store. + await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SET_REFERRAL_INFORMATION, { + referralNumber: savedOrderInfo.referralNumber, + correlationId: savedOrderInfo.referralCorrelationId, + referralDate: savedOrderInfo.referralDate, + }) + + // Set cookie properties. setHeritageCookieProperties({ DidHeritageFunnelUpdateLast: false }) } +export async function loadOrder() { + const loadOrderInfo = (await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER)).data; + + // Save the data from the loaded order to state. + await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SET_LOAD_ORDER_DATA, { loadOrderInfo }); +} + +// --------- PRIVATE FUNCTIONS --------- + /* Start cookie related functions */ export function getHeritageCookieValue() { console.log("A") @@ -83,7 +91,7 @@ function setHeritageCookieValue(cookieValue) { let cookieValueJson = cookieValue; if (typeof cookieValue == "object") cookieValueJson = JSON.stringify(cookieValue); - + document.cookie = `${cookieNames.ORDER_INFO}=${cookieValueJson}; path=/`; } @@ -91,7 +99,7 @@ function setHeritageCookieProperties(properties) { if (typeof properties == "object") { let cookie = getHeritageCookieValue(); - if (cookie != null) { + if (cookie !== null) { Object.keys(properties).forEach(key => { cookie[key] = properties[key]; }); @@ -100,4 +108,4 @@ function setHeritageCookieProperties(properties) { } } } -/* End cookie related functions */ \ No newline at end of file +/* End cookie related functions */ diff --git a/src/layouts/address-poc/address-poc.vue b/src/layouts/address-poc/address-poc.vue deleted file mode 100644 index 8bb42a659..000000000 --- a/src/layouts/address-poc/address-poc.vue +++ /dev/null @@ -1,233 +0,0 @@ - - - diff --git a/src/layouts/button-question-examples/button-question-examples.vue b/src/layouts/button-question-examples/button-question-examples.vue deleted file mode 100644 index 6df20ddf1..000000000 --- a/src/layouts/button-question-examples/button-question-examples.vue +++ /dev/null @@ -1,138 +0,0 @@ - - - \ No newline at end of file diff --git a/src/layouts/nested-radio-poc/nested-radio.vue b/src/layouts/nested-radio-poc/nested-radio.vue deleted file mode 100644 index d0a78d085..000000000 --- a/src/layouts/nested-radio-poc/nested-radio.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - - - diff --git a/src/router/index.js b/src/router/index.js index abc7a1991..2e9ed4db1 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -5,17 +5,15 @@ import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js" import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; import { routerParameterKeys } from '@/router/router-constants/router-parameter-keys' +import { handleInfoFromHeritageFunnel, saveOrder, getHeritageCookieValue } from "@/helpers/heritage-integration-helper"; + import baseMixin from "@/mixins/base-mixin"; import eventBus from "@/helpers/event-bus/event-bus"; import store from "@/store"; -import { handleInfoFromHeritageFunnel, saveOrder, getHeritageCookieValue } from "@/helpers/heritage-integration-helper"; // Components import ComponentTest from "@/layouts/component-test/component-test.vue"; -import AddressPOC from "@/layouts/address-poc/address-poc.vue"; import FormTest from "@/layouts/form-test/form-test.vue"; -import NestedRadio from "@/layouts/nested-radio-poc/nested-radio.vue"; -import buttonQuestionExamples from "@/layouts/button-question-examples/button-question-examples.vue" const routes = [ { @@ -28,26 +26,6 @@ const routes = [ name: "FormTest", component: FormTest, }, - { - path: "/address-poc", // This is a temporary route for testing. - name: "AddressPOC", - component: AddressPOC, - }, - { - path: "/form-test", // This is a temporary route for testing. - name: "FormTest", - component: FormTest, - }, - { - path: "/nested-radio", // This is a temporary route for testing. - name: "NestedRadio", - component: NestedRadio, - }, - { - path: "/button-question-examples", // This is a temporary route for testing. - name: "buttonQuestionExamples", - component: buttonQuestionExamples, - }, { path: "/", name: "root", @@ -139,9 +117,6 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery return; } - console.log(scenario) - console.log(currentRoute) - // Match our maps up and navigate if we have a destination. const matchingScenarioMap = getNavigationMap(scenario, currentRoute); const destinationFmgPageValue = matchingScenarioMap.destinationFmgPageValue; diff --git a/src/store/index.js b/src/store/index.js index f453aa340..dc93571d8 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -139,6 +139,11 @@ export const mutations = { }, resetState(state) { Object.assign(state, getDefaultState()); + }, + + // Misc Mutations + setLoadOrderInformation(state, orderInformation) { + } } @@ -287,6 +292,16 @@ export const actions = { }); }, + // Misc Actions + setReferralInformation(context, { referralNumber, referralDate, correlationId }) { + context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber); + context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate); + context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, correlationId); + }, + setLoadOrderData(context, { loadOrderData }) { + + }, + // Parts API Actions getPartsOrQuestions(context, { carId, glassArray, zipCode, vin = '' }) { return globalMethods.callHttpClient({ @@ -324,6 +339,18 @@ export const actions = { }, }); }, + + loadOrder(context, {referralNumber, referralDate, correlationId}) { + return globalMethods.callHttpClient({ + method: endpoints.LoadOrder.method, + endpoint: endpoints.LoadOrder.url, + payload: { + referralNumber: referralNumber, + referralDate: referralDate, + correlationId: correlationId + }, + }); + } } export default createStore({ From a279c9d0119b0a7873141334c89503c59ef2b8a7 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Mon, 21 Mar 2022 12:50:32 -0400 Subject: [PATCH 12/58] Load init --- src/constants/store-mutations.js | 1 + src/helpers/heritage-integration-helper.js | 21 ++++++++-------- .../heritage-integration-helper.spec.js | 8 +++--- src/router/index.js | 4 +-- src/store/index.js | 25 ++++++++++++++++++- 5 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 47dfcacca..2636464bd 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -19,6 +19,7 @@ const storeMutations = { UPDATE_REFERRAL_NUMBER: "updateReferralNumber", UPDATE_REFERRAL_DATE: "updateReferralDate", UPDATE_REFERRAL_CORRELATION_ID: "updateReferralCorrelationId", + UPDATE_PARENT_ACCT_NUMBER: "updateParentAcctNumber", // EVENT BUS MUTATIONS ADD_EVENT_TO_BUS: "addEventToBus", diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index cc2f9379e..e4534631f 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -6,22 +6,23 @@ import router from "@/router"; import baseMixin from "../mixins/base-mixin"; // Read info from heritage funnel and reset state or load referral -export function handleInfoFromHeritageFunnel() { +export async function loadReferralFromHeritageFunnelIfPresent() { const orderInfo = getHeritageCookieValue(); - if (orderInfo?.ShouldResetState) { + // Do nothing if there is no cookie. + if(orderInfo === null){ + return; + } + + // Reset state if cookie says to. + if (orderInfo.ShouldResetState) { baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); deleteHeritageCookie(); - } - else if (orderInfo?.DidHeritageFunnelUpdateLast) { - // Load referral here - - // setHeritageCookieProperties({ - // ShouldResetState: false - // }) + return; } - console.log("D") + // Load referral if there is a cookie, and it doesn't indicate it needs a state reset. + await loadOrder(); } export async function navigateToHeritageFunnel() { diff --git a/src/helpers/heritage-integration-helper.spec.js b/src/helpers/heritage-integration-helper.spec.js index 78f673e84..f99187474 100644 --- a/src/helpers/heritage-integration-helper.spec.js +++ b/src/helpers/heritage-integration-helper.spec.js @@ -19,7 +19,7 @@ describe("saveOrder", () => { } } - describe("handleInfoFromHeritageFunnel", () => { + describe("loadReferralFromHeritageFunnelIfPresent", () => { // test("ShouldResetState == true => heritage cookie is deleted", () => { // // Arrange // // TODO CSR-98 Can we not mock this?? @@ -42,7 +42,7 @@ describe("saveOrder", () => { // console.log(document.cookie) // // Act - // helper.handleInfoFromHeritageFunnel(); + // helper.loadReferralFromHeritageFunnelIfPresent(); // // Assert // console.log(document.cookie) @@ -54,7 +54,7 @@ describe("saveOrder", () => { // helper.getHeritageCookieValue = jest.fn(x => x.ShouldResetState = false); // // Act - // helper.handleInfoFromHeritageFunnel(); + // helper.loadReferralFromHeritageFunnelIfPresent(); // // Assert // expect(helper.getHeritageCookieValue).toHaveBeenCalled(); @@ -65,7 +65,7 @@ describe("saveOrder", () => { // helper.getHeritageCookieValue = jest.fn(x => x.ShouldResetState = true); // // Act - // helper.handleInfoFromHeritageFunnel(); + // helper.loadReferralFromHeritageFunnelIfPresent(); // // Assert // expect(helper.getHeritageCookieValue).toHaveBeenCalled(); diff --git a/src/router/index.js b/src/router/index.js index 2e9ed4db1..1aebd3b77 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -5,7 +5,7 @@ import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js" import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; import { routerParameterKeys } from '@/router/router-constants/router-parameter-keys' -import { handleInfoFromHeritageFunnel, saveOrder, getHeritageCookieValue } from "@/helpers/heritage-integration-helper"; +import { loadReferralFromHeritageFunnelIfPresent, saveOrder, getHeritageCookieValue } from "@/helpers/heritage-integration-helper"; import baseMixin from "@/mixins/base-mixin"; import eventBus from "@/helpers/event-bus/event-bus"; @@ -33,7 +33,7 @@ const routes = [ // On entering the concept funnel if (from.redirectedFrom === undefined) { // Read cookie information, decide what to do next - handleInfoFromHeritageFunnel(); + loadReferralFromHeritageFunnelIfPresent(); } // If we have no query string, or we don't have the FmgPage query string. diff --git a/src/store/index.js b/src/store/index.js index dc93571d8..14d90744b 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -33,6 +33,7 @@ const getDefaultState = () => { referralNumber: null, referralDate: null, referralCorrelationId: null, + parentAccountNumber: null, }, applicationUser: { eventBus: [], @@ -97,6 +98,10 @@ export const mutations = { updateReferralDate(state, referralDate) { state.order.referralDate = referralDate; }, + updateParentAcctNumber(state, parentAcctNumber) { + state.order.parentAccountNumber = parentAcctNumber; + }, + // EVENT BUS MUTATIONS addEventToBus(state, event) { @@ -143,7 +148,25 @@ export const mutations = { // Misc Mutations setLoadOrderInformation(state, orderInformation) { - + state.order.referralNumber = orderInformation.ReferralNumber; + state.order.referralDate = orderInformation.ReferralDate; + state.order.referralCorrelationId = orderInformation.CorrelationId; + state.order.vehicle = { + year: orderInformation.Year, + make: orderInformation.Make, + model: orderInformation.Model, + style: orderInformation.Style, + carId: orderInformation.CarId, + category: orderInformation.Category, + imageUrl: orderInformation.ImageUrl, + imageVifNumber: orderInformation.ImageVifNumber, + imageColor: orderInformation.ImageColor + }; + state.order.damage.glassToReplace = orderInformation.GlassToReplace; + state.order.damage.isRepair = orderInformation.IsRepair; + state.order.damage.numberOfChips = orderInformation.NumberOfChips; + state.order.lineItems.glassParts = orderInformation.Parts; + state.order.parentAccountNumber = orderInformation.ParentAccountNumber; } } From d6eb6e0353a4c2b1587ad1a0416b7113fb5d9b95 Mon Sep 17 00:00:00 2001 From: Katie Date: Mon, 21 Mar 2022 16:02:49 -0400 Subject: [PATCH 13/58] CSR-98 Add tests --- src/helpers/heritage-integration-helper.js | 12 +- .../heritage-integration-helper.spec.js | 358 +++++++++++------- src/helpers/unit-test-helper.js | 67 ++-- src/router/index.js | 2 +- 4 files changed, 252 insertions(+), 187 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index a994ad057..41ff2543f 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -8,13 +8,9 @@ import baseMixin from "../mixins/base-mixin"; // Read info from heritage funnel and reset state or load referral export function handleInfoFromHeritageFunnel() { - const orderInfo = getHeritageCookieValue(); - console.log("A") - console.log(orderInfo) - console.log(document.cookie) + const orderInfo = this.getHeritageCookieValue(); if (orderInfo?.ShouldResetState) { - console.log("B") store.dispatch(storeActions.RESET_STATE); deleteHeritageCookie(); } @@ -25,12 +21,10 @@ export function handleInfoFromHeritageFunnel() { // ShouldResetState: false // }) } - - console.log("D") } export async function navigateToHeritageFunnel() { - await saveOrder(); + await this.saveOrder(); const referralCorrelationId = store.getters.referralCorrelationId; router.navigate( @@ -47,7 +41,6 @@ export async function navigateToHeritageFunnel() { } export async function saveOrder() { - console.log("HI") const savedOrderInfo = (await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER)).data; store.commit(storeMutations.UPDATE_REFERRAL_NUMBER, savedOrderInfo.referralNumber); store.commit(storeMutations.UPDATE_REFERRAL_DATE, savedOrderInfo.referralDate); @@ -60,7 +53,6 @@ export async function saveOrder() { /* Start cookie related functions */ export function getHeritageCookieValue() { - console.log("A") const cookieJson = document.cookie ?.split("; ") ?.find(row => row.startsWith(`${cookieNames.ORDER_INFO}=`)) diff --git a/src/helpers/heritage-integration-helper.spec.js b/src/helpers/heritage-integration-helper.spec.js index 78f673e84..361a3de68 100644 --- a/src/helpers/heritage-integration-helper.spec.js +++ b/src/helpers/heritage-integration-helper.spec.js @@ -4,73 +4,86 @@ import { setupMocksForJsFiles } from "@/helpers/unit-test-helper.js"; import { storeActions } from "@/constants/store-actions"; import { storeMutations } from "@/constants/store-mutations"; import store from "@/store"; +import router from "@/router"; +import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; +describe("handleInfoFromHeritageFunnel", () => { + afterEach(() => { + removeAllTestCookies(); + }); + + test("ShouldResetState == true => heritage cookie is deleted", () => { + // Arrange + const testShouldResetState = true; + + const testCookieValue = { + ShouldResetState: testShouldResetState + } + + document.cookie = `${cookieNames.ORDER_INFO}=${JSON.stringify(testCookieValue)}; path=/; domain=${location.hostname}`; + + // Act + helper.handleInfoFromHeritageFunnel(); + + // Assert + expect(document.cookie).toBe(""); + }); + + test("ShouldResetState == true => reset store", () => { + // Arrange + const getHeritageCookieValueMethod = jest.spyOn(helper, "getHeritageCookieValue") + getHeritageCookieValueMethod.mockImplementation(() => { return { ShouldResetState: true, DidHeritageFunnelUpdateLast: false } }); + + const mockData = { + actionList: [{ + actionName: storeActions.RESET_STATE + }], + } + + setupMocksForJsFiles(mockData); + store.dispatch = jest.spyOn(store, "dispatch"); + + // Act + helper.handleInfoFromHeritageFunnel(); + + // Assert + expect(getHeritageCookieValueMethod).toHaveBeenCalled(); + expect(store.dispatch).toHaveBeenCalledWith(storeActions.RESET_STATE); + + getHeritageCookieValueMethod.mockRestore(); + store.dispatch.mockRestore(); + }); + + test("Heritage cookie is null => store is unchanged", () => { + // Arrange + const getHeritageCookieValueMethod = jest.spyOn(helper, "getHeritageCookieValue") + getHeritageCookieValueMethod.mockImplementation(() => null); + + store.dispatch = jest.spyOn(store, "dispatch"); + + const mockData = { + actionList: [{ + actionName: storeActions.RESET_STATE + }], + } + + setupMocksForJsFiles(mockData); + + // Act + helper.handleInfoFromHeritageFunnel(); + + // Assert + expect(helper.getHeritageCookieValue).toHaveBeenCalled(); + expect(store.dispatch).not.toHaveBeenCalledWith(storeActions.RESET_STATE); + + getHeritageCookieValueMethod.mockRestore(); + store.dispatch.mockRestore(); + }); +}); describe("saveOrder", () => { - - // afterEach(() => { - // removeAllTestCookies(); - // }); - - function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate ) { - return { - referralNumber: mockReferralNumber, - referralCorrelationId: mockCorrelationId, - referralDate: mockReferralDate - } - } - - describe("handleInfoFromHeritageFunnel", () => { - // test("ShouldResetState == true => heritage cookie is deleted", () => { - // // Arrange - // // TODO CSR-98 Can we not mock this?? - // const testShouldResetState = true; - - // const testCookieValue = { - // ShouldResetState: testShouldResetState - // } - - // console.log(cookieNames.ORDER_INFO); - // console.log(testCookieValue) - // console.log(JSON.stringify(testCookieValue)); - // console.log(location.hostname) - // let myString = `${cookieNames.ORDER_INFO}=${JSON.stringify(testCookieValue)};domain=${location.hostname};path=/;`; - // console.log(myString) - // document.cookie = 'OrderInfo={"Hahahah":true};domain=localhost;path=/;'; - // console.log(document.cookie) - // document.cookie = "Ahhh=AHHH;" - // document.cookie = `${cookieNames.ORDER_INFO}=; Max-Age=0; domain=${location.hostname};`; - // console.log(document.cookie) - - // // Act - // helper.handleInfoFromHeritageFunnel(); - - // // Assert - // console.log(document.cookie) - // // expect(document.cookie).toBe(); - // }); - - // test("ShouldResetState == true => reset store", () => { - // // Arrange - // helper.getHeritageCookieValue = jest.fn(x => x.ShouldResetState = false); - - // // Act - // helper.handleInfoFromHeritageFunnel(); - - // // Assert - // expect(helper.getHeritageCookieValue).toHaveBeenCalled(); - // }); - - // test("Heritage cookie is null => store is unchanged", () => { - // // Arrange - // helper.getHeritageCookieValue = jest.fn(x => x.ShouldResetState = true); - - // // Act - // helper.handleInfoFromHeritageFunnel(); - - // // Assert - // expect(helper.getHeritageCookieValue).toHaveBeenCalled(); - // }); - }); + afterEach(() => { + removeAllTestCookies(); + }); test("saveOrder => should set state order values", async () => { // Arrange @@ -79,16 +92,18 @@ describe("saveOrder", () => { const mockReferralDate = "2022"; const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); - + const mockData = { - actionList: [{ - actionName: storeActions.SAVE_ORDER, - data: mockOrderInfo, + actionList: [{ + actionName: storeActions.SAVE_ORDER, + data: mockOrderInfo, }], + router: router } - - setupMocksForJsFiles(mockData); + setupMocksForJsFiles(mockData); + store.commit = jest.spyOn(store, "commit"); + // Act await helper.saveOrder(); @@ -97,48 +112,110 @@ describe("saveOrder", () => { expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_REFERRAL_NUMBER, mockReferralNumber); expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, mockCorrelationId); expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_REFERRAL_DATE, mockReferralDate); + store.commit.mockRestore(); }); - // test("saveOrder => should update DidHeritageFunnelUpdateLast cookie value", async () => { - // // Arrange - // const mockReferralNumber = 2; - // const mockCorrelationId = "55"; - // const mockReferralDate = "2022"; + test("saveOrder => should update DidHeritageFunnelUpdateLast cookie value to false", async () => { + // Arrange + const testReferralNumber = 1566818; + const testReferralDate = "2022-03-15T10:56:24.597"; + const testReferralCorrelationId = "404d2b04-f86e-45c3-b373-127b6217b060"; - // const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); - - // const mockData = { - // actionList: [{ - // actionName: storeActions.SAVE_ORDER, - // data: mockOrderInfo, - // }], - // } - - // setupMocksForJsFiles(mockData); - - // // Act - // await helper.saveOrder(); + const mockOrderInfo = getMockOrderInfo(testReferralNumber, testReferralCorrelationId, testReferralDate); - // // Assert - - // }); + const mockData = { + actionList: [{ + actionName: storeActions.SAVE_ORDER, + data: mockOrderInfo, + }], + router: router + } + + setupMocksForJsFiles(mockData); + + const testCookieValue = { + ReferralNumber: testReferralNumber, + ReferralDate: testReferralDate, + ReferralCorrelationId: testReferralCorrelationId, + ShouldResetState: false, + DidHeritageFunnelUpdateLast: true + } + + setupCookies({ heritageCookieValue: JSON.stringify(testCookieValue) }); + + // Act + await helper.saveOrder(); + + // Assert + expect(helper.getHeritageCookieValue().DidHeritageFunnelUpdateLast).toEqual(false); + }); }); describe("navigateToHeritageFunnel", () => { - test("should go to external link", () => { + test("should save order", async () => { // Arrange + const mockReferralNumber = 2; + const mockCorrelationId = "55"; + const mockReferralDate = "2022"; + + const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); + + const mockData = { + actionList: [{ + actionName: storeActions.SAVE_ORDER, + data: mockOrderInfo, + }], + router: router + } + + setupMocksForJsFiles(mockData); + const saveOrderFunction = jest.spyOn(helper, "saveOrder"); // Act - helper.navigateToHeritageFunnel(); + await helper.navigateToHeritageFunnel(); + + // Assert + expect(saveOrderFunction).toHaveBeenCalled(); + + // Should alway save before we navigate to heritage + const saveOrderFunctionCallOrder = saveOrderFunction.mock.invocationCallOrder[0]; + const routerNavigateFunctionCallOrder = router.navigate.mock.invocationCallOrder[0]; + expect(saveOrderFunctionCallOrder).toBeLessThan(routerNavigateFunctionCallOrder); + saveOrderFunction.mockRestore(); + }); + + test("should go to heritage funnel", async () => { + // Arrange + const mockReferralNumber = 2; + const mockCorrelationId = "55"; + const mockReferralDate = "2022"; + + const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); + + const mockData = { + actionList: [{ + actionName: storeActions.SAVE_ORDER, + data: mockOrderInfo, + }], + router: router + } + + setupMocksForJsFiles(mockData); + + // Act + await helper.navigateToHeritageFunnel(); // Assert expect(router.navigate).toHaveBeenCalled(); - expect(window.location.assign).toHaveBeenCalled(); - }) + expect(router.navigate).toHaveBeenCalledWith(navigationScenarios.MOVE_TO_HERITAGE_FUNNEL, expect.anything(), + expect.objectContaining({ + corid: mockCorrelationId + }) + ); + }); }); -// TODO CSR-98 Remove skip -describe.skip("cookies", () => { +describe("cookies", () => { afterEach(() => { removeAllTestCookies(); }) @@ -172,7 +249,7 @@ describe.skip("cookies", () => { expect(result.ReferralCorrelationId).toEqual(testReferralCorrelationId); expect(result.ShouldResetState).toEqual(testShouldResetState); expect(result.DidHeritageFunnelUpdateLast).toEqual(testDidHeritageFunnelUpdateLast); - }) + }); test("returns empty object when value is empty object", () => { // Arrange @@ -186,7 +263,7 @@ describe.skip("cookies", () => { expect(result).toEqual(testCookieValue); expect(typeof result).toEqual("object"); expect(Object.keys(result)).toHaveLength(0); - }) + }); test("returns null when value is empty string", () => { // Arrange @@ -198,7 +275,7 @@ describe.skip("cookies", () => { // Assert expect(result).toEqual(null); - }) + }); test("returns null when heritage cookie doesn't exist", () => { // Arrange @@ -209,7 +286,31 @@ describe.skip("cookies", () => { // Assert expect(result).toEqual(null); - }) + }); + + test("gets correct cookie value", () => { + // Arrange + const testCookieValue = { test: "testValue" }; + + setupCookies({ heritageCookieValue: JSON.stringify(testCookieValue) }); + + // Act + const actualCookieValue = helper.getHeritageCookieValue(); + + // Assert + expect(actualCookieValue).toEqual(testCookieValue); + }); + + test("getCookieValue: Gets null cookie value", () => { + // Arrange + setupCookies({ includeHeritageCookie: false }); + + // Act + const actualCookieValue = helper.getHeritageCookieValue(); + + // Assert + expect(actualCookieValue).toBeNull(); + }); }) }) @@ -225,58 +326,25 @@ const cookies = { }; function setupCookies({ heritageCookieValue = "", includeHeritageCookie = true }) { - console.log(heritageCookieValue) Object.keys(cookies).forEach(key => { const cookieValue = key == cookieNames.ORDER_INFO ? heritageCookieValue : cookies[key]; - + if (includeHeritageCookie || key != cookieNames.ORDER_INFO) - document.cookie = `${key}=${cookieValue}`; + document.cookie = `${key}=${cookieValue}; path=/;`; }); } function removeAllTestCookies() { Object.keys(cookies).forEach(key => { document.cookie = `${key}=;Max-Age=0;`; + document.cookie = `${key}=;Max-Age=0;path=/`; }); } - - // test("getCookieValue: Gets correct cookie value", () => { - // // Arrange - // const mixIn = getMixInInstance({}); - // const testCookieName = "testCookie"; - // const testCookieValue = "testCookieValue"; - // document.cookie = `yearMakeModel=2020 ACURA MDX;`; - // document.cookie = `SavedQuoteID=d2770645-0680-4852-9649-6170659b1bd6;`; - // document.cookie = `${testCookieName}=${testCookieValue};`; - // document.cookie = `EMBEDDEDPAYMENTPAGE_PAYPAL_SUBMITBUTTON=COMPLETED;`; - // document.cookie = `orderconfirmation=7411543;`; - - // console.log(document.cookie) - - // // Act - // const actualCookieValue = mixIn.methods.getCookieValue(testCookieName); - - // // Assert - // expect(actualCookieValue).toEqual(testCookieValue); - // expect(document.cookie).toEqual(`yearMakeModel=2020 ACURA MDX; SavedQuoteID=d2770645-0680-4852-9649-6170659b1bd6; ${testCookieName}=${testCookieValue}; EMBEDDEDPAYMENTPAGE_PAYPAL_SUBMITBUTTON=COMPLETED; orderconfirmation=7411543`); - // clearCookies(); - // }); - - // test("getCookieValue: Gets undefined cookie value", () => { - // // Arrange - // const mixIn = getMixInInstance({}); - // const testCookieName = "testCookie"; - - // document.cookie = `yearMakeModel=2020 ACURA MDX;`; - // document.cookie = `SavedQuoteID=d2770645-0680-4852-9649-6170659b1bd6;`; - // document.cookie = `EMBEDDEDPAYMENTPAGE_PAYPAL_SUBMITBUTTON=COMPLETED;`; - // document.cookie = `orderconfirmation=7411543;`; - - // // Act - // const actualCookieValue = mixIn.methods.getCookieValue(testCookieName); - - // // Assert - // expect(actualCookieValue).toEqual(undefined); - // expect(document.cookie).toEqual(`yearMakeModel=2020 ACURA MDX; SavedQuoteID=d2770645-0680-4852-9649-6170659b1bd6; EMBEDDEDPAYMENTPAGE_PAYPAL_SUBMITBUTTON=COMPLETED; orderconfirmation=7411543;`); - // }); \ No newline at end of file +function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate) { + return { + referralNumber: mockReferralNumber, + referralCorrelationId: mockCorrelationId, + referralDate: mockReferralDate + } +} diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 386dfa414..623acbca8 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -4,29 +4,31 @@ import { navigationScenarios } from "@/router/router-constants/navigation-scenar import { vehicleCategories } from "@/constants/vehicle-categories.js"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import baseMixin from "@/mixins/base-mixin"; -import store from "@/store"; export function getMountOptions(mockData) { // Define our mocks to attached to the 'global' object for Vue/Jest. const mocks = {}; //this is mocking if you use the mixin directly(baseMixin.methods.dispatchNonBlockingStoreAction) vs this.dispatchNonBlockingStoreAction - if (mockData.actionList !== undefined) { - // baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); - // baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { - // let actionFilterResult = mockData.actionList.filter( - // (x) => x.actionName == actionName - // ); + setupBaseMixinDispatchNonBlockingStoreAction(mockData); + // if (mockData.actionList !== undefined) { + // // baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); + // // baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { + // // let actionFilterResult = mockData.actionList.filter( + // // (x) => x.actionName == actionName + // // ); - // if (actionFilterResult.length > 0 && actionFilterResult.length === 1) { - // return Promise.resolve({ - // data: actionFilterResult[0].data, - // }); - // } - // }); + // // if (actionFilterResult.length > 0 && actionFilterResult.length === 1) { + // // return Promise.resolve({ + // // data: actionFilterResult[0].data, + // // }); + // // } + // // }); - setupDispatchNonBlockingStoreAction(mockData); - } + + // } + + mocks.dispatchNonBlockingStoreAction = jest.fn(); mocks.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { let actionFilterResult = mockData.actionList.filter( @@ -59,23 +61,26 @@ export function getMountOptions(mockData) { return { global }; } -function setupDispatchNonBlockingStoreAction(mockData) { +function setupBaseMixinDispatchNonBlockingStoreAction(mockData) { baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); - baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { - let actionFilterResult = mockData.actionList.filter( - (x) => x.actionName == actionName - ); - - if (actionFilterResult.length > 0 && actionFilterResult.length === 1) { - return Promise.resolve({ - data: actionFilterResult[0].data, - }); - } - }); + if (mockData.actionList !== undefined) { + baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { + let actionFilterResult = mockData.actionList.filter( + (x) => x.actionName == actionName + ); + + if (actionFilterResult.length > 0 && actionFilterResult.length === 1) { + return Promise.resolve({ + data: actionFilterResult[0].data, + }); + } + }); + } } -export function setupMocksForJsFiles(mockData) { - setupDispatchNonBlockingStoreAction(mockData); - store.commit = jest.fn(); - router.navigate = jest.fn(); +export function setupMocksForJsFiles(mockData = {}) { + setupBaseMixinDispatchNonBlockingStoreAction(mockData); + + if (mockData.router) + mockData.router.navigate = jest.fn(); } \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index abc7a1991..ba9c7d34c 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -159,7 +159,7 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery // Append page data to the store for the NEXT page, if any. It will be an empty object if none is provided. baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); - // if cookie and referralNumber exists + // if cookie and referral exists if (getHeritageCookieValue()?.ReferralNumber) saveOrder(); From f7ddb5ff6cf08c6f343ceb55dbbb22cd8ccae91c Mon Sep 17 00:00:00 2001 From: FrankRua Date: Mon, 21 Mar 2022 16:18:25 -0400 Subject: [PATCH 14/58] cleanup, setup state for referrals --- src/helpers/heritage-integration-helper.js | 40 +++++++++------- src/router/index.js | 21 ++++----- .../router-constants/router-parameter-keys.js | 4 +- src/store/index.js | 47 +++++++++---------- 4 files changed, 55 insertions(+), 57 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index e4534631f..61e410604 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -9,8 +9,8 @@ import baseMixin from "../mixins/base-mixin"; export async function loadReferralFromHeritageFunnelIfPresent() { const orderInfo = getHeritageCookieValue(); - // Do nothing if there is no cookie. - if(orderInfo === null){ + // Do nothing if there is no cookie or no correlation id. + if (orderInfo === null || orderInfo.ReferralCorrelationId === undefined) { return; } @@ -22,12 +22,14 @@ export async function loadReferralFromHeritageFunnelIfPresent() { } // Load referral if there is a cookie, and it doesn't indicate it needs a state reset. - await loadOrder(); + await loadOrder(orderInfo.ReferralNumber, orderInfo.ReferralDate, orderInfo.ReferralCorrelationId); } +// Navigate to Heritage Funnel with the proper URL format. +// Will Save the referral if there is one in state, or create a new one if one is not in state. export async function navigateToHeritageFunnel() { await saveOrder(); - const referralCorrelationId = store.getters.referralCorrelationId; + const referralCorrelationId = store.state.order.referralCorrelationId; router.navigate( navigationScenarios.MOVE_TO_HERITAGE_FUNNEL, @@ -42,42 +44,44 @@ export async function navigateToHeritageFunnel() { ); } +// Saves Referral if one is available and commits referral details to state. +// Also sets cookie properties. export async function saveOrder() { - const savedOrderInfo = (await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER)).data; + const savedOrderInfo = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER); // Save the referral information back from the store. await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SET_REFERRAL_INFORMATION, { - referralNumber: savedOrderInfo.referralNumber, - correlationId: savedOrderInfo.referralCorrelationId, - referralDate: savedOrderInfo.referralDate, - }) + referralNumber: savedOrderInfo.data.referralNumber, + correlationId: savedOrderInfo.data.referralCorrelationId, + referralDate: savedOrderInfo.data.referralDate, + }, false); // Set cookie properties. setHeritageCookieProperties({ DidHeritageFunnelUpdateLast: false - }) + }); } -export async function loadOrder() { - const loadOrderInfo = (await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER)).data; - - // Save the data from the loaded order to state. - await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SET_LOAD_ORDER_DATA, { loadOrderInfo }); +// Loads order based on referral data in cookie, also loads the referral information into state. +export async function loadOrder(referralNumber, referralDate, correlationId) { + const loadOrderResponse = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER, + { referralNumber: referralNumber, referralDate: referralDate, correlationId: correlationId } + , false); } // --------- PRIVATE FUNCTIONS --------- /* Start cookie related functions */ export function getHeritageCookieValue() { - console.log("A") + console.log("getHeritageCookieValue called"); const cookieJson = document.cookie ?.split("; ") ?.find(row => row.startsWith(`${cookieNames.ORDER_INFO}=`)) ?.split("=")[1]; - + try { return JSON.parse(cookieJson); - } catch(error) { + } catch (error) { return null; } } diff --git a/src/router/index.js b/src/router/index.js index 1aebd3b77..2dd8e8486 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -4,7 +4,6 @@ import { storeActions } from "@/constants/store-actions"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; -import { routerParameterKeys } from '@/router/router-constants/router-parameter-keys' import { loadReferralFromHeritageFunnelIfPresent, saveOrder, getHeritageCookieValue } from "@/helpers/heritage-integration-helper"; import baseMixin from "@/mixins/base-mixin"; @@ -30,17 +29,17 @@ const routes = [ path: "/", name: "root", async beforeEnter(to, from, next) { - // On entering the concept funnel - if (from.redirectedFrom === undefined) { - // Read cookie information, decide what to do next - loadReferralFromHeritageFunnelIfPresent(); - } - // If we have no query string, or we don't have the FmgPage query string. if (to.query.fmgPage === undefined) { await GoToFunnelStartOn404(next); } else { try { + + // On entering the concept funnel "fresh", read cookie information, decide what to do next. + if (from.redirectedFrom === undefined) { + await loadReferralFromHeritageFunnelIfPresent(); + } + // 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. @@ -135,15 +134,16 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); // if cookie and referralNumber exists - if (getHeritageCookieValue()?.ReferralNumber) - saveOrder(); + if (getHeritageCookieValue()?.ReferralNumber) { + await saveOrder(); + } router.push({ name: "root", query: Object.assign(optionalQuery, { fmgPage: destinationFmgPageValue, }), - params: Object.assign(optionalParams, {[routerParameterKeys.FROM_ROUTER_NAVIGATE]: true}) + params: optionalParams }); } else if (matchingScenarioMap.destinationUrl !== undefined) { navigateToUrl(matchingScenarioMap.destinationUrl, optionalQuery); @@ -152,7 +152,6 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery // Get navigation map depending on the scenario and the current 'page' you're on. function getNavigationMap(scenario, currentRoute) { - console.log("A") const fmgPageValue = currentRoute.query.fmgPage; const matchedQueryValue = routingTable .filter( diff --git a/src/router/router-constants/router-parameter-keys.js b/src/router/router-constants/router-parameter-keys.js index 7ace86f37..2407d74c4 100644 --- a/src/router/router-constants/router-parameter-keys.js +++ b/src/router/router-constants/router-parameter-keys.js @@ -1,5 +1,3 @@ -const routerParameterKeys = { - FROM_ROUTER_NAVIGATE: 'fromRouterNavigate', - }; +const routerParameterKeys = { }; export { routerParameterKeys }; \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js index 14d90744b..62de9805c 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -148,25 +148,25 @@ export const mutations = { // Misc Mutations setLoadOrderInformation(state, orderInformation) { - state.order.referralNumber = orderInformation.ReferralNumber; - state.order.referralDate = orderInformation.ReferralDate; - state.order.referralCorrelationId = orderInformation.CorrelationId; + state.order.referralNumber = orderInformation.referralNumber; + state.order.referralDate = orderInformation.referralDate; + state.order.referralCorrelationId = orderInformation.correlationId; state.order.vehicle = { - year: orderInformation.Year, - make: orderInformation.Make, - model: orderInformation.Model, - style: orderInformation.Style, - carId: orderInformation.CarId, - category: orderInformation.Category, - imageUrl: orderInformation.ImageUrl, - imageVifNumber: orderInformation.ImageVifNumber, - imageColor: orderInformation.ImageColor + year: orderInformation.vehicle.year, + make: orderInformation.vehicle.make, + model: orderInformation.vehicle.model, + style: orderInformation.vehicle.style, + carId: orderInformation.vehicle.carId, + category: orderInformation.vehicle.category, + imageUrl: orderInformation.vehicle.imageUrl, + imageVifNumber: orderInformation.vehicle.imageVifNumber, + imageColor: orderInformation.vehicle.imageVifColor }; - state.order.damage.glassToReplace = orderInformation.GlassToReplace; - state.order.damage.isRepair = orderInformation.IsRepair; - state.order.damage.numberOfChips = orderInformation.NumberOfChips; - state.order.lineItems.glassParts = orderInformation.Parts; - state.order.parentAccountNumber = orderInformation.ParentAccountNumber; + state.order.damage.glassToReplace = orderInformation.glassToReplace; + state.order.damage.isRepair = orderInformation.isRepair; + state.order.damage.numberOfChips = orderInformation.numberOfChips; + state.order.lineItems.glassParts = orderInformation.parts; + state.order.parentAccountNumber = orderInformation.parentAccountNumber; } } @@ -184,9 +184,6 @@ export const getters = { eventBus: (state) => state.applicationUser.eventBus, damage: (state) => state.order.damage, lineItems: (state) => state.order.lineItems, - referralNumber: (state) => state.order.referralNumber, - referralDate: (state) => state.order.referralDate, - referralCorrelationId: (state) => state.order.referralCorrelationId, pageData: (state) => (page) => { return state.applicationUser.pageData[page]; } @@ -321,9 +318,6 @@ export const actions = { context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate); context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, correlationId); }, - setLoadOrderData(context, { loadOrderData }) { - - }, // Parts API Actions getPartsOrQuestions(context, { carId, glassArray, zipCode, vin = '' }) { @@ -357,8 +351,8 @@ export const actions = { }, numberOfChips: damage.numberOfChips, glassToReplace: damage.glassToReplace, - referralNumber: context.getters.referralNumber, - referralDate: context.getters.referralDate + referralNumber: context.state.order.referralNumber, + referralDate: context.state.order.referralDate }, }); }, @@ -372,6 +366,9 @@ export const actions = { referralDate: referralDate, correlationId: correlationId }, + }).then( (response) => { + context.commit(storeMutations.SET_LOAD_ORDER_INFO, response.data); + return response; }); } } From aeca237b0538bd1e1c818297bd5d6710f32638c6 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Mon, 21 Mar 2022 18:46:21 -0400 Subject: [PATCH 15/58] started to re-do cookie --- src/constants/application-config.js | 1 + src/constants/cookie-names.js | 2 +- src/constants/store-mutations.js | 2 +- src/helpers/heritage-integration-helper.js | 114 +++++++++++------- .../heritage-integration-helper.spec.js | 12 +- src/router/index.js | 12 +- src/store/index.js | 2 +- 7 files changed, 88 insertions(+), 57 deletions(-) diff --git a/src/constants/application-config.js b/src/constants/application-config.js index 4b80d25d1..8c033d4cd 100644 --- a/src/constants/application-config.js +++ b/src/constants/application-config.js @@ -1,5 +1,6 @@ const applicationConfig = { CONSUMER_APIGATEWAY_URL: process.env.VUE_APP_CONSUMER_API_GATEWAY, + SESSION_TIMEOUT_CONFIG: 30 }; export { applicationConfig }; diff --git a/src/constants/cookie-names.js b/src/constants/cookie-names.js index 33a76ae43..6b1e3c909 100644 --- a/src/constants/cookie-names.js +++ b/src/constants/cookie-names.js @@ -1,5 +1,5 @@ const cookieNames = { - ORDER_INFO: "OrderInfo" + CONCEPT_SESSION_INFO: "ConceptSessionInfo", }; export { cookieNames }; diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 2636464bd..00ac66d58 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -34,7 +34,7 @@ const storeMutations = { // OTHER MUTATIONS UPDATE_PAGE_DATA: "updatePageData", - SET_LOAD_ORDER_INFO: "setLoadOrderInformation" + SET_LOAD_CONCEPT_SESSION_INFO: "setLoadOrderInformation" }; diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 61e410604..01950fdce 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -1,28 +1,30 @@ import { storeActions } from "@/constants/store-actions.js"; import { cookieNames } from "@/constants/cookie-names"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; +import { applicationConfig } from "@/constants/application-config"; import store from "@/store"; import router from "@/router"; import baseMixin from "../mixins/base-mixin"; + // Read info from heritage funnel and reset state or load referral export async function loadReferralFromHeritageFunnelIfPresent() { - const orderInfo = getHeritageCookieValue(); + // const orderInfo = getHeritageCookieValue(); - // Do nothing if there is no cookie or no correlation id. - if (orderInfo === null || orderInfo.ReferralCorrelationId === undefined) { - return; - } + // // Do nothing if there is no cookie or no correlation id. + // if (orderInfo === null || orderInfo.ReferralCorrelationId === undefined) { + // return; + // } - // Reset state if cookie says to. - if (orderInfo.ShouldResetState) { - baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); - deleteHeritageCookie(); - return; - } + // // Reset state if cookie says to. + // if (orderInfo.ShouldResetState) { + // baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); + // //deleteHeritageCookie(); + // return; + // } - // Load referral if there is a cookie, and it doesn't indicate it needs a state reset. - await loadOrder(orderInfo.ReferralNumber, orderInfo.ReferralDate, orderInfo.ReferralCorrelationId); + // // Load referral if there is a cookie, and it doesn't indicate it needs a state reset. + // await loadOrder(orderInfo.ReferralNumber, orderInfo.ReferralDate, orderInfo.ReferralCorrelationId); } // Navigate to Heritage Funnel with the proper URL format. @@ -47,19 +49,19 @@ export async function navigateToHeritageFunnel() { // Saves Referral if one is available and commits referral details to state. // Also sets cookie properties. export async function saveOrder() { - const savedOrderInfo = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER); + // const savedOrderInfo = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER); - // Save the referral information back from the store. - await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SET_REFERRAL_INFORMATION, { - referralNumber: savedOrderInfo.data.referralNumber, - correlationId: savedOrderInfo.data.referralCorrelationId, - referralDate: savedOrderInfo.data.referralDate, - }, false); + // // Save the referral information back from the store. + // await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SET_REFERRAL_INFORMATION, { + // referralNumber: savedOrderInfo.data.referralNumber, + // correlationId: savedOrderInfo.data.referralCorrelationId, + // referralDate: savedOrderInfo.data.referralDate, + // }, false); - // Set cookie properties. - setHeritageCookieProperties({ - DidHeritageFunnelUpdateLast: false - }); + // // Set cookie properties. + // setHeritageCookieProperties({ + // DidHeritageFunnelUpdateLast: false + // }); } // Loads order based on referral data in cookie, also loads the referral information into state. @@ -69,14 +71,42 @@ export async function loadOrder(referralNumber, referralDate, correlationId) { , false); } +export function updateOrCreateConceptCookie() { + // Create the cookie + document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}={}; path=/`; + + // Set up cookie with all the props. + setConceptCookieProperties({ + LastTouched: new Date(), + DidHeritageFunnelUpdateLast: false, + ReferralNumber: store.state.order.referralNumber, + ReferralDate: store.state.order.referralDate, + ReferralCorrelationId: store.state.order.referralCorrelationId, + }); + +} + +export function isConceptSessionStillActive() { + if(getConceptCookie() !== null){ + const lastTouchedValue = getConceptCookie().LastTouched; + const timeoutAmount = applicationConfig.SESSION_TIMEOUT_CONFIG; + const isMoreThanHalfHourAgo = ((new Date() - new Date(lastTouchedValue)) / 60000) > timeoutAmount; + + if(isMoreThanHalfHourAgo){ + return false; + } + + return true; + } +} + // --------- PRIVATE FUNCTIONS --------- /* Start cookie related functions */ -export function getHeritageCookieValue() { - console.log("getHeritageCookieValue called"); +export function getConceptCookie() { const cookieJson = document.cookie ?.split("; ") - ?.find(row => row.startsWith(`${cookieNames.ORDER_INFO}=`)) + ?.find(row => row.startsWith(`${cookieNames.CONCEPT_SESSION_INFO}=`)) ?.split("=")[1]; try { @@ -86,31 +116,27 @@ export function getHeritageCookieValue() { } } -function deleteHeritageCookie() { - // If this cookie is ever created from the concept funnel, will need to add another - // line with the path=/fmg/ - document.cookie = `${cookieNames.ORDER_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; -} - -function setHeritageCookieValue(cookieValue) { - let cookieValueJson = cookieValue; - if (typeof cookieValue == "object") - cookieValueJson = JSON.stringify(cookieValue); - - document.cookie = `${cookieNames.ORDER_INFO}=${cookieValueJson}; path=/`; -} - -function setHeritageCookieProperties(properties) { +function setConceptCookieProperties(properties) { if (typeof properties == "object") { - let cookie = getHeritageCookieValue(); + let cookie = getConceptCookie(); if (cookie !== null) { Object.keys(properties).forEach(key => { cookie[key] = properties[key]; }); - setHeritageCookieValue(cookie); + const cookieValueJson = JSON.stringify(cookie); + + document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=${cookieValueJson}; path=/`; } } } + +// function deleteHeritageCookie() { +// // If this cookie is ever created from the concept funnel, will need to add another +// // line with the path=/fmg/ +// document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; +// } + + /* End cookie related functions */ diff --git a/src/helpers/heritage-integration-helper.spec.js b/src/helpers/heritage-integration-helper.spec.js index f99187474..a5f7fd437 100644 --- a/src/helpers/heritage-integration-helper.spec.js +++ b/src/helpers/heritage-integration-helper.spec.js @@ -29,16 +29,16 @@ describe("saveOrder", () => { // ShouldResetState: testShouldResetState // } - // console.log(cookieNames.ORDER_INFO); + // console.log(cookieNames.CONCEPT_SESSION_INFO); // console.log(testCookieValue) // console.log(JSON.stringify(testCookieValue)); // console.log(location.hostname) - // let myString = `${cookieNames.ORDER_INFO}=${JSON.stringify(testCookieValue)};domain=${location.hostname};path=/;`; + // let myString = `${cookieNames.CONCEPT_SESSION_INFO}=${JSON.stringify(testCookieValue)};domain=${location.hostname};path=/;`; // console.log(myString) // document.cookie = 'OrderInfo={"Hahahah":true};domain=localhost;path=/;'; // console.log(document.cookie) // document.cookie = "Ahhh=AHHH;" - // document.cookie = `${cookieNames.ORDER_INFO}=; Max-Age=0; domain=${location.hostname};`; + // document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; domain=${location.hostname};`; // console.log(document.cookie) // // Act @@ -217,7 +217,7 @@ describe.skip("cookies", () => { const cookies = { "orderconfirmation": 1565980, "optimizelyEndUserId": "oeu1610051865958r0.07937134272718804", - [cookieNames.ORDER_INFO]: `{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false,"DidHeritageFunnelUpdateLast":true}`, + [cookieNames.CONCEPT_SESSION_INFO]: `{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false,"DidHeritageFunnelUpdateLast":true}`, "UNIQUE_SESSION_ID": "33756020-b58e-4ec7-b8b8-3f1576719c40", "_ga": "GA1.1.1631274579.1622658999", "da_lid": "B10847599A73EA95861EBB99009A283E27|0|0|0 clientTag=null", @@ -227,9 +227,9 @@ const cookies = { function setupCookies({ heritageCookieValue = "", includeHeritageCookie = true }) { console.log(heritageCookieValue) Object.keys(cookies).forEach(key => { - const cookieValue = key == cookieNames.ORDER_INFO ? heritageCookieValue : cookies[key]; + const cookieValue = key == cookieNames.CONCEPT_SESSION_INFO ? heritageCookieValue : cookies[key]; - if (includeHeritageCookie || key != cookieNames.ORDER_INFO) + if (includeHeritageCookie || key != cookieNames.CONCEPT_SESSION_INFO) document.cookie = `${key}=${cookieValue}`; }); } diff --git a/src/router/index.js b/src/router/index.js index 2dd8e8486..79db19b63 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -4,7 +4,7 @@ import { storeActions } from "@/constants/store-actions"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; -import { loadReferralFromHeritageFunnelIfPresent, saveOrder, getHeritageCookieValue } from "@/helpers/heritage-integration-helper"; +import { updateOrCreateConceptCookie, loadReferralFromHeritageFunnelIfPresent, isConceptSessionStillActive} from "@/helpers/heritage-integration-helper"; import baseMixin from "@/mixins/base-mixin"; import eventBus from "@/helpers/event-bus/event-bus"; @@ -35,6 +35,10 @@ const routes = [ } else { try { + // Check our 'Session' is still good, update the cookie. + isConceptSessionStillActive(); + updateOrCreateConceptCookie(); + // On entering the concept funnel "fresh", read cookie information, decide what to do next. if (from.redirectedFrom === undefined) { await loadReferralFromHeritageFunnelIfPresent(); @@ -134,9 +138,9 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); // if cookie and referralNumber exists - if (getHeritageCookieValue()?.ReferralNumber) { - await saveOrder(); - } + // if (getHeritageCookieValue()?.ReferralNumber) { + // await saveOrder(); + // } router.push({ name: "root", diff --git a/src/store/index.js b/src/store/index.js index 62de9805c..af280675e 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -367,7 +367,7 @@ export const actions = { correlationId: correlationId }, }).then( (response) => { - context.commit(storeMutations.SET_LOAD_ORDER_INFO, response.data); + context.commit(storeMutations.SET_LOAD_CONCEPT_SESSION_INFO, response.data); return response; }); } From c6dac0bb96e00b594ab847b6eba300d114b599e9 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Mon, 21 Mar 2022 18:51:00 -0400 Subject: [PATCH 16/58] function updates --- src/helpers/heritage-integration-helper.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 01950fdce..010d1f1cb 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -103,7 +103,7 @@ export function isConceptSessionStillActive() { // --------- PRIVATE FUNCTIONS --------- /* Start cookie related functions */ -export function getConceptCookie() { +function getConceptCookie() { const cookieJson = document.cookie ?.split("; ") ?.find(row => row.startsWith(`${cookieNames.CONCEPT_SESSION_INFO}=`)) @@ -132,11 +132,11 @@ function setConceptCookieProperties(properties) { } } -// function deleteHeritageCookie() { -// // If this cookie is ever created from the concept funnel, will need to add another -// // line with the path=/fmg/ -// document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; -// } +function deleteConceptCookie() { + // If this cookie is ever created from the concept funnel, will need to add another + // line with the path=/fmg/ + document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; +} /* End cookie related functions */ From c77c8e12a2f9792769bd08d84452c3dd1c477773 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 22 Mar 2022 08:41:02 -0400 Subject: [PATCH 17/58] more integration helper changes --- src/helpers/heritage-integration-helper.js | 130 ++++++++++-------- .../heritage-integration-helper.spec.js | 8 +- src/router/index.js | 24 ++-- 3 files changed, 93 insertions(+), 69 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 010d1f1cb..6a421a90b 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -7,71 +7,64 @@ import router from "@/router"; import baseMixin from "../mixins/base-mixin"; -// Read info from heritage funnel and reset state or load referral -export async function loadReferralFromHeritageFunnelIfPresent() { - // const orderInfo = getHeritageCookieValue(); - - // // Do nothing if there is no cookie or no correlation id. - // if (orderInfo === null || orderInfo.ReferralCorrelationId === undefined) { - // return; - // } - - // // Reset state if cookie says to. - // if (orderInfo.ShouldResetState) { - // baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); - // //deleteHeritageCookie(); - // return; - // } - - // // Load referral if there is a cookie, and it doesn't indicate it needs a state reset. - // await loadOrder(orderInfo.ReferralNumber, orderInfo.ReferralDate, orderInfo.ReferralCorrelationId); -} - -// Navigate to Heritage Funnel with the proper URL format. -// Will Save the referral if there is one in state, or create a new one if one is not in state. -export async function navigateToHeritageFunnel() { - await saveOrder(); - const referralCorrelationId = store.state.order.referralCorrelationId; - - router.navigate( - navigationScenarios.MOVE_TO_HERITAGE_FUNNEL, - router.currentRoute.value, - { - corid: referralCorrelationId, - src: "concept-funnel", - // TODO CSR-98 REMOVE THIS - cns: "all", - experiments: "RemoveServiceAreaPage=ServAreaRemoval_V7=ServAreaNoRemove_V7_TEST=true,ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" - } - ); -} - // Saves Referral if one is available and commits referral details to state. -// Also sets cookie properties. export async function saveOrder() { - // const savedOrderInfo = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER); + console.log("saving order..."); + const savedOrderInfo = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER); - // // Save the referral information back from the store. - // await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SET_REFERRAL_INFORMATION, { - // referralNumber: savedOrderInfo.data.referralNumber, - // correlationId: savedOrderInfo.data.referralCorrelationId, - // referralDate: savedOrderInfo.data.referralDate, - // }, false); + // Save the referral information back from the store. + await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SET_REFERRAL_INFORMATION, { + referralNumber: savedOrderInfo.data.referralNumber, + correlationId: savedOrderInfo.data.referralCorrelationId, + referralDate: savedOrderInfo.data.referralDate, + }, false); - // // Set cookie properties. - // setHeritageCookieProperties({ - // DidHeritageFunnelUpdateLast: false - // }); + // Update the cookie with the referral information when saved. + updateOrCreateConceptCookie(); } // Loads order based on referral data in cookie, also loads the referral information into state. export async function loadOrder(referralNumber, referralDate, correlationId) { - const loadOrderResponse = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER, + console.log("loading order...", referralNumber, referralDate, correlationId); + await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER, { referralNumber: referralNumber, referralDate: referralDate, correlationId: correlationId } , false); } +// Read info from heritage funnel and reset state or load referral +export async function loadReferralIfPresent() { + console.log("attempting to load referral...."); + const conceptCookie = getConceptCookie(); + + // Do nothing if there is no cookie or no correlation id. + if (conceptCookie === null || conceptCookie.ReferralCorrelationId === null) { + console.log("No referral found"); + return; + } + + // Reset state if cookie says to. + if (conceptCookie.ShouldResetState) { + console.log("Resetting state..."); + baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); + deleteConceptCookie(); + return; + } + + console.log("Loading order..."); + // Load referral if there is a cookie, and it doesn't indicate it needs a state reset. + await loadOrder(conceptCookie.ReferralNumber, conceptCookie.ReferralDate, conceptCookie.ReferralCorrelationId); +} + export function updateOrCreateConceptCookie() { + console.log("Updating cookie...", { + LastTouched: new Date(), + DidHeritageFunnelUpdateLast: false, + ShouldResetState: false, + ReferralNumber: store.state.order.referralNumber, + ReferralDate: store.state.order.referralDate, + ReferralCorrelationId: store.state.order.referralCorrelationId, + }); + // Create the cookie document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}={}; path=/`; @@ -79,6 +72,7 @@ export function updateOrCreateConceptCookie() { setConceptCookieProperties({ LastTouched: new Date(), DidHeritageFunnelUpdateLast: false, + ShouldResetState: false, ReferralNumber: store.state.order.referralNumber, ReferralDate: store.state.order.referralDate, ReferralCorrelationId: store.state.order.referralCorrelationId, @@ -87,12 +81,14 @@ export function updateOrCreateConceptCookie() { } export function isConceptSessionStillActive() { - if(getConceptCookie() !== null){ + if (getConceptCookie() !== null) { const lastTouchedValue = getConceptCookie().LastTouched; const timeoutAmount = applicationConfig.SESSION_TIMEOUT_CONFIG; const isMoreThanHalfHourAgo = ((new Date() - new Date(lastTouchedValue)) / 60000) > timeoutAmount; - if(isMoreThanHalfHourAgo){ + console.log("has session expired -->", isMoreThanHalfHourAgo); + + if (isMoreThanHalfHourAgo) { return false; } @@ -100,10 +96,27 @@ export function isConceptSessionStillActive() { } } -// --------- PRIVATE FUNCTIONS --------- +// Navigate to Heritage Funnel with the proper URL format. +// Will Save the referral if there is one in state, or create a new one if one is not in state. +export async function navigateToHeritageFunnel() { + + // Create the order (or save existing order) when navigating to Heritage Funnel. + await saveOrder(); + + router.navigate( + navigationScenarios.MOVE_TO_HERITAGE_FUNNEL, + router.currentRoute.value, + { + corid: store.state.order.referralCorrelationId, + src: "concept-funnel", + cns: "all", + experiments: "RemoveServiceAreaPage=ServAreaRemoval_V7=ServAreaNoRemove_V7_TEST=true,ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" + } + ); +} /* Start cookie related functions */ -function getConceptCookie() { +export function getConceptCookie() { const cookieJson = document.cookie ?.split("; ") ?.find(row => row.startsWith(`${cookieNames.CONCEPT_SESSION_INFO}=`)) @@ -116,6 +129,11 @@ function getConceptCookie() { } } + + + +// --------- PRIVATE FUNCTIONS --------- + function setConceptCookieProperties(properties) { if (typeof properties == "object") { let cookie = getConceptCookie(); diff --git a/src/helpers/heritage-integration-helper.spec.js b/src/helpers/heritage-integration-helper.spec.js index a5f7fd437..eb1130c21 100644 --- a/src/helpers/heritage-integration-helper.spec.js +++ b/src/helpers/heritage-integration-helper.spec.js @@ -19,7 +19,7 @@ describe("saveOrder", () => { } } - describe("loadReferralFromHeritageFunnelIfPresent", () => { + describe("loadReferralIfPresent", () => { // test("ShouldResetState == true => heritage cookie is deleted", () => { // // Arrange // // TODO CSR-98 Can we not mock this?? @@ -42,7 +42,7 @@ describe("saveOrder", () => { // console.log(document.cookie) // // Act - // helper.loadReferralFromHeritageFunnelIfPresent(); + // helper.loadReferralIfPresent(); // // Assert // console.log(document.cookie) @@ -54,7 +54,7 @@ describe("saveOrder", () => { // helper.getHeritageCookieValue = jest.fn(x => x.ShouldResetState = false); // // Act - // helper.loadReferralFromHeritageFunnelIfPresent(); + // helper.loadReferralIfPresent(); // // Assert // expect(helper.getHeritageCookieValue).toHaveBeenCalled(); @@ -65,7 +65,7 @@ describe("saveOrder", () => { // helper.getHeritageCookieValue = jest.fn(x => x.ShouldResetState = true); // // Act - // helper.loadReferralFromHeritageFunnelIfPresent(); + // helper.loadReferralIfPresent(); // // Assert // expect(helper.getHeritageCookieValue).toHaveBeenCalled(); diff --git a/src/router/index.js b/src/router/index.js index 79db19b63..54a64c5d2 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -4,7 +4,7 @@ import { storeActions } from "@/constants/store-actions"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; -import { updateOrCreateConceptCookie, loadReferralFromHeritageFunnelIfPresent, isConceptSessionStillActive} from "@/helpers/heritage-integration-helper"; +import * as integrationHelper from "@/helpers/heritage-integration-helper"; import baseMixin from "@/mixins/base-mixin"; import eventBus from "@/helpers/event-bus/event-bus"; @@ -35,13 +35,19 @@ const routes = [ } else { try { - // Check our 'Session' is still good, update the cookie. - isConceptSessionStillActive(); - updateOrCreateConceptCookie(); + // Check our 'Session' is still good. + // If not, reset state and go back to the start. + if (!integrationHelper.isConceptSessionStillActive()) { + baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); + await GoToFunnelStartOn404(next); + } + + // Create funnel cookie, or update it if it already exists. + integrationHelper.updateOrCreateConceptCookie(); // On entering the concept funnel "fresh", read cookie information, decide what to do next. if (from.redirectedFrom === undefined) { - await loadReferralFromHeritageFunnelIfPresent(); + await integrationHelper.loadReferralIfPresent(); } // If we already have our route, go to it. @@ -137,10 +143,10 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery // Append page data to the store for the NEXT page, if any. It will be an empty object if none is provided. baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); - // if cookie and referralNumber exists - // if (getHeritageCookieValue()?.ReferralNumber) { - // await saveOrder(); - // } + // if cookie and referralNumber/Date exists + if (integrationHelper.getConceptCookie()?.ReferralNumber && integrationHelper.getConceptCookie()?.ReferralDate) { + await integrationHelper.saveOrder(); + } router.push({ name: "root", From 5eedfb9ce670ab149da92f9dfa2d73e287220d8c Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 22 Mar 2022 12:22:07 -0400 Subject: [PATCH 18/58] small refactor --- src/helpers/heritage-integration-helper.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 6a421a90b..53ff90aab 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -2,6 +2,7 @@ import { storeActions } from "@/constants/store-actions.js"; import { cookieNames } from "@/constants/cookie-names"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import { applicationConfig } from "@/constants/application-config"; + import store from "@/store"; import router from "@/router"; import baseMixin from "../mixins/base-mixin"; @@ -27,7 +28,7 @@ export async function saveOrder() { export async function loadOrder(referralNumber, referralDate, correlationId) { console.log("loading order...", referralNumber, referralDate, correlationId); await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER, - { referralNumber: referralNumber, referralDate: referralDate, correlationId: correlationId } + { referralNumber: referralNumber.toString(), referralDate: referralDate, correlationId: correlationId } , false); } @@ -50,14 +51,14 @@ export async function loadReferralIfPresent() { return; } - console.log("Loading order..."); + console.log("calling load order from loadReferralIfPresent()..."); // Load referral if there is a cookie, and it doesn't indicate it needs a state reset. await loadOrder(conceptCookie.ReferralNumber, conceptCookie.ReferralDate, conceptCookie.ReferralCorrelationId); } export function updateOrCreateConceptCookie() { console.log("Updating cookie...", { - LastTouched: new Date(), + LastTouched: new Date().toUTCString(), DidHeritageFunnelUpdateLast: false, ShouldResetState: false, ReferralNumber: store.state.order.referralNumber, @@ -70,7 +71,7 @@ export function updateOrCreateConceptCookie() { // Set up cookie with all the props. setConceptCookieProperties({ - LastTouched: new Date(), + LastTouched: new Date().toUTCString(), DidHeritageFunnelUpdateLast: false, ShouldResetState: false, ReferralNumber: store.state.order.referralNumber, @@ -85,7 +86,6 @@ export function isConceptSessionStillActive() { const lastTouchedValue = getConceptCookie().LastTouched; const timeoutAmount = applicationConfig.SESSION_TIMEOUT_CONFIG; const isMoreThanHalfHourAgo = ((new Date() - new Date(lastTouchedValue)) / 60000) > timeoutAmount; - console.log("has session expired -->", isMoreThanHalfHourAgo); if (isMoreThanHalfHourAgo) { @@ -129,9 +129,6 @@ export function getConceptCookie() { } } - - - // --------- PRIVATE FUNCTIONS --------- function setConceptCookieProperties(properties) { From 8e21ccec6cacf24adb2eab5dc25d3b1f293faa8f Mon Sep 17 00:00:00 2001 From: FrankRua Date: Wed, 23 Mar 2022 12:55:04 -0400 Subject: [PATCH 19/58] update to account for session --- src/helpers/heritage-integration-helper.js | 73 ++-- .../heritage-integration-helper.spec.js | 8 +- src/layouts/vehicle-damage/vehicle-damage.vue | 10 +- src/layouts/vehicle-make/vehicle-make.vue | 5 +- src/layouts/vehicle-model/vehicle-model.vue | 5 +- src/layouts/vehicle-parts/vehicle-parts.vue | 393 +++++++++--------- src/layouts/vehicle-style/vehicle-style.vue | 5 +- src/router/index.js | 16 +- src/router/router-constants/routing-table.js | 5 - src/store/index.js | 18 +- 10 files changed, 297 insertions(+), 241 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 53ff90aab..3ee84c437 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -1,14 +1,13 @@ import { storeActions } from "@/constants/store-actions.js"; import { cookieNames } from "@/constants/cookie-names"; -import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; +import { externalUrls } from "@/router/router-constants/externalUrl-values"; import { applicationConfig } from "@/constants/application-config"; +import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import store from "@/store"; import router from "@/router"; import baseMixin from "../mixins/base-mixin"; - -// Saves Referral if one is available and commits referral details to state. export async function saveOrder() { console.log("saving order..."); const savedOrderInfo = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER); @@ -24,23 +23,14 @@ export async function saveOrder() { updateOrCreateConceptCookie(); } -// Loads order based on referral data in cookie, also loads the referral information into state. -export async function loadOrder(referralNumber, referralDate, correlationId) { - console.log("loading order...", referralNumber, referralDate, correlationId); - await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER, - { referralNumber: referralNumber.toString(), referralDate: referralDate, correlationId: correlationId } - , false); -} - -// Read info from heritage funnel and reset state or load referral -export async function loadReferralIfPresent() { +export async function loadOrderIfPresent() { console.log("attempting to load referral...."); const conceptCookie = getConceptCookie(); // Do nothing if there is no cookie or no correlation id. if (conceptCookie === null || conceptCookie.ReferralCorrelationId === null) { console.log("No referral found"); - return; + return null; } // Reset state if cookie says to. @@ -48,12 +38,32 @@ export async function loadReferralIfPresent() { console.log("Resetting state..."); baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); deleteConceptCookie(); - return; + return null; } - console.log("calling load order from loadReferralIfPresent()..."); + console.log("calling load order from loadOrderIfPresent()..."); + // Load referral if there is a cookie, and it doesn't indicate it needs a state reset. - await loadOrder(conceptCookie.ReferralNumber, conceptCookie.ReferralDate, conceptCookie.ReferralCorrelationId); + return (await loadOrder(conceptCookie.ReferralNumber, conceptCookie.ReferralDate, conceptCookie.ReferralCorrelationId)).data; +} + +export async function getPageToRouteExistingOrderTo() { + const vehicleMakeComponent = (await lazyLoadComponent('vehicle-make')()).default; + const vehicleModelComponent = (await lazyLoadComponent('vehicle-model')()).default; + const vehicleStyleComponent = (await lazyLoadComponent('vehicle-style')()).default; + const vehicleDamageComponent = (await lazyLoadComponent('vehicle-damage')()).default; + + if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) { + return "vehicle-year"; + } else if (!vehicleModelComponent.methods.arePagePrerequisitesValid()) { + return "vehicle-make"; + } else if (!vehicleStyleComponent.methods.arePagePrerequisitesValid()) { + return "vehicle-model"; + } else if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) { + return "vehicle-style"; + }else { + return "vehicle-damage"; + } } export function updateOrCreateConceptCookie() { @@ -96,16 +106,13 @@ export function isConceptSessionStillActive() { } } -// Navigate to Heritage Funnel with the proper URL format. -// Will Save the referral if there is one in state, or create a new one if one is not in state. export async function navigateToHeritageFunnel() { // Create the order (or save existing order) when navigating to Heritage Funnel. await saveOrder(); - router.navigate( - navigationScenarios.MOVE_TO_HERITAGE_FUNNEL, - router.currentRoute.value, + router.navigateToExternalUrl( + externalUrls.HERITAGE_FUNNEL, { corid: store.state.order.referralCorrelationId, src: "concept-funnel", @@ -115,7 +122,6 @@ export async function navigateToHeritageFunnel() { ); } -/* Start cookie related functions */ export function getConceptCookie() { const cookieJson = document.cookie ?.split("; ") @@ -129,7 +135,27 @@ export function getConceptCookie() { } } + + + // --------- PRIVATE FUNCTIONS --------- +async function loadOrder(referralNumber, referralDate, correlationId) { + console.log("loading order...", referralNumber, referralDate, correlationId); + try { + + const response = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER, + { + referralNumber: referralNumber.toString(), + referralDate: referralDate, + correlationId: correlationId + }, false); + + return response; + + } catch (e) { + console.log("error loading order:", e); + } +} function setConceptCookieProperties(properties) { if (typeof properties == "object") { @@ -154,4 +180,3 @@ function deleteConceptCookie() { } -/* End cookie related functions */ diff --git a/src/helpers/heritage-integration-helper.spec.js b/src/helpers/heritage-integration-helper.spec.js index eb1130c21..1a2f09e48 100644 --- a/src/helpers/heritage-integration-helper.spec.js +++ b/src/helpers/heritage-integration-helper.spec.js @@ -19,7 +19,7 @@ describe("saveOrder", () => { } } - describe("loadReferralIfPresent", () => { + describe("loadOrderIfPresent", () => { // test("ShouldResetState == true => heritage cookie is deleted", () => { // // Arrange // // TODO CSR-98 Can we not mock this?? @@ -42,7 +42,7 @@ describe("saveOrder", () => { // console.log(document.cookie) // // Act - // helper.loadReferralIfPresent(); + // helper.loadOrderIfPresent(); // // Assert // console.log(document.cookie) @@ -54,7 +54,7 @@ describe("saveOrder", () => { // helper.getHeritageCookieValue = jest.fn(x => x.ShouldResetState = false); // // Act - // helper.loadReferralIfPresent(); + // helper.loadOrderIfPresent(); // // Assert // expect(helper.getHeritageCookieValue).toHaveBeenCalled(); @@ -65,7 +65,7 @@ describe("saveOrder", () => { // helper.getHeritageCookieValue = jest.fn(x => x.ShouldResetState = true); // // Act - // helper.loadReferralIfPresent(); + // helper.loadOrderIfPresent(); // // Assert // expect(helper.getHeritageCookieValue).toHaveBeenCalled(); diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index d2d786d5d..4268a7f92 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -70,8 +70,6 @@ import alert from "@/ux-components/alert/alert"; 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 { Form, defineRule } from "vee-validate"; import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; @@ -79,6 +77,9 @@ import { damageLocationsCms } from "@/constants/damage-locations-cms.js"; import { damageLocationsSelected } from "@/constants/damage-locations-selected.js"; import { navigateToHeritageFunnel } from "@/helpers/heritage-integration-helper"; +import store from "@/store"; +import baseMixin from "@/mixins/base-mixin"; + // DEFINE VALIDATION RULES defineRule("replace-options-required", required(errorMessages.REPLACE_OPTIONS_REQUIRED)); @@ -150,7 +151,10 @@ export default { }, methods: { arePagePrerequisitesValid() { - return store.getters.vehicle.carId !== null; + if(store.getters.vehicle.carId){ + return true; + } + return false; }, resetDependentState() { store.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); diff --git a/src/layouts/vehicle-make/vehicle-make.vue b/src/layouts/vehicle-make/vehicle-make.vue index 262bee6fd..4c00d7454 100644 --- a/src/layouts/vehicle-make/vehicle-make.vue +++ b/src/layouts/vehicle-make/vehicle-make.vue @@ -84,7 +84,10 @@ export default { ); }, arePagePrerequisitesValid() { - return store.getters.vehicle.year !== null; + if (store.getters.vehicle.year){ + return true; + } + return false; }, resetDependentState() { // Set diff --git a/src/layouts/vehicle-model/vehicle-model.vue b/src/layouts/vehicle-model/vehicle-model.vue index 97d017e34..749a926fe 100644 --- a/src/layouts/vehicle-model/vehicle-model.vue +++ b/src/layouts/vehicle-model/vehicle-model.vue @@ -85,7 +85,10 @@ export default { ); }, arePagePrerequisitesValid() { - return store.getters.vehicle.make !== null; + if(store.getters.vehicle.make){ + return true; + } + return false; }, resetDependentState() { // Set diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index abc8ee936..11f0811bf 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -1,26 +1,42 @@ diff --git a/src/layouts/vehicle-style/vehicle-style.vue b/src/layouts/vehicle-style/vehicle-style.vue index c5aec920c..137dda687 100644 --- a/src/layouts/vehicle-style/vehicle-style.vue +++ b/src/layouts/vehicle-style/vehicle-style.vue @@ -96,7 +96,10 @@ export default { ); }, arePagePrerequisitesValid() { - return store.getters.vehicle.model !== null; + if(store.getters.vehicle.model){ + return true; + } + return false; }, resetDependentState() { // Invokes diff --git a/src/router/index.js b/src/router/index.js index 54a64c5d2..4e85f7b21 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -35,8 +35,7 @@ const routes = [ } else { try { - // Check our 'Session' is still good. - // If not, reset state and go back to the start. + // Check our 'Session' is still good. If not, reset state and go back to the start. if (!integrationHelper.isConceptSessionStillActive()) { baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); await GoToFunnelStartOn404(next); @@ -47,7 +46,14 @@ const routes = [ // On entering the concept funnel "fresh", read cookie information, decide what to do next. if (from.redirectedFrom === undefined) { - await integrationHelper.loadReferralIfPresent(); + await integrationHelper.loadOrderIfPresent(); + + const pageToRedirectTo = await integrationHelper.getPageToRouteExistingOrderTo(); + + // Assign our fmgPage so it will load normally like the other pages. + to.query.fmgPage = pageToRedirectTo; + + console.log("Page to redirect to: ", pageToRedirectTo); } // If we already have our route, go to it. @@ -117,6 +123,10 @@ router.navigateAfterSave = (scenario, currentRoute, optionalQuery = {}, optional navigate(scenario, currentRoute, true, optionalQuery, optionalParams, optionalPageData); } +router.navigateToExternalUrl = (url, optionalQuery = {}) => { + navigateToUrl(url, optionalQuery); +} + // PRIVATE FUNCTIONS // Navigate to the next route, depending on the scenario. diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index c6a758cef..438d230a0 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -1,5 +1,4 @@ import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; -import { externalUrls } from "@/router/router-constants/externalUrl-values"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; const routingTable = [ @@ -58,10 +57,6 @@ const routingTable = [ scenario: navigationScenarios.CLICKED_BACK, destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE, }, - { - scenario: navigationScenarios.MOVE_TO_HERITAGE_FUNNEL, - destinationUrl: externalUrls.HERITAGE_FUNNEL, - }, { scenario: navigationScenarios.SELECTED_DAMAGE_WITH_SINGLE_PART, destinationFmgPageValue: fmgPageValues.REVEAL diff --git a/src/store/index.js b/src/store/index.js index af280675e..494be3dfb 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -152,15 +152,15 @@ export const mutations = { state.order.referralDate = orderInformation.referralDate; state.order.referralCorrelationId = orderInformation.correlationId; state.order.vehicle = { - year: orderInformation.vehicle.year, - make: orderInformation.vehicle.make, - model: orderInformation.vehicle.model, - style: orderInformation.vehicle.style, - carId: orderInformation.vehicle.carId, - category: orderInformation.vehicle.category, - imageUrl: orderInformation.vehicle.imageUrl, - imageVifNumber: orderInformation.vehicle.imageVifNumber, - imageColor: orderInformation.vehicle.imageVifColor + year: orderInformation.vehicle?.year, + make: orderInformation.vehicle?.make, + model: orderInformation.vehicle?.model, + style: orderInformation.vehicle?.style, + carId: orderInformation.vehicle?.carId, + category: orderInformation.vehicle?.category, + imageUrl: orderInformation.vehicle?.imageUrl, + imageVifNumber: orderInformation.vehicle?.imageVifNumber, + imageColor: orderInformation.vehicle?.imageVifColor }; state.order.damage.glassToReplace = orderInformation.glassToReplace; state.order.damage.isRepair = orderInformation.isRepair; From 5e834b22fdd3616b0be49cc0332056097c605dff Mon Sep 17 00:00:00 2001 From: Katie Date: Wed, 23 Mar 2022 12:56:56 -0400 Subject: [PATCH 20/58] CSR-98 Change correlationId to referralCorrelationId --- src/helpers/heritage-integration-helper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 53ff90aab..498be113d 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -16,7 +16,7 @@ export async function saveOrder() { // Save the referral information back from the store. await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SET_REFERRAL_INFORMATION, { referralNumber: savedOrderInfo.data.referralNumber, - correlationId: savedOrderInfo.data.referralCorrelationId, + referralCorrelationId: savedOrderInfo.data.referralCorrelationId, referralDate: savedOrderInfo.data.referralDate, }, false); From 0e6932d26652b6c850ff10524f100be8ef013e1e Mon Sep 17 00:00:00 2001 From: FrankRua Date: Thu, 24 Mar 2022 14:36:43 -0400 Subject: [PATCH 21/58] Handle other edge cases --- src/constants/application-config.js | 3 +- src/constants/query-strings.js | 7 + src/constants/widget-names.js | 8 - src/helpers/cms-content-helper.js | 1 - src/helpers/heritage-integration-helper.js | 154 ++++++++++++++---- src/mixins/base-mixin.js | 5 - src/mixins/base-mixin.spec.js | 13 -- src/router/index.js | 27 +-- .../router-constants/router-parameter-keys.js | 3 - src/store/index.js | 46 ++++-- 10 files changed, 181 insertions(+), 86 deletions(-) create mode 100644 src/constants/query-strings.js delete mode 100644 src/constants/widget-names.js delete mode 100644 src/router/router-constants/router-parameter-keys.js diff --git a/src/constants/application-config.js b/src/constants/application-config.js index 8c033d4cd..684c29467 100644 --- a/src/constants/application-config.js +++ b/src/constants/application-config.js @@ -1,6 +1,7 @@ const applicationConfig = { CONSUMER_APIGATEWAY_URL: process.env.VUE_APP_CONSUMER_API_GATEWAY, - SESSION_TIMEOUT_CONFIG: 30 + SESSION_TIMEOUT_CONFIG: 30, + SAVED_SESSION_TIMEOUT: 45 }; export { applicationConfig }; diff --git a/src/constants/query-strings.js b/src/constants/query-strings.js new file mode 100644 index 000000000..6655f9378 --- /dev/null +++ b/src/constants/query-strings.js @@ -0,0 +1,7 @@ +const queryStrings = { + FMG_PAGE: 'fmgPage', + START_TYPE: 'start_type' + }; + + export { queryStrings }; + \ No newline at end of file diff --git a/src/constants/widget-names.js b/src/constants/widget-names.js deleted file mode 100644 index d9782f90b..000000000 --- a/src/constants/widget-names.js +++ /dev/null @@ -1,8 +0,0 @@ -const widgetNames = { - FUNNEL_SUB_HEADER_WIDGET: "FunnelSubHeaderWidget", - RADIO_QUESTION_WIDGET: "RadioQuestionWidget", - VEHICLE_BANNER_WIDGET: "VehicleBannerWidget", - FUNNEL_HEADER_WIDGET: "FunnelHeaderWidget", -}; - -export { widgetNames }; diff --git a/src/helpers/cms-content-helper.js b/src/helpers/cms-content-helper.js index a20446ef8..3bd5319b5 100644 --- a/src/helpers/cms-content-helper.js +++ b/src/helpers/cms-content-helper.js @@ -1,5 +1,4 @@ import { storeActions } from "@/constants/store-actions.js"; -import { widgetNames } from "@/constants/widget-names.js"; import store from "@/store"; export function fetchCmsContentForPage(fmgPage) { diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 3ee84c437..290cc8fdb 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -1,13 +1,18 @@ import { storeActions } from "@/constants/store-actions.js"; import { cookieNames } from "@/constants/cookie-names"; +import { queryStrings } from "@/constants/query-strings"; import { externalUrls } from "@/router/router-constants/externalUrl-values"; import { applicationConfig } from "@/constants/application-config"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; - import store from "@/store"; import router from "@/router"; import baseMixin from "../mixins/base-mixin"; +/* + Will call API to save existing order, or create new one depending where it's called from. + This will also set Referral information in the store after saving, and then + update the cookie. +*/ export async function saveOrder() { console.log("saving order..."); const savedOrderInfo = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER); @@ -23,6 +28,12 @@ export async function saveOrder() { updateOrCreateConceptCookie(); } +/* + Will call API and hydrate state with data from API if present. If there is no order present + method will return null. If the cookie dictates the state should be reset + it will reset the state and go back to the start of the funnel. + +*/ export async function loadOrderIfPresent() { console.log("attempting to load referral...."); const conceptCookie = getConceptCookie(); @@ -47,7 +58,27 @@ export async function loadOrderIfPresent() { return (await loadOrder(conceptCookie.ReferralNumber, conceptCookie.ReferralDate, conceptCookie.ReferralCorrelationId)).data; } -export async function getPageToRouteExistingOrderTo() { +/* + If the user has visited the concept funnel before this method will determine the bets place to + drop them so they don't start at the beginning again. This method will return 'heritage' if + the user has an existing order and they come back in from the Safelite.com CTA. +*/ +export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHeritageOrder = false) { + + // If the user is coming in via the Safelite.Com CTA + if (toRoute.query[queryStrings.START_TYPE] === 'fmg') { + console.log("Start type is FMG... trying to figure out where to send them..."); + + // If they have an existing order, return 'heritage' for the page name. + if (existingHeritageOrder) { + console.log("Existing heritage order found, returning 'heritage' for page redirect..."); + return 'heritage'; + } + } + + // If this is a non-CTA navigation, determine where to send the user based on page prerequisites. + // This also works if a user has a 'fmg' start_type query string but no current order. + // That shouldn't happen, but it's possible. const vehicleMakeComponent = (await lazyLoadComponent('vehicle-make')()).default; const vehicleModelComponent = (await lazyLoadComponent('vehicle-model')()).default; const vehicleStyleComponent = (await lazyLoadComponent('vehicle-style')()).default; @@ -61,19 +92,30 @@ export async function getPageToRouteExistingOrderTo() { return "vehicle-model"; } else if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) { return "vehicle-style"; - }else { - return "vehicle-damage"; + } else if (!store.getters.damage.isRepair || !store.getters.vehicle.carId) { + return 'vehicle-damage' + } else { + if (store.getters.vehicle.vin) { + return "vin-lookup"; + } else { + return "estimate" + } } + } +/* + Will update the cookie if present, or create a new one if not. +*/ export function updateOrCreateConceptCookie() { console.log("Updating cookie...", { LastTouched: new Date().toUTCString(), + SavedQuoteTimeoutDate: store.getters.applicationUser.savedSessionTimeout, DidHeritageFunnelUpdateLast: false, ShouldResetState: false, - ReferralNumber: store.state.order.referralNumber, - ReferralDate: store.state.order.referralDate, - ReferralCorrelationId: store.state.order.referralCorrelationId, + ReferralNumber: store.getters.order.referralNumber, + ReferralDate: store.getters.order.referralDate, + ReferralCorrelationId: store.getters.order.referralCorrelationId, }); // Create the cookie @@ -82,21 +124,25 @@ export function updateOrCreateConceptCookie() { // Set up cookie with all the props. setConceptCookieProperties({ LastTouched: new Date().toUTCString(), + SavedQuoteTimeoutDate: store.getters.applicationUser.savedSessionTimeout, DidHeritageFunnelUpdateLast: false, ShouldResetState: false, - ReferralNumber: store.state.order.referralNumber, - ReferralDate: store.state.order.referralDate, - ReferralCorrelationId: store.state.order.referralCorrelationId, + ReferralNumber: store.getters.order.referralNumber, + ReferralDate: store.getters.order.referralDate, + ReferralCorrelationId: store.getters.order.referralCorrelationId, }); } -export function isConceptSessionStillActive() { +/* + Method to determine if our analytics session has timed out or not. + Amount used for timeout is configurable in application-config.js +*/ +export function isAnalyticsSessionStillActive() { if (getConceptCookie() !== null) { const lastTouchedValue = getConceptCookie().LastTouched; const timeoutAmount = applicationConfig.SESSION_TIMEOUT_CONFIG; const isMoreThanHalfHourAgo = ((new Date() - new Date(lastTouchedValue)) / 60000) > timeoutAmount; - console.log("has session expired -->", isMoreThanHalfHourAgo); if (isMoreThanHalfHourAgo) { return false; @@ -106,6 +152,31 @@ export function isConceptSessionStillActive() { } } +/* + Method to determine if the users 'saved' session is still active. + When user state is created, there is a date that is saved into state + this method checks against that date. + + Note: That time for saved session timeout is configurable in application-config.js +*/ +export function isSavedSessionStillActive() { + if (getConceptCookie() !== null) { + const savedSessionTimeStamp = new Date(getConceptCookie().SavedQuoteTimeoutDate); + const isSavedSessionTimedOut = (new Date(new Date().toUTCString()) > savedSessionTimeStamp); + + console.log("Saved Session Timed Out? --->", isSavedSessionTimedOut); + + if (isSavedSessionTimedOut) { + return false; + } + + return true; + } +} + +/* + Used to navigate to the heritage funnel with the correct query string and url. +*/ export async function navigateToHeritageFunnel() { // Create the order (or save existing order) when navigating to Heritage Funnel. @@ -114,7 +185,7 @@ export async function navigateToHeritageFunnel() { router.navigateToExternalUrl( externalUrls.HERITAGE_FUNNEL, { - corid: store.state.order.referralCorrelationId, + corid: store.getters.order.referralCorrelationId, src: "concept-funnel", cns: "all", experiments: "RemoveServiceAreaPage=ServAreaRemoval_V7=ServAreaNoRemove_V7_TEST=true,ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" @@ -122,6 +193,10 @@ export async function navigateToHeritageFunnel() { ); } +/* + Gets the current instance of the concept funnel cookie. + Returns null if cookie isn't valid JSON. +*/ export function getConceptCookie() { const cookieJson = document.cookie ?.split("; ") @@ -135,28 +210,40 @@ export function getConceptCookie() { } } +/* +Function to get the date for the saved session timeout. +*/ - - -// --------- PRIVATE FUNCTIONS --------- -async function loadOrder(referralNumber, referralDate, correlationId) { - console.log("loading order...", referralNumber, referralDate, correlationId); - try { - - const response = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER, - { - referralNumber: referralNumber.toString(), - referralDate: referralDate, - correlationId: correlationId - }, false); - - return response; - - } catch (e) { - console.log("error loading order:", e); - } +export function getDateForSavedSessionTimeout() { + const currentDate = new Date(new Date().toUTCString()) + currentDate.setDate(currentDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT) + return currentDate.toUTCString(); } +//-------------------------------------\\\ +// --------- PRIVATE FUNCTIONS --------- \\\ +//----------------------------------------\\\ + +/* + Calls API to load order given the referral number, referralDate, and referralCorrelationId + and returns the response. +*/ +async function loadOrder(referralNumber, referralDate, correlationId) { + console.log("loading order...", referralNumber, referralDate, correlationId); + const response = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER, + { + referralNumber: referralNumber.toString(), + referralDate: referralDate, + correlationId: correlationId + }, false); + + return response; +} + +/* + Used to set properties on the concept funnel cookie. + Takes an object with properties to set. Will overwrite existing properties. +*/ function setConceptCookieProperties(properties) { if (typeof properties == "object") { let cookie = getConceptCookie(); @@ -173,6 +260,9 @@ function setConceptCookieProperties(properties) { } } +/* + Removes concept cookie from browser. +*/ function deleteConceptCookie() { // If this cookie is ever created from the concept funnel, will need to add another // line with the path=/fmg/ diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js index af2eb1c2a..2e978fe0a 100644 --- a/src/mixins/base-mixin.js +++ b/src/mixins/base-mixin.js @@ -1,9 +1,7 @@ import store from "@/store"; -import router from "@/router"; import { storeActions } from "@/constants/store-actions.js"; import { storeMutations } from "@/constants/store-mutations.js"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; -import { widgetNames } from "@/constants/widget-names.js"; import { vehicleCategories } from "@/constants/vehicle-categories.js"; export default { @@ -33,9 +31,6 @@ export default { navigationScenarios() { return navigationScenarios; }, - widgetNames() { - return widgetNames; - }, vehicleCategories() { return vehicleCategories; }, diff --git a/src/mixins/base-mixin.spec.js b/src/mixins/base-mixin.spec.js index da684af1b..5c1f529e3 100644 --- a/src/mixins/base-mixin.spec.js +++ b/src/mixins/base-mixin.spec.js @@ -1,6 +1,5 @@ import baseMixin from "@/mixins/base-mixin"; import { storeActions } from "@/constants/store-actions.js"; -import { widgetNames } from "@/constants/widget-names.js"; import { storeMutations } from "@/constants/store-mutations.js"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import store from "@/store"; @@ -66,17 +65,6 @@ describe("baseMixin.js", () => { // Assert expect(navigationScenariosForTest).toEqual(navigationScenarios); }); - - test("computed: widgetNames should be equal to import object", () => { - // Arrange - const mixIn = getMixInInstance({}); - - // Act - let widgetNamesForTest = mixIn.computed.widgetNames(); - - // Assert - expect(widgetNamesForTest).toEqual(widgetNames); - }); }); function getMixInInstance({ isDispatchSuccess = true }) { @@ -100,7 +88,6 @@ function getMixInInstance({ isDispatchSuccess = true }) { const baseMixIn = baseMixin; baseMixIn.methods.$route = route; baseMixIn.methods.storeActions = storeActions; - baseMixIn.methods.widgetNames = widgetNames; store.dispatch = storeDispatch; store.commit = jest.fn(); diff --git a/src/router/index.js b/src/router/index.js index 4e85f7b21..e0701d095 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -4,7 +4,7 @@ import { storeActions } from "@/constants/store-actions"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; -import * as integrationHelper from "@/helpers/heritage-integration-helper"; +import * as heritageIntegrationHelper from "@/helpers/heritage-integration-helper"; import baseMixin from "@/mixins/base-mixin"; import eventBus from "@/helpers/event-bus/event-bus"; @@ -35,20 +35,25 @@ const routes = [ } else { try { - // Check our 'Session' is still good. If not, reset state and go back to the start. - if (!integrationHelper.isConceptSessionStillActive()) { - baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); + // If the saved session has timed out, clear the session, execute 404 logic. + if (!heritageIntegrationHelper.isSavedSessionStillActive()) { await GoToFunnelStartOn404(next); } - // Create funnel cookie, or update it if it already exists. - integrationHelper.updateOrCreateConceptCookie(); + // Process concept funnel cookie. + heritageIntegrationHelper.updateOrCreateConceptCookie(); // On entering the concept funnel "fresh", read cookie information, decide what to do next. if (from.redirectedFrom === undefined) { - await integrationHelper.loadOrderIfPresent(); + const loadOrderResponse = await heritageIntegrationHelper.loadOrderIfPresent(); + const pageToRedirectTo = await heritageIntegrationHelper.getPageToRouteExistingOrderTo(to, loadOrderResponse); - const pageToRedirectTo = await integrationHelper.getPageToRouteExistingOrderTo(); + // If getPageToRouteExistingOrderTo determines that the return user needs to + // go back to heritage funnel, send them there and stop our current navigation. + if (pageToRedirectTo === 'heritage') { + await heritageIntegrationHelper.navigateToHeritageFunnel(); + return next(false); + } // Assign our fmgPage so it will load normally like the other pages. to.query.fmgPage = pageToRedirectTo; @@ -154,8 +159,8 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); // if cookie and referralNumber/Date exists - if (integrationHelper.getConceptCookie()?.ReferralNumber && integrationHelper.getConceptCookie()?.ReferralDate) { - await integrationHelper.saveOrder(); + if (heritageIntegrationHelper.getConceptCookie()?.ReferralNumber && heritageIntegrationHelper.getConceptCookie()?.ReferralDate) { + await heritageIntegrationHelper.saveOrder(); } router.push({ @@ -187,7 +192,7 @@ function getNavigationMap(scenario, currentRoute) { //---------------------------------------------------------- Private Functions ---------------------------------------------------------- // Navigate to an external url. -function navigateToUrl(url, optionalQuery) { +function navigateToUrl(url, optionalQuery = {}) { // possibly show some loading screen in the future here. var externalUrl = new URL(url); diff --git a/src/router/router-constants/router-parameter-keys.js b/src/router/router-constants/router-parameter-keys.js deleted file mode 100644 index 2407d74c4..000000000 --- a/src/router/router-constants/router-parameter-keys.js +++ /dev/null @@ -1,3 +0,0 @@ -const routerParameterKeys = { }; - - export { routerParameterKeys }; \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js index 494be3dfb..9c5bfba5d 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,6 +1,7 @@ import { createStore } from "vuex"; import { endpoints } from "@/constants/endpoints.js"; import { storeMutations } from "@/constants/store-mutations"; +import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration-helper"; import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; @@ -17,16 +18,32 @@ const getDefaultState = () => { style: null, carId: null, category: null, + vin: null, imageUrl: null, imageVifNumber: null, imageColor: null, + registration: { + licensePlate: null, + address: null, + city: null, + state: null, + zipCode: null, + firstName: null, + lastName: null, + }, + }, + serviceLocation: { + zip: null, + }, + customer: { + emailAddress: null, }, damage: { isRepair: null, numberOfChips: null, glassToReplace: null, }, - lineItems:{ + lineItems: { glassParts: null, otherParts: null }, @@ -37,7 +54,8 @@ const getDefaultState = () => { }, applicationUser: { eventBus: [], - pageData: {} + pageData: {}, + savedSessionTimeout: getDateForSavedSessionTimeout() }, } }; @@ -74,19 +92,19 @@ export const mutations = { updateVehicleImageColor(state, imageColor) { state.order.vehicle.imageColor = imageColor; }, - updateIsRepair(state, isRepair){ + updateIsRepair(state, isRepair) { state.order.damage.isRepair = isRepair; }, - updateNumberOfChips(state, numberOfChips){ + updateNumberOfChips(state, numberOfChips) { state.order.damage.numberOfChips = numberOfChips; }, - updateGlassToReplace(state, glassToReplace){ + updateGlassToReplace(state, glassToReplace) { state.order.damage.glassToReplace = glassToReplace; }, - updateParts(state, partsData){ + updateParts(state, partsData) { state.order.lineItems.glassParts = partsData; }, - updatePageData(state, pageData){ + updatePageData(state, pageData) { state.applicationUser.pageData[pageData.page] = pageData.data; }, updateReferralCorrelationId(state, referralCorrelationId) { @@ -149,7 +167,7 @@ export const mutations = { // Misc Mutations setLoadOrderInformation(state, orderInformation) { state.order.referralNumber = orderInformation.referralNumber; - state.order.referralDate = orderInformation.referralDate; + state.order.referralDate = orderInformation.referralDate; state.order.referralCorrelationId = orderInformation.correlationId; state.order.vehicle = { year: orderInformation.vehicle?.year, @@ -186,7 +204,9 @@ export const getters = { lineItems: (state) => state.order.lineItems, pageData: (state) => (page) => { return state.applicationUser.pageData[page]; - } + }, + applicationUser: (state) => state.applicationUser, + order: (state) => state.order, } // Export Actions @@ -357,7 +377,7 @@ export const actions = { }); }, - loadOrder(context, {referralNumber, referralDate, correlationId}) { + loadOrder(context, { referralNumber, referralDate, correlationId }) { return globalMethods.callHttpClient({ method: endpoints.LoadOrder.method, endpoint: endpoints.LoadOrder.url, @@ -366,7 +386,7 @@ export const actions = { referralDate: referralDate, correlationId: correlationId }, - }).then( (response) => { + }).then((response) => { context.commit(storeMutations.SET_LOAD_CONCEPT_SESSION_INFO, response.data); return response; }); @@ -384,4 +404,6 @@ export default createStore({ mutations, getters, actions, -}); \ No newline at end of file +}); + +// Private Functions From 3e55448127833728b5607b2b7fbdef4794c28396 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Thu, 24 Mar 2022 14:47:22 -0400 Subject: [PATCH 22/58] things I didn't need --- src/constants/application-config.js | 2 +- src/helpers/heritage-integration-helper.js | 2 +- src/router/router-constants/navigation-scenarios.js | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/constants/application-config.js b/src/constants/application-config.js index d87698a0b..eae3ef956 100644 --- a/src/constants/application-config.js +++ b/src/constants/application-config.js @@ -1,7 +1,7 @@ const applicationConfig = { CONSUMER_APIGATEWAY_URL: process.env.VUE_APP_CONSUMER_API_GATEWAY, GOOGLE_PLACES_API_KEY: process.env.VUE_APP_GOOGLE_PLACES_API_KEY, - SESSION_TIMEOUT_CONFIG: 30, + ANALYTICS_SESSION_TIMEOUT: 30, SAVED_SESSION_TIMEOUT: 45 }; diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 290cc8fdb..7cd6ab149 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -141,7 +141,7 @@ export function updateOrCreateConceptCookie() { export function isAnalyticsSessionStillActive() { if (getConceptCookie() !== null) { const lastTouchedValue = getConceptCookie().LastTouched; - const timeoutAmount = applicationConfig.SESSION_TIMEOUT_CONFIG; + const timeoutAmount = applicationConfig.ANALYTICS_SESSION_TIMEOUT; const isMoreThanHalfHourAgo = ((new Date() - new Date(lastTouchedValue)) / 60000) > timeoutAmount; if (isMoreThanHalfHourAgo) { diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index 972944d80..55efdcaec 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -8,8 +8,7 @@ const navigationScenarios = { SELECTED_PARTS: "SELECTED_PARTS", SELECTED_DAMAGE_WITH_SINGLE_PART: "SELECTED_DAMAGE_WITH_SINGLE_PART", SELECTED_DAMAGE_WITH_MULTIPLE_PARTS: "SELECTED_DAMAGE_WITH_MULTIPLE_PARTS", - SELECTED_DAMAGE_WITH_PART_QUESTIONS: "SELECTED_DAMAGE_WITH_PART_QUESTIONS", - MOVE_TO_HERITAGE_FUNNEL: "MOVE_TO_HERITAGE_FUNNEL", + SELECTED_DAMAGE_WITH_PART_QUESTIONS: "SELECTED_DAMAGE_WITH_PART_QUESTIONS" }; export { navigationScenarios }; From 01d4dcd3f830d2f1a28fdb4b16dda9e4cff17ecc Mon Sep 17 00:00:00 2001 From: Katie Date: Thu, 24 Mar 2022 15:54:34 -0400 Subject: [PATCH 23/58] CSR-99 Change correlationId to referralCorrelationId --- src/helpers/heritage-integration-helper.js | 8 ++++---- src/store/index.js | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 7cd6ab149..64a42d0a5 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -20,7 +20,7 @@ export async function saveOrder() { // Save the referral information back from the store. await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SET_REFERRAL_INFORMATION, { referralNumber: savedOrderInfo.data.referralNumber, - correlationId: savedOrderInfo.data.referralCorrelationId, + referralCorrelationId: savedOrderInfo.data.referralCorrelationId, referralDate: savedOrderInfo.data.referralDate, }, false); @@ -228,13 +228,13 @@ export function getDateForSavedSessionTimeout() { Calls API to load order given the referral number, referralDate, and referralCorrelationId and returns the response. */ -async function loadOrder(referralNumber, referralDate, correlationId) { - console.log("loading order...", referralNumber, referralDate, correlationId); +async function loadOrder(referralNumber, referralDate, referralCorrelationId) { + console.log("loading order...", referralNumber, referralDate, referralCorrelationId); const response = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER, { referralNumber: referralNumber.toString(), referralDate: referralDate, - correlationId: correlationId + referralCorrelationId: referralCorrelationId }, false); return response; diff --git a/src/store/index.js b/src/store/index.js index 3182af5a3..27c252995 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -174,7 +174,7 @@ export const mutations = { setLoadOrderInformation(state, orderInformation) { state.order.referralNumber = orderInformation.referralNumber; state.order.referralDate = orderInformation.referralDate; - state.order.referralCorrelationId = orderInformation.correlationId; + state.order.referralCorrelationId = orderInformation.referralCorrelationId; state.order.vehicle = { year: orderInformation.vehicle?.year, make: orderInformation.vehicle?.make, @@ -339,10 +339,10 @@ export const actions = { }, // Misc Actions - setReferralInformation(context, { referralNumber, referralDate, correlationId }) { + setReferralInformation(context, { referralNumber, referralDate, referralCorrelationId }) { context.commit(storeMutations.UPDATE_REFERRAL_NUMBER, referralNumber); context.commit(storeMutations.UPDATE_REFERRAL_DATE, referralDate); - context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, correlationId); + context.commit(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, referralCorrelationId); }, // Parts API Actions @@ -383,14 +383,14 @@ export const actions = { }); }, - loadOrder(context, { referralNumber, referralDate, correlationId }) { + loadOrder(context, { referralNumber, referralDate, referralCorrelationId }) { return globalMethods.callHttpClient({ method: endpoints.LoadOrder.method, endpoint: endpoints.LoadOrder.url, payload: { referralNumber: referralNumber, referralDate: referralDate, - correlationId: correlationId + referralCorrelationId: referralCorrelationId }, }).then((response) => { context.commit(storeMutations.SET_LOAD_CONCEPT_SESSION_INFO, response.data); From 44c4fcfd6a787aecb6ba674e611d929a911cebd2 Mon Sep 17 00:00:00 2001 From: Katie Date: Fri, 25 Mar 2022 09:52:12 -0400 Subject: [PATCH 24/58] CSR-98 Fix tests --- src/helpers/unit-test-helper.js | 27 +++++++++---------- .../vehicle-parts/vehicle-parts.spec.js | 7 ++--- src/layouts/vehicle-parts/vehicle-parts.vue | 3 ++- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 20ee5990a..c6c766956 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -12,22 +12,19 @@ export function getMountOptions(mockData) { //this is mocking if you use the mixin directly(baseMixin.methods.dispatchNonBlockingStoreAction) vs this.dispatchNonBlockingStoreAction setupBaseMixinDispatchNonBlockingStoreAction(mockData); // if (mockData.actionList !== undefined) { - // // baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); - // // baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { - // // let actionFilterResult = mockData.actionList.filter( - // // (x) => x.actionName == actionName - // // ); + // baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); + // baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { + // let actionFilterResult = mockData.actionList.filter( + // (x) => x.actionName == actionName + // ); - // // if (actionFilterResult.length > 0 && actionFilterResult.length === 1) { - // // return Promise.resolve({ - // // data: actionFilterResult[0].data, - // // }); - // // } - // // }); - - + // if (actionFilterResult.length > 0 && actionFilterResult.length === 1) { + // return Promise.resolve({ + // data: actionFilterResult[0].data, + // }); + // } + // }); // } - mocks.dispatchNonBlockingStoreAction = jest.fn(); mocks.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { @@ -62,8 +59,8 @@ export function getMountOptions(mockData) { } function setupBaseMixinDispatchNonBlockingStoreAction(mockData) { - baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); if (mockData.actionList !== undefined) { + baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { let actionFilterResult = mockData.actionList.filter( (x) => x.actionName == actionName diff --git a/src/layouts/vehicle-parts/vehicle-parts.spec.js b/src/layouts/vehicle-parts/vehicle-parts.spec.js index 74196c524..428fe8a3b 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.spec.js +++ b/src/layouts/vehicle-parts/vehicle-parts.spec.js @@ -193,7 +193,7 @@ describe("vehicle-parts.vue", () => { test("PageData / isRepair populated in Vuex. arePagePrerequisitesValid should be true ", async () => { //Arrange - store.getters.pageData.mockReturnValueOnce(basePartResponse); + store.getters.pageData.mockReturnValue(basePartResponse); store.getters.lineItems = { glassParts: {} } const { wrapper } = setupMocks({ @@ -211,6 +211,7 @@ describe("vehicle-parts.vue", () => { }, } }); + console.info(store.getters.damage.isRepair) //Act vehicleParts.beforeRouteEnter.call( @@ -222,9 +223,9 @@ describe("vehicle-parts.vue", () => { let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); await nextTick(); - + console.log(arePagePrerequisitesValid) //Assert - expect(arePagePrerequisitesValid).toBe(true); + // expect(arePagePrerequisitesValid).toBe(true); }); test("Initial data, should populate this.glassParts", async () => { diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue index 11f0811bf..c02edfd27 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.vue +++ b/src/layouts/vehicle-parts/vehicle-parts.vue @@ -154,8 +154,9 @@ export default { methods: { arePagePrerequisitesValid() { // Check if isRepair is populated and if the pageData we need is here (Parts data) + console.log(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)) if ( - (store.getters.damage.isRepair) && + (store.getters.damage.isRepair != null) && Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)) .length !== 0 ) { From d4579137aeb72987319ca1b9222eab697df37ef1 Mon Sep 17 00:00:00 2001 From: Katie Date: Fri, 25 Mar 2022 09:59:43 -0400 Subject: [PATCH 25/58] CSR-98 Cleanup --- src/global-methods.js | 8 +------- src/helpers/heritage-integration-helper.js | 2 -- src/helpers/unit-test-helper.js | 14 -------------- src/layouts/vehicle-parts/vehicle-parts.spec.js | 5 ++--- 4 files changed, 3 insertions(+), 26 deletions(-) diff --git a/src/global-methods.js b/src/global-methods.js index 8efd163aa..f0675c02d 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -5,14 +5,8 @@ import httpStatusCodes from "http-status-codes"; export default { callHttpClient({ method, endpoint, payload }) { return new Promise((resolve, reject) => { - // TODO CSR-98 TEMP FOR TESTING - var apiGatewayUrl = applicationConfig.CONSUMER_APIGATEWAY_URL; + const apiGatewayUrl = applicationConfig.CONSUMER_APIGATEWAY_URL; - if (endpoint.includes("order")) { - apiGatewayUrl = "https://localhost:44346"; - } - - // const apiGatewayUrl = applicationConfig.CONSUMER_APIGATEWAY_URL; const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "FixMyGlass", }); diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 14dacb8eb..0147c25e5 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -264,8 +264,6 @@ function setConceptCookieProperties(properties) { Removes concept cookie from browser. */ function deleteConceptCookie() { - // If this cookie is ever created from the concept funnel, will need to add another - // line with the path=/fmg/ document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; } diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index c6c766956..00fa5f675 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -11,20 +11,6 @@ export function getMountOptions(mockData) { //this is mocking if you use the mixin directly(baseMixin.methods.dispatchNonBlockingStoreAction) vs this.dispatchNonBlockingStoreAction setupBaseMixinDispatchNonBlockingStoreAction(mockData); - // if (mockData.actionList !== undefined) { - // baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); - // baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { - // let actionFilterResult = mockData.actionList.filter( - // (x) => x.actionName == actionName - // ); - - // if (actionFilterResult.length > 0 && actionFilterResult.length === 1) { - // return Promise.resolve({ - // data: actionFilterResult[0].data, - // }); - // } - // }); - // } mocks.dispatchNonBlockingStoreAction = jest.fn(); mocks.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { diff --git a/src/layouts/vehicle-parts/vehicle-parts.spec.js b/src/layouts/vehicle-parts/vehicle-parts.spec.js index 428fe8a3b..6613fe6ad 100644 --- a/src/layouts/vehicle-parts/vehicle-parts.spec.js +++ b/src/layouts/vehicle-parts/vehicle-parts.spec.js @@ -211,7 +211,6 @@ describe("vehicle-parts.vue", () => { }, } }); - console.info(store.getters.damage.isRepair) //Act vehicleParts.beforeRouteEnter.call( @@ -223,9 +222,9 @@ describe("vehicle-parts.vue", () => { let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); await nextTick(); - console.log(arePagePrerequisitesValid) + //Assert - // expect(arePagePrerequisitesValid).toBe(true); + expect(arePagePrerequisitesValid).toBe(true); }); test("Initial data, should populate this.glassParts", async () => { From 0eaec7e5f8f9a14c6f9511e8906573d416a18f20 Mon Sep 17 00:00:00 2001 From: Katie Date: Fri, 25 Mar 2022 10:06:57 -0400 Subject: [PATCH 26/58] CSR-98 Remove experiments used for local testing --- src/helpers/heritage-integration-helper.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 0147c25e5..ecaa6548b 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -186,9 +186,7 @@ export async function navigateToHeritageFunnel() { externalUrls.HERITAGE_FUNNEL, { corid: store.getters.order.referralCorrelationId, - src: "concept-funnel", - cns: "all", - experiments: "RemoveServiceAreaPage=ServAreaRemoval_V7=ServAreaNoRemove_V7_TEST=true,ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" + src: "concept-funnel" } ); } From 950ca93ad8e38810b8c6945febc1d44aa84d5b57 Mon Sep 17 00:00:00 2001 From: Katie Date: Fri, 25 Mar 2022 11:39:14 -0400 Subject: [PATCH 27/58] CSR-98 Fix tests --- src/helpers/heritage-integration-helper.js | 7 +++++-- src/helpers/heritage-integration-helper.spec.js | 3 +-- src/router/router-constants/routing-table.js | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index ecaa6548b..960ab4e65 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -1,3 +1,4 @@ +import * as self from "./heritage-integration-helper"; import { storeActions } from "@/constants/store-actions.js"; import { cookieNames } from "@/constants/cookie-names"; import { queryStrings } from "@/constants/query-strings"; @@ -36,7 +37,7 @@ export async function saveOrder() { */ export async function loadOrderIfPresent() { console.log("attempting to load referral...."); - const conceptCookie = this.getConceptCookie(); + const conceptCookie = self.getConceptCookie(); // Do nothing if there is no cookie or no correlation id. if (conceptCookie === null || conceptCookie.ReferralCorrelationId === null) { @@ -177,10 +178,12 @@ export function isSavedSessionStillActive() { /* Used to navigate to the heritage funnel with the correct query string and url. */ + export async function navigateToHeritageFunnel() { // Create the order (or save existing order) when navigating to Heritage Funnel. - await this.saveOrder(); + // console.log(exports) + await self.saveOrder(); router.navigateToExternalUrl( externalUrls.HERITAGE_FUNNEL, diff --git a/src/helpers/heritage-integration-helper.spec.js b/src/helpers/heritage-integration-helper.spec.js index ff91d68c6..54ba8e9f6 100644 --- a/src/helpers/heritage-integration-helper.spec.js +++ b/src/helpers/heritage-integration-helper.spec.js @@ -102,8 +102,7 @@ describe("saveOrder", () => { { actionName: storeActions.SET_REFERRAL_INFORMATION } - ], - router: router + ] } const mocks = setupMocksForJsFiles(mockData); diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index d928f8696..760dac76a 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -1,6 +1,6 @@ import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; -import { applicationConfig } from "../../constants/application-config"; +import { applicationConfig } from "@/constants/application-config"; const routingTable = [ { From 2cb3c6c05283308c2a8dda108506213a9981418e Mon Sep 17 00:00:00 2001 From: FrankRua Date: Fri, 25 Mar 2022 16:28:39 -0400 Subject: [PATCH 28/58] init unit tests --- src/helpers/heritage-integration-helper.js | 4 +- .../heritage-integration-helper.spec.js | 127 ++++++++++++++++-- 2 files changed, 122 insertions(+), 9 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 960ab4e65..2eedb001e 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -77,6 +77,7 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita } } + // If this is a non-CTA navigation, determine where to send the user based on page prerequisites. // This also works if a user has a 'fmg' start_type query string but no current order. // That shouldn't happen, but it's possible. @@ -85,6 +86,7 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita const vehicleStyleComponent = (await lazyLoadComponent('vehicle-style')()).default; const vehicleDamageComponent = (await lazyLoadComponent('vehicle-damage')()).default; + if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) { return "vehicle-year"; } else if (!vehicleModelComponent.methods.arePagePrerequisitesValid()) { @@ -93,7 +95,7 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita return "vehicle-model"; } else if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) { return "vehicle-style"; - } else if (!store.getters.damage.isRepair || !store.getters.vehicle.carId) { + } else if (store.getters.damage.isRepair != null && store.getters.vehicle.carId) { return 'vehicle-damage' } else { if (store.getters.vehicle.vin) { diff --git a/src/helpers/heritage-integration-helper.spec.js b/src/helpers/heritage-integration-helper.spec.js index 54ba8e9f6..58ea971bb 100644 --- a/src/helpers/heritage-integration-helper.spec.js +++ b/src/helpers/heritage-integration-helper.spec.js @@ -2,12 +2,16 @@ import * as helper from "@/helpers/heritage-integration-helper"; import { cookieNames } from "@/constants/cookie-names"; import { setupMocksForJsFiles } from "@/helpers/unit-test-helper.js"; import { storeActions } from "@/constants/store-actions"; -import { storeMutations } from "@/constants/store-mutations"; import store from "@/store"; import router from "@/router"; -import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; import baseMixin from "@/mixins/base-mixin"; import { externalUrls } from "@/router/router-constants/externalUrl-values"; +import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; + +// Mock Lazy Load +jest.mock("@/router/dynamic-routing/component-loader.js", () => ({ + lazyLoadComponent: jest.fn(), +})); describe("loadOrderIfPresent", () => { afterEach(() => { @@ -321,21 +325,128 @@ describe("cookies", () => { }) }) +describe("getPageToRouteExistingOrderTo", () => { + test("getPageToRouteExistingOrderTo, should return vehicle-model", async () => { + // Arrange + const toRoute = { + query: {} + }; + + // Mock out the lazy load calls for all components. + lazyLoadComponent + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false) + } + } + } + }); + + // Act + const result = await helper.getPageToRouteExistingOrderTo(toRoute, false); + + //Assert + expect(result).toBe('vehicle-model'); + }); + + test("getPageToRouteExistingOrderTo, should return vehicle-damage", async () => { + // Arrange + const toRoute = { + query: {} + }; + + // Mock out the lazy load calls for all components. + lazyLoadComponent + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }); + + store.getters.damage.isRepair = false; + store.getters.vehicle.carId = 'C00000'; + + // Act + const result = await helper.getPageToRouteExistingOrderTo(toRoute, false); + + //Assert + expect(result).toBe('vehicle-damage'); + }); + +}); + // document.cookie is not just a string, needs to be added individually const cookies = { - "orderconfirmation": 1565980, - "optimizelyEndUserId": "oeu1610051865958r0.07937134272718804", [cookieNames.CONCEPT_SESSION_INFO]: `{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false,"DidHeritageFunnelUpdateLast":true}`, "UNIQUE_SESSION_ID": "33756020-b58e-4ec7-b8b8-3f1576719c40", - "_ga": "GA1.1.1631274579.1622658999", - "da_lid": "B10847599A73EA95861EBB99009A283E27|0|0|0 clientTag=null", - "addshoppers.com": "2%7C1%3A0%7C10%3A1646681050%7C15%3Aaddshoppers.com%7C44%3AODM1OTczNWI0MmFjNGNmMmExNDY3OWRlNTQ1NmM5MGY%3D%7Cef2a50fafe40fc5abf641a14ee5541c70bef2950666f59d3a809fd9352c7b963" + "anotherCookie": "{}", + "someOtherCookie": "{}" }; function setupCookies({ conceptCookieValue = "", includeHeritageCookie = true }) { Object.keys(cookies).forEach(key => { const cookieValue = key == cookieNames.CONCEPT_SESSION_INFO ? conceptCookieValue : cookies[key]; - + if (includeHeritageCookie || key != cookieNames.CONCEPT_SESSION_INFO) document.cookie = `${key}=${cookieValue}; path=/;`; }); From ce4c24e13b4ea1dc73646082fc19a5df0812ef72 Mon Sep 17 00:00:00 2001 From: Katie Date: Mon, 28 Mar 2022 16:24:32 -0400 Subject: [PATCH 29/58] CSR-98 Fix tests with getDateForSavedSessionTimeout commented out --- src/helpers/heritage-integration-helper.js | 45 +++++--- .../heritage-integration-helper.spec.js | 103 ++++++++++-------- src/router/index.js | 2 +- src/store/index.js | 4 +- 4 files changed, 89 insertions(+), 65 deletions(-) diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js index 2eedb001e..f4ae1c1a2 100644 --- a/src/helpers/heritage-integration-helper.js +++ b/src/helpers/heritage-integration-helper.js @@ -1,4 +1,4 @@ -import * as self from "./heritage-integration-helper"; +// import * as self from "./heritage-integration-helper"; import { storeActions } from "@/constants/store-actions.js"; import { cookieNames } from "@/constants/cookie-names"; import { queryStrings } from "@/constants/query-strings"; @@ -14,7 +14,7 @@ import baseMixin from "../mixins/base-mixin"; This will also set Referral information in the store after saving, and then update the cookie. */ -export async function saveOrder() { +async function saveOrder() { console.log("saving order..."); const savedOrderInfo = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER); @@ -35,9 +35,12 @@ export async function saveOrder() { it will reset the state and go back to the start of the funnel. */ -export async function loadOrderIfPresent() { +async function loadOrderIfPresent() { console.log("attempting to load referral...."); - const conceptCookie = self.getConceptCookie(); + // const conceptCookie = self.getConceptCookie(); + const conceptCookie = exportFunctions.getConceptCookie(); + + console.log(conceptCookie) // Do nothing if there is no cookie or no correlation id. if (conceptCookie === null || conceptCookie.ReferralCorrelationId === null) { @@ -64,7 +67,7 @@ export async function loadOrderIfPresent() { drop them so they don't start at the beginning again. This method will return 'heritage' if the user has an existing order and they come back in from the Safelite.com CTA. */ -export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHeritageOrder = false) { +async function getPageToRouteExistingOrderTo(toRoute = {}, existingHeritageOrder = false) { // If the user is coming in via the Safelite.Com CTA if (toRoute.query[queryStrings.START_TYPE] === 'fmg') { @@ -110,7 +113,7 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita /* Will update the cookie if present, or create a new one if not. */ -export function updateOrCreateConceptCookie() { +function updateOrCreateConceptCookie() { console.log("Updating cookie...", { LastTouched: new Date().toUTCString(), SavedQuoteTimeoutDate: store.getters.applicationUser.savedSessionTimeout, @@ -141,7 +144,7 @@ export function updateOrCreateConceptCookie() { Method to determine if our analytics session has timed out or not. Amount used for timeout is configurable in application-config.js */ -export function isAnalyticsSessionStillActive() { +function isAnalyticsSessionStillActive() { if (getConceptCookie() !== null) { const lastTouchedValue = getConceptCookie().LastTouched; const timeoutAmount = applicationConfig.ANALYTICS_SESSION_TIMEOUT; @@ -162,7 +165,7 @@ export function isAnalyticsSessionStillActive() { Note: That time for saved session timeout is configurable in application-config.js */ -export function isSavedSessionStillActive() { +function isSavedSessionStillActive() { if (getConceptCookie() !== null) { const savedSessionTimeStamp = new Date(getConceptCookie().SavedQuoteTimeoutDate); const isSavedSessionTimedOut = (new Date(new Date().toUTCString()) > savedSessionTimeStamp); @@ -181,17 +184,21 @@ export function isSavedSessionStillActive() { Used to navigate to the heritage funnel with the correct query string and url. */ -export async function navigateToHeritageFunnel() { +async function navigateToHeritageFunnel() { // Create the order (or save existing order) when navigating to Heritage Funnel. // console.log(exports) - await self.saveOrder(); + // await self.saveOrder(); + await exportFunctions.saveOrder(); router.navigateToExternalUrl( externalUrls.HERITAGE_FUNNEL, { corid: store.getters.order.referralCorrelationId, - src: "concept-funnel" + src: "concept-funnel", + // TODO CSR-28, remove this + cns: "all", + experiments: "RemoveServiceAreaPage=ServAreaRemoval_V7=ServAreaNoRemove_V7_TEST=true,ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" } ); } @@ -200,7 +207,7 @@ export async function navigateToHeritageFunnel() { Gets the current instance of the concept funnel cookie. Returns null if cookie isn't valid JSON. */ -export function getConceptCookie() { +function getConceptCookie() { const cookieJson = document.cookie ?.split("; ") ?.find(row => row.startsWith(`${cookieNames.CONCEPT_SESSION_INFO}=`)) @@ -217,7 +224,7 @@ export function getConceptCookie() { Function to get the date for the saved session timeout. */ -export function getDateForSavedSessionTimeout() { +function getDateForSavedSessionTimeout() { const currentDate = new Date(new Date().toUTCString()) currentDate.setDate(currentDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT) return currentDate.toUTCString(); @@ -270,4 +277,16 @@ function deleteConceptCookie() { document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; } +const exportFunctions = { + saveOrder, + loadOrderIfPresent, + getPageToRouteExistingOrderTo, + updateOrCreateConceptCookie, + isAnalyticsSessionStillActive, + isSavedSessionStillActive, + navigateToHeritageFunnel, + getConceptCookie, + getDateForSavedSessionTimeout +}; +export default exportFunctions; \ No newline at end of file diff --git a/src/helpers/heritage-integration-helper.spec.js b/src/helpers/heritage-integration-helper.spec.js index 58ea971bb..7d6de90c2 100644 --- a/src/helpers/heritage-integration-helper.spec.js +++ b/src/helpers/heritage-integration-helper.spec.js @@ -1,4 +1,4 @@ -import * as helper from "@/helpers/heritage-integration-helper"; +import helper from "@/helpers/heritage-integration-helper"; import { cookieNames } from "@/constants/cookie-names"; import { setupMocksForJsFiles } from "@/helpers/unit-test-helper.js"; import { storeActions } from "@/constants/store-actions"; @@ -37,8 +37,9 @@ describe("loadOrderIfPresent", () => { test("ShouldResetState == true => reset store", () => { // Arrange - const getConceptCookieMethod = jest.spyOn(helper, "getConceptCookie") - getConceptCookieMethod.mockImplementation(() => { return { ShouldResetState: true, DidHeritageFunnelUpdateLast: false } }); + // helper.getConceptCookie = jest.fn().mockReturnValueOnce({ ShouldResetState: true, DidHeritageFunnelUpdateLast: false }); + helper.getConceptCookie = jest.spyOn(helper, "getConceptCookie").mockReturnValueOnce({ ShouldResetState: true, ReferralCorrelationId: "xxx-xxx-xxx"}); + // store.dispatch = jest.spyOn(store, "dispatch"); const mockData = { actionList: [{ @@ -46,47 +47,49 @@ describe("loadOrderIfPresent", () => { }], } - setupMocksForJsFiles(mockData); - - // Act - helper.loadOrderIfPresent(); - - // Assert - expect(getConceptCookieMethod).toHaveBeenCalled(); - expect(baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.RESET_STATE); - - getConceptCookieMethod.mockRestore(); - }); - - test("Concept cookie is null => store is unchanged", () => { - // Arrange - const getConceptCookieMethod = jest.spyOn(helper, "getConceptCookie") - getConceptCookieMethod.mockImplementation(() => null); - - store.dispatch = jest.spyOn(store, "dispatch"); - - const mockData = { - actionList: [{ - actionName: storeActions.RESET_STATE - }], - } - - setupMocksForJsFiles(mockData); + var mocks = setupMocksForJsFiles(mockData); // Act helper.loadOrderIfPresent(); // Assert expect(helper.getConceptCookie).toHaveBeenCalled(); - expect(store.dispatch).not.toHaveBeenCalledWith(storeActions.RESET_STATE); + expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.RESET_STATE); - getConceptCookieMethod.mockRestore(); + helper.getConceptCookie.mockRestore(); + // store.dispatch.mockRestore(); + }); + + test("Concept cookie is null => store is unchanged", () => { + // Arrange + helper.getConceptCookie = jest.spyOn(helper, "getConceptCookie").mockReturnValueOnce(null); + // store.dispatch = jest.spyOn(store, "dispatch"); + + const mockData = { + actionList: [{ + actionName: storeActions.RESET_STATE + }], + } + + var mocks = setupMocksForJsFiles(mockData); + + // Act + helper.loadOrderIfPresent(); + + // Assert + expect(helper.getConceptCookie).toHaveBeenCalled(); + expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).not.toHaveBeenCalledWith(storeActions.RESET_STATE); + + helper.getConceptCookie.mockRestore(); }); }); describe("saveOrder", () => { afterEach(() => { removeAllTestCookies(); + // jest.resetAllMocks(); + // jest.unmock("@/helpers/heritage-integration-helper"); + // // helper.getConceptCookie = jest.fn().mockImplementation(arg => arg) }); test("saveOrder => should set state order values", async () => { @@ -137,7 +140,7 @@ describe("saveOrder", () => { data: mockOrderInfo, }], router: router - } + }; setupMocksForJsFiles(mockData); @@ -154,6 +157,10 @@ describe("saveOrder", () => { // Act await helper.saveOrder(); + console.log(document.cookie) + console.log(helper.getConceptCookie) + console.log(helper.getConceptCookie()) + // Assert expect(helper.getConceptCookie().DidHeritageFunnelUpdateLast).toEqual(false); }); @@ -334,7 +341,7 @@ describe("getPageToRouteExistingOrderTo", () => { // Mock out the lazy load calls for all components. lazyLoadComponent - .mockReturnValueOnce(() => { + .mockReturnValueOnce(() => { return { default: { methods: { @@ -342,8 +349,8 @@ describe("getPageToRouteExistingOrderTo", () => { } } } - }) - .mockReturnValueOnce(() => { + }) + .mockReturnValueOnce(() => { return { default: { methods: { @@ -351,8 +358,8 @@ describe("getPageToRouteExistingOrderTo", () => { } } } - }) - .mockReturnValueOnce(() => { + }) + .mockReturnValueOnce(() => { return { default: { methods: { @@ -360,8 +367,8 @@ describe("getPageToRouteExistingOrderTo", () => { } } } - }) - .mockReturnValueOnce(() => { + }) + .mockReturnValueOnce(() => { return { default: { methods: { @@ -369,7 +376,7 @@ describe("getPageToRouteExistingOrderTo", () => { } } } - }); + }); // Act const result = await helper.getPageToRouteExistingOrderTo(toRoute, false); @@ -386,7 +393,7 @@ describe("getPageToRouteExistingOrderTo", () => { // Mock out the lazy load calls for all components. lazyLoadComponent - .mockReturnValueOnce(() => { + .mockReturnValueOnce(() => { return { default: { methods: { @@ -394,8 +401,8 @@ describe("getPageToRouteExistingOrderTo", () => { } } } - }) - .mockReturnValueOnce(() => { + }) + .mockReturnValueOnce(() => { return { default: { methods: { @@ -403,8 +410,8 @@ describe("getPageToRouteExistingOrderTo", () => { } } } - }) - .mockReturnValueOnce(() => { + }) + .mockReturnValueOnce(() => { return { default: { methods: { @@ -412,8 +419,8 @@ describe("getPageToRouteExistingOrderTo", () => { } } } - }) - .mockReturnValueOnce(() => { + }) + .mockReturnValueOnce(() => { return { default: { methods: { @@ -421,7 +428,7 @@ describe("getPageToRouteExistingOrderTo", () => { } } } - }); + }); store.getters.damage.isRepair = false; store.getters.vehicle.carId = 'C00000'; diff --git a/src/router/index.js b/src/router/index.js index e0701d095..51e010980 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -4,7 +4,7 @@ import { storeActions } from "@/constants/store-actions"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; -import * as heritageIntegrationHelper from "@/helpers/heritage-integration-helper"; +import heritageIntegrationHelper from "@/helpers/heritage-integration-helper"; import baseMixin from "@/mixins/base-mixin"; import eventBus from "@/helpers/event-bus/event-bus"; diff --git a/src/store/index.js b/src/store/index.js index 27c252995..5d2a0a422 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -5,8 +5,6 @@ import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration-he import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; - - // Export State const getDefaultState = () => { return { @@ -55,7 +53,7 @@ const getDefaultState = () => { applicationUser: { eventBus: [], pageData: {}, - savedSessionTimeout: getDateForSavedSessionTimeout() + // savedSessionTimeout: getDateForSavedSessionTimeout() TODO CSR-98 }, } }; From c50e21a2a7f8e7483b29a684f9a5875d886b5fff Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 29 Mar 2022 09:13:19 -0400 Subject: [PATCH 30/58] refactor heritage helper --- src/helpers/heritage-integration-helper.js | 292 ----------- .../heritage-integration-helper.spec.js | 475 ------------------ .../heritage-integration/cookie-helper.js | 78 +++ .../cookie-helper.spec.js | 128 +++++ .../heritage-integration/navigation-helper.js | 77 +++ .../navigation-helper.spec.js | 310 ++++++++++++ .../heritage-integration/order-helper.js | 75 +++ .../heritage-integration/order-helper.spec.js | 187 +++++++ .../heritage-integration/session-helper.js | 52 ++ src/layouts/vehicle-damage/vehicle-damage.vue | 2 +- src/router/index.js | 21 +- src/store/index.js | 4 +- 12 files changed, 923 insertions(+), 778 deletions(-) delete mode 100644 src/helpers/heritage-integration-helper.js delete mode 100644 src/helpers/heritage-integration-helper.spec.js create mode 100644 src/helpers/heritage-integration/cookie-helper.js create mode 100644 src/helpers/heritage-integration/cookie-helper.spec.js create mode 100644 src/helpers/heritage-integration/navigation-helper.js create mode 100644 src/helpers/heritage-integration/navigation-helper.spec.js create mode 100644 src/helpers/heritage-integration/order-helper.js create mode 100644 src/helpers/heritage-integration/order-helper.spec.js create mode 100644 src/helpers/heritage-integration/session-helper.js diff --git a/src/helpers/heritage-integration-helper.js b/src/helpers/heritage-integration-helper.js deleted file mode 100644 index f4ae1c1a2..000000000 --- a/src/helpers/heritage-integration-helper.js +++ /dev/null @@ -1,292 +0,0 @@ -// import * as self from "./heritage-integration-helper"; -import { storeActions } from "@/constants/store-actions.js"; -import { cookieNames } from "@/constants/cookie-names"; -import { queryStrings } from "@/constants/query-strings"; -import { externalUrls } from "@/router/router-constants/externalUrl-values"; -import { applicationConfig } from "@/constants/application-config"; -import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; -import store from "@/store"; -import router from "@/router"; -import baseMixin from "../mixins/base-mixin"; - -/* - Will call API to save existing order, or create new one depending where it's called from. - This will also set Referral information in the store after saving, and then - update the cookie. -*/ -async function saveOrder() { - console.log("saving order..."); - const savedOrderInfo = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER); - - // Save the referral information back from the store. - await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SET_REFERRAL_INFORMATION, { - referralNumber: savedOrderInfo.data.referralNumber, - referralCorrelationId: savedOrderInfo.data.referralCorrelationId, - referralDate: savedOrderInfo.data.referralDate, - }, false); - - // Update the cookie with the referral information when saved. - updateOrCreateConceptCookie(); -} - -/* - Will call API and hydrate state with data from API if present. If there is no order present - method will return null. If the cookie dictates the state should be reset - it will reset the state and go back to the start of the funnel. - -*/ -async function loadOrderIfPresent() { - console.log("attempting to load referral...."); - // const conceptCookie = self.getConceptCookie(); - const conceptCookie = exportFunctions.getConceptCookie(); - - console.log(conceptCookie) - - // Do nothing if there is no cookie or no correlation id. - if (conceptCookie === null || conceptCookie.ReferralCorrelationId === null) { - console.log("No referral found"); - return null; - } - - // Reset state if cookie says to. - if (conceptCookie.ShouldResetState) { - console.log("Resetting state..."); - baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); - deleteConceptCookie(); - return null; - } - - console.log("calling load order from loadOrderIfPresent()..."); - - // Load referral if there is a cookie, and it doesn't indicate it needs a state reset. - return (await loadOrder(conceptCookie.ReferralNumber, conceptCookie.ReferralDate, conceptCookie.ReferralCorrelationId)).data; -} - -/* - If the user has visited the concept funnel before this method will determine the bets place to - drop them so they don't start at the beginning again. This method will return 'heritage' if - the user has an existing order and they come back in from the Safelite.com CTA. -*/ -async function getPageToRouteExistingOrderTo(toRoute = {}, existingHeritageOrder = false) { - - // If the user is coming in via the Safelite.Com CTA - if (toRoute.query[queryStrings.START_TYPE] === 'fmg') { - console.log("Start type is FMG... trying to figure out where to send them..."); - - // If they have an existing order, return 'heritage' for the page name. - if (existingHeritageOrder) { - console.log("Existing heritage order found, returning 'heritage' for page redirect..."); - return 'heritage'; - } - } - - - // If this is a non-CTA navigation, determine where to send the user based on page prerequisites. - // This also works if a user has a 'fmg' start_type query string but no current order. - // That shouldn't happen, but it's possible. - const vehicleMakeComponent = (await lazyLoadComponent('vehicle-make')()).default; - const vehicleModelComponent = (await lazyLoadComponent('vehicle-model')()).default; - const vehicleStyleComponent = (await lazyLoadComponent('vehicle-style')()).default; - const vehicleDamageComponent = (await lazyLoadComponent('vehicle-damage')()).default; - - - if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) { - return "vehicle-year"; - } else if (!vehicleModelComponent.methods.arePagePrerequisitesValid()) { - return "vehicle-make"; - } else if (!vehicleStyleComponent.methods.arePagePrerequisitesValid()) { - return "vehicle-model"; - } else if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) { - return "vehicle-style"; - } else if (store.getters.damage.isRepair != null && store.getters.vehicle.carId) { - return 'vehicle-damage' - } else { - if (store.getters.vehicle.vin) { - return "vin-lookup"; - } else { - return "estimate" - } - } - -} - -/* - Will update the cookie if present, or create a new one if not. -*/ -function updateOrCreateConceptCookie() { - console.log("Updating cookie...", { - LastTouched: new Date().toUTCString(), - SavedQuoteTimeoutDate: store.getters.applicationUser.savedSessionTimeout, - DidHeritageFunnelUpdateLast: false, - ShouldResetState: false, - ReferralNumber: store.getters.order.referralNumber, - ReferralDate: store.getters.order.referralDate, - ReferralCorrelationId: store.getters.order.referralCorrelationId, - }); - - // Create the cookie - document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}={}; path=/`; - - // Set up cookie with all the props. - setConceptCookieProperties({ - LastTouched: new Date().toUTCString(), - SavedQuoteTimeoutDate: store.getters.applicationUser.savedSessionTimeout, - DidHeritageFunnelUpdateLast: false, - ShouldResetState: false, - ReferralNumber: store.getters.order.referralNumber, - ReferralDate: store.getters.order.referralDate, - ReferralCorrelationId: store.getters.order.referralCorrelationId, - }); - -} - -/* - Method to determine if our analytics session has timed out or not. - Amount used for timeout is configurable in application-config.js -*/ -function isAnalyticsSessionStillActive() { - if (getConceptCookie() !== null) { - const lastTouchedValue = getConceptCookie().LastTouched; - const timeoutAmount = applicationConfig.ANALYTICS_SESSION_TIMEOUT; - const isMoreThanHalfHourAgo = ((new Date() - new Date(lastTouchedValue)) / 60000) > timeoutAmount; - - if (isMoreThanHalfHourAgo) { - return false; - } - - return true; - } -} - -/* - Method to determine if the users 'saved' session is still active. - When user state is created, there is a date that is saved into state - this method checks against that date. - - Note: That time for saved session timeout is configurable in application-config.js -*/ -function isSavedSessionStillActive() { - if (getConceptCookie() !== null) { - const savedSessionTimeStamp = new Date(getConceptCookie().SavedQuoteTimeoutDate); - const isSavedSessionTimedOut = (new Date(new Date().toUTCString()) > savedSessionTimeStamp); - - console.log("Saved Session Timed Out? --->", isSavedSessionTimedOut); - - if (isSavedSessionTimedOut) { - return false; - } - - return true; - } -} - -/* - Used to navigate to the heritage funnel with the correct query string and url. -*/ - -async function navigateToHeritageFunnel() { - - // Create the order (or save existing order) when navigating to Heritage Funnel. - // console.log(exports) - // await self.saveOrder(); - await exportFunctions.saveOrder(); - - router.navigateToExternalUrl( - externalUrls.HERITAGE_FUNNEL, - { - corid: store.getters.order.referralCorrelationId, - src: "concept-funnel", - // TODO CSR-28, remove this - cns: "all", - experiments: "RemoveServiceAreaPage=ServAreaRemoval_V7=ServAreaNoRemove_V7_TEST=true,ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" - } - ); -} - -/* - Gets the current instance of the concept funnel cookie. - Returns null if cookie isn't valid JSON. -*/ -function getConceptCookie() { - const cookieJson = document.cookie - ?.split("; ") - ?.find(row => row.startsWith(`${cookieNames.CONCEPT_SESSION_INFO}=`)) - ?.split("=")[1]; - - try { - return JSON.parse(cookieJson); - } catch (error) { - return null; - } -} - -/* -Function to get the date for the saved session timeout. -*/ - -function getDateForSavedSessionTimeout() { - const currentDate = new Date(new Date().toUTCString()) - currentDate.setDate(currentDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT) - return currentDate.toUTCString(); -} - -//-------------------------------------\\\ -// --------- PRIVATE FUNCTIONS --------- \\\ -//----------------------------------------\\\ - -/* - Calls API to load order given the referral number, referralDate, and referralCorrelationId - and returns the response. -*/ -async function loadOrder(referralNumber, referralDate, referralCorrelationId) { - console.log("loading order...", referralNumber, referralDate, referralCorrelationId); - const response = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER, - { - referralNumber: referralNumber.toString(), - referralDate: referralDate, - referralCorrelationId: referralCorrelationId - }, false); - - return response; -} - -/* - Used to set properties on the concept funnel cookie. - Takes an object with properties to set. Will overwrite existing properties. -*/ -function setConceptCookieProperties(properties) { - if (typeof properties == "object") { - let cookie = getConceptCookie(); - - if (cookie !== null) { - Object.keys(properties).forEach(key => { - cookie[key] = properties[key]; - }); - - const cookieValueJson = JSON.stringify(cookie); - - document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=${cookieValueJson}; path=/`; - } - } -} - -/* - Removes concept cookie from browser. -*/ -function deleteConceptCookie() { - document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; -} - -const exportFunctions = { - saveOrder, - loadOrderIfPresent, - getPageToRouteExistingOrderTo, - updateOrCreateConceptCookie, - isAnalyticsSessionStillActive, - isSavedSessionStillActive, - navigateToHeritageFunnel, - getConceptCookie, - getDateForSavedSessionTimeout -}; - -export default exportFunctions; \ No newline at end of file diff --git a/src/helpers/heritage-integration-helper.spec.js b/src/helpers/heritage-integration-helper.spec.js deleted file mode 100644 index 7d6de90c2..000000000 --- a/src/helpers/heritage-integration-helper.spec.js +++ /dev/null @@ -1,475 +0,0 @@ -import helper from "@/helpers/heritage-integration-helper"; -import { cookieNames } from "@/constants/cookie-names"; -import { setupMocksForJsFiles } from "@/helpers/unit-test-helper.js"; -import { storeActions } from "@/constants/store-actions"; -import store from "@/store"; -import router from "@/router"; -import baseMixin from "@/mixins/base-mixin"; -import { externalUrls } from "@/router/router-constants/externalUrl-values"; -import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; - -// Mock Lazy Load -jest.mock("@/router/dynamic-routing/component-loader.js", () => ({ - lazyLoadComponent: jest.fn(), -})); - -describe("loadOrderIfPresent", () => { - afterEach(() => { - removeAllTestCookies(); - }); - - test("ShouldResetState == true => concept cookie is deleted", () => { - // Arrange - const testShouldResetState = true; - - const testCookieValue = { - ShouldResetState: testShouldResetState - } - - document.cookie = `${cookieNames.ORDER_INFO}=${JSON.stringify(testCookieValue)}; path=/; domain=${location.hostname}`; - - // Act - helper.loadOrderIfPresent(); - - // Assert - expect(document.cookie).toBe(""); - }); - - test("ShouldResetState == true => reset store", () => { - // Arrange - // helper.getConceptCookie = jest.fn().mockReturnValueOnce({ ShouldResetState: true, DidHeritageFunnelUpdateLast: false }); - helper.getConceptCookie = jest.spyOn(helper, "getConceptCookie").mockReturnValueOnce({ ShouldResetState: true, ReferralCorrelationId: "xxx-xxx-xxx"}); - // store.dispatch = jest.spyOn(store, "dispatch"); - - const mockData = { - actionList: [{ - actionName: storeActions.RESET_STATE - }], - } - - var mocks = setupMocksForJsFiles(mockData); - - // Act - helper.loadOrderIfPresent(); - - // Assert - expect(helper.getConceptCookie).toHaveBeenCalled(); - expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.RESET_STATE); - - helper.getConceptCookie.mockRestore(); - // store.dispatch.mockRestore(); - }); - - test("Concept cookie is null => store is unchanged", () => { - // Arrange - helper.getConceptCookie = jest.spyOn(helper, "getConceptCookie").mockReturnValueOnce(null); - // store.dispatch = jest.spyOn(store, "dispatch"); - - const mockData = { - actionList: [{ - actionName: storeActions.RESET_STATE - }], - } - - var mocks = setupMocksForJsFiles(mockData); - - // Act - helper.loadOrderIfPresent(); - - // Assert - expect(helper.getConceptCookie).toHaveBeenCalled(); - expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).not.toHaveBeenCalledWith(storeActions.RESET_STATE); - - helper.getConceptCookie.mockRestore(); - }); -}); - -describe("saveOrder", () => { - afterEach(() => { - removeAllTestCookies(); - // jest.resetAllMocks(); - // jest.unmock("@/helpers/heritage-integration-helper"); - // // helper.getConceptCookie = jest.fn().mockImplementation(arg => arg) - }); - - test("saveOrder => should set state order values", async () => { - // Arrange - const mockReferralNumber = 2; - const mockCorrelationId = "55"; - const mockReferralDate = "2022"; - - const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); - - const mockData = { - actionList: [ - { - actionName: storeActions.SAVE_ORDER, - data: mockOrderInfo, - }, - { - actionName: storeActions.SET_REFERRAL_INFORMATION - } - ] - } - - const mocks = setupMocksForJsFiles(mockData); - - // Act - await helper.saveOrder(); - - // Assert - expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.SAVE_ORDER); - expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.SET_REFERRAL_INFORMATION, { - referralNumber: mockReferralNumber, - referralDate: mockReferralDate, - referralCorrelationId: mockCorrelationId - }, false); - }); - - test("saveOrder => should update DidHeritageFunnelUpdateLast cookie value to false", async () => { - // Arrange - const testReferralNumber = 1566818; - const testReferralDate = "2022-03-15T10:56:24.597"; - const testReferralCorrelationId = "404d2b04-f86e-45c3-b373-127b6217b060"; - - const mockOrderInfo = getMockOrderInfo(testReferralNumber, testReferralCorrelationId, testReferralDate); - - const mockData = { - actionList: [{ - actionName: storeActions.SAVE_ORDER, - data: mockOrderInfo, - }], - router: router - }; - - setupMocksForJsFiles(mockData); - - const testCookieValue = { - ReferralNumber: testReferralNumber, - ReferralDate: testReferralDate, - ReferralCorrelationId: testReferralCorrelationId, - ShouldResetState: false, - DidHeritageFunnelUpdateLast: true - } - - setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) }); - - // Act - await helper.saveOrder(); - - console.log(document.cookie) - console.log(helper.getConceptCookie) - console.log(helper.getConceptCookie()) - - // Assert - expect(helper.getConceptCookie().DidHeritageFunnelUpdateLast).toEqual(false); - }); -}); - -describe("navigateToHeritageFunnel", () => { - test("should save order", async () => { - // Arrange - const mockReferralNumber = 2; - const mockCorrelationId = "55"; - const mockReferralDate = "2022"; - - const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); - - const mockData = { - actionList: [{ - actionName: storeActions.SAVE_ORDER, - data: mockOrderInfo, - }] - } - - setupMocksForJsFiles(mockData); - const saveOrderFunction = jest.spyOn(helper, "saveOrder"); - router.navigateToExternalUrl = jest.fn(); - - // Act - await helper.navigateToHeritageFunnel(); - - // Assert - expect(saveOrderFunction).toHaveBeenCalled(); - - // Should alway save before we navigate to heritage - const saveOrderFunctionCallOrder = saveOrderFunction.mock.invocationCallOrder[0]; - const routerNavigateFunctionCallOrder = router.navigateToExternalUrl.mock.invocationCallOrder[0]; - expect(saveOrderFunctionCallOrder).toBeLessThan(routerNavigateFunctionCallOrder); - saveOrderFunction.mockRestore(); - }); - - test("should go to heritage funnel", async () => { - // Arrange - const mockReferralNumber = 2; - const mockCorrelationId = "55"; - const mockReferralDate = "2022"; - - const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); - - const mockData = { - actionList: [{ - actionName: storeActions.SAVE_ORDER, - data: mockOrderInfo, - }] - } - - setupMocksForJsFiles(mockData); - - store.getters.order.referralCorrelationId = mockCorrelationId - - router.navigateToExternalUrl = jest.fn(); - - // Act - await helper.navigateToHeritageFunnel(); - - // Assert - expect(router.navigateToExternalUrl).toHaveBeenCalled(); - expect(router.navigateToExternalUrl).toHaveBeenCalledWith(externalUrls.HERITAGE_FUNNEL, - expect.objectContaining({ - corid: mockCorrelationId - }) - ); - }); -}); - -describe("cookies", () => { - afterEach(() => { - removeAllTestCookies(); - }) - - describe("getConceptCookie method", () => { - test("gets correct value when cookie is present", () => { - // Arrange - const testReferralNumber = 1566818; - const testReferralDate = "2022-03-15T10:56:24.597"; - const testReferralCorrelationId = "404d2b04-f86e-45c3-b373-127b6217b060"; - const testShouldResetState = false; - const testDidHeritageFunnelUpdateLast = true; - - const testCookieValue = { - ReferralNumber: testReferralNumber, - ReferralDate: testReferralDate, - ReferralCorrelationId: testReferralCorrelationId, - ShouldResetState: testShouldResetState, - DidHeritageFunnelUpdateLast: testDidHeritageFunnelUpdateLast - } - setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) }); - - // Act - var result = helper.getConceptCookie(); - - // Assert - expect(result).toEqual(testCookieValue); - expect(typeof result).toEqual("object"); - expect(result.ReferralNumber).toEqual(testReferralNumber); - expect(result.ReferralDate).toEqual(testReferralDate); - expect(result.ReferralCorrelationId).toEqual(testReferralCorrelationId); - expect(result.ShouldResetState).toEqual(testShouldResetState); - expect(result.DidHeritageFunnelUpdateLast).toEqual(testDidHeritageFunnelUpdateLast); - }); - - test("returns empty object when value is empty object", () => { - // Arrange - const testCookieValue = {}; - setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) }); - - // Act - var result = helper.getConceptCookie(); - - // Assert - expect(result).toEqual(testCookieValue); - expect(typeof result).toEqual("object"); - expect(Object.keys(result)).toHaveLength(0); - }); - - test("returns null when value is empty string", () => { - // Arrange - const testCookieValue = ""; - setupCookies({ conceptCookieValue: testCookieValue }); - - // Act - var result = helper.getConceptCookie(); - - // Assert - expect(result).toEqual(null); - }); - - test("returns null when concept cookie doesn't exist", () => { - // Arrange - setupCookies({ includeHeritageCookie: false }); - - // Act - var result = helper.getConceptCookie(); - - // Assert - expect(result).toEqual(null); - }); - - test("gets correct cookie value", () => { - // Arrange - const testCookieValue = { test: "testValue" }; - - setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) }); - - // Act - const actualCookieValue = helper.getConceptCookie(); - - // Assert - expect(actualCookieValue).toEqual(testCookieValue); - }); - - test("getCookieValue: Gets null cookie value", () => { - // Arrange - setupCookies({ includeHeritageCookie: false }); - - // Act - const actualCookieValue = helper.getConceptCookie(); - - // Assert - expect(actualCookieValue).toBeNull(); - }); - }) -}) - -describe("getPageToRouteExistingOrderTo", () => { - test("getPageToRouteExistingOrderTo, should return vehicle-model", async () => { - // Arrange - const toRoute = { - query: {} - }; - - // Mock out the lazy load calls for all components. - lazyLoadComponent - .mockReturnValueOnce(() => { - return { - default: { - methods: { - arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) - } - } - } - }) - .mockReturnValueOnce(() => { - return { - default: { - methods: { - arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) - } - } - } - }) - .mockReturnValueOnce(() => { - return { - default: { - methods: { - arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false) - } - } - } - }) - .mockReturnValueOnce(() => { - return { - default: { - methods: { - arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false) - } - } - } - }); - - // Act - const result = await helper.getPageToRouteExistingOrderTo(toRoute, false); - - //Assert - expect(result).toBe('vehicle-model'); - }); - - test("getPageToRouteExistingOrderTo, should return vehicle-damage", async () => { - // Arrange - const toRoute = { - query: {} - }; - - // Mock out the lazy load calls for all components. - lazyLoadComponent - .mockReturnValueOnce(() => { - return { - default: { - methods: { - arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) - } - } - } - }) - .mockReturnValueOnce(() => { - return { - default: { - methods: { - arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) - } - } - } - }) - .mockReturnValueOnce(() => { - return { - default: { - methods: { - arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) - } - } - } - }) - .mockReturnValueOnce(() => { - return { - default: { - methods: { - arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) - } - } - } - }); - - store.getters.damage.isRepair = false; - store.getters.vehicle.carId = 'C00000'; - - // Act - const result = await helper.getPageToRouteExistingOrderTo(toRoute, false); - - //Assert - expect(result).toBe('vehicle-damage'); - }); - -}); - -// document.cookie is not just a string, needs to be added individually -const cookies = { - [cookieNames.CONCEPT_SESSION_INFO]: `{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false,"DidHeritageFunnelUpdateLast":true}`, - "UNIQUE_SESSION_ID": "33756020-b58e-4ec7-b8b8-3f1576719c40", - "anotherCookie": "{}", - "someOtherCookie": "{}" -}; - -function setupCookies({ conceptCookieValue = "", includeHeritageCookie = true }) { - Object.keys(cookies).forEach(key => { - const cookieValue = key == cookieNames.CONCEPT_SESSION_INFO ? conceptCookieValue : cookies[key]; - - if (includeHeritageCookie || key != cookieNames.CONCEPT_SESSION_INFO) - document.cookie = `${key}=${cookieValue}; path=/;`; - }); -} - -function removeAllTestCookies() { - Object.keys(cookies).forEach(key => { - document.cookie = `${key}=;Max-Age=0;`; - document.cookie = `${key}=;Max-Age=0;path=/`; - }); -} - -function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate) { - return { - referralNumber: mockReferralNumber, - referralCorrelationId: mockCorrelationId, - referralDate: mockReferralDate - } -} diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js new file mode 100644 index 000000000..9de5d5760 --- /dev/null +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -0,0 +1,78 @@ +import { cookieNames } from "@/constants/cookie-names"; +import store from "@/store"; + + +/* + Will update the cookie if present, or create a new one if not. +*/ +export function updateOrCreateConceptCookie() { + console.log("Updating cookie...", { + LastTouched: new Date().toUTCString(), + SavedQuoteTimeoutDate: store.getters.applicationUser.savedSessionTimeout, + DidHeritageFunnelUpdateLast: false, + ShouldResetState: false, + ReferralNumber: store.getters.order.referralNumber, + ReferralDate: store.getters.order.referralDate, + ReferralCorrelationId: store.getters.order.referralCorrelationId, + }); + + // Create the cookie + document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}={}; path=/`; + + // Set up cookie with all the props. + setConceptCookieProperties({ + LastTouched: new Date().toUTCString(), + SavedQuoteTimeoutDate: store.getters.applicationUser.savedSessionTimeout, + DidHeritageFunnelUpdateLast: false, + ShouldResetState: false, + ReferralNumber: store.getters.order.referralNumber, + ReferralDate: store.getters.order.referralDate, + ReferralCorrelationId: store.getters.order.referralCorrelationId, + }); + +} + +/* + Gets the current instance of the concept funnel cookie. + Returns null if cookie isn't valid JSON. +*/ +export function getConceptCookie() { + const cookieJson = document.cookie + ?.split("; ") + ?.find(row => row.startsWith(`${cookieNames.CONCEPT_SESSION_INFO}=`)) + ?.split("=")[1]; + + try { + return JSON.parse(cookieJson); + } catch (error) { + return null; + } +} + +/* + Removes concept cookie from browser. +*/ +export function deleteConceptCookie() { + document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; +} + +/* + Used to set properties on the concept funnel cookie. + Takes an object with properties to set. Will overwrite existing properties. +*/ +function setConceptCookieProperties(properties) { + if (typeof properties == "object") { + let cookie = getConceptCookie(); + + if (cookie !== null) { + Object.keys(properties).forEach(key => { + cookie[key] = properties[key]; + }); + + const cookieValueJson = JSON.stringify(cookie); + + document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=${cookieValueJson}; path=/`; + } + } +} + diff --git a/src/helpers/heritage-integration/cookie-helper.spec.js b/src/helpers/heritage-integration/cookie-helper.spec.js new file mode 100644 index 000000000..73b3bd9bc --- /dev/null +++ b/src/helpers/heritage-integration/cookie-helper.spec.js @@ -0,0 +1,128 @@ +import {getConceptCookie} from "@/helpers/heritage-integration/cookie-helper.js"; +import { cookieNames } from "@/constants/cookie-names"; + +describe("cookies", () => { + + afterEach(() => { + removeAllTestCookies(); + }) + + describe("getConceptCookie method", () => { + test("gets correct value when cookie is present", () => { + // Arrange + const testReferralNumber = 1566818; + const testReferralDate = "2022-03-15T10:56:24.597"; + const testReferralCorrelationId = "404d2b04-f86e-45c3-b373-127b6217b060"; + const testShouldResetState = false; + const testDidHeritageFunnelUpdateLast = true; + + const testCookieValue = { + ReferralNumber: testReferralNumber, + ReferralDate: testReferralDate, + ReferralCorrelationId: testReferralCorrelationId, + ShouldResetState: testShouldResetState, + DidHeritageFunnelUpdateLast: testDidHeritageFunnelUpdateLast + } + + setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) }); + + // Act + var result = getConceptCookie(); + + // Assert + expect(result).toEqual(testCookieValue); + expect(typeof result).toEqual("object"); + expect(result.ReferralNumber).toEqual(testReferralNumber); + expect(result.ReferralDate).toEqual(testReferralDate); + expect(result.ReferralCorrelationId).toEqual(testReferralCorrelationId); + expect(result.ShouldResetState).toEqual(testShouldResetState); + expect(result.DidHeritageFunnelUpdateLast).toEqual(testDidHeritageFunnelUpdateLast); + }); + + test("returns empty object when value is empty object", () => { + // Arrange + const testCookieValue = {}; + setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) }); + + // Act + var result = getConceptCookie(); + + // Assert + expect(result).toEqual(testCookieValue); + expect(typeof result).toEqual("object"); + expect(Object.keys(result)).toHaveLength(0); + }); + + test("returns null when value is empty string", () => { + // Arrange + const testCookieValue = ""; + setupCookies({ conceptCookieValue: testCookieValue }); + + // Act + var result = getConceptCookie(); + + // Assert + expect(result).toEqual(null); + }); + + test("returns null when concept cookie doesn't exist", () => { + // Arrange + setupCookies({ includeHeritageCookie: false }); + + // Act + var result = getConceptCookie(); + + // Assert + expect(result).toEqual(null); + }); + + test("gets correct cookie value", () => { + // Arrange + const testCookieValue = { test: "testValue" }; + + setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) }); + + // Act + const actualCookieValue = getConceptCookie(); + + // Assert + expect(actualCookieValue).toEqual(testCookieValue); + }); + + test("getCookieValue: Gets null cookie value", () => { + // Arrange + setupCookies({ includeHeritageCookie: false }); + + // Act + const actualCookieValue = getConceptCookie(); + + // Assert + expect(actualCookieValue).toBeNull(); + }); + }) + }) + + // document.cookie is not just a string, needs to be added individually +const cookies = { + [cookieNames.CONCEPT_SESSION_INFO]: `{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false,"DidHeritageFunnelUpdateLast":true}`, + "UNIQUE_SESSION_ID": "33756020-b58e-4ec7-b8b8-3f1576719c40", + "anotherCookie": "{}", + "someOtherCookie": "{}" + }; + + function setupCookies({ conceptCookieValue = "", includeHeritageCookie = true }) { + Object.keys(cookies).forEach(key => { + const cookieValue = key == cookieNames.CONCEPT_SESSION_INFO ? conceptCookieValue : cookies[key]; + + if (includeHeritageCookie || key != cookieNames.CONCEPT_SESSION_INFO) + document.cookie = `${key}=${cookieValue}; path=/;`; + }); + } + + function removeAllTestCookies() { + Object.keys(cookies).forEach(key => { + document.cookie = `${key}=;Max-Age=0;`; + document.cookie = `${key}=;Max-Age=0;path=/`; + }); + } + \ No newline at end of file diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js new file mode 100644 index 000000000..2195ce66c --- /dev/null +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -0,0 +1,77 @@ +import { queryStrings } from "@/constants/query-strings"; +import { externalUrls } from "@/router/router-constants/externalUrl-values"; +import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; +import {saveOrder} from "@/helpers/heritage-integration/order-helper.js"; +import store from "@/store"; +import router from "@/router"; + +/* + If the user has visited the concept funnel before this method will determine the bets place to + drop them so they don't start at the beginning again. This method will return 'heritage' if + the user has an existing order and they come back in from the Safelite.com CTA. +*/ +export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHeritageOrder = false) { + + // If the user is coming in via the Safelite.Com CTA + if (toRoute.query[queryStrings.START_TYPE] === 'fmg') { + console.log("Start type is FMG... trying to figure out where to send them..."); + + // If they have an existing order, return 'heritage' for the page name. + if (existingHeritageOrder) { + console.log("Existing heritage order found, returning 'heritage' for page redirect..."); + return 'heritage'; + } + } + + + // If this is a non-CTA navigation, determine where to send the user based on page prerequisites. + // This also works if a user has a 'fmg' start_type query string but no current order. + // That shouldn't happen, but it's possible. + const vehicleMakeComponent = (await lazyLoadComponent('vehicle-make')()).default; + const vehicleModelComponent = (await lazyLoadComponent('vehicle-model')()).default; + const vehicleStyleComponent = (await lazyLoadComponent('vehicle-style')()).default; + const vehicleDamageComponent = (await lazyLoadComponent('vehicle-damage')()).default; + + + if (!vehicleMakeComponent.methods.arePagePrerequisitesValid()) { + return "vehicle-year"; + } else if (!vehicleModelComponent.methods.arePagePrerequisitesValid()) { + return "vehicle-make"; + } else if (!vehicleStyleComponent.methods.arePagePrerequisitesValid()) { + return "vehicle-model"; + } else if (!vehicleDamageComponent.methods.arePagePrerequisitesValid()) { + return "vehicle-style"; + } else if (store.getters.damage.isRepair == null || !store.getters.vehicle.carId) { + return 'vehicle-damage' + } else { + if (store.getters.vehicle.vin) { + return "vin-lookup"; + } else { + return "estimate" + } + } + +} + +/* + Used to navigate to the heritage funnel with the correct query string and url. +*/ + +export async function navigateToHeritageFunnel() { + + // Create the order (or save existing order) when navigating to Heritage Funnel. + // console.log(exports) + // await self.saveOrder(); + await saveOrder(); + + router.navigateToExternalUrl( + externalUrls.HERITAGE_FUNNEL, + { + corid: store.getters.order.referralCorrelationId, + src: "concept-funnel", + // TODO CSR-28, remove this + cns: "all", + experiments: "RemoveServiceAreaPage=ServAreaRemoval_V7=ServAreaNoRemove_V7_TEST=true,ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" + } + ); +} \ No newline at end of file diff --git a/src/helpers/heritage-integration/navigation-helper.spec.js b/src/helpers/heritage-integration/navigation-helper.spec.js new file mode 100644 index 000000000..2c586a76f --- /dev/null +++ b/src/helpers/heritage-integration/navigation-helper.spec.js @@ -0,0 +1,310 @@ +import { getPageToRouteExistingOrderTo, navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; +import * as orderHelper from "@/helpers/heritage-integration/order-helper"; +import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; +import { storeActions } from "@/constants/store-actions"; +import { setupMocksForJsFiles } from "@/helpers/unit-test-helper.js"; +import { externalUrls } from "@/router/router-constants/externalUrl-values"; + +import store from "@/store"; +import router from "@/router"; + +// Mock Lazy Load +jest.mock("@/router/dynamic-routing/component-loader.js", () => ({ + lazyLoadComponent: jest.fn(), +})); + +describe("getPageToRouteExistingOrderTo", () => { + + test("getPageToRouteExistingOrderTo, should return vehicle-model", async () => { + // Arrange + const toRoute = { + query: {} + }; + + // Mock out the lazy load calls for all components. + lazyLoadComponent + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false) + } + } + } + }); + + // Act + const result = await getPageToRouteExistingOrderTo(toRoute, false); + + //Assert + expect(result).toBe('vehicle-model'); + }); + + test("getPageToRouteExistingOrderTo, should return vehicle-damage", async () => { + // Arrange + const toRoute = { + query: {} + }; + + // Mock out the lazy load calls for all components. + lazyLoadComponent + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }); + + store.getters.damage.isRepair = undefined; + store.getters.vehicle.carId = 'C00000'; + + // Act + const result = await getPageToRouteExistingOrderTo(toRoute, false); + + //Assert + expect(result).toBe('vehicle-damage'); + }); + + test("getPageToRouteExistingOrderTo, should return vin-lookup", async () => { + // Arrange + const toRoute = { + query: {} + }; + + // Mock out the lazy load calls for all components. + lazyLoadComponent + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }); + + store.getters.damage.isRepair = true; + store.getters.vehicle.carId = 'C00000'; + store.getters.vehicle.vin = "1FADP3F26DL212886" + + // Act + const result = await getPageToRouteExistingOrderTo(toRoute, false); + + //Assert + expect(result).toBe('vin-lookup'); + }); + + test("getPageToRouteExistingOrderTo, should return estimate", async () => { + // Arrange + const toRoute = { + query: {} + }; + + // Mock out the lazy load calls for all components. + lazyLoadComponent + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(true) + } + } + } + }); + + store.getters.damage.isRepair = true; + store.getters.vehicle.carId = 'C00000'; + store.getters.vehicle.vin = null; + // Act + const result = await getPageToRouteExistingOrderTo(toRoute, false); + + //Assert + expect(result).toBe('estimate'); + }); +}); + +describe("navigateToHeritageFunnel", () => { + test("should save order", async () => { + // Arrange + const mockReferralNumber = 2; + const mockCorrelationId = "55"; + const mockReferralDate = "2022"; + + const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); + + const mockData = { + actionList: [{ + actionName: storeActions.SAVE_ORDER, + data: mockOrderInfo, + }] + } + + setupMocksForJsFiles(mockData); + const saveOrderFunction = jest.spyOn(orderHelper, "saveOrder"); + router.navigateToExternalUrl = jest.fn(); + + // Act + await navigateToHeritageFunnel(); + + // Assert + expect(saveOrderFunction).toHaveBeenCalled(); + + // Should alway save before we navigate to heritage + const saveOrderFunctionCallOrder = saveOrderFunction.mock.invocationCallOrder[0]; + const routerNavigateFunctionCallOrder = router.navigateToExternalUrl.mock.invocationCallOrder[0]; + expect(saveOrderFunctionCallOrder).toBeLessThan(routerNavigateFunctionCallOrder); + saveOrderFunction.mockRestore(); + }); + + test("should go to heritage funnel", async () => { + // Arrange + const mockReferralNumber = 2; + const mockCorrelationId = "55"; + const mockReferralDate = "2022"; + + const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); + + const mockData = { + actionList: [{ + actionName: storeActions.SAVE_ORDER, + data: mockOrderInfo, + }] + } + + setupMocksForJsFiles(mockData); + + store.getters.order.referralCorrelationId = mockCorrelationId + + router.navigateToExternalUrl = jest.fn(); + + // Act + await navigateToHeritageFunnel(); + + // Assert + expect(router.navigateToExternalUrl).toHaveBeenCalled(); + expect(router.navigateToExternalUrl).toHaveBeenCalledWith(externalUrls.HERITAGE_FUNNEL, + expect.objectContaining({ + corid: mockCorrelationId + }) + ); + }); +}); + +function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate) { + return { + referralNumber: mockReferralNumber, + referralCorrelationId: mockCorrelationId, + referralDate: mockReferralDate + } +} diff --git a/src/helpers/heritage-integration/order-helper.js b/src/helpers/heritage-integration/order-helper.js new file mode 100644 index 000000000..8d8fe01d4 --- /dev/null +++ b/src/helpers/heritage-integration/order-helper.js @@ -0,0 +1,75 @@ +import { storeActions } from "@/constants/store-actions.js"; +import { getConceptCookie, updateOrCreateConceptCookie, deleteConceptCookie } from "@/helpers/heritage-integration/cookie-helper.js"; +import baseMixin from "@/mixins/base-mixin"; + +/* + Will call API and hydrate state with data from API if present. If there is no order present + method will return null. If the cookie dictates the state should be reset + it will reset the state and go back to the start of the funnel. + +*/ +export async function loadOrderIfPresent() { + console.log("attempting to load referral...."); + // const conceptCookie = self.getConceptCookie(); + const conceptCookie = getConceptCookie(); + + console.log(conceptCookie) + + // Do nothing if there is no cookie or no correlation id. + if (conceptCookie == null || conceptCookie.ReferralCorrelationId == null) { + console.log("No referral found"); + return null; + } + + // Reset state if cookie says to. + if (conceptCookie.ShouldResetState) { + console.log("Resetting state..."); + baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); + deleteConceptCookie(); + return null; + } + + console.log("calling load order from loadOrderIfPresent()..."); + + // Load referral if there is a cookie, and it doesn't indicate it needs a state reset. + return (await loadOrder(conceptCookie.ReferralNumber, conceptCookie.ReferralDate, conceptCookie.ReferralCorrelationId)).data; +} + +/* + Will call API to save existing order, or create new one depending where it's called from. + This will also set Referral information in the store after saving, and then + update the cookie. +*/ +export async function saveOrder() { + console.log("saving order..."); + const savedOrderInfo = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER); + + // Save the referral information back from the store. + await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SET_REFERRAL_INFORMATION, { + referralNumber: savedOrderInfo.data.referralNumber, + referralCorrelationId: savedOrderInfo.data.referralCorrelationId, + referralDate: savedOrderInfo.data.referralDate, + }, false); + + // Update the cookie with the referral information when saved. + updateOrCreateConceptCookie(); +} + + +// PRIVATE FUNCTIONS // + +/* + Calls API to load order given the referral number, referralDate, and referralCorrelationId + and returns the response. +*/ +async function loadOrder(referralNumber, referralDate, referralCorrelationId) { + console.log("loading order...", referralNumber, referralDate, referralCorrelationId); + const response = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER, + { + referralNumber: referralNumber.toString(), + referralDate: referralDate, + referralCorrelationId: referralCorrelationId + }, false); + + return response; +} \ No newline at end of file diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js new file mode 100644 index 000000000..1fa223466 --- /dev/null +++ b/src/helpers/heritage-integration/order-helper.spec.js @@ -0,0 +1,187 @@ +import * as cookieHelper from "@/helpers/heritage-integration/cookie-helper"; +import { loadOrderIfPresent, saveOrder } from "@/helpers/heritage-integration/order-helper"; +import { cookieNames } from "@/constants/cookie-names"; +import { setupMocksForJsFiles } from "@/helpers/unit-test-helper.js"; +import { storeActions } from "@/constants/store-actions"; +import router from "@/router"; + +describe("loadOrderIfPresent", () => { + + afterEach(() => { + removeAllTestCookies(); + }); + + test("ShouldResetState == true => concept cookie is deleted", () => { + // Arrange + const testShouldResetState = true; + + const testCookieValue = { + ShouldResetState: testShouldResetState + } + + document.cookie = `${cookieNames.ORDER_INFO}=${JSON.stringify(testCookieValue)}; path=/; domain=${location.hostname}`; + + // Act + loadOrderIfPresent(); + + // Assert + expect(document.cookie).toBe(""); + }); + + test("ShouldResetState == true => reset store", () => { + // Arrange + cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie").mockReturnValueOnce({ ShouldResetState: true, ReferralCorrelationId: "xxx-xxx-xxx" }); + + const mockData = { + actionList: [{ + actionName: storeActions.RESET_STATE + }], + } + + var mocks = setupMocksForJsFiles(mockData); + + // Act + loadOrderIfPresent(); + + // Assert + expect(cookieHelper.getConceptCookie).toHaveBeenCalled(); + expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.RESET_STATE); + + cookieHelper.getConceptCookie.mockRestore(); + // store.dispatch.mockRestore(); + }); + + test("Concept cookie is null => store is unchanged", () => { + // Arrange + cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie").mockReturnValueOnce(null); + + const mockData = { + actionList: [{ + actionName: storeActions.RESET_STATE + }], + } + + var mocks = setupMocksForJsFiles(mockData); + + // Act + loadOrderIfPresent(); + + // Assert + expect(cookieHelper.getConceptCookie).toHaveBeenCalled(); + expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).not.toHaveBeenCalledWith(storeActions.RESET_STATE); + + cookieHelper.getConceptCookie.mockRestore(); + }); +}); + +describe("saveOrder", () => { + + afterEach(() => { + removeAllTestCookies(); + }); + + test("saveOrder => should set state order values", async () => { + // Arrange + const mockReferralNumber = 2; + const mockCorrelationId = "55"; + const mockReferralDate = "2022"; + + const mockOrderInfo = getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate); + + const mockData = { + actionList: [ + { + actionName: storeActions.SAVE_ORDER, + data: mockOrderInfo, + }, + { + actionName: storeActions.SET_REFERRAL_INFORMATION + } + ] + } + + const mocks = setupMocksForJsFiles(mockData); + + // Act + await saveOrder(); + + // Assert + expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.SAVE_ORDER); + expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.SET_REFERRAL_INFORMATION, { + referralNumber: mockReferralNumber, + referralDate: mockReferralDate, + referralCorrelationId: mockCorrelationId + }, false); + }); + + test("saveOrder => should update DidHeritageFunnelUpdateLast cookie value to false", async () => { + // Arrange + const testReferralNumber = 1566818; + const testReferralDate = "2022-03-15T10:56:24.597"; + const testReferralCorrelationId = "404d2b04-f86e-45c3-b373-127b6217b060"; + + const mockOrderInfo = getMockOrderInfo(testReferralNumber, testReferralCorrelationId, testReferralDate); + + const mockData = { + actionList: [{ + actionName: storeActions.SAVE_ORDER, + data: mockOrderInfo, + }], + router: router + }; + + setupMocksForJsFiles(mockData); + + const testCookieValue = { + ReferralNumber: testReferralNumber, + ReferralDate: testReferralDate, + ReferralCorrelationId: testReferralCorrelationId, + ShouldResetState: false, + DidHeritageFunnelUpdateLast: true + } + + setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) }); + + // Act + await saveOrder(); + + console.log(document.cookie) + console.log(cookieHelper.getConceptCookie) + console.log(cookieHelper.getConceptCookie()) + + // Assert + expect(cookieHelper.getConceptCookie().DidHeritageFunnelUpdateLast).toEqual(false); + }); +}); + +// document.cookie is not just a string, needs to be added individually +const cookies = { + [cookieNames.CONCEPT_SESSION_INFO]: `{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false,"DidHeritageFunnelUpdateLast":true}`, + "UNIQUE_SESSION_ID": "33756020-b58e-4ec7-b8b8-3f1576719c40", + "anotherCookie": "{}", + "someOtherCookie": "{}" + }; + +function removeAllTestCookies() { + Object.keys(cookies).forEach(key => { + document.cookie = `${key}=;Max-Age=0;`; + document.cookie = `${key}=;Max-Age=0;path=/`; + }); +} + +function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate) { + return { + referralNumber: mockReferralNumber, + referralCorrelationId: mockCorrelationId, + referralDate: mockReferralDate + } +} + +function setupCookies({ conceptCookieValue = "", includeHeritageCookie = true }) { + Object.keys(cookies).forEach(key => { + const cookieValue = key == cookieNames.CONCEPT_SESSION_INFO ? conceptCookieValue : cookies[key]; + + if (includeHeritageCookie || key != cookieNames.CONCEPT_SESSION_INFO) + document.cookie = `${key}=${cookieValue}; path=/;`; + }); + } \ No newline at end of file diff --git a/src/helpers/heritage-integration/session-helper.js b/src/helpers/heritage-integration/session-helper.js new file mode 100644 index 000000000..068c445eb --- /dev/null +++ b/src/helpers/heritage-integration/session-helper.js @@ -0,0 +1,52 @@ +import { applicationConfig } from "@/constants/application-config"; +import { getConceptCookie} from "@/helpers/heritage-integration/cookie-helper.js"; + +/* + Method to determine if our analytics session has timed out or not. + Amount used for timeout is configurable in application-config.js +*/ +export function isAnalyticsSessionStillActive() { + if (getConceptCookie() !== null) { + const lastTouchedValue = getConceptCookie().LastTouched; + const timeoutAmount = applicationConfig.ANALYTICS_SESSION_TIMEOUT; + const isMoreThanHalfHourAgo = ((new Date() - new Date(lastTouchedValue)) / 60000) > timeoutAmount; + + if (isMoreThanHalfHourAgo) { + return false; + } + + return true; + } +} + +/* + Method to determine if the users 'saved' session is still active. + When user state is created, there is a date that is saved into state + this method checks against that date. + + Note: That time for saved session timeout is configurable in application-config.js +*/ +export function isSavedSessionStillActive() { + if (getConceptCookie() !== null) { + const savedSessionTimeStamp = new Date(getConceptCookie().SavedQuoteTimeoutDate); + const isSavedSessionTimedOut = (new Date(new Date().toUTCString()) > savedSessionTimeStamp); + + console.log("Saved Session Timed Out? --->", isSavedSessionTimedOut); + + if (isSavedSessionTimedOut) { + return false; + } + + return true; + } +} + +/* +Function to get the date for the saved session timeout. +*/ + +export function getDateForSavedSessionTimeout() { + const currentDate = new Date(new Date().toUTCString()) + currentDate.setDate(currentDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT) + return currentDate.toUTCString(); +} \ No newline at end of file diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index ae6ba756e..93a3c9680 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -74,7 +74,7 @@ import { required } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; import { damageLocationsCms } from "@/constants/damage-locations-cms.js"; import { damageLocationsSelected } from "@/constants/damage-locations-selected.js"; -import { navigateToHeritageFunnel } from "@/helpers/heritage-integration-helper"; +import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; import store from "@/store"; import baseMixin from "@/mixins/base-mixin"; diff --git a/src/router/index.js b/src/router/index.js index 51e010980..eef9d4b23 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -4,7 +4,12 @@ import { storeActions } from "@/constants/store-actions"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { routingTable } from "@/router/router-constants/routing-table.js"; import { globalEvents, globalEventTypes } from "@/constants/events"; -import heritageIntegrationHelper from "@/helpers/heritage-integration-helper"; + +// Heritage integration +import { isSavedSessionStillActive } from "@/helpers/heritage-integration/session-helper"; +import { updateOrCreateConceptCookie,getConceptCookie } from "@/helpers/heritage-integration/cookie-helper"; +import { loadOrderIfPresent, saveOrder } from "@/helpers/heritage-integration/order-helper"; +import { getPageToRouteExistingOrderTo, navigateToHeritageFunnel} from "@/helpers/heritage-integration/navigation-helper"; import baseMixin from "@/mixins/base-mixin"; import eventBus from "@/helpers/event-bus/event-bus"; @@ -36,22 +41,22 @@ const routes = [ try { // If the saved session has timed out, clear the session, execute 404 logic. - if (!heritageIntegrationHelper.isSavedSessionStillActive()) { + if (!isSavedSessionStillActive()) { await GoToFunnelStartOn404(next); } // Process concept funnel cookie. - heritageIntegrationHelper.updateOrCreateConceptCookie(); + updateOrCreateConceptCookie(); // On entering the concept funnel "fresh", read cookie information, decide what to do next. if (from.redirectedFrom === undefined) { - const loadOrderResponse = await heritageIntegrationHelper.loadOrderIfPresent(); - const pageToRedirectTo = await heritageIntegrationHelper.getPageToRouteExistingOrderTo(to, loadOrderResponse); + const loadOrderResponse = await loadOrderIfPresent(); + const pageToRedirectTo = await getPageToRouteExistingOrderTo(to, loadOrderResponse); // If getPageToRouteExistingOrderTo determines that the return user needs to // go back to heritage funnel, send them there and stop our current navigation. if (pageToRedirectTo === 'heritage') { - await heritageIntegrationHelper.navigateToHeritageFunnel(); + await navigateToHeritageFunnel(); return next(false); } @@ -159,8 +164,8 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); // if cookie and referralNumber/Date exists - if (heritageIntegrationHelper.getConceptCookie()?.ReferralNumber && heritageIntegrationHelper.getConceptCookie()?.ReferralDate) { - await heritageIntegrationHelper.saveOrder(); + if (getConceptCookie()?.ReferralNumber && getConceptCookie()?.ReferralDate) { + await saveOrder(); } router.push({ diff --git a/src/store/index.js b/src/store/index.js index 5d2a0a422..26a0b31b6 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,7 +1,7 @@ import { createStore } from "vuex"; import { endpoints } from "@/constants/endpoints.js"; import { storeMutations } from "@/constants/store-mutations"; -import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration-helper"; +import { getDateForSavedSessionTimeout } from "@/helpers/heritage-integration/session-helper"; import createPersistedState from "vuex-persistedstate"; import globalMethods from "@/global-methods"; @@ -53,7 +53,7 @@ const getDefaultState = () => { applicationUser: { eventBus: [], pageData: {}, - // savedSessionTimeout: getDateForSavedSessionTimeout() TODO CSR-98 + savedSessionTimeout: getDateForSavedSessionTimeout() }, } }; From 7e51f4be9268cb703be4689d361c0cd768c76109 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 29 Mar 2022 09:21:17 -0400 Subject: [PATCH 31/58] common method refactor --- .../cookie-helper.spec.js | 26 +--------- .../navigation-helper.spec.js | 10 +--- .../heritage-integration/order-helper.spec.js | 34 +------------ src/helpers/unit-test-helper.js | 51 ++++++++++++++++--- 4 files changed, 46 insertions(+), 75 deletions(-) diff --git a/src/helpers/heritage-integration/cookie-helper.spec.js b/src/helpers/heritage-integration/cookie-helper.spec.js index 73b3bd9bc..a20af9300 100644 --- a/src/helpers/heritage-integration/cookie-helper.spec.js +++ b/src/helpers/heritage-integration/cookie-helper.spec.js @@ -1,5 +1,5 @@ import {getConceptCookie} from "@/helpers/heritage-integration/cookie-helper.js"; -import { cookieNames } from "@/constants/cookie-names"; +import { removeAllTestCookies, setupCookies } from "@/helpers/unit-test-helper"; describe("cookies", () => { @@ -101,28 +101,4 @@ describe("cookies", () => { }); }) }) - - // document.cookie is not just a string, needs to be added individually -const cookies = { - [cookieNames.CONCEPT_SESSION_INFO]: `{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false,"DidHeritageFunnelUpdateLast":true}`, - "UNIQUE_SESSION_ID": "33756020-b58e-4ec7-b8b8-3f1576719c40", - "anotherCookie": "{}", - "someOtherCookie": "{}" - }; - - function setupCookies({ conceptCookieValue = "", includeHeritageCookie = true }) { - Object.keys(cookies).forEach(key => { - const cookieValue = key == cookieNames.CONCEPT_SESSION_INFO ? conceptCookieValue : cookies[key]; - - if (includeHeritageCookie || key != cookieNames.CONCEPT_SESSION_INFO) - document.cookie = `${key}=${cookieValue}; path=/;`; - }); - } - - function removeAllTestCookies() { - Object.keys(cookies).forEach(key => { - document.cookie = `${key}=;Max-Age=0;`; - document.cookie = `${key}=;Max-Age=0;path=/`; - }); - } \ No newline at end of file diff --git a/src/helpers/heritage-integration/navigation-helper.spec.js b/src/helpers/heritage-integration/navigation-helper.spec.js index 2c586a76f..78f91162b 100644 --- a/src/helpers/heritage-integration/navigation-helper.spec.js +++ b/src/helpers/heritage-integration/navigation-helper.spec.js @@ -2,7 +2,7 @@ import { getPageToRouteExistingOrderTo, navigateToHeritageFunnel } from "@/helpe import * as orderHelper from "@/helpers/heritage-integration/order-helper"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; import { storeActions } from "@/constants/store-actions"; -import { setupMocksForJsFiles } from "@/helpers/unit-test-helper.js"; +import { setupMocksForJsFiles, getMockOrderInfo } from "@/helpers/unit-test-helper.js"; import { externalUrls } from "@/router/router-constants/externalUrl-values"; import store from "@/store"; @@ -300,11 +300,3 @@ describe("navigateToHeritageFunnel", () => { ); }); }); - -function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate) { - return { - referralNumber: mockReferralNumber, - referralCorrelationId: mockCorrelationId, - referralDate: mockReferralDate - } -} diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js index 1fa223466..1826b6da6 100644 --- a/src/helpers/heritage-integration/order-helper.spec.js +++ b/src/helpers/heritage-integration/order-helper.spec.js @@ -1,7 +1,7 @@ import * as cookieHelper from "@/helpers/heritage-integration/cookie-helper"; import { loadOrderIfPresent, saveOrder } from "@/helpers/heritage-integration/order-helper"; import { cookieNames } from "@/constants/cookie-names"; -import { setupMocksForJsFiles } from "@/helpers/unit-test-helper.js"; +import { setupMocksForJsFiles, removeAllTestCookies, getMockOrderInfo, setupCookies } from "@/helpers/unit-test-helper.js"; import { storeActions } from "@/constants/store-actions"; import router from "@/router"; @@ -153,35 +153,3 @@ describe("saveOrder", () => { expect(cookieHelper.getConceptCookie().DidHeritageFunnelUpdateLast).toEqual(false); }); }); - -// document.cookie is not just a string, needs to be added individually -const cookies = { - [cookieNames.CONCEPT_SESSION_INFO]: `{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false,"DidHeritageFunnelUpdateLast":true}`, - "UNIQUE_SESSION_ID": "33756020-b58e-4ec7-b8b8-3f1576719c40", - "anotherCookie": "{}", - "someOtherCookie": "{}" - }; - -function removeAllTestCookies() { - Object.keys(cookies).forEach(key => { - document.cookie = `${key}=;Max-Age=0;`; - document.cookie = `${key}=;Max-Age=0;path=/`; - }); -} - -function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate) { - return { - referralNumber: mockReferralNumber, - referralCorrelationId: mockCorrelationId, - referralDate: mockReferralDate - } -} - -function setupCookies({ conceptCookieValue = "", includeHeritageCookie = true }) { - Object.keys(cookies).forEach(key => { - const cookieValue = key == cookieNames.CONCEPT_SESSION_INFO ? conceptCookieValue : cookies[key]; - - if (includeHeritageCookie || key != cookieNames.CONCEPT_SESSION_INFO) - document.cookie = `${key}=${cookieValue}; path=/;`; - }); - } \ No newline at end of file diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 00fa5f675..699c4f8e9 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -3,15 +3,17 @@ import { storeMutations } from "@/constants/store-mutations.js"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios.js"; import { vehicleCategories } from "@/constants/vehicle-categories.js"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; +import { cookieNames } from "@/constants/cookie-names"; import baseMixin from "@/mixins/base-mixin"; +// Common methods export function getMountOptions(mockData) { // Define our mocks to attached to the 'global' object for Vue/Jest. const mocks = {}; //this is mocking if you use the mixin directly(baseMixin.methods.dispatchNonBlockingStoreAction) vs this.dispatchNonBlockingStoreAction setupBaseMixinDispatchNonBlockingStoreAction(mockData); - + mocks.dispatchNonBlockingStoreAction = jest.fn(); mocks.dispatchNonBlockingStoreAction.mockImplementation((actionName) => { let actionFilterResult = mockData.actionList.filter( @@ -44,6 +46,45 @@ export function getMountOptions(mockData) { return { global }; } +export function setupMocksForJsFiles(mockData = {}) { + setupBaseMixinDispatchNonBlockingStoreAction(mockData); + + return { baseMixin }; +} + +// Heritage integration common methods +export const cookies = { + [cookieNames.CONCEPT_SESSION_INFO]: `{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false,"DidHeritageFunnelUpdateLast":true}`, + "UNIQUE_SESSION_ID": "33756020-b58e-4ec7-b8b8-3f1576719c40", + "anotherCookie": "{}", + "someOtherCookie": "{}" +}; + +export function removeAllTestCookies() { + Object.keys(cookies).forEach(key => { + document.cookie = `${key}=;Max-Age=0;`; + document.cookie = `${key}=;Max-Age=0;path=/`; + }); +} + +export function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockReferralDate) { + return { + referralNumber: mockReferralNumber, + referralCorrelationId: mockCorrelationId, + referralDate: mockReferralDate + } +} + +export function setupCookies({ conceptCookieValue = "", includeHeritageCookie = true }) { + Object.keys(cookies).forEach(key => { + const cookieValue = key == cookieNames.CONCEPT_SESSION_INFO ? conceptCookieValue : cookies[key]; + + if (includeHeritageCookie || key != cookieNames.CONCEPT_SESSION_INFO) + document.cookie = `${key}=${cookieValue}; path=/;`; + }); +} + +// Private methods function setupBaseMixinDispatchNonBlockingStoreAction(mockData) { if (mockData.actionList !== undefined) { baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); @@ -51,7 +92,7 @@ function setupBaseMixinDispatchNonBlockingStoreAction(mockData) { let actionFilterResult = mockData.actionList.filter( (x) => x.actionName == actionName ); - + if (actionFilterResult.length > 0 && actionFilterResult.length === 1) { return Promise.resolve({ data: actionFilterResult[0].data, @@ -59,10 +100,4 @@ function setupBaseMixinDispatchNonBlockingStoreAction(mockData) { } }); } -} - -export function setupMocksForJsFiles(mockData = {}) { - setupBaseMixinDispatchNonBlockingStoreAction(mockData); - - return { baseMixin }; } \ No newline at end of file From 5da7037e4d74dff9f91810b3472cd398cc5439fa Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 29 Mar 2022 09:30:26 -0400 Subject: [PATCH 32/58] lint --- src/.eslintrc.js | 6 ++++++ src/common-components/vehicle-banner/vehicle-banner.spec.js | 2 +- .../replace-options-question.spec.js | 2 +- .../side-door-options/side-door-options.spec.js | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 src/.eslintrc.js diff --git a/src/.eslintrc.js b/src/.eslintrc.js new file mode 100644 index 000000000..309a0e4fd --- /dev/null +++ b/src/.eslintrc.js @@ -0,0 +1,6 @@ +module.exports = { + env: { + jest: true + }, +//... +} \ No newline at end of file diff --git a/src/common-components/vehicle-banner/vehicle-banner.spec.js b/src/common-components/vehicle-banner/vehicle-banner.spec.js index a6dc13154..210653df2 100644 --- a/src/common-components/vehicle-banner/vehicle-banner.spec.js +++ b/src/common-components/vehicle-banner/vehicle-banner.spec.js @@ -93,7 +93,7 @@ function setupMocks({ categoryValue = "CAR" }) { //Mock store - store.dispatch = jest.fn(() => dataFromStoreApi); + store.dispatch = jest.fn(() => {}); store.getters = { vehicle: { category: categoryValue, imageUrl: imageUrlValue } }; const mountOptions = getMountOptions({ store: { diff --git a/src/layouts/vehicle-damage/replace-options-question/replace-options-question.spec.js b/src/layouts/vehicle-damage/replace-options-question/replace-options-question.spec.js index a6ee43924..be3ef9485 100644 --- a/src/layouts/vehicle-damage/replace-options-question/replace-options-question.spec.js +++ b/src/layouts/vehicle-damage/replace-options-question/replace-options-question.spec.js @@ -3,7 +3,7 @@ import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-que import { getMountOptions } from "@/helpers/unit-test-helper.js"; import { nextTick } from "vue"; import store from "@/store"; -jest.mock("@/store", () => { return {}; }, {virtual: true}); +jest.mock("@/store",()=>{return{};},{virtual:true}); describe("replace-options-question.vue", () => { test("Selected damage option is emitted upon selection.", async () => { diff --git a/src/layouts/vehicle-damage/side-door-options/side-door-options.spec.js b/src/layouts/vehicle-damage/side-door-options/side-door-options.spec.js index 9c40a0683..29bbb68b5 100644 --- a/src/layouts/vehicle-damage/side-door-options/side-door-options.spec.js +++ b/src/layouts/vehicle-damage/side-door-options/side-door-options.spec.js @@ -3,7 +3,7 @@ import sideDoorOptions from "@/layouts/vehicle-damage/side-door-options/side-doo import { getMountOptions } from "@/helpers/unit-test-helper.js"; import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question"; import store from "@/store"; -jest.mock("@/store", () => { return {}; }, {virtual: true}); +jest.mock("@/store",()=>{return{};},{virtual:true}); describe("replace-options-question.vue", () => { test("Selected side door option is emitted upon selection.", async () => { @@ -95,7 +95,7 @@ describe("replace-options-question.vue", () => { }) { //Mock store - store.dispatch = jest.fn(() => dataFromStoreApi); + store.dispatch = jest.fn(() => {}); store.getters = { vehicle: {year: 2019, make: 'honda', model: 'civc', style: '2 Door', category: 'CAR'} }; const mountOptions = getMountOptions({ store: { From 4ee9a3fd06a62a01e8202431976c56ef22b43311 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 29 Mar 2022 10:16:52 -0400 Subject: [PATCH 33/58] session helper unit tests --- .../heritage-integration/order-helper.spec.js | 26 ++++++- .../session-helper.spec.js | 67 +++++++++++++++++++ 2 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 src/helpers/heritage-integration/session-helper.spec.js diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js index 1826b6da6..b17e9ec75 100644 --- a/src/helpers/heritage-integration/order-helper.spec.js +++ b/src/helpers/heritage-integration/order-helper.spec.js @@ -47,7 +47,7 @@ describe("loadOrderIfPresent", () => { expect(cookieHelper.getConceptCookie).toHaveBeenCalled(); expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.RESET_STATE); - cookieHelper.getConceptCookie.mockRestore(); + // store.dispatch.mockRestore(); }); @@ -69,8 +69,30 @@ describe("loadOrderIfPresent", () => { // Assert expect(cookieHelper.getConceptCookie).toHaveBeenCalled(); expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).not.toHaveBeenCalledWith(storeActions.RESET_STATE); + }); - cookieHelper.getConceptCookie.mockRestore(); + test("Concept cookie valid, should call loadOrder", async () => { + // Arrange + cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie") + .mockReturnValueOnce({ ShouldResetState: false, ReferralNumber: 123456, ReferralCorrelationId: "yyy-yyy-yyyy", ReferralDate: new Date()}); + + const mockData = { + actionList: [{ + actionName: storeActions.LOAD_ORDER, + data: { ReferralNumber: 123456, vehicle: { year: 2010 } } + }], + } + + var mocks = setupMocksForJsFiles(mockData); + + // Act + const result = await loadOrderIfPresent(); + + // Assert + expect(cookieHelper.getConceptCookie).toHaveBeenCalled(); + expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).not.toHaveBeenCalledWith(storeActions.LOAD_ORDER); + expect(result.ReferralNumber).toBe(123456); + expect(result.vehicle.year).toBe(2010); }); }); diff --git a/src/helpers/heritage-integration/session-helper.spec.js b/src/helpers/heritage-integration/session-helper.spec.js new file mode 100644 index 000000000..b75923ebe --- /dev/null +++ b/src/helpers/heritage-integration/session-helper.spec.js @@ -0,0 +1,67 @@ +import * as cookieHelper from "@/helpers/heritage-integration/cookie-helper"; +import { isAnalyticsSessionStillActive, isSavedSessionStillActive } from "@/helpers/heritage-integration/session-helper"; + +describe("isAnalyticsSessionStillActive", () => { + test("isAnalyticsSessionStillActive, should return true", () => { + // Arrange + const mockDate = new Date(new Date().toUTCString()) + mockDate.setDate(mockDate.getDate() + 1) + + cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie") + .mockReturnValue({ LastTouched: mockDate }); + + // Act + const result = isAnalyticsSessionStillActive(); + + // Assert + expect(result).toBe(true); + }); + + test("isAnalyticsSessionStillActive, should return false", () => { + // Arrange + const mockDate = new Date(new Date().toUTCString()) + mockDate.setDate(mockDate.getDate() - 1) + + cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie") + .mockReturnValue({ LastTouched: mockDate }); + + // Act + const result = isAnalyticsSessionStillActive(); + + // Assert + expect(result).toBe(false); + }); +}); + +describe("isSavedSessionStillActive", () => { + test("isSavedSessionStillActive, should return true", () => { + // Arrange + const mockDate = new Date(new Date().toUTCString()) + mockDate.setDate(mockDate.getDate() + 1); + + cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie") + .mockReturnValue({ SavedQuoteTimeoutDate: mockDate }); + + // Act + const result = isSavedSessionStillActive(); + + // Assert + expect(result).toBe(true); + }); + + test("isSavedSessionStillActive, should return false", () => { + // Arrange + const mockDate = new Date(new Date().toUTCString()) + mockDate.setDate(mockDate.getDate() + 65) + + cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie") + .mockReturnValue({ SavedQuoteTimeoutDate: mockDate }); + + // Act + const result = isSavedSessionStillActive(); + + // Assert + expect(result).toBe(false); + + }); +}); \ No newline at end of file From 32c63e6b63ea3e7ff97456802d65b6f495d06fa9 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 29 Mar 2022 11:21:50 -0400 Subject: [PATCH 34/58] more unit tests --- .../navigation-helper.spec.js | 68 ++++++++++++++ .../heritage-integration/session-helper.js | 2 +- .../session-helper.spec.js | 21 ++++- src/store/store.spec.js | 92 +++++++++++++++++++ 4 files changed, 179 insertions(+), 4 deletions(-) diff --git a/src/helpers/heritage-integration/navigation-helper.spec.js b/src/helpers/heritage-integration/navigation-helper.spec.js index 78f91162b..fd06920c2 100644 --- a/src/helpers/heritage-integration/navigation-helper.spec.js +++ b/src/helpers/heritage-integration/navigation-helper.spec.js @@ -4,6 +4,7 @@ import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js" import { storeActions } from "@/constants/store-actions"; import { setupMocksForJsFiles, getMockOrderInfo } from "@/helpers/unit-test-helper.js"; import { externalUrls } from "@/router/router-constants/externalUrl-values"; +import { queryStrings } from "@/constants/query-strings"; import store from "@/store"; import router from "@/router"; @@ -15,6 +16,58 @@ jest.mock("@/router/dynamic-routing/component-loader.js", () => ({ describe("getPageToRouteExistingOrderTo", () => { + test("getPageToRouteExistingOrderTo, should return vehicle-year", async () => { + // Arrange + const toRoute = { + query: {} + }; + + // Mock out the lazy load calls for all components. + lazyLoadComponent + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false) + } + } + } + }) + .mockReturnValueOnce(() => { + return { + default: { + methods: { + arePagePrerequisitesValid: jest.fn().mockReturnValueOnce(false) + } + } + } + }); + + // Act + const result = await getPageToRouteExistingOrderTo(toRoute, false); + + //Assert + expect(result).toBe('vehicle-year'); + }); + test("getPageToRouteExistingOrderTo, should return vehicle-model", async () => { // Arrange const toRoute = { @@ -232,6 +285,21 @@ describe("getPageToRouteExistingOrderTo", () => { //Assert expect(result).toBe('estimate'); }); + + test("getPageToRouteExistingOrderTo, existing order, should return heritage", async () => { + // Arrange + const toRoute = { + query: { + [queryStrings.START_TYPE]: 'fmg' + } + } + + // Act + const result = await getPageToRouteExistingOrderTo(toRoute, true); + + // Assert + expect(result).toBe("heritage"); + }) }); describe("navigateToHeritageFunnel", () => { diff --git a/src/helpers/heritage-integration/session-helper.js b/src/helpers/heritage-integration/session-helper.js index 068c445eb..49a0d8530 100644 --- a/src/helpers/heritage-integration/session-helper.js +++ b/src/helpers/heritage-integration/session-helper.js @@ -30,7 +30,7 @@ export function isSavedSessionStillActive() { if (getConceptCookie() !== null) { const savedSessionTimeStamp = new Date(getConceptCookie().SavedQuoteTimeoutDate); const isSavedSessionTimedOut = (new Date(new Date().toUTCString()) > savedSessionTimeStamp); - + console.log(savedSessionTimeStamp, isSavedSessionTimedOut); console.log("Saved Session Timed Out? --->", isSavedSessionTimedOut); if (isSavedSessionTimedOut) { diff --git a/src/helpers/heritage-integration/session-helper.spec.js b/src/helpers/heritage-integration/session-helper.spec.js index b75923ebe..1c974d508 100644 --- a/src/helpers/heritage-integration/session-helper.spec.js +++ b/src/helpers/heritage-integration/session-helper.spec.js @@ -1,5 +1,6 @@ import * as cookieHelper from "@/helpers/heritage-integration/cookie-helper"; -import { isAnalyticsSessionStillActive, isSavedSessionStillActive } from "@/helpers/heritage-integration/session-helper"; +import { isAnalyticsSessionStillActive, isSavedSessionStillActive, getDateForSavedSessionTimeout} from "@/helpers/heritage-integration/session-helper"; +import { applicationConfig } from "@/constants/application-config"; describe("isAnalyticsSessionStillActive", () => { test("isAnalyticsSessionStillActive, should return true", () => { @@ -52,7 +53,7 @@ describe("isSavedSessionStillActive", () => { test("isSavedSessionStillActive, should return false", () => { // Arrange const mockDate = new Date(new Date().toUTCString()) - mockDate.setDate(mockDate.getDate() + 65) + mockDate.setDate(mockDate.getDate() - 1) cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie") .mockReturnValue({ SavedQuoteTimeoutDate: mockDate }); @@ -64,4 +65,18 @@ describe("isSavedSessionStillActive", () => { expect(result).toBe(false); }); -}); \ No newline at end of file +}); + +describe("getDateForSavedSessionTimeout", () => { + test("getDateForSavedSessionTimeout, should equal application config setting", () =>{ + // Arrange + const currentDate = new Date(new Date().toUTCString()) + currentDate.setDate(currentDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT) + + // Act + const result = getDateForSavedSessionTimeout(); + + // Assert + expect(result).toEqual(currentDate.toUTCString()); + }); +}) \ No newline at end of file diff --git a/src/store/store.spec.js b/src/store/store.spec.js index a3f8a5cb5..b97ede119 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -200,6 +200,38 @@ describe("Mutations", () => { expect(storeState.applicationUser.pageData['vehicle-year']).toEqual({}); }); + it("setLoadOrderInformation, should set order information in state", () => { + // Arrange + const storeState = state; + + // Act + mutations.setLoadOrderInformation(storeState, { + referralNumber: 123, + referralDate: new Date().toUTCString(), + referralCorrelationId: "xxx-xxx-xxx", + vehicle: { + year: "2019", + make: "Acura", + model: "ILX", + style: "4 DOOR SEDAN", + carId: "C0000001", + category: "CAR" + }, + glassToReplace: ["Windshield"], + isRepair: false, + numberOfChips: 0, + parts: [], + parentAccountNumber: "123456789", + }); + + // Assert + expect(storeState.order.referralNumber).toEqual(123); + expect(storeState.order.referralCorrelationId).toEqual("xxx-xxx-xxx"); + expect(storeState.order.vehicle.year).toEqual("2019"); + expect(storeState.order.vehicle.make).toEqual("Acura"); + expect(storeState.order.vehicle.model).toEqual("ILX"); + }); + }); describe("Actions", () => { @@ -466,6 +498,66 @@ describe("Actions", () => { expect(response.data).toEqual({ imageUrl: "https://test.com" }); }); + it("saveOrder action, returns order information", async () => { + // Arrange + const context = state; + + context.getters = { + vehicle: {}, + damage: {}, + }; + context.state = { + order: {} + }; + + globalMethods.callHttpClient.mockImplementation(() => { + return Promise.resolve({ data: { referralNumber: 123 } }); + }); + + // Act + const response = await actions.saveOrder(context); + + // Assert + expect(response.data).toEqual({ referralNumber: 123 }); + }); + + + it("loadOrder action, returns order information, calls mutation", async () => { + // Arrange + const context = state; + + globalMethods.callHttpClient.mockImplementation(() => { + return Promise.resolve({ data: { referralNumber: 123 } }); + }); + + const commit = jest.fn(); + + context.commit = commit; + + // Act + const response = await actions.loadOrder(context, {referralNumber: "123", referralDate: new Date().toUTCString(), referralCorrelationId: "xxx-xxx-xxx"}); + + // Assert + expect(response.data).toEqual({ referralNumber: 123 }); + expect(commit).toBeCalledWith(storeMutations.SET_LOAD_CONCEPT_SESSION_INFO, {"referralNumber": 123}); + }); + + it("setReferralInformation, should call commit three times", () => { + // Arrange + const context = state; + const commit = jest.fn(); + + context.commit = commit; + + // Act + actions.setReferralInformation(context, {referralNumber: "123", referralDate: new Date().toUTCString(), referralCorrelationId: "xxx-xxx-xxx"}); + + // Assert + expect(commit).toBeCalledWith(storeMutations.UPDATE_REFERRAL_NUMBER, "123"); + expect(commit).toBeCalledWith(storeMutations.UPDATE_REFERRAL_DATE, new Date().toUTCString()); + expect(commit).toBeCalledWith(storeMutations.UPDATE_REFERRAL_CORRELATION_ID, "xxx-xxx-xxx"); + }); + }); describe("Getters", () => { From a04c482ecd1c51569035403bdf2ff492109c522f Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 29 Mar 2022 11:48:57 -0400 Subject: [PATCH 35/58] CSR-98 Remove test logs and experiment strings --- src/helpers/heritage-integration/navigation-helper.js | 3 --- src/helpers/heritage-integration/order-helper.spec.js | 6 +----- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 2195ce66c..0aad13e50 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -69,9 +69,6 @@ export async function navigateToHeritageFunnel() { { corid: store.getters.order.referralCorrelationId, src: "concept-funnel", - // TODO CSR-28, remove this - cns: "all", - experiments: "RemoveServiceAreaPage=ServAreaRemoval_V7=ServAreaNoRemove_V7_TEST=true,ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" } ); } \ No newline at end of file diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js index 1826b6da6..37eb48687 100644 --- a/src/helpers/heritage-integration/order-helper.spec.js +++ b/src/helpers/heritage-integration/order-helper.spec.js @@ -144,11 +144,7 @@ describe("saveOrder", () => { // Act await saveOrder(); - - console.log(document.cookie) - console.log(cookieHelper.getConceptCookie) - console.log(cookieHelper.getConceptCookie()) - + // Assert expect(cookieHelper.getConceptCookie().DidHeritageFunnelUpdateLast).toEqual(false); }); From 3f09ccc022cb76179088397aed01b53f8756a012 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 29 Mar 2022 11:54:02 -0400 Subject: [PATCH 36/58] New variable --- azure-pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ba2e359dc..e58f51862 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -78,4 +78,5 @@ stages: appDeployVariables: __VUE_APP_CONSUMER_API_GATEWAY__: $(__VUE_APP_CONSUMER_API_GATEWAY__) __VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__) + __VUE_APP_HERITAGE_FUNNEL__: $(__VUE_APP_HERITAGE_FUNNEL__) cfDistributionId: $(cfDistributionId) \ No newline at end of file From 87820950aeece2a875cab94e777c832d43bc9bd5 Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 29 Mar 2022 11:58:54 -0400 Subject: [PATCH 37/58] CSR-98 Remove commented code --- src/helpers/heritage-integration/navigation-helper.js | 2 -- src/helpers/heritage-integration/order-helper.js | 1 - src/helpers/heritage-integration/order-helper.spec.js | 3 +-- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 0aad13e50..20a4315bf 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -60,8 +60,6 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita export async function navigateToHeritageFunnel() { // Create the order (or save existing order) when navigating to Heritage Funnel. - // console.log(exports) - // await self.saveOrder(); await saveOrder(); router.navigateToExternalUrl( diff --git a/src/helpers/heritage-integration/order-helper.js b/src/helpers/heritage-integration/order-helper.js index 8d8fe01d4..cf8a45d16 100644 --- a/src/helpers/heritage-integration/order-helper.js +++ b/src/helpers/heritage-integration/order-helper.js @@ -10,7 +10,6 @@ import baseMixin from "@/mixins/base-mixin"; */ export async function loadOrderIfPresent() { console.log("attempting to load referral...."); - // const conceptCookie = self.getConceptCookie(); const conceptCookie = getConceptCookie(); console.log(conceptCookie) diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js index 37eb48687..473e6c842 100644 --- a/src/helpers/heritage-integration/order-helper.spec.js +++ b/src/helpers/heritage-integration/order-helper.spec.js @@ -48,7 +48,6 @@ describe("loadOrderIfPresent", () => { expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.RESET_STATE); cookieHelper.getConceptCookie.mockRestore(); - // store.dispatch.mockRestore(); }); test("Concept cookie is null => store is unchanged", () => { @@ -144,7 +143,7 @@ describe("saveOrder", () => { // Act await saveOrder(); - + // Assert expect(cookieHelper.getConceptCookie().DidHeritageFunnelUpdateLast).toEqual(false); }); From 9f49aafb7b8752379cc881d62acbfd9de40d4437 Mon Sep 17 00:00:00 2001 From: Katie Date: Tue, 29 Mar 2022 12:09:28 -0400 Subject: [PATCH 38/58] CSR-98 Remove mockRestore() --- src/helpers/heritage-integration/order-helper.spec.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js index 4a24c0573..fd0507bbb 100644 --- a/src/helpers/heritage-integration/order-helper.spec.js +++ b/src/helpers/heritage-integration/order-helper.spec.js @@ -46,8 +46,6 @@ describe("loadOrderIfPresent", () => { // Assert expect(cookieHelper.getConceptCookie).toHaveBeenCalled(); expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.RESET_STATE); - - cookieHelper.getConceptCookie.mockRestore(); }); test("Concept cookie is null => store is unchanged", () => { From b6b5b6696e2c406364ec134a76527d6b2e8935e3 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 29 Mar 2022 13:56:44 -0400 Subject: [PATCH 39/58] Temporary until estimate and vin pages exist --- src/helpers/heritage-integration/navigation-helper.js | 6 ++++-- src/helpers/heritage-integration/navigation-helper.spec.js | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 0aad13e50..9369fc7ac 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -45,9 +45,11 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita return 'vehicle-damage' } else { if (store.getters.vehicle.vin) { - return "vin-lookup"; + return 'vehicle-damage'; + //return "vin-lookup"; (uncomment) } else { - return "estimate" + return 'vehicle-damage'; + //return "estimate" (uncomment) } } diff --git a/src/helpers/heritage-integration/navigation-helper.spec.js b/src/helpers/heritage-integration/navigation-helper.spec.js index fd06920c2..be1136e63 100644 --- a/src/helpers/heritage-integration/navigation-helper.spec.js +++ b/src/helpers/heritage-integration/navigation-helper.spec.js @@ -228,7 +228,8 @@ describe("getPageToRouteExistingOrderTo", () => { const result = await getPageToRouteExistingOrderTo(toRoute, false); //Assert - expect(result).toBe('vin-lookup'); + //expect(result).toBe('vin-lookup'); + expect(result).toBe('vehicle-damage'); }); test("getPageToRouteExistingOrderTo, should return estimate", async () => { @@ -283,7 +284,8 @@ describe("getPageToRouteExistingOrderTo", () => { const result = await getPageToRouteExistingOrderTo(toRoute, false); //Assert - expect(result).toBe('estimate'); + //expect(result).toBe('estimate'); + expect(result).toBe('vehicle-damage'); }); test("getPageToRouteExistingOrderTo, existing order, should return heritage", async () => { From a1c5150039f312c58b497d957acc974c0b9881d4 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Tue, 29 Mar 2022 16:21:48 -0400 Subject: [PATCH 40/58] rename concept to funnel --- src/constants/application-config.js | 4 +-- src/constants/cookie-names.js | 2 +- src/constants/store-mutations.js | 2 +- .../heritage-integration/cookie-helper.js | 36 +++++++------------ .../cookie-helper.spec.js | 26 +++++++------- .../heritage-integration/navigation-helper.js | 4 +-- .../heritage-integration/order-helper.js | 22 ++++-------- .../heritage-integration/order-helper.spec.js | 22 ++++++------ .../heritage-integration/session-helper.js | 16 ++++----- .../session-helper.spec.js | 10 +++--- src/helpers/unit-test-helper.js | 8 ++--- src/router/index.js | 12 +++---- src/store/index.js | 2 +- src/store/store.spec.js | 2 +- 14 files changed, 72 insertions(+), 96 deletions(-) diff --git a/src/constants/application-config.js b/src/constants/application-config.js index d427b1d72..f2aff2951 100644 --- a/src/constants/application-config.js +++ b/src/constants/application-config.js @@ -1,8 +1,8 @@ const applicationConfig = { CONSUMER_APIGATEWAY_URL: process.env.VUE_APP_CONSUMER_API_GATEWAY, GOOGLE_PLACES_API_KEY: process.env.VUE_APP_GOOGLE_PLACES_API_KEY, - ANALYTICS_SESSION_TIMEOUT: 30, - SAVED_SESSION_TIMEOUT: 45 + ANALYTICS_SESSION_TIMEOUT_MINUTES: 30, + SAVED_SESSION_TIMEOUT_DAYS: 45 }; diff --git a/src/constants/cookie-names.js b/src/constants/cookie-names.js index 6b1e3c909..2756a8eb7 100644 --- a/src/constants/cookie-names.js +++ b/src/constants/cookie-names.js @@ -1,5 +1,5 @@ const cookieNames = { - CONCEPT_SESSION_INFO: "ConceptSessionInfo", + FUNNEL_SESSION_INFO: "FunnelSessionInfo", }; export { cookieNames }; diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 00ac66d58..8b59bacb0 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -34,7 +34,7 @@ const storeMutations = { // OTHER MUTATIONS UPDATE_PAGE_DATA: "updatePageData", - SET_LOAD_CONCEPT_SESSION_INFO: "setLoadOrderInformation" + SET_LOAD_FUNNEL_SESSION_INFO: "setLoadOrderInformation" }; diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index 9de5d5760..096d03a04 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -5,22 +5,12 @@ import store from "@/store"; /* Will update the cookie if present, or create a new one if not. */ -export function updateOrCreateConceptCookie() { - console.log("Updating cookie...", { - LastTouched: new Date().toUTCString(), - SavedQuoteTimeoutDate: store.getters.applicationUser.savedSessionTimeout, - DidHeritageFunnelUpdateLast: false, - ShouldResetState: false, - ReferralNumber: store.getters.order.referralNumber, - ReferralDate: store.getters.order.referralDate, - ReferralCorrelationId: store.getters.order.referralCorrelationId, - }); - +export function updateOrCreateFunnelCookie() { // Create the cookie - document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}={}; path=/`; + document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}={}; path=/`; // Set up cookie with all the props. - setConceptCookieProperties({ + setFunnelCookieProperties({ LastTouched: new Date().toUTCString(), SavedQuoteTimeoutDate: store.getters.applicationUser.savedSessionTimeout, DidHeritageFunnelUpdateLast: false, @@ -33,13 +23,13 @@ export function updateOrCreateConceptCookie() { } /* - Gets the current instance of the concept funnel cookie. + Gets the current instance of the funnel cookie. Returns null if cookie isn't valid JSON. */ -export function getConceptCookie() { +export function getFunnelCookie() { const cookieJson = document.cookie ?.split("; ") - ?.find(row => row.startsWith(`${cookieNames.CONCEPT_SESSION_INFO}=`)) + ?.find(row => row.startsWith(`${cookieNames.FUNNEL_SESSION_INFO}=`)) ?.split("=")[1]; try { @@ -50,19 +40,19 @@ export function getConceptCookie() { } /* - Removes concept cookie from browser. + Removes cookie from browser. */ -export function deleteConceptCookie() { - document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; +export function deleteFunnelCookie() { + document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; } /* - Used to set properties on the concept funnel cookie. + Used to set properties on the funnel cookie. Takes an object with properties to set. Will overwrite existing properties. */ -function setConceptCookieProperties(properties) { +function setFunnelCookieProperties(properties) { if (typeof properties == "object") { - let cookie = getConceptCookie(); + let cookie = getFunnelCookie(); if (cookie !== null) { Object.keys(properties).forEach(key => { @@ -71,7 +61,7 @@ function setConceptCookieProperties(properties) { const cookieValueJson = JSON.stringify(cookie); - document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=${cookieValueJson}; path=/`; + document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}=${cookieValueJson}; path=/`; } } } diff --git a/src/helpers/heritage-integration/cookie-helper.spec.js b/src/helpers/heritage-integration/cookie-helper.spec.js index a20af9300..9d14389e2 100644 --- a/src/helpers/heritage-integration/cookie-helper.spec.js +++ b/src/helpers/heritage-integration/cookie-helper.spec.js @@ -1,4 +1,4 @@ -import {getConceptCookie} from "@/helpers/heritage-integration/cookie-helper.js"; +import {getFunnelCookie} from "@/helpers/heritage-integration/cookie-helper.js"; import { removeAllTestCookies, setupCookies } from "@/helpers/unit-test-helper"; describe("cookies", () => { @@ -7,7 +7,7 @@ describe("cookies", () => { removeAllTestCookies(); }) - describe("getConceptCookie method", () => { + describe("getFunnelCookie method", () => { test("gets correct value when cookie is present", () => { // Arrange const testReferralNumber = 1566818; @@ -24,10 +24,10 @@ describe("cookies", () => { DidHeritageFunnelUpdateLast: testDidHeritageFunnelUpdateLast } - setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) }); + setupCookies({ funnelCookieValue: JSON.stringify(testCookieValue) }); // Act - var result = getConceptCookie(); + var result = getFunnelCookie(); // Assert expect(result).toEqual(testCookieValue); @@ -42,10 +42,10 @@ describe("cookies", () => { test("returns empty object when value is empty object", () => { // Arrange const testCookieValue = {}; - setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) }); + setupCookies({ funnelCookieValue: JSON.stringify(testCookieValue) }); // Act - var result = getConceptCookie(); + var result = getFunnelCookie(); // Assert expect(result).toEqual(testCookieValue); @@ -56,21 +56,21 @@ describe("cookies", () => { test("returns null when value is empty string", () => { // Arrange const testCookieValue = ""; - setupCookies({ conceptCookieValue: testCookieValue }); + setupCookies({ funnelCookieValue: testCookieValue }); // Act - var result = getConceptCookie(); + var result = getFunnelCookie(); // Assert expect(result).toEqual(null); }); - test("returns null when concept cookie doesn't exist", () => { + test("returns null when funnel cookie doesn't exist", () => { // Arrange setupCookies({ includeHeritageCookie: false }); // Act - var result = getConceptCookie(); + var result = getFunnelCookie(); // Assert expect(result).toEqual(null); @@ -80,10 +80,10 @@ describe("cookies", () => { // Arrange const testCookieValue = { test: "testValue" }; - setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) }); + setupCookies({ funnelCookieValue: JSON.stringify(testCookieValue) }); // Act - const actualCookieValue = getConceptCookie(); + const actualCookieValue = getFunnelCookie(); // Assert expect(actualCookieValue).toEqual(testCookieValue); @@ -94,7 +94,7 @@ describe("cookies", () => { setupCookies({ includeHeritageCookie: false }); // Act - const actualCookieValue = getConceptCookie(); + const actualCookieValue = getFunnelCookie(); // Assert expect(actualCookieValue).toBeNull(); diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 6207351dc..19e036561 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -6,7 +6,7 @@ import store from "@/store"; import router from "@/router"; /* - If the user has visited the concept funnel before this method will determine the bets place to + If the user has visited the funnel before this method will determine the bets place to drop them so they don't start at the beginning again. This method will return 'heritage' if the user has an existing order and they come back in from the Safelite.com CTA. */ @@ -14,11 +14,9 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita // If the user is coming in via the Safelite.Com CTA if (toRoute.query[queryStrings.START_TYPE] === 'fmg') { - console.log("Start type is FMG... trying to figure out where to send them..."); // If they have an existing order, return 'heritage' for the page name. if (existingHeritageOrder) { - console.log("Existing heritage order found, returning 'heritage' for page redirect..."); return 'heritage'; } } diff --git a/src/helpers/heritage-integration/order-helper.js b/src/helpers/heritage-integration/order-helper.js index cf8a45d16..aaf0db740 100644 --- a/src/helpers/heritage-integration/order-helper.js +++ b/src/helpers/heritage-integration/order-helper.js @@ -1,5 +1,5 @@ import { storeActions } from "@/constants/store-actions.js"; -import { getConceptCookie, updateOrCreateConceptCookie, deleteConceptCookie } from "@/helpers/heritage-integration/cookie-helper.js"; +import { getFunnelCookie, updateOrCreateFunnelCookie, deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper.js"; import baseMixin from "@/mixins/base-mixin"; /* @@ -9,29 +9,23 @@ import baseMixin from "@/mixins/base-mixin"; */ export async function loadOrderIfPresent() { - console.log("attempting to load referral...."); - const conceptCookie = getConceptCookie(); - - console.log(conceptCookie) + const funnelCookie = getFunnelCookie(); // Do nothing if there is no cookie or no correlation id. - if (conceptCookie == null || conceptCookie.ReferralCorrelationId == null) { - console.log("No referral found"); + if (funnelCookie == null || funnelCookie.ReferralCorrelationId == null) { return null; } // Reset state if cookie says to. - if (conceptCookie.ShouldResetState) { - console.log("Resetting state..."); + if (funnelCookie.ShouldResetState) { baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); - deleteConceptCookie(); + deleteFunnelCookie(); return null; } - console.log("calling load order from loadOrderIfPresent()..."); // Load referral if there is a cookie, and it doesn't indicate it needs a state reset. - return (await loadOrder(conceptCookie.ReferralNumber, conceptCookie.ReferralDate, conceptCookie.ReferralCorrelationId)).data; + return (await loadOrder(funnelCookie.ReferralNumber, funnelCookie.ReferralDate, funnelCookie.ReferralCorrelationId)).data; } /* @@ -40,7 +34,6 @@ export async function loadOrderIfPresent() { update the cookie. */ export async function saveOrder() { - console.log("saving order..."); const savedOrderInfo = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.SAVE_ORDER); // Save the referral information back from the store. @@ -51,7 +44,7 @@ export async function saveOrder() { }, false); // Update the cookie with the referral information when saved. - updateOrCreateConceptCookie(); + updateOrCreateFunnelCookie(); } @@ -62,7 +55,6 @@ export async function saveOrder() { and returns the response. */ async function loadOrder(referralNumber, referralDate, referralCorrelationId) { - console.log("loading order...", referralNumber, referralDate, referralCorrelationId); const response = await baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.LOAD_ORDER, { referralNumber: referralNumber.toString(), diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js index fd0507bbb..2e68867e9 100644 --- a/src/helpers/heritage-integration/order-helper.spec.js +++ b/src/helpers/heritage-integration/order-helper.spec.js @@ -11,7 +11,7 @@ describe("loadOrderIfPresent", () => { removeAllTestCookies(); }); - test("ShouldResetState == true => concept cookie is deleted", () => { + test("ShouldResetState == true => funnel cookie is deleted", () => { // Arrange const testShouldResetState = true; @@ -30,7 +30,7 @@ describe("loadOrderIfPresent", () => { test("ShouldResetState == true => reset store", () => { // Arrange - cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie").mockReturnValueOnce({ ShouldResetState: true, ReferralCorrelationId: "xxx-xxx-xxx" }); + cookieHelper.getFunnelCookie = jest.spyOn(cookieHelper, "getFunnelCookie").mockReturnValueOnce({ ShouldResetState: true, ReferralCorrelationId: "xxx-xxx-xxx" }); const mockData = { actionList: [{ @@ -44,13 +44,13 @@ describe("loadOrderIfPresent", () => { loadOrderIfPresent(); // Assert - expect(cookieHelper.getConceptCookie).toHaveBeenCalled(); + expect(cookieHelper.getFunnelCookie).toHaveBeenCalled(); expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).toHaveBeenCalledWith(storeActions.RESET_STATE); }); - test("Concept cookie is null => store is unchanged", () => { + test("Funnel cookie is null => store is unchanged", () => { // Arrange - cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie").mockReturnValueOnce(null); + cookieHelper.getFunnelCookie = jest.spyOn(cookieHelper, "getFunnelCookie").mockReturnValueOnce(null); const mockData = { actionList: [{ @@ -64,13 +64,13 @@ describe("loadOrderIfPresent", () => { loadOrderIfPresent(); // Assert - expect(cookieHelper.getConceptCookie).toHaveBeenCalled(); + expect(cookieHelper.getFunnelCookie).toHaveBeenCalled(); expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).not.toHaveBeenCalledWith(storeActions.RESET_STATE); }); - test("Concept cookie valid, should call loadOrder", async () => { + test("Funnel cookie valid, should call loadOrder", async () => { // Arrange - cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie") + cookieHelper.getFunnelCookie = jest.spyOn(cookieHelper, "getFunnelCookie") .mockReturnValueOnce({ ShouldResetState: false, ReferralNumber: 123456, ReferralCorrelationId: "yyy-yyy-yyyy", ReferralDate: new Date()}); const mockData = { @@ -86,7 +86,7 @@ describe("loadOrderIfPresent", () => { const result = await loadOrderIfPresent(); // Assert - expect(cookieHelper.getConceptCookie).toHaveBeenCalled(); + expect(cookieHelper.getFunnelCookie).toHaveBeenCalled(); expect(mocks.baseMixin.methods.dispatchNonBlockingStoreAction).not.toHaveBeenCalledWith(storeActions.LOAD_ORDER); expect(result.ReferralNumber).toBe(123456); expect(result.vehicle.year).toBe(2010); @@ -159,12 +159,12 @@ describe("saveOrder", () => { DidHeritageFunnelUpdateLast: true } - setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) }); + setupCookies({ funnelCookieValue: JSON.stringify(testCookieValue) }); // Act await saveOrder(); // Assert - expect(cookieHelper.getConceptCookie().DidHeritageFunnelUpdateLast).toEqual(false); + expect(cookieHelper.getFunnelCookie().DidHeritageFunnelUpdateLast).toEqual(false); }); }); diff --git a/src/helpers/heritage-integration/session-helper.js b/src/helpers/heritage-integration/session-helper.js index 49a0d8530..ba816cdb1 100644 --- a/src/helpers/heritage-integration/session-helper.js +++ b/src/helpers/heritage-integration/session-helper.js @@ -1,14 +1,14 @@ import { applicationConfig } from "@/constants/application-config"; -import { getConceptCookie} from "@/helpers/heritage-integration/cookie-helper.js"; +import { getFunnelCookie} from "@/helpers/heritage-integration/cookie-helper.js"; /* Method to determine if our analytics session has timed out or not. Amount used for timeout is configurable in application-config.js */ export function isAnalyticsSessionStillActive() { - if (getConceptCookie() !== null) { - const lastTouchedValue = getConceptCookie().LastTouched; - const timeoutAmount = applicationConfig.ANALYTICS_SESSION_TIMEOUT; + if (getFunnelCookie() !== null) { + const lastTouchedValue = getFunnelCookie().LastTouched; + const timeoutAmount = applicationConfig.ANALYTICS_SESSION_TIMEOUT_MINUTES; const isMoreThanHalfHourAgo = ((new Date() - new Date(lastTouchedValue)) / 60000) > timeoutAmount; if (isMoreThanHalfHourAgo) { @@ -27,11 +27,9 @@ export function isAnalyticsSessionStillActive() { Note: That time for saved session timeout is configurable in application-config.js */ export function isSavedSessionStillActive() { - if (getConceptCookie() !== null) { - const savedSessionTimeStamp = new Date(getConceptCookie().SavedQuoteTimeoutDate); + if (getFunnelCookie() !== null) { + const savedSessionTimeStamp = new Date(getFunnelCookie().SavedQuoteTimeoutDate); const isSavedSessionTimedOut = (new Date(new Date().toUTCString()) > savedSessionTimeStamp); - console.log(savedSessionTimeStamp, isSavedSessionTimedOut); - console.log("Saved Session Timed Out? --->", isSavedSessionTimedOut); if (isSavedSessionTimedOut) { return false; @@ -47,6 +45,6 @@ Function to get the date for the saved session timeout. export function getDateForSavedSessionTimeout() { const currentDate = new Date(new Date().toUTCString()) - currentDate.setDate(currentDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT) + currentDate.setDate(currentDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT_DAYS) return currentDate.toUTCString(); } \ No newline at end of file diff --git a/src/helpers/heritage-integration/session-helper.spec.js b/src/helpers/heritage-integration/session-helper.spec.js index 1c974d508..8a17743d1 100644 --- a/src/helpers/heritage-integration/session-helper.spec.js +++ b/src/helpers/heritage-integration/session-helper.spec.js @@ -8,7 +8,7 @@ describe("isAnalyticsSessionStillActive", () => { const mockDate = new Date(new Date().toUTCString()) mockDate.setDate(mockDate.getDate() + 1) - cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie") + cookieHelper.getFunnelCookie = jest.spyOn(cookieHelper, "getFunnelCookie") .mockReturnValue({ LastTouched: mockDate }); // Act @@ -23,7 +23,7 @@ describe("isAnalyticsSessionStillActive", () => { const mockDate = new Date(new Date().toUTCString()) mockDate.setDate(mockDate.getDate() - 1) - cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie") + cookieHelper.getFunnelCookie = jest.spyOn(cookieHelper, "getFunnelCookie") .mockReturnValue({ LastTouched: mockDate }); // Act @@ -40,7 +40,7 @@ describe("isSavedSessionStillActive", () => { const mockDate = new Date(new Date().toUTCString()) mockDate.setDate(mockDate.getDate() + 1); - cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie") + cookieHelper.getFunnelCookie = jest.spyOn(cookieHelper, "getFunnelCookie") .mockReturnValue({ SavedQuoteTimeoutDate: mockDate }); // Act @@ -55,7 +55,7 @@ describe("isSavedSessionStillActive", () => { const mockDate = new Date(new Date().toUTCString()) mockDate.setDate(mockDate.getDate() - 1) - cookieHelper.getConceptCookie = jest.spyOn(cookieHelper, "getConceptCookie") + cookieHelper.getFunnelCookie = jest.spyOn(cookieHelper, "getFunnelCookie") .mockReturnValue({ SavedQuoteTimeoutDate: mockDate }); // Act @@ -71,7 +71,7 @@ describe("getDateForSavedSessionTimeout", () => { test("getDateForSavedSessionTimeout, should equal application config setting", () =>{ // Arrange const currentDate = new Date(new Date().toUTCString()) - currentDate.setDate(currentDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT) + currentDate.setDate(currentDate.getDate() + applicationConfig.SAVED_SESSION_TIMEOUT_DAYS) // Act const result = getDateForSavedSessionTimeout(); diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 699c4f8e9..62fcc4ae4 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -54,7 +54,7 @@ export function setupMocksForJsFiles(mockData = {}) { // Heritage integration common methods export const cookies = { - [cookieNames.CONCEPT_SESSION_INFO]: `{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false,"DidHeritageFunnelUpdateLast":true}`, + [cookieNames.FUNNEL_SESSION_INFO]: `{"ReferralNumber":"1566818","ReferralDate":"2022-03-15T10:56:24.597","ReferralCorrelationId":"404d2b04-f86e-45c3-b373-127b6217b060","ShouldResetState":false,"DidHeritageFunnelUpdateLast":true}`, "UNIQUE_SESSION_ID": "33756020-b58e-4ec7-b8b8-3f1576719c40", "anotherCookie": "{}", "someOtherCookie": "{}" @@ -75,11 +75,11 @@ export function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockRefe } } -export function setupCookies({ conceptCookieValue = "", includeHeritageCookie = true }) { +export function setupCookies({ funnelCookieValue = "", includeHeritageCookie = true }) { Object.keys(cookies).forEach(key => { - const cookieValue = key == cookieNames.CONCEPT_SESSION_INFO ? conceptCookieValue : cookies[key]; + const cookieValue = key == cookieNames.FUNNEL_SESSION_INFO ? funnelCookieValue : cookies[key]; - if (includeHeritageCookie || key != cookieNames.CONCEPT_SESSION_INFO) + if (includeHeritageCookie || key != cookieNames.FUNNEL_SESSION_INFO) document.cookie = `${key}=${cookieValue}; path=/;`; }); } diff --git a/src/router/index.js b/src/router/index.js index eef9d4b23..bbb58e725 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -7,7 +7,7 @@ import { globalEvents, globalEventTypes } from "@/constants/events"; // Heritage integration import { isSavedSessionStillActive } from "@/helpers/heritage-integration/session-helper"; -import { updateOrCreateConceptCookie,getConceptCookie } from "@/helpers/heritage-integration/cookie-helper"; +import { updateOrCreateFunnelCookie,getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper"; import { loadOrderIfPresent, saveOrder } from "@/helpers/heritage-integration/order-helper"; import { getPageToRouteExistingOrderTo, navigateToHeritageFunnel} from "@/helpers/heritage-integration/navigation-helper"; @@ -45,10 +45,10 @@ const routes = [ await GoToFunnelStartOn404(next); } - // Process concept funnel cookie. - updateOrCreateConceptCookie(); + // Process funnel cookie. + updateOrCreateFunnelCookie(); - // On entering the concept funnel "fresh", read cookie information, decide what to do next. + // On entering the funnel "fresh", read cookie information, decide what to do next. if (from.redirectedFrom === undefined) { const loadOrderResponse = await loadOrderIfPresent(); const pageToRedirectTo = await getPageToRouteExistingOrderTo(to, loadOrderResponse); @@ -62,8 +62,6 @@ const routes = [ // Assign our fmgPage so it will load normally like the other pages. to.query.fmgPage = pageToRedirectTo; - - console.log("Page to redirect to: ", pageToRedirectTo); } // If we already have our route, go to it. @@ -164,7 +162,7 @@ async function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery baseMixin.methods.savePageDataToStore(destinationFmgPageValue, optionalPageData); // if cookie and referralNumber/Date exists - if (getConceptCookie()?.ReferralNumber && getConceptCookie()?.ReferralDate) { + if (getFunnelCookie()?.ReferralNumber && getFunnelCookie()?.ReferralDate) { await saveOrder(); } diff --git a/src/store/index.js b/src/store/index.js index 26a0b31b6..5f08cf0ba 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -391,7 +391,7 @@ export const actions = { referralCorrelationId: referralCorrelationId }, }).then((response) => { - context.commit(storeMutations.SET_LOAD_CONCEPT_SESSION_INFO, response.data); + context.commit(storeMutations.SET_LOAD_FUNNEL_SESSION_INFO, response.data); return response; }); } diff --git a/src/store/store.spec.js b/src/store/store.spec.js index b97ede119..c8fe2476b 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -539,7 +539,7 @@ describe("Actions", () => { // Assert expect(response.data).toEqual({ referralNumber: 123 }); - expect(commit).toBeCalledWith(storeMutations.SET_LOAD_CONCEPT_SESSION_INFO, {"referralNumber": 123}); + expect(commit).toBeCalledWith(storeMutations.SET_LOAD_FUNNEL_SESSION_INFO, {"referralNumber": 123}); }); it("setReferralInformation, should call commit three times", () => { From 5de5f2d17c03ff2913d2f3f184b5a173f0c27266 Mon Sep 17 00:00:00 2001 From: bmauger Date: Tue, 29 Mar 2022 16:28:58 -0400 Subject: [PATCH 41/58] CSR-269 fix rounded border, error border color and size, alert position, container padding --- .../funnel-header/funnel-header.vue | 3 +++ src/layouts/vehicle-damage/vehicle-damage.vue | 12 ++++++------ src/styles/common-error-styles.scss | 8 ++++++++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/common-components/funnel-header/funnel-header.vue b/src/common-components/funnel-header/funnel-header.vue index 382640219..3266b88a9 100644 --- a/src/common-components/funnel-header/funnel-header.vue +++ b/src/common-components/funnel-header/funnel-header.vue @@ -66,4 +66,7 @@ export default { .logo-image { max-width: 78px; } +.alert { + left: 0; +} diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index 93a3c9680..fd3f55a74 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -5,7 +5,7 @@ ref="theForm" v-slot="{ meta }" > -
+
@@ -285,7 +285,7 @@ export default { }, navigateForward(partsData){ - // CSR-98 TEMP + // CSR-98 TEMP if (store.getters.vehicle.year == 2010) { navigateToHeritageFunnel(); return; @@ -393,15 +393,15 @@ export default { hasSplitSingleConflict() { if (!this.selectedWindshieldOptions.selectedWindshieldReplaceOptions) return false; - return this.selectedWindshieldOptions.selectedWindshieldReplaceOptions.some(selectedSingleWindshield => + return this.selectedWindshieldOptions.selectedWindshieldReplaceOptions.some(selectedSingleWindshield => { return selectedSingleWindshield.toUpperCase() === damageLocationsSelected.SINGLE.toUpperCase(); - }) && - (this.selectedWindshieldOptions.selectedWindshieldReplaceOptions.some(selectedDriverWindshield => + }) && + (this.selectedWindshieldOptions.selectedWindshieldReplaceOptions.some(selectedDriverWindshield => { return selectedDriverWindshield.toUpperCase() === damageLocationsSelected.DRIVER.toUpperCase(); }) || - this.selectedWindshieldOptions.selectedWindshieldReplaceOptions.some(selectedPassengerWindshield => + this.selectedWindshieldOptions.selectedWindshieldReplaceOptions.some(selectedPassengerWindshield => { return selectedPassengerWindshield.toUpperCase() === damageLocationsSelected.PASSENGER.toUpperCase(); }) diff --git a/src/styles/common-error-styles.scss b/src/styles/common-error-styles.scss index 323430dfe..9fdd0ef44 100644 --- a/src/styles/common-error-styles.scss +++ b/src/styles/common-error-styles.scss @@ -11,6 +11,11 @@ input[type=radio]:focus + label { box-shadow: 0 0 0 2.5px $red; } + + &:hover { + box-shadow: 0px 0px 0px 4px $red-200; + border-radius: 10px !important; + } } input[type=checkbox]:checked + label, @@ -21,6 +26,9 @@ color: $red; label { border: 1px solid $red; + &:hover { + box-shadow: 0px 0px 0px 4px $red-200; + } } input[type=checkbox]:focus + label, input[type=radio]:focus + label { From 091e9b129e6de82efaab5c02c3a171f07b9b1408 Mon Sep 17 00:00:00 2001 From: bmauger Date: Wed, 30 Mar 2022 09:21:58 -0400 Subject: [PATCH 42/58] Update error styles. --- src/styles/common-error-styles.scss | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/styles/common-error-styles.scss b/src/styles/common-error-styles.scss index 9fdd0ef44..fe1637e43 100644 --- a/src/styles/common-error-styles.scss +++ b/src/styles/common-error-styles.scss @@ -3,18 +3,18 @@ &.list-card { border: 1px solid $red; color: $red; - label { - box-shadow: 0 0 1px $red !important; - border-radius: .5rem; - } input[type=checkbox]:focus + label, input[type=radio]:focus + label { box-shadow: 0 0 0 2.5px $red; } - + input[type=checkbox]:focus + label:hover, + input[type=radio]:focus + label { + box-shadow: 0 0 0 1px $red; + } &:hover { box-shadow: 0px 0px 0px 4px $red-200; border-radius: 10px !important; + border: 1px solid $red; } } From b4a0e36e6b4ce04ea47b8e356e6ebba15e1a7366 Mon Sep 17 00:00:00 2001 From: FrankRua Date: Wed, 30 Mar 2022 10:31:27 -0400 Subject: [PATCH 43/58] Stopped 404 from happening on initial load --- src/router/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/router/index.js b/src/router/index.js index bbb58e725..fc24e70c4 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -41,7 +41,7 @@ const routes = [ try { // If the saved session has timed out, clear the session, execute 404 logic. - if (!isSavedSessionStillActive()) { + if (getFunnelCookie() !== null && !isSavedSessionStillActive()) { await GoToFunnelStartOn404(next); } From 7f1a4b79b460cda20fd86691bdb351438fbe2faf Mon Sep 17 00:00:00 2001 From: bmauger Date: Wed, 30 Mar 2022 10:39:39 -0400 Subject: [PATCH 44/58] Update button border fix for Safari/iOS. --- src/ux-components/button-main/button-main.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ux-components/button-main/button-main.vue b/src/ux-components/button-main/button-main.vue index 60497df84..3ddd0bd6b 100644 --- a/src/ux-components/button-main/button-main.vue +++ b/src/ux-components/button-main/button-main.vue @@ -58,6 +58,9 @@ export default { @media (hover: hover) { background: linear-gradient(270deg, $blue-500 0%, $blue-700 100%); } + &:focus { + box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700; + } &:focus, // Mouse, touch, stylus focus &:focus-visible { // Keyboard focus for accessibility @@ -88,6 +91,7 @@ export default { &.has-loader { color: $white; background: $blue-700; + box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700; } &.delay {// fixes flicker while transitioning between states transition: background 0s 0s ease-in-out; From e24f61e5f18df9d974a6c2dfbc750f8716c4b24a Mon Sep 17 00:00:00 2001 From: Katie Date: Wed, 30 Mar 2022 11:36:23 -0400 Subject: [PATCH 45/58] CSR-98 Use correct domain in cookie --- src/constants/application-config.js | 5 ++-- .../heritage-integration/cookie-helper.js | 26 +++++++++++++++---- .../heritage-integration/navigation-helper.js | 11 +++++--- .../heritage-integration/order-helper.spec.js | 9 ++++--- src/helpers/unit-test-helper.js | 24 ++++++++++++++--- vue.config.js | 1 - 6 files changed, 58 insertions(+), 18 deletions(-) diff --git a/src/constants/application-config.js b/src/constants/application-config.js index d427b1d72..f2e4c76ac 100644 --- a/src/constants/application-config.js +++ b/src/constants/application-config.js @@ -1,9 +1,10 @@ + const applicationConfig = { CONSUMER_APIGATEWAY_URL: process.env.VUE_APP_CONSUMER_API_GATEWAY, GOOGLE_PLACES_API_KEY: process.env.VUE_APP_GOOGLE_PLACES_API_KEY, - ANALYTICS_SESSION_TIMEOUT: 30, - SAVED_SESSION_TIMEOUT: 45 + ANALYTICS_SESSION_TIMEOUT: 30, SAVED_SESSION_TIMEOUT: 45, }; + export { applicationConfig }; diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index 9de5d5760..487c261b7 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -1,7 +1,6 @@ import { cookieNames } from "@/constants/cookie-names"; import store from "@/store"; - /* Will update the cookie if present, or create a new one if not. */ @@ -17,7 +16,7 @@ export function updateOrCreateConceptCookie() { }); // Create the cookie - document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}={}; path=/`; + document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}={}; domain=${getDomainWithoutSubdomain()}; path=/;`; // Set up cookie with all the props. setConceptCookieProperties({ @@ -37,11 +36,15 @@ export function updateOrCreateConceptCookie() { Returns null if cookie isn't valid JSON. */ export function getConceptCookie() { + console.log("getConceptCookie") + console.log(document.cookie) + console.log(location.hostname) + console.log(getDomainWithoutSubdomain()) const cookieJson = document.cookie ?.split("; ") ?.find(row => row.startsWith(`${cookieNames.CONCEPT_SESSION_INFO}=`)) ?.split("=")[1]; - + console.log(cookieJson) try { return JSON.parse(cookieJson); } catch (error) { @@ -53,7 +56,7 @@ export function getConceptCookie() { Removes concept cookie from browser. */ export function deleteConceptCookie() { - document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; path=/; domain=${location.hostname}`; + document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=; Max-Age=0; domain=${getDomainWithoutSubdomain()}; path=/`; } /* @@ -71,8 +74,21 @@ function setConceptCookieProperties(properties) { const cookieValueJson = JSON.stringify(cookie); - document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=${cookieValueJson}; path=/`; + document.cookie = `${cookieNames.CONCEPT_SESSION_INFO}=${cookieValueJson}; domain=${getDomainWithoutSubdomain()}; path=/`; } } } +function getDomainWithoutSubdomain() { + let url = location.hostname; + if (url == "localhost") { + return "localhost"; + } + + const urlParts = url.split('.'); + + return `.${urlParts + .slice(0) + .slice(-(urlParts.length === 4 ? 3 : 2)) + .join('.')}`; +} diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 20a4315bf..4b9da5572 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -1,7 +1,7 @@ import { queryStrings } from "@/constants/query-strings"; import { externalUrls } from "@/router/router-constants/externalUrl-values"; import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js"; -import {saveOrder} from "@/helpers/heritage-integration/order-helper.js"; +import { saveOrder } from "@/helpers/heritage-integration/order-helper.js"; import store from "@/store"; import router from "@/router"; @@ -45,9 +45,11 @@ export async function getPageToRouteExistingOrderTo(toRoute = {}, existingHerita return 'vehicle-damage' } else { if (store.getters.vehicle.vin) { - return "vin-lookup"; + return "vehicle-damage"; + // return "vin-lookup"; } else { - return "estimate" + return "vehicle-damage"; + // return "estimate" } } @@ -67,6 +69,9 @@ export async function navigateToHeritageFunnel() { { corid: store.getters.order.referralCorrelationId, src: "concept-funnel", + // TODO CSR-28, remove this + cns: "all", + experiments: "RemoveServiceAreaPage=ServAreaRemoval_V7=ServAreaNoRemove_V7_TEST=true,ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" } ); } \ No newline at end of file diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js index 473e6c842..9d6b72f6e 100644 --- a/src/helpers/heritage-integration/order-helper.spec.js +++ b/src/helpers/heritage-integration/order-helper.spec.js @@ -19,7 +19,7 @@ describe("loadOrderIfPresent", () => { ShouldResetState: testShouldResetState } - document.cookie = `${cookieNames.ORDER_INFO}=${JSON.stringify(testCookieValue)}; path=/; domain=${location.hostname}`; + document.cookie = `${cookieNames.ORDER_INFO}=${JSON.stringify(testCookieValue)}; path=/; domain=.safelite.com`; // Act loadOrderIfPresent(); @@ -74,7 +74,6 @@ describe("loadOrderIfPresent", () => { }); describe("saveOrder", () => { - afterEach(() => { removeAllTestCookies(); }); @@ -113,7 +112,7 @@ describe("saveOrder", () => { }, false); }); - test("saveOrder => should update DidHeritageFunnelUpdateLast cookie value to false", async () => { + test.only("saveOrder => should update DidHeritageFunnelUpdateLast cookie value to false", async () => { // Arrange const testReferralNumber = 1566818; const testReferralDate = "2022-03-15T10:56:24.597"; @@ -139,8 +138,12 @@ describe("saveOrder", () => { DidHeritageFunnelUpdateLast: true } + console.log("A") + console.log(location.hostname) setupCookies({ conceptCookieValue: JSON.stringify(testCookieValue) }); + console.log(document.cookie) + // Act await saveOrder(); diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 699c4f8e9..f95dc6f69 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -62,8 +62,8 @@ export const cookies = { export function removeAllTestCookies() { Object.keys(cookies).forEach(key => { - document.cookie = `${key}=;Max-Age=0;`; - document.cookie = `${key}=;Max-Age=0;path=/`; + document.cookie = `${key}=;Max-Age=0;domain=${getDomainWithoutSubdomain()};`; + document.cookie = `${key}=;Max-Age=0;domain=${getDomainWithoutSubdomain()};path=/`; }); } @@ -78,10 +78,11 @@ export function getMockOrderInfo(mockReferralNumber, mockCorrelationId, mockRefe export function setupCookies({ conceptCookieValue = "", includeHeritageCookie = true }) { Object.keys(cookies).forEach(key => { const cookieValue = key == cookieNames.CONCEPT_SESSION_INFO ? conceptCookieValue : cookies[key]; - if (includeHeritageCookie || key != cookieNames.CONCEPT_SESSION_INFO) - document.cookie = `${key}=${cookieValue}; path=/;`; + document.cookie = `${key}=${cookieValue}; domain=${getDomainWithoutSubdomain()}; path=/;`; }); + + console.log(document.cookie) } // Private methods @@ -100,4 +101,19 @@ function setupBaseMixinDispatchNonBlockingStoreAction(mockData) { } }); } +} + + +function getDomainWithoutSubdomain() { + let url = location.hostname; + if (url == "localhost") { + return "localhost"; + } + + const urlParts = url.split('.'); + + return `.${urlParts + .slice(0) + .slice(-(urlParts.length === 4 ? 3 : 2)) + .join('.')}`; } \ No newline at end of file diff --git a/vue.config.js b/vue.config.js index 7bca415e3..c3cf92368 100644 --- a/vue.config.js +++ b/vue.config.js @@ -2,7 +2,6 @@ process.env.VUE_APP_CONSUMER_API_GATEWAY = "https://consumerapidev.safelite.com"; process.env.VUE_APP_HERITAGE_FUNNEL = "http://localhost:38000/default.aspx"; - process.env.VUE_APP_GOOGLE_PLACES_API_KEY = "AIzaSyDptGCkOPgN2uWJOy4ou4M33phRD4MAoJo" From d6e935a2d851b1c5bb2ce8eb679087100308c386 Mon Sep 17 00:00:00 2001 From: Katie Date: Wed, 30 Mar 2022 11:40:32 -0400 Subject: [PATCH 46/58] CSR-98 Fix merge conflicts --- src/helpers/heritage-integration/cookie-helper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index daf51876b..d8cda8a67 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -45,7 +45,7 @@ export function getFunnelCookie() { /* Removes cookie from browser. */ -export function deleteConceptCookie() { +export function deleteFunnelCookie() { document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}=; Max-Age=0; domain=${getDomainWithoutSubdomain()}; path=/`; } From 1e40e0e1f8e2582255d88e990d5a0c13a34e8347 Mon Sep 17 00:00:00 2001 From: Katie Date: Wed, 30 Mar 2022 13:11:42 -0400 Subject: [PATCH 47/58] CSR-98 Fix tests --- .../heritage-integration/cookie-helper.js | 10 +++++--- .../heritage-integration/order-helper.spec.js | 4 +--- src/helpers/unit-test-helper.js | 24 ++++--------------- 3 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index d8cda8a67..18632fc51 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -6,7 +6,7 @@ import store from "@/store"; */ export function updateOrCreateFunnelCookie() { // Create the cookie - document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}={}; domain=${getDomainWithoutSubdomain()}; path=/;`; + document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}={}; path=/; ${getCookieDomainValue()};`; // Set up cookie with all the props. setFunnelCookieProperties({ @@ -46,7 +46,7 @@ export function getFunnelCookie() { Removes cookie from browser. */ export function deleteFunnelCookie() { - document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}=; Max-Age=0; domain=${getDomainWithoutSubdomain()}; path=/`; + document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}=; Max-Age=0; path=/; ${getCookieDomainValue()}`; } /* @@ -64,11 +64,15 @@ function setFunnelCookieProperties(properties) { const cookieValueJson = JSON.stringify(cookie); - document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}=${cookieValueJson}; domain=${getDomainWithoutSubdomain()}; path=/`; + document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}=${cookieValueJson}; path=/; ${getCookieDomainValue()}`; } } } +export function getCookieDomainValue() { + return location.hostname.includes("localhost") ? "" : `domain=${getDomainWithoutSubdomain()};`; +} + function getDomainWithoutSubdomain() { let url = location.hostname; if (url == "localhost") { diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js index 5de25b6c0..382132bbe 100644 --- a/src/helpers/heritage-integration/order-helper.spec.js +++ b/src/helpers/heritage-integration/order-helper.spec.js @@ -132,7 +132,7 @@ describe("saveOrder", () => { }, false); }); - test.only("saveOrder => should update DidHeritageFunnelUpdateLast cookie value to false", async () => { + test("saveOrder => should update DidHeritageFunnelUpdateLast cookie value to false", async () => { // Arrange const testReferralNumber = 1566818; const testReferralDate = "2022-03-15T10:56:24.597"; @@ -160,8 +160,6 @@ describe("saveOrder", () => { setupCookies({ funnelCookieValue: JSON.stringify(testCookieValue) }); - console.log(document.cookie) - // Act await saveOrder(); diff --git a/src/helpers/unit-test-helper.js b/src/helpers/unit-test-helper.js index 13ef9d632..7b81cca00 100644 --- a/src/helpers/unit-test-helper.js +++ b/src/helpers/unit-test-helper.js @@ -5,6 +5,7 @@ import { vehicleCategories } from "@/constants/vehicle-categories.js"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import { cookieNames } from "@/constants/cookie-names"; import baseMixin from "@/mixins/base-mixin"; +import { getCookieDomainValue } from "@/helpers/heritage-integration/cookie-helper"; // Common methods export function getMountOptions(mockData) { @@ -62,8 +63,8 @@ export const cookies = { export function removeAllTestCookies() { Object.keys(cookies).forEach(key => { - document.cookie = `${key}=;Max-Age=0;domain=${getDomainWithoutSubdomain()};`; - document.cookie = `${key}=;Max-Age=0;domain=${getDomainWithoutSubdomain()};path=/`; + document.cookie = `${key}=;Max-Age=0;`; + document.cookie = `${key}=;Max-Age=0;path=/;${getCookieDomainValue()}`; }); } @@ -79,10 +80,8 @@ export function setupCookies({ funnelCookieValue = "", includeHeritageCookie = t Object.keys(cookies).forEach(key => { const cookieValue = key == cookieNames.FUNNEL_SESSION_INFO ? funnelCookieValue : cookies[key]; if (includeHeritageCookie || key != cookieNames.FUNNEL_SESSION_INFO) - document.cookie = `${key}=${cookieValue}; domain=${getDomainWithoutSubdomain()}; path=/;`; + document.cookie = `${key}=${cookieValue}; path=/; ${getCookieDomainValue()}`; }); - - console.log(document.cookie) } // Private methods @@ -101,19 +100,4 @@ function setupBaseMixinDispatchNonBlockingStoreAction(mockData) { } }); } -} - - -function getDomainWithoutSubdomain() { - let url = location.hostname; - if (url == "localhost") { - return "localhost"; - } - - const urlParts = url.split('.'); - - return `.${urlParts - .slice(0) - .slice(-(urlParts.length === 4 ? 3 : 2)) - .join('.')}`; } \ No newline at end of file From 5803b4dcbb7a0945830f1e0fce68adaff26562c4 Mon Sep 17 00:00:00 2001 From: Katie Date: Wed, 30 Mar 2022 13:15:51 -0400 Subject: [PATCH 48/58] CSR-98 Cleanup --- src/helpers/heritage-integration/cookie-helper.js | 8 ++------ src/helpers/heritage-integration/navigation-helper.js | 3 --- src/helpers/heritage-integration/order-helper.spec.js | 2 +- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index 18632fc51..f8cf05174 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -26,15 +26,11 @@ export function updateOrCreateFunnelCookie() { Returns null if cookie isn't valid JSON. */ export function getFunnelCookie() { - console.log("getConceptCookie") - console.log(document.cookie) - console.log(location.hostname) - console.log(getDomainWithoutSubdomain()) const cookieJson = document.cookie ?.split("; ") ?.find(row => row.startsWith(`${cookieNames.FUNNEL_SESSION_INFO}=`)) ?.split("=")[1]; - console.log(cookieJson) + try { return JSON.parse(cookieJson); } catch (error) { @@ -75,7 +71,7 @@ export function getCookieDomainValue() { function getDomainWithoutSubdomain() { let url = location.hostname; - if (url == "localhost") { + if (url.includes("localhost")) { return "localhost"; } diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index b6fd5a5b4..12207acf4 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -67,9 +67,6 @@ export async function navigateToHeritageFunnel() { { corid: store.getters.order.referralCorrelationId, src: "concept-funnel", - // TODO CSR-28, remove this - cns: "all", - experiments: "RemoveServiceAreaPage=ServAreaRemoval_V7=ServAreaNoRemove_V7_TEST=true,ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true" } ); } \ No newline at end of file diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js index 382132bbe..d53afc232 100644 --- a/src/helpers/heritage-integration/order-helper.spec.js +++ b/src/helpers/heritage-integration/order-helper.spec.js @@ -19,7 +19,7 @@ describe("loadOrderIfPresent", () => { ShouldResetState: testShouldResetState } - document.cookie = `${cookieNames.ORDER_INFO}=${JSON.stringify(testCookieValue)}; path=/; domain=.safelite.com`; + document.cookie = `${cookieNames.ORDER_INFO}=${JSON.stringify(testCookieValue)}; path=/; ${cookieHelper.getCookieDomainValue()}`; // Act loadOrderIfPresent(); From b98ec44714ab5ae1f4aca80830fd4777f7d807b2 Mon Sep 17 00:00:00 2001 From: Katie Date: Wed, 30 Mar 2022 13:34:14 -0400 Subject: [PATCH 49/58] CSR-98 Fix tests --- src/helpers/heritage-integration/cookie-helper.js | 1 + src/helpers/heritage-integration/order-helper.js | 2 ++ src/helpers/heritage-integration/order-helper.spec.js | 7 +++++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/helpers/heritage-integration/cookie-helper.js b/src/helpers/heritage-integration/cookie-helper.js index f8cf05174..cee400e0c 100644 --- a/src/helpers/heritage-integration/cookie-helper.js +++ b/src/helpers/heritage-integration/cookie-helper.js @@ -42,6 +42,7 @@ export function getFunnelCookie() { Removes cookie from browser. */ export function deleteFunnelCookie() { + console.log("hi there") document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}=; Max-Age=0; path=/; ${getCookieDomainValue()}`; } diff --git a/src/helpers/heritage-integration/order-helper.js b/src/helpers/heritage-integration/order-helper.js index aaf0db740..8dddb5436 100644 --- a/src/helpers/heritage-integration/order-helper.js +++ b/src/helpers/heritage-integration/order-helper.js @@ -10,6 +10,7 @@ import baseMixin from "@/mixins/base-mixin"; */ export async function loadOrderIfPresent() { const funnelCookie = getFunnelCookie(); + console.log(funnelCookie) // Do nothing if there is no cookie or no correlation id. if (funnelCookie == null || funnelCookie.ReferralCorrelationId == null) { @@ -20,6 +21,7 @@ export async function loadOrderIfPresent() { if (funnelCookie.ShouldResetState) { baseMixin.methods.dispatchNonBlockingStoreAction(storeActions.RESET_STATE); deleteFunnelCookie(); + console.log("sup") return null; } diff --git a/src/helpers/heritage-integration/order-helper.spec.js b/src/helpers/heritage-integration/order-helper.spec.js index d53afc232..cbe54ba25 100644 --- a/src/helpers/heritage-integration/order-helper.spec.js +++ b/src/helpers/heritage-integration/order-helper.spec.js @@ -13,18 +13,21 @@ describe("loadOrderIfPresent", () => { test("ShouldResetState == true => funnel cookie is deleted", () => { // Arrange + cookieHelper.deleteFunnelCookie = jest.spyOn(cookieHelper, "deleteFunnelCookie"); const testShouldResetState = true; const testCookieValue = { - ShouldResetState: testShouldResetState + ShouldResetState: testShouldResetState, + ReferralCorrelationId: "xxx" } - document.cookie = `${cookieNames.ORDER_INFO}=${JSON.stringify(testCookieValue)}; path=/; ${cookieHelper.getCookieDomainValue()}`; + document.cookie = `${cookieNames.FUNNEL_SESSION_INFO}=${JSON.stringify(testCookieValue)}; path=/; ${cookieHelper.getCookieDomainValue()}`; // Act loadOrderIfPresent(); // Assert + expect(cookieHelper.deleteFunnelCookie).toHaveBeenCalled(); expect(document.cookie).toBe(""); }); From 44dfb7cadbb69a32033bd84b63db8aedd467982a Mon Sep 17 00:00:00 2001 From: bmauger Date: Wed, 30 Mar 2022 15:10:32 -0400 Subject: [PATCH 50/58] Remove outline to fix rounded corners issue. --- src/ux-components/list-card/list-card.vue | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ux-components/list-card/list-card.vue b/src/ux-components/list-card/list-card.vue index a9755904e..922aec1d3 100644 --- a/src/ux-components/list-card/list-card.vue +++ b/src/ux-components/list-card/list-card.vue @@ -219,13 +219,13 @@ export default { box-shadow: 0 0 0 2.5px $blue; border-radius: 0.5rem; } - + &:checked { &:focus + label { box-shadow: 0 0 0 2.5px $blue; } } - + &:checked + label { p { color: $black; @@ -331,6 +331,7 @@ export default { } + label { + outline: none; min-height: 48px; color: $gray-600; From 63a9facc665f7877119eb3a8f26bde3cef1a21ca Mon Sep 17 00:00:00 2001 From: bmauger Date: Thu, 31 Mar 2022 08:40:39 -0400 Subject: [PATCH 51/58] Remove outline. --- .../list-button-horizontal/list-button-horizontal.vue | 1 + src/ux-components/list-card/list-card.vue | 1 + 2 files changed, 2 insertions(+) diff --git a/src/ux-components/list-button-horizontal/list-button-horizontal.vue b/src/ux-components/list-button-horizontal/list-button-horizontal.vue index 68aceec51..cef3d765c 100644 --- a/src/ux-components/list-button-horizontal/list-button-horizontal.vue +++ b/src/ux-components/list-button-horizontal/list-button-horizontal.vue @@ -161,6 +161,7 @@ export default { } } label { + outline: none; position: relative; background: $white; transition: all 150ms linear; diff --git a/src/ux-components/list-card/list-card.vue b/src/ux-components/list-card/list-card.vue index 922aec1d3..adbd8a377 100644 --- a/src/ux-components/list-card/list-card.vue +++ b/src/ux-components/list-card/list-card.vue @@ -192,6 +192,7 @@ export default { position: absolute; + label { + outline: none; display: block; position: relative; From b110a828593534bd7e05a0f953315d10d03eefae Mon Sep 17 00:00:00 2001 From: bmauger Date: Thu, 31 Mar 2022 13:27:15 -0400 Subject: [PATCH 52/58] Remove outline from list-button. --- src/ux-components/list-button/list-button.vue | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue index caef528de..775b19ff4 100644 --- a/src/ux-components/list-button/list-button.vue +++ b/src/ux-components/list-button/list-button.vue @@ -128,9 +128,9 @@ export default { fieldOptions['initialValue'] = fieldOptions.potentialInitialValue; } - const { - checked, - handleChange, + const { + checked, + handleChange, errors, } = useField(props.groupName, props.validationRules, fieldOptions); @@ -147,6 +147,7 @@ export default {