mirror of
https://github.com/langgenius/dify.git
synced 2026-07-24 04:58:32 +08:00
160 lines
5.9 KiB
TypeScript
160 lines
5.9 KiB
TypeScript
import type { ReactElement } from 'react'
|
|
import { fireEvent, screen } from '@testing-library/react'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { renderWithConsoleQuery } from '@/test/console/query-data'
|
|
import { PluginSource } from '../../types'
|
|
import { OperationDropdown } from '../operation-dropdown'
|
|
|
|
const render = (ui: ReactElement, enableMarketplace = true) =>
|
|
renderWithConsoleQuery(ui, { systemFeatures: { enable_marketplace: enableMarketplace } })
|
|
|
|
const openDropdown = () => {
|
|
fireEvent.click(screen.getByRole('button', { name: 'plugin.detailPanel.operation.moreActions' }))
|
|
}
|
|
|
|
describe('OperationDropdown', () => {
|
|
const mockOnInfo = vi.fn()
|
|
const mockOnCheckVersion = vi.fn()
|
|
const mockOnRemove = vi.fn()
|
|
const mockOnViewReadme = vi.fn()
|
|
const defaultProps = {
|
|
source: PluginSource.github,
|
|
detailUrl: 'https://github.com/test/repo',
|
|
onInfo: mockOnInfo,
|
|
onCheckVersion: mockOnCheckVersion,
|
|
onRemove: mockOnRemove,
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
describe('Rendering', () => {
|
|
it('should render the actions trigger', () => {
|
|
render(<OperationDropdown {...defaultProps} />)
|
|
|
|
expect(
|
|
screen.getByRole('button', { name: 'plugin.detailPanel.operation.moreActions' }),
|
|
).toBeInTheDocument()
|
|
})
|
|
|
|
it('should render GitHub actions when marketplace is enabled', () => {
|
|
render(<OperationDropdown {...defaultProps} source={PluginSource.github} />)
|
|
|
|
openDropdown()
|
|
|
|
expect(screen.getByText('plugin.detailPanel.operation.info')).toBeInTheDocument()
|
|
expect(screen.getByText('plugin.detailPanel.operation.checkUpdate')).toBeInTheDocument()
|
|
expect(screen.getByText('plugin.detailPanel.operation.viewDetail')).toBeInTheDocument()
|
|
expect(screen.getByText('plugin.detailPanel.operation.remove')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should render marketplace detail action for marketplace source', () => {
|
|
render(<OperationDropdown {...defaultProps} source={PluginSource.marketplace} />)
|
|
|
|
openDropdown()
|
|
|
|
expect(screen.queryByText('plugin.detailPanel.operation.info')).not.toBeInTheDocument()
|
|
expect(screen.queryByText('plugin.detailPanel.operation.checkUpdate')).not.toBeInTheDocument()
|
|
expect(screen.getByText('plugin.detailPanel.operation.viewDetail')).toBeInTheDocument()
|
|
expect(screen.getByText('plugin.detailPanel.operation.remove')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should render README action only when provided', () => {
|
|
const { unmount } = render(<OperationDropdown {...defaultProps} />)
|
|
|
|
openDropdown()
|
|
expect(screen.queryByText('plugin.detailPanel.operation.viewReadme')).not.toBeInTheDocument()
|
|
|
|
unmount()
|
|
render(<OperationDropdown {...defaultProps} onViewReadme={mockOnViewReadme} />)
|
|
openDropdown()
|
|
expect(screen.getByText('plugin.detailPanel.operation.viewReadme')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should not render marketplace detail when source cannot open a detail page', () => {
|
|
render(<OperationDropdown {...defaultProps} source={PluginSource.local} />)
|
|
|
|
openDropdown()
|
|
|
|
expect(screen.queryByText('plugin.detailPanel.operation.viewDetail')).not.toBeInTheDocument()
|
|
expect(screen.getByText('plugin.detailPanel.operation.remove')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should not render the trigger when every action is unavailable', () => {
|
|
render(
|
|
<OperationDropdown
|
|
{...defaultProps}
|
|
source={PluginSource.local}
|
|
showRemove={false}
|
|
showCheckVersion={false}
|
|
/>,
|
|
)
|
|
|
|
expect(
|
|
screen.queryByRole('button', { name: 'plugin.detailPanel.operation.moreActions' }),
|
|
).not.toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
describe('User Interactions', () => {
|
|
it('should call onInfo when the info action is clicked', () => {
|
|
render(<OperationDropdown {...defaultProps} source={PluginSource.github} />)
|
|
|
|
openDropdown()
|
|
fireEvent.click(screen.getByText('plugin.detailPanel.operation.info'))
|
|
|
|
expect(mockOnInfo).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('should call onCheckVersion when the check update action is clicked', () => {
|
|
render(<OperationDropdown {...defaultProps} source={PluginSource.github} />)
|
|
|
|
openDropdown()
|
|
fireEvent.click(screen.getByText('plugin.detailPanel.operation.checkUpdate'))
|
|
|
|
expect(mockOnCheckVersion).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('should call onRemove when the remove action is clicked', () => {
|
|
render(<OperationDropdown {...defaultProps} source={PluginSource.github} />)
|
|
|
|
openDropdown()
|
|
fireEvent.click(screen.getByText('plugin.detailPanel.operation.remove'))
|
|
|
|
expect(mockOnRemove).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('should call onViewReadme when README action is clicked', () => {
|
|
render(<OperationDropdown {...defaultProps} onViewReadme={mockOnViewReadme} />)
|
|
|
|
openDropdown()
|
|
fireEvent.click(screen.getByText('plugin.detailPanel.operation.viewReadme'))
|
|
|
|
expect(mockOnViewReadme).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('should render view detail as an external link', () => {
|
|
render(<OperationDropdown {...defaultProps} source={PluginSource.github} />)
|
|
|
|
openDropdown()
|
|
|
|
const link = screen.getByText('plugin.detailPanel.operation.viewDetail').closest('a')
|
|
expect(link).toHaveAttribute('href', 'https://github.com/test/repo')
|
|
expect(link).toHaveAttribute('target', '_blank')
|
|
expect(link).toHaveAttribute('rel', 'noopener noreferrer')
|
|
})
|
|
})
|
|
|
|
describe('Feature Flags', () => {
|
|
it('should hide marketplace detail when marketplace is disabled', () => {
|
|
render(<OperationDropdown {...defaultProps} source={PluginSource.github} />, false)
|
|
|
|
openDropdown()
|
|
|
|
expect(screen.queryByText('plugin.detailPanel.operation.viewDetail')).not.toBeInTheDocument()
|
|
expect(screen.getByText('plugin.detailPanel.operation.info')).toBeInTheDocument()
|
|
})
|
|
})
|
|
})
|