mirror of
https://github.com/langgenius/dify.git
synced 2026-04-15 09:57:03 +08:00
fix: web tests
This commit is contained in:
parent
7520d65a7e
commit
341fdc8201
@ -69,6 +69,7 @@ vi.mock('lexical', async (importOriginal) => {
|
|||||||
getChildren: () => mocks.rootLines.map(line => ({
|
getChildren: () => mocks.rootLines.map(line => ({
|
||||||
getTextContent: () => line,
|
getTextContent: () => line,
|
||||||
})),
|
})),
|
||||||
|
getAllTextNodes: () => [],
|
||||||
}),
|
}),
|
||||||
TextNode: class TextNode {
|
TextNode: class TextNode {
|
||||||
__text: string
|
__text: string
|
||||||
|
|||||||
@ -21,6 +21,16 @@ vi.mock('@/context/dataset-detail', () => ({
|
|||||||
selector({ dataset: { doc_form: ChunkingMode.text } }),
|
selector({ dataset: { doc_form: ChunkingMode.text } }),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/app/components/datasets/metadata/hooks/use-batch-edit-document-metadata', () => ({
|
||||||
|
default: () => ({
|
||||||
|
isShowEditModal: false,
|
||||||
|
showEditModal: vi.fn(),
|
||||||
|
hideEditModal: vi.fn(),
|
||||||
|
originalList: [],
|
||||||
|
handleSave: vi.fn(),
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
|
||||||
const createTestQueryClient = () => new QueryClient({
|
const createTestQueryClient = () => new QueryClient({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
queries: { retry: false, gcTime: 0 },
|
queries: { retry: false, gcTime: 0 },
|
||||||
|
|||||||
@ -8,6 +8,7 @@ const mockUseStore = vi.hoisted(() => vi.fn())
|
|||||||
const mockUseNodesInteractions = vi.hoisted(() => vi.fn())
|
const mockUseNodesInteractions = vi.hoisted(() => vi.fn())
|
||||||
const mockUsePanelInteractions = vi.hoisted(() => vi.fn())
|
const mockUsePanelInteractions = vi.hoisted(() => vi.fn())
|
||||||
const mockUseWorkflowStartRun = vi.hoisted(() => vi.fn())
|
const mockUseWorkflowStartRun = vi.hoisted(() => vi.fn())
|
||||||
|
const mockUseWorkflowMoveMode = vi.hoisted(() => vi.fn())
|
||||||
const mockUseOperator = vi.hoisted(() => vi.fn())
|
const mockUseOperator = vi.hoisted(() => vi.fn())
|
||||||
const mockUseDSL = vi.hoisted(() => vi.fn())
|
const mockUseDSL = vi.hoisted(() => vi.fn())
|
||||||
|
|
||||||
@ -23,6 +24,9 @@ vi.mock('@/app/components/workflow/store', () => ({
|
|||||||
useStore: (selector: (state: {
|
useStore: (selector: (state: {
|
||||||
panelMenu?: { left: number, top: number }
|
panelMenu?: { left: number, top: number }
|
||||||
clipboardElements: unknown[]
|
clipboardElements: unknown[]
|
||||||
|
pendingComment: null | { pageX: number, pageY: number, elementX: number, elementY: number }
|
||||||
|
setCommentPlacing: (placing: boolean) => void
|
||||||
|
setCommentQuickAdd: (quickAdd: boolean) => void
|
||||||
setShowImportDSLModal: (visible: boolean) => void
|
setShowImportDSLModal: (visible: boolean) => void
|
||||||
}) => unknown) => mockUseStore(selector),
|
}) => unknown) => mockUseStore(selector),
|
||||||
}))
|
}))
|
||||||
@ -31,6 +35,7 @@ vi.mock('@/app/components/workflow/hooks', () => ({
|
|||||||
useNodesInteractions: () => mockUseNodesInteractions(),
|
useNodesInteractions: () => mockUseNodesInteractions(),
|
||||||
usePanelInteractions: () => mockUsePanelInteractions(),
|
usePanelInteractions: () => mockUsePanelInteractions(),
|
||||||
useWorkflowStartRun: () => mockUseWorkflowStartRun(),
|
useWorkflowStartRun: () => mockUseWorkflowStartRun(),
|
||||||
|
useWorkflowMoveMode: () => mockUseWorkflowMoveMode(),
|
||||||
useDSL: () => mockUseDSL(),
|
useDSL: () => mockUseDSL(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@ -62,14 +67,18 @@ describe('PanelContextmenu', () => {
|
|||||||
const mockHandleAddNote = vi.fn()
|
const mockHandleAddNote = vi.fn()
|
||||||
const mockExportCheck = vi.fn()
|
const mockExportCheck = vi.fn()
|
||||||
const mockSetShowImportDSLModal = vi.fn()
|
const mockSetShowImportDSLModal = vi.fn()
|
||||||
|
const mockSetCommentPlacing = vi.fn()
|
||||||
|
const mockSetCommentQuickAdd = vi.fn()
|
||||||
let panelMenu: { left: number, top: number } | undefined
|
let panelMenu: { left: number, top: number } | undefined
|
||||||
let clipboardElements: unknown[]
|
let clipboardElements: unknown[]
|
||||||
|
let pendingComment: null | { pageX: number, pageY: number, elementX: number, elementY: number }
|
||||||
let clickAwayHandler: (() => void) | undefined
|
let clickAwayHandler: (() => void) | undefined
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks()
|
vi.clearAllMocks()
|
||||||
panelMenu = undefined
|
panelMenu = undefined
|
||||||
clipboardElements = []
|
clipboardElements = []
|
||||||
|
pendingComment = null
|
||||||
clickAwayHandler = undefined
|
clickAwayHandler = undefined
|
||||||
|
|
||||||
mockUseClickAway.mockImplementation((handler: () => void) => {
|
mockUseClickAway.mockImplementation((handler: () => void) => {
|
||||||
@ -81,10 +90,16 @@ describe('PanelContextmenu', () => {
|
|||||||
mockUseStore.mockImplementation((selector: (state: {
|
mockUseStore.mockImplementation((selector: (state: {
|
||||||
panelMenu?: { left: number, top: number }
|
panelMenu?: { left: number, top: number }
|
||||||
clipboardElements: unknown[]
|
clipboardElements: unknown[]
|
||||||
|
pendingComment: null | { pageX: number, pageY: number, elementX: number, elementY: number }
|
||||||
|
setCommentPlacing: (placing: boolean) => void
|
||||||
|
setCommentQuickAdd: (quickAdd: boolean) => void
|
||||||
setShowImportDSLModal: (visible: boolean) => void
|
setShowImportDSLModal: (visible: boolean) => void
|
||||||
}) => unknown) => selector({
|
}) => unknown) => selector({
|
||||||
panelMenu,
|
panelMenu,
|
||||||
clipboardElements,
|
clipboardElements,
|
||||||
|
pendingComment,
|
||||||
|
setCommentPlacing: mockSetCommentPlacing,
|
||||||
|
setCommentQuickAdd: mockSetCommentQuickAdd,
|
||||||
setShowImportDSLModal: mockSetShowImportDSLModal,
|
setShowImportDSLModal: mockSetShowImportDSLModal,
|
||||||
}))
|
}))
|
||||||
mockUseNodesInteractions.mockReturnValue({
|
mockUseNodesInteractions.mockReturnValue({
|
||||||
@ -96,6 +111,9 @@ describe('PanelContextmenu', () => {
|
|||||||
mockUseWorkflowStartRun.mockReturnValue({
|
mockUseWorkflowStartRun.mockReturnValue({
|
||||||
handleStartWorkflowRun: mockHandleStartWorkflowRun,
|
handleStartWorkflowRun: mockHandleStartWorkflowRun,
|
||||||
})
|
})
|
||||||
|
mockUseWorkflowMoveMode.mockReturnValue({
|
||||||
|
isCommentModeAvailable: false,
|
||||||
|
})
|
||||||
mockUseOperator.mockReturnValue({
|
mockUseOperator.mockReturnValue({
|
||||||
handleAddNote: mockHandleAddNote,
|
handleAddNote: mockHandleAddNote,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -2,13 +2,10 @@ import { act, fireEvent, render, screen } from '@testing-library/react'
|
|||||||
import UndoRedo from '../undo-redo'
|
import UndoRedo from '../undo-redo'
|
||||||
|
|
||||||
const mockUnsubscribe = vi.fn()
|
const mockUnsubscribe = vi.fn()
|
||||||
const mockCanUndo = vi.fn()
|
|
||||||
const mockCanRedo = vi.fn()
|
|
||||||
const mockOnUndoRedoStateChange = vi.fn()
|
|
||||||
const mockHandleUndo = vi.fn()
|
const mockHandleUndo = vi.fn()
|
||||||
const mockHandleRedo = vi.fn()
|
const mockHandleRedo = vi.fn()
|
||||||
|
|
||||||
let latestUndoRedoListener: ((state: { canUndo: boolean, canRedo: boolean }) => void) | undefined
|
let latestTemporalListener: ((state: { pastStates: unknown[], futureStates: unknown[] }) => void) | undefined
|
||||||
let mockNodesReadOnly = false
|
let mockNodesReadOnly = false
|
||||||
|
|
||||||
vi.mock('@/app/components/workflow/header/view-workflow-history', () => ({
|
vi.mock('@/app/components/workflow/header/view-workflow-history', () => ({
|
||||||
@ -23,22 +20,19 @@ vi.mock('@/app/components/workflow/hooks', () => ({
|
|||||||
|
|
||||||
vi.mock('@/app/components/workflow/workflow-history-store', () => ({
|
vi.mock('@/app/components/workflow/workflow-history-store', () => ({
|
||||||
useWorkflowHistoryStore: () => ({
|
useWorkflowHistoryStore: () => ({
|
||||||
|
store: {
|
||||||
|
temporal: {
|
||||||
|
subscribe: (listener: (state: { pastStates: unknown[], futureStates: unknown[] }) => void) => {
|
||||||
|
latestTemporalListener = listener
|
||||||
|
return mockUnsubscribe
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
shortcutsEnabled: true,
|
shortcutsEnabled: true,
|
||||||
setShortcutsEnabled: vi.fn(),
|
setShortcutsEnabled: vi.fn(),
|
||||||
}),
|
}),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
vi.mock('@/app/components/workflow/collaboration/core/collaboration-manager', () => ({
|
|
||||||
collaborationManager: {
|
|
||||||
canUndo: () => mockCanUndo(),
|
|
||||||
canRedo: () => mockCanRedo(),
|
|
||||||
onUndoRedoStateChange: (listener: (state: { canUndo: boolean, canRedo: boolean }) => void) => {
|
|
||||||
latestUndoRedoListener = listener
|
|
||||||
return mockOnUndoRedoStateChange(listener)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
|
|
||||||
vi.mock('@/app/components/base/divider', () => ({
|
vi.mock('@/app/components/base/divider', () => ({
|
||||||
default: () => <div data-testid="divider" />,
|
default: () => <div data-testid="divider" />,
|
||||||
}))
|
}))
|
||||||
@ -51,19 +45,16 @@ describe('UndoRedo', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks()
|
vi.clearAllMocks()
|
||||||
mockNodesReadOnly = false
|
mockNodesReadOnly = false
|
||||||
latestUndoRedoListener = undefined
|
latestTemporalListener = undefined
|
||||||
mockCanUndo.mockReturnValue(false)
|
|
||||||
mockCanRedo.mockReturnValue(false)
|
|
||||||
mockOnUndoRedoStateChange.mockReturnValue(mockUnsubscribe)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('enables undo and redo when history exists and triggers the callbacks', () => {
|
it('enables undo and redo when history exists and triggers the callbacks', () => {
|
||||||
render(<UndoRedo handleRedo={mockHandleRedo} handleUndo={mockHandleUndo} />)
|
render(<UndoRedo handleRedo={mockHandleRedo} handleUndo={mockHandleUndo} />)
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
latestUndoRedoListener?.({
|
latestTemporalListener?.({
|
||||||
canUndo: true,
|
pastStates: [{}],
|
||||||
canRedo: true,
|
futureStates: [{}],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -95,9 +86,9 @@ describe('UndoRedo', () => {
|
|||||||
const redoButton = screen.getByRole('button', { name: 'workflow.common.redo' })
|
const redoButton = screen.getByRole('button', { name: 'workflow.common.redo' })
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
latestUndoRedoListener?.({
|
latestTemporalListener?.({
|
||||||
canUndo: true,
|
pastStates: [{}],
|
||||||
canRedo: true,
|
futureStates: [{}],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -32,6 +32,18 @@ vi.mock('@/service/use-triggers', () => ({
|
|||||||
useTriggerPluginDynamicOptions: () => mockTriggerDynamicOptionsState,
|
useTriggerPluginDynamicOptions: () => mockTriggerDynamicOptionsState,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/app/components/workflow/hooks', () => ({
|
||||||
|
useIsChatMode: () => false,
|
||||||
|
useWorkflow: () => ({
|
||||||
|
getTreeLeafNodes: () => [],
|
||||||
|
getNodeById: () => undefined,
|
||||||
|
getBeforeNodesInSameBranchIncludeParent: () => [],
|
||||||
|
}),
|
||||||
|
useWorkflowVariables: () => ({
|
||||||
|
getNodeAvailableVars: () => [],
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
|
||||||
vi.mock('@/app/components/plugins/plugin-detail-panel/app-selector', () => ({
|
vi.mock('@/app/components/plugins/plugin-detail-panel/app-selector', () => ({
|
||||||
default: ({ onSelect }: { onSelect: (value: string) => void }) => (
|
default: ({ onSelect }: { onSelect: (value: string) => void }) => (
|
||||||
<button onClick={() => onSelect('app-1')}>app-selector</button>
|
<button onClick={() => onSelect('app-1')}>app-selector</button>
|
||||||
|
|||||||
@ -6,6 +6,18 @@ import { renderWorkflowFlowComponent } from '@/app/components/workflow/__tests__
|
|||||||
import { VarKindType } from '../../types'
|
import { VarKindType } from '../../types'
|
||||||
import FormInputItem from '../form-input-item'
|
import FormInputItem from '../form-input-item'
|
||||||
|
|
||||||
|
vi.mock('@/app/components/workflow/hooks', () => ({
|
||||||
|
useIsChatMode: () => false,
|
||||||
|
useWorkflow: () => ({
|
||||||
|
getTreeLeafNodes: () => [],
|
||||||
|
getNodeById: () => undefined,
|
||||||
|
getBeforeNodesInSameBranchIncludeParent: () => [],
|
||||||
|
}),
|
||||||
|
useWorkflowVariables: () => ({
|
||||||
|
getNodeAvailableVars: () => [],
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
|
||||||
const createSchema = (
|
const createSchema = (
|
||||||
overrides: Partial<CredentialFormSchema & {
|
overrides: Partial<CredentialFormSchema & {
|
||||||
_type?: FormTypeEnum
|
_type?: FormTypeEnum
|
||||||
|
|||||||
@ -20,6 +20,19 @@ vi.mock('@/service/use-plugins', () => ({
|
|||||||
}),
|
}),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/app/components/workflow/hooks', () => ({
|
||||||
|
useIsChatMode: () => false,
|
||||||
|
useWorkflow: () => ({
|
||||||
|
getTreeLeafNodes: () => [],
|
||||||
|
getNodeById: () => undefined,
|
||||||
|
getBeforeNodesInSameBranchIncludeParent: () => [],
|
||||||
|
}),
|
||||||
|
useWorkflowVariables: () => ({
|
||||||
|
getNodeAvailableVars: () => [],
|
||||||
|
getCurrentVariableType: () => undefined,
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
|
||||||
vi.mock('../var-reference-popup', () => ({
|
vi.mock('../var-reference-popup', () => ({
|
||||||
default: ({
|
default: ({
|
||||||
onChange,
|
onChange,
|
||||||
|
|||||||
@ -6,6 +6,19 @@ import { renderWorkflowFlowComponent } from '@/app/components/workflow/__tests__
|
|||||||
import { BlockEnum, InputVarType, VarType } from '@/app/components/workflow/types'
|
import { BlockEnum, InputVarType, VarType } from '@/app/components/workflow/types'
|
||||||
import VarReferencePicker from '../var-reference-picker'
|
import VarReferencePicker from '../var-reference-picker'
|
||||||
|
|
||||||
|
vi.mock('@/app/components/workflow/hooks', () => ({
|
||||||
|
useIsChatMode: () => false,
|
||||||
|
useWorkflow: () => ({
|
||||||
|
getTreeLeafNodes: () => [],
|
||||||
|
getNodeById: () => undefined,
|
||||||
|
getBeforeNodesInSameBranchIncludeParent: () => [],
|
||||||
|
}),
|
||||||
|
useWorkflowVariables: () => ({
|
||||||
|
getNodeAvailableVars: () => [],
|
||||||
|
getCurrentVariableType: () => undefined,
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
|
||||||
describe('VarReferencePicker', () => {
|
describe('VarReferencePicker', () => {
|
||||||
const startNode = createStartNode({
|
const startNode = createStartNode({
|
||||||
id: 'start-node',
|
id: 'start-node',
|
||||||
|
|||||||
@ -7,6 +7,19 @@ import { BlockEnum, VarType } from '@/app/components/workflow/types'
|
|||||||
import { AssignerNodeInputType, WriteMode } from '../../../types'
|
import { AssignerNodeInputType, WriteMode } from '../../../types'
|
||||||
import VarList from '../index'
|
import VarList from '../index'
|
||||||
|
|
||||||
|
vi.mock('@/app/components/workflow/hooks', () => ({
|
||||||
|
useIsChatMode: () => false,
|
||||||
|
useWorkflow: () => ({
|
||||||
|
getTreeLeafNodes: () => [],
|
||||||
|
getNodeById: () => undefined,
|
||||||
|
getBeforeNodesInSameBranchIncludeParent: () => [],
|
||||||
|
}),
|
||||||
|
useWorkflowVariables: () => ({
|
||||||
|
getNodeAvailableVars: () => [],
|
||||||
|
getCurrentVariableType: () => undefined,
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
|
||||||
const sourceNode = createNode({
|
const sourceNode = createNode({
|
||||||
id: 'node-a',
|
id: 'node-a',
|
||||||
data: {
|
data: {
|
||||||
|
|||||||
@ -19,6 +19,8 @@ const {
|
|||||||
mockFindUsedVarNodes,
|
mockFindUsedVarNodes,
|
||||||
mockUpdateNodeVars,
|
mockUpdateNodeVars,
|
||||||
mockVariableTriggerState,
|
mockVariableTriggerState,
|
||||||
|
mockUpdateEnvironmentVariables,
|
||||||
|
mockGetSocket,
|
||||||
} = vi.hoisted(() => ({
|
} = vi.hoisted(() => ({
|
||||||
mockDoSyncWorkflowDraft: vi.fn(() => Promise.resolve()),
|
mockDoSyncWorkflowDraft: vi.fn(() => Promise.resolve()),
|
||||||
mockGetNodes: vi.fn<() => MockWorkflowNode[]>(() => []),
|
mockGetNodes: vi.fn<() => MockWorkflowNode[]>(() => []),
|
||||||
@ -34,6 +36,8 @@ const {
|
|||||||
mockVariableTriggerState: {
|
mockVariableTriggerState: {
|
||||||
savePayload: undefined as EnvironmentVariable | undefined,
|
savePayload: undefined as EnvironmentVariable | undefined,
|
||||||
},
|
},
|
||||||
|
mockUpdateEnvironmentVariables: vi.fn(() => Promise.resolve({})),
|
||||||
|
mockGetSocket: vi.fn(() => null),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
vi.mock('@/app/components/workflow/hooks/use-nodes-sync-draft', () => ({
|
vi.mock('@/app/components/workflow/hooks/use-nodes-sync-draft', () => ({
|
||||||
@ -56,6 +60,16 @@ vi.mock('@/app/components/workflow/nodes/_base/components/variable/utils', () =>
|
|||||||
updateNodeVars: mockUpdateNodeVars,
|
updateNodeVars: mockUpdateNodeVars,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/service/workflow', () => ({
|
||||||
|
updateEnvironmentVariables: (payload: { appId: string, environmentVariables: EnvironmentVariable[] }) => mockUpdateEnvironmentVariables(payload),
|
||||||
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/app/components/workflow/collaboration/core/websocket-manager', () => ({
|
||||||
|
webSocketClient: {
|
||||||
|
getSocket: (appId: string) => mockGetSocket(appId),
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
vi.mock('@/app/components/workflow/nodes/_base/components/remove-effect-var-confirm', () => ({
|
vi.mock('@/app/components/workflow/nodes/_base/components/remove-effect-var-confirm', () => ({
|
||||||
default: ({
|
default: ({
|
||||||
isShow,
|
isShow,
|
||||||
@ -171,6 +185,8 @@ describe('EnvPanel container', () => {
|
|||||||
mockGetNodes.mockReturnValue([])
|
mockGetNodes.mockReturnValue([])
|
||||||
mockFindUsedVarNodes.mockReturnValue([])
|
mockFindUsedVarNodes.mockReturnValue([])
|
||||||
mockVariableTriggerState.savePayload = undefined
|
mockVariableTriggerState.savePayload = undefined
|
||||||
|
mockUpdateEnvironmentVariables.mockResolvedValue({})
|
||||||
|
mockGetSocket.mockReturnValue(null)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should close the panel from the header action', async () => {
|
it('should close the panel from the header action', async () => {
|
||||||
|
|||||||
@ -8,15 +8,15 @@ describe('createWorkflowSlice', () => {
|
|||||||
localStorage.clear()
|
localStorage.clear()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('defaults to hand mode until a persisted pointer mode is present', () => {
|
it('defaults to pointer mode and restores persisted control mode', () => {
|
||||||
const defaultStore = createStore(createWorkflowSlice)
|
const defaultStore = createStore(createWorkflowSlice)
|
||||||
|
|
||||||
expect(defaultStore.getState().controlMode).toBe('hand')
|
expect(defaultStore.getState().controlMode).toBe('pointer')
|
||||||
|
|
||||||
localStorage.setItem('workflow-operation-mode', 'pointer')
|
localStorage.setItem('workflow-operation-mode', 'hand')
|
||||||
const persistedStore = createStore(createWorkflowSlice)
|
const persistedStore = createStore(createWorkflowSlice)
|
||||||
|
|
||||||
expect(persistedStore.getState().controlMode).toBe('pointer')
|
expect(persistedStore.getState().controlMode).toBe('hand')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('persists control mode updates and stores run state payloads', () => {
|
it('persists control mode updates and stores run state payloads', () => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user