diff --git a/jest.config.js b/jest.config.js index c1edf3074..1273d62c1 100644 --- a/jest.config.js +++ b/jest.config.js @@ -17,11 +17,9 @@ module.exports = { "!src/layouts/vin-lookup/vin-lookup.vue", "!src/layouts/vehicle-damage/windshield-damage-type-question/windshield-damage-type-question.vue", "!src/layouts/vehicle-damage/windshield-options/windshield-options.vue", - "!src/layouts/address-poc/address-poc.vue", - "!src/layouts/nested-radio-poc/nested-radio.vue", - "!src/layouts/button-question-examples/**/*.vue", "!src/layouts/part-questions/**/*.vue", "!src/layouts/reveal/**/*.vue", + "!src/layouts/estimate/**/*.vue", // REMOVE THESE AFTER WRITING UNIT TESTS "!src/layouts/address-lookup/address-lookup.vue", "!src/layouts/address-lookup/customer-questions/customer-questions.vue", diff --git a/src/common-components/funnel-footer/funnel-footer.vue b/src/common-components/funnel-footer/funnel-footer.vue index c6e7659b9..424003708 100644 --- a/src/common-components/funnel-footer/funnel-footer.vue +++ b/src/common-components/funnel-footer/funnel-footer.vue @@ -22,13 +22,13 @@ isPrimary :buttonText="buttonText" loaderColor="white" - :class="isDisabled && 'form-test-invalid'" - :aria-disabled="isDisabled" - :isDisabled="isDisabled" + :class="isForwardActionDisabled && 'form-test-invalid'" + :aria-disabled="isForwardActionDisabled" + :isDisabled="isForwardActionDisabled" @click-event="buttonClick" /> - diff --git a/src/layouts/estimate/estimate.vue b/src/layouts/estimate/estimate.vue new file mode 100644 index 000000000..0e41b24ed --- /dev/null +++ b/src/layouts/estimate/estimate.vue @@ -0,0 +1,13 @@ + + diff --git a/src/layouts/form-test/form-test.vue b/src/layouts/form-test/form-test.vue index 8e9aefe22..046b0c234 100644 --- a/src/layouts/form-test/form-test.vue +++ b/src/layouts/form-test/form-test.vue @@ -44,7 +44,7 @@ /> diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index d12e11529..789289c6a 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -52,7 +52,7 @@ diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js index fe3a4aa51..7b28e4bb5 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.spec.js +++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js @@ -36,6 +36,11 @@ jest.mock("@/store", () => ({ vehicle: { carId: "C00000000", image: "test.jpg", + payment: { + insuranceCoverage: { + isVerified: false + } + } }, eventBusItem: jest.fn(), damage: { @@ -134,6 +139,7 @@ describe("vehicle-damage.vue", () => { store: { getters: { vehicle: {}, + payment: { insuranceCoverage: { isVerified: false } }, }, }, }, @@ -201,6 +207,7 @@ describe("vehicle-damage.vue", () => { store: { getters: { vehicle: {}, + payment: { insuranceCoverage: { isVerified: false } }, }, }, }, @@ -291,6 +298,7 @@ describe("vehicle-damage.vue", () => { store: { getters: { vehicle: {}, + payment: { insuranceCoverage: { isVerified: false } }, }, }, }, @@ -336,6 +344,7 @@ describe("vehicle-damage.vue", () => { store: { getters: { vehicle: {}, + payment: { insuranceCoverage: { isVerified: false } }, }, }, }, @@ -734,6 +743,7 @@ function setupMocks({ store: { getters: { vehicle: {}, + payment: { insuranceCoverage: { isVerified: false } }, }, }, }, diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index 45ea9d92b..6dad2d9e4 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -47,7 +47,8 @@ /> @@ -145,9 +146,11 @@ export default { } return false; }, + resetDependentState() { store.dispatch(storeActions.RESET_PARTS_STATE_AND_DEPENDENCIES); }, + backButtonAction() { // route to move backwards this.$router.navigate( @@ -155,6 +158,7 @@ export default { this.$route ); }, + getDamageLocationsFromStore() { var glassSelections = []; @@ -275,13 +279,20 @@ export default { }, navigateForward(partsData){ - // CSR-98 TEMP + + // Temporary easter egg to navigate to heritage funnel. const vehicleYearsToShowHeritageFunnel = [ 2001, 2002, 2010 ]; if (vehicleYearsToShowHeritageFunnel.includes(store.getters.vehicle.year)) { navigateToHeritageFunnel(); return; } + // If vin already exists, navigate directly to vin-lookup + if(this.$store.getters.vehicle.vin){ + this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_VIN, this.$route); + 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); @@ -398,6 +409,9 @@ export default { }) ); }, + shouldHideBackButton(){ + return this.$store.getters.payment.insuranceCoverage.isVerified; + } }, components: { diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index fc9058abf..c3a1bbc33 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -1,41 +1,272 @@ - - diff --git a/src/router/index.js b/src/router/index.js index 778c55cfc..1759dec68 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -7,9 +7,9 @@ import { globalEvents, globalEventTypes } from "@/constants/events"; // Heritage integration import { isSavedSessionStillActive } from "@/helpers/heritage-integration/session-helper"; -import { updateOrCreateFunnelCookie,getFunnelCookie } 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"; +import { getPageToRouteExistingOrderTo, navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; import baseMixin from "@/mixins/base-mixin"; import eventBus from "@/helpers/event-bus/event-bus"; @@ -35,84 +35,79 @@ const routes = [ name: "root", async beforeEnter(to, from, next) { // 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 { + try { - // If the saved session has timed out, clear the session, execute 404 logic. - if (getFunnelCookie() !== null && !isSavedSessionStillActive()) { - await GoToFunnelStartOn404(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); - - // 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 navigateToHeritageFunnel(); - return next(false); - } - - // Assign our fmgPage so it will load normally like the other pages. - to.query.fmgPage = pageToRedirectTo; - } - - // Process funnel cookie. - updateOrCreateFunnelCookie(); - - // 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; - - // If the component hasn't been loaded fully, load it before we check prerequisites. - if (component.default.methods === undefined) { - component = await component.default(); - } - - if (!arePagePrerequisitesValid(component)) { - await GoToFunnelStartOn404(next); - } - - return next({ name: to.query.fmgPage, query: to.query, params: to.params }); - } - - // Get route info for the given url. Names will have a 1:1 relationship with names in the Cms. - const routeData = await GetRouteInfoFromPageName(to.query.fmgPage); - - // Add our dynamic route. - router.addRoute({ - path: routeData[0].path, // Always the same path, because we control it with query strings. - name: routeData[0].name, - component: routeData[0].component, - }); - - // Call the next components arePagePrerequisitesValid method before load. - // If it returns false, use the 404 logic. - const nextComponent = await router.getRoutes().filter((x) => x.name === routeData[0].name)[0].components.default(); - - if (!arePagePrerequisitesValid(nextComponent)) { - await GoToFunnelStartOn404(next); - } - - // Assign current query string parameters, as well as our fmgPage one. - next({ - name: routeData[0].name, - query: Object.assign(to.query, { fmgPage: routeData[0].name }), - params: to.params - }); - } catch (error) { - console.log(error); - - // If we don't have a route, go to our 404 page. + // If the saved session has timed out, clear the session, execute 404 logic. + if (getFunnelCookie() !== null && !isSavedSessionStillActive()) { await GoToFunnelStartOn404(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); + + // 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 navigateToHeritageFunnel(); + return next(false); + } + + + // Assign our fmgPage so it will load normally like the other pages. + to.query.fmgPage = pageToRedirectTo; + } + + // Process funnel cookie. + updateOrCreateFunnelCookie(); + + // 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; + + // If the component hasn't been loaded fully, load it before we check prerequisites. + if (component.default.methods === undefined) { + component = await component.default(); + } + + if (!arePagePrerequisitesValid(component)) { + await GoToFunnelStartOn404(next); + } + + return next({ name: to.query.fmgPage, query: to.query, params: to.params }); + } + + // Get route info for the given url. Names will have a 1:1 relationship with names in the Cms. + const routeData = await GetRouteInfoFromPageName(to.query.fmgPage); + + // Add our dynamic route. + router.addRoute({ + path: routeData[0].path, // Always the same path, because we control it with query strings. + name: routeData[0].name, + component: routeData[0].component, + }); + + // Call the next components arePagePrerequisitesValid method before load. + // If it returns false, use the 404 logic. + const nextComponent = await router.getRoutes().filter((x) => x.name === routeData[0].name)[0].components.default(); + + if (!arePagePrerequisitesValid(nextComponent)) { + await GoToFunnelStartOn404(next); + } + + // Assign current query string parameters, as well as our fmgPage one. + next({ + name: routeData[0].name, + query: Object.assign(to.query, { fmgPage: routeData[0].name }), + params: to.params + }); + } catch (error) { + console.log(error); + + // If we don't have a route, go to our 404 page. + await GoToFunnelStartOn404(next); } }, }, diff --git a/src/router/router-constants/fmgPage-values.js b/src/router/router-constants/fmgPage-values.js index f3c811de3..9abb45cd2 100644 --- a/src/router/router-constants/fmgPage-values.js +++ b/src/router/router-constants/fmgPage-values.js @@ -11,6 +11,7 @@ const fmgPageValues = { LICENSE_PLATE_LOOKUP: "license-plate-lookup", REVEAL: "reveal", ESTIMATE: "estimate", + ADDRESS_VEHICLES: "address-vehicles", }; export { fmgPageValues }; diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js index da170da53..57f07a041 100644 --- a/src/router/router-constants/navigation-scenarios.js +++ b/src/router/router-constants/navigation-scenarios.js @@ -4,7 +4,9 @@ const navigationScenarios = { SELECTED_MAKE: "SELECTED_MAKE", SELECTED_STYLE: "SELECTED_STYLE", CLICKED_BACK: "CLICKED_BACK", + CLICKED_BACK_WITH_VIN: "CLICKED_BACK_WITH_VIN", CLICKED_FORWARD: "CLICKED_FORWARD", + CLICKED_FORWARD_WITH_VIN: "CLICKED_FORWARD_WITH_VIN", SELECTED_PARTS: "SELECTED_PARTS", SELECTED_DAMAGE_WITH_SINGLE_PART: "SELECTED_DAMAGE_WITH_SINGLE_PART", SELECTED_DAMAGE_WITH_MULTIPLE_PARTS: "SELECTED_DAMAGE_WITH_MULTIPLE_PARTS", diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index 99583b975..bd0caf109 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -1,6 +1,5 @@ import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; -import { applicationConfig } from "@/constants/application-config"; const routingTable = [ { @@ -58,9 +57,13 @@ const routingTable = [ scenario: navigationScenarios.CLICKED_BACK, destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE, }, + { + scenario: navigationScenarios.CLICKED_FORWARD_WITH_VIN, + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, + }, { scenario: navigationScenarios.SELECTED_DAMAGE_WITH_SINGLE_PART, - destinationFmgPageValue: fmgPageValues.REVEAL + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, }, { scenario: navigationScenarios.SELECTED_DAMAGE_WITH_MULTIPLE_PARTS, @@ -68,7 +71,7 @@ const routingTable = [ }, { scenario: navigationScenarios.SELECTED_DAMAGE_WITH_PART_QUESTIONS, - destinationFmgPageValue: fmgPageValues.PART_QUESTIONS, + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP,//This might be temporary }, ], }, @@ -107,6 +110,10 @@ const routingTable = [ maps: [ { scenario: navigationScenarios.CLICKED_BACK, + destinationFmgPageValue: fmgPageValues.REVEAL, + }, + { + scenario: navigationScenarios.CLICKED_BACK_WITH_VIN, destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE, }, { diff --git a/src/store/index.js b/src/store/index.js index b101d0524..3e4a40673 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -45,6 +45,12 @@ const getDefaultState = () => { glassParts: null, otherParts: null }, + payment:{ + isInsurance: null, + insuranceCoverage: { + isVerified: null + } + }, referralNumber: null, referralDate: null, referralCorrelationId: null, @@ -120,6 +126,12 @@ export const mutations = { updateParentAcctNumber(state, parentAcctNumber) { state.order.parentAccountNumber = parentAcctNumber; }, + updateIsInsurance(state, isInsurance) { + state.order.payment.isInsurance = isInsurance; + }, + updateInsuranceVerifiedStatus(state, isVerified) { + state.order.payment.insuranceCoverage.isVerified = isVerified; + }, // EVENT BUS MUTATIONS @@ -176,23 +188,30 @@ export const mutations = { state.order.referralNumber = orderInformation.referralNumber; state.order.referralDate = orderInformation.referralDate; state.order.referralCorrelationId = orderInformation.referralCorrelationId; + state.order.vehicle = Object.assign(state.order.vehicle, { year: orderInformation.vehicle?.year, make: orderInformation.vehicle?.make, model: orderInformation.vehicle?.model, style: orderInformation.vehicle?.style, + vin: orderInformation.vehicle?.vin, carId: orderInformation.vehicle?.carId, category: orderInformation.vehicle?.category, imageUrl: orderInformation.vehicle?.imageUrl, imageVifNumber: orderInformation.vehicle?.imageVifNumber, - imageColor: orderInformation.vehicle?.imageVifColor + 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.serviceLocation.zipCode = orderInformation.zipCode; + + state.order.payment.isInsurance = orderInformation.IsInsuranceOrder; + state.order.payment.insuranceCoverage.isVerified = orderInformation?.insuranceInfo.coverageVerified; } } @@ -210,11 +229,10 @@ export const getters = { eventBus: (state) => state.applicationUser.eventBus, damage: (state) => state.order.damage, lineItems: (state) => state.order.lineItems, - pageData: (state) => (page) => { - return state.applicationUser.pageData[page]; - }, + pageData: (state) => (page) => { return state.applicationUser.pageData[page]; }, applicationUser: (state) => state.applicationUser, order: (state) => state.order, + payment: (state) => state.order.payment, } // Export Actions diff --git a/src/store/store.spec.js b/src/store/store.spec.js index 08db50bd0..7618cc25a 100644 --- a/src/store/store.spec.js +++ b/src/store/store.spec.js @@ -222,6 +222,7 @@ describe("Mutations", () => { numberOfChips: 0, parts: [], parentAccountNumber: "123456789", + insuranceInfo: {} }); // Assert @@ -232,6 +233,17 @@ describe("Mutations", () => { expect(storeState.order.vehicle.model).toEqual("ILX"); }); + it("updateInsuranceVerifiedStatus, should set isVerified flag", () => { + // Arrange + const storeState = state; + + // Act + mutations.updateInsuranceVerifiedStatus(storeState, true); + + // Assert + expect(storeState.order.payment.insuranceCoverage.isVerified).toEqual(true); + }); + }); describe("Actions", () => { @@ -690,4 +702,15 @@ describe("Getters", () => { }); + it("Payment getter, should return payment data", () => { + // Arrange + const storeState = state; + + //Act + mutations.updateInsuranceVerifiedStatus(storeState, true ); + + //Assert + expect(getters.payment(storeState).insuranceCoverage.isVerified).toEqual(true); + }); + }); \ No newline at end of file