DigitalConsumer.FixMyGlass/src/mixins/input-button-wrapper-mixin.spec.js
2024-08-27 16:18:22 -04:00

314 lines
13 KiB
JavaScript

import { mount } from "@vue/test-utils";
import baseInputButton from "@/digital-components/base-input-button/base-input-button";
import inputButtonWrapperMixin from "@/mixins/input-button-wrapper-mixin";
import listButtonHorizontal from "@/ux-components/list-button-horizontal/list-button-horizontal";
import listButton from "@/ux-components/list-button/list-button";
import listCard from "@/ux-components/list-card/list-card";
import radio from "@/ux-components/radio/radio";
describe("input-button-wrapper-mixin", () => {
describe("mouse clicks", () => {
describe("checkbox", () => {
test("click on both => both are selected", async () => {
// Arrange
const { wrapper } = setupBaseInputButtonWrapper({
mockData: {
isMultiSelect: true,
},
});
// Act
const buttonWrappers = wrapper.findAllComponents({
name: "baseInputButtonWrapper",
});
const inputButtonOne = buttonWrappers.at(0);
const inputButtonTwo = buttonWrappers.at(1);
expect(inputButtonOne.vm.isMultiSelect).toBe(true);
expect(inputButtonTwo.vm.isMultiSelect).toBe(true);
expect(wrapper.vm.value).toEqual([]);
await inputButtonOne.find("input").setChecked();
await inputButtonTwo.find("input").setChecked();
// Assert
expect(wrapper.vm.value).toEqual(["value1", "value2"]);
});
test("click input 1, 2, 1 => only input 2 selected", async () => {
// Arrange
const { wrapper } = setupBaseInputButtonWrapper({
mockData: {
isMultiSelect: true,
},
});
// Act
const buttonWrappers = wrapper.findAllComponents({
name: "baseInputButtonWrapper",
});
const inputButtonOne = buttonWrappers.at(0);
const inputButtonTwo = buttonWrappers.at(1);
expect(inputButtonOne.vm.isMultiSelect).toBe(true);
expect(inputButtonTwo.vm.isMultiSelect).toBe(true);
expect(wrapper.vm.value).toEqual([]);
await inputButtonOne.find("input").setChecked();
await inputButtonTwo.find("input").setChecked();
await inputButtonOne.find("input").setChecked(false);
// Assert
expect(wrapper.vm.value).toEqual(["value2"]);
});
});
describe("radio", () => {
test("click on both => last clicked is selected", async () => {
// Arrange
const { wrapper } = setupBaseInputButtonWrapper({
mockData: {
isMultiSelect: false,
},
});
// Act
const buttonWrappers = wrapper.findAllComponents({
name: "baseInputButtonWrapper",
});
const inputButtonOne = buttonWrappers.at(0);
const inputButtonTwo = buttonWrappers.at(1);
expect(inputButtonOne.vm.isMultiSelect).toBe(false);
expect(inputButtonTwo.vm.isMultiSelect).toBe(false);
expect(wrapper.vm.value).toEqual("");
await inputButtonOne.find("input").setChecked();
await inputButtonTwo.find("input").setChecked();
// Assert
expect(wrapper.vm.value).toEqual("value2");
});
test("click input 1, 2, 1 => input 1 is selected", async () => {
// Arrange
const { wrapper } = setupBaseInputButtonWrapper({
mockData: {
isMultiSelect: false,
},
});
// Act
const buttonWrappers = wrapper.findAllComponents({
name: "baseInputButtonWrapper",
});
const inputButtonOne = buttonWrappers.at(0);
const inputButtonTwo = buttonWrappers.at(1);
expect(inputButtonOne.vm.isMultiSelect).toBe(false);
expect(inputButtonTwo.vm.isMultiSelect).toBe(false);
expect(wrapper.vm.value).toEqual("");
await inputButtonOne.find("input").setChecked();
await inputButtonTwo.find("input").setChecked();
await inputButtonOne.find("input").setChecked();
// Assert
expect(wrapper.vm.value).toEqual("value1");
});
});
});
describe("initial values", () => {
describe("checkbox", () => {
const defaultCheckedCases = [
[["value2"], false, true],
[["value1", "value2"], true, true],
[["value1"], true, false],
[[], false, false],
];
test.each(defaultCheckedCases)(
"initial value is %s => correct input buttons are selected",
async (modelValue, isInputButtonOneChecked, isInputButtonTwoChecked) => {
// Arrange
const { wrapper } = setupBaseInputButtonWrapper({
mockData: {
isMultiSelect: true,
initialValue: modelValue,
},
});
// Act
const buttonWrappers = wrapper.findAllComponents({
name: "baseInputButtonWrapper",
});
const inputs = wrapper.findAll("input");
const inputButtonOne = buttonWrappers.at(0);
const inputButtonTwo = buttonWrappers.at(1);
// Assert
expect(inputButtonOne.vm.isMultiSelect).toBe(true);
expect(inputButtonTwo.vm.isMultiSelect).toBe(true);
expect(inputs[0].element.checked).toBe(isInputButtonOneChecked);
expect(inputs[1].element.checked).toBe(isInputButtonTwoChecked);
expect(wrapper.vm.value).toEqual(modelValue);
}
);
});
describe("radio", () => {
const defaultCheckedCases = [
["", false, false],
["value1", true, false],
["value2", false, true],
[[], false, false],
];
test.each(defaultCheckedCases)(
"initial value is %s => correct input buttons are selected",
async (modelValue, isInputButtonOneChecked, isInputButtonTwoChecked) => {
// Arrange
const { wrapper } = setupBaseInputButtonWrapper({
mockData: {
isMultiSelect: false,
initialValue: modelValue,
},
});
// Act
const buttonWrappers = wrapper.findAllComponents({
name: "baseInputButtonWrapper",
});
const inputs = wrapper.findAll("input");
const inputButtonOne = buttonWrappers.at(0);
const inputButtonTwo = buttonWrappers.at(1);
// Assert
expect(inputButtonOne.vm.isMultiSelect).toBe(false);
expect(inputButtonTwo.vm.isMultiSelect).toBe(false);
expect(inputs[0].element.checked).toBe(isInputButtonOneChecked);
expect(inputs[1].element.checked).toBe(isInputButtonTwoChecked);
expect(wrapper.vm.value).toEqual(modelValue);
}
);
});
});
// shared checks between components that use input-button-wrapper-mixin
describe("shared checks", () => {
const inputButtonComponents = [listButtonHorizontal, listButton, listCard, radio];
test.each(inputButtonComponents.map((x) => [x.name, x]))(
"%s - should return input type checkbox if isMultiSelect is true",
async (name, inputButtonComponent) => {
// Act
const { wrapper } = setupMocksForComponentsUsingInputButtonWrapperMixin({
component: inputButtonComponent,
mockData: {
propsData: {
isMultiSelect: true,
},
},
});
// Assert
const input = wrapper.find("input");
expect(input.attributes().type).toEqual("checkbox");
}
);
test.each(inputButtonComponents.map((x) => [x.name, x]))(
"%s - return input type radio if isMultiSelect is false or not specified",
async (name, inputButtonComponent) => {
// Act
const { wrapper } = setupMocksForComponentsUsingInputButtonWrapperMixin({
component: inputButtonComponent,
mockData: {
propsData: {
isMultiSelect: false,
},
},
});
// Assert
const input = wrapper.find("input");
expect(input.attributes().type).toEqual("radio");
}
);
const selectedValues = ["something", ["test"]];
inputButtonComponents.forEach((inputButtonComponent) => {
test.each(selectedValues)(
`${inputButtonComponent.name} with selectedValue %s - should emit button value on click`,
async (selectedValue) => {
// Act
const { wrapper } = setupMocksForComponentsUsingInputButtonWrapperMixin({
component: inputButtonComponent,
mockData: {
propsData: {
isRadioHorizontal: true,
buttonLabel: "Windshield",
value: "List Card Checkbox",
groupID: "radio-demo-1",
groupName: "radio 1",
buttonImage: "windshield-damage.svg",
isRequired: true,
isWide: false,
modelValue: ["List Card Checkbox"],
buttonID: "list-card-id",
},
},
});
// Act
wrapper.vm.selectedValue = selectedValue;
await wrapper.vm.$nextTick();
// Assert
expect(wrapper.emitted()["update:modelValue"][0][0]).toEqual(selectedValue);
}
);
});
});
});
function setupMocksForComponentsUsingInputButtonWrapperMixin({ mockData, component }) {
const wrapper = mount(component, {
...mockData,
propsData: {
...mockData.propsData,
groupName: "my-group",
modelValue: mockData.propsData?.isMultiSelect ? ["5"] : "5",
value: "4",
},
mixins: [inputButtonWrapperMixin],
});
return { wrapper };
}
function setupBaseInputButtonWrapper({ mockData = {} }) {
baseInputButton.methods.pushClickEventToGA = jest.fn();
const baseInputButtonWrapper = {
name: "baseInputButtonWrapper",
components: { baseInputButton },
template: '<div><baseInputButton v-bind="$props" v-model="selectedValue" /></div>',
mixins: [inputButtonWrapperMixin],
};
let parentComponentTemplate = `<div>`;
parentComponentTemplate += `<baseInputButtonWrapper v-model="value" groupName="myGroupName" :isMultiSelect="${mockData.isMultiSelect}" value="value1" />`;
parentComponentTemplate += `<baseInputButtonWrapper v-model="value" groupName="myGroupName" :isMultiSelect="${mockData.isMultiSelect}" value="value2" />`;
parentComponentTemplate += `</div>`;
const wrapper = mount({
data() {
return {
value: mockData.initialValue ?? (mockData.isMultiSelect ? [] : ""),
$route: {
query: {
fmgPage: "myPage",
},
},
};
},
template: parentComponentTemplate,
components: { baseInputButtonWrapper },
});
return { wrapper };
}