Files
lemonspace_app/components/canvas/__tests__/canvas-toolbar.test.tsx

174 lines
5.2 KiB
TypeScript

// @vitest-environment jsdom
import React, { act } from "react";
import { createRoot, type Root } from "react-dom/client";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const mocks = vi.hoisted(() => ({
createNodeWithIntersection: vi.fn(async () => undefined),
getCenteredPosition: vi.fn(() => ({ x: 0, y: 0 })),
}));
vi.mock("@/components/canvas/canvas-placement-context", () => ({
useCanvasPlacement: () => ({
createNodeWithIntersection: mocks.createNodeWithIntersection,
}),
}));
vi.mock("@/hooks/use-centered-flow-node-position", () => ({
useCenteredFlowNodePosition: () => mocks.getCenteredPosition,
}));
vi.mock("@/components/ui/dropdown-menu", () => ({
DropdownMenu: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
DropdownMenuTrigger: ({ children }: { children: React.ReactNode }) => <>{children}</>,
DropdownMenuContent: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
DropdownMenuItem: ({ children }: { children: React.ReactNode }) => <button type="button">{children}</button>,
DropdownMenuLabel: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
DropdownMenuSeparator: () => <hr />,
}));
vi.mock("@/components/canvas/credit-display", () => ({
CreditDisplay: () => <div data-testid="credit-display" />,
}));
vi.mock("@/components/canvas/export-button", () => ({
ExportButton: ({ canvasName }: { canvasName: string }) => (
<button type="button">Export {canvasName}</button>
),
}));
vi.mock("@/lib/canvas-node-catalog", () => ({
NODE_CATEGORIES_ORDERED: [],
NODE_CATEGORY_META: {},
catalogEntriesByCategory: () => new Map(),
getTemplateForCatalogType: () => null,
isNodePaletteEnabled: () => false,
}));
import CanvasToolbar from "@/components/canvas/canvas-toolbar";
(globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
describe("CanvasToolbar", () => {
let container: HTMLDivElement | null = null;
let root: Root | null = null;
beforeEach(() => {
mocks.createNodeWithIntersection.mockClear();
mocks.getCenteredPosition.mockClear();
container = document.createElement("div");
document.body.appendChild(container);
root = createRoot(container);
});
afterEach(async () => {
if (root) {
await act(async () => {
root?.unmount();
});
}
container?.remove();
container = null;
root = null;
});
it("renders the favorites filter button", async () => {
await act(async () => {
root?.render(
<CanvasToolbar
activeTool="select"
onToolChange={vi.fn()}
onFavoriteFilterChange={vi.fn()}
/>,
);
});
const favoriteButton = container?.querySelector('button[title="Favoriten hervorheben"]');
expect(favoriteButton).not.toBeNull();
});
it("reflects active state via aria-pressed", async () => {
await act(async () => {
root?.render(
<CanvasToolbar
activeTool="select"
onToolChange={vi.fn()}
favoriteFilterActive={false}
onFavoriteFilterChange={vi.fn()}
/>,
);
});
let favoriteButton = container?.querySelector('button[title="Favoriten hervorheben"]');
expect(favoriteButton?.getAttribute("aria-pressed")).toBe("false");
await act(async () => {
root?.render(
<CanvasToolbar
activeTool="select"
onToolChange={vi.fn()}
favoriteFilterActive
onFavoriteFilterChange={vi.fn()}
/>,
);
});
favoriteButton = container?.querySelector('button[title="Favoriten hervorheben"]');
expect(favoriteButton?.getAttribute("aria-pressed")).toBe("true");
});
it("toggles and calls onFavoriteFilterChange", async () => {
const onFavoriteFilterChange = vi.fn();
await act(async () => {
root?.render(
<CanvasToolbar
activeTool="select"
onToolChange={vi.fn()}
favoriteFilterActive={false}
onFavoriteFilterChange={onFavoriteFilterChange}
/>,
);
});
const favoriteButton = container?.querySelector('button[title="Favoriten hervorheben"]');
if (!(favoriteButton instanceof HTMLButtonElement)) {
throw new Error("Favorite filter button not found");
}
await act(async () => {
favoriteButton.click();
});
expect(onFavoriteFilterChange).toHaveBeenCalledTimes(1);
expect(onFavoriteFilterChange).toHaveBeenCalledWith(true);
onFavoriteFilterChange.mockClear();
await act(async () => {
root?.render(
<CanvasToolbar
activeTool="select"
onToolChange={vi.fn()}
favoriteFilterActive
onFavoriteFilterChange={onFavoriteFilterChange}
/>,
);
});
const activeFavoriteButton = container?.querySelector('button[title="Favoriten hervorheben"]');
if (!(activeFavoriteButton instanceof HTMLButtonElement)) {
throw new Error("Active favorite filter button not found");
}
await act(async () => {
activeFavoriteButton.click();
});
expect(onFavoriteFilterChange).toHaveBeenCalledTimes(1);
expect(onFavoriteFilterChange).toHaveBeenCalledWith(false);
});
});