Merge pull request #3254 from Safelite/feature/CASH-2948

CASH-2948: ServicePackageNameTest experiment
This commit is contained in:
Chris 2026-07-08 13:07:11 -04:00 committed by GitHub
commit 4864784828
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 194 additions and 1 deletions

View file

@ -52,6 +52,12 @@ const experimentSettings = {
// Claim and Coverage for 2.0
ENABLE_NON_CLAIM_AND_COVERAGE_FLOW: "EnableNonC&CFlow",
NON_CLAIM_AND_COVERAGE_TEST_PARENT_ACCOUNT: "NonC&CTestParentAccount",
// Service Package Name
SHOW_SERVICE_PACKAGE_NAME_TEST: "ShowServicePackageNameTest",
TIER_ONE: "TierOne",
TIER_TWO: "TierTwo",
TIER_THREE: "TierThree",
};
const experimentTriggers = {

View file

@ -1,12 +1,20 @@
import { partTypeStrings } from "@/constants/part-type-strings";
import { damageLocationsSelected as glassLocations } from "@/constants/damage-locations-selected";
import { packageNames, externalParamPackageLabels } from "@/constants/package-names";
import { experimentSettings } from "@/constants/experiments";
import baseMixin from "@/mixins/base-mixin.js";
import { getItemsWithoutRecalParts } from "@/helpers/recal-helper";
import {
getPromosThatMatchLineItemsOnOrder,
removeVapsPromosFromPromoArray,
} from "@/helpers/promotions-helper";
import * as experimentHelper from "@/helpers/experiment-helper";
const tierExperimentSettingKeys = {
[packageNames.TIER_ONE]: experimentSettings.TIER_ONE,
[packageNames.TIER_TWO]: experimentSettings.TIER_TWO,
[packageNames.TIER_THREE]: experimentSettings.TIER_THREE,
};
export function containsLineItemWithPartType(typeToFind, itemsToSearch) {
const partTypeMatches = findLineItemsWithPartType(typeToFind, itemsToSearch);
@ -267,6 +275,27 @@ export function getPackageLabel(packageName) {
}
}
export function isServicePackageNameTestActive(experimentSettingsMap) {
return experimentHelper.hasSettingEqualTo(
experimentSettings.SHOW_SERVICE_PACKAGE_NAME_TEST,
"true",
experimentSettingsMap
);
}
export function getExperimentPackageDisplayName(tierName, experimentSettingsMap) {
if (!isServicePackageNameTestActive(experimentSettingsMap)) {
return null;
}
const settingKey = tierExperimentSettingKeys[tierName];
if (!settingKey) {
return null;
}
return experimentHelper.getSettingValue(settingKey, experimentSettingsMap);
}
function maxTier(tierA, tierB) {
if (tierA === packageNames.TIER_THREE || tierB === packageNames.TIER_THREE) {
return packageNames.TIER_THREE;

View file

@ -966,6 +966,68 @@ describe("service-package-helper.js", () => {
expect(result).toEqual(packageNames.TIER_ONE);
});
});
describe("getExperimentPackageDisplayName", () => {
const { experimentSettings } = require("@/constants/experiments");
it("Returns null when the experiment is not active", () => {
const result = servicePackageHelper.getExperimentPackageDisplayName(
packageNames.TIER_ONE,
{}
);
expect(result).toBeNull();
});
it("Returns null when the test flag is not true", () => {
const result = servicePackageHelper.getExperimentPackageDisplayName(
packageNames.TIER_ONE,
{
[experimentSettings.SHOW_SERVICE_PACKAGE_NAME_TEST]: "false",
[experimentSettings.TIER_ONE]: "Essential",
}
);
expect(result).toBeNull();
});
it("Returns the experiment display name for each tier when active", () => {
const experimentSettingsMap = {
[experimentSettings.SHOW_SERVICE_PACKAGE_NAME_TEST]: "true",
[experimentSettings.TIER_ONE]: "Essential",
[experimentSettings.TIER_TWO]: "Plus",
[experimentSettings.TIER_THREE]: "Full Service",
};
expect(
servicePackageHelper.getExperimentPackageDisplayName(
packageNames.TIER_ONE,
experimentSettingsMap
)
).toBe("Essential");
expect(
servicePackageHelper.getExperimentPackageDisplayName(
packageNames.TIER_TWO,
experimentSettingsMap
)
).toBe("Plus");
expect(
servicePackageHelper.getExperimentPackageDisplayName(
packageNames.TIER_THREE,
experimentSettingsMap
)
).toBe("Full Service");
});
it("Returns null for an unknown tier", () => {
const result = servicePackageHelper.getExperimentPackageDisplayName("UnknownTier", {
[experimentSettings.SHOW_SERVICE_PACKAGE_NAME_TEST]: "true",
[experimentSettings.TIER_ONE]: "Essential",
});
expect(result).toBeNull();
});
});
});
// Constants

