diff --git a/jest.config.js b/jest.config.js
index bce302e5a..36c4507fc 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -18,7 +18,7 @@ module.exports = {
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
coverageThreshold: {
global: {
- statements: 87,
+ statements: 89,
},
},
};
diff --git a/src/common-components/funnel-footer/funnel-footer.spec.js b/src/common-components/funnel-footer/funnel-footer.spec.js
new file mode 100644
index 000000000..f1a885dfd
--- /dev/null
+++ b/src/common-components/funnel-footer/funnel-footer.spec.js
@@ -0,0 +1,60 @@
+import { mount } from "@vue/test-utils";
+import funnelFooter from "./funnel-footer";
+
+describe("funnel-footer.vue", () => {
+
+ it("Should return footer-link class", async () => {
+ // Act
+ try {
+ global.document.getElementById = jest.fn().mockImplementation(()=> {
+ return {}
+ });
+
+ const wrapper = mount(funnelFooter, {
+ propsData: {
+ footer: true
+ },
+ });
+
+ // Assert
+ const link = wrapper.find("a");
+
+ // Expect
+ expect(link.attributes('class')).toContain("footer-link");
+ expect(global.document.getElementById).toBeCalled();
+ } catch(error) {
+ console.log(error);
+ }
+
+ });
+
+ it("Should return link text", async () => {
+ // Act
+ const wrapper = mount(funnelFooter, {
+ propsData: {
+ text: "Terms of use",
+ },
+ });
+
+ // Assert
+ const link = wrapper.find("a");
+
+ expect(link.text()).toEqual("Terms of use");
+ });
+
+ it("Should return class btn-primary", async () => {
+ // Act
+ const wrapper = mount(funnelFooter, {
+ propsData: {
+ isPrimary: true,
+ },
+ });
+
+ // Assert
+ const input = wrapper.find("button");
+
+ // Expect
+ expect(input.attributes("class")).toContain("btn-primary");
+ });
+
+});
diff --git a/src/common-components/funnel-footer/funnel-footer.vue b/src/common-components/funnel-footer/funnel-footer.vue
new file mode 100644
index 000000000..90c380b08
--- /dev/null
+++ b/src/common-components/funnel-footer/funnel-footer.vue
@@ -0,0 +1,81 @@
+
+
+
+
+
+
diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js
index 263f153df..177211ae0 100644
--- a/src/constants/store-actions.js
+++ b/src/constants/store-actions.js
@@ -11,9 +11,12 @@ const storeActions = {
GET_EVOX_IMAGE: "getEvoxImage",
LOOKUP_VEHICLE_BY_YMMS: "lookupVehicleByYmms",
LOOKUP_VEHICLE_BY_VIN: "lookupVehicleByVin",
- // EVENT BUS
- ADD_EVENT_TO_BUS: "addEventToBus",
- REMOVE_EVENT_FROM_BUS: "removeEventFromBus",
+
+ // DEPENDENCY MUTATIONS
+ RESET_VEHICLE_AND_DEPS: "resetVehicleAndDependencies",
+ RESET_DAMAGE_AND_DEPS: "resetDamageAndDependencies",
+ RESET_REGISTRATION_AND_DEPS: "resetRegistrationAndDependencies",
+ RESET_PARTS_AND_DEPS: "resetPartsAndDependencies",
};
export { storeActions };
diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js
index 61882b691..f779b11cf 100644
--- a/src/constants/store-mutations.js
+++ b/src/constants/store-mutations.js
@@ -1,9 +1,23 @@
const storeMutations = {
+
+ // VEHICLE MUTATIONS
UPDATE_YEAR: "updateYear",
UPDATE_MAKE: "updateMake",
UPDATE_MODEL: "updateModel",
UPDATE_STYLE: "updateStyle",
- UPDATE_VEHICLE: "updateVehicle",
+ UPDATE_CAR_ID: "updateCarId",
+ UPDATE_VEHICLE_CATEGORY: "updateVehicleCategory",
+
+ // EVENT BUS MUTATIONS
+ ADD_EVENT_TO_BUS: "addEventToBus",
+ REMOVE_EVENT_FROM_BUS: "removeEventFromBus",
+
+ // DEPENDENCY MUTATIONS
+ RESET_VEHICLE_AND_DEPS: "resetVehicleAndDependencies",
+ RESET_DAMAGE_AND_DEPS: "resetDamageAndDependencies",
+ RESET_REGISTRATION_AND_DEPS: "resetRegistrationAndDependencies",
+ RESET_PARTS_AND_DEPS: "resetPartsAndDependencies",
+
};
export { storeMutations };
diff --git a/src/helpers/event-bus/event-bus.js b/src/helpers/event-bus/event-bus.js
index 47f229210..19b30870c 100644
--- a/src/helpers/event-bus/event-bus.js
+++ b/src/helpers/event-bus/event-bus.js
@@ -1,10 +1,10 @@
import store from "@/store";
-import { storeActions } from "@/constants/store-actions.js";
+import { storeMutations } from "@/constants/store-mutations.js";
export default {
// Adds event to the bus given its category, subcategory, and eventValue;
addEventToBus(category, subCategory, eventValue) {
- store.commit(storeActions.ADD_EVENT_TO_BUS, {
+ store.commit(storeMutations.ADD_EVENT_TO_BUS, {
category: category,
subCategory: subCategory,
eventValue: eventValue,
@@ -15,7 +15,7 @@ export default {
readAndPopEventFromBus(category, subCategory) {
const event = store.getters.eventBusItem(category, subCategory);
- store.commit(storeActions.REMOVE_EVENT_FROM_BUS, {
+ store.commit(storeMutations.REMOVE_EVENT_FROM_BUS, {
category: category,
subCategory: subCategory,
});
diff --git a/src/layouts/component-test/component-test.vue b/src/layouts/component-test/component-test.vue
index 2f5dc0308..0b8ec119b 100644
--- a/src/layouts/component-test/component-test.vue
+++ b/src/layouts/component-test/component-test.vue
@@ -40,6 +40,31 @@
+
+
List Card
@@ -60,7 +85,7 @@
/>
Button Question
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -910,6 +949,7 @@ import listButtonHorizontal from "@/ux-components/list-button-horizontal/list-bu
import checkbox from "@/ux-components/checkbox/checkbox";
import buttonQuestion from "@/common-components/button-question/button-question";
import textLink from "@/ux-components/text-link/text-link";
+import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
export default {
name: "App",
components: {
@@ -924,6 +964,7 @@ export default {
funnelHeader,
buttonQuestion,
textLink,
+ funnelFooter
},
data() {
return {
@@ -946,7 +987,7 @@ export default {
Text: "List Card CB",
SubText: "checkbox",
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
- AnswerImageUrl: "side-window-damage-right-all.svg",
+ AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
},
],
listCardRadio: [
@@ -955,7 +996,7 @@ export default {
Text: "List Card R",
SubText: "Radio",
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
- AnswerImageUrl: "side-window-damage-right-all.svg",
+ AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
},
],
listCardCheckBoxHorizontalSubText: [
@@ -964,7 +1005,7 @@ export default {
Text: "List Card CBHst",
SubText: "With Subtext",
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
- AnswerImageUrl: "side-window-damage-right-all.svg",
+ AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
},
],
listCardCheckBoxHorizontal: [
@@ -972,7 +1013,7 @@ export default {
Name: "List-Card-CBH",
Text: "List Card CBH",
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
- AnswerImageUrl: "side-window-damage-right-all.svg",
+ AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
},
],
listRadioHorizontalSubText: [
@@ -981,7 +1022,7 @@ export default {
Text: "List Card RHst",
SubText: "With Subtext",
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
- AnswerImageUrl: "side-window-damage-right-all.svg",
+ AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
},
],
listRadioHorizontal: [
@@ -989,7 +1030,7 @@ export default {
Name: "List-Card-RH",
Text: "List Card RH",
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
- AnswerImageUrl: "side-window-damage-right-all.svg",
+ AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
},
],
listCardGroup: [
@@ -998,20 +1039,20 @@ export default {
Text: "Side Window",
SubText: "With Subtext",
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
- AnswerImageUrl: "side-window-damage-right-all.svg",
+ AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
},
{
Name: "Side-Window-2",
Text: "Side Window",
SubText: "With Subtext that is more than one line",
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
- AnswerImageUrl: "side-window-damage-right-all.svg",
+ AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
},
{
Name: "Side-Window-3",
Text: "Side Window",
ImageId: "53343ce4-5b6a-46aa-a80a-f948c1723955",
- AnswerImageUrl: "side-window-damage-right-all.svg",
+ AnswerImageUrl: "https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3",
},
],
};
diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js
index 7817d743c..49df756c2 100644
--- a/src/layouts/vehicle-damage/vehicle-damage.spec.js
+++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js
@@ -13,6 +13,8 @@ import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { nextTick } from "vue";
+import { storeActions } from "@/constants/store-actions";
+import store from "@/store";
// Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({
@@ -26,6 +28,8 @@ jest.mock("@/helpers/cms-content-helper", () => ({
// Mock Store
jest.mock("@/store", () => ({
+ commit: jest.fn(),
+ dispatch: jest.fn(),
getters: {
vehicle: {
carId: "C00000000",
@@ -138,6 +142,28 @@ describe("vehicle-damage.vue", () => {
});
});
+describe("vehicle-damage.vue", () => {
+ test("Call invalidation, ResetPartsAndDeps should be called", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ vehicleDamage.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-damage" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ wrapper.vm.resetDependentState();
+
+ //Assert
+ expect(store.dispatch).toBeCalledWith(storeActions.RESET_PARTS_AND_DEPS)
+
+ });
+});
+
function setupMocks({
pageHeaderWidgetHeaderText = {},
mountOptionsMockData = {},
diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue
index c820832de..3524c84bc 100644
--- a/src/layouts/vehicle-damage/vehicle-damage.vue
+++ b/src/layouts/vehicle-damage/vehicle-damage.vue
@@ -20,9 +20,10 @@ import damageLocationQuestion from"@/layouts/vehicle-damage/damage-location-ques
// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
+import { storeActions } from "@/constants/store-actions";
import store from "@/store";
import baseMixin from "@/mixins/base-mixin";
-import { storeActions } from "@/constants/store-actions";
+
export default {
name: "vehicle-damage",
@@ -81,6 +82,10 @@ export default {
arePagePrerequisitesValid() {
return store.getters.vehicle.carId !== null;
},
+ resetDependentState() {
+ // Invokes
+ store.dispatch(storeActions.RESET_PARTS_AND_DEPS);
+ },
},
components: {
funnelHeader,
diff --git a/src/layouts/vehicle-make/make-question/make-question.vue b/src/layouts/vehicle-make/make-question/make-question.vue
index 70ba0f909..3bda78285 100644
--- a/src/layouts/vehicle-make/make-question/make-question.vue
+++ b/src/layouts/vehicle-make/make-question/make-question.vue
@@ -8,6 +8,7 @@
textPosition="text-start"
:loaderEnabled="true"
v-model="modelValue"
+ isRequired=true
/>
diff --git a/src/layouts/vehicle-make/vehicle-make.spec.js b/src/layouts/vehicle-make/vehicle-make.spec.js
index 146dd6318..b2c4dcaf7 100644
--- a/src/layouts/vehicle-make/vehicle-make.spec.js
+++ b/src/layouts/vehicle-make/vehicle-make.spec.js
@@ -1,15 +1,23 @@
-import { shallowMount, flushPromises } from "@vue/test-utils";
+// 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";
+import { storeMutations } from "@/constants/store-mutations";
+import { storeActions } from "@/constants/store-actions";
+
+// Components
import vehicleMake from "@/layouts/vehicle-make/vehicle-make.vue";
import makeQuestion from "@/layouts/vehicle-make/make-question/make-question";
import funnelHeader from "@/common-components/funnel-header/funnel-header";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
-import { settleAllPromises } from "@/helpers/layout-helper.js";
-import { nextTick } from "vue";
-import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
+import store from "@/store";
jest.mock("@/store", () => ({
+ commit: jest.fn(),
+ dispatch: jest.fn(),
getters: {
vehicle: {
year: 2019,
@@ -27,9 +35,6 @@ jest.mock("@/helpers/layout-helper.js", () => ({
settleAllPromises: jest.fn(),
}));
-beforeEach(() => {
- jest.resetModules();
-});
describe("vehicle-make.vue", () => {
test("Make question component is initized with api data", async (done) => {
@@ -190,13 +195,40 @@ describe("vehicle-make.vue", () => {
);
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
- await nextTick();
//Assert
expect(arePagePrerequisitesValid).toBe(true);
});
});
+describe("vehicle-make.vue", () => {
+ test("Year set, call invalidation, model, style, carId, category should be null", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ vehicleMake.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-make" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ wrapper.vm.resetDependentState();
+
+ //Assert
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_MODEL, null)
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null)
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null)
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null)
+
+ expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_AND_DEPS)
+ expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_AND_DEPS)
+
+ });
+});
+
function setupMocks({
vehicleMakeQuestionCmsContent = {},
makeQuestionInitialData = {},
diff --git a/src/layouts/vehicle-make/vehicle-make.vue b/src/layouts/vehicle-make/vehicle-make.vue
index 087a10d8b..fcb6a999d 100644
--- a/src/layouts/vehicle-make/vehicle-make.vue
+++ b/src/layouts/vehicle-make/vehicle-make.vue
@@ -25,7 +25,10 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he
// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
+import { storeMutations } from "@/constants/store-mutations";
+import { storeActions } from "@/constants/store-actions";
import store from "@/store";
+
export default {
name: "vehicle-make",
data() {
@@ -75,17 +78,31 @@ export default {
methods: {
backButtonAction() {
// route to move backwards
- this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
+ this.$router.navigate(
+ this.navigationScenarios.CLICKED_BACK,
+ this.$route
+ );
},
arePagePrerequisitesValid() {
return store.getters.vehicle.year !== null;
},
+ resetDependentState() {
+ // Set
+ store.commit(storeMutations.UPDATE_MODEL, null);
+ store.commit(storeMutations.UPDATE_STYLE, null);
+ store.commit(storeMutations.UPDATE_CAR_ID, null);
+ store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
+
+ // Invokes
+ store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
+ store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
+ },
},
watch: {
selectedMake(make) {
this.$store.commit(this.storeMutations.UPDATE_MAKE, make);
- this.$router.navigate(
+ this.$router.navigateAfterSave(
this.navigationScenarios.SELECTED_MAKE,
this.$route
);
diff --git a/src/layouts/vehicle-model/model-question/model-question.vue b/src/layouts/vehicle-model/model-question/model-question.vue
index 312d6c45f..be2c64be5 100644
--- a/src/layouts/vehicle-model/model-question/model-question.vue
+++ b/src/layouts/vehicle-model/model-question/model-question.vue
@@ -8,6 +8,7 @@
textPosition="text-start"
:loaderEnabled="true"
v-model="modelValue"
+ isRequired=true
/>
diff --git a/src/layouts/vehicle-model/vehicle-model.spec.js b/src/layouts/vehicle-model/vehicle-model.spec.js
index 4c61215ba..7f8f96eb6 100644
--- a/src/layouts/vehicle-model/vehicle-model.spec.js
+++ b/src/layouts/vehicle-model/vehicle-model.spec.js
@@ -7,10 +7,13 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he
// Supporting files
import { settleAllPromises } from "@/helpers/layout-helper.js";
-import { shallowMount, flushPromises } from "@vue/test-utils";
+import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { nextTick } from "vue";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
+import { storeMutations } from "@/constants/store-mutations";
+import { storeActions } from "@/constants/store-actions";
+import store from "@/store";
// Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({
@@ -24,6 +27,8 @@ jest.mock("@/helpers/cms-content-helper", () => ({
// Mock Store
jest.mock("@/store", () => ({
+ commit: jest.fn(),
+ dispatch: jest.fn(),
getters: {
vehicle: {
make: "Acura",
@@ -182,6 +187,33 @@ describe("vehicle-model.vue", () => {
});
});
+describe("vehicle-model.vue", () => {
+ test("Year set, call invalidation, style, carId, category should be null", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ vehicleModel.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-model" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ wrapper.vm.resetDependentState();
+
+ //Assert
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null)
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null)
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null)
+
+ expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_AND_DEPS)
+ expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_AND_DEPS)
+
+ });
+});
+
function setupMocks({
buttonQuestionContent = {},
modelQuestionInitialData = {},
diff --git a/src/layouts/vehicle-model/vehicle-model.vue b/src/layouts/vehicle-model/vehicle-model.vue
index 917fcd348..9e5c0243d 100644
--- a/src/layouts/vehicle-model/vehicle-model.vue
+++ b/src/layouts/vehicle-model/vehicle-model.vue
@@ -24,6 +24,8 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
+import { storeMutations } from "@/constants/store-mutations";
+import { storeActions } from "@/constants/store-actions";
import { settleAllPromises } from "@/helpers/layout-helper";
import store from "@/store";
@@ -77,17 +79,30 @@ export default {
methods: {
backButtonAction() {
// route to move backwards
- this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
+ this.$router.navigate(
+ this.navigationScenarios.CLICKED_BACK,
+ this.$route
+ );
},
arePagePrerequisitesValid() {
return store.getters.vehicle.make !== null;
},
+ resetDependentState() {
+ // Set
+ store.commit(storeMutations.UPDATE_STYLE, null);
+ store.commit(storeMutations.UPDATE_CAR_ID, null);
+ store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
+
+ // Invokes
+ store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
+ store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
+ },
},
watch: {
selectedModel(model) {
this.$store.commit(this.storeMutations.UPDATE_MODEL, model);
- this.$router.navigate(
+ this.$router.navigateAfterSave(
this.navigationScenarios.SELECTED_MODEL,
this.$route
);
diff --git a/src/layouts/vehicle-style/style-question/style-question.vue b/src/layouts/vehicle-style/style-question/style-question.vue
index 2af223011..e44514904 100644
--- a/src/layouts/vehicle-style/style-question/style-question.vue
+++ b/src/layouts/vehicle-style/style-question/style-question.vue
@@ -8,6 +8,7 @@
textPosition="text-start"
:loaderEnabled="true"
v-model="modelValue"
+ isRequired=true
/>
diff --git a/src/layouts/vehicle-style/vehicle-style.vue b/src/layouts/vehicle-style/vehicle-style.vue
index 7adff0b73..98c86aa93 100644
--- a/src/layouts/vehicle-style/vehicle-style.vue
+++ b/src/layouts/vehicle-style/vehicle-style.vue
@@ -25,6 +25,7 @@ import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
+import { storeActions } from "@/constants/store-actions";
import store from "@/store";
export default {
@@ -77,7 +78,10 @@ export default {
methods: {
backButtonAction() {
// route to move backwards
- this.$router.navigate(this.navigationScenarios.CLICKED_BACK, this.$route);
+ this.$router.navigate(
+ this.navigationScenarios.CLICKED_BACK,
+ this.$route
+ );
},
setVehicle() {
return this.dispatchNonBlockingStoreAction(
@@ -93,13 +97,18 @@ export default {
arePagePrerequisitesValid() {
return store.getters.vehicle.model !== null;
},
+ resetDependentState() {
+ // Invokes
+ store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
+ store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
+ },
},
watch: {
selectedStyle(style) {
this.$store.commit(this.storeMutations.UPDATE_STYLE, style);
this.setVehicle().then(() => {
- this.$router.navigate(
+ this.$router.navigateAfterSave(
this.navigationScenarios.SELECTED_STYLE,
this.$route
);
diff --git a/src/layouts/vehicle-year/vehicle-year.spec.js b/src/layouts/vehicle-year/vehicle-year.spec.js
index 9b27e6555..5ef3ea404 100644
--- a/src/layouts/vehicle-year/vehicle-year.spec.js
+++ b/src/layouts/vehicle-year/vehicle-year.spec.js
@@ -1,18 +1,35 @@
import { shallowMount, flushPromises } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
+import { settleAllPromises } from "@/helpers/layout-helper.js";
+import { nextTick } from "vue";
+import { storeMutations } from "@/constants/store-mutations";
+import { storeActions } from "@/constants/store-actions";
+import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
+
import vehicleYear from "@/layouts/vehicle-year/vehicle-year.vue";
import yearQuestion from "@/layouts/vehicle-year/year-question/year-question";
import funnelHeader from "@/common-components/funnel-header/funnel-header";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
-import { settleAllPromises } from "@/helpers/layout-helper.js";
-import { nextTick } from "vue";
+
+import store from "@/store";
+
+jest.mock("@/store", () => ({
+ commit: jest.fn(),
+ dispatch: jest.fn(),
+}));
// Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({
settleAllPromises: jest.fn(),
}));
+// Mock fetchCmsContentForPage
+jest.mock("@/helpers/cms-content-helper", () => ({
+ fetchCmsContentForPage: jest.fn(),
+}));
+
+
describe("vehicle-year.vue", () => {
test("Year question component is initized with api data", async (done) => {
//Arrange
@@ -123,6 +140,34 @@ describe("vehicle-year.vue", () => {
});
});
+describe("vehicle-year.vue", () => {
+ test("Year set, call invalidation, make, model, style, carId, category should be null", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ vehicleYear.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-year" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ wrapper.vm.resetDependentState();
+
+ //Assert
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_MAKE, null)
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_MODEL, null)
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_STYLE, null)
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null)
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null)
+
+ expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_AND_DEPS)
+ expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_AND_DEPS)
+
+ });
+});
function setupMocks({
vehicleYearQuestionCmsContent = {},
yearQuestionInitialData = {},
@@ -146,7 +191,9 @@ function setupMocks({
yearQuestionInitialData: yearQuestionInitialData,
};
const apiPromise = Promise.resolve(apiResponses);
+
settleAllPromises.mockImplementation(() => apiPromise);
+ fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
//Mock year question methods
yearQuestion.methods = {
@@ -162,6 +209,7 @@ function setupMocks({
funnelSubHeader.methods = {
initializeComponent: jest.fn(),
};
+
const mountOptions = getMountOptions(mountOptionsMockData);
const wrapper = shallowMount(vehicleYear, mountOptions);
const yearQuestionWrapper = wrapper.findComponent({ name: "yearQuestion" });
diff --git a/src/layouts/vehicle-year/vehicle-year.vue b/src/layouts/vehicle-year/vehicle-year.vue
index afcece898..2ee00e5eb 100644
--- a/src/layouts/vehicle-year/vehicle-year.vue
+++ b/src/layouts/vehicle-year/vehicle-year.vue
@@ -20,7 +20,9 @@ import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-he
// Supporting files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
-import eventBus from "@/helpers/event-bus/event-bus";
+import { storeMutations } from "@/constants/store-mutations";
+import { storeActions } from "@/constants/store-actions";
+import store from "@/store";
export default {
name: "vehicle-year",
@@ -71,8 +73,9 @@ export default {
watch: {
selectedYear(year) {
+
this.$store.commit(this.storeMutations.UPDATE_YEAR, year);
- this.$router.navigate(
+ this.$router.navigateAfterSave(
this.navigationScenarios.SELECTED_YEAR,
this.$route
);
@@ -82,6 +85,19 @@ export default {
arePagePrerequisitesValid() {
return true;
},
+ resetDependentState() {
+
+ // Set
+ store.commit(storeMutations.UPDATE_MAKE, null);
+ store.commit(storeMutations.UPDATE_MODEL, null);
+ store.commit(storeMutations.UPDATE_STYLE, null);
+ store.commit(storeMutations.UPDATE_CAR_ID, null);
+ store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
+
+ // Invokes
+ store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
+ store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
+ }
},
components: {
yearQuestion,
diff --git a/src/router/index.js b/src/router/index.js
index eb4942d6a..02859e660 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -45,16 +45,16 @@ const routes = [
// If we already have our route, go to it.
if (router.hasRoute(to.query.fmgPage)) {
// Since our route is already in scope, we can grab the component from it and call the arePagePrerequisitesValid function.
- const arePagePrerequisitesValid = router
+ const component = router
.getRoutes()
- .filter((x) => x.name === to.query.fmgPage)[0]
- .components.default.methods.arePagePrerequisitesValid();
+ .filter((x) => x.name === to.query.fmgPage)[0].components;
- if (!arePagePrerequisitesValid) {
+ if (!arePagePrerequisitesValid(component)) {
await GoToFunnelStartOn404(next);
}
- return next({ name: to.query.fmgPage, query: to.query, params: to.params });
+
+ return next({ name: to.query.fmgPage, query: to.query, params: to.params });
}
// Get route info for the given url. Names will have a 1:1 relationship with names in the Cms.
@@ -74,7 +74,7 @@ const routes = [
.filter((x) => x.name === routeData[0].name)[0]
.components.default();
- if (!nextComponent.default.methods.arePagePrerequisitesValid()) {
+ if (!arePagePrerequisitesValid(nextComponent)) {
await GoToFunnelStartOn404(next);
}
@@ -102,23 +102,36 @@ const router = createRouter({
//---------------------------------------------------------- Router Functions ----------------------------------------------------------
+router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) => {
+ navigate(scenario, currentRoute, false, optionalQuery, optionalParams);
+}
+
+router.navigateAfterSave = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) => {
+ navigate(scenario, currentRoute, true, optionalQuery, optionalParams);
+}
+
+// PRIVATE FUNCTIONS
+
// Navigate to the next route, depending on the scenario.
-router.navigate = (
- scenario,
- currentRoute,
- optionalQuery = {},
- optionalParams = {}
-) => {
+function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, optionalParams = {}) {
if (!scenario) {
console.error("No scenario provided. Please review the routing table.");
return;
}
// Match our maps up and navigate if we have a destination.
- const matchingScenarioMap = router.getNavigationMap(scenario, currentRoute);
+ const matchingScenarioMap = getNavigationMap(scenario, currentRoute);
if (matchingScenarioMap.destinationFmgPageValue !== undefined) {
// We're always pushing the same path, just changing query strings. Make sure our optional query strings get combined with our fmgPage one.
+
+ // If we need to do invalidation
+ const currentComponent = currentRoute.matched[0].components;
+
+ if (invalidateOnSave) {
+ resetDependentState(currentComponent);
+ }
+
router.push({
name: "root",
query: Object.assign(optionalQuery, {
@@ -132,7 +145,7 @@ router.navigate = (
};
// Get navigation map depending on the scenario and the current 'page' you're on.
-router.getNavigationMap = (scenario, currentRoute) => {
+function getNavigationMap(scenario, currentRoute) {
const fmgPageValue = currentRoute.query.fmgPage;
const matchedQueryValue = routingTable
.filter(
@@ -197,4 +210,14 @@ async function GoToFunnelStartOn404(next) {
});
}
+// Checks arePagePrerequisitesValid on the component passed in.
+function arePagePrerequisitesValid(component) {
+ return component.default.methods.arePagePrerequisitesValid();
+}
+
+// Reset dependant state on route change.
+function resetDependentState(component) {
+ return component.default.methods.resetDependentState();
+}
+
export default router;
diff --git a/src/store/index.js b/src/store/index.js
index 9d5078f74..a0c64fcfc 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -3,7 +3,228 @@ import { endpoints } from "@/constants/endpoints.js";
import { storeMutations } from "@/constants/store-mutations";
import createPersistedState from "vuex-persistedstate";
import globalMethods from "@/global-methods";
-import eventBus from "../helpers/event-bus/event-bus";
+
+
+
+// Export State
+export const state = {
+ order: {
+ vehicle: {
+ year: null,
+ make: null,
+ model: null,
+ style: null,
+ carId: null,
+ category: null,
+ },
+ damage: {
+ isRepair: null,
+ numberOfChips: null,
+ glassToReplace: null,
+ },
+ },
+ applicationUser: {
+ eventBus: [],
+ },
+}
+
+// Export Mutations
+export const mutations = {
+ // VEHICLE MUTATIONS
+ updateYear(state, year) {
+ state.order.vehicle.year = year;
+ },
+ updateMake(state, make) {
+ state.order.vehicle.make = make;
+ },
+ updateModel(state, model) {
+ state.order.vehicle.model = model;
+ },
+ updateStyle(state, style) {
+ state.order.vehicle.style = style;
+ },
+ updateCarId(state, carId) {
+ state.order.vehicle.carId = carId;
+ },
+ updateVehicleCategory(state, category) {
+ state.order.vehicle.category = category;
+ },
+
+ // EVENT BUS MUTATIONS
+ addEventToBus(state, event) {
+ state.applicationUser.eventBus.push(event);
+ },
+ removeEventFromBus(state, eventData) {
+ const matchedEvent = state.applicationUser.eventBus.find(
+ ({ category, subCategory }) =>
+ category === eventData.category &&
+ subCategory === eventData.subCategory
+ );
+ const itemIndex = state.applicationUser.eventBus.indexOf(matchedEvent);
+
+ // If the item exists, remove it.
+ if (itemIndex > -1) {
+ state.applicationUser.eventBus.splice(itemIndex, 1);
+ }
+ },
+
+ // DEPENDENCY MUTATIONS
+ resetVehicleAndDependencies(state) {
+ state.order.vehicle.year = null;
+ state.order.vehicle.make = null;
+ state.order.vehicle.model = null;
+ state.order.vehicle.style = null;
+ state.order.vehicle.carId = null;
+ state.order.vehicle.category = null;
+ },
+ resetDamageAndDependencies(state) {
+ state.order.damage.isRepair = null;
+ state.order.damage.numberOfChips = null;
+ state.order.damage.windshieldGlassToReplace = null;
+ state.order.damage.driverSideGlassToReplace = null;
+ state.order.damage.passengerSideGlassToReplace = null;
+ state.order.damage.rearGlassToReplace = null;
+
+ },
+ resetRegistrationAndDependencies(state) {
+
+ },
+ resetPartsAndDependencies(state) {
+
+ }
+}
+
+// Export Getters
+export const getters = {
+ vehicle: (state) => state.order.vehicle,
+ eventBusItem: (state) => (eventCategory, eventSubCategory) => {
+ const matchedEvent = state.applicationUser.eventBus.find(
+ ({ category, subCategory }) =>
+ category === eventCategory && subCategory === eventSubCategory
+ );
+
+ return matchedEvent !== undefined ? matchedEvent.eventValue : undefined;
+ },
+ eventBus: (state) => state.applicationUser.eventBus,
+}
+
+// Export Actions
+export const actions = {
+ // Vehicle API Actions
+ getVehicleYears(context) {
+ return globalMethods.callHttpClient({
+ method: endpoints.GetVehicleYears.method,
+ endpoint: endpoints.GetVehicleYears.url,
+ payload: {},
+ });
+ },
+ lookupVehicleByYmms(context, { year, make, model, style }) {
+ return globalMethods.callHttpClient({
+ method: endpoints.LookupVehicleByYmms.method,
+ endpoint: `${endpoints.LookupVehicleByYmms.url}/${year}/${make}/${model}/${style}`,
+ payload: {},
+ });
+ },
+ lookupVehicleByVin(context, { vin }) {
+ return globalMethods.callHttpClient({
+ method: endpoints.LookupVehicleByVin.method,
+ endpoint: endpoints.LookupVehicleByVin.url,
+ payload: {
+ vin: vin, // EX "1J4GW58S4XC541166"
+ },
+ });
+ },
+ getVehicleMakes(context, { year }) {
+ return globalMethods.callHttpClient({
+ method: endpoints.GetVehicleMakes.method,
+ endpoint: `${endpoints.GetVehicleMakes.url}/${year}`,
+ payload: {},
+ });
+ },
+ getVehicleModels(context, { year, make }) {
+ return globalMethods.callHttpClient({
+ method: endpoints.GetVehicleModels.method,
+ endpoint: `${endpoints.GetVehicleModels.url}/${year}/${make}`,
+ payload: {},
+ });
+ },
+ getVehicleStyles(context, { year, make, model }) {
+ return globalMethods.callHttpClient({
+ method: endpoints.GetVehicleStyles.method,
+ endpoint: `${endpoints.GetVehicleStyles.url}/${year}/${make}/${model}`,
+ payload: {},
+ });
+ },
+ setVehicle(context, { year, make, model, style }) {
+ return globalMethods
+ .callHttpClient({
+ methods: endpoints.GetVehicle.method,
+ endpoint: `${endpoints.GetVehicle.url}/${year}/${make}/${model}/${style}`,
+ payload: {},
+ })
+ .then((response) => {
+ context.commit(storeMutations.UPDATE_CAR_ID, response.data.carId);
+ context.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, response.data.category);
+ return response;
+ });
+ },
+ getDamageOptions(context, { carId }) {
+ return globalMethods.callHttpClient({
+ methods: endpoints.GetDamageOptions.method,
+ endpoint: `${endpoints.GetDamageOptions.url}/${carId}`,
+ payload: {},
+ });
+ },
+
+ // DEPENDENCY ACTIONS
+ resetVehicleAndDependencies(context) {
+ context.commit(storeMutations.RESET_VEHICLE_AND_DEPS);
+ context.commit(storeMutations.RESET_DAMAGE_AND_DEPS);
+ context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS);
+ },
+ resetDamageAndDependencies(context) {
+ context.commit(storeMutations.RESET_DAMAGE_AND_DEPS);
+ context.commit(storeMutations.RESET_PARTS_AND_DEPS);
+ },
+ resetRegistrationAndDependencies(context) {
+ context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS);
+ context.commit(storeMutations.RESET_PARTS_AND_DEPS)
+ },
+ resetPartsAndDependencies(context) {
+ context.commit(storeMutations.RESET_PARTS_AND_DEPS);
+ },
+
+ // Content API Actions
+ getRouteInfo(context, { pageName }) {
+ return globalMethods.callHttpClient({
+ method: endpoints.GetRouteInfo.method,
+ endpoint: endpoints.GetRouteInfo.url,
+ payload: {
+ pageName: pageName,
+ },
+ });
+ },
+ getHomepageName(context) {
+ return globalMethods.callHttpClient({
+ method: endpoints.GetHomepageInfo.method,
+ endpoint: endpoints.GetHomepageInfo.url,
+ });
+ },
+ getPageData(context, { pageName }) {
+ return globalMethods.callHttpClient({
+ method: endpoints.GetPageData.method,
+ endpoint: `${endpoints.GetPageData.url}/${pageName}`,
+ payload: {},
+ });
+ },
+ getEvoxImage(context, { relativeUrl }) {
+ return globalMethods.callHttpClient({
+ method: endpoints.GetPageData.method,
+ endpoint: relativeUrl,
+ payload: {},
+ });
+ },
+}
export default createStore({
plugins: [createPersistedState()],
@@ -12,169 +233,8 @@ export default createStore({
// * The CMS can reference the fields by name
// * Return users may have a previous "version" of the model, and we don't want
// them to have a breaking experience, because the model might have changed.
- state: {
- order: {
- vehicle: {
- year: null,
- make: null,
- model: null,
- style: null,
- carId: null,
- category: null,
- damage: {
- isRepair: null,
- numberOfChips: null,
- glassToReplace: null,
- },
- },
- },
- applicationUser: {
- eventBus: [],
- },
- },
- // See IMPORTANT note at top of "state" declaration.
-
- mutations: {
- updateYear(state, year) {
- state.order.vehicle.year = year;
- },
- updateMake(state, make) {
- state.order.vehicle.make = make;
- },
- updateModel(state, model) {
- state.order.vehicle.model = model;
- },
- updateStyle(state, style) {
- state.order.vehicle.style = style;
- },
- updateVehicle(state, data) {
- state.order.vehicle.carId = data.carId;
- state.order.vehicle.category = data.category;
- },
- addEventToBus(state, event) {
- state.applicationUser.eventBus.push(event);
- },
- removeEventFromBus(state, eventData) {
- const matchedEvent = state.applicationUser.eventBus.find(
- ({ category, subCategory }) =>
- category === eventData.category &&
- subCategory === eventData.subCategory
- );
- const itemIndex = state.applicationUser.eventBus.indexOf(matchedEvent);
-
- // If the item exists, remove it.
- if (itemIndex > -1) {
- state.applicationUser.eventBus.splice(itemIndex, 1);
- }
- },
- },
- getters: {
- vehicle: (state) => state.order.vehicle,
- eventBusItem: (state) => (eventCategory, eventSubCategory) => {
- const matchedEvent = state.applicationUser.eventBus.find(
- ({ category, subCategory }) =>
- category === eventCategory && subCategory === eventSubCategory
- );
-
- return matchedEvent !== undefined ? matchedEvent.eventValue : undefined;
- },
- eventBus: (state) => state.applicationUser.eventBus,
- },
- actions: {
- // Vehicle API Actions
- getVehicleYears(context) {
- return globalMethods.callHttpClient({
- method: endpoints.GetVehicleYears.method,
- endpoint: endpoints.GetVehicleYears.url,
- payload: {},
- });
- },
- lookupVehicleByYmms(context, { year, make, model, style }) {
- return globalMethods.callHttpClient({
- method: endpoints.LookupVehicleByYmms.method,
- endpoint: `${endpoints.LookupVehicleByYmms.url}/${year}/${make}/${model}/${style}`,
- payload: {},
- });
- },
- lookupVehicleByVin(context, { vin }) {
- return globalMethods.callHttpClient({
- method: endpoints.LookupVehicleByVin.method,
- endpoint: endpoints.LookupVehicleByVin.url,
- payload: {
- vin: vin, // EX "1J4GW58S4XC541166"
- },
- });
- },
- getVehicleMakes(context, { year }) {
- return globalMethods.callHttpClient({
- method: endpoints.GetVehicleMakes.method,
- endpoint: `${endpoints.GetVehicleMakes.url}/${year}`,
- payload: {},
- });
- },
- getVehicleModels(context, { year, make }) {
- return globalMethods.callHttpClient({
- method: endpoints.GetVehicleModels.method,
- endpoint: `${endpoints.GetVehicleModels.url}/${year}/${make}`,
- payload: {},
- });
- },
- getVehicleStyles(context, { year, make, model }) {
- return globalMethods.callHttpClient({
- method: endpoints.GetVehicleStyles.method,
- endpoint: `${endpoints.GetVehicleStyles.url}/${year}/${make}/${model}`,
- payload: {},
- });
- },
- setVehicle(context, { year, make, model, style }) {
- return globalMethods
- .callHttpClient({
- methods: endpoints.GetVehicle.method,
- endpoint: `${endpoints.GetVehicle.url}/${year}/${make}/${model}/${style}`,
- payload: {},
- })
- .then((response) => {
- context.commit(storeMutations.UPDATE_VEHICLE, response.data);
- return response;
- });
- },
- getDamageOptions(context, { carId }) {
- return globalMethods.callHttpClient({
- methods: endpoints.GetDamageOptions.method,
- endpoint: `${endpoints.GetDamageOptions.url}/${carId}`,
- payload: {},
- });
- },
-
- // Content API Actions
- getRouteInfo(context, { pageName }) {
- return globalMethods.callHttpClient({
- method: endpoints.GetRouteInfo.method,
- endpoint: endpoints.GetRouteInfo.url,
- payload: {
- pageName: pageName,
- },
- });
- },
- getHomepageName(context) {
- return globalMethods.callHttpClient({
- method: endpoints.GetHomepageInfo.method,
- endpoint: endpoints.GetHomepageInfo.url,
- });
- },
- getPageData(context, { pageName }) {
- return globalMethods.callHttpClient({
- method: endpoints.GetPageData.method,
- endpoint: `${endpoints.GetPageData.url}/${pageName}`,
- payload: {},
- });
- },
- getEvoxImage(context, { relativeUrl }) {
- return globalMethods.callMockHttpClient({
- method: endpoints.GetPageData.method,
- endpoint: relativeUrl,
- payload: {},
- });
- },
- },
+ state,
+ mutations,
+ getters,
+ actions,
});
diff --git a/src/store/store.spec.js b/src/store/store.spec.js
index e71f07909..f33595e58 100644
--- a/src/store/store.spec.js
+++ b/src/store/store.spec.js
@@ -1,328 +1,483 @@
-import store from "./index";
import globalMethods from "@/global-methods";
+import { mutations, state, actions, getters } from "@/store";
+import { storeMutations } from "@/constants/store-mutations";
-describe("Actions", () => {
- it("Should return list of years retrieved", async () => {
+// Mock global method
+globalMethods.callHttpClient = jest.fn();
+
+
+describe("Mutations", () => {
+
+ it("Updates vehicle year in state", () => {
// Arrange
- let years = [];
+ const storeState = state;
+
+ // Act
+ mutations.updateYear(storeState, "2019");
+
+ // Assert
+ expect(storeState.order.vehicle.year).toEqual("2019");
+ });
+
+ it("Updates vehicle make in state", () => {
+ // Arrange
+ const storeState = state;
+
+ // Act
+ mutations.updateMake(storeState, "Acura");
+
+ // Assert
+ expect(storeState.order.vehicle.make).toEqual("Acura");
+ });
+
+ it("Updates vehicle model in state", () => {
+ // Arrange
+ const storeState = state;
+
+ // Act
+ mutations.updateModel(storeState, "ILX");
+
+ // Assert
+ expect(storeState.order.vehicle.model).toEqual("ILX");
+ });
+
+ it("Updates vehicle style in state", () => {
+ // Arrange
+ const storeState = state;
+
+ // Act
+ mutations.updateStyle(storeState, "4 DOOR SEDAN");
+
+ // Assert
+ expect(storeState.order.vehicle.style).toEqual("4 DOOR SEDAN");
+ });
+
+ it("Updates vehicle carId in state", () => {
+ // Arrange
+ const storeState = state;
+
+ // Act
+ mutations.updateCarId(storeState, "C0000001");
+
+ // Assert
+ expect(storeState.order.vehicle.carId).toEqual("C0000001");
+ });
+
+ it("Updates vehicle vehicle category in state", () => {
+ // Arrange
+ const storeState = state;
+
+ // Act
+ mutations.updateVehicleCategory(storeState, "CAR");
+
+ // Assert
+ expect(storeState.order.vehicle.category).toEqual("CAR");
+ });
+
+ it("Remove item to eventBus in state", () => {
+ // Arrange
+ const storeState = state;
+ const event = { category: "CategoryOne", subCategory: "SubCategoryOne" }
+
+ // Act / Assert
+ mutations.addEventToBus(storeState, event);
+ expect(storeState.applicationUser.eventBus).toEqual([event]);
+
+ // Act / Assert
+ mutations.removeEventFromBus(storeState, event);
+ expect(storeState.applicationUser.eventBus).toEqual([]);
+
+ });
+
+ it("Adds item to eventBus in state", () => {
+ // Arrange
+ const storeState = state;
+
+ // Act
+ mutations.addEventToBus(storeState, { EventOne: "ValueOne" });
+
+ // Assert
+ expect(storeState.applicationUser.eventBus).toEqual([{ EventOne: "ValueOne" }]);
+ });
+
+ it("resetVehicleAndDependencies, should set fields to null", () => {
+ // Arrange
+ const storeState = state;
+
+ mutations.updateYear(storeState, "2019");
+ mutations.updateMake(storeState, "Acura");
+ mutations.updateModel(storeState, "ILX");
+ mutations.updateStyle(storeState, "4 DOOR SEDAN");
+ mutations.updateCarId(storeState, "C0000001");
+ mutations.updateVehicleCategory(storeState, "CAR");
+
+ // Expect
+ expect(storeState.order.vehicle.year).toEqual("2019");
+ expect(storeState.order.vehicle.make).toEqual("Acura");
+ expect(storeState.order.vehicle.model).toEqual("ILX");
+ expect(storeState.order.vehicle.style).toEqual("4 DOOR SEDAN");
+ expect(storeState.order.vehicle.carId).toEqual("C0000001");
+ expect(storeState.order.vehicle.category).toEqual("CAR");
+
+ // Act
+ mutations.resetVehicleAndDependencies(storeState);
+
+ // Expect
+ expect(storeState.order.vehicle.year).toEqual(null);
+ expect(storeState.order.vehicle.make).toEqual(null);
+ expect(storeState.order.vehicle.model).toEqual(null);
+ expect(storeState.order.vehicle.style).toEqual(null);
+ expect(storeState.order.vehicle.carId).toEqual(null);
+ expect(storeState.order.vehicle.category).toEqual(null);
+
+ });
+
+ it("resetDamageAndDependencies, should set fields to null", () => {
+ // Arrange
+ const storeState = state;
+
+ storeState.order.damage = {
+ isRepair: true,
+ numberOfChips: 2,
+ windshieldGlassToReplace: "Front",
+ driverSideGlassToReplace: "Rear",
+ passengerSideGlassToReplace: "Rear",
+ rearGlassToReplace: "Slider"
+ }
+
+ // Expect
+ expect(storeState.order.damage.isRepair).toEqual(true);
+ expect(storeState.order.damage.numberOfChips).toEqual(2);
+ expect(storeState.order.damage.windshieldGlassToReplace).toEqual("Front");
+ expect(storeState.order.damage.driverSideGlassToReplace).toEqual("Rear");
+ expect(storeState.order.damage.passengerSideGlassToReplace).toEqual("Rear");
+ expect(storeState.order.damage.rearGlassToReplace).toEqual("Slider");
+
+ // Act
+ mutations.resetDamageAndDependencies(storeState);
+
+ // Expect
+ expect(storeState.order.damage.isRepair).toEqual(null);
+ expect(storeState.order.damage.numberOfChips).toEqual(null);
+ expect(storeState.order.damage.windshieldGlassToReplace).toEqual(null);
+ expect(storeState.order.damage.driverSideGlassToReplace).toEqual(null);
+ expect(storeState.order.damage.passengerSideGlassToReplace).toEqual(null);
+ expect(storeState.order.damage.rearGlassToReplace).toEqual(null);
+
+ });
+
+});
+
+describe("Actions", () => {
+ it("getVehicleYears action, should return years array", async () => {
+
+ // Arrange
+ const context = state;
// Act
- globalMethods.callHttpClient = jest.fn();
globalMethods.callHttpClient.mockImplementation(() => {
return Promise.resolve({ data: [2023, 2022, 2021] });
});
- await store.dispatch("getVehicleYears").then((response) => {
- years = response.data;
- });
// Assert
- expect(years[0]).toBe(2023);
+ const response = await actions.getVehicleYears(context)
+
+ expect(response.data).toEqual([2023, 2022, 2021]);
});
- it("Should return list of makes retrieved", async () => {
+ it("lookupVehicleByYmms action, should return car data", async () => {
+
// Arrange
- let makes = [];
+ const context = state;
// Act
globalMethods.callHttpClient.mockImplementation(() => {
- return Promise.resolve({ data: ["Baic", "Honda", "Ford"] });
- });
- await store.dispatch("getVehicleMakes", { year: 2023 }).then((response) => {
- makes = response.data;
+ return Promise.resolve({ data: { carId: "C00000001" } });
});
// Assert
- expect(makes[0]).toBe("Baic");
+ const response = await actions.lookupVehicleByYmms(context, "2019", "Acura", "ILX", "4 DOOR SEDAN")
+
+ expect(response.data).toEqual({ carId: "C00000001" });
});
- it("Should return list of models retrieved", async () => {
+ it("lookupVehicleByVin action, should return car data", async () => {
+
// Arrange
- let models = [];
+ const context = state;
// Act
globalMethods.callHttpClient.mockImplementation(() => {
- return Promise.resolve({ data: ["BJ40 (MEX)", "Civic", "Accord"] });
+ return Promise.resolve({ data: { carId: "C00000001" } });
});
- await store
- .dispatch("getVehicleModels", { year: 2023, make: "Baic" })
- .then((response) => {
- models = response.data;
- });
// Assert
- expect(models[0]).toBe("BJ40 (MEX)");
+ const response = await actions.lookupVehicleByVin(context, "12345678901234567")
+
+ expect(response.data).toEqual({ carId: "C00000001" });
});
- it("Should return list of styles retrieved", async () => {
+ it("getVehicleMakes action, should return makes list", async () => {
+
// Arrange
- let styles = [];
+ const context = state;
// Act
globalMethods.callHttpClient.mockImplementation(() => {
- return Promise.resolve({ data: ["4 DOOR UTILITY", "2 DOOR"] });
+ return Promise.resolve({ data: ["Acura", "Honda"] });
});
- await store
- .dispatch("getVehicleStyles", {
- year: 2023,
- make: "Baic",
- model: "BJ40 (MEX)",
- })
- .then((response) => {
- styles = response.data;
- });
// Assert
- expect(styles[0]).toBe("4 DOOR UTILITY");
+ const response = await actions.getVehicleMakes(context, "2019")
+
+ expect(response.data).toEqual(["Acura", "Honda"]);
});
- it("Should return list of damage options retrieved", async () => {
+ it("getVehicleModels action, should return models list", async () => {
+
// Arrange
- let damageOptions = [];
+ const context = state;
// Act
globalMethods.callHttpClient.mockImplementation(() => {
- return Promise.resolve({ data: ["Front Window", "Rear Window"] });
+ return Promise.resolve({ data: ["ILX", "RDX"] });
});
- await store
- .dispatch("getDamageOptions", {
- carId: "CR00070154",
- })
- .then((response) => {
- damageOptions = response.data;
- });
// Assert
- expect(damageOptions[0]).toBe("Front Window");
+ const response = await actions.getVehicleModels(context, "2019", "Acura")
+
+ expect(response.data).toEqual(["ILX", "RDX"]);
});
- it("Should return data from url retrieved", async () => {
+ it("getVehicleStyles action, should return models list", async () => {
+
// Arrange
- let routeInfo = [];
+ const context = state;
// Act
globalMethods.callHttpClient.mockImplementation(() => {
- return Promise.resolve({
- data: {
- Result: "Route Info Data",
- },
- });
+ return Promise.resolve({ data: { style: "4 DOOR SEDAN" } });
});
- await store
- .dispatch("getRouteInfo", { pageName: "vehicle-year" })
- .then((response) => {
- routeInfo = response.data.Result;
- });
// Assert
- expect(routeInfo).toBe("Route Info Data");
+ const response = await actions.getVehicleStyles(context, "2019", "Acura", "ILX")
+
+ expect(response.data).toEqual({ style: "4 DOOR SEDAN" });
});
- it("Should return page data from url retrieved", async () => {
+ it("setVehicle action, should get vehicle data and set carId and vehicle category", async () => {
+
// Arrange
- let pageData = [];
+ const context = state;
+ const commit = jest.fn();
+
+ context.commit = commit;
// Act
globalMethods.callHttpClient.mockImplementation(() => {
- return Promise.resolve({
- data: {
- Result: "Page Info Data",
- },
- });
+ return Promise.resolve({ data: { carId: "C00000000", category: "CAR" } });
});
- await store
- .dispatch("getPageData", { pageName: "vehicle-year" })
- .then((response) => {
- pageData = response.data.Result;
- });
// Assert
- expect(pageData).toBe("Page Info Data");
+ const response = await actions.setVehicle(context, "C00000000")
+
+ expect(commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, "C00000000");
+ expect(commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, "CAR");
+ expect(response.data).toEqual({ carId: "C00000000", category: "CAR" });
});
- it("Should return data from url retrieved", async () => {
+ it("getDamageOptions action", async () => {
+
// Arrange
- let returnData = [];
+ const context = state;
// Act
globalMethods.callHttpClient.mockImplementation(() => {
- return Promise.resolve({
- data: {
- Result: "2018 Honda Civic",
- },
- });
+ return Promise.resolve({ data: ["Windshield", "DriversFrontDoor"] });
});
- await store
- .dispatch("lookupVehicleByYmms", {
- year: "2018",
- make: "Honda",
- model: "Civic",
- style: "2 Door",
- })
- .then((response) => {
- returnData = response.data.Result;
- });
+
+ const response = await actions.getDamageOptions(context, "C00000000")
// Assert
- expect(returnData).toBe("2018 Honda Civic");
+ expect(response.data).toEqual(["Windshield", "DriversFrontDoor"]);
});
- it("Should return vehicle data from url retrieved", async () => {
+ it("resetVehicleAndDependencies action", async () => {
+
// Arrange
- let returnData = [];
+ const context = state;
+ const commit = jest.fn();
+
+ context.commit = commit;
// Act
+ await actions.resetVehicleAndDependencies(context)
+
+ expect(commit).toBeCalledWith(storeMutations.RESET_VEHICLE_AND_DEPS);
+ expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_AND_DEPS);
+ expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_AND_DEPS);
+
+ });
+
+ it("resetDamageAndDependencies action", async () => {
+
+ // Arrange
+ const context = state;
+ const commit = jest.fn();
+
+ context.commit = commit;
+
+ // Act
+ await actions.resetDamageAndDependencies(context)
+
+ expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_AND_DEPS);
+ expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS);
+
+ });
+
+ it("resetRegistrationAndDependencies action", async () => {
+
+ // Arrange
+ const context = state;
+ const commit = jest.fn();
+
+ context.commit = commit;
+
+ // Act
+ await actions.resetRegistrationAndDependencies(context)
+
+ expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_AND_DEPS);
+ expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS);
+
+ });
+
+ it("resetPartsAndDependencies action", async () => {
+
+ // Arrange
+ const context = state;
+ const commit = jest.fn();
+
+ context.commit = commit;
+
+ // Act
+ await actions.resetPartsAndDependencies(context)
+
+ expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS);
+
+ });
+
+ it("getRouteInfo action, returns route info", async () => {
+
+ // Arrange
+ const context = state;
+
globalMethods.callHttpClient.mockImplementation(() => {
- return Promise.resolve({
- data: {
- Result: "2021 Honda Civic",
- },
- });
+ return Promise.resolve({ data: { Widget: "Data" } });
});
- await store
- .dispatch("lookupVehicleByVin", { vin: "12345678" })
- .then((response) => {
- returnData = response.data.Result;
- });
-
- // Assert
- expect(returnData).toBe("2021 Honda Civic");
- });
-
- it("Should return vehicle image data from url retrieved", async () => {
- // Arrange
- let returnData = [];
// Act
- globalMethods.callMockHttpClient = jest.fn();
- globalMethods.callMockHttpClient.mockImplementation(() => {
- return Promise.resolve({
- data: {
- Result: "2008_honda_civic.jpg",
- },
- });
+ const response = await actions.getRouteInfo(context, "vehicle-year")
+
+
+ expect(response.data).toEqual({ Widget: "Data" });
+
+ });
+
+ it("getHomepageName action, returns homepage name", async () => {
+
+ // Arrange
+ const context = state;
+
+ globalMethods.callHttpClient.mockImplementation(() => {
+ return Promise.resolve({ data: { Name: "vehicle-year" } });
});
- await store
- .dispatch("getEvoxImage", { relativeUrl: "evox_image.com" })
- .then((response) => {
- returnData = response.data.Result;
- });
- // Assert
- expect(returnData).toBe("2008_honda_civic.jpg");
- });
-});
-
-describe("Mutations", () => {
- it("Should update the year property in the store", () => {
// Act
- store.commit("updateYear", 2020);
+ const response = await actions.getHomepageName(context)
+
+
+ expect(response.data).toEqual({ Name: "vehicle-year" });
- // Assert
- expect(store.state.order.vehicle.year).toBe(2020);
});
- it("Should update the make property in the store", () => {
- // Act
- store.commit("updateMake", "Honda");
+ it("getPageData action, returns page data", async () => {
- // Assert
- expect(store.state.order.vehicle.make).toBe("Honda");
- });
-
- it("Should update the model property in the store", () => {
- // Act
- store.commit("updateModel", "Civic");
-
- // Assert
- expect(store.state.order.vehicle.model).toBe("Civic");
- });
-
- it("Should update the style property in the store", () => {
- // Act
- store.commit("updateStyle", "2 Door");
-
- // Assert
- expect(store.state.order.vehicle.style).toBe("2 Door");
- });
-
- it("Should update the carID and category propertys in the store", () => {
// Arrange
- const carData = {
- carId: "123abc",
- category: "car",
- };
- // Act
- store.commit("updateVehicle", carData);
+ const context = state;
+
+ globalMethods.callHttpClient.mockImplementation(() => {
+ return Promise.resolve({ data: { Results: [{ Widget: "Data" }] } });
+ });
+
+ // Act
+ const response = await actions.getPageData(context, "vehicle-year")
+
+
+ expect(response.data).toEqual({ Results: [{ Widget: "Data" }] });
- // Assert
- expect(store.state.order.vehicle.carId).toBe("123abc");
- expect(store.state.order.vehicle.category).toBe("car");
});
- it("Should add event onto bus and update state", () => {
+ it("getEvoxImage action, returns image url", async () => {
// Arrange
- const event = {
- category: "TestCategoryOne",
- subCategory: "TestSubCategoryOne",
- eventValue: "TestEventValueOne",
- };
+ const context = state;
+
+ globalMethods.callHttpClient.mockImplementation(() => {
+ return Promise.resolve({ data: { imageUrl: "https://test.com" } });
+ });
// Act
- store.commit("addEventToBus", event);
+ const response = await actions.getEvoxImage(context, { relativeUrl: "https://relativeurl.com" });
- //Assert
- expect(store.state.applicationUser.eventBus[0].category).toBe(
- "TestCategoryOne"
- );
- expect(store.state.applicationUser.eventBus[0].subCategory).toBe(
- "TestSubCategoryOne"
- );
- expect(store.state.applicationUser.eventBus[0].eventValue).toBe(
- "TestEventValueOne"
- );
+
+ expect(response.data).toEqual({ imageUrl: "https://test.com" });
});
+
});
describe("Getters", () => {
- it("Should validate vehicle getter", () => {
+ it("Vehicle getter, should return vehicle data", () => {
// Arrange
- const vehicle = store.getters.vehicle;
-
- // Assert
- expect(typeof vehicle).toBe("object");
- });
-
- it("Should get item from bus via getter", () => {
- // Arrange
- const event = {
- category: "TestCategoryOne",
- subCategory: "TestSubCategoryOne",
- eventValue: "TestEventValueOne",
- };
+ const storeState = state;
// Act
- store.commit("addEventToBus", event);
+ mutations.updateYear(storeState, "2019");
+ mutations.updateMake(storeState, "Acura");
+ mutations.updateModel(storeState, "ILX");
// Assert
- const returnedEventValue = store.getters.eventBusItem(
- event.category,
- event.subCategory
- );
- expect(returnedEventValue).toBe("TestEventValueOne");
+ expect(getters.vehicle(storeState).year).toEqual("2019");
+ expect(getters.vehicle(storeState).make).toEqual("Acura");
+ expect(getters.vehicle(storeState).model).toEqual("ILX");
+
});
- it("Should get eventbus from getter, should have length > 0", () => {
+ it("Get event bus item by event category and eventSubCategory", () => {
// Arrange
- const event = {
- category: "TestCategoryOne",
- subCategory: "TestSubCategoryOne",
- eventValue: "TestEventValueOne",
- };
+ const storeState = state;
+ const event = { category: "CategoryOne", subCategory: "SubCategoryOne", eventValue: "EventValueOne" };
// Act
- store.commit("addEventToBus", event);
+ mutations.addEventToBus(storeState, event);
+
+ // Assert
+ //expect(storeState.applicationUser.eventBus).toEqual([event]);
+ expect(getters.eventBusItem(storeState)(event.category, event.subCategory)).toEqual(event.eventValue);
- //Assert
- expect(store.getters.eventBus.length).toBeGreaterThan(0);
});
-});
+
+ it("Get event bus", () => {
+ // Arrange
+ const storeState = state;
+ storeState.applicationUser.eventBus = [];
+
+ const event = { category: "CategoryOne", subCategory: "SubCategoryOne", eventValue: "EventValueOne" };
+
+ // Act
+ mutations.addEventToBus(storeState, event);
+
+ // Assert
+ expect(getters.eventBus(storeState)).toEqual([event]);
+
+ });
+
+});
\ No newline at end of file
diff --git a/src/ux-components/button-main/button-main.vue b/src/ux-components/button-main/button-main.vue
index ff2a5f83a..c8888c310 100644
--- a/src/ux-components/button-main/button-main.vue
+++ b/src/ux-components/button-main/button-main.vue
@@ -1,11 +1,5 @@
-