Merge pull request #2470 from Safelite/feature/CASH-376

Feature/cash 376
This commit is contained in:
Matt Caimi 2025-04-30 11:43:56 -04:00 committed by GitHub
commit e585f90a4f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 83 additions and 110 deletions

View file

@ -1,70 +1,72 @@
<template> <template>
<div class="mobile-location-questions"> <transition name="fade" mode="out-in">
<div class="text-center" :id="componentId"> <div class="mobile-location-questions">
<label <div class="text-center" :id="componentId">
for="mobileLocationLinkPromptId" <label
:aria-label="mobileLocationLinkPromptText" for="mobileLocationLinkPromptId"
class="form-label fw-bold w-100 ps-4 pe-4 pt-4 text-black" :aria-label="mobileLocationLinkPromptText"
v-html="mobileLocationLinkPromptText"></label> class="form-label fw-bold w-100 ps-4 pe-4 pt-4 text-black"
<div class="update-mobile-location-text-link"> v-html="mobileLocationLinkPromptText"></label>
<textLink <div class="update-mobile-location-text-link">
ref="mobileLocationLink" <textLink
id="mobileLocationLinkPromptId" ref="mobileLocationLink"
linkType="text" id="mobileLocationLinkPromptId"
:text="mobileLocationLinkText" linkType="text"
href="#!" :text="mobileLocationLinkText"
@click-event="openModal" /> href="#!"
@click-event="openModal" />
</div>
<div v-show="errorMessage" class="row my-1 form-test-error">
<span
class="d-inline-flex small mt-0 center-error-message"
aria-atomic="true"
aria-live="polite">
{{ errorMessage }}
</span>
</div>
<textBlock
v-if="mobileFeeApplies"
:customText="mobileFeeText"
cmsWidgetName="MobileFeeDisclaimerWidget"
typeStyle="caption" />
</div> </div>
<div v-show="errorMessage" class="row my-1 form-test-error"> <modal
<span :ref="modalName"
class="d-inline-flex small mt-0 center-error-message" :headerText="modalHeaderText"
aria-atomic="true" :footerButtonText="modalFooterText"
aria-live="polite"> :onModalOpenedCallback="onModalOpened"
{{ errorMessage }} :onModalClosedCallback="onModalClosed"
</span> @isModalOpened="setModalStatus"
</div> @footer-button-event="setMobileLocation">
<textBlock <template v-if="isModalOpened">
v-if="mobileFeeApplies" <addressQuestions
:customText="mobileFeeText" ref="addressQuestions"
cmsWidgetName="MobileFeeDisclaimerWidget" v-model="internalModel.addressQuestions"
typeStyle="caption" /> captureApartmentNumberOrBusinessName="true"
preserveCityAndStateOnReset="true" />
<vehicleProtectedQuestion
ref="vehicleProtectedQuestion"
v-model="internalModel.isVehicleProtected"
cmsWidgetName="VehicleProtectedQuestionWidget" />
<textBlock cmsWidgetName="WorkspaceRequirementsWidget" typeStyle="caption" />
<alert
ref="alertInvalidZip"
v-if="displayInvalidZipAlert"
class="my-4"
cmsWidgetName="AlertInvalidZipWidget"
alertClass="alert-danger"
v-bind:isDismissible="false" />
<alert
ref="alertMismatchStateAndZip"
v-if="displayMismatchStateAndZipAlert"
class="my-4"
cmsWidgetName="AlertMismatchStateAndZipWidget"
alertClass="alert-danger"
v-bind:isDismissible="false" />
</template>
</modal>
</div> </div>
<modal </transition>
:ref="modalName"
:headerText="modalHeaderText"
:footerButtonText="modalFooterText"
:onModalOpenedCallback="onModalOpened"
:onModalClosedCallback="onModalClosed"
@isModalOpened="setModalStatus"
@footer-button-event="setMobileLocation">
<template v-if="isModalOpened">
<addressQuestions
ref="addressQuestions"
v-model="internalModel.addressQuestions"
captureApartmentNumberOrBusinessName="true"
preserveCityAndStateOnReset="true" />
<vehicleProtectedQuestion
ref="vehicleProtectedQuestion"
v-model="internalModel.isVehicleProtected"
cmsWidgetName="VehicleProtectedQuestionWidget" />
<textBlock cmsWidgetName="WorkspaceRequirementsWidget" typeStyle="caption" />
<alert
ref="alertInvalidZip"
v-if="displayInvalidZipAlert"
class="my-4"
cmsWidgetName="AlertInvalidZipWidget"
alertClass="alert-danger"
v-bind:isDismissible="false" />
<alert
ref="alertMismatchStateAndZip"
v-if="displayMismatchStateAndZipAlert"
class="my-4"
cmsWidgetName="AlertMismatchStateAndZipWidget"
alertClass="alert-danger"
v-bind:isDismissible="false" />
</template>
</modal>
</div>
</template> </template>
<script> <script>
@ -148,7 +150,6 @@ export default {
zipCode: "", zipCode: "",
}, },
isVehicleProtected: null, isVehicleProtected: null,
isMobileSelected: false,
}), }),
}, },
mobileFeePart: { mobileFeePart: {
@ -168,7 +169,17 @@ export default {
return this.getCmsContent(this.linkWidgetName, "HeaderText"); return this.getCmsContent(this.linkWidgetName, "HeaderText");
}, },
mobileLocationLinkText() { mobileLocationLinkText() {
if (this.isMobileAddressComplete()) { if (
this.addressModel.streetAddress &&
this.addressModel.streetAddress !== "" &&
this.addressModel.city &&
this.addressModel.city !== "" &&
this.addressModel.state &&
this.addressModel.state !== "" &&
this.addressModel.zipCode &&
this.addressModel.zipCode !== "" &&
this.internalModel.isVehicleProtected !== null
) {
return `${this.addressModel.streetAddress}\n${this.addressModel.city}, ${this.addressModel.state} ${this.addressModel.zipCode}`; return `${this.addressModel.streetAddress}\n${this.addressModel.city}, ${this.addressModel.state} ${this.addressModel.zipCode}`;
} }
return this.getCmsContent(this.linkWidgetName, "BodyText"); return this.getCmsContent(this.linkWidgetName, "BodyText");
@ -207,19 +218,6 @@ export default {
}, },
}, },
methods: { methods: {
isMobileAddressComplete() {
return (
this.addressModel.streetAddress &&
this.addressModel.streetAddress !== "" &&
this.addressModel.city &&
this.addressModel.city !== "" &&
this.addressModel.state &&
this.addressModel.state !== "" &&
this.addressModel.zipCode &&
this.addressModel.zipCode !== "" &&
this.internalModel.isVehicleProtected !== null
);
},
openModal() { openModal() {
this.modal.openModal(); this.modal.openModal();
}, },

View file

@ -81,16 +81,6 @@ jest.mock(
}) })
); );
jest.mock(
"@/layouts/service-location/mobile-location-modal-questions/mobile-location-modal-questions.vue",
() => ({
isMobileAddressComplete: jest.fn(() => {
return true;
}),
openModal: jest.fn(),
})
);
jest.spyOn(baseMixin.methods, "getZipCodeData").mockImplementation((serviceZipCode) => { jest.spyOn(baseMixin.methods, "getZipCodeData").mockImplementation((serviceZipCode) => {
return new Promise((resolve) => { return new Promise((resolve) => {
let mockContainsMilitaryBase = false; let mockContainsMilitaryBase = false;
@ -353,7 +343,6 @@ describe("service-location.vue", () => {
zipCode: "43054", zipCode: "43054",
}, },
isVehicleProtected: true, isVehicleProtected: true,
isMobileSelected: true,
}; };
wrapper.vm.mobileLocationQuestions = mobileLocationQuestions; wrapper.vm.mobileLocationQuestions = mobileLocationQuestions;
@ -366,7 +355,6 @@ describe("service-location.vue", () => {
zipCode: "61606", zipCode: "61606",
}, },
isVehicleProtected: null, isVehicleProtected: null,
isMobileSelected: false,
}; };
// Act // Act
@ -469,7 +457,6 @@ describe("service-location.vue", () => {
zipCode: "", zipCode: "",
}, },
isVehicleProtected: null, isVehicleProtected: null,
isMobileSelected: false,
}; };
wrapper.vm.mobileLocationQuestions = mobileLocationQuestions; wrapper.vm.mobileLocationQuestions = mobileLocationQuestions;
const newMobileLocationQuestions = { const newMobileLocationQuestions = {
@ -481,7 +468,6 @@ describe("service-location.vue", () => {
zipCode: "43054", zipCode: "43054",
}, },
isVehicleProtected: true, isVehicleProtected: true,
isMobileSelected: true,
}; };
wrapper.vm.closeModalAction = jest.fn(); wrapper.vm.closeModalAction = jest.fn();
@ -531,7 +517,6 @@ describe("service-location.vue", () => {
zipCode: "", zipCode: "",
}, },
isVehicleProtected: null, isVehicleProtected: null,
isMobileSelected: false,
mobileFeePart: null, mobileFeePart: null,
}; };
wrapper.vm.mobileLocationQuestions = mobileLocationQuestions; wrapper.vm.mobileLocationQuestions = mobileLocationQuestions;
@ -545,7 +530,6 @@ describe("service-location.vue", () => {
zipCode: "43081", zipCode: "43081",
}, },
isVehicleProtected: true, isVehicleProtected: true,
isMobileSelected: true,
mobileFeePart: null, mobileFeePart: null,
}; };
@ -609,7 +593,6 @@ describe("service-location.vue", () => {
zipCode: "43081", zipCode: "43081",
}, },
isVehicleProtected: "YesAnswer", isVehicleProtected: "YesAnswer",
isMobileSelected: true,
}; };
wrapper.vm.closeModalAction = jest.fn(); wrapper.vm.closeModalAction = jest.fn();
@ -1450,7 +1433,5 @@ function setupMocks({ mountOptionsMockData = {} }) {
const mountOptions = getMountOptions(mountOptionsMockData); const mountOptions = getMountOptions(mountOptionsMockData);
const wrapper = shallowMount(serviceLocation, mountOptions); const wrapper = shallowMount(serviceLocation, mountOptions);
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent; wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;
wrapper.vm.$refs.mobileLocationQuestions.isMobileAddressComplete = jest.fn();
wrapper.vm.$refs.mobileLocationQuestions.openModal = jest.fn();
return { wrapper, apiPromise }; return { wrapper, apiPromise };
} }

