Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/components/layouts/buttons/LayoutButtons.test.tsx
T

94 lines
3.6 KiB
TypeScript

import "@testing-library/jest-dom";
import { fireEvent, render, screen } from "@testing-library/react";
import { MemoryRouter } from "react-router";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { UI_ACTION_IDS } from "~/application/ui/uiRegistry";
import NotificationsButton from "./NotificationsButton";
import ProfileButton from "./ProfileButton";
import SearchButton from "./SearchButton";
vi.mock("react-i18next", () => ({
useTranslation: () => ({ t: (value: string) => value }),
}));
vi.mock("react-router", async () => {
const actual = await vi.importActual<typeof import("react-router")>("react-router");
return {
...actual,
Form: ({ children, ...props }: React.ComponentProps<"form">) => <form {...props}>{children}</form>,
};
});
vi.mock("~/utils/data/useRootData", () => ({
useRootData: () => (globalThis as any).__layoutButtonsRootData,
}));
vi.mock("~/utils/data/useAppOrAdminData", () => ({
useAppOrAdminData: () => ({ permissions: [] }),
}));
describe("layout button UI IDs", () => {
beforeEach(() => {
(globalThis as any).__layoutButtonsRootData = { appConfiguration: { app: { features: { tenantApiKeys: false } } } };
});
it("renders SearchButton with a stable action ID", () => {
render(<SearchButton onClick={vi.fn()} />);
expect(document.querySelector(`[data-ui-id="${UI_ACTION_IDS.search}"]`)).toBeInTheDocument();
});
it("renders NotificationsButton with a stable action ID", () => {
render(
<MemoryRouter>
<NotificationsButton unseenCount={2} to="/acme/notifications" />
</MemoryRouter>
);
expect(screen.getByLabelText("shell.notifications.ariaLabel")).toHaveAttribute("data-ui-id", UI_ACTION_IDS.notifications);
expect(screen.getByLabelText("shell.notifications.ariaLabel")).toHaveAttribute("href", "/acme/notifications");
});
it("renders ProfileButton with stable action and menu IDs", () => {
render(
<MemoryRouter>
<ProfileButton user={{ email: "user@example.com", firstName: "Ada", lastName: "Lovelace", avatar: null }} layout="admin" />
</MemoryRouter>
);
expect(document.querySelector(`[data-ui-id="${UI_ACTION_IDS.profile}.menu"]`)).toBeInTheDocument();
expect(screen.getByLabelText("shell.profile.userMenu")).toHaveAttribute("data-ui-id", UI_ACTION_IDS.profile);
});
it("uses default tenant settings links in the public profile menu when available", () => {
(globalThis as any).__layoutButtonsRootData = {
...(globalThis as any).__layoutButtonsRootData,
currentTenant: { id: "tenant_1", slug: "acme" },
};
render(
<MemoryRouter>
<ProfileButton user={{ email: "user@example.com", firstName: "Ada", lastName: "Lovelace", avatar: null }} layout="/" />
</MemoryRouter>
);
fireEvent.click(screen.getByLabelText("shell.profile.userMenu"));
expect(screen.getByRole("menuitem", { name: "app.navbar.profile" })).toHaveAttribute("href", "/acme/settings/profile");
expect(screen.getByRole("menuitem", { name: "app.navbar.subscription" })).toHaveAttribute("href", "/acme/settings/subscription");
});
it("localizes the public admin menu link", () => {
render(
<MemoryRouter>
<ProfileButton user={{ email: "admin@example.com", firstName: "Ada", lastName: "Lovelace", avatar: null, admin: { userId: "user_1" } }} layout="/" />
</MemoryRouter>
);
fireEvent.click(screen.getByLabelText("shell.profile.userMenu"));
expect(screen.getByRole("menuitem", { name: "shared.admin" })).toHaveAttribute("href", "/dashboard");
expect(screen.queryByRole("menuitem", { name: "Admin" })).not.toBeInTheDocument();
});
});