Add more tests

This commit is contained in:
Katie 2022-09-13 13:13:07 -04:00
parent f51135b030
commit 8e8f663be3
7 changed files with 178 additions and 47 deletions

View file

@ -25,8 +25,7 @@ module.exports = {
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"], testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
coverageThreshold: { coverageThreshold: {
global: { global: {
// TODO after release/2022.09.15, raise this back up!! statements: 90,
statements: 80,
// Got the go ahead from Mark to temporarily lower this. Taking out initialize component made the year,make,model and style coverage drop a bit. Once unit tests for license plate lookup, vin lookup and address lookup are in the coverage should go back up to 90 // Got the go ahead from Mark to temporarily lower this. Taking out initialize component made the year,make,model and style coverage drop a bit. Once unit tests for license plate lookup, vin lookup and address lookup are in the coverage should go back up to 90
}, },
}, },

View file

@ -10,6 +10,9 @@ import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { storeActions } from "@/constants/store-actions"; import { storeActions } from "@/constants/store-actions";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper"; import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import baseMixin from "@/mixins/base-mixin.js"; import baseMixin from "@/mixins/base-mixin.js";
import router from "@/router"
import store from "@/store"
import { storeMutations } from "@/constants/store-mutations";
// Mock our module for promises. // Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({ jest.mock("@/helpers/layout-helper.js", () => ({
@ -21,25 +24,16 @@ jest.mock("@/helpers/cms-content-helper", () => ({
fetchCmsContentForPage: jest.fn(), fetchCmsContentForPage: jest.fn(),
})); }));
// Mock Store // Mock fetchCmsContentForPage
jest.mock("@/store", () => ({ jest.mock("@/router", () => ({
getters: { overrideNavigation: jest.fn(),
vehicle: {
model: "TL",
},
applicationUser:{
pageData: {
"part-questions": null,
"vehicle-make": {},
"vehicle-model": {},
"vehicle-style": {},
"vehicle-damage": {}
}
}
},
})); }));
describe("vehicle-style.vue", () => { describe("vehicle-style.vue", () => {
beforeEach(() => {
jest.clearAllMocks();
})
test("Style question component is initized with api data", async (done) => { test("Style question component is initized with api data", async (done) => {
//Arrange //Arrange
const styleQuestionInitialData = ["2 Door", "4 Door"]; const styleQuestionInitialData = ["2 Door", "4 Door"];
@ -63,9 +57,7 @@ describe("vehicle-style.vue", () => {
done(); done();
}); });
}); });
});
describe("vehicle-style.vue", () => {
test("BackButtonAction triggers a router.navigateWithoutSaving change", async (done) => { test("BackButtonAction triggers a router.navigateWithoutSaving change", async (done) => {
//Arrange //Arrange
const { wrapper, apiPromise } = setupMocks({ const { wrapper, apiPromise } = setupMocks({
@ -95,20 +87,12 @@ describe("vehicle-style.vue", () => {
done(); done();
}); });
}); });
});
describe("vehicle-style.vue", () => { test("setVehicle triggers a dispatchStoreAction commit", async (done) => {
test("selectVehicle triggers a dispatchStoreAction commit", async (done) => {
//Arrange //Arrange
const { wrapper, apiPromise } = setupMocks({ const { wrapper, apiPromise } = setupMocks({
pageHeaderWidgetHeaderText: "Select a style to get started", pageHeaderWidgetHeaderText: "Select a style to get started",
mountOptionsMockData: { mountOptionsMockData: {
store: {
commit: jest.fn(),
getters: {
vehicle: {},
},
},
actionList: [ actionList: [
{ {
actionName: storeActions.SET_VEHICLE, actionName: storeActions.SET_VEHICLE,
@ -134,9 +118,7 @@ describe("vehicle-style.vue", () => {
done(); done();
}); });
}); });
});
describe("vehicle-style.vue", () => {
test("Model set, arePagePrerequisitesValid should be true ", async () => { test("Model set, arePagePrerequisitesValid should be true ", async () => {
//Arrange //Arrange
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
@ -155,7 +137,61 @@ describe("vehicle-style.vue", () => {
//Assert //Assert
expect(arePagePrerequisitesValid).toBe(true); expect(arePagePrerequisitesValid).toBe(true);
}); });
test("there is only one vehicle style => autoselect and move to vehicle damage", async () => {
//Arrange
const { wrapper } = setupMocks({
styleQuestionInitialData: ["2 door sedan"],
});
// Act
await vehicleStyle.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-style" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(store.commit).toHaveBeenCalledWith(storeMutations.UPDATE_STYLE, "2 door sedan");
expect(router.overrideNavigation).toHaveBeenCalled();
})
test("there is only one vehicle style and vehicle-damage was visited => don't autoselect or move to vehicle damage", async () => {
//Arrange
const { wrapper } = setupMocks({
styleQuestionInitialData: ["2 door sedan"],
mountOptionsMockData: {
store: {
getters: {
applicationUser: {
pageData: {
"part-questions": null,
"vehicle-make": {},
"vehicle-model": {},
"vehicle-style": {},
"vehicle-damage": {}
}
}
}
}
}
});
// Act
await vehicleStyle.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-style" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(store.commit).not.toHaveBeenCalledWith(storeMutations.UPDATE_STYLE, "2 door sedan");
expect(router.overrideNavigation).not.toHaveBeenCalled();
})
}); });
function setupMocks({ function setupMocks({
vehicleStyleQuestionCmsContent = {}, vehicleStyleQuestionCmsContent = {},
styleQuestionInitialData = {}, styleQuestionInitialData = {},
@ -190,7 +226,26 @@ function setupMocks({
initializeComponent: jest.fn(), initializeComponent: jest.fn(),
}; };
const mountOptions = getMountOptions(mountOptionsMockData); store.commit = jest.fn();
store.dispatch = jest.fn();
store.getters = mountOptionsMockData.store?.getters ?? {
vehicle: {
model: "TL",
},
applicationUser: {
pageData: {
"part-questions": null,
"vehicle-make": {},
"vehicle-model": {},
"vehicle-style": {},
}
}
}
const mountOptions = getMountOptions({
...mountOptionsMockData,
store
});
const wrapper = shallowMount(vehicleStyle, mountOptions); const wrapper = shallowMount(vehicleStyle, mountOptions);
wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent; wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;

View file

@ -26,6 +26,7 @@
<script> <script>
// Components // Components
import baseMixin from "@/mixins/base-mixin.js";
import styleQuestion from "@/layouts/vehicle-style/style-question/style-question"; import styleQuestion from "@/layouts/vehicle-style/style-question/style-question";
import funnelHeader from "@/common-components/funnel-header/funnel-header"; import funnelHeader from "@/common-components/funnel-header/funnel-header";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header"; import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
@ -71,15 +72,12 @@ export default {
const resultMap = await settleAllPromises(promiseResultMap); const resultMap = await settleAllPromises(promiseResultMap);
const visitedVehicleDamage = JSON.stringify(store.getters.applicationUser.pageData).indexOf(fmgPageValues.VEHICLE_DAMAGE) < 0 ? false : true; const visitedVehicleDamage = JSON.stringify(store.getters.applicationUser.pageData).indexOf(fmgPageValues.VEHICLE_DAMAGE) < 0 ? false : true;
// Call the "next" function to complete the transition to this page.
// If we have exactly one style then navigate directly to vehicle-damage // If we have exactly one style then navigate directly to vehicle-damage
if(resultMap.styleQuestionInitialData.length === 1 && !visitedVehicleDamage) { if(resultMap.styleQuestionInitialData.length === 1 && !visitedVehicleDamage) {
// TODO KO
store.commit(storeMutations.UPDATE_STYLE, resultMap.styleQuestionInitialData[0]); store.commit(storeMutations.UPDATE_STYLE, resultMap.styleQuestionInitialData[0]);
await store.dispatch(storeActions.SET_VEHICLE, await baseMixin.methods.dispatchStoreAction(storeActions.SET_VEHICLE,
{ {
year: store.getters.vehicle.year, year: store.getters.vehicle.year,
make: store.getters.vehicle.make, make: store.getters.vehicle.make,

View file

@ -65,7 +65,7 @@ describe("vin-lookup.vue", () => {
it("Should call navigateForward() if the store carId matches the vin response carId and forward button is clicked", async () => { it("Should call navigateForward() if the store carId matches the vin response carId and forward button is clicked", async () => {
// Arrange // Arrange
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
mockOutPromises(); mockOutPromises({ carId: "C00000" });
wrapper.vm.navigateForward = jest.fn(); wrapper.vm.navigateForward = jest.fn();
// Act // Act
@ -78,7 +78,7 @@ describe("vin-lookup.vue", () => {
it("Should not call navigateForward() if the store carId does not match the vin response carId and forward button is clicked", async () => { it("Should not call navigateForward() if the store carId does not match the vin response carId and forward button is clicked", async () => {
// Arrange // Arrange
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
mockOutPromises('C11111'); mockOutPromises({ carId: 'C11111' });
wrapper.vm.vinTouched = true; wrapper.vm.vinTouched = true;
wrapper.vm.vin = ""; wrapper.vm.vin = "";
@ -95,7 +95,7 @@ describe("vin-lookup.vue", () => {
it("Should call navigateForward() if the store carId does not match the vin response carId but does match previously enterted carId and forward button is clicked", async () => { it("Should call navigateForward() if the store carId does not match the vin response carId but does match previously enterted carId and forward button is clicked", async () => {
// Arrange // Arrange
const { wrapper } = setupMocks({}); const { wrapper } = setupMocks({});
mockOutPromises('C11111'); mockOutPromises({ carId: 'C11111' });
wrapper.vm.lookupVehicle = jest.fn().mockImplementation(() => vinPromise); wrapper.vm.lookupVehicle = jest.fn().mockImplementation(() => vinPromise);
wrapper.vm.navigateForward = jest.fn(); wrapper.vm.navigateForward = jest.fn();
@ -203,6 +203,35 @@ describe("vin-lookup.vue", () => {
expect(wrapper.vm.navigateForwardWithSingleCarMatch).toBeCalledTimes(1); expect(wrapper.vm.navigateForwardWithSingleCarMatch).toBeCalledTimes(1);
}) })
}) })
describe("alerts", () => {
test("Zip is invalid => show AlertInvalidZipWidget", async () => {
// Arrange
const { wrapper } = setupMocks({});
mockOutPromises({ isZipValid: false });
await wrapper.setData({serviceZipCode: "11111"})
// Act
await wrapper.vm.forwardButtonAction();
// Assert
expect(wrapper.vm.displayInvalidZipAlert).toEqual(true);
expect(wrapper.findComponent({ref: "alertInvalidZip"}).exists()).toBe(true);
})
test("Vin not found => show AlertVinNotFoundWidget", async () => {
// Arrange
const { wrapper } = setupMocks({});
mockOutPromises({});
// Act
await wrapper.vm.forwardButtonAction();
// Assert
expect(wrapper.vm.displayVinNotFoundAlert).toEqual(true);
expect(wrapper.findComponent({cmsWidgetName: "AlertVinNotFoundWidget"}).exists()).toBe(true);
})
})
}); });
@ -217,20 +246,17 @@ function setupMocks({ customMountOptions }) {
mountOptions['attachTo'] = document.body; // append wrapper to document.body to test DOM methods mountOptions['attachTo'] = document.body; // append wrapper to document.body to test DOM methods
const wrapper = shallowMount(vinLookup, mountOptions); const wrapper = shallowMount(vinLookup, mountOptions);
mockOutPromises(wrapper);
mockOutStubFunctions(wrapper); mockOutStubFunctions(wrapper);
return { wrapper }; return { wrapper };
} }
function mockOutPromises(carId = 'C00000') { function mockOutPromises({carId, isZipValid = true, isZipServiceable = true}) {
const apiResponses = { const apiResponses = {
serviceZipValidationResponse: { serviceZipValidationResponse: {
isValid: true, isValid: isZipValid,
isServiceable: true isServiceable: isZipServiceable
}, },
vehicleLookupResponse: { vehicleLookupResponse: carId ? { carId: carId } : null
carId: carId
}
}; };
settleAllPromises.mockImplementation(() => apiResponses); settleAllPromises.mockImplementation(() => apiResponses);

View file

@ -240,11 +240,17 @@ export default {
// If a Service Zip is entered and it is an invalid zip code (ex. 11111) then show an alert // If a Service Zip is entered and it is an invalid zip code (ex. 11111) then show an alert
const isZipValid = resultMap.serviceZipValidationResponse.isValid; const isZipValid = resultMap.serviceZipValidationResponse.isValid;
console.log(isZipValid)
console.log(this.serviceZipCode)
if (this.serviceZipCode && !isZipValid) { if (this.serviceZipCode && !isZipValid) {
console.log("HIII")
this.displayInvalidZipAlert = true; this.displayInvalidZipAlert = true;
return this.$refs.funnelFooter.removeLoader(); return this.$refs.funnelFooter.removeLoader();
} }
console.log("BOO")
this.displayInvalidZipAlert = false; this.displayInvalidZipAlert = false;
// console.log(resultMap.vehicleLookupResponse)
// console.log(resultMap.serviceZipValidationResponse)
// If either lookup fails, remove the loader and stop processing the page. // If either lookup fails, remove the loader and stop processing the page.
if (!resultMap.vehicleLookupResponse || !resultMap.serviceZipValidationResponse.isServiceable) { if (!resultMap.vehicleLookupResponse || !resultMap.serviceZipValidationResponse.isServiceable) {

View file

@ -225,6 +225,8 @@ function navigateToUrl(url, optionalQuery = {}) {
externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]); externalUrl.searchParams.append(queryKey, optionalQuery[queryKey]);
} }
externalUrl.searchParams.append("experiments", "ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_TEST=true");
window.location.assign(externalUrl); window.location.assign(externalUrl);
} }

View file

@ -650,6 +650,51 @@ describe("Actions", () => {
expect(commit).toBeCalledWith(storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, { "referralNumber": 123 }); expect(commit).toBeCalledWith(storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, { "referralNumber": 123 });
}); });
it("loadOrder: state doesn't have EON => do not reset state", async () => {
// Arrange
const context = state;
globalMethods.callHttpClient.mockImplementation(() => {
return Promise.resolve({ data: { eon: "123" } });
});
context.commit = jest.fn();
context.state = {
order: {
}
}
// Act
const response = await actions.loadOrder(context, { referralNumber: "123", referralDate: new Date().toUTCString(), referralCorrelationId: "xxx-xxx-xxx" });
// Assert
expect(response.data.eon).toEqual("123");
expect(context.commit).not.toBeCalledWith(storeMutations.RESET_STATE);
});
it("loadOrder eon doesn't match eon in state => reset state", async () => {
// Arrange
const context = state;
globalMethods.callHttpClient.mockImplementation(() => {
return Promise.resolve({ data: { eon: "123" } });
});
context.commit = jest.fn();
context.state = {
order: {
eon: "456"
}
}
// Act
const response = await actions.loadOrder(context, { referralNumber: "123", referralDate: new Date().toUTCString(), referralCorrelationId: "xxx-xxx-xxx" });
// Assert
expect(response.data.eon).toEqual("123");
expect(context.commit).toBeCalledWith(storeMutations.RESET_STATE);
});
it("updateStoreWithSaveOrderResponse, should call commit six times", () => { it("updateStoreWithSaveOrderResponse, should call commit six times", () => {
// Arrange // Arrange
const context = state; const context = state;