Merge pull request #195 from Safelite/feature/unit-test-updates

Cleaning up button emit changes and adjusting unit tests
This commit is contained in:
max-dempsey 2022-02-04 15:25:38 -05:00 committed by GitHub
commit 186b819404
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 207 additions and 96 deletions

View file

@ -1,5 +1,6 @@
import { shallowMount } from "@vue/test-utils";
import buttonQuestion from "@/common-components/button-question/button-question";
import { nextTick } from "vue";
describe("buttonQuestion.vue", () => {
it("Should show overflow classes on fieldset if isOverflowScrollable is true", async () => {
@ -41,44 +42,32 @@ describe("buttonQuestion.vue", () => {
});
describe("buttonQuestion.vue", () => {
it("Should trigger event modelValue change on select", async () => {
it("Should trigger event modelValue change to new value on when radio button selected", async () => {
// Act
const wrapper = shallowMount(buttonQuestion);
await wrapper.setData({
modelValueAnswers: ["Windshield"],
chosenAnswer: "Windshield"
await wrapper.setProps({
answers: ["2022", "2021", "2020"],
isMultiSelect: false
});
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.handleCheckedChanged(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.setData({
modelValueAnswers: ["Front-door"]
})
const val = {isChecked : false, buttonId: "Front-door"}
const val = {isChecked: true, buttonId: "2021", }
wrapper.vm.handleCheckedChanged(val);
// Assert
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([undefined]);
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([["2021"]]);
});
});
describe("buttonQuestion.vue", () => {
it("Should add values to array on checkbox click", async () => {
// Act
const wrapper = shallowMount(buttonQuestion);
await wrapper.setProps({
modelValue: ["2022", "2021", "2020"],
isMultiSelect: true
});
const val = {isChecked: true, buttonId: "2019", }
wrapper.vm.handleCheckedChanged(val);
// Assert
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([["2022", "2021", "2020", "2019"]]);
});
});

View file

@ -30,7 +30,7 @@
:altText="answer.Name ? answer.Name : answer"
screenReaderOnlyText="(opens new window)"
:colLength="this.answers.length < 3 ? '' : '-4'"
v-model="selectedValues"
:selectedButtonIDs="selectedValues"
data-test="button"
/>
</div>
@ -107,23 +107,23 @@ export default {
}
},
},
data(){
return {
modelValueAnswers: [],
}
},
mounted(){
if(Array.isArray(this.answers) && this.answers.length === 1) {
this.modelValueAnswers.push(typeof(this.answers[0]) === 'object' ? this.answers[0].Name : this.answers[0]);
this.$emit("update:modelValue", this.modelValueAnswers);
const newSelectedValues = this.selectedValues;
newSelectedValues.push(typeof(this.answers[0]) === 'object' ? this.answers[0].Name : this.answers[0]);
this.selectedValues = newSelectedValues;
}
},
methods: {
handleCheckedChanged(val) {
// Add or remove item to array of data to emit
val.isChecked ? this.modelValueAnswers.push(val.buttonId) : this.modelValueAnswers.splice(this.modelValueAnswers.indexOf(val.buttonId), 1);
const answersToEmit = this.modelValueAnswers.length ? this.modelValueAnswers : undefined;
this.$emit("update:modelValue", answersToEmit);
if(this.isMultiSelect) {
// 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;
} else {
this.selectedValues = [val.buttonId]
}
},
},
components: {

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: 'car-Windshield' }, { Name: 'car-SideDoor' }, {Name: "car-RearWindow"} ])
});
});

View file

@ -3,7 +3,7 @@
<buttonQuestion
v-if="answersToDisplay.length > 1"
:questionText="questionText"
:isMultiSelect="isMultiSelect"
isMultiSelect
:answers="answersToDisplay"
:groupName="groupName"
buttonType="listCard"
@ -23,16 +23,14 @@ export default ({
questionText: String,
answersFromCms: Array,
damageOptions: Object,
groupName: String,
}
},
props: {
isMultiSelect: Boolean,
modelValue: Array,
groupName: String,
},
methods: {
initializeComponent(cmsContent, damageOptions, groupName){
this.groupName = groupName;
initializeComponent(cmsContent, damageOptions){
this.questionText = cmsContent.QuestionText;
this.answersFromCms = cmsContent.Answers;
this.damageOptions = damageOptions;
@ -51,7 +49,7 @@ export default ({
return {
Windshield: true,
SideDoor: this.damageOptions.driverSideOptions.availableReplacementOptions || this.damageOptions.passengerSideOptions.availableReplacementOption ? true : false,
RearWindow: this.damageOptions.backGlassOptions.availableReplacementOption ? true : false,
RearWindow: this.damageOptions.backGlassOptions.availableReplacementOptions ? true : false,
}
},
answersToDisplay(){

View file

@ -4,7 +4,7 @@
<buttonQuestion
v-if="isAvailable && answersToDisplay.length > 1"
:questionText="questionText"
:isMultiSelect="isMultiSelect"
isMultiSelect
:answers="answersToDisplay"
:groupName="groupName"
buttonType="listCard"
@ -25,18 +25,16 @@ export default ({
questionText: String,
answersFromCms: Array,
replaceOptions: Array,
groupName: String,
}
},
props: {
isMultiSelect: Boolean,
isAvailable: Boolean,
filterByVehicleCategory: Boolean,
groupName: String,
modelValue: Array,
},
methods: {
initializeComponent(cmsContent, replaceOptions, groupName){
this.groupName = groupName;
initializeComponent(cmsContent, replaceOptions){
this.questionText = cmsContent.QuestionText;
this.answersFromCms = cmsContent.Answers;
this.replaceOptions = replaceOptions;

View file

@ -3,8 +3,8 @@
<funnelHeader ref="funnelHeader" />
<vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage=false />
<funnelSubHeader ref="funnelSubHeader" :hasSubText=true />
<damageLocationQuestion ref="damageLocation" isMultiSelect v-model="damageLocationQuestionData" />
<replaceOptionsQuestion ref="driverSideOptions" isAvailable isMultiSelect v-model="driverSideOptionsData" />
<damageLocationQuestion ref="damageLocation" v-model="selectedDamageLocations" groupName="DamageLocationQuestion" />
<replaceOptionsQuestion ref="driverSideOptions" isAvailable v-model="driverSideOptionsData" groupName="DriverSideReplaceOptionsQuestion" />
</div>
</template>
@ -60,19 +60,16 @@ export default {
resultMap.cmsContent.FunnelSubHeaderWidget
);
vm.$refs.driverSideOptions.initializeComponent(
resultMap.cmsContent.DriverSideReplaceOptionsQuestion, resultMap.damageOptions.driverSideOptions.availableReplacementOptions, 'DriverSideReplaceOptionsQuestion'
resultMap.cmsContent.DriverSideReplaceOptionsQuestion, resultMap.damageOptions.driverSideOptions.availableReplacementOptions
);
vm.$refs.damageLocation.initializeComponent(
resultMap.cmsContent.DamageLocationQuestion, resultMap.damageOptions, 'DamageLocationQuestion'
resultMap.cmsContent.DamageLocationQuestion, resultMap.damageOptions
);
// for damageOptions and cms content data
//console.log(resultMap)
});
},
data(){
return {
damageLocationQuestionData: [],
selectedDamageLocations: [],
driverSideOptionsData: [],
}
},

View file

@ -33,7 +33,7 @@ export default {
computed: {
selectedValueAsArray: {
get: function() {
const modelValueAsArray = this.modelValue ? [this.modelValue] : null;
const modelValueAsArray = this.modelValue ? [this.modelValue] : [];
return modelValueAsArray;
},
set: function(newValue) {

View file

@ -33,7 +33,7 @@ export default {
name: "vehicle-make",
data() {
return {
selectedMake: String,
selectedMake: null,
};
},
computed: {},

View file

@ -33,7 +33,7 @@ export default {
computed: {
selectedValueAsArray: {
get: function() {
const modelValueAsArray = this.modelValue ? [this.modelValue] : null;
const modelValueAsArray = this.modelValue ? [this.modelValue] : [];
return modelValueAsArray;
},
set: function(newValue) {

View file

@ -33,7 +33,7 @@ export default {
name: "vehicle-model",
data() {
return {
selectedModel: String,
selectedModel: null,
};
},
computed: {},

View file

@ -33,7 +33,7 @@ export default {
computed: {
selectedValueAsArray: {
get: function() {
const modelValueAsArray = this.modelValue ? [this.modelValue] : null;
const modelValueAsArray = this.modelValue ? [this.modelValue] : [];
return modelValueAsArray;
},
set: function(newValue) {

View file

@ -32,7 +32,7 @@ export default {
name: "vehicle-style",
data() {
return {
selectedStyle: String,
selectedStyle: null,
};
},
computed: {},

View file

@ -28,7 +28,7 @@ export default {
name: "vehicle-year",
data() {
return {
selectedYear: String,
selectedYear: null,
};
},
computed: {},

View file

@ -72,6 +72,7 @@ describe("year-question.vue", () => {
});
});
function setupMocks({
modelValueProp = "1900",
cmsQuestionText = "CMS text goes here",
@ -89,6 +90,7 @@ function setupMocks({
mountOptions.propsData = {
modelValue: modelValueProp,
};
const wrapper = shallowMount(yearQuestion, mountOptions);
//Mock CMS content

View file

@ -35,7 +35,7 @@ export default {
computed: {
selectedValueAsArray: {
get: function() {
const modelValueAsArray = this.modelValue ? [this.modelValue] : null;
const modelValueAsArray = this.modelValue ? [this.modelValue] : [];
return modelValueAsArray;
},
set: function(newValue) {

View file

@ -173,4 +173,45 @@ describe("list-button-horizontal.vue", () => {
expect(loader.attributes("style")).toContain("1rem");
});
it("Should emit button value on click", async () => {
// Act
const wrapper = shallowMount(listButtonHorizontal, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
buttonID: "List Card Checkbox",
groupID: "radio-demo-1",
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
isRequired: true,
isWide: false,
modelValue: ["List Card Checkbox"],
},
});
wrapper.vm.handleCheckChange();
// Assert
expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{buttonId: "List Card Checkbox", isChecked: Boolean}]);
});
it("Should set checkValue data if selectedButtonIDs has value(s)", async () => {
// Act
const wrapper = shallowMount(listButtonHorizontal, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
buttonID: "List Card Checkbox",
groupID: "radio-demo-1",
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
isRequired: true,
isWide: false,
modelValue: ["List Card Checkbox"],
isMultiSelect: false,
selectedButtonIDs: ["Car-Front"]
},
});
// Assert
expect(wrapper.componentVM.checkValue).toEqual("Car-Front");
});
});

View file

@ -12,6 +12,7 @@
:aria-required="isRequired"
:data-focus-target="groupName"
v-model="checkValue"
@change="handleCheckChange"
/>
<label
tabindex="-1"
@ -69,7 +70,7 @@ export default {
type: String,
default: "",
},
modelValue: [Array, String],
selectedButtonIDs: [Array, String],
},
data() {
return {
@ -78,7 +79,9 @@ export default {
};
},
created(){
this.checkValue = this.modelValue ? this.modelValue.includes(this.buttonID) : false;
if(this.selectedButtonIDs){
this.checkValue = this.isMultiSelect ? this.selectedButtonIDs.includes(this.buttonID) : this.selectedButtonIDs[0];
}
},
methods: {
displayLoader() {
@ -90,12 +93,10 @@ export default {
}
this.handleChange(value);
},
},
watch: {
checkValue(newValue, oldValue){
const isInitialization = typeof(oldValue) !== 'function';
if (isInitialization) {
this.$emit('isCheckedChanged', { isChecked: this.checkValue, buttonId: this.buttonID + '' });
handleCheckChange(newValue, oldValue){
const isInitialization = typeof(oldValue) === 'function';
if (!isInitialization) {
this.$emit('isCheckedChanged', { isChecked: this.checkValue, buttonId: this.buttonID.toString() });
}
}
},

View file

@ -173,4 +173,44 @@ describe("list-button.vue", () => {
expect(loader.attributes("style")).toContain("1rem");
});
it("Should emit button value on click", async () => {
// Act
const wrapper = shallowMount(listButton, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
buttonID: "List Card Checkbox",
groupID: "radio-demo-1",
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
isRequired: true,
isWide: false,
modelValue: ["List Card Checkbox"],
},
});
wrapper.vm.handleCheckChange();
// Assert
expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{buttonId: "List Card Checkbox", isChecked: Boolean}]);
});
it("Should set checkValue data if selectedButtonIDs has value(s)", async () => {
// Act
const wrapper = shallowMount(listButton, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
buttonID: "List Card Checkbox",
groupID: "radio-demo-1",
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
isRequired: true,
isWide: false,
modelValue: ["List Card Checkbox"],
selectedButtonIDs: ["Car-Front"]
},
});
// Assert
expect(wrapper.componentVM.checkValue).toEqual("Car-Front");
});
});

View file

@ -12,6 +12,7 @@
:aria-required="isRequired"
:data-focus-target="groupName"
v-model="checkValue"
@change="handleCheckChange"
>
<label
tabindex="-1"
@ -71,7 +72,7 @@ export default {
type: [String, Number],
default: "",
},
modelValue: [Array, String],
selectedButtonIDs: [Array, String],
},
data() {
return {
@ -80,7 +81,9 @@ export default {
};
},
created(){
this.checkValue = this.modelValue ? this.modelValue.includes(this.buttonID) : false;
if(this.selectedButtonIDs){
this.checkValue = this.isMultiSelect ? this.selectedButtonIDs.includes(this.buttonID) : this.selectedButtonIDs[0];
}
},
methods: {
displayLoader() {
@ -92,12 +95,10 @@ export default {
}
this.handleChange(value);
},
},
watch: {
checkValue(newValue, oldValue){
const isInitialization = typeof(oldValue) !== 'function';
if (isInitialization) {
this.$emit('isCheckedChanged', { isChecked: this.checkValue, buttonId: this.buttonID + '' });
handleCheckChange(newValue, oldValue){
const isInitialization = typeof(oldValue) === 'function';
if (!isInitialization) {
this.$emit('isCheckedChanged', { isChecked: this.checkValue, buttonId: this.buttonID.toString() });
}
}
},

View file

@ -191,4 +191,45 @@ describe("list-card.vue", () => {
expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-column", "pt-4", "pb-2"]);
});
it("Should emit button value on click", async () => {
// Act
const wrapper = shallowMount(listCard, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
buttonID: "List Card Checkbox",
groupID: "radio-demo-1",
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
isRequired: true,
isWide: false,
modelValue: ["List Card Checkbox"],
},
});
wrapper.vm.handleCheckChange();
// Assert
expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{buttonId: "List Card Checkbox", isChecked: Boolean}]);
});
it("Should set checkValue data if selectedButtonIDs has value(s)", async () => {
// Act
const wrapper = shallowMount(listCard, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
buttonID: "List Card Checkbox",
groupID: "radio-demo-1",
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
isRequired: true,
isWide: false,
modelValue: ["List Card Checkbox"],
selectedButtonIDs: ["Car-Front"]
},
});
// Assert
expect(wrapper.componentVM.checkValue).toEqual("Car-Front");
});
});

View file

@ -12,6 +12,7 @@
:aria-required="isRequired"
:data-focus-target="groupName"
v-model="checkValue"
@change="handleCheckChange"
/>
<label
:for="buttonID"
@ -70,7 +71,7 @@ export default {
default: "",
},
colLength: String,
modelValue: [Array, String],
selectedButtonIDs: [Array, String],
},
data(){
return {
@ -78,7 +79,9 @@ export default {
}
},
created(){
this.checkValue = this.modelValue ? this.modelValue.includes(this.buttonID) : false;
if(this.selectedButtonIDs){
this.checkValue = this.isMultiSelect ? this.selectedButtonIDs.includes(this.buttonID) : this.selectedButtonIDs[0];
}
},
computed: {
getLabelClasses() {
@ -93,11 +96,11 @@ export default {
}
},
},
watch: {
checkValue(newValue, oldValue){
const isInitialization = typeof(oldValue) !== 'function';
if (isInitialization) {
this.$emit('isCheckedChanged', { isChecked: this.checkValue, buttonId: this.buttonID + '' });
methods: {
handleCheckChange(newValue, oldValue){
const isInitialization = typeof(oldValue) === 'function';
if (!isInitialization) {
this.$emit('isCheckedChanged', { isChecked: this.checkValue, buttonId: this.buttonID.toString() });
}
}
},