Files
stack/apps/web/src/components/widgets/__tests__/WidgetGrid.test.tsx
T
jason.woltjeandClaude Sonnet 4.5 f0704db560 fix: Resolve web package lint and typecheck errors
Fixes ESLint and TypeScript errors in web package to pass CI checks:

- Fixed all Quality Rails violations (14 explicit any types)
- Fixed deprecated React event types (FormEvent → SyntheticEvent)
- Fixed 26 TypeScript errors (Promise types, test mocks, HTMLElement assertions)
- Added vitest DOM matcher type definitions
- Fixed unused variables and empty functions
- Resolved 43+ additional lint errors

Typecheck:  0 errors
Lint: 542 remaining (non-blocking in CI)

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2026-01-30 21:34:12 -06:00

103 lines
3.2 KiB
TypeScript

/**
* WidgetGrid Component Tests
* Following TDD - write tests first!
*/
import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import { WidgetGrid } from "../WidgetGrid";
import type { WidgetPlacement } from "@mosaic/shared";
// Mock react-grid-layout
vi.mock("react-grid-layout", () => ({
default: ({ children }: { children: React.ReactNode }) => (
<div data-testid="grid-layout">{children}</div>
),
Responsive: ({ children }: { children: React.ReactNode }) => (
<div data-testid="responsive-grid-layout">{children}</div>
),
}));
describe("WidgetGrid", (): void => {
const mockLayout: WidgetPlacement[] = [
{ i: "tasks-1", x: 0, y: 0, w: 2, h: 2 },
{ i: "calendar-1", x: 2, y: 0, w: 2, h: 2 },
];
const mockOnLayoutChange = vi.fn();
it("should render grid layout", (): void => {
render(<WidgetGrid layout={mockLayout} onLayoutChange={mockOnLayoutChange} />);
expect(screen.getByTestId("grid-layout")).toBeInTheDocument();
});
it("should render widgets from layout", (): void => {
render(<WidgetGrid layout={mockLayout} onLayoutChange={mockOnLayoutChange} />);
// Should render correct number of widgets
const widgets = screen.getAllByTestId(/widget-/);
expect(widgets).toHaveLength(mockLayout.length);
});
it("should call onLayoutChange when layout changes", (): void => {
const { rerender } = render(
<WidgetGrid layout={mockLayout} onLayoutChange={mockOnLayoutChange} />
);
const newLayout: WidgetPlacement[] = [
{ i: "tasks-1", x: 1, y: 0, w: 2, h: 2 },
{ i: "calendar-1", x: 2, y: 0, w: 2, h: 2 },
];
rerender(<WidgetGrid layout={newLayout} onLayoutChange={mockOnLayoutChange} />);
// Layout change handler should be set up (actual calls handled by react-grid-layout)
expect(mockOnLayoutChange).toBeDefined();
});
it("should support edit mode", (): void => {
render(<WidgetGrid layout={mockLayout} onLayoutChange={mockOnLayoutChange} isEditing={true} />);
// In edit mode, widgets should have edit controls
expect(screen.getByTestId("grid-layout")).toBeInTheDocument();
});
it("should support read-only mode", (): void => {
render(
<WidgetGrid layout={mockLayout} onLayoutChange={mockOnLayoutChange} isEditing={false} />
);
expect(screen.getByTestId("grid-layout")).toBeInTheDocument();
});
it("should render empty state when no widgets", (): void => {
render(<WidgetGrid layout={[]} onLayoutChange={mockOnLayoutChange} />);
expect(screen.getByText(/no widgets/i)).toBeInTheDocument();
});
it("should handle widget removal", (): void => {
const mockOnRemoveWidget = vi.fn();
render(
<WidgetGrid
layout={mockLayout}
onLayoutChange={mockOnLayoutChange}
onRemoveWidget={mockOnRemoveWidget}
isEditing={true}
/>
);
// Widget removal should be supported
expect(mockOnRemoveWidget).toBeDefined();
});
it("should apply custom className", (): void => {
const { container } = render(
<WidgetGrid layout={mockLayout} onLayoutChange={mockOnLayoutChange} className="custom-grid" />
);
expect(container.querySelector(".custom-grid")).toBeInTheDocument();
});
});