Files
jobtrackingapp/job-tracker-ui/src/components/DashboardGrid.test.tsx
T

76 lines
4.3 KiB
TypeScript

import React from 'react';
import { fireEvent, render, screen, within } from '@testing-library/react';
import DashboardGrid from './DashboardGrid';
import { defaultDashboardLayout } from '../dashboardLayout';
import { I18nProvider } from '../i18n/I18nProvider';
let mockGridProps: any;
let mockMeasuredWidth = 1200;
jest.mock('react-grid-layout', () => ({
...jest.requireActual('react-grid-layout'),
__esModule: true,
default: (props: any) => { mockGridProps = props; return <div>{props.children}</div>; },
useContainerWidth: () => ({ width: mockMeasuredWidth, containerRef: { current: null } }),
}));
beforeEach(() => { mockMeasuredWidth = 1200; mockGridProps = null; });
test('library collision handling resolves resize overlaps but leaves deliberate gaps unchanged', () => {
render(<I18nProvider><DashboardGrid layout={defaultDashboardLayout()} editing disabled={false} onChange={jest.fn()} childrenFor={() => <p>Report</p>} /></I18nProvider>);
const items = [
{ i: 'a', x: 0, y: 17, w: 6, h: 10 },
{ i: 'b', x: 0, y: 25, w: 6, h: 8 },
{ i: 'c', x: 6, y: 25, w: 6, h: 8 },
];
const original = JSON.stringify(items);
const resolved = mockGridProps.compactor.compact(items, 12);
const { getAllCollisions } = jest.requireActual('react-grid-layout');
expect(resolved.every((item: any) => getAllCollisions(resolved, item).length === 0)).toBe(true);
expect(JSON.stringify(items)).toBe(original);
const spaced = [{ i: 'a', x: 4, y: 17, w: 8, h: 10 }];
expect(mockGridProps.compactor.compact(spaced, 12)).toMatchObject(spaced);
});
test('mount and compaction do not save; completed resize keeps hidden geometry and uses the draft owner revision', () => {
const layout = defaultDashboardLayout(); layout.revision = 8;
layout.widgets[2] = { ...layout.widgets[2], visible: false, x: 4, y: 17, w: 8, h: 10 };
const change = jest.fn();
render(<I18nProvider><DashboardGrid layout={layout} editing disabled={false} onChange={change} childrenFor={widget => <p>{widget.id} content</p>} /></I18nProvider>);
expect(change).not.toHaveBeenCalled();
expect(mockGridProps.onLayoutChange).toBeUndefined();
const next = mockGridProps.layout.map((row: any) => row.i === 'attention' ? { ...row, w: 8, h: 12 } : row);
mockGridProps.onResizeStop(next);
expect(change).toHaveBeenCalledTimes(1);
const saved = change.mock.calls[0][0];
expect(saved.revision).toBe(8);
expect(saved.widgets.find((widget: { id: string }) => widget.id === 'attention')).toMatchObject({ w: 8, h: 12, size: 'standard' });
expect(saved.widgets[2]).toEqual(layout.widgets[2]);
});
test('narrow viewport retains desktop geometry and keyboard height changes are bounded', () => {
mockMeasuredWidth = 390;
const layout = defaultDashboardLayout();
const change = jest.fn();
const view = render(<I18nProvider><DashboardGrid layout={layout} editing disabled={false} onChange={change} childrenFor={widget => <p>{widget.id} content</p>} /></I18nProvider>);
expect(mockGridProps).toBeNull();
expect(change).not.toHaveBeenCalled();
const preview = screen.getByRole('region', { name: 'Dashboard preview' });
fireEvent.click(within(preview).getByText('Today'));
fireEvent.change(screen.getByLabelText('Height for Today'), { target: { value: '25' } });
expect(change).not.toHaveBeenCalled();
fireEvent.change(screen.getByLabelText('Height for Today'), { target: { value: '12' } });
expect(change.mock.calls[0][0].widgets.find((widget: { id: string }) => widget.id === 'attention').h).toBe(12);
mockMeasuredWidth = 1200;
view.rerender(<I18nProvider><DashboardGrid layout={layout} editing disabled={false} onChange={change} childrenFor={widget => <p>{widget.id} content</p>} /></I18nProvider>);
expect(change).toHaveBeenCalledTimes(1);
expect(mockGridProps.layout[1]).toMatchObject({ x: layout.widgets[1].x, y: layout.widgets[1].y });
});
test('conflict disables pointer operations and ignores a late completion callback', () => {
const change = jest.fn();
render(<I18nProvider><DashboardGrid layout={defaultDashboardLayout()} editing disabled onChange={change} childrenFor={() => <p>Report</p>} /></I18nProvider>);
expect(mockGridProps.dragConfig.enabled).toBe(false);
expect(mockGridProps.resizeConfig.enabled).toBe(false);
mockGridProps.onDragStop(mockGridProps.layout);
expect(change).not.toHaveBeenCalled();
});