Merge pull request #527 from Safelite/feature/CSR-347

Feature/CSR-347 - Add unit tests for address-vehicles page
This commit is contained in:
AdamCaouetteSafelite 2022-06-01 10:20:56 -04:00 committed by GitHub
commit a3898b057d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 418 additions and 145 deletions

View file

@ -23,8 +23,6 @@ module.exports = {
"!src/layouts/address-lookup/address-lookup.vue",
"!src/layouts/address-lookup/customer-questions/customer-questions.vue",
"!src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue",
"!src/layouts/address-vehicles/address-vehicles.vue",
"!src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue",
"!src/ux-components/alert\alert.vue",
"!src/helpers/validation-rules.js",
"!src/common-components/menu-modal/menu-modal.vue",

View file

@ -329,8 +329,8 @@ export default {
{
licenseLastName: lastName,
licenseStreetAddress: streetAddress,
licenseZip: zip,
licenseState: state
licenseZip: zip,
licenseState: state,
}, false
);
},

View file

@ -0,0 +1,63 @@
import { shallowMount } from "@vue/test-utils";
import addressVehiclesQuestion from "@/layouts/address-vehicles/address-vehicles-question/address-vehicles-question";
describe("addressVehiclesQuestion.vue", () => {
it("Should return content for differentVehicleAlertHeader", () => {
// Arrange
const wrapper = shallowMount(addressVehiclesQuestion, {
mixins: [mockMixin],
});
// Assert
expect(wrapper.vm.differentVehicleAlertHeader).toEqual('FoundWindshieldTestReturn');
});
it("Should return content for differentVehicleAlertBody", () => {
// Arrange
const wrapper = shallowMount(addressVehiclesQuestion, {
mixins: [mockMixin],
propsData: {
vehicles: ["1", "2"],
modelValue: ["1", "2"],
}
});
// Assert
expect(wrapper.vm.differentVehicleAlertBody).toEqual('FoundWindshieldTestReturn');
});
it("Should emit a modelValue change when setting selectedVehicleVin", async () => {
// Arrange
const wrapper = shallowMount(addressVehiclesQuestion, {
mixins: [mockMixin],
propsData: {
vehicles: ["1", "2"],
modelValue: ["1", "2"],
}
});
// Act
const localThis = { $emit: jest.fn() }
addressVehiclesQuestion.computed.selectedVehicleVin.set.call(localThis, 'newValue');
// Assert
expect(localThis.$emit).toBeCalledWith("update:modelValue", "newValue");
});
});
const mockMixin = {
methods: {
getCmsContent: jest.fn((contentName) => {
if (contentName === "FoundWindshield") {
return 'FoundWindshieldTestReturn';
}
return null;
}),
vehicles: jest.fn(() => {
return [{ vehicle: "test" }];
})
}
}

View file

@ -1,113 +0,0 @@
import { shallowMount } from "@vue/test-utils";
import addressVehiclesQuestion from "@/layouts/address-vehicles/address-vehicles-question/address-vehicles-question";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
// import store from "@/store";
// jest.mock("@/store", () => { return {}; }, { virtual: true });
describe("addressVehiclesQuestion.vue", () => {
it("Should include button-question component", () => {
// Arrange
const wrapper = shallowMount(addressVehiclesQuestion, {
propsData: {
// vehicles: [
// {
// "Name": "testname",
// "Text": "testtext",
// }
// ]
}
});
// console.log('wrapper.html: ', wrapper.html());
// Assert
const buttonQuestion = wrapper.find('button-question-stub');
expect(buttonQuestion).toBe;
});
it("on initialize should pass in questionText", () => {
// Arrange
const wrapper = shallowMount(addressVehiclesQuestion, {
propsData: {},
});
//Act
addressVehiclesQuestion.methods.initializeComponent.call(wrapper.vm, {QuestionText: 'Testing question text'});
// console.log('wrapper.html: ', wrapper.html());
// console.log('wrapper.vm.questionText: ', wrapper.vm.questionText);
// Assert
expect(wrapper.vm.questionText).toEqual('Testing question text');
});
// it("Alert should show if prop isCarIdDifferent is true", () => {
// // Arrange
// const wrapper = shallowMount(addressVehiclesQuestion, setupMountOptions({
// propsData: {
// isCarIdDifferent: true,
// }
// }));
// //Act
// const alert = wrapper.find('alert');
// console.log('wrapper.html: ', wrapper.html());
// console.log('wrapper.vm.questionText: ', wrapper.vm.questionText);
// // Assert
// // expect(wrapper.vm.questionText).toEqual('Testing question text');
// });
});
function setupMountOptions(mountOptionsMockData = {}) {
// //Mock store
// store.dispatch = jest.fn(() => {});
// store.getters = {};
// const mockMixin = {
// methods: {
// getCmsContent: jest.fn().mockImplementation(() => {
// return '';
// }),
// getDamageString: jest.fn().mockImplementation(() => {
// return '';
// })
// },
// store: {
// dispatch: store.dispatch,
// getters: store.getters,
// },
// }
const mockGetCmsContent = jest.fn();
mockGetCmsContent((cmsWidget, field) => {
return field
});
const defaultMountOptions = {
// route: { query: { fmgPage: 'page-name' } },
mixins: {
methods: {
getCmsContent: mockGetCmsContent,
},
},
global: {
mocks: {
store: {
dispatch: store.dispatch,
getters: store.getters,
},
},
},
};
const baseMountOptions = getMountOptions(Object.assign(defaultMountOptions, mountOptionsMockData));
const allMountOptions = Object.assign(defaultMountOptions, baseMountOptions);
console.log('what are allMountOptions??? ', allMountOptions);
return allMountOptions;
}

