Files
pepperplus-ui/test/pages/visProgPage/visualProgrammingUI/VisProgStores.test.tsx
2025-10-25 17:13:42 +02:00

225 lines
6.3 KiB
TypeScript

import {act} from '@testing-library/react';
import useFlowStore from '../../../../src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx';
import { mockReactFlow } from '../../../setupFlowTests.ts';
beforeAll(() => {
mockReactFlow();
});
describe('FlowStore Functionality', () => {
describe('Node changes', () => {
// currently just using a single function from the ReactFlow library,
// so testing would mean we are testing already tested behavior.
// if implementation gets modified tests should be added for custom behavior
});
describe('Edge changes', () => {
// currently just using a single function from the ReactFlow library,
// so testing would mean we are testing already tested behavior.
// if implementation gets modified tests should be added for custom behavior
})
describe('ReactFlow onConnect', () => {
test('adds an edge when onConnect is triggered', () => {
const {onConnect} = useFlowStore.getState();
act(() => {
onConnect({
source: 'A',
target: 'B',
sourceHandle: null,
targetHandle: null,
});
});
const updatedEdges = useFlowStore.getState().edges;
expect(updatedEdges).toHaveLength(1);
expect(updatedEdges[0]).toMatchObject({
source: 'A',
target: 'B',
});
});
});
describe('ReactFlow onReconnect', () => {
test('reconnects an existing edge when onReconnect is triggered', () => {
const {onReconnect} = useFlowStore.getState();
const oldEdge = {
id: 'xy-edge__A-B',
source: 'A',
target: 'B'
};
const newConnection = {
source: 'A',
target: 'C',
sourceHandle: null,
targetHandle: null,
};
act(() => {
useFlowStore.setState({
edges: [oldEdge]
});
onReconnect(oldEdge, newConnection);
});
const updatedEdges = useFlowStore.getState().edges;
expect(updatedEdges).toHaveLength(1);
expect(updatedEdges[0]).toMatchObject({
id: 'xy-edge__A-C',
source: 'A',
target: 'C',
});
});
});
describe('ReactFlow onReconnectStart', () => {
test('does correct setup for edge reconnection sequences', () => {
const {onReconnectStart} = useFlowStore.getState();
act(() => {
onReconnectStart();
});
const updatedState = useFlowStore.getState().edgeReconnectSuccessful;
expect(updatedState).toEqual(false);
});
});
describe('ReactFlow onReconnectEnd', () => {
// prepares the state to have an edge in the edge array
beforeEach(() => {
useFlowStore.setState({edges: [
{
id: 'xy-edge__A-B',
source: 'A',
target: 'B'
}
]}
);
});
test('successfully removes edge if no successful reconnect occurred', () => {
const {onReconnectEnd} = useFlowStore.getState();
useFlowStore.setState({edgeReconnectSuccessful: false});
act(() => {
onReconnectEnd(null, {id: 'xy-edge__A-B'});
});
const updatedState = useFlowStore.getState();
expect(updatedState.edgeReconnectSuccessful).toBe(true);
expect(updatedState.edges).toHaveLength(0);
});
test('does not remove reconnecting edge if successful reconnect occurred', () => {
const {onReconnectEnd} = useFlowStore.getState();
act(() => {
onReconnectEnd(null, {id: 'xy-edge__A-B'});
});
const updatedState = useFlowStore.getState();
expect(updatedState.edgeReconnectSuccessful).toBe(true);
expect(updatedState.edges).toHaveLength(1);
expect(updatedState.edges).toMatchObject([
{
id: 'xy-edge__A-B',
source: 'A',
target: 'B'
}]
);
});
});
describe('ReactFlow deleteNode', () => {
// test deleting A and B, so we make sure the connecting edge gets deleted regardless of
test.each([['A','B'],['B','A']])('deletes a node and its connected edges', (nodeId, undeletedNodeId) => {
const {deleteNode} = useFlowStore.getState();
useFlowStore.setState({
nodes: [
{
id: 'A',
type: 'default',
position: {x: 0, y: 0},
data: {label: 'A'}
},
{
id: 'B',
type: 'default',
position: {x: 0, y: 300},
data: {label: 'A'}
}],
edges: [
{
id: 'xy-edge__A-B',
source: 'A',
target: 'B'
}]
});
act(()=> {
deleteNode(nodeId);
});
const updatedState = useFlowStore.getState();
expect(updatedState.edges).toHaveLength(0);
expect(updatedState.nodes).toHaveLength(1);
expect(updatedState.nodes[0].id).toBe(undeletedNodeId);
});
});
describe('ReactFlow setNodes', () => {
test('sets nodes to the provided list of nodes', () => {
const {setNodes} = useFlowStore.getState();
act(() => {
setNodes([
{
id: 'start',
type: 'start',
position: {x: 0, y: 0},
data: {label: 'start'}
},
{
id: 'end',
type: 'end',
position: {x: 0, y: 300},
data: {label: 'End'}
}
]);
});
const updatedNodes = useFlowStore.getState().nodes;
expect(updatedNodes).toHaveLength(2);
expect(updatedNodes[0]).toMatchObject({
id: 'start',
type: 'start',
position: {x: 0, y: 0},
data: {label: 'start'}
});
expect(updatedNodes[1]).toMatchObject({
id: 'end',
type: 'end',
position: {x: 0, y: 300},
data: {label: 'End'}
});
});
});
describe('ReactFlow setEdges', () => {
test('sets edges to the provided list of edges', () => {
const {setEdges} = useFlowStore.getState();
act(() => {
setEdges([
{
id: 'start-end',
source: 'start',
target: 'end'
}
]);
});
const updatedEdges = useFlowStore.getState().edges;
expect(updatedEdges).toHaveLength(1);
expect(updatedEdges[0]).toMatchObject({
id: 'start-end',
source: 'start',
target: 'end'
});
});
});
});