Creating side-door-options component

This commit is contained in:
Max 2022-02-22 10:29:16 -05:00
parent 830c474955
commit 1dfee19cfd
8 changed files with 233 additions and 60 deletions

View file

@ -41,7 +41,7 @@ describe("damage-location-question.vue", () => {
damageLocationQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, damageOptions, "car-group");
//Assert
expect(wrapper.vm.answersToDisplay).toStrictEqual([ { Name: 'car-Windshield' }, { Name: 'car-SideDoor' } ])
expect(wrapper.vm.answersToDisplay).toStrictEqual([ { Name: 'Windshield' }, { Name: 'SideDoor' } ])
});
});

View file

@ -67,13 +67,18 @@ export default ({
}
},
answersToDisplay(){
return Array.isArray(this.answersFromCms)
const filteredAnswers = Array.isArray(this.answersFromCms)
? this.answersFromCms.filter(ans =>
{
const name = ans.Name.split('-');
return name[0].toUpperCase() === store.getters.vehicle.category && this.damageOptionsMap[name[1]];
})
: [];
return filteredAnswers.map(ans => {
const newName = ans.Name.includes('-') ? ans.Name.split('-')[1] : ans.Name;
ans.Name = newName;
return ans;
});
},
},
components: {

View file

@ -30,7 +30,7 @@ describe("replace-options-question.vue", () => {
replaceOptionsQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, replaceOptions, "car-group");
//Assert
expect(wrapper.vm.answersToDisplay).toStrictEqual([ { Name: 'car-Windshield' }, { Name: 'car-FrontDoor' } ])
expect(wrapper.vm.answersToDisplay).toStrictEqual([ { Name: 'Windshield' }, { Name: 'FrontDoor' } ])
});
});

View file

@ -1,8 +1,7 @@
<template>
<transition name="fade">
<div class="replace-options-question" :class="this.answersToDisplay.length < 2 ? 'd-none' : ''">
<transition name="fade" mode="out-in">
<div v-if="isAvailable && this.answersToDisplay.length > 0" class="replace-options-question" :class="this.answersToDisplay.length < 2 ? 'd-none' : ''">
<buttonQuestion
v-if="isAvailable"
isWide
:questionText="questionText"
isMultiSelect
@ -61,17 +60,23 @@ export default ({
}
},
answersToDisplay(){
return Array.isArray(this.answersFromCms)
const filteredAnswers = Array.isArray(this.answersFromCms)
? this.answersFromCms.filter(ans =>
{
const name = ans.Name.split('-');
return this.filterByVehicleCategory ? name[0].toUpperCase() === store.getters.vehicle.category && this.replaceOptions.includes(name[1]) : this.replaceOptions.includes(ans.Name);
})
: [];
return filteredAnswers.map(ans => {
const newName = ans.Name.includes('-') ? ans.Name.split('-')[1] : ans.Name;
ans.Name = newName;
return ans;
});
},
},
mounted(){
if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1) {
if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1 && this.selectedValues) {
const newSelectedValues = this.selectedValues;
newSelectedValues.push(this.answersToDisplay[0].Name);
this.selectedValues = newSelectedValues;
@ -86,7 +91,7 @@ export default ({
<style lang="scss" scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
transition: opacity 0.3s ease;
}
.fade-enter-from,

View file

@ -0,0 +1,124 @@
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"]
}) {
//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,
};
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 };
}

View file