View file

@ -0,0 +1,349 @@
// Components
import addressVehicles from "@/layouts/address-vehicles/address-vehicles";
// Supporting Files
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import store from "@/store";
import * as navigateToHeritage from "@/helpers/heritage-integration/navigation-helper";
// Mock our module for promises.
jest.mock("@/helpers/damage-helper", () => ({
isGlassAvailableForCarId: () => {
return false;
},
}));
describe("addressVehicles.vue", () => {
test("Should return true for valid page requisites if carId / zipCode / emailAddress / pageData exists", async () => {
// Arrange
const { wrapper } = setupMocks({});
wrapper.vm.$router.navigate = jest.fn();
// Act
const result = wrapper.vm.arePagePrerequisitesValid();
//Assert
expect(result).toBe(true);
wrapper.unmount();
});
test("Should return false for valid page requisites if carId is missing", async () => {
// Arrange
const { wrapper } = setupMocks({});
wrapper.vm.$router.navigate = jest.fn();
// Act
wrapper.vm.$store.getters.order.vehicle.carId = null;
const result = wrapper.vm.arePagePrerequisitesValid();
//Assert
expect(result).toBe(false);
wrapper.unmount();
});
// NOTE: this test is only here to meet code coverage; it does not test any logic in the original function
test("Should navigate to CLICKED_BACK if backButtonAction is run", async () => {
// Arrange
const { wrapper } = setupMocks({});
wrapper.vm.$router.navigate = jest.fn();
// Act
wrapper.setData({
selectedVehicleVin: ['5NMS3CADXLH233004'],
});
wrapper.vm.backButtonAction();
//Assert
expect(wrapper.vm.$router.navigate).toBeCalled();
wrapper.unmount();
});
// NOTE: this test is only here to meet code coverage; it does not test any logic in the original function
test("Should run several related methods if forwardButtonAction is run", async () => {
// Arrange
const { wrapper } = setupMocks({});
const lookupVinResponse = {
data: {
carId: "456"
}
}
// the following has to be set BEFORE changing the data which is being watched, and requires updateButtonText to be mocked
wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
wrapper.vm.$refs.funnelFooter.removeLoader = jest.fn();
wrapper.vm.lookupVin = jest.fn(() => Promise.resolve(lookupVinResponse));
wrapper.vm.$router.navigateAfterSave = jest.fn();
wrapper.vm.updateCustomerInfo = jest.fn().mockImplementation(()=> {});
wrapper.vm.navigateForward = jest.fn().mockImplementation(()=> {});
// Act
wrapper.setData({
selectedVehicleVin: ['5NMS3CADXLH233004'],
});
await wrapper.vm.forwardButtonAction();
wrapper.vm.$nextTick();
//Assert
expect(wrapper.vm.updateCustomerInfo).toBeCalled();
expect(wrapper.vm.navigateForward).toBeCalled();
wrapper.unmount();
});
test("Should return out of forwardButtonAction if lookupVin returns with an error", async () => {
// Arrange
const { wrapper } = setupMocks({});
const lookupVinResponse = {
error: "there is an error"
}
// the following has to be set BEFORE changing the data which is being watched, and requires updateButtonText to be mocked
wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
wrapper.vm.$refs.funnelFooter.removeLoader = jest.fn();
wrapper.vm.lookupVin = jest.fn(() => Promise.reject(lookupVinResponse));
wrapper.vm.$router.navigateAfterSave = jest.fn();
wrapper.vm.updateCustomerInfo = jest.fn().mockImplementation(()=> {});
// Act
wrapper.setData({
selectedVehicleVin: ['5NMS3CADXLH233004'],
});
await wrapper.vm.forwardButtonAction();
wrapper.vm.$nextTick();
//Assert
expect(wrapper.vm.forwardButtonAction).toReturn;
wrapper.unmount();
});
test("Should send dispatch reset if carId is different and selected glass not available for vehicle on updateCustomerInfo", async () => {
// Arrange
const { wrapper } = setupMocks({});
const lookupVinResponse = {
data: {
carId: "456"
}
}
// the following has to be set BEFORE changing the data which is being watched, and requires updateButtonText to be mocked
wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
wrapper.vm.lookupVin = jest.fn(() => Promise.resolve(lookupVinResponse));
wrapper.vm.$router.navigateAfterSave = jest.fn();
// Act
wrapper.setData({
selectedVehicleVin: ['5NMS3CADXLH233004'],
isSelectedGlassAvailableForVehicle: false,
isCarIdDifferent: true,
});
await wrapper.vm.updateCustomerInfo(wrapper.vm.selectedVehicle.vin, wrapper.vm.selectedVehicle.vehicle);
//Assert
expect(store.dispatch).toBeCalledWith("resetDamageAndDependencies");
wrapper.unmount();
});
// NOTE: this test is only here to meet code coverage; it does not test any logic in the original function
test("Should send dispatch store action if lookupVin is called", async () => {
// Arrange
const { wrapper } = setupMocks({});
// Act
await wrapper.vm.lookupVin('1234567890');
//Assert
expect(store.dispatch).toBeCalledWith("lookupVehicleByVin", {"vin": "1234567890"});
wrapper.unmount();
});
test("If selectedVehicleVin changes, then should update isCarIdDifferent", async () => {
// Arrange
const { wrapper } = setupMocks({});
wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
// Act
wrapper.setData({
selectedVehicleVin: ['5NMS3CADXLH233004'],
isCarIdDifferent: false,
});
await wrapper.vm.resetDependentState();
//Assert
expect(wrapper.vm.isCarIdDifferent).toBe(true);
wrapper.unmount();
});
test("If selectedVehicleVin changes, then text on funnel footer should be updated", async () => {
// Arrange
const { wrapper } = setupMocks({});
wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
// Act
wrapper.setData({
selectedVehicleVin: ['5NMS3CADXLH233004'],
isCarIdDifferent: false,
});
await wrapper.vm.resetDependentState();
//Assert
expect(wrapper.vm.$refs.funnelFooter.updateButtonText).toBeCalled();
wrapper.unmount();
});
test("Should navigate to CLICKED_FORWARD scenario if carId is different and selected glass not available for vehicle on navigateForward", async () => {
// Arrange
const { wrapper } = setupMocks({});
wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
wrapper.vm.$router.navigateAfterSave = jest.fn();
// Act
wrapper.setData({
selectedVehicleVin: ['5NMS3CADXLH233004'],
isSelectedGlassAvailableForVehicle: false,
isCarIdDifferent: true,
});
await wrapper.vm.navigateForward();
//Assert
expect(wrapper.vm.$router.navigateAfterSave).toBeCalledTimes(1);
wrapper.unmount();
});
test("Should navigate to navigateAfterSaveToHeritageFunnel if carId is not different on navigateForward", async () => {
// Arrange
const { wrapper } = setupMocks({});
wrapper.vm.$refs.funnelFooter.updateButtonText = jest.fn();
wrapper.vm.$refs.loadingModal.showModal = jest.fn();
navigateToHeritage.navigateAfterSaveToHeritageFunnel = jest.fn();
// Act
wrapper.setData({
selectedVehicleVin: ['5NMS3CADXLH233004'],
isSelectedGlassAvailableForVehicle: true,
isCarIdDifferent: false,
});
await wrapper.vm.navigateForward();
//Assert
expect(navigateToHeritage.navigateAfterSaveToHeritageFunnel).toBeCalledTimes(1);
wrapper.unmount();
});
});
function setupMocks({
// modelValueProp = "1900",
cmsQuestionText = "CMS text goes here",
// dataFromStoreApi = [],
}) {
//Mock store
store.dispatch = jest.fn(() => {});
store.getters = {
pageData: jest.fn((pageName) => {
// console.log('pageName: ', pageName) // address-vehicles
return [
{
vehicle: {
"carId": "CR00069309",
"category": "SUV",
"year": 2020,
"make": "Hyundai",
"model": "Santa Fe",
"style": "4 door utility",
"imageUrl": "https://dbhdyzvm8lm25.cloudfront.net/color_0320_032/MY2020/13769/13769_cc0320_032_WW8.jpg",
"imageVifNumber": "13769",
"imageVifColor": "white"
},
vin: "5NMS3CADXLH233004"
},
];
}),
order: {
vehicle: {
carId: "123",
},
serviceLocation: {
zipCode: "12345"
},
customer: {
emailAddress: "qw@er.ty"
}
},
damage: {
glassToReplace: "Windshield"
},
vehicle: {
carId: "456",
}
};
// baseMixin.methods.dispatchStoreAction = jest.fn();
const mountOptions = getMountOptions({
store: {
dispatch: store.dispatch,
getters: store.getters,
},
router: {
navigate: jest.fn(),
},
});
//Mock props
const mockMixin = {
methods: {
getCmsContent: jest.fn((contentName) => {
if (contentName === "FoundMultipleVehicles") {
return 'FoundMultipleVehiclesTestReturn';
}
if (contentName === "ProvideVinAlert") {
return 'ProvideVinAlertTestReturn';
}
return null;
}),
// dispatchStoreAction: jest.fn(() => {
// console.log("23424243")
// }),
// isGlassAvailableForCarId: () => {
// console.log("%%%%%%%%%%%%%%%")
// return Promise.resolve(true)
// }
// lookupVin: jest.fn(() => Promise.resolve(lookupVinResponse)),
},
}
// mountOptions.propsData = {
// modelValue: modelValueProp,
// };
mountOptions.mixins = [mockMixin];
const wrapper = shallowMount(addressVehicles, mountOptions);
//Mock CMS content
const cmsContent = {
QuestionText: cmsQuestionText,
};
return { wrapper };
}

