mirror of
https://github.com/langgenius/dify.git
synced 2026-02-22 02:44:43 +08:00
Co-authored-by: CodingOnStar <hanxujiang@dify.ai> Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
309 lines
8.8 KiB
TypeScript
309 lines
8.8 KiB
TypeScript
import { act, renderHook, waitFor } from '@testing-library/react'
|
|
import { describe, expect, it, vi } from 'vitest'
|
|
import { DataType } from '../types'
|
|
import useEditDatasetMetadata from './use-edit-dataset-metadata'
|
|
|
|
// Mock service hooks
|
|
const mockDoAddMetaData = vi.fn().mockResolvedValue({})
|
|
const mockDoRenameMetaData = vi.fn().mockResolvedValue({})
|
|
const mockDoDeleteMetaData = vi.fn().mockResolvedValue({})
|
|
const mockToggleBuiltInStatus = vi.fn().mockResolvedValue({})
|
|
|
|
vi.mock('@/service/knowledge/use-metadata', () => ({
|
|
useDatasetMetaData: () => ({
|
|
data: {
|
|
doc_metadata: [
|
|
{ id: '1', name: 'field_one', type: DataType.string, count: 5 },
|
|
{ id: '2', name: 'field_two', type: DataType.number, count: 3 },
|
|
],
|
|
built_in_field_enabled: false,
|
|
},
|
|
}),
|
|
useCreateMetaData: () => ({
|
|
mutate: mockDoAddMetaData,
|
|
}),
|
|
useRenameMeta: () => ({
|
|
mutate: mockDoRenameMetaData,
|
|
}),
|
|
useDeleteMetaData: () => ({
|
|
mutateAsync: mockDoDeleteMetaData,
|
|
}),
|
|
useUpdateBuiltInStatus: () => ({
|
|
mutateAsync: mockToggleBuiltInStatus,
|
|
}),
|
|
useBuiltInMetaDataFields: () => ({
|
|
data: {
|
|
fields: [
|
|
{ name: 'created_at', type: DataType.time },
|
|
{ name: 'modified_at', type: DataType.time },
|
|
],
|
|
},
|
|
}),
|
|
}))
|
|
|
|
// Mock Toast
|
|
vi.mock('@/app/components/base/toast', () => ({
|
|
default: {
|
|
notify: vi.fn(),
|
|
},
|
|
}))
|
|
|
|
// Mock useCheckMetadataName
|
|
vi.mock('./use-check-metadata-name', () => ({
|
|
default: () => ({
|
|
checkName: (name: string) => ({
|
|
errorMsg: name && /^[a-z][a-z0-9_]*$/.test(name) ? '' : 'Invalid name',
|
|
}),
|
|
}),
|
|
}))
|
|
|
|
// Mock localStorage
|
|
const localStorageMock = {
|
|
getItem: vi.fn(),
|
|
setItem: vi.fn(),
|
|
removeItem: vi.fn(),
|
|
clear: vi.fn(),
|
|
}
|
|
Object.defineProperty(window, 'localStorage', { value: localStorageMock })
|
|
|
|
describe('useEditDatasetMetadata', () => {
|
|
const defaultProps = {
|
|
datasetId: 'ds-1',
|
|
onUpdateDocList: vi.fn(),
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
localStorageMock.getItem.mockReturnValue(null)
|
|
})
|
|
|
|
describe('Hook Initialization', () => {
|
|
it('should initialize with isShowEditModal as false', () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
expect(result.current.isShowEditModal).toBe(false)
|
|
})
|
|
|
|
it('should return showEditModal function', () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
expect(typeof result.current.showEditModal).toBe('function')
|
|
})
|
|
|
|
it('should return hideEditModal function', () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
expect(typeof result.current.hideEditModal).toBe('function')
|
|
})
|
|
|
|
it('should return datasetMetaData', () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
expect(result.current.datasetMetaData).toBeDefined()
|
|
})
|
|
|
|
it('should return handleAddMetaData function', () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
expect(typeof result.current.handleAddMetaData).toBe('function')
|
|
})
|
|
|
|
it('should return handleRename function', () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
expect(typeof result.current.handleRename).toBe('function')
|
|
})
|
|
|
|
it('should return handleDeleteMetaData function', () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
expect(typeof result.current.handleDeleteMetaData).toBe('function')
|
|
})
|
|
|
|
it('should return builtInMetaData', () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
expect(result.current.builtInMetaData).toBeDefined()
|
|
})
|
|
|
|
it('should return builtInEnabled', () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
expect(typeof result.current.builtInEnabled).toBe('boolean')
|
|
})
|
|
|
|
it('should return setBuiltInEnabled function', () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
expect(typeof result.current.setBuiltInEnabled).toBe('function')
|
|
})
|
|
})
|
|
|
|
describe('Modal Control', () => {
|
|
it('should show modal when showEditModal is called', () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
|
|
act(() => {
|
|
result.current.showEditModal()
|
|
})
|
|
|
|
expect(result.current.isShowEditModal).toBe(true)
|
|
})
|
|
|
|
it('should hide modal when hideEditModal is called', () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
|
|
act(() => {
|
|
result.current.showEditModal()
|
|
})
|
|
|
|
act(() => {
|
|
result.current.hideEditModal()
|
|
})
|
|
|
|
expect(result.current.isShowEditModal).toBe(false)
|
|
})
|
|
|
|
it('should handle toggle of modal state', () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
|
|
// Initially closed
|
|
expect(result.current.isShowEditModal).toBe(false)
|
|
|
|
// Show, hide, show
|
|
act(() => result.current.showEditModal())
|
|
expect(result.current.isShowEditModal).toBe(true)
|
|
|
|
act(() => result.current.hideEditModal())
|
|
expect(result.current.isShowEditModal).toBe(false)
|
|
|
|
act(() => result.current.showEditModal())
|
|
expect(result.current.isShowEditModal).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('handleAddMetaData', () => {
|
|
it('should call doAddMetaData with valid name', async () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
|
|
await act(async () => {
|
|
await result.current.handleAddMetaData({
|
|
name: 'valid_name',
|
|
type: DataType.string,
|
|
})
|
|
})
|
|
|
|
expect(mockDoAddMetaData).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should reject invalid name', async () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
|
|
await expect(
|
|
act(async () => {
|
|
await result.current.handleAddMetaData({
|
|
name: '',
|
|
type: DataType.string,
|
|
})
|
|
}),
|
|
).rejects.toThrow()
|
|
})
|
|
})
|
|
|
|
describe('handleRename', () => {
|
|
it('should call doRenameMetaData with valid name', async () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
|
|
await act(async () => {
|
|
await result.current.handleRename({
|
|
id: '1',
|
|
name: 'new_valid_name',
|
|
type: DataType.string,
|
|
count: 5,
|
|
})
|
|
})
|
|
|
|
expect(mockDoRenameMetaData).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should call onUpdateDocList after rename', async () => {
|
|
const onUpdateDocList = vi.fn()
|
|
const { result } = renderHook(() =>
|
|
useEditDatasetMetadata({ ...defaultProps, onUpdateDocList }),
|
|
)
|
|
|
|
await act(async () => {
|
|
await result.current.handleRename({
|
|
id: '1',
|
|
name: 'renamed',
|
|
type: DataType.string,
|
|
count: 5,
|
|
})
|
|
})
|
|
|
|
await waitFor(() => {
|
|
expect(onUpdateDocList).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
it('should reject invalid name for rename', async () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
|
|
await expect(
|
|
act(async () => {
|
|
await result.current.handleRename({
|
|
id: '1',
|
|
name: 'Invalid Name',
|
|
type: DataType.string,
|
|
count: 5,
|
|
})
|
|
}),
|
|
).rejects.toThrow()
|
|
})
|
|
})
|
|
|
|
describe('handleDeleteMetaData', () => {
|
|
it('should call doDeleteMetaData', async () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
|
|
await act(async () => {
|
|
await result.current.handleDeleteMetaData('1')
|
|
})
|
|
|
|
expect(mockDoDeleteMetaData).toHaveBeenCalledWith('1')
|
|
})
|
|
|
|
it('should call onUpdateDocList after delete', async () => {
|
|
const onUpdateDocList = vi.fn()
|
|
const { result } = renderHook(() =>
|
|
useEditDatasetMetadata({ ...defaultProps, onUpdateDocList }),
|
|
)
|
|
|
|
await act(async () => {
|
|
await result.current.handleDeleteMetaData('1')
|
|
})
|
|
|
|
await waitFor(() => {
|
|
expect(onUpdateDocList).toHaveBeenCalled()
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('Built-in Status', () => {
|
|
it('should toggle built-in status', async () => {
|
|
const { result } = renderHook(() => useEditDatasetMetadata(defaultProps))
|
|
|
|
await act(async () => {
|
|
await result.current.setBuiltInEnabled(true)
|
|
})
|
|
|
|
expect(mockToggleBuiltInStatus).toHaveBeenCalledWith(true)
|
|
})
|
|
})
|
|
|
|
describe('Edge Cases', () => {
|
|
it('should handle different datasetIds', () => {
|
|
const { result, rerender } = renderHook(
|
|
props => useEditDatasetMetadata(props),
|
|
{ initialProps: defaultProps },
|
|
)
|
|
|
|
expect(result.current).toBeDefined()
|
|
|
|
rerender({ ...defaultProps, datasetId: 'ds-2' })
|
|
|
|
expect(result.current).toBeDefined()
|
|
})
|
|
})
|
|
})
|