mirror of https://github.com/langgenius/dify.git
test: add testcase for config prompt components (#29491)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
1a877bb4d0
commit
6419ce02c7
|
|
@ -0,0 +1,49 @@
|
|||
import React from 'react'
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import ConfirmAddVar from './index'
|
||||
|
||||
jest.mock('react-i18next', () => ({
|
||||
useTranslation: () => ({
|
||||
t: (key: string) => key,
|
||||
}),
|
||||
}))
|
||||
|
||||
jest.mock('../../base/var-highlight', () => ({
|
||||
__esModule: true,
|
||||
default: ({ name }: { name: string }) => <span data-testid="var-highlight">{name}</span>,
|
||||
}))
|
||||
|
||||
describe('ConfirmAddVar', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it('should render variable names', () => {
|
||||
render(<ConfirmAddVar varNameArr={['foo', 'bar']} onConfirm={jest.fn()} onCancel={jest.fn()} onHide={jest.fn()} />)
|
||||
|
||||
const highlights = screen.getAllByTestId('var-highlight')
|
||||
expect(highlights).toHaveLength(2)
|
||||
expect(highlights[0]).toHaveTextContent('foo')
|
||||
expect(highlights[1]).toHaveTextContent('bar')
|
||||
})
|
||||
|
||||
it('should trigger cancel actions', () => {
|
||||
const onConfirm = jest.fn()
|
||||
const onCancel = jest.fn()
|
||||
render(<ConfirmAddVar varNameArr={['foo']} onConfirm={onConfirm} onCancel={onCancel} onHide={jest.fn()} />)
|
||||
|
||||
fireEvent.click(screen.getByText('common.operation.cancel'))
|
||||
|
||||
expect(onCancel).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('should trigger confirm actions', () => {
|
||||
const onConfirm = jest.fn()
|
||||
const onCancel = jest.fn()
|
||||
render(<ConfirmAddVar varNameArr={['foo']} onConfirm={onConfirm} onCancel={onCancel} onHide={jest.fn()} />)
|
||||
|
||||
fireEvent.click(screen.getByText('common.operation.add'))
|
||||
|
||||
expect(onConfirm).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
import React from 'react'
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import EditModal from './edit-modal'
|
||||
import type { ConversationHistoriesRole } from '@/models/debug'
|
||||
|
||||
jest.mock('react-i18next', () => ({
|
||||
useTranslation: () => ({
|
||||
t: (key: string) => key,
|
||||
}),
|
||||
}))
|
||||
|
||||
jest.mock('@/app/components/base/modal', () => ({
|
||||
__esModule: true,
|
||||
default: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||
}))
|
||||
|
||||
describe('Conversation history edit modal', () => {
|
||||
const data: ConversationHistoriesRole = {
|
||||
user_prefix: 'user',
|
||||
assistant_prefix: 'assistant',
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it('should render provided prefixes', () => {
|
||||
render(<EditModal isShow saveLoading={false} data={data} onClose={jest.fn()} onSave={jest.fn()} />)
|
||||
|
||||
expect(screen.getByDisplayValue('user')).toBeInTheDocument()
|
||||
expect(screen.getByDisplayValue('assistant')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should update prefixes and save changes', () => {
|
||||
const onSave = jest.fn()
|
||||
render(<EditModal isShow saveLoading={false} data={data} onClose={jest.fn()} onSave={onSave} />)
|
||||
|
||||
fireEvent.change(screen.getByDisplayValue('user'), { target: { value: 'member' } })
|
||||
fireEvent.change(screen.getByDisplayValue('assistant'), { target: { value: 'helper' } })
|
||||
fireEvent.click(screen.getByText('common.operation.save'))
|
||||
|
||||
expect(onSave).toHaveBeenCalledWith({
|
||||
user_prefix: 'member',
|
||||
assistant_prefix: 'helper',
|
||||
})
|
||||
})
|
||||
|
||||
it('should call close handler', () => {
|
||||
const onClose = jest.fn()
|
||||
render(<EditModal isShow saveLoading={false} data={data} onClose={onClose} onSave={jest.fn()} />)
|
||||
|
||||
fireEvent.click(screen.getByText('common.operation.cancel'))
|
||||
|
||||
expect(onClose).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import HistoryPanel from './history-panel'
|
||||
|
||||
jest.mock('react-i18next', () => ({
|
||||
useTranslation: () => ({
|
||||
t: (key: string) => key,
|
||||
}),
|
||||
}))
|
||||
|
||||
const mockDocLink = jest.fn(() => 'doc-link')
|
||||
jest.mock('@/context/i18n', () => ({
|
||||
useDocLink: () => mockDocLink,
|
||||
}))
|
||||
|
||||
jest.mock('@/app/components/app/configuration/base/operation-btn', () => ({
|
||||
__esModule: true,
|
||||
default: ({ onClick }: { onClick: () => void }) => (
|
||||
<button type="button" data-testid="edit-button" onClick={onClick}>
|
||||
edit
|
||||
</button>
|
||||
),
|
||||
}))
|
||||
|
||||
jest.mock('@/app/components/app/configuration/base/feature-panel', () => ({
|
||||
__esModule: true,
|
||||
default: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||
}))
|
||||
|
||||
describe('HistoryPanel', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it('should render warning content and link when showWarning is true', () => {
|
||||
render(<HistoryPanel showWarning onShowEditModal={jest.fn()} />)
|
||||
|
||||
expect(screen.getByText('appDebug.feature.conversationHistory.tip')).toBeInTheDocument()
|
||||
const link = screen.getByText('appDebug.feature.conversationHistory.learnMore')
|
||||
expect(link).toHaveAttribute('href', 'doc-link')
|
||||
})
|
||||
|
||||
it('should hide warning when showWarning is false', () => {
|
||||
render(<HistoryPanel showWarning={false} onShowEditModal={jest.fn()} />)
|
||||
|
||||
expect(screen.queryByText('appDebug.feature.conversationHistory.tip')).toBeNull()
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,351 @@
|
|||
import React from 'react'
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import Prompt, { type IPromptProps } from './index'
|
||||
import ConfigContext from '@/context/debug-configuration'
|
||||
import { MAX_PROMPT_MESSAGE_LENGTH } from '@/config'
|
||||
import { type PromptItem, PromptRole, type PromptVariable } from '@/models/debug'
|
||||
import { AppModeEnum, ModelModeType } from '@/types/app'
|
||||
|
||||
jest.mock('react-i18next', () => ({
|
||||
useTranslation: () => ({
|
||||
t: (key: string) => key,
|
||||
}),
|
||||
}))
|
||||
|
||||
type DebugConfiguration = {
|
||||
isAdvancedMode: boolean
|
||||
currentAdvancedPrompt: PromptItem | PromptItem[]
|
||||
setCurrentAdvancedPrompt: (prompt: PromptItem | PromptItem[], isUserChanged?: boolean) => void
|
||||
modelModeType: ModelModeType
|
||||
dataSets: Array<{
|
||||
id: string
|
||||
name?: string
|
||||
}>
|
||||
hasSetBlockStatus: {
|
||||
context: boolean
|
||||
history: boolean
|
||||
query: boolean
|
||||
}
|
||||
}
|
||||
|
||||
const defaultPromptVariables: PromptVariable[] = [
|
||||
{ key: 'var', name: 'Variable', type: 'string', required: true },
|
||||
]
|
||||
|
||||
let mockSimplePromptInputProps: IPromptProps | null = null
|
||||
|
||||
jest.mock('./simple-prompt-input', () => ({
|
||||
__esModule: true,
|
||||
default: (props: IPromptProps) => {
|
||||
mockSimplePromptInputProps = props
|
||||
return (
|
||||
<div
|
||||
data-testid="simple-prompt-input"
|
||||
data-mode={props.mode}
|
||||
data-template={props.promptTemplate}
|
||||
data-readonly={props.readonly ?? false}
|
||||
data-no-title={props.noTitle ?? false}
|
||||
data-gradient-border={props.gradientBorder ?? false}
|
||||
data-editor-height={props.editorHeight ?? ''}
|
||||
data-no-resize={props.noResize ?? false}
|
||||
onClick={() => props.onChange?.('mocked prompt', props.promptVariables)}
|
||||
>
|
||||
SimplePromptInput Mock
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}))
|
||||
|
||||
type AdvancedMessageInputProps = {
|
||||
isChatMode: boolean
|
||||
type: PromptRole
|
||||
value: string
|
||||
onTypeChange: (value: PromptRole) => void
|
||||
canDelete: boolean
|
||||
onDelete: () => void
|
||||
onChange: (value: string) => void
|
||||
promptVariables: PromptVariable[]
|
||||
isContextMissing: boolean
|
||||
onHideContextMissingTip: () => void
|
||||
noResize?: boolean
|
||||
}
|
||||
|
||||
jest.mock('./advanced-prompt-input', () => ({
|
||||
__esModule: true,
|
||||
default: (props: AdvancedMessageInputProps) => {
|
||||
return (
|
||||
<div
|
||||
data-testid="advanced-message-input"
|
||||
data-type={props.type}
|
||||
data-value={props.value}
|
||||
data-chat-mode={props.isChatMode}
|
||||
data-can-delete={props.canDelete}
|
||||
data-context-missing={props.isContextMissing}
|
||||
>
|
||||
<button type="button" onClick={() => props.onChange('updated text')}>
|
||||
change
|
||||
</button>
|
||||
<button type="button" onClick={() => props.onTypeChange(PromptRole.assistant)}>
|
||||
type
|
||||
</button>
|
||||
<button type="button" onClick={props.onDelete}>
|
||||
delete
|
||||
</button>
|
||||
<button type="button" onClick={props.onHideContextMissingTip}>
|
||||
hide-context
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}))
|
||||
const getContextValue = (overrides: Partial<DebugConfiguration> = {}): DebugConfiguration => {
|
||||
return {
|
||||
setCurrentAdvancedPrompt: jest.fn(),
|
||||
isAdvancedMode: false,
|
||||
currentAdvancedPrompt: [],
|
||||
modelModeType: ModelModeType.chat,
|
||||
dataSets: [],
|
||||
hasSetBlockStatus: {
|
||||
context: false,
|
||||
history: false,
|
||||
query: false,
|
||||
},
|
||||
...overrides,
|
||||
}
|
||||
}
|
||||
|
||||
const renderComponent = (
|
||||
props: Partial<IPromptProps> = {},
|
||||
contextOverrides: Partial<DebugConfiguration> = {},
|
||||
) => {
|
||||
const mergedProps: IPromptProps = {
|
||||
mode: AppModeEnum.CHAT,
|
||||
promptTemplate: 'initial template',
|
||||
promptVariables: defaultPromptVariables,
|
||||
onChange: jest.fn(),
|
||||
...props,
|
||||
}
|
||||
const contextValue = getContextValue(contextOverrides)
|
||||
|
||||
return {
|
||||
contextValue,
|
||||
...render(
|
||||
<ConfigContext.Provider value={contextValue as any}>
|
||||
<Prompt {...mergedProps} />
|
||||
</ConfigContext.Provider>,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
describe('Prompt config component', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
mockSimplePromptInputProps = null
|
||||
})
|
||||
|
||||
// Rendering simple mode
|
||||
it('should render simple prompt when advanced mode is disabled', () => {
|
||||
const onChange = jest.fn()
|
||||
renderComponent({ onChange }, { isAdvancedMode: false })
|
||||
|
||||
const simplePrompt = screen.getByTestId('simple-prompt-input')
|
||||
expect(simplePrompt).toBeInTheDocument()
|
||||
expect(simplePrompt).toHaveAttribute('data-mode', AppModeEnum.CHAT)
|
||||
expect(mockSimplePromptInputProps?.promptTemplate).toBe('initial template')
|
||||
fireEvent.click(simplePrompt)
|
||||
expect(onChange).toHaveBeenCalledWith('mocked prompt', defaultPromptVariables)
|
||||
expect(screen.queryByTestId('advanced-message-input')).toBeNull()
|
||||
})
|
||||
|
||||
// Rendering advanced chat messages
|
||||
it('should render advanced chat prompts and show context missing tip when dataset context is not set', () => {
|
||||
const currentAdvancedPrompt: PromptItem[] = [
|
||||
{ role: PromptRole.user, text: 'first' },
|
||||
{ role: PromptRole.assistant, text: 'second' },
|
||||
]
|
||||
renderComponent(
|
||||
{},
|
||||
{
|
||||
isAdvancedMode: true,
|
||||
currentAdvancedPrompt,
|
||||
modelModeType: ModelModeType.chat,
|
||||
dataSets: [{ id: 'ds' } as unknown as DebugConfiguration['dataSets'][number]],
|
||||
hasSetBlockStatus: { context: false, history: true, query: true },
|
||||
},
|
||||
)
|
||||
|
||||
const renderedMessages = screen.getAllByTestId('advanced-message-input')
|
||||
expect(renderedMessages).toHaveLength(2)
|
||||
expect(renderedMessages[0]).toHaveAttribute('data-context-missing', 'true')
|
||||
fireEvent.click(screen.getAllByText('hide-context')[0])
|
||||
expect(screen.getAllByTestId('advanced-message-input')[0]).toHaveAttribute('data-context-missing', 'false')
|
||||
})
|
||||
|
||||
// Chat message mutations
|
||||
it('should update chat prompt value and call setter with user change flag', () => {
|
||||
const currentAdvancedPrompt: PromptItem[] = [
|
||||
{ role: PromptRole.user, text: 'first' },
|
||||
{ role: PromptRole.assistant, text: 'second' },
|
||||
]
|
||||
const setCurrentAdvancedPrompt = jest.fn()
|
||||
renderComponent(
|
||||
{},
|
||||
{
|
||||
isAdvancedMode: true,
|
||||
currentAdvancedPrompt,
|
||||
modelModeType: ModelModeType.chat,
|
||||
setCurrentAdvancedPrompt,
|
||||
},
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getAllByText('change')[0])
|
||||
expect(setCurrentAdvancedPrompt).toHaveBeenCalledWith(
|
||||
[
|
||||
{ role: PromptRole.user, text: 'updated text' },
|
||||
{ role: PromptRole.assistant, text: 'second' },
|
||||
],
|
||||
true,
|
||||
)
|
||||
})
|
||||
|
||||
it('should update chat prompt role when type changes', () => {
|
||||
const currentAdvancedPrompt: PromptItem[] = [
|
||||
{ role: PromptRole.user, text: 'first' },
|
||||
{ role: PromptRole.user, text: 'second' },
|
||||
]
|
||||
const setCurrentAdvancedPrompt = jest.fn()
|
||||
renderComponent(
|
||||
{},
|
||||
{
|
||||
isAdvancedMode: true,
|
||||
currentAdvancedPrompt,
|
||||
modelModeType: ModelModeType.chat,
|
||||
setCurrentAdvancedPrompt,
|
||||
},
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getAllByText('type')[1])
|
||||
expect(setCurrentAdvancedPrompt).toHaveBeenCalledWith(
|
||||
[
|
||||
{ role: PromptRole.user, text: 'first' },
|
||||
{ role: PromptRole.assistant, text: 'second' },
|
||||
],
|
||||
)
|
||||
})
|
||||
|
||||
it('should delete chat prompt item', () => {
|
||||
const currentAdvancedPrompt: PromptItem[] = [
|
||||
{ role: PromptRole.user, text: 'first' },
|
||||
{ role: PromptRole.assistant, text: 'second' },
|
||||
]
|
||||
const setCurrentAdvancedPrompt = jest.fn()
|
||||
renderComponent(
|
||||
{},
|
||||
{
|
||||
isAdvancedMode: true,
|
||||
currentAdvancedPrompt,
|
||||
modelModeType: ModelModeType.chat,
|
||||
setCurrentAdvancedPrompt,
|
||||
},
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getAllByText('delete')[0])
|
||||
expect(setCurrentAdvancedPrompt).toHaveBeenCalledWith([{ role: PromptRole.assistant, text: 'second' }])
|
||||
})
|
||||
|
||||
// Add message behavior
|
||||
it('should append a mirrored role message when clicking add in chat mode', () => {
|
||||
const currentAdvancedPrompt: PromptItem[] = [
|
||||
{ role: PromptRole.user, text: 'first' },
|
||||
]
|
||||
const setCurrentAdvancedPrompt = jest.fn()
|
||||
renderComponent(
|
||||
{},
|
||||
{
|
||||
isAdvancedMode: true,
|
||||
currentAdvancedPrompt,
|
||||
modelModeType: ModelModeType.chat,
|
||||
setCurrentAdvancedPrompt,
|
||||
},
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByText('appDebug.promptMode.operation.addMessage'))
|
||||
expect(setCurrentAdvancedPrompt).toHaveBeenCalledWith([
|
||||
{ role: PromptRole.user, text: 'first' },
|
||||
{ role: PromptRole.assistant, text: '' },
|
||||
])
|
||||
})
|
||||
|
||||
it('should append a user role when the last chat prompt is from assistant', () => {
|
||||
const currentAdvancedPrompt: PromptItem[] = [
|
||||
{ role: PromptRole.assistant, text: 'reply' },
|
||||
]
|
||||
const setCurrentAdvancedPrompt = jest.fn()
|
||||
renderComponent(
|
||||
{},
|
||||
{
|
||||
isAdvancedMode: true,
|
||||
currentAdvancedPrompt,
|
||||
modelModeType: ModelModeType.chat,
|
||||
setCurrentAdvancedPrompt,
|
||||
},
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByText('appDebug.promptMode.operation.addMessage'))
|
||||
expect(setCurrentAdvancedPrompt).toHaveBeenCalledWith([
|
||||
{ role: PromptRole.assistant, text: 'reply' },
|
||||
{ role: PromptRole.user, text: '' },
|
||||
])
|
||||
})
|
||||
|
||||
it('should insert a system message when adding to an empty chat prompt list', () => {
|
||||
const setCurrentAdvancedPrompt = jest.fn()
|
||||
renderComponent(
|
||||
{},
|
||||
{
|
||||
isAdvancedMode: true,
|
||||
currentAdvancedPrompt: [],
|
||||
modelModeType: ModelModeType.chat,
|
||||
setCurrentAdvancedPrompt,
|
||||
},
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByText('appDebug.promptMode.operation.addMessage'))
|
||||
expect(setCurrentAdvancedPrompt).toHaveBeenCalledWith([{ role: PromptRole.system, text: '' }])
|
||||
})
|
||||
|
||||
it('should not show add button when reaching max prompt length', () => {
|
||||
const prompts: PromptItem[] = Array.from({ length: MAX_PROMPT_MESSAGE_LENGTH }, (_, index) => ({
|
||||
role: PromptRole.user,
|
||||
text: `item-${index}`,
|
||||
}))
|
||||
renderComponent(
|
||||
{},
|
||||
{
|
||||
isAdvancedMode: true,
|
||||
currentAdvancedPrompt: prompts,
|
||||
modelModeType: ModelModeType.chat,
|
||||
},
|
||||
)
|
||||
|
||||
expect(screen.queryByText('appDebug.promptMode.operation.addMessage')).toBeNull()
|
||||
})
|
||||
|
||||
// Completion mode
|
||||
it('should update completion prompt value and flag as user change', () => {
|
||||
const setCurrentAdvancedPrompt = jest.fn()
|
||||
renderComponent(
|
||||
{},
|
||||
{
|
||||
isAdvancedMode: true,
|
||||
currentAdvancedPrompt: { role: PromptRole.user, text: 'single' },
|
||||
modelModeType: ModelModeType.completion,
|
||||
setCurrentAdvancedPrompt,
|
||||
},
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByText('change'))
|
||||
|
||||
expect(setCurrentAdvancedPrompt).toHaveBeenCalledWith({ role: PromptRole.user, text: 'updated text' }, true)
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import React from 'react'
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import MessageTypeSelector from './message-type-selector'
|
||||
import { PromptRole } from '@/models/debug'
|
||||
|
||||
describe('MessageTypeSelector', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it('should render current value and keep options hidden by default', () => {
|
||||
render(<MessageTypeSelector value={PromptRole.user} onChange={jest.fn()} />)
|
||||
|
||||
expect(screen.getByText(PromptRole.user)).toBeInTheDocument()
|
||||
expect(screen.queryByText(PromptRole.system)).toBeNull()
|
||||
})
|
||||
|
||||
it('should toggle option list when clicking the selector', () => {
|
||||
render(<MessageTypeSelector value={PromptRole.system} onChange={jest.fn()} />)
|
||||
|
||||
fireEvent.click(screen.getByText(PromptRole.system))
|
||||
|
||||
expect(screen.getByText(PromptRole.user)).toBeInTheDocument()
|
||||
expect(screen.getByText(PromptRole.assistant)).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should call onChange with selected type and close the list', () => {
|
||||
const onChange = jest.fn()
|
||||
render(<MessageTypeSelector value={PromptRole.assistant} onChange={onChange} />)
|
||||
|
||||
fireEvent.click(screen.getByText(PromptRole.assistant))
|
||||
fireEvent.click(screen.getByText(PromptRole.user))
|
||||
|
||||
expect(onChange).toHaveBeenCalledWith(PromptRole.user)
|
||||
expect(screen.queryByText(PromptRole.system)).toBeNull()
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
import React from 'react'
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import PromptEditorHeightResizeWrap from './prompt-editor-height-resize-wrap'
|
||||
|
||||
describe('PromptEditorHeightResizeWrap', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
jest.useFakeTimers()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
jest.runOnlyPendingTimers()
|
||||
jest.useRealTimers()
|
||||
})
|
||||
|
||||
it('should render children, footer, and hide resize handler when requested', () => {
|
||||
const { container } = render(
|
||||
<PromptEditorHeightResizeWrap
|
||||
className="wrapper"
|
||||
height={150}
|
||||
minHeight={100}
|
||||
onHeightChange={jest.fn()}
|
||||
footer={<div>footer</div>}
|
||||
hideResize
|
||||
>
|
||||
<div>content</div>
|
||||
</PromptEditorHeightResizeWrap>,
|
||||
)
|
||||
|
||||
expect(screen.getByText('content')).toBeInTheDocument()
|
||||
expect(screen.getByText('footer')).toBeInTheDocument()
|
||||
expect(container.querySelector('.cursor-row-resize')).toBeNull()
|
||||
})
|
||||
|
||||
it('should resize height with mouse events and clamp to minHeight', () => {
|
||||
const onHeightChange = jest.fn()
|
||||
|
||||
const { container } = render(
|
||||
<PromptEditorHeightResizeWrap
|
||||
height={150}
|
||||
minHeight={100}
|
||||
onHeightChange={onHeightChange}
|
||||
>
|
||||
<div>content</div>
|
||||
</PromptEditorHeightResizeWrap>,
|
||||
)
|
||||
|
||||
const handle = container.querySelector('.cursor-row-resize')
|
||||
expect(handle).not.toBeNull()
|
||||
|
||||
fireEvent.mouseDown(handle as Element, { clientY: 100 })
|
||||
expect(document.body.style.userSelect).toBe('none')
|
||||
|
||||
fireEvent.mouseMove(document, { clientY: 130 })
|
||||
jest.runAllTimers()
|
||||
expect(onHeightChange).toHaveBeenLastCalledWith(180)
|
||||
|
||||
onHeightChange.mockClear()
|
||||
fireEvent.mouseMove(document, { clientY: -100 })
|
||||
jest.runAllTimers()
|
||||
expect(onHeightChange).toHaveBeenLastCalledWith(100)
|
||||
|
||||
fireEvent.mouseUp(document)
|
||||
expect(document.body.style.userSelect).toBe('')
|
||||
})
|
||||
})
|
||||
Loading…
Reference in New Issue