View file

@ -1,26 +0,0 @@
import { shallowMount } from "@vue/test-utils";
import addressVehicles from "@/layouts/address-vehicles/address-vehicles";
describe("addressVehicles.vue", () => {
it("Should include address-vehicles-question component", () => {
// Arrange
const wrapper = shallowMount(addressVehicles, {
propsData: {
vehicles: [
{
"Name": "testname",
"Text": "testtext",
}
]
}
});
// console.log('wrapper.html: ', wrapper.html());
// Assert
const addressVehiclesQuestion = wrapper.find('address-vehicles-question-stub');
expect(addressVehiclesQuestion).toBe;
});
});

View file

@ -162,8 +162,10 @@ export default {
async forwardButtonAction() {
const vinLookup = await this.lookupVin(this.selectedVehicle.vin).catch(() => {
this.$refs.funnelFooter.removeLoader();
return;
});
if (!vinLookup) {
return;
}
this.isSelectedGlassAvailableForVehicle = await isGlassAvailableForCarId(vinLookup.data.carId);
this.updateCustomerInfo(this.selectedVehicle.vin, this.selectedVehicle.vehicle);
this.navigateForward();
@ -210,7 +212,7 @@ export default {
},
watch: {
selectedVehicleVin(vehicleVin) {
selectedVehicleVin() {
// does this vehicle match the previously selected carId?
this.isCarIdDifferent = this.selectedVehicle.vehicle.carId !== store.getters.vehicle.carId;
this.$refs.funnelFooter.updateButtonText(`Continue with ${this.selectedVehicle.vehicle.year} ${this.selectedVehicle.vehicle.make} ${this.selectedVehicle.vehicle.model}`);