import { render, screen, fireEvent } from '@testing-library/react'; import { ReactFlowProvider } from '@xyflow/react'; import { WorkflowNode } from '../WorkflowNode'; import type { WfNode } from '../types'; // xyflow handles need a provider + measured store; render inside one. function renderNode(props: Parameters[0]) { return render( ); } function baseData(overrides: Partial = {}) { const node: WfNode = { id: 'n1', name: 'Send email', type: 'action.email', ...overrides, }; return { node, category: 'action', status: 'idle' as const, }; } describe('WorkflowNode', () => { it('renders the node title', () => { renderNode({ id: 'n1', data: baseData(), selected: false } as never); expect(screen.getByText('Send email')).toBeInTheDocument(); }); it('renders a status badge reflecting the node status', () => { renderNode({ id: 'n1', data: { ...baseData(), status: 'running' }, selected: false, } as never); expect(screen.getByText('Running')).toBeInTheDocument(); }); it('renders the category label from the theme', () => { renderNode({ id: 'n1', data: baseData(), selected: false } as never); // action category resolves to label "Action" expect(screen.getByText('Action')).toBeInTheDocument(); }); it('renders one output handle per output (multi-output: if/else)', () => { const { container } = renderNode({ id: 'n1', data: { ...baseData({ type: 'condition.if' }), category: 'condition', outputLabels: ['true', 'false'], outputCount: 2, }, selected: false, } as never); const outputs = container.querySelectorAll('[data-handle-kind="output"]'); expect(outputs).toHaveLength(2); expect(screen.getByText('true')).toBeInTheDocument(); expect(screen.getByText('false')).toBeInTheDocument(); }); it('applies disabled styling when disabled', () => { const { container } = renderNode({ id: 'n1', data: { ...baseData({ disabled: true }) }, selected: false, } as never); expect( container.querySelector('[data-disabled="true"]') ).toBeInTheDocument(); }); it('invokes onRename when the title is edited', () => { const onRename = jest.fn(); renderNode({ id: 'n1', data: { ...baseData(), onRename }, selected: true, } as never); // double-click the title to enter edit mode fireEvent.doubleClick(screen.getByText('Send email')); const input = screen.getByRole('textbox'); fireEvent.change(input, { target: { value: 'Send welcome email' } }); fireEvent.blur(input); expect(onRename).toHaveBeenCalledWith('n1', 'Send welcome email'); }); });