diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 2760d6a1a..e6fa6d0ff 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -76,7 +76,7 @@ stages: deployFolder: '' region: us-east-1 appDeployVariables: - __VUE_APP_CONSUMER_API_GATEWAY__: $(__VUE_APP_CONSUMER_API_GATEWAY__) + __VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__) __VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__) __VUE_APP_HERITAGE_FUNNEL__: $(__VUE_APP_HERITAGE_FUNNEL__) indexDeployVariables: @@ -92,7 +92,7 @@ stages: jobs: - deployment: qaBuildDeployment displayName: Build and Deploy FMG - QA - environment: digitalCloud-qa + environment: NoApproval-All container: node workspace: clean: all @@ -116,7 +116,7 @@ stages: deployFolder: '' region: us-east-1 appDeployVariables: - __VUE_APP_CONSUMER_API_GATEWAY__: $(__VUE_APP_CONSUMER_API_GATEWAY__) + __VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__) __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 diff --git a/jest.config.js b/jest.config.js index 7f7516934..e75fc82ab 100644 --- a/jest.config.js +++ b/jest.config.js @@ -21,13 +21,15 @@ module.exports = { "!src/layouts/part-questions/**/*.vue", "!src/layouts/reveal/**/*.vue", "!src/layouts/estimate/**/*.vue", - // REMOVE THESE AFTER WRITING UNIT TESTS + // REMOVE THESE AFTER WRITING UNIT TESTS "!src/layouts/address-lookup/address-lookup.vue", "!src/layouts/address-lookup/customer-questions/customer-questions.vue", "!src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue", - "!src/common-components/dropdown-question/dropdown-question.vue", - "!src/common-components/textbox-question/textbox-question.vue", - // END + "!src/common-components/dropdown-question/dropdown-question.vue", + "!src/common-components/textbox-question/textbox-question.vue", + "!src/helpers/validation-rules.js", + "!src/helpers/damage-helper.js", + // END ], //! means exclude from coverage. testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"], coverageThreshold: { diff --git a/src/common-components/textbox-question/textbox-question.vue b/src/common-components/textbox-question/textbox-question.vue index 062ceb683..00dcdfb88 100644 --- a/src/common-components/textbox-question/textbox-question.vue +++ b/src/common-components/textbox-question/textbox-question.vue @@ -15,7 +15,7 @@ autocomplete="off" :class="[hasIcon ? 'has-icon' : '', iconRight ? 'icon-right' : '']" :validationRules="validationRules" - @input="handleChange" + @change="handleChange" @blur="handleBlur" />
{{ errorMessage }} @@ -110,11 +110,6 @@ export default { } } }, - watch: { - value(newValue) { - this.handleChange(newValue); - } - } }; diff --git a/src/constants/application-config.js b/src/constants/application-config.js index a7841e5a9..b1ab342a7 100644 --- a/src/constants/application-config.js +++ b/src/constants/application-config.js @@ -1,6 +1,6 @@ const applicationConfig = { - CONSUMER_APIGATEWAY_URL: process.env.VUE_APP_CONSUMER_API_GATEWAY, + CONSUMER_CF_DISTRO: process.env.VUE_APP_CONSUMER_CF_DISTRO, GOOGLE_PLACES_API_KEY: process.env.VUE_APP_GOOGLE_PLACES_API_KEY, ANALYTICS_SESSION_TIMEOUT_MINUTES: 30, SAVED_SESSION_TIMEOUT_DAYS: 45, diff --git a/src/global-methods.js b/src/global-methods.js index e7996c4fa..5e4d04ea3 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -7,10 +7,10 @@ import { GaCategories, GaActions, GaLabels } from "@/constants/analytics"; export default { callHttpClient({ method, endpoint, payload, logApiCall = true }) { return new Promise((resolve, reject) => { - const apiGatewayUrl = applicationConfig.CONSUMER_APIGATEWAY_URL; + const cfDistroUrl = applicationConfig.CONSUMER_CF_DISTRO; const payloadAndAnalyticsData = Object.assign({}, payload, { AppName: "FixMyGlass" }); - axios({ method: method, url: apiGatewayUrl + endpoint, data: payloadAndAnalyticsData, crossDomain: true, responseType: {} }) + axios({ method: method, url: cfDistroUrl + endpoint, data: payloadAndAnalyticsData, crossDomain: true, responseType: {} }) .then((response) => { if (logApiCall) { diff --git a/src/helpers/damage-helper.js b/src/helpers/damage-helper.js index cf363e4d9..e56761dc5 100644 --- a/src/helpers/damage-helper.js +++ b/src/helpers/damage-helper.js @@ -24,8 +24,8 @@ export async function isGlassAvailableForCarId(carId){ for(const option of currentGlassOptions){ if(!newGlassOptions.data[optionsMap[option.location]].availableReplacementOptions.includes(option.name)){ return false; - } + } } return true; - } \ No newline at end of file + } diff --git a/src/helpers/damage-helper.spec.js b/src/helpers/damage-helper.spec.js index 96cbdd0d4..ad5f8f878 100644 --- a/src/helpers/damage-helper.spec.js +++ b/src/helpers/damage-helper.spec.js @@ -13,30 +13,4 @@ jest.mock("@/store", () => ({ const damage = getDamageString(); expect(damage).toEqual("Windshield") }); - }); - - // describe("damage-helper.js", () => { - // it("Should return false if no mismatches between each array", async () => { - // const updatedOptions = { - // data: { - // windshieldOptions: {availableReplacementOptions: ["windshield"]} - // } - // } - // baseMixin.methods.dispatchStoreAction = jest.fn().mockImplementation(()=> { - // return updatedOptions; - // }); - // const misMatch = await isGlassAvailableForCarId(); - // expect(misMatch).toEqual(false); - // }); - // }); - - // describe("damage-helper.js", () => { - // it("Should return true if there are any mismatches between arrays", () => { - // const newOptions = { - // windshieldOptions: {availableReplacementOptions: ["window"]} - // } - // const currentOptions = [{location: "Windshield", name: "windshield"}]; - // const misMatch = compareGlassOptions(newOptions, currentOptions); - // expect(misMatch).toEqual(true); - // }); - // }); \ No newline at end of file + }); \ No newline at end of file diff --git a/src/helpers/heritage-integration/navigation-helper.js b/src/helpers/heritage-integration/navigation-helper.js index 989dec817..49c4ab354 100644 --- a/src/helpers/heritage-integration/navigation-helper.js +++ b/src/helpers/heritage-integration/navigation-helper.js @@ -95,7 +95,7 @@ async function getLatestPageForRedirection() { if (store.getters.vehicle.vin) { return fmgPageValues.LICENSE_PLATE_LOOKUP; } else { - return fmgPageValues.ESTIMATE; + return fmgPageValues.VIN_LOOKUP; } } } @@ -134,7 +134,7 @@ function overrideYmmsDirectionIfNeeded(toRoute) { /* istanbul ignore next */ function isVinRelatedPage(toRoute) { const fmgPageValue = toRoute.query[queryStrings.FMG_PAGE]; - + return fmgPageValue === fmgPageValues.VIN_LOOKUP || fmgPageValue === fmgPageValues.LICENSE_PLATE_LOOKUP || fmgPageValue === fmgPageValues.ADDRESS_LOOKUP || diff --git a/src/helpers/heritage-integration/navigation-helper.spec.js b/src/helpers/heritage-integration/navigation-helper.spec.js index 17561ba52..de5df0239 100644 --- a/src/helpers/heritage-integration/navigation-helper.spec.js +++ b/src/helpers/heritage-integration/navigation-helper.spec.js @@ -283,7 +283,7 @@ describe("getPageToRouteExistingOrderTo", () => { const result = await getPageToRouteExistingOrderTo(toRoute, false); //Assert - expect(result).toBe('estimate'); + expect(result).toBe('vin-lookup'); }); test("getPageToRouteExistingOrderTo, existing order, should return heritage", async () => { diff --git a/src/layouts/address-lookup/address-lookup.spec.js1 b/src/layouts/address-lookup/address-lookup.spec.js1 index 43f3649b0..4443100c3 100644 --- a/src/layouts/address-lookup/address-lookup.spec.js1 +++ b/src/layouts/address-lookup/address-lookup.spec.js1 @@ -118,7 +118,7 @@ describe("address-lookup.vue", () => { }, }) { //Mock api responses - baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); + baseMixin.methods.dispatchStoreAction = jest.fn(); const apiResponses = { cmsContent: { FunnelSubHeaderWidget: pageHeaderWidgetHeaderText, diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js index 8253a97b5..533a8e38d 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.spec.js +++ b/src/layouts/license-plate-lookup/license-plate-lookup.spec.js @@ -51,7 +51,7 @@ jest.mock("@/store", () => ({ }, eventBusItem: jest.fn(), damage: { - glassToReplace: [] + glassToReplace: [] }, }, })); @@ -144,4 +144,4 @@ function setupMocks({ wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent; return { wrapper, apiPromise }; -} \ No newline at end of file +} diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index ecee25f79..59be19cbd 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -11,17 +11,17 @@
- +
- +
- +
+ \ No newline at end of file diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index 4064da145..36dfaf137 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -31,10 +31,11 @@
- - { + const vehicleLookup = await this.lookupVehicle(this.vin).catch(() => { + this.vinNotFound = true; this.$refs.funnelFooter.removeLoader(); - this.noMatchAlert = true; + this.noServiceZip = false; return; }); - if (vinLookup.data.carId !== store.getters.vehicle.carId) { - this.customAlertData.vehicleInfo = vinLookup.data.vehicle; + this.isCarIdDifferent = vehicleLookup.data.carId !== store.getters.vehicle.carId; + + if (this.isCarIdDifferent && (vehicleLookup.data.carId !== this.previouslyEnteredCarId)) { + this.previouslyEnteredCarId = vehicleLookup.data.carId; + this.noServiceZip = false; + this.customAlertData.vehicleInfo = vehicleLookup.data; + this.$refs.funnelFooter.updateButtonText(`Continue with ${vehicleLookup.data.year} ${vehicleLookup.data.make} ${vehicleLookup.data.model}`); + this.isVinValid = true; + this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vehicleLookup.data.carId); this.$refs.funnelFooter.removeLoader(); - this.foundWindshieldAlert = true; + this.matchedDifferentVehicle = true; return; } - const carInfo = this.vinDoesNotMatchCarId ? vinLookup.data : store.getters.vehicle; - this.updateStore(carInfo) - const partsData = await baseMixin.methods.dispatchStoreAction( - this.storeActions.GET_PARTS_OR_QUESTIONS, - { - carId: store.getters.vehicle.carId, - glassArray: store.getters.damage.glassToReplace, - zipCode: this.zip, - vin: vinLookup.vin - }, - false - ); - this.navigateForward(partsData); + this.updateStore(vehicleLookup.data); + this.navigateForward(); }, - navigateForward(partsData){ - if(partsData.data.partsOrQuestions[0].partQuestions && partsData.data.partsOrQuestions[0].partQuestions.length > 0){ - this.$router.navigateAfterSave(this.navigationScenarios.CONTINUING_WITH_PARTS_QUESTION, this.$route, {}, {}, partsData.data); + navigateForward(){ + if(this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle){ + this.$router.navigateAfterSave(this.navigationScenarios.CLICKED_FORWARD, this.$route, {}, { displayVehicleChangeAlert: true }, {}); return; - } else if((!partsData.data.partsOrQuestions[0].partQuestions || partsData.data.partsOrQuestions[0].partQuestions.length < 1) && partsData.data.partsOrQuestions[0].parts.length > 1) { - this.$router.navigateAfterSave(this.navigationScenarios.CONTINUING_WITH_MULTIPLE_PARTS, this.$route, {}, {}, partsData.data); - return; } else { - this.$router.navigate(this.navigationScenarios.CONTINUING_WITH_SINGLE_PART, this.$route); + navigateAfterSaveToHeritageFunnel(this.$route); + return; } }, validateZip(zip) { @@ -231,16 +262,16 @@ export default { { zip } ); }, - lookupVin(vin) { + lookupVehicle(vin) { return baseMixin.methods.dispatchStoreAction( storeActions.LOOKUP_VEHICLE_BY_VIN, { vin } ); }, updateStore(carInfo) { - // if(vehicleDamage){ - // store.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); - // } + if(this.isCarIdDifferent && !this.isSelectedGlassAvailableForVehicle){ + store.dispatch(storeActions.RESET_DAMAGE_STATE_AND_DEPENDENCIES); + } store.commit(storeMutations.UPDATE_VEHICLE_VIN, this.vin); store.commit(storeMutations.UPDATE_YEAR, carInfo.year); store.commit(storeMutations.UPDATE_MAKE, carInfo.make); @@ -250,16 +281,11 @@ export default { store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, carInfo.category); store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_URL, carInfo.imageUrl); store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_VIF_NUMBER, carInfo.imageVifNumber); - store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, carInfo.imageColor); + store.commit(storeMutations.UPDATE_VEHICLE_IMAGE_COLOR, carInfo.imageVifNumber); store.commit(storeMutations.UPDATE_SERVICE_LOCATION_ZIP, this.zip); store.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, this.email); }, }, - computed: { - isVinFieldReadOnly(){ - return this.$store.getters.payment.insuranceCoverage.isVerified; - } - }, components: { Form, funnelHeader, diff --git a/src/mixins/base-mixin.spec.js b/src/mixins/base-mixin.spec.js index f343336c3..b0c8b26f3 100644 --- a/src/mixins/base-mixin.spec.js +++ b/src/mixins/base-mixin.spec.js @@ -6,7 +6,7 @@ import { vehicleCategories } from "@/constants/vehicle-categories.js"; import store from "@/store"; describe("baseMixin.js", () => { - test("dispatchNonblockingStoreAction: calls dispatch with type and payload", () => { + test("dispatchStoreAction: calls dispatch with type and payload", () => { const mixIn = getMixInInstance({}); const type = ""; const payload = {}; @@ -16,7 +16,7 @@ describe("baseMixin.js", () => { expect(store.dispatch).toBeCalledWith(type, payload); }); - test("dispatchNonblockingStoreAction: calls dispatch with type and payload, handles Uri encode", () => { + test("dispatchStoreAction: calls dispatch with type and payload, handles Uri encode", () => { const mixIn = getMixInInstance({}); const type = ""; const payload = { make: "Alfa Romeo/Chrysler" }; diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js index f2c9aef3d..8ae57d043 100644 --- a/src/router/router-constants/routing-table.js +++ b/src/router/router-constants/routing-table.js @@ -67,7 +67,7 @@ const routingTable = [ }, { scenario: navigationScenarios.SELECTED_DAMAGE_WITH_MULTIPLE_PARTS, - destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS, + destinationFmgPageValue: fmgPageValues.VIN_LOOKUP, }, { scenario: navigationScenarios.SELECTED_DAMAGE_WITH_PART_QUESTIONS, @@ -124,6 +124,10 @@ const routingTable = [ scenario: navigationScenarios.VIN_LOOKUP, destinationFmgPageValue: fmgPageValues.PART_QUESTIONS, }, + { + scenario: navigationScenarios.CLICKED_FORWARD, + destinationFmgPageValue: fmgPageValues.ESTIMATE, + } ], }, { diff --git a/src/store/index.js b/src/store/index.js index 60c2f6435..66005abd5 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -147,14 +147,14 @@ export const mutations = { updateServiceLocationZip(state, serviceLocationZip){ state.order.serviceLocation.zip = serviceLocationZip; }, - updateRegistrationCity(state, registrationCity){ - state.order.vehicle.registration.city = registrationCity; + updateRegistrationCity(state, serviceCity){ + state.order.serviceLocation.city = serviceCity; }, updateRegistrationFirstName(state, firstName){ - state.order.vehicle.registration.firstName = firstName; + state.order.serviceLocation.firstName = firstName; }, updateRegistrationLastName(state, lastName){ - state.order.vehicle.registration.lastName = lastName; + state.order.serviceLocation.lastName = lastName; }, updateCustomerEmailAddress(state, customerEmailAddress){ state.order.customer.emailAddress = customerEmailAddress; @@ -303,13 +303,13 @@ export const actions = { method: endpoints.LookupVinByAddress.method, endpoint: endpoints.LookupVinByAddress.url, payload: { - licenseLastName: licenseLastName, + licenseLastName: licenseLastName, licenseStreetAddress: licenseStreetAddress, licenseZip: licenseZip, licenseState: licenseState }, }); - }, + }, getVehicleMakes(context, { year }) { return globalMethods.callHttpClient({ method: endpoints.GetVehicleMakes.method, @@ -466,7 +466,7 @@ export const actions = { payload: {} }); }, - + // Parts API Actions getPartsOrQuestions(context, { carId, glassArray, zipCode, vin = '' }) { diff --git a/vue.config.js b/vue.config.js index b58adc020..99c9cd754 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,4 +1,4 @@ -process.env.VUE_APP_CONSUMER_API_GATEWAY = +process.env.VUE_APP_CONSUMER_CF_DISTRO = "https://consumerapidev.safelite.com"; process.env.VUE_APP_HERITAGE_FUNNEL = "http://localhost:38000/default.aspx"; diff --git a/vue.release.config.js b/vue.release.config.js index bb6a6194e..8c705b074 100644 --- a/vue.release.config.js +++ b/vue.release.config.js @@ -1,4 +1,4 @@ -process.env.VUE_APP_CONSUMER_API_GATEWAY = "__VUE_APP_CONSUMER_API_GATEWAY__"; +process.env.VUE_APP_CONSUMER_CF_DISTRO = "__VUE_APP_CONSUMER_CF_DISTRO__"; process.env.VUE_APP_GOOGLE_PLACES_API_KEY = "__VUE_APP_GOOGLE_PLACES_API_KEY__"; process.env.VUE_APP_HERITAGE_FUNNEL = "__VUE_APP_HERITAGE_FUNNEL__";