import React from "react";
import { DesktopLinkGroups } from "./index";
import { act, fireEvent, render, screen } from "@testing-library/react";
jest.mock("@shared/components/material-icon", () => ({
MaterialIcon: ({ name, className }: any) => (
{name}
),
}));
jest.mock("@shared/components/text", () => ({
Text: ({ as: Tag = "span", children, className }: any) => (
{children}
),
}));
jest.mock("@shared/contentful/blocks/button", () => ({
Button: ({
children,
buttonClassName,
onClick,
linkClassName,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
showButtonAs,
...rest
}: any) => (
),
}));
let outsideClickCallback: (() => void) | null = null;
jest.mock("@shared/hooks/use-outside-click", () => ({
useOutsideClick: (_ref: any, cb: () => void) => {
outsideClickCallback = cb;
},
}));
jest.mock("@shared/utils", () => ({
cx: (...args: any[]) => args.filter(Boolean).join(" "),
}));
describe("DesktopLinkGroups", () => {
it("renders nothing when link is undefined", () => {
const { container } = render(
);
expect(container.innerHTML).toBe("");
});
it("renders single Button when link is a button (has href)", () => {
const link = {
href: "/products",
buttonLabel: "Products",
anchorId: "prod",
};
render();
expect(screen.getByTestId("button")).toHaveTextContent("Products");
});
describe("Group rendering", () => {
const groupLink = {
anchorId: "group-1",
title: "My Account",
items: {
items: [
{ buttonLabel: "Profile", href: "/profile", anchorId: "p1" },
{ buttonLabel: "Settings", href: "/settings", anchorId: "p2" },
],
},
};
it("renders group title button", () => {
render(
);
expect(screen.getByText("My Account")).toBeInTheDocument();
});
it("renders dropdown arrow icon (down when closed)", () => {
render(
);
expect(
screen.getByTestId("icon-keyboard_arrow_down")
).toBeInTheDocument();
});
it("toggles open state and shows up arrow when open", () => {
render(
);
const toggleBtn = screen.getAllByTestId("button")[0];
fireEvent.click(toggleBtn);
expect(screen.getByTestId("icon-keyboard_arrow_up")).toBeInTheDocument();
});
it("renders submenu items when open", () => {
render(
);
const toggleBtn = screen.getAllByTestId("button")[0];
fireEvent.click(toggleBtn);
expect(screen.getByText("Profile")).toBeInTheDocument();
expect(screen.getByText("Settings")).toBeInTheDocument();
});
it("closes when toggled again", () => {
render(
);
const toggleBtn = screen.getAllByTestId("button")[0];
fireEvent.click(toggleBtn);
fireEvent.click(toggleBtn);
expect(
screen.getByTestId("icon-keyboard_arrow_down")
).toBeInTheDocument();
});
it("renders null title when title is missing", () => {
const noTitleLink = { ...groupLink, title: null };
render(
);
// Should still render without error
expect(screen.getAllByTestId("button")[0]).toBeInTheDocument();
});
it("handles empty items array", () => {
const emptyItems = { ...groupLink, items: { items: [] } };
render(
);
const toggleBtn = screen.getAllByTestId("button")[0];
fireEvent.click(toggleBtn);
// No submenu links rendered
expect(screen.getAllByTestId("button")).toHaveLength(1);
});
it("handles null items", () => {
const nullItems = { ...groupLink, items: null };
render(
);
const toggleBtn = screen.getAllByTestId("button")[0];
fireEvent.click(toggleBtn);
expect(screen.getAllByTestId("button")).toHaveLength(1);
});
it("closes when a submenu anchor link is clicked", () => {
render(
);
const toggleBtn = screen.getAllByTestId("button")[0];
fireEvent.click(toggleBtn);
// Simulate clicking an anchor within the submenu ul
const submenuList = screen.getByRole("list");
const anchor = document.createElement("a");
anchor.href = "/profile";
submenuList.appendChild(anchor);
fireEvent.click(anchor);
// After click, arrow should be down (closed)
expect(
screen.getByTestId("icon-keyboard_arrow_down")
).toBeInTheDocument();
});
it("does not close when non-anchor element is clicked in submenu", () => {
render(
);
const toggleBtn = screen.getAllByTestId("button")[0];
fireEvent.click(toggleBtn);
const submenuList = screen.getByRole("list");
// Click on a non-anchor element
fireEvent.click(submenuList);
// Should still be open
expect(screen.getByTestId("icon-keyboard_arrow_up")).toBeInTheDocument();
});
it("closes when outside click is triggered", () => {
render(
);
const toggleBtn = screen.getAllByTestId("button")[0];
fireEvent.click(toggleBtn);
// Should be open
expect(screen.getByTestId("icon-keyboard_arrow_up")).toBeInTheDocument();
// Trigger outside click callback
act(() => {
outsideClickCallback!();
});
// Should close
expect(
screen.getByTestId("icon-keyboard_arrow_down")
).toBeInTheDocument();
});
});
});