CSR-762 Update some tests, get GA working for inputs for keyboard navigation

This commit is contained in:
Katie 2022-09-27 15:50:49 -04:00
parent d4100f4d26
commit fff1aa1848
10 changed files with 205 additions and 371 deletions

View file

@ -12,6 +12,8 @@
:aria-required="isRequired" :aria-required="isRequired"
:value="value" :value="value"
:checked="isChecked" :checked="isChecked"
@blur="handleBlur"
@focus="handleFocus"
@keypress.enter="handleEventAction('keypressSubmit', $event)" @keypress.enter="handleEventAction('keypressSubmit', $event)"
@change="handleEventAction('change', $event)" /> @change="handleEventAction('change', $event)" />
@ -56,6 +58,7 @@ export default {
type: Boolean, type: Boolean,
default: true, default: true,
}, },
isRequired: Boolean,
}, },
data() { data() {
return { return {
@ -89,7 +92,10 @@ export default {
} else { } else {
switch (eventType) { switch (eventType) {
case eventTypes.CLICK: case eventTypes.CLICK:
console.log("RADIO CLICK");
// falls through. Keep this comment for the linter
case eventTypes.KEYPRESS_SUBMIT: case eventTypes.KEYPRESS_SUBMIT:
console.log("RADIO KEYPRESS CLICK");
this.handleClick(e); this.handleClick(e);
break; break;
case eventTypes.CHANGE: case eventTypes.CHANGE:
@ -117,22 +123,61 @@ export default {
this.valueToEmit = this.value; this.valueToEmit = this.value;
} }
window.currentlySelectedValues =
window.currentlySelectedValues ?? {};
window.currentlySelectedValues[this.groupName] = this.value;
this.handleChange(this.valueToEmit); this.handleChange(this.valueToEmit);
this.pushClickEventToGA();
}, },
handleClick(e) { handleClick(e) {
this.handleSelectionChange(e); this.handleSelectionChange(e);
// console.log("clicked/selected: ", this.valueToEmit)
if (this.isMultiSelect) {
this.pushClickEventToGA();
}
this.$emit("buttonClicked", this.valueToEmit); this.$emit("buttonClicked", this.valueToEmit);
}, },
pushClickEventToGA() { pushClickEventToGA(value) {
console.log("PUSHING: ", {
route: this.$route.query[queryStrings.FMG_PAGE],
value: value ?? this.value?.toString(),
valueToLogType: this.valueToLogType,
});
window.firedGaClickEventValues = window.firedGaClickEventValues ?? {}
window.firedGaClickEventValues[window.lastFocusedInputGroup] = value ?? this.value
this.pushEventToGA( this.pushEventToGA(
this.$route.query[queryStrings.FMG_PAGE], this.$route.query[queryStrings.FMG_PAGE],
this.GaActions.CLICKED, this.GaActions.CLICKED,
this.value?.toString(), value?.toString ?? this.value?.toString(),
true, true,
this.valueToLogType this.valueToLogType
); );
}, },
handleBlur() {
window.lastFocusedInputGroup = this.groupName;
window.wasLastFocusedInputMultiselect = this.isMultiSelect
},
handleFocus() {
console.log("FOCUS: ", {
currentlySelectedValues: window.currentlySelectedValues,
firedGaClickEventValues: window.firedGaClickEventValues,
lastFocusedInputGroup: window.lastFocusedInputGroup,
wasLastFocusedInputMultiselect: window.wasLastFocusedInputMultiselect,
groupName: this.groupName
})
if (
window.currentlySelectedValues &&
window.firedGaClickEventValues &&
window.lastFocusedInputGroup &&
!window.wasLastFocusedInputMultiselect &&
window.currentlySelectedValues[window.lastFocusedInputGroup] &&
window.lastFocusedInputGroup != this.groupName &&
window.firedGaClickEventValues[window.lastFocusedInputGroup] != window.currentlySelectedValues[window.lastFocusedInputGroup]
) {
// TODO MAKE SURE THIS IS FIRING THE RIGHT VALUE
this.pushClickEventToGA(window.currentlySelectedValues[window.lastFocusedInputGroup])
}
},
}, },
computed: { computed: {
isChecked() { isChecked() {

View file

@ -22,8 +22,7 @@
<legend <legend
class="sr-only" class="sr-only"
:data-focus-target="formatString(groupName)" :data-focus-target="formatString(groupName)"
:id="formatString(groupName)" :id="formatString(groupName)">
tabindex="-1">
{{ questionText }} {{ questionText }}
{{ {{
isMultiSelect && answers && answers.length > 1 isMultiSelect && answers && answers.length > 1
@ -51,6 +50,8 @@
:validationRules="validationRules" :validationRules="validationRules"
:textPosition="textPosition" :textPosition="textPosition"
:selectOnKeypress="selectOnKeypress" :selectOnKeypress="selectOnKeypress"
@blur="handleBlur"
@focus="handleFocus"
@buttonClicked="handleAnswerChange" /> @buttonClicked="handleAnswerChange" />
<!-- For nested questions --> <!-- For nested questions -->
<transition name="fade" mode="out-in"> <transition name="fade" mode="out-in">
@ -123,6 +124,7 @@ export default {
data() { data() {
return { return {
primaryValue: "", primaryValue: "",
lastFocusedInputGroup: "",
}; };
}, },
computed: { computed: {
@ -175,10 +177,6 @@ export default {
} }
}, },
buttonsInfo() { buttonsInfo() {
console.log({
answers: this.answers,
isArray: Array.isArray(this.answers),
});
// TODO KO temporary. It should always just be an array // TODO KO temporary. It should always just be an array
return (Array.isArray(this.answers) ? this.answers : [])?.map( return (Array.isArray(this.answers) ? this.answers : [])?.map(
(answer) => ({ (answer) => ({
@ -191,7 +189,8 @@ export default {
buttonImageId: answer.buttonImageId ?? answer.ImageId, buttonImageId: answer.buttonImageId ?? answer.ImageId,
groupName: this.formatString(this.groupName), groupName: this.formatString(this.groupName),
value: value:
answer.value ?? (this.useTextForValue answer.value ??
(this.useTextForValue
? answer.Text ? answer.Text
: answer.Name ?? answer), : answer.Name ?? answer),
}) })
@ -225,6 +224,17 @@ export default {
this.$emit("buttonQuestionChange", primaryAnswerValue); this.$emit("buttonQuestionChange", primaryAnswerValue);
this.$emit("update:modelValue", primaryAnswerValue); this.$emit("update:modelValue", primaryAnswerValue);
}, },
handleBlur() {
// this.lastFocusedInputGroup = this.groupName;
// window.lastFocusedInputGroup = this.groupName
// console.log("blur: ", this.groupName);
},
handleFocus() {
// console.log("focused: ", {
// groupName: this.groupName,
// lastFocusedInputGroup: this.lastFocusedInputGroup,
// });
},
}, },
components: { components: {
listButton, listButton,

View file

@ -1,67 +1,62 @@
import { shallowMount } from "@vue/test-utils"; import { shallowMount } from "@vue/test-utils";
import windshieldChipCountQuestion from "@/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question"; import windshieldChipCountQuestion from "@/layouts/vehicle-damage/windshield-options/windshield-chip-count-question/windshield-chip-count-question";
import { getMountOptions } from "@/helpers/unit-test-helper.js"; import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { nextTick } from "vue";
import store from "@/store"; import store from "@/store";
jest.mock("@/store", () => { return {}; }, {virtual: true}); jest.mock(
"@/store",
() => {
return {};
},
{ virtual: true }
);
describe("windshield-chip-count-question.vue", () => { describe("windshield-chip-count-question.vue", () => {
test("Selected chip count is emitted upon selection.", async () => { test("Selected chip count is emitted upon selection.", async () => {
//Arrange //Arrange
const { wrapper } = setupMocks({modelValueProp: ["One"]}); const { wrapper } = setupMocks({ modelValueProp: 1 });
//Act //Act
wrapper.setValue({ modelValue: ["Two"] }); await wrapper.setData({ numberOfChips: 2 });
await wrapper.vm.$nextTick();
//Assert //Assert
expect(wrapper.vm.selectedChipCountValues).toEqual(["One"]); expect(wrapper.emitted()["update:modelValue"][0]).toEqual([2]);
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ modelValue: ["Two"] }]);
}); });
}); });
describe("Windshield-chip-count-question.vue", () => { function setupMocks({
test("Should display question and answers from api.", async () => {
//Arrange
const { wrapper } = setupMocks({modelValueProp: ["One"]});
//Act
wrapper.setProps({isAvailable: true});
wrapper.vm.updateSelectedValues = jest.fn();
await wrapper.vm.$nextTick();
//Assert
expect(wrapper.vm.updateSelectedValues).toBeCalled();
});
});
function setupMocks({
modelValueProp = ["Two"], modelValueProp = ["Two"],
groupName = "WindshieldChipCountQuestion", groupName = "WindshieldChipCountQuestion",
cmsQuestionText = "How many chips are we repairing?", cmsQuestionText = "How many chips are we repairing?",
cmsAnswers = [{Name: "One"}, {Name: "Two"}, {Name: "Three"}], cmsAnswers = [{ Name: "One" }, { Name: "Two" }, { Name: "Three" }],
dataFromStoreApi = [], dataFromStoreApi = [],
}) { }) {
//Mock store //Mock store
store.dispatch = jest.fn(() => dataFromStoreApi); store.dispatch = jest.fn(() => dataFromStoreApi);
store.getters = { vehicle: {year: 2019, make: 'honda', model: 'civc', style: '2 Door', category: 'CAR'} }; store.getters = {
vehicle: {
year: 2019,
make: "honda",
model: "civc",
style: "2 Door",
category: "CAR",
},
};
const mountOptions = getMountOptions({ const mountOptions = getMountOptions({
store: { store: {
dispatch: store.dispatch, dispatch: store.dispatch,
getters: store.getters, getters: store.getters,
}, },
}); });
//Mock props //Mock props
const mockMixin = { const mockMixin = {
methods: { methods: {
getCmsContent: jest.fn() getCmsContent: jest.fn(),
} },
} };
mountOptions.propsData = { mountOptions.propsData = {
modelValue: modelValueProp modelValue: modelValueProp,
}; };
mountOptions.mixins = [mockMixin]; mountOptions.mixins = [mockMixin];
@ -69,10 +64,10 @@ describe("windshield-chip-count-question.vue", () => {
//Mock CMS content //Mock CMS content
const cmsContent = { const cmsContent = {
groupName: groupName, groupName: groupName,
QuestionText: cmsQuestionText, QuestionText: cmsQuestionText,
Answers: cmsAnswers, Answers: cmsAnswers,
}; };
const damageOptions = dataFromStoreApi; const damageOptions = dataFromStoreApi;
return { wrapper, cmsContent, damageOptions }; return { wrapper, cmsContent, damageOptions };
} }

View file

@ -6,22 +6,22 @@ import store from "@/store";
jest.mock("@/store", () => { return {}; }, {virtual: true}); jest.mock("@/store", () => { return {}; }, {virtual: true});
describe("windshield-damage-type-question.vue", () => { describe("windshield-damage-type-question.vue", () => {
test("Selected chip count is emitted upon selection.", async () => { test("Selected windshield damage is emitted upon selection.", async () => {
//Arrange //Arrange
const { wrapper } = setupMocks({modelValueProp: ["Repair"]}); const { wrapper } = setupMocks({modelValueProp: "Repair"});
//Act //Act
wrapper.setValue({ modelValue: ["Replace"] }); wrapper.setValue({ modelValue: "Replace" });
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
//Assert //Assert
expect(wrapper.vm.selectedValues).toEqual(["Repair"]); expect(wrapper.vm.selectedWindshieldDamageType).toEqual("Repair");
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ modelValue: ["Replace"] }]); expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ modelValue: "Replace" }]);
}); });
}); });
function setupMocks({ function setupMocks({
modelValueProp = ["Two"], modelValueProp = "",
groupName = "WindshieldDamageTypeQuestion", groupName = "WindshieldDamageTypeQuestion",
cmsQuestionText = "What's your windshield damage?", cmsQuestionText = "What's your windshield damage?",
cmsAnswers = [{Name: "Repair"}, {Name: "Replace"}], cmsAnswers = [{Name: "Repair"}, {Name: "Replace"}],

View file

@ -7,12 +7,16 @@ export default {
buttonLabel: [Number, String], buttonLabel: [Number, String],
buttonLabelSubCopy: String, buttonLabelSubCopy: String,
buttonImage: String, buttonImage: String,
altText: String, altText: {
type: String,
default: ""
},
textPosition: String, textPosition: String,
screenReaderOnlyText: String, screenReaderOnlyText: String,
valueToLogType: String, valueToLogType: String,
validationRules: String, validationRules: String,
isWide: Boolean isWide: Boolean,
isRequired: Boolean
}, },
data() { data() {
return { return {

View file

@ -4,7 +4,6 @@
buttonWrapperClasses="list-group list-button rounded-3 d-flex flex-column w-100 mb-2" buttonWrapperClasses="list-group list-button rounded-3 d-flex flex-column w-100 mb-2"
@buttonClicked="handleAnswerChange"> @buttonClicked="handleAnswerChange">
<div <div
tabindex="-1"
:aria-label="buttonLabel" :aria-label="buttonLabel"
class="list-button-content d-flex flex-column justify-content-center py-3 px-4"> class="list-button-content d-flex flex-column justify-content-center py-3 px-4">
<span class="m-0" :class="textPosition"> <span class="m-0" :class="textPosition">

View file

@ -1,12 +1,12 @@
import { shallowMount } from "@vue/test-utils"; import { mount } from "@vue/test-utils";
import listCard from "./list-card"; import listCard from "./list-card";
import { nextTick } from "vue"; import { nextTick } from "vue";
import { GaActions } from "@/constants/analytics"; import { GaActions } from "@/constants/analytics";
describe("list-card.vue", () => { describe("list-card.vue", () => {
it("Should return input type checkbox if isMultiSelect is true", async () => { it("Should return input type checkbox if isMultiSelect is true", () => {
// Act // Act
const wrapper = shallowMount(listCard, { const wrapper = mount(listCard, {
propsData: { propsData: {
isMultiSelect: true, isMultiSelect: true,
buttonLabel: "Windshield", buttonLabel: "Windshield",
@ -22,9 +22,9 @@ describe("list-card.vue", () => {
expect(input.attributes().type).toEqual("checkbox"); expect(input.attributes().type).toEqual("checkbox");
}); });
it("Should return primary label text", async () => { it("Should return primary label text", () => {
// Act // Act
const wrapper = shallowMount(listCard, { const wrapper = mount(listCard, {
propsData: { propsData: {
isRadioHorizontal: true, isRadioHorizontal: true,
buttonLabel: "Windshield", buttonLabel: "Windshield",
@ -40,9 +40,9 @@ describe("list-card.vue", () => {
expect(paragraph.text()).toEqual("Windshield"); expect(paragraph.text()).toEqual("Windshield");
}); });
it("Should return secondary (sub) label text", async () => { it("Should return secondary (sub) label text", () => {
// Act // Act
const wrapper = shallowMount(listCard, { const wrapper = mount(listCard, {
propsData: { propsData: {
isRadioHorizontal: true, isRadioHorizontal: true,
buttonLabel: "Windshield", buttonLabel: "Windshield",
@ -59,28 +59,9 @@ describe("list-card.vue", () => {
expect(paragraph.text()).toEqual("Test"); expect(paragraph.text()).toEqual("Test");
}); });
it("Should return value used for various text settings including the label 'for' and input id", async () => { it("Should return input group name used for radio or checkbox", () => {
// Act // Act
const wrapper = shallowMount(listCard, { const wrapper = mount(listCard, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
buttonID: "List Card Checkbox",
groupID: "radio-demo-1",
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
buttonLabelSubCopy: "Test",
},
});
// Assert
const label = wrapper.find("label");
expect(label.attributes().for).toEqual("List Card Checkbox");
});
it("Should return input group name used for radio or checkbox", async () => {
// Act
const wrapper = shallowMount(listCard, {
propsData: { propsData: {
isRadioHorizontal: true, isRadioHorizontal: true,
buttonLabel: "Windshield", buttonLabel: "Windshield",
@ -97,9 +78,9 @@ describe("list-card.vue", () => {
expect(input.attributes().name).toEqual("radio 1"); expect(input.attributes().name).toEqual("radio 1");
}); });
it("Should return aria-required state", async () => { it("Should return aria-required state", () => {
// Act // Act
const wrapper = shallowMount(listCard, { const wrapper = mount(listCard, {
propsData: { propsData: {
isRadioHorizontal: true, isRadioHorizontal: true,
buttonLabel: "Windshield", buttonLabel: "Windshield",
@ -116,9 +97,9 @@ describe("list-card.vue", () => {
expect(input.attributes()["aria-required"]).toEqual("true"); expect(input.attributes()["aria-required"]).toEqual("true");
}); });
it("Should return flex row classes if isWide is true", async () => { it("Should return flex row classes if isWide is true", () => {
// Act // Act
const wrapper = shallowMount(listCard, { const wrapper = mount(listCard, {
propsData: { propsData: {
isRadioHorizontal: true, isRadioHorizontal: true,
buttonLabel: "Windshield", buttonLabel: "Windshield",
@ -133,13 +114,16 @@ describe("list-card.vue", () => {
}); });
// Assert // Assert
const label = wrapper.find("label"); const label = wrapper.find(".list-card-content");
expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-row", "py-2", "ps-4", "pe-4"]); expect(label.exists()).toBe(true);
const labelClasses = wrapper.vm.labelClasses;
expect(labelClasses).toContain("flex-row");
expect(label.classes()).toContain("flex-row");
}); });
it("Should return flex row classes if isWide is true and checkboxTop if buttonLabelSubCopy is true", async () => { it("Should return flex row classes if isWide is true and checkboxTop if buttonLabelSubCopy is provided", () => {
// Act // Act
const wrapper = shallowMount(listCard, { const wrapper = mount(listCard, {
propsData: { propsData: {
isRadioHorizontal: true, isRadioHorizontal: true,
buttonLabel: "Windshield", buttonLabel: "Windshield",
@ -154,13 +138,18 @@ describe("list-card.vue", () => {
}); });
// Assert // Assert
const label = wrapper.find("label"); const label = wrapper.find(".list-card-content");
expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-row", "py-2", "ps-4", "pe-4", "checkboxTop"]); expect(label.exists()).toBe(true);
const labelClasses = wrapper.vm.labelClasses;
expect(labelClasses).toContain("flex-row");
expect(label.classes()).toContain("flex-row");
expect(labelClasses).toContain("checkboxTop");
expect(label.classes()).toContain("checkboxTop");
}); });
it("Should return flex column classes if isWide is false", async () => { it("Should return flex column classes if isWide is false", () => {
// Act // Act
const wrapper = shallowMount(listCard, { const wrapper = mount(listCard, {
propsData: { propsData: {
isRadioHorizontal: true, isRadioHorizontal: true,
buttonLabel: "Windshield", buttonLabel: "Windshield",
@ -174,161 +163,10 @@ describe("list-card.vue", () => {
}); });
// Assert // Assert
const label = wrapper.find("label"); const label = wrapper.find(".list-card-content");
expect(label.classes()).toEqual(["d-flex", "w-100", "align-items-center", "px-2", "h-100", "flex-column", "pt-4", "pb-3"]); expect(label.exists()).toBe(true);
const labelClasses = wrapper.vm.labelClasses;
expect(labelClasses).toContain("flex-column");
expect(label.classes()).toContain("flex-column");
}); });
it("Should emit button value on click", async () => {
// Act
const wrapper = shallowMount(listCard, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
value: "List Card Checkbox",
groupID: "radio-demo-1",
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
isRequired: true,
isWide: false,
buttonID: 'list-card-id',
selectedValues: "List Card Checkbox"
},
});
wrapper.vm.handleCheckChange();
// Assert
expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{value: "List Card Checkbox", checkValue: true, buttonId: 'list-card-id'}]);
});
it("Should set checkValue data if selectedButtonIDs has value(s)", async () => {
// Act
const wrapper = shallowMount(listCard, {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
value: "List Card Checkbox",
groupID: "radio-demo-1",
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
isRequired: true,
isWide: false,
selectedValues: "Car-Front"
},
});
// Assert
expect(wrapper.componentVM.checkValue).toEqual(false);
});
it("Should set an initial value for validation if selectedValues include the value", async () => {
// Arrange
const wrapper = shallowMount(listCard, {
propsData: {
value: "Windshield",
groupName: "radio 1",
selectedValues: ["Windshield"],
},
});
// Assert
expect(wrapper.vm.fieldOptions.initialValue).toEqual([ 'Windshield' ]);
});
it("Should run handleCheckChange if selectingInitiatesLoad is false and handleInputChange is triggered", async () => {
// Act
const wrapper = shallowMount(listCard, {
propsData: {
selectingInitiatesLoad: false,
},
});
// Assert
wrapper.vm.handleInputChange();
await nextTick();
expect(wrapper.vm.handleCheckChange).toBeCalled;
});
it("Should do nothing if isMultiSelect is true and handleKeyupArrow is triggered", async () => {
// Act
const wrapper = shallowMount(listCard, {
propsData: {
isMultiSelect: true,
},
});
// Assert
wrapper.vm.handleKeyupArrow();
await nextTick();
expect(wrapper.vm.handleKeyupArrow).toHaveReturned;
});
it("Should run handleCheckChange if selectingInitiatesLoad is false and handleKeyupArrow is triggered", async () => {
// Act
const wrapper = shallowMount(listCard, {
propsData: {
selectingInitiatesLoad: false,
isMultiSelect: false,
},
});
// Assert
wrapper.vm.handleKeyupArrow();
await nextTick();
expect(wrapper.vm.handleCheckChange).toBeCalled;
});
it("Should run handleChange if triggerButton is triggered", async () => {
// Act
const wrapper = shallowMount(listCard, {
global: {
mocks: {
'$route': { query: { fmgPage: 'page-name' } },
GaActions: GaActions,
pushEventToGA: jest.fn(),
}
},
propsData: {
selectingInitiatesLoad: false,
},
});
// Assert
wrapper.vm.triggerButton();
await nextTick();
expect(wrapper.vm.handleChange).toBeCalled;
expect(wrapper.vm.handleCheckChange).not.toBeCalled;
expect(wrapper.vm.displayLoader).not.toBeCalled;
});
it("Should run handleCheckChange and displayLoader if triggerButton is triggered and seletingInitiatesLoad is true", async () => {
// Act
const wrapper = shallowMount(listCard, {
global: {
mocks: {
'$route': { query: { fmgPage: 'page-name' } },
GaActions: GaActions,
pushEventToGA: jest.fn(),
}
},
propsData: {
selectingInitiatesLoad: true,
},
});
// Assert
wrapper.vm.triggerButton();
await nextTick();
expect(wrapper.vm.handleCheckChange).toBeCalled;
expect(wrapper.vm.displayLoader).toBeCalled;
});
}); });

View file

@ -8,7 +8,7 @@
@buttonClicked="handleAnswerChange"> @buttonClicked="handleAnswerChange">
<div <div
class="d-flex w-100 align-items-center px-2 h-100 list-card-content" class="d-flex w-100 align-items-center px-2 h-100 list-card-content"
:class="getLabelClasses"> :class="labelClasses">
<img <img
:id="buttonImageId" :id="buttonImageId"
:class="!isWide ? 'order-1' : 'ms-auto order-3'" :class="!isWide ? 'order-1' : 'ms-auto order-3'"
@ -46,7 +46,7 @@ export default {
baseInputButton, baseInputButton,
}, },
computed: { computed: {
getLabelClasses() { labelClasses() {
if (this.isWide) { if (this.isWide) {
let classes = "flex-row py-2 ps-4 pe-4"; let classes = "flex-row py-2 ps-4 pe-4";
if (this.buttonLabelSubCopy) { if (this.buttonLabelSubCopy) {

View file

@ -1,117 +1,60 @@
import { shallowMount } from "@vue/test-utils"; import { mount } from "@vue/test-utils";
import radio from "./radio"; import radio from "./radio";
import { nextTick } from "vue"; import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { GaActions } from "@/constants/analytics"; import inputButtonWrapperMixin from "@/mixins/input-button-wrapper-mixin";
describe("radio.vue", () => { describe("radio.vue", () => {
it("Should return group name", async () => { it("Should have correct group name", async () => {
// Act // Arrange
const wrapper = shallowMount(radio, { let { wrapper } = setupMocks({});
propsData: {
groupName: "radio-button-test", // Act
}, await wrapper.setProps({
groupName: "radio-button-test",
});
const input = wrapper.find("input");
// Assert
expect(input.attributes().name).toEqual("radio-button-test");
}); });
// Assert it("Should have correct label text", async () => {
const input = wrapper.find("input"); // Act
let { wrapper } = setupMocks({});
// Expect // Arrange
expect(input.attributes().name).toEqual("radio-button-test"); await wrapper.setProps({
}); buttonLabel: "label text",
});
const paragraph = wrapper.find("p");
it("Should return checkbox id", async () => { // Assert
// Act expect(paragraph.text()).toEqual("label text");
const wrapper = shallowMount(radio, {
propsData: {
buttonID: "Radio ID",
},
}); });
// Assert it("Should have correct screenreader-only text", async () => {
const input = wrapper.find("input"); // Act
let { wrapper } = setupMocks({});
// Expect // Arrange
expect(input.attributes().id).toEqual("Radio ID"); await wrapper.setProps({
}); screenReaderOnlyText: "screenreader text",
});
const paragraph = wrapper.find(".sr-only");
it("Should return label text", async () => { // Assert
// Act expect(paragraph.text()).toEqual("screenreader text");
const wrapper = shallowMount(radio, {
propsData: {
buttonLabel: "label text",
},
}); });
// Assert
const paragraph = wrapper.find("p");
expect(paragraph.text()).toEqual("label text");
});
it("Should return label text", async () => {
// Act
const wrapper = shallowMount(radio, {
propsData: {
screenReaderOnlyText: "screenreader text",
},
});
// Assert
const paragraph = wrapper.find("span");
expect(paragraph.text()).toEqual("screenreader text");
});
it("Should emit button value on click", async () => {
// Act
const wrapper = shallowMount(radio, {
global: {
mocks: {
'$route': { query: { fmgPage: 'page-name' } },
GaActions: GaActions,
pushEventToGA: jest.fn(),
}
},
propsData: {
buttonLabel: "Windshield",
value: "List Card Checkbox",
buttonID: "List Card Checkbox",
groupID: "radio-demo-1",
groupName: "radio 1",
isRequired: true,
isWide: false,
modelValue: ["List Card Checkbox"],
},
});
wrapper.vm.handleCheckChange();
// Assert
expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{"buttonID": "List Card Checkbox", value: "List Card Checkbox", checkValue: false}]);;
expect(wrapper.vm.pushEventToGA).toHaveBeenCalled();
});
it("Should set checkValue data if selectedButtonIDs has value(s)", async () => {
// Act
const wrapper = shallowMount(radio, {
global: {
mocks: {
'$route': { query: { fmgPage: 'page-name' } },
GaActions: GaActions,
pushEventToGA: jest.fn(),
}
},
propsData: {
buttonLabel: "Windshield",
buttonID: "List Card Checkbox",
groupID: "radio-demo-1",
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
isRequired: true,
modelValue: ["List Card Checkbox"],
value: "Car-Front",
selectedValues: "Car-Front"
},
});
// Assert
expect(wrapper.componentVM.checkValue).toEqual(true);
});
}); });
function setupMocks({ mountOptionsMockData = {} }) {
const wrapper = mount(
radio,
getMountOptions({
...mountOptionsMockData,
mixins: [inputButtonWrapperMixin],
})
);
return { wrapper };
}

View file

@ -4,7 +4,7 @@
buttonWrapperClasses="ui-radio form-check" buttonWrapperClasses="ui-radio form-check"
inputClasses="form-check-input" inputClasses="form-check-input"
@buttonClicked="handleAnswerChange"> @buttonClicked="handleAnswerChange">
<div class="d-flex align-items-start form-check-label" :for="buttonID"> <div class="d-flex align-items-start form-check-label">
<p v-if="buttonLabel" class="m-0">{{ buttonLabel }}</p> <p v-if="buttonLabel" class="m-0">{{ buttonLabel }}</p>
<span v-if="screenReaderOnlyText" class="sr-only">{{ <span v-if="screenReaderOnlyText" class="sr-only">{{
screenReaderOnlyText screenReaderOnlyText