DigitalConsumer.FixMyGlass/src/layouts/license-plate-lookup/license-plate-lookup.spec.js

612 lines
21 KiB
JavaScript

// Components
import licensePlateLookup from "@/layouts/license-plate-lookup/license-plate-lookup.vue";
// Supporting Files
import { settleAllPromises } from "@/helpers/layout-helper.js";
import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { nextTick } from "vue";
import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations";
import store from "@/store";
jest.mock('@/assets/img/loader.gif', () => 'loader.gif')
jest.mock('@/assets/img/windshield.png', () => 'windshield.png')
// Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({
settleAllPromises: jest.fn(),
}));
// Mock fetchCmsContentForPage
jest.mock("@/helpers/cms-content-helper", () => ({
fetchCmsContentForPage: jest.fn(),
}));
describe("license-plate-lookup.vue", () => {
describe("get values from store", () => {
test("getLicensePlateFromStore returns store license plate", async () => {
// Arrange
const { wrapper } = setupMocks({});
const mockLicensePlate = "TESTPLATE";
store.commit(storeMutations.UPDATE_REGISTRATION_LICENSE_PLATE, mockLicensePlate);
// Act
const licensePlate = wrapper.vm.getLicensePlateFromStore();
// Assert
expect(licensePlate).toEqual(mockLicensePlate);
});
test("getRegistrationZipFromStore returns store registration zip", async () => {
// Arrange
const { wrapper } = setupMocks({});
const mockRegistrationZip = "12345";
store.commit(storeMutations.UPDATE_REGISTRATION_ZIP_CODE, mockRegistrationZip);
// ACT
const registrationZip = wrapper.vm.getRegistrationZipFromStore();
// Assert
expect(registrationZip).toEqual(mockRegistrationZip);
});
test("getEmailFromStore returns store customer email", async () => {
// Arrange
const { wrapper } = setupMocks({});
const mockEmail = "test@test.com";
store.commit(storeMutations.UPDATE_CUSTOMER_EMAIL_ADDRESS, mockEmail);
// ACT
const customerEmail = wrapper.vm.getEmailFromStore();
// Assert
expect(customerEmail).toEqual(mockEmail);
});
test("getServiceZipFromStore returns store service zip", async () => {
// Arrange
const { wrapper } = setupMocks({});
const mockServiceZip = "11111";
store.commit(storeMutations.UPDATE_SERVICE_LOCATION_ZIP_CODE, mockServiceZip);
// ACT
const serviceZip = wrapper.vm.getServiceZipFromStore();
// Assert
expect(serviceZip).toEqual(mockServiceZip);
});
});
describe("navigation", () => {
test("BackButtonAction triggers a router.navigate change", async () => {
//Arrange
const { wrapper } = setupMocks({});
//Act
licensePlateLookup.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "license-plate-lookup" } },
undefined,
(c) => c(wrapper.vm)
);
wrapper.vm.backButtonAction();
//Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
});
describe("on forwardButtonAction click", () => {
test("Navigate forward should be called and isCarIdDifferent should be set to false when data entered matches store data on forwardButtonAction click", async () => {
// Arrange
const { wrapper } = setupMocks({});
const mockCarId = "TESTID";
store.commit(storeMutations.UPDATE_GLASS_TO_REPLACE, []);
store.commit(storeMutations.UPDATE_CAR_ID, mockCarId);
wrapper.vm.validateZip = jest.fn().mockImplementation(() => {
return { data: { isServiceable: true } };
});
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => "");
const vinLookup = { data: { vehicle: { carId: mockCarId } } }
wrapper.vm.lookupVin = jest.fn().mockImplementation(() => {
return new Promise(resolve => resolve(vinLookup));
});
wrapper.vm.navigateForward = jest.fn();
//Act
licensePlateLookup.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "license-plate-lookup" } },
undefined,
(c) => c(wrapper.vm)
);
await wrapper.vm.forwardButtonAction();
//Assert
expect(wrapper.vm.isCarIdDifferent).toEqual(false);
expect(wrapper.vm.navigateForward).toHaveBeenCalled();
});
test("Function should stop and datam isRegistrationZipServicable should be set to false when service zip entered returns false on forwardButtonAction click", async () => {
// Arrange
const { wrapper } = setupMocks({});
wrapper.vm.validateZip = jest.fn().mockImplementation(() => {
return { data: { isServiceable: false } };
});
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => {
return '';
});
//Act
licensePlateLookup.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "license-plate-lookup" } },
undefined,
(c) => c(wrapper.vm)
);
await wrapper.vm.forwardButtonAction();
//Assert
expect(wrapper.vm.isRegistrationZipServicable).toEqual(false);
});
test("Function should stop and datam isCarIdDifferent should be set to true when carId entered doesn't match store carId or previously entered carId on forwardButtonAction click", async () => {
// Arrange
const { wrapper } = setupMocks({});
store.commit(storeMutations.UPDATE_GLASS_TO_REPLACE, []);
wrapper.vm.validateZip = jest.fn().mockImplementation(() => {
return { data: { isServiceable: true } };
});
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => {
return '';
});
const vinLookup = { data: { vehicle: { carId: "TESTID1" } } }
wrapper.vm.lookupVin = jest.fn().mockImplementation(() => {
return new Promise(resolve => resolve(vinLookup));
});
//Act
licensePlateLookup.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "license-plate-lookup" } },
undefined,
(c) => c(wrapper.vm)
);
await wrapper.vm.forwardButtonAction();
//Assert
expect(wrapper.vm.isCarIdDifferent).toEqual(true);
});
test("Navigate forward should be called and isCarId should be set to true when carId entered matches previously entered carId and rest of data entered matches store data on forwardButtonAction click", async () => {
// Arrange
const { wrapper } = setupMocks({});
wrapper.vm.validateZip = jest.fn().mockImplementation(() => {
return { data: { isServiceable: true } };
});
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => {
return '';
});
const vinLookup = { data: { vehicle: { carId: "TESTID1" } } }
wrapper.vm.lookupVin = jest.fn().mockImplementation(() => {
return new Promise(resolve => resolve(vinLookup));
});
wrapper.vm.previouslyEnteredCarId = "TESTID1";
wrapper.vm.navigateForward = jest.fn();
//Act
licensePlateLookup.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "license-plate-lookup" } },
undefined,
(c) => c(wrapper.vm)
);
await wrapper.vm.forwardButtonAction();
//Assert
expect(wrapper.vm.navigateForward).toHaveBeenCalled();
expect(wrapper.vm.isCarIdDifferent).toEqual(true);
});
});
describe("navigateForward", () => {
test("navigateAfterSave should be called if isCarIdDifferent is true and isSelectedGlassAvailableForVehicle is false when navigateForward is called", async () => {
// Arrange
const { wrapper } = setupMocks({});
//Act
await wrapper.setData({
isCarIdDifferent: true,
isSelectedGlassAvailableForVehicle: false
})
wrapper.vm.$router.navigateAfterSave = jest.fn();
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => {
return '';
});
wrapper.vm.dispatchStoreAction = jest.fn();
await wrapper.vm.navigateForward();
//Assert
expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled();
});
test("navigateAfterSaveToHeritageFunnel should be called if isCarIdDifferent is false or isSelectedGlassAvailableForVehicle is true when navigateForward is called", async () => {
// Arrange
const { wrapper } = setupMocks({});
//Act
await wrapper.setData({
isCarIdDifferent: false
})
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => {
return '';
});
navigateToHeritage.navigateAfterSaveToHeritageFunnel = jest.fn();
await wrapper.vm.navigateForward();
//Assert
expect(navigateToHeritage.navigateAfterSaveToHeritageFunnel).toHaveBeenCalled();
});
test("carId matches returned vehicle => navigateForwardWithSingleCarMatch", async () => {
// Arrange
const { wrapper } = setupMocks({});
await wrapper.setData({
isCarIdDifferent: false
})
wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
// Act
await wrapper.vm.navigateForward();
//Assert
expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalledTimes(1);
});
test("selected glass is available for returned vehicle => navigateForwardWithSingleCarMatch", async () => {
// Arrange
const { wrapper } = setupMocks({});
await wrapper.setData({
isSelectedGlassAvailableForVehicle: true
})
wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
// Act
await wrapper.vm.navigateForward();
//Assert
expect(wrapper.vm.navigateForwardWithSingleCarMatch).toHaveBeenCalledTimes(1);
});
});
});
describe("button text", () => {
test("Button Text should revert to initial value when licensePlate textfield has new text", async () => {
// Arrange
const { wrapper } = setupMocks({});
//Act
wrapper.setData({
licensePlate: "NEWPLATE"
})
wrapper.vm.getCmsContent = jest.fn();
await wrapper.vm.$nextTick();
//Assert
expect(wrapper.vm.$refs.funnelFooter.updateButtonText).toHaveBeenCalled();
});
test("Button Text should revert to initial value when registrationZip textfield has new text", async () => {
// Arrange
const { wrapper } = setupMocks({});
//Act
await wrapper.setData({
registrationZip: "55555"
})
wrapper.vm.getCmsContent = jest.fn();
await wrapper.vm.$nextTick();
//Assert
expect(wrapper.vm.$refs.funnelFooter.updateButtonText).toHaveBeenCalled();
});
test("Button Text should revert to initial value when serviceZip textfield has new text", async () => {
// Arrange
const { wrapper } = setupMocks({});
//Act
await wrapper.setData({
serviceZip: "55555"
})
wrapper.vm.getCmsContent = jest.fn();
await wrapper.vm.$nextTick();
//Assert
expect(wrapper.vm.$refs.funnelFooter.updateButtonText).toHaveBeenCalled();
});
})
describe("saving registrationZip and serviceZip on continue", () => {
test("registrationZip is serviceable and vehicle match is found => sets service zip/state to registration zip/state", async () => {
// Arrange
const { wrapper } = setupMocks({});
const mockCarId = "TESTID";
store.commit(storeMutations.UPDATE_GLASS_TO_REPLACE, []);
store.commit(storeMutations.UPDATE_CAR_ID, mockCarId)
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => "");
wrapper.vm.validateZip = jest.fn().mockImplementation((zip) => {
if (zip)
return { data: { isServiceable: true, state: "OH" } };
return
});
const vinLookup = { data: { vehicle: { carId: mockCarId } } }
wrapper.vm.lookupVin = jest.fn().mockImplementation(() => new Promise(resolve => resolve(vinLookup)));
await wrapper.setData({ registrationZip: "00000" });
navigateToHeritage.navigateAfterSaveToHeritageFunnel = jest.fn();
// Act
await wrapper.vm.forwardButtonAction();
// Assert
expect(store.getters.order.serviceLocation.zipCode).toEqual(store.getters.vehicle.registration.zipCode);
expect(store.getters.vehicle.registration.zipCode).toEqual("00000");
expect(store.getters.order.serviceLocation.zipCode).toEqual("00000");
})
test("vehicle match is found but registrationZip is not serviceable => shows service zip/state field", async () => {
// Arrange
const { wrapper } = setupMocks({});
wrapper.vm.validateZip = jest.fn().mockImplementation(() => {
return { data: { isServiceable: false, state: "XX" } };
});
await wrapper.setData({ registrationZip: "00000" });
navigateToHeritage.navigateAfterSaveToHeritageFunnel = jest.fn();
// Act
await wrapper.vm.forwardButtonAction();
// Assert
const serviceZipField = wrapper.findComponent("[cmsWidgetName='ServiceZip']");
expect(serviceZipField.exists()).toBe(true);
expect(serviceZipField.isVisible()).toBe(true);
})
test("registrationZip is not serviceable so serviceZip field is shown, continue clicked => user cannot continue", async () => {
// Arrange
const { wrapper } = setupMocks({});
wrapper.vm.validateZip = jest.fn().mockImplementation(() => {
return { data: { isServiceable: false, state: "XX" } };
});
await wrapper.setData({ registrationZip: "00000" });
navigateToHeritage.navigateAfterSaveToHeritageFunnel = jest.fn();
await wrapper.vm.forwardButtonAction();
wrapper.vm.$router.navigateAfterSave = jest.fn();
// At this point, serviceZip field is shown
// Act
// Continue without entering anything into service zip field
await wrapper.vm.forwardButtonAction();
// Assert
const serviceZipField = wrapper.findComponent("[cmsWidgetName='ServiceZip']");
expect(serviceZipField.exists()).toBe(true);
expect(serviceZipField.isVisible()).toBe(true); 3
expect(navigateToHeritage.navigateAfterSaveToHeritageFunnel).not.toHaveBeenCalled();
expect(wrapper.vm.$router.navigateAfterSave).not.toHaveBeenCalled();
});
test("registrationZip is not serviceable so serviceZip field is shown, user enters serviceZip => user can continue", async () => {
// Arrange
const { wrapper } = setupMocks({});
const registrationZip = "00000";
const serviceZip = "99999";
const mockCarId = "TestCarId";
store.commit(storeMutations.UPDATE_CAR_ID, mockCarId);
wrapper.vm.validateZip = jest.fn().mockImplementation((zip) => {
return { data: { isServiceable: zip == registrationZip ? false : true, state: "XX" } };
});
const vinLookup = { data: { vehicle: { carId: mockCarId } } }
wrapper.vm.lookupVin = jest.fn().mockImplementation(() => {
return new Promise(resolve => resolve(vinLookup));
});
wrapper.vm.navigateForward = jest.fn();
await wrapper.setData({ registrationZip: registrationZip });
await wrapper.vm.forwardButtonAction();
// At this point, serviceZip field is shown
await wrapper.setData({ serviceZip: serviceZip });
// Act
// Continue after entering input into service zip field
await wrapper.vm.forwardButtonAction();
// Assert
const serviceZipField = wrapper.findComponent("[cmsWidgetName='ServiceZip']");
expect(serviceZipField.exists()).toBe(true);
expect(serviceZipField.isVisible()).toBe(true);
expect(wrapper.vm.navigateForward).toHaveBeenCalled();
});
test("registrationZip is not serviceable so serviceZip field is shown, user enters serviceZip => service and registration zips/states saved", async () => {
// Arrange
const { wrapper } = setupMocks({});
const registrationZip = "00000";
const serviceZip = "99999";
const mockCarId = "TestCarId";
store.commit(storeMutations.UPDATE_CAR_ID, mockCarId);
wrapper.vm.validateZip = jest.fn().mockImplementation((zip) => {
return { data: { isServiceable: zip == registrationZip ? false : true, state: "XX" } };
});
const vinLookup = { data: { vehicle: { carId: mockCarId } } }
wrapper.vm.lookupVin = jest.fn().mockImplementation(() => {
return new Promise(resolve => resolve(vinLookup));
});
wrapper.vm.navigateForward = jest.fn();
await wrapper.setData({ registrationZip: registrationZip });
await wrapper.vm.forwardButtonAction();
// At this point, serviceZip field is shown
await wrapper.setData({ serviceZip: serviceZip });
// Act
// Continue after entering value into service zip field
await wrapper.vm.forwardButtonAction();
// Assert
expect(store.getters.vehicle.registration.zipCode).toEqual(registrationZip);
expect(store.getters.order.serviceLocation.zipCode).toEqual(serviceZip);
expect(wrapper.vm.navigateForward).toHaveBeenCalled();
});
})
describe("miscellaneous", () => {
test("CarId set, arePagePrerequisitesValid should be true ", async () => {
//Arrange
const { wrapper } = setupMocks({});
store.commit(storeMutations.UPDATE_CAR_ID, "TESTCARID");
//Act
licensePlateLookup.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "license-plate-lookup" } },
undefined,
(c) => c(wrapper.vm)
);
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
await nextTick();
//Assert
expect(arePagePrerequisitesValid).toBe(true);
});
test("Dispatch reset damage and dependencies should be called if isCarIdDifferent is true and isSelectedGlassAvailableForVehicle is false when updateCustomerInfo is called", async () => {
// Arrange
const { wrapper } = setupMocks({});
//Act
await wrapper.setData({
isCarIdDifferent: true,
isSelectedGlassAvailableForVehicle: false
})
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => {
return '';
});
store.commit = jest.fn();
const vehicleInfo = { year: "2020", make: "honda", model: "civic", style: "2 door", carId: "TestId", category: "testCat", imageUrl: "image.jpg", imageVifNumber: "123", imageColor: "blue" }
await wrapper.vm.updateCustomerInfo('vin', vehicleInfo, 'registrationState');
//Assert
expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalled();
})
test("dispatchStoreAction called on validate zip", async () => {
// Arrange
const { wrapper } = setupMocks({});
//Act
await wrapper.vm.validateZip("12345");
//Assert
expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalled();
});
test("dispatchStoreAction called on lookup vin", async () => {
// Arrange
const { wrapper } = setupMocks({});
//Act
await wrapper.vm.lookupVin("zzz123fqsfwg");
//Assert
expect(wrapper.vm.dispatchStoreAction).toHaveBeenCalled();
});
})
});
function setupMocks({
pageHeaderWidgetHeaderText = {},
mountOptionsMockData = {},
partsOrQuestions = []
}) {
store.commit(storeMutations.RESET_STATE);
//Mock api responses
const apiResponses = {
cmsContent: {
FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
VehicleBannerWidget: {
GenericVehicleImage:
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
},
FunnelHeaderWidget: {
LogoImage:
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
},
},
};
mountOptionsMockData = {
...mountOptionsMockData,
router: {
navigate: jest.fn(),
},
actionList: [
{
actionName: storeActions.GET_PARTS_OR_QUESTIONS,
data: {
partsOrQuestions: partsOrQuestions
}
},
]
}
const apiPromise = Promise.resolve(apiResponses);
settleAllPromises.mockImplementation(() => apiPromise);
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
const mountOptions = getMountOptions(mountOptionsMockData);
mountOptions['attachTo'] = document.body; // append wrapper to document.body to test DOM methods
const wrapper = shallowMount(licensePlateLookup, mountOptions);
wrapper.vm.setCmsContent = jest.fn();
wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => "");
wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
wrapper.vm.$refs.funnelFooter.removeLoader = jest.fn();
wrapper.vm.$refs.loadingModal.showModal = jest.fn();
return { wrapper, apiPromise };
}