-
-
{{ questionText }}
+
+
+ {{ questionText }}
@@ -1136,6 +1144,7 @@
import textLink from "@/ux-components/text-link/text-link";
import textboxQuestion from "@/common-components/textbox-question/textbox-question";
import dropdownQuestion from "@/common-components/dropdown-question/dropdown-question";
+ import vinInformation from "@/common-components/vin-information/vin-information";
export default {
name: "App",
components: {
@@ -1150,6 +1159,7 @@
textLink,
textboxQuestion,
dropdownQuestion,
+ vinInformation,
},
data() {
return {
diff --git a/src/layouts/form-test/form-test.vue b/src/layouts/form-test/form-test.vue
index f12abb261..774d863a8 100644
--- a/src/layouts/form-test/form-test.vue
+++ b/src/layouts/form-test/form-test.vue
@@ -144,7 +144,7 @@ export default {
},
resetDependentState() {
// Invokes
- store.dispatch(storeActions.RESET_PARTS_AND_DEPS);
+ store.dispatch(storeActions.RESET_PARTS_STATE);
},
onSubmit(values) {
window.alert('Success! Submitted values: ' + JSON.stringify(values, null ,2))
diff --git a/src/layouts/nested-radio-poc/nested-radio.vue b/src/layouts/nested-radio-poc/nested-radio.vue
index 3bdeba866..d0a78d085 100644
--- a/src/layouts/nested-radio-poc/nested-radio.vue
+++ b/src/layouts/nested-radio-poc/nested-radio.vue
@@ -1,20 +1,18 @@
-
-
Ok, select the features
-
@@ -66,10 +64,11 @@ export default {
.nested-radio {
.ui-radio {
flex-direction: column;
- margin: .25rem 0;
+ margin: 0.25rem 0;
}
+
p {
- font-size: .875rem;
+ font-size: 0.875rem;
}
}
diff --git a/src/layouts/part-questions/part-questions.vue b/src/layouts/part-questions/part-questions.vue
new file mode 100644
index 000000000..75cf54527
--- /dev/null
+++ b/src/layouts/part-questions/part-questions.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+
Part Questions Page Placeholder
+
+
+
+
+
diff --git a/src/layouts/reveal/reveal.vue b/src/layouts/reveal/reveal.vue
new file mode 100644
index 000000000..18f0e499d
--- /dev/null
+++ b/src/layouts/reveal/reveal.vue
@@ -0,0 +1,71 @@
+
+
+
+
Reveal Confetti Page Placeholder
+
+
+
+
+
diff --git a/src/layouts/vehicle-damage/damage-location-question/damage-location-question.spec.js b/src/layouts/vehicle-damage/damage-location-question/damage-location-question.spec.js
index 92feec9b8..20c016a12 100644
--- a/src/layouts/vehicle-damage/damage-location-question/damage-location-question.spec.js
+++ b/src/layouts/vehicle-damage/damage-location-question/damage-location-question.spec.js
@@ -2,82 +2,81 @@ import { shallowMount } from "@vue/test-utils";
import damageLocationQuestion from "@/layouts/vehicle-damage/damage-location-question/damage-location-question";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import store from "@/store";
-jest.mock("@/store", () => { return {}; }, {virtual: true});
+jest.mock("@/store", () => { return {}; }, { virtual: true });
describe("damage-location-question.vue", () => {
- test("Selected location option is emitted upon selection.", async () => {
-
- //Arrange
- const { wrapper } = setupMocks({ modelValueProp: ["Windshield"] });
- const locationToSelect = ["Backseat"];
-
- //Act
- wrapper.setValue({ modelValue: locationToSelect });
- await wrapper.vm.$nextTick();
-
- //Assert
- expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{modelValue: ["Backseat"]}]);
- });
+ test("Selected location option is emitted upon selection.", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({ modelValueProp: ["Windshield"] });
+ const locationToSelect = ["Backseat"];
+
+ //Act
+ wrapper.setValue({ modelValue: locationToSelect });
+ await wrapper.vm.$nextTick();
+
+ //Assert
+ expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ modelValue: ["Backseat"] }]);
});
- describe("damage-location-question.vue", () => {
- test("Answers to display filtered by data from api.", async () => {
-
- //Arrange
- const { wrapper, cmsContent, damageOptions } = setupMocks({ dataFromStoreApi: {
- driverSideOptions: {
- availableReplacementOptions: ['Quarter', 'Front']
- },
- windshieldOptions: {
- availableReplacementOptions: ['Single']
- },
- backGlassOptions: {
- availableReplacementOptions: []
- }
- }
- });
-
- //Act
- damageLocationQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, damageOptions, "car-group");
-
- //Assert
- expect(wrapper.vm.answersToDisplay).toStrictEqual([ { Name: 'Windshield' }, { Name: 'SideDoor' } ])
+ test("Answers to display filtered by data from api.", async () => {
+
+ //Arrange
+ const { wrapper, cmsContent, damageOptions } = setupMocks({
+ dataFromStoreApi: {
+ driverSideOptions: {
+ availableReplacementOptions: ['Quarter', 'Front']
+ },
+ windshieldOptions: {
+ availableReplacementOptions: ['Single']
+ },
+ backGlassOptions: {
+ availableReplacementOptions: []
+ }
+ }
});
+
+ //Act
+ damageLocationQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, damageOptions, "car-group");
+
+ //Assert
+ expect(wrapper.vm.answersToDisplay).toStrictEqual([{ Name: 'Windshield' }, { Name: 'SideDoor' }])
+ });
+});
+
+function setupMocks({
+ modelValueProp = ["Windshield", "SideDoor"],
+ isMultiSelect = false,
+ groupName = "damageQuestion",
+ cmsQuestionText = "CMS text goes here",
+ cmsAnswers = [{ Name: "car-Windshield" }, { Name: "car-SideDoor" }, { Name: "car-RearWindow" }],
+ dataFromStoreApi = [],
+}) {
+
+ //Mock store
+ store.dispatch = jest.fn(() => dataFromStoreApi);
+ store.getters = { vehicle: { year: 2019, make: 'honda', model: 'civc', style: '2 Door', category: 'CAR' } };
+ const mountOptions = getMountOptions({
+ store: {
+ dispatch: store.dispatch,
+ getters: store.getters,
+ },
});
- function setupMocks({
- modelValueProp = ["Windshield", "SideDoor"],
- isMultiSelect = false,
- groupName = "damageQuestion",
- cmsQuestionText = "CMS text goes here",
- cmsAnswers = [{Name: "car-Windshield"}, {Name: "car-SideDoor"}, {Name: "car-RearWindow"}],
- dataFromStoreApi = [],
- }) {
-
- //Mock store
- store.dispatch = jest.fn(() => dataFromStoreApi);
- store.getters = { vehicle: {year: 2019, make: 'honda', model: 'civc', style: '2 Door', category: 'CAR'} };
- const mountOptions = getMountOptions({
- store: {
- dispatch: store.dispatch,
- getters: store.getters,
- },
- });
-
- //Mock props
- mountOptions.propsData = {
- modelValue: modelValueProp,
- isMultiSelect: isMultiSelect,
- };
-
- const wrapper = shallowMount(damageLocationQuestion, mountOptions);
-
- //Mock CMS content
- const cmsContent = {
- groupName: groupName,
- QuestionText: cmsQuestionText,
- Answers: cmsAnswers,
- };
- const damageOptions = dataFromStoreApi;
- return { wrapper, cmsContent, damageOptions };
- }
\ No newline at end of file
+ //Mock props
+ mountOptions.propsData = {
+ modelValue: modelValueProp,
+ isMultiSelect: isMultiSelect,
+ };
+
+ const wrapper = shallowMount(damageLocationQuestion, mountOptions);
+
+ //Mock CMS content
+ const cmsContent = {
+ groupName: groupName,
+ QuestionText: cmsQuestionText,
+ Answers: cmsAnswers,
+ };
+ const damageOptions = dataFromStoreApi;
+ return { wrapper, cmsContent, damageOptions };
+}
\ No newline at end of file
diff --git a/src/layouts/vehicle-damage/replace-options-question/replace-options-question.vue b/src/layouts/vehicle-damage/replace-options-question/replace-options-question.vue
index 978cf6b41..25eca62da 100644
--- a/src/layouts/vehicle-damage/replace-options-question/replace-options-question.vue
+++ b/src/layouts/vehicle-damage/replace-options-question/replace-options-question.vue
@@ -52,7 +52,7 @@ export default ({
},
updateSelectedValues() {
// UPDATE SELECTEDVALUES IF ONLY ONE ANSWER
- if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1 && this.selectedValues) {
+ if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1) {
this.selectedValues = [this.answersToDisplay[0].Name];
}
},
diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js
index 519d33457..3b5913e56 100644
--- a/src/layouts/vehicle-damage/vehicle-damage.spec.js
+++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js
@@ -17,6 +17,7 @@ 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 { storeMutations } from "@/constants/store-mutations";
import store from "@/store";
// Mock our module for promises.
@@ -145,28 +146,6 @@ 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)
-
- });
-});
-
describe("vehicle-damage.vue", () => {
test("BackButtonAction triggers a router.navigate change", async () => {
@@ -189,6 +168,303 @@ describe("vehicle-damage.vue", () => {
});
});
+describe("vehicle-damage.vue", () => {
+ test("Replace several pieces of glass on ForwardButtonAction triggers a router.navigateAfterSave and saves selections to store", async () => {
+ //Arrange
+ const partsData = {
+ partsOrQuestions: [{
+ glassName: "Single",
+ glassLocation: "Windshield",
+ parts: null,
+ partQuestions: [{
+ questionSequence: 1,
+ questionText: "Is your vehicle equipped with a heated steering wheel?",
+ answers: [{
+ answerText: "Yes",
+ nextQuestionSequence: null,
+ answerResult: "FW04957"
+ },
+ {
+ answerText: "No",
+ nextQuestionSequence: 2,
+ answerResult: ""
+ }]
+ },
+ {
+ questionSequence: 2,
+ questionText: "Is your vehicle equipped with a remote start?",
+ answers: [{
+ answerText: "Yes",
+ nextQuestionSequence: null,
+ answerResult: "FW04181"
+ },
+ {
+ answerText: "No",
+ nextQuestionSequence: null,
+ answerResult: "FW04179"
+ }]
+ }]
+ }]
+ };
+
+ const { wrapper } = setupMocks({
+ pageHeaderWidgetHeaderText: "",
+ mountOptionsMockData: {
+ router: { navigateAfterSave: jest.fn(), },
+ actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },],
+ },
+ });
+
+ wrapper.vm.selectedDamageLocations = ["Windshield", "SideDoor", "RearWindow"];
+ wrapper.vm.selectedWindshieldOptions = {
+ selectedWindshieldChipCount : null,
+ selectedWindshieldReplaceOptions : ["Single"],
+ selectedWindshieldDamageType: ["Replace"]
+ };
+
+ wrapper.vm.sideDoorOptionsData = {
+ selectedDoorSides: ["DriverSide", "PassengerSide"],
+ selectedDriverSideReplaceOptions: ["Back"],
+ selectedPassengerSideReplaceOptions: ["Quarter"]
+ };
+
+ wrapper.vm.selectedRearReplaceOptions = ["Stationary"];
+
+ const expectedGlassToReplace = [{location: "Windshield", name: "Single"}, {location: "Driver", name: "Back"},
+ {location: "Passenger", name: "Quarter"}, {location: "Rear", name: "Stationary"}];
+
+ //Act
+ vehicleDamage.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-damage" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ await wrapper.vm.forwardButtonAction();
+
+ //Assert
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled();
+ expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_IS_REPAIR, false);
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_GLASS_TO_REPLACE, expectedGlassToReplace);
+ });
+});
+
+describe("vehicle-damage.vue", () => {
+ test("Windshield replace with single part on ForwardButtonAction triggers a router.navigateAfterSave and saves selections to store", async () => {
+ //Arrange
+ const partsData = { partsOrQuestions: [
+ {
+ glassLocation: "Windshield",
+ glassName: "Single",
+ partQuestions: null,
+ parts: [
+ {
+ color: "Green Tint, Green Shade",
+ description: "rain sensor, solar",
+ partNumber: "FW02728GGYN",
+ requiresCapabilityQuestions: false,
+ requiresRecalibration: false
+ }
+ ]}]};
+
+ const { wrapper } = setupMocks({
+ pageHeaderWidgetHeaderText: "",
+ mountOptionsMockData: {
+ router: { navigateAfterSave: jest.fn(), },
+ actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },],},
+ });
+
+ wrapper.vm.selectedDamageLocations = ["Windshield"];
+ wrapper.vm.selectedWindshieldOptions = {
+ selectedWindshieldChipCount : null,
+ selectedWindshieldReplaceOptions : ["Single"],
+ selectedWindshieldDamageType: ["Replace"]
+ };
+
+ const expectedGlassToReplace = [{location: "Windshield", name: "Single"},];
+
+ //Act
+ vehicleDamage.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-damage" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ await wrapper.vm.forwardButtonAction();
+
+ //Assert
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled();
+ expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_IS_REPAIR, false);
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_GLASS_TO_REPLACE, expectedGlassToReplace);
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_PARTS, partsData.partsOrQuestions[0].parts);
+ });
+});
+
+describe("vehicle-damage.vue", () => {
+ test("Windshield replace with multiple parts on ForwardButtonAction triggers a router.navigateAfterSave and saves selections to store", async () => {
+ //Arrange
+ const partsData = { partsOrQuestions: [
+ {
+ glassLocation: "Windshield",
+ glassName: "Single",
+ partQuestions: null,
+ parts: [
+ {
+ color: "Green Tint, Green Shade",
+ description: "rain sensor, solar",
+ partNumber: "FW02728GGYN",
+ requiresCapabilityQuestions: false,
+ requiresRecalibration: false
+ },
+ {
+ color: "Green Tint, Green Shade",
+ description: "rain sensor, solar, hydrophobic coating",
+ partNumber: "FW02760GGYN",
+ requiresCapabilityQuestions: false,
+ requiresRecalibration: false
+ }
+ ]},
+ {
+ glassName: "Stationary",
+ glassLocation: "Rear",
+ parts: [
+ {
+ partNumber: "DB09626GTYN",
+ description: "heated glass, solar, antenna",
+ color: "Green Tint",
+ requiresRecalibration: false,
+ requiresCapabilityQuestions: false,
+ childParts: null
+ },
+ {
+ partNumber: "DB09821GTYN",
+ description: "heated glass, solar, antenna, onstar",
+ color: "Green Tint",
+ requiresRecalibration: false,
+ requiresCapabilityQuestions: false,
+ childParts: null
+ }
+ ],
+ "partQuestions": null
+ }
+ ]};
+
+ const { wrapper } = setupMocks({
+ pageHeaderWidgetHeaderText: "",
+ mountOptionsMockData: {
+ router: { navigateAfterSave: jest.fn(), },
+ actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },],},
+ });
+
+ wrapper.vm.selectedDamageLocations = ["Windshield"];
+ wrapper.vm.selectedWindshieldOptions = {
+ selectedWindshieldChipCount : null,
+ selectedWindshieldReplaceOptions : ["Single"],
+ selectedWindshieldDamageType: ["Replace"]
+ };
+
+ const expectedGlassToReplace = [{location: "Windshield", name: "Single"},];
+
+ //Act
+ vehicleDamage.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-damage" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ await wrapper.vm.forwardButtonAction();
+
+ //Assert
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled();
+ expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_IS_REPAIR, false);
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_GLASS_TO_REPLACE, expectedGlassToReplace);
+ });
+});
+
+
+describe("vehicle-damage.vue", () => {
+ test("Windshield repair on ForwardButtonAction triggers a router.navigateAfterSave and saves selection to store", async () => {
+ //Arrange
+ const partsData = { partsOrQuestions: []};
+ const { wrapper } = setupMocks({
+ pageHeaderWidgetHeaderText: "",
+ mountOptionsMockData: {
+ router: { navigateAfterSave: jest.fn(), },
+ actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },],},
+ });
+
+ wrapper.vm.selectedDamageLocations = ["Windshield"];
+ wrapper.vm.selectedWindshieldOptions = {
+ selectedWindshieldChipCount : [2],
+ selectedWindshieldDamageType: ["Repair"]
+ };
+
+ //Act
+ vehicleDamage.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-damage" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ await wrapper.vm.forwardButtonAction();
+
+ //Assert
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled();
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_IS_REPAIR, true);
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_NUMBER_OF_CHIPS, 2);
+ });
+});
+
+describe("vehicle-damage.vue", () => {
+ test("isWindshieldDamageLocation is true when windshield is selected", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ vehicleDamage.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-damage" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ wrapper.vm.selectedDamageLocations = ["Windshield"];
+
+ //Assert
+ expect(wrapper.vm.isWindshieldDamageLocation).toEqual(true);
+ });
+});
+
+describe("vehicle-damage.vue", () => {
+ test("isSideDoorDamageLocation is true Side door is selected", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ vehicleDamage.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-damage" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ wrapper.vm.selectedDamageLocations = ["Sidedoor"];
+
+ //Assert
+ expect(wrapper.vm.isSideDoorDamageLocation).toEqual(true);
+ });
+});
+
+
describe("vehicle-damage.vue", () => {
test("isRearWindowDamageLocation is true if Rear Window damage is selected", async () => {
@@ -207,6 +483,115 @@ describe("vehicle-damage.vue", () => {
//Assert
expect(wrapper.vm.isRearWindowDamageLocation).toEqual(true);
+ });
+});
+
+describe("vehicle-damage.vue", () => {
+ test("isWindshieldRepair is true if windshield repair is selected", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ vehicleDamage.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-damage" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ wrapper.vm.selectedDamageLocations = ["Windshield"];
+ wrapper.vm.selectedWindshieldOptions = { selectedWindshieldDamageType: ["Repair"]};
+
+ //Assert
+ expect(wrapper.vm.isWindshieldRepair).toEqual(true);
+ });
+});
+
+describe("vehicle-damage.vue", () => {
+ test("isWindshieldRepair is false if windshield damage is not selected", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ vehicleDamage.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-damage" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ wrapper.vm.selectedDamageLocations = ["SideDoor"];
+ wrapper.vm.selectedWindshieldOptions = { selectedWindshieldDamageType: ["Repair"]};
+
+ //Assert
+ expect(wrapper.vm.isWindshieldRepair).toEqual(false);
+ });
+});
+
+describe("vehicle-damage.vue", () => {
+ test("isDriverSideReplace is true if side door driver is selected", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ vehicleDamage.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-damage" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ wrapper.vm.selectedDamageLocations = ["Sidedoor"];
+ wrapper.vm.sideDoorOptionsData = { selectedDoorSides: ["DriverSide"]};
+
+ //Assert
+ expect(wrapper.vm.isDriverSideReplace).toEqual(true);
+ });
+});
+
+describe("vehicle-damage.vue", () => {
+ test("isPassengerSideReplace is true if side door passenger selected", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({});
+
+ //Act
+ vehicleDamage.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-damage" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ wrapper.vm.selectedDamageLocations = ["Sidedoor"];
+ wrapper.vm.sideDoorOptionsData = { selectedDoorSides: ["PassengerSide"]};
+
+ //Assert
+ expect(wrapper.vm.isPassengerSideReplace).toEqual(true);
+ });
+});
+
+describe("vehicle-damage.vue", () => {
+ test("Call invalidation, ResetPartsAndState 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_STATE)
});
});
@@ -300,14 +685,14 @@ function setupMocks({
const sideDoorOptionsWrapper = wrapper.findComponent({ name: "sideDoorOptions" });
sideDoorOptionsWrapper.vm.initializeComponent =
- sideDoorOptions.methods.initializeComponent;
+ sideDoorOptions.methods.initializeComponent;
const windshieldOptionsWrapper = wrapper.findComponent({
name: "windshieldOptions",
});
-
+
windshieldOptionsWrapper.vm.initializeComponent =
- windshieldOptions.methods.initializeComponent;
+ windshieldOptions.methods.initializeComponent;
const funnelSubHeaderWrapper = wrapper.findComponent({
name: "funnelSubHeader",
@@ -319,13 +704,13 @@ function setupMocks({
name: "replaceOptionsQuestion",
});
backGlassOptionsWrapper.vm.initializeComponent =
- replaceOptionsQuestion.methods.initializeComponent;
+ replaceOptionsQuestion.methods.initializeComponent;
const damageLocationQuestionWrapper = wrapper.findComponent({
name: "damageLocationQuestion",
});
damageLocationQuestionWrapper.vm.initializeComponent =
- damageLocationQuestion.methods.initializeComponent;
+ damageLocationQuestion.methods.initializeComponent;
const funnelFooterWrapper = wrapper.findComponent({
name: "funnelFooter",
diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue
index aa888e14a..5a9eca92f 100644
--- a/src/layouts/vehicle-damage/vehicle-damage.vue
+++ b/src/layouts/vehicle-damage/vehicle-damage.vue
@@ -25,7 +25,7 @@
v-model="selectedRearReplaceOptions"
groupName="BackGlassReplaceOptionsQuestion"
/>
-
+
@@ -46,6 +46,8 @@ import { settleAllPromises } from "@/helpers/layout-helper";
import { storeActions } from "@/constants/store-actions";
import store from "@/store";
import baseMixin from "@/mixins/base-mixin";
+import { damageLocationsParts } from "@/constants/damage-locations-parts.js";
+import { damageLocationsCms } from "@/constants/damage-locations-cms.js";
export default {
@@ -102,14 +104,6 @@ export default {
);
});
},
- computed: {
- isRearWindowDamageLocation() {
- return this.selectedDamageLocations.some(selectedDamages =>
- {
- return selectedDamages.toUpperCase() === "REARWINDOW";
- });
- },
- },
data(){
return {
selectedDamageLocations: [],
@@ -127,8 +121,7 @@ export default {
return store.getters.vehicle.carId !== null;
},
resetDependentState() {
- // Invokes
- store.dispatch(storeActions.RESET_PARTS_AND_DEPS);
+ store.dispatch(storeActions.RESET_PARTS_STATE);
},
backButtonAction() {
// route to move backwards
@@ -137,7 +130,126 @@ export default {
this.$route
);
},
+
+ async forwardButtonAction() {
+ var windshieldChipCount = this.selectedWindshieldOptions.selectedWindshieldChipCount && this.isWindshieldDamageLocation ?
+ this.selectedWindshieldOptions.selectedWindshieldChipCount[0] : null;
+
+ store.commit(this.storeMutations.UPDATE_IS_REPAIR, this.isWindshieldRepair);
+
+ if (windshieldChipCount){
+ store.commit(this.storeMutations.UPDATE_NUMBER_OF_CHIPS, parseInt(windshieldChipCount));
+ }
+
+ store.commit(this.storeMutations.UPDATE_GLASS_TO_REPLACE, this.selectedGlassToReplace());
+
+ var partsData = await baseMixin.methods.dispatchNonBlockingStoreAction(this.storeActions.GET_PARTS_OR_QUESTIONS,
+ { carId: store.getters.vehicle.carId, glassArray: this.selectedGlassToReplace()}, false);
+
+ this.navigateForward(partsData);
+ },
+
+ navigateForward(partsData){
+ //found problem questions
+ if (partsData.data.partsOrQuestions.some(pq => pq.partQuestions != null && pq.partQuestions.length > 0)){
+ this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_DAMAGE_WITH_PART_QUESTIONS, this.$route, {}, {}, partsData.data);
+ return;
+ }
+
+ //found multiple parts for a single glass location (Windshield, Driver, Passenger, Rear)
+ if (partsData.data.partsOrQuestions){
+ var multiParts = false;
+ partsData.data.partsOrQuestions.forEach(pq => {
+ if (pq.parts != null && pq.parts.length > 1){
+ this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_DAMAGE_WITH_MULTIPLE_PARTS, this.$route, {}, {}, partsData.data);
+ multiParts = true;
+ }
+ });
+ if (multiParts) return;
+ }
+
+ //if not a repair then there should only be 1 part and no problem questions at this point so save the part to the store.
+ if (!this.isWindshieldRepair){
+ store.commit(this.storeMutations.UPDATE_PARTS, partsData.data.partsOrQuestions[0].parts);
+ }
+
+ this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_DAMAGE_WITH_SINGLE_PART, this.$route);
+ },
+
+ selectedGlassToReplace() {
+ var selectedGlassToReplace = [];
+ if (this.isWindshieldDamageLocation && !this.isWindshieldRepair){
+ this.selectedWindshieldOptions.selectedWindshieldReplaceOptions.forEach(wsItem => {
+ selectedGlassToReplace.push({ location: damageLocationsParts.WINDSHIELD, name: wsItem});
+ })
+ }
+
+ if (this.isDriverSideReplace){
+ this.sideDoorOptionsData.selectedDriverSideReplaceOptions.forEach(driverItem => {
+ selectedGlassToReplace.push({ location: damageLocationsParts.DRIVER, name: driverItem});
+ })
+ }
+
+ if (this.isPassengerSideReplace){
+ this.sideDoorOptionsData.selectedPassengerSideReplaceOptions.forEach(passengerItem => {
+ selectedGlassToReplace.push({ location: damageLocationsParts.PASSENGER, name: passengerItem});
+ })
+ }
+
+ if (this.isRearWindowDamageLocation) {
+ this.selectedRearReplaceOptions.forEach(rearItem => {
+ selectedGlassToReplace.push({ location: damageLocationsParts.REAR, name: rearItem});
+ })
+ }
+
+ return selectedGlassToReplace;
+ },
},
+ computed:{
+ isWindshieldDamageLocation() {
+ return this.selectedDamageLocations.some(selectedDamages =>
+ {
+ return selectedDamages.toUpperCase() === damageLocationsCms.WINDSHIELD;
+ });
+ },
+ isSideDoorDamageLocation() {
+ return this.selectedDamageLocations.some(selectedDamages =>
+ {
+ return selectedDamages.toUpperCase() === damageLocationsCms.SIDEDOOR;
+ });
+ },
+ isRearWindowDamageLocation() {
+ return this.selectedDamageLocations.some(selectedDamages =>
+ {
+ return selectedDamages.toUpperCase() === damageLocationsCms.REARWINDOW;
+ });
+ },
+ isWindshieldRepair() {
+ if (!this.isWindshieldDamageLocation) return false;
+
+ return this.selectedWindshieldOptions.selectedWindshieldDamageType.some(selectedDamageType =>
+ {
+ return selectedDamageType.toUpperCase() === "REPAIR";
+ });
+ },
+ isDriverSideReplace() {
+ if (!this.isSideDoorDamageLocation) return false;
+
+ return this.sideDoorOptionsData.selectedDoorSides.some(selectedDriverSide =>
+ {
+ return selectedDriverSide.toUpperCase() === damageLocationsCms.DRIVERSIDE;
+ });
+ },
+ isPassengerSideReplace() {
+ if (!this.isSideDoorDamageLocation) return false;
+
+ return this.sideDoorOptionsData.selectedDoorSides.some(selectedPassengerSide =>
+ {
+ return selectedPassengerSide.toUpperCase() === damageLocationsCms.PASSENGERSIDE;
+ });
+ }
+ },
+
components: {
funnelHeader,
funnelFooter,
diff --git a/src/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question.vue b/src/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question.vue
index 347ee2fdf..3226d9656 100644
--- a/src/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question.vue
+++ b/src/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question.vue
@@ -6,6 +6,7 @@
:answers="answersFromCms"
:groupName="groupName"
buttonType="listButtonHorizontal"
+ useTextForValue
v-model="selectedChipCountValues"
/>
diff --git a/src/layouts/vehicle-make/vehicle-make.spec.js b/src/layouts/vehicle-make/vehicle-make.spec.js
index b2c4dcaf7..ab04bb1d2 100644
--- a/src/layouts/vehicle-make/vehicle-make.spec.js
+++ b/src/layouts/vehicle-make/vehicle-make.spec.js
@@ -223,8 +223,8 @@ describe("vehicle-make.vue", () => {
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)
+ expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_STATE)
+ expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_STATE)
});
});
diff --git a/src/layouts/vehicle-make/vehicle-make.vue b/src/layouts/vehicle-make/vehicle-make.vue
index c91379318..41c19a64c 100644
--- a/src/layouts/vehicle-make/vehicle-make.vue
+++ b/src/layouts/vehicle-make/vehicle-make.vue
@@ -94,8 +94,8 @@ export default {
store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
// Invokes
- store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
- store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
+ store.dispatch(storeActions.RESET_DAMAGE_STATE);
+ store.dispatch(storeActions.RESET_REGISTRATION_STATE);
},
},
diff --git a/src/layouts/vehicle-model/vehicle-model.spec.js b/src/layouts/vehicle-model/vehicle-model.spec.js
index 7f8f96eb6..4e40a89cb 100644
--- a/src/layouts/vehicle-model/vehicle-model.spec.js
+++ b/src/layouts/vehicle-model/vehicle-model.spec.js
@@ -208,8 +208,8 @@ describe("vehicle-model.vue", () => {
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)
+ expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_STATE)
+ expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_STATE)
});
});
diff --git a/src/layouts/vehicle-model/vehicle-model.vue b/src/layouts/vehicle-model/vehicle-model.vue
index 02de04c3b..f57429c8b 100644
--- a/src/layouts/vehicle-model/vehicle-model.vue
+++ b/src/layouts/vehicle-model/vehicle-model.vue
@@ -94,8 +94,8 @@ export default {
store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
// Invokes
- store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
- store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
+ store.dispatch(storeActions.RESET_DAMAGE_STATE);
+ store.dispatch(storeActions.RESET_REGISTRATION_STATE);
},
},
diff --git a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.spec.js b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.spec.js
new file mode 100644
index 000000000..ec687023c
--- /dev/null
+++ b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.spec.js
@@ -0,0 +1,122 @@
+import { shallowMount } from "@vue/test-utils";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+import glassPartQuestion from "@/layouts/vehicle-parts/glass-part-question/glass-part-question.vue";
+import store from "@/store";
+
+jest.mock("@/store", () => { return {}; }, { virtual: true });
+
+const featureListData = {
+ colorAnswersProp: [
+ { ColorAnswerText: 'Green Tint', FeatureAnswers: [{ FeatureAnswerText: "heated glass, solar, 1 hole", PartNumber: "DB12209GTYN" }] },
+ { ColorAnswerText: 'Gray Tint Privacy', FeatureAnswers: [{ FeatureAnswerText: "heated glass, solar, 1 hole", PartNumber: "DB12209YPYN" }] }
+ ],
+ glassLocationProp: "Rear",
+ glassNameProp: "Stationary",
+ modelValueProp: {}
+}
+
+describe("glass-part-question.vue", () => {
+
+ test("Part data passed in, should map data for ButtonQuestion (radio type)", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks(featureListData);
+
+ //Act
+ await wrapper.vm.$nextTick();
+
+ //Assert
+ expect(Object.keys(wrapper.vm.featureListData).length).toBe(2);
+ expect(wrapper.vm.featureListData['Green Tint'][0].Text).toBe("heated glass, solar, 1 hole");
+ expect(wrapper.vm.featureListData['Green Tint'][0].Name).toBe("DB12209GTYN");
+ expect(wrapper.vm.featureListData['Gray Tint Privacy'][0].Text).toBe("heated glass, solar, 1 hole");
+ expect(wrapper.vm.featureListData['Gray Tint Privacy'][0].Name).toBe("DB12209YPYN");
+
+ });
+
+ test("Tint mapper, should get tint image by glassLocation and tintColor", async () => {
+
+ //Arrange
+
+ const { wrapper } = setupMocks(featureListData);
+
+ //Act
+ await wrapper.vm.$nextTick();
+ const tintSourceImage = wrapper.vm.getTintSourceImage("Rear", "Green Tint");
+
+ //Assert
+ expect(tintSourceImage).toBe("Glass-NoShade-GreenTint.svg");
+
+ });
+
+
+ test("Tint mapper, should return empty string if no tint map found", async () => {
+
+ //Arrange
+
+ const { wrapper } = setupMocks(featureListData);
+
+ //Act
+ await wrapper.vm.$nextTick();
+ const tintSourceImage = wrapper.vm.getTintSourceImage("Rear", "Crazy Rainbow Tint");
+
+ //Assert
+ expect(tintSourceImage).toBe("");
+
+ });
+
+ test("Should emit updateModelValue, and have correct attributes", async () => {
+
+ //Arrange
+
+ const { wrapper } = setupMocks(featureListData);
+
+ //Act
+ await wrapper.vm.$nextTick();
+ const listCard = await wrapper.findComponent({
+ name: "listCard",
+ });
+
+ wrapper.setValue({ selectedTint: 'Green Tint' });
+
+ //Assert
+ expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ selectedTint: 'Green Tint' }]);
+ expect(listCard.attributes("buttonid")).toBe("Rear-Stationary-Green Tint");
+ expect(listCard.attributes("groupname")).toBe("Rear-Stationary");
+ expect(listCard.attributes("isradio")).toBe("true");
+ });
+
+ test("ResetTintAndPartSelections, should reset data elements ", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks(featureListData);
+
+ //Act
+ await wrapper.vm.$nextTick();
+ wrapper.setData({selectedTint: {"Rear-Stationary" : 'Green Tint' } });
+
+ expect(wrapper.vm.selectedTint).toStrictEqual({"Rear-Stationary": 'Green Tint'});
+
+ await wrapper.vm.ResetTintAndPartSelections();
+ expect(wrapper.vm.selectedTint).toStrictEqual({});
+ });
+
+});
+
+
+function setupMocks({ glassNameProp, glassLocationProp, colorAnswersProp, modelValueProp }) {
+
+ //Mock store
+ const mountOptions = getMountOptions({});
+
+ mountOptions.propsData = {
+ glassName: glassNameProp,
+ glassLocation: glassLocationProp,
+ colorAnswers: colorAnswersProp,
+ modelValue: modelValueProp
+ };
+
+ const wrapper = shallowMount(glassPartQuestion, mountOptions);
+
+ return { wrapper };
+}
\ No newline at end of file
diff --git a/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue
new file mode 100644
index 000000000..8e159aebe
--- /dev/null
+++ b/src/layouts/vehicle-parts/glass-part-question/glass-part-question.vue
@@ -0,0 +1,143 @@
+
+
+
+
{{ colorQuestionText }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/vehicle-parts/vehicle-parts.spec.js b/src/layouts/vehicle-parts/vehicle-parts.spec.js
new file mode 100644
index 000000000..5d22a458c
--- /dev/null
+++ b/src/layouts/vehicle-parts/vehicle-parts.spec.js
@@ -0,0 +1,385 @@
+// Components
+import vehicleParts from "@/layouts/vehicle-parts/vehicle-parts.vue";
+import funnelHeader from "@/common-components/funnel-header/funnel-header";
+import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
+import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
+import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
+import glassPartQuestion from "@/layouts/vehicle-parts/glass-part-question/glass-part-question";
+
+// Supporting Files
+import { settleAllPromises } from "@/helpers/layout-helper.js";
+import baseMixin from "@/mixins/base-mixin";
+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 { storeMutations } from "@/constants/store-mutations";
+import store from "@/store";
+
+// 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(),
+}));
+
+// Mock store
+jest.mock("@/store", () => { return {}; }, { virtual: true });
+
+store.getters = {
+ pageData: jest.fn(),
+ damage: {
+ isRepair: false
+ }
+};
+
+const basePartResponse = {
+ partsOrQuestions: [
+ {
+ glassName: "Stationary",
+ glassLocation: "Rear",
+ parts: [
+ {
+ partNumber: "DB12209GTYN",
+ description: "heated glass, solar, 1 hole",
+ color: "Green Tint",
+ requiresRecalibration: false,
+ requiresCapabilityQuestions: false,
+ childParts: null
+ },
+ {
+ partNumber: "DB12209YPYNOEM",
+ description: "heated glass, solar, 1 hole",
+ color: "Gray Tint Privacy",
+ requiresRecalibration: false,
+ requiresCapabilityQuestions: false,
+ childParts: null
+ }
+ ],
+ partQuestions: null
+ }
+ ]
+}
+
+
+describe("vehicle-parts.vue", () => {
+
+ test("Page header is initialized with api data", async (done) => {
+ //Arrange
+ store.getters.pageData.mockReturnValueOnce({
+ partsOrQuestions: [
+ {
+ glassName: "Stationary",
+ glassLocation: "Rear",
+ parts: [
+ {
+ partNumber: "DB12209GTYN",
+ description: "heated glass, solar, 1 hole",
+ color: "Green Tint",
+ requiresRecalibration: false,
+ requiresCapabilityQuestions: false,
+ childParts: null
+ },
+ {
+ partNumber: "DB12209YPYNOEM",
+ description: "heated glass, solar, 1 hole",
+ color: "Gray Tint Privacy",
+ requiresRecalibration: false,
+ requiresCapabilityQuestions: false,
+ childParts: null
+ }
+ ],
+ partQuestions: null
+ }
+ ]
+ });
+
+ const pageHeaderWidgetHeaderText = "Select Parts";
+ const { wrapper, apiPromise } = setupMocks(
+ {
+ pageHeaderWidgetHeaderText: pageHeaderWidgetHeaderText,
+ mountOptionsMockData: {
+ router: {
+ navigateAfterSave: jest.fn()
+ },
+ route: {
+ query: {
+ fmgPage: 'vehicle-parts',
+ }
+ },
+ store: {
+ getters: store.getters
+ },
+ }
+ });
+
+ //Act
+ vehicleParts.beforeRouteEnter.call(wrapper.vm,
+ { query: { fmgPage: "vehicle-parts" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ //Assert
+ apiPromise.finally(() => {
+ expect(funnelSubHeader.methods.initializeComponent).toHaveBeenCalledWith(pageHeaderWidgetHeaderText);
+ done();
+ });
+ });
+
+ test("Page logo image is initialized with api data", async (done) => {
+ //Arrange
+ const SiteHeaderWidget = {
+ LogoImage:
+ "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
+ };
+
+ store.getters.pageData.mockReturnValueOnce(basePartResponse);
+
+ const { wrapper, apiPromise } = setupMocks(
+ {
+ SiteHeaderWidget: SiteHeaderWidget,
+ mountOptionsMockData: {
+ router: {
+ navigateAfterSave: jest.fn()
+ },
+ route: {
+ query: {
+ fmgPage: 'vehicle-parts',
+ }
+ },
+ store: {
+ getters: store.getters
+ },
+ }
+ });
+
+ //Act
+ vehicleParts.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-parts" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ //Assert
+ apiPromise.finally(() => {
+ expect(funnelHeader.methods.initializeComponent).toHaveBeenCalledWith(SiteHeaderWidget);
+ done();
+ });
+ });
+
+ test("Vehicle image is initialized with api data", async (done) => {
+ //Arrange
+ const VehicleBannerWidget = {
+ GenericVehicleImage:
+ "https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
+ };
+
+ store.getters.pageData.mockReturnValue(basePartResponse);
+
+ const { wrapper, apiPromise } = setupMocks(
+ {
+ VehicleBannerWidget: VehicleBannerWidget,
+ mountOptionsMockData: {
+ router: {
+ navigateAfterSave: jest.fn()
+ },
+ route: {
+ query: {
+ fmgPage: 'vehicle-parts',
+ }
+ },
+ store: {
+ getters: store.getters
+ },
+ }
+ });
+
+ //Act
+ vehicleParts.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-parts" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ //Assert
+ apiPromise.finally(() => {
+ expect(vehicleBanner.methods.initializeComponent).toHaveBeenCalledWith(VehicleBannerWidget);
+ done();
+ });
+ });
+
+ test("PageData / isRepair populated in Vuex. arePagePrerequisitesValid should be true ", async () => {
+
+ //Arrange
+ store.getters.pageData.mockReturnValueOnce(basePartResponse);
+ const { wrapper } = setupMocks({
+ mountOptionsMockData: {
+ router: {
+ navigateAfterSave: jest.fn()
+ },
+ route: {
+ query: {
+ fmgPage: 'vehicle-parts',
+ }
+ },
+ store: {
+ getters: store.getters
+ },
+ }
+ });
+
+ //Act
+ vehicleParts.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-parts" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
+ await nextTick();
+
+ //Assert
+ expect(arePagePrerequisitesValid).toBe(true);
+ });
+
+ test("BackButtonAction triggers a router.navigate change", async () => {
+
+ //Arrange
+ store.getters.pageData.mockReturnValueOnce(basePartResponse);
+ const { wrapper } = setupMocks({
+ mountOptionsMockData: {
+ router: {
+ navigateAfterSave: jest.fn(),
+ navigate: jest.fn()
+ },
+ route: {
+ query: {
+ fmgPage: 'vehicle-parts',
+ }
+ },
+ store: {
+ getters: store.getters
+ },
+ }
+ });
+
+ //Act
+ vehicleParts.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-parts" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ wrapper.vm.backButtonAction();
+
+ //Assert
+ expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
+
+ });
+
+ test("ForwardButtonAction triggers a router.navigate change and saves selected parts to store", async () => {
+
+ //Arrange
+ store.getters.pageData.mockReturnValueOnce(basePartResponse);
+ store.commit = jest.fn();
+
+ const { wrapper } = setupMocks({
+ mountOptionsMockData: {
+ router: {
+ navigateAfterSave: jest.fn(),
+ navigate: jest.fn()
+ },
+ route: {
+ query: {
+ fmgPage: 'vehicle-parts',
+ }
+ },
+ store: {
+ getters: store.getters,
+ commit: store.commit
+ },
+ }
+ });
+
+ wrapper.setData({ glassParts: { "Rear-Stationary": { "Rear": ['DB12209YPYNOEM'] } } });
+
+ //Act
+ vehicleParts.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { fmgPage: "vehicle-parts" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ await wrapper.vm.forwardButtonAction();
+
+ //Assert
+ expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled();
+ // expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
+ // expect(store.commit).toBeCalledWith(storeMutations.UPDATE_IS_REPAIR, false);
+ // expect(store.commit).toBeCalledWith(storeMutations.UPDATE_GLASS_TO_REPLACE, expectedGlassToReplace);
+ });
+});
+
+function setupMocks({ pageHeaderWidgetHeaderText = {}, mountOptionsMockData = {} }) {
+ //Mock api responses
+ const apiResponses = {
+ cmsContent: {
+ FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
+ 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",
+ },
+ ColorQuestionWidget: 'Please choose your rear window tint color',
+ FeatureQuestionWidget: 'Ok no choose features',
+ AlertWidget: {
+ BodyText: 'Please choose your tint color',
+ HeadlineText: 'Just a few more steps to go',
+ }
+ }
+ };
+
+ const apiPromise = Promise.resolve(apiResponses);
+
+ settleAllPromises.mockImplementation(() => apiPromise);
+ fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
+
+ //Mock damage initialize methods
+ funnelHeader.methods = { initializeComponent: jest.fn() };
+ vehicleBanner.methods = { initializeComponent: jest.fn() };
+ funnelSubHeader.methods = { initializeComponent: jest.fn() };
+ funnelFooter.methods = { initializeComponent: jest.fn() }
+
+ const mountOptions = getMountOptions(mountOptionsMockData,);
+ const wrapper = shallowMount(vehicleParts, mountOptions);
+
+ const funnelHeaderWrapper = wrapper.findComponent({ name: "funnelHeader" });
+ funnelHeaderWrapper.vm.initializeComponent = funnelHeader.methods.initializeComponent;
+
+ const vehicleBannerWrapper = wrapper.findComponent({ name: "vehicleBanner" });
+ vehicleBannerWrapper.vm.initializeComponent = vehicleBanner.methods.initializeComponent;
+
+ const funnelSubHeaderWrapper = wrapper.findComponent({ name: "funnelSubHeader", });
+ funnelSubHeaderWrapper.vm.initializeComponent = funnelSubHeader.methods.initializeComponent;
+
+ const funnelFooterWrapper = wrapper.findComponent({ name: "funnelFooter", });
+ funnelFooterWrapper.vm.initializeComponent = funnelFooter.methods.initializeComponent;
+
+ const partQuestionRearWrapper = wrapper.findComponent({ name: "glassPartQuestion", });
+ partQuestionRearWrapper.vm.initializeComponent = glassPartQuestion.methods.initializeComponent;
+
+ return { wrapper, apiPromise };
+}
diff --git a/src/layouts/vehicle-parts/vehicle-parts.vue b/src/layouts/vehicle-parts/vehicle-parts.vue
new file mode 100644
index 000000000..aaa7f8620
--- /dev/null
+++ b/src/layouts/vehicle-parts/vehicle-parts.vue
@@ -0,0 +1,192 @@
+
+
+
+
+
diff --git a/src/layouts/vehicle-style/vehicle-style.vue b/src/layouts/vehicle-style/vehicle-style.vue
index 3009a696a..11653e25d 100644
--- a/src/layouts/vehicle-style/vehicle-style.vue
+++ b/src/layouts/vehicle-style/vehicle-style.vue
@@ -99,8 +99,8 @@ export default {
},
resetDependentState() {
// Invokes
- store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
- store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
+ store.dispatch(storeActions.RESET_DAMAGE_STATE);
+ store.dispatch(storeActions.RESET_REGISTRATION_STATE);
},
},
diff --git a/src/layouts/vehicle-year/vehicle-year.spec.js b/src/layouts/vehicle-year/vehicle-year.spec.js
index 5ef3ea404..c04d61b17 100644
--- a/src/layouts/vehicle-year/vehicle-year.spec.js
+++ b/src/layouts/vehicle-year/vehicle-year.spec.js
@@ -163,8 +163,8 @@ describe("vehicle-year.vue", () => {
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)
+ expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_STATE)
+ expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_STATE)
});
});
diff --git a/src/layouts/vehicle-year/vehicle-year.vue b/src/layouts/vehicle-year/vehicle-year.vue
index e8e69c29a..d73ac46f9 100644
--- a/src/layouts/vehicle-year/vehicle-year.vue
+++ b/src/layouts/vehicle-year/vehicle-year.vue
@@ -95,8 +95,8 @@ export default {
store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
// Invokes
- store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
- store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
+ store.dispatch(storeActions.RESET_DAMAGE_STATE);
+ store.dispatch(storeActions.RESET_REGISTRATION_STATE);
}
},
components: {
diff --git a/src/mixins/base-mixin.js b/src/mixins/base-mixin.js
index d37ba38d7..d46841b6a 100644
--- a/src/mixins/base-mixin.js
+++ b/src/mixins/base-mixin.js
@@ -18,6 +18,9 @@ export default {
return store.dispatch(type, payload);
},
+ savePageDataToStore(page, data){
+ store.commit(storeMutations.UPDATE_PAGE_DATA, { page: page, data: data });
+ }
},
computed: {
storeActions() {
diff --git a/src/mixins/base-mixin.spec.js b/src/mixins/base-mixin.spec.js
index bdc083399..da684af1b 100644
--- a/src/mixins/base-mixin.spec.js
+++ b/src/mixins/base-mixin.spec.js
@@ -26,6 +26,14 @@ describe("baseMixin.js", () => {
expect(store.dispatch).toBeCalledWith(type, payload);
});
+ test("savePageDataToStore, should call store commit", () => {
+ const mixIn = getMixInInstance({});
+
+ mixIn.methods.savePageDataToStore('vehicle-year', {});
+
+ expect(store.commit).toBeCalledWith(storeMutations.UPDATE_PAGE_DATA, { page: 'vehicle-year', data: {}});
+ });
+
test("computed: storeActions should be equal to import object", () => {
// Arrange
const mixIn = getMixInInstance({});
@@ -91,9 +99,11 @@ function getMixInInstance({ isDispatchSuccess = true }) {
// Attach mocks to mixin
const baseMixIn = baseMixin;
baseMixIn.methods.$route = route;
- store.dispatch = storeDispatch;
baseMixIn.methods.storeActions = storeActions;
baseMixIn.methods.widgetNames = widgetNames;
+ store.dispatch = storeDispatch;
+ store.commit = jest.fn();
+
return baseMixIn;
}
diff --git a/src/router/index.js b/src/router/index.js
index 337c3f766..be434e9d8 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,6 +1,7 @@
// Supporting files
import { createWebHistory, createRouter } from "vue-router";
import { storeActions } from "@/constants/store-actions";
+import baseMixin from "@/mixins/base-mixin";
import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js";
import { routingTable } from "@/router/router-constants/routing-table.js";
import { globalEvents, globalEventTypes } from "@/constants/events";
@@ -56,17 +57,20 @@ const routes = [
try {
// 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 component = router
- .getRoutes()
- .filter((x) => x.name === to.query.fmgPage)[0].components;
+ let component = router.getRoutes().filter((x) => x.name === to.query.fmgPage)[0].components;
+
+ // If the component hasn't been loaded fully, load it before we check prerequisites.
+ if (component.default.methods === undefined) {
+ component = await component.default();
+ }
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.
@@ -81,10 +85,7 @@ const routes = [
// Call the next components arePagePrerequisitesValid method before load.
// If it returns false, use the 404 logic.
- const nextComponent = await router
- .getRoutes()
- .filter((x) => x.name === routeData[0].name)[0]
- .components.default();
+ const nextComponent = await router.getRoutes().filter((x) => x.name === routeData[0].name)[0].components.default();
if (!arePagePrerequisitesValid(nextComponent)) {
await GoToFunnelStartOn404(next);
@@ -114,18 +115,18 @@ const router = createRouter({
//---------------------------------------------------------- Router Functions ----------------------------------------------------------
-router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) => {
- navigate(scenario, currentRoute, false, optionalQuery, optionalParams);
+router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) => {
+ navigate(scenario, currentRoute, false, optionalQuery, optionalParams, optionalPageData);
}
-router.navigateAfterSave = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) => {
- navigate(scenario, currentRoute, true, optionalQuery, optionalParams);
+router.navigateAfterSave = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) => {
+ navigate(scenario, currentRoute, true, optionalQuery, optionalParams, optionalPageData);
}
// PRIVATE FUNCTIONS
// Navigate to the next route, depending on the scenario.
-function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, optionalParams = {}) {
+function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) {
if (!scenario) {
console.error("No scenario provided. Please review the routing table.");
return;
@@ -144,6 +145,9 @@ function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {},
resetDependentState(currentComponent);
}
+ // Append page data to the store for the NEXT page, if any. It will be an empty object if none is provided.
+ baseMixin.methods.savePageDataToStore(matchingScenarioMap.destinationFmgPageValue, optionalPageData);
+
router.push({
name: "root",
query: Object.assign(optionalQuery, {
@@ -232,4 +236,4 @@ function resetDependentState(component) {
return component.default.methods.resetDependentState();
}
-export default router;
+export default router;
\ No newline at end of file
diff --git a/src/router/router-constants/fmgPage-values.js b/src/router/router-constants/fmgPage-values.js
index ca4338b14..7421984cb 100644
--- a/src/router/router-constants/fmgPage-values.js
+++ b/src/router/router-constants/fmgPage-values.js
@@ -5,6 +5,9 @@ const fmgPageValues = {
VEHICLE_STYLE: "vehicle-style",
VEHICLE_DAMAGE: "vehicle-damage",
ADDRESS_LOOKUP: "address-lookup",
+ VEHICLE_PARTS: "vehicle-parts",
+ PART_QUESTIONS: "part-questions",
+ REVEAL : "reveal",
};
-export { fmgPageValues };
+export { fmgPageValues };
\ No newline at end of file
diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js
index 48e36996b..9fd1c6311 100644
--- a/src/router/router-constants/navigation-scenarios.js
+++ b/src/router/router-constants/navigation-scenarios.js
@@ -4,6 +4,10 @@ const navigationScenarios = {
SELECTED_MAKE: "SELECTED_MAKE",
SELECTED_STYLE: "SELECTED_STYLE",
CLICKED_BACK: "CLICKED_BACK",
+ SELECTED_PARTS: "SELECTED_PARTS",
+ SELECTED_DAMAGE_WITH_SINGLE_PART: "SELECTED_DAMAGE_WITH_SINGLE_PART",
+ SELECTED_DAMAGE_WITH_MULTIPLE_PARTS: "SELECTED_DAMAGE_WITH_MULTIPLE_PARTS",
+ SELECTED_DAMAGE_WITH_PART_QUESTIONS: "SELECTED_DAMAGE_WITH_PART_QUESTIONS"
};
export { navigationScenarios };
diff --git a/src/router/router-constants/router-parameter-keys.js b/src/router/router-constants/router-parameter-keys.js
new file mode 100644
index 000000000..0c75eb738
--- /dev/null
+++ b/src/router/router-constants/router-parameter-keys.js
@@ -0,0 +1,3 @@
+const routerParameterKeys = { };
+
+ export { routerParameterKeys };
\ No newline at end of file
diff --git a/src/router/router-constants/routing-table.js b/src/router/router-constants/routing-table.js
index 88c47563c..3540d3bf8 100644
--- a/src/router/router-constants/routing-table.js
+++ b/src/router/router-constants/routing-table.js
@@ -57,6 +57,49 @@ const routingTable = [
scenario: navigationScenarios.CLICKED_BACK,
destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE,
},
+ {
+ scenario: navigationScenarios.SELECTED_DAMAGE_WITH_SINGLE_PART,
+ destinationFmgPageValue: fmgPageValues.REVEAL,
+ },
+ ],
+ },
+ {
+ fmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
+ maps: [
+ {
+ scenario: navigationScenarios.CLICKED_BACK,
+ destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE,
+ },
+ {
+ scenario: navigationScenarios.SELECTED_DAMAGE_WITH_MULTIPLE_PARTS,
+ destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS,
+ },
+ ],
+ },
+ {
+ fmgPageValue: fmgPageValues.VEHICLE_PARTS,
+ maps: [
+ {
+ scenario: navigationScenarios.CLICKED_BACK,
+ destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
+ },
+ {
+ scenario: navigationScenarios.SELECTED_PARTS,
+ destinationFmgPageValue: fmgPageValues.QUOTE,
+ },
+ ],
+ },
+ {
+ fmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
+ maps: [
+ {
+ scenario: navigationScenarios.CLICKED_BACK,
+ destinationFmgPageValue: fmgPageValues.VEHICLE_STYLE,
+ },
+ {
+ scenario: navigationScenarios.SELECTED_DAMAGE_WITH_PART_QUESTIONS,
+ destinationFmgPageValue: fmgPageValues.PART_QUESTIONS,
+ },
],
},
];
diff --git a/src/store/index.js b/src/store/index.js
index c7227de47..41daf3955 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -25,9 +25,14 @@ export const state = {
numberOfChips: null,
glassToReplace: null,
},
+ lineItems:{
+ glassParts: null,
+ otherParts: null
+ }
},
applicationUser: {
eventBus: [],
+ pageData: {}
},
}
@@ -61,6 +66,21 @@ export const mutations = {
updateVehicleImageColor(state, imageColor) {
state.order.vehicle.imageColor = imageColor;
},
+ updateIsRepair(state, isRepair){
+ state.order.damage.isRepair = isRepair;
+ },
+ updateNumberOfChips(state, numberOfChips){
+ state.order.damage.numberOfChips = numberOfChips;
+ },
+ updateGlassToReplace(state, glassToReplace){
+ state.order.damage.glassToReplace = glassToReplace;
+ },
+ updateParts(state, partsData){
+ state.order.lineItems.glassParts = partsData;
+ },
+ updatePageData(state, pageData){
+ state.applicationUser.pageData[pageData.page] = pageData.data;
+ },
// EVENT BUS MUTATIONS
addEventToBus(state, event) {
@@ -81,7 +101,7 @@ export const mutations = {
},
// DEPENDENCY MUTATIONS
- resetVehicleAndDependencies(state) {
+ resetVehicleState(state) {
state.order.vehicle.year = null;
state.order.vehicle.make = null;
state.order.vehicle.model = null;
@@ -89,7 +109,7 @@ export const mutations = {
state.order.vehicle.carId = null;
state.order.vehicle.category = null;
},
- resetDamageAndDependencies(state) {
+ resetDamageState(state) {
state.order.damage.isRepair = null;
state.order.damage.numberOfChips = null;
state.order.damage.windshieldGlassToReplace = null;
@@ -98,11 +118,13 @@ export const mutations = {
state.order.damage.rearGlassToReplace = null;
},
- resetRegistrationAndDependencies(state) {
+ resetRegistrationState(state) {
},
- resetPartsAndDependencies(state) {
-
+ resetPartsState(state) {
+ state.glassParts = null;
+ state.childParts = null;
+ state.otherParts = null;
}
}
@@ -118,6 +140,11 @@ export const getters = {
return matchedEvent !== undefined ? matchedEvent.eventValue : undefined;
},
eventBus: (state) => state.applicationUser.eventBus,
+ damage: (state) => state.order.damage,
+ lineItems: (state) => state.order.lineItems,
+ pageData: (state) => (page) => {
+ return state.applicationUser.pageData[page];
+ }
}
// Export Actions
@@ -193,20 +220,20 @@ export const actions = {
// 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);
+ context.commit(storeMutations.RESET_VEHICLE_STATE);
+ context.commit(storeMutations.RESET_DAMAGE_STATE);
+ context.commit(storeMutations.RESET_REGISTRATION_STATE);
},
resetDamageAndDependencies(context) {
- context.commit(storeMutations.RESET_DAMAGE_AND_DEPS);
- context.commit(storeMutations.RESET_PARTS_AND_DEPS);
+ context.commit(storeMutations.RESET_DAMAGE_STATE);
+ context.commit(storeMutations.RESET_PARTS_STATE);
},
resetRegistrationAndDependencies(context) {
- context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS);
- context.commit(storeMutations.RESET_PARTS_AND_DEPS)
+ context.commit(storeMutations.RESET_REGISTRATION_STATE);
+ context.commit(storeMutations.RESET_PARTS_STATE)
},
resetPartsAndDependencies(context) {
- context.commit(storeMutations.RESET_PARTS_AND_DEPS);
+ context.commit(storeMutations.RESET_PARTS_STATE);
},
// Content API Actions
@@ -239,6 +266,20 @@ export const actions = {
payload: {},
});
},
+
+ // Parts API Actions
+ getPartsOrQuestions(context, { carId, glassArray, zipCode, vin = '' }) {
+ return globalMethods.callHttpClient({
+ method: endpoints.GetPartsOrQuestions.method,
+ endpoint: endpoints.GetPartsOrQuestions.url,
+ payload: {
+ carId: carId,
+ glass: glassArray,
+ zip: zipCode,
+ vin: vin
+ },
+ });
+ }
}
export default createStore({
@@ -252,4 +293,4 @@ export default createStore({
mutations,
getters,
actions,
-});
+});
\ No newline at end of file
diff --git a/src/store/store.spec.js b/src/store/store.spec.js
index f33595e58..ccb715e50 100644
--- a/src/store/store.spec.js
+++ b/src/store/store.spec.js
@@ -100,7 +100,7 @@ describe("Mutations", () => {
expect(storeState.applicationUser.eventBus).toEqual([{ EventOne: "ValueOne" }]);
});
- it("resetVehicleAndDependencies, should set fields to null", () => {
+ it("resetVehicleState, should set fields to null", () => {
// Arrange
const storeState = state;
@@ -120,7 +120,7 @@ describe("Mutations", () => {
expect(storeState.order.vehicle.category).toEqual("CAR");
// Act
- mutations.resetVehicleAndDependencies(storeState);
+ mutations.resetVehicleState(storeState);
// Expect
expect(storeState.order.vehicle.year).toEqual(null);
@@ -132,7 +132,7 @@ describe("Mutations", () => {
});
- it("resetDamageAndDependencies, should set fields to null", () => {
+ it("resetDamageState, should set fields to null", () => {
// Arrange
const storeState = state;
@@ -154,7 +154,7 @@ describe("Mutations", () => {
expect(storeState.order.damage.rearGlassToReplace).toEqual("Slider");
// Act
- mutations.resetDamageAndDependencies(storeState);
+ mutations.resetDamageState(storeState);
// Expect
expect(storeState.order.damage.isRepair).toEqual(null);
@@ -166,6 +166,50 @@ describe("Mutations", () => {
});
+ it("Updates number of chips in state", () => {
+ // Arrange
+ const storeState = state;
+
+ // Act
+ mutations.updateNumberOfChips(storeState, "1");
+
+ // Assert
+ expect(storeState.order.damage.numberOfChips).toEqual("1");
+ });
+
+ it("Updates glass to replace in state", () => {
+ // Arrange
+ const storeState = state;
+
+ // Act
+ mutations.updateGlassToReplace(storeState, ["Windshield"]);
+
+ // Assert
+ expect(storeState.order.damage.glassToReplace).toEqual(["Windshield"]);
+ });
+
+ it("Updates Parts in state", () => {
+ // Arrange
+ const storeState = state;
+
+ // Act
+ mutations.updateParts(storeState, { 'Windshield-Single': 'PARTNUM101'});
+
+ // Assert
+ expect(storeState.order.lineItems.glassParts).toEqual({ 'Windshield-Single': 'PARTNUM101'});
+ });
+
+ it("Updates page data in state", () => {
+ // Arrange
+ const storeState = state;
+
+ // Act
+ mutations.updatePageData(storeState, { page: 'vehicle-year', data: {} });
+
+ // Assert
+ expect(storeState.applicationUser.pageData['vehicle-year']).toEqual({});
+ });
+
});
describe("Actions", () => {
@@ -313,9 +357,9 @@ describe("Actions", () => {
// 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);
+ expect(commit).toBeCalledWith(storeMutations.RESET_VEHICLE_STATE);
+ expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_STATE);
+ expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_STATE);
});
@@ -330,8 +374,8 @@ describe("Actions", () => {
// Act
await actions.resetDamageAndDependencies(context)
- expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_AND_DEPS);
- expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS);
+ expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_STATE);
+ expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_STATE);
});
@@ -346,8 +390,8 @@ describe("Actions", () => {
// Act
await actions.resetRegistrationAndDependencies(context)
- expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_AND_DEPS);
- expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS);
+ expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_STATE);
+ expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_STATE);
});
@@ -362,7 +406,7 @@ describe("Actions", () => {
// Act
await actions.resetPartsAndDependencies(context)
- expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS);
+ expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_STATE);
});
@@ -480,4 +524,41 @@ describe("Getters", () => {
});
+ it("Damage getter, should return damage data", () => {
+ // Arrange
+ const storeState = state;
+
+ // Act
+ mutations.updateGlassToReplace(storeState, ["Rear"]);
+
+ // Assert
+ expect(getters.damage(storeState).glassToReplace).toEqual(["Rear"]);
+
+ });
+
+ it("lineItems getter, should return lineItem data", () => {
+ // Arrange
+ const storeState = state;
+
+ // Act
+ mutations.updateParts(storeState, {"Rear-Stationary": 'PART101'});
+
+ // Assert
+ expect(getters.lineItems(storeState).glassParts).toEqual({"Rear-Stationary": 'PART101'});
+
+ });
+
+
+ it("PageData getter, should return page data for specific page", () => {
+ // Arrange
+ const storeState = state;
+
+ // Act
+ mutations.updatePageData(storeState, { page: 'vehicle-year', data: {} });
+
+ // Assert
+ expect(getters.pageData(storeState)('vehicle-year')).toEqual({});
+
+ });
+
});
\ No newline at end of file
diff --git a/src/styles/common-styles.scss b/src/styles/common-styles.scss
index ae409dd36..47ea0815d 100644
--- a/src/styles/common-styles.scss
+++ b/src/styles/common-styles.scss
@@ -3,7 +3,6 @@
body {
font-size: 16px;
background-color: #fff;
-
.container-fluid {
max-width: 576px; //Remove once desktop app is complete
&.container-shadow {
@@ -14,6 +13,9 @@ body {
display: flex;
flex-direction: column;
}
+ .prevent-squish{
+ overflow-x: unset;
+ }
}
.pointer {
cursor: pointer;
diff --git a/src/ux-components/list-button-horizontal/list-button-horizontal.vue b/src/ux-components/list-button-horizontal/list-button-horizontal.vue
index 5c328bc4c..c64a2adb4 100644
--- a/src/ux-components/list-button-horizontal/list-button-horizontal.vue
+++ b/src/ux-components/list-button-horizontal/list-button-horizontal.vue
@@ -157,9 +157,11 @@ export default {
width: 100%;
color: $gray-600;
&:hover {
- box-shadow: 0 0 0 4px $blue-300;
- cursor: pointer;
- z-index: 4 !important;
+ @include media-breakpoint-up(sm) {
+ box-shadow: 0 0 0 4px $blue-300;
+ cursor: pointer;
+ z-index: 4 !important;
+ }
}
+ p {
display: none;
diff --git a/src/ux-components/list-card/list-card.spec.js b/src/ux-components/list-card/list-card.spec.js
index 2176e683d..cee720503 100644
--- a/src/ux-components/list-card/list-card.spec.js
+++ b/src/ux-components/list-card/list-card.spec.js
@@ -188,7 +188,7 @@ describe("list-card.vue", () => {
// Assert
const label = wrapper.find("label");
- expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-column", "pt-4", "pb-2"]);
+ expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-column", "pt-4", "pb-3"]);
});
it("Should emit button value on click", async () => {
@@ -204,11 +204,12 @@ describe("list-card.vue", () => {
isRequired: true,
isWide: false,
modelValue: ["List Card Checkbox"],
+ buttonID: 'list-card-id'
},
});
wrapper.vm.handleCheckChange();
// Assert
- expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{value: "List Card Checkbox", checkValue: Boolean}]);
+ expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{value: "List Card Checkbox", checkValue: Boolean, buttonId: 'list-card-id'}]);
});
it("Should set checkValue data if selectedButtonIDs has value(s)", async () => {
diff --git a/src/ux-components/list-card/list-card.vue b/src/ux-components/list-card/list-card.vue
index 526744af5..c1fc6d089 100644
--- a/src/ux-components/list-card/list-card.vue
+++ b/src/ux-components/list-card/list-card.vue
@@ -49,7 +49,6 @@