import {renderHook} from "@testing-library/react"; import type {Connection} from "@xyflow/react"; import { ruleResult, type RuleResult, useHandleRules } from "../../../../src/pages/VisProgPage/visualProgrammingUI/HandleRuleLogic.ts"; import useFlowStore from "../../../../src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx"; describe('useHandleRules', () => { it('should register rules on mount and validate connection', () => { const rules = [() => ({ isSatisfied: true } as RuleResult)]; const { result } = renderHook(() => useHandleRules('node1', 'h1', 'target', rules)); // Confirm rules registered const storedRules = useFlowStore.getState().getTargetRules('node1', 'h1'); expect(storedRules).toEqual(rules); // Validate a connection const connection = { source: 'node2', sourceHandle: 'h2', target: 'node1', targetHandle: 'h1' }; const validation = result.current(connection); expect(validation).toEqual(ruleResult.satisfied); }); it('should throw error if targetHandle missing', () => { const rules: any[] = []; const { result } = renderHook(() => useHandleRules('node1', 'h1', 'target', rules)); expect(() => result.current({ source: 'a', target: 'b', targetHandle: null, sourceHandle: null }) ).toThrow('No target handle was provided'); }); }); describe('useHandleRules with multiple failed rules', () => { it('should return the first failed rule message and consider connectionCount', () => { // Mock rules for the target handle const failingRules = [ (_conn: any, ctx: any) => { if (ctx.connectionCount >= 1) { return { isSatisfied: false, message: 'Max connections reached' } as RuleResult; } return { isSatisfied: true } as RuleResult; }, () => ({ isSatisfied: false, message: 'Other rule failed' } as RuleResult), () => ({ isSatisfied: true } as RuleResult), ]; // Register rules for the target handle useFlowStore.getState().registerRules('targetNode', 'targetHandle', failingRules); // Add one existing edge to simulate connectionCount useFlowStore.setState({ edges: [ { id: 'edge-1', source: 'sourceNode', sourceHandle: 'sourceHandle', target: 'targetNode', targetHandle: 'targetHandle', }, ], }); // Create hook for a source node handle const rulesForSource = [ (_c: Connection) => ({ isSatisfied: true } as RuleResult) ]; const { result } = renderHook(() => useHandleRules('sourceNode', 'sourceHandle', 'source', rulesForSource) ); const connection = { source: 'sourceNode', sourceHandle: 'sourceHandle', target: 'targetNode', targetHandle: 'targetHandle', }; const validation = result.current(connection); // Should fail with first failing rule message expect(validation).toEqual(ruleResult.notSatisfied('Max connections reached')); }); });