From d53b7e276c0f01c2ac913457f0e909e227114d02 Mon Sep 17 00:00:00 2001 From: Jason Wheeler Date: Tue, 10 Jan 2023 09:07:35 -0500 Subject: [PATCH] check in so I can pull develop into this branch. --- src/constants/application-config.js | 1 + src/constants/error-messages.js | 4 +- .../address-lookup/address-lookup.spec.js | 730 ++++++++++++++++++ src/layouts/address-lookup/address-lookup.vue | 531 +++++++++++-- .../address-questions.spec.js | 590 ++++++++++++++ .../address-questions/address-questions.vue | 403 ++++++++++ .../customer-questions.spec.js | 33 + .../customer-questions/customer-questions.vue | 102 +++ src/mixins/vin-pages-mixin.js | 15 + src/mixins/vin-pages-mixin.spec.js | 70 ++ src/store/index.js | 3 + vue.config.js | 2 + 12 files changed, 2404 insertions(+), 80 deletions(-) create mode 100644 src/layouts/address-lookup/address-lookup.spec.js create mode 100644 src/layouts/address-lookup/customer-questions/address-questions/address-questions.spec.js create mode 100644 src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue create mode 100644 src/layouts/address-lookup/customer-questions/customer-questions.spec.js create mode 100644 src/layouts/address-lookup/customer-questions/customer-questions.vue create mode 100644 src/mixins/vin-pages-mixin.js create mode 100644 src/mixins/vin-pages-mixin.spec.js diff --git a/src/constants/application-config.js b/src/constants/application-config.js index 51496b9f..a3baacb2 100644 --- a/src/constants/application-config.js +++ b/src/constants/application-config.js @@ -8,6 +8,7 @@ const applicationConfig = { SITE_ENTRY_TRIGGER_VALUE: "SelfService", APPLICATION_ABBREVIATION: "iss", PAGE_QUERYSTRING: 'issPage', + GOOGLE_PLACES_API_KEY: process.env.VUE_APP_GOOGLE_PLACES_API_KEY, }; export { applicationConfig }; \ No newline at end of file diff --git a/src/constants/error-messages.js b/src/constants/error-messages.js index 19dda7e8..6c206946 100644 --- a/src/constants/error-messages.js +++ b/src/constants/error-messages.js @@ -18,8 +18,8 @@ const errorMessages = { LAST_NAME_REQUIRED: "Please enter your last name", EMAIL_ADDRESS_REQUIRED: "Please enter your email address", EMAIL_ADDRESS_FORMAT: "Please enter a valid email address", - SERVICE_ZIP_REQUIRED: "Please enter your service ZIP", - SERVICE_ZIP_FORMAT: "Please enter a valid service ZIP", + SERVICE_ZIP_REQUIRED: "Please enter your ZIP", + SERVICE_ZIP_FORMAT: "Please enter a valid ZIP", VIN_REQUIRED: "Please enter your VIN", VIN_FORMAT: "Invalid VIN. Please make sure that you entered the correct 17-digit, alpha-numeric number. VINs do not contain the letters I, O, or Q", OPTION_REQUIRED: "Please select an option", diff --git a/src/layouts/address-lookup/address-lookup.spec.js b/src/layouts/address-lookup/address-lookup.spec.js new file mode 100644 index 00000000..2c4b4495 --- /dev/null +++ b/src/layouts/address-lookup/address-lookup.spec.js @@ -0,0 +1,730 @@ +// Components +import addressLookup from "@/layouts/address-lookup/address-lookup.vue"; + +// Supporting Files +import { settleAllPromises } from "@/helpers/layout-helper.js"; +import { shallowMount } from "@vue/test-utils"; +import { getMountOptions } from "@/helpers/unit-test-helper.js"; +import { storeActions } from "@/constants/store-actions"; +import { storeMutations } from "@/constants/store-mutations"; +import { navigationScenarios } from "@/router/router-constants/navigation-scenarios"; +import store from "@/store"; +import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper"; + +jest.mock("@/helpers/damage-helper", () => ({ + isGlassAvailableForCarId: jest.fn().mockImplementation(() => true), + getDamageString: jest.fn(), +})); + +jest.mock("@/helpers/heritage-integration/navigation-helper", () => ({ + navigateToHeritageFunnel: jest.fn(), +})); + +// Mock our module for promises. +jest.mock("@/helpers/layout-helper.js", () => ({ + settleAllPromises: jest.fn(), +})); + +describe("address-lookup.vue", () => { + describe("page level alerts", () => { + test("if the address is not serviceable display the Non-Serviceable Zip Alert", async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: "1234 Main St", + city: "Columbus", + state: "OH", + zipCode: "43215", + }; + + const { wrapper } = setupMocks({ + isZipValid: true, + isZipServiceable: false, + vinVehicles: [ + { + vin: "TEST_VIN", + vehicle: { + carId: "C0000", + }, + }, + ], + }); + + store.commit(storeMutations.UPDATE_CAR_ID, "CARID"); + + await wrapper.setData({ + customerQuestions: { + addressQuestions: mockRegistrationAddress, + }, + }); + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.findComponent({ ref: "alertNonServiceableZip" }).isVisible()).toBe(true); + }); + + test("if the address matches a different vehicle display the Matched Different VehicleAlert", async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: "1234 Main St", + city: "Columbus", + state: "OH", + zipCode: "43215", + }; + + const { wrapper } = setupMocks({ + isZipServiceable: true, + vinVehicles: [ + { + vehicle: { + carId: "C00000", + }, + }, + ], + }); + + store.commit(storeMutations.UPDATE_CAR_ID, "CARID2"); + + await wrapper.setData({ + customerQuestions: { + addressQuestions: mockRegistrationAddress, + }, + }); + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.findComponent({ ref: "alertMatchedDifferentVehicle" }).isVisible()).toBe( + true + ); + }); + + test("if the looking up VIN by address is not allowed in the state selected display the Vin Lookup By HomeAddress Not Allowed Alert", async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: "1234 Main St", + city: "Columbus", + state: "OH", + zipCode: "43215", + }; + + const { wrapper } = setupMocks({ + isZipServiceable: true, + isStatePermissible: false, + lookupVinbyAddressResponse: { + isStatePermissible: false, + vinVehicles: [ + { + vin: "TEST_VIN", + vehicle: { + carId: "CARID", + }, + }, + { + vin: "TEST_VIN2", + vehicle: { + carId: "CARID2", + }, + }, + ], + }, + }); + + store.commit(storeMutations.UPDATE_CAR_ID, "CARID"); + + await wrapper.setData({ + customerQuestions: { + addressQuestions: mockRegistrationAddress, + }, + }); + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect( + wrapper.findComponent({ ref: "alertVinLookupsByHomeAddressNotAllowed" }).isVisible() + ).toBe(true); + }); + + test("if no vehicles found, display Vin Not Found alert", async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: "1234 Main St", + city: "Columbus", + state: "OH", + zipCode: "43215", + }; + + const { wrapper } = setupMocks({ + isZipServiceable: true, + lookupVinbyAddressResponse: { + isStatePermissible: true, + vinVehicles: [], // Return no vehicles + }, + }); + + store.commit(storeMutations.UPDATE_CAR_ID, "CARID"); + + await wrapper.setData({ + customerQuestions: { + addressQuestions: mockRegistrationAddress, + }, + }); + + wrapper.vm.navigateForward = jest.fn(); + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.findComponent({ ref: "alertVinNotFound" }).isVisible()).toBe(true); + }); + }); + + describe("navigation", () => { + test("if the back button is clicked, navigate back", async () => { + // Arrange + const { wrapper } = setupMocks({ + isZipServiceable: true, + }); + + // Act + await wrapper.vm.backButtonAction(); + + // Assert + expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled(); + }); + + test("if the car entered matches one of the vehicles found and the zip is serviceable, navigate forward", async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: "1234 Main St", + city: "Columbus", + state: "OH", + zipCode: "43215", + }; + + const { wrapper } = setupMocks({ + isZipServiceable: true, + vinVehicles: [ + { + vehicle: { + carId: "C11111", + }, + }, + ], + }); + + await wrapper.setData({ + previouslyEnteredCarId: "C11111", + customerQuestions: { + addressQuestions: mockRegistrationAddress, + }, + }); + + wrapper.vm.navigateForward = jest.fn(); + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.vm.navigateForward).toHaveBeenCalled(); + }); + + test("if the car entered does not match any of the multiple vehicles found, navigate to address-vehicles page", async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: "1234 Main St", + city: "Columbus", + state: "OH", + zipCode: "43215", + }; + + const { wrapper } = setupMocks({ + isZipServiceable: true, + isStatePermissible: true, + vinVehicles: [ + { + vin: "TEST_VIN", + vehicle: { + carId: "CARID", + }, + }, + { + vin: "TEST_VIN2", + vehicle: { + carId: "CARID2", + }, + }, + ], + }); + + store.commit(storeMutations.UPDATE_CAR_ID, "CARID_A"); + + const carsFound = [ + { + vin: "TEST_VIN", + vehicle: { + carId: "CARID", + }, + }, + { + vin: "TEST_VIN2", + vehicle: { + carId: "CARID2", + }, + }, + ]; + + await wrapper.setData({ + customerQuestions: { + addressQuestions: mockRegistrationAddress, + }, + }); + + wrapper.vm.updateVehicleInfo = jest.fn(); + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith( + navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES, + undefined, + {}, + {}, + carsFound + ); + }); + + test("if the car entered matches one of the vehicles found but the zip is NOT serviceable, do not navigate forward", async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: "1234 Main St", + city: "Columbus", + state: "OH", + zipCode: "43215", + }; + + const { wrapper } = setupMocks({ + isZipServiceable: false, + isStatePermissible: true, + vinVehicles: [ + { + vin: "TEST_VIN", + vehicle: { + carId: "CARID", + }, + }, + { + vin: "TEST_VIN2", + vehicle: { + carId: "CARID2", + }, + }, + ], + }); + + store.commit(storeMutations.UPDATE_CAR_ID, "CARID"); + + await wrapper.setData({ + customerQuestions: { + addressQuestions: mockRegistrationAddress, + }, + }); + + wrapper.vm.navigateForward = jest.fn(); + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.vm.navigateForward).toHaveBeenCalledTimes(0); + }); + + test("if a different vehicle is found than the one entered and the selected glass is not available for that vehicle, navigate back to vehicle-damage page", async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: "1234 Main St", + city: "Columbus", + state: "OH", + zipCode: "43215", + }; + + const { wrapper } = setupMocks({ + isZipServiceable: true, + isStatePermissible: true, + }); + + await wrapper.setData({ + customerQuestions: { + addressQuestions: mockRegistrationAddress, + }, + isCarIdDifferent: true, + isSelectedGlassAvailableForVehicle: false, + }); + + let carsFound = [ + { + vin: "TEST_VIN2", + vehicle: { + carId: "C0000", + }, + }, + ]; + + // Act + await wrapper.vm.navigateForward(carsFound); + + // Assert + expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith( + navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS, + undefined, + {}, + { displayVehicleChangeAlert: true } + ); + }); + + test("single car was found and matches entered vehicle => navigateForwardWithSingleCarMatch", async () => { + // Arrange + + const carsFound = [ + { + vin: "TEST_VIN_2", + vehicle: { + carId: "C0000", + }, + }, + ]; + + const { wrapper } = setupMocks({}, {}); + wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn(); + + // Act + wrapper.vm.navigateForward(carsFound); + + // Assert + expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalledTimes(1); + }); + + test("multiple cars were found and one matches entered vehicle => navigateForwardWithSingleCarMatch", async () => { + // Arrange + const carsFound = [ + { + vin: "TEST_VIN_1", + vehicle: { + carId: "C0000", + }, + }, + { + vin: "TEST_VIN_2", + vehicle: { + carId: "CARID2", + }, + }, + { + vin: "TEST_VIN_3", + vehicle: { + carId: "CARID3", + }, + }, + ]; + + const { wrapper } = setupMocks({}); + wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn(); + + // Act + wrapper.vm.navigateForward(carsFound); + + // Assert + expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalledTimes(1); + }); + }); + + describe("registration and service zips", () => { + describe("if registration zip is serviceable", () => { + test("if registration address is provided => update service address on successful continue", async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: "1234 Main St", + city: "Columbus", + state: "OH", + zipCode: "43215", + }; + + const { wrapper } = setupMocks({ + isZipServiceable: true, + }); + + store.commit(storeMutations.UPDATE_CAR_ID, "CARID"); + + await wrapper.setData({ + customerQuestions: { + addressQuestions: mockRegistrationAddress, + }, + }); + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalledWith( + "lookupVinByAddress", + { + licenseLastName: undefined, + licenseState: "OH", + licenseStreetAddress: "1234 Main St", + licenseZip: "43215", + }, + false + ); + + expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalledWith("validateZip", { + zip: "43215", + }); + }); + }); + + describe("if registration zip is not serviceable", () => { + test("if registration address is provided and user clicks continue => show non-serviceable zip alert", async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: "1234 Main St", + city: "Columbus", + state: "OH", + zipCode: "43215", + }; + + const { wrapper } = setupMocks({ + isZipValid: true, + isZipServiceable: false, + vinVehicles: [ + { + vin: "TEST_VIN", + vehicle: { + carId: "C0000", + }, + }, + ], + }); + + store.commit(storeMutations.UPDATE_CAR_ID, "CARID"); + + await wrapper.setData({ + customerQuestions: { + addressQuestions: mockRegistrationAddress, + }, + }); + + expect(wrapper.findComponent({ ref: "alertNonServiceableZip" }).exists()).toBe( + false + ); + + // Act + await wrapper.vm.forwardButtonAction(); + + // Assert + expect(wrapper.vm.displayNonServiceableZipAlert).toBe(true); + expect(wrapper.findComponent({ ref: "alertNonServiceableZip" }).exists()).toBe( + true + ); + expect(wrapper.findComponent({ ref: "alertNonServiceableZip" }).isVisible()).toBe( + true + ); + }); + + test("if registration address, service zip are provided, and user clicks continue => don't update service address", async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: "1234 Main St", + city: "Columbus", + state: "OH", + zipCode: "43215", + }; + + const { wrapper } = setupMocks({ + isZipServiceable: false, + }); + + store.commit(storeMutations.UPDATE_CAR_ID, "CARID"); + + await wrapper.setData({ + customerQuestions: { + addressQuestions: mockRegistrationAddress, + }, + }); + + // Act + await wrapper.vm.forwardButtonAction(); + + //FIX THIS + // Assert + expect(wrapper.vm.dispatchStoreAction).not.toHaveBeenCalledWith( + storeActions.UPDATE_SERVICE_LOCATION_WITH_VEHICLE_REGISTRATION + ); + }); + + test("if registration address, service zip are provided, and user clicks continue => both zips are saved and are different", async () => { + // Arrange + const mockRegistrationAddress = { + streetAddress: "1234 Main St", + city: "Columbus", + state: "OH", + zipCode: "43215", + }; + + const { wrapper } = setupMocks({}); + wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn(); + + store.commit(storeMutations.UPDATE_CAR_ID, "CARID"); + + wrapper.vm.dispatchStoreAction = jest.fn(); + wrapper.vm.dispatchStoreAction.mockImplementation((actionName, value) => { + let data = {}; + if (actionName == storeActions.VALIDATE_ZIP) { + if (value == "43215") { + data = { + isServiceable: false, + }; + } else { + data = { + isServiceable: true, + }; + } + } else if (actionName == storeActions.LOOKUP_VIN_BY_ADDRESS) { + data = { + isStatePermissible: true, + vinVehicles: [ + { + vin: "TEST_VIN", + vehicle: { + carId: "CARID", + }, + }, + ], + }; + } + + return Promise.resolve({ data }); + }); + + await wrapper.setData({ + customerQuestions: { + addressQuestions: mockRegistrationAddress, + }, + }); + + await wrapper.vm.forwardButtonAction(); + await wrapper.setData({ + serviceZipCode: "12345", + }); + + // // Act + await wrapper.vm.forwardButtonAction(); + + // // Assert + expect(wrapper.vm.$store.getters.order.serviceLocation.zipCode).not.toEqual( + wrapper.vm.$store.getters.vehicle.registration.zipCode + ); + expect(wrapper.vm.$store.getters.vehicle.registration.zipCode).toEqual("12345"); + expect(wrapper.vm.$store.getters.order.serviceLocation.zipCode).toEqual("11111"); + }); + }); + }); +}); + +function setupMocks({ + isZipValid = true, + isZipServiceable = true, + lookupVinbyAddressResponse, + partsOrQuestions = [], + isStatePermissible = true, + vinVehicles = [], + carId = "C0000", +}) { + store.commit(storeMutations.RESET_STATE); + const wrapper = shallowMount( + addressLookup, + getMountOptions({ + actionList: [ + { + actionName: storeActions.VALIDATE_ZIP, + data: { + isValid: isZipValid, + isServiceable: isZipServiceable, + }, + }, + { + actionName: storeActions.LOOKUP_VIN_BY_ADDRESS, + data: lookupVinbyAddressResponse + ? lookupVinbyAddressResponse + : { + isStatePermissible: true, + vinVehicles: [ + { + vin: "TEST_VIN", + vehicle: { + carId: "CARID", + }, + }, + ], + }, + }, + { + actionName: storeActions.GET_PARTS_OR_QUESTIONS, + data: { + partsOrQuestions: partsOrQuestions, + }, + }, + ], + router: { + navigate: jest.fn(), + navigate: jest.fn(), + navigateWithSaving: jest.fn(), + navigateWithoutSaving: jest.fn(), + }, + store: { + getters: { + vehicle: { + carId: carId, + registration: { + licensePlate: "TESTPLATE", + zipCode: "12345", + }, + }, + order: { + customer: { + emailAddress: "test@test.com", + }, + serviceLocation: { + zipCode: "11111", + }, + }, + }, + }, + }) + ); + + const apiResponses = { + serviceZipValidationResponse: { + isValid: isZipValid, + isServiceable: isZipServiceable, + }, + vinLookupResponse: { + isStatePermissible: isStatePermissible, + vinVehicles: vinVehicles, + }, + }; + + settleAllPromises.mockImplementation(() => apiResponses); + + wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => ""); + wrapper.vm.setCmsContent = jest.fn(); + wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn(); + wrapper.vm.$refs.funnelFooter.removeLoader = jest.fn(); + + return { wrapper }; +} diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index 4dff1016..de93f09f 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -1,90 +1,465 @@ -