diff --git a/src/global-methods.js b/src/global-methods.js index 9e9f7bd3..b5f784ee 100644 --- a/src/global-methods.js +++ b/src/global-methods.js @@ -21,7 +21,7 @@ export default { url: cfDistroUrl + endpoint, data: payloadAndAnalyticsData, crossDomain: true, - responseType: {}, + responseType: 'json', headers: headers, }) .then((response) => { diff --git a/src/layouts/order-confirmation/order-confirmation.vue b/src/layouts/order-confirmation/order-confirmation.vue new file mode 100644 index 00000000..2cdbc680 --- /dev/null +++ b/src/layouts/order-confirmation/order-confirmation.vue @@ -0,0 +1,69 @@ + + diff --git a/src/layouts/policy-vehicles/policy-vehicles-question/policy-vehicles-question.vue b/src/layouts/policy-vehicles/policy-vehicles-question/policy-vehicles-question.vue new file mode 100644 index 00000000..a69fb31c --- /dev/null +++ b/src/layouts/policy-vehicles/policy-vehicles-question/policy-vehicles-question.vue @@ -0,0 +1,28 @@ + + + \ No newline at end of file diff --git a/src/layouts/policy-vehicles/policy-vehicles.vue b/src/layouts/policy-vehicles/policy-vehicles.vue new file mode 100644 index 00000000..6a747bcd --- /dev/null +++ b/src/layouts/policy-vehicles/policy-vehicles.vue @@ -0,0 +1,71 @@ + + \ No newline at end of file diff --git a/src/layouts/service-location/service-location.spec.js b/src/layouts/service-location/service-location.spec.js index d402619f..6d1ba5e2 100644 --- a/src/layouts/service-location/service-location.spec.js +++ b/src/layouts/service-location/service-location.spec.js @@ -1,6 +1,34 @@ import { shallowMount } from "@vue/test-utils"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; import serviceLocation from "@/layouts/service-location/service-location.vue"; +import { getServiceabilityDetails, getZipCodeData } from "@/helpers/service-location-helper"; + +// Define Mocks +jest.mock("@/helpers/cms-content-helper", () => ({ + fetchCmsContentForPage: jest.fn(() => { + return Promise.resolve("content"); + }), +})); + +const mockGetServiceabilityDetails = (mockServiceZipCode) => { + const serviceabilityDetails = { + isGlassServiceableInshop: true, + isRecalibrationServiceableInshop: true, + isGlassServiceableMobile: true, + isRecalibrationServiceableMobile: true, + }; + + return Promise.resolve(serviceabilityDetails); +}; + +jest.mock( + "@/helpers/service-location-helper", + () => ({ + getServiceabilityDetails: jest.fn((mockServiceZipCode) => { + return mockGetServiceabilityDetails(mockServiceZipCode); + }), + }) +); const mockMixin = { methods: { @@ -26,6 +54,14 @@ const mockMixin = { }); } + if (zip === "45433") { + return Promise.resolve({ + containsMilitaryBase: true, + isValid: true, + state: "OH", + }); + } + return Promise.resolve({ containsMilitaryBase: false, isValid: false, @@ -98,6 +134,34 @@ describe("updating service zip", () => { // Assert expect(wrapper.vm.selectedAppointmentType).toStrictEqual(null); }); + + test("displays military zip message when zip is updated", () => { + // Arrange + const { wrapper } = setupMocks({}); + + const mobileLocationQuestionsComponent = wrapper.findComponent({ + ref: "mobileLocationQuestions", + }); + mobileLocationQuestionsComponent.resetComponent = jest.fn(); + + const serviceZipCodeComponent = wrapper.findComponent({ + ref: "serviceZipCodeQuestion", + }); + serviceZipCodeComponent.resetMobileFeePart = jest.fn(); + + expect(wrapper.vm.zipContainsMilitaryBase).toBe(false); + + const newServiceZipCodeQuestion = { + zipCode: "45433", + state: "OH", + }; + + // Act + serviceZipCodeComponent.vm.$emit("updated-contains-military-base", true); + + // Assert + expect(wrapper.vm.zipContainsMilitaryBase).toBe(true); + }); }); function setupMocks() diff --git a/src/layouts/service-location/service-location.vue b/src/layouts/service-location/service-location.vue index 037423df..f5652c18 100644 --- a/src/layouts/service-location/service-location.vue +++ b/src/layouts/service-location/service-location.vue @@ -12,7 +12,15 @@ + { vm.setCmsContent(resultMap.cmsContent); + vm.setData( + resultMap.zipCodeData, + resultMap.serviceabilityDetails, + ) }); }, setup() { @@ -111,7 +124,10 @@ export default { zipCode: this.mainStore.order.customer.address.zipCode, state: this.mainStore.order.customer.address.state, isServiceZipServiceable: null, + isGlassServiceableMobile: null, + isRecalibrationServiceableMobile: null, selectedAppointmentType: "", + zipContainsMilitaryBase: false, }; }, computed: { @@ -138,6 +154,16 @@ export default { this.$nextTick(); }, + }, + isServiceableMobile() { + if (this.isRecalibrationServiceableMobile !== null) { + return this.isGlassServiceableMobile && this.isRecalibrationServiceableMobile; + } else { + return this.isGlassServiceableMobile; + } + }, + displayMilitaryZipAlert() { + return this.zipContainsMilitaryBase && this.isServiceableMobile; } }, methods: { @@ -154,7 +180,30 @@ export default { //validate and save data here this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD, this.$route); }, - resetDependentState() {}, + resetDependentState() { + + }, + setData(zipCodeData, serviceabilityDetails) { + if (zipCodeData) { + this.zipContainsMilitaryBase = zipCodeData.containsMilitaryBase; + } + if (serviceabilityDetails) { + this.setServiceabilityDetails(serviceabilityDetails); + } + }, + setContainsMilitaryBase(val) { + if (this.zipContainsMilitaryBase !== val) { + this.zipContainsMilitaryBase = val; + } + }, + setServiceabilityDetails(serviceabilityDetails) { + this.isGlassServiceableInshop = serviceabilityDetails.isGlassServiceableInshop; + this.isRecalibrationServiceableInshop = + serviceabilityDetails.isRecalibrationServiceableInshop; + this.isGlassServiceableMobile = serviceabilityDetails.isGlassServiceableMobile; + this.isRecalibrationServiceableMobile = + serviceabilityDetails.isRecalibrationServiceableMobile; + }, }, components: { siteFooter, @@ -163,6 +212,7 @@ export default { buttonQuestion, Form, serviceZipModalQuestion, + alert }, }; diff --git a/src/layouts/service-packages/service-package-question/service-package-question.vue b/src/layouts/service-packages/service-package-question/service-package-question.vue index ede27160..1a44ba9b 100644 --- a/src/layouts/service-packages/service-package-question/service-package-question.vue +++ b/src/layouts/service-packages/service-package-question/service-package-question.vue @@ -24,6 +24,7 @@ }; export default { name: 'servicePackageQuestion', + emits: ['vapsItemsSelected'], props: { cmsWidgetName: String, groupName: String, @@ -34,16 +35,10 @@ data() { return { servicePackageRadio: servicePackageRadio, - selectedPackageName: null + selectedPackageName: packageNames.TIER_ONE }; }, watch: { - availableLineItems() { - const store = useMainStore(); - if (this.allGlassPartsAndSupportingItemsHavePrices(store.order.lineItems)) { - this.selectDefaultPackage(); - } - }, selectedPackageName(newValue) { const VapsProductsInSelectedPackage = this.getVapsLineItemsForSelectedPackage(newValue); this.$emit('vapsItemsSelected', VapsProductsInSelectedPackage); @@ -51,10 +46,14 @@ }, computed: { nullSafeAvailableLineItems() { + if (this.availableLineItems?.lineItems) { + return this.availableLineItems.lineItems; + } + return this.availableLineItems ?? []; }, servicePackageAnswers() { - if (!this.cmsWidgetName) return {}; + if (!this.cmsWidgetName) return []; const cmsAnswersContent = [ { Name: 'TierOne', @@ -84,6 +83,9 @@ )); return modifiedAnswers; }, + isRecalibrationOnOrder() { + return this.lineItemsContainsPartType(partTypeStrings.RECALIBRATION); + }, frontWipersApplicableForTierTwo() { const store = useMainStore(); const frontWipersAreAvailable = this.lineItemsContainsPartType( @@ -205,50 +207,6 @@ }); return vapsPrice; }, - selectDefaultPackage() { - const store = useMainStore(); - const vapsFromStore = store.lineItems.vaps; - let lowestTierForPackage = packageNames.TIER_ONE; - if (vapsFromStore?.length > 0) { - vapsFromStore.every((vapsItem) => { - let lowestTierForThisItem = this.getLowestTierForThisItem(vapsItem); - if (lowestTierForThisItem === packageNames.TIER_THREE) { - lowestTierForPackage = packageNames.TIER_THREE; - return false; - } else if (lowestTierForThisItem === packageNames.TIER_TWO) { - lowestTierForPackage = packageNames.TIER_TWO; - return true; - } else { - return true; - } - }); - } - this.selectedPackageName = lowestTierForPackage; - }, - allGlassPartsAndSupportingItemsHavePrices(lineItems) { - if (lineItems?.glassParts) { - for (let i = 0; i < lineItems.glassParts.length; i++) { - if (this.priceIsNullOrZero(lineItems.glassParts[i])) { - return false; - } - } - } - if (lineItems?.supportingItems) { - for (let i = 0; i < lineItems.supportingItems.length; i++) { - if (this.priceIsNullOrZero(lineItems.supportingItems[i])) { - return false; - } - } - } - return true; - }, - priceIsNullOrZero(lineItem) { - return ( - (lineItem.kitPrice == null || lineItem.kitPrice == 0) && - (lineItem.laborAmount == null || lineItem.laborAmount == 0) && - (lineItem.sellingPrice == null || lineItem.sellingPrice == 0) - ); - }, getLowestTierForThisItem(vapsItem) { let lowestTierForThisItem = null; switch (vapsItem.partType) { @@ -345,7 +303,7 @@ return !!glassLocationMatches.length; }, getTotalLineItemPrice(lineItem) { - return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice + return lineItem.kitPrice + lineItem.laborAmount + lineItem.sellingPrice; } }, components: { diff --git a/src/layouts/service-packages/service-package-question/service-package-radio/service-package-radio.vue b/src/layouts/service-packages/service-package-question/service-package-radio/service-package-radio.vue index c32dd9d3..fbf3f111 100644 --- a/src/layouts/service-packages/service-package-question/service-package-radio/service-package-radio.vue +++ b/src/layouts/service-packages/service-package-question/service-package-radio/service-package-radio.vue @@ -1,5 +1,5 @@