This commit is contained in:
Jason Wheeler 2022-11-01 10:54:26 -04:00
parent e02070fa39
commit 76087dc752
6 changed files with 292 additions and 23 deletions

52
package-lock.json generated
View file

@ -1794,6 +1794,14 @@
"fastq": "^1.6.0"
}
},
"@pinia/testing": {
"version": "0.0.14",
"resolved": "https://registry.npmjs.org/@pinia/testing/-/testing-0.0.14.tgz",
"integrity": "sha512-ZmZwVNd/NnKYLIfjfuKl0zlJ3UdiXFpsHzSlL6wCeezSlyrqGMxsIQKv0J6fleu38gyCNTPBEipfxrt8V4+VIg==",
"requires": {
"vue-demi": "*"
}
},
"@polka/url": {
"version": "1.0.0-next.21",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz",
@ -2540,6 +2548,29 @@
"webpack-merge": "^5.7.3",
"webpack-virtual-modules": "^0.4.2",
"whatwg-fetch": "^3.6.2"
},
"dependencies": {
"@vue/vue-loader-v15": {
"version": "npm:vue-loader@15.10.0",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.10.0.tgz",
"integrity": "sha512-VU6tuO8eKajrFeBzMssFUP9SvakEeeSi1BxdTH5o3+1yUyrldp8IERkSdXlMI2t4kxF2sqYUDsQY+WJBxzBmZg==",
"dev": true,
"requires": {
"@vue/component-compiler-utils": "^3.1.0",
"hash-sum": "^1.0.2",
"loader-utils": "^1.1.0",
"vue-hot-reload-api": "^2.3.0",
"vue-style-loader": "^4.1.0"
},
"dependencies": {
"hash-sum": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
"integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
"dev": true
}
}
}
}
},
"@vue/cli-shared-utils": {
@ -2789,27 +2820,6 @@
"integrity": "sha512-E2P4oXSaWDqTZNbmKZFVLrNN/siVN78YkEqs7pHryWerrlZR9bBFLWdJwRoguX45Ru6HxIflzKl4vQvwRMwm5g==",
"dev": true
},
"@vue/vue-loader-v15": {
"version": "npm:vue-loader@15.10.0",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.10.0.tgz",
"integrity": "sha512-VU6tuO8eKajrFeBzMssFUP9SvakEeeSi1BxdTH5o3+1yUyrldp8IERkSdXlMI2t4kxF2sqYUDsQY+WJBxzBmZg==",
"dev": true,
"requires": {
"@vue/component-compiler-utils": "^3.1.0",
"hash-sum": "^1.0.2",
"loader-utils": "^1.1.0",
"vue-hot-reload-api": "^2.3.0",
"vue-style-loader": "^4.1.0"
},
"dependencies": {
"hash-sum": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
"integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
"dev": true
}
}
},
"@vue/vue3-jest": {
"version": "27.0.0",
"resolved": "https://registry.npmjs.org/@vue/vue3-jest/-/vue3-jest-27.0.0.tgz",

View file

@ -9,6 +9,7 @@
"test:unit:lite": "vue-cli-service test:unit --ci"
},
"dependencies": {
"@pinia/testing": "0.0.14",
"@popperjs/core": "^2.10.2",
"axios": "^0.27.2",
"bootstrap": "^5.2.2",

View file

@ -0,0 +1,46 @@
import { storeActions } from "@/constants/store-actions";
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios.js";
import { vehicleCategories } from "@/constants/vehicle-categories.js";
import { issPageValues } from "@/router/router-constants/issPage-values";
import { Form } from "vee-validate";
import { queryStrings } from "@/constants/query-strings";
import { useMainStore } from "@/store";
import { mapStores } from "pinia";
import { createTestingPinia } from '@pinia/testing';
const pinia = createTestingPinia();
useMainStore(pinia);
const mockMixin = {
methods: {
getCmsContent: jest.fn()
},
computed: {
...mapStores(useMainStore),
}
};
// Common methods
export function getMountOptions(mockData) {
// Define our mocks to attached to the 'global' object for Vue/Jest.
const mocks = {};
// Mock const files
mocks.storeActions = storeActions;
mocks.navigationScenarios = navigationScenarios;
mocks.vehicleCategories = vehicleCategories;
mocks.issPageValues = issPageValues;
mocks.queryStrings = queryStrings;
const global = {
mocks: mocks,
mixins: [mockMixin],
plugins: [pinia],
stubs: { Form }
};
return { global };
}

View file

@ -0,0 +1,84 @@
import makeQuestion from "@/layouts/vehicle-make/make-question/make-question";
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import store from "@/store";
jest.mock(
"@/store",
() => {
return {};
},
{ virtual: true }
);
describe("make-question.vue", () => {
test("Data from store api are used as radio question answers.", async () => {
//Arrange
const { wrapper, cmsContent } = setupMocks({
dataFromStoreApi: ["honda", "ford", "dodge"],
});
//Act
const initialData = makeQuestion.methods.loadInitialData.call(wrapper.vm);
makeQuestion.methods.initializeComponent.call(
wrapper.vm,
initialData
);
//Assert
const buttonQuestionComponent = await wrapper.findComponent({
name: "buttonQuestion",
});
expect(buttonQuestionComponent.attributes("answers")).toBe(
"honda,ford,dodge"
);
});
test("Selected make is emitted upon selection.", async () => {
//Arrange
const { wrapper } = setupMocks({ modelValueProp: "honda" });
const makeToSelect = "ford";
//Act
wrapper.setValue({ selectedMake: makeToSelect });
await wrapper.vm.$nextTick();
//Assert
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([
{ selectedMake: "ford" },
]);
});
});
function setupMocks({
modelValueProp = "1900",
cmsQuestionText = "CMS text goes here",
dataFromStoreApi = [],
}) {
//Mock store
store.getVehicleMakes = jest.fn(() => dataFromStoreApi);
const mountOptions = getMountOptions({
store: {
getVehicleMakes: store.getVehicleMakes,
},
});
//Mock props
const mockMixin = {
methods: {
getCmsContent: jest.fn()
}
}
mountOptions.propsData = {
modelValue: modelValueProp,
};
mountOptions.mixins = [mockMixin];
const wrapper = shallowMount(makeQuestion, mountOptions);
//Mock CMS content
const cmsContent = {
QuestionText: cmsQuestionText,
};
return { wrapper, cmsContent };
}

View file

@ -41,7 +41,6 @@
set: function(newValue) {
this.$emit("update:modelValue", newValue);
this.mainStore.updateVehicleMake(newValue);
console.log(this.mainStore.order.vehicle.make)
this.$router.navigate(this.navigationScenarios.SELECTED_MAKE, this.$route)
}
}

View file

@ -1 +1,130 @@
test.todo("some test to be written in the future");
// Supporting Files
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { settleAllPromises } from "@/helpers/layout-helper.js";
import { nextTick } from "vue";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
// Components
import vehicleMake from "@/layouts/vehicle-make/vehicle-make.vue";
import makeQuestion from "@/layouts/vehicle-make/make-question/make-question";
jest.mock("@/store", () => ({
getVehicleMakes: jest.fn(),
order: {
vehicle: {
year: 2019,
},
},
}));
// Mock fetchCmsContentForPage
jest.mock("@/helpers/cms-content-helper", () => ({
fetchCmsContentForPage: jest.fn(),
}));
// Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({
settleAllPromises: jest.fn(),
}));
/*
describe("vehicle-make.vue", () => {
test("Make question component is initized with api data", async (done) => {
//Arrange
const makeQuestionInitialData = ["honda", "ford", "dodge"];
const { wrapper, apiPromise } = setupMocks({
makeQuestionInitialData: makeQuestionInitialData,
});
//Act
vehicleMake.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: "vehicle-make" } },
undefined,
(c) => c(wrapper.vm)
);
//Assert
apiPromise.finally(() => {
expect(makeQuestion.methods.initializeComponent).toHaveBeenCalledWith(
makeQuestionInitialData
);
//done();
});
});
});
*/
describe("vehicle-make.vue", () => {
test("BackButtonAction triggers a router.navigate change", async (done) => {
const { wrapper, apiPromise } = setupMocks({
pageHeaderWidgetHeaderText: "Select a make to get started",
mountOptionsMockData: {
router: {
navigate: jest.fn(),
},
},
});
vehicleMake.beforeRouteEnter.call(
wrapper.vm,
{ query: { issPage: "vehicle-make" } },
undefined,
(c) => c(wrapper.vm)
);
wrapper.vm.backButtonAction();
await nextTick();
apiPromise.finally(() => {
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
//done();
});
});
});
function setupMocks({
vehicleMakeQuestionCmsContent = {},
makeQuestionInitialData = {},
pageHeaderWidgetHeaderText = {},
mountOptionsMockData = {},
}) {
//Mock api responses
const apiResponses = {
cmsContent: {
FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
VehicleMakeQuestion: vehicleMakeQuestionCmsContent,
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",
},
},
makeQuestionInitialData: makeQuestionInitialData,
};
const apiPromise = Promise.resolve(apiResponses);
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
settleAllPromises.mockImplementation(() => apiPromise);
//Mock make question methods
makeQuestion.methods = {
loadInitialData: jest.fn(),
initializeComponent: jest.fn(),
};
const mountOptions = getMountOptions(mountOptionsMockData);
const wrapper = shallowMount(vehicleMake, mountOptions);
const makeQuestionWrapper = wrapper.findComponent({ name: "makeQuestion" });
makeQuestionWrapper.vm.initializeComponent =
makeQuestion.methods.initializeComponent;
wrapper.vm.setCmsContent = jest.fn();
return { wrapper, apiPromise };
}