This commit is contained in:
Sneha 2024-10-28 17:12:59 +05:30
parent c36d9eba27
commit 3ebbc47e9f
4 changed files with 105 additions and 41 deletions

View file

@ -12,6 +12,7 @@ const experimentSettings = {
SUBMIT_ORDER_ENABLE_PIA: "SubmitOrder_Enable_PIA", SUBMIT_ORDER_ENABLE_PIA: "SubmitOrder_Enable_PIA",
IS_EMAIL_OPTIONAL: "isEmailOptional", IS_EMAIL_OPTIONAL: "isEmailOptional",
SERVICE_PACKAGE_DISCOUNT: "OfferServicePackageDiscount", SERVICE_PACKAGE_DISCOUNT: "OfferServicePackageDiscount",
PROMO_ON_PACKAGE: "Offer_Promo_On_Pkg",
RECAL_PRICE_REMOVE: "RecalPriceRemove", RECAL_PRICE_REMOVE: "RecalPriceRemove",
INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL: "NextGen_InternalInsuranceTabDisplayThreshold", INSURANCE_TAB_TO_DISPLAY_THRESHOLD_INTERNAL: "NextGen_InternalInsuranceTabDisplayThreshold",
INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL: "NextGen_ExternalInsuranceTabDisplayThreshold", INSURANCE_TAB_TO_DISPLAY_THRESHOLD_EXTERNAL: "NextGen_ExternalInsuranceTabDisplayThreshold",

View file

@ -10,6 +10,7 @@ import {
containsLineItemWithPartType, containsLineItemWithPartType,
findLineItemsWithPartType, findLineItemsWithPartType,
} from "@/helpers/service-package-helper"; } from "@/helpers/service-package-helper";
import { experimentSettings } from "@/constants/experiments";
import baseMixin from "@/mixins/base-mixin.js"; import baseMixin from "@/mixins/base-mixin.js";
import { partTypeStrings } from "@/constants/part-type-strings"; import { partTypeStrings } from "@/constants/part-type-strings";
import { nextTick } from "vue"; import { nextTick } from "vue";
@ -19,6 +20,18 @@ jest.mock("@/store", () => ({
dispatch: jest.fn(), dispatch: jest.fn(),
})); }));
const mockExperimentSettings = experimentSettings;
jest.mock("@/mixins/experiment-mixin.js", () => ({
methods: {
getSettingValue(settingName) {
if (settingName === mockExperimentSettings.PROMO_ON_PACKAGE) {
return true;
}
},
},
}));
describe("service-package-question.vue", () => { describe("service-package-question.vue", () => {
beforeEach(async () => { beforeEach(async () => {
processedCmsContent = inputQuestionWidgetAnswers; processedCmsContent = inputQuestionWidgetAnswers;
@ -162,6 +175,19 @@ describe("service-package-question.vue", () => {
wrapper.vm.servicePackageAnswers[0].buttonAuxillaryCopy.includes("As little as") wrapper.vm.servicePackageAnswers[0].buttonAuxillaryCopy.includes("As little as")
).toBe(true); ).toBe(true);
}); });
it("should show service package discount when insurance is not selected", () => {
// Arrange
mockProps.isInsuranceSelected = false;
const wrapper = setupMocks({});
// Act
// Assert
expect(
wrapper.vm.servicePackageAnswers[0].additionalButtonData.Text.includes(
"Special: Save $"
)
).toBe(true);
});
it("should return [] from nullSafeAvailableLineItems and not error out if availableLineItems is null", () => { it("should return [] from nullSafeAvailableLineItems and not error out if availableLineItems is null", () => {
// Arrange // Arrange
mockProps.availableLineItems = null; mockProps.availableLineItems = null;

View file

@ -36,6 +36,8 @@ import {
getLineItemsThatMatchPromos, getLineItemsThatMatchPromos,
} from "@/helpers/promotions-helper"; } from "@/helpers/promotions-helper";
import { containsRecalParts, getItemsWithoutRecalParts } from "@/helpers/recal-helper"; import { containsRecalParts, getItemsWithoutRecalParts } from "@/helpers/recal-helper";
import experimentMixin from "@/mixins/experiment-mixin.js";
import { experimentSettings } from "@/constants/experiments";
export default { export default {
name: "servicePackageQuestion", name: "servicePackageQuestion",
@ -129,16 +131,22 @@ export default {
buttonLabelSubCopy: this.getSubheaderTextFromCms(answer.SubWidgetName), buttonLabelSubCopy: this.getSubheaderTextFromCms(answer.SubWidgetName),
buttonBodyCopy: this.getBodyTextFromCms(answer.SubWidgetName), buttonBodyCopy: this.getBodyTextFromCms(answer.SubWidgetName),
//The package supports service-package-discount if it has the text value in CMS //The package supports service-package-discount if it has the text value in CMS
buttonAuxillaryCopy: this.getDiscountedPackagePriceString( buttonAuxillaryCopy: this.isInsuranceSelected
answer.Name, ? this.getDiscountedPackagePriceString(answer.Name, false)
this.isServicePackageDiscountOnOrder && answer.Text != "" : this.getDiscountedPackagePriceString(
), answer.Name,
this.isServicePackageDiscountOnOrder &&
this.discountPackageNames == answer.Name
),
buttonFooterCopy: this.getFooterTextFromCms(answer.SubWidgetName), buttonFooterCopy: this.getFooterTextFromCms(answer.SubWidgetName),
additionalButtonData: { additionalButtonData: {
strikeThroughPrice: this.getPackagePriceString(answer.Name), strikeThroughPrice: this.getPackagePriceString(answer.Name),
servicePackageDiscount: servicePackageDiscount:
this.isServicePackageDiscountOnOrder && answer.Text != "", this.isServicePackageDiscountOnOrder &&
Text: answer.Text + this.getServicePackageDiscountPrice(), this.discountPackageNames == answer.Name,
Text: this.isInsuranceSelected
? false
: "Special: Save $" + this.getServicePackageDiscountPrice(),
}, },
})); }));
return modifiedAnswers; return modifiedAnswers;
@ -149,6 +157,21 @@ export default {
this.nullSafeAvailableLineItems this.nullSafeAvailableLineItems
); );
}, },
discountPackageNames() {
const discountServicePackage = experimentMixin.methods.getSettingValue(
experimentSettings.PROMO_ON_PACKAGE
);
switch (discountServicePackage) {
case "ECON":
return packageNames.TIER_ONE;
case "STANDARD":
return packageNames.TIER_TWO;
case "PREMIUM":
return packageNames.TIER_THREE;
default:
return null;
}
},
frontWipersApplicableForTierTwo() { frontWipersApplicableForTierTwo() {
return shouldFrontWipersBeAvailable( return shouldFrontWipersBeAvailable(
this.glassToReplace, this.glassToReplace,

View file

@ -1,15 +1,8 @@
<template> <template>
<div
:class="[this.additionalButtonData.Text ? 'discount-text' : '']"
v-if="this.additionalButtonData.servicePackageDiscount"
v-html="this.additionalButtonData.Text"></div>
<baseInputButton v-bind="$props" @buttonClicked="handleAnswerChange" v-model="selectedValue"> <baseInputButton v-bind="$props" @buttonClicked="handleAnswerChange" v-model="selectedValue">
<div <div
class="package-label" class="package-label"
:class="[ :class="[this.buttonLabelSubCopy ? 'has-subheader' : '']"
this.buttonLabelSubCopy ? 'has-subheader' : '',
this.additionalButtonData.servicePackageDiscount ? 'has-text' : '',
]"
for="testradio"> for="testradio">
<div class="package-specs"> <div class="package-specs">
<div v-if="this.additionalButtonData.servicePackageDiscount" class="row"> <div v-if="this.additionalButtonData.servicePackageDiscount" class="row">
@ -82,6 +75,15 @@
v-if="this.buttonFooterCopy" v-if="this.buttonFooterCopy"
v-html="this.buttonFooterCopy"></div> v-html="this.buttonFooterCopy"></div>
</div> </div>
<!-- This div will show up in all service packages until logic is written -->
<div
v-if="
this.additionalButtonData.servicePackageDiscount &&
this.additionalButtonData.Text
"
class="special-save-box">
<span v-html="this.additionalButtonData.Text"></span>
</div>
</div> </div>
</div> </div>
</baseInputButton> </baseInputButton>
@ -143,20 +145,13 @@ export default {
margin: 1rem 0.5rem; margin: 1rem 0.5rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-self: flex-end;
} }
label { label {
display: block; display: block;
@include media-breakpoint-up(md) { @include media-breakpoint-up(md) {
display: flex; display: flex;
min-height: 336px; height: 100%;
}
//Unique breakpoint for this page only to accommodate price spacing issues
//from use of position: absolute on .service-package-discount (per Design Team request)
@media only screen and (min-width: 860px) {
display: flex;
min-height: 276px;
} }
} }
@ -179,19 +174,16 @@ export default {
border-radius: 0.5rem; border-radius: 0.5rem;
overflow: hidden; overflow: hidden;
min-height: 60px; min-height: 60px;
max-height: 100px; max-height: 126px;
@include media-breakpoint-up(md) { @include media-breakpoint-up(md) {
max-height: 500px; max-height: 500px;
padding-bottom: 3rem;
} }
transition: max-height 0.25s ease-in; transition: max-height 0.25s ease-in;
&.has-subheader { &.has-subheader {
min-height: 80px; min-height: 80px;
} }
&.has-text {
border-radius: 0 0 0.5rem 0.5rem;
border: 1px solid $green;
}
&:before { &:before {
content: ""; content: "";
@ -245,6 +237,9 @@ export default {
background-color: $blue-100; background-color: $blue-100;
border: 1px solid $blue; border: 1px solid $blue;
max-height: 500px; max-height: 500px;
.special-save-box {
background-color: $green-200;
}
} }
+ .package-label { + .package-label {
&:before { &:before {
@ -294,8 +289,8 @@ export default {
bottom: 0.75rem; bottom: 0.75rem;
left: 0; left: 0;
width: 100%; width: 100%;
text-align: center; margin-left: 1.25rem;
font-size: 1.125rem; font-weight: 600;
} }
span.strikethrough-price { span.strikethrough-price {
text-decoration: line-through; text-decoration: line-through;
@ -316,28 +311,32 @@ export default {
&.service-package-discount { &.service-package-discount {
color: $green; color: $green;
text-align: end; text-align: end;
font-weight: 500; font-weight: 600;
font-size: 13px; font-size: 0.875rem;
display: flex;
justify-content: space-between;
div.strikethrough-discount-price { div.strikethrough-discount-price {
text-decoration: line-through; text-decoration: line-through;
margin-right: 0; margin-right: 0.5rem;
font-weight: 400; font-weight: 600;
font-size: 0.875rem; font-size: 0.75rem;
line-height: 20px; line-height: 20px;
color: $gray-500; color: $gray-550;
padding-right: 2px; @include media-breakpoint-up(md) {
margin-right: 0.5rem;
font-size: 0.75rem;
}
} }
div.discount-price { div.discount-price {
color: $green; color: $green;
font-weight: 600;
font-size: 1.625rem;
} }
@include media-breakpoint-up(md) { @include media-breakpoint-up(md) {
position: absolute; position: absolute;
bottom: 0.75rem; bottom: 0.75rem;
left: 0; left: 0.5rem;
width: 100%; display: flex;
text-align: center; align-items: center;
justify-content: flex-start;
} }
} }
} }
@ -388,6 +387,21 @@ export default {
font-weight: 600; font-weight: 600;
letter-spacing: 0.75px; letter-spacing: 0.75px;
} }
.special-save-box {
background-color: $green-100;
display: flex;
flex-direction: row;
margin: auto;
margin-left: -2rem;
padding: 0.5rem 1rem;
border-radius: 0.25rem;
margin-top: 0.5rem;
span {
color: $green;
font-size: 0.875rem;
font-weight: 600;
}
}
} }
} }
</style> </style>