import { shallowMount, mount } from "@vue/test-utils"; import baseInputButton from "./base-input-button"; describe("baseInputButton.vue", () => { describe("general", () => { describe("checkbox", () => { test("isMultiSelect => baseInputButton is a checkbox", () => { // Arrange/Act const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: true, }, }, }); // Assert const inputElement = wrapper.find("input"); expect(inputElement.attributes().type).toEqual("checkbox"); }); }); describe("radio", () => { test("!isMultiSelect => baseInputButton is a radio button", () => { // Arrange/Act const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: false, }, }, }); // Assert const inputElement = wrapper.find("input"); expect(inputElement.attributes().type).toEqual("radio"); }); }); // tests in here should be test.each describe("shared", () => { const isMultiSelectOptions = [true, false]; test.each(isMultiSelectOptions)("groupName", (isMultiSelect) => { const { wrapper } = setupMocks({ mockData: { propsData: { groupName: "boogly", isMultiSelect: isMultiSelect, }, }, }); // Assert const inputElement = wrapper.find("input"); const inputElementAttributes = inputElement.attributes(); expect(inputElementAttributes.name).toEqual("boogly"); }); }); }); describe("mouse clicks", () => { describe("checkbox", () => { test("clicked => correct event and value are emitted", async () => { // Arrange const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: true, value: "X", }, }, }); // Act await wrapper.trigger("mousedown.left"); await wrapper.trigger("click"); // Assert expect(wrapper.emitted()["inputButtonClicked"][0][0]).toEqual([ "X", ]); }); }); describe("radio", () => { test("clicked => correct event and value are emitted", async () => { // Arrange const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: false, value: "X", }, }, }); // Act await wrapper.trigger("mousedown.left"); await wrapper.trigger("click"); // Assert expect(wrapper.emitted()["inputButtonClicked"][0][0]).toEqual( "X" ); }); }); }); describe("keyboard navigation and events", () => { describe("checkbox", () => { test.todo( "focus on a checkbox => inputButtonClicked is not emitted" ); test.todo( "blur from a checkbox => inputButtonClicked is not emitted" ); test("change event fired from checkbox => inputButtonClicked is emitted with correct value", async () => { // Arrange const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: true, value: "Hi", }, }, }); const input = wrapper.find("input"); // Act await input.trigger("change"); // Assert expect(wrapper.emitted()["inputButtonClicked"][0][0]).toEqual([ "Hi", ]); }); test("focus and click space on a checkbox => inputButtonClicked is not emitted", async () => { // Arrange const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: true, value: "Hi", }, }, }); const input = wrapper.find("input"); // Act await input.trigger("keypress", { key: "space" }); // Assert expect(wrapper.emitted()).not.toHaveProperty( "inputButtonClicked" ); }); test("focus and click enter on a checkbox => inputButtonClicked is emitted with correct value", async () => { // Arrange const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: true, value: "Hi", }, }, }); const input = wrapper.find("input"); // Act await input.trigger("keypress", { key: "enter" }); // Assert expect(wrapper.emitted()["inputButtonClicked"][0][0]).toEqual([ "Hi", ]); }); }); describe("radio", () => { test.todo( "focus on a radio button => inputButtonClicked is not emitted" ); test.todo( "blur from a radio button => inputButtonClicked is not emitted" ); test("focus and click space on a radio button => inputButtonClicked is emitted with correct value", async () => { // Arrange const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: false, value: "Hi", }, }, }); const input = wrapper.find("input"); // Act await input.trigger("keypress", { key: "space" }); // Assert expect(wrapper.emitted()).toHaveProperty("inputButtonClicked"); expect(wrapper.emitted()["inputButtonClicked"][0][0]).toEqual( "Hi" ); }); test( "focus and click enter on a radio button => inputButtonClicked is emitted with correct value", async () => { // Arrange const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: false, value: "Hi", }, }, }); const input = wrapper.find("input"); // Act await input.trigger("keypress", { key: "enter" }); // Assert expect(wrapper.emitted()).toHaveProperty( "inputButtonClicked" ); expect( wrapper.emitted()["inputButtonClicked"][0][0] ).toEqual("Hi"); } ); }); }); describe("methods", () => { describe("handleEventAction", () => {}); describe("handleSelectionChange", () => { test.todo("handleChange is called with valueToEmit") describe("checkbox", () => { test.todo("modelValue is null => valueToEmit is correct value") test.todo("modelValue is undefined => valueToEmit is correct value") test.todo("modelValue is empty => valueToEmit is correct value") test.todo("modelValue is not empty and does not contain this button's value => valueToEmit is correct value") test.todo("modelValue is not empty and does contain this button's value => valueToEmit is correct value") }) describe("radio", () => { }) }); describe("handleClick", () => { test.todo("handleSelectChange is also called") test.todo("inputButtonClicked is emitted with valueToEmit") }); }); describe("computed", () => { describe("isChecked", () => { describe("checkbox", () => { const falsyModelValues = [[], null, undefined]; test.each(falsyModelValues)( "modelValue is falsy/empty => checkbox isn't checked", (modelValue) => { // Arrange/Act const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: true, modelValue, }, }, }); // Assert const inputElement = wrapper.find("input"); expect(wrapper.vm.isChecked).toEqual(false); expect(inputElement.element.checked).toBe(false); } ); test("modelValue doesn't contain this button's value => checkbox isn't checked", async () => { // Arrange/Act const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: true, modelValue: ["Aaa", "Bbb", "Ccc"], value: "Ddd", }, }, }); await wrapper.vm.$nextTick(); // Assert const inputElement = wrapper.find("input"); expect(wrapper.vm.isChecked).toEqual(false); expect(inputElement.element.checked).toBe(false); }); test("modelValue contains this button's value => checkbox is checked", () => { // Arrange/Act const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: true, modelValue: ["Aaa", "Bbb", "Ddd", "Ccc"], value: "Ddd", }, }, }); // Assert const inputElement = wrapper.find("input"); expect(wrapper.vm.isChecked).toEqual(true); expect(inputElement.element.checked).toBe(true); }); }); describe("radio", () => { const falsyModelValues = ["", null, undefined, []]; test.each(falsyModelValues)( "modelValue is falsy/empty => radio button isn't checked", (modelValue) => { // Arrange/Act const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: false, modelValue, value: "Aaa", }, }, }); // Assert const inputElement = wrapper.find("input"); expect(wrapper.vm.isChecked).toEqual(false); expect(inputElement.element.checked).toBe(false); } ); test("modelValue equals this button's value => radio button is checked", () => { // Arrange/Act const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: false, modelValue: "Ddd", value: "Ddd", }, }, }); // Assert const inputElement = wrapper.find("input"); expect(wrapper.vm.isChecked).toEqual(true); expect(inputElement.element.checked).toBe(true); }); test("modelValue doesn't equal this button's value => radio button isn't checked", () => { // Arrange/Act const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: false, modelValue: "Aaa", value: "Ddd", }, }, }); // Assert const inputElement = wrapper.find("input"); expect(wrapper.vm.isChecked).toEqual(false); expect(inputElement.element.checked).toBe(false); }); }); }); describe("buttonId", () => { test("groupName and value combo yield correct id for input button with string value", () => { // Arrange/Act const { wrapper } = setupMocks({ mockData: { propsData: { groupName: "my test-name", value: "Aaa-BBB CcC", }, }, }); // Assert const inputElement = wrapper.find("input"); expect(wrapper.vm.buttonId).toBe("my-test-name-Aaa-BBB-CcC"); expect(inputElement.attributes().id).toBe( "my-test-name-Aaa-BBB-CcC" ); }); test("groupName and value combo yield correct id for input button with number value", () => { // Arrange/Act const { wrapper } = setupMocks({ mockData: { propsData: { groupName: "my test-name", value: 2, }, }, }); // Assert const inputElement = wrapper.find("input"); expect(wrapper.vm.buttonId).toBe("my-test-name-2"); expect(inputElement.attributes().id).toBe("my-test-name-2"); }); }); describe("inputType", () => { test("isMultiSelect is true => inputType is 'checkbox'", () => { // Arrange/Act const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: true, }, }, }); // Assert const inputElement = wrapper.find("input"); expect(wrapper.vm.inputType).toEqual("checkbox"); expect(inputElement.attributes().type).toBe("checkbox"); }); test("isMultiSelect is false => inputType is 'radio'", () => { // Arrange/Act const { wrapper } = setupMocks({ mockData: { propsData: { isMultiSelect: false, }, }, }); // Assert const inputElement = wrapper.find("input"); expect(wrapper.vm.inputType).toEqual("radio"); expect(inputElement.attributes().type).toBe("radio"); }); }); }); }); // TODO KO look at how I tested groups of these in SFA (making sure selecting one radio changes the value, etc, that this acts like a regular input aside from a different emitted event) function setupMocks({ mockData = {}, shouldShallowMount = true }) { const baseInputButtonWrapper = { components: { baseInputButton }, template: '', data() { return { myValue: "", }; }, }; const mountMockData = { ...mockData, propsData: { // to get rid of some annoying warnings groupName: "groupName", modelValue: mockData.propsData?.isMultiSelect ? [] : "", value: "5", // should override the above if they exist ...mockData.propsData, }, }; const wrapper = shouldShallowMount ? shallowMount(baseInputButton, mountMockData) : mount(baseInputButton, mountMockData); return { wrapper }; } function setupBaseInputButtonWrapper({ mockData = {} }) { const baseInputButtonWrapper = { components: { baseInputButton }, template: '
', data() { return { myValue: "", isMultiSelect: mockData.isMultiSelect, }; }, // const parentComponent = mount({ // data() { // return { // value: "value1", // } // }, // template: '
', // components: { baseInputButton } // }) }; const wrapper = mount(baseInputButtonWrapper, {}); return { wrapper }; }