import React from "react";
import { createSerializer } from "@emotion/jest";
import { Typeahead, TextInput } from "../../index";
import { render, fireEvent } from "@testing-library/react";
expect.addSnapshotSerializer(createSerializer());
const items = [
{ label: "Exosphere", value: "Exosphere" },
{ label: "Thermosphere", value: "Thermosphere" },
{ label: "Stratosphere", value: "Stratosphere" }
];
describe("Typeahead", () => {
it("renders", () => {
const { asFragment } = render(
}
/>
);
expect(asFragment()).toMatchSnapshot();
});
it("renders a menu with a max height", () => {
const { asFragment } = render(
}
/>
);
expect(asFragment()).toMatchSnapshot();
});
it("opens the menu on focus", () => {
const { getByTestId } = render(
}
/>
);
const textInputElement = getByTestId("textInput-input");
textInputElement.focus();
expect(textInputElement.children.length).toBe(0);
expect(textInputElement).toBeTruthy();
});
it("opens the menu on click even if it's focused", () => {
const { getByTestId, queryByTestId } = render(
}
/>
);
const textInputElement = getByTestId("textInput-input");
expect(queryByTestId("typeahead-dropdown")).toBeNull();
textInputElement.focus();
fireEvent.keyDown(textInputElement, {
key: "ArrowDown"
});
fireEvent.keyDown(textInputElement, {
key: "Enter"
});
expect(queryByTestId("typeahead-dropdown")).toBeNull();
fireEvent.click(textInputElement);
expect(queryByTestId("typeahead-dropdown")).toBeTruthy();
});
it("renders an empty state if no items are passed", () => {
const { getByTestId } = render(
Empty}
textField={
}
/>
);
fireEvent.click(getByTestId("textInput-input"));
expect(getByTestId("emptyState")).toBeTruthy();
});
it("does not render an empty state if items are passed", () => {
const { getByTestId, queryByTestId } = render(
Empty}
textField={
}
/>
);
fireEvent.click(getByTestId("textInput-input"));
expect(queryByTestId("emptyState")).toBeFalsy();
});
it("renders whatever text input field that is passed", () => {
const { getByTestId } = render(
} />
);
expect(getByTestId("randomInput")).toBeTruthy();
});
it("calls onSelect prop with the selected values", () => {
const onSelectFn = jest.fn();
const { getByTestId } = render(
}
/>
);
const textInputElement = getByTestId("textInput-input");
textInputElement.focus();
expect(onSelectFn).not.toHaveBeenCalled();
fireEvent.keyDown(textInputElement, {
key: "ArrowDown"
});
fireEvent.keyDown(textInputElement, {
key: "Enter"
});
expect(onSelectFn).toHaveBeenCalledWith([items[0].value], items[0].value);
});
it("sets the input value to the selected item's value on select", () => {
const onSelectFn = jest.fn();
const { getByTestId } = render(
}
/>
);
const textInputElement = getByTestId("textInput-input");
expect(textInputElement).toHaveValue("");
textInputElement.focus();
expect(onSelectFn).not.toHaveBeenCalled();
fireEvent.keyDown(textInputElement, {
key: "ArrowDown"
});
fireEvent.keyDown(textInputElement, {
key: "Enter"
});
expect(textInputElement).toHaveValue(items[0].value);
});
it("skips disabled option on arrow down and select", () => {
const onSelectFn = jest.fn();
const itemsWithDisabledOption = [
{ label: "K8sphere", value: "K8sphere", disabled: true },
...items
];
const { getByTestId } = render(
}
/>
);
const textInputElement = getByTestId("textInput-input");
expect(textInputElement).toHaveValue("");
fireEvent.focus(textInputElement);
expect(onSelectFn).not.toHaveBeenCalled();
fireEvent.keyDown(textInputElement, {
key: "ArrowDown"
});
fireEvent.keyDown(textInputElement, {
key: "Enter"
});
// skips over index 0 because it's disabled
expect(textInputElement).toHaveValue(itemsWithDisabledOption[1].value);
});
it("does not hide the dropdown when selecting an item if multiSelect is true", () => {
const onSelectFn = jest.fn();
const { getByTestId, queryByTestId } = render(
}
/>
);
const textInputElement = getByTestId("textInput-input");
expect(queryByTestId("typeahead-dropdown")).toBeNull();
textInputElement.focus();
expect(onSelectFn).not.toHaveBeenCalled();
fireEvent.keyDown(textInputElement, {
key: "ArrowDown"
});
fireEvent.keyDown(textInputElement, {
key: "Enter"
});
expect(queryByTestId("typeahead-dropdown")).toBeTruthy();
});
it("hides the dropdown when selecting an item if keepOpenOnSelect is false", () => {
const onSelectFn = jest.fn();
const { getByTestId, queryByTestId } = render(
}
/>
);
const textInputElement = getByTestId("textInput-input");
expect(queryByTestId("typeahead-dropdown")).toBeNull();
textInputElement.focus();
expect(onSelectFn).not.toHaveBeenCalled();
fireEvent.keyDown(textInputElement, {
key: "ArrowDown"
});
fireEvent.keyDown(textInputElement, {
key: "Enter"
});
expect(queryByTestId("typeahead-dropdown")).toBeNull();
});
it("does not set the input value if multiSelect is true", () => {
const onSelectFn = jest.fn();
const { getByTestId } = render(
}
/>
);
const textInputElement = getByTestId("textInput-input");
expect(textInputElement).toHaveValue("");
textInputElement.focus();
expect(onSelectFn).not.toHaveBeenCalled();
fireEvent.keyDown(textInputElement, {
key: "ArrowDown"
});
fireEvent.keyDown(textInputElement, {
key: "Enter"
});
expect(textInputElement).toHaveValue("");
});
it("does not set the input value if resetInputOnSelect is true", () => {
const onSelectFn = jest.fn();
const { getByTestId } = render(
}
/>
);
const textInputElement = getByTestId("textInput-input");
expect(textInputElement).toHaveValue("");
textInputElement.focus();
expect(onSelectFn).not.toHaveBeenCalled();
fireEvent.keyDown(textInputElement, {
key: "ArrowDown"
});
fireEvent.keyDown(textInputElement, {
key: "Enter"
});
expect(textInputElement).toHaveValue("");
});
it("calls the input's onClick prop", () => {
const onClickFn = jest.fn();
const { getByTestId } = render(
}
/>
);
const textInputElement = getByTestId("textInput-input");
expect(textInputElement).toHaveValue("");
expect(onClickFn).not.toHaveBeenCalled();
fireEvent.click(textInputElement);
expect(onClickFn).toHaveBeenCalled();
});
it("calls the input's onFocus prop", () => {
const onFocusFn = jest.fn();
const { getByTestId } = render(
}
/>
);
const textInputElement = getByTestId("textInput-input");
expect(textInputElement).toHaveValue("");
expect(onFocusFn).not.toHaveBeenCalled();
textInputElement.addEventListener("focus", onFocusFn);
textInputElement.focus();
expect(onFocusFn).toHaveBeenCalled();
});
});