Yeuoly b76e17b25d
feat: introduce trigger functionality (#27644)
Signed-off-by: lyzno1 <yuanyouhuilyz@gmail.com>
Co-authored-by: Stream <Stream_2@qq.com>
Co-authored-by: lyzno1 <92089059+lyzno1@users.noreply.github.com>
Co-authored-by: zhsama <torvalds@linux.do>
Co-authored-by: Harry <xh001x@hotmail.com>
Co-authored-by: lyzno1 <yuanyouhuilyz@gmail.com>
Co-authored-by: yessenia <yessenia.contact@gmail.com>
Co-authored-by: hjlarry <hjlarry@163.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: WTW0313 <twwu@dify.ai>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-12 17:59:37 +08:00

151 lines
4.7 KiB
TypeScript

import React from 'react'
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
import '@testing-library/jest-dom'
import InputWithCopy from './index'
// Mock the copy-to-clipboard library
jest.mock('copy-to-clipboard', () => jest.fn(() => true))
// Mock the i18n hook
jest.mock('react-i18next', () => ({
useTranslation: () => ({
t: (key: string) => {
const translations: Record<string, string> = {
'common.operation.copy': 'Copy',
'common.operation.copied': 'Copied',
'appOverview.overview.appInfo.embedded.copy': 'Copy',
'appOverview.overview.appInfo.embedded.copied': 'Copied',
}
return translations[key] || key
},
}),
}))
// Mock lodash-es debounce
jest.mock('lodash-es', () => ({
debounce: (fn: any) => fn,
}))
describe('InputWithCopy component', () => {
beforeEach(() => {
jest.clearAllMocks()
})
it('renders correctly with default props', () => {
const mockOnChange = jest.fn()
render(<InputWithCopy value="test value" onChange={mockOnChange} />)
const input = screen.getByDisplayValue('test value')
const copyButton = screen.getByRole('button')
expect(input).toBeInTheDocument()
expect(copyButton).toBeInTheDocument()
})
it('hides copy button when showCopyButton is false', () => {
const mockOnChange = jest.fn()
render(<InputWithCopy value="test value" onChange={mockOnChange} showCopyButton={false} />)
const input = screen.getByDisplayValue('test value')
const copyButton = screen.queryByRole('button')
expect(input).toBeInTheDocument()
expect(copyButton).not.toBeInTheDocument()
})
it('copies input value when copy button is clicked', async () => {
const copyToClipboard = require('copy-to-clipboard')
const mockOnChange = jest.fn()
render(<InputWithCopy value="test value" onChange={mockOnChange} />)
const copyButton = screen.getByRole('button')
fireEvent.click(copyButton)
expect(copyToClipboard).toHaveBeenCalledWith('test value')
})
it('copies custom value when copyValue prop is provided', async () => {
const copyToClipboard = require('copy-to-clipboard')
const mockOnChange = jest.fn()
render(<InputWithCopy value="display value" onChange={mockOnChange} copyValue="custom copy value" />)
const copyButton = screen.getByRole('button')
fireEvent.click(copyButton)
expect(copyToClipboard).toHaveBeenCalledWith('custom copy value')
})
it('calls onCopy callback when copy button is clicked', async () => {
const onCopyMock = jest.fn()
const mockOnChange = jest.fn()
render(<InputWithCopy value="test value" onChange={mockOnChange} onCopy={onCopyMock} />)
const copyButton = screen.getByRole('button')
fireEvent.click(copyButton)
expect(onCopyMock).toHaveBeenCalledWith('test value')
})
it('shows copied state after successful copy', async () => {
const mockOnChange = jest.fn()
render(<InputWithCopy value="test value" onChange={mockOnChange} />)
const copyButton = screen.getByRole('button')
fireEvent.click(copyButton)
// Hover over the button to trigger tooltip
fireEvent.mouseEnter(copyButton)
// Check if the tooltip shows "Copied" state
await waitFor(() => {
expect(screen.getByText('Copied')).toBeInTheDocument()
}, { timeout: 2000 })
})
it('passes through all input props correctly', () => {
const mockOnChange = jest.fn()
render(
<InputWithCopy
value="test value"
onChange={mockOnChange}
placeholder="Custom placeholder"
disabled
readOnly
className="custom-class"
/>,
)
const input = screen.getByDisplayValue('test value')
expect(input).toHaveAttribute('placeholder', 'Custom placeholder')
expect(input).toBeDisabled()
expect(input).toHaveAttribute('readonly')
expect(input).toHaveClass('custom-class')
})
it('handles empty value correctly', () => {
const copyToClipboard = require('copy-to-clipboard')
const mockOnChange = jest.fn()
render(<InputWithCopy value="" onChange={mockOnChange} />)
const input = screen.getByRole('textbox')
const copyButton = screen.getByRole('button')
expect(input).toBeInTheDocument()
expect(copyButton).toBeInTheDocument()
fireEvent.click(copyButton)
expect(copyToClipboard).toHaveBeenCalledWith('')
})
it('maintains focus on input after copy', async () => {
const mockOnChange = jest.fn()
render(<InputWithCopy value="test value" onChange={mockOnChange} />)
const input = screen.getByDisplayValue('test value')
const copyButton = screen.getByRole('button')
input.focus()
expect(input).toHaveFocus()
fireEvent.click(copyButton)
// Input should maintain focus after copy
expect(input).toHaveFocus()
})
})