import * as React from "react"; import {act, render} from "@testing-library/react"; import {Button} from "@nextui-org/button"; import userEvent from "@testing-library/user-event"; import {User} from "@nextui-org/user"; import {Dropdown, DropdownTrigger, DropdownMenu, DropdownItem, DropdownSection} from "../src"; // e.g. console.error Warning: Function components cannot be given refs. // Attempts to access this ref will fail. Did you mean to use React.forwardRef()? const spy = jest.spyOn(console, "error").mockImplementation(() => {}); describe("Dropdown", () => { afterEach(() => { jest.clearAllMocks(); }); it("should render correctly (static)", () => { const wrapper = render( New file Copy link Edit file Delete file , ); expect(() => wrapper.unmount()).not.toThrow(); }); it("should render correctly (dynamic)", () => { const menuItems = [ {key: "new", name: "New File"}, {key: "copy", name: "Copy Link"}, {key: "edit", name: "Edit File"}, {key: "delete", name: "Delete File"}, ]; const wrapper = render( {(item: any) => {item.name}} , ); expect(() => wrapper.unmount()).not.toThrow(); }); it("should render correctly with section (static)", () => { const wrapper = render( New file Copy link Edit file Delete file , ); expect(() => wrapper.unmount()).not.toThrow(); }); it("should render correctly with section (dynamic)", () => { const menuItems = [ { title: "Actions", children: [ {key: "new", name: "New File"}, {key: "copy", name: "Copy Link"}, {key: "edit", name: "Edit File"}, ], }, { title: "Danger Zone", children: [{key: "delete", name: "Delete File"}], }, ]; const wrapper = render( {(section: any) => ( {/* @ts-ignore */} {(item: any) => {item.name}} )} , ); expect(() => wrapper.unmount()).not.toThrow(); }); it("should not throw any error when clicking button", async () => { const wrapper = render( New file Copy link Edit file Delete file , ); let triggerButton = wrapper.getByTestId("trigger-test"); expect(triggerButton).toBeTruthy(); await act(async () => { await userEvent.click(triggerButton); }); expect(spy).toBeCalledTimes(0); }); it("should work with single selection (controlled)", async () => { let onOpenChange = jest.fn(); let onSelectionChange = jest.fn(); const wrapper = render( New file Copy link Edit file Delete file , ); let triggerButton = wrapper.getByTestId("trigger-test"); expect(onOpenChange).toBeCalledTimes(0); act(() => { triggerButton.click(); }); expect(onOpenChange).toBeCalledTimes(1); let menu = wrapper.getByRole("menu"); expect(menu).toBeTruthy(); // validates if the menu has the triggerButton id as aria-labelledby expect(menu.getAttribute("aria-labelledby")).toBe(triggerButton.id); let menuItems = wrapper.getAllByRole("menuitemradio"); expect(menuItems.length).toBe(4); await act(async () => { await userEvent.click(menuItems[1]); expect(onSelectionChange).toBeCalledTimes(1); expect(onOpenChange).toBeCalled(); }); }); it("should work with multiple selection (controlled)", async () => { let onOpenChange = jest.fn(); let onSelectionChange = jest.fn(); const wrapper = render( New file Copy link Edit file Delete file , ); let triggerButton = wrapper.getByTestId("trigger-test"); expect(onOpenChange).toBeCalledTimes(0); act(() => { triggerButton.click(); }); expect(onOpenChange).toBeCalledTimes(1); let menu = wrapper.getByRole("menu"); expect(menu).toBeTruthy(); // validates if the menu has the triggerButton id as aria-labelledby expect(menu.getAttribute("aria-labelledby")).toBe(triggerButton.id); let menuItems = wrapper.getAllByRole("menuitemcheckbox"); expect(menuItems.length).toBe(4); await act(async () => { await userEvent.click(menuItems[0]); expect(onSelectionChange).toBeCalledTimes(1); expect(onOpenChange).toBeCalled(); }); }); it("should show checkmarks if selectionMode is single and has a selected item", () => { const wrapper = render( New file Copy link Edit file Delete file , ); let menuItems = wrapper.getAllByRole("menuitemradio"); expect(menuItems.length).toBe(4); expect(menuItems[0].getAttribute("aria-checked")).toBe("true"); expect(menuItems[1].getAttribute("aria-checked")).toBe("false"); expect(menuItems[2].getAttribute("aria-checked")).toBe("false"); expect(menuItems[3].getAttribute("aria-checked")).toBe("false"); let svg = menuItems[0].querySelector("svg"); expect(svg).toBeTruthy(); expect(svg?.getAttribute("data-selected")).toBe("true"); }); it("should show multiple checkmarks if selectionMode is multiple and has selected items", () => { const wrapper = render( New file Copy link Edit file Delete file , ); let menuItems = wrapper.getAllByRole("menuitemcheckbox"); expect(menuItems.length).toBe(4); expect(menuItems[0].getAttribute("aria-checked")).toBe("true"); expect(menuItems[1].getAttribute("aria-checked")).toBe("true"); expect(menuItems[2].getAttribute("aria-checked")).toBe("false"); expect(menuItems[3].getAttribute("aria-checked")).toBe("false"); let checkmark1 = menuItems[0].querySelector("svg"); expect(checkmark1).toBeTruthy(); expect(checkmark1?.getAttribute("data-selected")).toBe("true"); let checkmark2 = menuItems[1].querySelector("svg"); expect(checkmark2).toBeTruthy(); expect(checkmark2?.getAttribute("data-selected")).toBe("true"); }); it("should not show checkmarks if selectionMode not defined", () => { const wrapper = render( New file Copy link Edit file Delete file , ); let menuItems = wrapper.getAllByRole("menuitem"); expect(menuItems.length).toBe(4); expect(menuItems[0].getAttribute("aria-checked")).toBeFalsy(); expect(menuItems[1].getAttribute("aria-checked")).toBeFalsy(); expect(menuItems[2].getAttribute("aria-checked")).toBeFalsy(); expect(menuItems[3].getAttribute("aria-checked")).toBeFalsy(); let checkmark1 = menuItems[0].querySelector("svg"); expect(checkmark1).toBeFalsy(); }); it("should not open on disabled button", () => { const wrapper = render( New file Copy link Edit file Delete file , ); let triggerButton = wrapper.getByTestId("trigger-test"); expect(triggerButton).toBeTruthy(); act(() => { triggerButton.click(); }); let menu = wrapper.queryByRole("menu"); expect(menu).toBeFalsy(); }); it("should not open on disabled dropdown", () => { const wrapper = render( New file Copy link Edit file Delete file , ); let triggerButton = wrapper.getByTestId("trigger-test"); expect(triggerButton).toBeTruthy(); act(() => { triggerButton.click(); }); let menu = wrapper.queryByRole("menu"); expect(menu).toBeFalsy(); }); it("should not select on disabled item", () => { const onSelectionChange = jest.fn(); const wrapper = render( New file Copy link Edit file Delete file , ); let menuItems = wrapper.getAllByRole("menuitemradio"); expect(menuItems.length).toBe(4); act(() => { menuItems[1].click(); }); expect(onSelectionChange).toBeCalledTimes(0); }); it("should render without error (custom trigger + isDisabled)", async () => { const spy = jest.spyOn(console, "error").mockImplementation(() => {}); render(
Trigger
New file Copy link Edit file Delete file
, ); expect(spy).toBeCalledTimes(0); spy.mockRestore(); render( New file Copy link Edit file Delete file , ); expect(spy).toBeCalledTimes(0); spy.mockRestore(); }); });