Merge remote-tracking branch 'origin/develop' into feature/CASH-2815

This commit is contained in:
scottkiener-at-safelite 2026-07-15 09:35:58 -04:00
commit e7b746dd2a
10 changed files with 90 additions and 40 deletions

View file

@ -88,6 +88,7 @@ const storeActions = {
SAVE_EMAIL: "saveEmail",
SAVE_PHONE_NUMBER: "savePhoneNumber",
SAVE_IS_SMS_OPT_IN: "saveIsSmsOptIn",
SAVE_IS_SMS_MARKETING_OPT_IN: "saveIsSmsMarketingOptIn",
SAVE_WAITLIST_REQUESTED: "saveWaitListRequested",
SAVE_REGISTRATION_LICENSE_PLATE_LOOKUP: "saveRegistrationLicensePlateLookup",
SAVE_VIN: "saveVin",

View file

@ -49,6 +49,7 @@ const storeMutations = {
UPDATE_CUSTOMER_EMAIL_ADDRESS: "updateCustomerEmailAddress",
UPDATE_CUSTOMER_PHONE_NUMBER: "updateCustomerPhoneNumber",
UPDATE_CUSTOMER_IS_SMS_OPT_IN: "updateCustomerIsSmsOptin",
UPDATE_CUSTOMER_IS_SMS_MARKETING_OPT_IN: "updateCustomerIsSmsMarketingOptin",
UPDATE_CUSTOMER_DETAILS: "updateCustomerDetails",
UPDATE_CUSTOMER_WAITLIST_REQUESTED: "updateCustomerWaitListRequested",

View file

@ -10,7 +10,7 @@ jest.mock("@/helpers/heritage-integration/order-helper.js", () => ({
jest.mock("@/helpers/save-progress-sms-consent/save-progress-sms-consent-helper", () => ({
...jest.requireActual("@/helpers/save-progress-sms-consent/save-progress-sms-consent-helper"),
getSaveProgressSmsConsentConfig: jest.fn().mockResolvedValue({
getSaveProgressSmsConsentConfig: jest.fn().mockReturnValue({
copy: {
transactional: "Sign me up for updates about my upcoming service.",
marketing: "Sign me up for promotional and product offers.",

View file

@ -138,7 +138,7 @@ export default {
},
},
async mounted() {
await this.loadSmsConsentConfig();
this.loadSmsConsentConfig();
if (this.showSaveProgressPopup) this.modal.openModal();
},
@ -200,8 +200,8 @@ export default {
},
},
methods: {
async loadSmsConsentConfig() {
const config = await getSaveProgressSmsConsentConfig();
loadSmsConsentConfig() {
const config = getSaveProgressSmsConsentConfig();
this.smsConsentCopy = config.copy;
if (!this.isProgressSaved) {
@ -257,7 +257,6 @@ export default {
contactMethod: this.contactMethod,
userInput: this.userInput,
smsConsent: this.smsConsent,
pageName: this.pageName,
});
// send store call to send to new API (that triggers an email/SMS send)

View file

@ -1,5 +1,4 @@
import { storeActions } from "@/constants/store-actions";
import store from "@/store";
export const saveProgressPopupContactMethods = {
PHONE: "PhoneAnswer",
@ -20,7 +19,7 @@ export function normalizePhoneNumberForStore(phoneNumber) {
export async function saveProgressPopupContactToStore(
dispatchStoreAction,
{ contactMethod, userInput, smsConsent, pageName }
{ contactMethod, userInput, smsConsent }
) {
if (isPhoneContactMethod(contactMethod)) {
await dispatchStoreAction(
@ -29,17 +28,9 @@ export async function saveProgressPopupContactToStore(
false
);
await dispatchStoreAction(storeActions.SAVE_IS_SMS_OPT_IN, smsConsent.transactional, false);
const existingPageData = store.getters.pageData(pageName) ?? {};
await dispatchStoreAction(
storeActions.SAVE_PAGE_DATA,
{
page: pageName,
data: {
...existingPageData,
saveProgressSmsConsent: { ...smsConsent },
},
},
storeActions.SAVE_IS_SMS_MARKETING_OPT_IN,
smsConsent.marketing,
false
);

View file

@ -1,5 +1,4 @@
import { storeActions } from "@/constants/store-actions";
import store from "@/store";
import {
isPhoneContactMethod,
normalizePhoneNumberForStore,
@ -7,16 +6,9 @@ import {
saveProgressPopupContactToStore,
} from "./save-progress-popup-contact-helper";
jest.mock("@/store", () => ({
getters: {
pageData: jest.fn(),
},
}));
describe("save-progress-popup-contact-helper", () => {
beforeEach(() => {
jest.clearAllMocks();
store.getters.pageData.mockReturnValue({ servicePackageSelected: "premium" });
});
describe("isPhoneContactMethod", () => {
@ -41,7 +33,7 @@ describe("save-progress-popup-contact-helper", () => {
});
describe("saveProgressPopupContactToStore", () => {
it("should save phone number and persist sms consent on phone tab", async () => {
it("should save phone number and sms consent on customer when phone tab is selected", async () => {
const dispatchStoreAction = jest.fn().mockResolvedValue(undefined);
const smsConsent = { transactional: true, marketing: false };
@ -49,7 +41,6 @@ describe("save-progress-popup-contact-helper", () => {
contactMethod: saveProgressPopupContactMethods.PHONE,
userInput: "555-123-4567",
smsConsent,
pageName: "quote",
});
expect(dispatchStoreAction).toHaveBeenCalledWith(
@ -68,14 +59,13 @@ describe("save-progress-popup-contact-helper", () => {
false
);
expect(dispatchStoreAction).toHaveBeenCalledWith(
storeActions.SAVE_IS_SMS_MARKETING_OPT_IN,
false,
false
);
expect(dispatchStoreAction).not.toHaveBeenCalledWith(
storeActions.SAVE_PAGE_DATA,
{
page: "quote",
data: {
servicePackageSelected: "premium",
saveProgressSmsConsent: smsConsent,
},
},
expect.anything(),
false
);
});
@ -87,7 +77,6 @@ describe("save-progress-popup-contact-helper", () => {
contactMethod: saveProgressPopupContactMethods.EMAIL,
userInput: "test@example.com",
smsConsent: { transactional: false, marketing: false },
pageName: "quote",
});
expect(dispatchStoreAction).toHaveBeenCalledWith(
@ -105,6 +94,11 @@ describe("save-progress-popup-contact-helper", () => {
expect.anything(),
false
);
expect(dispatchStoreAction).not.toHaveBeenCalledWith(
storeActions.SAVE_IS_SMS_MARKETING_OPT_IN,
expect.anything(),
false
);
expect(dispatchStoreAction).not.toHaveBeenCalledWith(
storeActions.SAVE_PAGE_DATA,
expect.anything(),

View file

@ -1,3 +1,5 @@
import store from "@/store";
const SAVE_PROGRESS_SMS_CONSENT_FALLBACK_COPY = {
transactional: "Sign me up for updates about my upcoming service.",
marketing: "Sign me up for promotional and product offers.",
@ -18,10 +20,12 @@ export function hasSaveProgressSmsConsentSelection(consent, showConsentManagemen
return Boolean(consent?.transactional || (showConsentManagement && consent?.marketing));
}
export async function getSaveProgressSmsConsentConfig() {
// Replace with Consent Management API lookup (CASH-1911).
export function getSaveProgressSmsConsentConfig() {
return {
copy: getSaveProgressSmsConsentFallbackCopy(),
value: defaultSaveProgressSmsConsent(),
value: {
transactional: Boolean(store.getters.order.customer.isSmsOptIn),
marketing: Boolean(store.getters.order.customer.isSmsMarketingOptIn),
},
};
}

View file

@ -1,3 +1,5 @@
import { storeActions } from "@/constants/store-actions";
import store from "@/store";
import {
defaultSaveProgressSmsConsent,
getSaveProgressSmsConsentFallbackCopy,
@ -5,12 +7,38 @@ import {
hasSaveProgressSmsConsentSelection,
} from "./save-progress-sms-consent-helper";
jest.mock("@/store", () => ({
getters: {
order: {
customer: {
isSmsOptIn: null,
isSmsMarketingOptIn: null,
},
},
},
}));
describe("save-progress-sms-consent-helper", () => {
beforeEach(() => {
jest.clearAllMocks();
store.getters.order.customer.isSmsOptIn = null;
store.getters.order.customer.isSmsMarketingOptIn = null;
});
describe("getSaveProgressSmsConsentConfig", () => {
it("should return fallback copy and default consent values", async () => {
const config = await getSaveProgressSmsConsentConfig();
it("should return fallback copy and consent values from the store", () => {
store.getters.order.customer.isSmsOptIn = true;
store.getters.order.customer.isSmsMarketingOptIn = true;
const config = getSaveProgressSmsConsentConfig();
expect(config.copy).toEqual(getSaveProgressSmsConsentFallbackCopy());
expect(config.value).toEqual({ transactional: true, marketing: true });
});
it("should return defaults when no consent is stored", () => {
const config = getSaveProgressSmsConsentConfig();
expect(config.value).toEqual(defaultSaveProgressSmsConsent());
});
});

View file

@ -113,6 +113,7 @@ const getDefaultState = () => {
phoneNumber: null,
phoneExtension: null,
isSmsOptIn: null,
isSmsMarketingOptIn: null,
waitListRequested: null,
address: {
streetAddress: null,
@ -499,6 +500,9 @@ export const mutations = {
updateCustomerIsSmsOptin(state, isSmsOptIn) {
state.order.customer.isSmsOptIn = isSmsOptIn;
},
updateCustomerIsSmsMarketingOptin(state, isSmsMarketingOptIn) {
state.order.customer.isSmsMarketingOptIn = isSmsMarketingOptIn;
},
updateCustomerWaitListRequested(state, waitListRequested) {
state.order.customer.waitListRequested = waitListRequested;
},
@ -575,6 +579,9 @@ export const mutations = {
state.order.customer.emailAddress = customerDetails.emailAddress;
state.order.customer.phoneNumber = customerDetails.phoneNumber;
state.order.customer.isSmsOptIn = customerDetails.isSmsOptIn;
if (customerDetails.isSmsMarketingOptIn !== undefined) {
state.order.customer.isSmsMarketingOptIn = customerDetails.isSmsMarketingOptIn;
}
}
},
updateInsuranceDetails(state, insuranceDetails) {
@ -972,6 +979,8 @@ export const mutations = {
state.order.customer.phoneNumber = sessionInformation.order.customer.homePhone;
state.order.customer.phoneExtension = sessionInformation.order.customer.phoneExt;
state.order.customer.isSmsOptIn = sessionInformation.order.customer.isSmsOptIn;
state.order.customer.isSmsMarketingOptIn =
sessionInformation.order.customer.isSmsMarketingOptIn;
if (sessionInformation.order.customer.address) {
state.order.customer.address = Object.assign(state.order.customer.address, {
@ -2830,6 +2839,7 @@ export const actions = {
firstName: order.customer.firstName,
lastName: order.customer.lastName,
isSmsOptIn: order.customer.isSmsOptIn,
isSmsMarketingOptIn: order.customer.isSmsMarketingOptIn,
phoneNumber: order.customer.phoneNumber,
phoneExt: order.customer.phoneExtension,
address: {
@ -3882,6 +3892,9 @@ export const actions = {
saveIsSmsOptIn(context, isSmsOptIn) {
context.commit(storeMutations.UPDATE_CUSTOMER_IS_SMS_OPT_IN, isSmsOptIn);
},
saveIsSmsMarketingOptIn(context, isSmsMarketingOptIn) {
context.commit(storeMutations.UPDATE_CUSTOMER_IS_SMS_MARKETING_OPT_IN, isSmsMarketingOptIn);
},
saveWaitListRequested(context, waitListRequested) {
context.commit(storeMutations.UPDATE_CUSTOMER_WAITLIST_REQUESTED, waitListRequested);

View file

@ -354,6 +354,7 @@ describe("Mutations", () => {
emailAddress: "foo@bar.com",
phoneNumber: "555-555-5555",
isSmsOptIn: true,
isSmsMarketingOptIn: false,
};
// Act
@ -365,6 +366,24 @@ describe("Mutations", () => {
expect(state.order.customer.emailAddress).toEqual("foo@bar.com");
expect(state.order.customer.phoneNumber).toEqual("555-555-5555");
expect(state.order.customer.isSmsOptIn).toEqual(true);
expect(state.order.customer.isSmsMarketingOptIn).toEqual(false);
});
it("updateCustomerDetails, should preserve marketing sms consent when not provided", () => {
const storeState = state;
storeState.order.customer.isSmsOptIn = true;
storeState.order.customer.isSmsMarketingOptIn = true;
mutations.updateCustomerDetails(storeState, {
firstName: "foo",
lastName: "bar",
emailAddress: "foo@bar.com",
phoneNumber: "555-555-5555",
isSmsOptIn: false,
});
expect(state.order.customer.isSmsOptIn).toEqual(false);
expect(state.order.customer.isSmsMarketingOptIn).toEqual(true);
});
it("incrementSubmittedStateRevision, should increment submittedStateRevision", () => {