diff --git a/src/App.vue b/src/App.vue index 76a01d29c..603bd2cb3 100644 --- a/src/App.vue +++ b/src/App.vue @@ -7,4 +7,5 @@ @import "@/styles/common-styles.scss"; @import "@/styles/common-typography-styles.scss"; @import "@/styles/common-error-styles.scss"; + @import "@/styles/common-animations.scss"; diff --git a/src/common-components/button-question/button-question.spec.js b/src/common-components/button-question/button-question.spec.js index 464fcf245..d36b73012 100644 --- a/src/common-components/button-question/button-question.spec.js +++ b/src/common-components/button-question/button-question.spec.js @@ -53,7 +53,7 @@ describe("buttonQuestion.vue", () => { answers: ["2022", "2021", "2020"], isMultiSelect: false }); - const val = {isChecked: true, buttonId: "2021", } + const val = {checkValue: true, value: "2021", } wrapper.vm.handleCheckedChanged(val); // Assert expect(wrapper.emitted()["update:modelValue"][0]).toEqual([["2021"]]); @@ -69,7 +69,7 @@ describe("buttonQuestion.vue", () => { isMultiSelect: true, } }); - const val = {isChecked: true, buttonId: "2019", } + const val = {checkValue: true, value: "2019", } wrapper.vm.handleCheckedChanged(val); // Assert expect(wrapper.emitted()["update:modelValue"][0]).toEqual([["2022", "2021", "2020", "2019"]]); diff --git a/src/common-components/button-question/button-question.vue b/src/common-components/button-question/button-question.vue index b8a2967b4..3ea8fd52e 100644 --- a/src/common-components/button-question/button-question.vue +++ b/src/common-components/button-question/button-question.vue @@ -12,7 +12,7 @@ v-for="answer in answers" :key="answer.Name ? answer.Name : answer" @isCheckedChanged="handleCheckedChanged" - :buttonID="answer.Name ? answer.Name : answer" + :buttonID="answer.Name ? groupName + '-' + answer.Name : groupName + '-' + answer" :value="answer.Name ? answer.Name : answer" :buttonLabel="answer.Text ? answer.Text : answer" :buttonLabelSubCopy="answer.SubText" @@ -29,7 +29,7 @@ :altText="answer.Name ? answer.Name : answer" screenReaderOnlyText="(opens new window)" :colLength="getColLength" - :selectedButtonIDs="selectedValues" + :selectedValues="selectedValues" data-test="button" :validationRules="validationRules" /> @@ -124,11 +124,13 @@ export default { handleCheckedChanged(val) { if(this.isMultiSelect && this.selectedValues) { // Add or remove item to array of data to emit - const newSelectedValues = this.selectedValues; - val.isChecked ? newSelectedValues.push(val.buttonId) : newSelectedValues.splice(newSelectedValues.indexOf(val.buttonId), 1); - this.selectedValues = newSelectedValues; + if(Array.isArray(this.selectedValues)) { + const newSelectedValues = this.selectedValues; + val.checkValue ? newSelectedValues.push(val.value) : newSelectedValues.splice(newSelectedValues.indexOf(val.value), 1); + this.selectedValues = newSelectedValues; + } } else { - this.selectedValues = [val.buttonId]; + this.selectedValues = [val.value]; } }, }, diff --git a/src/common-components/funnel-header/funnel-header.vue b/src/common-components/funnel-header/funnel-header.vue index 86cb76197..382640219 100644 --- a/src/common-components/funnel-header/funnel-header.vue +++ b/src/common-components/funnel-header/funnel-header.vue @@ -60,7 +60,7 @@ export default { diff --git a/src/layouts/vehicle-damage/side-door-options/side-door-options.spec.js b/src/layouts/vehicle-damage/side-door-options/side-door-options.spec.js new file mode 100644 index 000000000..239a54fd4 --- /dev/null +++ b/src/layouts/vehicle-damage/side-door-options/side-door-options.spec.js @@ -0,0 +1,126 @@ +import { shallowMount } from "@vue/test-utils"; +import sideDoorOptions from "@/layouts/vehicle-damage/side-door-options/side-door-options"; +import { getMountOptions } from "@/helpers/unit-test-helper.js"; +import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question"; +import store from "@/store"; +jest.mock("@/store", () => { return {}; }, {virtual: true}); + +describe("replace-options-question.vue", () => { + test("Selected side door option is emitted upon selection.", async () => { + + //Arrange + const { wrapper } = setupMocks({ modelValueProp: ["Windshield"] }); + const sideDoorOptions = ["Backseat"]; + + //Act + wrapper.setValue({ modelValue: sideDoorOptions }); + await wrapper.vm.$nextTick(); + + //Assert + expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{modelValue: ["Backseat"]}]); + }); + }); + + describe("replace-options-question.vue", () => { + test("Selected door side option is updated when selection made.", async () => { + + //Arrange + const { wrapper } = setupMocks({}); + + //Act + wrapper.vm.selectedDoorSidesValues = ["DriverSide"] + await wrapper.vm.$nextTick(); + + //Assert + expect(wrapper.emitted()["update:selectedDoorSides"][0]).toEqual([["DriverSide"]]); + }); + }); + + describe("replace-options-question.vue", () => { + test("Selected driver side option is updated when selection made.", async () => { + + //Arrange + const { wrapper } = setupMocks({}); + + //Act + wrapper.vm.selectedDriverSideReplacOptionsValues = ["FrontDoor"] + await wrapper.vm.$nextTick(); + + //Assert + expect(wrapper.emitted()["update:selectedDriverSideReplacOptions"][0]).toEqual([["FrontDoor"]]); + }); + }); + + describe("replace-options-question.vue", () => { + test("Selected passenger side option is updated when selection made.", async () => { + + //Arrange + const { wrapper } = setupMocks({}); + + //Act + wrapper.vm.selectedPassengerSideReplaceOptionsValues = ["BacktDoor"] + await wrapper.vm.$nextTick(); + + //Assert + expect(wrapper.emitted()["update:selectedPassengerSideReplaceOptions"][0]).toEqual([["BacktDoor"]]); + }); + }); + + + describe("replace-options-question.vue", () => { + test("Answers to display filtered by data from api.", async () => { + + //Arrange + const { wrapper, cmsContent, driverSideReplaceOptions, passengerSideReplaceOptions, driverSideOptions, passengerSideOptions } = setupMocks({}); + + //Act + sideDoorOptions.methods.initializeComponent.call(wrapper.vm, cmsContent, driverSideReplaceOptions, passengerSideReplaceOptions, driverSideOptions, passengerSideOptions, "car-group"); + + //Assert + expect(wrapper.vm.answersToDisplay).toStrictEqual([ { Name: 'DriverSide' }, { Name: 'PassengerSide' } ]) + }); + }); + + + function setupMocks({ + modelValueProp = ["DriverSide"], + groupName = "sideDoorOptions", + cmsQuestionText = "CMS text goes here", + cmsAnswers = [{Name: "Car-DriverSide"}, {Name: "Car-PassengerSide"}], + driverSideReplaceOptions = ["FrontDoor", "BackDoor"], + passengerSideReplaceOptions = ["FrontDoor", "BackDoor"], + driverSideOptions = ["Car-FrontDoor", "Car-BackDoor"], + passengerSideOptions = ["Car-FrontDoor", "Car-BackDoor"], + selectedDamageLocations = ["SideDoor"] + }) { + + //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, + groupName: groupName, + selectedDamageLocations: selectedDamageLocations, + }; + + const wrapper = shallowMount(sideDoorOptions, mountOptions); + + const OptionsWrapper = wrapper.findAllComponents({name: "replaceOptionsQuestion"}); + OptionsWrapper[0].vm.initializeComponent = replaceOptionsQuestion.methods.initializeComponent; + OptionsWrapper[1].vm.initializeComponent = replaceOptionsQuestion.methods.initializeComponent; + //Mock CMS content + const cmsContent = { + groupName: groupName, + QuestionText: cmsQuestionText, + Answers: cmsAnswers, + }; + return { wrapper, cmsContent, driverSideReplaceOptions, passengerSideReplaceOptions, driverSideOptions, passengerSideOptions }; + } \ No newline at end of file diff --git a/src/layouts/vehicle-damage/side-door-options/side-door-options.vue b/src/layouts/vehicle-damage/side-door-options/side-door-options.vue new file mode 100644 index 000000000..1372f23f6 --- /dev/null +++ b/src/layouts/vehicle-damage/side-door-options/side-door-options.vue @@ -0,0 +1,130 @@ + + + \ No newline at end of file diff --git a/src/layouts/vehicle-damage/vehicle-damage.spec.js b/src/layouts/vehicle-damage/vehicle-damage.spec.js index 4a26b3426..60590ba84 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.spec.js +++ b/src/layouts/vehicle-damage/vehicle-damage.spec.js @@ -4,7 +4,7 @@ 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 replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question"; +import sideDoorOptions from "@/layouts/vehicle-damage/side-door-options/side-door-options"; import damageLocationQuestion from "@/layouts/vehicle-damage/damage-location-question/damage-location-question"; import windshieldOptions from "@/layouts/vehicle-damage/windshield-options/windshield-options"; @@ -172,16 +172,6 @@ function setupMocks({ }) { //Mock api responses baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn(); - baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation(() => { - return Promise.resolve({ - driverSideOptions: { - availableReplacementOptions: ["Front", "Back", "Side"], - }, - windshieldOptions: { - availableReplacementOptions: ["Single", "Driver", "Passenger"], - }, - }); - }); const apiResponses = { cmsContent: { FunnelSubHeaderWidget: pageHeaderWidgetHeaderText, @@ -198,6 +188,9 @@ function setupMocks({ driverSideOptions: { availableReplacementOptions: ["Front", "Back", "Side"], }, + passengerSideOptions: { + availableReplacementOptions: ["Front", "Back", "Side"], + }, windshieldOptions: { availableReplacementOptions: ["Single", "Driver", "Passenger"], }, @@ -222,12 +215,11 @@ function setupMocks({ initializeComponent: jest.fn(), }; - const driverSideOptions = replaceOptionsQuestion - driverSideOptions.methods = { + damageLocationQuestion.methods = { initializeComponent: jest.fn(), }; - damageLocationQuestion.methods = { + sideDoorOptions.methods = { initializeComponent: jest.fn(), }; @@ -250,17 +242,9 @@ function setupMocks({ vehicleBannerWrapper.vm.initializeComponent = vehicleBanner.methods.initializeComponent; - const funnelSubHeaderWrapper = wrapper.findComponent({ - name: "funnelSubHeader", - }); - funnelSubHeaderWrapper.vm.initializeComponent = - funnelSubHeader.methods.initializeComponent; - - const driverSideOptionsWrapper = wrapper.findAllComponents({ - name: "replaceOptionsQuestion", - }).at(0); - driverSideOptionsWrapper.vm.initializeComponent = - replaceOptionsQuestion.methods.initializeComponent; + const sideDoorOptionsWrapper = wrapper.findComponent({ name: "sideDoorOptions" }); + sideDoorOptionsWrapper.vm.initializeComponent = + sideDoorOptions.methods.initializeComponent; const windshieldOptionsWrapper = wrapper.findComponent({ name: "windshieldOptions", @@ -269,6 +253,11 @@ function setupMocks({ windshieldOptionsWrapper.vm.initializeComponent = windshieldOptions.methods.initializeComponent; + const funnelSubHeaderWrapper = wrapper.findComponent({ + name: "funnelSubHeader", + }); + funnelSubHeaderWrapper.vm.initializeComponent = + funnelSubHeader.methods.initializeComponent; const damageLocationQuestionWrapper = wrapper.findComponent({ name: "damageLocationQuestion", diff --git a/src/layouts/vehicle-damage/vehicle-damage.vue b/src/layouts/vehicle-damage/vehicle-damage.vue index 998a43892..bce74b92f 100644 --- a/src/layouts/vehicle-damage/vehicle-damage.vue +++ b/src/layouts/vehicle-damage/vehicle-damage.vue @@ -4,12 +4,11 @@ - - + @@ -20,8 +19,8 @@ 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 replaceOptionsQuestion from"@/layouts/vehicle-damage/replace-options-question/replace-options-question"; -import damageLocationQuestion from"@/layouts/vehicle-damage/damage-location-question/damage-location-question"; +import sideDoorOptions from "@/layouts/vehicle-damage/side-door-options/side-door-options"; +import damageLocationQuestion from "@/layouts/vehicle-damage/damage-location-question/damage-location-question"; import windshieldOptions from "@/layouts/vehicle-damage/windshield-options/windshield-options"; // Supporting files @@ -68,12 +67,12 @@ export default { vm.$refs.funnelSubHeader.initializeComponent( resultMap.cmsContent.FunnelSubHeaderWidget ); - vm.$refs.driverSideOptions.initializeComponent( - resultMap.cmsContent.DriverSideReplaceOptionsQuestion, resultMap.damageOptions.driverSideOptions.availableReplacementOptions - ); vm.$refs.damageLocation.initializeComponent( resultMap.cmsContent.DamageLocationQuestion, resultMap.damageOptions ); + vm.$refs.sideDoorOptions.initializeComponent( + resultMap.cmsContent.SideDoorSideQuestion, resultMap.cmsContent.DriverSideReplaceOptionsQuestion, resultMap.cmsContent.PassengerSideReplaceOptionsQuestion, resultMap.damageOptions.driverSideOptions.availableReplacementOptions, resultMap.damageOptions.passengerSideOptions.availableReplacementOptions + ); vm.$refs.windshieldOptions.initializeComponent( resultMap.cmsContent.WindshieldDamageTypeQuestion, resultMap.cmsContent.WindshieldChipCountQuestion, resultMap.cmsContent.WindshieldReplaceOptionsQuestion, resultMap.damageOptions.windshieldOptions.availableReplacementOptions @@ -86,7 +85,11 @@ export default { data(){ return { selectedDamageLocations: [], - driverSideOptionsData: [], + sideDoorOptionsData: { + selectedDoorSides: [], + selectedDriverSideReplacOptions: [], + selectedPassengerSideReplaceOptions: [] + }, selectedWindshieldOptions: [] } }, @@ -111,7 +114,7 @@ export default { funnelFooter, vehicleBanner, funnelSubHeader, - replaceOptionsQuestion, + sideDoorOptions, damageLocationQuestion, windshieldOptions, }, 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 41a3b872b..347ee2fdf 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 @@ -1,8 +1,7 @@