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

View file

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

View file

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

View file

@ -5,7 +5,7 @@
groupName="ChooseAddressVehicle"
:questionText="questionText"
:answers="vehicles"
v-model="selectedVehicleVinAsArray"
v-model="selectedVehicleVin"
isRequired
:validation-rules="validationRules"
:valueToLogType="ValueToLogTypes.LAST_5"
@ -63,18 +63,16 @@ export default {
questionText() {
return this.getCmsContent("VehicleConfirmationQuestion", "QuestionText");
},
selectedVehicleVinAsArray: {
selectedVehicleVin: {
get: function() {
const modelValueAsArray = this.modelValue ? [this.modelValue] : [];
return modelValueAsArray;
return this.modelValue;
},
set: function(newValue) {
const newValueAsScalar = newValue && newValue.length > 0 ? newValue[newValue.length-1] : null;
this.$emit("update:modelValue", newValueAsScalar);
this.$emit("update:modelValue", newValue);
}
},
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: {

View file

@ -195,7 +195,7 @@ export default {
selectedVehicleVin: {
handler() {
// 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) {
this.$refs.funnelFooter.updateButtonText(`Continue with ${this.selectedVehicle.vehicle.year} ${this.selectedVehicle.vehicle.make} ${this.selectedVehicle.vehicle.model}`);
} else {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,18 +1,16 @@
<template>
<transition name="fade" mode="out-in">
<div
class="windshield-damage-type-question"
v-if="isAvailable"
aria-live="polite">
<div class="windshield-damage-type-question" v-if="isAvailable" aria-live="polite">
<buttonQuestion
:questionText="questionText"
:answers="answersFromCms"
:groupName="groupName"
buttonType="listCard"
v-model="selectedWindshieldDamageType"
v-model="selectedValues"
:suppressError="suppressError"
:validationRules="validationRules"
isRequired />
isRequired
/>
</div>
</transition>
</template>
@ -20,13 +18,8 @@
<script>
import buttonQuestion from "@/common-components/button-question/button-question";
export default {
export default ({
name: "windshieldDamageTypeQuestion",
data() {
return {
selectedWindshieldDamageType: this.modelValue,
};
},
props: {
modelValue: String,
groupName: String,
@ -36,20 +29,23 @@ export default {
cmsWidgetName: String,
},
computed: {
questionText() {
return this.getCmsContent(this.cmsWidgetName, "QuestionText");
questionText(){
return this.getCmsContent(this.cmsWidgetName, 'QuestionText');
},
answersFromCms() {
return this.getCmsContent(this.cmsWidgetName, "Answers");
answersFromCms(){
return this.getCmsContent(this.cmsWidgetName, 'Answers');
},
},
watch: {
selectedWindshieldDamageType(selectedWindshieldDamageType) {
this.$emit("update:modelValue", selectedWindshieldDamageType);
selectedValues: {
get: function() {
return this.modelValue;
},
set: function(newValue) {
this.$emit("update:modelValue", newValue);
}
},
},
components: {
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) => {
return selectedWindshieldDamageType.toString() != damageLocationsSelected.REPAIR ||
!selectedDamageLocations.includes(damageLocationsSelected.WINDSHIELD) ||
selectedDamageLocations.length === 1;
(!selectedDamageLocations.includes(damageLocationsSelected.WINDSHIELD) && !selectedDamageLocations[0]?.includes(damageLocationsSelected.WINDSHIELD)) ||
(selectedDamageLocations.length === 1 && selectedDamageLocations[0].length === 1);
});
defineRule("repair-only", (value) => {
return value.toString() === damageLocationsSelected.REPAIR;

View file

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

View file

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

View file

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

View file

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

View file

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