import { describe, it, beforeEach } from '@jest/globals'; import { screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { renderWithProviders } from '../.././/./../../test-utils/test-utils'; import TriggerNode, { TriggerReduce, TriggerConnects, TriggerNodeCanConnect, type TriggerNodeData } from '../../../../../src/pages/VisProgPage/visualProgrammingUI/nodes/TriggerNode'; import useFlowStore from '../../../../../src/pages/VisProgPage/visualProgrammingUI/VisProgStores'; import type { Node } from '@xyflow/react'; import '@testing-library/jest-dom'; describe('TriggerNode', () => { let user: ReturnType; beforeEach(() => { user = userEvent.setup(); }); describe('Rendering', () => { it('should render TriggerNode with keywords type', () => { const mockNode: Node = { id: 'trigger-1', type: 'trigger', position: { x: 0, y: 0 }, data: { label: 'Keyword Trigger', droppable: true, triggerType: 'keywords', triggers: [], hasReduce: true, }, }; renderWithProviders( ); expect(screen.getByText(/Triggers when the keyword is spoken/i)).toBeInTheDocument(); expect(screen.getByPlaceholderText('...')).toBeInTheDocument(); }); it('should render TriggerNode with emotion type', () => { const mockNode: Node = { id: 'trigger-2', type: 'trigger', position: { x: 0, y: 0 }, data: { label: 'Emotion Trigger', droppable: true, triggerType: 'emotion', triggers: [], hasReduce: true, }, }; renderWithProviders( ); expect(screen.getByText(/Emotion\?/i)).toBeInTheDocument(); }); }); describe('User Interactions', () => { it('should add a new keyword', async () => { const mockNode: Node = { id: 'trigger-1', type: 'trigger', position: { x: 0, y: 0 }, data: { label: 'Keyword Trigger', droppable: true, triggerType: 'keywords', triggers: [], hasReduce: true, }, }; useFlowStore.setState({ nodes: [mockNode], edges: [] }); renderWithProviders( ); const input = screen.getByPlaceholderText('...'); await user.type(input, 'hello{enter}'); await waitFor(() => { const node = useFlowStore.getState().nodes.find(n => n.id === 'trigger-1') as Node | undefined; expect(node?.data.triggers.length).toBe(1); expect(node?.data.triggers[0].keyword).toBe('hello'); }); }); it('should remove a keyword when cleared', async () => { const mockNode: Node = { id: 'trigger-1', type: 'trigger', position: { x: 0, y: 0 }, data: { label: 'Keyword Trigger', droppable: true, triggerType: 'keywords', triggers: [{ id: 'kw1', keyword: 'hello' }], hasReduce: true, }, }; useFlowStore.setState({ nodes: [mockNode], edges: [] }); renderWithProviders( ); const input = screen.getByDisplayValue('hello'); for (let i = 0; i < 'hello'.length; i++) { await user.type(input, '{backspace}'); } await user.type(input, '{enter}'); await waitFor(() => { const node = useFlowStore.getState().nodes.find(n => n.id === 'trigger-1') as Node | undefined; expect(node?.data.triggers.length).toBe(0); }); }); }); describe('TriggerReduce Function', () => { it('should reduce a trigger node to its essential data', () => { const triggerNode: Node = { id: 'trigger-1', type: 'trigger', position: { x: 0, y: 0 }, data: { label: 'Keyword Trigger', droppable: true, triggerType: 'keywords', triggers: [{ id: 'kw1', keyword: 'hello' }], hasReduce: true, }, }; const allNodes: Node[] = [triggerNode]; const result = TriggerReduce(triggerNode, allNodes); expect(result).toEqual({ id: 'trigger-1', type: 'keywords', label: 'Keyword Trigger', keywords: [{ id: 'kw1', keyword: 'hello' }], }); }); }); describe('TriggerConnects Function', () => { it('should handle connection without errors', () => { const node1: Node = { id: 'trigger-1', type: 'trigger', position: { x: 0, y: 0 }, data: { label: 'Trigger 1', droppable: true, triggerType: 'keywords', triggers: [], hasReduce: true, }, }; const node2: Node = { id: 'norm-1', type: 'norm', position: { x: 100, y: 0 }, data: { label: 'Norm 1', droppable: true, norm: 'test', hasReduce: true, }, }; expect(() => { TriggerConnects(node1, node2, true); TriggerConnects(node1, node2, false); }).not.toThrow(); }); it('should return true for TriggerNodeCanConnect if connection exists', () => { const connection = { source: 'trigger-1', target: 'norm-1' }; expect(TriggerNodeCanConnect(connection as any)).toBe(true); }); }); });