diff --git a/src/dropdown/list/DropdownList.tsx b/src/dropdown/list/DropdownList.tsx
index b99e5722..95158516 100644
--- a/src/dropdown/list/DropdownList.tsx
+++ b/src/dropdown/list/DropdownList.tsx
@@ -10,7 +10,7 @@ import DropdownListItem, {
} from "./item/DropdownListItem";
import {computeScrollAmountToMakeChildVisible} from "../../core/utils/dom/domUtils";
-interface DropdownListProps {
+export interface DropdownListProps {
isVisible: boolean;
options: DropdownOption[];
selectedOption: DropdownSelectedOption;
diff --git a/src/dropdown/list/dropdown-list.test.tsx b/src/dropdown/list/dropdown-list.test.tsx
new file mode 100644
index 00000000..fd913ee3
--- /dev/null
+++ b/src/dropdown/list/dropdown-list.test.tsx
@@ -0,0 +1,51 @@
+import React from "react";
+import {render, screen} from "@testing-library/react";
+import "@testing-library/jest-dom";
+
+import {testA11y} from "../../core/utils/test/testUtils";
+import DropdownList, {DropdownListProps} from "./DropdownList";
+
+describe("", () => {
+ const defaultDropdownListProps: DropdownListProps = {
+ testid: "dropdown-list",
+ options: [
+ {id: "1", title: "dropdown-option-1"},
+ {id: "2", title: "dropdown-option-2"},
+ {id: "3", title: "dropdown-option-3"}
+ ],
+ focusedOption: {id: "1", title: "test"},
+ isVisible: true,
+ onFocus: jest.fn(),
+ onSelect: jest.fn(),
+ selectedOption: {id: "1", title: "test"},
+ role: "listbox"
+ };
+
+ it("should render correctly", () => {
+ render();
+ });
+
+ it("should pass a11y test", async () => {
+ const {container} = render();
+
+ await testA11y(container, {
+ rules: {
+ "aria-required-parent": {enabled: false},
+ list: {enabled: false},
+ "aria-input-field-name": {enabled: false}
+ }
+ });
+ });
+
+ it("should render noOptionsMessage if options are empty", () => {
+ render(
+
+ );
+
+ expect(screen.getByRole("listbox")).toContainElement(screen.getByText("No options"));
+ });
+});
diff --git a/src/dropdown/list/item/DropdownListItem.tsx b/src/dropdown/list/item/DropdownListItem.tsx
index 8412beea..c27621c4 100644
--- a/src/dropdown/list/item/DropdownListItem.tsx
+++ b/src/dropdown/list/item/DropdownListItem.tsx
@@ -24,7 +24,7 @@ export type DropdownSelectedOption =
| null
| undefined;
-interface DropdownListItemProps {
+export interface DropdownListItemProps {
testid?: string;
option: DropdownOption;
selectedOption: DropdownSelectedOption;
diff --git a/src/dropdown/list/item/dropdown-list-item.test.tsx b/src/dropdown/list/item/dropdown-list-item.test.tsx
new file mode 100644
index 00000000..96950748
--- /dev/null
+++ b/src/dropdown/list/item/dropdown-list-item.test.tsx
@@ -0,0 +1,147 @@
+import React from "react";
+import {render, screen, fireEvent} from "@testing-library/react";
+import "@testing-library/jest-dom";
+import userEvent from "@testing-library/user-event";
+
+import {testA11y} from "../../../core/utils/test/testUtils";
+import DropdownListItem, {DropdownListItemProps} from "./DropdownListItem";
+
+describe("", () => {
+ const defaultDropdownListItemProps: DropdownListItemProps = {
+ testid: "dropdown-list-item",
+ selectedOption: {id: "1", title: "test"},
+ option: {id: "1", title: "test"},
+ onFocus: jest.fn(),
+ onSelect: jest.fn(),
+ onKeyDown: jest.fn()
+ };
+
+ it("should render correctly", () => {
+ render();
+ });
+
+ it("should pass a11y test", async () => {
+ const {container} = render();
+
+ await testA11y(container, {rules: {"aria-required-parent": {enabled: false}}});
+ });
+
+ it("should render custom content if it exists", () => {
+ const {container} = render(
+ {"custom content"}
+ }}
+ />
+ );
+
+ expect(container).toContainElement(screen.getByText("custom content"));
+ });
+
+ describe("should handle event handlers correctly", () => {
+ it("should not run click event handler when option is disabled and option is selected or canSelectAlreadySelected is provided as false", () => {
+ // isDisabled: true, isSelected: true , canSelectAlreadySelected: default = false
+ const {rerender} = render(
+
+ );
+
+ userEvent.click(screen.getByRole("option"));
+ expect(defaultDropdownListItemProps.onSelect).not.toHaveBeenCalled();
+
+ // isDisabled: true, isSelected: false , canSelectAlreadySelected: default = false
+ rerender(
+
+ );
+
+ userEvent.click(screen.getByRole("option"));
+ expect(defaultDropdownListItemProps.onSelect).not.toHaveBeenCalled();
+
+ // isDisabled: true, isSelected: true , canSelectAlreadySelected: true
+ rerender(
+
+ );
+
+ userEvent.click(screen.getByRole("option"));
+ expect(defaultDropdownListItemProps.onSelect).not.toHaveBeenCalled();
+ });
+
+ it("should run click event handler when option is not disabled and option is not selected or canSelectAlreadySelected is provided as true", () => {
+ // isDisabled: false, isSelected: true , canSelectAlreadySelected: true
+ const {rerender} = render(
+
+ );
+
+ userEvent.click(screen.getByRole("option"));
+ expect(defaultDropdownListItemProps.onSelect).toHaveBeenCalledTimes(1);
+
+ jest.clearAllMocks();
+
+ // isDisabled: false, isSelected: false , canSelectAlreadySelected: default = false
+ rerender(
+
+ );
+
+ userEvent.click(screen.getByRole("option"));
+ expect(defaultDropdownListItemProps.onSelect).toHaveBeenCalledTimes(1);
+
+ jest.clearAllMocks();
+
+ // isDisabled: false, isSelected: false , canSelectAlreadySelected: true
+ rerender(
+
+ );
+
+ userEvent.click(screen.getByRole("option"));
+ expect(defaultDropdownListItemProps.onSelect).toHaveBeenCalledTimes(1);
+ });
+
+ it("should run focus event handler correctly", () => {
+ render();
+
+ fireEvent.focus(screen.getByRole("option"));
+
+ expect(defaultDropdownListItemProps.onFocus).toHaveBeenCalledTimes(1);
+ });
+
+ it("should run key down event handler correctly", () => {
+ const {rerender} = render();
+
+ fireEvent.keyDown(screen.getByRole("option"), {
+ keyCode: 16
+ });
+
+ expect(defaultDropdownListItemProps.onKeyDown).toHaveBeenCalledTimes(1);
+
+ jest.clearAllMocks();
+
+ rerender(
+
+ );
+
+ expect(defaultDropdownListItemProps.onKeyDown).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/src/dropdown/util/dropdown-utils.test.ts b/src/dropdown/util/dropdown-utils.test.ts
new file mode 100644
index 00000000..e13dd22b
--- /dev/null
+++ b/src/dropdown/util/dropdown-utils.test.ts
@@ -0,0 +1,85 @@
+import {DropdownOption} from "../list/item/DropdownListItem";
+import {
+ findIndexForClosestMatch,
+ generateInitialFocusedDropdownOptionIndex
+} from "./dropdownUtils";
+import {DropdownPosition} from "./dropdownConstants";
+
+describe("generateInitialFocusedDropdownOptionIndex", () => {
+ const position: DropdownPosition = "left";
+ const options: DropdownOption[] = [
+ {id: "1", title: "Hipo"},
+ {id: "2", title: "hIpO lAbS"},
+ {id: "3", title: "lAbS"},
+ {id: "4", title: "Labss"},
+ {id: "5", title: ""},
+ {id: "6", title: "hİpOğÜ_*!>labs"}
+ ];
+
+ it("should return provided selectedOption's index if it exists", () => {
+ expect(
+ generateInitialFocusedDropdownOptionIndex(position, options, options[1])
+ ).toEqual(1);
+ });
+
+ it("should return 0 when provided selectedOption does not exists and position is not equal to top", () => {
+ expect(
+ generateInitialFocusedDropdownOptionIndex(position, options, {
+ id: "-1",
+ title: "test"
+ })
+ ).toEqual(0);
+
+ expect(generateInitialFocusedDropdownOptionIndex(position, options, null)).toEqual(0);
+ expect(
+ generateInitialFocusedDropdownOptionIndex(position, options, undefined)
+ ).toEqual(0);
+ });
+
+ it("should return last option's index when selectedOption does not exists and position is equal to top", () => {
+ expect(
+ generateInitialFocusedDropdownOptionIndex("top", options, {
+ id: "-1",
+ title: "test"
+ })
+ ).toEqual(options.length - 1);
+ });
+
+ expect(generateInitialFocusedDropdownOptionIndex("top", options, null)).toEqual(
+ options.length - 1
+ );
+ expect(generateInitialFocusedDropdownOptionIndex("top", options, undefined)).toEqual(
+ options.length - 1
+ );
+});
+
+describe("findIndexForClosestMatch", () => {
+ const options: DropdownOption[] = [
+ {id: "1", title: "Hipo"},
+ {id: "2", title: "hIpO lAbS"},
+ {id: "3", title: "lAbS"},
+ {id: "4", title: "Labss"},
+ {id: "5", title: ""},
+ {id: "6", title: "hİpOğÜ_*!>labs"}
+ ];
+
+ it("should return closest index by provided query", () => {
+ expect(findIndexForClosestMatch(options, "HipO")).toEqual(0);
+ // eslint-disable-next-line no-magic-numbers
+ expect(findIndexForClosestMatch(options, "labs")).toEqual(2);
+ expect(findIndexForClosestMatch(options, "hipo la")).toEqual(1);
+ });
+
+ it("should return 0 if the provided query is empty", () => {
+ expect(findIndexForClosestMatch(options, "")).toEqual(0);
+ });
+
+ it("should return -1 if the provided query does not exists", () => {
+ expect(findIndexForClosestMatch(options, "test")).toEqual(-1);
+ });
+
+ it("should handle special characters", () => {
+ // eslint-disable-next-line no-magic-numbers
+ expect(findIndexForClosestMatch(options, "hİpOğÜ_*!>")).toEqual(5);
+ });
+});