@ -6,9 +6,12 @@
:answers="answersToDisplay"
:groupName="groupName"
buttonType="listCard"
v-model="selectedValues"
v-model="selectedDoorSidesValues"
/>
<replaceOptionsQuestion />
<replaceOptionsQuestion ref="driverSideOptions" :isAvailable="isDriverSideReplaceOptionsQuestionAvailable" groupName="driverSideOptions" filterByVehicleCategory v-model="selectedDriverSideReplacOptionsValues" />
<replaceOptionsQuestion ref="passengerSideOptions" :isAvailable="isPassengerSideReplaceOptionsQuestionAvailable" groupName="passengerSideOptions" filterByVehicleCategory v-model="selectedPassengerSideReplaceOptionsValues" />
</div>
</template>
@ -18,11 +21,15 @@ import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-que
import store from "@/store";
export default ({
name: "replaceOptionsQuestion",
name: "sideDoorOptions",
data(){
return {
questionText: String,
answersFromCms: Array,
selectedDoorSides: [],
// Child component data
selectedDriverSideReplacOptions: [],
selectedPassengerSideReplaceOptions: [],
}
},
props: {
@ -30,9 +37,19 @@ export default ({
modelValue: Array,
},
methods: {
initializeComponent(cmsContent){
initializeComponent(cmsContent, driverSideReplaceOptions, passengerSideReplaceOptions, driverSideOptions, passengerSideOptions){
this.questionText = cmsContent.QuestionText;
this.answersFromCms = cmsContent.Answers;
// Child Components intialize
this.$refs.driverSideOptions.initializeComponent(driverSideReplaceOptions, driverSideOptions);
this.$refs.passengerSideOptions.initializeComponent(passengerSideReplaceOptions, passengerSideOptions);
},
getSideDoorReplacementOptions(){
return {
selectedDoorSides: this.selectedDoorSides,
selectedDriverSideReplacOptions: this.selectedDriverSideReplacOptions,
selectedPassengerSideReplaceOptions: this.selectedPassengerSideReplaceOptions
}
},
},
computed: {
@ -44,15 +61,61 @@ export default ({
this.$emit("update:modelValue", newValue);
}
},
answersToDisplay(){
return Array.isArray(this.answersFromCms)
selectedDoorSidesValues: {
get: function() {
return this.selectedDoorSides;
},
set: function(newValue) {
this.$emit("update:selectedDoorSides", newValue);
this.selectedValues = this.getSideDoorReplacementOptions();
}
},
selectedDriverSideReplacOptionsValues: {
get: function() {
return this.selectedDriverSideReplacOptions;
},
set: function(newValue) {
this.$emit("update:selectedDriverSideReplacOptions", newValue);
this.selectedValues = this.getSideDoorReplacementOptions();
}
},
selectedPassengerSideReplaceOptionsValues: {
get: function() {
return this.selectedPassengerSideReplaceOptions;
},
set: function(newValue) {
this.$emit("update:selectedPassengerSideReplaceOptions", newValue);
this.selectedValues = this.getSideDoorReplacementOptions();
}
},
answersToDisplay(){
const filteredAnswers = Array.isArray(this.answersFromCms)
? this.answersFromCms.filter(ans =>
{
const name = ans.Name.split('-');
return name[0].toUpperCase() === store.getters.vehicle.category && this.replaceOptions.includes(name[1]);
return name[0].toUpperCase() === store.getters.vehicle.category;
})
: [];
return filteredAnswers.map(ans => {
const newName = ans.Name.includes('-') ? ans.Name.split('-')[1] : ans.Name;
ans.Name = newName;
return ans;
});
},
isDriverSideReplaceOptionsQuestionAvailable(){
return Array.isArray(this.selectedDoorSidesValues) && this.selectedDoorSidesValues.includes("DriverSide");
},
isPassengerSideReplaceOptionsQuestionAvailable(){
return Array.isArray(this.selectedDoorSidesValues) && this.selectedDoorSidesValues.includes("PassengerSide");
},
},
mounted() {
if(typeof(this.selectedValues) === "object"){
this.selectedDoorSides = this.selectedValues.selectedDoorSides;
this.selectedDriverSideReplacOptions = this.selectedValues.selectedDriverSideReplacOptions;
this.selectedPassengerSideReplaceOptions = this.selectedValues.selectedPassengerSideReplaceOptions;
}
},
components: {
buttonQuestion,

View file

@ -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";
// Supporting Files
@ -171,16 +171,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: ["Front", "Back", "Side"],
},
});
});
const apiResponses = {
cmsContent: {
FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
@ -197,7 +187,7 @@ function setupMocks({
driverSideOptions: {
availableReplacementOptions: ["Front", "Back", "Side"],
},
windshieldOptions: {
passengerSideOptions: {
availableReplacementOptions: ["Front", "Back", "Side"],
}
},
@ -221,20 +211,14 @@ function setupMocks({
initializeComponent: jest.fn(),
};
const driverSideOptions = replaceOptionsQuestion
driverSideOptions.methods = {
initializeComponent: jest.fn(),
};
const windshieldOptions = replaceOptionsQuestion
windshieldOptions.methods = {
initializeComponent: jest.fn(),
};
damageLocationQuestion.methods = {
initializeComponent: jest.fn(),
};
sideDoorOptions.methods = {
initializeComponent: jest.fn(),
};
funnelFooter.methods = {
initializeComponent: jest.fn(),
}
@ -250,24 +234,16 @@ function setupMocks({
vehicleBannerWrapper.vm.initializeComponent =
vehicleBanner.methods.initializeComponent;
const sideDoorOptionsWrapper = wrapper.findComponent({ name: "sideDoorOptions" });
sideDoorOptionsWrapper.vm.initializeComponent =
sideDoorOptions.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 windshieldOptionsWrapper = wrapper.findAllComponents({
name: "replaceOptionsQuestion",
}).at(1);
windshieldOptionsWrapper.vm.initializeComponent =
replaceOptionsQuestion.methods.initializeComponent;
const damageLocationQuestionWrapper = wrapper.findComponent({
name: "damageLocationQuestion",
});

View file

@ -4,8 +4,7 @@
<vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=false />
<funnelSubHeader ref="funnelSubHeader" />
<damageLocationQuestion ref="damageLocation" v-model="selectedDamageLocations" groupName="DamageLocationQuestion" />
<replaceOptionsQuestion ref="driverSideOptions" isAvailable filterByVehicleCategory v-model="driverSideOptionsData" groupName="DriverSideReplaceOptionsQuestion" />
<replaceOptionsQuestion ref="windshieldOptions" isAvailable groupName="windshieldOptions" v-model="windshieldOptionsData" />
<sideDoorOptions ref="sideDoorOptions" isAvailable groupName="SideDoorSideQuestion" v-model="sideDoorOptionsData" />
<funnelFooter ref="funnelFooter" @back-clicked="backButtonAction" />
</div>
</template>
@ -16,7 +15,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";
// Supporting files
@ -63,14 +62,11 @@ 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.windshieldOptions.initializeComponent(
resultMap.cmsContent.WindshieldReplaceOptionsQuestion, resultMap.damageOptions.windshieldOptions.availableReplacementOptions
vm.$refs.sideDoorOptions.initializeComponent(
resultMap.cmsContent.SideDoorSideQuestion, resultMap.cmsContent.DriverSideReplaceOptionsQuestion, resultMap.cmsContent.PassengerSideReplaceOptionsQuestion, resultMap.damageOptions.driverSideOptions.availableReplacementOptions, resultMap.damageOptions.passengerSideOptions.availableReplacementOptions
);
vm.$refs.funnelFooter.initializeComponent(
resultMap.cmsContent.FunnelFooterWidget
@ -80,7 +76,11 @@ export default {
data(){
return {
selectedDamageLocations: [],
driverSideOptionsData: [],
sideDoorOptionsData: {
selectedDoorSides: [],
selectedDriverSideReplacOptions: [],
selectedPassengerSideReplaceOptions: []
},
windshieldOptionsData: [],
}
},
@ -105,7 +105,7 @@ export default {
funnelFooter,
vehicleBanner,
funnelSubHeader,
replaceOptionsQuestion,
sideDoorOptions,
damageLocationQuestion,
},
};