![]()
{ return {}; }, {virtual: true});
+
+describe("make-question.vue", () => {
+ test("Selected make is emitted upon selection.", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({ modelValueProp: "honda" });
+ const makeToSelect = "ford";
+
+ //Act
+ wrapper.setData({ selectedMake: makeToSelect });
+ await wrapper.vm.$nextTick();
+
+ //Assert
+ expect(wrapper.emitted()["update:modelValue"][0]).toEqual(["ford"]);
+ });
+});
+
+describe("make-question.vue", () => {
+ test("CMS question text is used as radio question text.", async () => {
+
+ //Arrange
+ const { wrapper, cmsContent } = setupMocks({ cmsQuestionText: "What make is your vehicle?" });
+
+ //Act
+ makeQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, null);
+
+ //Assert
+ const buttonQuestionComponent = await wrapper.findComponent({ name: "buttonQuestion" });
+ expect(buttonQuestionComponent.attributes("questiontext")).toBe("What make is your vehicle?");
+ });
+});
+
+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, cmsContent, initialData);
+
+ //Assert
+ const buttonQuestionComponent = await wrapper.findComponent({ name: "buttonQuestion" });
+ expect(buttonQuestionComponent.attributes("answers")).toBe("honda,ford,dodge");
+ });
+});
+
+
+function setupMocks({
+ modelValueProp = "1900",
+ cmsQuestionText = "CMS text goes here",
+ dataFromStoreApi = [],
+}) {
+
+ //Mock store
+ store.dispatch = jest.fn(() => dataFromStoreApi);
+ store.getters = { vehicle: {year: 2019} };
+ const mountOptions = getMountOptions({
+ store: {
+ dispatch: store.dispatch,
+ getters: store.getters,
+ },
+ });
+
+ //Mock props
+ mountOptions.propsData = {
+ modelValue: modelValueProp,
+ };
+ const wrapper = shallowMount(makeQuestion, mountOptions);
+
+ //Mock CMS content
+ const cmsContent = {
+ QuestionText: cmsQuestionText
+ };
+ return { wrapper, cmsContent };
+}
\ No newline at end of file
diff --git a/src/layouts/vehicle-make/make-question/make-question.vue b/src/layouts/vehicle-make/make-question/make-question.vue
new file mode 100644
index 000000000..8edb13152
--- /dev/null
+++ b/src/layouts/vehicle-make/make-question/make-question.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
diff --git a/src/layouts/vehicle-make/vehicle-make.spec.js b/src/layouts/vehicle-make/vehicle-make.spec.js
new file mode 100644
index 000000000..0f46067e4
--- /dev/null
+++ b/src/layouts/vehicle-make/vehicle-make.spec.js
@@ -0,0 +1,94 @@
+import { shallowMount, flushPromises } from "@vue/test-utils";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+import vehicleMake from "@/layouts/vehicle-make/vehicle-make.vue";
+import makeQuestion from "@/layouts/vehicle-make/make-question/make-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-make.vue", () => {
+ test("Make question component is initized with api data", async (done) => {
+
+ //Arange
+ const radioQuestionCmsContent = { QuestionText: "What make is your vehicle?" };
+ const makeQuestionInitialData = ["2023", "2022", "2021"];
+ const { wrapper, apiPromise } = setupMocks( {
+ radioQuestionCmsContent: radioQuestionCmsContent,
+ makeQuestionInitialData: makeQuestionInitialData,
+ } );
+
+ //Act
+ vehicleMake.beforeRouteEnter.call(wrapper.vm, { query: { fmgPage: "vehicle-make" } }, undefined, (c) => c(wrapper.vm));
+
+ //Assert
+ apiPromise.finally(() => {
+ expect(makeQuestion.methods.initializeComponent).toHaveBeenCalledWith(radioQuestionCmsContent, makeQuestionInitialData);
+ done();
+ });
+ });
+});
+
+describe("vehicle-make.vue", () => {
+ test("Page header is passed data from CMS", async (done) => {
+
+ //Arange
+ const { wrapper, apiPromise } = setupMocks( { pageHeaderWidgetHeaderText: "Select a make to get started" });
+
+ //Act
+ vehicleMake.beforeRouteEnter.call(wrapper.vm, { query: { fmgPage: "vehicle-make" } }, undefined, (c) => c(wrapper.vm));
+
+ //Assert
+ const header = await wrapper.find(".Header");
+ apiPromise.finally(() => {
+ expect(header.attributes("text")).toEqual("Select a make to get started");
+ done();
+ });
+ });
+});
+
+function setupMocks({
+ radioQuestionCmsContent = {},
+ makeQuestionInitialData = {},
+ 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",
+ },
+ ],
+ isCmsContentReady: true,
+ },
+ makeQuestionInitialData: makeQuestionInitialData,
+ };
+ const apiPromise = Promise.resolve(apiResponses);
+ settleAllPromises.mockImplementation(() => apiPromise);
+
+ //Mock make question methods
+ makeQuestion.methods = {
+ loadInitialData: jest.fn(),
+ initializeComponent: jest.fn(),
+ };
+ const mountOptions = getMountOptions({ });
+ const wrapper = shallowMount(vehicleMake, mountOptions);
+ const makeQuestionWrapper = wrapper.findComponent({ name: "makeQuestion" });
+ makeQuestionWrapper.vm.initializeComponent = makeQuestion.methods.initializeComponent;
+
+ return { wrapper, apiPromise };
+}
\ No newline at end of file
diff --git a/src/layouts/vehicle-make/vehicle-make.vue b/src/layouts/vehicle-make/vehicle-make.vue
new file mode 100644
index 000000000..a9cedabbf
--- /dev/null
+++ b/src/layouts/vehicle-make/vehicle-make.vue
@@ -0,0 +1,77 @@
+
+
+
+
+
diff --git a/src/layouts/vehicle-year/vehicle-year.vue b/src/layouts/vehicle-year/vehicle-year.vue
index f5ce99324..842cb68ba 100644
--- a/src/layouts/vehicle-year/vehicle-year.vue
+++ b/src/layouts/vehicle-year/vehicle-year.vue
@@ -64,7 +64,7 @@ export default {
watch: {
selectedYear(year) {
this.$store.commit(this.storeMutations.UPDATE_YEAR, year);
- this.$router.push('?fmgPage=vehicle-make');
+ this.$router.navigate(this.navigationScenarios.SELECTED_YEAR, this.$route);
}
},
@@ -76,15 +76,3 @@ export default {
},
};
-
-
diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js
index afe618125..14da7a16b 100644
--- a/src/mixins/base-mixin.js
+++ b/src/mixins/base-mixin.js
@@ -1,5 +1,6 @@
import { storeActions } from "@/constants/store-actions.js";
import { storeMutations } from "@/constants/store-mutations.js";
+import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
import { widgetNames } from "@/constants/widget-names.js";
export default {
@@ -31,6 +32,9 @@ export default {
storeMutations() {
return storeMutations;
},
+ navigationScenarios() {
+ return navigationScenarios;
+ },
widgetNames() {
return widgetNames;
},
diff --git a/src/router/router-constants/fmgPage-values.js b/src/router/router-constants/fmgPage-values.js
index e84d9e9ea..53e8272d8 100644
--- a/src/router/router-constants/fmgPage-values.js
+++ b/src/router/router-constants/fmgPage-values.js
@@ -1,6 +1,7 @@
const fmgPageValues = {
VEHICLE_YEAR: "vehicle-year",
VEHICLE_MAKE: "vehicle-make",
+ VEHICLE_MODEL: "vehicle-model",
};
export { fmgPageValues };
diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js
index 3fc642d65..72703ef58 100644
--- a/src/router/router-constants/navigation-scenarios.js
+++ b/src/router/router-constants/navigation-scenarios.js
@@ -1,5 +1,6 @@
const navigationScenarios = {
SELECTED_YEAR: "SELECTED_YEAR",
+ SELECTED_MAKE: "SELECTED_MAKE",
};
export { navigationScenarios };
diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js
index 7f3f3d0d1..243baeb80 100644
--- a/src/router/router-constants/routing-table.js
+++ b/src/router/router-constants/routing-table.js
@@ -9,6 +9,15 @@ const routingTable = [
scenario: navigationScenarios.SELECTED_YEAR,
destinationFmgPageValue: fmgPageValues.VEHICLE_MAKE,
},
+ {
+ fmgPageValue: fmgPageValues.VEHICLE_MAKE,
+ maps: [
+ {
+ scenario: navigationScenarios.SELECTED_MAKE,
+ destinationFmgPageValue: fmgPageValues.VEHICLE_MODEL,
+ },
+ ],
+ },
],
},
];
diff --git a/src/store/index.js b/src/store/index.js
index 036694868..1bf7243b7 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -65,6 +65,9 @@ export default createStore({
state.order.vehicle.year = year;
},
},
+ getters: {
+ vehicle: state => state.order.vehicle
+ },
actions: {
// Vehicle API Actions
getVehicleYears(context) {
diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue
index e23a96dfc..c20f1c6cb 100644
--- a/src/ux-components/list-button/list-button.vue
+++ b/src/ux-components/list-button/list-button.vue
@@ -18,7 +18,7 @@ export default {
name: "listButton",
props: {
groupName: String, /* Required, unique for each button GROUP */
- buttonID: String, /* Required, unique for each button. Used for button id, label and