Merge branch 'release/2025.02.27' into rlsmerge/2025.02.27-to-develop
This commit is contained in:
commit
1900da762b
11 changed files with 203 additions and 46 deletions
|
|
@ -99,8 +99,8 @@
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import loader from "@/ux-components/loader/loader";
|
import loader from "@/ux-components/loader/loader";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import { TIMINGFUNC_MAP, BUFFER_OFFSET, MONTHS_OF_YEAR } from "./mixins/constants";
|
import { TIMINGFUNC_MAP, BUFFER_OFFSET, MONTHS_OF_YEAR } from "@/digital-components/date-picker/mixins/constants";
|
||||||
import { selectableDaysOptions, requiredParameter, forceTwoDigitString } from "./mixins/helpers";
|
import { selectableDaysOptions, requiredParameter, forceTwoDigitString } from "@/digital-components/date-picker/mixins/helpers";
|
||||||
import {
|
import {
|
||||||
convertDateToDateString,
|
convertDateToDateString,
|
||||||
convertDateStringToDate,
|
convertDateStringToDate,
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
:class="[
|
:class="[
|
||||||
this.buttonLabelSubCopy ? 'has-subheader' : '',
|
this.buttonLabelSubCopy ? 'has-subheader' : '',
|
||||||
this.isInsuranceSelected ? 'pricing-by-day-pkg-lbl-ins' : 'pricing-by-day-pkg-lbl',
|
this.isInsuranceSelected ? 'pricing-by-day-pkg-lbl-ins' : 'pricing-by-day-pkg-lbl',
|
||||||
|
!this.additionalButtonData.servicePackageDiscount ? 'adjust-top' : '',
|
||||||
]"
|
]"
|
||||||
for="testradio">
|
for="testradio">
|
||||||
<div class="package-specs">
|
<div class="package-specs">
|
||||||
|
|
@ -193,7 +194,7 @@ export default {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -9999px;
|
left: -9999px;
|
||||||
|
|
||||||
+ .package-label.pricing-by-day-pkg-lbl {
|
+ .package-label.pricing-by-day-pkg-lbl.adjust-top {
|
||||||
/* Copying a component for an experiment will cause duplication of css classes.
|
/* Copying a component for an experiment will cause duplication of css classes.
|
||||||
This can cause problems if you want change the value of something only for the experiment
|
This can cause problems if you want change the value of something only for the experiment
|
||||||
version of the component. So added a more specific selector for the parts I want to change
|
version of the component. So added a more specific selector for the parts I want to change
|
||||||
|
|
|
||||||
|
|
@ -58,3 +58,15 @@ export function getTopLevelPartsWithRecal(lineItems) {
|
||||||
|
|
||||||
return lineItems.filter((li) => isRecalPartOrHasChildRecalPart(li));
|
return lineItems.filter((li) => isRecalPartOrHasChildRecalPart(li));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getRecalPartNumbers(glassPartsArray) {
|
||||||
|
if (glassPartsArray && glassPartsArray.length > 0) {
|
||||||
|
const topLevel = glassPartsArray.filter((gp) => isRecalPart(gp)).map((gp) => gp.partNumber);
|
||||||
|
|
||||||
|
const children = glassPartsArray.map((gp) => getRecalPartNumbers(gp.childParts)).flat();
|
||||||
|
|
||||||
|
return [...topLevel, ...children];
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -357,15 +357,18 @@ export default {
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
if (vinPagesMixin.methods.isPhoneNumber(this.customerQuestions.emailOrSms)) {
|
// if no value due to field being optional, blank both phone and email address
|
||||||
const phone = this.customerQuestions.emailOrSms.replace(/[()]/g, "");
|
if (!this.customerQuestions.emailOrSms) {
|
||||||
await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false);
|
await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, "", false);
|
||||||
} else {
|
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, "", false);
|
||||||
await this.dispatchStoreAction(
|
}
|
||||||
storeActions.SAVE_EMAIL,
|
else {
|
||||||
this.customerQuestions.emailOrSms,
|
if (vinPagesMixin.methods.isPhoneNumber(this.customerQuestions.emailOrSms)) {
|
||||||
false
|
const phone = this.customerQuestions.emailOrSms.replace(/[()]/g, "");
|
||||||
);
|
await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false);
|
||||||
|
} else {
|
||||||
|
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.customerQuestions.emailOrSms, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.dispatchStoreAction(
|
await this.dispatchStoreAction(
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
describe("insurance-company.vue", () => {
|
|
||||||
it.todo("Some test for the future");
|
|
||||||
});
|
|
||||||
105
src/layouts/insurance-company/insurance-company.spec.js
Normal file
105
src/layouts/insurance-company/insurance-company.spec.js
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
import { shallowMount } from '@vue/test-utils';
|
||||||
|
import InsuranceCompany from '@/layouts/insurance-company/insurance-company.vue';
|
||||||
|
import { applicationConfig } from '@/constants/application-config.js';
|
||||||
|
import store from "@/store";
|
||||||
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
|
|
||||||
|
|
||||||
|
jest.mock('@/store', () => ({
|
||||||
|
getters: {
|
||||||
|
order: {
|
||||||
|
payment: {
|
||||||
|
parentAccountNumber: '12345',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
var mockRouter = {
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.mock('@/mixins/base-mixin.js', () => ({
|
||||||
|
methods: {
|
||||||
|
navigateWithoutSaving: jest.fn(),
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
navigationScenarios: {
|
||||||
|
CLICKED_BACK: 'clicked_back',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("insurance-company.vue", () => {
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// Reset the store's parentAccountNumber before each test
|
||||||
|
store.getters.order.payment.parentAccountNumber = '12345';
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return true when parentAccountNumber matches CASH_PARENT_ACCOUNT_NUMBER', () => {
|
||||||
|
applicationConfig.CASH_PARENT_ACCOUNT_NUMBER = "12345";
|
||||||
|
const wrapper = shallowMount(InsuranceCompany, {
|
||||||
|
global: {
|
||||||
|
mocks: {
|
||||||
|
$store: store
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.vm.isCashParentAccountNumber()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return false when parentAccountNumber does not match CASH_PARENT_ACCOUNT_NUMBER', () => {
|
||||||
|
applicationConfig.CASH_PARENT_ACCOUNT_NUMBER = "12345";
|
||||||
|
store.getters.order.payment.parentAccountNumber = '67890';
|
||||||
|
const wrapper = shallowMount(InsuranceCompany, {
|
||||||
|
global: {
|
||||||
|
mocks: {
|
||||||
|
$store: store,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(wrapper.vm.isCashParentAccountNumber()).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should call navigateWithoutSaving with { isCashSelected: true } when forceCashSelection is true', () => {
|
||||||
|
const wrapper = shallowMount(InsuranceCompany, {
|
||||||
|
global: {
|
||||||
|
mocks: {
|
||||||
|
$store: store,
|
||||||
|
$router: mockRouter,
|
||||||
|
},
|
||||||
|
mixins: [baseMixin],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
wrapper.vm.backButtonAction(true);
|
||||||
|
expect(mockRouter.navigateWithoutSaving).toHaveBeenCalledWith(
|
||||||
|
wrapper.vm.navigationScenarios.CLICKED_BACK,
|
||||||
|
wrapper.vm.$route,
|
||||||
|
{ isCashSelected: true }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should call navigateWithoutSaving with no extra parameter when forceCashSelection is false', () => {
|
||||||
|
const wrapper = shallowMount(InsuranceCompany, {
|
||||||
|
global: {
|
||||||
|
mocks: {
|
||||||
|
$store: store,
|
||||||
|
$router: mockRouter,
|
||||||
|
},
|
||||||
|
mixins: [baseMixin],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
wrapper.vm.backButtonAction(false);
|
||||||
|
expect(mockRouter.navigateWithoutSaving).toHaveBeenCalledWith(
|
||||||
|
wrapper.vm.navigationScenarios.CLICKED_BACK,
|
||||||
|
wrapper.vm.$route
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -311,11 +311,18 @@ export default {
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) {
|
// if no value due to field being optional, blank both phone and email address
|
||||||
const phone = this.emailOrSms.replace(/[()]/g, "");
|
if (!this.emailOrSms) {
|
||||||
await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false);
|
await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, "", false);
|
||||||
} else {
|
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, "", false);
|
||||||
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false);
|
}
|
||||||
|
else {
|
||||||
|
if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) {
|
||||||
|
const phone = this.emailOrSms.replace(/[()]/g, "");
|
||||||
|
await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false);
|
||||||
|
} else {
|
||||||
|
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.dispatchStoreAction(
|
await this.dispatchStoreAction(
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import baseMixin from "../../mixins/base-mixin";
|
import baseMixin from "../../mixins/base-mixin";
|
||||||
|
import { experimentSettings } from "../../constants/experiments";
|
||||||
|
|
||||||
// Mock basemixin
|
// Mock basemixin
|
||||||
jest.mock("@/mixins/base-mixin.js", () => ({
|
jest.mock("@/mixins/base-mixin.js", () => ({
|
||||||
|
|
@ -177,6 +178,7 @@ beforeEach(() => {
|
||||||
glassParts: [],
|
glassParts: [],
|
||||||
supportingItems: [],
|
supportingItems: [],
|
||||||
},
|
},
|
||||||
|
experimentSettings: {},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,18 @@
|
||||||
marginTopSizeOverride="1" />
|
marginTopSizeOverride="1" />
|
||||||
</template>
|
</template>
|
||||||
<locationAlerts cmsWidgetPrefix="LocationAlert-" ref="locationAlerts" />
|
<locationAlerts cmsWidgetPrefix="LocationAlert-" ref="locationAlerts" />
|
||||||
|
<datePicker
|
||||||
|
v-if="!isPricingByDayExperiment"
|
||||||
|
customComponentId="dateQuestion"
|
||||||
|
selectableDatesSetting="custom"
|
||||||
|
ref="datePicker"
|
||||||
|
v-model="selectedDate"
|
||||||
|
class="text-link-small"
|
||||||
|
:customSelectableDatesCallback="getAvailableDatesMethod"
|
||||||
|
validationRules="date-required"
|
||||||
|
@date-clicked="openInshopTimeSlotsModal" />
|
||||||
<datePicker2
|
<datePicker2
|
||||||
|
v-if="isPricingByDayExperiment"
|
||||||
customComponentId="dateQuestion"
|
customComponentId="dateQuestion"
|
||||||
selectableDatesSetting="custom"
|
selectableDatesSetting="custom"
|
||||||
ref="datePicker"
|
ref="datePicker"
|
||||||
|
|
@ -69,7 +80,8 @@ import navbar from "@/fmg-components/nav-bar/nav-bar";
|
||||||
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
import funnelSubHeader from "@/fmg-components/funnel-sub-header/funnel-sub-header";
|
||||||
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
|
import loadingModal from "@/fmg-components/loading-modal/loading-modal.vue";
|
||||||
import { Form, defineRule } from "vee-validate";
|
import { Form, defineRule } from "vee-validate";
|
||||||
import datePicker2 from "@/digital-components/date-picker/date-picker-2";
|
import datePicker from "@/digital-components/date-picker/date-picker";
|
||||||
|
import datePicker2 from "@/experiment-components/date-picker-2";
|
||||||
import locationAlerts from "@/layouts/schedule/location-alerts/location-alerts";
|
import locationAlerts from "@/layouts/schedule/location-alerts/location-alerts";
|
||||||
import timeSlotModalQuestion from "./time-slot-modal-question/time-slot-modal-question";
|
import timeSlotModalQuestion from "./time-slot-modal-question/time-slot-modal-question";
|
||||||
import textBlock from "@/digital-components/text-block/text-block";
|
import textBlock from "@/digital-components/text-block/text-block";
|
||||||
|
|
@ -91,6 +103,8 @@ import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from "@/constants/sched
|
||||||
import { errorMessages } from "@/constants/error-messages";
|
import { errorMessages } from "@/constants/error-messages";
|
||||||
import { required } from "@/helpers/validation-rules";
|
import { required } from "@/helpers/validation-rules";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
|
import experimentMixin from "@/mixins/experiment-mixin.js";
|
||||||
|
import { experimentSettings } from "@/constants/experiments";
|
||||||
|
|
||||||
// DEFINE VALIDATION RULES
|
// DEFINE VALIDATION RULES
|
||||||
defineRule("date-required", required(errorMessages.DATE_REQUIRED));
|
defineRule("date-required", required(errorMessages.DATE_REQUIRED));
|
||||||
|
|
@ -301,6 +315,13 @@ export default {
|
||||||
(selectableDate) => selectableDate.date === this.selectedDate
|
(selectableDate) => selectableDate.date === this.selectedDate
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
isPricingByDayExperiment() {
|
||||||
|
return (
|
||||||
|
experimentMixin.methods
|
||||||
|
.getSettingValue(experimentSettings.PRICING_BY_DAY)
|
||||||
|
?.toLowerCase() === "true"
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
splitCopyOnCMSPlaceHolder,
|
splitCopyOnCMSPlaceHolder,
|
||||||
|
|
@ -537,6 +558,7 @@ export default {
|
||||||
funnelSubHeader,
|
funnelSubHeader,
|
||||||
Form,
|
Form,
|
||||||
loadingModal,
|
loadingModal,
|
||||||
|
datePicker,
|
||||||
datePicker2,
|
datePicker2,
|
||||||
locationAlerts,
|
locationAlerts,
|
||||||
timeSlotModalQuestion,
|
timeSlotModalQuestion,
|
||||||
|
|
|
||||||
|
|
@ -330,11 +330,18 @@ export default {
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) {
|
// if no value due to field being optional, blank both phone and email address
|
||||||
const phone = this.emailOrSms.replace(/[()]/g, "");
|
if (!this.emailOrSms) {
|
||||||
await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false);
|
await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, "", false);
|
||||||
} else {
|
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, "", false);
|
||||||
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false);
|
}
|
||||||
|
else {
|
||||||
|
if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) {
|
||||||
|
const phone = this.emailOrSms.replace(/[()]/g, "");
|
||||||
|
await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false);
|
||||||
|
} else {
|
||||||
|
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.dispatchStoreAction(
|
await this.dispatchStoreAction(
|
||||||
|
|
@ -380,11 +387,18 @@ export default {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) {
|
// if no value due to field being optional, blank both phone and email address
|
||||||
const phone = this.emailOrSms.replace(/[()]/g, "");
|
if (!this.emailOrSms) {
|
||||||
await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false);
|
await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, "", false);
|
||||||
} else {
|
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, "", false);
|
||||||
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false);
|
}
|
||||||
|
else {
|
||||||
|
if (vinPagesMixin.methods.isPhoneNumber(this.emailOrSms)) {
|
||||||
|
const phone = this.emailOrSms.replace(/[()]/g, "");
|
||||||
|
await this.dispatchStoreAction(storeActions.SAVE_PHONE_NUMBER, phone, false);
|
||||||
|
} else {
|
||||||
|
await this.dispatchStoreAction(storeActions.SAVE_EMAIL, this.emailOrSms, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.dispatchStoreAction(
|
await this.dispatchStoreAction(
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ import {
|
||||||
containsRecalParts,
|
containsRecalParts,
|
||||||
getTopLevelPartsWithRecal,
|
getTopLevelPartsWithRecal,
|
||||||
isRecalPartOrHasChildRecalPart,
|
isRecalPartOrHasChildRecalPart,
|
||||||
|
getRecalPartNumbers,
|
||||||
} from "@/helpers/recal-helper";
|
} from "@/helpers/recal-helper";
|
||||||
import { externalParameterStatus } from "@/constants/external-parameters";
|
import { externalParameterStatus } from "@/constants/external-parameters";
|
||||||
import { experimentSettings } from "@/constants/experiments";
|
import { experimentSettings } from "@/constants/experiments";
|
||||||
|
|
@ -1712,10 +1713,15 @@ export const actions = {
|
||||||
|
|
||||||
var endPoint = `${endpoints.GetMobileFeePart.url}/?serviceType=${serviceType}&facilityType=${facilityType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItacOptimized=${isItacOptimized}&zipCode=${zipCode}`;
|
var endPoint = `${endpoints.GetMobileFeePart.url}/?serviceType=${serviceType}&facilityType=${facilityType}&parentAccountNumber=${parentAccountNumber}&billToAccountNumber=${billToAccountNumber}&providerNumber=${providerNumber}&isItacOptimized=${isItacOptimized}&zipCode=${zipCode}`;
|
||||||
|
|
||||||
const recalPartNumber = getRecalPartNumber(order.lineItems?.glassParts[0]);
|
const recalPartNumbers = getRecalPartNumbers(order.lineItems?.glassParts);
|
||||||
const carId = order.vehicle?.carId;
|
const carId = order.vehicle?.carId;
|
||||||
if (recalPartNumber && carId) {
|
if (recalPartNumbers && recalPartNumbers.length > 0 && carId) {
|
||||||
endPoint = `${endPoint}&partNumbers=${recalPartNumber}&carId=${carId}`;
|
let additionalQueryParams = ``;
|
||||||
|
for (let i = 0; i < recalPartNumbers.length; i++) {
|
||||||
|
additionalQueryParams += `&partNumbers[${i}]=${recalPartNumbers[i]}`;
|
||||||
|
}
|
||||||
|
additionalQueryParams += `&carId=${carId}`;
|
||||||
|
endPoint += additionalQueryParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coverageStatus) {
|
if (coverageStatus) {
|
||||||
|
|
@ -3760,15 +3766,3 @@ function getExternalParameterDefaultState() {
|
||||||
function saveExternalParameterState(externalParameterState) {
|
function saveExternalParameterState(externalParameterState) {
|
||||||
window.sessionStorage.setItem("externalParameterState", JSON.stringify(externalParameterState));
|
window.sessionStorage.setItem("externalParameterState", JSON.stringify(externalParameterState));
|
||||||
}
|
}
|
||||||
|
|
||||||
//This function finds the recalibration part and returns the part number for it.
|
|
||||||
function getRecalPartNumber(glassPartsArray) {
|
|
||||||
const recalPart = glassPartsArray.childParts.find(
|
|
||||||
(item) => item.partType === partTypeStrings.ADAS_RECALIBRATION
|
|
||||||
);
|
|
||||||
if (recalPart) {
|
|
||||||
return recalPart.partNumber;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue