Merge pull request #3301 from Safelite/feature/CASH-3105
CASH-3105 - Add Recalibration acknowledgement modal
This commit is contained in:
commit
2d3a9af49e
2 changed files with 135 additions and 1 deletions
|
|
@ -28,6 +28,7 @@ jest.mock("@/store", () => ({
|
|||
damage: { isRepair: false },
|
||||
lineItems: { glassParts: [] },
|
||||
policy: { isItac: false, isNoComp: false },
|
||||
isRecalAcknowledgedForScheduling: "",
|
||||
},
|
||||
lineItems: { supportingItems: [] },
|
||||
applicationUser: {
|
||||
|
|
@ -84,6 +85,7 @@ function setupMocks({ isAppleBrowser = false } = {}) {
|
|||
CLICKED_FORWARD: "clickedForward",
|
||||
CLICKED_FORWARD_WITH_MOBILE_SERVICE: "clickedForwardWithMobileService",
|
||||
CLICKED_BACK: "clickedBack",
|
||||
ZIP_CODE_CHANGED_RECAL_ACK: "ZIP_CODE_CHANGED_RECAL_ACK",
|
||||
};
|
||||
},
|
||||
pageName() {
|
||||
|
|
@ -283,6 +285,36 @@ describe("scheduling.vue", () => {
|
|||
expect(wrapper.vm.$refs.schedulingZipSearch.focusZipInput).toHaveBeenCalled();
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test("navigates to service-zip when zip changes and recal acknowledgement applies", async () => {
|
||||
store.getters.order.lineItems = {
|
||||
glassParts: [
|
||||
{
|
||||
partType: "WINDSHIELD",
|
||||
requiresRecalibration: true,
|
||||
canSafeliteRecalibrate: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
try {
|
||||
const { wrapper } = setupMocks();
|
||||
await wrapper.setData({
|
||||
isRecalAcknowledgedForScheduling: "",
|
||||
isLoadingDates: false,
|
||||
});
|
||||
|
||||
await wrapper.vm.onZipSearched({ zipCode: "44101", billToAccountNumber: "87291" });
|
||||
|
||||
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalledWith(
|
||||
"ZIP_CODE_CHANGED_RECAL_ACK",
|
||||
"scheduling"
|
||||
);
|
||||
expect(wrapper.vm.isLoadingDates).toBe(false);
|
||||
wrapper.unmount();
|
||||
} finally {
|
||||
store.getters.order.lineItems = { glassParts: [] };
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("forwardButtonAction", () => {
|
||||
|
|
@ -413,6 +445,56 @@ describe("scheduling.vue", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("forwardButtonAction (recal acknowledgement)", () => {
|
||||
test("opens recal modal and does not navigate when required", async () => {
|
||||
store.getters.order.lineItems = {
|
||||
glassParts: [
|
||||
{
|
||||
partType: "WINDSHIELD",
|
||||
requiresRecalibration: true,
|
||||
canSafeliteRecalibrate: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
const { wrapper } = setupMocks();
|
||||
wrapper.vm.$refs.navbar.removeLoader = jest.fn();
|
||||
wrapper.vm.$refs.recalAckModal.openModal = jest.fn();
|
||||
await wrapper.setData({ isRecalAcknowledgedForScheduling: "" });
|
||||
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
|
||||
expect(wrapper.vm.$refs.recalAckModal.openModal).toHaveBeenCalled();
|
||||
expect(wrapper.vm.$router.navigateWithSaving).not.toHaveBeenCalled();
|
||||
wrapper.unmount();
|
||||
store.getters.order.lineItems = { glassParts: [] };
|
||||
});
|
||||
|
||||
test("navigates forward after recal acknowledgement is saved", async () => {
|
||||
const { wrapper } = setupMocks();
|
||||
await wrapper.setData({ isRecalAcknowledgedForScheduling: "Yes" });
|
||||
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(
|
||||
"saveIsRecalAcknowledgedForScheduling",
|
||||
"Yes"
|
||||
);
|
||||
expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
test("onRecalAcknowledged sets acknowledgement and continues forward", async () => {
|
||||
const { wrapper } = setupMocks();
|
||||
wrapper.vm.forwardButtonAction = jest.fn();
|
||||
|
||||
wrapper.vm.onRecalAcknowledged("Yes");
|
||||
|
||||
expect(wrapper.vm.isRecalAcknowledgedForScheduling).toBe("Yes");
|
||||
expect(wrapper.vm.forwardButtonAction).toHaveBeenCalled();
|
||||
wrapper.unmount();
|
||||
});
|
||||
});
|
||||
|
||||
describe("in-shop Maps link", () => {
|
||||
const address = {
|
||||
city: "Lewis Center",
|
||||
|
|
|
|||
|
|
@ -84,6 +84,12 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<recalAckModal
|
||||
modalWidgetName="RecalAckModalWidget"
|
||||
agreementWidgetName="RecalAgreementQuestionWidget"
|
||||
groupName="recalAckGroup"
|
||||
@recalAcknowledged="onRecalAcknowledged"
|
||||
ref="recalAckModal" />
|
||||
</Form>
|
||||
</template>
|
||||
|
||||
|
|
@ -98,15 +104,21 @@ import inshopSchedulingCard from "@/layouts/scheduling/inshop-scheduling-card/in
|
|||
import interceptOverlay from "@/ux-components/intercept-overlay/intercept-overlay";
|
||||
import waitlistQuestion from "@/layouts/scheduling/waitlist-question/waitlist-question";
|
||||
import schedulingZipSearch from "@/layouts/scheduling/scheduling-zip-search/scheduling-zip-search";
|
||||
import recalAckModal from "@/layouts/schedule/recal-ack-modal/recal-ack-modal.vue";
|
||||
import textLink from "@/ux-components/text-link/text-link";
|
||||
import store from "@/store";
|
||||
import { storeActions } from "@/constants/store-actions";
|
||||
import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from "@/constants/schedule-constants";
|
||||
import {
|
||||
AppointmentTypeStrings,
|
||||
PREMIUM_FEE_PART_TYPE,
|
||||
RECAL_ACK_YES,
|
||||
} from "@/constants/schedule-constants";
|
||||
import { isDropOffRouteCode } from "@/layouts/schedule/helpers/schedule-helper";
|
||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
||||
import { getDisplayTextForDurationLength } from "@/helpers/duration-length-helper";
|
||||
import { partTypeStrings } from "@/constants/part-type-strings";
|
||||
import {
|
||||
flushPagePrereqsLogs,
|
||||
hasServiceZipInfo,
|
||||
|
|
@ -394,6 +406,8 @@ export default {
|
|||
zipSearchCode: store.getters.order.serviceLocation.zipCode ?? "",
|
||||
datePickerKey: 0,
|
||||
billToAccountNumber: store.getters.order.payment?.billToAccountNumber ?? null,
|
||||
isRecalAcknowledgedForScheduling:
|
||||
store.getters.order.isRecalAcknowledgedForScheduling ?? "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -503,6 +517,15 @@ export default {
|
|||
this.$refs.schedulingZipSearch?.focusZipInput();
|
||||
},
|
||||
async onZipSearched({ zipCode, billToAccountNumber }) {
|
||||
// When recal ack applies, changing zip must re-run parts selection via service-zip.
|
||||
if (this.shouldShowRecalAckModal()) {
|
||||
this.$router.navigateWithSaving(
|
||||
this.navigationScenarios.ZIP_CODE_CHANGED_RECAL_ACK,
|
||||
this.pageName
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
this.billToAccountNumber = billToAccountNumber;
|
||||
this.isLoadingDates = true;
|
||||
try {
|
||||
|
|
@ -731,9 +754,20 @@ export default {
|
|||
);
|
||||
},
|
||||
async forwardButtonAction() {
|
||||
if (this.shouldShowRecalAckModal()) {
|
||||
this.$refs.navbar.removeLoader();
|
||||
this.$refs.recalAckModal.openModal();
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedScheduling = this.selectedScheduling;
|
||||
const selectedDate = this.selectedDate;
|
||||
|
||||
await store.dispatch(
|
||||
storeActions.SAVE_IS_RECAL_ACKNOWLEDGED_FOR_SCHEDULING,
|
||||
this.isRecalAcknowledgedForScheduling
|
||||
);
|
||||
|
||||
const appointmentType = this.getInShopOrDropOffApptType(selectedScheduling);
|
||||
const selectedProvider = this.getSelectedProvider(appointmentType, selectedScheduling);
|
||||
const serviceLocation = store.getters.order.serviceLocation;
|
||||
|
|
@ -826,6 +860,23 @@ export default {
|
|||
);
|
||||
}
|
||||
},
|
||||
shouldShowRecalAckModal() {
|
||||
if (this.isRecalAcknowledgedForScheduling === RECAL_ACK_YES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const glassParts = store.getters.order.lineItems?.glassParts ?? [];
|
||||
return glassParts.some(
|
||||
(part) =>
|
||||
part.partType === partTypeStrings.WINDSHIELD &&
|
||||
part.requiresRecalibration === true &&
|
||||
part.canSafeliteRecalibrate === false
|
||||
);
|
||||
},
|
||||
onRecalAcknowledged(isAcknowledged) {
|
||||
this.isRecalAcknowledgedForScheduling = isAcknowledged;
|
||||
this.forwardButtonAction();
|
||||
},
|
||||
},
|
||||
components: {
|
||||
funnelHeader,
|
||||
|
|
@ -838,6 +889,7 @@ export default {
|
|||
interceptOverlay,
|
||||
waitlistQuestion,
|
||||
schedulingZipSearch,
|
||||
recalAckModal,
|
||||
textLink,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue