diff --git a/src/common-components/button-question/button-question.vue b/src/common-components/button-question/button-question.vue
index e1fee1e40..d86dcd2ce 100644
--- a/src/common-components/button-question/button-question.vue
+++ b/src/common-components/button-question/button-question.vue
@@ -10,7 +10,8 @@
diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js
index d9292b5f8..c6d8484da 100644
--- a/src/constants/store-mutations.js
+++ b/src/constants/store-mutations.js
@@ -1,5 +1,7 @@
const storeMutations = {
UPDATE_YEAR: "updateYear",
+ UPDATE_MAKE: "updateMake",
+ UPDATE_MODEL: "updateModel",
};
export { storeMutations };
diff --git a/src/layouts/vehicle-make/vehicle-make.spec.js b/src/layouts/vehicle-make/vehicle-make.spec.js
index 120f8de4f..cc2325dfc 100644
--- a/src/layouts/vehicle-make/vehicle-make.spec.js
+++ b/src/layouts/vehicle-make/vehicle-make.spec.js
@@ -44,6 +44,7 @@ describe("vehicle-make.vue", () => {
//Assert
const header = await wrapper.find(".Header");
apiPromise.finally(() => {
+ console.log(header)
expect(header.attributes("text")).toEqual("Select a make to get started");
done();
});
diff --git a/src/layouts/vehicle-model/model-question/model-question.spec.js b/src/layouts/vehicle-model/model-question/model-question.spec.js
new file mode 100644
index 000000000..d6259eb72
--- /dev/null
+++ b/src/layouts/vehicle-model/model-question/model-question.spec.js
@@ -0,0 +1,82 @@
+import modelQuestion from "@/layouts/vehicle-model/model-question/model-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("model-question.vue", () => {
+ test("Selected model is emitted upon selection.", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({ modelValueProp: "Accord" });
+ const modelToSelect = "Civic";
+
+ //Act
+ wrapper.setData({ selectedModel: modelToSelect });
+ await wrapper.vm.$nextTick();
+
+ //Assert
+ expect(wrapper.emitted()["update:modelValue"][0]).toEqual(["Civic"]);
+ });
+});
+
+describe("model-question.vue", () => {
+ test("CMS question text is used as radio question text.", async () => {
+
+ //Arrange
+ const { wrapper, cmsContent } = setupMocks({ cmsQuestionText: "What model is your vehicle?" });
+
+ //Act
+ modelQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, null);
+
+ //Assert
+ const buttonQuestionComponent = await wrapper.findComponent({ name: "buttonQuestion" });
+ expect(buttonQuestionComponent.attributes("questiontext")).toBe("What model is your vehicle?");
+ });
+});
+
+describe("model-question.vue", () => {
+ test("Data from store api are used as radio question answers.", async () => {
+
+ //Arrange
+ const { wrapper, cmsContent } = setupMocks({ dataFromStoreApi: ["accord", "civic", "insight"] });
+
+ //Act
+ const initialData = modelQuestion.methods.loadInitialData.call(wrapper.vm);
+ modelQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, initialData);
+
+ //Assert
+ const buttonQuestionComponent = await wrapper.findComponent({ name: "buttonQuestion" });
+ expect(buttonQuestionComponent.attributes("answers")).toBe("accord,civic,insight");
+ });
+});
+
+
+function setupMocks({
+ modelValueProp = "1900",
+ cmsQuestionText = "CMS text goes here",
+ dataFromStoreApi = [],
+}) {
+
+ //Mock store
+ store.dispatch = jest.fn(() => dataFromStoreApi);
+ store.getters = { vehicle: {year: 2019, make: 'honda'} };
+ const mountOptions = getMountOptions({
+ store: {
+ dispatch: store.dispatch,
+ getters: store.getters,
+ },
+ });
+
+ //Mock props
+ mountOptions.propsData = {
+ modelValue: modelValueProp,
+ };
+ const wrapper = shallowMount(modelQuestion, mountOptions);
+
+ //Mock CMS content
+ const cmsContent = {
+ QuestionText: cmsQuestionText
+ };
+ return { wrapper, cmsContent };
+}
\ No newline at end of file
diff --git a/src/layouts/vehicle-model/model-question/model-question.vue b/src/layouts/vehicle-model/model-question/model-question.vue
new file mode 100644
index 000000000..95b72909b
--- /dev/null
+++ b/src/layouts/vehicle-model/model-question/model-question.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
diff --git a/src/layouts/vehicle-model/vehicle-model.spec.js b/src/layouts/vehicle-model/vehicle-model.spec.js
new file mode 100644
index 000000000..8ee3885de
--- /dev/null
+++ b/src/layouts/vehicle-model/vehicle-model.spec.js
@@ -0,0 +1,93 @@
+import { shallowMount, flushPromises } from "@vue/test-utils";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+import vehicleModel from "@/layouts/vehicle-model/vehicle-model.vue";
+import modelQuestion from "@/layouts/vehicle-model/model-question/model-question";
+import { settleAllPromises } from "@/helpers/layout-helper.js";
+import { nextTick } from "vue";
+
+// Mock our module for promises.
+jest.mock("@/helpers/layout-helper.js", () => ({
+ settleAllPromises: jest.fn(),
+}));
+
+describe("vehicle-model.vue", () => {
+ test("Model question component is initized with api data", async (done) => {
+
+ //Arange
+ const radioQuestionCmsContent = { QuestionText: "What model is your vehicle?" };
+ const modelQuestionInitialData = ["accord", "civic", "insight"];
+ const { wrapper, apiPromise } = setupMocks( {
+ radioQuestionCmsContent: radioQuestionCmsContent,
+ modelQuestionInitialData: modelQuestionInitialData,
+ } );
+
+ //Act
+ vehicleModel.beforeRouteEnter.call(wrapper.vm, { query: { fmgPage: "vehicle-model" } }, undefined, (c) => c(wrapper.vm));
+
+ //Assert
+ apiPromise.finally(() => {
+ expect(modelQuestion.methods.initializeComponent).toHaveBeenCalledWith(radioQuestionCmsContent, modelQuestionInitialData);
+ done();
+ });
+ });
+});
+
+describe("vehicle-model.vue", () => {
+ test("Page header is passed data from CMS", async (done) => {
+
+ //Arange
+ const { wrapper, apiPromise } = setupMocks( { pageHeaderWidgetHeaderText: "Select a model to get started" });
+
+ //Act
+ vehicleModel.beforeRouteEnter.call(wrapper.vm, { query: { fmgPage: "vehicle-model" } }, undefined, (c) => c(wrapper.vm));
+
+ //Assert
+ const header = await wrapper.find(".Header");
+ apiPromise.finally(() => {
+ expect(header.attributes("text")).toEqual("Select a model to get started");
+ done();
+ });
+ });
+});
+
+function setupMocks({
+ radioQuestionCmsContent = {},
+ modelQuestionInitialData = {},
+ pageHeaderWidgetHeaderText = {},
+}) {
+
+ //Mock api responses
+ const apiResponses = {
+ cmsContent: {
+ PageHeaderWidget: [{ HeaderText: pageHeaderWidgetHeaderText }],
+ RadioQuestionWidget: [radioQuestionCmsContent],
+ VehicleBannerWidget: [
+ {
+ GenericVehicleImage:
+ "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
+ },
+ ],
+ SiteHeaderWidget: [
+ {
+ LogoImage:
+ "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
+ },
+ ],
+ },
+ modelQuestionInitialData: modelQuestionInitialData,
+ };
+ const apiPromise = Promise.resolve(apiResponses);
+ settleAllPromises.mockImplementation(() => apiPromise);
+
+ //Mock model question methods
+ modelQuestion.methods = {
+ loadInitialData: jest.fn(),
+ initializeComponent: jest.fn(),
+ };
+ const mountOptions = getMountOptions({ });
+ const wrapper = shallowMount(vehicleModel, mountOptions);
+ const modelQuestionWrapper = wrapper.findComponent({ name: "modelQuestion" });
+ modelQuestionWrapper.vm.initializeComponent = modelQuestion.methods.initializeComponent;
+
+ return { wrapper, apiPromise };
+}
\ No newline at end of file
diff --git a/src/layouts/vehicle-model/vehicle-model.vue b/src/layouts/vehicle-model/vehicle-model.vue
new file mode 100644
index 000000000..1d86c99b4
--- /dev/null
+++ b/src/layouts/vehicle-model/vehicle-model.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
diff --git a/src/store/index.js b/src/store/index.js
index 1bf7243b7..5e21f7ce4 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -64,6 +64,12 @@ export default createStore({
updateYear(state, year) {
state.order.vehicle.year = year;
},
+ updateMake(state, make) {
+ state.order.vehicle.make = make;
+ },
+ updateModel(state, model) {
+ state.order.vehicle.model = model;
+ },
},
getters: {
vehicle: state => state.order.vehicle