Files
dify/web/app/components/base/prompt-editor/plugins/context-block/node.spec.tsx

245 lines
8.2 KiB
TypeScript

import { $getRoot } from 'lexical'
import { createTestEditor, withEditorUpdate } from '../__tests__/utils'
import { $createContextBlockNode, $isContextBlockNode, ContextBlockNode } from './node'
const mockDatasets = [
{ id: '1', name: 'Dataset A', type: 'text' },
{ id: '2', name: 'Dataset B', type: 'text' },
]
const mockOnAddContext = vi.fn()
const createContextBlockTestEditor = () => createTestEditor([ContextBlockNode])
describe('ContextBlockNode', () => {
beforeEach(() => {
vi.clearAllMocks()
})
describe('Static Methods', () => {
it('should return correct type', () => {
expect(ContextBlockNode.getType()).toBe('context-block')
})
it('should clone a node', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext, true)
$getRoot().append(node)
const cloned = ContextBlockNode.clone(node)
expect(cloned).toBeInstanceOf(ContextBlockNode)
})
})
})
describe('Constructor', () => {
it('should store datasets', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext)
$getRoot().append(node)
expect(node.getDatasets()).toEqual(mockDatasets)
})
})
it('should store onAddContext callback', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext)
$getRoot().append(node)
expect(node.getOnAddContext()).toBe(mockOnAddContext)
})
})
it('should store canNotAddContext', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext, true)
$getRoot().append(node)
expect(node.getCanNotAddContext()).toBe(true)
})
})
it('should default canNotAddContext to false', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext)
$getRoot().append(node)
expect(node.getCanNotAddContext()).toBe(false)
})
})
})
describe('isInline', () => {
it('should return true', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext)
expect(node.isInline()).toBe(true)
})
})
})
describe('createDOM', () => {
it('should create a div element', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext)
const dom = node.createDOM()
expect(dom.tagName).toBe('DIV')
})
})
it('should add correct CSS classes', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext)
const dom = node.createDOM()
expect(dom.classList.contains('inline-flex')).toBe(true)
expect(dom.classList.contains('items-center')).toBe(true)
expect(dom.classList.contains('align-middle')).toBe(true)
})
})
})
describe('updateDOM', () => {
it('should return false', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext)
expect(node.updateDOM()).toBe(false)
})
})
})
describe('decorate', () => {
it('should return a React element', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext, true)
$getRoot().append(node)
const result = node.decorate()
expect(result).toBeDefined()
expect(result.props).toEqual(
expect.objectContaining({
datasets: mockDatasets,
onAddContext: mockOnAddContext,
canNotAddContext: true,
}),
)
})
})
it('should pass nodeKey prop', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext)
$getRoot().append(node)
const result = node.decorate()
expect(result.props.nodeKey).toBe(node.getKey())
})
})
})
describe('getTextContent', () => {
it('should return the context placeholder', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext)
expect(node.getTextContent()).toBe('{{#context#}}')
})
})
})
describe('exportJSON', () => {
it('should export correct JSON structure', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext, true)
$getRoot().append(node)
const json = node.exportJSON()
expect(json.type).toBe('context-block')
expect(json.version).toBe(1)
expect(json.datasets).toEqual(mockDatasets)
expect(json.onAddContext).toBe(mockOnAddContext)
expect(json.canNotAddContext).toBe(true)
})
})
})
describe('importJSON', () => {
it('should create a node from serialized data', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const serialized = {
type: 'context-block' as const,
version: 1,
datasets: mockDatasets,
onAddContext: mockOnAddContext,
canNotAddContext: false,
}
const node = ContextBlockNode.importJSON(serialized)
$getRoot().append(node)
expect(node).toBeInstanceOf(ContextBlockNode)
expect(node.getDatasets()).toEqual(mockDatasets)
expect(node.getOnAddContext()).toBe(mockOnAddContext)
expect(node.getCanNotAddContext()).toBe(false)
})
})
})
describe('$createContextBlockNode', () => {
it('should create a ContextBlockNode instance', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext)
expect(node).toBeInstanceOf(ContextBlockNode)
})
})
it('should pass canNotAddContext when provided', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext, true)
$getRoot().append(node)
expect(node.getCanNotAddContext()).toBe(true)
})
})
})
describe('$isContextBlockNode', () => {
it('should return true for ContextBlockNode instances', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext)
expect($isContextBlockNode(node)).toBe(true)
})
})
it('should return false for null', () => {
expect($isContextBlockNode(null)).toBe(false)
})
it('should return false for undefined', () => {
expect($isContextBlockNode(undefined)).toBe(false)
})
})
describe('Edge Cases', () => {
it('should handle empty datasets', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode([], mockOnAddContext)
$getRoot().append(node)
expect(node.getDatasets()).toEqual([])
})
})
it('should handle canNotAddContext as false explicitly', () => {
const editor = createContextBlockTestEditor()
withEditorUpdate(editor, () => {
const node = $createContextBlockNode(mockDatasets, mockOnAddContext, false)
$getRoot().append(node)
expect(node.getCanNotAddContext()).toBe(false)
})
})
})
})