diff --git a/src/digital-components/date-picker/date-picker-2.vue b/src/experiment-components/date-picker-2.vue similarity index 99% rename from src/digital-components/date-picker/date-picker-2.vue rename to src/experiment-components/date-picker-2.vue index 8becf6266..414f794e0 100644 --- a/src/digital-components/date-picker/date-picker-2.vue +++ b/src/experiment-components/date-picker-2.vue @@ -99,8 +99,8 @@ // Supporting files import loader from "@/ux-components/loader/loader"; import store from "@/store"; -import { TIMINGFUNC_MAP, BUFFER_OFFSET, MONTHS_OF_YEAR } from "./mixins/constants"; -import { selectableDaysOptions, requiredParameter, forceTwoDigitString } from "./mixins/helpers"; +import { TIMINGFUNC_MAP, BUFFER_OFFSET, MONTHS_OF_YEAR } from "@/digital-components/date-picker/mixins/constants"; +import { selectableDaysOptions, requiredParameter, forceTwoDigitString } from "@/digital-components/date-picker/mixins/helpers"; import { convertDateToDateString, convertDateStringToDate, diff --git a/src/experiment-components/service-package-radio.vue b/src/experiment-components/service-package-radio.vue index 8634250ab..a3bfd9937 100644 --- a/src/experiment-components/service-package-radio.vue +++ b/src/experiment-components/service-package-radio.vue @@ -5,6 +5,7 @@ :class="[ this.buttonLabelSubCopy ? 'has-subheader' : '', this.isInsuranceSelected ? 'pricing-by-day-pkg-lbl-ins' : 'pricing-by-day-pkg-lbl', + !this.additionalButtonData.servicePackageDiscount ? 'adjust-top' : '', ]" for="testradio">
@@ -193,7 +194,7 @@ export default { position: absolute; left: -9999px; - + .package-label.pricing-by-day-pkg-lbl { + + .package-label.pricing-by-day-pkg-lbl.adjust-top { /* Copying a component for an experiment will cause duplication of css classes. This can cause problems if you want change the value of something only for the experiment version of the component. So added a more specific selector for the parts I want to change diff --git a/src/helpers/recal-helper.js b/src/helpers/recal-helper.js index c73755e8f..d43da5d34 100644 --- a/src/helpers/recal-helper.js +++ b/src/helpers/recal-helper.js @@ -58,3 +58,15 @@ export function getTopLevelPartsWithRecal(lineItems) { return lineItems.filter((li) => isRecalPartOrHasChildRecalPart(li)); } + +export function getRecalPartNumbers(glassPartsArray) { + if (glassPartsArray && glassPartsArray.length > 0) { + const topLevel = glassPartsArray.filter((gp) => isRecalPart(gp)).map((gp) => gp.partNumber); + + const children = glassPartsArray.map((gp) => getRecalPartNumbers(gp.childParts)).flat(); + + return [...topLevel, ...children]; + } else { + return []; + } +} diff --git a/src/layouts/address-lookup/address-lookup.vue b/src/layouts/address-lookup/address-lookup.vue index e069ee48d..08f602fb4 100644 --- a/src/layouts/address-lookup/address-lookup.vue +++ b/src/layouts/address-lookup/address-lookup.vue @@ -357,15 +357,18 @@ export default { false ); - if (vinPagesMixin.methods.isPhoneNumber(this.customerQuestions.emailOrSms)) { - const phone = this.customerQuestions.emailOrSms.replace(/[()]/g, ""); - await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); - } else { - await this.dispatchStoreAction( - storeActions.SAVE_EMAIL, - this.customerQuestions.emailOrSms, - false - ); + // if no value due to field being optional, blank both phone and email address + if (!this.customerQuestions.emailOrSms) { + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, "", false); + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, "", false); + } + else { + if (vinPagesMixin.methods.isPhoneNumber(this.customerQuestions.emailOrSms)) { + const phone = this.customerQuestions.emailOrSms.replace(/[()]/g, ""); + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); + } else { + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.customerQuestions.emailOrSms, false); + } } await this.dispatchStoreAction( diff --git a/src/layouts/insurance-company/insurance-company-spec.js b/src/layouts/insurance-company/insurance-company-spec.js deleted file mode 100644 index bd932b7d2..000000000 --- a/src/layouts/insurance-company/insurance-company-spec.js +++ /dev/null @@ -1,3 +0,0 @@ -describe("insurance-company.vue", () => { - it.todo("Some test for the future"); -}); diff --git a/src/layouts/insurance-company/insurance-company.spec.js b/src/layouts/insurance-company/insurance-company.spec.js new file mode 100644 index 000000000..b1297d13b --- /dev/null +++ b/src/layouts/insurance-company/insurance-company.spec.js @@ -0,0 +1,105 @@ +import { shallowMount } from '@vue/test-utils'; +import InsuranceCompany from '@/layouts/insurance-company/insurance-company.vue'; +import { applicationConfig } from '@/constants/application-config.js'; +import store from "@/store"; +import baseMixin from "@/mixins/base-mixin.js"; + + +jest.mock('@/store', () => ({ + getters: { + order: { + payment: { + parentAccountNumber: '12345', + }, + }, + }, + })); + +var mockRouter = { + navigateWithoutSaving: jest.fn(), + }; + + jest.mock('@/mixins/base-mixin.js', () => ({ + methods: { + navigateWithoutSaving: jest.fn(), + }, + data() { + return { + navigationScenarios: { + CLICKED_BACK: 'clicked_back', + }, + }; + }, + })); + +describe("insurance-company.vue", () => { + + beforeEach(() => { + // Reset the store's parentAccountNumber before each test + store.getters.order.payment.parentAccountNumber = '12345'; + }); + + test('should return true when parentAccountNumber matches CASH_PARENT_ACCOUNT_NUMBER', () => { + applicationConfig.CASH_PARENT_ACCOUNT_NUMBER = "12345"; + const wrapper = shallowMount(InsuranceCompany, { + global: { + mocks: { + $store: store + }, + }, + }); + + expect(wrapper.vm.isCashParentAccountNumber()).toBe(true); + }); + + test('should return false when parentAccountNumber does not match CASH_PARENT_ACCOUNT_NUMBER', () => { + applicationConfig.CASH_PARENT_ACCOUNT_NUMBER = "12345"; + store.getters.order.payment.parentAccountNumber = '67890'; + const wrapper = shallowMount(InsuranceCompany, { + global: { + mocks: { + $store: store, + }, + }, + }); + + expect(wrapper.vm.isCashParentAccountNumber()).toBe(false); + }); + + test('should call navigateWithoutSaving with { isCashSelected: true } when forceCashSelection is true', () => { + const wrapper = shallowMount(InsuranceCompany, { + global: { + mocks: { + $store: store, + $router: mockRouter, + }, + mixins: [baseMixin], + }, + }); + + + wrapper.vm.backButtonAction(true); + expect(mockRouter.navigateWithoutSaving).toHaveBeenCalledWith( + wrapper.vm.navigationScenarios.CLICKED_BACK, + wrapper.vm.$route, + { isCashSelected: true } + ); + }); + + test('should call navigateWithoutSaving with no extra parameter when forceCashSelection is false', () => { + const wrapper = shallowMount(InsuranceCompany, { + global: { + mocks: { + $store: store, + $router: mockRouter, + }, + mixins: [baseMixin], + }, + }); + wrapper.vm.backButtonAction(false); + expect(mockRouter.navigateWithoutSaving).toHaveBeenCalledWith( + wrapper.vm.navigationScenarios.CLICKED_BACK, + wrapper.vm.$route + ); + }); +}); diff --git a/src/layouts/license-plate-lookup/license-plate-lookup.vue b/src/layouts/license-plate-lookup/license-plate-lookup.vue index e1b3f721e..6f6521dde 100644 --- a/src/layouts/license-plate-lookup/license-plate-lookup.vue +++ b/src/layouts/license-plate-lookup/license-plate-lookup.vue @@ -311,11 +311,18 @@ export default { false ); - if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) { - const phone = this.emailOrSms.replace(/[()]/g, ""); - await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); - } else { - await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false); + // if no value due to field being optional, blank both phone and email address + if (!this.emailOrSms) { + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, "", false); + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, "", false); + } + else { + if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) { + const phone = this.emailOrSms.replace(/[()]/g, ""); + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); + } else { + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false); + } } await this.dispatchStoreAction( diff --git a/src/layouts/schedule/schedule.spec.js b/src/layouts/schedule/schedule.spec.js index 270da75f0..18e659ec5 100644 --- a/src/layouts/schedule/schedule.spec.js +++ b/src/layouts/schedule/schedule.spec.js @@ -7,6 +7,7 @@ import { getMountOptions } from "@/helpers/unit-test-helper.js"; import store from "@/store"; import router from "@/router"; import baseMixin from "../../mixins/base-mixin"; +import { experimentSettings } from "../../constants/experiments"; // Mock basemixin jest.mock("@/mixins/base-mixin.js", () => ({ @@ -177,6 +178,7 @@ beforeEach(() => { glassParts: [], supportingItems: [], }, + experimentSettings: {}, }; }); afterEach(() => { diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index 63a2d7d64..0853664e2 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -18,7 +18,18 @@ marginTopSizeOverride="1" /> + selectableDate.date === this.selectedDate ); }, + isPricingByDayExperiment() { + return ( + experimentMixin.methods + .getSettingValue(experimentSettings.PRICING_BY_DAY) + ?.toLowerCase() === "true" + ); + }, }, methods: { splitCopyOnCMSPlaceHolder, @@ -537,6 +558,7 @@ export default { funnelSubHeader, Form, loadingModal, + datePicker, datePicker2, locationAlerts, timeSlotModalQuestion, diff --git a/src/layouts/vin-lookup/vin-lookup.vue b/src/layouts/vin-lookup/vin-lookup.vue index 82c54d43a..2c93e7182 100644 --- a/src/layouts/vin-lookup/vin-lookup.vue +++ b/src/layouts/vin-lookup/vin-lookup.vue @@ -330,11 +330,18 @@ export default { false ); - if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) { - const phone = this.emailOrSms.replace(/[()]/g, ""); - await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); - } else { - await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false); + // if no value due to field being optional, blank both phone and email address + if (!this.emailOrSms) { + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, "", false); + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, "", false); + } + else { + if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) { + const phone = this.emailOrSms.replace(/[()]/g, ""); + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); + } else { + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false); + } } await this.dispatchStoreAction( @@ -380,11 +387,18 @@ export default { ); } - if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) { - const phone = this.emailOrSms.replace(/[()]/g, ""); - await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); - } else { - await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false); + // if no value due to field being optional, blank both phone and email address + if (!this.emailOrSms) { + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, "", false); + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, "", false); + } + else { + if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) { + const phone = this.emailOrSms.replace(/[()]/g, ""); + await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false); + } else { + await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false); + } } await this.dispatchStoreAction( diff --git a/src/store/index.js b/src/store/index.js index b69c71e15..6234f7b1a 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -46,6 +46,7 @@ import { containsRecalParts, getTopLevelPartsWithRecal, isRecalPartOrHasChildRecalPart, + getRecalPartNumbers, } from "@/helpers/recal-helper"; import { externalParameterStatus } from "@/constants/external-parameters"; import { experimentSettings } from "@/constants/experiments"; @@ -1714,10 +1715,15 @@ export const actions = { var endPoint = `${endpoints.GetMobileFeePart.url}/?serviceType=${serviceType}&facilityType=${facilityType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItacOptimized=${isItacOptimized}&zipCode=${zipCode}`; - const recalPartNumber = getRecalPartNumber(order.lineItems?.glassParts[0]); + const recalPartNumbers = getRecalPartNumbers(order.lineItems?.glassParts); const carId = order.vehicle?.carId; - if (recalPartNumber && carId) { - endPoint = `${endPoint}&partNumbers=${recalPartNumber}&carId=${carId}`; + if (recalPartNumbers && recalPartNumbers.length > 0 && carId) { + let additionalQueryParams = ``; + for (let i = 0; i < recalPartNumbers.length; i++) { + additionalQueryParams += `&partNumbers[${i}]=${recalPartNumbers[i]}`; + } + additionalQueryParams += `&carId=${carId}`; + endPoint += additionalQueryParams; } if (coverageStatus) { @@ -3798,15 +3804,3 @@ function getExternalParameterDefaultState() { function saveExternalParameterState(externalParameterState) { window.sessionStorage.setItem("externalParameterState", JSON.stringify(externalParameterState)); } - -//This function finds the recalibration part and returns the part number for it. -function getRecalPartNumber(glassPartsArray) { - const recalPart = glassPartsArray.childParts.find( - (item) => item.partType === partTypeStrings.ADAS_RECALIBRATION - ); - if (recalPart) { - return recalPart.partNumber; - } else { - return null; - } -}