diff --git a/packages/agentflow/jest.config.js b/packages/agentflow/jest.config.js index fcbcdcf71..24f9fe624 100644 --- a/packages/agentflow/jest.config.js +++ b/packages/agentflow/jest.config.js @@ -20,6 +20,7 @@ const baseConfig = { // so we redirect to lightweight CJS stubs under src/__mocks__/. '^@tiptap/(.+)$': '/src/__mocks__/@tiptap/$1.ts', '^lowlight$': '/src/__mocks__/lowlight.ts', + '^tippy\\.js$': '/src/__mocks__/tippy.js.ts', // Bypass React.lazy wrappers — resolve Foo.lazy → Foo so tests render synchronously '(.*)\\.lazy$': '$1' } diff --git a/packages/agentflow/package.json b/packages/agentflow/package.json index 204fa1c82..696b571fe 100644 --- a/packages/agentflow/package.json +++ b/packages/agentflow/package.json @@ -72,10 +72,13 @@ "@codemirror/lang-json": "^6.0.0", "@codemirror/lang-python": "^6.1.0", "@tabler/icons-react": "^3.7.0", - "@tiptap/extension-code-block-lowlight": "^3.4.3", - "@tiptap/extension-placeholder": "^2.11.5", - "@tiptap/react": "^2.11.5", - "@tiptap/starter-kit": "^2.11.5", + "@tiptap/core": "^3.20.4", + "@tiptap/extension-code-block-lowlight": "^3.20.4", + "@tiptap/extension-mention": "^3.20.4", + "@tiptap/extension-placeholder": "^3.20.4", + "@tiptap/pm": "^3.20.4", + "@tiptap/react": "^3.20.4", + "@tiptap/starter-kit": "^3.20.4", "@uiw/codemirror-theme-sublime": "^4.21.0", "@uiw/codemirror-theme-vscode": "^4.21.0", "@uiw/react-codemirror": "^4.21.0", @@ -85,6 +88,7 @@ "html-react-parser": "^3.0.16", "lodash": "^4.17.21", "lowlight": "^3.3.0", + "tippy.js": "^6.3.7", "uuid": "^10.0.0" }, "devDependencies": { diff --git a/packages/agentflow/src/__mocks__/@tiptap/core.ts b/packages/agentflow/src/__mocks__/@tiptap/core.ts new file mode 100644 index 000000000..bb6a5e359 --- /dev/null +++ b/packages/agentflow/src/__mocks__/@tiptap/core.ts @@ -0,0 +1,10 @@ +export const mergeAttributes = jest.fn((...attrs: Record[]) => Object.assign({}, ...attrs)) + +export class PasteRule { + find: unknown + handler: unknown + constructor(config: Record) { + this.find = config.find + this.handler = config.handler + } +} diff --git a/packages/agentflow/src/__mocks__/@tiptap/extension-mention.ts b/packages/agentflow/src/__mocks__/@tiptap/extension-mention.ts new file mode 100644 index 000000000..1c46115c4 --- /dev/null +++ b/packages/agentflow/src/__mocks__/@tiptap/extension-mention.ts @@ -0,0 +1,7 @@ +const Mention = { + extend: jest.fn(() => ({ + configure: jest.fn(() => 'CustomMention') + })), + configure: jest.fn(() => 'Mention') +} +export default Mention diff --git a/packages/agentflow/src/__mocks__/@tiptap/markdown.ts b/packages/agentflow/src/__mocks__/@tiptap/markdown.ts new file mode 100644 index 000000000..66d5f003a --- /dev/null +++ b/packages/agentflow/src/__mocks__/@tiptap/markdown.ts @@ -0,0 +1 @@ +export const Markdown = { configure: jest.fn(() => 'Markdown') } diff --git a/packages/agentflow/src/__mocks__/@tiptap/pm.ts b/packages/agentflow/src/__mocks__/@tiptap/pm.ts new file mode 100644 index 000000000..3ee412e96 --- /dev/null +++ b/packages/agentflow/src/__mocks__/@tiptap/pm.ts @@ -0,0 +1,4 @@ +export const model = {} +export const state = {} +export const view = {} +export const transform = {} diff --git a/packages/agentflow/src/__mocks__/@tiptap/react.ts b/packages/agentflow/src/__mocks__/@tiptap/react.ts index 82cce7a97..f2443a169 100644 --- a/packages/agentflow/src/__mocks__/@tiptap/react.ts +++ b/packages/agentflow/src/__mocks__/@tiptap/react.ts @@ -2,6 +2,7 @@ import { createElement, forwardRef } from 'react' export const useEditor = (config?: Record) => ({ getHTML: () => (config?.content as string) ?? '

', + getMarkdown: () => (config?.content as string) ?? '', setEditable: jest.fn(), commands: { focus: jest.fn(), setContent: jest.fn() }, _onUpdate: config?.onUpdate @@ -11,3 +12,10 @@ export const EditorContent = forwardRef ({ + element: document.createElement('div'), + ref: null, + updateProps: jest.fn(), + destroy: jest.fn() +})) diff --git a/packages/agentflow/src/__mocks__/tippy.js.ts b/packages/agentflow/src/__mocks__/tippy.js.ts new file mode 100644 index 000000000..5dea12889 --- /dev/null +++ b/packages/agentflow/src/__mocks__/tippy.js.ts @@ -0,0 +1,9 @@ +const tippy = jest.fn(() => [ + { + setProps: jest.fn(), + destroy: jest.fn(), + hide: jest.fn(), + show: jest.fn() + } +]) +export default tippy diff --git a/packages/agentflow/src/atoms/JsonInput.tsx b/packages/agentflow/src/atoms/JsonInput.tsx index c85ebca00..51540b953 100644 --- a/packages/agentflow/src/atoms/JsonInput.tsx +++ b/packages/agentflow/src/atoms/JsonInput.tsx @@ -4,8 +4,8 @@ import { FormControl, Popover } from '@mui/material' import { useTheme } from '@mui/material/styles' import ReactJson from 'flowise-react-json-view' -import type { VariableItem } from './SelectVariable' -import { SelectVariable } from './SelectVariable' +import type { VariableItem } from './VariablePicker' +import { VariablePicker } from './VariablePicker' export interface JsonInputProps { value: string @@ -153,7 +153,7 @@ export function JsonInput({ value, onChange, disabled = false, variableItems }: transformOrigin={{ vertical: 'top', horizontal: 'left' }} slotProps={{ paper: { sx: { width: 320, maxHeight: 400 } } }} > - { setNewVal(val) diff --git a/packages/agentflow/src/atoms/NodeInputHandler.test.tsx b/packages/agentflow/src/atoms/NodeInputHandler.test.tsx index fff3a6d8d..aac393cf5 100644 --- a/packages/agentflow/src/atoms/NodeInputHandler.test.tsx +++ b/packages/agentflow/src/atoms/NodeInputHandler.test.tsx @@ -36,6 +36,12 @@ jest.mock('./RichTextEditor.lazy', () => ({ ) })) +jest.mock('./VariableInput', () => ({ + VariableInput: ({ suggestionItems }: { suggestionItems?: { id: string }[] }) => ( +
i.id))} /> + ) +})) + jest.mock('@tabler/icons-react', () => ({ IconArrowsMaximize: () => , IconInfoCircle: () => , @@ -328,8 +334,8 @@ jest.mock('./JsonInput', () => ({ ) })) -jest.mock('./SelectVariable', () => ({ - SelectVariable: ({ items, onSelect }: { items: Array<{ value: string }>; onSelect: (v: string) => void }) => ( +jest.mock('./VariablePicker', () => ({ + VariablePicker: ({ items, onSelect }: { items: Array<{ value: string }>; onSelect: (v: string) => void }) => (
{items.map((item, i) => (