diff --git a/src/common-components/base-input-button/base-input-button.spec.js b/src/common-components/base-input-button/base-input-button.spec.js
new file mode 100644
index 000000000..9a6e7c168
--- /dev/null
+++ b/src/common-components/base-input-button/base-input-button.spec.js
@@ -0,0 +1,523 @@
+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", () => {
+ describe("checkbox", () => {
+ test.todo("modelValue is null => inputButtonClicked is emitted with correct")
+ })
+
+ 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: '