247 lines
6.9 KiB
TypeScript
247 lines
6.9 KiB
TypeScript
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<typeof userEvent.setup>;
|
|
|
|
beforeEach(() => {
|
|
user = userEvent.setup();
|
|
});
|
|
|
|
describe('Rendering', () => {
|
|
it('should render TriggerNode with keywords type', () => {
|
|
const mockNode: Node<TriggerNodeData> = {
|
|
id: 'trigger-1',
|
|
type: 'trigger',
|
|
position: { x: 0, y: 0 },
|
|
data: {
|
|
label: 'Keyword Trigger',
|
|
droppable: true,
|
|
triggerType: 'keywords',
|
|
triggers: [],
|
|
hasReduce: true,
|
|
},
|
|
};
|
|
|
|
renderWithProviders(
|
|
<TriggerNode
|
|
id={mockNode.id}
|
|
type={mockNode.type as string}
|
|
data={mockNode.data as any}
|
|
selected={false}
|
|
isConnectable={true}
|
|
zIndex={0}
|
|
dragging={false}
|
|
selectable={true}
|
|
deletable={true}
|
|
draggable={true}
|
|
positionAbsoluteX={0}
|
|
positionAbsoluteY={0}
|
|
/>
|
|
);
|
|
|
|
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<TriggerNodeData> = {
|
|
id: 'trigger-2',
|
|
type: 'trigger',
|
|
position: { x: 0, y: 0 },
|
|
data: {
|
|
label: 'Emotion Trigger',
|
|
droppable: true,
|
|
triggerType: 'emotion',
|
|
triggers: [],
|
|
hasReduce: true,
|
|
},
|
|
};
|
|
|
|
renderWithProviders(
|
|
<TriggerNode
|
|
id={mockNode.id}
|
|
type={mockNode.type as string}
|
|
data={mockNode.data as any}
|
|
selected={false}
|
|
isConnectable={true}
|
|
zIndex={0}
|
|
dragging={false}
|
|
selectable={true}
|
|
deletable={true}
|
|
draggable={true}
|
|
positionAbsoluteX={0}
|
|
positionAbsoluteY={0}
|
|
/>
|
|
);
|
|
|
|
expect(screen.getByText(/Emotion\?/i)).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
describe('User Interactions', () => {
|
|
it('should add a new keyword', async () => {
|
|
const mockNode: Node<TriggerNodeData> = {
|
|
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(
|
|
<TriggerNode
|
|
id={mockNode.id}
|
|
type={mockNode.type as string}
|
|
data={mockNode.data as any}
|
|
selected={false}
|
|
isConnectable={true}
|
|
zIndex={0}
|
|
dragging={false}
|
|
selectable={true}
|
|
deletable={true}
|
|
draggable={true}
|
|
positionAbsoluteX={0}
|
|
positionAbsoluteY={0}
|
|
/>
|
|
);
|
|
|
|
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<TriggerNodeData> | 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<TriggerNodeData> = {
|
|
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(
|
|
<TriggerNode
|
|
id={mockNode.id}
|
|
type={mockNode.type as string}
|
|
data={mockNode.data as any}
|
|
selected={false}
|
|
isConnectable={true}
|
|
zIndex={0}
|
|
dragging={false}
|
|
selectable={true}
|
|
deletable={true}
|
|
draggable={true}
|
|
positionAbsoluteX={0}
|
|
positionAbsoluteY={0}
|
|
/>
|
|
);
|
|
|
|
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<TriggerNodeData> | 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);
|
|
});
|
|
});
|
|
});
|