From 9e77f61c97a5799f7ebaf85f4d2cbe771dec4806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?An=C4=B1lerkan?= <43711824+Anlerkan@users.noreply.github.com> Date: Thu, 1 Jul 2021 14:39:36 +0300 Subject: [PATCH 1/6] feat(dropdown/test): Add test for dropdownUtils and dropdownListItem --- src/dropdown/list/item/DropdownListItem.tsx | 2 +- .../dropdown-list-item.test.tsx.snap | 29 +++ .../list/item/dropdown-list-item.test.tsx | 187 ++++++++++++++++++ src/dropdown/util/dropdown-utils.test.ts | 85 ++++++++ 4 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 src/dropdown/list/item/__snapshots__/dropdown-list-item.test.tsx.snap create mode 100644 src/dropdown/list/item/dropdown-list-item.test.tsx create mode 100644 src/dropdown/util/dropdown-utils.test.ts 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/__snapshots__/dropdown-list-item.test.tsx.snap b/src/dropdown/list/item/__snapshots__/dropdown-list-item.test.tsx.snap new file mode 100644 index 00000000..9b19a5de --- /dev/null +++ b/src/dropdown/list/item/__snapshots__/dropdown-list-item.test.tsx.snap @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` should match snapshot 1`] = ` +
  • +
    +
    +

    + test +

    +
    +
  • +`; 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..4dc0eaa9 --- /dev/null +++ b/src/dropdown/list/item/dropdown-list-item.test.tsx @@ -0,0 +1,187 @@ +import React from "react"; +import {render, screen, fireEvent} from "@testing-library/react"; +import "@testing-library/jest-dom"; +import {create} from "react-test-renderer"; +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 match snapshot", () => { + const tree = create().toJSON(); + + expect(tree).toMatchSnapshot(); + }); + + it("should pass a11y test", async () => { + const {container} = render(); + + await testA11y(container, {rules: {"aria-required-parent": {enabled: false}}}); + }); + + it("should have proper class name", () => { + const {rerender} = render(); + + expect(screen.getByRole("option")).toHaveClass("dropdown-list-item--is-selected"); + + rerender( + + ); + + expect(screen.getByRole("option")).toHaveClass("dropdown-list-item--is-focused"); + + rerender( + + ); + + expect(screen.getByRole("option")).toHaveClass("dropdown-list-item--can-be-selected"); + + rerender( + + ); + + expect(screen.getByRole("option")).toHaveClass("dropdown-list-item--is-disabled"); + }); + + 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", () => { + const {container} = render(); + + fireEvent.focus(container); + + 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); + }); +}); From 1b114e5c38d7c8f593d85b6e16b110ce2a77c0ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?An=C4=B1lerkan?= <43711824+Anlerkan@users.noreply.github.com> Date: Thu, 1 Jul 2021 14:46:55 +0300 Subject: [PATCH 2/6] fix(dropdown/list/item): Class name tests improvements --- .../list/item/dropdown-list-item.test.tsx | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/dropdown/list/item/dropdown-list-item.test.tsx b/src/dropdown/list/item/dropdown-list-item.test.tsx index 4dc0eaa9..8dea10b5 100644 --- a/src/dropdown/list/item/dropdown-list-item.test.tsx +++ b/src/dropdown/list/item/dropdown-list-item.test.tsx @@ -34,26 +34,16 @@ describe("", () => { }); it("should have proper class name", () => { - const {rerender} = render(); - - expect(screen.getByRole("option")).toHaveClass("dropdown-list-item--is-selected"); - - rerender( - - ); - - expect(screen.getByRole("option")).toHaveClass("dropdown-list-item--is-focused"); - - rerender( + const {rerender} = render( ); + expect(screen.getByRole("option")).toHaveClass("dropdown-list-item--is-selected"); + expect(screen.getByRole("option")).toHaveClass("dropdown-list-item--is-focused"); expect(screen.getByRole("option")).toHaveClass("dropdown-list-item--can-be-selected"); rerender( From c6a237caad63f5cfa369be0b545d15935958246e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?An=C4=B1lerkan?= <43711824+Anlerkan@users.noreply.github.com> Date: Wed, 14 Jul 2021 17:11:26 +0300 Subject: [PATCH 3/6] fix: Remove snapshot tests --- .../dropdown-list-item.test.tsx.snap | 29 ------------------- .../list/item/dropdown-list-item.test.tsx | 7 ----- 2 files changed, 36 deletions(-) delete mode 100644 src/dropdown/list/item/__snapshots__/dropdown-list-item.test.tsx.snap diff --git a/src/dropdown/list/item/__snapshots__/dropdown-list-item.test.tsx.snap b/src/dropdown/list/item/__snapshots__/dropdown-list-item.test.tsx.snap deleted file mode 100644 index 9b19a5de..00000000 --- a/src/dropdown/list/item/__snapshots__/dropdown-list-item.test.tsx.snap +++ /dev/null @@ -1,29 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` should match snapshot 1`] = ` -
  • -
    -
    -

    - test -

    -
    -
  • -`; diff --git a/src/dropdown/list/item/dropdown-list-item.test.tsx b/src/dropdown/list/item/dropdown-list-item.test.tsx index 8dea10b5..a086a0b5 100644 --- a/src/dropdown/list/item/dropdown-list-item.test.tsx +++ b/src/dropdown/list/item/dropdown-list-item.test.tsx @@ -1,7 +1,6 @@ import React from "react"; import {render, screen, fireEvent} from "@testing-library/react"; import "@testing-library/jest-dom"; -import {create} from "react-test-renderer"; import userEvent from "@testing-library/user-event"; import {testA11y} from "../../../core/utils/test/testUtils"; @@ -21,12 +20,6 @@ describe("", () => { render(); }); - it("should match snapshot", () => { - const tree = create().toJSON(); - - expect(tree).toMatchSnapshot(); - }); - it("should pass a11y test", async () => { const {container} = render(); From 67f47e98f3f16b0b5cec4f2843049f1bcda3421f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?An=C4=B1lerkan?= <43711824+Anlerkan@users.noreply.github.com> Date: Thu, 22 Jul 2021 13:54:54 +0300 Subject: [PATCH 4/6] feat(dropdown/list): Add tests --- src/dropdown/list/DropdownList.tsx | 2 +- src/dropdown/list/dropdown-list.test.tsx | 61 +++++++++++++++++++ .../list/item/dropdown-list-item.test.tsx | 2 +- 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/dropdown/list/dropdown-list.test.tsx 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..f38db773 --- /dev/null +++ b/src/dropdown/list/dropdown-list.test.tsx @@ -0,0 +1,61 @@ +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 add dropdown-list--is-visible class name while isVisible is true", () => { + const {rerender} = render(); + + expect(screen.getByRole("listbox")).toHaveClass("dropdown-list--is-visible"); + + rerender(); + + expect(screen.getByRole("listbox")).not.toHaveClass("dropdown-list--is-visible"); + }); + + 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/dropdown-list-item.test.tsx b/src/dropdown/list/item/dropdown-list-item.test.tsx index a086a0b5..55752b54 100644 --- a/src/dropdown/list/item/dropdown-list-item.test.tsx +++ b/src/dropdown/list/item/dropdown-list-item.test.tsx @@ -26,7 +26,7 @@ describe("", () => { await testA11y(container, {rules: {"aria-required-parent": {enabled: false}}}); }); - it("should have proper class name", () => { + it("should have proper modifier class name", () => { const {rerender} = render( Date: Tue, 27 Jul 2021 13:46:09 +0300 Subject: [PATCH 5/6] fix: Remove class name tests --- src/dropdown/list/dropdown-list.test.tsx | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/dropdown/list/dropdown-list.test.tsx b/src/dropdown/list/dropdown-list.test.tsx index f38db773..fd913ee3 100644 --- a/src/dropdown/list/dropdown-list.test.tsx +++ b/src/dropdown/list/dropdown-list.test.tsx @@ -37,16 +37,6 @@ describe("", () => { }); }); - it("should add dropdown-list--is-visible class name while isVisible is true", () => { - const {rerender} = render(); - - expect(screen.getByRole("listbox")).toHaveClass("dropdown-list--is-visible"); - - rerender(); - - expect(screen.getByRole("listbox")).not.toHaveClass("dropdown-list--is-visible"); - }); - it("should render noOptionsMessage if options are empty", () => { render( Date: Thu, 2 Sep 2021 13:24:00 +0300 Subject: [PATCH 6/6] fix(dropdown-list-item/test): Remove class name tests --- .../list/item/dropdown-list-item.test.tsx | 27 ++----------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/src/dropdown/list/item/dropdown-list-item.test.tsx b/src/dropdown/list/item/dropdown-list-item.test.tsx index 55752b54..96950748 100644 --- a/src/dropdown/list/item/dropdown-list-item.test.tsx +++ b/src/dropdown/list/item/dropdown-list-item.test.tsx @@ -26,29 +26,6 @@ describe("", () => { await testA11y(container, {rules: {"aria-required-parent": {enabled: false}}}); }); - it("should have proper modifier class name", () => { - const {rerender} = render( - - ); - - expect(screen.getByRole("option")).toHaveClass("dropdown-list-item--is-selected"); - expect(screen.getByRole("option")).toHaveClass("dropdown-list-item--is-focused"); - expect(screen.getByRole("option")).toHaveClass("dropdown-list-item--can-be-selected"); - - rerender( - - ); - - expect(screen.getByRole("option")).toHaveClass("dropdown-list-item--is-disabled"); - }); - it("should render custom content if it exists", () => { const {container} = render( ", () => { }); it("should run focus event handler correctly", () => { - const {container} = render(); + render(); - fireEvent.focus(container); + fireEvent.focus(screen.getByRole("option")); expect(defaultDropdownListItemProps.onFocus).toHaveBeenCalledTimes(1); });