CASH-2563: Bailout on 500 from GetPartsOrQuestions
This commit is contained in:
parent
dd291a980c
commit
75f0184314
8 changed files with 171 additions and 20 deletions
|
|
@ -131,6 +131,8 @@ const storeActions = {
|
|||
UPDATE_HAS_TRIGGERED_ERROR: "updateHasTriggeredError",
|
||||
GET_VALID_IDEMPOTENCY_KEY: "getValidIdempotencyKey",
|
||||
CORRECT_IDEMPOTENCY_KEY_EXPIRY: "correctIdempotencyKeyExpiry",
|
||||
|
||||
SAVE_BAILOUT_CODE: "saveBailoutCode",
|
||||
};
|
||||
|
||||
export { storeActions };
|
||||
|
|
|
|||
|
|
@ -114,6 +114,9 @@ const storeMutations = {
|
|||
UPDATE_EXPERIMENTS: "updateExperiments",
|
||||
UPDATE_TRIGGERED_SITE_ENTRY: "updateTriggeredSiteEntry",
|
||||
|
||||
// BAILOUT MUTATIONS
|
||||
UPDATE_BAILOUT_CODE: "updateBailoutCode",
|
||||
|
||||
// EXTERNAL_PARAMETER MUTATIONS
|
||||
UPDATE_IS_EXTERNAL_PARAMETER: "updateIsExternalParameter",
|
||||
UPDATE_EXTERNAL_PARAMETER_YEAR: "updateExternalParameterYear",
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ export default {
|
|||
|
||||
methods: {
|
||||
getBailoutCodeFromStore() {
|
||||
return bailoutCodes.PARTS_NOT_FOUND;
|
||||
return store.getters.applicationUser.bailoutCode;
|
||||
},
|
||||
getFirstNameFromStore() {
|
||||
return store.getters.order.customer.firstName;
|
||||
|
|
@ -248,10 +248,11 @@ export default {
|
|||
|
||||
computed: {
|
||||
getSubHeaderWidget() {
|
||||
if (this.bailoutCode === bailoutCodes.PARTS_NOT_FOUND) {
|
||||
return "PartsNotFoundSubHeaderWidget";
|
||||
} else {
|
||||
return "FunnelSubHeaderWidget";
|
||||
switch (this.bailoutCode) {
|
||||
case bailoutCodes.PARTS_NOT_FOUND:
|
||||
return "PartsNotFoundSubHeaderWidget";
|
||||
default:
|
||||
return "FunnelSubHeaderWidget";
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
|||
13
src/mixins/bailout-mixin.js
Normal file
13
src/mixins/bailout-mixin.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { navigationScenarios } from "@/router/constants/navigation-scenarios";
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
navigateToBailoutPage(vm, bailoutCode) {
|
||||
const self = vm ?? this;
|
||||
|
||||
self.dispatchStoreAction(self.storeActions.SAVE_BAILOUT_CODE, bailoutCode).then(() => {
|
||||
self.$router.navigateWithoutSaving(navigationScenarios.BAILOUT, self.pageName);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
103
src/mixins/bailout-mixin.spec.js
Normal file
103
src/mixins/bailout-mixin.spec.js
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
import bailoutMixin from "@/mixins/bailout-mixin";
|
||||
import { storeActions } from "@/constants/store-actions.js";
|
||||
import { navigationScenarios } from "@/router/constants/navigation-scenarios";
|
||||
import { bailoutCodes } from "@/constants/bailout-codes.js";
|
||||
|
||||
describe("bailout-mixin.js", () => {
|
||||
test("navigateToBailoutPage: dispatches SAVE_BAILOUT_CODE action with bailout code", async () => {
|
||||
// Arrange
|
||||
const mockVm = createMockVm();
|
||||
const bailoutCode = bailoutCodes.PARTS_NOT_FOUND;
|
||||
|
||||
// Act
|
||||
await bailoutMixin.methods.navigateToBailoutPage(mockVm, bailoutCode);
|
||||
|
||||
// Assert
|
||||
expect(mockVm.dispatchStoreAction).toHaveBeenCalledWith(
|
||||
storeActions.SAVE_BAILOUT_CODE,
|
||||
bailoutCode
|
||||
);
|
||||
});
|
||||
|
||||
test("navigateToBailoutPage: navigates to bailout page after saving bailout code", async () => {
|
||||
// Arrange
|
||||
const mockVm = createMockVm();
|
||||
const bailoutCode = bailoutCodes.PARTS_NOT_FOUND;
|
||||
|
||||
// Act
|
||||
await bailoutMixin.methods.navigateToBailoutPage(mockVm, bailoutCode);
|
||||
|
||||
// Assert
|
||||
expect(mockVm.$router.navigateWithoutSaving).toHaveBeenCalledWith(
|
||||
navigationScenarios.BAILOUT,
|
||||
mockVm.pageName
|
||||
);
|
||||
});
|
||||
|
||||
test("navigateToBailoutPage: uses current context (this) when vm is not provided", async () => {
|
||||
// Arrange
|
||||
const mockRouter = {
|
||||
navigateWithoutSaving: jest.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
const mockThis = {
|
||||
dispatchStoreAction: jest.fn().mockResolvedValue(undefined),
|
||||
$router: mockRouter,
|
||||
storeActions: storeActions,
|
||||
pageName: "test-page",
|
||||
};
|
||||
|
||||
const bailoutCode = bailoutCodes.PARTS_NOT_FOUND;
|
||||
|
||||
// Act
|
||||
await bailoutMixin.methods.navigateToBailoutPage.call(mockThis, undefined, bailoutCode);
|
||||
|
||||
// Assert
|
||||
expect(mockThis.dispatchStoreAction).toHaveBeenCalledWith(
|
||||
storeActions.SAVE_BAILOUT_CODE,
|
||||
bailoutCode
|
||||
);
|
||||
});
|
||||
|
||||
test("navigateToBailoutPage: passes correct bailout code to store", async () => {
|
||||
// Arrange
|
||||
const mockVm = createMockVm();
|
||||
const customBailoutCode = 999;
|
||||
|
||||
// Act
|
||||
await bailoutMixin.methods.navigateToBailoutPage(mockVm, customBailoutCode);
|
||||
|
||||
// Assert
|
||||
expect(mockVm.dispatchStoreAction).toHaveBeenCalledWith(
|
||||
storeActions.SAVE_BAILOUT_CODE,
|
||||
customBailoutCode
|
||||
);
|
||||
});
|
||||
|
||||
test("navigateToBailoutPage: calls navigateWithoutSaving with correct parameters", async () => {
|
||||
// Arrange
|
||||
const mockVm = createMockVm();
|
||||
const mockPageName = "vehicle-damage";
|
||||
mockVm.pageName = mockPageName;
|
||||
const bailoutCode = bailoutCodes.PARTS_NOT_FOUND;
|
||||
|
||||
// Act
|
||||
await bailoutMixin.methods.navigateToBailoutPage(mockVm, bailoutCode);
|
||||
|
||||
// Assert
|
||||
expect(mockVm.$router.navigateWithoutSaving).toHaveBeenCalledWith(
|
||||
navigationScenarios.BAILOUT,
|
||||
mockPageName
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
function createMockVm() {
|
||||
return {
|
||||
dispatchStoreAction: jest.fn().mockResolvedValue(undefined),
|
||||
$router: {
|
||||
navigateWithoutSaving: jest.fn().mockResolvedValue(undefined),
|
||||
},
|
||||
storeActions,
|
||||
pageName: "test-page",
|
||||
};
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
import { storeActions } from "@/constants/store-actions.js";
|
||||
import store from "@/store";
|
||||
import vehicleQuestionsMixin from "@/mixins/vehicle-questions-mixin";
|
||||
import bailoutMixin from "@/mixins/bailout-mixin";
|
||||
import { saveSession } from "@/helpers/heritage-integration/order-helper.js";
|
||||
import { experimentSettings } from "@/constants/experiments";
|
||||
import { vinLookupMethodSelections } from "@/constants/vin-lookup-method-selections.js";
|
||||
import { bailoutCodes } from "@/constants/bailout-codes";
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
|
|
@ -34,6 +36,11 @@ export default {
|
|||
const result = await this.dispatchStoreAction(storeActions.GET_PARTS_OR_QUESTIONS, {
|
||||
pageNameToLog: pageName,
|
||||
});
|
||||
|
||||
if (result.PartsNotFound) {
|
||||
bailoutMixin.methods.navigateToBailoutPage(this, bailoutCodes.PARTS_NOT_FOUND);
|
||||
}
|
||||
|
||||
const partsOrQuestions = result.data.partsOrQuestions;
|
||||
|
||||
vehicleQuestionsMixin.methods.navigateForward(partsOrQuestions, this);
|
||||
|
|
|
|||
|
|
@ -274,6 +274,10 @@ const routingTable = function () {
|
|||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
|
||||
destinationPageData: routeData.QUOTE,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.BAILOUT,
|
||||
destinationPageData: routeData.BAILOUT,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -216,6 +216,7 @@ const getDefaultState = () => {
|
|||
affiliateCookies: [],
|
||||
loggingOption: false,
|
||||
hasAlreadyTriggeredError: false,
|
||||
bailoutCode: null,
|
||||
},
|
||||
idempotencyKeyFields: {
|
||||
referralCorrelationId: null,
|
||||
|
|
@ -950,6 +951,9 @@ export const mutations = {
|
|||
state.idempotencyKeyFields.totalInCents = totalInCents;
|
||||
state.idempotencyKeyFields.expiryTime = expiryTime;
|
||||
},
|
||||
updateBailoutCode(state, bailoutCode) {
|
||||
state.applicationUser.bailoutCode = bailoutCode;
|
||||
},
|
||||
};
|
||||
|
||||
// Export Getters
|
||||
|
|
@ -1903,21 +1907,31 @@ export const actions = {
|
|||
// create a new array to avoid mutating state
|
||||
const glassArrayForPayload = convertGlassPieceNamingForApi(glassArray);
|
||||
|
||||
const response = await globalMethods.callHttpClient({
|
||||
method: endpoints.GetPartsOrQuestions.method,
|
||||
endpoint: endpoints.GetPartsOrQuestions.url,
|
||||
payload: {
|
||||
carId: carId,
|
||||
glassPieces: glassArrayForPayload,
|
||||
zip: zipCode,
|
||||
vin: vin,
|
||||
serviceType: serviceType,
|
||||
referralSeqNumber: referralSeqNumber,
|
||||
parentAccountNumber: parentAccountNumber,
|
||||
},
|
||||
logApiCall: true,
|
||||
pageNameToLog: pageNameToLog,
|
||||
});
|
||||
const response = await globalMethods
|
||||
.callHttpClient({
|
||||
method: endpoints.GetPartsOrQuestions.method,
|
||||
endpoint: endpoints.GetPartsOrQuestions.url,
|
||||
payload: {
|
||||
carId: carId,
|
||||
glassPieces: glassArrayForPayload,
|
||||
zip: zipCode,
|
||||
vin: vin,
|
||||
serviceType: serviceType,
|
||||
referralSeqNumber: referralSeqNumber,
|
||||
parentAccountNumber: parentAccountNumber,
|
||||
},
|
||||
logApiCall: true,
|
||||
pageNameToLog: pageNameToLog,
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.status == 500) {
|
||||
return { PartsNotFound: true };
|
||||
}
|
||||
});
|
||||
|
||||
if (response.PartsNotFound) {
|
||||
return response;
|
||||
}
|
||||
|
||||
// Flatten location and name properties
|
||||
response.data.partsOrQuestions = convertGlassPieceNamingFromApi(
|
||||
|
|
@ -3820,6 +3834,10 @@ export const actions = {
|
|||
context.commit(storeMutations.UPDATE_IDEMPOTENCY_KEY, newKey);
|
||||
}
|
||||
},
|
||||
|
||||
saveBailoutCode(context, bailoutCode) {
|
||||
context.commit(storeMutations.UPDATE_BAILOUT_CODE, bailoutCode);
|
||||
},
|
||||
};
|
||||
|
||||
export default createStore({
|
||||
|
|
|
|||
Loading…
Reference in a new issue