diff --git a/src/common-components/button-question/button-question.spec.js b/src/common-components/button-question/button-question.spec.js
index 4a1f42822..e59b6da39 100644
--- a/src/common-components/button-question/button-question.spec.js
+++ b/src/common-components/button-question/button-question.spec.js
@@ -19,3 +19,67 @@ describe("buttonQuestion.vue", () => {
expect(wrapper.props().modelValue).toBe("2020");
});
});
+
+describe("buttonQuestion.vue", () => {
+ it("Should show overflow classes on fieldset if isOverflowScrollable is true", async () => {
+ // Act
+ const wrapper = shallowMount(buttonQuestion);
+ await wrapper.setProps({
+ isOverflowScrollable: true,
+ });
+ // Assert
+ const fieldSet = wrapper.find('fieldset');
+ expect(fieldSet.classes()).toContain("overflow-scroll");
+ });
+});
+
+describe("buttonQuestion.vue", () => {
+ it("Should show appropriate classes for button type", async () => {
+ // Act
+ const wrapper = shallowMount(buttonQuestion);
+ await wrapper.setProps({
+ buttonType: "listCard",
+ });
+ // Assert
+ const Div = wrapper.find('fieldset div');
+ expect(Div.classes()).toContain("row");
+ });
+});
+
+describe("buttonQuestion.vue", () => {
+ it("Should trigger event modelValue change on select", async () => {
+ // Act
+ const wrapper = shallowMount(buttonQuestion);
+ await wrapper.setData({
+ modelValueAnswers: ["Windshield"],
+ chosenAnswer: "Windshield"
+ });
+ wrapper.setValue({ answer: wrapper.vm.chosenAnswer });
+ await wrapper.vm.$nextTick();
+ // Assert
+ expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{answer: "Windshield"}]);
+ });
+});
+
+describe("buttonQuestion.vue", () => {
+ it("Should trigger event modelValue change with an array of string values on select if checked is true and multiple options are chosen", async () => {
+ // Act
+ const wrapper = shallowMount(buttonQuestion);
+ await wrapper.setData({
+ modelValueAnswers: ["Windshield", "BackDoor"]
+ });
+ wrapper.vm.isItemChecked(true);
+ // Assert
+ expect(typeof wrapper.emitted()["update:modelValue"][0]).toEqual('object');
+ });
+});
+
+describe("buttonQuestion.vue", () => {
+ it("Should not trigger event modelValue change on select if checked is false", async () => {
+ // Act
+ const wrapper = shallowMount(buttonQuestion);
+ wrapper.vm.isItemChecked(false);
+ // Assert
+ expect(wrapper.emitted()["update:modelValue"][0]).toEqual([undefined]);
+ });
+});
\ No newline at end of file
diff --git a/src/common-components/button-question/button-question.vue b/src/common-components/button-question/button-question.vue
index bf52b4ac8..857e3e621 100644
--- a/src/common-components/button-question/button-question.vue
+++ b/src/common-components/button-question/button-question.vue
@@ -4,40 +4,37 @@
{{ questionText }}
-
@@ -79,7 +76,7 @@ export default {
isRequired: Boolean,
isOverflowScrollable: Boolean,
isWide: Boolean,
- modelValue: String,
+ modelValue: [Array, String],
},
computed: {
getFieldSetClasses() {
@@ -96,16 +93,34 @@ export default {
case "listButtonHorizontal":
classes = "d-flex flex-row p-0";
break;
- case "listCard":
- classes = "row g-2";
+ case 'listCard':
+ classes = 'row justify-content-center g-2'
break;
}
return classes;
},
},
+ data(){
+ return {
+ modelValueAnswers: [],
+ chosenAnswer: String
+ }
+ },
+ created(){
+ if(Array.isArray(this.answers) && this.answers.length === 1) {
+ const onlyAnswer = typeof(this.answers[0]) === 'object' ? this.answers[0].Name : this.answers[0];
+ this.$emit("update:modelValue", onlyAnswer);
+ }
+ },
methods: {
chooseAnswer(answer) {
- this.$emit("update:modelValue", answer);
+ this.chosenAnswer = answer;
+ },
+ isItemChecked(val) {
+ // Add or remove item to array of data to emit
+ val ? this.modelValueAnswers.push(this.chosenAnswer) : this.modelValueAnswers.splice(this.modelValueAnswers.indexOf(this.chosenAnswer), 1);
+
+ this.$emit("update:modelValue", this.modelValueAnswers.length ? this.modelValueAnswers : undefined);
},
},
components: {
diff --git a/src/layouts/vehicle-damage/replace-options-question/replace-options-question.spec.js b/src/layouts/vehicle-damage/replace-options-question/replace-options-question.spec.js
new file mode 100644
index 000000000..103aecd4c
--- /dev/null
+++ b/src/layouts/vehicle-damage/replace-options-question/replace-options-question.spec.js
@@ -0,0 +1,76 @@
+import { shallowMount } from "@vue/test-utils";
+import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+import store from "@/store";
+jest.mock("@/store", () => { return {}; }, {virtual: true});
+
+describe("replace-options-question.vue", () => {
+ test("Selected damage option is emitted upon selection.", async () => {
+
+ //Arrange
+ const { wrapper } = setupMocks({ modelValueProp: ["Windshield"] });
+ const damageToSelect = ["Backseat"];
+
+ //Act
+ wrapper.setValue({ modelValue: damageToSelect });
+ await wrapper.vm.$nextTick();
+
+ //Assert
+ expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{modelValue: ["Backseat"]}]);
+ });
+ });
+
+ describe("replace-options-question.vue", () => {
+ test("Answers to display filtered by data from api.", async () => {
+
+ //Arrange
+ const { wrapper, cmsContent, replaceOptions } = setupMocks({ dataFromStoreApi: ["Windshield", "FrontDoor"]});
+
+ //Act
+ replaceOptionsQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, replaceOptions, "car-group");
+
+ //Assert
+ expect(wrapper.vm.answersToDisplay).toStrictEqual([ { Name: 'car-Windshield' }, { Name: 'car-FrontDoor' } ])
+ });
+ });
+
+ function setupMocks({
+ modelValueProp = ["Windshield"],
+ isAvailale = true,
+ isMultiSelect = false,
+ filterByVehicleCategory = false,
+ groupName = "damageQuestion",
+ cmsQuestionText = "CMS text goes here",
+ cmsAnswers = [{Name: "car-Windshield"}, {Name: "car-BackDoor"}, {Name: "car-FrontDoor"}],
+ 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,
+ isAvailable: isAvailale,
+ isMultiSelect: isMultiSelect,
+ filterByVehicleCategory: filterByVehicleCategory
+ };
+
+ const wrapper = shallowMount(replaceOptionsQuestion, mountOptions);
+
+ //Mock CMS content
+ const cmsContent = {
+ groupName: groupName,
+ QuestionText: cmsQuestionText,
+ Answers: cmsAnswers,
+ };
+ const replaceOptions = dataFromStoreApi;
+ return { wrapper, cmsContent, replaceOptions };
+ }
\ 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
new file mode 100644
index 000000000..f01f0cd90
--- /dev/null
+++ b/src/layouts/vehicle-damage/replace-options-question/replace-options-question.vue
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js
index 81c7c8b7a..caf008b78 100644
--- a/src/layouts/vehicle-damage/vehicle-damage.spec.js
+++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js
@@ -3,6 +3,7 @@ import vehicleDamage from "@/layouts/vehicle-damage/vehicle-damage.vue";
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 replaceOptionsQuestion from"@/layouts/vehicle-damage/replace-options-question/replace-options-question";
// Supporting Files
import { settleAllPromises } from "@/helpers/layout-helper.js";
@@ -144,7 +145,9 @@ function setupMocks({
baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn();
baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation(() => {
return Promise.resolve({
- data: ["Front Window", "Back Window", "Side Window"],
+ driverSideOptions: {
+ availableReplacementOptions: ["Front", "Back", "Side"],
+ }
});
});
const apiResponses = {
@@ -159,7 +162,11 @@ function setupMocks({
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
},
},
- damageOptions: ["Front Window", "Back Window", "Side Window"],
+ damageOptions: {
+ driverSideOptions: {
+ availableReplacementOptions: ["Front", "Back", "Side"],
+ }
+ },
};
const apiPromise = Promise.resolve(apiResponses);
@@ -180,6 +187,11 @@ function setupMocks({
initializeComponent: jest.fn(),
};
+ const driverSideOptions = replaceOptionsQuestion
+ driverSideOptions.methods = {
+ initializeComponent: jest.fn(),
+ };
+
const mountOptions = getMountOptions(mountOptionsMockData);
const wrapper = shallowMount(vehicleDamage, mountOptions);
@@ -197,5 +209,11 @@ function setupMocks({
funnelSubHeaderWrapper.vm.initializeComponent =
funnelSubHeader.methods.initializeComponent;
+ const driverSideOptionsWrapper = wrapper.findComponent({
+ name: "replaceOptionsQuestion",
+ });
+ driverSideOptionsWrapper.vm.initializeComponent =
+ replaceOptionsQuestion.methods.initializeComponent;
+
return { wrapper, apiPromise };
}
diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue
index e18b594e0..ba46df331 100644
--- a/src/layouts/vehicle-damage/vehicle-damage.vue
+++ b/src/layouts/vehicle-damage/vehicle-damage.vue
@@ -1,9 +1,12 @@
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/layouts/vehicle-year/year-question/year-question.vue b/src/layouts/vehicle-year/year-question/year-question.vue
index 7ee281c06..3fa7de233 100644
--- a/src/layouts/vehicle-year/year-question/year-question.vue
+++ b/src/layouts/vehicle-year/year-question/year-question.vue
@@ -28,6 +28,7 @@ export default {
props: {
modelValue: String,
},
+ emits: ['update:modelValue'],
components: {
buttonQuestion,
},
diff --git a/src/router/router-constants/navigation-scenarios.js b/src/router/router-constants/navigation-scenarios.js
index 9f6fa4e92..48e36996b 100644
--- a/src/router/router-constants/navigation-scenarios.js
+++ b/src/router/router-constants/navigation-scenarios.js
@@ -3,7 +3,6 @@ const navigationScenarios = {
SELECTED_MODEL: "SELECTED_MODEL",
SELECTED_MAKE: "SELECTED_MAKE",
SELECTED_STYLE: "SELECTED_STYLE",
- VEHICLE_DAMAGE: "VEHICLE_DAMAGE",
CLICKED_BACK: "CLICKED_BACK",
};
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 c0e2bd0b8..aa574c559 100644
--- a/src/ux-components/list-button-horizontal/list-button-horizontal.vue
+++ b/src/ux-components/list-button-horizontal/list-button-horizontal.vue
@@ -1,34 +1,44 @@
-
-
-
@@ -59,6 +69,7 @@ export default {
type: String,
default: "",
},
+ modelValue: false,
},
data() {
return {
@@ -76,6 +87,11 @@ export default {
this.handleChange(value);
},
},
+ watch: {
+ modelValue(){
+ this.$emit('isChecked', this.modelValue);
+ }
+ },
components: {
loader,
},
diff --git a/src/ux-components/list-button/list-button.vue b/src/ux-components/list-button/list-button.vue
index a93b2a45a..17a1e7a8b 100644
--- a/src/ux-components/list-button/list-button.vue
+++ b/src/ux-components/list-button/list-button.vue
@@ -1,30 +1,43 @@
-