Merge pull request #484 from Safelite/feature/digital/SSR-462
SSR-462 VIN passed or input doesn't match a CarID in our system
This commit is contained in:
commit
da8f2e2776
9 changed files with 203 additions and 25 deletions
|
|
@ -243,7 +243,7 @@ function mapStringToState(str) {
|
|||
// Reset store state for each match.
|
||||
const valueFromStore = getStoreValueFromString(match[2]);
|
||||
if (!valueFromStore) {
|
||||
console.warning('Unable to resolve global state data.');
|
||||
console.warn('Unable to resolve global state data.');
|
||||
return ''; // if we can't map our string to state data, return an empty string.
|
||||
}
|
||||
const stringWithReplacement = str.replace(match[0], valueFromStore);
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ describe('policyEndorsements.vue', () => {
|
|||
expect(wrapper.vm.$router.navigate)
|
||||
.toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK, undefined);
|
||||
});
|
||||
test('Forward button clicked triggers navigation', () => {
|
||||
test('Forward button clicked with valid car id triggers navigation', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(policyEndorsements, getMountOptions({
|
||||
router: {
|
||||
|
|
@ -148,6 +148,10 @@ describe('policyEndorsements.vue', () => {
|
|||
}
|
||||
}));
|
||||
|
||||
wrapper.setData({
|
||||
hasValidCarId: true
|
||||
});
|
||||
|
||||
// Act
|
||||
wrapper.vm.forwardButtonAction();
|
||||
wrapper.vm.navigateForward();
|
||||
|
|
@ -157,6 +161,27 @@ describe('policyEndorsements.vue', () => {
|
|||
expect(wrapper.vm.$router.navigate)
|
||||
.toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD, undefined);
|
||||
});
|
||||
test('Forward button clicked with invalid car id triggers navigation scenario CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND', () => {
|
||||
// Arrange
|
||||
const wrapper = shallowMount(policyEndorsements, getMountOptions({
|
||||
router: {
|
||||
navigate: jest.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
wrapper.setData({
|
||||
hasValidCarId: false,
|
||||
});
|
||||
|
||||
// Act
|
||||
wrapper.vm.forwardButtonAction();
|
||||
wrapper.vm.navigateForward();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
|
||||
expect(wrapper.vm.$router.navigate)
|
||||
.toHaveBeenCalledWith(navigationScenarios.CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND, undefined);
|
||||
});
|
||||
test('Forward button clicked saves endorsement question answers', () => {
|
||||
// Arrange
|
||||
const mountOptions = getMountOptions({
|
||||
|
|
|
|||
|
|
@ -96,11 +96,17 @@ export default {
|
|||
});
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
setup() {
|
||||
const mainStore = useMainStore();
|
||||
|
||||
return { mainStore };
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
questionAnswersArray: [],
|
||||
schoolPropertyAnswer: '',
|
||||
parkingLotAnswer: '',
|
||||
hasValidCarId: this.mainStore.vehicle.carId && this.mainStore.vehicle.carId !== '0',
|
||||
rules: {
|
||||
selectionRequired: globalRules.OPTION_REQUIRED
|
||||
}
|
||||
|
|
@ -158,10 +164,17 @@ export default {
|
|||
return this.navigateForward();
|
||||
},
|
||||
navigateForward() {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD,
|
||||
this.$route
|
||||
);
|
||||
if (!this.hasValidCarId) {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND,
|
||||
this.$route
|
||||
);
|
||||
} else {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD,
|
||||
this.$route
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -100,7 +100,8 @@ describe('policy-vehicles.vue', () => {
|
|||
policyVehicles: [
|
||||
{ vin }
|
||||
],
|
||||
bailout: false
|
||||
bailout: false,
|
||||
policyVinFound: true
|
||||
});
|
||||
|
||||
const year = getRandomInt(1998, 2023);
|
||||
|
|
@ -126,6 +127,7 @@ describe('policy-vehicles.vue', () => {
|
|||
|
||||
// Assert
|
||||
expect(wrapper.vm.bailout).toBeFalsy();
|
||||
expect(wrapper.vm.policyVinFound).toBeTruthy();
|
||||
expect(store.updateVehicle).toHaveBeenCalledWith(expectedInput);
|
||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
||||
navigationScenarios.CLICKED_FORWARD_LISTED_VEHICLE,
|
||||
|
|
@ -190,6 +192,7 @@ describe('policy-vehicles.vue', () => {
|
|||
async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
wrapper.vm.lookupVehicleByVin = jest.fn().mockReturnValue({ error: true, status: 500 });
|
||||
|
||||
const vin = getRandomString(17, 17);
|
||||
await wrapper.setData({
|
||||
|
|
@ -197,9 +200,6 @@ describe('policy-vehicles.vue', () => {
|
|||
bailout: false
|
||||
});
|
||||
|
||||
const store = useMainStore();
|
||||
store.lookupVehicleByVin.mockReturnValue(Promise.reject());
|
||||
|
||||
// Act
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
|
||||
|
|
@ -214,6 +214,43 @@ describe('policy-vehicles.vue', () => {
|
|||
}
|
||||
);
|
||||
|
||||
test(
|
||||
// eslint-disable-next-line max-len
|
||||
'Vehicle not found in lookupVehicleByVin call => policyVinFound false and navigate forward with CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND scenario.',
|
||||
async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
wrapper.vm.lookupVehicleByVin = jest.fn().mockReturnValue({ error: true, status: 404 });
|
||||
|
||||
const vin = getRandomString(17, 17);
|
||||
await wrapper.setData({
|
||||
selectedVehicleVin: vin,
|
||||
bailout: false,
|
||||
policyVinFound: true,
|
||||
policyVehicles: [{
|
||||
vin,
|
||||
vehicleYear: getRandomInt(2000, 2100),
|
||||
vehicleMake: getRandomString(5, 10),
|
||||
vehicleMode: getRandomString(5, 10),
|
||||
vehicleStyle: getRandomString(5, 10)
|
||||
}]
|
||||
});
|
||||
|
||||
// Act
|
||||
await wrapper.vm.forwardButtonAction();
|
||||
|
||||
// Assert
|
||||
expect(wrapper.vm.bailout).toBeFalsy();
|
||||
expect(wrapper.vm.policyVinFound).toBeFalsy();
|
||||
expect(wrapper.vm.$router.navigate).toHaveBeenCalledWith(
|
||||
navigationScenarios.CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND,
|
||||
undefined,
|
||||
{},
|
||||
{}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
test('vehicle not listed => navigate forward with CLICKED_FORWARD_NON_LISTED_VEHICLE scenario.', async () => {
|
||||
// Arrange
|
||||
const { wrapper } = setupMocks({});
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ export default {
|
|||
policyVehicles,
|
||||
selectedVehicleVin: '',
|
||||
displayGeneric: true,
|
||||
policyVinFound: true,
|
||||
bailout: false,
|
||||
rules: {
|
||||
optionRequired: globalRules.OPTION_REQUIRED
|
||||
|
|
@ -174,6 +175,26 @@ export default {
|
|||
if (this.selectedVehicleVin !== vehicleSelectionOptions.VEHICLE_NOT_LISTED) {
|
||||
const vehicleLookupResponse = await this.lookupVehicleByVin(this.selectedVehicleVin);
|
||||
if (vehicleLookupResponse.error) {
|
||||
if (vehicleLookupResponse.status === 404) {
|
||||
const vehicle = this.policyVehicles.find((pv) => pv.vin === this.selectedVehicleVin);
|
||||
this.mainStore.resetVehicleState();
|
||||
useMainStore().updateVehicle({
|
||||
carId: '0',
|
||||
category: '',
|
||||
year: vehicle.vehicleYear || '',
|
||||
make: vehicle.vehicleMake || '',
|
||||
model: vehicle.vehicleModel || '',
|
||||
style: vehicle.vehicleStyle || '',
|
||||
vin: vehicle.vin,
|
||||
noCoverage: this.noCoverageForSelectedVehicle,
|
||||
deductible: this.deductibleForSelectedVehicle,
|
||||
repairWaived: this.repairWaivedForSelectedVehicle
|
||||
|
||||
});
|
||||
this.policyVinFound = false;
|
||||
return this.navigateForward();
|
||||
}
|
||||
|
||||
this.bailout = true;
|
||||
return this.navigateForward();
|
||||
}
|
||||
|
|
@ -192,12 +213,13 @@ export default {
|
|||
},
|
||||
navigateForward() {
|
||||
if (this.bailout) {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,
|
||||
this.$route,
|
||||
{},
|
||||
{}
|
||||
);
|
||||
this.$router
|
||||
.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,
|
||||
this.$route,
|
||||
{},
|
||||
{}
|
||||
);
|
||||
} else if (this.selectedVehicleVin === vehicleSelectionOptions.VEHICLE_NOT_LISTED) {
|
||||
this.$router
|
||||
.navigate(
|
||||
|
|
@ -211,6 +233,13 @@ export default {
|
|||
this.navigationScenarios.CLICKED_FORWARD_WITH_ENDORSEMENTS,
|
||||
this.$route
|
||||
);
|
||||
} else if (!this.policyVinFound) {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND,
|
||||
this.$route,
|
||||
{},
|
||||
{}
|
||||
);
|
||||
} else {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CLICKED_FORWARD_LISTED_VEHICLE,
|
||||
|
|
@ -225,7 +254,8 @@ export default {
|
|||
return await useMainStore().lookupVehicleByVin(vin);
|
||||
} catch (responseError) {
|
||||
return {
|
||||
error: true
|
||||
error: true,
|
||||
status: responseError.status
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -477,6 +477,43 @@ describe('vin-lookup.vue', () => {
|
|||
);
|
||||
});
|
||||
});
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
test('Policy Vehicle with invalid vin corrected. Click "Continue", execute navigate with navigationScenario.CORRECTED_VIN_FROM_POLICY_VEHICLE', async () => {
|
||||
const user = userEvent.setup();
|
||||
mountOptions.global.stubs.vinQuestion = false;
|
||||
|
||||
mountOptions.data = () => ({
|
||||
vinWithNonMatchingCarId: true,
|
||||
isCarIdDifferentFromTheStore: false,
|
||||
vin: mockValidVin
|
||||
});
|
||||
|
||||
getPartsOrQuestions.mockResponse = vehicleWithNoAdditionalPartsOrQuestionsMockResponse;
|
||||
|
||||
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||
.mockResolvedValue(lookupVehicleByVin.mockResponse);
|
||||
jest.spyOn(vehicleQuestionsMixin.methods, getPartsOrQuestions.methodName)
|
||||
.mockResolvedValue(getPartsOrQuestions.mockResponse);
|
||||
|
||||
const { container } = render(VinLookupComponent, mountOptions);
|
||||
|
||||
const vinInput = container.querySelector(vinInputSelector);
|
||||
await user.type(vinInput, mockValidVin);
|
||||
|
||||
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||
await user.click(continueButton);
|
||||
|
||||
await flushPromises();
|
||||
await waitFor(() => {
|
||||
expect(mockRouter.navigate).toHaveBeenCalledTimes(1);
|
||||
expect(mockRouter.navigate)
|
||||
.toHaveBeenCalledWith(
|
||||
navigationScenarios.CORRECTED_VIN_FROM_POLICY_VEHICLE,
|
||||
mockRoute
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<vehicleBanner
|
||||
class="mt-2 mb-4"
|
||||
cmsWidgetName="VehicleBannerWidget"
|
||||
:displayGenericVehicleImage="false" />
|
||||
:displayGenericVehicleImage="carIdIsValid" />
|
||||
<siteSubHeader cmsWidgetName="SiteSubHeaderWidget" />
|
||||
<vinLookupAlerts
|
||||
class="mt-5"
|
||||
|
|
@ -106,23 +106,28 @@ export default {
|
|||
return { mainStore };
|
||||
},
|
||||
data() {
|
||||
const vin = this.getVinFromStore();
|
||||
return {
|
||||
activeVehicleLookupAlertType: null,
|
||||
activeVehicleLookupAlertType: vin?.length > 0 && !this.hasValidCarId() ? vehicleLookupAlertTypes.NOT_FOUND : null,
|
||||
needToLookupVehicle: true,
|
||||
vehicleFromLookup: null,
|
||||
vin: this.getVinFromStore(),
|
||||
vinWithNonMatchingCarId: vin?.length > 0 && !this.hasValidCarId(),
|
||||
vin,
|
||||
forwardButtonCarStyle: '',
|
||||
vinPopulatedOnPageLoad: this.getVinFromStore()?.length > 0
|
||||
vinPopulatedOnPageLoad: vin?.length > 0 && this.hasValidCarId()
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isCarIdDifferentFromTheStore() {
|
||||
return (
|
||||
this.vehicleFromLookup !== null
|
||||
this.vehicleFromLookup !== null && this.hasValidCarId()
|
||||
&& this.vehicleFromLookup.carId !== this.mainStore.vehicle.carId
|
||||
);
|
||||
},
|
||||
isTwoIdenticalYMMVehicleFound() {
|
||||
if (this.vehicleFromLookup === null) {
|
||||
return false;
|
||||
}
|
||||
const vinYmmFound = `${this.vehicleFromLookup.year} ${this.vehicleFromLookup.make} ${this.vehicleFromLookup.model}`;
|
||||
const vinYmmExpected =
|
||||
`${this.mainStore.order.vehicle.year} ${this.mainStore.order.vehicle.make} ${this.mainStore.order.vehicle.model}`;
|
||||
|
|
@ -138,6 +143,9 @@ export default {
|
|||
return `!X!X!X!X!X!X!X!X!X!X!X${lastSixChars}`;
|
||||
}
|
||||
return 'XXXXXXXXXXXXXXXXX';
|
||||
},
|
||||
carIdIsValid() {
|
||||
return this.hasValidCarId();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
|
@ -155,10 +163,13 @@ export default {
|
|||
getVinFromStore() {
|
||||
return this.mainStore.vehicle.vin;
|
||||
},
|
||||
hasValidCarId() {
|
||||
return this.mainStore.vehicle.carId && this.mainStore.vehicle.carId !== '0';
|
||||
},
|
||||
backButtonAction() {
|
||||
/**
|
||||
* this.navigationScenarios comes from base-mixin
|
||||
*/
|
||||
* this.navigationScenarios comes from base-mixin
|
||||
*/
|
||||
this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
|
||||
},
|
||||
// NOTE: If form is not valid, this method is not called when 'Continue' button is clicked
|
||||
|
|
@ -228,6 +239,14 @@ export default {
|
|||
this.mainStore.updateVehicle(this.vehicleFromLookup);
|
||||
}
|
||||
|
||||
if (this.vinWithNonMatchingCarId) {
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.CORRECTED_VIN_FROM_POLICY_VEHICLE,
|
||||
this.$route
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const partsOrQuestionsResponse = await this.getPartsOrQuestions();
|
||||
if (partsOrQuestionsResponse.error) {
|
||||
// To Do: Need requirement on what to do here
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ const navigationScenarios = Object.freeze({
|
|||
|
||||
// Policy Vehicle
|
||||
CLICKED_FORWARD_LISTED_VEHICLE: 'CLICKED_FORWARD_LISTED_VEHICLE',
|
||||
CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND: 'CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND',
|
||||
CLICKED_FORWARD_NON_LISTED_VEHICLE: 'CLICKED_FORWARD_NON_LISTED_VEHICLE',
|
||||
CLICKED_FORWARD_WITH_ENDORSEMENTS: 'CLICKED_FORWARD_WITH_ENDORSEMENTS',
|
||||
|
||||
|
|
@ -36,6 +37,7 @@ const navigationScenarios = Object.freeze({
|
|||
CLICKED_FORWARD_WITHOUT_VIN: 'CLICKED_FORWARD_WITHOUT_VIN',
|
||||
CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES: 'CLICKED_FORWARD_WITH_MULTIPLE_VEHICLES',
|
||||
SELECTED_VIN_WITH_MISMATCHED_GLASS: 'SELECTED_VIN_WITH_MISMATCHED_GLASS',
|
||||
CORRECTED_VIN_FROM_POLICY_VEHICLE: 'CORRECTED_VIN_FROM_POLICY_VEHICLE',
|
||||
SELECTED_MANUAL_VIN: 'SELECTED_MANUAL_VIN',
|
||||
SELECTED_LICENSE_PLATE: 'SELECTED_LICENSE_PLATE',
|
||||
SELECTED_HOME_ADDRESS: 'SELECTED_HOME_ADDRESS',
|
||||
|
|
|
|||
|
|
@ -86,6 +86,10 @@ const routingTable = () => [
|
|||
scenario: navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CORRECTED_VIN_FROM_POLICY_VEHICLE,
|
||||
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_PART_QUESTIONS,
|
||||
destinationIssPageValue: issPageValues.PART_QUESTIONS
|
||||
|
|
@ -110,6 +114,10 @@ const routingTable = () => [
|
|||
scenario: issPageValues.VEHICLE_LOOKUP,
|
||||
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP
|
||||
},
|
||||
{
|
||||
scenario: issPageValues.BAILOUT_PAGE,
|
||||
destinationIssPageValue: issPageValues.BAILOUT_PAGE
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,
|
||||
destinationIssPageValue: issPageValues.BAILOUT_PAGE
|
||||
|
|
@ -447,6 +455,10 @@ const routingTable = () => [
|
|||
scenario: navigationScenarios.CLICKED_FORWARD_NON_LISTED_VEHICLE,
|
||||
destinationIssPageValue: issPageValues.VEHICLE_SELECTION
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND,
|
||||
destinationIssPageValue: issPageValues.VIN_LOOKUP
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_BAILOUT,
|
||||
destinationIssPageValue: issPageValues.BAILOUT_PAGE
|
||||
|
|
@ -455,7 +467,6 @@ const routingTable = () => [
|
|||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_ENDORSEMENTS,
|
||||
destinationIssPageValue: issPageValues.POLICY_ENDORSEMENTS
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -681,6 +692,10 @@ const routingTable = () => [
|
|||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD,
|
||||
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAR_ID_NOT_FOUND,
|
||||
destinationIssPageValue: issPageValues.VIN_LOOKUP
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue