Merge pull request #1740 from Safelite/feature/CSR-1764.1
Revert "CSR-1764"
This commit is contained in:
commit
7af5e5eb11
7 changed files with 48 additions and 336 deletions
|
|
@ -33,7 +33,6 @@
|
|||
class="small mt-4"
|
||||
v-model="lineItems"
|
||||
:availableVaps="availableVaps"
|
||||
pageName="payment-method"
|
||||
modalWidgetName="PromoModalWidget" />
|
||||
|
||||
<hr class="my-5" />
|
||||
|
|
|
|||
|
|
@ -1,25 +1,5 @@
|
|||
import { mount, shallowMount } from "@vue/test-utils";
|
||||
import promoModalQuestion from "./promo-modal-question";
|
||||
import { storeActions } from "@/constants/store-actions";
|
||||
import baseMixin from "@/mixins/base-mixin.js";
|
||||
|
||||
let mockReturnsForStoreActions = {};
|
||||
|
||||
jest.mock("@/mixins/base-mixin", () => ({
|
||||
...jest.requireActual("@/mixins/base-mixin"),
|
||||
methods: {
|
||||
dispatchStoreActionWithLogging: jest.fn(
|
||||
(action, { promoCode, addableVaps }, pageNameToLog, someBool) => {
|
||||
return mockReturnsForStoreActions[action];
|
||||
}
|
||||
),
|
||||
},
|
||||
}));
|
||||
|
||||
afterEach(() => {
|
||||
// reset store action returns
|
||||
mockReturnsForStoreActions = {};
|
||||
});
|
||||
|
||||
jest.mock("@/digital-components/textbox-question/textbox-question", () => ({
|
||||
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
|
||||
|
|
@ -99,127 +79,4 @@ describe("promo-modal-question.vue", () => {
|
|||
// Assert
|
||||
expect(wrapper.emitted("update:modelValue")).toEqual([[lineItems]]);
|
||||
});
|
||||
it("focuses on the input element when focusOnPromoInput is called", async () => {
|
||||
// Arrange
|
||||
const lineItems = {
|
||||
glassParts: [],
|
||||
supportingItems: [],
|
||||
vaps: [],
|
||||
promos: [],
|
||||
};
|
||||
|
||||
const wrapper = mount(promoModalQuestion, {
|
||||
mixins: [mockMixin],
|
||||
props: {
|
||||
modelValue: lineItems,
|
||||
modalWidgetName: modalWidgetName,
|
||||
},
|
||||
attachTo: document.body,
|
||||
});
|
||||
const focusMock = jest.fn();
|
||||
const inputMock = { focus: focusMock };
|
||||
|
||||
// Mock document.getElementById to return the inputMock
|
||||
jest.spyOn(document, "getElementById").mockReturnValue(inputMock);
|
||||
|
||||
//Act
|
||||
|
||||
wrapper.vm.focusOnPromoInput();
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
//Assert
|
||||
expect(focusMock).toHaveBeenCalled();
|
||||
});
|
||||
it("returns a validate response on applying promo", async () => {
|
||||
// Arrange
|
||||
const newPromo = "testPromo";
|
||||
const pageNameToLog = "testPage";
|
||||
const validateResponse = { orderPromos: [] };
|
||||
const addableVaps = [];
|
||||
mockReturnsForStoreActions[storeActions.VALIDATE_ORDER_PROMO_AND_SAVE_SERVER_DATA] =
|
||||
validateResponse;
|
||||
const lineItems = {
|
||||
glassParts: [],
|
||||
supportingItems: [],
|
||||
vaps: [],
|
||||
promos: [],
|
||||
};
|
||||
|
||||
const wrapper = mount(promoModalQuestion, {
|
||||
mixins: [mockMixin],
|
||||
props: {
|
||||
modelValue: lineItems,
|
||||
modalWidgetName: modalWidgetName,
|
||||
},
|
||||
attachTo: document.body,
|
||||
});
|
||||
// Act
|
||||
|
||||
wrapper.vm.getPromoCodeData();
|
||||
|
||||
const promoValidationResponse = await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||
storeActions.VALIDATE_ORDER_PROMO_AND_SAVE_SERVER_DATA,
|
||||
{
|
||||
newPromo,
|
||||
lineItems,
|
||||
addableVaps,
|
||||
},
|
||||
pageNameToLog,
|
||||
false
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(promoValidationResponse).toEqual(validateResponse);
|
||||
});
|
||||
test("If promocode is valid return taxed lineItems", async () => {
|
||||
//Arrange
|
||||
const taxedlineItems = {};
|
||||
|
||||
mockReturnsForStoreActions[storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA] =
|
||||
taxedlineItems;
|
||||
|
||||
const lineItems = {
|
||||
glassParts: [],
|
||||
supportingItems: [],
|
||||
vaps: [],
|
||||
promos: [],
|
||||
};
|
||||
|
||||
let promoCode = "1wiper0";
|
||||
const pricedLineItemsToTax = [];
|
||||
|
||||
pricedLineItemsToTax.push(promoCode);
|
||||
const wrapper = mount(promoModalQuestion, {
|
||||
mixins: [mockMixin],
|
||||
|
||||
props: {
|
||||
modelValue: lineItems,
|
||||
modalWidgetName: modalWidgetName,
|
||||
},
|
||||
|
||||
attachTo: document.body,
|
||||
});
|
||||
wrapper.vm.addPromoCode();
|
||||
|
||||
const taxedLineItems = await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||
storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
||||
{
|
||||
billToAccountNumber: "87291",
|
||||
providerNumber: 2,
|
||||
appointmentType: "IN_SHOP",
|
||||
serviceLocationCity: "city",
|
||||
serviceLocationState: "state",
|
||||
serviceLocationZipCode: "12345",
|
||||
pricedLineItems: pricedLineItemsToTax,
|
||||
},
|
||||
|
||||
"payment-method",
|
||||
|
||||
false
|
||||
);
|
||||
|
||||
// Assert
|
||||
|
||||
expect(taxedLineItems).toEqual(taxedlineItems);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -100,12 +100,6 @@ export default {
|
|||
modelValue: Object,
|
||||
modalWidgetName: String,
|
||||
availableVaps: Object,
|
||||
pageName: String,
|
||||
taxPromos: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
promoLinkText() {
|
||||
|
|
@ -259,51 +253,44 @@ export default {
|
|||
this.promoCode,
|
||||
this.lineItems,
|
||||
this.availableVaps,
|
||||
this.pageName
|
||||
"payment-method"
|
||||
);
|
||||
|
||||
if (promoCodeData.isValid) {
|
||||
if (this.taxPromos) {
|
||||
const pricedLineItemsToTax = [];
|
||||
pricedLineItemsToTax.push(...promoCodeData.promoCode);
|
||||
const taxedLineItems =
|
||||
await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||
storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
||||
{
|
||||
billToAccountNumber: "87291",
|
||||
providerNumber:
|
||||
store.getters.order.serviceLocation.provider.providerNumber,
|
||||
appointmentType:
|
||||
store.getters.order.serviceLocation.appointmentType,
|
||||
serviceLocationCity: store.getters.order.serviceLocation.city,
|
||||
serviceLocationState: store.getters.order.serviceLocation.state,
|
||||
serviceLocationZipCode:
|
||||
store.getters.order.serviceLocation.zipCode,
|
||||
pricedLineItems: pricedLineItemsToTax,
|
||||
},
|
||||
"payment-method",
|
||||
false
|
||||
);
|
||||
const pricedLineItemsToTax = [];
|
||||
pricedLineItemsToTax.push(...promoCodeData.promoCode);
|
||||
const taxedLineItems = await baseMixin.methods.dispatchStoreActionWithLogging(
|
||||
storeActions.TAX_ORDER_ITEMS_AND_SAVE_SERVER_DATA,
|
||||
{
|
||||
billToAccountNumber: "87291",
|
||||
providerNumber:
|
||||
store.getters.order.serviceLocation.provider.providerNumber,
|
||||
appointmentType: store.getters.order.serviceLocation.appointmentType,
|
||||
serviceLocationCity: store.getters.order.serviceLocation.city,
|
||||
serviceLocationState: store.getters.order.serviceLocation.state,
|
||||
serviceLocationZipCode: store.getters.order.serviceLocation.zipCode,
|
||||
pricedLineItems: pricedLineItemsToTax,
|
||||
},
|
||||
"payment-method",
|
||||
false
|
||||
);
|
||||
|
||||
// Match all line items to the line items as they are in the store
|
||||
// and rebuild the original structure.
|
||||
this.lineItems = mapTaxedLineItemsToStoreFormat(
|
||||
taxedLineItems,
|
||||
this.lineItems
|
||||
);
|
||||
const taxedVaps = mapTaxedLineItemsToStoreFormat(
|
||||
taxedLineItems,
|
||||
this.availableVaps
|
||||
);
|
||||
// Match all line items to the line items as they are in the store
|
||||
// and rebuild the original structure.
|
||||
this.lineItems = mapTaxedLineItemsToStoreFormat(taxedLineItems, this.lineItems);
|
||||
const taxedVaps = mapTaxedLineItemsToStoreFormat(
|
||||
taxedLineItems,
|
||||
this.availableVaps
|
||||
);
|
||||
|
||||
const getVaps = getVapsThatNeedToBeAddedToSatisfyPromos(
|
||||
promoCodeData.promoCode,
|
||||
taxedVaps,
|
||||
this.lineItems
|
||||
);
|
||||
|
||||
const getVaps = getVapsThatNeedToBeAddedToSatisfyPromos(
|
||||
promoCodeData.promoCode,
|
||||
taxedVaps,
|
||||
this.lineItems
|
||||
);
|
||||
this.lineItems?.vaps.push(...getVaps);
|
||||
}
|
||||
this.lineItems?.promos.push(...promoCodeData.promoCode);
|
||||
this.lineItems.vaps?.push(...getVaps);
|
||||
this.closeModal();
|
||||
} else {
|
||||
this.getErrorMessage(promoCodeData.errorCode, promoCodeData.additionalInfo);
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ import { applicationConfig } from "@/constants/application-config";
|
|||
import { storeActions } from "@/constants/store-actions";
|
||||
import quote from "@/layouts/quote/quote.vue";
|
||||
import store from "@/store";
|
||||
import promotionsHelper from "@/helpers/promotions-helper";
|
||||
import baseMixin from "@/mixins/base-mixin.js";
|
||||
import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper";
|
||||
import { nextTick } from "vue";
|
||||
|
||||
|
|
@ -135,6 +133,8 @@ describe("quote.vue", () => {
|
|||
};
|
||||
});
|
||||
|
||||
wrapper.vm.pricedGlassParts = [];
|
||||
|
||||
//Act
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
|
||||
|
|
@ -250,8 +250,9 @@ describe("quote.vue", () => {
|
|||
);
|
||||
|
||||
//Assert
|
||||
expect(wrapper.vm.pricedGlassParts !== null).toBe(true);
|
||||
expect(wrapper.vm.supportingItems !== null).toBe(true);
|
||||
expect(wrapper.vm.availableLineItems !== null).toBe(true);
|
||||
expect(wrapper.vm.availableVaps !== null).toBe(true);
|
||||
// This should have its own test
|
||||
//expect(vm.isInsuranceSelected !== null).toBe(true);
|
||||
});
|
||||
|
|
@ -509,31 +510,6 @@ describe("quote.vue", () => {
|
|||
//Assert
|
||||
expect(wrapper.vm.isInsuranceSelected).toBe(true);
|
||||
});
|
||||
test("On forward button action save promos", async () => {
|
||||
//Arrange
|
||||
store.getters.payment = {
|
||||
insuranceCoverage: {},
|
||||
isInsurance: false,
|
||||
};
|
||||
store.getters.order = {
|
||||
lineItems: [],
|
||||
payment: {
|
||||
parentAccountNumber: 167132,
|
||||
},
|
||||
};
|
||||
const { wrapper } = setupMocks({
|
||||
customMountOptions: {
|
||||
router: {
|
||||
navigateWithSaving: jest.fn(),
|
||||
},
|
||||
route: { quote },
|
||||
},
|
||||
});
|
||||
|
||||
wrapper.vm.forwardButtonAction();
|
||||
|
||||
expect(wrapper.vm.lineItems.promos !== null).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
function setupMocks({ customMountOptions }) {
|
||||
|
|
|
|||
|
|
@ -39,15 +39,6 @@
|
|||
cmsWidgetName="AfterpayModalWidget"
|
||||
:lineItems="availableLineItems" />
|
||||
|
||||
<promoModalQuestion
|
||||
class="small mt-4"
|
||||
v-model="lineItems"
|
||||
:availableVaps="availableVaps"
|
||||
:availableLineItems="availableLineItems"
|
||||
pageName="quote"
|
||||
:taxPromos="false"
|
||||
modalWidgetName="PromoModalWidget" />
|
||||
|
||||
<textBlock
|
||||
cmsWidgetName="quoteDisclaimer"
|
||||
justifyText="left"
|
||||
|
|
@ -98,11 +89,9 @@ import { payWithInsuranceStates } from "@/constants/pay-with-insurance-states";
|
|||
import {
|
||||
revalidatePromosAndValidateQueryStringPromo,
|
||||
buildToastMessagesFromRevalidateOrValidatePromoResponse,
|
||||
createPromoSuccessAlert,
|
||||
} from "@/helpers/promotions-helper";
|
||||
import { queryStrings } from "@/constants/query-strings";
|
||||
import { getQuerystringParameter } from "@/helpers/querystring-helper";
|
||||
import promoModalQuestion from "@/layouts/payment-method/promo-modal-question/promo-modal-question";
|
||||
|
||||
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
||||
|
||||
|
|
@ -150,8 +139,7 @@ export default {
|
|||
];
|
||||
|
||||
const resultMap = await settleAllPromises(promiseResultMap);
|
||||
const lineItems = store.getters.order.lineItems;
|
||||
const nullSafeGlassParts = lineItems.glassParts ?? [];
|
||||
const nullSafeGlassParts = store.getters.order.lineItems.glassParts ?? [];
|
||||
const availableLineItems = [
|
||||
resultMap.rainDefense,
|
||||
...resultMap.supportingItems,
|
||||
|
|
@ -176,7 +164,6 @@ export default {
|
|||
|
||||
// Promo logic
|
||||
// Populate the previous state of promos for toast message usage in "next()"
|
||||
const availableVaps = [...resultMap.wipers, resultMap.rainDefense];
|
||||
const oldActivePromos = store.getters.lineItems.promos?.slice(0);
|
||||
const oldInactivePromos = store.getters.order.payment.inactivePromos?.slice(0);
|
||||
|
||||
|
|
@ -188,17 +175,14 @@ export default {
|
|||
pricingResults,
|
||||
"quote"
|
||||
);
|
||||
|
||||
lineItems.promos = lineItems.promos ?? [];
|
||||
lineItems.vaps = lineItems.vaps ?? [];
|
||||
// End of promo logic
|
||||
|
||||
// Call the "next" function to complete the transition to this page.
|
||||
next((vm) => {
|
||||
vm.setCmsContent(resultMap.cmsContent);
|
||||
vm.pricedGlassParts = nullSafeGlassParts;
|
||||
vm.supportingItems = resultMap.supportingItems;
|
||||
vm.availableLineItems = pricingResults;
|
||||
vm.availableVaps = availableVaps;
|
||||
vm.lineItems = lineItems;
|
||||
vm.isInsuranceSelected = vm.getDefaultIsInsuranceSelectedValue(vm.availableLineItems);
|
||||
|
||||
if (revalidatePromoResponse) {
|
||||
|
|
@ -224,17 +208,15 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
isInsuranceSelected: null,
|
||||
selectedVaps: null,
|
||||
availableLineItems: null,
|
||||
availableVaps: [],
|
||||
lineItems: [],
|
||||
supportingItems: null,
|
||||
pricedGlassParts: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
allActivePromos() {
|
||||
return this.lineItems.promos ?? [];
|
||||
},
|
||||
lineItemsCloneForWatcher() {
|
||||
return Object.assign({}, this.lineItems);
|
||||
return this.$store.getters.order.lineItems.promos ?? [];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -276,7 +258,7 @@ export default {
|
|||
}
|
||||
},
|
||||
vapsItemsSelectedAction(vapsItemsSelected) {
|
||||
this.lineItems.vaps = vapsItemsSelected;
|
||||
this.selectedVaps = vapsItemsSelected;
|
||||
},
|
||||
backButtonAction() {
|
||||
vehicleQuestionsMixin.methods.navigateBack(this);
|
||||
|
|
@ -300,26 +282,18 @@ export default {
|
|||
this.$store.getters.order.payment.parentAccountNumber !=
|
||||
applicationConfig.CASH_PARENT_ACCOUNT_NUMBER
|
||||
) {
|
||||
this.lineItems.supportingItems = this.filterOutFees(this.lineItems.supportingItems);
|
||||
this.supportingItems = this.filterOutFees(this.supportingItems);
|
||||
}
|
||||
|
||||
if (this.lineItems.glassParts?.length > 0) {
|
||||
if (this.pricedGlassParts.length > 0) {
|
||||
this.dispatchStoreAction(
|
||||
this.storeActions.SAVE_GLASS_PARTS_SUPPRESSING_STATE_RESETTING,
|
||||
this.lineItems.glassParts,
|
||||
this.pricedGlassParts,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
this.dispatchStoreAction(this.storeActions.SAVE_VAPS, this.lineItems.vaps, false);
|
||||
this.dispatchStoreAction(
|
||||
storeActions.SAVE_ACTIVE_AND_OR_INACTIVE_PROMOS,
|
||||
{
|
||||
activePromos: this.lineItems.promos,
|
||||
inactivePromos: this.$store.getters.order.payment.inactivePromos,
|
||||
},
|
||||
false
|
||||
);
|
||||
this.dispatchStoreAction(this.storeActions.SAVE_VAPS, this.selectedVaps, false);
|
||||
|
||||
const payment = this.$store.getters.payment;
|
||||
if (payment.isInsurance) {
|
||||
|
|
@ -335,32 +309,6 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
lineItemsCloneForWatcher: {
|
||||
handler(newValue, oldValue) {
|
||||
if (
|
||||
!oldValue ||
|
||||
oldValue.length == 0 ||
|
||||
!oldValue.vaps ||
|
||||
!newValue ||
|
||||
newValue.length == 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (oldValue.promos.length < newValue.promos.length) {
|
||||
const oldPromoCodes = oldValue.promos.map(
|
||||
(promoObject) => promoObject.promoCode
|
||||
);
|
||||
const newlyActivatedPromoCodes = newValue.promos.filter(
|
||||
(newPromo) => !oldPromoCodes.includes(newPromo.promoCode)
|
||||
);
|
||||
const alert = createPromoSuccessAlert(newlyActivatedPromoCodes[0].promoCode);
|
||||
this.$refs.funnelHeader.pushGlobalAlert(alert, alert.shouldAutoFade);
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
funnelHeader,
|
||||
navbar,
|
||||
|
|
@ -373,7 +321,6 @@ export default {
|
|||
contentGroupModal,
|
||||
loadingModal,
|
||||
afterpayModalBanner,
|
||||
promoModalQuestion,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -256,57 +256,6 @@ describe("service-package-question.vue", () => {
|
|||
// Assert
|
||||
expect(wrapper.vm.selectedPackageName).toBe("TierThree");
|
||||
});
|
||||
it("should select default package if promos are added", async () => {
|
||||
//Arrange
|
||||
mockProps.activePromos != null;
|
||||
const wrapper = setupMocks({
|
||||
mountOptionsMockData: {
|
||||
store: {
|
||||
getters: {
|
||||
order: {
|
||||
damage: {
|
||||
isRepair: false,
|
||||
glassToReplace: [{ glassLocation: "Windshield" }],
|
||||
},
|
||||
},
|
||||
lineItems: {
|
||||
vaps: [],
|
||||
},
|
||||
hasAnyNonWindshieldGlassParts: false,
|
||||
payment: {
|
||||
isInsurance: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
//Act
|
||||
wrapper.setProps({
|
||||
activePromos: [
|
||||
{
|
||||
discountedLineItemIds: [
|
||||
{
|
||||
0: "428ec73c-38e4-4e14-8703-a987b0391898",
|
||||
1: "79db94d7-163c-4408-a1ec-f83e58c11992",
|
||||
},
|
||||
],
|
||||
partType: "PROMO_DISCOUNT",
|
||||
promoCode: "1WIPER0",
|
||||
partNumber: "WIPER DISCOUNT",
|
||||
laborAmount: 0,
|
||||
sellingPrice: -10,
|
||||
kitPrice: 0,
|
||||
salesTax: null,
|
||||
},
|
||||
],
|
||||
});
|
||||
const selectDefaultPackageMock = jest.spyOn(wrapper.vm, "selectDefaultPackage");
|
||||
await nextTick();
|
||||
|
||||
//Assert
|
||||
expect(selectDefaultPackageMock).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
describe("service-package-question.vue, matching business rules for package display", () => {
|
||||
// mock scenarios in figma:
|
||||
|
|
|
|||
|
|
@ -63,9 +63,6 @@ export default {
|
|||
this.selectDefaultPackage();
|
||||
}
|
||||
},
|
||||
activePromos() {
|
||||
this.selectDefaultPackage();
|
||||
},
|
||||
selectedPackageName(newValue) {
|
||||
const VapsProductsInSelectedPackage = this.getVapsLineItemsForSelectedPackage(newValue);
|
||||
this.$emit("vapsItemsSelected", VapsProductsInSelectedPackage);
|
||||
|
|
|
|||
Loading…
Reference in a new issue