diff --git a/test/cases/pageComponents/app/detail/WorkflowComponents/utils.test.ts b/test/cases/pageComponents/app/detail/WorkflowComponents/utils.test.ts new file mode 100644 index 000000000..779b462ed --- /dev/null +++ b/test/cases/pageComponents/app/detail/WorkflowComponents/utils.test.ts @@ -0,0 +1,179 @@ +import { describe, expect, it, vi } from 'vitest'; +import { + uiWorkflow2StoreWorkflow, + filterExportModules, + getEditorVariables +} from '@/pageComponents/app/detail/WorkflowComponents/utils'; +import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant'; +import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; +import type { FlowNodeItemType } from '@fastgpt/global/core/workflow/type/node.d'; +import type { AppDetailType } from '@fastgpt/global/core/app/type'; + +vi.mock('@/web/core/workflow/utils', () => ({ + getNodeAllSource: vi.fn().mockReturnValue([]) +})); + +describe('WorkflowComponents utils', () => { + describe('uiWorkflow2StoreWorkflow', () => { + it('should convert UI workflow to store workflow', () => { + const mockHandleList = [{ getAttribute: () => 'source1' }, { getAttribute: () => 'target1' }]; + + const mockQuerySelector = vi.fn().mockReturnValue({ + querySelectorAll: () => mockHandleList + }); + + global.document = { + querySelector: mockQuerySelector + } as any; + + const nodes = [ + { + data: { + nodeId: '1', + parentNodeId: 'parent1', + name: 'Node 1', + intro: 'Intro 1', + toolDescription: 'Tool desc', + avatar: 'avatar1', + flowNodeType: FlowNodeTypeEnum.userInput, + showStatus: true, + version: 1, + inputs: [], + outputs: [], + isFolded: false, + pluginId: 'plugin1', + toolConfig: {}, + catchError: false + }, + position: { x: 100, y: 100 } + } + ]; + + const edges = [ + { + source: '1', + target: '2', + sourceHandle: 'source1', + targetHandle: 'target1' + } + ]; + + const result = uiWorkflow2StoreWorkflow({ nodes, edges }); + + expect(result.nodes[0]).toMatchObject({ + nodeId: '1', + parentNodeId: 'parent1', + name: 'Node 1', + intro: 'Intro 1', + toolDescription: 'Tool desc', + avatar: 'avatar1', + flowNodeType: FlowNodeTypeEnum.userInput, + position: { x: 100, y: 100 } + }); + + expect(result.edges).toHaveLength(1); + expect(result.edges[0]).toMatchObject({ + source: '1', + target: '2', + sourceHandle: 'source1', + targetHandle: 'target1' + }); + }); + }); + + describe('filterExportModules', () => { + it('should filter dataset search node values', () => { + const modules = [ + { + flowNodeType: FlowNodeTypeEnum.datasetSearchNode, + inputs: [ + { + key: NodeInputKeyEnum.datasetSelectList, + value: ['dataset1'] + } + ] + } + ]; + + const result = filterExportModules(modules); + const parsed = JSON.parse(result); + + expect(parsed[0].inputs[0].value).toEqual([]); + }); + + it('should not modify non-dataset nodes', () => { + const modules = [ + { + flowNodeType: FlowNodeTypeEnum.userInput, + inputs: [ + { + key: 'someKey', + value: ['value1'] + } + ] + } + ]; + + const result = filterExportModules(modules); + const parsed = JSON.parse(result); + + expect(parsed[0].inputs[0].value).toEqual(['value1']); + }); + }); + + describe('getEditorVariables', () => { + it('should return variables for node', () => { + const nodeId = 'node1'; + const nodeList: FlowNodeItemType[] = [ + { + nodeId: 'node1', + name: 'Node 1', + avatar: 'avatar1', + inputs: [ + { + key: 'input1', + label: 'Input 1', + canEdit: true + } + ], + outputs: [] + } + ]; + const edges = []; + const appDetail = { + chatConfig: {} + } as AppDetailType; + const t = (key: string) => key; + + const result = getEditorVariables({ + nodeId, + nodeList, + edges, + appDetail, + t + }); + + expect(result[0]).toEqual({ + key: 'input1', + label: 'Input 1', + parent: { + id: 'node1', + label: 'Node 1', + avatar: 'avatar1' + } + }); + }); + + it('should return empty array when node not found', () => { + const result = getEditorVariables({ + nodeId: 'nonexistent', + nodeList: [], + edges: [], + appDetail: {} as AppDetailType, + t: (key: string) => key + }); + + expect(result).toEqual([]); + }); + }); +});