SSR-189
This commit is contained in:
parent
5e6eadfe62
commit
8e0ec66203
9 changed files with 706 additions and 33 deletions
|
|
@ -0,0 +1,58 @@
|
|||
/* eslint-env jest */
|
||||
import { render } from '@testing-library/vue';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import '@testing-library/jest-dom';
|
||||
import VinLocationInformationComponent from './vin-location-information.vue';
|
||||
|
||||
const mockText = Object.freeze({
|
||||
HEADER: 'Mock Header',
|
||||
BODY: 'Mock Body',
|
||||
});
|
||||
|
||||
const mountOptions = {
|
||||
global: {
|
||||
mixins: [
|
||||
{
|
||||
methods: {
|
||||
getCmsContent: jest.fn((cmsWidgetName, fieldName) => {
|
||||
if (cmsWidgetName === 'WhereCanIFindMyVINToggle') {
|
||||
if (fieldName === 'HeaderText') {
|
||||
return mockText.HEADER;
|
||||
}
|
||||
|
||||
if (fieldName === 'BodyText') {
|
||||
return mockText.BODY;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
describe('vin-location-information.vue', () => {
|
||||
test('VIN Location Detail is NOT displayed on the screen as a default.', () => {
|
||||
const { container } = render(VinLocationInformationComponent, mountOptions);
|
||||
|
||||
const vinLocationDetailSection = container.querySelector('#vin-location-detail-wrapper');
|
||||
|
||||
expect(vinLocationDetailSection).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('Toggling VIN Location Detail', async () => {
|
||||
const user = userEvent.setup();
|
||||
const { container, getByText } = render(VinLocationInformationComponent, mountOptions);
|
||||
const toggleLink = getByText(mockText.HEADER);
|
||||
|
||||
await user.click(toggleLink);
|
||||
let vinLocationDetailSection = container.querySelector('#vin-location-detail-wrapper');
|
||||
expect(vinLocationDetailSection).toBeVisible();
|
||||
|
||||
await user.click(toggleLink);
|
||||
vinLocationDetailSection = container.querySelector('#vin-location-detail-wrapper');
|
||||
expect(vinLocationDetailSection).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
alertClass="alert-danger"
|
||||
cmsWidgetName="AlertVinNotFoundWidget"
|
||||
id="vehicle-not-found-alert"
|
||||
aria-label="vehicle-not-found-alert"
|
||||
/>
|
||||
</template>
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
cmsWidgetName="AlertMatchedDifferentVehicleWidget"
|
||||
:manualCopy="body"
|
||||
:manualHeadline="header"
|
||||
aria-label="vehicle-not-matched-alert"
|
||||
/>
|
||||
</template>
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
/* eslint-env jest */
|
||||
import { getDamageString } from '@/helpers/damage-helper';
|
||||
import vehicleLookupAlertTypes from '@/constants/vehicle-lookup-alert-types';
|
||||
import { RouterLinkStub } from '@vue/test-utils';
|
||||
import { render } from '@testing-library/vue';
|
||||
import '@testing-library/jest-dom';
|
||||
import VinLookupAlertsComponent from './vin-lookup-alerts.vue';
|
||||
|
||||
jest.mock('@/helpers/damage-helper');
|
||||
|
||||
const mountOptions = {
|
||||
global: {
|
||||
stubs: {
|
||||
RouterLink: RouterLinkStub,
|
||||
},
|
||||
mixins: [
|
||||
{
|
||||
methods: {
|
||||
getCmsContent: jest.fn(() => ''),
|
||||
getFooterInfoBoxHeight: jest.fn(() => 80),
|
||||
cssClassNameForCmsWidget: jest.fn(() => 'widget-name-mock-class'),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
describe('vin-lookup-alerts.vue', () => {
|
||||
test('VehicleNotFoundAlert is displayed on the screen', () => {
|
||||
mountOptions.props = {
|
||||
activeAlertType: vehicleLookupAlertTypes.NOT_FOUND,
|
||||
};
|
||||
const { queryByRole } = render(VinLookupAlertsComponent, mountOptions);
|
||||
const vehicleNotFoundAlert = queryByRole('alert', { name: 'vehicle-not-found-alert' });
|
||||
const vehicleNotMatchedAlert = queryByRole('alert', { name: 'vehicle-not-matched-alert' });
|
||||
|
||||
expect(vehicleNotFoundAlert).toBeVisible();
|
||||
expect(vehicleNotMatchedAlert).toEqual(null);
|
||||
});
|
||||
|
||||
test('VehicleNotMatchedAlert is displayed on the screen', () => {
|
||||
getDamageString.mockImplementation(() => 'Mock Damage String');
|
||||
mountOptions.props = {
|
||||
activeAlertType: vehicleLookupAlertTypes.NOT_MATCHED,
|
||||
};
|
||||
mountOptions.global.provide = {
|
||||
vehicleFromLookup: {},
|
||||
};
|
||||
|
||||
const { queryByRole } = render(VinLookupAlertsComponent, mountOptions);
|
||||
const vehicleNotFoundAlert = queryByRole('alert', { name: 'vehicle-not-found-alert' });
|
||||
const vehicleNotMatchedAlert = queryByRole('alert', { name: 'vehicle-not-matched-alert' });
|
||||
|
||||
expect(vehicleNotFoundAlert).toEqual(null);
|
||||
expect(vehicleNotMatchedAlert).toBeVisible();
|
||||
});
|
||||
});
|
||||
453
src/layouts/vin-lookup/vin-lookup.spec.js
Normal file
453
src/layouts/vin-lookup/vin-lookup.spec.js
Normal file
|
|
@ -0,0 +1,453 @@
|
|||
/* eslint-env jest */
|
||||
import '@testing-library/jest-dom';
|
||||
import { flushPromises } from '@vue/test-utils';
|
||||
import { render, waitFor } from '@testing-library/vue';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { errorMessages } from '@/constants/error-messages';
|
||||
import { issPageValues } from '@/router/router-constants/issPage-values';
|
||||
import { navigationScenarios } from '@/router/router-constants/navigation-scenarios';
|
||||
import { routerParams } from '@/router/router-params';
|
||||
import { useMainStore } from '@/store';
|
||||
import VinLookupComponent from './vin-lookup.vue';
|
||||
|
||||
const continueButtonQuerySelector = '[data-test-id="site-footer-main-button"]';
|
||||
const errorMessageWrapperElSelector = '#vin-question-wrapper .form-test-error';
|
||||
const vinInputSelector = '#vin-question';
|
||||
const mockValidVin = '12345678901234567';
|
||||
const mockCarId = 'Mock Car Id';
|
||||
const lookupVehicleByVin = {
|
||||
methodName: 'lookupVehicleByVin',
|
||||
mockResponse: {
|
||||
data: {
|
||||
carId: mockCarId,
|
||||
},
|
||||
},
|
||||
};
|
||||
const getPartsOrQuestions = {
|
||||
methodName: 'getPartsOrQuestions',
|
||||
mockResponse: null,
|
||||
};
|
||||
|
||||
const vehicleWithPartQuestionsMockResponse = {
|
||||
data: {
|
||||
partsOrQuestions: [
|
||||
{
|
||||
partQuestions: [
|
||||
{
|
||||
id: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const vehicleWithMultiplePartsMockResponse = {
|
||||
data: {
|
||||
partsOrQuestions: [
|
||||
{
|
||||
parts: [
|
||||
{
|
||||
id: 1,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const vehicleWithMoldingQuestionsMockResponse = {
|
||||
data: {
|
||||
partsOrQuestions: [
|
||||
{
|
||||
parts: [
|
||||
{
|
||||
childPartQuestions: [
|
||||
{
|
||||
id: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const vehicleWithCapabilityQuestionsMockResponse = {
|
||||
data: {
|
||||
partsOrQuestions: [
|
||||
{
|
||||
parts: [
|
||||
{
|
||||
requiresCapabilityQuestions: true,
|
||||
partNumber: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const vehicleWithNoAdditionalPartsOrQuestionsMockResponse = {
|
||||
data: {
|
||||
partsOrQuestions: [
|
||||
{
|
||||
parts: [
|
||||
{
|
||||
childPartQuestions: [],
|
||||
requiresCapabilityQuestions: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
partQuestions: null,
|
||||
},
|
||||
};
|
||||
|
||||
const mockRoute = {
|
||||
query: {
|
||||
// Needed inside vehicle-questions-mixin
|
||||
issPage: issPageValues.VIN_LOOKUP,
|
||||
},
|
||||
};
|
||||
const mockRouter = {
|
||||
navigate: jest.fn(),
|
||||
};
|
||||
const maska = jest.fn();
|
||||
jest.mock('@/helpers/damage-helper', () => ({
|
||||
isGlassAvailableForCarId: jest.fn().mockResolvedValue(false),
|
||||
}));
|
||||
const mountOptions = {
|
||||
global: {
|
||||
directives: {
|
||||
maska,
|
||||
},
|
||||
mixins: [
|
||||
{
|
||||
methods: {
|
||||
getCmsContent: jest.fn(() => ''),
|
||||
getFooterInfoBoxHeight: jest.fn(() => 80),
|
||||
cssClassNameForCmsWidget: jest.fn(() => 'widget-name-mock-class'),
|
||||
getPageNameByQueryString: jest.fn(() => ''),
|
||||
},
|
||||
computed: {
|
||||
navigationScenarios() {
|
||||
return navigationScenarios;
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
mocks: {
|
||||
$route: mockRoute,
|
||||
$router: mockRouter,
|
||||
},
|
||||
plugins: [createTestingPinia({
|
||||
initialState: {
|
||||
main: {
|
||||
order: {
|
||||
vehicle: {
|
||||
carId: mockCarId,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
stubActions: false,
|
||||
})],
|
||||
stubs: {
|
||||
siteHeader: true,
|
||||
siteSubHeader: true,
|
||||
vehicleBanner: true,
|
||||
vinLocationInformation: true,
|
||||
vinLookupAlerts: true,
|
||||
vinQuestion: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('vin-lookup.vue', () => {
|
||||
describe('Client-side validation', () => {
|
||||
test.each([
|
||||
{ vin: null },
|
||||
{ vin: '' },
|
||||
])('VIN Required error messsage is displayed.', async ({ vin }) => {
|
||||
const user = userEvent.setup();
|
||||
mountOptions.data = () => ({
|
||||
vin,
|
||||
});
|
||||
mountOptions.global.stubs.vinQuestion = false;
|
||||
const { container } = render(VinLookupComponent, mountOptions);
|
||||
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||
|
||||
user.click(continueButton);
|
||||
await flushPromises();
|
||||
await waitFor(() => {
|
||||
const errorMessageWrapperEl = container.querySelector(errorMessageWrapperElSelector);
|
||||
expect(errorMessageWrapperEl).toBeVisible();
|
||||
|
||||
const errorMessageEl = errorMessageWrapperEl.querySelector('span');
|
||||
expect(errorMessageEl.textContent).toBe(errorMessages.VIN_REQUIRED);
|
||||
});
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ vin: '11' },
|
||||
{ vin: 'I1234567890123456' },
|
||||
{ vin: 'O1234567890123456' },
|
||||
{ vin: 'Q1234567890123456' },
|
||||
])('VIN Invalid Format error messsage is displayed.', async ({ vin }) => {
|
||||
const user = userEvent.setup();
|
||||
mountOptions.data = () => ({
|
||||
vin,
|
||||
});
|
||||
mountOptions.global.stubs.vinQuestion = false;
|
||||
const { container } = render(VinLookupComponent, mountOptions);
|
||||
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||
|
||||
user.click(continueButton);
|
||||
await flushPromises();
|
||||
await waitFor(() => {
|
||||
const errorMessageWrapperEl = container.querySelector(errorMessageWrapperElSelector);
|
||||
expect(errorMessageWrapperEl).toBeVisible();
|
||||
|
||||
const errorMessageEl = errorMessageWrapperEl.querySelector('span');
|
||||
expect(errorMessageEl.textContent).toBe(errorMessages.VIN_FORMAT);
|
||||
});
|
||||
});
|
||||
|
||||
test('No error message is displayed when the vin is in the accepted format.', async () => {
|
||||
const user = userEvent.setup();
|
||||
mountOptions.data = () => ({
|
||||
vin: '12345678901234567',
|
||||
});
|
||||
mountOptions.global.stubs.vinQuestion = false;
|
||||
const { container } = render(VinLookupComponent, mountOptions);
|
||||
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||
|
||||
user.click(continueButton);
|
||||
await flushPromises();
|
||||
await waitFor(() => {
|
||||
const errorMessageWrapperEl = container.querySelector(errorMessageWrapperElSelector);
|
||||
expect(errorMessageWrapperEl).not.toBeVisible();
|
||||
|
||||
const errorMessageEl = errorMessageWrapperEl.querySelector('span');
|
||||
expect(errorMessageEl.textContent).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Navigation', () => {
|
||||
test('Click "Back", execute navigate with navigationScenario.CLICKED_BACK.', async () => {
|
||||
const user = userEvent.setup();
|
||||
const { container } = render(VinLookupComponent, mountOptions);
|
||||
const backButton = container.querySelector('[data-test-id="site-footer-back-button"]');
|
||||
|
||||
await user.click(backButton);
|
||||
|
||||
expect(mockRouter.navigate).toHaveBeenCalledTimes(1);
|
||||
expect(mockRouter.navigate).toHaveBeenCalledWith(navigationScenarios.CLICKED_BACK, mockRoute);
|
||||
});
|
||||
|
||||
test('Different vehicle is found than the one entered and the selected glass is not available for that vehicle, navigate back to vehicle-damage page.', async () => {
|
||||
const user = userEvent.setup();
|
||||
mountOptions.global.stubs.vinQuestion = false;
|
||||
getPartsOrQuestions.mockResponse = vehicleWithPartQuestionsMockResponse;
|
||||
lookupVehicleByVin.mockResponse.data.carId = 'Different Car Id';
|
||||
|
||||
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||
.mockResolvedValue(lookupVehicleByVin.mockResponse);
|
||||
jest.spyOn(VinLookupComponent.methods, getPartsOrQuestions.methodName)
|
||||
.mockResolvedValue(getPartsOrQuestions.mockResponse);
|
||||
|
||||
mountOptions.data = () => ({
|
||||
activeVehicleLookupAlertType: null,
|
||||
needToLookupVehicle: false,
|
||||
vehicleFromLookup: {
|
||||
carId: 'Different Car Id',
|
||||
},
|
||||
vin: mockValidVin,
|
||||
});
|
||||
const { container } = render(VinLookupComponent, mountOptions);
|
||||
|
||||
const continueButton = container.querySelector(continueButtonQuerySelector);
|
||||
await user.click(continueButton);
|
||||
|
||||
await flushPromises();
|
||||
await waitFor(() => {
|
||||
expect(mockRouter.navigate).toHaveBeenCalledTimes(1);
|
||||
expect(mockRouter.navigate).toHaveBeenCalledWith(
|
||||
navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||
mockRoute,
|
||||
{},
|
||||
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Succesful navigateForward', () => {
|
||||
test('Vehicle with Part Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_PART_QUESTIONS', async () => {
|
||||
const user = userEvent.setup();
|
||||
mountOptions.global.stubs.vinQuestion = false;
|
||||
getPartsOrQuestions.mockResponse = vehicleWithPartQuestionsMockResponse;
|
||||
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||
.mockResolvedValue(lookupVehicleByVin.mockResponse);
|
||||
jest.spyOn(VinLookupComponent.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.CLICKED_FORWARD_WITH_PART_QUESTIONS,
|
||||
mockRoute,
|
||||
{},
|
||||
{},
|
||||
{ partsOrQuestions: getPartsOrQuestions.mockResponse.data.partsOrQuestions },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('Vehicle with Multiple Parts. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE', async () => {
|
||||
const user = userEvent.setup();
|
||||
mountOptions.global.stubs.vinQuestion = false;
|
||||
getPartsOrQuestions.mockResponse = vehicleWithMultiplePartsMockResponse;
|
||||
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||
.mockResolvedValue(lookupVehicleByVin.mockResponse);
|
||||
jest.spyOn(VinLookupComponent.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.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE,
|
||||
mockRoute,
|
||||
{},
|
||||
{},
|
||||
{ partsOrQuestions: getPartsOrQuestions.mockResponse.data.partsOrQuestions },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('Vehicle with Molding Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS', async () => {
|
||||
const user = userEvent.setup();
|
||||
mountOptions.global.stubs.vinQuestion = false;
|
||||
getPartsOrQuestions.mockResponse = vehicleWithMoldingQuestionsMockResponse;
|
||||
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||
.mockResolvedValue(lookupVehicleByVin.mockResponse);
|
||||
jest.spyOn(VinLookupComponent.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.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS,
|
||||
mockRoute,
|
||||
{},
|
||||
{},
|
||||
{ partsOrQuestions: getPartsOrQuestions.mockResponse.data.partsOrQuestions },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('Vehicle with Capability Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS', async () => {
|
||||
const user = userEvent.setup();
|
||||
const store = useMainStore();
|
||||
mountOptions.global.stubs.vinQuestion = false;
|
||||
getPartsOrQuestions.mockResponse = vehicleWithCapabilityQuestionsMockResponse;
|
||||
|
||||
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||
.mockResolvedValue(lookupVehicleByVin.mockResponse);
|
||||
jest.spyOn(VinLookupComponent.methods, getPartsOrQuestions.methodName)
|
||||
.mockResolvedValue(getPartsOrQuestions.mockResponse);
|
||||
store.getCapabilityQuestions.mockResolvedValueOnce({ data: [] });
|
||||
|
||||
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.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS,
|
||||
mockRoute,
|
||||
{},
|
||||
{},
|
||||
{ partsOrQuestions: getPartsOrQuestions.mockResponse.data.partsOrQuestions },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('Vehicle no additional Parts or Questions. Click "Continue", execute navigate with navigationScenario.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS', async () => {
|
||||
const user = userEvent.setup();
|
||||
mountOptions.global.stubs.vinQuestion = false;
|
||||
getPartsOrQuestions.mockResponse = vehicleWithNoAdditionalPartsOrQuestionsMockResponse;
|
||||
|
||||
jest.spyOn(VinLookupComponent.methods, lookupVehicleByVin.methodName)
|
||||
.mockResolvedValue(lookupVehicleByVin.mockResponse);
|
||||
jest.spyOn(VinLookupComponent.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.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
|
||||
mockRoute,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -40,15 +40,16 @@
|
|||
<script>
|
||||
// Import Supporting Files
|
||||
import { computed } from 'vue';
|
||||
import { endpoints } from '@/constants/endpoints';
|
||||
import vehicleLookupAlertTypes from '@/constants/vehicle-lookup-alert-types';
|
||||
import globalMethods from '@/global-methods';
|
||||
import { fetchCmsContentForPage } from '@/helpers/cms-content-helper';
|
||||
import { isGlassAvailableForCarId } from '@/helpers/damage-helper';
|
||||
import { settleAllPromises } from '@/helpers/layout-helper';
|
||||
import { routerParams } from '@/router/router-params';
|
||||
import { useMainStore } from '@/store';
|
||||
|
||||
// Import Component
|
||||
import baseFormMixin from '@/mixins/base-form-mixin';
|
||||
import vehicleQuestionsMixin from '@/mixins/vehicle-questions-mixin';
|
||||
import { Form } from 'vee-validate';
|
||||
import siteFooter from '@/common-components/site-footer/site-footer.vue';
|
||||
import siteHeader from '@/common-components/site-header/site-header.vue';
|
||||
|
|
@ -60,7 +61,7 @@ import vinQuestion from './vin-question/vin-question.vue';
|
|||
|
||||
export default {
|
||||
name: 'vin-lookup',
|
||||
mixins: [baseFormMixin],
|
||||
mixins: [baseFormMixin, vehicleQuestionsMixin],
|
||||
components: {
|
||||
siteFooter,
|
||||
siteHeader,
|
||||
|
|
@ -79,8 +80,9 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
activeVehicleLookupAlertType: null,
|
||||
needToLookupVehicle: true,
|
||||
vehicleFromLookup: null,
|
||||
vin: null,
|
||||
vin: null,
|
||||
};
|
||||
},
|
||||
provide() {
|
||||
|
|
@ -105,6 +107,14 @@ export default {
|
|||
vm.setCmsContent(resultMap.cmsContent);
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
isCarIdDifferentFromTheStore() {
|
||||
return (
|
||||
this.vehicleFromLookup !== null
|
||||
&& this.vehicleFromLookup.carId !== this.mainStore.vehicle.carId
|
||||
);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
arePagePrerequisiteValid() {
|
||||
return true;
|
||||
|
|
@ -115,40 +125,77 @@ export default {
|
|||
*/
|
||||
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
|
||||
async forwardButtonAction() {
|
||||
this.resetActiveAlert();
|
||||
// Temp solution to reset the 'disabled' style on the Continue button
|
||||
this.$refs.siteFooter.enableForwardAction();
|
||||
|
||||
if (this.needToLookupVehicle) {
|
||||
const vehicleLookupResponse = await this.lookupVehicleByVin(this.vin);
|
||||
|
||||
// NOTE: If form is not valid, this method is not called when 'Continue' button is clicked
|
||||
const vehicleLookupResponse = await this.lookupVehicleByVin(this.vin);
|
||||
if (vehicleLookupResponse.error) {
|
||||
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NOT_FOUND;
|
||||
this.resetVehicleFromLookup();
|
||||
this.$refs.siteFooter.removeLoader();
|
||||
// Temp solution to turn on 'disabled' style on the Continue button
|
||||
// because the form itself actually passes its client-side validation.
|
||||
// SSR-189 Scenario #4.
|
||||
this.$refs.siteFooter.disableForwardButton();
|
||||
return;
|
||||
}
|
||||
|
||||
if (vehicleLookupResponse.error) {
|
||||
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NOT_FOUND;
|
||||
this.resetVehicleFromLookup();
|
||||
// Add vin bcs the response from the service doesn't contain vin
|
||||
this.vehicleFromLookup = Object.assign(vehicleLookupResponse.data, { vin: this.vin });
|
||||
}
|
||||
|
||||
if (this.needToLookupVehicle && this.isCarIdDifferentFromTheStore) {
|
||||
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NOT_MATCHED;
|
||||
|
||||
const vehicleYearMakeModel = `${this.vehicleFromLookup.year} ${this.vehicleFromLookup.make} ${this.vehicleFromLookup.model}`;
|
||||
this.$refs.siteFooter.updateButtonText(`Continue with ${vehicleYearMakeModel}`);
|
||||
this.$refs.siteFooter.removeLoader();
|
||||
|
||||
this.needToLookupVehicle = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let isSelectedGlassAvailableForVehicle = true;
|
||||
if (this.isCarIdDifferentFromTheStore) {
|
||||
isSelectedGlassAvailableForVehicle =
|
||||
await isGlassAvailableForCarId(this.vehicleFromLookup.carId);
|
||||
}
|
||||
|
||||
// navigate back to vehicle-damage
|
||||
if (this.isCarIdDifferentFromTheStore && !isSelectedGlassAvailableForVehicle) {
|
||||
this.mainStore.updateVehicle(this.vehicleFromLookup);
|
||||
this.$router.navigate(
|
||||
this.navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||
this.$route,
|
||||
{},
|
||||
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true }
|
||||
);
|
||||
|
||||
// navigate() doesn't stop the processing flow
|
||||
return;
|
||||
}
|
||||
|
||||
this.mainStore.updateVehicle(this.vehicleFromLookup);
|
||||
const partsOrQuestionsResponse = await this.getPartsOrQuestions();
|
||||
if (partsOrQuestionsResponse.error) {
|
||||
// To Do: Need requirement on what to do here
|
||||
console.error('Error on retrieving PartsOrQuestions');
|
||||
this.$refs.siteFooter.removeLoader();
|
||||
return;
|
||||
}
|
||||
|
||||
this.vehicleFromLookup = vehicleLookupResponse.data;
|
||||
if (this.vehicleFromLookup.carId !== this.mainStore.vehicle.carId) {
|
||||
this.activeVehicleLookupAlertType = vehicleLookupAlertTypes.NOT_MATCHED;
|
||||
|
||||
const vehicleYearMakeModel = `${this.vehicleFromLookup.year} ${this.vehicleFromLookup.make} ${this.vehicleFromLookup.model}`;
|
||||
|
||||
this.$refs.siteFooter.updateButtonText(`Continue with ${vehicleYearMakeModel}`);
|
||||
this.$refs.siteFooter.removeLoader();
|
||||
}
|
||||
|
||||
// Continue
|
||||
// Comes from vehicleQuestionsMixin.navigateForward()
|
||||
await this.navigateForward(partsOrQuestionsResponse.data.partsOrQuestions, this);
|
||||
},
|
||||
async lookupVehicleByVin(vin) {
|
||||
try {
|
||||
const response = await globalMethods.callHttpClient({
|
||||
method: endpoints.LookupVehicleByVin.method,
|
||||
endpoint: endpoints.LookupVehicleByVin.url,
|
||||
payload: {
|
||||
vin,
|
||||
},
|
||||
});
|
||||
async getPartsOrQuestions() {
|
||||
try {
|
||||
const response = await this.mainStore.getPartsOrQuestions();
|
||||
|
||||
return response;
|
||||
} catch (responseError) {
|
||||
|
|
@ -159,6 +206,18 @@ export default {
|
|||
};
|
||||
}
|
||||
},
|
||||
async lookupVehicleByVin(vin) {
|
||||
try {
|
||||
return await this.mainStore.lookupVehicleByVin(vin);
|
||||
}
|
||||
catch (responseError) {
|
||||
return {
|
||||
error: {
|
||||
status: responseError.status,
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
resetActiveAlert() {
|
||||
this.activeVehicleLookupAlertType = null;
|
||||
},
|
||||
|
|
@ -167,5 +226,15 @@ export default {
|
|||
},
|
||||
resetDependentState() {},
|
||||
},
|
||||
watch: {
|
||||
vin() {
|
||||
this.resetActiveAlert();
|
||||
this.$refs.siteFooter.enableForwardAction();
|
||||
this.needToLookupVehicle = true;
|
||||
this.$refs.siteFooter.updateButtonText(
|
||||
this.getCmsContent('SiteFooterWidget', 'ForwardButtonText')
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -100,7 +100,31 @@ const routingTable = function(store) {
|
|||
{
|
||||
scenario: navigationScenarios.CLICKED_BACK,
|
||||
destinationIssPageValue: issPageValues.VEHICLE_LOOKUP,
|
||||
},
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.SELECTED_VIN_WITH_MISMATCHED_GLASS,
|
||||
destinationIssPageValue: issPageValues.VEHICLE_DAMAGE,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_PART_QUESTIONS,
|
||||
destinationIssPageValue: issPageValues.PART_QUESTIONS,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MULTIPLE_PARTS_TO_CHOOSE,
|
||||
destinationIssPageValue: issPageValues.VEHICLE_PARTS,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_MOLDING_QUESTIONS,
|
||||
destinationIssPageValue: issPageValues.MOLDING_QUESTIONS,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_CAPABILITY_QUESTIONS,
|
||||
destinationIssPageValue: issPageValues.CAPABILITY_QUESTIONS,
|
||||
},
|
||||
{
|
||||
scenario: navigationScenarios.CLICKED_FORWARD_WITH_NO_MORE_QUESTIONS,
|
||||
destinationIssPageValue: issPageValues.COVERAGE_STATEMENT,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const routerParams = {
|
||||
DISPLAY_VEHICLE_CHANGE_ALERT: "displayVehicleChangeAlert",
|
||||
};
|
||||
const routerParams = Object.freeze({
|
||||
DISPLAY_VEHICLE_CHANGE_ALERT: "displayVehicleChangeAlert",
|
||||
});
|
||||
|
||||
export { routerParams };
|
||||
|
|
@ -389,6 +389,16 @@ export const useMainStore = defineStore({
|
|||
});
|
||||
},
|
||||
|
||||
lookupVehicleByVin(vin) {
|
||||
return globalMethods.callHttpClient({
|
||||
method: endpoints.LookupVehicleByVin.method,
|
||||
endpoint: endpoints.LookupVehicleByVin.url,
|
||||
payload: {
|
||||
vin,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
setVehicle() {
|
||||
return globalMethods
|
||||
.callHttpClient({
|
||||
|
|
|
|||
Loading…
Reference in a new issue