CASH-1524: Add Save progress SMS consent management

This commit is contained in:
credelinghuys 2026-08-03 13:20:25 -04:00
parent 9d2322e079
commit 6852896f45
5 changed files with 70 additions and 54 deletions

View file

@ -0,0 +1,10 @@
const saveProgressCmsWidgets = {
PHONE_SPECIFIC: "SaveProgressPopupWidget_PhoneSpecific",
EMAIL_SPECIFIC: "SaveProgressPopupWidget_EmailSpecific",
MODAL_PHONE_QUESTION: "SaveProgressPhoneQuestionWidget",
MODAL_EMAIL_QUESTION: "SaveProgressEmailQuestionWidget",
POPUP_PHONE_QUESTION: "SaveProgressPopupPhoneQuestionWidget",
POPUP_EMAIL_QUESTION: "SaveProgressPopupEmailQuestionWidget",
};
export { saveProgressCmsWidgets };

View file

@ -1,7 +1,8 @@
import { mount, flushPromises } from "@vue/test-utils";
import { mount } from "@vue/test-utils";
import saveProgressModalQuestion from "./save-progress-modal-question";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { storeActions } from "@/constants/store-actions";
import { saveProgressCmsWidgets } from "@/constants/save-progress-cms-widgets";
import { saveQuote } from "@/helpers/heritage-integration/order-helper.js";
import experimentMixin from "@/mixins/experiment-mixin.js";
import { experimentSettings } from "@/constants/experiments";
@ -114,14 +115,14 @@ describe("save-progress-modal-question", () => {
expect(wrapper.vm.isPhoneTabSelected).toBe(true);
});
test("should use modal-specific tab labels from CMS widgets", () => {
test("should use popup-specific tab labels from CMS widgets", () => {
const { wrapper } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
},
cmsContent: {
SaveProgressModalWidget_PhoneSpecific: { HeadlineText: "PHONE" },
SaveProgressModalWidget_EmailSpecific: { HeadlineText: "EMAIL" },
SaveProgressPopupWidget_PhoneSpecific: { HeadlineText: "PHONE" },
SaveProgressPopupWidget_EmailSpecific: { HeadlineText: "EMAIL" },
},
});
@ -131,14 +132,29 @@ describe("save-progress-modal-question", () => {
]);
});
test("should keep the legacy email disclaimer on the email tab", async () => {
test("should use the modal question CMS widgets for phone and email inputs", () => {
const { wrapper } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
},
});
expect(wrapper.vm.phoneQuestionWidgetName).toBe(
saveProgressCmsWidgets.MODAL_PHONE_QUESTION
);
expect(wrapper.vm.emailQuestionWidgetName).toBe(
saveProgressCmsWidgets.MODAL_EMAIL_QUESTION
);
});
test("should use the email-specific popup disclaimer on the email tab", async () => {
const { wrapper } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
},
cmsContent: {
SaveProgressModalWidget: { FooterText2: "Email disclaimer" },
SaveProgressModalWidget_PhoneSpecific: { BodyText: "Phone disclaimer" },
SaveProgressPopupWidget_EmailSpecific: { BodyText: "Email disclaimer" },
SaveProgressPopupWidget_PhoneSpecific: { BodyText: "Phone disclaimer" },
},
});
@ -148,14 +164,14 @@ describe("save-progress-modal-question", () => {
expect(wrapper.vm.modalDisclaimerText).toBe("Email disclaimer");
});
test("should use the phone-specific disclaimer on the phone tab", () => {
test("should use the phone-specific popup disclaimer on the phone tab", () => {
const { wrapper } = setupMocks({
props: {
modalWidgetName: "SaveProgressModalWidget",
},
cmsContent: {
SaveProgressModalWidget: { FooterText2: "Email disclaimer" },
SaveProgressModalWidget_PhoneSpecific: { BodyText: "Phone disclaimer" },
SaveProgressPopupWidget_EmailSpecific: { BodyText: "Email disclaimer" },
SaveProgressPopupWidget_PhoneSpecific: { BodyText: "Phone disclaimer" },
},
});

View file

@ -62,18 +62,13 @@
:showConsentErrors="showConsentErrors"
:showConsentManagement="showConsentManagement" />
</div>
<saveProgressQuestion
v-else
ref="saveProgressQuestion"
v-model="userInput"
:cmsWidgetName="emailQuestionWidgetName"
:isDisabled="isProgressSaved" />
</template>
<saveProgressQuestion
v-else
v-if="!showConsentManagement || !isPhoneTabSelected"
ref="saveProgressQuestion"
v-model="userInput"
cmsWidgetName="SaveProgressQuestionWidget" />
:cmsWidgetName="emailQuestionWidgetName"
:isDisabled="isProgressSaved" />
<template v-slot:modal-footer-slot>
<modalButtonMain
v-if="showConsentManagement && isPhoneTabSelected && !isProgressSaved"
@ -114,14 +109,13 @@ import {
} from "@/helpers/save-progress-sms-consent/save-progress-sms-consent-helper";
import experimentMixin from "@/mixins/experiment-mixin.js";
import { experimentSettings } from "@/constants/experiments";
import { saveProgressCmsWidgets } from "@/constants/save-progress-cms-widgets";
import { defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
const PHONE_SPECIFIC_WIDGET = "SaveProgressModalWidget_PhoneSpecific";
const EMAIL_SPECIFIC_WIDGET = "SaveProgressModalWidget_EmailSpecific";
const PHONE_QUESTION_WIDGET = "SaveProgressModalPhoneQuestionWidget";
const EMAIL_QUESTION_WIDGET = "SaveProgressQuestionWidget";
const { PHONE_SPECIFIC, EMAIL_SPECIFIC, MODAL_PHONE_QUESTION, MODAL_EMAIL_QUESTION } =
saveProgressCmsWidgets;
defineRule("save-progress-modal-phone-number-required", required(errorMessages.PHONE_REQUIRED));
@ -150,7 +144,6 @@ export default {
},
},
props: {
modelValue: Object,
modalWidgetName: String,
pageName: String,
},
@ -174,11 +167,13 @@ export default {
return this.getCmsContent(this.modalWidgetName, "FooterText");
},
modalDisclaimerText() {
if (!this.showConsentManagement || !this.isPhoneTabSelected) {
if (!this.showConsentManagement) {
return this.getCmsContent(this.modalWidgetName, "FooterText2");
}
return this.getCmsContent(PHONE_SPECIFIC_WIDGET, "BodyText");
const disclaimerWidgetName = this.isPhoneTabSelected ? PHONE_SPECIFIC : EMAIL_SPECIFIC;
return this.getCmsContent(disclaimerWidgetName, "BodyText");
},
modalName() {
return this.modalWidgetName;
@ -189,11 +184,11 @@ export default {
contactTabs() {
return [
{
label: this.getCmsContent(PHONE_SPECIFIC_WIDGET, "HeadlineText") || "Phone",
label: this.getCmsContent(PHONE_SPECIFIC, "HeadlineText") || "Phone",
value: saveProgressPopupContactMethods.PHONE,
},
{
label: this.getCmsContent(EMAIL_SPECIFIC_WIDGET, "HeadlineText") || "Email",
label: this.getCmsContent(EMAIL_SPECIFIC, "HeadlineText") || "Email",
value: saveProgressPopupContactMethods.EMAIL,
},
];
@ -202,10 +197,10 @@ export default {
return this.contactMethod === saveProgressPopupContactMethods.PHONE;
},
phoneQuestionWidgetName() {
return PHONE_QUESTION_WIDGET;
return MODAL_PHONE_QUESTION;
},
emailQuestionWidgetName() {
return EMAIL_QUESTION_WIDGET;
return MODAL_EMAIL_QUESTION;
},
},
methods: {
@ -272,19 +267,16 @@ export default {
this.$refs.phoneSendButton?.resetButtonStyle();
},
async saveProgress() {
if (this.showConsentManagement) {
await saveProgressPopupContactToStore(this.dispatchStoreAction, {
contactMethod: this.contactMethod,
userInput: this.userInput,
smsConsent: this.smsConsent,
});
} else {
await saveProgressPopupContactToStore(this.dispatchStoreAction, {
contactMethod: saveProgressPopupContactMethods.EMAIL,
userInput: this.userInput,
smsConsent: defaultSaveProgressSmsConsent(),
});
}
await saveProgressPopupContactToStore(this.dispatchStoreAction, {
contactMethod: this.showConsentManagement
? this.contactMethod
: saveProgressPopupContactMethods.EMAIL,
userInput: this.userInput,
smsConsent:
this.showConsentManagement && this.isPhoneTabSelected
? this.smsConsent
: defaultSaveProgressSmsConsent(),
});
await saveQuote({ pageNameToLog: this.pageName });
@ -486,6 +478,7 @@ export default {
flex-direction: column;
gap: 0.5rem;
margin: 0 0 1.5rem 0;
text-align: left;
}
.phone-number-question {

View file

@ -111,11 +111,10 @@ import {
import { defineRule } from "vee-validate";
import { required } from "@/helpers/validation-rules";
import { errorMessages } from "@/constants/error-messages";
import { saveProgressCmsWidgets } from "@/constants/save-progress-cms-widgets";
const PHONE_SPECIFIC_WIDGET = "SaveProgressPopupWidget_PhoneSpecific";
const EMAIL_SPECIFIC_WIDGET = "SaveProgressPopupWidget_EmailSpecific";
const PHONE_QUESTION_WIDGET = "SaveProgressPopupPhoneQuestionWidget";
const EMAIL_QUESTION_WIDGET = "SaveProgressPopupEmailQuestionWidget";
const { PHONE_SPECIFIC, EMAIL_SPECIFIC, POPUP_PHONE_QUESTION, POPUP_EMAIL_QUESTION } =
saveProgressCmsWidgets;
defineRule("phone-number-required", required(errorMessages.PHONE_REQUIRED));
@ -171,9 +170,7 @@ export default {
return this.getCmsContent(this.modalWidgetName, "FooterText");
},
modalDisclaimerText() {
const disclaimerWidgetName = this.isPhoneTabSelected
? PHONE_SPECIFIC_WIDGET
: EMAIL_SPECIFIC_WIDGET;
const disclaimerWidgetName = this.isPhoneTabSelected ? PHONE_SPECIFIC : EMAIL_SPECIFIC;
return this.getCmsContent(disclaimerWidgetName, "BodyText");
},
@ -186,11 +183,11 @@ export default {
contactTabs() {
return [
{
label: this.getCmsContent(PHONE_SPECIFIC_WIDGET, "HeadlineText") || "Phone",
label: this.getCmsContent(PHONE_SPECIFIC, "HeadlineText") || "Phone",
value: saveProgressPopupContactMethods.PHONE,
},
{
label: this.getCmsContent(EMAIL_SPECIFIC_WIDGET, "HeadlineText") || "Email",
label: this.getCmsContent(EMAIL_SPECIFIC, "HeadlineText") || "Email",
value: saveProgressPopupContactMethods.EMAIL,
},
];
@ -202,10 +199,10 @@ export default {
return this.isProgressSaved || this.isPhoneTabSelected;
},
phoneQuestionWidgetName() {
return PHONE_QUESTION_WIDGET;
return POPUP_PHONE_QUESTION;
},
emailQuestionWidgetName() {
return EMAIL_QUESTION_WIDGET;
return POPUP_EMAIL_QUESTION;
},
},
methods: {

View file

@ -81,7 +81,7 @@ import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import customerInstructions from "./customer-instructions/customer-instructions.vue";
import priceDisplay from "./price-display/price-display.vue";
import saveProgressModalQuestion from "@/fmg-components/save-progress-modal-question/save-progress-modal-question.vue";
import saveProgressModalQuestion from "@/fmg-components/save-progress-modal-question/save-progress-modal-question";
import { hasSaveProgressContactInStore } from "@/helpers/save-progress-popup-contact-helper";
import afterpayBreakout from "../payment-method/afterpay-breakout/afterpay-breakout.vue";
import modal from "@/digital-components/modal/modal";