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 }}
-
- {{ groupName }} -
- -
+
+ {{groupName}} +
+ +
@@ -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 @@