View file

@ -817,6 +817,79 @@ describe("service-package-question.vue, matching business rules for package disp
expectedModifiedAnswers[packageNameKey].tierThree
);
});
it("should use experiment package names when ServicePackageNameTest is active", () => {
const getExperimentPackageLabelSpy = jest
.spyOn(servicePackageQuestion.methods, "getExperimentPackageLabel")
.mockImplementation((tierName) => {
const experimentPackageNames = {
[packageNames.TIER_ONE]: "Essential",
[packageNames.TIER_TWO]: "Plus",
[packageNames.TIER_THREE]: "Full Service",
};
return experimentPackageNames[tierName] ?? null;
});
const packageNameKey = "05_01_CSR_Quote_Standard_Repair";
Object.assign(processedCmsContent, mockProcessedCmsContent[packageNameKey]);
mockProps.availableLineItems.push(driverFrontWiperLineItem);
mockProps.availableLineItems.push(passengerFrontWiperLineItem);
const wrapper = setupMocks({
mountOptionsMockData: {
store: {
getters: {
order: {
damage: {
isRepair: true,
glassToReplace: [],
},
},
hasAnyNonWindshieldGlassParts: false,
},
},
},
});
expect(wrapper.vm.servicePackageAnswers[0].buttonLabel).toBe("Essential");
expect(wrapper.vm.servicePackageAnswers[1].buttonLabel).toBe("Plus");
expect(wrapper.vm.servicePackageAnswers[2].buttonLabel).toBe("Full Service");
getExperimentPackageLabelSpy.mockRestore();
});
it("should use CMS package names when ServicePackageNameTest is not active", () => {
const packageNameKey = "05_01_CSR_Quote_Standard_Repair";
Object.assign(processedCmsContent, mockProcessedCmsContent[packageNameKey]);
mockProps.availableLineItems.push(driverFrontWiperLineItem);
mockProps.availableLineItems.push(passengerFrontWiperLineItem);
const wrapper = setupMocks({
mountOptionsMockData: {
store: {
getters: {
order: {
damage: {
isRepair: true,
glassToReplace: [],
},
},
hasAnyNonWindshieldGlassParts: false,
},
},
},
});
runPackageAnswerExpectStatements(
wrapper.vm.servicePackageAnswers[0],
expectedModifiedAnswers[packageNameKey].tierOne
);
runPackageAnswerExpectStatements(
wrapper.vm.servicePackageAnswers[1],
expectedModifiedAnswers[packageNameKey].tierTwo
);
runPackageAnswerExpectStatements(
wrapper.vm.servicePackageAnswers[2],
expectedModifiedAnswers[packageNameKey].tierThree
);
});
});
function runPackageAnswerExpectStatements(servicePackageAnswer, expectedOutput) {

View file

@ -141,7 +141,7 @@ export default {
const modifiedAnswers = cmsAnswersContent.map((answer) => ({
value: answer.Name,
buttonLabel: this.getHeaderTextFromCms(answer.SubWidgetName),
buttonLabel: this.getPackageButtonLabel(answer.Name, answer.SubWidgetName),
buttonLabelSubCopy: this.getSubheaderTextFromCms(answer.SubWidgetName),
buttonBodyCopy: this.getBodyTextFromCms(answer.SubWidgetName),
//The package supports service-package-discount if it has the text value in CMS
@ -259,6 +259,29 @@ export default {
}
return this.servicePackageRadio;
},
getPackageButtonLabel(tierName, subWidgetName) {
return (
this.getExperimentPackageLabel(tierName) ?? this.getHeaderTextFromCms(subWidgetName)
);
},
getExperimentPackageLabel(tierName) {
if (
!experimentMixin.methods.hasSettingEqualTo(
experimentSettings.SHOW_SERVICE_PACKAGE_NAME_TEST,
"true"
)
) {
return null;
}
const tierSettingKey = {
[packageNames.TIER_ONE]: experimentSettings.TIER_ONE,
[packageNames.TIER_TWO]: experimentSettings.TIER_TWO,
[packageNames.TIER_THREE]: experimentSettings.TIER_THREE,
}[tierName];
return tierSettingKey ? experimentMixin.methods.getSettingValue(tierSettingKey) : null;
},
getHeaderTextFromCms(cmsWidgetName) {
return this.getCmsContent(cmsWidgetName, "HeaderText");
},