View file

@ -88,7 +88,7 @@
<div class="col-md-6 col-xl-4"> <div class="col-md-6 col-xl-4">
<mobileLocationModalQuestions <mobileLocationModalQuestions
customComponentId="mobileLocationQuestions" customComponentId="mobileLocationQuestions"
v-show="selectedAppointmentType === 'Mobile'" v-if="selectedAppointmentType === 'Mobile'"
v-model="mobileLocationQuestions" v-model="mobileLocationQuestions"
:mobileFeePart="mobileFeePart" :mobileFeePart="mobileFeePart"
:mobileFeeApplies="mobileFeeApplies" :mobileFeeApplies="mobileFeeApplies"
@ -171,12 +171,11 @@ const MOBILE_FEE_PART_TYPE = "MOBILE FEE";
// DEFINE VALIDATION RULES // DEFINE VALIDATION RULES
defineRule("mobile-location-required", (value) => { defineRule("mobile-location-required", (value) => {
if ( if (
value.isMobileSelected && !value.addressQuestions.streetAddress ||
(!value.addressQuestions.streetAddress || !value.addressQuestions.city ||
!value.addressQuestions.city || !value.addressQuestions.state ||
!value.addressQuestions.state || !value.addressQuestions.zipCode ||
!value.addressQuestions.zipCode || !value.isVehicleProtected
!value.isVehicleProtected)
) { ) {
return errorMessages.MOBILE_LOCATION_REQUIRED; return errorMessages.MOBILE_LOCATION_REQUIRED;
} }
@ -298,7 +297,6 @@ export default {
zipCode: this.zipCode, zipCode: this.zipCode,
}, },
isVehicleProtected: this.isVehicleProtected, isVehicleProtected: this.isVehicleProtected,
isMobileSelected: this.selectedAppointmentType === "Mobile",
}; };
}, },
}, },
@ -767,10 +765,6 @@ export default {
this.selectedProvider = new Provider( this.selectedProvider = new Provider(
this.shopProviderData.mobileProviderNumber this.shopProviderData.mobileProviderNumber
); );
var mobileLocationQs = this.$refs.mobileLocationQuestions;
if (!mobileLocationQs.isMobileAddressComplete()) {
mobileLocationQs.openModal();
}
} else { } else {
this.selectedProvider = new Provider(); this.selectedProvider = new Provider();
} }