Merge pull request #606 from Safelite/feature/digital/SSR-1049

SSR-1049 Heavy Vehicle bailout
This commit is contained in:
Josh Dassinger 2024-04-08 08:16:04 -05:00 committed by GitHub
commit 1ab14d7413
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 77 additions and 26 deletions

View file

@ -7,7 +7,8 @@ const bailoutCode = Object.freeze({
DoNotSeeMyShop: 5,
PricingResponseError: 6,
TPANotEnabled: 7,
RequestCallback: 8
RequestCallback: 8,
HeavyTruckVehicle: 9
});
export default bailoutCode;

View file

@ -48,6 +48,10 @@ const bailoutMessage = Object.freeze({
RequestCallback: () => ({
code: bailoutCode.RequestCallback,
message: 'User selected option to receive callback from Safelite'
}),
HeavyTruckVehicle: (carId) => ({
code: bailoutCode.HeavyTruckVehicle,
message: `User selected a heavy truck vehicle. Car ID: ${carId} `
})
});

View file

@ -135,10 +135,6 @@ import { formatAmountInDollars } from '@/helpers/text-helper.js';
const SAFELITE_PROVIDER = 'Safelite';
function setBailout(currentRoute, message) {
useMainStore().setBailout(currentRoute, message);
}
export default {
name: 'coverage-statement',
components: {
@ -186,7 +182,7 @@ export default {
await useMainStore().getFinalDeductible();
pricingResults = await useMainStore().getPriceOrderItems(availableLineItems)
.catch((err) => {
setBailout(to, bailoutMessage.pricingResponseError(
useMainStore().setBailout(bailoutMessage.pricingResponseError(
availableLineItems.map((li) => li.partNumber),
{ code: err.code, message: err.message, data: err.data }
));
@ -397,17 +393,14 @@ export default {
useMainStore().updateSupportingItems(this.supportingItems);
this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_SAFELITE);
} else {
this.setBailoutWithMessage(bailoutMessage.RequestCallback());
useMainStore().setBailout(bailoutMessage.RequestCallback());
this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_NON_SAFELITE_SHOP);
}
} else {
this.setBailoutWithMessage(bailoutMessage.coverageStatementInvalidState());
useMainStore().setBailout(bailoutMessage.coverageStatementInvalidState());
this.navigateWithScenario(navigationScenarios.CLICKED_FORWARD_WITH_INVALID_STATE);
}
},
setBailoutWithMessage(message) {
setBailout(this.$router.currentRoute, message);
},
navigateWithScenario(scenario) {
this.$router.navigate(scenario, this.$route);
},

View file

@ -123,7 +123,6 @@ export default {
const pricedVaps = await useMainStore().getPriceOrderItems(unpricedVaps)
.catch((err) => {
useMainStore().setBailout(
to,
bailoutMessage.pricingResponseError(
unpricedVaps.map((li) => li.partNumber),
{ code: err.code, message: err.message, data: err.data }

View file

@ -274,7 +274,7 @@ describe('policy-vehicles.vue', () => {
// Assert
// eslint-disable-next-line max-len
expect(wrapper.vm.mainStore.setBailout).toHaveBeenCalledWith(wrapper.vm.$router.currentRoute, bailoutMessage.vehicleLookupError(vin, lookupReturnValue.data));
expect(wrapper.vm.mainStore.setBailout).toHaveBeenCalledWith(bailoutMessage.vehicleLookupError(vin, lookupReturnValue.data));
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,
undefined,

View file

@ -195,7 +195,7 @@ export default {
return this.navigateForward();
}
this.mainStore.setBailout(this.$router.currentRoute, bailoutMessage.vehicleLookupError(vehicle.vin, vehicleLookupResponse.data));
this.mainStore.setBailout(bailoutMessage.vehicleLookupError(vehicle.vin, vehicleLookupResponse.data));
return this.navigateForward();
}

View file

@ -196,7 +196,7 @@ export default {
}
scenario = this.navigationScenarios.CLICKED_FORWARD_WITH_TPA_ENABLED;
} else {
this.mainStore.setBailout(this.$router.currentRoute, bailoutMessage.TPANotEnabled());
this.mainStore.setBailout(bailoutMessage.TPANotEnabled());
scenario = this.navigationScenarios.CLICKED_FORWARD_WITH_TPA_DISABLED;
}
break;

View file

@ -125,7 +125,6 @@ export default {
const pricingResults = await store.getPriceOrderItems(availableLineItems)
.catch((err) => {
useMainStore().setBailout(
to,
bailoutMessage.pricingResponseError(
availableLineItems.map((li) => li.partNumber),
{ code: err.code, message: err.message, data: err.data }

View file

@ -361,10 +361,7 @@ describe('TPAConfirmation.vue', () => {
await contactCarrierText.trigger('click');
// Assert
expect(wrapper.vm.mainStore.setBailout).toHaveBeenCalledWith(
wrapper.vm.$router.currentRoute,
bailoutMessage.RequestCallback
);
expect(wrapper.vm.mainStore.setBailout).toHaveBeenCalledWith(bailoutMessage.RequestCallback);
});
});
describe('Navigation', () => {

View file

@ -203,7 +203,7 @@ export default {
}
},
setBailoutInfo() {
this.mainStore.setBailout(this.$router.currentRoute, bailoutMessage.RequestCallback);
this.mainStore.setBailout(bailoutMessage.RequestCallback);
},
toDisplayPhoneNumber,
formatAmountInDollars,

View file

@ -365,7 +365,7 @@ export default {
return getTpaProvidersResult?.data?.shopProviders ?? [];
},
doNotSeeMyShopLinkClick() {
this.mainStore.setBailout(this.$router.currentRoute, bailoutMessage.doNotSeeMyShop());
this.mainStore.setBailout(bailoutMessage.doNotSeeMyShop());
this.$router.navigate(
this.navigationScenarios.CLICKED_DO_NOT_SEE_MY_SHOP_LINK,
this.$route

View file

@ -197,6 +197,11 @@ export default {
navigateForward() {
this.mainStore.setVehicle().then(() => {
if (this.mainStore.isBailout) {
this.$router.navigate(this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT, this.$route);
return;
}
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD,
this.$route

View file

@ -179,7 +179,7 @@ export default {
if (vehicleLookupResponse.error) {
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NOT_FOUND;
this.mainStore.setBailout(this.$router.currentRoute, bailoutMessage.vehicleNotFound(this.vin));
this.mainStore.setBailout(bailoutMessage.vehicleNotFound(this.vin));
this.resetVehicleFromLookup();
this.$refs.siteFooter.removeLoader();
// Temp solution to turn on 'disabled' style on the Continue button

View file

@ -175,7 +175,7 @@ router.afterEach(async (to, from) => {
const saveSessionSynchronous = !!from.params[routerParams.SAVE_SESSION_SYNCHRONOUS];
await saveSession({ shouldAwaitSaveSessionQueue: saveSessionSynchronous }).catch((error) => {
if (from.name === issPageValues.WELCOME_PAGE) {
store.setBailout(router, bailoutMessage.saveSessionError(error.data));
store.setBailout(bailoutMessage.saveSessionError(error.data));
router.navigate(
navigationScenarios.SAVE_SESSION_FAILED,
{ query: { issPage: issPageValues.WELCOME_PAGE } }

View file

@ -14,6 +14,10 @@ const routingTable = () => [
{
scenario: navigationScenarios.CLICKED_FORWARD,
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE
},
{
scenario: navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,
destinationIssPageValue: issPageValues.BAILOUT_PAGE
}
]
},

View file

@ -22,6 +22,8 @@ import {
repairWaivedForSelectedVehicle
} from '@/helpers/policy-vehicle-helper';
import partTypeStrings from '@/constants/part-type-strings';
import bailoutMessage from '@/constants/bailoutMessage';
import bailoutCode from "@/constants/bailoutCode";
const storeId = 'main';
@ -261,6 +263,7 @@ export const useMainStore = defineStore({
isClaimRegistrationRequired: (state) => state.issConfig.isClaimRegistrationRequired,
isClaimAlreadyRegistered: (state) => state.order.payment.insuranceCoverage.claimNumber !== null,
isBailout: (state) => state.applicationUser.pageData[issPageValues.BAILOUT_PAGE] != null,
bailoutCode: (state) => state.applicationUser.pageData[issPageValues.BAILOUT_PAGE]?.bailoutCode,
isNoComp: (state) => !!state.order.policy.noCoverage,
isITAC: (state) => !!state.order.policy.isITAC,
isVerifiedCoverageStatus: (state) => state.order.payment.insuranceCoverage.coverageStatus === coverageStatuses.VERIFIED,
@ -1588,6 +1591,15 @@ export const useMainStore = defineStore({
this.order.vehicle.imageVifNumber = vehicle.imageVifNumber;
this.order.vehicle.imageColor = vehicle.imageVifColor;
if (vehicle.canSafeliteService) {
if (this.isBailout && this.bailoutCode === bailoutCode.HeavyTruckVehicle) {
// reset previously set bailout if vehicle can be serviced.
this.resetBailout();
}
} else {
this.setBailout(bailoutMessage.HeavyTruckVehicle(vehicle.carId));
}
// These could be undefined
this.order.policy.noCoverage = vehicle.noCoverage;
const currentCoverageStatus = vehicle.noCoverage ? coverageStatuses.NO_COMP : coverageStatuses.PENDING;
@ -2249,12 +2261,15 @@ export const useMainStore = defineStore({
this.updateRegistration(registrationInfo);
},
setBailout(currentRoute, bailoutData) {
setBailout(bailoutData) {
const params = new URL(document.location.toString()).searchParams;
const currentPage = params.get('issPage');
this.updatePageData({
page: issPageValues.BAILOUT_PAGE,
data: {
url: window.location.href,
page: currentRoute.value?.name ?? currentRoute.name,
page: currentPage || 'Unknown Page',
bailoutCode: bailoutData.code,
errorMessage: bailoutData.message,
submit: false

View file

@ -6,6 +6,7 @@ import coverageStatuses from '@/constants/coverage-statuses.js';
import { paymentMethods } from '@/constants/payment-method-constants';
import { endpoints } from '@/constants/endpoints';
import { AppointmentTypeStrings } from '@/constants/schedule-constants';
import bailoutCode from '@/constants/bailoutCode';
describe('Store', () => {
let store;
@ -228,6 +229,21 @@ describe('Store', () => {
}
);
it('setVehicle is bailout if the vehicle cannot be serviced by Safelite', () => {
// Arrange
const vehicle = {
carId: getRandomString(6, 6),
canSafeliteService: false
};
// Act
store.updateVehicle(vehicle);
// Assert
expect(store.isBailout).toBe(true);
expect(store.bailoutCode).toBe(bailoutCode.HeavyTruckVehicle);
});
// TODO update test to work also checking store values
it('setVehicle should call globalMethods.callHttpClient', () => {
// Arrange
@ -1050,6 +1066,12 @@ describe('Store', () => {
it('sets expected vehicle data', async () => {
// Arrange
globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve(fullApiResponse));
store.lookupVehicleByVin = jest.fn().mockReturnValue(Promise.resolve({
data: {
vin: vehicle.vin,
canSafeliteService: true
}
}));
const duplicate = {
referralNumber: getRandomString(6, 6),
@ -1073,6 +1095,12 @@ describe('Store', () => {
it('sets expected customer data', async () => {
// Arrange
globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve(fullApiResponse));
store.lookupVehicleByVin = jest.fn().mockReturnValue(Promise.resolve({
data: {
vin: vehicle.vin,
canSafeliteService: true
}
}));
const duplicate = {
referralNumber: getRandomString(6, 6),
@ -1099,6 +1127,12 @@ describe('Store', () => {
it('sets expected remaining order data', async () => {
// Arrange
globalMethods.callHttpClient = jest.fn().mockReturnValue(Promise.resolve(fullApiResponse));
store.lookupVehicleByVin = jest.fn().mockReturnValue(Promise.resolve({
data: {
vin: vehicle.vin,
canSafeliteService: true
}
}));
const duplicate = {
referralNumber: getRandomString(6, 6),