138 lines
4.0 KiB
TypeScript
138 lines
4.0 KiB
TypeScript
import {fireEvent, render, screen} from '@testing-library/react';
|
|
import '@testing-library/jest-dom';
|
|
import {useReactFlow, useStoreApi} from "@xyflow/react";
|
|
import {
|
|
type EditorWarning,
|
|
globalWarning
|
|
} from "../../../../../src/pages/VisProgPage/visualProgrammingUI/components/EditorWarnings.tsx";
|
|
import {WarningsSidebar} from "../../../../../src/pages/VisProgPage/visualProgrammingUI/components/WarningSidebar.tsx";
|
|
import useFlowStore from "../../../../../src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx";
|
|
|
|
|
|
jest.mock('@xyflow/react', () => ({
|
|
useReactFlow: jest.fn(),
|
|
useStoreApi: jest.fn(),
|
|
}));
|
|
|
|
jest.mock('../../../../../src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx');
|
|
|
|
function makeWarning(
|
|
overrides?: Partial<EditorWarning>
|
|
): EditorWarning {
|
|
return {
|
|
scope: { id: 'node-1' },
|
|
type: 'MISSING_INPUT',
|
|
severity: 'ERROR',
|
|
description: 'Missing input',
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
describe('WarningsSidebar', () => {
|
|
let getStateSpy: jest.SpyInstance;
|
|
|
|
const setCenter = jest.fn(() => Promise.resolve());
|
|
const getNode = jest.fn();
|
|
const addSelectedNodes = jest.fn();
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
|
|
// React Flow hooks
|
|
(useReactFlow as jest.Mock).mockReturnValue({
|
|
getNode,
|
|
setCenter,
|
|
});
|
|
(useStoreApi as jest.Mock).mockReturnValue({
|
|
getState: () => ({ addSelectedNodes }),
|
|
});
|
|
|
|
// Use spyOn to override store
|
|
const mockWarnings = [
|
|
makeWarning({ description: 'Node warning', scope: { id: 'node-1' } }),
|
|
makeWarning({
|
|
description: 'Global warning',
|
|
scope: { id: globalWarning },
|
|
type: 'INCOMPLETE_PROGRAM',
|
|
severity: 'WARNING',
|
|
}),
|
|
makeWarning({
|
|
description: 'Info warning',
|
|
scope: { id: 'node-2' },
|
|
severity: 'INFO',
|
|
}),
|
|
];
|
|
|
|
getStateSpy = jest
|
|
.spyOn(useFlowStore, 'getState')
|
|
.mockReturnValue({
|
|
getWarnings: () => mockWarnings,
|
|
} as any);
|
|
});
|
|
|
|
afterEach(() => {
|
|
getStateSpy.mockRestore();
|
|
});
|
|
|
|
it('renders warnings header', () => {
|
|
render(<WarningsSidebar />);
|
|
expect(screen.getByText('Warnings')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders all warning descriptions', () => {
|
|
render(<WarningsSidebar />);
|
|
expect(screen.getByText('Node warning')).toBeInTheDocument();
|
|
expect(screen.getByText('Global warning')).toBeInTheDocument();
|
|
expect(screen.getByText('Info warning')).toBeInTheDocument();
|
|
});
|
|
|
|
it('splits global and other warnings correctly', () => {
|
|
render(<WarningsSidebar />);
|
|
expect(screen.getByText('global:')).toBeInTheDocument();
|
|
expect(screen.getByText('other:')).toBeInTheDocument();
|
|
});
|
|
|
|
it('shows empty state when no warnings exist', () => {
|
|
getStateSpy.mockReturnValueOnce({
|
|
getWarnings: () => [],
|
|
} as any);
|
|
|
|
render(<WarningsSidebar />);
|
|
expect(screen.getByText('No warnings!')).toBeInTheDocument();
|
|
});
|
|
|
|
it('filters by severity', () => {
|
|
render(<WarningsSidebar />);
|
|
fireEvent.click(screen.getByText('ERROR'));
|
|
|
|
expect(screen.getByText('Node warning')).toBeInTheDocument();
|
|
expect(screen.queryByText('Global warning')).not.toBeInTheDocument();
|
|
expect(screen.queryByText('Info warning')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('filters INFO severity correctly', () => {
|
|
render(<WarningsSidebar />);
|
|
fireEvent.click(screen.getByText('INFO'));
|
|
|
|
expect(screen.getByText('Info warning')).toBeInTheDocument();
|
|
expect(screen.queryByText('Node warning')).not.toBeInTheDocument();
|
|
expect(screen.queryByText('Global warning')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('clicking global warning does NOT jump', () => {
|
|
render(<WarningsSidebar />);
|
|
fireEvent.click(screen.getByText('Global warning'));
|
|
|
|
expect(setCenter).not.toHaveBeenCalled();
|
|
expect(addSelectedNodes).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('does nothing if node does not exist', () => {
|
|
getNode.mockReturnValue(undefined);
|
|
|
|
render(<WarningsSidebar />);
|
|
fireEvent.click(screen.getByText('Node warning'));
|
|
|
|
expect(setCenter).not.toHaveBeenCalled();
|
|
});
|
|
}); |