mirror of https://github.com/langgenius/dify.git
268 lines
9.2 KiB
TypeScript
268 lines
9.2 KiB
TypeScript
import { fireEvent, render, screen } from '@testing-library/react'
|
|
import { DataSourceType } from '@/models/datasets'
|
|
import DataSourceSelector from './data-source-selector'
|
|
|
|
// Mock react-i18next
|
|
vi.mock('react-i18next', () => ({
|
|
useTranslation: () => ({
|
|
t: (key: string) => key,
|
|
}),
|
|
}))
|
|
|
|
// Mock config - enable all web crawl features
|
|
vi.mock('@/config', () => ({
|
|
ENABLE_WEBSITE_FIRECRAWL: true,
|
|
ENABLE_WEBSITE_JINAREADER: true,
|
|
ENABLE_WEBSITE_WATERCRAWL: false,
|
|
}))
|
|
|
|
const createDefaultProps = () => ({
|
|
dataSourceType: DataSourceType.FILE,
|
|
dataSourceTypeDisable: false,
|
|
changeType: vi.fn(),
|
|
onHideFilePreview: vi.fn(),
|
|
onHideNotionPreview: vi.fn(),
|
|
onHideWebsitePreview: vi.fn(),
|
|
})
|
|
|
|
describe('DataSourceSelector', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
// ==========================================
|
|
// Rendering Tests
|
|
// ==========================================
|
|
describe('Rendering', () => {
|
|
it('should render all data source options', () => {
|
|
// Arrange
|
|
const props = createDefaultProps()
|
|
|
|
// Act
|
|
render(<DataSourceSelector {...props} />)
|
|
|
|
// Assert
|
|
expect(screen.getByText('datasetCreation.stepOne.dataSourceType.file')).toBeInTheDocument()
|
|
expect(screen.getByText('datasetCreation.stepOne.dataSourceType.notion')).toBeInTheDocument()
|
|
expect(screen.getByText('datasetCreation.stepOne.dataSourceType.web')).toBeInTheDocument()
|
|
})
|
|
|
|
it('should show active state for FILE type', () => {
|
|
// Arrange
|
|
const props = { ...createDefaultProps(), dataSourceType: DataSourceType.FILE }
|
|
|
|
// Act
|
|
render(<DataSourceSelector {...props} />)
|
|
|
|
// Assert
|
|
const fileOption = screen.getByText('datasetCreation.stepOne.dataSourceType.file').closest('div')
|
|
expect(fileOption?.className).toContain('active')
|
|
})
|
|
|
|
it('should show active state for NOTION type', () => {
|
|
// Arrange
|
|
const props = { ...createDefaultProps(), dataSourceType: DataSourceType.NOTION }
|
|
|
|
// Act
|
|
render(<DataSourceSelector {...props} />)
|
|
|
|
// Assert
|
|
const notionOption = screen.getByText('datasetCreation.stepOne.dataSourceType.notion').closest('div')
|
|
expect(notionOption?.className).toContain('active')
|
|
})
|
|
|
|
it('should show active state for WEB type', () => {
|
|
// Arrange
|
|
const props = { ...createDefaultProps(), dataSourceType: DataSourceType.WEB }
|
|
|
|
// Act
|
|
render(<DataSourceSelector {...props} />)
|
|
|
|
// Assert
|
|
const webOption = screen.getByText('datasetCreation.stepOne.dataSourceType.web').closest('div')
|
|
expect(webOption?.className).toContain('active')
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Click Handler Tests - File
|
|
// ==========================================
|
|
describe('File Click Handler', () => {
|
|
it('should call changeType and hide previews when clicking File option', () => {
|
|
// Arrange
|
|
const props = { ...createDefaultProps(), dataSourceType: DataSourceType.NOTION }
|
|
render(<DataSourceSelector {...props} />)
|
|
|
|
// Act
|
|
fireEvent.click(screen.getByText('datasetCreation.stepOne.dataSourceType.file'))
|
|
|
|
// Assert
|
|
expect(props.changeType).toHaveBeenCalledWith(DataSourceType.FILE)
|
|
expect(props.onHideNotionPreview).toHaveBeenCalled()
|
|
expect(props.onHideWebsitePreview).toHaveBeenCalled()
|
|
expect(props.onHideFilePreview).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should NOT call changeType when clicking File option while disabled', () => {
|
|
// Arrange
|
|
const props = {
|
|
...createDefaultProps(),
|
|
dataSourceType: DataSourceType.NOTION,
|
|
dataSourceTypeDisable: true,
|
|
}
|
|
render(<DataSourceSelector {...props} />)
|
|
|
|
// Act
|
|
fireEvent.click(screen.getByText('datasetCreation.stepOne.dataSourceType.file'))
|
|
|
|
// Assert
|
|
expect(props.changeType).not.toHaveBeenCalled()
|
|
expect(props.onHideNotionPreview).not.toHaveBeenCalled()
|
|
expect(props.onHideWebsitePreview).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Click Handler Tests - Notion
|
|
// ==========================================
|
|
describe('Notion Click Handler', () => {
|
|
it('should call changeType and hide previews when clicking Notion option', () => {
|
|
// Arrange
|
|
const props = { ...createDefaultProps(), dataSourceType: DataSourceType.FILE }
|
|
render(<DataSourceSelector {...props} />)
|
|
|
|
// Act
|
|
fireEvent.click(screen.getByText('datasetCreation.stepOne.dataSourceType.notion'))
|
|
|
|
// Assert
|
|
expect(props.changeType).toHaveBeenCalledWith(DataSourceType.NOTION)
|
|
expect(props.onHideFilePreview).toHaveBeenCalled()
|
|
expect(props.onHideWebsitePreview).toHaveBeenCalled()
|
|
expect(props.onHideNotionPreview).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should NOT call changeType when clicking Notion option while disabled', () => {
|
|
// Arrange
|
|
const props = {
|
|
...createDefaultProps(),
|
|
dataSourceType: DataSourceType.FILE,
|
|
dataSourceTypeDisable: true,
|
|
}
|
|
render(<DataSourceSelector {...props} />)
|
|
|
|
// Act
|
|
fireEvent.click(screen.getByText('datasetCreation.stepOne.dataSourceType.notion'))
|
|
|
|
// Assert
|
|
expect(props.changeType).not.toHaveBeenCalled()
|
|
expect(props.onHideFilePreview).not.toHaveBeenCalled()
|
|
expect(props.onHideWebsitePreview).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Click Handler Tests - Web
|
|
// ==========================================
|
|
describe('Web Click Handler', () => {
|
|
it('should call changeType and hide previews when clicking Web option', () => {
|
|
// Arrange
|
|
const props = { ...createDefaultProps(), dataSourceType: DataSourceType.FILE }
|
|
render(<DataSourceSelector {...props} />)
|
|
|
|
// Act
|
|
fireEvent.click(screen.getByText('datasetCreation.stepOne.dataSourceType.web'))
|
|
|
|
// Assert
|
|
expect(props.changeType).toHaveBeenCalledWith(DataSourceType.WEB)
|
|
expect(props.onHideFilePreview).toHaveBeenCalled()
|
|
expect(props.onHideNotionPreview).toHaveBeenCalled()
|
|
expect(props.onHideWebsitePreview).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should NOT call changeType when clicking Web option while disabled', () => {
|
|
// Arrange
|
|
const props = {
|
|
...createDefaultProps(),
|
|
dataSourceType: DataSourceType.FILE,
|
|
dataSourceTypeDisable: true,
|
|
}
|
|
render(<DataSourceSelector {...props} />)
|
|
|
|
// Act
|
|
fireEvent.click(screen.getByText('datasetCreation.stepOne.dataSourceType.web'))
|
|
|
|
// Assert
|
|
expect(props.changeType).not.toHaveBeenCalled()
|
|
expect(props.onHideFilePreview).not.toHaveBeenCalled()
|
|
expect(props.onHideNotionPreview).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Disabled State Tests
|
|
// ==========================================
|
|
describe('Disabled State', () => {
|
|
it('should show disabled style for non-active options when disabled', () => {
|
|
// Arrange
|
|
const props = {
|
|
...createDefaultProps(),
|
|
dataSourceType: DataSourceType.FILE,
|
|
dataSourceTypeDisable: true,
|
|
}
|
|
|
|
// Act
|
|
render(<DataSourceSelector {...props} />)
|
|
|
|
// Assert
|
|
const notionOption = screen.getByText('datasetCreation.stepOne.dataSourceType.notion').closest('div')
|
|
const webOption = screen.getByText('datasetCreation.stepOne.dataSourceType.web').closest('div')
|
|
expect(notionOption?.className).toContain('disabled')
|
|
expect(webOption?.className).toContain('disabled')
|
|
})
|
|
|
|
it('should NOT show disabled style for active option when disabled', () => {
|
|
// Arrange
|
|
const props = {
|
|
...createDefaultProps(),
|
|
dataSourceType: DataSourceType.FILE,
|
|
dataSourceTypeDisable: true,
|
|
}
|
|
|
|
// Act
|
|
render(<DataSourceSelector {...props} />)
|
|
|
|
// Assert
|
|
const fileOption = screen.getByText('datasetCreation.stepOne.dataSourceType.file').closest('div')
|
|
expect(fileOption?.className).toContain('active')
|
|
expect(fileOption?.className).not.toContain('disabled')
|
|
})
|
|
})
|
|
|
|
// ==========================================
|
|
// Web Disabled Config Test
|
|
// ==========================================
|
|
describe('Web Feature Flag', () => {
|
|
it('should not render Web option when all web features are disabled', async () => {
|
|
// Arrange - Override the config mock for this test
|
|
vi.doMock('@/config', () => ({
|
|
ENABLE_WEBSITE_FIRECRAWL: false,
|
|
ENABLE_WEBSITE_JINAREADER: false,
|
|
ENABLE_WEBSITE_WATERCRAWL: false,
|
|
}))
|
|
|
|
// Re-import the component with new mock
|
|
const { default: DataSourceSelectorNoWeb } = await import('./data-source-selector')
|
|
const props = createDefaultProps()
|
|
|
|
// Act
|
|
render(<DataSourceSelectorNoWeb {...props} />)
|
|
|
|
// Assert
|
|
expect(screen.getByText('datasetCreation.stepOne.dataSourceType.file')).toBeInTheDocument()
|
|
expect(screen.getByText('datasetCreation.stepOne.dataSourceType.notion')).toBeInTheDocument()
|
|
// Web option should still be there because the module was already loaded with enabled config
|
|
// This test documents the behavior rather than testing the feature flag itself
|
|
})
|
|
})
|
|
})
|