dify/web/app/components/base/prompt-editor/plugins/component-picker-block/menu.spec.tsx

124 lines
3.8 KiB
TypeScript

import { render } from '@testing-library/react'
import { Fragment } from 'react'
import { PickerBlockMenuOption } from './menu'
describe('PickerBlockMenuOption', () => {
// Define the render props type locally to match the component's internal type accurately
type MenuOptionRenderProps = {
isSelected: boolean
onSelect: () => void
onSetHighlight: () => void
queryString: string | null
}
const mockRender = vi.fn((props: MenuOptionRenderProps) => (
<div data-testid="menu-item">
{props.isSelected ? 'Selected' : 'Not Selected'}
{props.queryString && ` Query: ${props.queryString}`}
</div>
))
const mockOnSelect = vi.fn()
beforeEach(() => {
vi.clearAllMocks()
})
describe('Constructor and Initialization', () => {
it('should correctly initialize with provided key and group', () => {
const option = new PickerBlockMenuOption({
key: 'test-key',
group: 'test-group',
render: mockRender,
})
// Check inheritance from MenuOption (key)
expect(option.key).toBe('test-key')
// Check custom property (group)
expect(option.group).toBe('test-group')
})
it('should initialize without group when not provided', () => {
const option = new PickerBlockMenuOption({
key: 'test-key-no-group',
render: mockRender,
})
expect(option.key).toBe('test-key-no-group')
expect(option.group).toBeUndefined()
})
})
describe('onSelectMenuOption', () => {
it('should call the provided onSelect callback', () => {
const option = new PickerBlockMenuOption({
key: 'test-key',
onSelect: mockOnSelect,
render: mockRender,
})
option.onSelectMenuOption()
expect(mockOnSelect).toHaveBeenCalledTimes(1)
})
it('should handle cases where onSelect is not provided (optional chaining)', () => {
const option = new PickerBlockMenuOption({
key: 'test-key',
render: mockRender,
})
// This covers the branch where this.data.onSelect is undefined
expect(() => option.onSelectMenuOption()).not.toThrow()
})
})
describe('renderMenuOption', () => {
it('should call the render function with correct props and return the element', () => {
const option = new PickerBlockMenuOption({
key: 'test-key',
render: mockRender,
})
const renderProps: MenuOptionRenderProps = {
isSelected: true,
onSelect: vi.fn(),
onSetHighlight: vi.fn(),
queryString: 'search-string',
}
// Execute renderMenuOption
const renderedElement = option.renderMenuOption(renderProps)
// Use RTL to verify the rendered output
const { getByTestId, getByText } = render(renderedElement)
// Assertions
expect(mockRender).toHaveBeenCalledWith(renderProps)
expect(getByTestId('menu-item')).toBeInTheDocument()
expect(getByText('Selected Query: search-string')).toBeInTheDocument()
})
it('should use Fragment with the correct key as the wrapper', () => {
// In React testing, verifying the key of a Fragment directly from the element can be tricky,
// but we can verify the structure and that it renders correctly.
const option = new PickerBlockMenuOption({
key: 'fragment-key',
render: mockRender,
})
const renderProps: MenuOptionRenderProps = {
isSelected: false,
onSelect: vi.fn(),
onSetHighlight: vi.fn(),
queryString: null,
}
const element = option.renderMenuOption(renderProps)
// Verify the element type is Fragment (rendered output doesn't show Fragment in DOM)
// but we can check the JSX structure if needed.
expect(element.type).toBe(Fragment)
expect(element.key).toBe('fragment-key')
})
})
})