Merge branch 'feature/CSR-762' into feature/CSR-762-tests

This commit is contained in:
Katie 2022-10-04 14:44:04 -04:00
commit c76d476e5f
17 changed files with 173 additions and 159 deletions

View file

@ -14,7 +14,8 @@
:value="value" :value="value"
:checked="isChecked" :checked="isChecked"
@blur="handleBlur" @blur="handleBlur"
@keypress.enter="handleEventAction('keypressSubmit', $event)" @keypress.space="handleEventAction('space', $event)"
@keypress.enter="handleEventAction('enter', $event)"
@change="handleEventAction('change', $event)" /> @change="handleEventAction('change', $event)" />
<slot></slot> <slot></slot>
@ -75,13 +76,14 @@ export default {
handleEventAction(eventType, e) { handleEventAction(eventType, e) {
const eventTypes = { const eventTypes = {
CHANGE: "change", CHANGE: "change",
KEYPRESS_SUBMIT: "keypressSubmit", ENTER: "enter",
SPACE: "space",
CLICK: "click", CLICK: "click",
}; };
if (this.isMultiSelect) { if (this.isMultiSelect) {
switch (eventType) { switch (eventType) {
case eventTypes.KEYPRESS_SUBMIT: case eventTypes.ENTER:
case eventTypes.CHANGE: case eventTypes.CHANGE:
this.handleClick(e); this.handleClick(e);
this.dispatchStoreAction( this.dispatchStoreAction(
@ -96,7 +98,8 @@ export default {
} else { } else {
switch (eventType) { switch (eventType) {
case eventTypes.CLICK: case eventTypes.CLICK:
case eventTypes.KEYPRESS_SUBMIT: case eventTypes.ENTER:
case eventTypes.SPACE:
this.handleClick(e); this.handleClick(e);
this.pushClickEventToGAIfReady(); this.pushClickEventToGAIfReady();
break; break;

View file

@ -13,6 +13,7 @@
</div> </div>
<div class="w-100 d-flex justify-content-center"> <div class="w-100 d-flex justify-content-center">
<fieldset <fieldset
class="w-100" class="w-100"
:aria-required="isRequired" :aria-required="isRequired"
@ -22,6 +23,7 @@
<legend <legend
class="sr-only" class="sr-only"
:data-focus-target="formatString(groupName)" :data-focus-target="formatString(groupName)"
tabindex="-1"
:id="formatString(groupName)"> :id="formatString(groupName)">
{{ questionText }} {{ questionText }}
{{ {{

View file

@ -34,14 +34,14 @@ describe("addressVehiclesQuestion.vue", () => {
const wrapper = shallowMount(addressVehiclesQuestion, { const wrapper = shallowMount(addressVehiclesQuestion, {
mixins: [mockMixin], mixins: [mockMixin],
propsData: { propsData: {
vehicles: ["1", "2"], vehicles: ["1", "2", "newValue"],
modelValue: ["1", "2"], modelValue: "2",
} }
}); });
// Act // Act
const localThis = { $emit: jest.fn() } const localThis = { $emit: jest.fn() }
addressVehiclesQuestion.computed.selectedVehicleVinAsArray.set.call(localThis, ['newValue']); addressVehiclesQuestion.computed.selectedVehicleVin.set.call(localThis, 'newValue');
// Assert // Assert
expect(localThis.$emit).toBeCalledWith("update:modelValue", "newValue"); expect(localThis.$emit).toBeCalledWith("update:modelValue", "newValue");

View file

@ -5,7 +5,7 @@
groupName="ChooseAddressVehicle" groupName="ChooseAddressVehicle"
:questionText="questionText" :questionText="questionText"
:answers="vehicles" :answers="vehicles"
v-model="selectedVehicleVinAsArray" v-model="selectedVehicleVin"
isRequired isRequired
:validation-rules="validationRules" :validation-rules="validationRules"
:valueToLogType="ValueToLogTypes.LAST_5" :valueToLogType="ValueToLogTypes.LAST_5"
@ -63,18 +63,16 @@ export default {
questionText() { questionText() {
return this.getCmsContent("VehicleConfirmationQuestion", "QuestionText"); return this.getCmsContent("VehicleConfirmationQuestion", "QuestionText");
}, },
selectedVehicleVinAsArray: { selectedVehicleVin: {
get: function() { get: function() {
const modelValueAsArray = this.modelValue ? [this.modelValue] : []; return this.modelValue;
return modelValueAsArray;
}, },
set: function(newValue) { set: function(newValue) {
const newValueAsScalar = newValue && newValue.length > 0 ? newValue[newValue.length-1] : null; this.$emit("update:modelValue", newValue);
this.$emit("update:modelValue", newValueAsScalar);
} }
}, },
selectedVehicle() { // this computed is only needed for the computed differentVehicleAlertBody text above selectedVehicle() { // this computed is only needed for the computed differentVehicleAlertBody text above
return this.vehicles.find( ({ vin }) => vin === this.selectedVehicleVinAsArray[this.selectedVehicleVinAsArray.length-1] ); return this.vehicles.find( ({ vin }) => vin === this.selectedVehicleVin[this.selectedVehicleVin.length-1] );
}, },
}, },
components: { components: {

View file

@ -195,7 +195,7 @@ export default {
selectedVehicleVin: { selectedVehicleVin: {
handler() { handler() {
// does this vehicle match the previously selected carId? // does this vehicle match the previously selected carId?
this.isCarIdDifferent = this.selectedVehicle.vehicle.carId !== store.getters.vehicle.carId; this.isCarIdDifferent = this.selectedVehicle?.vehicle.carId !== store.getters.vehicle.carId;
if (this.isCarIdDifferent) { if (this.isCarIdDifferent) {
this.$refs.funnelFooter.updateButtonText(`Continue with ${this.selectedVehicle.vehicle.year} ${this.selectedVehicle.vehicle.make} ${this.selectedVehicle.vehicle.model}`); this.$refs.funnelFooter.updateButtonText(`Continue with ${this.selectedVehicle.vehicle.year} ${this.selectedVehicle.vehicle.make} ${this.selectedVehicle.vehicle.model}`);
} else { } else {

View file

@ -6,7 +6,8 @@
:answers="answersToDisplay" :answers="answersToDisplay"
:groupName="groupName" :groupName="groupName"
buttonType="listCard" buttonType="listCard"
v-model="selectedDamageLocations" isRequired
v-model="selectedValues"
validationRules="damage-location-required" validationRules="damage-location-required"
/> />
</div> </div>
@ -26,12 +27,11 @@ export default ({
name: "damageLocationQuestion", name: "damageLocationQuestion",
data(){ data(){
return { return {
damageOptions: {}, damageOptions: Object,
selectedDamageLocations: this.modelValue
} }
}, },
props: { props: {
modelValue: [Array, String, Number], modelValue: Array,
groupName: String, groupName: String,
cmsWidgetName: String, cmsWidgetName: String,
}, },
@ -47,6 +47,14 @@ export default ({
answersFromCms(){ answersFromCms(){
return this.getCmsContent(this.cmsWidgetName, 'Answers'); return this.getCmsContent(this.cmsWidgetName, 'Answers');
}, },
selectedValues: {
get: function() {
return this.modelValue;
},
set: function(newValue) {
this.$emit("update:modelValue", newValue);
}
},
damageOptionsMap(){ damageOptionsMap(){
return { return {
Windshield: true, Windshield: true,
@ -69,11 +77,6 @@ export default ({
}); });
}, },
}, },
watch: {
selectedDamageLocations(selectedDamageLocations) {
this.$emit("update:modelValue", selectedDamageLocations);
}
},
components: { components: {
buttonQuestion, buttonQuestion,
}, },

View file

@ -8,7 +8,7 @@
:answers="answersToDisplay" :answers="answersToDisplay"
:groupName="groupName" :groupName="groupName"
buttonType="listCard" buttonType="listCard"
v-model="selectedReplaceOptions" v-model="selectedValues"
:validationRules="validationRules" :validationRules="validationRules"
:suppressError="suppressError" :suppressError="suppressError"
:isRequired="isRequired" :isRequired="isRequired"
@ -23,17 +23,16 @@ import store from "@/store";
export default ({ export default ({
name: "replaceOptionsQuestion", name: "replaceOptionsQuestion",
data() { data(){
return { return {
replaceOptions: [], replaceOptions: [],
selectedReplaceOptions: this.modelValue
} }
}, },
props: { props: {
modelValue: [Array, String, Number],
isAvailable: Boolean, isAvailable: Boolean,
filterByVehicleCategory: Boolean, filterByVehicleCategory: Boolean,
groupName: String, groupName: String,
modelValue: [Array, String, Number],
isMultiSelect: Boolean, isMultiSelect: Boolean,
validationRules: String, validationRules: String,
suppressError: Boolean, suppressError: Boolean,
@ -41,15 +40,13 @@ export default ({
isRequired: Boolean, isRequired: Boolean,
}, },
methods: { methods: {
initializeComponent(replaceOptions) { initializeComponent(replaceOptions){
this.replaceOptions = replaceOptions; this.replaceOptions = replaceOptions;
}, },
updateSelectedValues() { updateSelectedValues() {
// UPDATE SELECTEDVALUES IF ONLY ONE ANSWER // UPDATE SELECTEDVALUES IF ONLY ONE ANSWER
// ex: BackGlass stationary if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1) {
if (Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1) { this.selectedValues = [this.answersToDisplay[0].Name];
const selectedAnswer = this.answersToDisplay[0].Name;
this.selectedReplaceOptions = this.isMultiSelect ? [selectedAnswer] : selectedAnswer;
} }
}, },
}, },
@ -60,6 +57,14 @@ export default ({
answersFromCms(){ answersFromCms(){
return this.getCmsContent(this.cmsWidgetName, 'Answers'); return this.getCmsContent(this.cmsWidgetName, 'Answers');
}, },
selectedValues: {
get: function() {
return this.modelValue;
},
set: function(newValue) {
this.$emit("update:modelValue", newValue);
}
},
answersToDisplay(){ answersToDisplay(){
const filteredAnswers = Array.isArray(this.answersFromCms) const filteredAnswers = Array.isArray(this.answersFromCms)
? this.answersFromCms.filter(ans => ? this.answersFromCms.filter(ans =>
@ -86,11 +91,8 @@ export default ({
}, },
shouldDisplayReplaceOptionsQuestion(shouldDisplayReplaceOptionsQuestion) { shouldDisplayReplaceOptionsQuestion(shouldDisplayReplaceOptionsQuestion) {
if (!shouldDisplayReplaceOptionsQuestion) { if (!shouldDisplayReplaceOptionsQuestion) {
this.selectedReplaceOptions = []; this.selectedValues = [];
} }
},
selectedReplaceOptions(selectedReplaceOptions) {
this.$emit("update:modelValue", selectedReplaceOptions);
} }
}, },
components: { components: {

View file

@ -17,7 +17,7 @@ describe("windshield-chip-count-question.vue", () => {
const { wrapper } = setupMocks({ modelValueProp: 1 }); const { wrapper } = setupMocks({ modelValueProp: 1 });
//Act //Act
await wrapper.setData({ numberOfChips: 2 }); wrapper.vm.selectedValue = "2";
//Assert //Assert
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([2]); expect(wrapper.emitted()["update:modelValue"][0]).toEqual([2]);

View file

@ -7,7 +7,7 @@
:groupName="groupName" :groupName="groupName"
buttonType="listButtonHorizontal" buttonType="listButtonHorizontal"
useTextForValue useTextForValue
v-model="numberOfChips" v-model="selectedValue"
:validationRules="validationRules" :validationRules="validationRules"
isRequired isRequired
/> />
@ -19,12 +19,7 @@
import buttonQuestion from "@/common-components/button-question/button-question"; import buttonQuestion from "@/common-components/button-question/button-question";
export default ({ export default ({
name: "windshieldChipCountQuestion", name: "windshieldOptions",
data() {
return {
numberOfChips: this.modelValue
}
},
props: { props: {
modelValue: [String, Number], modelValue: [String, Number],
groupName: String, groupName: String,
@ -39,14 +34,18 @@ export default ({
answersFromCms(){ answersFromCms(){
return this.getCmsContent(this.cmsWidgetName, 'Answers'); return this.getCmsContent(this.cmsWidgetName, 'Answers');
}, },
selectedValue: {
get: function() {
return this.modelValue;
},
set: function(newValue) {
const numberValue = Number(newValue);
this.$emit("update:modelValue", numberValue);
}
},
}, },
components: { components: {
buttonQuestion, buttonQuestion,
},
watch: {
numberOfChips(numberOfChips) {
this.$emit("update:modelValue", numberOfChips);
}
} }
}) })
</script> </script>

View file

@ -15,7 +15,7 @@ describe("windshield-damage-type-question.vue", () => {
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
//Assert //Assert
expect(wrapper.vm.selectedWindshieldDamageType).toEqual("Repair"); expect(wrapper.vm.selectedValues).toEqual("Repair");
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ modelValue: "Replace" }]); expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ modelValue: "Replace" }]);
}); });
}); });

View file

@ -1,18 +1,16 @@
<template> <template>
<transition name="fade" mode="out-in"> <transition name="fade" mode="out-in">
<div <div class="windshield-damage-type-question" v-if="isAvailable" aria-live="polite">
class="windshield-damage-type-question"
v-if="isAvailable"
aria-live="polite">
<buttonQuestion <buttonQuestion
:questionText="questionText" :questionText="questionText"
:answers="answersFromCms" :answers="answersFromCms"
:groupName="groupName" :groupName="groupName"
buttonType="listCard" buttonType="listCard"
v-model="selectedWindshieldDamageType" v-model="selectedValues"
:suppressError="suppressError" :suppressError="suppressError"
:validationRules="validationRules" :validationRules="validationRules"
isRequired /> isRequired
/>
</div> </div>
</transition> </transition>
</template> </template>
@ -20,13 +18,8 @@
<script> <script>
import buttonQuestion from "@/common-components/button-question/button-question"; import buttonQuestion from "@/common-components/button-question/button-question";
export default { export default ({
name: "windshieldDamageTypeQuestion", name: "windshieldDamageTypeQuestion",
data() {
return {
selectedWindshieldDamageType: this.modelValue,
};
},
props: { props: {
modelValue: String, modelValue: String,
groupName: String, groupName: String,
@ -36,20 +29,23 @@ export default {
cmsWidgetName: String, cmsWidgetName: String,
}, },
computed: { computed: {
questionText() { questionText(){
return this.getCmsContent(this.cmsWidgetName, "QuestionText"); return this.getCmsContent(this.cmsWidgetName, 'QuestionText');
}, },
answersFromCms() { answersFromCms(){
return this.getCmsContent(this.cmsWidgetName, "Answers"); return this.getCmsContent(this.cmsWidgetName, 'Answers');
}, },
}, selectedValues: {
watch: { get: function() {
selectedWindshieldDamageType(selectedWindshieldDamageType) { return this.modelValue;
this.$emit("update:modelValue", selectedWindshieldDamageType); },
set: function(newValue) {
this.$emit("update:modelValue", newValue);
}
}, },
}, },
components: { components: {
buttonQuestion, buttonQuestion,
}, }
}; })
</script> </script>

View file

@ -57,8 +57,8 @@ defineRule("windshield-replace-options-required", required(errorMessages.WINSHIE
defineRule("check-for-repair-and-replace", (selectedWindshieldDamageType, selectedDamageLocations) => { defineRule("check-for-repair-and-replace", (selectedWindshieldDamageType, selectedDamageLocations) => {
return selectedWindshieldDamageType.toString() != damageLocationsSelected.REPAIR || return selectedWindshieldDamageType.toString() != damageLocationsSelected.REPAIR ||
!selectedDamageLocations.includes(damageLocationsSelected.WINDSHIELD) || (!selectedDamageLocations.includes(damageLocationsSelected.WINDSHIELD) && !selectedDamageLocations[0]?.includes(damageLocationsSelected.WINDSHIELD)) ||
selectedDamageLocations.length === 1; (selectedDamageLocations.length === 1 && selectedDamageLocations[0].length === 1);
}); });
defineRule("repair-only", (value) => { defineRule("repair-only", (value) => {
return value.toString() === damageLocationsSelected.REPAIR; return value.toString() === damageLocationsSelected.REPAIR;

View file

@ -1,15 +1,16 @@
<template> <template>
<buttonQuestion <buttonQuestion
class="radioQuestion" class="radioQuestion"
isOverflowScrollable isOverflowScrollable
selectingInitiatesLoad selectingInitiatesLoad
:questionText="questionText" :questionText="questionText"
:answers="makes" :answers="makes"
groupName="ChooseVehicleMake" groupName="ChooseVehicleMake"
textPosition="text-start" textPosition="text-start"
v-model="selectedMake" v-model="selectedValue"
:selectOnKeypress="false" :selectOnKeypress="false"
isRequired /> isRequired
/>
</template> </template>
<script> <script>
@ -20,40 +21,42 @@ import { storeActions } from "@/constants/store-actions.js";
import baseMixin from "@/mixins/base-mixin.js"; import baseMixin from "@/mixins/base-mixin.js";
export default { export default {
name: "make-question", name: "make-question",
data() { data() {
return { return {
makes: [], makes: [],
selectedMake: "" };
}; },
props: {
modelValue: String,
cmsWidgetName: String,
},
computed: {
questionText(){
return this.getCmsContent(this.cmsWidgetName, 'QuestionText');
}, },
props: { selectedValue: {
modelValue: String, get: function() {
cmsWidgetName: String, return this.modelValue
},
set: function(newValue) {
this.$emit("update:modelValue", newValue);
}
}
},
components: {
buttonQuestion,
},
methods: {
loadInitialData() {
return baseMixin.methods.dispatchStoreAction(
storeActions.GET_VEHICLE_MAKES,
{ year: store.getters.vehicle.year }
);
}, },
computed: { initializeComponent(initialData) {
questionText() { this.makes = initialData;
return this.getCmsContent(this.cmsWidgetName, "QuestionText");
},
},
components: {
buttonQuestion,
},
methods: {
loadInitialData() {
return baseMixin.methods.dispatchStoreAction(
storeActions.GET_VEHICLE_MAKES,
{ year: store.getters.vehicle.year }
);
},
initializeComponent(initialData) {
this.makes = initialData;
},
},
watch: {
selectedMake(selectedMake) {
this.$emit("update:modelValue", selectedMake);
},
}, },
},
}; };
</script> </script>

View file

@ -7,7 +7,7 @@
:answers="models" :answers="models"
groupName="ChooseVehicleModel" groupName="ChooseVehicleModel"
textPosition="text-start" textPosition="text-start"
v-model="selectedModel" v-model="selectedValue"
:selectOnKeypress="false" :selectOnKeypress="false"
isRequired isRequired
/> />
@ -25,7 +25,6 @@ export default {
data() { data() {
return { return {
models: [], models: [],
selectedModel: ""
}; };
}, },
props: { props: {
@ -36,6 +35,14 @@ export default {
questionText(){ questionText(){
return this.getCmsContent(this.cmsWidgetName, 'QuestionText'); return this.getCmsContent(this.cmsWidgetName, 'QuestionText');
}, },
selectedValue: {
get: function() {
return this.modelValue
},
set: function(newValue) {
this.$emit("update:modelValue", newValue);
}
}
}, },
components: { components: {
buttonQuestion, buttonQuestion,
@ -51,10 +58,5 @@ export default {
this.models = initialData; this.models = initialData;
}, },
}, },
watch: {
selectedModel(selectedModel) {
this.$emit("update:modelValue", selectedModel);
}
}
}; };
</script> </script>

View file

@ -7,7 +7,7 @@
:answers="styles" :answers="styles"
groupName="ChooseVehicleStyle" groupName="ChooseVehicleStyle"
textPosition="text-start" textPosition="text-start"
v-model="selectedStyle" v-model="selectedValue"
:selectOnKeypress="false" :selectOnKeypress="false"
isRequired isRequired
/> />
@ -25,16 +25,24 @@ export default {
data() { data() {
return { return {
styles: [], styles: [],
selectedStyle: ""
}; };
}, },
props: { props: {
modelValue: String,
cmsWidgetName: String, cmsWidgetName: String,
}, },
computed: { computed: {
questionText(){ questionText(){
return this.getCmsContent(this.cmsWidgetName, 'QuestionText'); return this.getCmsContent(this.cmsWidgetName, 'QuestionText');
}, },
selectedValue: {
get: function() {
return this.modelValue
},
set: function(newValue) {
this.$emit("update:modelValue", newValue);
}
}
}, },
components: { components: {
buttonQuestion, buttonQuestion,
@ -54,10 +62,5 @@ export default {
this.styles = initialData; this.styles = initialData;
}, },
}, },
watch: {
selectedStyle(selectedStyle) {
this.$emit("update:modelValue", selectedStyle);
}
}
}; };
</script> </script>

View file

@ -1,18 +1,16 @@
<template> <template>
<div> <buttonQuestion
<buttonQuestion class="radioQuestion"
class="radioQuestion" isOverflowScrollable
isOverflowScrollable selectingInitiatesLoad
selectingInitiatesLoad :questionText="questionText"
:questionText="questionText" :answers="years"
:answers="years" groupName="ChooseVehicleYear"
groupName="ChooseVehicleYear" textPosition="text-start"
textPosition="text-start" v-model="selectedValue"
v-model="selectedYear" :selectOnKeypress="false"
:selectOnKeypress="false" isRequired
isRequired />
/>
</div>
</template> </template>
<script> <script>
@ -20,25 +18,32 @@ import buttonQuestion from "@/common-components/button-question/button-question"
// Supporting files // Supporting files
import { storeActions } from "@/constants/store-actions.js"; import { storeActions } from "@/constants/store-actions.js";
import baseMixin from "@/mixins/base-mixin.js"; import baseMixin from "@/mixins/base-mixin.js";
export default { export default {
name: "year-question", name: "year-question",
data() { data() {
return { return {
years: [], years: [],
selectedYear: ""
}; };
}, },
props: { props: {
modelValue: String,
cmsWidgetName: String, cmsWidgetName: String,
}, },
components: { components: {
buttonQuestion buttonQuestion,
}, },
computed: { computed: {
questionText() { questionText(){
return this.getCmsContent(this.cmsWidgetName, "QuestionText"); return this.getCmsContent(this.cmsWidgetName, 'QuestionText');
}, },
selectedValue: {
get: function() {
return this.modelValue
},
set: function(newValue) {
this.$emit("update:modelValue", newValue);
}
}
}, },
methods: { methods: {
loadInitialData() { loadInitialData() {
@ -51,10 +56,5 @@ export default {
this.years = initialData; this.years = initialData;
}, },
}, },
watch: {
selectedYear(selectedYear) {
this.$emit("update:modelValue", selectedYear);
}
}
}; };
</script> </script>

View file

@ -16,7 +16,10 @@ export default {
valueToLogType: String, valueToLogType: String,
validationRules: String, validationRules: String,
isWide: Boolean, isWide: Boolean,
isRequired: Boolean isRequired: {
type: Boolean,
default: true
}
}, },
data() { data() {
return { return {